update about dialog
[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) || major>3)
496   {
497     client->major=3;
498     client->minor=8;
499   }
500
501   rfbClientLog("VNC server supports protocol version %d.%d (viewer %d.%d)\n",
502           major, minor, rfbProtocolMajorVersion, rfbProtocolMinorVersion);
503
504   sprintf(pv,rfbProtocolVersionFormat,client->major,client->minor);
505
506   if (!WriteToRFBServer(client, pv, sz_rfbProtocolVersionMsg)) return FALSE;
507
508
509   /* 3.7 and onwards sends a # of security types first */
510   if (client->major==3 && client->minor > 6)
511   {
512     uint8_t count=0;
513     uint8_t loop=0;
514     uint8_t flag=0;
515     uint8_t tAuth=0;
516     
517     if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE;
518
519     if (count==0)
520     {
521         rfbClientLog("List of security types is ZERO, expecting an error to follow\n"); 
522
523         /* we have an error following */
524         if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
525         reasonLen = rfbClientSwap32IfLE(reasonLen);
526         reason = malloc(reasonLen+1);
527         if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
528         reason[reasonLen]=0;
529         rfbClientLog("VNC connection failed: %s\n",reason);
530         free(reason);
531         return FALSE;
532     }
533
534     rfbClientLog("We have %d security types to read\n", count);
535     /* now, we have a list of available security types to read ( uint8_t[] ) */
536     for (loop=0;loop<count;loop++)
537     {
538         if (!ReadFromRFBServer(client, (char *)&tAuth, 1)) return FALSE;
539         rfbClientLog("%d) Received security type %d\n", loop, tAuth);
540         if ((flag==0) && ((tAuth==rfbVncAuth) || (tAuth==rfbNoAuth)))
541         {
542             flag++;
543             authScheme=tAuth;
544             rfbClientLog("Selecting security type %d (%d/%d in the list)\n", authScheme, loop, count);
545             /* send back a single byte indicating which security type to use */
546             if (!WriteToRFBServer(client, (char *)&tAuth, 1)) return FALSE;
547             
548         }
549     }
550   }
551   else
552   {
553     if (!ReadFromRFBServer(client, (char *)&authScheme, 4)) return FALSE;
554     authScheme = rfbClientSwap32IfLE(authScheme);
555   }
556   
557   rfbClientLog("Selected Security Scheme %d\n", authScheme);
558   
559   switch (authScheme) {
560
561   case rfbConnFailed:
562     if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
563     reasonLen = rfbClientSwap32IfLE(reasonLen);
564
565     reason = malloc(reasonLen+1);
566
567     if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
568     reason[reasonLen]=0;
569     rfbClientLog("VNC connection failed: %s\n", reason);
570     free(reason);
571     return FALSE;
572
573   case rfbNoAuth:
574     rfbClientLog("No authentication needed\n");
575
576     /* 3.8 and upwards sends a Security Result for rfbNoAuth */
577     if ((client->major==3 && client->minor > 7) || client->major>3)
578         if (!rfbHandleAuthResult(client)) return FALSE;        
579
580     break;
581
582   case rfbVncAuth:
583     if (!ReadFromRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
584
585     if (client->serverPort!=-1) { /* if not playing a vncrec file */
586       if (client->GetPassword)
587         passwd = client->GetPassword(client);
588
589       if ((!passwd) || (strlen(passwd) == 0)) {
590         rfbClientLog("Reading password failed\n");
591         return FALSE;
592       }
593       if (strlen(passwd) > 8) {
594         passwd[8] = '\0';
595       }
596
597       rfbClientEncryptBytes(challenge, passwd);
598
599       /* Lose the password from memory */
600       for (i = strlen(passwd); i >= 0; i--) {
601         passwd[i] = '\0';
602       }
603       free(passwd);
604
605       if (!WriteToRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
606     }
607
608     /* Handle the SecurityResult message */
609     if (!rfbHandleAuthResult(client)) return FALSE;
610     break;
611
612   default:
613     rfbClientLog("Unknown authentication scheme from VNC server: %d\n",
614             (int)authScheme);
615     return FALSE;
616   }
617
618   ci.shared = (client->appData.shareDesktop ? 1 : 0);
619
620   if (!WriteToRFBServer(client,  (char *)&ci, sz_rfbClientInitMsg)) return FALSE;
621
622   if (!ReadFromRFBServer(client, (char *)&client->si, sz_rfbServerInitMsg)) return FALSE;
623
624   client->si.framebufferWidth = rfbClientSwap16IfLE(client->si.framebufferWidth);
625   client->si.framebufferHeight = rfbClientSwap16IfLE(client->si.framebufferHeight);
626   client->si.format.redMax = rfbClientSwap16IfLE(client->si.format.redMax);
627   client->si.format.greenMax = rfbClientSwap16IfLE(client->si.format.greenMax);
628   client->si.format.blueMax = rfbClientSwap16IfLE(client->si.format.blueMax);
629   client->si.nameLength = rfbClientSwap32IfLE(client->si.nameLength);
630
631   client->desktopName = malloc(client->si.nameLength + 1);
632   if (!client->desktopName) {
633     rfbClientLog("Error allocating memory for desktop name, %lu bytes\n",
634             (unsigned long)client->si.nameLength);
635     return FALSE;
636   }
637
638   if (!ReadFromRFBServer(client, client->desktopName, client->si.nameLength)) return FALSE;
639
640   client->desktopName[client->si.nameLength] = 0;
641
642   rfbClientLog("Desktop name \"%s\"\n",client->desktopName);
643
644   rfbClientLog("Connected to VNC server, using protocol version %d.%d\n",
645           client->major, client->minor);
646
647   rfbClientLog("VNC server default format:\n");
648   PrintPixelFormat(&client->si.format);
649
650   return TRUE;
651 }
652
653
654 /*
655  * SetFormatAndEncodings.
656  */
657
658 rfbBool
659 SetFormatAndEncodings(rfbClient* client)
660 {
661   rfbSetPixelFormatMsg spf;
662   char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4];
663
664   rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf;
665   uint32_t *encs = (uint32_t *)(&buf[sz_rfbSetEncodingsMsg]);
666   int len = 0;
667   rfbBool requestCompressLevel = FALSE;
668   rfbBool requestQualityLevel = FALSE;
669   rfbBool requestLastRectEncoding = FALSE;
670   rfbClientProtocolExtension* e;
671
672   if (!SupportsClient2Server(client, rfbSetPixelFormat)) return TRUE;
673
674   spf.type = rfbSetPixelFormat;
675   spf.format = client->format;
676   spf.format.redMax = rfbClientSwap16IfLE(spf.format.redMax);
677   spf.format.greenMax = rfbClientSwap16IfLE(spf.format.greenMax);
678   spf.format.blueMax = rfbClientSwap16IfLE(spf.format.blueMax);
679
680   if (!WriteToRFBServer(client, (char *)&spf, sz_rfbSetPixelFormatMsg))
681     return FALSE;
682
683
684   if (!SupportsClient2Server(client, rfbSetEncodings)) return TRUE;
685
686   se->type = rfbSetEncodings;
687   se->nEncodings = 0;
688
689   if (client->appData.encodingsString) {
690     const char *encStr = client->appData.encodingsString;
691     int encStrLen;
692     do {
693       const char *nextEncStr = strchr(encStr, ' ');
694       if (nextEncStr) {
695         encStrLen = nextEncStr - encStr;
696         nextEncStr++;
697       } else {
698         encStrLen = strlen(encStr);
699       }
700
701       if (strncasecmp(encStr,"raw",encStrLen) == 0) {
702         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRaw);
703       } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) {
704         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCopyRect);
705 #ifdef LIBVNCSERVER_HAVE_LIBZ
706 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
707       } else if (strncasecmp(encStr,"tight",encStrLen) == 0) {
708         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTight);
709         requestLastRectEncoding = TRUE;
710         if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
711           requestCompressLevel = TRUE;
712         if (client->appData.enableJPEG)
713           requestQualityLevel = TRUE;
714 #endif
715 #endif
716       } else if (strncasecmp(encStr,"hextile",encStrLen) == 0) {
717         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingHextile);
718 #ifdef LIBVNCSERVER_HAVE_LIBZ
719       } else if (strncasecmp(encStr,"zlib",encStrLen) == 0) {
720         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlib);
721         if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
722           requestCompressLevel = TRUE;
723       } else if (strncasecmp(encStr,"zlibhex",encStrLen) == 0) {
724         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlibHex);
725         if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
726           requestCompressLevel = TRUE;
727       } else if (strncasecmp(encStr,"zrle",encStrLen) == 0) {
728         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZRLE);
729       } else if (strncasecmp(encStr,"zywrle",encStrLen) == 0) {
730         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZYWRLE);
731         requestQualityLevel = TRUE;
732 #endif
733       } else if ((strncasecmp(encStr,"ultra",encStrLen) == 0) || (strncasecmp(encStr,"ultrazip",encStrLen) == 0)) {
734         /* There are 2 encodings used in 'ultra' */
735         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltra);
736         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltraZip);
737       } else if (strncasecmp(encStr,"corre",encStrLen) == 0) {
738         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCoRRE);
739       } else if (strncasecmp(encStr,"rre",encStrLen) == 0) {
740         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE);
741       } else {
742         rfbClientLog("Unknown encoding '%.*s'\n",encStrLen,encStr);
743       }
744
745       encStr = nextEncStr;
746     } while (encStr && se->nEncodings < MAX_ENCODINGS);
747
748     if (se->nEncodings < MAX_ENCODINGS && requestCompressLevel) {
749       encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.compressLevel +
750                                           rfbEncodingCompressLevel0);
751     }
752
753     if (se->nEncodings < MAX_ENCODINGS && requestQualityLevel) {
754       if (client->appData.qualityLevel < 0 || client->appData.qualityLevel > 9)
755         client->appData.qualityLevel = 5;
756       encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel +
757                                           rfbEncodingQualityLevel0);
758     }
759   }
760   else {
761     if (SameMachine(client->sock)) {
762       /* TODO:
763       if (!tunnelSpecified) {
764       */
765       rfbClientLog("Same machine: preferring raw encoding\n");
766       encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRaw);
767       /*
768       } else {
769         rfbClientLog("Tunneling active: preferring tight encoding\n");
770       }
771       */
772     }
773
774     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCopyRect);
775 #ifdef LIBVNCSERVER_HAVE_LIBZ
776 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
777     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTight);
778     requestLastRectEncoding = TRUE;
779 #endif
780 #endif
781     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingHextile);
782 #ifdef LIBVNCSERVER_HAVE_LIBZ
783     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlib);
784     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZRLE);
785     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZYWRLE);
786 #endif
787     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltra);
788     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltraZip);
789     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCoRRE);
790     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE);
791
792     if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9) {
793       encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.compressLevel +
794                                           rfbEncodingCompressLevel0);
795     } else /* if (!tunnelSpecified) */ {
796       /* If -tunnel option was provided, we assume that server machine is
797          not in the local network so we use default compression level for
798          tight encoding instead of fast compression. Thus we are
799          requesting level 1 compression only if tunneling is not used. */
800       encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCompressLevel1);
801     }
802
803     if (client->appData.enableJPEG) {
804       if (client->appData.qualityLevel < 0 || client->appData.qualityLevel > 9)
805         client->appData.qualityLevel = 5;
806       encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel +
807                                           rfbEncodingQualityLevel0);
808     }
809   }
810
811
812
813   /* Remote Cursor Support (local to viewer) */
814   if (client->appData.useRemoteCursor) {
815     if (se->nEncodings < MAX_ENCODINGS)
816       encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingXCursor);
817     if (se->nEncodings < MAX_ENCODINGS)
818       encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRichCursor);
819     if (se->nEncodings < MAX_ENCODINGS)
820       encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPointerPos);
821   }
822
823   /* Keyboard State Encodings */
824   if (se->nEncodings < MAX_ENCODINGS)
825     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingKeyboardLedState);
826
827   /* New Frame Buffer Size */
828   if (se->nEncodings < MAX_ENCODINGS && client->canHandleNewFBSize)
829     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingNewFBSize);
830
831   /* Last Rect */
832   if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding)
833     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect);
834
835   /* Server Capabilities */
836   if (se->nEncodings < MAX_ENCODINGS)
837     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedMessages);
838   if (se->nEncodings < MAX_ENCODINGS)
839     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedEncodings);
840   if (se->nEncodings < MAX_ENCODINGS)
841     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingServerIdentity);
842
843
844   /* client extensions */
845   for(e = rfbClientExtensions; e; e = e->next)
846     if(e->encodings) {
847       int* enc;
848       for(enc = e->encodings; *enc; enc++)
849         encs[se->nEncodings++] = rfbClientSwap32IfLE(*enc);
850     }
851
852   len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
853
854   se->nEncodings = rfbClientSwap16IfLE(se->nEncodings);
855
856   if (!WriteToRFBServer(client, buf, len)) return FALSE;
857
858   return TRUE;
859 }
860
861
862 /*
863  * SendIncrementalFramebufferUpdateRequest.
864  */
865
866 rfbBool
867 SendIncrementalFramebufferUpdateRequest(rfbClient* client)
868 {
869         return SendFramebufferUpdateRequest(client,
870                         client->updateRect.x, client->updateRect.y,
871                         client->updateRect.w, client->updateRect.h, TRUE);
872 }
873
874
875 /*
876  * SendFramebufferUpdateRequest.
877  */
878
879 rfbBool
880 SendFramebufferUpdateRequest(rfbClient* client, int x, int y, int w, int h, rfbBool incremental)
881 {
882   rfbFramebufferUpdateRequestMsg fur;
883
884   if (!SupportsClient2Server(client, rfbFramebufferUpdateRequest)) return TRUE;
885   
886   fur.type = rfbFramebufferUpdateRequest;
887   fur.incremental = incremental ? 1 : 0;
888   fur.x = rfbClientSwap16IfLE(x);
889   fur.y = rfbClientSwap16IfLE(y);
890   fur.w = rfbClientSwap16IfLE(w);
891   fur.h = rfbClientSwap16IfLE(h);
892
893   if (!WriteToRFBServer(client, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg))
894     return FALSE;
895
896   return TRUE;
897 }
898
899
900 /*
901  * SendScaleSetting.
902  */
903 rfbBool
904 SendScaleSetting(rfbClient* client,int scaleSetting)
905 {
906   rfbSetScaleMsg ssm;
907
908   ssm.scale = scaleSetting;
909   ssm.pad = 0;
910   
911   /* favor UltraVNC SetScale if both are supported */
912   if (SupportsClient2Server(client, rfbSetScale)) {
913       ssm.type = rfbSetScale;
914       if (!WriteToRFBServer(client, (char *)&ssm, sz_rfbSetScaleMsg))
915           return FALSE;
916   }
917   
918   if (SupportsClient2Server(client, rfbPalmVNCSetScaleFactor)) {
919       ssm.type = rfbPalmVNCSetScaleFactor;
920       if (!WriteToRFBServer(client, (char *)&ssm, sz_rfbSetScaleMsg))
921           return FALSE;
922   }
923
924   return TRUE;
925 }
926
927 /*
928  * TextChatFunctions (UltraVNC)
929  * Extremely bandwidth friendly method of communicating with a user
930  * (Think HelpDesk type applications)
931  */
932
933 rfbBool TextChatSend(rfbClient* client, char *text)
934 {
935     rfbTextChatMsg chat;
936     int count = strlen(text);
937
938     if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
939     chat.type = rfbTextChat;
940     chat.pad1 = 0;
941     chat.pad2 = 0;
942     chat.length = (uint32_t)count;
943     chat.length = rfbClientSwap32IfLE(chat.length);
944
945     if (!WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg))
946         return FALSE;
947
948     if (count>0) {
949         if (!WriteToRFBServer(client, text, count))
950             return FALSE;
951     }
952     return TRUE;
953 }
954
955 rfbBool TextChatOpen(rfbClient* client)
956 {
957     rfbTextChatMsg chat;
958
959     if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
960     chat.type = rfbTextChat;
961     chat.pad1 = 0;
962     chat.pad2 = 0;
963     chat.length = rfbClientSwap32IfLE(rfbTextChatOpen);
964     return  (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
965 }
966
967 rfbBool TextChatClose(rfbClient* client)
968 {
969     rfbTextChatMsg chat;
970     if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
971     chat.type = rfbTextChat;
972     chat.pad1 = 0;
973     chat.pad2 = 0;
974     chat.length = rfbClientSwap32IfLE(rfbTextChatClose);
975     return  (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
976 }
977
978 rfbBool TextChatFinish(rfbClient* client)
979 {
980     rfbTextChatMsg chat;
981     if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
982     chat.type = rfbTextChat;
983     chat.pad1 = 0;
984     chat.pad2 = 0;
985     chat.length = rfbClientSwap32IfLE(rfbTextChatFinished);
986     return  (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
987 }
988
989 /*
990  * UltraVNC Server Input Disable
991  * Apparently, the remote client can *prevent* the local user from interacting with the display
992  * I would think this is extremely helpful when used in a HelpDesk situation
993  */
994 rfbBool PermitServerInput(rfbClient* client, int enabled)
995 {
996     rfbSetServerInputMsg msg;
997
998     if (!SupportsClient2Server(client, rfbSetServerInput)) return TRUE;
999     /* enabled==1, then server input from local keyboard is disabled */
1000     msg.type = rfbSetServerInput;
1001     msg.status = (enabled ? 1 : 0);
1002     msg.pad = 0;
1003     return  (WriteToRFBServer(client, (char *)&msg, sz_rfbSetServerInputMsg) ? TRUE : FALSE);
1004 }
1005
1006
1007 /*
1008  * SendPointerEvent.
1009  */
1010
1011 rfbBool
1012 SendPointerEvent(rfbClient* client,int x, int y, int buttonMask)
1013 {
1014   rfbPointerEventMsg pe;
1015
1016   if (!SupportsClient2Server(client, rfbPointerEvent)) return TRUE;
1017
1018   pe.type = rfbPointerEvent;
1019   pe.buttonMask = buttonMask;
1020   if (x < 0) x = 0;
1021   if (y < 0) y = 0;
1022
1023   pe.x = rfbClientSwap16IfLE(x);
1024   pe.y = rfbClientSwap16IfLE(y);
1025   return WriteToRFBServer(client, (char *)&pe, sz_rfbPointerEventMsg);
1026 }
1027
1028
1029 /*
1030  * SendKeyEvent.
1031  */
1032
1033 rfbBool
1034 SendKeyEvent(rfbClient* client, uint32_t key, rfbBool down)
1035 {
1036   rfbKeyEventMsg ke;
1037
1038   if (!SupportsClient2Server(client, rfbKeyEvent)) return TRUE;
1039
1040   ke.type = rfbKeyEvent;
1041   ke.down = down ? 1 : 0;
1042   ke.key = rfbClientSwap32IfLE(key);
1043   return WriteToRFBServer(client, (char *)&ke, sz_rfbKeyEventMsg);
1044 }
1045
1046
1047 /*
1048  * SendClientCutText.
1049  */
1050
1051 rfbBool
1052 SendClientCutText(rfbClient* client, char *str, int len)
1053 {
1054   rfbClientCutTextMsg cct;
1055
1056   if (!SupportsClient2Server(client, rfbClientCutText)) return TRUE;
1057
1058   cct.type = rfbClientCutText;
1059   cct.length = rfbClientSwap32IfLE(len);
1060   return  (WriteToRFBServer(client, (char *)&cct, sz_rfbClientCutTextMsg) &&
1061            WriteToRFBServer(client, str, len));
1062 }
1063
1064
1065
1066 /*
1067  * HandleRFBServerMessage.
1068  */
1069
1070 rfbBool
1071 HandleRFBServerMessage(rfbClient* client)
1072 {
1073   rfbServerToClientMsg msg;
1074
1075   if (client->serverPort==-1)
1076     client->vncRec->readTimestamp = TRUE;
1077   if (!ReadFromRFBServer(client, (char *)&msg, 1))
1078     return FALSE;
1079
1080   switch (msg.type) {
1081
1082   case rfbSetColourMapEntries:
1083   {
1084     /* TODO:
1085     int i;
1086     uint16_t rgb[3];
1087     XColor xc;
1088
1089     if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
1090                            sz_rfbSetColourMapEntriesMsg - 1))
1091       return FALSE;
1092
1093     msg.scme.firstColour = rfbClientSwap16IfLE(msg.scme.firstColour);
1094     msg.scme.nColours = rfbClientSwap16IfLE(msg.scme.nColours);
1095
1096     for (i = 0; i < msg.scme.nColours; i++) {
1097       if (!ReadFromRFBServer(client, (char *)rgb, 6))
1098         return FALSE;
1099       xc.pixel = msg.scme.firstColour + i;
1100       xc.red = rfbClientSwap16IfLE(rgb[0]);
1101       xc.green = rfbClientSwap16IfLE(rgb[1]);
1102       xc.blue = rfbClientSwap16IfLE(rgb[2]);
1103       xc.flags = DoRed|DoGreen|DoBlue;
1104       XStoreColor(dpy, cmap, &xc);
1105     }
1106     */
1107
1108     break;
1109   }
1110
1111   case rfbFramebufferUpdate:
1112   {
1113     rfbFramebufferUpdateRectHeader rect;
1114     int linesToRead;
1115     int bytesPerLine;
1116     int i;
1117
1118     if (!ReadFromRFBServer(client, ((char *)&msg.fu) + 1,
1119                            sz_rfbFramebufferUpdateMsg - 1))
1120       return FALSE;
1121
1122     msg.fu.nRects = rfbClientSwap16IfLE(msg.fu.nRects);
1123
1124     for (i = 0; i < msg.fu.nRects; i++) {
1125       if (!ReadFromRFBServer(client, (char *)&rect, sz_rfbFramebufferUpdateRectHeader))
1126         return FALSE;
1127
1128       rect.encoding = rfbClientSwap32IfLE(rect.encoding);
1129       if (rect.encoding == rfbEncodingLastRect)
1130         break;
1131
1132       rect.r.x = rfbClientSwap16IfLE(rect.r.x);
1133       rect.r.y = rfbClientSwap16IfLE(rect.r.y);
1134       rect.r.w = rfbClientSwap16IfLE(rect.r.w);
1135       rect.r.h = rfbClientSwap16IfLE(rect.r.h);
1136
1137
1138       if (rect.encoding == rfbEncodingXCursor ||
1139           rect.encoding == rfbEncodingRichCursor) {
1140
1141         if (!HandleCursorShape(client,
1142                                rect.r.x, rect.r.y, rect.r.w, rect.r.h,
1143                                rect.encoding)) {
1144           return FALSE;
1145         }
1146         continue;
1147       }
1148
1149       if (rect.encoding == rfbEncodingPointerPos) {
1150         if (!client->HandleCursorPos(client,rect.r.x, rect.r.y)) {
1151           return FALSE;
1152         }
1153         continue;
1154       }
1155       
1156       if (rect.encoding == rfbEncodingKeyboardLedState) {
1157           /* OK! We have received a keyboard state message!!! */
1158           client->KeyboardLedStateEnabled = 1;
1159           if (client->HandleKeyboardLedState!=NULL)
1160               client->HandleKeyboardLedState(client, rect.r.x, 0);
1161           /* stash it for the future */
1162           client->CurrentKeyboardLedState = rect.r.x;
1163           continue;
1164       }
1165
1166       if (rect.encoding == rfbEncodingNewFBSize) {
1167         client->width = rect.r.w;
1168         client->height = rect.r.h;
1169         client->MallocFrameBuffer(client);
1170         SendFramebufferUpdateRequest(client, 0, 0, rect.r.w, rect.r.h, FALSE);
1171         rfbClientLog("Got new framebuffer size: %dx%d\n", rect.r.w, rect.r.h);
1172         continue;
1173       }
1174
1175       /* rect.r.w=byte count */
1176       if (rect.encoding == rfbEncodingSupportedMessages) {
1177           int loop;
1178           if (!ReadFromRFBServer(client, (char *)&client->supportedMessages, sz_rfbSupportedMessages))
1179               return FALSE;
1180
1181           /* msgs is two sets of bit flags of supported messages client2server[] and server2client[] */
1182           /* currently ignored by this library */
1183
1184           rfbClientLog("client2server supported messages (bit flags)\n");
1185           for (loop=0;loop<32;loop+=8)
1186             rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop,
1187                 client->supportedMessages.client2server[loop],   client->supportedMessages.client2server[loop+1],
1188                 client->supportedMessages.client2server[loop+2], client->supportedMessages.client2server[loop+3],
1189                 client->supportedMessages.client2server[loop+4], client->supportedMessages.client2server[loop+5],
1190                 client->supportedMessages.client2server[loop+6], client->supportedMessages.client2server[loop+7]);
1191
1192           rfbClientLog("server2client supported messages (bit flags)\n");
1193           for (loop=0;loop<32;loop+=8)
1194             rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop,
1195                 client->supportedMessages.server2client[loop],   client->supportedMessages.server2client[loop+1],
1196                 client->supportedMessages.server2client[loop+2], client->supportedMessages.server2client[loop+3],
1197                 client->supportedMessages.server2client[loop+4], client->supportedMessages.server2client[loop+5],
1198                 client->supportedMessages.server2client[loop+6], client->supportedMessages.server2client[loop+7]);
1199           continue;
1200       }
1201
1202       /* rect.r.w=byte count, rect.r.h=# of encodings */
1203       if (rect.encoding == rfbEncodingSupportedEncodings) {
1204           char *buffer;
1205           buffer = malloc(rect.r.w);
1206           if (!ReadFromRFBServer(client, buffer, rect.r.w))
1207           {
1208               free(buffer);
1209               return FALSE;
1210           }
1211
1212           /* buffer now contains rect.r.h # of uint32_t encodings that the server supports */
1213           /* currently ignored by this library */
1214           free(buffer);
1215           continue;
1216       }
1217
1218       /* rect.r.w=byte count */
1219       if (rect.encoding == rfbEncodingServerIdentity) {
1220           char *buffer;
1221           buffer = malloc(rect.r.w+1);
1222           if (!ReadFromRFBServer(client, buffer, rect.r.w))
1223           {
1224               free(buffer);
1225               return FALSE;
1226           }
1227           buffer[rect.r.w]=0; /* null terminate, just in case */
1228           rfbClientLog("Connected to Server \"%s\"\n", buffer);
1229           free(buffer);
1230           continue;
1231       }
1232
1233       /* rfbEncodingUltraZip is a collection of subrects.   x = # of subrects, and h is always 0 */
1234       if (rect.encoding != rfbEncodingUltraZip)
1235       {
1236         if ((rect.r.x + rect.r.w > client->width) ||
1237             (rect.r.y + rect.r.h > client->height))
1238             {
1239               rfbClientLog("Rect too large: %dx%d at (%d, %d)\n",
1240                   rect.r.w, rect.r.h, rect.r.x, rect.r.y);
1241               return FALSE;
1242             }
1243
1244         /* UltraVNC with scaling, will send rectangles with a zero W or H
1245          *
1246         if ((rect.encoding != rfbEncodingTight) && 
1247             (rect.r.h * rect.r.w == 0))
1248         {
1249           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);
1250           continue;
1251         }
1252         */
1253         
1254         /* If RichCursor encoding is used, we should prevent collisions
1255            between framebuffer updates and cursor drawing operations. */
1256         client->SoftCursorLockArea(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
1257       }
1258
1259       switch (rect.encoding) {
1260
1261       case rfbEncodingRaw: {
1262         int y=rect.r.y, h=rect.r.h;
1263
1264         bytesPerLine = rect.r.w * client->format.bitsPerPixel / 8;
1265         linesToRead = RFB_BUFFER_SIZE / bytesPerLine;
1266
1267         while (h > 0) {
1268           if (linesToRead > h)
1269             linesToRead = h;
1270
1271           if (!ReadFromRFBServer(client, client->buffer,bytesPerLine * linesToRead))
1272             return FALSE;
1273
1274           CopyRectangle(client, (uint8_t *)client->buffer,
1275                            rect.r.x, y, rect.r.w,linesToRead);
1276
1277           h -= linesToRead;
1278           y += linesToRead;
1279
1280         }
1281       } break;
1282
1283       case rfbEncodingCopyRect:
1284       {
1285         rfbCopyRect cr;
1286
1287         if (!ReadFromRFBServer(client, (char *)&cr, sz_rfbCopyRect))
1288           return FALSE;
1289
1290         cr.srcX = rfbClientSwap16IfLE(cr.srcX);
1291         cr.srcY = rfbClientSwap16IfLE(cr.srcY);
1292
1293         /* If RichCursor encoding is used, we should extend our
1294            "cursor lock area" (previously set to destination
1295            rectangle) to the source rectangle as well. */
1296         client->SoftCursorLockArea(client,
1297                                    cr.srcX, cr.srcY, rect.r.w, rect.r.h);
1298
1299         if (client->GotCopyRect != NULL) {
1300           client->GotCopyRect(client, cr.srcX, cr.srcY, rect.r.w, rect.r.h,
1301               rect.r.x, rect.r.y);
1302         } else
1303                 CopyRectangleFromRectangle(client,
1304                                    cr.srcX, cr.srcY, rect.r.w, rect.r.h,
1305                                    rect.r.x, rect.r.y);
1306
1307         break;
1308       }
1309
1310       case rfbEncodingRRE:
1311       {
1312         switch (client->format.bitsPerPixel) {
1313         case 8:
1314           if (!HandleRRE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1315             return FALSE;
1316           break;
1317         case 16:
1318           if (!HandleRRE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1319             return FALSE;
1320           break;
1321         case 32:
1322           if (!HandleRRE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1323             return FALSE;
1324           break;
1325         }
1326         break;
1327       }
1328
1329       case rfbEncodingCoRRE:
1330       {
1331         switch (client->format.bitsPerPixel) {
1332         case 8:
1333           if (!HandleCoRRE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1334             return FALSE;
1335           break;
1336         case 16:
1337           if (!HandleCoRRE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1338             return FALSE;
1339           break;
1340         case 32:
1341           if (!HandleCoRRE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1342             return FALSE;
1343           break;
1344         }
1345         break;
1346       }
1347
1348       case rfbEncodingHextile:
1349       {
1350         switch (client->format.bitsPerPixel) {
1351         case 8:
1352           if (!HandleHextile8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1353             return FALSE;
1354           break;
1355         case 16:
1356           if (!HandleHextile16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1357             return FALSE;
1358           break;
1359         case 32:
1360           if (!HandleHextile32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1361             return FALSE;
1362           break;
1363         }
1364         break;
1365       }
1366
1367       case rfbEncodingUltra:
1368       {
1369         switch (client->format.bitsPerPixel) {
1370         case 8:
1371           if (!HandleUltra8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1372             return FALSE;
1373           break;
1374         case 16:
1375           if (!HandleUltra16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1376             return FALSE;
1377           break;
1378         case 32:
1379           if (!HandleUltra32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1380             return FALSE;
1381           break;
1382         }
1383         break;
1384       }
1385       case rfbEncodingUltraZip:
1386       {
1387         switch (client->format.bitsPerPixel) {
1388         case 8:
1389           if (!HandleUltraZip8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1390             return FALSE;
1391           break;
1392         case 16:
1393           if (!HandleUltraZip16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1394             return FALSE;
1395           break;
1396         case 32:
1397           if (!HandleUltraZip32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1398             return FALSE;
1399           break;
1400         }
1401         break;
1402       }
1403
1404 #ifdef LIBVNCSERVER_HAVE_LIBZ
1405       case rfbEncodingZlib:
1406       {
1407         switch (client->format.bitsPerPixel) {
1408         case 8:
1409           if (!HandleZlib8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1410             return FALSE;
1411           break;
1412         case 16:
1413           if (!HandleZlib16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1414             return FALSE;
1415           break;
1416         case 32:
1417           if (!HandleZlib32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1418             return FALSE;
1419           break;
1420         }
1421         break;
1422      }
1423
1424 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
1425       case rfbEncodingTight:
1426       {
1427         switch (client->format.bitsPerPixel) {
1428         case 8:
1429           if (!HandleTight8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1430             return FALSE;
1431           break;
1432         case 16:
1433           if (!HandleTight16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1434             return FALSE;
1435           break;
1436         case 32:
1437           if (!HandleTight32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1438             return FALSE;
1439           break;
1440         }
1441         break;
1442       }
1443 #endif
1444       case rfbEncodingZRLE:
1445         /* Fail safe for ZYWRLE unsupport VNC server. */
1446         client->appData.qualityLevel = 9;
1447         /* fall through */
1448       case rfbEncodingZYWRLE:
1449       {
1450         switch (client->format.bitsPerPixel) {
1451         case 8:
1452           if (!HandleZRLE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1453             return FALSE;
1454           break;
1455         case 16:
1456           if (client->si.format.greenMax > 0x1F) {
1457             if (!HandleZRLE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1458               return FALSE;
1459           } else {
1460             if (!HandleZRLE15(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1461               return FALSE;
1462           }
1463           break;
1464         case 32:
1465         {
1466           uint32_t maxColor=(client->format.redMax<<client->format.redShift)|
1467                 (client->format.greenMax<<client->format.greenShift)|
1468                 (client->format.blueMax<<client->format.blueShift);
1469           if ((client->format.bigEndian && (maxColor&0xff)==0) ||
1470               (!client->format.bigEndian && (maxColor&0xff000000)==0)) {
1471             if (!HandleZRLE24(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1472               return FALSE;
1473           } else if (!client->format.bigEndian && (maxColor&0xff)==0) {
1474             if (!HandleZRLE24Up(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1475               return FALSE;
1476           } else if (client->format.bigEndian && (maxColor&0xff000000)==0) {
1477             if (!HandleZRLE24Down(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1478               return FALSE;
1479           } else if (!HandleZRLE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1480             return FALSE;
1481           break;
1482         }
1483         }
1484         break;
1485      }
1486
1487 #endif
1488
1489       default:
1490          {
1491            rfbBool handled = FALSE;
1492            rfbClientProtocolExtension* e;
1493
1494            for(e = rfbClientExtensions; !handled && e; e = e->next)
1495              if(e->handleEncoding && e->handleEncoding(client, &rect))
1496                handled = TRUE;
1497
1498            if(!handled) {
1499              rfbClientLog("Unknown rect encoding %d\n",
1500                  (int)rect.encoding);
1501              return FALSE;
1502            }
1503          }
1504       }
1505
1506       /* Now we may discard "soft cursor locks". */
1507       client->SoftCursorUnlockScreen(client);
1508
1509       client->GotFrameBufferUpdate(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
1510     }
1511
1512     if (!SendIncrementalFramebufferUpdateRequest(client))
1513       return FALSE;
1514
1515     break;
1516   }
1517
1518   case rfbBell:
1519   {
1520     client->Bell(client);
1521
1522     break;
1523   }
1524
1525   case rfbServerCutText:
1526   {
1527     char *buffer;
1528
1529     if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
1530                            sz_rfbServerCutTextMsg - 1))
1531       return FALSE;
1532
1533     msg.sct.length = rfbClientSwap32IfLE(msg.sct.length);
1534
1535     buffer = malloc(msg.sct.length+1);
1536
1537     if (!ReadFromRFBServer(client, buffer, msg.sct.length))
1538       return FALSE;
1539
1540     buffer[msg.sct.length] = 0;
1541
1542     if (client->GotXCutText)
1543       client->GotXCutText(client, buffer, msg.sct.length);
1544
1545     free(buffer);
1546
1547     break;
1548   }
1549
1550   case rfbTextChat:
1551   {
1552       char *buffer=NULL;
1553       if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
1554                              sz_rfbTextChatMsg- 1))
1555         return FALSE;
1556       msg.tc.length = rfbClientSwap32IfLE(msg.sct.length);
1557       switch(msg.tc.length) {
1558       case rfbTextChatOpen:
1559           rfbClientLog("Received TextChat Open\n");
1560           if (client->HandleTextChat!=NULL)
1561               client->HandleTextChat(client, (int)rfbTextChatOpen, NULL);
1562           break;
1563       case rfbTextChatClose:
1564           rfbClientLog("Received TextChat Close\n");
1565          if (client->HandleTextChat!=NULL)
1566               client->HandleTextChat(client, (int)rfbTextChatClose, NULL);
1567           break;
1568       case rfbTextChatFinished:
1569           rfbClientLog("Received TextChat Finished\n");
1570          if (client->HandleTextChat!=NULL)
1571               client->HandleTextChat(client, (int)rfbTextChatFinished, NULL);
1572           break;
1573       default:
1574           buffer=malloc(msg.tc.length+1);
1575           if (!ReadFromRFBServer(client, buffer, msg.tc.length))
1576           {
1577               free(buffer);
1578               return FALSE;
1579           }
1580           /* Null Terminate <just in case> */
1581           buffer[msg.tc.length]=0;
1582           rfbClientLog("Received TextChat \"%s\"\n", buffer);
1583           if (client->HandleTextChat!=NULL)
1584               client->HandleTextChat(client, (int)msg.tc.length, buffer);
1585           free(buffer);
1586           break;
1587       }
1588       break;
1589   }
1590
1591   case rfbResizeFrameBuffer:
1592   {
1593     if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
1594                            sz_rfbResizeFrameBufferMsg -1))
1595       return FALSE;
1596     client->width = rfbClientSwap16IfLE(msg.rsfb.framebufferWidth);
1597     client->height = rfbClientSwap16IfLE(msg.rsfb.framebufferHeigth);
1598     client->MallocFrameBuffer(client);
1599     SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE);
1600     rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height);
1601     break;
1602   }
1603
1604   case rfbPalmVNCReSizeFrameBuffer:
1605   {
1606     if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
1607                            sz_rfbPalmVNCReSizeFrameBufferMsg -1))
1608       return FALSE;
1609     client->width = rfbClientSwap16IfLE(msg.prsfb.buffer_w);
1610     client->height = rfbClientSwap16IfLE(msg.prsfb.buffer_h);
1611     client->MallocFrameBuffer(client);
1612     SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE);
1613     rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height);
1614     break;
1615   }
1616
1617   default:
1618     {
1619       rfbBool handled = FALSE;
1620       rfbClientProtocolExtension* e;
1621
1622       for(e = rfbClientExtensions; !handled && e; e = e->next)
1623         if(e->handleMessage && e->handleMessage(client, &msg))
1624           handled = TRUE;
1625
1626       if(!handled) {
1627         char buffer[256];
1628         rfbClientLog("Unknown message type %d from VNC server\n",msg.type);
1629         ReadFromRFBServer(client, buffer, 256);
1630         return FALSE;
1631       }
1632     }
1633   }
1634
1635   return TRUE;
1636 }
1637
1638
1639 #define GET_PIXEL8(pix, ptr) ((pix) = *(ptr)++)
1640
1641 #define GET_PIXEL16(pix, ptr) (((uint8_t*)&(pix))[0] = *(ptr)++, \
1642                                ((uint8_t*)&(pix))[1] = *(ptr)++)
1643
1644 #define GET_PIXEL32(pix, ptr) (((uint8_t*)&(pix))[0] = *(ptr)++, \
1645                                ((uint8_t*)&(pix))[1] = *(ptr)++, \
1646                                ((uint8_t*)&(pix))[2] = *(ptr)++, \
1647                                ((uint8_t*)&(pix))[3] = *(ptr)++)
1648
1649 /* CONCAT2 concatenates its two arguments.  CONCAT2E does the same but also
1650    expands its arguments if they are macros */
1651
1652 #define CONCAT2(a,b) a##b
1653 #define CONCAT2E(a,b) CONCAT2(a,b)
1654 #define CONCAT3(a,b,c) a##b##c
1655 #define CONCAT3E(a,b,c) CONCAT3(a,b,c)
1656
1657 #define BPP 8
1658 #include "rre.c"
1659 #include "corre.c"
1660 #include "hextile.c"
1661 #include "ultra.c"
1662 #include "zlib.c"
1663 #include "tight.c"
1664 #include "zrle.c"
1665 #undef BPP
1666 #define BPP 16
1667 #include "rre.c"
1668 #include "corre.c"
1669 #include "hextile.c"
1670 #include "ultra.c"
1671 #include "zlib.c"
1672 #include "tight.c"
1673 #include "zrle.c"
1674 #define REALBPP 15
1675 #include "zrle.c"
1676 #undef BPP
1677 #define BPP 32
1678 #include "rre.c"
1679 #include "corre.c"
1680 #include "hextile.c"
1681 #include "ultra.c"
1682 #include "zlib.c"
1683 #include "tight.c"
1684 #include "zrle.c"
1685 #define REALBPP 24
1686 #include "zrle.c"
1687 #define REALBPP 24
1688 #define UNCOMP 8
1689 #include "zrle.c"
1690 #define REALBPP 24
1691 #define UNCOMP -8
1692 #include "zrle.c"
1693 #undef BPP
1694
1695
1696 /*
1697  * PrintPixelFormat.
1698  */
1699
1700 void
1701 PrintPixelFormat(rfbPixelFormat *format)
1702 {
1703   if (format->bitsPerPixel == 1) {
1704     rfbClientLog("  Single bit per pixel.\n");
1705     rfbClientLog(
1706             "  %s significant bit in each byte is leftmost on the screen.\n",
1707             (format->bigEndian ? "Most" : "Least"));
1708   } else {
1709     rfbClientLog("  %d bits per pixel.\n",format->bitsPerPixel);
1710     if (format->bitsPerPixel != 8) {
1711       rfbClientLog("  %s significant byte first in each pixel.\n",
1712               (format->bigEndian ? "Most" : "Least"));
1713     }
1714     if (format->trueColour) {
1715       rfbClientLog("  TRUE colour: max red %d green %d blue %d"
1716                    ", shift red %d green %d blue %d\n",
1717                    format->redMax, format->greenMax, format->blueMax,
1718                    format->redShift, format->greenShift, format->blueShift);
1719     } else {
1720       rfbClientLog("  Colour map (not true colour).\n");
1721     }
1722   }
1723 }
1724
1725 /* avoid name clashes with LibVNCServer */
1726
1727 #define rfbEncryptBytes rfbClientEncryptBytes
1728 #define rfbDes rfbClientDes
1729 #define rfbDesKey rfbClientDesKey
1730 #define rfbUseKey rfbClientUseKey
1731 #define rfbCPKey rfbClientCPKey
1732
1733 #include "../libvncserver/vncauth.c"
1734 #include "../libvncserver/d3des.c"