summaryrefslogtreecommitdiffstats
path: root/krdc/vnc/rfbproto.c
diff options
context:
space:
mode:
Diffstat (limited to 'krdc/vnc/rfbproto.c')
-rw-r--r--krdc/vnc/rfbproto.c1335
1 files changed, 0 insertions, 1335 deletions
diff --git a/krdc/vnc/rfbproto.c b/krdc/vnc/rfbproto.c
deleted file mode 100644
index 8424e6ac..00000000
--- a/krdc/vnc/rfbproto.c
+++ /dev/null
@@ -1,1335 +0,0 @@
-/*
- * Copyright (C) 2002, Tim Jansen. All Rights Reserved.
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- */
-
-/*
- * rfbproto.c - functions to deal with client side of RFB protocol.
- * tim@tjansen.de: - added softcursor encoding
- * - changed various things for krdc
- */
-
-#include <unistd.h>
-#include <errno.h>
-#include <pwd.h>
-#include "vncviewer.h"
-#include "vncauth.h"
-#include <zlib.h>
-#include <jpeglib.h>
-
-static Bool HandleHextile8(int rx, int ry, int rw, int rh);
-static Bool HandleHextile16(int rx, int ry, int rw, int rh);
-static Bool HandleHextile32(int rx, int ry, int rw, int rh);
-static Bool HandleZlib8(int rx, int ry, int rw, int rh);
-static Bool HandleZlib16(int rx, int ry, int rw, int rh);
-static Bool HandleZlib32(int rx, int ry, int rw, int rh);
-static Bool HandleTight8(int rx, int ry, int rw, int rh);
-static Bool HandleTight16(int rx, int ry, int rw, int rh);
-static Bool HandleTight32(int rx, int ry, int rw, int rh);
-
-static long ReadCompactLen (void);
-
-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, CARD8 *compressedData,
- int compressedLen);
-
-
-#define RGB24_TO_PIXEL(bpp,r,g,b) \
- ((((CARD##bpp)(r) & 0xFF) * myFormat.redMax + 127) / 255 \
- << myFormat.redShift | \
- (((CARD##bpp)(g) & 0xFF) * myFormat.greenMax + 127) / 255 \
- << myFormat.greenShift | \
- (((CARD##bpp)(b) & 0xFF) * myFormat.blueMax + 127) / 255 \
- << myFormat.blueShift)
-
-int rfbsock;
-char *desktopName;
-rfbPixelFormat myFormat;
-rfbServerInitMsg si;
-
-int endianTest = 1;
-
-/*
- * Softcursor variables
- */
-
-int cursorX, cursorY;
-int imageIndex = -1;
-
-PointerImage pointerImages[rfbSoftCursorMaxImages];
-
-
-/* Hextile assumes it is big enough to hold 16 * 16 * 32 bits.
- Tight encoding assumes BUFFER_SIZE is at least 16384 bytes. */
-
-#define BUFFER_SIZE (16384)
-static char buffer[BUFFER_SIZE];
-
-
-/* The zlib encoding requires expansion/decompression/deflation of the
- compressed data in the "buffer" above into another, result buffer.
- However, the size of the result buffer can be determined precisely
- based on the bitsPerPixel, height and width of the rectangle. We
- allocate this buffer one time to be the full size of the buffer. */
-
-static int raw_buffer_size = -1;
-static char *raw_buffer = NULL;
-
-static z_stream decompStream;
-static Bool decompStreamInited = False;
-
-
-/*
- * Variables for the ``tight'' encoding implementation.
- */
-
-/* Separate buffer for compressed data. */
-#define ZLIB_BUFFER_SIZE 512
-static char zlib_buffer[ZLIB_BUFFER_SIZE];
-
-/* Four independent compression streams for zlib library. */
-static z_stream zlibStream[4];
-static Bool zlibStreamActive[4] = {
- False, False, False, False
-};
-
-/* Filter stuff. Should be initialized by filter initialization code. */
-static Bool cutZeros;
-static int rectWidth, rectColors;
-static char tightPalette[256*4];
-static CARD8 tightPrevRow[2048*3*sizeof(CARD16)];
-
-/* JPEG decoder state. */
-static Bool jpegError;
-
-/* Maximum length for the cut buffer (16 MB)*/
-#define MAX_CUTBUFFER (1024*1024*16)
-
-/* Maximum length for the strings (64 kB)*/
-#define MAX_STRING (1024*64)
-
-/* Maximum length for the strings (32 MB)*/
-#define MAX_JPEG_SIZE (1024*1024*32)
-
-
-/*
- * ConnectToRFBServer.
- */
-
-int
-ConnectToRFBServer(const char *hostname, int port)
-{
- unsigned int host;
-
- if (!StringToIPAddr(hostname, &host)) {
- fprintf(stderr,"Couldn't convert '%s' to host address\n", hostname);
- return -(int)INIT_NAME_RESOLUTION_FAILURE;
- }
-
- rfbsock = ConnectToTcpAddr(host, port);
- if (rfbsock < 0) {
- fprintf(stderr,"Unable to connect to VNC server\n");
- }
-
- return rfbsock;
-}
-
-
-/*
- * InitialiseRFBConnection.
- */
-
-enum InitStatus
-InitialiseRFBConnection()
-{
- rfbProtocolVersionMsg pv;
- int major,minor;
- CARD32 authScheme, reasonLen, authResult;
- char *reason;
- CARD8 challenge[CHALLENGESIZE];
- char passwd[9];
- int i;
- rfbClientInitMsg ci;
-
- /* if the connection is immediately closed, don't report anything, so
- that pmw's monitor can make test connections */
-
- if (!ReadFromRFBServer(pv, sz_rfbProtocolVersionMsg)) return INIT_SERVER_BLOCKED;
-
- errorMessageOnReadFailure = True;
-
- pv[sz_rfbProtocolVersionMsg] = 0;
-
- if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) {
- fprintf(stderr,"Not a valid VNC server\n");
- return INIT_PROTOCOL_FAILURE;
- }
-
- fprintf(stderr,"VNC server supports protocol version %d.%d (viewer %d.%d)\n",
- major, minor, rfbProtocolMajorVersion, rfbProtocolMinorVersion);
-
- major = rfbProtocolMajorVersion;
- minor = rfbProtocolMinorVersion;
-
- sprintf(pv,rfbProtocolVersionFormat,major,minor);
-
- if (!WriteExact(rfbsock, pv, sz_rfbProtocolVersionMsg)) return INIT_CONNECTION_FAILED;
-
- if (!ReadFromRFBServer((char *)&authScheme, 4)) return INIT_CONNECTION_FAILED;
-
- authScheme = Swap32IfLE(authScheme);
-
- switch (authScheme) {
-
- case rfbConnFailed:
- if (!ReadFromRFBServer((char *)&reasonLen, 4)) return INIT_CONNECTION_FAILED;
- reasonLen = Swap32IfLE(reasonLen);
-
- if (reasonLen > MAX_STRING) {
- fprintf(stderr, "Connection failure reason too long.\n");
- return INIT_CONNECTION_FAILED;
- }
-
- reason = malloc(reasonLen);
- if (!reason)
- return INIT_CONNECTION_FAILED;
-
- if (!ReadFromRFBServer(reason, reasonLen)) return INIT_CONNECTION_FAILED;
-
- fprintf(stderr,"VNC connection failed: %.*s\n",(int)reasonLen, reason);
- free(reason);
- return INIT_CONNECTION_FAILED;
-
- case rfbNoAuth:
- fprintf(stderr,"No authentication needed\n");
- break;
-
- case rfbVncAuth:
- if (!ReadFromRFBServer((char *)challenge, CHALLENGESIZE)) return INIT_CONNECTION_FAILED;
-
- if (!getPassword(passwd, 8))
- return INIT_ABORTED;
-
- passwd[8] = '\0';
-
- vncEncryptBytes(challenge, passwd);
-
- /* Lose the password from memory */
- for (i = strlen(passwd); i >= 0; i--) {
- passwd[i] = '\0';
- }
-
- if (!WriteExact(rfbsock, (char *)challenge, CHALLENGESIZE)) return INIT_CONNECTION_FAILED;
-
- if (!ReadFromRFBServer((char *)&authResult, 4)) return INIT_CONNECTION_FAILED;
-
- authResult = Swap32IfLE(authResult);
-
- switch (authResult) {
- case rfbVncAuthOK:
- fprintf(stderr,"VNC authentication succeeded\n");
- break;
- case rfbVncAuthFailed:
- fprintf(stderr,"VNC authentication failed\n");
- return INIT_AUTHENTICATION_FAILED;
- case rfbVncAuthTooMany:
- fprintf(stderr,"VNC authentication failed - too many tries\n");
- return INIT_AUTHENTICATION_FAILED;
- default:
- fprintf(stderr,"Unknown VNC authentication result: %d\n",
- (int)authResult);
- return INIT_CONNECTION_FAILED;
- }
- break;
-
- default:
- fprintf(stderr,"Unknown authentication scheme from VNC server: %d\n",
- (int)authScheme);
- return INIT_CONNECTION_FAILED;
- }
-
- ci.shared = (appData.shareDesktop ? 1 : 0);
-
- if (!WriteExact(rfbsock, (char *)&ci, sz_rfbClientInitMsg)) return INIT_CONNECTION_FAILED;
-
- if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg)) return INIT_CONNECTION_FAILED;
-
- si.framebufferWidth = Swap16IfLE(si.framebufferWidth);
- si.framebufferHeight = Swap16IfLE(si.framebufferHeight);
- si.format.redMax = Swap16IfLE(si.format.redMax);
- si.format.greenMax = Swap16IfLE(si.format.greenMax);
- si.format.blueMax = Swap16IfLE(si.format.blueMax);
- si.nameLength = Swap32IfLE(si.nameLength);
-
- if ((si.framebufferWidth*si.framebufferHeight) > (4096*4096))
- return INIT_CONNECTION_FAILED;
-
- if (si.nameLength > MAX_STRING) {
- fprintf(stderr, "Display name too long.\n");
- return INIT_CONNECTION_FAILED;
- }
-
- desktopName = malloc(si.nameLength + 1);
- if (!desktopName) {
- fprintf(stderr, "Error allocating memory for desktop name, %lu bytes\n",
- (unsigned long)si.nameLength);
- return INIT_CONNECTION_FAILED;
- }
-
- if (!ReadFromRFBServer(desktopName, si.nameLength)) return INIT_CONNECTION_FAILED;
-
- desktopName[si.nameLength] = 0;
-
- fprintf(stderr,"Desktop name \"%s\"\n",desktopName);
-
- fprintf(stderr,"Connected to VNC server, using protocol version %d.%d\n",
- rfbProtocolMajorVersion, rfbProtocolMinorVersion);
-
- fprintf(stderr,"VNC server default format:\n");
- PrintPixelFormat(&si.format);
-
- return INIT_OK;
-}
-
-
-/*
- * SetFormatAndEncodings.
- */
-
-Bool
-SetFormatAndEncodings()
-{
- rfbSetPixelFormatMsg spf;
- char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4];
- rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf;
- CARD32 *encs = (CARD32 *)(&buf[sz_rfbSetEncodingsMsg]);
- int len = 0;
- Bool requestCompressLevel = False;
- Bool requestQualityLevel = False;
- Bool requestLastRectEncoding = False;
-
- spf.type = rfbSetPixelFormat;
- spf.pad1 = 0;
- spf.pad2 = 0;
- spf.format = myFormat;
- spf.format.redMax = Swap16IfLE(spf.format.redMax);
- spf.format.greenMax = Swap16IfLE(spf.format.greenMax);
- spf.format.blueMax = Swap16IfLE(spf.format.blueMax);
-
- if (!WriteExact(rfbsock, (char *)&spf, sz_rfbSetPixelFormatMsg))
- return False;
-
- se->type = rfbSetEncodings;
- se->pad = 0;
- se->nEncodings = 0;
-
- if (appData.encodingsString) {
- const char *encStr = appData.encodingsString;
- int encStrLen;
- do {
- char *nextEncStr = strchr(encStr, ' ');
- if (nextEncStr) {
- encStrLen = nextEncStr - encStr;
- nextEncStr++;
- } else {
- encStrLen = strlen(encStr);
- }
-
- if (strncasecmp(encStr,"raw",encStrLen) == 0) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw);
- } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect);
- } else if (strncasecmp(encStr,"softcursor",encStrLen) == 0) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingSoftCursor);
- /* if server supports SoftCursor, it will ignore X/RichCursor
- * and PointerPos */
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor);
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor);
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos);
- } else if (strncasecmp(encStr,"background",encStrLen) == 0) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingBackground);
- } else if (strncasecmp(encStr,"tight",encStrLen) == 0) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight);
- requestLastRectEncoding = True;
- if (appData.compressLevel >= 0 && appData.compressLevel <= 9)
- requestCompressLevel = True;
- if (appData.qualityLevel >= 0 && appData.qualityLevel <= 9)
- requestQualityLevel = True;
- } else if (strncasecmp(encStr,"hextile",encStrLen) == 0) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile);
- } else if (strncasecmp(encStr,"zlib",encStrLen) == 0) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib);
- if (appData.compressLevel >= 0 && appData.compressLevel <= 9)
- requestCompressLevel = True;
- } else {
- fprintf(stderr,"Unknown encoding '%.*s'\n",encStrLen,encStr);
- }
-
- encStr = nextEncStr;
- } while (encStr && se->nEncodings < MAX_ENCODINGS);
-
- if (se->nEncodings < MAX_ENCODINGS && requestCompressLevel) {
- encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel +
- rfbEncodingCompressLevel0);
- }
-
- if (se->nEncodings < MAX_ENCODINGS && requestQualityLevel) {
- encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel +
- rfbEncodingQualityLevel0);
- }
-
- if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
- }
- }
- else {
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect);
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight);
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile);
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib);
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw);
-
- if (appData.compressLevel >= 0 && appData.compressLevel <= 9) {
- encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel +
- rfbEncodingCompressLevel0);
- }
-
- if (appData.qualityLevel >= 0 && appData.qualityLevel <= 9) {
- encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel +
- rfbEncodingQualityLevel0);
- }
-
- if (si.format.depth >= 8)
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingSoftCursor);
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
- }
-
- len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
-
- se->nEncodings = Swap16IfLE(se->nEncodings);
-
- if (!WriteExact(rfbsock, buf, len)) return False;
-
- return True;
-}
-
-
-/*
- * SendIncrementalFramebufferUpdateRequest.
- * Note: this should only be called by the WriterThread
- */
-
-Bool
-SendIncrementalFramebufferUpdateRequest()
-{
- return SendFramebufferUpdateRequest(0, 0, si.framebufferWidth,
- si.framebufferHeight, True);
-}
-
-
-/*
- * SendFramebufferUpdateRequest.
- * Note: this should only be called by the WriterThread
- */
-
-Bool
-SendFramebufferUpdateRequest(int x, int y, int w, int h, Bool incremental)
-{
- rfbFramebufferUpdateRequestMsg fur;
-
- fur.type = rfbFramebufferUpdateRequest;
- fur.incremental = incremental ? 1 : 0;
- fur.x = Swap16IfLE(x);
- fur.y = Swap16IfLE(y);
- fur.w = Swap16IfLE(w);
- fur.h = Swap16IfLE(h);
-
- if (!WriteExact(rfbsock, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg))
- return False;
-
- return True;
-}
-
-
-/*
- * SendPointerEvent.
- * Note: this should only be called by the WriterThread
- */
-
-Bool
-SendPointerEvent(int x, int y, int buttonMask)
-{
- rfbPointerEventMsg pe;
-
- pe.type = rfbPointerEvent;
- pe.buttonMask = buttonMask;
- if (x < 0) x = 0;
- if (y < 0) y = 0;
- pe.x = Swap16IfLE(x);
- pe.y = Swap16IfLE(y);
- return WriteExact(rfbsock, (char *)&pe, sz_rfbPointerEventMsg);
-}
-
-
-/*
- * SendKeyEvent.
- * Note: this should only be called by the WriterThread
- */
-
-Bool
-SendKeyEvent(CARD32 key, Bool down)
-{
- rfbKeyEventMsg ke;
-
- ke.type = rfbKeyEvent;
- ke.down = down ? 1 : 0;
- ke.key = Swap32IfLE(key);
- return WriteExact(rfbsock, (char *)&ke, sz_rfbKeyEventMsg);
-}
-
-
-/*
- * SendClientCutText.
- * Note: this should only be called by the WriterThread
- */
-
-Bool
-SendClientCutText(const char *str, int len)
-{
- rfbClientCutTextMsg cct;
-
- cct.type = rfbClientCutText;
- cct.length = Swap32IfLE((unsigned int)len);
- return (WriteExact(rfbsock, (char *)&cct, sz_rfbClientCutTextMsg) &&
- WriteExact(rfbsock, str, len));
-}
-
-
-static Bool
-HandleSoftCursorSetImage(rfbSoftCursorSetImage *msg, rfbRectangle *rect)
-{
- int iindex = msg->imageIndex - rfbSoftCursorSetIconOffset;
- PointerImage *pi = &pointerImages[iindex];
- if (iindex >= rfbSoftCursorMaxImages) {
- fprintf(stderr, "Received invalid soft cursor image index %d for SetImage\n", iindex);
- return False;
- }
- EnableClientCursor(0);
-
- if (pi->set && pi->image)
- free(pi->image);
-
- pi->w = rect->w;
- pi->h = rect->h;
- pi->hotX = rect->x;
- pi->hotY = rect->y;
- pi->len = Swap16IfLE(msg->imageLength);
- pi->image = malloc(pi->len);
- if (!pi->image) {
- fprintf(stderr, "out of memory (size=%d)\n", pi->len);
- return False;
- }
-
- if (!ReadFromRFBServer(pi->image, pi->len))
- return False;
- pi->set = 1;
- return True;
-}
-
-/* framebuffer must be locked when calling this!!! */
-static Bool
-PointerMove(unsigned int x, unsigned int y, unsigned int mask,
- int ox, int oy, int ow, int oh)
-{
- int nx, ny, nw, nh;
-
- if (x >= si.framebufferWidth)
- x = si.framebufferWidth - 1;
- if (y >= si.framebufferHeight)
- y = si.framebufferHeight - 1;
-
- cursorX = x;
- cursorY = y;
- drawCursor();
- UnlockFramebuffer();
-
- getBoundingRectCursor(cursorX, cursorY, imageIndex,
- &nx, &ny, &nw, &nh);
-
- if (rectsIntersect(ox, oy, ow, oh, nx, ny, nw, nh)) {
- rectsJoin(&ox, &oy, &ow, &oh, nx, ny, nw, nh);
- SyncScreenRegion(ox, oy, ow, oh);
- }
- else {
- SyncScreenRegion(ox, oy, ow, oh);
- SyncScreenRegion(nx, ny, nw, nh);
- }
-
- postMouseEvent(cursorX, cursorY, mask);
-
- return True;
-}
-
-static Bool
-HandleSoftCursorMove(rfbSoftCursorMove *msg, rfbRectangle *rect)
-{
- int ii, ox, oy, ow, oh;
-
- /* get old cursor rect to know what to update */
- getBoundingRectCursor(cursorX, cursorY, imageIndex,
- &ox, &oy, &ow, &oh);
-
- ii = msg->imageIndex;
- if (ii >= rfbSoftCursorMaxImages) {
- fprintf(stderr, "Received invalid soft cursor image index %d for Move\n", ii);
- return False;
- }
-
- if (!pointerImages[ii].set)
- return True;
-
- LockFramebuffer();
- undrawCursor();
- imageIndex = ii;
-
- return PointerMove(rect->w, rect->h, msg->buttonMask, ox, oy, ow, oh);
-}
-
-static Bool
-HandleCursorPos(unsigned int x, unsigned int y)
-{
- int ox, oy, ow, oh;
-
- /* get old cursor rect to know what to update */
- getBoundingRectCursor(cursorX, cursorY, imageIndex,
- &ox, &oy, &ow, &oh);
- if (!pointerImages[0].set)
- return True;
-
- LockFramebuffer();
- undrawCursor();
- imageIndex = 0;
- return PointerMove(x, y, 0, ox, oy, ow, oh);
-}
-
-/* call only from X11 thread. Only updates framebuffer, does not sync! */
-void DrawCursorX11Thread(int x, int y) {
- int ox, oy, ow, oh, nx, ny, nw, nh;
- if (!pointerImages[0].set)
- return True;
- imageIndex = 0;
-
- if (x >= si.framebufferWidth)
- x = si.framebufferWidth - 1;
- if (y >= si.framebufferHeight)
- y = si.framebufferHeight - 1;
-
- LockFramebuffer();
- getBoundingRectCursor(cursorX, cursorY, imageIndex,
- &ox, &oy, &ow, &oh);
- undrawCursor();
- cursorX = x;
- cursorY = y;
- drawCursor();
- UnlockFramebuffer();
-
- getBoundingRectCursor(cursorX, cursorY, imageIndex,
- &nx, &ny, &nw, &nh);
- if (rectsIntersect(ox, oy, ow, oh, nx, ny, nw, nh)) {
- rectsJoin(&ox, &oy, &ow, &oh, nx, ny, nw, nh);
- SyncScreenRegionX11Thread(ox, oy, ow, oh);
- }
- else {
- SyncScreenRegionX11Thread(ox, oy, ow, oh);
- SyncScreenRegionX11Thread(nx, ny, nw, nh);
- }
-}
-
-/**
- * Create a softcursor in the "compressed alpha" format.
- * Returns the softcursor, caller owns the object
- */
-static void *MakeSoftCursor(int bpp, int cursorWidth, int cursorHeight,
- CARD8 *cursorData, CARD8 *cursorMask, short *imageLen)
-{
- int w = (cursorWidth+7)/8;
- unsigned char *cp, *sp, *dstData;
- int state; /* 0 = transparent, 1 otherwise */
- CARD8 *counter;
- unsigned char bit;
- int i,j;
-
- sp = (unsigned char*)cursorData;
- dstData = cp = (unsigned char*)calloc(cursorWidth*(bpp+2),cursorHeight);
- if (!dstData)
- return 0;
-
- state = 0;
- counter = cp++;
- *counter = 0;
-
- for(j=0;j<cursorHeight;j++)
- for(i=0,bit=0x80;i<cursorWidth;i++,bit=(bit&1)?0x80:bit>>1)
- if(cursorMask[j*w+i/8]&bit) {
- if (state) {
- memcpy(cp,sp,bpp);
- cp += bpp;
- sp += bpp;
- (*counter)++;
- if (*counter == 255) {
- state = 0;
- counter = cp++;
- *counter = 0;
- }
- }
- else {
- state = 1;
- counter = cp++;
- *counter = 1;
- memcpy(cp,sp,bpp);
- cp += bpp;
- sp += bpp;
- }
- }
- else {
- if (!state) {
- (*counter)++;
- if (*counter == 255) {
- state = 1;
- counter = cp++;
- *counter = 0;
- }
- }
- else {
- state = 0;
- counter = cp++;
- *counter = 1;
- }
- sp += bpp;
- }
-
- *imageLen = cp - dstData;
- return (void*) dstData;
-}
-
-
-/*********************************************************************
- * HandleCursorShape(). Support for XCursor and RichCursor shape
- * updates. We emulate cursor operating on the frame buffer (that is
- * why we call it "software cursor").
- ********************************************************************/
-
-static Bool HandleCursorShape(int xhot, int yhot, int width, int height, CARD32 enc)
-{
- int bytesPerPixel;
- size_t bytesPerRow, bytesMaskData;
- rfbXCursorColors rgb;
- CARD32 colors[2];
- CARD8 *ptr, *rcSource, *rcMask;
- void *softCursor;
- int x, y, b;
- int ox, oy, ow, oh;
- PointerImage *pi;
- short imageLen;
-
- bytesPerPixel = myFormat.bitsPerPixel / 8;
- bytesPerRow = (width + 7) / 8;
- bytesMaskData = bytesPerRow * height;
-
- if (width * height == 0)
- return True;
-
- /* Allocate memory for pixel data and temporary mask data. */
-
- rcSource = malloc(width * height * bytesPerPixel);
- if (rcSource == NULL)
- return False;
-
- rcMask = malloc(bytesMaskData);
- if (rcMask == NULL) {
- free(rcSource);
- return False;
- }
-
- /* Read and decode cursor pixel data, depending on the encoding type. */
-
- if (enc == rfbEncodingXCursor) {
- /* Read and convert background and foreground colors. */
- if (!ReadFromRFBServer((char *)&rgb, sz_rfbXCursorColors)) {
- free(rcSource);
- free(rcMask);
- return False;
- }
- colors[0] = RGB24_TO_PIXEL(32, rgb.backRed, rgb.backGreen, rgb.backBlue);
- colors[1] = RGB24_TO_PIXEL(32, rgb.foreRed, rgb.foreGreen, rgb.foreBlue);
-
- /* Read 1bpp pixel data into a temporary buffer. */
- if (!ReadFromRFBServer((char*)rcMask, bytesMaskData)) {
- free(rcSource);
- free(rcMask);
- return False;
- }
-
- /* Convert 1bpp data to byte-wide color indices. */
- ptr = rcSource;
- for (y = 0; y < height; y++) {
- for (x = 0; x < width / 8; x++) {
- for (b = 7; b >= 0; b--) {
- *ptr = rcMask[y * bytesPerRow + x] >> b & 1;
- ptr += bytesPerPixel;
- }
- }
- for (b = 7; b > 7 - width % 8; b--) {
- *ptr = rcMask[y * bytesPerRow + x] >> b & 1;
- ptr += bytesPerPixel;
- }
- }
-
- /* Convert indices into the actual pixel values. */
- switch (bytesPerPixel) {
- case 1:
- for (x = 0; x < width * height; x++)
- rcSource[x] = (CARD8)colors[rcSource[x]];
- break;
- case 2:
- for (x = 0; x < width * height; x++)
- ((CARD16 *)rcSource)[x] = (CARD16)colors[rcSource[x * 2]];
- break;
- case 4:
- for (x = 0; x < width * height; x++)
- ((CARD32 *)rcSource)[x] = colors[rcSource[x * 4]];
- break;
- }
-
-
- } else {
- if (!ReadFromRFBServer((char *)rcSource, width * height * bytesPerPixel)) {
- free(rcSource);
- free(rcMask);
- return False;
- }
- }
-
- /* Read mask data. */
-
- if (!ReadFromRFBServer((char*)rcMask, bytesMaskData)) {
- free(rcSource);
- free(rcMask);
- return False;
- }
-
-
- /* Set the soft cursor. */
- softCursor = MakeSoftCursor(bytesPerPixel, width, height, rcSource, rcMask, &imageLen);
- if (!softCursor) {
- free(rcMask);
- free(rcSource);
- return False;
- }
-
- /* get old cursor rect to know what to update */
- EnableClientCursor(1);
- LockFramebuffer();
- getBoundingRectCursor(cursorX, cursorY, imageIndex,
- &ox, &oy, &ow, &oh);
- undrawCursor();
-
- pi = &pointerImages[0];
- if (pi->set && pi->image)
- free(pi->image);
- pi->w = width;
- pi->h = height;
- pi->hotX = xhot;
- pi->hotY = yhot;
- pi->len = imageLen;
- pi->image = softCursor;
- pi->set = 1;
-
- imageIndex = 0;
-
- free(rcMask);
- free(rcSource);
-
- return PointerMove(cursorX, cursorY, 0, ox, oy, ow, oh);
-}
-
-
-
-/*
- * HandleRFBServerMessage.
- */
-
-Bool
-HandleRFBServerMessage()
-{
- rfbServerToClientMsg msg;
- if (!ReadFromRFBServer((char *)&msg, 1))
- return False;
-
- switch (msg.type) {
-
- case rfbSetColourMapEntries:
- {
- int i;
- CARD16 rgb[3];
- XColor xc;
-
- if (!ReadFromRFBServer(((char *)&msg) + 1,
- sz_rfbSetColourMapEntriesMsg - 1))
- return False;
-
- msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour);
- msg.scme.nColours = Swap16IfLE(msg.scme.nColours);
-
- for (i = 0; i < msg.scme.nColours; i++) {
- if (!ReadFromRFBServer((char *)rgb, 6))
- return False;
- xc.pixel = msg.scme.firstColour + i;
- xc.red = Swap16IfLE(rgb[0]);
- xc.green = Swap16IfLE(rgb[1]);
- xc.blue = Swap16IfLE(rgb[2]);
- xc.flags = DoRed|DoGreen|DoBlue;
- /* Disable colormaps
- lockTQt();
- XStoreColor(dpy, cmap, &xc);
- unlockTQt();
- */
- }
-
- break;
- }
-
- case rfbFramebufferUpdate:
- {
- rfbFramebufferUpdateRectHeader rect;
- int linesToRead;
- int bytesPerLine;
- int i;
-
- announceIncrementalUpdateRequest();
-
- if (!ReadFromRFBServer(((char *)&msg.fu) + 1,
- sz_rfbFramebufferUpdateMsg - 1))
- return False;
-
- msg.fu.nRects = Swap16IfLE(msg.fu.nRects);
-
- for (i = 0; i < msg.fu.nRects; i++) {
- if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader))
- return False;
-
- rect.encoding = Swap32IfLE(rect.encoding);
- if (rect.encoding == rfbEncodingLastRect)
- break;
-
- rect.r.x = Swap16IfLE(rect.r.x);
- rect.r.y = Swap16IfLE(rect.r.y);
- rect.r.w = Swap16IfLE(rect.r.w);
- rect.r.h = Swap16IfLE(rect.r.h);
-
- if (rect.encoding == rfbEncodingPointerPos) {
- if (!HandleCursorPos(rect.r.x, rect.r.y)) {
- return False;
- }
- continue;
- }
-
- if (rect.encoding == rfbEncodingXCursor ||
- rect.encoding == rfbEncodingRichCursor) {
- if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h,
- rect.encoding)) {
- return False;
- }
- continue;
- }
-
- if ((rect.r.x + rect.r.w > si.framebufferWidth) ||
- (rect.r.y + rect.r.h > si.framebufferHeight))
- {
- fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n",
- rect.r.w, rect.r.h, rect.r.x, rect.r.y);
- return False;
- }
-
- if ((rect.r.h * rect.r.w == 0) &&
- (rect.encoding != rfbEncodingSoftCursor)) {
- fprintf(stderr,"Zero size rect - ignoring\n");
- continue;
- }
-
- switch (rect.encoding) {
-
- case rfbEncodingRaw:
-
- bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8;
- linesToRead = BUFFER_SIZE / bytesPerLine;
-
- while (rect.r.h > 0) {
- if (linesToRead > rect.r.h)
- linesToRead = rect.r.h;
-
- if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead))
- return False;
-
- CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w,
- linesToRead);
-
- rect.r.h -= linesToRead;
- rect.r.y += linesToRead;
-
- }
- break;
-
- case rfbEncodingCopyRect:
- {
- rfbCopyRect cr;
-
- if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect))
- return False;
-
- cr.srcX = Swap16IfLE(cr.srcX);
- cr.srcY = Swap16IfLE(cr.srcY);
-
- CopyArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h, rect.r.x, rect.r.y);
-
- break;
- }
-
- case rfbEncodingHextile:
- {
- switch (myFormat.bitsPerPixel) {
- case 8:
- if (!HandleHextile8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return False;
- break;
- case 16:
- if (!HandleHextile16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return False;
- break;
- case 32:
- if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return False;
- break;
- }
- break;
- }
-
- case rfbEncodingZlib:
- {
- switch (myFormat.bitsPerPixel) {
- case 8:
- if (!HandleZlib8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return False;
- break;
- case 16:
- if (!HandleZlib16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return False;
- break;
- case 32:
- if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return False;
- break;
- }
- break;
- }
-
- case rfbEncodingTight:
- {
- switch (myFormat.bitsPerPixel) {
- case 8:
- if (!HandleTight8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return False;
- break;
- case 16:
- if (!HandleTight16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return False;
- break;
- case 32:
- if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
- return False;
- break;
- }
- break;
- }
-
- case rfbEncodingSoftCursor:
- {
- rfbSoftCursorMsg scmsg;
- if (!ReadFromRFBServer((char *)&scmsg, 1))
- return False;
- if (scmsg.type < rfbSoftCursorMaxImages) {
- if (!ReadFromRFBServer(((char *)&scmsg)+1,
- sizeof(rfbSoftCursorMove)- 1))
- return False;
- if (!HandleSoftCursorMove(&scmsg.move, &rect.r))
- return False;
- }
- else if((scmsg.type >= rfbSoftCursorSetIconOffset) &&
- (scmsg.type < rfbSoftCursorSetIconOffset+rfbSoftCursorMaxImages)) {
- if (!ReadFromRFBServer(((char *)&scmsg)+1,
- sizeof(rfbSoftCursorSetImage)- 1))
- return False;
- if (!HandleSoftCursorSetImage(&scmsg.setImage, &rect.r))
- return False;
- }
- else {
- fprintf(stderr,"Unknown soft cursor image index %d\n",
- (int)scmsg.type);
- return False;
- }
- break;
- }
-
- default:
- fprintf(stderr,"Unknown rect encoding %d\n",
- (int)rect.encoding);
- return False;
- }
-
- }
-
- queueIncrementalUpdateRequest();
-
- break;
- }
-
- case rfbBell:
- {
- beep();
- break;
- }
-
- case rfbServerCutText:
- {
- char *serverCutText;
- if (!ReadFromRFBServer(((char *)&msg) + 1,
- sz_rfbServerCutTextMsg - 1))
- return False;
-
- msg.sct.length = Swap32IfLE(msg.sct.length);
-
- if (msg.sct.length > MAX_CUTBUFFER) {
- fprintf(stderr, "Cutbuffer too long.\n");
- return False;
- }
-
- serverCutText = malloc(msg.sct.length+1);
-
- if (!serverCutText) {
- fprintf(stderr, "Out-of-memory, cutbuffer too long.\n");
- return False;
- }
-
- if (!ReadFromRFBServer(serverCutText, msg.sct.length))
- return False;
-
- serverCutText[msg.sct.length] = 0;
- newServerCut(serverCutText, msg.sct.length); /* takes ownership of serverCutText */
-
- break;
- }
-
- default:
- fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type);
- return False;
- }
-
- return True;
-}
-
-
-#define GET_PIXEL8(pix, ptr) ((pix) = *(ptr)++)
-
-#define GET_PIXEL16(pix, ptr) (((CARD8*)&(pix))[0] = *(ptr)++, \
- ((CARD8*)&(pix))[1] = *(ptr)++)
-
-#define GET_PIXEL32(pix, ptr) (((CARD8*)&(pix))[0] = *(ptr)++, \
- ((CARD8*)&(pix))[1] = *(ptr)++, \
- ((CARD8*)&(pix))[2] = *(ptr)++, \
- ((CARD8*)&(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 BPP 8
-#include "hextile.c"
-#include "zlib.c"
-#include "tight.c"
-#undef BPP
-#define BPP 16
-#include "hextile.c"
-#include "zlib.c"
-#include "tight.c"
-#undef BPP
-#define BPP 32
-#include "hextile.c"
-#include "zlib.c"
-#include "tight.c"
-#undef BPP
-
-
-/*
- * PrintPixelFormat.
- */
-
-void
-PrintPixelFormat(format)
- rfbPixelFormat *format;
-{
- if (format->bitsPerPixel == 1) {
- fprintf(stderr," Single bit per pixel.\n");
- fprintf(stderr,
- " %s significant bit in each byte is leftmost on the screen.\n",
- (format->bigEndian ? "Most" : "Least"));
- } else {
- fprintf(stderr," %d bits per pixel.\n",format->bitsPerPixel);
- if (format->bitsPerPixel != 8) {
- fprintf(stderr," %s significant byte first in each pixel.\n",
- (format->bigEndian ? "Most" : "Least"));
- }
- if (format->trueColour) {
- fprintf(stderr," True colour: max red %d green %d blue %d",
- format->redMax, format->greenMax, format->blueMax);
- fprintf(stderr,", shift red %d green %d blue %d\n",
- format->redShift, format->greenShift, format->blueShift);
- } else {
- fprintf(stderr," Colour map (not true colour).\n");
- }
- }
-}
-
-static long
-ReadCompactLen (void)
-{
- long len;
- CARD8 b;
-
- if (!ReadFromRFBServer((char *)&b, 1))
- return -1;
- len = (int)b & 0x7F;
- if (b & 0x80) {
- if (!ReadFromRFBServer((char *)&b, 1))
- return -1;
- len |= ((int)b & 0x7F) << 7;
- if (b & 0x80) {
- if (!ReadFromRFBServer((char *)&b, 1))
- return -1;
- len |= ((int)b & 0xFF) << 14;
- }
- }
- return len;
-}
-
-void freeRFBProtoResources() {
- int i;
-
- if (desktopName)
- free(desktopName);
- if (raw_buffer)
- free(raw_buffer);
- for (i = 0; i < rfbSoftCursorMaxImages; i++)
- if (pointerImages[i].set && pointerImages[i].image)
- free(pointerImages[i].image);
-
- raw_buffer_size = -1;
- raw_buffer = NULL;
- decompStreamInited = False;
- zlibStreamActive[0] = False;
- zlibStreamActive[1] = False;
- zlibStreamActive[2] = False;
- zlibStreamActive[3] = False;
- for (i = 0; i < rfbSoftCursorMaxImages; i++)
- pointerImages[i].set = 0;
- imageIndex = -1;
-}
-
-void freeResources() {
- freeSocketsResources();
- freeDesktopResources();
- freeRFBProtoResources();
-}
-
-/*
- * JPEG source manager functions for JPEG decompression in Tight decoder.
- */
-
-static struct jpeg_source_mgr jpegSrcManager;
-static JOCTET *jpegBufferPtr;
-static size_t jpegBufferLen;
-
-static void
-JpegInitSource(j_decompress_ptr cinfo)
-{
- jpegError = False;
-}
-
-static boolean
-JpegFillInputBuffer(j_decompress_ptr cinfo)
-{
- jpegError = True;
- jpegSrcManager.bytes_in_buffer = jpegBufferLen;
- jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr;
-
- return TRUE;
-}
-
-static void
-JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes)
-{
- if (num_bytes < 0 || num_bytes > jpegSrcManager.bytes_in_buffer) {
- jpegError = True;
- jpegSrcManager.bytes_in_buffer = jpegBufferLen;
- jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr;
- } else {
- jpegSrcManager.next_input_byte += (size_t) num_bytes;
- jpegSrcManager.bytes_in_buffer -= (size_t) num_bytes;
- }
-}
-
-static void
-JpegTermSource(j_decompress_ptr cinfo)
-{
- /* No work necessary here. */
-}
-
-static void
-JpegSetSrcManager(j_decompress_ptr cinfo, CARD8 *compressedData,
- int compressedLen)
-{
- jpegBufferPtr = (JOCTET *)compressedData;
- jpegBufferLen = (size_t)compressedLen;
-
- jpegSrcManager.init_source = JpegInitSource;
- jpegSrcManager.fill_input_buffer = JpegFillInputBuffer;
- jpegSrcManager.skip_input_data = JpegSkipInputData;
- jpegSrcManager.resync_to_restart = jpeg_resync_to_restart;
- jpegSrcManager.term_source = JpegTermSource;
- jpegSrcManager.next_input_byte = jpegBufferPtr;
- jpegSrcManager.bytes_in_buffer = jpegBufferLen;
-
- cinfo->src = &jpegSrcManager;
-}
-