1 /*
2  *  Copyright (C) 2000-2006 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 #include <unistd.h>
27 #include <errno.h>
28 #include <pwd.h>
29 #include <vncviewer.h>
30 #include <vncauth.h>
31 #include <zlib.h>
32 #include <jpeglib.h>
33 
34 static void InitCapabilities(void);
35 static Bool SetupTunneling(void);
36 static int ReadSecurityType(void);
37 static int SelectSecurityType(void);
38 static Bool PerformAuthenticationTight(void);
39 static Bool AuthenticateVNC(void);
40 static Bool AuthenticateNone(void);
41 static Bool ReadAuthenticationResult(void);
42 static Bool ReadInteractionCaps(void);
43 static Bool ReadCapabilityList(CapsContainer *caps, int count);
44 
45 static Bool HandleRRE8(int rx, int ry, int rw, int rh);
46 static Bool HandleRRE16(int rx, int ry, int rw, int rh);
47 static Bool HandleRRE32(int rx, int ry, int rw, int rh);
48 static Bool HandleCoRRE8(int rx, int ry, int rw, int rh);
49 static Bool HandleCoRRE16(int rx, int ry, int rw, int rh);
50 static Bool HandleCoRRE32(int rx, int ry, int rw, int rh);
51 static Bool HandleHextile8(int rx, int ry, int rw, int rh);
52 static Bool HandleHextile16(int rx, int ry, int rw, int rh);
53 static Bool HandleHextile32(int rx, int ry, int rw, int rh);
54 static Bool HandleZlib8(int rx, int ry, int rw, int rh);
55 static Bool HandleZlib16(int rx, int ry, int rw, int rh);
56 static Bool HandleZlib32(int rx, int ry, int rw, int rh);
57 static Bool HandleTight8(int rx, int ry, int rw, int rh);
58 static Bool HandleTight16(int rx, int ry, int rw, int rh);
59 static Bool HandleTight32(int rx, int ry, int rw, int rh);
60 
61 static void ReadConnFailedReason(void);
62 static long ReadCompactLen (void);
63 
64 static void JpegInitSource(j_decompress_ptr cinfo);
65 static boolean JpegFillInputBuffer(j_decompress_ptr cinfo);
66 static void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes);
67 static void JpegTermSource(j_decompress_ptr cinfo);
68 static void JpegSetSrcManager(j_decompress_ptr cinfo, CARD8 *compressedData,
69                               int compressedLen);
70 
71 
72 int rfbsock;
73 char *desktopName;
74 rfbPixelFormat myFormat;
75 rfbServerInitMsg si;
76 char *serverCutText = NULL;
77 Bool newServerCutText = False;
78 
79 int endianTest = 1;
80 
81 static int protocolMinorVersion;
82 static Bool tightVncProtocol = False;
83 static CapsContainer *tunnelCaps;    /* known tunneling/encryption methods */
84 static CapsContainer *authCaps;	     /* known authentication schemes       */
85 static CapsContainer *serverMsgCaps; /* known non-standard server messages */
86 static CapsContainer *clientMsgCaps; /* known non-standard client messages */
87 static CapsContainer *encodingCaps;  /* known encodings besides Raw        */
88 
89 
90 /* Note that the CoRRE encoding uses this buffer and assumes it is big enough
91    to hold 255 * 255 * 32 bits -> 260100 bytes.  640*480 = 307200 bytes.
92    Hextile also assumes it is big enough to hold 16 * 16 * 32 bits.
93    Tight encoding assumes BUFFER_SIZE is at least 16384 bytes. */
94 
95 #define BUFFER_SIZE (640*480)
96 static char buffer[BUFFER_SIZE];
97 
98 
99 /* The zlib encoding requires expansion/decompression/deflation of the
100    compressed data in the "buffer" above into another, result buffer.
101    However, the size of the result buffer can be determined precisely
102    based on the bitsPerPixel, height and width of the rectangle.  We
103    allocate this buffer one time to be the full size of the buffer. */
104 
105 static int raw_buffer_size = -1;
106 static char *raw_buffer;
107 
108 static z_stream decompStream;
109 static Bool decompStreamInited = False;
110 
111 
112 /*
113  * Variables for the ``tight'' encoding implementation.
114  */
115 
116 /* Separate buffer for compressed data. */
117 #define ZLIB_BUFFER_SIZE 512
118 static char zlib_buffer[ZLIB_BUFFER_SIZE];
119 
120 /* Four independent compression streams for zlib library. */
121 static z_stream zlibStream[4];
122 static Bool zlibStreamActive[4] = {
123   False, False, False, False
124 };
125 
126 /* Filter stuff. Should be initialized by filter initialization code. */
127 static Bool cutZeros;
128 static int rectWidth, rectColors;
129 static char tightPalette[256*4];
130 static CARD8 tightPrevRow[2048*3*sizeof(CARD16)];
131 
132 /* JPEG decoder state. */
133 static Bool jpegError;
134 
135 
136 /*
137  * InitCapabilities.
138  */
139 
140 static void
InitCapabilities(void)141 InitCapabilities(void)
142 {
143   tunnelCaps    = CapsNewContainer();
144   authCaps      = CapsNewContainer();
145   serverMsgCaps = CapsNewContainer();
146   clientMsgCaps = CapsNewContainer();
147   encodingCaps  = CapsNewContainer();
148 
149   /* Supported authentication methods */
150   CapsAdd(authCaps, rfbAuthNone, rfbStandardVendor, sig_rfbAuthNone,
151 	  "No authentication");
152   CapsAdd(authCaps, rfbAuthVNC, rfbStandardVendor, sig_rfbAuthVNC,
153 	  "Standard VNC password authentication");
154 
155   /* Supported encoding types */
156   CapsAdd(encodingCaps, rfbEncodingCopyRect, rfbStandardVendor,
157 	  sig_rfbEncodingCopyRect, "Standard CopyRect encoding");
158   CapsAdd(encodingCaps, rfbEncodingRRE, rfbStandardVendor,
159 	  sig_rfbEncodingRRE, "Standard RRE encoding");
160   CapsAdd(encodingCaps, rfbEncodingCoRRE, rfbStandardVendor,
161 	  sig_rfbEncodingCoRRE, "Standard CoRRE encoding");
162   CapsAdd(encodingCaps, rfbEncodingHextile, rfbStandardVendor,
163 	  sig_rfbEncodingHextile, "Standard Hextile encoding");
164   CapsAdd(encodingCaps, rfbEncodingZlib, rfbTridiaVncVendor,
165 	  sig_rfbEncodingZlib, "Zlib encoding from TridiaVNC");
166   CapsAdd(encodingCaps, rfbEncodingTight, rfbTightVncVendor,
167 	  sig_rfbEncodingTight, "Tight encoding by Constantin Kaplinsky");
168 
169   /* Supported "fake" encoding types */
170   CapsAdd(encodingCaps, rfbEncodingCompressLevel0, rfbTightVncVendor,
171 	  sig_rfbEncodingCompressLevel0, "Compression level");
172   CapsAdd(encodingCaps, rfbEncodingQualityLevel0, rfbTightVncVendor,
173 	  sig_rfbEncodingQualityLevel0, "JPEG quality level");
174   CapsAdd(encodingCaps, rfbEncodingXCursor, rfbTightVncVendor,
175 	  sig_rfbEncodingXCursor, "X-style cursor shape update");
176   CapsAdd(encodingCaps, rfbEncodingRichCursor, rfbTightVncVendor,
177 	  sig_rfbEncodingRichCursor, "Rich-color cursor shape update");
178   CapsAdd(encodingCaps, rfbEncodingPointerPos, rfbTightVncVendor,
179 	  sig_rfbEncodingPointerPos, "Pointer position update");
180   CapsAdd(encodingCaps, rfbEncodingLastRect, rfbTightVncVendor,
181 	  sig_rfbEncodingLastRect, "LastRect protocol extension");
182 }
183 
184 
185 /*
186  * ConnectToRFBServer.
187  */
188 
189 Bool
ConnectToRFBServer(const char * hostname,int port)190 ConnectToRFBServer(const char *hostname, int port)
191 {
192   unsigned int host;
193 
194   if (!StringToIPAddr(hostname, &host)) {
195     fprintf(stderr,"Couldn't convert '%s' to host address\n", hostname);
196     return False;
197   }
198 
199   rfbsock = ConnectToTcpAddr(host, port);
200 
201   if (rfbsock < 0) {
202     fprintf(stderr,"Unable to connect to VNC server\n");
203     return False;
204   }
205 
206   return SetNonBlocking(rfbsock);
207 }
208 
209 
210 /*
211  * InitialiseRFBConnection.
212  */
213 
214 Bool
InitialiseRFBConnection(void)215 InitialiseRFBConnection(void)
216 {
217   rfbProtocolVersionMsg pv;
218   int server_major, server_minor;
219   rfbClientInitMsg ci;
220   int secType;
221 
222   /* if the connection is immediately closed, don't report anything, so
223        that pmw's monitor can make test connections */
224 
225   if (listenSpecified)
226     errorMessageOnReadFailure = False;
227 
228   if (!ReadFromRFBServer(pv, sz_rfbProtocolVersionMsg))
229     return False;
230 
231   errorMessageOnReadFailure = True;
232 
233   pv[sz_rfbProtocolVersionMsg] = 0;
234 
235   if (sscanf(pv, rfbProtocolVersionFormat,
236 	     &server_major, &server_minor) != 2) {
237     fprintf(stderr,"Not a valid VNC server\n");
238     return False;
239   }
240 
241   if (server_major == 3 && server_minor >= 8) {
242     /* the server supports protocol 3.8 or higher version */
243     protocolMinorVersion = 8;
244   } else if (server_major == 3 && server_minor == 7) {
245     /* the server supports protocol 3.7 */
246     protocolMinorVersion = 7;
247   } else {
248     /* any other server version, request the standard 3.3 */
249     protocolMinorVersion = 3;
250   }
251 
252   fprintf(stderr, "Connected to RFB server, using protocol version 3.%d\n",
253 	  protocolMinorVersion);
254 
255   sprintf(pv, rfbProtocolVersionFormat, 3, protocolMinorVersion);
256 
257   if (!WriteExact(rfbsock, pv, sz_rfbProtocolVersionMsg))
258     return False;
259 
260   /* Read or select the security type. */
261   if (protocolMinorVersion >= 7) {
262     secType = SelectSecurityType();
263   } else {
264     secType = ReadSecurityType();
265   }
266   if (secType == rfbSecTypeInvalid)
267     return False;
268 
269   switch (secType) {
270   case rfbSecTypeNone:
271     if (!AuthenticateNone())
272       return False;
273     break;
274   case rfbSecTypeVncAuth:
275     if (!AuthenticateVNC())
276       return False;
277     break;
278   case rfbSecTypeTight:
279     tightVncProtocol = True;
280     InitCapabilities();
281     if (!SetupTunneling())
282       return False;
283     if (!PerformAuthenticationTight())
284       return False;
285     break;
286   default:                      /* should never happen */
287     fprintf(stderr, "Internal error: Invalid security type\n");
288     return False;
289   }
290 
291   ci.shared = (appData.shareDesktop ? 1 : 0);
292 
293   if (!WriteExact(rfbsock, (char *)&ci, sz_rfbClientInitMsg))
294     return False;
295 
296   if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg))
297     return False;
298 
299   si.framebufferWidth = Swap16IfLE(si.framebufferWidth);
300   si.framebufferHeight = Swap16IfLE(si.framebufferHeight);
301   si.format.redMax = Swap16IfLE(si.format.redMax);
302   si.format.greenMax = Swap16IfLE(si.format.greenMax);
303   si.format.blueMax = Swap16IfLE(si.format.blueMax);
304   si.nameLength = Swap32IfLE(si.nameLength);
305 
306   /* FIXME: Check arguments to malloc() calls. */
307   desktopName = malloc(si.nameLength + 1);
308   if (!desktopName) {
309     fprintf(stderr, "Error allocating memory for desktop name, %lu bytes\n",
310             (unsigned long)si.nameLength);
311     return False;
312   }
313 
314   if (!ReadFromRFBServer(desktopName, si.nameLength)) return False;
315 
316   desktopName[si.nameLength] = 0;
317 
318   fprintf(stderr,"Desktop name \"%s\"\n",desktopName);
319 
320   fprintf(stderr,"VNC server default format:\n");
321   PrintPixelFormat(&si.format);
322 
323   if (tightVncProtocol) {
324     /* Read interaction capabilities (protocol 3.7t, 3.8t) */
325     if (!ReadInteractionCaps())
326       return False;
327   }
328 
329   return True;
330 }
331 
332 
333 /*
334  * Read security type from the server (protocol 3.3)
335  */
336 
337 static int
ReadSecurityType(void)338 ReadSecurityType(void)
339 {
340   CARD32 secType;
341 
342   /* Read the security type */
343   if (!ReadFromRFBServer((char *)&secType, sizeof(secType)))
344     return rfbSecTypeInvalid;
345 
346   secType = Swap32IfLE(secType);
347 
348   if (secType == rfbSecTypeInvalid) {
349     ReadConnFailedReason();
350     return rfbSecTypeInvalid;
351   }
352 
353   if (secType != rfbSecTypeNone && secType != rfbSecTypeVncAuth) {
354     fprintf(stderr, "Unknown security type from RFB server: %d\n",
355             (int)secType);
356     return rfbSecTypeInvalid;
357   }
358 
359   return (int)secType;
360 }
361 
362 
363 /*
364  * Select security type from the server's list (protocol 3.7 and above)
365  */
366 
367 static int
SelectSecurityType(void)368 SelectSecurityType(void)
369 {
370   CARD8 nSecTypes;
371   char *secTypeNames[] = {"None", "VncAuth"};
372   CARD8 knownSecTypes[] = {rfbSecTypeNone, rfbSecTypeVncAuth};
373   int nKnownSecTypes = sizeof(knownSecTypes);
374   CARD8 *secTypes;
375   CARD8 secType = rfbSecTypeInvalid;
376   int i, j;
377 
378   /* Read the list of secutiry types. */
379   if (!ReadFromRFBServer((char *)&nSecTypes, sizeof(nSecTypes)))
380     return rfbSecTypeInvalid;
381 
382   if (nSecTypes == 0) {
383     ReadConnFailedReason();
384     return rfbSecTypeInvalid;
385   }
386 
387   secTypes = malloc(nSecTypes);
388   if (!ReadFromRFBServer((char *)secTypes, nSecTypes))
389     return rfbSecTypeInvalid;
390 
391   /* Find out if the server supports TightVNC protocol extensions */
392   for (j = 0; j < (int)nSecTypes; j++) {
393     if (secTypes[j] == rfbSecTypeTight) {
394       free(secTypes);
395       secType = rfbSecTypeTight;
396       if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType)))
397         return rfbSecTypeInvalid;
398       fprintf(stderr, "Enabling TightVNC protocol extensions\n");
399       return rfbSecTypeTight;
400     }
401   }
402 
403   /* Find first supported security type */
404   for (j = 0; j < (int)nSecTypes; j++) {
405     for (i = 0; i < nKnownSecTypes; i++) {
406       if (secTypes[j] == knownSecTypes[i]) {
407         secType = secTypes[j];
408         if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType))) {
409           free(secTypes);
410           return rfbSecTypeInvalid;
411         }
412         break;
413       }
414     }
415     if (secType != rfbSecTypeInvalid) break;
416   }
417 
418   free(secTypes);
419 
420   if (secType == rfbSecTypeInvalid)
421     fprintf(stderr, "Server did not offer supported security type\n");
422 
423   return (int)secType;
424 }
425 
426 
427 /*
428  * Setup tunneling (protocol 3.7t, 3.8t).
429  */
430 
431 static Bool
SetupTunneling(void)432 SetupTunneling(void)
433 {
434   rfbTunnelingCapsMsg caps;
435   CARD32 tunnelType;
436 
437   /* In protocols 3.7t/3.8t, the server informs us about
438      supported tunneling methods. Here we read this information. */
439 
440   if (!ReadFromRFBServer((char *)&caps, sz_rfbTunnelingCapsMsg))
441     return False;
442 
443   caps.nTunnelTypes = Swap32IfLE(caps.nTunnelTypes);
444 
445   if (caps.nTunnelTypes) {
446     if (!ReadCapabilityList(tunnelCaps, caps.nTunnelTypes))
447       return False;
448 
449     /* We cannot do tunneling anyway yet. */
450     tunnelType = Swap32IfLE(rfbNoTunneling);
451     if (!WriteExact(rfbsock, (char *)&tunnelType, sizeof(tunnelType)))
452       return False;
453   }
454 
455   return True;
456 }
457 
458 
459 /*
460  * Negotiate authentication scheme (protocol 3.7t, 3.8t)
461  */
462 
463 static Bool
PerformAuthenticationTight(void)464 PerformAuthenticationTight(void)
465 {
466   rfbAuthenticationCapsMsg caps;
467   CARD32 authScheme;
468   int i;
469 
470   /* In protocols 3.7t/3.8t, the server informs us about supported
471      authentication schemes. Here we read this information. */
472 
473   if (!ReadFromRFBServer((char *)&caps, sz_rfbAuthenticationCapsMsg))
474     return False;
475 
476   caps.nAuthTypes = Swap32IfLE(caps.nAuthTypes);
477 
478   /* Special case - empty capability list stands for no authentication. */
479   if (!caps.nAuthTypes)
480     return AuthenticateNone();
481 
482   if (!ReadCapabilityList(authCaps, caps.nAuthTypes))
483     return False;
484 
485   /* Try server's preferred authentication scheme. */
486   for (i = 0; i < CapsNumEnabled(authCaps); i++) {
487     authScheme = CapsGetByOrder(authCaps, i);
488     if (authScheme != rfbAuthVNC && authScheme != rfbAuthNone)
489       continue;                 /* unknown scheme - cannot use it */
490     authScheme = Swap32IfLE(authScheme);
491     if (!WriteExact(rfbsock, (char *)&authScheme, sizeof(authScheme)))
492       return False;
493     authScheme = Swap32IfLE(authScheme); /* convert it back */
494 
495     switch (authScheme) {
496     case rfbAuthNone:
497       return AuthenticateNone();
498     case rfbAuthVNC:
499       return AuthenticateVNC();
500     default:                      /* should never happen */
501       fprintf(stderr, "Internal error: Invalid authentication type\n");
502       return False;
503     }
504   }
505 
506   fprintf(stderr, "No suitable authentication schemes offered by server\n");
507   return False;
508 }
509 
510 
511 /*
512  * Null authentication.
513  */
514 
515 static Bool
AuthenticateNone(void)516 AuthenticateNone(void)
517 {
518   fprintf(stderr, "No authentication needed\n");
519 
520   if (protocolMinorVersion >= 8) {
521     if (!ReadAuthenticationResult())
522       return False;
523   }
524 
525   return True;
526 }
527 
528 
529 /*
530  * Standard VNC authentication.
531  */
532 
533 static Bool
AuthenticateVNC(void)534 AuthenticateVNC(void)
535 {
536   CARD32 authScheme;
537   CARD8 challenge[CHALLENGESIZE];
538   char *passwd;
539   char  buffer[64];
540   char* cstatus;
541   int   len;
542 
543   fprintf(stderr, "Performing standard VNC authentication\n");
544 
545   if (!ReadFromRFBServer((char *)challenge, CHALLENGESIZE))
546     return False;
547 
548   if (appData.passwordFile) {
549     passwd = vncDecryptPasswdFromFile(appData.passwordFile);
550     if (!passwd) {
551       fprintf(stderr, "Cannot read valid password from file \"%s\"\n",
552 	      appData.passwordFile);
553       return False;
554     }
555   } else if (appData.autoPass) {
556     passwd = buffer;
557     cstatus = fgets(buffer, sizeof buffer, stdin);
558     if (cstatus == NULL)
559        buffer[0] = '\0';
560     else
561     {
562        len = strlen(buffer);
563        if (len > 0 && buffer[len - 1] == '\n')
564 	  buffer[len - 1] = '\0';
565     }
566   } else if (appData.passwordDialog) {
567     passwd = DoPasswordDialog();
568   } else {
569     passwd = getpass("Password: ");
570   }
571 
572   if (!passwd) {
573     fprintf(stderr, "Reading password failed\n");
574     return False;
575   }
576   if (strlen(passwd) > 8) {
577     passwd[8] = '\0';
578   }
579 
580   vncEncryptBytes(challenge, passwd);
581 
582   /* Lose the password from memory */
583   memset(passwd, '\0', strlen(passwd));
584 
585   if (!WriteExact(rfbsock, (char *)challenge, CHALLENGESIZE))
586     return False;
587 
588   return ReadAuthenticationResult();
589 }
590 
591 /*
592  * Read and report the result of authentication.
593  */
594 
595 static Bool
ReadAuthenticationResult(void)596 ReadAuthenticationResult(void)
597 {
598   CARD32 authResult;
599 
600   if (!ReadFromRFBServer((char *)&authResult, 4))
601     return False;
602 
603   authResult = Swap32IfLE(authResult);
604 
605   switch (authResult) {
606   case rfbAuthOK:
607     fprintf(stderr, "Authentication successful\n");
608     break;
609   case rfbAuthFailed:
610     if (protocolMinorVersion >= 8) {
611       ReadConnFailedReason();
612     } else {
613       fprintf(stderr, "Authentication failure\n");
614     }
615     return False;
616   case rfbAuthTooMany:
617     fprintf(stderr, "Authentication failure, too many tries\n");
618     return False;
619   default:
620     fprintf(stderr, "Unknown result of authentication (%d)\n",
621 	    (int)authResult);
622     return False;
623   }
624 
625   return True;
626 }
627 
628 /*
629  * In protocols 3.7t/3.8t, the server informs us about supported
630  * protocol messages and encodings. Here we read this information.
631  */
632 
633 static Bool
ReadInteractionCaps(void)634 ReadInteractionCaps(void)
635 {
636   rfbInteractionCapsMsg intr_caps;
637 
638   /* Read the counts of list items following */
639   if (!ReadFromRFBServer((char *)&intr_caps, sz_rfbInteractionCapsMsg))
640     return False;
641   intr_caps.nServerMessageTypes = Swap16IfLE(intr_caps.nServerMessageTypes);
642   intr_caps.nClientMessageTypes = Swap16IfLE(intr_caps.nClientMessageTypes);
643   intr_caps.nEncodingTypes = Swap16IfLE(intr_caps.nEncodingTypes);
644 
645   /* Read the lists of server- and client-initiated messages */
646   return (ReadCapabilityList(serverMsgCaps, intr_caps.nServerMessageTypes) &&
647 	  ReadCapabilityList(clientMsgCaps, intr_caps.nClientMessageTypes) &&
648 	  ReadCapabilityList(encodingCaps, intr_caps.nEncodingTypes));
649 }
650 
651 
652 /*
653  * Read the list of rfbCapabilityInfo structures and enable corresponding
654  * capabilities in the specified container. The count argument specifies how
655  * many records to read from the socket.
656  */
657 
658 static Bool
ReadCapabilityList(CapsContainer * caps,int count)659 ReadCapabilityList(CapsContainer *caps, int count)
660 {
661   rfbCapabilityInfo msginfo;
662   int i;
663 
664   for (i = 0; i < count; i++) {
665     if (!ReadFromRFBServer((char *)&msginfo, sz_rfbCapabilityInfo))
666       return False;
667     msginfo.code = Swap32IfLE(msginfo.code);
668     CapsEnable(caps, &msginfo);
669   }
670 
671   return True;
672 }
673 
674 
675 /*
676  * SetFormatAndEncodings.
677  */
678 
679 Bool
SetFormatAndEncodings()680 SetFormatAndEncodings()
681 {
682   rfbSetPixelFormatMsg spf;
683   char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4];
684   rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf;
685   CARD32 *encs = (CARD32 *)(&buf[sz_rfbSetEncodingsMsg]);
686   int len = 0;
687   Bool requestCompressLevel = False;
688   Bool requestQualityLevel = False;
689   Bool requestLastRectEncoding = False;
690 
691   spf.type = rfbSetPixelFormat;
692   spf.format = myFormat;
693   spf.format.redMax = Swap16IfLE(spf.format.redMax);
694   spf.format.greenMax = Swap16IfLE(spf.format.greenMax);
695   spf.format.blueMax = Swap16IfLE(spf.format.blueMax);
696 
697   if (!WriteExact(rfbsock, (char *)&spf, sz_rfbSetPixelFormatMsg))
698     return False;
699 
700   se->type = rfbSetEncodings;
701   se->nEncodings = 0;
702 
703   if (appData.encodingsString) {
704     char *encStr = appData.encodingsString;
705     int encStrLen;
706     do {
707       char *nextEncStr = strchr(encStr, ' ');
708       if (nextEncStr) {
709 	encStrLen = nextEncStr - encStr;
710 	nextEncStr++;
711       } else {
712 	encStrLen = strlen(encStr);
713       }
714 
715       if (strncasecmp(encStr,"raw",encStrLen) == 0) {
716 	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw);
717       } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) {
718 	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect);
719       } else if (strncasecmp(encStr,"tight",encStrLen) == 0) {
720 	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight);
721 	requestLastRectEncoding = True;
722 	if (appData.compressLevel >= 0 && appData.compressLevel <= 9)
723 	  requestCompressLevel = True;
724 	if (appData.enableJPEG)
725 	  requestQualityLevel = True;
726       } else if (strncasecmp(encStr,"hextile",encStrLen) == 0) {
727 	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile);
728       } else if (strncasecmp(encStr,"zlib",encStrLen) == 0) {
729 	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib);
730 	if (appData.compressLevel >= 0 && appData.compressLevel <= 9)
731 	  requestCompressLevel = True;
732       } else if (strncasecmp(encStr,"corre",encStrLen) == 0) {
733 	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE);
734       } else if (strncasecmp(encStr,"rre",encStrLen) == 0) {
735 	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRRE);
736       } else {
737 	fprintf(stderr,"Unknown encoding '%.*s'\n",encStrLen,encStr);
738       }
739 
740       encStr = nextEncStr;
741     } while (encStr && se->nEncodings < MAX_ENCODINGS);
742 
743     if (se->nEncodings < MAX_ENCODINGS && requestCompressLevel) {
744       encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel +
745 					  rfbEncodingCompressLevel0);
746     }
747 
748     if (se->nEncodings < MAX_ENCODINGS && requestQualityLevel) {
749       if (appData.qualityLevel < 0 || appData.qualityLevel > 9)
750         appData.qualityLevel = 5;
751       encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel +
752 					  rfbEncodingQualityLevel0);
753     }
754 
755     if (appData.useRemoteCursor) {
756       if (se->nEncodings < MAX_ENCODINGS)
757 	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor);
758       if (se->nEncodings < MAX_ENCODINGS)
759 	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor);
760       if (se->nEncodings < MAX_ENCODINGS)
761 	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos);
762     }
763 
764     if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) {
765       encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
766     }
767   }
768   else {
769     if (SameMachine(rfbsock)) {
770       if (!tunnelSpecified) {
771 	fprintf(stderr,"Same machine: preferring raw encoding\n");
772 	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw);
773       } else {
774 	fprintf(stderr,"Tunneling active: preferring tight encoding\n");
775       }
776     }
777 
778     encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect);
779     encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight);
780     encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile);
781     encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib);
782     encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE);
783     encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRRE);
784 
785     if (appData.compressLevel >= 0 && appData.compressLevel <= 9) {
786       encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel +
787 					  rfbEncodingCompressLevel0);
788     } else if (!tunnelSpecified) {
789       /* If -tunnel option was provided, we assume that server machine is
790 	 not in the local network so we use default compression level for
791 	 tight encoding instead of fast compression. Thus we are
792 	 requesting level 1 compression only if tunneling is not used. */
793       encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCompressLevel1);
794     }
795 
796     if (appData.enableJPEG) {
797       if (appData.qualityLevel < 0 || appData.qualityLevel > 9)
798 	appData.qualityLevel = 5;
799       encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel +
800 					  rfbEncodingQualityLevel0);
801     }
802 
803     if (appData.useRemoteCursor) {
804       encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor);
805       encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor);
806       encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos);
807     }
808 
809     encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
810   }
811 
812   len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
813 
814   se->nEncodings = Swap16IfLE(se->nEncodings);
815 
816   if (!WriteExact(rfbsock, buf, len)) return False;
817 
818   return True;
819 }
820 
821 
822 /*
823  * SendIncrementalFramebufferUpdateRequest.
824  */
825 
826 Bool
SendIncrementalFramebufferUpdateRequest()827 SendIncrementalFramebufferUpdateRequest()
828 {
829   return SendFramebufferUpdateRequest(0, 0, si.framebufferWidth,
830 				      si.framebufferHeight, True);
831 }
832 
833 
834 /*
835  * SendFramebufferUpdateRequest.
836  */
837 
838 Bool
SendFramebufferUpdateRequest(int x,int y,int w,int h,Bool incremental)839 SendFramebufferUpdateRequest(int x, int y, int w, int h, Bool incremental)
840 {
841   rfbFramebufferUpdateRequestMsg fur;
842 
843   fur.type = rfbFramebufferUpdateRequest;
844   fur.incremental = incremental ? 1 : 0;
845   fur.x = Swap16IfLE(x);
846   fur.y = Swap16IfLE(y);
847   fur.w = Swap16IfLE(w);
848   fur.h = Swap16IfLE(h);
849 
850   if (!WriteExact(rfbsock, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg))
851     return False;
852 
853   return True;
854 }
855 
856 
857 /*
858  * SendPointerEvent.
859  */
860 
861 Bool
SendPointerEvent(int x,int y,int buttonMask)862 SendPointerEvent(int x, int y, int buttonMask)
863 {
864   rfbPointerEventMsg pe;
865 
866   pe.type = rfbPointerEvent;
867   pe.buttonMask = buttonMask;
868   if (x < 0) x = 0;
869   if (y < 0) y = 0;
870 
871   if (!appData.useX11Cursor)
872     SoftCursorMove(x, y);
873 
874   pe.x = Swap16IfLE(x);
875   pe.y = Swap16IfLE(y);
876   return WriteExact(rfbsock, (char *)&pe, sz_rfbPointerEventMsg);
877 }
878 
879 
880 /*
881  * SendKeyEvent.
882  */
883 
884 Bool
SendKeyEvent(CARD32 key,Bool down)885 SendKeyEvent(CARD32 key, Bool down)
886 {
887   rfbKeyEventMsg ke;
888 
889   ke.type = rfbKeyEvent;
890   ke.down = down ? 1 : 0;
891   ke.key = Swap32IfLE(key);
892   return WriteExact(rfbsock, (char *)&ke, sz_rfbKeyEventMsg);
893 }
894 
895 
896 /*
897  * SendClientCutText.
898  */
899 
900 Bool
SendClientCutText(char * str,int len)901 SendClientCutText(char *str, int len)
902 {
903   rfbClientCutTextMsg cct;
904 
905   if (serverCutText)
906     free(serverCutText);
907   serverCutText = NULL;
908 
909   cct.type = rfbClientCutText;
910   cct.length = Swap32IfLE(len);
911   return  (WriteExact(rfbsock, (char *)&cct, sz_rfbClientCutTextMsg) &&
912 	   WriteExact(rfbsock, str, len));
913 }
914 
915 
916 /*
917  * HandleRFBServerMessage.
918  */
919 
920 Bool
HandleRFBServerMessage()921 HandleRFBServerMessage()
922 {
923   rfbServerToClientMsg msg;
924 
925   if (!ReadFromRFBServer((char *)&msg, 1))
926     return False;
927 
928   switch (msg.type) {
929 
930   case rfbSetColourMapEntries:
931   {
932     int i;
933     CARD16 rgb[3];
934     XColor xc;
935 
936     if (!ReadFromRFBServer(((char *)&msg) + 1,
937 			   sz_rfbSetColourMapEntriesMsg - 1))
938       return False;
939 
940     msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour);
941     msg.scme.nColours = Swap16IfLE(msg.scme.nColours);
942 
943     for (i = 0; i < msg.scme.nColours; i++) {
944       if (!ReadFromRFBServer((char *)rgb, 6))
945 	return False;
946       xc.pixel = msg.scme.firstColour + i;
947       xc.red = Swap16IfLE(rgb[0]);
948       xc.green = Swap16IfLE(rgb[1]);
949       xc.blue = Swap16IfLE(rgb[2]);
950       xc.flags = DoRed|DoGreen|DoBlue;
951       XStoreColor(dpy, cmap, &xc);
952     }
953 
954     break;
955   }
956 
957   case rfbFramebufferUpdate:
958   {
959     rfbFramebufferUpdateRectHeader rect;
960     int linesToRead;
961     int bytesPerLine;
962     int i;
963     int usecs;
964 
965     if (!ReadFromRFBServer(((char *)&msg.fu) + 1,
966 			   sz_rfbFramebufferUpdateMsg - 1))
967       return False;
968 
969     msg.fu.nRects = Swap16IfLE(msg.fu.nRects);
970 
971     for (i = 0; i < msg.fu.nRects; i++) {
972       if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader))
973 	return False;
974 
975       rect.encoding = Swap32IfLE(rect.encoding);
976       if (rect.encoding == rfbEncodingLastRect)
977 	break;
978 
979       rect.r.x = Swap16IfLE(rect.r.x);
980       rect.r.y = Swap16IfLE(rect.r.y);
981       rect.r.w = Swap16IfLE(rect.r.w);
982       rect.r.h = Swap16IfLE(rect.r.h);
983 
984       if (rect.encoding == rfbEncodingXCursor ||
985 	  rect.encoding == rfbEncodingRichCursor) {
986 	if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h,
987 			      rect.encoding)) {
988 	  return False;
989 	}
990 	continue;
991       }
992 
993       if (rect.encoding == rfbEncodingPointerPos) {
994 	if (!HandleCursorPos(rect.r.x, rect.r.y)) {
995 	  return False;
996 	}
997 	continue;
998       }
999 
1000       if ((rect.r.x + rect.r.w > si.framebufferWidth) ||
1001 	  (rect.r.y + rect.r.h > si.framebufferHeight))
1002 	{
1003 	  fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n",
1004 		  rect.r.w, rect.r.h, rect.r.x, rect.r.y);
1005 	  return False;
1006 	}
1007 
1008       if (rect.r.h * rect.r.w == 0) {
1009 	fprintf(stderr,"Zero size rect - ignoring\n");
1010 	continue;
1011       }
1012 
1013       /* If RichCursor encoding is used, we should prevent collisions
1014 	 between framebuffer updates and cursor drawing operations. */
1015       SoftCursorLockArea(rect.r.x, rect.r.y, rect.r.w, rect.r.h);
1016 
1017       switch (rect.encoding) {
1018 
1019       case rfbEncodingRaw:
1020 
1021 	bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8;
1022 	linesToRead = BUFFER_SIZE / bytesPerLine;
1023 
1024 	while (rect.r.h > 0) {
1025 	  if (linesToRead > rect.r.h)
1026 	    linesToRead = rect.r.h;
1027 
1028 	  if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead))
1029 	    return False;
1030 
1031 	  CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w,
1032 			   linesToRead);
1033 
1034 	  rect.r.h -= linesToRead;
1035 	  rect.r.y += linesToRead;
1036 
1037 	}
1038 	break;
1039 
1040       case rfbEncodingCopyRect:
1041       {
1042 	rfbCopyRect cr;
1043 
1044 	if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect))
1045 	  return False;
1046 
1047 	cr.srcX = Swap16IfLE(cr.srcX);
1048 	cr.srcY = Swap16IfLE(cr.srcY);
1049 
1050 	/* If RichCursor encoding is used, we should extend our
1051 	   "cursor lock area" (previously set to destination
1052 	   rectangle) to the source rectangle as well. */
1053 	SoftCursorLockArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h);
1054 
1055 	if (appData.copyRectDelay != 0) {
1056 	  XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY,
1057 			 rect.r.w, rect.r.h);
1058 	  XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y,
1059 			 rect.r.w, rect.r.h);
1060 	  XSync(dpy,False);
1061 	  usleep(appData.copyRectDelay * 1000);
1062 	  XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y,
1063 			 rect.r.w, rect.r.h);
1064 	  XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY,
1065 			 rect.r.w, rect.r.h);
1066 	}
1067 
1068 	XCopyArea(dpy, desktopWin, desktopWin, gc, cr.srcX, cr.srcY,
1069 		  rect.r.w, rect.r.h, rect.r.x, rect.r.y);
1070 
1071 	break;
1072       }
1073 
1074       case rfbEncodingRRE:
1075       {
1076 	switch (myFormat.bitsPerPixel) {
1077 	case 8:
1078 	  if (!HandleRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1079 	    return False;
1080 	  break;
1081 	case 16:
1082 	  if (!HandleRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1083 	    return False;
1084 	  break;
1085 	case 32:
1086 	  if (!HandleRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1087 	    return False;
1088 	  break;
1089 	}
1090 	break;
1091       }
1092 
1093       case rfbEncodingCoRRE:
1094       {
1095 	switch (myFormat.bitsPerPixel) {
1096 	case 8:
1097 	  if (!HandleCoRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1098 	    return False;
1099 	  break;
1100 	case 16:
1101 	  if (!HandleCoRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1102 	    return False;
1103 	  break;
1104 	case 32:
1105 	  if (!HandleCoRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1106 	    return False;
1107 	  break;
1108 	}
1109 	break;
1110       }
1111 
1112       case rfbEncodingHextile:
1113       {
1114 	switch (myFormat.bitsPerPixel) {
1115 	case 8:
1116 	  if (!HandleHextile8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1117 	    return False;
1118 	  break;
1119 	case 16:
1120 	  if (!HandleHextile16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1121 	    return False;
1122 	  break;
1123 	case 32:
1124 	  if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1125 	    return False;
1126 	  break;
1127 	}
1128 	break;
1129       }
1130 
1131       case rfbEncodingZlib:
1132       {
1133 	switch (myFormat.bitsPerPixel) {
1134 	case 8:
1135 	  if (!HandleZlib8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1136 	    return False;
1137 	  break;
1138 	case 16:
1139 	  if (!HandleZlib16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1140 	    return False;
1141 	  break;
1142 	case 32:
1143 	  if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1144 	    return False;
1145 	  break;
1146 	}
1147 	break;
1148      }
1149 
1150       case rfbEncodingTight:
1151       {
1152 	switch (myFormat.bitsPerPixel) {
1153 	case 8:
1154 	  if (!HandleTight8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1155 	    return False;
1156 	  break;
1157 	case 16:
1158 	  if (!HandleTight16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1159 	    return False;
1160 	  break;
1161 	case 32:
1162 	  if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1163 	    return False;
1164 	  break;
1165 	}
1166 	break;
1167       }
1168 
1169       default:
1170 	fprintf(stderr,"Unknown rect encoding %d\n",
1171 		(int)rect.encoding);
1172 	return False;
1173       }
1174 
1175       /* Now we may discard "soft cursor locks". */
1176       SoftCursorUnlockScreen();
1177     }
1178 
1179 #ifdef MITSHM
1180     /* if using shared memory PutImage, make sure that the X server has
1181        updated its framebuffer before we reuse the shared memory.  This is
1182        mainly to avoid copyrect using invalid screen contents - not sure
1183        if we'd need it otherwise. */
1184 
1185     if (appData.useShm)
1186       XSync(dpy, False);
1187 #endif
1188 
1189     if (!SendIncrementalFramebufferUpdateRequest())
1190       return False;
1191 
1192     break;
1193   }
1194 
1195   case rfbBell:
1196   {
1197     Window toplevelWin;
1198 
1199     XBell(dpy, 0);
1200 
1201     if (appData.raiseOnBeep) {
1202       toplevelWin = XtWindow(toplevel);
1203       XMapRaised(dpy, toplevelWin);
1204     }
1205 
1206     break;
1207   }
1208 
1209   case rfbServerCutText:
1210   {
1211     if (!ReadFromRFBServer(((char *)&msg) + 1,
1212 			   sz_rfbServerCutTextMsg - 1))
1213       return False;
1214 
1215     msg.sct.length = Swap32IfLE(msg.sct.length);
1216 
1217     if (serverCutText)
1218       free(serverCutText);
1219 
1220     serverCutText = malloc(msg.sct.length+1);
1221 
1222     if (!ReadFromRFBServer(serverCutText, msg.sct.length))
1223       return False;
1224 
1225     serverCutText[msg.sct.length] = 0;
1226 
1227     newServerCutText = True;
1228 
1229     break;
1230   }
1231 
1232   default:
1233     fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type);
1234     return False;
1235   }
1236 
1237   return True;
1238 }
1239 
1240 
1241 #define GET_PIXEL8(pix, ptr) ((pix) = *(ptr)++)
1242 
1243 #define GET_PIXEL16(pix, ptr) (((CARD8*)&(pix))[0] = *(ptr)++, \
1244 			       ((CARD8*)&(pix))[1] = *(ptr)++)
1245 
1246 #define GET_PIXEL32(pix, ptr) (((CARD8*)&(pix))[0] = *(ptr)++, \
1247 			       ((CARD8*)&(pix))[1] = *(ptr)++, \
1248 			       ((CARD8*)&(pix))[2] = *(ptr)++, \
1249 			       ((CARD8*)&(pix))[3] = *(ptr)++)
1250 
1251 /* CONCAT2 concatenates its two arguments.  CONCAT2E does the same but also
1252    expands its arguments if they are macros */
1253 
1254 #define CONCAT2(a,b) a##b
1255 #define CONCAT2E(a,b) CONCAT2(a,b)
1256 
1257 #define BPP 8
1258 #include "rre.c"
1259 #include "corre.c"
1260 #include "hextile.c"
1261 #include "zlib.c"
1262 #include "tight.c"
1263 #undef BPP
1264 #define BPP 16
1265 #include "rre.c"
1266 #include "corre.c"
1267 #include "hextile.c"
1268 #include "zlib.c"
1269 #include "tight.c"
1270 #undef BPP
1271 #define BPP 32
1272 #include "rre.c"
1273 #include "corre.c"
1274 #include "hextile.c"
1275 #include "zlib.c"
1276 #include "tight.c"
1277 #undef BPP
1278 
1279 /*
1280  * Read the string describing the reason for a connection failure.
1281  */
1282 
1283 static void
ReadConnFailedReason(void)1284 ReadConnFailedReason(void)
1285 {
1286   CARD32 reasonLen;
1287   char *reason = NULL;
1288 
1289   if (ReadFromRFBServer((char *)&reasonLen, sizeof(reasonLen))) {
1290     reasonLen = Swap32IfLE(reasonLen);
1291     if ((reason = malloc(reasonLen)) != NULL &&
1292         ReadFromRFBServer(reason, reasonLen)) {
1293       fprintf(stderr,"%.*s\n", (int)reasonLen, reason);
1294       free(reason);
1295       return;
1296     }
1297   }
1298 
1299   fprintf(stderr, "VNC connection failed\n");
1300 
1301   if (reason != NULL)
1302     free(reason);
1303 }
1304 
1305 /*
1306  * PrintPixelFormat.
1307  */
1308 
1309 void
PrintPixelFormat(format)1310 PrintPixelFormat(format)
1311     rfbPixelFormat *format;
1312 {
1313   if (format->bitsPerPixel == 1) {
1314     fprintf(stderr,"  Single bit per pixel.\n");
1315     fprintf(stderr,
1316 	    "  %s significant bit in each byte is leftmost on the screen.\n",
1317 	    (format->bigEndian ? "Most" : "Least"));
1318   } else {
1319     fprintf(stderr,"  %d bits per pixel.\n",format->bitsPerPixel);
1320     if (format->bitsPerPixel != 8) {
1321       fprintf(stderr,"  %s significant byte first in each pixel.\n",
1322 	      (format->bigEndian ? "Most" : "Least"));
1323     }
1324     if (format->trueColour) {
1325       fprintf(stderr,"  True colour: max red %d green %d blue %d",
1326 	      format->redMax, format->greenMax, format->blueMax);
1327       fprintf(stderr,", shift red %d green %d blue %d\n",
1328 	      format->redShift, format->greenShift, format->blueShift);
1329     } else {
1330       fprintf(stderr,"  Colour map (not true colour).\n");
1331     }
1332   }
1333 }
1334 
1335 /*
1336  * Read an integer value encoded in 1..3 bytes. This function is used
1337  * by the Tight decoder.
1338  */
1339 
1340 static long
ReadCompactLen(void)1341 ReadCompactLen (void)
1342 {
1343   long len;
1344   CARD8 b;
1345 
1346   if (!ReadFromRFBServer((char *)&b, 1))
1347     return -1;
1348   len = (int)b & 0x7F;
1349   if (b & 0x80) {
1350     if (!ReadFromRFBServer((char *)&b, 1))
1351       return -1;
1352     len |= ((int)b & 0x7F) << 7;
1353     if (b & 0x80) {
1354       if (!ReadFromRFBServer((char *)&b, 1))
1355 	return -1;
1356       len |= ((int)b & 0xFF) << 14;
1357     }
1358   }
1359   return len;
1360 }
1361 
1362 
1363 /*
1364  * JPEG source manager functions for JPEG decompression in Tight decoder.
1365  */
1366 
1367 static struct jpeg_source_mgr jpegSrcManager;
1368 static JOCTET *jpegBufferPtr;
1369 static size_t jpegBufferLen;
1370 
1371 static void
JpegInitSource(j_decompress_ptr cinfo)1372 JpegInitSource(j_decompress_ptr cinfo)
1373 {
1374   jpegError = False;
1375 }
1376 
1377 static boolean
JpegFillInputBuffer(j_decompress_ptr cinfo)1378 JpegFillInputBuffer(j_decompress_ptr cinfo)
1379 {
1380   jpegError = True;
1381   jpegSrcManager.bytes_in_buffer = jpegBufferLen;
1382   jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr;
1383 
1384   return TRUE;
1385 }
1386 
1387 static void
JpegSkipInputData(j_decompress_ptr cinfo,long num_bytes)1388 JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes)
1389 {
1390   if (num_bytes < 0 || num_bytes > jpegSrcManager.bytes_in_buffer) {
1391     jpegError = True;
1392     jpegSrcManager.bytes_in_buffer = jpegBufferLen;
1393     jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr;
1394   } else {
1395     jpegSrcManager.next_input_byte += (size_t) num_bytes;
1396     jpegSrcManager.bytes_in_buffer -= (size_t) num_bytes;
1397   }
1398 }
1399 
1400 static void
JpegTermSource(j_decompress_ptr cinfo)1401 JpegTermSource(j_decompress_ptr cinfo)
1402 {
1403   /* No work necessary here. */
1404 }
1405 
1406 static void
JpegSetSrcManager(j_decompress_ptr cinfo,CARD8 * compressedData,int compressedLen)1407 JpegSetSrcManager(j_decompress_ptr cinfo, CARD8 *compressedData,
1408 		  int compressedLen)
1409 {
1410   jpegBufferPtr = (JOCTET *)compressedData;
1411   jpegBufferLen = (size_t)compressedLen;
1412 
1413   jpegSrcManager.init_source = JpegInitSource;
1414   jpegSrcManager.fill_input_buffer = JpegFillInputBuffer;
1415   jpegSrcManager.skip_input_data = JpegSkipInputData;
1416   jpegSrcManager.resync_to_restart = jpeg_resync_to_restart;
1417   jpegSrcManager.term_source = JpegTermSource;
1418   jpegSrcManager.next_input_byte = jpegBufferPtr;
1419   jpegSrcManager.bytes_in_buffer = jpegBufferLen;
1420 
1421   cinfo->src = &jpegSrcManager;
1422 }
1423 
1424