home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory
- *
- * Copyright (C) 1998 International Computer Science Institute (ICSI)
- *
- * 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.
- */
-
- #include "palmVNC.h"
- #include "palmVNCRsc.h"
- #include "vncauth.h"
-
- static Bool HandleHextileEncoding8(int x, int y, int w, int h);
-
- int rfbsock = 0;
- char *desktopName;
- Bool useBGR233 = True;
- int requestedDepth = 0;
- Bool debug = False;
-
- rfbPixelFormat myFormat;
- rfbServerInitMsg si;
- Bool sendUpdateRequest;
-
- PRFBViewport palmFB;
-
- int endianTest = 1;
-
-
- /* note that the CoRRE encoding uses this buffer and assumes it is big enough
- to hold 255 * 255 * 32 bits -> 260100 bytes. 640*480 = 307200 bytes */
- /* also hextile assumes it is big enough to hold 16 * 16 * 32 bits */
-
- #define BUFFER_SIZE (16*16) // that works with BGR233 only!
- static unsigned char buffer[BUFFER_SIZE];
-
-
- /******************************************************************
- * ConnectToRFBServer
- *
- * connects on the networkl level
- *****************************************************************/
- Bool ConnectToRFBServer (char *hostname, int port)
- {
- unsigned long host = 0;
-
- if (!StringToIPAddr (hostname, &host)) {
- printf ("Couldn't convert \"%s\" to a real host address\n", hostname);
- return False;
- }
-
- rfbsock = ConnectToTcpAddr (host, port);
-
- if (rfbsock < 0) {
- printf ("Unable to connect to the VNC server \"%s\", port %d\n",
- hostname, port);
- return False;
- }
-
- printf ("Network connection established\n");
- return True;
- }
-
-
- /******************************************************************
- * InitialiseRFBConnection.
- *
- * connects on the VNC protocol level, i.e. handshake, authentication, etc
- *****************************************************************/
-
- Bool InitialiseRFBConnection (int sock)
- {
- rfbProtocolVersionMsg pv;
- int majorV,minorV;
- Bool authWillWork = True;
- CARD32 authScheme, reasonLen;
- char *reason;
- CARD32 authResult;
- CARD8 challenge[CHALLENGESIZE];
- rfbClientInitMsg ci;
- char testVer[8];
-
- if (!ReadExact(sock, (unsigned char*)pv, sz_rfbProtocolVersionMsg))
- return False;
-
- PostProgressMessage ("Handshaking...", 0, 0);
-
- errorMessageFromReadExact = True;
-
- pv[sz_rfbProtocolVersionMsg] = 0;
-
- majorV = rfbProtocolMajorVersion;
- minorV = rfbProtocolMinorVersion;
-
- StrPrintF (testVer, "00%d.00%d\n", majorV, minorV);
-
- if (StrStr (pv, "RFB") == 0) {
- printf ("Not a valid VNC server\n");
- return False;
- }
-
- printf ("VNC server supports protocol version: %s\nViewer supports %d.%d\n",
- pv, majorV, minorV);
-
- if (StrStr (pv, testVer) == 0) {
- // if server is before 3.3 authentication won't work
- authWillWork = False;
- }
-
- StrPrintF (pv, rfbProtocolVersionFormat, majorV, minorV);
-
- if (!WriteExact(sock, (unsigned char*)pv, sz_rfbProtocolVersionMsg)) return False;
-
- if (!ReadExact(sock, (unsigned char*)&authScheme, 4)) return False;
-
- authScheme = Swap32IfLE(authScheme);
-
- switch (authScheme) {
-
- case rfbConnFailed:
- if (!ReadExact(sock, (unsigned char*)&reasonLen, 4)) return False;
- reasonLen = Swap32IfLE(reasonLen);
-
- if ((reason = MemPtrNew (reasonLen)) == 0) {
- printf ("ERROR: cannot allocate mem ptr\n");
- return false;
- }
-
- if (!ReadExact(sock, (unsigned char*)reason, (int)reasonLen)) return False;
-
- printf ("VNC connection failed: %s\n", reason);
-
- MemPtrFree (reason);
-
- return False;
-
- case rfbNoAuth:
- printf ("No authentication needed\n");
- break;
-
- case rfbVncAuth:
- if (!authWillWork) {
- printf (
- "\nVNC server uses the old authentication scheme.\n"
- "You should kill your old desktop(s) and restart.\n"
- "If you really need to connect to this desktop use "
- "vncviewer3.2\n\n");
- return False;
- }
-
- if (!ReadExact(sock, (unsigned char*)challenge, CHALLENGESIZE)) return False;
-
- vncEncryptBytes(challenge, pref.server.password);
-
- if (!WriteExact(sock, (unsigned char*)challenge, CHALLENGESIZE)) return False;
-
- if (!ReadExact(sock, (unsigned char*)&authResult, 4)) return False;
-
- authResult = Swap32IfLE(authResult);
-
- switch (authResult) {
- case rfbVncAuthOK:
- printf ("VNC authentication succeeded\n");
- break;
- case rfbVncAuthFailed:
- printf ("\nVNC authentication failed\n\n");
- return False;
- case rfbVncAuthTooMany:
- printf ("VNC authentication failed - too many tries\n");
- return False;
- default:
- printf ("Unknown VNC authentication result: %d\n", (int)authResult);
- return False;
- }
- break;
- default:
- printf ("Unknown authentication scheme from VNC server: %d\n",
- (int)authScheme);
- return False;
- }
-
- ci.shared = (pref.server.sharedDesktop ? 1 : 0);
-
- if (!WriteExact(sock, (unsigned char*)&ci, sz_rfbClientInitMsg)) return False;
-
- if (!ReadExact(sock, (unsigned char*)&si, sz_rfbServerInitMsg)) return False;
-
- 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);
-
- palmFB.remote.w = si.framebufferWidth;
- palmFB.remote.h = si.framebufferHeight;
-
- if ((desktopName = MemPtrNew (si.nameLength + 1)) == 0) {
- printf ("ERROR: cannot allocate mem ptr\n");
- return false;
- }
-
- if (!ReadExact(sock, (unsigned char*)desktopName, (int)si.nameLength)) return False;
-
- desktopName[si.nameLength] = 0;
-
- printf ("Desktop size: %dx%d\n", si.framebufferWidth, si.framebufferHeight);
- printf ("Desktop name \"%s\"\n", desktopName);
-
- MemPtrFree (desktopName);
-
- printf ("Connected to VNC server, using protocol version %d.%d\n",
- rfbProtocolMajorVersion, rfbProtocolMinorVersion);
-
- return True;
- }
-
-
- /******************************************************************
- * SetFormatAndEncodings
- *****************************************************************/
- Bool SetFormatAndEncodings()
- {
- rfbSetPixelFormatMsg spf;
- unsigned char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4];
- rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf;
- CARD32 *encs = (CARD32 *)(&buf[sz_rfbSetEncodingsMsg]);
- int len = 0;
-
- spf.type = rfbSetPixelFormat;
- 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, (unsigned char*)&spf, sz_rfbSetPixelFormatMsg))
- return False;
-
- se->type = rfbSetEncodings;
- se->nEncodings = 0;
-
- // VM PalmVNC currently supports only Hextile encoding */
- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile);
-
- len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
-
- se->nEncodings = Swap16IfLE(se->nEncodings);
-
- if (!WriteExact(rfbsock, buf, len)) return False;
-
- return True;
- }
-
-
- /******************************************************************
- * SendIncrementalFramebufferUpdateRequest
- *****************************************************************/
- Bool SendIncrementalFramebufferUpdateRequest()
- {
-
- return SendFramebufferUpdateRequest((int)palmFB.virtual.x,
- (int)palmFB.virtual.y,
- (int)palmFB.virtual.w,
- (int)palmFB.virtual.h,
- true);
- }
-
-
- /******************************************************************
- * SendFramebufferUpdateRequest.
- *****************************************************************/
- Bool SendFramebufferUpdateRequest(int x, int y, int w, int h, int incremental)
- {
- rfbFramebufferUpdateRequestMsg fur;
-
- #ifdef DEBUG_VNC_CODING
- printf ("rect req: %dx%d (%d,%d) inc %d\n",
- w, h, x, y, incremental);
- #endif
-
- 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, (unsigned char*)&fur,
- sz_rfbFramebufferUpdateRequestMsg))
- return False;
-
- // we do this in the event loop, it was: sendUpdateRequest = false;
-
- return True;
- }
-
-
- /******************************************************************
- * SendPointerEvent.
- *****************************************************************/
- 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, (unsigned char*)&pe, sz_rfbPointerEventMsg);
- }
-
-
- /******************************************************************
- * SendKeyEvent.
- *****************************************************************/
- Bool SendKeyEvent(CARD32 key, int down)
- {
- rfbKeyEventMsg ke;
-
- ke.type = rfbKeyEvent;
- ke.down = down ? 1 : 0;
- ke.key = Swap32IfLE(key);
- return WriteExact(rfbsock, (unsigned char*)&ke, sz_rfbKeyEventMsg);
- }
-
-
- /******************************************************************
- * SendClientCutText.
- *****************************************************************/
- Bool SendClientCutText(char *str, int len)
- {
- rfbClientCutTextMsg cct;
-
- #ifdef DEBUG_VNC
- printf ("%d bytes in CutText sent:\n", len);
- printf ("\t\"%s\"\n", str);
- #endif
-
- cct.type = rfbClientCutText;
- cct.length = Swap32IfLE (len);
-
- return (WriteExact(rfbsock, (unsigned char*)&cct,
- sz_rfbClientCutTextMsg) &&
- WriteExact(rfbsock, (unsigned char*)str, len));
- }
-
-
- /******************************************************************
- * HandleRFBServerMessage.
- *****************************************************************/
- Bool HandleRFBServerMessage()
- {
- rfbServerToClientMsg msg;
-
- if (!ReadExact(rfbsock, (unsigned char*)&msg, 1))
- return False;
-
- switch (msg.type) {
-
- case rfbSetColourMapEntries:
- {
- if (!ReadExact(rfbsock, ((unsigned char*)&msg) + 1,
- sz_rfbSetColourMapEntriesMsg - 1))
- return False;
-
- #ifdef DEBUG_VNC_CODING
- printf ("-> colormap: n %d, NOT SUPPORTED YET\n", msg.scme.nColours);
- #endif
- break;
- }
-
- case rfbFramebufferUpdate:
- {
- rfbFramebufferUpdateRectHeader rect;
- int i;
-
- if (!ReadExact(rfbsock, ((unsigned char*)&msg.fu) + 1,
- sz_rfbFramebufferUpdateMsg - 1))
- return False;
-
- msg.fu.nRects = Swap16IfLE(msg.fu.nRects);
-
- #ifdef DEBUG_VNC_CODING
- printf (" %d nRects in a msg\n", msg.fu.nRects);
- #endif
-
- for (i = 0; i < msg.fu.nRects; i++) {
-
- if (!ReadExact(rfbsock, (unsigned char*)&rect,
- sz_rfbFramebufferUpdateRectHeader))
- return False;
-
- 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);
-
- rect.encoding = Swap32IfLE(rect.encoding);
-
- if ((rect.r.x + rect.r.w > si.framebufferWidth) ||
- (rect.r.y + rect.r.h > si.framebufferHeight))
- {
- printf ("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) {
- printf ("zero size rect - ignoring\n");
- continue;
- }
-
- switch (rect.encoding) {
-
- case rfbEncodingRaw:
- #ifdef DEBUG_VNC_CODING
- printf ("->raw encoding: rec %dx%d, NOT SUPPORTED\n",
- rect.r.h, rect.r.w);
- #endif
- return False;
- break;
-
- case rfbEncodingCopyRect:
- {
- #ifdef DEBUG_VNC_CODING
- printf ("-> copy rect, rect %dx%d, NOT SUPPORTED\n",
- rect.r.h, rect.r.w);
- #endif
- return False;
- break;
- }
-
- case rfbEncodingRRE:
- {
-
- #ifdef DEBUG_VNC_CODING
- printf ("-> REE encoding, NOT SUPPORTED\n");
- #endif
- return False;
- }
-
- case rfbEncodingCoRRE:
- {
- #ifdef DEBUG_VNC_CODING
- printf ("-> CoREE encoding, NOT SUPPORTED\n");
- #endif
- return False;
- }
-
- case rfbEncodingHextile:
- {
- #ifdef DEBUG_VNC_CODING
- printf ("-> Hext r %dx%d (%d,%d)\n",
- rect.r.w, rect.r.h, rect.r.x, rect.r.y);
- #endif
- switch (myFormat.bitsPerPixel) {
- case 8:
- if (!HandleHextileEncoding8((int)rect.r.x, (int)rect.r.y,
- (int)rect.r.w, (int)rect.r.h))
- return False;
- break;
- default:
- #ifdef DEBUG_VNC_CODING
- printf ("-> Hextile %d bit, NOT SUPPORTED\n", myFormat.bitsPerPixel);
- #endif
- return False;
- }
- break;
- }
-
- default:
- printf ("unknown rect encoding %d\n", (int)rect.encoding);
- return False;
- }
- }
-
- sendUpdateRequest = True;
-
- break;
- }
-
- case rfbBell:
- SndPlaySystemSound ((SndSysBeepType)sndInfo);
- break;
-
- case rfbServerCutText:
- {
- char *str;
- Word length = 0;
- Word buttonID = 0;
-
- if (!ReadExact(rfbsock, ((unsigned char*)&msg) + 1,
- sz_rfbServerCutTextMsg - 1))
- return False;
-
- msg.sct.length = Swap32IfLE(msg.sct.length);
-
- str = MemPtrNew (msg.sct.length);
-
- if (!ReadExact(rfbsock, (unsigned char*)str, msg.sct.length))
- return False;
-
- #ifdef DEBUG_VNC
- printf ("%d bytes in CutText received\n", (Word)msg.sct.length);
- printf ("\t\"%s\"\n", str);
- #endif
- if (msg.sct.length > cbdMaxTextLength)
- length = cbdMaxTextLength;
- else
- length = msg.sct.length;
-
- if ((buttonID = FrmCustomAlert (ClipboardAlert, str, " ", " ")) == 0) { // the firt button, "OK"
- ClipboardAddItem (clipboardText, str, length);
- #ifdef DEBUG_VNC
- printf ("CutText copied into clipboard\n");
- #endif
- }
-
- MemPtrFree (str);
-
- break;
- }
-
- default:
- printf ("unknown message type %d from VNC server\n", msg.type);
- return false;
- }
-
- return true;
- }
-
-
- #define GET_PIXEL8(pix,ptr) ((pix)=*(ptr)++)
-
- static Bool HandleHextileEncoding8(int rx, int ry, int rw, int rh)
- {
- CARD8 bg, fg;
- int i;
- CARD8 *ptr;
- short x, y;
- unsigned short w, h;
- short sx, sy;
- unsigned short sw, sh;
- CARD8 subencoding;
- CARD8 nSubrects;
-
- #ifdef DEBUG_VNC_CODING
- printf ("hextile %d and %d\n", ry+rh, rx+rw);
- #endif
-
- for (y = ry; y < ry+rh; y += 16) {
- PostProgressMessage ("Processing...", y, ry+rh);
- for (x = rx; x < rx+rw; x += 16) {
- w = h = 16;
- if (rx+rw - x < 16)
- w = rx+rw - x;
- if (ry+rh - y < 16)
- h = ry+rh - y;
-
- if (!ReadExact(rfbsock, (unsigned char*)&subencoding, 1))
- return False;
-
- if (subencoding & rfbHextileRaw) {
- if (!ReadExact(rfbsock, buffer, (int)(w * h)))
- return False;
-
- CopyDataToScreen ((CARD8 *)buffer, x, y, w, h);
- continue;
- }
-
- if (subencoding & rfbHextileBackgroundSpecified)
- if (!ReadExact(rfbsock, (unsigned char*)&bg, 1))
- return False;
- /*
- #ifdef DEBUG_VNC_CODING
- printf (" spec bg %d r %dx%d (%d,%d)\n",
- bg, w, h, x, y);
- #endif
- */
- DrawVirtualFilledRectangle (BGR233ToPixel[bg], x, y, w, h, true);
-
- if (subencoding & rfbHextileForegroundSpecified)
- if (!ReadExact(rfbsock, (unsigned char*)&fg, 1))
- return False;
-
- if (!(subencoding & rfbHextileAnySubrects)) {
- continue;
- }
-
- if (!ReadExact(rfbsock, (unsigned char*)&nSubrects, 1))
- return False;
-
- ptr = (CARD8 *)buffer;
-
- if (subencoding & rfbHextileSubrectsColoured) {
- if (!ReadExact(rfbsock, buffer, nSubrects * (2 + 1)))
- return False;
-
- #ifdef DEBUG_VNC_CODING
- printf (" %d subr. colored\n", nSubrects);
- #endif
-
- for (i = 0; i < nSubrects; i++) {
- GET_PIXEL8(fg, ptr);
- sx = rfbHextileExtractX(*ptr);
- sy = rfbHextileExtractY(*ptr);
- ptr++;
- sw = rfbHextileExtractW(*ptr);
- sh = rfbHextileExtractH(*ptr);
- ptr++;
- /*
- #ifdef DEBUG_VNC_CODING
- printf (" color %d\n", fg);
- #endif
- */
- DrawVirtualFilledRectangle (BGR233ToPixel[fg],
- x+sx, y+sy, sw, sh, true);
- }
-
- } else {
- if (!ReadExact(rfbsock, buffer, nSubrects * 2))
- return False;
-
- for (i = 0; i < nSubrects; i++) {
- sx = rfbHextileExtractX(*ptr);
- sy = rfbHextileExtractY(*ptr);
- ptr++;
- sw = rfbHextileExtractW(*ptr);
- sh = rfbHextileExtractH(*ptr);
- ptr++;
- /*
- #ifdef DEBUG_VNC_CODING
- printf (" color %d\n", fg);
- #endif
- */
- DrawVirtualFilledRectangle (BGR233ToPixel[fg],
- x+sx, y+sy, sw, sh, true);
- }
- }
- }
- }
-
- return True;
- }
-
-