fix disconnect bug in libvncserver
[presencevnc] / libvnc / libvncclient / rfbproto.c
1 /*
2  *  Copyright (C) 2000-2002 Constantin Kaplinsky.  All Rights Reserved.
3  *  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved.
4  *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
5  *
6  *  This is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This software is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this software; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
19  *  USA.
20  */
21
22 /*
23  * rfbproto.c - functions to deal with client side of RFB protocol.
24  */
25
26 #ifdef __STRICT_ANSI__
27 #define _BSD_SOURCE
28 #define _POSIX_SOURCE
29 #endif
30 #ifndef WIN32
31 #include <unistd.h>
32 #else
33 #define strncasecmp _strnicmp
34 #endif
35 #include <errno.h>
36 #ifndef WIN32
37 #include <pwd.h>
38 #endif
39 #include <rfb/rfbclient.h>
40 #ifdef LIBVNCSERVER_HAVE_LIBZ
41 #include <zlib.h>
42 #ifdef __CHECKER__
43 #undef Z_NULL
44 #define Z_NULL NULL
45 #endif
46 #endif
47 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
48 #include <jpeglib.h>
49 #endif
50 #include <stdarg.h>
51 #include <time.h>
52
53 #include "minilzo.h"
54
55 /*
56  * rfbClientLog prints a time-stamped message to the log file (stderr).
57  */
58
59 rfbBool rfbEnableClientLogging=TRUE;
60
61 static void
62 rfbDefaultClientLog(const char *format, ...)
63 {
64     va_list args;
65     char buf[256];
66     time_t log_clock;
67
68     if(!rfbEnableClientLogging)
69       return;
70
71     va_start(args, format);
72
73     time(&log_clock);
74     strftime(buf, 255, "%d/%m/%Y %X ", localtime(&log_clock));
75     fprintf(stderr,buf);
76
77     vfprintf(stderr, format, args);
78     fflush(stderr);
79
80     va_end(args);
81 }
82
83 rfbClientLogProc rfbClientLog=rfbDefaultClientLog;
84 rfbClientLogProc rfbClientErr=rfbDefaultClientLog;
85
86 /* extensions */
87
88 rfbClientProtocolExtension* rfbClientExtensions = NULL;
89
90 void rfbClientRegisterExtension(rfbClientProtocolExtension* e)
91 {
92         e->next = rfbClientExtensions;
93         rfbClientExtensions = e;
94 }
95
96 /* client data */
97
98 void rfbClientSetClientData(rfbClient* client, void* tag, void* data)
99 {
100         rfbClientData* clientData = client->clientData;
101
102         while(clientData && clientData->tag != tag)
103                 clientData = clientData->next;
104         if(clientData == NULL) {
105                 clientData = calloc(sizeof(rfbClientData), 1);
106                 clientData->next = client->clientData;
107                 client->clientData = clientData;
108                 clientData->tag = tag;
109         }
110
111         clientData->data = data;
112 }
113
114 void* rfbClientGetClientData(rfbClient* client, void* tag)
115 {
116         rfbClientData* clientData = client->clientData;
117
118         while(clientData) {
119                 if(clientData->tag == tag)
120                         return clientData->data;
121                 clientData = clientData->next;
122         }
123
124         return NULL;
125 }
126
127 /* messages */
128
129 static void FillRectangle(rfbClient* client, int x, int y, int w, int h, uint32_t colour) {
130   int i,j;
131
132 #define FILL_RECT(BPP) \
133     for(j=y*client->width;j<(y+h)*client->width;j+=client->width) \
134       for(i=x;i<x+w;i++) \
135         ((uint##BPP##_t*)client->frameBuffer)[j+i]=colour;
136
137   switch(client->format.bitsPerPixel) {
138   case  8: FILL_RECT(8);  break;
139   case 16: FILL_RECT(16); break;
140   case 32: FILL_RECT(32); break;
141   default:
142     rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel);
143   }
144 }
145
146 static void CopyRectangle(rfbClient* client, uint8_t* buffer, int x, int y, int w, int h) {
147   int j;
148
149 #define COPY_RECT(BPP) \
150   { \
151     int rs = w * BPP / 8, rs2 = client->width * BPP / 8; \
152     for (j = ((x * (BPP / 8)) + (y * rs2)); j < (y + h) * rs2; j += rs2) { \
153       memcpy(client->frameBuffer + j, buffer, rs); \
154       buffer += rs; \
155     } \
156   }
157
158   switch(client->format.bitsPerPixel) {
159   case  8: COPY_RECT(8);  break;
160   case 16: COPY_RECT(16); break;
161   case 32: COPY_RECT(32); break;
162   default:
163     rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel);
164   }
165 }
166
167 /* TODO: test */
168 static void CopyRectangleFromRectangle(rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y) {
169   int i,j;
170
171 #define COPY_RECT_FROM_RECT(BPP) \
172   { \
173     uint##BPP##_t* _buffer=((uint##BPP##_t*)client->frameBuffer)+(src_y-dest_y)*client->width+src_x-dest_x; \
174     if (dest_y < src_y) { \
175       for(j = dest_y*client->width; j < (dest_y+h)*client->width; j += client->width) { \
176         if (dest_x < src_x) { \
177           for(i = dest_x; i < dest_x+w; i++) { \
178             ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
179           } \
180         } else { \
181           for(i = dest_x+w-1; i >= dest_x; i--) { \
182             ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
183           } \
184         } \
185       } \
186     } else { \
187       for(j = (dest_y+h-1)*client->width; j >= dest_y*client->width; j-=client->width) { \
188         if (dest_x < src_x) { \
189           for(i = dest_x; i < dest_x+w; i++) { \
190             ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
191           } \
192         } else { \
193           for(i = dest_x+w-1; i >= dest_x; i--) { \
194             ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
195           } \
196         } \
197       } \
198     } \
199   }
200
201   switch(client->format.bitsPerPixel) {
202   case  8: COPY_RECT_FROM_RECT(8);  break;
203   case 16: COPY_RECT_FROM_RECT(16); break;
204   case 32: COPY_RECT_FROM_RECT(32); break;
205   default:
206     rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel);
207   }
208 }
209
210 static rfbBool HandleRRE8(rfbClient* client, int rx, int ry, int rw, int rh);
211 static rfbBool HandleRRE16(rfbClient* client, int rx, int ry, int rw, int rh);
212 static rfbBool HandleRRE32(rfbClient* client, int rx, int ry, int rw, int rh);
213 static rfbBool HandleCoRRE8(rfbClient* client, int rx, int ry, int rw, int rh);
214 static rfbBool HandleCoRRE16(rfbClient* client, int rx, int ry, int rw, int rh);
215 static rfbBool HandleCoRRE32(rfbClient* client, int rx, int ry, int rw, int rh);
216 static rfbBool HandleHextile8(rfbClient* client, int rx, int ry, int rw, int rh);
217 static rfbBool HandleHextile16(rfbClient* client, int rx, int ry, int rw, int rh);
218 static rfbBool HandleHextile32(rfbClient* client, int rx, int ry, int rw, int rh);
219 static rfbBool HandleUltra8(rfbClient* client, int rx, int ry, int rw, int rh);
220 static rfbBool HandleUltra16(rfbClient* client, int rx, int ry, int rw, int rh);
221 static rfbBool HandleUltra32(rfbClient* client, int rx, int ry, int rw, int rh);
222 static rfbBool HandleUltraZip8(rfbClient* client, int rx, int ry, int rw, int rh);
223 static rfbBool HandleUltraZip16(rfbClient* client, int rx, int ry, int rw, int rh);
224 static rfbBool HandleUltraZip32(rfbClient* client, int rx, int ry, int rw, int rh);
225 #ifdef LIBVNCSERVER_HAVE_LIBZ
226 static rfbBool HandleZlib8(rfbClient* client, int rx, int ry, int rw, int rh);
227 static rfbBool HandleZlib16(rfbClient* client, int rx, int ry, int rw, int rh);
228 static rfbBool HandleZlib32(rfbClient* client, int rx, int ry, int rw, int rh);
229 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
230 static rfbBool HandleTight8(rfbClient* client, int rx, int ry, int rw, int rh);
231 static rfbBool HandleTight16(rfbClient* client, int rx, int ry, int rw, int rh);
232 static rfbBool HandleTight32(rfbClient* client, int rx, int ry, int rw, int rh);
233
234 static long ReadCompactLen (rfbClient* client);
235
236 static void JpegInitSource(j_decompress_ptr cinfo);
237 static boolean JpegFillInputBuffer(j_decompress_ptr cinfo);
238 static void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes);
239 static void JpegTermSource(j_decompress_ptr cinfo);
240 static void JpegSetSrcManager(j_decompress_ptr cinfo, uint8_t *compressedData,
241                               int compressedLen);
242 #endif
243 static rfbBool HandleZRLE8(rfbClient* client, int rx, int ry, int rw, int rh);
244 static rfbBool HandleZRLE15(rfbClient* client, int rx, int ry, int rw, int rh);
245 static rfbBool HandleZRLE16(rfbClient* client, int rx, int ry, int rw, int rh);
246 static rfbBool HandleZRLE24(rfbClient* client, int rx, int ry, int rw, int rh);
247 static rfbBool HandleZRLE24Up(rfbClient* client, int rx, int ry, int rw, int rh);
248 static rfbBool HandleZRLE24Down(rfbClient* client, int rx, int ry, int rw, int rh);
249 static rfbBool HandleZRLE32(rfbClient* client, int rx, int ry, int rw, int rh);
250 #endif
251
252 /*
253  * Server Capability Functions
254  */
255 rfbBool
256 SupportsClient2Server(rfbClient* client, int messageType)
257 {
258     return (client->supportedMessages.client2server[((messageType & 0xFF)/8)] & (1<<(messageType % 8)) ? TRUE : FALSE);
259 }
260
261 rfbBool
262 SupportsServer2Client(rfbClient* client, int messageType)
263 {
264     return (client->supportedMessages.server2client[((messageType & 0xFF)/8)] & (1<<(messageType % 8)) ? TRUE : FALSE);
265 }
266
267 void
268 SetClient2Server(rfbClient* client, int messageType)
269 {
270   client->supportedMessages.client2server[((messageType & 0xFF)/8)] |= (1<<(messageType % 8));
271 }
272
273 void
274 SetServer2Client(rfbClient* client, int messageType)
275 {
276   client->supportedMessages.server2client[((messageType & 0xFF)/8)] |= (1<<(messageType % 8));
277 }
278
279 void
280 ClearClient2Server(rfbClient* client, int messageType)
281 {
282   client->supportedMessages.client2server[((messageType & 0xFF)/8)] &= (!(1<<(messageType % 8)));
283 }
284
285 void
286 ClearServer2Client(rfbClient* client, int messageType)
287 {
288   client->supportedMessages.server2client[((messageType & 0xFF)/8)] &= (!(1<<(messageType % 8)));
289 }
290
291
292 void
293 DefaultSupportedMessages(rfbClient* client)
294 {
295     memset((char *)&client->supportedMessages,0,sizeof(client->supportedMessages));
296
297     /* Default client supported messages (universal RFB 3.3 protocol) */
298     SetClient2Server(client, rfbSetPixelFormat);
299     /* SetClient2Server(client, rfbFixColourMapEntries); Not currently supported */
300     SetClient2Server(client, rfbSetEncodings);
301     SetClient2Server(client, rfbFramebufferUpdateRequest);
302     SetClient2Server(client, rfbKeyEvent);
303     SetClient2Server(client, rfbPointerEvent);
304     SetClient2Server(client, rfbClientCutText);
305     /* technically, we only care what we can *send* to the server
306      * but, we set Server2Client Just in case it ever becomes useful
307      */
308     SetServer2Client(client, rfbFramebufferUpdate);
309     SetServer2Client(client, rfbSetColourMapEntries);
310     SetServer2Client(client, rfbBell);
311     SetServer2Client(client, rfbServerCutText);
312 }
313
314 void
315 DefaultSupportedMessagesUltraVNC(rfbClient* client)
316 {
317     DefaultSupportedMessages(client);
318     SetClient2Server(client, rfbFileTransfer);
319     SetClient2Server(client, rfbSetScale);
320     SetClient2Server(client, rfbSetServerInput);
321     SetClient2Server(client, rfbSetSW);
322     SetClient2Server(client, rfbTextChat);
323     SetClient2Server(client, rfbPalmVNCSetScaleFactor);
324     /* technically, we only care what we can *send* to the server */
325     SetServer2Client(client, rfbResizeFrameBuffer);
326     SetServer2Client(client, rfbPalmVNCReSizeFrameBuffer);
327     SetServer2Client(client, rfbFileTransfer);
328     SetServer2Client(client, rfbTextChat);
329 }
330
331
332 void
333 DefaultSupportedMessagesTightVNC(rfbClient* client)
334 {
335     DefaultSupportedMessages(client);
336     SetClient2Server(client, rfbFileTransfer);
337     SetClient2Server(client, rfbSetServerInput);
338     SetClient2Server(client, rfbSetSW);
339     /* SetClient2Server(client, rfbTextChat); */
340     /* technically, we only care what we can *send* to the server */
341     SetServer2Client(client, rfbFileTransfer);
342     SetServer2Client(client, rfbTextChat);
343 }
344
345 /*
346  * ConnectToRFBServer.
347  */
348
349 rfbBool
350 ConnectToRFBServer(rfbClient* client,const char *hostname, int port)
351 {
352   unsigned int host;
353
354   if (client->serverPort==-1) {
355     /* serverHost is a file recorded by vncrec. */
356     const char* magic="vncLog0.0";
357     char buffer[10];
358     rfbVNCRec* rec = (rfbVNCRec*)malloc(sizeof(rfbVNCRec));
359     client->vncRec = rec;
360
361     rec->file = fopen(client->serverHost,"rb");
362     rec->tv.tv_sec = 0;
363     rec->readTimestamp = FALSE;
364     rec->doNotSleep = FALSE;
365     
366     if (!rec->file) {
367       rfbClientLog("Could not open %s.\n",client->serverHost);
368       return FALSE;
369     }
370     setbuf(rec->file,NULL);
371     fread(buffer,1,strlen(magic),rec->file);
372     if (strncmp(buffer,magic,strlen(magic))) {
373       rfbClientLog("File %s was not recorded by vncrec.\n",client->serverHost);
374       fclose(rec->file);
375       return FALSE;
376     }
377     client->sock = 0;
378     return TRUE;
379   }
380
381   if (!StringToIPAddr(hostname, &host)) {
382     rfbClientLog("Couldn't convert '%s' to host address\n", hostname);
383     return FALSE;
384   }
385
386   client->sock = ConnectClientToTcpAddr(host, port);
387
388   if (client->sock < 0) {
389     rfbClientLog("Unable to connect to VNC server\n");
390     return FALSE;
391   }
392
393   return SetNonBlocking(client->sock);
394 }
395
396 extern void rfbClientEncryptBytes(unsigned char* bytes, char* passwd);
397
398 rfbBool
399 rfbHandleAuthResult(rfbClient* client)
400 {
401     uint32_t authResult=0, reasonLen=0;
402     char *reason=NULL;
403
404     if (!ReadFromRFBServer(client, (char *)&authResult, 4)) return FALSE;
405
406     authResult = rfbClientSwap32IfLE(authResult);
407
408     switch (authResult) {
409     case rfbVncAuthOK:
410       rfbClientLog("VNC authentication succeeded\n");
411       return TRUE;
412       break;
413     case rfbVncAuthFailed:
414       if (client->major==3 && client->minor>7)
415       {
416         /* we have an error following */
417         if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
418         reasonLen = rfbClientSwap32IfLE(reasonLen);
419         reason = malloc(reasonLen+1);
420         if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
421         reason[reasonLen]=0;
422         rfbClientLog("VNC connection failed: %s\n",reason);
423         free(reason);
424         return FALSE;
425       }
426       rfbClientLog("VNC authentication failed\n");
427       return FALSE;
428     case rfbVncAuthTooMany:
429       rfbClientLog("VNC authentication failed - too many tries\n");
430       return FALSE;
431     }
432
433     rfbClientLog("Unknown VNC authentication result: %d\n",
434                  (int)authResult);
435     return FALSE;
436 }
437
438
439 /*
440  * InitialiseRFBConnection.
441  */
442
443 rfbBool
444 InitialiseRFBConnection(rfbClient* client)
445 {
446   rfbProtocolVersionMsg pv;
447   int major,minor;
448   uint32_t authScheme, reasonLen;
449   char *reason;
450   uint8_t challenge[CHALLENGESIZE];
451   char *passwd=NULL;
452   int i;
453   rfbClientInitMsg ci;
454
455   /* if the connection is immediately closed, don't report anything, so
456        that pmw's monitor can make test connections */
457
458   if (client->listenSpecified)
459     errorMessageOnReadFailure = FALSE;
460
461   if (!ReadFromRFBServer(client, pv, sz_rfbProtocolVersionMsg)) return FALSE;
462   pv[sz_rfbProtocolVersionMsg]=0;
463
464   errorMessageOnReadFailure = TRUE;
465
466   pv[sz_rfbProtocolVersionMsg] = 0;
467
468   if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) {
469     rfbClientLog("Not a valid VNC server (%s)\n",pv);
470     return FALSE;
471   }
472
473
474   DefaultSupportedMessages(client);
475   client->major = major;
476   client->minor = minor;
477
478   /* fall back to viewer supported version */
479   if ((major==rfbProtocolMajorVersion) && (minor>rfbProtocolMinorVersion))
480     client->minor = rfbProtocolMinorVersion;
481
482   /* UltraVNC uses minor codes 4 and 6 for the server */
483   if (major==3 && (minor==4 || minor==6)) {
484       rfbClientLog("UltraVNC server detected, enabling UltraVNC specific messages\n",pv);
485       DefaultSupportedMessagesUltraVNC(client);
486   }
487
488   /* TightVNC uses minor codes 5 for the server */
489   if (major==3 && minor==5) {
490       rfbClientLog("TightVNC server detected, enabling TightVNC specific messages\n",pv);
491       DefaultSupportedMessagesTightVNC(client);
492   }
493
494   /* we do not support > RFB3.8 */
495   if (major==3 && minor>8)
496     client->minor=8;
497
498   rfbClientLog("VNC server supports protocol version %d.%d (viewer %d.%d)\n",
499           major, minor, rfbProtocolMajorVersion, rfbProtocolMinorVersion);
500
501   sprintf(pv,rfbProtocolVersionFormat,client->major,client->minor);
502
503   if (!WriteToRFBServer(client, pv, sz_rfbProtocolVersionMsg)) return FALSE;
504
505
506   /* 3.7 and onwards sends a # of security types first */
507   if (client->major==3 && client->minor > 6)
508   {
509     uint8_t count=0;
510     uint8_t loop=0;
511     uint8_t flag=0;
512     uint8_t tAuth=0;
513     
514     if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE;
515
516     if (count==0)
517     {
518         rfbClientLog("List of security types is ZERO, expecting an error to follow\n"); 
519
520         /* we have an error following */
521         if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
522         reasonLen = rfbClientSwap32IfLE(reasonLen);
523         reason = malloc(reasonLen+1);
524         if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
525         reason[reasonLen]=0;
526         rfbClientLog("VNC connection failed: %s\n",reason);
527         free(reason);
528         return FALSE;
529     }
530
531     rfbClientLog("We have %d security types to read\n", count);
532     /* now, we have a list of available security types to read ( uint8_t[] ) */
533     for (loop=0;loop<count;loop++)
534     {
535         if (!ReadFromRFBServer(client, (char *)&tAuth, 1)) return FALSE;
536         rfbClientLog("%d) Received security type %d\n", loop, tAuth);
537         if ((flag==0) && ((tAuth==rfbVncAuth) || (tAuth==rfbNoAuth)))
538         {
539             flag++;
540             authScheme=tAuth;
541             rfbClientLog("Selecting security type %d (%d/%d in the list)\n", authScheme, loop, count);
542             /* send back a single byte indicating which security type to use */
543             if (!WriteToRFBServer(client, (char *)&tAuth, 1)) return FALSE;
544             
545         }
546     }
547   }
548   else
549   {
550     if (!ReadFromRFBServer(client, (char *)&authScheme, 4)) return FALSE;
551     authScheme = rfbClientSwap32IfLE(authScheme);
552   }
553   
554   rfbClientLog("Selected Security Scheme %d\n", authScheme);
555   
556   switch (authScheme) {
557
558   case rfbConnFailed:
559     if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
560     reasonLen = rfbClientSwap32IfLE(reasonLen);
561
562     reason = malloc(reasonLen+1);
563
564     if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
565     reason[reasonLen]=0;
566     rfbClientLog("VNC connection failed: %s\n", reason);
567     free(reason);
568     return FALSE;
569
570   case rfbNoAuth:
571     rfbClientLog("No authentication needed\n");
572
573     /* 3.8 and upwards sends a Security Result for rfbNoAuth */
574     if (client->major==3 && client->minor > 7)
575         if (!rfbHandleAuthResult(client)) return FALSE;        
576
577     break;
578
579   case rfbVncAuth:
580     if (!ReadFromRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
581
582     if (client->serverPort!=-1) { /* if not playing a vncrec file */
583       if (client->GetPassword)
584         passwd = client->GetPassword(client);
585
586       if ((!passwd) || (strlen(passwd) == 0)) {
587         rfbClientLog("Reading password failed\n");
588         return FALSE;
589       }
590       if (strlen(passwd) > 8) {
591         passwd[8] = '\0';
592       }
593
594       rfbClientEncryptBytes(challenge, passwd);
595
596       /* Lose the password from memory */
597       for (i = strlen(passwd); i >= 0; i--) {
598         passwd[i] = '\0';
599       }
600       free(passwd);
601
602       if (!WriteToRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
603     }
604
605     /* Handle the SecurityResult message */
606     if (!rfbHandleAuthResult(client)) return FALSE;
607     break;
608
609   default:
610     rfbClientLog("Unknown authentication scheme from VNC server: %d\n",
611             (int)authScheme);
612     return FALSE;
613   }
614
615   ci.shared = (client->appData.shareDesktop ? 1 : 0);
616
617   if (!WriteToRFBServer(client,  (char *)&ci, sz_rfbClientInitMsg)) return FALSE;
618
619   if (!ReadFromRFBServer(client, (char *)&client->si, sz_rfbServerInitMsg)) return FALSE;
620
621   client->si.framebufferWidth = rfbClientSwap16IfLE(client->si.framebufferWidth);
622   client->si.framebufferHeight = rfbClientSwap16IfLE(client->si.framebufferHeight);
623   client->si.format.redMax = rfbClientSwap16IfLE(client->si.format.redMax);
624   client->si.format.greenMax = rfbClientSwap16IfLE(client->si.format.greenMax);
625   client->si.format.blueMax = rfbClientSwap16IfLE(client->si.format.blueMax);
626   client->si.nameLength = rfbClientSwap32IfLE(client->si.nameLength);
627
628   client->desktopName = malloc(client->si.nameLength + 1);
629   if (!client->desktopName) {
630     rfbClientLog("Error allocating memory for desktop name, %lu bytes\n",
631             (unsigned long)client->si.nameLength);
632     return FALSE;
633   }
634
635   if (!ReadFromRFBServer(client, client->desktopName, client->si.nameLength)) return FALSE;
636
637   client->desktopName[client->si.nameLength] = 0;
638
639   rfbClientLog("Desktop name \"%s\"\n",client->desktopName);
640
641   rfbClientLog("Connected to VNC server, using protocol version %d.%d\n",
642           client->major, client->minor);
643
644   rfbClientLog("VNC server default format:\n");
645   PrintPixelFormat(&client->si.format);
646
647   return TRUE;
648 }
649
650
651 /*
652  * SetFormatAndEncodings.
653  */
654
655 rfbBool
656 SetFormatAndEncodings(rfbClient* client)
657 {
658   rfbSetPixelFormatMsg spf;
659   char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4];
660
661   rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf;
662   uint32_t *encs = (uint32_t *)(&buf[sz_rfbSetEncodingsMsg]);
663   int len = 0;
664   rfbBool requestCompressLevel = FALSE;
665   rfbBool requestQualityLevel = FALSE;
666   rfbBool requestLastRectEncoding = FALSE;
667   rfbClientProtocolExtension* e;
668
669   if (!SupportsClient2Server(client, rfbSetPixelFormat)) return TRUE;
670
671   spf.type = rfbSetPixelFormat;
672   spf.format = client->format;
673   spf.format.redMax = rfbClientSwap16IfLE(spf.format.redMax);
674   spf.format.greenMax = rfbClientSwap16IfLE(spf.format.greenMax);
675   spf.format.blueMax = rfbClientSwap16IfLE(spf.format.blueMax);
676
677   if (!WriteToRFBServer(client, (char *)&spf, sz_rfbSetPixelFormatMsg))
678     return FALSE;
679
680
681   if (!SupportsClient2Server(client, rfbSetEncodings)) return TRUE;
682
683   se->type = rfbSetEncodings;
684   se->nEncodings = 0;
685
686   if (client->appData.encodingsString) {
687     const char *encStr = client->appData.encodingsString;
688     int encStrLen;
689     do {
690       const char *nextEncStr = strchr(encStr, ' ');
691       if (nextEncStr) {
692         encStrLen = nextEncStr - encStr;
693         nextEncStr++;
694       } else {
695         encStrLen = strlen(encStr);
696       }
697
698       if (strncasecmp(encStr,"raw",encStrLen) == 0) {
699         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRaw);
700       } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) {
701         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCopyRect);
702 #ifdef LIBVNCSERVER_HAVE_LIBZ
703 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
704       } else if (strncasecmp(encStr,"tight",encStrLen) == 0) {
705         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTight);
706         requestLastRectEncoding = TRUE;
707         if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
708           requestCompressLevel = TRUE;
709         if (client->appData.enableJPEG)
710           requestQualityLevel = TRUE;
711 #endif
712 #endif
713       } else if (strncasecmp(encStr,"hextile",encStrLen) == 0) {
714         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingHextile);
715 #ifdef LIBVNCSERVER_HAVE_LIBZ
716       } else if (strncasecmp(encStr,"zlib",encStrLen) == 0) {
717         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlib);
718         if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
719           requestCompressLevel = TRUE;
720       } else if (strncasecmp(encStr,"zlibhex",encStrLen) == 0) {
721         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlibHex);
722         if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
723           requestCompressLevel = TRUE;
724       } else if (strncasecmp(encStr,"zrle",encStrLen) == 0) {
725         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZRLE);
726       } else if (strncasecmp(encStr,"zywrle",encStrLen) == 0) {
727         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZYWRLE);
728         requestQualityLevel = TRUE;
729 #endif
730       } else if ((strncasecmp(encStr,"ultra",encStrLen) == 0) || (strncasecmp(encStr,"ultrazip",encStrLen) == 0)) {
731         /* There are 2 encodings used in 'ultra' */
732         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltra);
733         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltraZip);
734       } else if (strncasecmp(encStr,"corre",encStrLen) == 0) {
735         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCoRRE);
736       } else if (strncasecmp(encStr,"rre",encStrLen) == 0) {
737         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE);
738       } else {
739         rfbClientLog("Unknown encoding '%.*s'\n",encStrLen,encStr);
740       }
741
742       encStr = nextEncStr;
743     } while (encStr && se->nEncodings < MAX_ENCODINGS);
744
745     if (se->nEncodings < MAX_ENCODINGS && requestCompressLevel) {
746       encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.compressLevel +
747                                           rfbEncodingCompressLevel0);
748     }
749
750     if (se->nEncodings < MAX_ENCODINGS && requestQualityLevel) {
751       if (client->appData.qualityLevel < 0 || client->appData.qualityLevel > 9)
752         client->appData.qualityLevel = 5;
753       encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel +
754                                           rfbEncodingQualityLevel0);
755     }
756   }
757   else {
758     if (SameMachine(client->sock)) {
759       /* TODO:
760       if (!tunnelSpecified) {
761       */
762       rfbClientLog("Same machine: preferring raw encoding\n");
763       encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRaw);
764       /*
765       } else {
766         rfbClientLog("Tunneling active: preferring tight encoding\n");
767       }
768       */
769     }
770
771     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCopyRect);
772 #ifdef LIBVNCSERVER_HAVE_LIBZ
773 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
774     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTight);
775     requestLastRectEncoding = TRUE;
776 #endif
777 #endif
778     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingHextile);
779 #ifdef LIBVNCSERVER_HAVE_LIBZ
780     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlib);
781     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZRLE);
782     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZYWRLE);
783 #endif
784     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltra);
785     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltraZip);
786     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCoRRE);
787     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE);
788
789     if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9) {
790       encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.compressLevel +
791                                           rfbEncodingCompressLevel0);
792     } else /* if (!tunnelSpecified) */ {
793       /* If -tunnel option was provided, we assume that server machine is
794          not in the local network so we use default compression level for
795          tight encoding instead of fast compression. Thus we are
796          requesting level 1 compression only if tunneling is not used. */
797       encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCompressLevel1);
798     }
799
800     if (client->appData.enableJPEG) {
801       if (client->appData.qualityLevel < 0 || client->appData.qualityLevel > 9)
802         client->appData.qualityLevel = 5;
803       encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel +
804                                           rfbEncodingQualityLevel0);
805     }
806   }
807
808
809
810   /* Remote Cursor Support (local to viewer) */
811   if (client->appData.useRemoteCursor) {
812     if (se->nEncodings < MAX_ENCODINGS)
813       encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingXCursor);
814     if (se->nEncodings < MAX_ENCODINGS)
815       encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRichCursor);
816     if (se->nEncodings < MAX_ENCODINGS)
817       encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPointerPos);
818   }
819
820   /* Keyboard State Encodings */
821   if (se->nEncodings < MAX_ENCODINGS)
822     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingKeyboardLedState);
823
824   /* New Frame Buffer Size */
825   if (se->nEncodings < MAX_ENCODINGS && client->canHandleNewFBSize)
826     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingNewFBSize);
827
828   /* Last Rect */
829   if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding)
830     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect);
831
832   /* Server Capabilities */
833   if (se->nEncodings < MAX_ENCODINGS)
834     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedMessages);
835   if (se->nEncodings < MAX_ENCODINGS)
836     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedEncodings);
837   if (se->nEncodings < MAX_ENCODINGS)
838     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingServerIdentity);
839
840
841   /* client extensions */
842   for(e = rfbClientExtensions; e; e = e->next)
843     if(e->encodings) {
844       int* enc;
845       for(enc = e->encodings; *enc; enc++)
846         encs[se->nEncodings++] = rfbClientSwap32IfLE(*enc);
847     }
848
849   len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
850
851   se->nEncodings = rfbClientSwap16IfLE(se->nEncodings);
852
853   if (!WriteToRFBServer(client, buf, len)) return FALSE;
854
855   return TRUE;
856 }
857
858
859 /*
860  * SendIncrementalFramebufferUpdateRequest.
861  */
862
863 rfbBool
864 SendIncrementalFramebufferUpdateRequest(rfbClient* client)
865 {
866         return SendFramebufferUpdateRequest(client,
867                         client->updateRect.x, client->updateRect.y,
868                         client->updateRect.w, client->updateRect.h, TRUE);
869 }
870
871
872 /*
873  * SendFramebufferUpdateRequest.
874  */
875
876 rfbBool
877 SendFramebufferUpdateRequest(rfbClient* client, int x, int y, int w, int h, rfbBool incremental)
878 {
879   rfbFramebufferUpdateRequestMsg fur;
880
881   if (!SupportsClient2Server(client, rfbFramebufferUpdateRequest)) return TRUE;
882   
883   fur.type = rfbFramebufferUpdateRequest;
884   fur.incremental = incremental ? 1 : 0;
885   fur.x = rfbClientSwap16IfLE(x);
886   fur.y = rfbClientSwap16IfLE(y);
887   fur.w = rfbClientSwap16IfLE(w);
888   fur.h = rfbClientSwap16IfLE(h);
889
890   if (!WriteToRFBServer(client, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg))
891     return FALSE;
892
893   return TRUE;
894 }
895
896
897 /*
898  * SendScaleSetting.
899  */
900 rfbBool
901 SendScaleSetting(rfbClient* client,int scaleSetting)
902 {
903   rfbSetScaleMsg ssm;
904
905   ssm.scale = scaleSetting;
906   ssm.pad = 0;
907   
908   /* favor UltraVNC SetScale if both are supported */
909   if (SupportsClient2Server(client, rfbSetScale)) {
910       ssm.type = rfbSetScale;
911       if (!WriteToRFBServer(client, (char *)&ssm, sz_rfbSetScaleMsg))
912           return FALSE;
913   }
914   
915   if (SupportsClient2Server(client, rfbPalmVNCSetScaleFactor)) {
916       ssm.type = rfbPalmVNCSetScaleFactor;
917       if (!WriteToRFBServer(client, (char *)&ssm, sz_rfbSetScaleMsg))
918           return FALSE;
919   }
920
921   return TRUE;
922 }
923
924 /*
925  * TextChatFunctions (UltraVNC)
926  * Extremely bandwidth friendly method of communicating with a user
927  * (Think HelpDesk type applications)
928  */
929
930 rfbBool TextChatSend(rfbClient* client, char *text)
931 {
932     rfbTextChatMsg chat;
933     int count = strlen(text);
934
935     if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
936     chat.type = rfbTextChat;
937     chat.pad1 = 0;
938     chat.pad2 = 0;
939     chat.length = (uint32_t)count;
940     chat.length = rfbClientSwap32IfLE(chat.length);
941
942     if (!WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg))
943         return FALSE;
944
945     if (count>0) {
946         if (!WriteToRFBServer(client, text, count))
947             return FALSE;
948     }
949     return TRUE;
950 }
951
952 rfbBool TextChatOpen(rfbClient* client)
953 {
954     rfbTextChatMsg chat;
955
956     if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
957     chat.type = rfbTextChat;
958     chat.pad1 = 0;
959     chat.pad2 = 0;
960     chat.length = rfbClientSwap32IfLE(rfbTextChatOpen);
961     return  (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
962 }
963
964 rfbBool TextChatClose(rfbClient* client)
965 {
966     rfbTextChatMsg chat;
967     if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
968     chat.type = rfbTextChat;
969     chat.pad1 = 0;
970     chat.pad2 = 0;
971     chat.length = rfbClientSwap32IfLE(rfbTextChatClose);
972     return  (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
973 }
974
975 rfbBool TextChatFinish(rfbClient* client)
976 {
977     rfbTextChatMsg chat;
978     if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
979     chat.type = rfbTextChat;
980     chat.pad1 = 0;
981     chat.pad2 = 0;
982     chat.length = rfbClientSwap32IfLE(rfbTextChatFinished);
983     return  (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
984 }
985
986 /*
987  * UltraVNC Server Input Disable
988  * Apparently, the remote client can *prevent* the local user from interacting with the display
989  * I would think this is extremely helpful when used in a HelpDesk situation
990  */
991 rfbBool PermitServerInput(rfbClient* client, int enabled)
992 {
993     rfbSetServerInputMsg msg;
994
995     if (!SupportsClient2Server(client, rfbSetServerInput)) return TRUE;
996     /* enabled==1, then server input from local keyboard is disabled */
997     msg.type = rfbSetServerInput;
998     msg.status = (enabled ? 1 : 0);
999     msg.pad = 0;
1000     return  (WriteToRFBServer(client, (char *)&msg, sz_rfbSetServerInputMsg) ? TRUE : FALSE);
1001 }
1002
1003
1004 /*
1005  * SendPointerEvent.
1006  */
1007
1008 rfbBool
1009 SendPointerEvent(rfbClient* client,int x, int y, int buttonMask)
1010 {
1011   rfbPointerEventMsg pe;
1012
1013   if (!SupportsClient2Server(client, rfbPointerEvent)) return TRUE;
1014
1015   pe.type = rfbPointerEvent;
1016   pe.buttonMask = buttonMask;
1017   if (x < 0) x = 0;
1018   if (y < 0) y = 0;
1019
1020   pe.x = rfbClientSwap16IfLE(x);
1021   pe.y = rfbClientSwap16IfLE(y);
1022   return WriteToRFBServer(client, (char *)&pe, sz_rfbPointerEventMsg);
1023 }
1024
1025
1026 /*
1027  * SendKeyEvent.
1028  */
1029
1030 rfbBool
1031 SendKeyEvent(rfbClient* client, uint32_t key, rfbBool down)
1032 {
1033   rfbKeyEventMsg ke;
1034
1035   if (!SupportsClient2Server(client, rfbKeyEvent)) return TRUE;
1036
1037   ke.type = rfbKeyEvent;
1038   ke.down = down ? 1 : 0;
1039   ke.key = rfbClientSwap32IfLE(key);
1040   return WriteToRFBServer(client, (char *)&ke, sz_rfbKeyEventMsg);
1041 }
1042
1043
1044 /*
1045  * SendClientCutText.
1046  */
1047
1048 rfbBool
1049 SendClientCutText(rfbClient* client, char *str, int len)
1050 {
1051   rfbClientCutTextMsg cct;
1052
1053   if (!SupportsClient2Server(client, rfbClientCutText)) return TRUE;
1054
1055   cct.type = rfbClientCutText;
1056   cct.length = rfbClientSwap32IfLE(len);
1057   return  (WriteToRFBServer(client, (char *)&cct, sz_rfbClientCutTextMsg) &&
1058            WriteToRFBServer(client, str, len));
1059 }
1060
1061
1062
1063 /*
1064  * HandleRFBServerMessage.
1065  */
1066
1067 rfbBool
1068 HandleRFBServerMessage(rfbClient* client)
1069 {
1070   rfbServerToClientMsg msg;
1071
1072   if (client->serverPort==-1)
1073     client->vncRec->readTimestamp = TRUE;
1074   if (!ReadFromRFBServer(client, (char *)&msg, 1))
1075     return FALSE;
1076
1077   switch (msg.type) {
1078
1079   case rfbSetColourMapEntries:
1080   {
1081     /* TODO:
1082     int i;
1083     uint16_t rgb[3];
1084     XColor xc;
1085
1086     if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
1087                            sz_rfbSetColourMapEntriesMsg - 1))
1088       return FALSE;
1089
1090     msg.scme.firstColour = rfbClientSwap16IfLE(msg.scme.firstColour);
1091     msg.scme.nColours = rfbClientSwap16IfLE(msg.scme.nColours);
1092
1093     for (i = 0; i < msg.scme.nColours; i++) {
1094       if (!ReadFromRFBServer(client, (char *)rgb, 6))
1095         return FALSE;
1096       xc.pixel = msg.scme.firstColour + i;
1097       xc.red = rfbClientSwap16IfLE(rgb[0]);
1098       xc.green = rfbClientSwap16IfLE(rgb[1]);
1099       xc.blue = rfbClientSwap16IfLE(rgb[2]);
1100       xc.flags = DoRed|DoGreen|DoBlue;
1101       XStoreColor(dpy, cmap, &xc);
1102     }
1103     */
1104
1105     break;
1106   }
1107
1108   case rfbFramebufferUpdate:
1109   {
1110     rfbFramebufferUpdateRectHeader rect;
1111     int linesToRead;
1112     int bytesPerLine;
1113     int i;
1114
1115     if (!ReadFromRFBServer(client, ((char *)&msg.fu) + 1,
1116                            sz_rfbFramebufferUpdateMsg - 1))
1117       return FALSE;
1118
1119     msg.fu.nRects = rfbClientSwap16IfLE(msg.fu.nRects);
1120
1121     for (i = 0; i < msg.fu.nRects; i++) {
1122       if (!ReadFromRFBServer(client, (char *)&rect, sz_rfbFramebufferUpdateRectHeader))
1123         return FALSE;
1124
1125       rect.encoding = rfbClientSwap32IfLE(rect.encoding);
1126       if (rect.encoding == rfbEncodingLastRect)
1127         break;
1128
1129       rect.r.x = rfbClientSwap16IfLE(rect.r.x);
1130       rect.r.y = rfbClientSwap16IfLE(rect.r.y);
1131       rect.r.w = rfbClientSwap16IfLE(rect.r.w);
1132       rect.r.h = rfbClientSwap16IfLE(rect.r.h);
1133
1134
1135       if (rect.encoding == rfbEncodingXCursor ||
1136           rect.encoding == rfbEncodingRichCursor) {
1137
1138         if (!HandleCursorShape(client,
1139                                rect.r.x, rect.r.y, rect.r.w, rect.r.h,
1140                                rect.encoding)) {
1141           return FALSE;
1142         }
1143         continue;
1144       }
1145
1146       if (rect.encoding == rfbEncodingPointerPos) {
1147         if (!client->HandleCursorPos(client,rect.r.x, rect.r.y)) {
1148           return FALSE;
1149         }
1150         continue;
1151       }
1152       
1153       if (rect.encoding == rfbEncodingKeyboardLedState) {
1154           /* OK! We have received a keyboard state message!!! */
1155           client->KeyboardLedStateEnabled = 1;
1156           if (client->HandleKeyboardLedState!=NULL)
1157               client->HandleKeyboardLedState(client, rect.r.x, 0);
1158           /* stash it for the future */
1159           client->CurrentKeyboardLedState = rect.r.x;
1160           continue;
1161       }
1162
1163       if (rect.encoding == rfbEncodingNewFBSize) {
1164         client->width = rect.r.w;
1165         client->height = rect.r.h;
1166         client->MallocFrameBuffer(client);
1167         SendFramebufferUpdateRequest(client, 0, 0, rect.r.w, rect.r.h, FALSE);
1168         rfbClientLog("Got new framebuffer size: %dx%d\n", rect.r.w, rect.r.h);
1169         continue;
1170       }
1171
1172       /* rect.r.w=byte count */
1173       if (rect.encoding == rfbEncodingSupportedMessages) {
1174           int loop;
1175           if (!ReadFromRFBServer(client, (char *)&client->supportedMessages, sz_rfbSupportedMessages))
1176               return FALSE;
1177
1178           /* msgs is two sets of bit flags of supported messages client2server[] and server2client[] */
1179           /* currently ignored by this library */
1180
1181           rfbClientLog("client2server supported messages (bit flags)\n");
1182           for (loop=0;loop<32;loop+=8)
1183             rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop,
1184                 client->supportedMessages.client2server[loop],   client->supportedMessages.client2server[loop+1],
1185                 client->supportedMessages.client2server[loop+2], client->supportedMessages.client2server[loop+3],
1186                 client->supportedMessages.client2server[loop+4], client->supportedMessages.client2server[loop+5],
1187                 client->supportedMessages.client2server[loop+6], client->supportedMessages.client2server[loop+7]);
1188
1189           rfbClientLog("server2client supported messages (bit flags)\n");
1190           for (loop=0;loop<32;loop+=8)
1191             rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop,
1192                 client->supportedMessages.server2client[loop],   client->supportedMessages.server2client[loop+1],
1193                 client->supportedMessages.server2client[loop+2], client->supportedMessages.server2client[loop+3],
1194                 client->supportedMessages.server2client[loop+4], client->supportedMessages.server2client[loop+5],
1195                 client->supportedMessages.server2client[loop+6], client->supportedMessages.server2client[loop+7]);
1196           continue;
1197       }
1198
1199       /* rect.r.w=byte count, rect.r.h=# of encodings */
1200       if (rect.encoding == rfbEncodingSupportedEncodings) {
1201           char *buffer;
1202           buffer = malloc(rect.r.w);
1203           if (!ReadFromRFBServer(client, buffer, rect.r.w))
1204           {
1205               free(buffer);
1206               return FALSE;
1207           }
1208
1209           /* buffer now contains rect.r.h # of uint32_t encodings that the server supports */
1210           /* currently ignored by this library */
1211           free(buffer);
1212           continue;
1213       }
1214
1215       /* rect.r.w=byte count */
1216       if (rect.encoding == rfbEncodingServerIdentity) {
1217           char *buffer;
1218           buffer = malloc(rect.r.w+1);
1219           if (!ReadFromRFBServer(client, buffer, rect.r.w))
1220           {
1221               free(buffer);
1222               return FALSE;
1223           }
1224           buffer[rect.r.w]=0; /* null terminate, just in case */
1225           rfbClientLog("Connected to Server \"%s\"\n", buffer);
1226           free(buffer);
1227           continue;
1228       }
1229
1230       /* rfbEncodingUltraZip is a collection of subrects.   x = # of subrects, and h is always 0 */
1231       if (rect.encoding != rfbEncodingUltraZip)
1232       {
1233         if ((rect.r.x + rect.r.w > client->width) ||
1234             (rect.r.y + rect.r.h > client->height))
1235             {
1236               rfbClientLog("Rect too large: %dx%d at (%d, %d)\n",
1237                   rect.r.w, rect.r.h, rect.r.x, rect.r.y);
1238               return FALSE;
1239             }
1240
1241         /* UltraVNC with scaling, will send rectangles with a zero W or H
1242          *
1243         if ((rect.encoding != rfbEncodingTight) && 
1244             (rect.r.h * rect.r.w == 0))
1245         {
1246           rfbClientLog("Zero size rect - ignoring (encoding=%d (0x%08x) %dx, %dy, %dw, %dh)\n", rect.encoding, rect.encoding, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
1247           continue;
1248         }
1249         */
1250         
1251         /* If RichCursor encoding is used, we should prevent collisions
1252            between framebuffer updates and cursor drawing operations. */
1253         client->SoftCursorLockArea(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
1254       }
1255
1256       switch (rect.encoding) {
1257
1258       case rfbEncodingRaw: {
1259         int y=rect.r.y, h=rect.r.h;
1260
1261         bytesPerLine = rect.r.w * client->format.bitsPerPixel / 8;
1262         linesToRead = RFB_BUFFER_SIZE / bytesPerLine;
1263
1264         while (h > 0) {
1265           if (linesToRead > h)
1266             linesToRead = h;
1267
1268           if (!ReadFromRFBServer(client, client->buffer,bytesPerLine * linesToRead))
1269             return FALSE;
1270
1271           CopyRectangle(client, (uint8_t *)client->buffer,
1272                            rect.r.x, y, rect.r.w,linesToRead);
1273
1274           h -= linesToRead;
1275           y += linesToRead;
1276
1277         }
1278       } break;
1279
1280       case rfbEncodingCopyRect:
1281       {
1282         rfbCopyRect cr;
1283
1284         if (!ReadFromRFBServer(client, (char *)&cr, sz_rfbCopyRect))
1285           return FALSE;
1286
1287         cr.srcX = rfbClientSwap16IfLE(cr.srcX);
1288         cr.srcY = rfbClientSwap16IfLE(cr.srcY);
1289
1290         /* If RichCursor encoding is used, we should extend our
1291            "cursor lock area" (previously set to destination
1292            rectangle) to the source rectangle as well. */
1293         client->SoftCursorLockArea(client,
1294                                    cr.srcX, cr.srcY, rect.r.w, rect.r.h);
1295
1296         if (client->GotCopyRect != NULL) {
1297           client->GotCopyRect(client, cr.srcX, cr.srcY, rect.r.w, rect.r.h,
1298               rect.r.x, rect.r.y);
1299         } else
1300                 CopyRectangleFromRectangle(client,
1301                                    cr.srcX, cr.srcY, rect.r.w, rect.r.h,
1302                                    rect.r.x, rect.r.y);
1303
1304         break;
1305       }
1306
1307       case rfbEncodingRRE:
1308       {
1309         switch (client->format.bitsPerPixel) {
1310         case 8:
1311           if (!HandleRRE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1312             return FALSE;
1313           break;
1314         case 16:
1315           if (!HandleRRE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1316             return FALSE;
1317           break;
1318         case 32:
1319           if (!HandleRRE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1320             return FALSE;
1321           break;
1322         }
1323         break;
1324       }
1325
1326       case rfbEncodingCoRRE:
1327       {
1328         switch (client->format.bitsPerPixel) {
1329         case 8:
1330           if (!HandleCoRRE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1331             return FALSE;
1332           break;
1333         case 16:
1334           if (!HandleCoRRE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1335             return FALSE;
1336           break;
1337         case 32:
1338           if (!HandleCoRRE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1339             return FALSE;
1340           break;
1341         }
1342         break;
1343       }
1344
1345       case rfbEncodingHextile:
1346       {
1347         switch (client->format.bitsPerPixel) {
1348         case 8:
1349           if (!HandleHextile8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1350             return FALSE;
1351           break;
1352         case 16:
1353           if (!HandleHextile16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1354             return FALSE;
1355           break;
1356         case 32:
1357           if (!HandleHextile32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1358             return FALSE;
1359           break;
1360         }
1361         break;
1362       }
1363
1364       case rfbEncodingUltra:
1365       {
1366         switch (client->format.bitsPerPixel) {
1367         case 8:
1368           if (!HandleUltra8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1369             return FALSE;
1370           break;
1371         case 16:
1372           if (!HandleUltra16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1373             return FALSE;
1374           break;
1375         case 32:
1376           if (!HandleUltra32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1377             return FALSE;
1378           break;
1379         }
1380         break;
1381       }
1382       case rfbEncodingUltraZip:
1383       {
1384         switch (client->format.bitsPerPixel) {
1385         case 8:
1386           if (!HandleUltraZip8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1387             return FALSE;
1388           break;
1389         case 16:
1390           if (!HandleUltraZip16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1391             return FALSE;
1392           break;
1393         case 32:
1394           if (!HandleUltraZip32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1395             return FALSE;
1396           break;
1397         }
1398         break;
1399       }
1400
1401 #ifdef LIBVNCSERVER_HAVE_LIBZ
1402       case rfbEncodingZlib:
1403       {
1404         switch (client->format.bitsPerPixel) {
1405         case 8:
1406           if (!HandleZlib8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1407             return FALSE;
1408           break;
1409         case 16:
1410           if (!HandleZlib16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1411             return FALSE;
1412           break;
1413         case 32:
1414           if (!HandleZlib32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1415             return FALSE;
1416           break;
1417         }
1418         break;
1419      }
1420
1421 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
1422       case rfbEncodingTight:
1423       {
1424         switch (client->format.bitsPerPixel) {
1425         case 8:
1426           if (!HandleTight8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1427             return FALSE;
1428           break;
1429         case 16:
1430           if (!HandleTight16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1431             return FALSE;
1432           break;
1433         case 32:
1434           if (!HandleTight32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1435             return FALSE;
1436           break;
1437         }
1438         break;
1439       }
1440 #endif
1441       case rfbEncodingZRLE:
1442         /* Fail safe for ZYWRLE unsupport VNC server. */
1443         client->appData.qualityLevel = 9;
1444         /* fall through */
1445       case rfbEncodingZYWRLE:
1446       {
1447         switch (client->format.bitsPerPixel) {
1448         case 8:
1449           if (!HandleZRLE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1450             return FALSE;
1451           break;
1452         case 16:
1453           if (client->si.format.greenMax > 0x1F) {
1454             if (!HandleZRLE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1455               return FALSE;
1456           } else {
1457             if (!HandleZRLE15(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1458               return FALSE;
1459           }
1460           break;
1461         case 32:
1462         {
1463           uint32_t maxColor=(client->format.redMax<<client->format.redShift)|
1464                 (client->format.greenMax<<client->format.greenShift)|
1465                 (client->format.blueMax<<client->format.blueShift);
1466           if ((client->format.bigEndian && (maxColor&0xff)==0) ||
1467               (!client->format.bigEndian && (maxColor&0xff000000)==0)) {
1468             if (!HandleZRLE24(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1469               return FALSE;
1470           } else if (!client->format.bigEndian && (maxColor&0xff)==0) {
1471             if (!HandleZRLE24Up(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1472               return FALSE;
1473           } else if (client->format.bigEndian && (maxColor&0xff000000)==0) {
1474             if (!HandleZRLE24Down(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1475               return FALSE;
1476           } else if (!HandleZRLE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1477             return FALSE;
1478           break;
1479         }
1480         }
1481         break;
1482      }
1483
1484 #endif
1485
1486       default:
1487          {
1488            rfbBool handled = FALSE;
1489            rfbClientProtocolExtension* e;
1490
1491            for(e = rfbClientExtensions; !handled && e; e = e->next)
1492              if(e->handleEncoding && e->handleEncoding(client, &rect))
1493                handled = TRUE;
1494
1495            if(!handled) {
1496              rfbClientLog("Unknown rect encoding %d\n",
1497                  (int)rect.encoding);
1498              return FALSE;
1499            }
1500          }
1501       }
1502
1503       /* Now we may discard "soft cursor locks". */
1504       client->SoftCursorUnlockScreen(client);
1505
1506       client->GotFrameBufferUpdate(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
1507     }
1508
1509     if (!SendIncrementalFramebufferUpdateRequest(client))
1510       return FALSE;
1511
1512     break;
1513   }
1514
1515   case rfbBell:
1516   {
1517     client->Bell(client);
1518
1519     break;
1520   }
1521
1522   case rfbServerCutText:
1523   {
1524     char *buffer;
1525
1526     if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
1527                            sz_rfbServerCutTextMsg - 1))
1528       return FALSE;
1529
1530     msg.sct.length = rfbClientSwap32IfLE(msg.sct.length);
1531
1532     buffer = malloc(msg.sct.length+1);
1533
1534     if (!ReadFromRFBServer(client, buffer, msg.sct.length))
1535       return FALSE;
1536
1537     buffer[msg.sct.length] = 0;
1538
1539     if (client->GotXCutText)
1540       client->GotXCutText(client, buffer, msg.sct.length);
1541
1542     free(buffer);
1543
1544     break;
1545   }
1546
1547   case rfbTextChat:
1548   {
1549       char *buffer=NULL;
1550       if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
1551                              sz_rfbTextChatMsg- 1))
1552         return FALSE;
1553       msg.tc.length = rfbClientSwap32IfLE(msg.sct.length);
1554       switch(msg.tc.length) {
1555       case rfbTextChatOpen:
1556           rfbClientLog("Received TextChat Open\n");
1557           if (client->HandleTextChat!=NULL)
1558               client->HandleTextChat(client, (int)rfbTextChatOpen, NULL);
1559           break;
1560       case rfbTextChatClose:
1561           rfbClientLog("Received TextChat Close\n");
1562          if (client->HandleTextChat!=NULL)
1563               client->HandleTextChat(client, (int)rfbTextChatClose, NULL);
1564           break;
1565       case rfbTextChatFinished:
1566           rfbClientLog("Received TextChat Finished\n");
1567          if (client->HandleTextChat!=NULL)
1568               client->HandleTextChat(client, (int)rfbTextChatFinished, NULL);
1569           break;
1570       default:
1571           buffer=malloc(msg.tc.length+1);
1572           if (!ReadFromRFBServer(client, buffer, msg.tc.length))
1573           {
1574               free(buffer);
1575               return FALSE;
1576           }
1577           /* Null Terminate <just in case> */
1578           buffer[msg.tc.length]=0;
1579           rfbClientLog("Received TextChat \"%s\"\n", buffer);
1580           if (client->HandleTextChat!=NULL)
1581               client->HandleTextChat(client, (int)msg.tc.length, buffer);
1582           free(buffer);
1583           break;
1584       }
1585       break;
1586   }
1587
1588   case rfbResizeFrameBuffer:
1589   {
1590     if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
1591                            sz_rfbResizeFrameBufferMsg -1))
1592       return FALSE;
1593     client->width = rfbClientSwap16IfLE(msg.rsfb.framebufferWidth);
1594     client->height = rfbClientSwap16IfLE(msg.rsfb.framebufferHeigth);
1595     client->MallocFrameBuffer(client);
1596     SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE);
1597     rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height);
1598     break;
1599   }
1600
1601   case rfbPalmVNCReSizeFrameBuffer:
1602   {
1603     if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
1604                            sz_rfbPalmVNCReSizeFrameBufferMsg -1))
1605       return FALSE;
1606     client->width = rfbClientSwap16IfLE(msg.prsfb.buffer_w);
1607     client->height = rfbClientSwap16IfLE(msg.prsfb.buffer_h);
1608     client->MallocFrameBuffer(client);
1609     SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE);
1610     rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height);
1611     break;
1612   }
1613
1614   default:
1615     {
1616       rfbBool handled = FALSE;
1617       rfbClientProtocolExtension* e;
1618
1619       for(e = rfbClientExtensions; !handled && e; e = e->next)
1620         if(e->handleMessage && e->handleMessage(client, &msg))
1621           handled = TRUE;
1622
1623       if(!handled) {
1624         char buffer[256];
1625         rfbClientLog("Unknown message type %d from VNC server\n",msg.type);
1626         ReadFromRFBServer(client, buffer, 256);
1627         return FALSE;
1628       }
1629     }
1630   }
1631
1632   return TRUE;
1633 }
1634
1635
1636 #define GET_PIXEL8(pix, ptr) ((pix) = *(ptr)++)
1637
1638 #define GET_PIXEL16(pix, ptr) (((uint8_t*)&(pix))[0] = *(ptr)++, \
1639                                ((uint8_t*)&(pix))[1] = *(ptr)++)
1640
1641 #define GET_PIXEL32(pix, ptr) (((uint8_t*)&(pix))[0] = *(ptr)++, \
1642                                ((uint8_t*)&(pix))[1] = *(ptr)++, \
1643                                ((uint8_t*)&(pix))[2] = *(ptr)++, \
1644                                ((uint8_t*)&(pix))[3] = *(ptr)++)
1645
1646 /* CONCAT2 concatenates its two arguments.  CONCAT2E does the same but also
1647    expands its arguments if they are macros */
1648
1649 #define CONCAT2(a,b) a##b
1650 #define CONCAT2E(a,b) CONCAT2(a,b)
1651 #define CONCAT3(a,b,c) a##b##c
1652 #define CONCAT3E(a,b,c) CONCAT3(a,b,c)
1653
1654 #define BPP 8
1655 #include "rre.c"
1656 #include "corre.c"
1657 #include "hextile.c"
1658 #include "ultra.c"
1659 #include "zlib.c"
1660 #include "tight.c"
1661 #include "zrle.c"
1662 #undef BPP
1663 #define BPP 16
1664 #include "rre.c"
1665 #include "corre.c"
1666 #include "hextile.c"
1667 #include "ultra.c"
1668 #include "zlib.c"
1669 #include "tight.c"
1670 #include "zrle.c"
1671 #define REALBPP 15
1672 #include "zrle.c"
1673 #undef BPP
1674 #define BPP 32
1675 #include "rre.c"
1676 #include "corre.c"
1677 #include "hextile.c"
1678 #include "ultra.c"
1679 #include "zlib.c"
1680 #include "tight.c"
1681 #include "zrle.c"
1682 #define REALBPP 24
1683 #include "zrle.c"
1684 #define REALBPP 24
1685 #define UNCOMP 8
1686 #include "zrle.c"
1687 #define REALBPP 24
1688 #define UNCOMP -8
1689 #include "zrle.c"
1690 #undef BPP
1691
1692
1693 /*
1694  * PrintPixelFormat.
1695  */
1696
1697 void
1698 PrintPixelFormat(rfbPixelFormat *format)
1699 {
1700   if (format->bitsPerPixel == 1) {
1701     rfbClientLog("  Single bit per pixel.\n");
1702     rfbClientLog(
1703             "  %s significant bit in each byte is leftmost on the screen.\n",
1704             (format->bigEndian ? "Most" : "Least"));
1705   } else {
1706     rfbClientLog("  %d bits per pixel.\n",format->bitsPerPixel);
1707     if (format->bitsPerPixel != 8) {
1708       rfbClientLog("  %s significant byte first in each pixel.\n",
1709               (format->bigEndian ? "Most" : "Least"));
1710     }
1711     if (format->trueColour) {
1712       rfbClientLog("  TRUE colour: max red %d green %d blue %d"
1713                    ", shift red %d green %d blue %d\n",
1714                    format->redMax, format->greenMax, format->blueMax,
1715                    format->redShift, format->greenShift, format->blueShift);
1716     } else {
1717       rfbClientLog("  Colour map (not true colour).\n");
1718     }
1719   }
1720 }
1721
1722 /* avoid name clashes with LibVNCServer */
1723
1724 #define rfbEncryptBytes rfbClientEncryptBytes
1725 #define rfbDes rfbClientDes
1726 #define rfbDesKey rfbClientDesKey
1727 #define rfbUseKey rfbClientUseKey
1728 #define rfbCPKey rfbClientCPKey
1729
1730 #include "../libvncserver/vncauth.c"
1731 #include "../libvncserver/d3des.c"