Home | History | Annotate | Download | only in libvncclient
      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 #include <sys/types.h>
     33 #include <sys/stat.h>
     34 #include <pwd.h>
     35 #endif
     36 #include <errno.h>
     37 #include <rfb/rfbclient.h>
     38 #ifdef WIN32
     39 #undef SOCKET
     40 #undef socklen_t
     41 #endif
     42 #ifdef LIBVNCSERVER_HAVE_LIBZ
     43 #include <zlib.h>
     44 #ifdef __CHECKER__
     45 #undef Z_NULL
     46 #define Z_NULL NULL
     47 #endif
     48 #endif
     49 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
     50 #ifdef _RPCNDR_H /* This Windows header typedefs 'boolean', jpeglib has to know */
     51 #define HAVE_BOOLEAN
     52 #endif
     53 #include <jpeglib.h>
     54 #endif
     55 #include <stdarg.h>
     56 #include <time.h>
     57 
     58 #ifdef LIBVNCSERVER_WITH_CLIENT_GCRYPT
     59 #include <gcrypt.h>
     60 #endif
     61 
     62 #include "minilzo.h"
     63 #include "tls.h"
     64 
     65 /*
     66  * rfbClientLog prints a time-stamped message to the log file (stderr).
     67  */
     68 
     69 rfbBool rfbEnableClientLogging=TRUE;
     70 
     71 static void
     72 rfbDefaultClientLog(const char *format, ...)
     73 {
     74     va_list args;
     75     char buf[256];
     76     time_t log_clock;
     77 
     78     if(!rfbEnableClientLogging)
     79       return;
     80 
     81     va_start(args, format);
     82 
     83     time(&log_clock);
     84     strftime(buf, 255, "%d/%m/%Y %X ", localtime(&log_clock));
     85     fprintf(stderr, "%s", buf);
     86 
     87     vfprintf(stderr, format, args);
     88     fflush(stderr);
     89 
     90     va_end(args);
     91 }
     92 
     93 rfbClientLogProc rfbClientLog=rfbDefaultClientLog;
     94 rfbClientLogProc rfbClientErr=rfbDefaultClientLog;
     95 
     96 /* extensions */
     97 
     98 rfbClientProtocolExtension* rfbClientExtensions = NULL;
     99 
    100 void rfbClientRegisterExtension(rfbClientProtocolExtension* e)
    101 {
    102 	e->next = rfbClientExtensions;
    103 	rfbClientExtensions = e;
    104 }
    105 
    106 /* client data */
    107 
    108 void rfbClientSetClientData(rfbClient* client, void* tag, void* data)
    109 {
    110 	rfbClientData* clientData = client->clientData;
    111 
    112 	while(clientData && clientData->tag != tag)
    113 		clientData = clientData->next;
    114 	if(clientData == NULL) {
    115 		clientData = calloc(sizeof(rfbClientData), 1);
    116 		clientData->next = client->clientData;
    117 		client->clientData = clientData;
    118 		clientData->tag = tag;
    119 	}
    120 
    121 	clientData->data = data;
    122 }
    123 
    124 void* rfbClientGetClientData(rfbClient* client, void* tag)
    125 {
    126 	rfbClientData* clientData = client->clientData;
    127 
    128 	while(clientData) {
    129 		if(clientData->tag == tag)
    130 			return clientData->data;
    131 		clientData = clientData->next;
    132 	}
    133 
    134 	return NULL;
    135 }
    136 
    137 /* messages */
    138 
    139 static void FillRectangle(rfbClient* client, int x, int y, int w, int h, uint32_t colour) {
    140   int i,j;
    141 
    142 #define FILL_RECT(BPP) \
    143     for(j=y*client->width;j<(y+h)*client->width;j+=client->width) \
    144       for(i=x;i<x+w;i++) \
    145 	((uint##BPP##_t*)client->frameBuffer)[j+i]=colour;
    146 
    147   switch(client->format.bitsPerPixel) {
    148   case  8: FILL_RECT(8);  break;
    149   case 16: FILL_RECT(16); break;
    150   case 32: FILL_RECT(32); break;
    151   default:
    152     rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel);
    153   }
    154 }
    155 
    156 static void CopyRectangle(rfbClient* client, uint8_t* buffer, int x, int y, int w, int h) {
    157   int j;
    158 
    159 #define COPY_RECT(BPP) \
    160   { \
    161     int rs = w * BPP / 8, rs2 = client->width * BPP / 8; \
    162     for (j = ((x * (BPP / 8)) + (y * rs2)); j < (y + h) * rs2; j += rs2) { \
    163       memcpy(client->frameBuffer + j, buffer, rs); \
    164       buffer += rs; \
    165     } \
    166   }
    167 
    168   switch(client->format.bitsPerPixel) {
    169   case  8: COPY_RECT(8);  break;
    170   case 16: COPY_RECT(16); break;
    171   case 32: COPY_RECT(32); break;
    172   default:
    173     rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel);
    174   }
    175 }
    176 
    177 /* TODO: test */
    178 static void CopyRectangleFromRectangle(rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y) {
    179   int i,j;
    180 
    181 #define COPY_RECT_FROM_RECT(BPP) \
    182   { \
    183     uint##BPP##_t* _buffer=((uint##BPP##_t*)client->frameBuffer)+(src_y-dest_y)*client->width+src_x-dest_x; \
    184     if (dest_y < src_y) { \
    185       for(j = dest_y*client->width; j < (dest_y+h)*client->width; j += client->width) { \
    186         if (dest_x < src_x) { \
    187           for(i = dest_x; i < dest_x+w; i++) { \
    188             ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
    189           } \
    190         } else { \
    191           for(i = dest_x+w-1; i >= dest_x; i--) { \
    192             ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
    193           } \
    194         } \
    195       } \
    196     } else { \
    197       for(j = (dest_y+h-1)*client->width; j >= dest_y*client->width; j-=client->width) { \
    198         if (dest_x < src_x) { \
    199           for(i = dest_x; i < dest_x+w; i++) { \
    200             ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
    201           } \
    202         } else { \
    203           for(i = dest_x+w-1; i >= dest_x; i--) { \
    204             ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
    205           } \
    206         } \
    207       } \
    208     } \
    209   }
    210 
    211   switch(client->format.bitsPerPixel) {
    212   case  8: COPY_RECT_FROM_RECT(8);  break;
    213   case 16: COPY_RECT_FROM_RECT(16); break;
    214   case 32: COPY_RECT_FROM_RECT(32); break;
    215   default:
    216     rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel);
    217   }
    218 }
    219 
    220 static rfbBool HandleRRE8(rfbClient* client, int rx, int ry, int rw, int rh);
    221 static rfbBool HandleRRE16(rfbClient* client, int rx, int ry, int rw, int rh);
    222 static rfbBool HandleRRE32(rfbClient* client, int rx, int ry, int rw, int rh);
    223 static rfbBool HandleCoRRE8(rfbClient* client, int rx, int ry, int rw, int rh);
    224 static rfbBool HandleCoRRE16(rfbClient* client, int rx, int ry, int rw, int rh);
    225 static rfbBool HandleCoRRE32(rfbClient* client, int rx, int ry, int rw, int rh);
    226 static rfbBool HandleHextile8(rfbClient* client, int rx, int ry, int rw, int rh);
    227 static rfbBool HandleHextile16(rfbClient* client, int rx, int ry, int rw, int rh);
    228 static rfbBool HandleHextile32(rfbClient* client, int rx, int ry, int rw, int rh);
    229 static rfbBool HandleUltra8(rfbClient* client, int rx, int ry, int rw, int rh);
    230 static rfbBool HandleUltra16(rfbClient* client, int rx, int ry, int rw, int rh);
    231 static rfbBool HandleUltra32(rfbClient* client, int rx, int ry, int rw, int rh);
    232 static rfbBool HandleUltraZip8(rfbClient* client, int rx, int ry, int rw, int rh);
    233 static rfbBool HandleUltraZip16(rfbClient* client, int rx, int ry, int rw, int rh);
    234 static rfbBool HandleUltraZip32(rfbClient* client, int rx, int ry, int rw, int rh);
    235 #ifdef LIBVNCSERVER_HAVE_LIBZ
    236 static rfbBool HandleZlib8(rfbClient* client, int rx, int ry, int rw, int rh);
    237 static rfbBool HandleZlib16(rfbClient* client, int rx, int ry, int rw, int rh);
    238 static rfbBool HandleZlib32(rfbClient* client, int rx, int ry, int rw, int rh);
    239 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
    240 static rfbBool HandleTight8(rfbClient* client, int rx, int ry, int rw, int rh);
    241 static rfbBool HandleTight16(rfbClient* client, int rx, int ry, int rw, int rh);
    242 static rfbBool HandleTight32(rfbClient* client, int rx, int ry, int rw, int rh);
    243 
    244 static long ReadCompactLen (rfbClient* client);
    245 
    246 static void JpegInitSource(j_decompress_ptr cinfo);
    247 static boolean JpegFillInputBuffer(j_decompress_ptr cinfo);
    248 static void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes);
    249 static void JpegTermSource(j_decompress_ptr cinfo);
    250 static void JpegSetSrcManager(j_decompress_ptr cinfo, uint8_t *compressedData,
    251                               int compressedLen);
    252 #endif
    253 static rfbBool HandleZRLE8(rfbClient* client, int rx, int ry, int rw, int rh);
    254 static rfbBool HandleZRLE15(rfbClient* client, int rx, int ry, int rw, int rh);
    255 static rfbBool HandleZRLE16(rfbClient* client, int rx, int ry, int rw, int rh);
    256 static rfbBool HandleZRLE24(rfbClient* client, int rx, int ry, int rw, int rh);
    257 static rfbBool HandleZRLE24Up(rfbClient* client, int rx, int ry, int rw, int rh);
    258 static rfbBool HandleZRLE24Down(rfbClient* client, int rx, int ry, int rw, int rh);
    259 static rfbBool HandleZRLE32(rfbClient* client, int rx, int ry, int rw, int rh);
    260 #endif
    261 
    262 /*
    263  * Server Capability Functions
    264  */
    265 rfbBool
    266 SupportsClient2Server(rfbClient* client, int messageType)
    267 {
    268     return (client->supportedMessages.client2server[((messageType & 0xFF)/8)] & (1<<(messageType % 8)) ? TRUE : FALSE);
    269 }
    270 
    271 rfbBool
    272 SupportsServer2Client(rfbClient* client, int messageType)
    273 {
    274     return (client->supportedMessages.server2client[((messageType & 0xFF)/8)] & (1<<(messageType % 8)) ? TRUE : FALSE);
    275 }
    276 
    277 void
    278 SetClient2Server(rfbClient* client, int messageType)
    279 {
    280   client->supportedMessages.client2server[((messageType & 0xFF)/8)] |= (1<<(messageType % 8));
    281 }
    282 
    283 void
    284 SetServer2Client(rfbClient* client, int messageType)
    285 {
    286   client->supportedMessages.server2client[((messageType & 0xFF)/8)] |= (1<<(messageType % 8));
    287 }
    288 
    289 void
    290 ClearClient2Server(rfbClient* client, int messageType)
    291 {
    292   client->supportedMessages.client2server[((messageType & 0xFF)/8)] &= (!(1<<(messageType % 8)));
    293 }
    294 
    295 void
    296 ClearServer2Client(rfbClient* client, int messageType)
    297 {
    298   client->supportedMessages.server2client[((messageType & 0xFF)/8)] &= (!(1<<(messageType % 8)));
    299 }
    300 
    301 
    302 void
    303 DefaultSupportedMessages(rfbClient* client)
    304 {
    305     memset((char *)&client->supportedMessages,0,sizeof(client->supportedMessages));
    306 
    307     /* Default client supported messages (universal RFB 3.3 protocol) */
    308     SetClient2Server(client, rfbSetPixelFormat);
    309     /* SetClient2Server(client, rfbFixColourMapEntries); Not currently supported */
    310     SetClient2Server(client, rfbSetEncodings);
    311     SetClient2Server(client, rfbFramebufferUpdateRequest);
    312     SetClient2Server(client, rfbKeyEvent);
    313     SetClient2Server(client, rfbPointerEvent);
    314     SetClient2Server(client, rfbClientCutText);
    315     /* technically, we only care what we can *send* to the server
    316      * but, we set Server2Client Just in case it ever becomes useful
    317      */
    318     SetServer2Client(client, rfbFramebufferUpdate);
    319     SetServer2Client(client, rfbSetColourMapEntries);
    320     SetServer2Client(client, rfbBell);
    321     SetServer2Client(client, rfbServerCutText);
    322 }
    323 
    324 void
    325 DefaultSupportedMessagesUltraVNC(rfbClient* client)
    326 {
    327     DefaultSupportedMessages(client);
    328     SetClient2Server(client, rfbFileTransfer);
    329     SetClient2Server(client, rfbSetScale);
    330     SetClient2Server(client, rfbSetServerInput);
    331     SetClient2Server(client, rfbSetSW);
    332     SetClient2Server(client, rfbTextChat);
    333     SetClient2Server(client, rfbPalmVNCSetScaleFactor);
    334     /* technically, we only care what we can *send* to the server */
    335     SetServer2Client(client, rfbResizeFrameBuffer);
    336     SetServer2Client(client, rfbPalmVNCReSizeFrameBuffer);
    337     SetServer2Client(client, rfbFileTransfer);
    338     SetServer2Client(client, rfbTextChat);
    339 }
    340 
    341 
    342 void
    343 DefaultSupportedMessagesTightVNC(rfbClient* client)
    344 {
    345     DefaultSupportedMessages(client);
    346     SetClient2Server(client, rfbFileTransfer);
    347     SetClient2Server(client, rfbSetServerInput);
    348     SetClient2Server(client, rfbSetSW);
    349     /* SetClient2Server(client, rfbTextChat); */
    350     /* technically, we only care what we can *send* to the server */
    351     SetServer2Client(client, rfbFileTransfer);
    352     SetServer2Client(client, rfbTextChat);
    353 }
    354 
    355 #ifndef WIN32
    356 static rfbBool
    357 IsUnixSocket(const char *name)
    358 {
    359   struct stat sb;
    360   if(stat(name, &sb) == 0 && (sb.st_mode & S_IFMT) == S_IFSOCK)
    361     return TRUE;
    362   return FALSE;
    363 }
    364 #endif
    365 
    366 /*
    367  * ConnectToRFBServer.
    368  */
    369 
    370 rfbBool
    371 ConnectToRFBServer(rfbClient* client,const char *hostname, int port)
    372 {
    373   if (client->serverPort==-1) {
    374     /* serverHost is a file recorded by vncrec. */
    375     const char* magic="vncLog0.0";
    376     char buffer[10];
    377     rfbVNCRec* rec = (rfbVNCRec*)malloc(sizeof(rfbVNCRec));
    378     client->vncRec = rec;
    379 
    380     rec->file = fopen(client->serverHost,"rb");
    381     rec->tv.tv_sec = 0;
    382     rec->readTimestamp = FALSE;
    383     rec->doNotSleep = FALSE;
    384 
    385     if (!rec->file) {
    386       rfbClientLog("Could not open %s.\n",client->serverHost);
    387       return FALSE;
    388     }
    389     setbuf(rec->file,NULL);
    390     fread(buffer,1,strlen(magic),rec->file);
    391     if (strncmp(buffer,magic,strlen(magic))) {
    392       rfbClientLog("File %s was not recorded by vncrec.\n",client->serverHost);
    393       fclose(rec->file);
    394       return FALSE;
    395     }
    396     client->sock = -1;
    397     return TRUE;
    398   }
    399 
    400 #ifndef WIN32
    401   if(IsUnixSocket(hostname))
    402     /* serverHost is a UNIX socket. */
    403     client->sock = ConnectClientToUnixSock(hostname);
    404   else
    405 #endif
    406   {
    407 #ifdef LIBVNCSERVER_IPv6
    408     client->sock = ConnectClientToTcpAddr6(hostname, port);
    409     if (client->sock == -1)
    410 #endif
    411     {
    412       unsigned int host;
    413 
    414       /* serverHost is a hostname */
    415       if (!StringToIPAddr(hostname, &host)) {
    416         rfbClientLog("Couldn't convert '%s' to host address\n", hostname);
    417         return FALSE;
    418       }
    419       client->sock = ConnectClientToTcpAddr(host, port);
    420     }
    421   }
    422 
    423   if (client->sock < 0) {
    424     rfbClientLog("Unable to connect to VNC server\n");
    425     return FALSE;
    426   }
    427 
    428   if(client->QoS_DSCP && !SetDSCP(client->sock, client->QoS_DSCP))
    429      return FALSE;
    430 
    431   return SetNonBlocking(client->sock);
    432 }
    433 
    434 /*
    435  * ConnectToRFBRepeater.
    436  */
    437 
    438 rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int repeaterPort, const char *destHost, int destPort)
    439 {
    440   rfbProtocolVersionMsg pv;
    441   int major,minor;
    442   char tmphost[250];
    443 
    444 #ifdef LIBVNCSERVER_IPv6
    445   client->sock = ConnectClientToTcpAddr6(repeaterHost, repeaterPort);
    446   if (client->sock == -1)
    447 #endif
    448   {
    449     unsigned int host;
    450     if (!StringToIPAddr(repeaterHost, &host)) {
    451       rfbClientLog("Couldn't convert '%s' to host address\n", repeaterHost);
    452       return FALSE;
    453     }
    454 
    455     client->sock = ConnectClientToTcpAddr(host, repeaterPort);
    456   }
    457 
    458   if (client->sock < 0) {
    459     rfbClientLog("Unable to connect to VNC repeater\n");
    460     return FALSE;
    461   }
    462 
    463   if (!SetNonBlocking(client->sock))
    464     return FALSE;
    465 
    466   if (!ReadFromRFBServer(client, pv, sz_rfbProtocolVersionMsg))
    467     return FALSE;
    468   pv[sz_rfbProtocolVersionMsg] = 0;
    469 
    470   /* UltraVNC repeater always report version 000.000 to identify itself */
    471   if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2 || major != 0 || minor != 0) {
    472     rfbClientLog("Not a valid VNC repeater (%s)\n",pv);
    473     return FALSE;
    474   }
    475 
    476   rfbClientLog("Connected to VNC repeater, using protocol version %d.%d\n", major, minor);
    477 
    478   snprintf(tmphost, sizeof(tmphost), "%s:%d", destHost, destPort);
    479   if (!WriteToRFBServer(client, tmphost, sizeof(tmphost)))
    480     return FALSE;
    481 
    482   return TRUE;
    483 }
    484 
    485 extern void rfbClientEncryptBytes(unsigned char* bytes, char* passwd);
    486 extern void rfbClientEncryptBytes2(unsigned char *where, const int length, unsigned char *key);
    487 
    488 rfbBool
    489 rfbHandleAuthResult(rfbClient* client)
    490 {
    491     uint32_t authResult=0, reasonLen=0;
    492     char *reason=NULL;
    493 
    494     if (!ReadFromRFBServer(client, (char *)&authResult, 4)) return FALSE;
    495 
    496     authResult = rfbClientSwap32IfLE(authResult);
    497 
    498     switch (authResult) {
    499     case rfbVncAuthOK:
    500       rfbClientLog("VNC authentication succeeded\n");
    501       return TRUE;
    502       break;
    503     case rfbVncAuthFailed:
    504       if (client->major==3 && client->minor>7)
    505       {
    506         /* we have an error following */
    507         if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
    508         reasonLen = rfbClientSwap32IfLE(reasonLen);
    509         reason = malloc(reasonLen+1);
    510         if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
    511         reason[reasonLen]=0;
    512         rfbClientLog("VNC connection failed: %s\n",reason);
    513         free(reason);
    514         return FALSE;
    515       }
    516       rfbClientLog("VNC authentication failed\n");
    517       return FALSE;
    518     case rfbVncAuthTooMany:
    519       rfbClientLog("VNC authentication failed - too many tries\n");
    520       return FALSE;
    521     }
    522 
    523     rfbClientLog("Unknown VNC authentication result: %d\n",
    524                  (int)authResult);
    525     return FALSE;
    526 }
    527 
    528 static void
    529 ReadReason(rfbClient* client)
    530 {
    531     uint32_t reasonLen;
    532     char *reason;
    533 
    534     /* we have an error following */
    535     if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return;
    536     reasonLen = rfbClientSwap32IfLE(reasonLen);
    537     reason = malloc(reasonLen+1);
    538     if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return; }
    539     reason[reasonLen]=0;
    540     rfbClientLog("VNC connection failed: %s\n",reason);
    541     free(reason);
    542 }
    543 
    544 static rfbBool
    545 ReadSupportedSecurityType(rfbClient* client, uint32_t *result, rfbBool subAuth)
    546 {
    547     uint8_t count=0;
    548     uint8_t loop=0;
    549     uint8_t flag=0;
    550     uint8_t tAuth[256];
    551     char buf1[500],buf2[10];
    552     uint32_t authScheme;
    553 
    554     if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE;
    555 
    556     if (count==0)
    557     {
    558         rfbClientLog("List of security types is ZERO, expecting an error to follow\n");
    559         ReadReason(client);
    560         return FALSE;
    561     }
    562 
    563     rfbClientLog("We have %d security types to read\n", count);
    564     authScheme=0;
    565     /* now, we have a list of available security types to read ( uint8_t[] ) */
    566     for (loop=0;loop<count;loop++)
    567     {
    568         if (!ReadFromRFBServer(client, (char *)&tAuth[loop], 1)) return FALSE;
    569         rfbClientLog("%d) Received security type %d\n", loop, tAuth[loop]);
    570         if (flag) continue;
    571         if (tAuth[loop]==rfbVncAuth || tAuth[loop]==rfbNoAuth ||
    572             (tAuth[loop]==rfbARD && client->GetCredential) ||
    573             (!subAuth && (tAuth[loop]==rfbTLS || (tAuth[loop]==rfbVeNCrypt && client->GetCredential))))
    574         {
    575             if (!subAuth && client->clientAuthSchemes)
    576             {
    577                 int i;
    578                 for (i=0;client->clientAuthSchemes[i];i++)
    579                 {
    580                     if (client->clientAuthSchemes[i]==(uint32_t)tAuth[loop])
    581                     {
    582                         flag++;
    583                         authScheme=tAuth[loop];
    584                         break;
    585                     }
    586                 }
    587             }
    588             else
    589             {
    590                 flag++;
    591                 authScheme=tAuth[loop];
    592             }
    593             if (flag)
    594             {
    595                 rfbClientLog("Selecting security type %d (%d/%d in the list)\n", authScheme, loop, count);
    596                 /* send back a single byte indicating which security type to use */
    597                 if (!WriteToRFBServer(client, (char *)&tAuth[loop], 1)) return FALSE;
    598             }
    599         }
    600     }
    601     if (authScheme==0)
    602     {
    603         memset(buf1, 0, sizeof(buf1));
    604         for (loop=0;loop<count;loop++)
    605         {
    606             if (strlen(buf1)>=sizeof(buf1)-1) break;
    607             snprintf(buf2, sizeof(buf2), (loop>0 ? ", %d" : "%d"), (int)tAuth[loop]);
    608             strncat(buf1, buf2, sizeof(buf1)-strlen(buf1)-1);
    609         }
    610         rfbClientLog("Unknown authentication scheme from VNC server: %s\n",
    611                buf1);
    612         return FALSE;
    613     }
    614     *result = authScheme;
    615     return TRUE;
    616 }
    617 
    618 static rfbBool
    619 HandleVncAuth(rfbClient *client)
    620 {
    621     uint8_t challenge[CHALLENGESIZE];
    622     char *passwd=NULL;
    623     int i;
    624 
    625     if (!ReadFromRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
    626 
    627     if (client->serverPort!=-1) { /* if not playing a vncrec file */
    628       if (client->GetPassword)
    629         passwd = client->GetPassword(client);
    630 
    631       if ((!passwd) || (strlen(passwd) == 0)) {
    632         rfbClientLog("Reading password failed\n");
    633         return FALSE;
    634       }
    635       if (strlen(passwd) > 8) {
    636         passwd[8] = '\0';
    637       }
    638 
    639       rfbClientEncryptBytes(challenge, passwd);
    640 
    641       /* Lose the password from memory */
    642       for (i = strlen(passwd); i >= 0; i--) {
    643         passwd[i] = '\0';
    644       }
    645       free(passwd);
    646 
    647       if (!WriteToRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
    648     }
    649 
    650     /* Handle the SecurityResult message */
    651     if (!rfbHandleAuthResult(client)) return FALSE;
    652 
    653     return TRUE;
    654 }
    655 
    656 static void
    657 FreeUserCredential(rfbCredential *cred)
    658 {
    659   if (cred->userCredential.username) free(cred->userCredential.username);
    660   if (cred->userCredential.password) free(cred->userCredential.password);
    661   free(cred);
    662 }
    663 
    664 static rfbBool
    665 HandlePlainAuth(rfbClient *client)
    666 {
    667   uint32_t ulen, ulensw;
    668   uint32_t plen, plensw;
    669   rfbCredential *cred;
    670 
    671   if (!client->GetCredential)
    672   {
    673     rfbClientLog("GetCredential callback is not set.\n");
    674     return FALSE;
    675   }
    676   cred = client->GetCredential(client, rfbCredentialTypeUser);
    677   if (!cred)
    678   {
    679     rfbClientLog("Reading credential failed\n");
    680     return FALSE;
    681   }
    682 
    683   ulen = (cred->userCredential.username ? strlen(cred->userCredential.username) : 0);
    684   ulensw = rfbClientSwap32IfLE(ulen);
    685   plen = (cred->userCredential.password ? strlen(cred->userCredential.password) : 0);
    686   plensw = rfbClientSwap32IfLE(plen);
    687   if (!WriteToRFBServer(client, (char *)&ulensw, 4) ||
    688       !WriteToRFBServer(client, (char *)&plensw, 4))
    689   {
    690     FreeUserCredential(cred);
    691     return FALSE;
    692   }
    693   if (ulen > 0)
    694   {
    695     if (!WriteToRFBServer(client, cred->userCredential.username, ulen))
    696     {
    697       FreeUserCredential(cred);
    698       return FALSE;
    699     }
    700   }
    701   if (plen > 0)
    702   {
    703     if (!WriteToRFBServer(client, cred->userCredential.password, plen))
    704     {
    705       FreeUserCredential(cred);
    706       return FALSE;
    707     }
    708   }
    709 
    710   FreeUserCredential(cred);
    711 
    712   /* Handle the SecurityResult message */
    713   if (!rfbHandleAuthResult(client)) return FALSE;
    714 
    715   return TRUE;
    716 }
    717 
    718 /* Simple 64bit big integer arithmetic implementation */
    719 /* (x + y) % m, works even if (x + y) > 64bit */
    720 #define rfbAddM64(x,y,m) ((x+y)%m+(x+y<x?(((uint64_t)-1)%m+1)%m:0))
    721 /* (x * y) % m */
    722 static uint64_t
    723 rfbMulM64(uint64_t x, uint64_t y, uint64_t m)
    724 {
    725   uint64_t r;
    726   for(r=0;x>0;x>>=1)
    727   {
    728     if (x&1) r=rfbAddM64(r,y,m);
    729     y=rfbAddM64(y,y,m);
    730   }
    731   return r;
    732 }
    733 /* (x ^ y) % m */
    734 static uint64_t
    735 rfbPowM64(uint64_t b, uint64_t e, uint64_t m)
    736 {
    737   uint64_t r;
    738   for(r=1;e>0;e>>=1)
    739   {
    740     if(e&1) r=rfbMulM64(r,b,m);
    741     b=rfbMulM64(b,b,m);
    742   }
    743   return r;
    744 }
    745 
    746 static rfbBool
    747 HandleMSLogonAuth(rfbClient *client)
    748 {
    749   uint64_t gen, mod, resp, priv, pub, key;
    750   uint8_t username[256], password[64];
    751   rfbCredential *cred;
    752 
    753   if (!ReadFromRFBServer(client, (char *)&gen, 8)) return FALSE;
    754   if (!ReadFromRFBServer(client, (char *)&mod, 8)) return FALSE;
    755   if (!ReadFromRFBServer(client, (char *)&resp, 8)) return FALSE;
    756   gen = rfbClientSwap64IfLE(gen);
    757   mod = rfbClientSwap64IfLE(mod);
    758   resp = rfbClientSwap64IfLE(resp);
    759 
    760   if (!client->GetCredential)
    761   {
    762     rfbClientLog("GetCredential callback is not set.\n");
    763     return FALSE;
    764   }
    765   rfbClientLog("WARNING! MSLogon security type has very low password encryption! "\
    766     "Use it only with SSH tunnel or trusted network.\n");
    767   cred = client->GetCredential(client, rfbCredentialTypeUser);
    768   if (!cred)
    769   {
    770     rfbClientLog("Reading credential failed\n");
    771     return FALSE;
    772   }
    773 
    774   memset(username, 0, sizeof(username));
    775   strncpy((char *)username, cred->userCredential.username, sizeof(username));
    776   memset(password, 0, sizeof(password));
    777   strncpy((char *)password, cred->userCredential.password, sizeof(password));
    778   FreeUserCredential(cred);
    779 
    780   srand(time(NULL));
    781   priv = ((uint64_t)rand())<<32;
    782   priv |= (uint64_t)rand();
    783 
    784   pub = rfbPowM64(gen, priv, mod);
    785   key = rfbPowM64(resp, priv, mod);
    786   pub = rfbClientSwap64IfLE(pub);
    787   key = rfbClientSwap64IfLE(key);
    788 
    789   rfbClientEncryptBytes2(username, sizeof(username), (unsigned char *)&key);
    790   rfbClientEncryptBytes2(password, sizeof(password), (unsigned char *)&key);
    791 
    792   if (!WriteToRFBServer(client, (char *)&pub, 8)) return FALSE;
    793   if (!WriteToRFBServer(client, (char *)username, sizeof(username))) return FALSE;
    794   if (!WriteToRFBServer(client, (char *)password, sizeof(password))) return FALSE;
    795 
    796   /* Handle the SecurityResult message */
    797   if (!rfbHandleAuthResult(client)) return FALSE;
    798 
    799   return TRUE;
    800 }
    801 
    802 #ifdef LIBVNCSERVER_WITH_CLIENT_GCRYPT
    803 static rfbBool
    804 rfbMpiToBytes(const gcry_mpi_t value, uint8_t *result, size_t size)
    805 {
    806   gcry_error_t error;
    807   size_t len;
    808   int i;
    809 
    810   error = gcry_mpi_print(GCRYMPI_FMT_USG, result, size, &len, value);
    811   if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
    812   {
    813     rfbClientLog("gcry_mpi_print error: %s\n", gcry_strerror(error));
    814     return FALSE;
    815   }
    816   for (i=size-1;i>(int)size-1-(int)len;--i)
    817     result[i] = result[i-size+len];
    818   for (;i>=0;--i)
    819     result[i] = 0;
    820   return TRUE;
    821 }
    822 
    823 static rfbBool
    824 HandleARDAuth(rfbClient *client)
    825 {
    826   uint8_t gen[2], len[2];
    827   size_t keylen;
    828   uint8_t *mod = NULL, *resp, *pub, *key, *shared;
    829   gcry_mpi_t genmpi = NULL, modmpi = NULL, respmpi = NULL;
    830   gcry_mpi_t privmpi = NULL, pubmpi = NULL, keympi = NULL;
    831   gcry_md_hd_t md5 = NULL;
    832   gcry_cipher_hd_t aes = NULL;
    833   gcry_error_t error;
    834   uint8_t userpass[128], ciphertext[128];
    835   int passwordLen, usernameLen;
    836   rfbCredential *cred = NULL;
    837   rfbBool result = FALSE;
    838 
    839   while (1)
    840   {
    841     if (!ReadFromRFBServer(client, (char *)gen, 2))
    842       break;
    843     if (!ReadFromRFBServer(client, (char *)len, 2))
    844       break;
    845 
    846     if (!client->GetCredential)
    847     {
    848       rfbClientLog("GetCredential callback is not set.\n");
    849       break;
    850     }
    851     cred = client->GetCredential(client, rfbCredentialTypeUser);
    852     if (!cred)
    853     {
    854       rfbClientLog("Reading credential failed\n");
    855       break;
    856     }
    857 
    858     keylen = 256*len[0]+len[1];
    859     mod = (uint8_t*)malloc(keylen*4);
    860     if (!mod)
    861     {
    862       rfbClientLog("malloc out of memory\n");
    863       break;
    864     }
    865     resp = mod+keylen;
    866     pub = resp+keylen;
    867     key = pub+keylen;
    868 
    869     if (!ReadFromRFBServer(client, (char *)mod, keylen))
    870       break;
    871     if (!ReadFromRFBServer(client, (char *)resp, keylen))
    872       break;
    873 
    874     error = gcry_mpi_scan(&genmpi, GCRYMPI_FMT_USG, gen, 2, NULL);
    875     if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
    876     {
    877       rfbClientLog("gcry_mpi_scan error: %s\n", gcry_strerror(error));
    878       break;
    879     }
    880     error = gcry_mpi_scan(&modmpi, GCRYMPI_FMT_USG, mod, keylen, NULL);
    881     if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
    882     {
    883       rfbClientLog("gcry_mpi_scan error: %s\n", gcry_strerror(error));
    884       break;
    885     }
    886     error = gcry_mpi_scan(&respmpi, GCRYMPI_FMT_USG, resp, keylen, NULL);
    887     if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
    888     {
    889       rfbClientLog("gcry_mpi_scan error: %s\n", gcry_strerror(error));
    890       break;
    891     }
    892 
    893     privmpi = gcry_mpi_new(keylen);
    894     if (!privmpi)
    895     {
    896       rfbClientLog("gcry_mpi_new out of memory\n");
    897       break;
    898     }
    899     gcry_mpi_randomize(privmpi, (keylen/8)*8, GCRY_STRONG_RANDOM);
    900 
    901     pubmpi = gcry_mpi_new(keylen);
    902     if (!pubmpi)
    903     {
    904       rfbClientLog("gcry_mpi_new out of memory\n");
    905       break;
    906     }
    907     gcry_mpi_powm(pubmpi, genmpi, privmpi, modmpi);
    908 
    909     keympi = gcry_mpi_new(keylen);
    910     if (!keympi)
    911     {
    912       rfbClientLog("gcry_mpi_new out of memory\n");
    913       break;
    914     }
    915     gcry_mpi_powm(keympi, respmpi, privmpi, modmpi);
    916 
    917     if (!rfbMpiToBytes(pubmpi, pub, keylen))
    918       break;
    919     if (!rfbMpiToBytes(keympi, key, keylen))
    920       break;
    921 
    922     error = gcry_md_open(&md5, GCRY_MD_MD5, 0);
    923     if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
    924     {
    925       rfbClientLog("gcry_md_open error: %s\n", gcry_strerror(error));
    926       break;
    927     }
    928     gcry_md_write(md5, key, keylen);
    929     error = gcry_md_final(md5);
    930     if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
    931     {
    932       rfbClientLog("gcry_md_final error: %s\n", gcry_strerror(error));
    933       break;
    934     }
    935     shared = gcry_md_read(md5, GCRY_MD_MD5);
    936 
    937     passwordLen = strlen(cred->userCredential.password)+1;
    938     usernameLen = strlen(cred->userCredential.username)+1;
    939     if (passwordLen > sizeof(userpass)/2)
    940       passwordLen = sizeof(userpass)/2;
    941     if (usernameLen > sizeof(userpass)/2)
    942       usernameLen = sizeof(userpass)/2;
    943 
    944     gcry_randomize(userpass, sizeof(userpass), GCRY_STRONG_RANDOM);
    945     memcpy(userpass, cred->userCredential.username, usernameLen);
    946     memcpy(userpass+sizeof(userpass)/2, cred->userCredential.password, passwordLen);
    947 
    948     error = gcry_cipher_open(&aes, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB, 0);
    949     if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
    950     {
    951       rfbClientLog("gcry_cipher_open error: %s\n", gcry_strerror(error));
    952       break;
    953     }
    954     error = gcry_cipher_setkey(aes, shared, 16);
    955     if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
    956     {
    957       rfbClientLog("gcry_cipher_setkey error: %s\n", gcry_strerror(error));
    958       break;
    959     }
    960     error = gcry_cipher_encrypt(aes, ciphertext, sizeof(ciphertext), userpass, sizeof(userpass));
    961     if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
    962     {
    963       rfbClientLog("gcry_cipher_encrypt error: %s\n", gcry_strerror(error));
    964       break;
    965     }
    966 
    967     if (!WriteToRFBServer(client, (char *)ciphertext, sizeof(ciphertext)))
    968       break;
    969     if (!WriteToRFBServer(client, (char *)pub, keylen))
    970       break;
    971 
    972     /* Handle the SecurityResult message */
    973     if (!rfbHandleAuthResult(client))
    974       break;
    975 
    976     result = TRUE;
    977     break;
    978   }
    979 
    980   if (cred)
    981     FreeUserCredential(cred);
    982   if (mod)
    983     free(mod);
    984   if (genmpi)
    985     gcry_mpi_release(genmpi);
    986   if (modmpi)
    987     gcry_mpi_release(modmpi);
    988   if (respmpi)
    989     gcry_mpi_release(respmpi);
    990   if (privmpi)
    991     gcry_mpi_release(privmpi);
    992   if (pubmpi)
    993     gcry_mpi_release(pubmpi);
    994   if (keympi)
    995     gcry_mpi_release(keympi);
    996   if (md5)
    997     gcry_md_close(md5);
    998   if (aes)
    999     gcry_cipher_close(aes);
   1000   return result;
   1001 }
   1002 #endif
   1003 
   1004 /*
   1005  * SetClientAuthSchemes.
   1006  */
   1007 
   1008 void
   1009 SetClientAuthSchemes(rfbClient* client,const uint32_t *authSchemes, int size)
   1010 {
   1011   int i;
   1012 
   1013   if (client->clientAuthSchemes)
   1014   {
   1015     free(client->clientAuthSchemes);
   1016     client->clientAuthSchemes = NULL;
   1017   }
   1018   if (authSchemes)
   1019   {
   1020     if (size<0)
   1021     {
   1022       /* If size<0 we assume the passed-in list is also 0-terminate, so we
   1023        * calculate the size here */
   1024       for (size=0;authSchemes[size];size++) ;
   1025     }
   1026     client->clientAuthSchemes = (uint32_t*)malloc(sizeof(uint32_t)*(size+1));
   1027     for (i=0;i<size;i++)
   1028       client->clientAuthSchemes[i] = authSchemes[i];
   1029     client->clientAuthSchemes[size] = 0;
   1030   }
   1031 }
   1032 
   1033 /*
   1034  * InitialiseRFBConnection.
   1035  */
   1036 
   1037 rfbBool
   1038 InitialiseRFBConnection(rfbClient* client)
   1039 {
   1040   rfbProtocolVersionMsg pv;
   1041   int major,minor;
   1042   uint32_t authScheme;
   1043   uint32_t subAuthScheme;
   1044   rfbClientInitMsg ci;
   1045 
   1046   /* if the connection is immediately closed, don't report anything, so
   1047        that pmw's monitor can make test connections */
   1048 
   1049   if (client->listenSpecified)
   1050     errorMessageOnReadFailure = FALSE;
   1051 
   1052   if (!ReadFromRFBServer(client, pv, sz_rfbProtocolVersionMsg)) return FALSE;
   1053   pv[sz_rfbProtocolVersionMsg]=0;
   1054 
   1055   errorMessageOnReadFailure = TRUE;
   1056 
   1057   pv[sz_rfbProtocolVersionMsg] = 0;
   1058 
   1059   if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) {
   1060     rfbClientLog("Not a valid VNC server (%s)\n",pv);
   1061     return FALSE;
   1062   }
   1063 
   1064 
   1065   DefaultSupportedMessages(client);
   1066   client->major = major;
   1067   client->minor = minor;
   1068 
   1069   /* fall back to viewer supported version */
   1070   if ((major==rfbProtocolMajorVersion) && (minor>rfbProtocolMinorVersion))
   1071     client->minor = rfbProtocolMinorVersion;
   1072 
   1073   /* UltraVNC uses minor codes 4 and 6 for the server */
   1074   if (major==3 && (minor==4 || minor==6)) {
   1075       rfbClientLog("UltraVNC server detected, enabling UltraVNC specific messages\n",pv);
   1076       DefaultSupportedMessagesUltraVNC(client);
   1077   }
   1078 
   1079   /* UltraVNC Single Click uses minor codes 14 and 16 for the server */
   1080   if (major==3 && (minor==14 || minor==16)) {
   1081      minor = minor - 10;
   1082      client->minor = minor;
   1083      rfbClientLog("UltraVNC Single Click server detected, enabling UltraVNC specific messages\n",pv);
   1084      DefaultSupportedMessagesUltraVNC(client);
   1085   }
   1086 
   1087   /* TightVNC uses minor codes 5 for the server */
   1088   if (major==3 && minor==5) {
   1089       rfbClientLog("TightVNC server detected, enabling TightVNC specific messages\n",pv);
   1090       DefaultSupportedMessagesTightVNC(client);
   1091   }
   1092 
   1093   /* we do not support > RFB3.8 */
   1094   if ((major==3 && minor>8) || major>3)
   1095   {
   1096     client->major=3;
   1097     client->minor=8;
   1098   }
   1099 
   1100   rfbClientLog("VNC server supports protocol version %d.%d (viewer %d.%d)\n",
   1101 	  major, minor, rfbProtocolMajorVersion, rfbProtocolMinorVersion);
   1102 
   1103   sprintf(pv,rfbProtocolVersionFormat,client->major,client->minor);
   1104 
   1105   if (!WriteToRFBServer(client, pv, sz_rfbProtocolVersionMsg)) return FALSE;
   1106 
   1107 
   1108   /* 3.7 and onwards sends a # of security types first */
   1109   if (client->major==3 && client->minor > 6)
   1110   {
   1111     if (!ReadSupportedSecurityType(client, &authScheme, FALSE)) return FALSE;
   1112   }
   1113   else
   1114   {
   1115     if (!ReadFromRFBServer(client, (char *)&authScheme, 4)) return FALSE;
   1116     authScheme = rfbClientSwap32IfLE(authScheme);
   1117   }
   1118 
   1119   rfbClientLog("Selected Security Scheme %d\n", authScheme);
   1120   client->authScheme = authScheme;
   1121 
   1122   switch (authScheme) {
   1123 
   1124   case rfbConnFailed:
   1125     ReadReason(client);
   1126     return FALSE;
   1127 
   1128   case rfbNoAuth:
   1129     rfbClientLog("No authentication needed\n");
   1130 
   1131     /* 3.8 and upwards sends a Security Result for rfbNoAuth */
   1132     if ((client->major==3 && client->minor > 7) || client->major>3)
   1133         if (!rfbHandleAuthResult(client)) return FALSE;
   1134 
   1135     break;
   1136 
   1137   case rfbVncAuth:
   1138     if (!HandleVncAuth(client)) return FALSE;
   1139     break;
   1140 
   1141   case rfbMSLogon:
   1142     if (!HandleMSLogonAuth(client)) return FALSE;
   1143     break;
   1144 
   1145   case rfbARD:
   1146 #ifndef LIBVNCSERVER_WITH_CLIENT_GCRYPT
   1147     rfbClientLog("GCrypt support was not compiled in\n");
   1148     return FALSE;
   1149 #else
   1150     if (!HandleARDAuth(client)) return FALSE;
   1151 #endif
   1152     break;
   1153 
   1154   case rfbTLS:
   1155     if (!HandleAnonTLSAuth(client)) return FALSE;
   1156     /* After the TLS session is established, sub auth types are expected.
   1157      * Note that all following reading/writing are through the TLS session from here.
   1158      */
   1159     if (!ReadSupportedSecurityType(client, &subAuthScheme, TRUE)) return FALSE;
   1160     client->subAuthScheme = subAuthScheme;
   1161 
   1162     switch (subAuthScheme) {
   1163 
   1164       case rfbConnFailed:
   1165         ReadReason(client);
   1166         return FALSE;
   1167 
   1168       case rfbNoAuth:
   1169         rfbClientLog("No sub authentication needed\n");
   1170         /* 3.8 and upwards sends a Security Result for rfbNoAuth */
   1171         if ((client->major==3 && client->minor > 7) || client->major>3)
   1172             if (!rfbHandleAuthResult(client)) return FALSE;
   1173         break;
   1174 
   1175       case rfbVncAuth:
   1176         if (!HandleVncAuth(client)) return FALSE;
   1177         break;
   1178 
   1179       default:
   1180         rfbClientLog("Unknown sub authentication scheme from VNC server: %d\n",
   1181             (int)subAuthScheme);
   1182         return FALSE;
   1183     }
   1184 
   1185     break;
   1186 
   1187   case rfbVeNCrypt:
   1188     if (!HandleVeNCryptAuth(client)) return FALSE;
   1189 
   1190     switch (client->subAuthScheme) {
   1191 
   1192       case rfbVeNCryptTLSNone:
   1193       case rfbVeNCryptX509None:
   1194         rfbClientLog("No sub authentication needed\n");
   1195         if (!rfbHandleAuthResult(client)) return FALSE;
   1196         break;
   1197 
   1198       case rfbVeNCryptTLSVNC:
   1199       case rfbVeNCryptX509VNC:
   1200         if (!HandleVncAuth(client)) return FALSE;
   1201         break;
   1202 
   1203       case rfbVeNCryptTLSPlain:
   1204       case rfbVeNCryptX509Plain:
   1205         if (!HandlePlainAuth(client)) return FALSE;
   1206         break;
   1207 
   1208       default:
   1209         rfbClientLog("Unknown sub authentication scheme from VNC server: %d\n",
   1210             client->subAuthScheme);
   1211         return FALSE;
   1212     }
   1213 
   1214     break;
   1215 
   1216   default:
   1217     rfbClientLog("Unknown authentication scheme from VNC server: %d\n",
   1218 	    (int)authScheme);
   1219     return FALSE;
   1220   }
   1221 
   1222   ci.shared = (client->appData.shareDesktop ? 1 : 0);
   1223 
   1224   if (!WriteToRFBServer(client,  (char *)&ci, sz_rfbClientInitMsg)) return FALSE;
   1225 
   1226   if (!ReadFromRFBServer(client, (char *)&client->si, sz_rfbServerInitMsg)) return FALSE;
   1227 
   1228   client->si.framebufferWidth = rfbClientSwap16IfLE(client->si.framebufferWidth);
   1229   client->si.framebufferHeight = rfbClientSwap16IfLE(client->si.framebufferHeight);
   1230   client->si.format.redMax = rfbClientSwap16IfLE(client->si.format.redMax);
   1231   client->si.format.greenMax = rfbClientSwap16IfLE(client->si.format.greenMax);
   1232   client->si.format.blueMax = rfbClientSwap16IfLE(client->si.format.blueMax);
   1233   client->si.nameLength = rfbClientSwap32IfLE(client->si.nameLength);
   1234 
   1235   client->desktopName = malloc(client->si.nameLength + 1);
   1236   if (!client->desktopName) {
   1237     rfbClientLog("Error allocating memory for desktop name, %lu bytes\n",
   1238             (unsigned long)client->si.nameLength);
   1239     return FALSE;
   1240   }
   1241 
   1242   if (!ReadFromRFBServer(client, client->desktopName, client->si.nameLength)) return FALSE;
   1243 
   1244   client->desktopName[client->si.nameLength] = 0;
   1245 
   1246   rfbClientLog("Desktop name \"%s\"\n",client->desktopName);
   1247 
   1248   rfbClientLog("Connected to VNC server, using protocol version %d.%d\n",
   1249 	  client->major, client->minor);
   1250 
   1251   rfbClientLog("VNC server default format:\n");
   1252   PrintPixelFormat(&client->si.format);
   1253 
   1254   return TRUE;
   1255 }
   1256 
   1257 
   1258 /*
   1259  * SetFormatAndEncodings.
   1260  */
   1261 
   1262 rfbBool
   1263 SetFormatAndEncodings(rfbClient* client)
   1264 {
   1265   rfbSetPixelFormatMsg spf;
   1266   char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4];
   1267 
   1268   rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf;
   1269   uint32_t *encs = (uint32_t *)(&buf[sz_rfbSetEncodingsMsg]);
   1270   int len = 0;
   1271   rfbBool requestCompressLevel = FALSE;
   1272   rfbBool requestQualityLevel = FALSE;
   1273   rfbBool requestLastRectEncoding = FALSE;
   1274   rfbClientProtocolExtension* e;
   1275 
   1276   if (!SupportsClient2Server(client, rfbSetPixelFormat)) return TRUE;
   1277 
   1278   spf.type = rfbSetPixelFormat;
   1279   spf.format = client->format;
   1280   spf.format.redMax = rfbClientSwap16IfLE(spf.format.redMax);
   1281   spf.format.greenMax = rfbClientSwap16IfLE(spf.format.greenMax);
   1282   spf.format.blueMax = rfbClientSwap16IfLE(spf.format.blueMax);
   1283 
   1284   if (!WriteToRFBServer(client, (char *)&spf, sz_rfbSetPixelFormatMsg))
   1285     return FALSE;
   1286 
   1287 
   1288   if (!SupportsClient2Server(client, rfbSetEncodings)) return TRUE;
   1289 
   1290   se->type = rfbSetEncodings;
   1291   se->nEncodings = 0;
   1292 
   1293   if (client->appData.encodingsString) {
   1294     const char *encStr = client->appData.encodingsString;
   1295     int encStrLen;
   1296     do {
   1297       const char *nextEncStr = strchr(encStr, ' ');
   1298       if (nextEncStr) {
   1299 	encStrLen = nextEncStr - encStr;
   1300 	nextEncStr++;
   1301       } else {
   1302 	encStrLen = strlen(encStr);
   1303       }
   1304 
   1305       if (strncasecmp(encStr,"raw",encStrLen) == 0) {
   1306 	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRaw);
   1307       } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) {
   1308 	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCopyRect);
   1309 #ifdef LIBVNCSERVER_HAVE_LIBZ
   1310 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
   1311       } else if (strncasecmp(encStr,"tight",encStrLen) == 0) {
   1312 	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTight);
   1313 	requestLastRectEncoding = TRUE;
   1314 	if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
   1315 	  requestCompressLevel = TRUE;
   1316 	if (client->appData.enableJPEG)
   1317 	  requestQualityLevel = TRUE;
   1318 #endif
   1319 #endif
   1320       } else if (strncasecmp(encStr,"hextile",encStrLen) == 0) {
   1321 	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingHextile);
   1322 #ifdef LIBVNCSERVER_HAVE_LIBZ
   1323       } else if (strncasecmp(encStr,"zlib",encStrLen) == 0) {
   1324 	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlib);
   1325 	if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
   1326 	  requestCompressLevel = TRUE;
   1327       } else if (strncasecmp(encStr,"zlibhex",encStrLen) == 0) {
   1328 	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlibHex);
   1329 	if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
   1330 	  requestCompressLevel = TRUE;
   1331       } else if (strncasecmp(encStr,"zrle",encStrLen) == 0) {
   1332 	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZRLE);
   1333       } else if (strncasecmp(encStr,"zywrle",encStrLen) == 0) {
   1334 	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZYWRLE);
   1335 	requestQualityLevel = TRUE;
   1336 #endif
   1337       } else if ((strncasecmp(encStr,"ultra",encStrLen) == 0) || (strncasecmp(encStr,"ultrazip",encStrLen) == 0)) {
   1338         /* There are 2 encodings used in 'ultra' */
   1339         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltra);
   1340         encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltraZip);
   1341       } else if (strncasecmp(encStr,"corre",encStrLen) == 0) {
   1342 	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCoRRE);
   1343       } else if (strncasecmp(encStr,"rre",encStrLen) == 0) {
   1344 	encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE);
   1345       } else {
   1346 	rfbClientLog("Unknown encoding '%.*s'\n",encStrLen,encStr);
   1347       }
   1348 
   1349       encStr = nextEncStr;
   1350     } while (encStr && se->nEncodings < MAX_ENCODINGS);
   1351 
   1352     if (se->nEncodings < MAX_ENCODINGS && requestCompressLevel) {
   1353       encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.compressLevel +
   1354 					  rfbEncodingCompressLevel0);
   1355     }
   1356 
   1357     if (se->nEncodings < MAX_ENCODINGS && requestQualityLevel) {
   1358       if (client->appData.qualityLevel < 0 || client->appData.qualityLevel > 9)
   1359         client->appData.qualityLevel = 5;
   1360       encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel +
   1361 					  rfbEncodingQualityLevel0);
   1362     }
   1363   }
   1364   else {
   1365     if (SameMachine(client->sock)) {
   1366       /* TODO:
   1367       if (!tunnelSpecified) {
   1368       */
   1369       rfbClientLog("Same machine: preferring raw encoding\n");
   1370       encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRaw);
   1371       /*
   1372       } else {
   1373 	rfbClientLog("Tunneling active: preferring tight encoding\n");
   1374       }
   1375       */
   1376     }
   1377 
   1378     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCopyRect);
   1379 #ifdef LIBVNCSERVER_HAVE_LIBZ
   1380 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
   1381     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTight);
   1382     requestLastRectEncoding = TRUE;
   1383 #endif
   1384 #endif
   1385     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingHextile);
   1386 #ifdef LIBVNCSERVER_HAVE_LIBZ
   1387     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlib);
   1388     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZRLE);
   1389     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZYWRLE);
   1390 #endif
   1391     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltra);
   1392     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltraZip);
   1393     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCoRRE);
   1394     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE);
   1395 
   1396     if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9) {
   1397       encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.compressLevel +
   1398 					  rfbEncodingCompressLevel0);
   1399     } else /* if (!tunnelSpecified) */ {
   1400       /* If -tunnel option was provided, we assume that server machine is
   1401 	 not in the local network so we use default compression level for
   1402 	 tight encoding instead of fast compression. Thus we are
   1403 	 requesting level 1 compression only if tunneling is not used. */
   1404       encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCompressLevel1);
   1405     }
   1406 
   1407     if (client->appData.enableJPEG) {
   1408       if (client->appData.qualityLevel < 0 || client->appData.qualityLevel > 9)
   1409 	client->appData.qualityLevel = 5;
   1410       encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel +
   1411 					  rfbEncodingQualityLevel0);
   1412     }
   1413   }
   1414 
   1415 
   1416 
   1417   /* Remote Cursor Support (local to viewer) */
   1418   if (client->appData.useRemoteCursor) {
   1419     if (se->nEncodings < MAX_ENCODINGS)
   1420       encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingXCursor);
   1421     if (se->nEncodings < MAX_ENCODINGS)
   1422       encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRichCursor);
   1423     if (se->nEncodings < MAX_ENCODINGS)
   1424       encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPointerPos);
   1425   }
   1426 
   1427   /* Keyboard State Encodings */
   1428   if (se->nEncodings < MAX_ENCODINGS)
   1429     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingKeyboardLedState);
   1430 
   1431   /* New Frame Buffer Size */
   1432   if (se->nEncodings < MAX_ENCODINGS && client->canHandleNewFBSize)
   1433     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingNewFBSize);
   1434 
   1435   /* Last Rect */
   1436   if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding)
   1437     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect);
   1438 
   1439   /* Server Capabilities */
   1440   if (se->nEncodings < MAX_ENCODINGS)
   1441     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedMessages);
   1442   if (se->nEncodings < MAX_ENCODINGS)
   1443     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedEncodings);
   1444   if (se->nEncodings < MAX_ENCODINGS)
   1445     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingServerIdentity);
   1446 
   1447   /* xvp */
   1448   if (se->nEncodings < MAX_ENCODINGS)
   1449     encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingXvp);
   1450 
   1451   /* client extensions */
   1452   for(e = rfbClientExtensions; e; e = e->next)
   1453     if(e->encodings) {
   1454       int* enc;
   1455       for(enc = e->encodings; *enc; enc++)
   1456 	encs[se->nEncodings++] = rfbClientSwap32IfLE(*enc);
   1457     }
   1458 
   1459   len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
   1460 
   1461   se->nEncodings = rfbClientSwap16IfLE(se->nEncodings);
   1462 
   1463   if (!WriteToRFBServer(client, buf, len)) return FALSE;
   1464 
   1465   return TRUE;
   1466 }
   1467 
   1468 
   1469 /*
   1470  * SendIncrementalFramebufferUpdateRequest.
   1471  */
   1472 
   1473 rfbBool
   1474 SendIncrementalFramebufferUpdateRequest(rfbClient* client)
   1475 {
   1476 	return SendFramebufferUpdateRequest(client,
   1477 			client->updateRect.x, client->updateRect.y,
   1478 			client->updateRect.w, client->updateRect.h, TRUE);
   1479 }
   1480 
   1481 
   1482 /*
   1483  * SendFramebufferUpdateRequest.
   1484  */
   1485 
   1486 rfbBool
   1487 SendFramebufferUpdateRequest(rfbClient* client, int x, int y, int w, int h, rfbBool incremental)
   1488 {
   1489   rfbFramebufferUpdateRequestMsg fur;
   1490 
   1491   if (!SupportsClient2Server(client, rfbFramebufferUpdateRequest)) return TRUE;
   1492 
   1493   fur.type = rfbFramebufferUpdateRequest;
   1494   fur.incremental = incremental ? 1 : 0;
   1495   fur.x = rfbClientSwap16IfLE(x);
   1496   fur.y = rfbClientSwap16IfLE(y);
   1497   fur.w = rfbClientSwap16IfLE(w);
   1498   fur.h = rfbClientSwap16IfLE(h);
   1499 
   1500   if (!WriteToRFBServer(client, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg))
   1501     return FALSE;
   1502 
   1503   return TRUE;
   1504 }
   1505 
   1506 
   1507 /*
   1508  * SendScaleSetting.
   1509  */
   1510 rfbBool
   1511 SendScaleSetting(rfbClient* client,int scaleSetting)
   1512 {
   1513   rfbSetScaleMsg ssm;
   1514 
   1515   ssm.scale = scaleSetting;
   1516   ssm.pad = 0;
   1517 
   1518   /* favor UltraVNC SetScale if both are supported */
   1519   if (SupportsClient2Server(client, rfbSetScale)) {
   1520       ssm.type = rfbSetScale;
   1521       if (!WriteToRFBServer(client, (char *)&ssm, sz_rfbSetScaleMsg))
   1522           return FALSE;
   1523   }
   1524 
   1525   if (SupportsClient2Server(client, rfbPalmVNCSetScaleFactor)) {
   1526       ssm.type = rfbPalmVNCSetScaleFactor;
   1527       if (!WriteToRFBServer(client, (char *)&ssm, sz_rfbSetScaleMsg))
   1528           return FALSE;
   1529   }
   1530 
   1531   return TRUE;
   1532 }
   1533 
   1534 /*
   1535  * TextChatFunctions (UltraVNC)
   1536  * Extremely bandwidth friendly method of communicating with a user
   1537  * (Think HelpDesk type applications)
   1538  */
   1539 
   1540 rfbBool TextChatSend(rfbClient* client, char *text)
   1541 {
   1542     rfbTextChatMsg chat;
   1543     int count = strlen(text);
   1544 
   1545     if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
   1546     chat.type = rfbTextChat;
   1547     chat.pad1 = 0;
   1548     chat.pad2 = 0;
   1549     chat.length = (uint32_t)count;
   1550     chat.length = rfbClientSwap32IfLE(chat.length);
   1551 
   1552     if (!WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg))
   1553         return FALSE;
   1554 
   1555     if (count>0) {
   1556         if (!WriteToRFBServer(client, text, count))
   1557             return FALSE;
   1558     }
   1559     return TRUE;
   1560 }
   1561 
   1562 rfbBool TextChatOpen(rfbClient* client)
   1563 {
   1564     rfbTextChatMsg chat;
   1565 
   1566     if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
   1567     chat.type = rfbTextChat;
   1568     chat.pad1 = 0;
   1569     chat.pad2 = 0;
   1570     chat.length = rfbClientSwap32IfLE(rfbTextChatOpen);
   1571     return  (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
   1572 }
   1573 
   1574 rfbBool TextChatClose(rfbClient* client)
   1575 {
   1576     rfbTextChatMsg chat;
   1577     if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
   1578     chat.type = rfbTextChat;
   1579     chat.pad1 = 0;
   1580     chat.pad2 = 0;
   1581     chat.length = rfbClientSwap32IfLE(rfbTextChatClose);
   1582     return  (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
   1583 }
   1584 
   1585 rfbBool TextChatFinish(rfbClient* client)
   1586 {
   1587     rfbTextChatMsg chat;
   1588     if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
   1589     chat.type = rfbTextChat;
   1590     chat.pad1 = 0;
   1591     chat.pad2 = 0;
   1592     chat.length = rfbClientSwap32IfLE(rfbTextChatFinished);
   1593     return  (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
   1594 }
   1595 
   1596 /*
   1597  * UltraVNC Server Input Disable
   1598  * Apparently, the remote client can *prevent* the local user from interacting with the display
   1599  * I would think this is extremely helpful when used in a HelpDesk situation
   1600  */
   1601 rfbBool PermitServerInput(rfbClient* client, int enabled)
   1602 {
   1603     rfbSetServerInputMsg msg;
   1604 
   1605     if (!SupportsClient2Server(client, rfbSetServerInput)) return TRUE;
   1606     /* enabled==1, then server input from local keyboard is disabled */
   1607     msg.type = rfbSetServerInput;
   1608     msg.status = (enabled ? 1 : 0);
   1609     msg.pad = 0;
   1610     return  (WriteToRFBServer(client, (char *)&msg, sz_rfbSetServerInputMsg) ? TRUE : FALSE);
   1611 }
   1612 
   1613 
   1614 /*
   1615  * send xvp client message
   1616  * A client supporting the xvp extension sends this to request that the server initiate
   1617  * a clean shutdown, clean reboot or abrupt reset of the system whose framebuffer the
   1618  * client is displaying.
   1619  *
   1620  * only version 1 is defined in the protocol specs
   1621  *
   1622  * possible values for code are:
   1623  *   rfbXvp_Shutdown
   1624  *   rfbXvp_Reboot
   1625  *   rfbXvp_Reset
   1626  */
   1627 
   1628 rfbBool SendXvpMsg(rfbClient* client, uint8_t version, uint8_t code)
   1629 {
   1630     rfbXvpMsg xvp;
   1631 
   1632     if (!SupportsClient2Server(client, rfbXvp)) return TRUE;
   1633     xvp.type = rfbXvp;
   1634     xvp.pad = 0;
   1635     xvp.version = version;
   1636     xvp.code = code;
   1637 
   1638     if (!WriteToRFBServer(client, (char *)&xvp, sz_rfbXvpMsg))
   1639         return FALSE;
   1640 
   1641     return TRUE;
   1642 }
   1643 
   1644 
   1645 /*
   1646  * SendPointerEvent.
   1647  */
   1648 
   1649 rfbBool
   1650 SendPointerEvent(rfbClient* client,int x, int y, int buttonMask)
   1651 {
   1652   rfbPointerEventMsg pe;
   1653 
   1654   if (!SupportsClient2Server(client, rfbPointerEvent)) return TRUE;
   1655 
   1656   pe.type = rfbPointerEvent;
   1657   pe.buttonMask = buttonMask;
   1658   if (x < 0) x = 0;
   1659   if (y < 0) y = 0;
   1660 
   1661   pe.x = rfbClientSwap16IfLE(x);
   1662   pe.y = rfbClientSwap16IfLE(y);
   1663   return WriteToRFBServer(client, (char *)&pe, sz_rfbPointerEventMsg);
   1664 }
   1665 
   1666 
   1667 /*
   1668  * SendKeyEvent.
   1669  */
   1670 
   1671 rfbBool
   1672 SendKeyEvent(rfbClient* client, uint32_t key, rfbBool down)
   1673 {
   1674   rfbKeyEventMsg ke;
   1675 
   1676   if (!SupportsClient2Server(client, rfbKeyEvent)) return TRUE;
   1677 
   1678   ke.type = rfbKeyEvent;
   1679   ke.down = down ? 1 : 0;
   1680   ke.key = rfbClientSwap32IfLE(key);
   1681   return WriteToRFBServer(client, (char *)&ke, sz_rfbKeyEventMsg);
   1682 }
   1683 
   1684 
   1685 /*
   1686  * SendClientCutText.
   1687  */
   1688 
   1689 rfbBool
   1690 SendClientCutText(rfbClient* client, char *str, int len)
   1691 {
   1692   rfbClientCutTextMsg cct;
   1693 
   1694   if (!SupportsClient2Server(client, rfbClientCutText)) return TRUE;
   1695 
   1696   cct.type = rfbClientCutText;
   1697   cct.length = rfbClientSwap32IfLE(len);
   1698   return  (WriteToRFBServer(client, (char *)&cct, sz_rfbClientCutTextMsg) &&
   1699 	   WriteToRFBServer(client, str, len));
   1700 }
   1701 
   1702 
   1703 
   1704 /*
   1705  * HandleRFBServerMessage.
   1706  */
   1707 
   1708 rfbBool
   1709 HandleRFBServerMessage(rfbClient* client)
   1710 {
   1711   rfbServerToClientMsg msg;
   1712 
   1713   if (client->serverPort==-1)
   1714     client->vncRec->readTimestamp = TRUE;
   1715   if (!ReadFromRFBServer(client, (char *)&msg, 1))
   1716     return FALSE;
   1717 
   1718   switch (msg.type) {
   1719 
   1720   case rfbSetColourMapEntries:
   1721   {
   1722     /* TODO:
   1723     int i;
   1724     uint16_t rgb[3];
   1725     XColor xc;
   1726 
   1727     if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
   1728 			   sz_rfbSetColourMapEntriesMsg - 1))
   1729       return FALSE;
   1730 
   1731     msg.scme.firstColour = rfbClientSwap16IfLE(msg.scme.firstColour);
   1732     msg.scme.nColours = rfbClientSwap16IfLE(msg.scme.nColours);
   1733 
   1734     for (i = 0; i < msg.scme.nColours; i++) {
   1735       if (!ReadFromRFBServer(client, (char *)rgb, 6))
   1736 	return FALSE;
   1737       xc.pixel = msg.scme.firstColour + i;
   1738       xc.red = rfbClientSwap16IfLE(rgb[0]);
   1739       xc.green = rfbClientSwap16IfLE(rgb[1]);
   1740       xc.blue = rfbClientSwap16IfLE(rgb[2]);
   1741       xc.flags = DoRed|DoGreen|DoBlue;
   1742       XStoreColor(dpy, cmap, &xc);
   1743     }
   1744     */
   1745 
   1746     break;
   1747   }
   1748 
   1749   case rfbFramebufferUpdate:
   1750   {
   1751     rfbFramebufferUpdateRectHeader rect;
   1752     int linesToRead;
   1753     int bytesPerLine;
   1754     int i;
   1755 
   1756     if (!ReadFromRFBServer(client, ((char *)&msg.fu) + 1,
   1757 			   sz_rfbFramebufferUpdateMsg - 1))
   1758       return FALSE;
   1759 
   1760     msg.fu.nRects = rfbClientSwap16IfLE(msg.fu.nRects);
   1761 
   1762     for (i = 0; i < msg.fu.nRects; i++) {
   1763       if (!ReadFromRFBServer(client, (char *)&rect, sz_rfbFramebufferUpdateRectHeader))
   1764 	return FALSE;
   1765 
   1766       rect.encoding = rfbClientSwap32IfLE(rect.encoding);
   1767       if (rect.encoding == rfbEncodingLastRect)
   1768 	break;
   1769 
   1770       rect.r.x = rfbClientSwap16IfLE(rect.r.x);
   1771       rect.r.y = rfbClientSwap16IfLE(rect.r.y);
   1772       rect.r.w = rfbClientSwap16IfLE(rect.r.w);
   1773       rect.r.h = rfbClientSwap16IfLE(rect.r.h);
   1774 
   1775 
   1776       if (rect.encoding == rfbEncodingXCursor ||
   1777 	  rect.encoding == rfbEncodingRichCursor) {
   1778 
   1779 	if (!HandleCursorShape(client,
   1780 			       rect.r.x, rect.r.y, rect.r.w, rect.r.h,
   1781 			       rect.encoding)) {
   1782 	  return FALSE;
   1783 	}
   1784 	continue;
   1785       }
   1786 
   1787       if (rect.encoding == rfbEncodingPointerPos) {
   1788 	if (!client->HandleCursorPos(client,rect.r.x, rect.r.y)) {
   1789 	  return FALSE;
   1790 	}
   1791 	continue;
   1792       }
   1793 
   1794       if (rect.encoding == rfbEncodingKeyboardLedState) {
   1795           /* OK! We have received a keyboard state message!!! */
   1796           client->KeyboardLedStateEnabled = 1;
   1797           if (client->HandleKeyboardLedState!=NULL)
   1798               client->HandleKeyboardLedState(client, rect.r.x, 0);
   1799           /* stash it for the future */
   1800           client->CurrentKeyboardLedState = rect.r.x;
   1801           continue;
   1802       }
   1803 
   1804       if (rect.encoding == rfbEncodingNewFBSize) {
   1805 	client->width = rect.r.w;
   1806 	client->height = rect.r.h;
   1807 	client->updateRect.x = client->updateRect.y = 0;
   1808 	client->updateRect.w = client->width;
   1809 	client->updateRect.h = client->height;
   1810 	client->MallocFrameBuffer(client);
   1811 	SendFramebufferUpdateRequest(client, 0, 0, rect.r.w, rect.r.h, FALSE);
   1812 	rfbClientLog("Got new framebuffer size: %dx%d\n", rect.r.w, rect.r.h);
   1813 	continue;
   1814       }
   1815 
   1816       /* rect.r.w=byte count */
   1817       if (rect.encoding == rfbEncodingSupportedMessages) {
   1818           int loop;
   1819           if (!ReadFromRFBServer(client, (char *)&client->supportedMessages, sz_rfbSupportedMessages))
   1820               return FALSE;
   1821 
   1822           /* msgs is two sets of bit flags of supported messages client2server[] and server2client[] */
   1823           /* currently ignored by this library */
   1824 
   1825           rfbClientLog("client2server supported messages (bit flags)\n");
   1826           for (loop=0;loop<32;loop+=8)
   1827             rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop,
   1828                 client->supportedMessages.client2server[loop],   client->supportedMessages.client2server[loop+1],
   1829                 client->supportedMessages.client2server[loop+2], client->supportedMessages.client2server[loop+3],
   1830                 client->supportedMessages.client2server[loop+4], client->supportedMessages.client2server[loop+5],
   1831                 client->supportedMessages.client2server[loop+6], client->supportedMessages.client2server[loop+7]);
   1832 
   1833           rfbClientLog("server2client supported messages (bit flags)\n");
   1834           for (loop=0;loop<32;loop+=8)
   1835             rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop,
   1836                 client->supportedMessages.server2client[loop],   client->supportedMessages.server2client[loop+1],
   1837                 client->supportedMessages.server2client[loop+2], client->supportedMessages.server2client[loop+3],
   1838                 client->supportedMessages.server2client[loop+4], client->supportedMessages.server2client[loop+5],
   1839                 client->supportedMessages.server2client[loop+6], client->supportedMessages.server2client[loop+7]);
   1840           continue;
   1841       }
   1842 
   1843       /* rect.r.w=byte count, rect.r.h=# of encodings */
   1844       if (rect.encoding == rfbEncodingSupportedEncodings) {
   1845           char *buffer;
   1846           buffer = malloc(rect.r.w);
   1847           if (!ReadFromRFBServer(client, buffer, rect.r.w))
   1848           {
   1849               free(buffer);
   1850               return FALSE;
   1851           }
   1852 
   1853           /* buffer now contains rect.r.h # of uint32_t encodings that the server supports */
   1854           /* currently ignored by this library */
   1855           free(buffer);
   1856           continue;
   1857       }
   1858 
   1859       /* rect.r.w=byte count */
   1860       if (rect.encoding == rfbEncodingServerIdentity) {
   1861           char *buffer;
   1862           buffer = malloc(rect.r.w+1);
   1863           if (!ReadFromRFBServer(client, buffer, rect.r.w))
   1864           {
   1865               free(buffer);
   1866               return FALSE;
   1867           }
   1868           buffer[rect.r.w]=0; /* null terminate, just in case */
   1869           rfbClientLog("Connected to Server \"%s\"\n", buffer);
   1870           free(buffer);
   1871           continue;
   1872       }
   1873 
   1874       /* rfbEncodingUltraZip is a collection of subrects.   x = # of subrects, and h is always 0 */
   1875       if (rect.encoding != rfbEncodingUltraZip)
   1876       {
   1877         if ((rect.r.x + rect.r.w > client->width) ||
   1878 	    (rect.r.y + rect.r.h > client->height))
   1879 	    {
   1880 	      rfbClientLog("Rect too large: %dx%d at (%d, %d)\n",
   1881 	  	  rect.r.w, rect.r.h, rect.r.x, rect.r.y);
   1882 	      return FALSE;
   1883             }
   1884 
   1885         /* UltraVNC with scaling, will send rectangles with a zero W or H
   1886          *
   1887         if ((rect.encoding != rfbEncodingTight) &&
   1888             (rect.r.h * rect.r.w == 0))
   1889         {
   1890 	  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);
   1891 	  continue;
   1892         }
   1893         */
   1894 
   1895         /* If RichCursor encoding is used, we should prevent collisions
   1896 	   between framebuffer updates and cursor drawing operations. */
   1897         client->SoftCursorLockArea(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
   1898       }
   1899 
   1900       switch (rect.encoding) {
   1901 
   1902       case rfbEncodingRaw: {
   1903 	int y=rect.r.y, h=rect.r.h;
   1904 
   1905 	bytesPerLine = rect.r.w * client->format.bitsPerPixel / 8;
   1906 	linesToRead = RFB_BUFFER_SIZE / bytesPerLine;
   1907 
   1908 	while (h > 0) {
   1909 	  if (linesToRead > h)
   1910 	    linesToRead = h;
   1911 
   1912 	  if (!ReadFromRFBServer(client, client->buffer,bytesPerLine * linesToRead))
   1913 	    return FALSE;
   1914 
   1915 	  CopyRectangle(client, (uint8_t *)client->buffer,
   1916 			   rect.r.x, y, rect.r.w,linesToRead);
   1917 
   1918 	  h -= linesToRead;
   1919 	  y += linesToRead;
   1920 
   1921 	}
   1922       } break;
   1923 
   1924       case rfbEncodingCopyRect:
   1925       {
   1926 	rfbCopyRect cr;
   1927 
   1928 	if (!ReadFromRFBServer(client, (char *)&cr, sz_rfbCopyRect))
   1929 	  return FALSE;
   1930 
   1931 	cr.srcX = rfbClientSwap16IfLE(cr.srcX);
   1932 	cr.srcY = rfbClientSwap16IfLE(cr.srcY);
   1933 
   1934 	/* If RichCursor encoding is used, we should extend our
   1935 	   "cursor lock area" (previously set to destination
   1936 	   rectangle) to the source rectangle as well. */
   1937 	client->SoftCursorLockArea(client,
   1938 				   cr.srcX, cr.srcY, rect.r.w, rect.r.h);
   1939 
   1940         if (client->GotCopyRect != NULL) {
   1941           client->GotCopyRect(client, cr.srcX, cr.srcY, rect.r.w, rect.r.h,
   1942               rect.r.x, rect.r.y);
   1943         } else
   1944 		CopyRectangleFromRectangle(client,
   1945 				   cr.srcX, cr.srcY, rect.r.w, rect.r.h,
   1946 				   rect.r.x, rect.r.y);
   1947 
   1948 	break;
   1949       }
   1950 
   1951       case rfbEncodingRRE:
   1952       {
   1953 	switch (client->format.bitsPerPixel) {
   1954 	case 8:
   1955 	  if (!HandleRRE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   1956 	    return FALSE;
   1957 	  break;
   1958 	case 16:
   1959 	  if (!HandleRRE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   1960 	    return FALSE;
   1961 	  break;
   1962 	case 32:
   1963 	  if (!HandleRRE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   1964 	    return FALSE;
   1965 	  break;
   1966 	}
   1967 	break;
   1968       }
   1969 
   1970       case rfbEncodingCoRRE:
   1971       {
   1972 	switch (client->format.bitsPerPixel) {
   1973 	case 8:
   1974 	  if (!HandleCoRRE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   1975 	    return FALSE;
   1976 	  break;
   1977 	case 16:
   1978 	  if (!HandleCoRRE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   1979 	    return FALSE;
   1980 	  break;
   1981 	case 32:
   1982 	  if (!HandleCoRRE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   1983 	    return FALSE;
   1984 	  break;
   1985 	}
   1986 	break;
   1987       }
   1988 
   1989       case rfbEncodingHextile:
   1990       {
   1991 	switch (client->format.bitsPerPixel) {
   1992 	case 8:
   1993 	  if (!HandleHextile8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   1994 	    return FALSE;
   1995 	  break;
   1996 	case 16:
   1997 	  if (!HandleHextile16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   1998 	    return FALSE;
   1999 	  break;
   2000 	case 32:
   2001 	  if (!HandleHextile32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2002 	    return FALSE;
   2003 	  break;
   2004 	}
   2005 	break;
   2006       }
   2007 
   2008       case rfbEncodingUltra:
   2009       {
   2010         switch (client->format.bitsPerPixel) {
   2011         case 8:
   2012           if (!HandleUltra8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2013             return FALSE;
   2014           break;
   2015         case 16:
   2016           if (!HandleUltra16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2017             return FALSE;
   2018           break;
   2019         case 32:
   2020           if (!HandleUltra32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2021             return FALSE;
   2022           break;
   2023         }
   2024         break;
   2025       }
   2026       case rfbEncodingUltraZip:
   2027       {
   2028         switch (client->format.bitsPerPixel) {
   2029         case 8:
   2030           if (!HandleUltraZip8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2031             return FALSE;
   2032           break;
   2033         case 16:
   2034           if (!HandleUltraZip16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2035             return FALSE;
   2036           break;
   2037         case 32:
   2038           if (!HandleUltraZip32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2039             return FALSE;
   2040           break;
   2041         }
   2042         break;
   2043       }
   2044 
   2045 #ifdef LIBVNCSERVER_HAVE_LIBZ
   2046       case rfbEncodingZlib:
   2047       {
   2048 	switch (client->format.bitsPerPixel) {
   2049 	case 8:
   2050 	  if (!HandleZlib8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2051 	    return FALSE;
   2052 	  break;
   2053 	case 16:
   2054 	  if (!HandleZlib16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2055 	    return FALSE;
   2056 	  break;
   2057 	case 32:
   2058 	  if (!HandleZlib32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2059 	    return FALSE;
   2060 	  break;
   2061 	}
   2062 	break;
   2063      }
   2064 
   2065 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
   2066       case rfbEncodingTight:
   2067       {
   2068 	switch (client->format.bitsPerPixel) {
   2069 	case 8:
   2070 	  if (!HandleTight8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2071 	    return FALSE;
   2072 	  break;
   2073 	case 16:
   2074 	  if (!HandleTight16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2075 	    return FALSE;
   2076 	  break;
   2077 	case 32:
   2078 	  if (!HandleTight32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2079 	    return FALSE;
   2080 	  break;
   2081 	}
   2082 	break;
   2083       }
   2084 #endif
   2085       case rfbEncodingZRLE:
   2086 	/* Fail safe for ZYWRLE unsupport VNC server. */
   2087 	client->appData.qualityLevel = 9;
   2088 	/* fall through */
   2089       case rfbEncodingZYWRLE:
   2090       {
   2091 	switch (client->format.bitsPerPixel) {
   2092 	case 8:
   2093 	  if (!HandleZRLE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2094 	    return FALSE;
   2095 	  break;
   2096 	case 16:
   2097 	  if (client->si.format.greenMax > 0x1F) {
   2098 	    if (!HandleZRLE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2099 	      return FALSE;
   2100 	  } else {
   2101 	    if (!HandleZRLE15(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2102 	      return FALSE;
   2103 	  }
   2104 	  break;
   2105 	case 32:
   2106 	{
   2107 	  uint32_t maxColor=(client->format.redMax<<client->format.redShift)|
   2108 		(client->format.greenMax<<client->format.greenShift)|
   2109 		(client->format.blueMax<<client->format.blueShift);
   2110 	  if ((client->format.bigEndian && (maxColor&0xff)==0) ||
   2111 	      (!client->format.bigEndian && (maxColor&0xff000000)==0)) {
   2112 	    if (!HandleZRLE24(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2113 	      return FALSE;
   2114 	  } else if (!client->format.bigEndian && (maxColor&0xff)==0) {
   2115 	    if (!HandleZRLE24Up(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2116 	      return FALSE;
   2117 	  } else if (client->format.bigEndian && (maxColor&0xff000000)==0) {
   2118 	    if (!HandleZRLE24Down(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2119 	      return FALSE;
   2120 	  } else if (!HandleZRLE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
   2121 	    return FALSE;
   2122 	  break;
   2123 	}
   2124 	}
   2125 	break;
   2126      }
   2127 
   2128 #endif
   2129 
   2130       default:
   2131 	 {
   2132 	   rfbBool handled = FALSE;
   2133 	   rfbClientProtocolExtension* e;
   2134 
   2135 	   for(e = rfbClientExtensions; !handled && e; e = e->next)
   2136 	     if(e->handleEncoding && e->handleEncoding(client, &rect))
   2137 	       handled = TRUE;
   2138 
   2139 	   if(!handled) {
   2140 	     rfbClientLog("Unknown rect encoding %d\n",
   2141 		 (int)rect.encoding);
   2142 	     return FALSE;
   2143 	   }
   2144 	 }
   2145       }
   2146 
   2147       /* Now we may discard "soft cursor locks". */
   2148       client->SoftCursorUnlockScreen(client);
   2149 
   2150       client->GotFrameBufferUpdate(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
   2151     }
   2152 
   2153     if (!SendIncrementalFramebufferUpdateRequest(client))
   2154       return FALSE;
   2155 
   2156     if (client->FinishedFrameBufferUpdate)
   2157       client->FinishedFrameBufferUpdate(client);
   2158 
   2159     break;
   2160   }
   2161 
   2162   case rfbBell:
   2163   {
   2164     client->Bell(client);
   2165 
   2166     break;
   2167   }
   2168 
   2169   case rfbServerCutText:
   2170   {
   2171     char *buffer;
   2172 
   2173     if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
   2174 			   sz_rfbServerCutTextMsg - 1))
   2175       return FALSE;
   2176 
   2177     msg.sct.length = rfbClientSwap32IfLE(msg.sct.length);
   2178 
   2179     buffer = malloc(msg.sct.length+1);
   2180 
   2181     if (!ReadFromRFBServer(client, buffer, msg.sct.length))
   2182       return FALSE;
   2183 
   2184     buffer[msg.sct.length] = 0;
   2185 
   2186     if (client->GotXCutText)
   2187       client->GotXCutText(client, buffer, msg.sct.length);
   2188 
   2189     free(buffer);
   2190 
   2191     break;
   2192   }
   2193 
   2194   case rfbTextChat:
   2195   {
   2196       char *buffer=NULL;
   2197       if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
   2198                              sz_rfbTextChatMsg- 1))
   2199         return FALSE;
   2200       msg.tc.length = rfbClientSwap32IfLE(msg.sct.length);
   2201       switch(msg.tc.length) {
   2202       case rfbTextChatOpen:
   2203           rfbClientLog("Received TextChat Open\n");
   2204           if (client->HandleTextChat!=NULL)
   2205               client->HandleTextChat(client, (int)rfbTextChatOpen, NULL);
   2206           break;
   2207       case rfbTextChatClose:
   2208           rfbClientLog("Received TextChat Close\n");
   2209          if (client->HandleTextChat!=NULL)
   2210               client->HandleTextChat(client, (int)rfbTextChatClose, NULL);
   2211           break;
   2212       case rfbTextChatFinished:
   2213           rfbClientLog("Received TextChat Finished\n");
   2214          if (client->HandleTextChat!=NULL)
   2215               client->HandleTextChat(client, (int)rfbTextChatFinished, NULL);
   2216           break;
   2217       default:
   2218           buffer=malloc(msg.tc.length+1);
   2219           if (!ReadFromRFBServer(client, buffer, msg.tc.length))
   2220           {
   2221               free(buffer);
   2222               return FALSE;
   2223           }
   2224           /* Null Terminate <just in case> */
   2225           buffer[msg.tc.length]=0;
   2226           rfbClientLog("Received TextChat \"%s\"\n", buffer);
   2227           if (client->HandleTextChat!=NULL)
   2228               client->HandleTextChat(client, (int)msg.tc.length, buffer);
   2229           free(buffer);
   2230           break;
   2231       }
   2232       break;
   2233   }
   2234 
   2235   case rfbXvp:
   2236   {
   2237     if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
   2238                            sz_rfbXvpMsg -1))
   2239       return FALSE;
   2240 
   2241     SetClient2Server(client, rfbXvp);
   2242     /* technically, we only care what we can *send* to the server
   2243      * but, we set Server2Client Just in case it ever becomes useful
   2244      */
   2245     SetServer2Client(client, rfbXvp);
   2246 
   2247     if(client->HandleXvpMsg)
   2248       client->HandleXvpMsg(client, msg.xvp.version, msg.xvp.code);
   2249 
   2250     break;
   2251   }
   2252 
   2253   case rfbResizeFrameBuffer:
   2254   {
   2255     if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
   2256                            sz_rfbResizeFrameBufferMsg -1))
   2257       return FALSE;
   2258     client->width = rfbClientSwap16IfLE(msg.rsfb.framebufferWidth);
   2259     client->height = rfbClientSwap16IfLE(msg.rsfb.framebufferHeigth);
   2260     client->updateRect.x = client->updateRect.y = 0;
   2261     client->updateRect.w = client->width;
   2262     client->updateRect.h = client->height;
   2263     client->MallocFrameBuffer(client);
   2264     SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE);
   2265     rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height);
   2266     break;
   2267   }
   2268 
   2269   case rfbPalmVNCReSizeFrameBuffer:
   2270   {
   2271     if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
   2272                            sz_rfbPalmVNCReSizeFrameBufferMsg -1))
   2273       return FALSE;
   2274     client->width = rfbClientSwap16IfLE(msg.prsfb.buffer_w);
   2275     client->height = rfbClientSwap16IfLE(msg.prsfb.buffer_h);
   2276     client->updateRect.x = client->updateRect.y = 0;
   2277     client->updateRect.w = client->width;
   2278     client->updateRect.h = client->height;
   2279     client->MallocFrameBuffer(client);
   2280     SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE);
   2281     rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height);
   2282     break;
   2283   }
   2284 
   2285   default:
   2286     {
   2287       rfbBool handled = FALSE;
   2288       rfbClientProtocolExtension* e;
   2289 
   2290       for(e = rfbClientExtensions; !handled && e; e = e->next)
   2291 	if(e->handleMessage && e->handleMessage(client, &msg))
   2292 	  handled = TRUE;
   2293 
   2294       if(!handled) {
   2295 	char buffer[256];
   2296 	rfbClientLog("Unknown message type %d from VNC server\n",msg.type);
   2297 	ReadFromRFBServer(client, buffer, 256);
   2298 	return FALSE;
   2299       }
   2300     }
   2301   }
   2302 
   2303   return TRUE;
   2304 }
   2305 
   2306 
   2307 #define GET_PIXEL8(pix, ptr) ((pix) = *(ptr)++)
   2308 
   2309 #define GET_PIXEL16(pix, ptr) (((uint8_t*)&(pix))[0] = *(ptr)++, \
   2310 			       ((uint8_t*)&(pix))[1] = *(ptr)++)
   2311 
   2312 #define GET_PIXEL32(pix, ptr) (((uint8_t*)&(pix))[0] = *(ptr)++, \
   2313 			       ((uint8_t*)&(pix))[1] = *(ptr)++, \
   2314 			       ((uint8_t*)&(pix))[2] = *(ptr)++, \
   2315 			       ((uint8_t*)&(pix))[3] = *(ptr)++)
   2316 
   2317 /* CONCAT2 concatenates its two arguments.  CONCAT2E does the same but also
   2318    expands its arguments if they are macros */
   2319 
   2320 #define CONCAT2(a,b) a##b
   2321 #define CONCAT2E(a,b) CONCAT2(a,b)
   2322 #define CONCAT3(a,b,c) a##b##c
   2323 #define CONCAT3E(a,b,c) CONCAT3(a,b,c)
   2324 
   2325 #define BPP 8
   2326 #include "rre.c"
   2327 #include "corre.c"
   2328 #include "hextile.c"
   2329 #include "ultra.c"
   2330 #include "zlib.c"
   2331 #include "tight.c"
   2332 #include "zrle.c"
   2333 #undef BPP
   2334 #define BPP 16
   2335 #include "rre.c"
   2336 #include "corre.c"
   2337 #include "hextile.c"
   2338 #include "ultra.c"
   2339 #include "zlib.c"
   2340 #include "tight.c"
   2341 #include "zrle.c"
   2342 #define REALBPP 15
   2343 #include "zrle.c"
   2344 #undef BPP
   2345 #define BPP 32
   2346 #include "rre.c"
   2347 #include "corre.c"
   2348 #include "hextile.c"
   2349 #include "ultra.c"
   2350 #include "zlib.c"
   2351 #include "tight.c"
   2352 #include "zrle.c"
   2353 #define REALBPP 24
   2354 #include "zrle.c"
   2355 #define REALBPP 24
   2356 #define UNCOMP 8
   2357 #include "zrle.c"
   2358 #define REALBPP 24
   2359 #define UNCOMP -8
   2360 #include "zrle.c"
   2361 #undef BPP
   2362 
   2363 
   2364 /*
   2365  * PrintPixelFormat.
   2366  */
   2367 
   2368 void
   2369 PrintPixelFormat(rfbPixelFormat *format)
   2370 {
   2371   if (format->bitsPerPixel == 1) {
   2372     rfbClientLog("  Single bit per pixel.\n");
   2373     rfbClientLog(
   2374 	    "  %s significant bit in each byte is leftmost on the screen.\n",
   2375 	    (format->bigEndian ? "Most" : "Least"));
   2376   } else {
   2377     rfbClientLog("  %d bits per pixel.\n",format->bitsPerPixel);
   2378     if (format->bitsPerPixel != 8) {
   2379       rfbClientLog("  %s significant byte first in each pixel.\n",
   2380 	      (format->bigEndian ? "Most" : "Least"));
   2381     }
   2382     if (format->trueColour) {
   2383       rfbClientLog("  TRUE colour: max red %d green %d blue %d"
   2384 		   ", shift red %d green %d blue %d\n",
   2385 		   format->redMax, format->greenMax, format->blueMax,
   2386 		   format->redShift, format->greenShift, format->blueShift);
   2387     } else {
   2388       rfbClientLog("  Colour map (not true colour).\n");
   2389     }
   2390   }
   2391 }
   2392 
   2393 /* avoid name clashes with LibVNCServer */
   2394 
   2395 #define rfbEncryptBytes rfbClientEncryptBytes
   2396 #define rfbEncryptBytes2 rfbClientEncryptBytes2
   2397 #define rfbDes rfbClientDes
   2398 #define rfbDesKey rfbClientDesKey
   2399 #define rfbUseKey rfbClientUseKey
   2400 #define rfbCPKey rfbClientCPKey
   2401 
   2402 #include "vncauth.c"
   2403 #include "d3des.c"
   2404