+++ /dev/null
-/*
- * Copyright (C) 2000-2002 Constantin Kaplinsky. All Rights Reserved.
- * Copyright (C) 2000 Tridia Corporation. All Rights Reserved.
- * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- * USA.
- */
-
-/*
- * rfbproto.c - functions to deal with client side of RFB protocol.
- */
-
-#ifdef __STRICT_ANSI__
-#define _BSD_SOURCE
-#define _POSIX_SOURCE
-#endif
-#ifndef WIN32
-#include <unistd.h>
-#else
-#define strncasecmp _strnicmp
-#endif
-#include <errno.h>
-#ifndef WIN32
-#include <pwd.h>
-#endif
-#include <rfb/rfbclient.h>
-#ifdef LIBVNCSERVER_HAVE_LIBZ
-#include <zlib.h>
-#ifdef __CHECKER__
-#undef Z_NULL
-#define Z_NULL NULL
-#endif
-#endif
-#ifdef LIBVNCSERVER_HAVE_LIBJPEG
-#include <jpeglib.h>
-#endif
-#include <stdarg.h>
-#include <time.h>
-
-#include "minilzo.h"
-
-/*
- * rfbClientLog prints a time-stamped message to the log file (stderr).
- */
-
-rfbBool rfbEnableClientLogging=TRUE;
-
-static void
-rfbDefaultClientLog(const char *format, ...)
-{
- va_list args;
- char buf[256];
- time_t log_clock;
-
- if(!rfbEnableClientLogging)
- return;
-
- va_start(args, format);
-
- time(&log_clock);
- strftime(buf, 255, "%d/%m/%Y %X ", localtime(&log_clock));
- fprintf(stderr,buf);
-
- vfprintf(stderr, format, args);
- fflush(stderr);
-
- va_end(args);
-}
-
-rfbClientLogProc rfbClientLog=rfbDefaultClientLog;
-rfbClientLogProc rfbClientErr=rfbDefaultClientLog;
-
-/* extensions */
-
-rfbClientProtocolExtension* rfbClientExtensions = NULL;
-
-void rfbClientRegisterExtension(rfbClientProtocolExtension* e)
-{
- e->next = rfbClientExtensions;
- rfbClientExtensions = e;
-}
-
-/* client data */
-
-void rfbClientSetClientData(rfbClient* client, void* tag, void* data)
-{
- rfbClientData* clientData = client->clientData;
-
- while(clientData && clientData->tag != tag)
- clientData = clientData->next;
- if(clientData == NULL) {
- clientData = calloc(sizeof(rfbClientData), 1);
- clientData->next = client->clientData;
- client->clientData = clientData;
- clientData->tag = tag;
- }
-
- clientData->data = data;
-}
-
-void* rfbClientGetClientData(rfbClient* client, void* tag)
-{
- rfbClientData* clientData = client->clientData;
-
- while(clientData) {
- if(clientData->tag == tag)
- return clientData->data;
- clientData = clientData->next;
- }
-
- return NULL;
-}
-
-/* messages */
-
-static void FillRectangle(rfbClient* client, int x, int y, int w, int h, uint32_t colour) {
- int i,j;
-
-#define FILL_RECT(BPP) \
- for(j=y*client->width;j<(y+h)*client->width;j+=client->width) \
- for(i=x;i<x+w;i++) \
- ((uint##BPP##_t*)client->frameBuffer)[j+i]=colour;
-
- switch(client->format.bitsPerPixel) {
- case 8: FILL_RECT(8); break;
- case 16: FILL_RECT(16); break;
- case 32: FILL_RECT(32); break;
- default:
- rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel);
- }
-}
-
-static void CopyRectangle(rfbClient* client, uint8_t* buffer, int x, int y, int w, int h) {
- int j;
-
-#define COPY_RECT(BPP) \
- { \
- int rs = w * BPP / 8, rs2 = client->width * BPP / 8; \
- for (j = ((x * (BPP / 8)) + (y * rs2)); j < (y + h) * rs2; j += rs2) { \
- memcpy(client->frameBuffer + j, buffer, rs); \
- buffer += rs; \
- } \
- }
-
- switch(client->format.bitsPerPixel) {
- case 8: COPY_RECT(8); break;
- case 16: COPY_RECT(16); break;
- case 32: COPY_RECT(32); break;
- default:
- rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel);
- }
-}
-
-/* TODO: test */
-static void CopyRectangleFromRectangle(rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y) {
- int i,j;
-
-#define COPY_RECT_FROM_RECT(BPP) \
- { \
- uint##BPP##_t* _buffer=((uint##BPP##_t*)client->frameBuffer)+(src_y-dest_y)*client->width+src_x-dest_x; \
- if (dest_y < src_y) { \
- for(j = dest_y*client->width; j < (dest_y+h)*client->width; j += client->width) { \
- if (dest_x < src_x) { \
- for(i = dest_x; i < dest_x+w; i++) { \
- ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
- } \
- } else { \
- for(i = dest_x+w-1; i >= dest_x; i--) { \
- ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
- } \
- } \
- } \
- } else { \
- for(j = (dest_y+h-1)*client->width; j >= dest_y*client->width; j-=client->width) { \
- if (dest_x < src_x) { \
- for(i = dest_x; i < dest_x+w; i++) { \
- ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
- } \
- } else { \
- for(i = dest_x+w-1; i >= dest_x; i--) { \
- ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
- } \
- } \
- } \
- } \
- }
-
- switch(client->format.bitsPerPixel) {
- case 8: COPY_RECT_FROM_RECT(8); break;
- case 16: COPY_RECT_FROM_RECT(16); break;
- case 32: COPY_RECT_FROM_RECT(32); break;
- default:
- rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel);
- }
-}
-
-static rfbBool HandleRRE8(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleRRE16(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleRRE32(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleCoRRE8(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleCoRRE16(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleCoRRE32(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleHextile8(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleHextile16(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleHextile32(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleUltra8(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleUltra16(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleUltra32(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleUltraZip8(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleUltraZip16(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleUltraZip32(rfbClient* client, int rx, int ry, int rw, int rh);
-#ifdef LIBVNCSERVER_HAVE_LIBZ
-static rfbBool HandleZlib8(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleZlib16(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleZlib32(rfbClient* client, int rx, int ry, int rw, int rh);
-#ifdef LIBVNCSERVER_HAVE_LIBJPEG
-static rfbBool HandleTight8(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleTight16(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleTight32(rfbClient* client, int rx, int ry, int rw, int rh);
-
-static long ReadCompactLen (rfbClient* client);
-
-static void JpegInitSource(j_decompress_ptr cinfo);
-static boolean JpegFillInputBuffer(j_decompress_ptr cinfo);
-static void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes);
-static void JpegTermSource(j_decompress_ptr cinfo);
-static void JpegSetSrcManager(j_decompress_ptr cinfo, uint8_t *compressedData,
- int compressedLen);
-#endif
-static rfbBool HandleZRLE8(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleZRLE15(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleZRLE16(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleZRLE24(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleZRLE24Up(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleZRLE24Down(rfbClient* client, int rx, int ry, int rw, int rh);
-static rfbBool HandleZRLE32(rfbClient* client, int rx, int ry, int rw, int rh);
-#endif
-
-/*
- * Server Capability Functions
- */
-rfbBool
-SupportsClient2Server(rfbClient* client, int messageType)
-{
- return (client->supportedMessages.client2server[((messageType & 0xFF)/8)] & (1<<(messageType % 8)) ? TRUE : FALSE);
-}
-
-rfbBool
-SupportsServer2Client(rfbClient* client, int messageType)
-{
- return (client->supportedMessages.server2client[((messageType & 0xFF)/8)] & (1<<(messageType % 8)) ? TRUE : FALSE);
-}
-
-void
-SetClient2Server(rfbClient* client, int messageType)
-{
- client->supportedMessages.client2server[((messageType & 0xFF)/8)] |= (1<<(messageType % 8));
-}
-
-void
-SetServer2Client(rfbClient* client, int messageType)
-{
- client->supportedMessages.server2client[((messageType & 0xFF)/8)] |= (1<<(messageType % 8));
-}
-
-void
-ClearClient2Server(rfbClient* client, int messageType)
-{
- client->supportedMessages.client2server[((messageType & 0xFF)/8)] &= (!(1<<(messageType % 8)));
-}
-
-void
-ClearServer2Client(rfbClient* client, int messageType)
-{
- client->supportedMessages.server2client[((messageType & 0xFF)/8)] &= (!(1<<(messageType % 8)));
-}
-
-
-void
-DefaultSupportedMessages(rfbClient* client)
-{
- memset((char *)&client->supportedMessages,0,sizeof(client->supportedMessages));
-
- /* Default client supported messages (universal RFB 3.3 protocol) */
- SetClient2Server(client, rfbSetPixelFormat);
- /* SetClient2Server(client, rfbFixColourMapEntries); Not currently supported */
- SetClient2Server(client, rfbSetEncodings);
- SetClient2Server(client, rfbFramebufferUpdateRequest);
- SetClient2Server(client, rfbKeyEvent);
- SetClient2Server(client, rfbPointerEvent);
- SetClient2Server(client, rfbClientCutText);
- /* technically, we only care what we can *send* to the server
- * but, we set Server2Client Just in case it ever becomes useful
- */
- SetServer2Client(client, rfbFramebufferUpdate);
- SetServer2Client(client, rfbSetColourMapEntries);
- SetServer2Client(client, rfbBell);
- SetServer2Client(client, rfbServerCutText);
-}
-
-void
-DefaultSupportedMessagesUltraVNC(rfbClient* client)
-{
- DefaultSupportedMessages(client);
- SetClient2Server(client, rfbFileTransfer);
- SetClient2Server(client, rfbSetScale);
- SetClient2Server(client, rfbSetServerInput);
- SetClient2Server(client, rfbSetSW);
- SetClient2Server(client, rfbTextChat);
- SetClient2Server(client, rfbPalmVNCSetScaleFactor);
- /* technically, we only care what we can *send* to the server */
- SetServer2Client(client, rfbResizeFrameBuffer);
- SetServer2Client(client, rfbPalmVNCReSizeFrameBuffer);
- SetServer2Client(client, rfbFileTransfer);
- SetServer2Client(client, rfbTextChat);
-}
-
-
-void
-DefaultSupportedMessagesTightVNC(rfbClient* client)
-{
- DefaultSupportedMessages(client);
- SetClient2Server(client, rfbFileTransfer);
- SetClient2Server(client, rfbSetServerInput);
- SetClient2Server(client, rfbSetSW);
- /* SetClient2Server(client, rfbTextChat); */
- /* technically, we only care what we can *send* to the server */
- SetServer2Client(client, rfbFileTransfer);
- SetServer2Client(client, rfbTextChat);
-}
-
-/*
- * ConnectToRFBServer.
- */
-
-rfbBool
-ConnectToRFBServer(rfbClient* client,const char *hostname, int port)
-{
- unsigned int host;
-
- if (client->serverPort==-1) {
- /* serverHost is a file recorded by vncrec. */
- const char* magic="vncLog0.0";
- char buffer[10];
- rfbVNCRec* rec = (rfbVNCRec*)malloc(sizeof(rfbVNCRec));
- client->vncRec = rec;
-
- rec->file = fopen(client->serverHost,"rb");
- rec->tv.tv_sec = 0;
- rec->readTimestamp = FALSE;
- rec->doNotSleep = FALSE;
-
- if (!rec->file) {
- rfbClientLog("Could not open %s.\n",client->serverHost);
- return FALSE;
- }
- setbuf(rec->file,NULL);
- fread(buffer,1,strlen(magic),rec->file);
- if (strncmp(buffer,magic,strlen(magic))) {
- rfbClientLog("File %s was not recorded by vncrec.\n",client->serverHost);
- fclose(rec->file);
- return FALSE;
- }
- client->sock = 0;
- return TRUE;
- }
-
- if (!StringToIPAddr(hostname, &host)) {
- rfbClientLog("Couldn't convert '%s' to host address\n", hostname);
- return FALSE;
- }
-
- client->sock = ConnectClientToTcpAddr(host, port);
-
- if (client->sock < 0) {
- rfbClientLog("Unable to connect to VNC server\n");
- return FALSE;
- }
-
- return SetNonBlocking(client->sock);
-}
-
-extern void rfbClientEncryptBytes(unsigned char* bytes, char* passwd);
-
-rfbBool
-rfbHandleAuthResult(rfbClient* client)
-{
- uint32_t authResult=0, reasonLen=0;
- char *reason=NULL;
-
- if (!ReadFromRFBServer(client, (char *)&authResult, 4)) return FALSE;
-
- authResult = rfbClientSwap32IfLE(authResult);
-
- switch (authResult) {
- case rfbVncAuthOK:
- rfbClientLog("VNC authentication succeeded\n");
- return TRUE;
- break;
- case rfbVncAuthFailed:
- if (client->major==3 && client->minor>7)
- {
- /* we have an error following */
- if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
- reasonLen = rfbClientSwap32IfLE(reasonLen);
- reason = malloc(reasonLen+1);
- if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
- reason[reasonLen]=0;
- rfbClientLog("VNC connection failed: %s\n",reason);
- free(reason);
- return FALSE;
- }
- rfbClientLog("VNC authentication failed\n");
- return FALSE;
- case rfbVncAuthTooMany:
- rfbClientLog("VNC authentication failed - too many tries\n");
- return FALSE;
- }
-
- rfbClientLog("Unknown VNC authentication result: %d\n",
- (int)authResult);
- return FALSE;
-}
-
-
-/*
- * InitialiseRFBConnection.
- */
-
-rfbBool
-InitialiseRFBConnection(rfbClient* client)
-{
- rfbProtocolVersionMsg pv;
- int major,minor;
- uint32_t authScheme, reasonLen;
- char *reason;
- uint8_t challenge[CHALLENGESIZE];
- char *passwd=NULL;
- int i;
- rfbClientInitMsg ci;
-
- /* if the connection is immediately closed, don't report anything, so
- that pmw's monitor can make test connections */
-
- if (client->listenSpecified)
- errorMessageOnReadFailure = FALSE;
-
- if (!ReadFromRFBServer(client, pv, sz_rfbProtocolVersionMsg)) return FALSE;
- pv[sz_rfbProtocolVersionMsg]=0;
-
- errorMessageOnReadFailure = TRUE;
-
- pv[sz_rfbProtocolVersionMsg] = 0;
-
- if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) {
- rfbClientLog("Not a valid VNC server (%s)\n",pv);
- return FALSE;
- }
-
-
- DefaultSupportedMessages(client);
- client->major = major;
- client->minor = minor;
-
- /* fall back to viewer supported version */
- if ((major==rfbProtocolMajorVersion) && (minor>rfbProtocolMinorVersion))
- client->minor = rfbProtocolMinorVersion;
-
- /* UltraVNC uses minor codes 4 and 6 for the server */
- if (major==3 && (minor==4 || minor==6)) {
- rfbClientLog("UltraVNC server detected, enabling UltraVNC specific messages\n",pv);
- DefaultSupportedMessagesUltraVNC(client);
- }
-
- /* TightVNC uses minor codes 5 for the server */
- if (major==3 && minor==5) {
- rfbClientLog("TightVNC server detected, enabling TightVNC specific messages\n",pv);
- DefaultSupportedMessagesTightVNC(client);
- }
-
- /* we do not support > RFB3.8 */
- if (major==3 && minor>8)
- client->minor=8;
-
- rfbClientLog("VNC server supports protocol version %d.%d (viewer %d.%d)\n",
- major, minor, rfbProtocolMajorVersion, rfbProtocolMinorVersion);
-
- sprintf(pv,rfbProtocolVersionFormat,client->major,client->minor);
-
- if (!WriteToRFBServer(client, pv, sz_rfbProtocolVersionMsg)) return FALSE;
-
-
- /* 3.7 and onwards sends a # of security types first */
- if (client->major==3 && client->minor > 6)
- {
- uint8_t count=0;
- uint8_t loop=0;
- uint8_t flag=0;
- uint8_t tAuth=0;
-
- if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE;
-
- if (count==0)
- {
- rfbClientLog("List of security types is ZERO, expecting an error to follow\n");
-
- /* we have an error following */
- if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
- reasonLen = rfbClientSwap32IfLE(reasonLen);
- reason = malloc(reasonLen+1);
- if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
- reason[reasonLen]=0;
- rfbClientLog("VNC connection failed: %s\n",reason);
- free(reason);
- return FALSE;
- }
-
- rfbClientLog("We have %d security types to read\n", count);
- /* now, we have a list of available security types to read ( uint8_t[] ) */
- for (loop=0;loop<count;loop++)
- {
- if (!ReadFromRFBServer(client, (char *)&tAuth, 1)) return FALSE;
- rfbClientLog("%d) Received security type %d\n", loop, tAuth);
- if ((flag==0) && ((tAuth==rfbVncAuth) || (tAuth==rfbNoAuth)))
- {
- flag++;
- authScheme=tAuth;
- rfbClientLog("Selecting security type %d (%d/%d in the list)\n", authScheme, loop, count);
- /* send back a single byte indicating which security type to use */
- if (!WriteToRFBServer(client, (char *)&tAuth, 1)) return FALSE;
-
- }
- }
- }
- else
- {
- if (!ReadFromRFBServer(client, (char *)&authScheme, 4)) return FALSE;
- authScheme = rfbClientSwap32IfLE(authScheme);
- }
-
- rfbClientLog("Selected Security Scheme %d\n", authScheme);
-
- switch (authScheme) {
-
- case rfbConnFailed:
- if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
- reasonLen = rfbClientSwap32IfLE(reasonLen);
-
- reason = malloc(reasonLen+1);
-
- if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
- reason[reasonLen]=0;
- rfbClientLog("VNC connection failed: %s\n", reason);
- free(reason);
- return FALSE;
-
- case rfbNoAuth:
- rfbClientLog("No authentication needed\n");
-
- /* 3.8 and upwards sends a Security Result for rfbNoAuth */
- if (client->major==3 && client->minor > 7)
- if (!rfbHandleAuthResult(client)) return FALSE;
-
- break;
-
- case rfbVncAuth:
- if (!ReadFromRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
-
- if (client->serverPort!=-1) { /* if not playing a vncrec file */
- if (client->GetPassword)
- passwd = client->GetPassword(client);
-
- if ((!passwd) || (strlen(passwd) == 0)) {
- rfbClientLog("Reading password failed\n");
- return FALSE;
- }
- if (strlen(passwd) > 8) {
- passwd[8] = '\0';
- }
-
- rfbClientEncryptBytes(challenge, passwd);
-
- /* Lose the password from memory */
- for (i = strlen(passwd); i >= 0; i--) {
- passwd[i] = '\0';
- }
- free(passwd);
-
- if (!WriteToRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
- }
-
- /* Handle the SecurityResult message */
- if (!rfbHandleAuthResult(client)) return FALSE;
- break;
-
- default:
- rfbClientLog("Unknown authentication scheme from VNC server: %d\n",
- (int)authScheme);
- return FALSE;
- }
-
- ci.shared = (client->appData.shareDesktop ? 1 : 0);
-
- if (!WriteToRFBServer(client, (char *)&ci, sz_rfbClientInitMsg)) return FALSE;
-
- if (!ReadFromRFBServer(client, (char *)&client->si, sz_rfbServerInitMsg)) return FALSE;
-
- client->si.framebufferWidth = rfbClientSwap16IfLE(client->si.framebufferWidth);
- client->si.framebufferHeight = rfbClientSwap16IfLE(client->si.framebufferHeight);
- client->si.format.redMax = rfbClientSwap16IfLE(client->si.format.redMax);
- client->si.format.greenMax = rfbClientSwap16IfLE(client->si.format.greenMax);
- client->si.format.blueMax = rfbClientSwap16IfLE(client->si.format.blueMax);
- client->si.nameLength = rfbClientSwap32IfLE(client->si.nameLength);
-
- client->desktopName = malloc(client->si.nameLength + 1);
- if (!client->desktopName) {
- rfbClientLog("Error allocating memory for desktop name, %lu bytes\n",
- (unsigned long)client->si.nameLength);
- return FALSE;
- }
-
- if (!ReadFromRFBServer(client, client->desktopName, client->si.nameLength)) return FALSE;
-
- client->desktopName[client->si.nameLength] = 0;
-
- rfbClientLog("Desktop name \"%s\"\n",client->desktopName);
-
- rfbClientLog("Connected to VNC server, using protocol version %d.%d\n",
- client->major, client->minor);
-
- rfbClientLog("VNC server default format:\n");
- PrintPixelFormat(&client->si.format);
-
- return TRUE;
-}
-
-
-/*
- * SetFormatAndEncodings.
- */
-
-rfbBool
-SetFormatAndEncodings(rfbClient* client)
-{
- rfbSetPixelFormatMsg spf;
- char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4];
-
- rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf;
- uint32_t *encs = (uint32_t *)(&buf[sz_rfbSetEncodingsMsg]);
- int len = 0;
- rfbBool requestCompressLevel = FALSE;
- rfbBool requestQualityLevel = FALSE;
- rfbBool requestLastRectEncoding = FALSE;
- rfbClientProtocolExtension* e;
-
- if (!SupportsClient2Server(client, rfbSetPixelFormat)) return TRUE;
-
- spf.type = rfbSetPixelFormat;
- spf.format = client->format;
- spf.format.redMax = rfbClientSwap16IfLE(spf.format.redMax);
- spf.format.greenMax = rfbClientSwap16IfLE(spf.format.greenMax);
- spf.format.blueMax = rfbClientSwap16IfLE(spf.format.blueMax);
-
- if (!WriteToRFBServer(client, (char *)&spf, sz_rfbSetPixelFormatMsg))
- return FALSE;
-
-
- if (!SupportsClient2Server(client, rfbSetEncodings)) return TRUE;
-
- se->type = rfbSetEncodings;
- se->nEncodings = 0;
-
- if (client->appData.encodingsString) {
- const char *encStr = client->appData.encodingsString;
- int encStrLen;
- do {
- const char *nextEncStr = strchr(encStr, ' ');
- if (nextEncStr) {
- encStrLen = nextEncStr - encStr;
- nextEncStr++;
- } else {
- encStrLen = strlen(encStr);
- }
-
- if (strncasecmp(encStr,"raw",encStrLen) == 0) {
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRaw);
- } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) {
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCopyRect);
-#ifdef LIBVNCSERVER_HAVE_LIBZ
-#ifdef LIBVNCSERVER_HAVE_LIBJPEG
- } else if (strncasecmp(encStr,"tight",encStrLen) == 0) {
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTight);
- requestLastRectEncoding = TRUE;
- if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
- requestCompressLevel = TRUE;
- if (client->appData.enableJPEG)
- requestQualityLevel = TRUE;
-#endif
-#endif
- } else if (strncasecmp(encStr,"hextile",encStrLen) == 0) {
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingHextile);
-#ifdef LIBVNCSERVER_HAVE_LIBZ
- } else if (strncasecmp(encStr,"zlib",encStrLen) == 0) {
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlib);
- if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
- requestCompressLevel = TRUE;
- } else if (strncasecmp(encStr,"zlibhex",encStrLen) == 0) {
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlibHex);
- if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
- requestCompressLevel = TRUE;
- } else if (strncasecmp(encStr,"zrle",encStrLen) == 0) {
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZRLE);
- } else if (strncasecmp(encStr,"zywrle",encStrLen) == 0) {
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZYWRLE);
- requestQualityLevel = TRUE;
-#endif
- } else if ((strncasecmp(encStr,"ultra",encStrLen) == 0) || (strncasecmp(encStr,"ultrazip",encStrLen) == 0)) {
- /* There are 2 encodings used in 'ultra' */
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltra);
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltraZip);
- } else if (strncasecmp(encStr,"corre",encStrLen) == 0) {
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCoRRE);
- } else if (strncasecmp(encStr,"rre",encStrLen) == 0) {
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE);
- } else {
- rfbClientLog("Unknown encoding '%.*s'\n",encStrLen,encStr);
- }
-
- encStr = nextEncStr;
- } while (encStr && se->nEncodings < MAX_ENCODINGS);
-
- if (se->nEncodings < MAX_ENCODINGS && requestCompressLevel) {
- encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.compressLevel +
- rfbEncodingCompressLevel0);
- }
-
- if (se->nEncodings < MAX_ENCODINGS && requestQualityLevel) {
- if (client->appData.qualityLevel < 0 || client->appData.qualityLevel > 9)
- client->appData.qualityLevel = 5;
- encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel +
- rfbEncodingQualityLevel0);
- }
- }
- else {
- if (SameMachine(client->sock)) {
- /* TODO:
- if (!tunnelSpecified) {
- */
- rfbClientLog("Same machine: preferring raw encoding\n");
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRaw);
- /*
- } else {
- rfbClientLog("Tunneling active: preferring tight encoding\n");
- }
- */
- }
-
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCopyRect);
-#ifdef LIBVNCSERVER_HAVE_LIBZ
-#ifdef LIBVNCSERVER_HAVE_LIBJPEG
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTight);
- requestLastRectEncoding = TRUE;
-#endif
-#endif
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingHextile);
-#ifdef LIBVNCSERVER_HAVE_LIBZ
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlib);
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZRLE);
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZYWRLE);
-#endif
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltra);
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltraZip);
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCoRRE);
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE);
-
- if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9) {
- encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.compressLevel +
- rfbEncodingCompressLevel0);
- } else /* if (!tunnelSpecified) */ {
- /* If -tunnel option was provided, we assume that server machine is
- not in the local network so we use default compression level for
- tight encoding instead of fast compression. Thus we are
- requesting level 1 compression only if tunneling is not used. */
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCompressLevel1);
- }
-
- if (client->appData.enableJPEG) {
- if (client->appData.qualityLevel < 0 || client->appData.qualityLevel > 9)
- client->appData.qualityLevel = 5;
- encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel +
- rfbEncodingQualityLevel0);
- }
- }
-
-
-
- /* Remote Cursor Support (local to viewer) */
- if (client->appData.useRemoteCursor) {
- if (se->nEncodings < MAX_ENCODINGS)
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingXCursor);
- if (se->nEncodings < MAX_ENCODINGS)
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRichCursor);
- if (se->nEncodings < MAX_ENCODINGS)
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPointerPos);
- }
-
- /* Keyboard State Encodings */
- if (se->nEncodings < MAX_ENCODINGS)
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingKeyboardLedState);
-
- /* New Frame Buffer Size */
- if (se->nEncodings < MAX_ENCODINGS && client->canHandleNewFBSize)
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingNewFBSize);
-
- /* Last Rect */
- if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding)
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect);
-
- /* Server Capabilities */
- if (se->nEncodings < MAX_ENCODINGS)
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedMessages);
- if (se->nEncodings < MAX_ENCODINGS)
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedEncodings);
- if (se->nEncodings < MAX_ENCODINGS)
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingServerIdentity);
-
-
- /* client extensions */
- for(e = rfbClientExtensions; e; e = e->next)
- if(e->encodings) {
- int* enc;
- for(enc = e->encodings; *enc; enc++)
- encs[se->nEncodings++] = rfbClientSwap32IfLE(*enc);
- }
-
- len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
-
- se->nEncodings = rfbClientSwap16IfLE(se->nEncodings);
-
- if (!WriteToRFBServer(client, buf, len)) return FALSE;
-
- return TRUE;
-}
-
-
-/*
- * SendIncrementalFramebufferUpdateRequest.
- */
-
-rfbBool
-SendIncrementalFramebufferUpdateRequest(rfbClient* client)
-{
- return SendFramebufferUpdateRequest(client,
- client->updateRect.x, client->updateRect.y,
- client->updateRect.w, client->updateRect.h, TRUE);
-}
-
-
-/*
- * SendFramebufferUpdateRequest.
- */
-
-rfbBool
-SendFramebufferUpdateRequest(rfbClient* client, int x, int y, int w, int h, rfbBool incremental)
-{
- rfbFramebufferUpdateRequestMsg fur;
-
- if (!SupportsClient2Server(client, rfbFramebufferUpdateRequest)) return TRUE;
-
- fur.type = rfbFramebufferUpdateRequest;
- fur.incremental = incremental ? 1 : 0;
- fur.x = rfbClientSwap16IfLE(x);
- fur.y = rfbClientSwap16IfLE(y);
- fur.w = rfbClientSwap16IfLE(w);
- fur.h = rfbClientSwap16IfLE(h);
-
- if (!WriteToRFBServer(client, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg))
- return FALSE;
-
- return TRUE;
-}
-
-
-/*
- * SendScaleSetting.
- */
-rfbBool
-SendScaleSetting(rfbClient* client,int scaleSetting)
-{
- rfbSetScaleMsg ssm;
-
- ssm.scale = scaleSetting;
- ssm.pad = 0;
-
- /* favor UltraVNC SetScale if both are supported */
- if (SupportsClient2Server(client, rfbSetScale)) {
- ssm.type = rfbSetScale;
- if (!WriteToRFBServer(client, (char *)&ssm, sz_rfbSetScaleMsg))
- return FALSE;
- }
-
- if (SupportsClient2Server(client, rfbPalmVNCSetScaleFactor)) {
- ssm.type = rfbPalmVNCSetScaleFactor;
- if (!WriteToRFBServer(client, (char *)&ssm, sz_rfbSetScaleMsg))
- return FALSE;
- }
-
- return TRUE;
-}
-
-/*
- * TextChatFunctions (UltraVNC)
- * Extremely bandwidth friendly method of communicating with a user
- * (Think HelpDesk type applications)
- */
-
-rfbBool TextChatSend(rfbClient* client, char *text)
-{
- rfbTextChatMsg chat;
- int count = strlen(text);
-
- if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
- chat.type = rfbTextChat;
- chat.pad1 = 0;
- chat.pad2 = 0;
- chat.length = (uint32_t)count;
- chat.length = rfbClientSwap32IfLE(chat.length);
-
- if (!WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg))
- return FALSE;
-
- if (count>0) {
- if (!WriteToRFBServer(client, text, count))
- return FALSE;
- }
- return TRUE;
-}
-
-rfbBool TextChatOpen(rfbClient* client)
-{
- rfbTextChatMsg chat;
-
- if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
- chat.type = rfbTextChat;
- chat.pad1 = 0;
- chat.pad2 = 0;
- chat.length = rfbClientSwap32IfLE(rfbTextChatOpen);
- return (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
-}
-
-rfbBool TextChatClose(rfbClient* client)
-{
- rfbTextChatMsg chat;
- if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
- chat.type = rfbTextChat;
- chat.pad1 = 0;
- chat.pad2 = 0;
- chat.length = rfbClientSwap32IfLE(rfbTextChatClose);
- return (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
-}
-
-rfbBool TextChatFinish(rfbClient* client)
-{
- rfbTextChatMsg chat;
- if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
- chat.type = rfbTextChat;
- chat.pad1 = 0;
- chat.pad2 = 0;
- chat.length = rfbClientSwap32IfLE(rfbTextChatFinished);
- return (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
-}
-
-/*
- * UltraVNC Server Input Disable
- * Apparently, the remote client can *prevent* the local user from interacting with the display
- * I would think this is extremely helpful when used in a HelpDesk situation
- */
-rfbBool PermitServerInput(rfbClient* client, int enabled)
-{
- rfbSetServerInputMsg msg;
-
- if (!SupportsClient2Server(client, rfbSetServerInput)) return TRUE;
- /* enabled==1, then server input from local keyboard is disabled */
- msg.type = rfbSetServerInput;
- msg.status = (enabled ? 1 : 0);
- msg.pad = 0;
- return (WriteToRFBServer(client, (char *)&msg, sz_rfbSetServerInputMsg) ? TRUE : FALSE);
-}
-
-
-/*
- * SendPointerEvent.
- */
-
-rfbBool
-SendPointerEvent(rfbClient* client,int x, int y, int buttonMask)
-{
- rfbPointerEventMsg pe;
-
- if (!SupportsClient2Server(client, rfbPointerEvent)) return TRUE;
-
- pe.type = rfbPointerEvent;
- pe.buttonMask = buttonMask;
- if (x < 0) x = 0;
- if (y < 0) y = 0;
-
- pe.x = rfbClientSwap16IfLE(x);
- pe.y = rfbClientSwap16IfLE(y);
- return WriteToRFBServer(client, (char *)&pe, sz_rfbPointerEventMsg);
-}
-
-
-/*
- * SendKeyEvent.
- */
-
-rfbBool
-SendKeyEvent(rfbClient* client, uint32_t key, rfbBool down)
-{
- rfbKeyEventMsg ke;
-
- if (!SupportsClient2Server(client, rfbKeyEvent)) return TRUE;
-
- ke.type = rfbKeyEvent;
- ke.down = down ? 1 : 0;
- ke.key = rfbClientSwap32IfLE(key);
- return WriteToRFBServer(client, (char *)&ke, sz_rfbKeyEventMsg);
-}
-
-
-/*
- * SendClientCutText.
- */
-
-rfbBool
-SendClientCutText(rfbClient* client, char *str, int len)
-{
- rfbClientCutTextMsg cct;
-
- if (!SupportsClient2Server(client, rfbClientCutText)) return TRUE;
-
- cct.type = rfbClientCutText;
- cct.length = rfbClientSwap32IfLE(len);
- return (WriteToRFBServer(client, (char *)&cct, sz_rfbClientCutTextMsg) &&
- WriteToRFBServer(client, str, len));
-}
-
-
-
-/*
- * HandleRFBServerMessage.
- */
-
-rfbBool
-HandleRFBServerMessage(rfbClient* client)
-{
- rfbServerToClientMsg msg;
-
- if (client->serverPort==-1)
- client->vncRec->readTimestamp = TRUE;
- if (!ReadFromRFBServer(client, (char *)&msg, 1))
- return FALSE;
-
- switch (msg.type) {
-
- case rfbSetColourMapEntries:
- {
- /* TODO:
- int i;
- uint16_t rgb[3];
- XColor xc;
-
- if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
- sz_rfbSetColourMapEntriesMsg - 1))
- return FALSE;
-
- msg.scme.firstColour = rfbClientSwap16IfLE(msg.scme.firstColour);
- msg.scme.nColours = rfbClientSwap16IfLE(msg.scme.nColours);
-
- for (i = 0; i < msg.scme.nColours; i++) {
- if (!ReadFromRFBServer(client, (char *)rgb, 6))
- return FALSE;
- xc.pixel = msg.scme.firstColour + i;
- xc.red = rfbClientSwap16IfLE(rgb[0]);
- xc.green = rfbClientSwap16IfLE(rgb[1]);
- xc.blue = rfbClientSwap16IfLE(rgb[2]);
- xc.flags = DoRed|DoGreen|DoBlue;
- XStoreColor(dpy, cmap, &xc);
- }
- */
-
- break;
- }
-
- case rfbFramebufferUpdate:
- {
- rfbFramebufferUpdateRectHeader rect;
- int linesToRead;
- int bytesPerLine;
- int i;
-
- if (!ReadFromRFBServer(client, ((char *)&msg.fu) + 1,
- sz_rfbFramebufferUpdateMsg - 1))
- return FALSE;
-
- msg.fu.nRects = rfbClientSwap16IfLE(msg.fu.nRects);
-
- for (i = 0; i < msg.fu.nRects; i++) {
- if (!ReadFromRFBServer(client, (char *)&rect, sz_rfbFramebufferUpdateRectHeader))
- return FALSE;
-
- rect.encoding = rfbClientSwap32IfLE(rect.encoding);
- if (rect.encoding == rfbEncodingLastRect)
- break;
-
- rect.r.x = rfbClientSwap16IfLE(rect.r.x);
- rect.r.y = rfbClientSwap16IfLE(rect.r.y);
- rect.r.w = rfbClientSwap16IfLE(rect.r.w);
- rect.r.h = rfbClientSwap16IfLE(rect.r.h);
-
-
- if (rect.encoding == rfbEncodingXCursor ||
- rect.encoding == rfbEncodingRichCursor) {
-
- if (!HandleCursorShape(client,
- rect.r.x, rect.r.y, rect.r.w, rect.r.h,
- rect.encoding)) {
- return FALSE;
- }
- continue;
- }
-
- if (rect.encoding == rfbEncodingPointerPos) {
- if (!client->HandleCursorPos(client,rect.r.x, rect.r.y)) {
- return FALSE;
- }
- continue;
- }
-
- if (rect.encoding == rfbEncodingKeyboardLedState) {
- /* OK! We have received a keyboard state message!!! */
- client->KeyboardLedStateEnabled = 1;
- if (client->HandleKeyboardLedState!=NULL)
- client->HandleKeyboardLedState(client, rect.r.x, 0);
- /* stash it for the future */
- client->CurrentKeyboardLedState = rect.r.x;
- continue;
- }
-
- if (rect.encoding == rfbEncodingNewFBSize) {
- client->width = rect.r.w;
- client->height = rect.r.h;
- client->MallocFrameBuffer(client);
- SendFramebufferUpdateRequest(client, 0, 0, rect.r.w, rect.r.h, FALSE);
- rfbClientLog("Got new framebuffer size: %dx%d\n", rect.r.w, rect.r.h);
- continue;
- }
-
- /* rect.r.w=byte count */
- if (rect.encoding == rfbEncodingSupportedMessages) {
- int loop;
- if (!ReadFromRFBServer(client, (char *)&client->supportedMessages, sz_rfbSupportedMessages))
- return FALSE;
-
- /* msgs is two sets of bit flags of supported messages client2server[] and server2client[] */
- /* currently ignored by this library */
-
- rfbClientLog("client2server supported messages (bit flags)\n");
- for (loop=0;loop<32;loop+=8)
- rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop,
- client->supportedMessages.client2server[loop], client->supportedMessages.client2server[loop+1],
- client->supportedMessages.client2server[loop+2], client->supportedMessages.client2server[loop+3],
- client->supportedMessages.client2server[loop+4], client->supportedMessages.client2server[loop+5],
- client->supportedMessages.client2server[loop+6], client->supportedMessages.client2server[loop+7]);
-
- rfbClientLog("server2client supported messages (bit flags)\n");
- for (loop=0;loop<32;loop+=8)
- rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop,
- client->supportedMessages.server2client[loop], client->supportedMessages.server2client[loop+1],
- client->supportedMessages.server2client[loop+2], client->supportedMessages.server2client[loop+3],
- client->supportedMessages.server2client[loop+4], client->supportedMessages.server2client[loop+5],
- client->supportedMessages.server2client[loop+6], client->supportedMessages.server2client[loop+7]);
- continue;
- }
-
- /* rect.r.w=byte count, rect.r.h=# of encodings */
- if (rect.encoding == rfbEncodingSupportedEncodings) {
- char *buffer;
- buffer = malloc(rect.r.w);
- if (!ReadFromRFBServer(client, buffer, rect.r.w))
- {
- free(buffer);
- return FALSE;
- }
-
- /* buffer now contains rect.r.h # of uint32_t encodings that the server supports */
- /* currently ignored by this library */
- free(buffer);
- continue;
- }
-
- /* rect.r.w=byte count */
- if (rect.encoding == rfbEncodingServerIdentity) {
- char *buffer;
- buffer = malloc(rect.r.w+1);
- if (!ReadFromRFBServer(client, buffer, rect.r.w))
- {
- free(buffer);
- return FALSE;
- }
- buffer[rect.r.w]=0; /* null terminate, just in case */
- rfbClientLog("Connected to Server \"%s\"\n", buffer);
- free(buffer);
- continue;
- }
-
- /* rfbEncodingUltraZip is a collection of subrects. x = # of subrects, and h is always 0 */
- if (rect.encoding != rfbEncodingUltraZip)
- {
- if ((rect.r.x + rect.r.w > client->width) ||
- (rect.r.y + rect.r.h > client->height))
- {
- rfbClientLog("Rect too large: %dx%d at (%d, %d)\n",
- rect.r.w, rect.r.h, rect.r.x, rect.r.y);
- return FALSE;
- }
-
- /* UltraVNC with scaling, will send rectangles with a zero W or H
- *
- if ((rect.encoding != rfbEncodingTight) &&
- (rect.r.h * rect.r.w == 0))
- {
- 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);
- continue;
- }
- */
-
- /* If RichCursor encoding is used, we should prevent collisions
- between framebuffer updates and cursor drawing operations. */
- client->SoftCursorLockArea(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
- }
-
- switch (rect.encoding) {
-
- case rfbEncodingRaw: {
- int y=rect.r.y, h=rect.r.h;
-
- bytesPerLine = rect.r.w * client->format.bitsPerPixel / 8;
- linesToRead = RFB_BUFFER_SIZE / bytesPerLine;
-
- while (h > 0) {
- if (linesToRead > h)
- linesToRead = h;
-
- if (!ReadFromRFBServer(client, client->buffer,bytesPerLine * linesToRead))
- return FALSE;
-
- CopyRectangle(client, (uint8_t *)client->buffer,
- rect.r.x, y, rect.r.w,linesToRead);
-
- h -= linesToRead;
- y += linesToRead;
-
- }
- } break;
-
- case rfbEncodingCopyRect:
- {
- rfbCopyRect cr;
-
- if (!ReadFromRFBServer(client, (char *)&cr, sz_rfbCopyRect))
- return FALSE;
-
- cr.srcX = rfbClientSwap16IfLE(cr.srcX);
- cr.srcY = rfbClientSwap16IfLE(cr.srcY);
-
- /* If RichCursor encoding is used, we should extend our
- "cursor lock area" (previously set to destination
- rectangle) to the source rectangle as well. */
- client->SoftCursorLockArea(client,
- cr.srcX, cr.srcY, rect.r.w, rect.r.h);
-
- if (client->GotCopyRect != NULL) {
- client->GotCopyRect(client, cr.srcX, cr.srcY, rect.r.w, rect.r.h,
- rect.r.x, rect.r.y);
- } else
- CopyRectangleFromRectangle(client,
- cr.srcX, cr.srcY, rect.r.w, rect.r.h,
- rect.r.x, rect.r.y);
-
- break;
- }
-
- case rfbEncodingRRE:
- {
- switch (client->format.bitsPerPixel) {
- case 8:
- if (!HandleRRE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- case 16:
- if (!HandleRRE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- case 32:
- if (!HandleRRE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- }
- break;
- }
-
- case rfbEncodingCoRRE:
- {
- switch (client->format.bitsPerPixel) {
- case 8:
- if (!HandleCoRRE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- case 16:
- if (!HandleCoRRE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- case 32:
- if (!HandleCoRRE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- }
- break;
- }
-
- case rfbEncodingHextile:
- {
- switch (client->format.bitsPerPixel) {
- case 8:
- if (!HandleHextile8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- case 16:
- if (!HandleHextile16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- case 32:
- if (!HandleHextile32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- }
- break;
- }
-
- case rfbEncodingUltra:
- {
- switch (client->format.bitsPerPixel) {
- case 8:
- if (!HandleUltra8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- case 16:
- if (!HandleUltra16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- case 32:
- if (!HandleUltra32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- }
- break;
- }
- case rfbEncodingUltraZip:
- {
- switch (client->format.bitsPerPixel) {
- case 8:
- if (!HandleUltraZip8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- case 16:
- if (!HandleUltraZip16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- case 32:
- if (!HandleUltraZip32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- }
- break;
- }
-
-#ifdef LIBVNCSERVER_HAVE_LIBZ
- case rfbEncodingZlib:
- {
- switch (client->format.bitsPerPixel) {
- case 8:
- if (!HandleZlib8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- case 16:
- if (!HandleZlib16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- case 32:
- if (!HandleZlib32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- }
- break;
- }
-
-#ifdef LIBVNCSERVER_HAVE_LIBJPEG
- case rfbEncodingTight:
- {
- switch (client->format.bitsPerPixel) {
- case 8:
- if (!HandleTight8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- case 16:
- if (!HandleTight16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- case 32:
- if (!HandleTight32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- }
- break;
- }
-#endif
- case rfbEncodingZRLE:
- /* Fail safe for ZYWRLE unsupport VNC server. */
- client->appData.qualityLevel = 9;
- /* fall through */
- case rfbEncodingZYWRLE:
- {
- switch (client->format.bitsPerPixel) {
- case 8:
- if (!HandleZRLE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- case 16:
- if (client->si.format.greenMax > 0x1F) {
- if (!HandleZRLE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- } else {
- if (!HandleZRLE15(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- }
- break;
- case 32:
- {
- uint32_t maxColor=(client->format.redMax<<client->format.redShift)|
- (client->format.greenMax<<client->format.greenShift)|
- (client->format.blueMax<<client->format.blueShift);
- if ((client->format.bigEndian && (maxColor&0xff)==0) ||
- (!client->format.bigEndian && (maxColor&0xff000000)==0)) {
- if (!HandleZRLE24(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- } else if (!client->format.bigEndian && (maxColor&0xff)==0) {
- if (!HandleZRLE24Up(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- } else if (client->format.bigEndian && (maxColor&0xff000000)==0) {
- if (!HandleZRLE24Down(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- } else if (!HandleZRLE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return FALSE;
- break;
- }
- }
- break;
- }
-
-#endif
-
- default:
- {
- rfbBool handled = FALSE;
- rfbClientProtocolExtension* e;
-
- for(e = rfbClientExtensions; !handled && e; e = e->next)
- if(e->handleEncoding && e->handleEncoding(client, &rect))
- handled = TRUE;
-
- if(!handled) {
- rfbClientLog("Unknown rect encoding %d\n",
- (int)rect.encoding);
- return FALSE;
- }
- }
- }
-
- /* Now we may discard "soft cursor locks". */
- client->SoftCursorUnlockScreen(client);
-
- client->GotFrameBufferUpdate(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
- }
-
- if (!SendIncrementalFramebufferUpdateRequest(client))
- return FALSE;
-
- break;
- }
-
- case rfbBell:
- {
- client->Bell(client);
-
- break;
- }
-
- case rfbServerCutText:
- {
- char *buffer;
-
- if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
- sz_rfbServerCutTextMsg - 1))
- return FALSE;
-
- msg.sct.length = rfbClientSwap32IfLE(msg.sct.length);
-
- buffer = malloc(msg.sct.length+1);
-
- if (!ReadFromRFBServer(client, buffer, msg.sct.length))
- return FALSE;
-
- buffer[msg.sct.length] = 0;
-
- if (client->GotXCutText)
- client->GotXCutText(client, buffer, msg.sct.length);
-
- free(buffer);
-
- break;
- }
-
- case rfbTextChat:
- {
- char *buffer=NULL;
- if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
- sz_rfbTextChatMsg- 1))
- return FALSE;
- msg.tc.length = rfbClientSwap32IfLE(msg.sct.length);
- switch(msg.tc.length) {
- case rfbTextChatOpen:
- rfbClientLog("Received TextChat Open\n");
- if (client->HandleTextChat!=NULL)
- client->HandleTextChat(client, (int)rfbTextChatOpen, NULL);
- break;
- case rfbTextChatClose:
- rfbClientLog("Received TextChat Close\n");
- if (client->HandleTextChat!=NULL)
- client->HandleTextChat(client, (int)rfbTextChatClose, NULL);
- break;
- case rfbTextChatFinished:
- rfbClientLog("Received TextChat Finished\n");
- if (client->HandleTextChat!=NULL)
- client->HandleTextChat(client, (int)rfbTextChatFinished, NULL);
- break;
- default:
- buffer=malloc(msg.tc.length+1);
- if (!ReadFromRFBServer(client, buffer, msg.tc.length))
- {
- free(buffer);
- return FALSE;
- }
- /* Null Terminate <just in case> */
- buffer[msg.tc.length]=0;
- rfbClientLog("Received TextChat \"%s\"\n", buffer);
- if (client->HandleTextChat!=NULL)
- client->HandleTextChat(client, (int)msg.tc.length, buffer);
- free(buffer);
- break;
- }
- break;
- }
-
- case rfbResizeFrameBuffer:
- {
- if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
- sz_rfbResizeFrameBufferMsg -1))
- return FALSE;
- client->width = rfbClientSwap16IfLE(msg.rsfb.framebufferWidth);
- client->height = rfbClientSwap16IfLE(msg.rsfb.framebufferHeigth);
- client->MallocFrameBuffer(client);
- SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE);
- rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height);
- break;
- }
-
- case rfbPalmVNCReSizeFrameBuffer:
- {
- if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
- sz_rfbPalmVNCReSizeFrameBufferMsg -1))
- return FALSE;
- client->width = rfbClientSwap16IfLE(msg.prsfb.buffer_w);
- client->height = rfbClientSwap16IfLE(msg.prsfb.buffer_h);
- client->MallocFrameBuffer(client);
- SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE);
- rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height);
- break;
- }
-
- default:
- {
- rfbBool handled = FALSE;
- rfbClientProtocolExtension* e;
-
- for(e = rfbClientExtensions; !handled && e; e = e->next)
- if(e->handleMessage && e->handleMessage(client, &msg))
- handled = TRUE;
-
- if(!handled) {
- char buffer[256];
- rfbClientLog("Unknown message type %d from VNC server\n",msg.type);
- ReadFromRFBServer(client, buffer, 256);
- return FALSE;
- }
- }
- }
-
- return TRUE;
-}
-
-
-#define GET_PIXEL8(pix, ptr) ((pix) = *(ptr)++)
-
-#define GET_PIXEL16(pix, ptr) (((uint8_t*)&(pix))[0] = *(ptr)++, \
- ((uint8_t*)&(pix))[1] = *(ptr)++)
-
-#define GET_PIXEL32(pix, ptr) (((uint8_t*)&(pix))[0] = *(ptr)++, \
- ((uint8_t*)&(pix))[1] = *(ptr)++, \
- ((uint8_t*)&(pix))[2] = *(ptr)++, \
- ((uint8_t*)&(pix))[3] = *(ptr)++)
-
-/* CONCAT2 concatenates its two arguments. CONCAT2E does the same but also
- expands its arguments if they are macros */
-
-#define CONCAT2(a,b) a##b
-#define CONCAT2E(a,b) CONCAT2(a,b)
-#define CONCAT3(a,b,c) a##b##c
-#define CONCAT3E(a,b,c) CONCAT3(a,b,c)
-
-#define BPP 8
-#include "rre.c"
-#include "corre.c"
-#include "hextile.c"
-#include "ultra.c"
-#include "zlib.c"
-#include "tight.c"
-#include "zrle.c"
-#undef BPP
-#define BPP 16
-#include "rre.c"
-#include "corre.c"
-#include "hextile.c"
-#include "ultra.c"
-#include "zlib.c"
-#include "tight.c"
-#include "zrle.c"
-#define REALBPP 15
-#include "zrle.c"
-#undef BPP
-#define BPP 32
-#include "rre.c"
-#include "corre.c"
-#include "hextile.c"
-#include "ultra.c"
-#include "zlib.c"
-#include "tight.c"
-#include "zrle.c"
-#define REALBPP 24
-#include "zrle.c"
-#define REALBPP 24
-#define UNCOMP 8
-#include "zrle.c"
-#define REALBPP 24
-#define UNCOMP -8
-#include "zrle.c"
-#undef BPP
-
-
-/*
- * PrintPixelFormat.
- */
-
-void
-PrintPixelFormat(rfbPixelFormat *format)
-{
- if (format->bitsPerPixel == 1) {
- rfbClientLog(" Single bit per pixel.\n");
- rfbClientLog(
- " %s significant bit in each byte is leftmost on the screen.\n",
- (format->bigEndian ? "Most" : "Least"));
- } else {
- rfbClientLog(" %d bits per pixel.\n",format->bitsPerPixel);
- if (format->bitsPerPixel != 8) {
- rfbClientLog(" %s significant byte first in each pixel.\n",
- (format->bigEndian ? "Most" : "Least"));
- }
- if (format->trueColour) {
- rfbClientLog(" TRUE colour: max red %d green %d blue %d"
- ", shift red %d green %d blue %d\n",
- format->redMax, format->greenMax, format->blueMax,
- format->redShift, format->greenShift, format->blueShift);
- } else {
- rfbClientLog(" Colour map (not true colour).\n");
- }
- }
-}
-
-/* avoid name clashes with LibVNCServer */
-
-#define rfbEncryptBytes rfbClientEncryptBytes
-#define rfbDes rfbClientDes
-#define rfbDesKey rfbClientDesKey
-#define rfbUseKey rfbClientUseKey
-#define rfbCPKey rfbClientCPKey
-
-#include "../libvncserver/vncauth.c"
-#include "../libvncserver/d3des.c"