]> git.sesse.net Git - rdpsrv/blobdiff - Xserver/programs/Xserver/hw/vnc/rfbserver.c
Removed Xserver/ directory, it does nothing useful ATM.
[rdpsrv] / Xserver / programs / Xserver / hw / vnc / rfbserver.c
diff --git a/Xserver/programs/Xserver/hw/vnc/rfbserver.c b/Xserver/programs/Xserver/hw/vnc/rfbserver.c
deleted file mode 100644 (file)
index b959d0a..0000000
+++ /dev/null
@@ -1,1221 +0,0 @@
-/*
- * rfbserver.c - deal with server-side of the RFB protocol.
- */
-
-/*
- *  Copyright (C) 2002-2003 RealVNC Ltd.
- *  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.
- */
-
-/* Use ``#define CORBA'' to enable CORBA control interface */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <pwd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include "windowstr.h"
-#include "rfb.h"
-#include "input.h"
-#include "mipointer.h"
-#include "sprite.h"
-
-#ifdef CORBA
-#include <vncserverctrl.h>
-#endif
-
-char updateBuf[UPDATE_BUF_SIZE];
-int ublen;
-
-rfbClientPtr rfbClientHead = NULL;
-rfbClientPtr pointerClient = NULL;  /* Mutex for pointer events */
-
-Bool rfbAlwaysShared = FALSE;
-Bool rfbNeverShared = FALSE;
-Bool rfbDontDisconnect = FALSE;
-int rfbMaxRects = 50;
-
-static rfbClientPtr rfbNewClient(int sock);
-static void rfbProcessClientProtocolVersion(rfbClientPtr cl);
-static void rfbProcessClientNormalMessage(rfbClientPtr cl);
-static void rfbProcessClientInitMessage(rfbClientPtr cl);
-static Bool rfbSendCopyRegion(rfbClientPtr cl, RegionPtr reg, int dx, int dy);
-
-
-/*
- * rfbNewClientConnection is called from sockets.c when a new connection
- * comes in.
- */
-
-void
-rfbNewClientConnection(sock)
-    int sock;
-{
-    rfbClientPtr cl;
-
-    cl = rfbNewClient(sock);
-
-#ifdef CORBA
-    if (cl != NULL)
-       newConnection(cl, (KEYBOARD_DEVICE|POINTER_DEVICE), 1, 1, 1);
-#endif
-}
-
-
-/*
- * rfbReverseConnection is called by the CORBA stuff to make an outward
- * connection to a "listening" RFB client.
- */
-
-rfbClientPtr
-rfbReverseConnection(host, port)
-    char *host;
-    int port;
-{
-    int sock;
-    rfbClientPtr cl;
-
-    if ((sock = rfbConnect(host, port)) < 0)
-       return (rfbClientPtr)NULL;
-
-    cl = rfbNewClient(sock);
-
-    if (cl) {
-       cl->reverseConnection = TRUE;
-    }
-
-    return cl;
-}
-
-
-/*
- * rfbNewClient is called when a new connection has been made by whatever
- * means.
- */
-
-static rfbClientPtr
-rfbNewClient(sock)
-    int sock;
-{
-    rfbProtocolVersionMsg pv;
-    rfbClientPtr cl;
-    BoxRec box;
-    struct sockaddr_in addr;
-    unsigned int addrlen = sizeof(struct sockaddr_in);
-
-    if (rfbClientHead == NULL) {
-       /* no other clients - make sure we don't think any keys are pressed */
-       KbdReleaseAllKeys();
-    } else {
-       rfbLog("  (other clients");
-       for (cl = rfbClientHead; cl; cl = cl->next) {
-           fprintf(stderr," %s",cl->host);
-       }
-       fprintf(stderr,")\n");
-    }
-
-    cl = (rfbClientPtr)xalloc(sizeof(rfbClientRec));
-
-    cl->sock = sock;
-    getpeername(sock, (struct sockaddr *)&addr, &addrlen);
-    cl->host = strdup(inet_ntoa(addr.sin_addr));
-
-    cl->state = RFB_PROTOCOL_VERSION;
-
-    cl->reverseConnection = FALSE;
-    cl->readyForSetColourMapEntries = FALSE;
-    cl->useCopyRect = FALSE;
-    cl->preferredEncoding = rfbEncodingRaw;
-    cl->correMaxWidth = 48;
-    cl->correMaxHeight = 48;
-    cl->zrleData = 0;
-
-    REGION_INIT(pScreen,&cl->copyRegion,NullBox,0);
-    cl->copyDX = 0;
-    cl->copyDY = 0;
-
-    box.x1 = box.y1 = 0;
-    box.x2 = rfbScreen.width;
-    box.y2 = rfbScreen.height;
-    REGION_INIT(pScreen,&cl->modifiedRegion,&box,0);
-
-    REGION_INIT(pScreen,&cl->requestedRegion,NullBox,0);
-
-    cl->deferredUpdateScheduled = FALSE;
-    cl->deferredUpdateTimer = NULL;
-
-    cl->format = rfbServerFormat;
-    cl->translateFn = rfbTranslateNone;
-    cl->translateLookupTable = NULL;
-
-    cl->next = rfbClientHead;
-    rfbClientHead = cl;
-
-    rfbResetStats(cl);
-
-    sprintf(pv,rfbProtocolVersionFormat,rfbProtocolMajorVersion,
-           rfbProtocolMinorVersion);
-
-    if (WriteExact(sock, pv, sz_rfbProtocolVersionMsg) < 0) {
-       rfbLogPerror("rfbNewClient: write");
-       rfbCloseSock(sock);
-       return NULL;
-    }
-
-    return cl;
-}
-
-
-/*
- * rfbClientConnectionGone is called from sockets.c just after a connection
- * has gone away.
- */
-
-void
-rfbClientConnectionGone(sock)
-    int sock;
-{
-    rfbClientPtr cl, prev;
-
-    for (prev = NULL, cl = rfbClientHead; cl; prev = cl, cl = cl->next) {
-       if (sock == cl->sock)
-           break;
-    }
-
-    if (!cl) {
-       rfbLog("rfbClientConnectionGone: unknown socket %d\n",sock);
-       return;
-    }
-
-    rfbLog("Client %s gone\n",cl->host);
-    free(cl->host);
-
-    if (pointerClient == cl)
-       pointerClient = NULL;
-
-#ifdef CORBA
-    destroyConnection(cl);
-#endif
-
-    if (prev)
-       prev->next = cl->next;
-    else
-       rfbClientHead = cl->next;
-
-    FreeZrleData(cl);
-    REGION_UNINIT(pScreen,&cl->copyRegion);
-    REGION_UNINIT(pScreen,&cl->modifiedRegion);
-    TimerFree(cl->deferredUpdateTimer);
-
-    rfbPrintStats(cl);
-
-    if (cl->translateLookupTable) free(cl->translateLookupTable);
-
-    xfree(cl);
-}
-
-
-/*
- * rfbProcessClientMessage is called when there is data to read from a client.
- */
-
-void
-rfbProcessClientMessage(sock)
-    int sock;
-{
-    rfbClientPtr cl;
-
-    for (cl = rfbClientHead; cl; cl = cl->next) {
-       if (sock == cl->sock)
-           break;
-    }
-
-    if (!cl) {
-       rfbLog("rfbProcessClientMessage: unknown socket %d\n",sock);
-       rfbCloseSock(sock);
-       return;
-    }
-
-#ifdef CORBA
-    if (isClosePending(cl)) {
-       rfbLog("Closing connection to client %s\n", cl->host);
-       rfbCloseSock(sock);
-       return;
-    }
-#endif
-
-    switch (cl->state) {
-    case RFB_PROTOCOL_VERSION:
-       rfbProcessClientProtocolVersion(cl);
-       return;
-    case RFB_AUTHENTICATION:
-       rfbAuthProcessClientMessage(cl);
-       return;
-    case RFB_INITIALISATION:
-       rfbProcessClientInitMessage(cl);
-       return;
-    default:
-       rfbProcessClientNormalMessage(cl);
-       return;
-    }
-}
-
-
-/*
- * rfbProcessClientProtocolVersion is called when the client sends its
- * protocol version.
- */
-
-static void
-rfbProcessClientProtocolVersion(cl)
-    rfbClientPtr cl;
-{
-    rfbProtocolVersionMsg pv;
-    int n, major, minor;
-    char failureReason[256];
-
-    if ((n = ReadExact(cl->sock, pv, sz_rfbProtocolVersionMsg)) <= 0) {
-       if (n == 0)
-           rfbLog("rfbProcessClientProtocolVersion: client gone\n");
-       else
-           rfbLogPerror("rfbProcessClientProtocolVersion: read");
-       rfbCloseSock(cl->sock);
-       return;
-    }
-
-    pv[sz_rfbProtocolVersionMsg] = 0;
-    if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) {
-       rfbLog("rfbProcessClientProtocolVersion: not a valid RFB client\n");
-       rfbCloseSock(cl->sock);
-       return;
-    }
-    rfbLog("Protocol version %d.%d\n", major, minor);
-
-    if (major != rfbProtocolMajorVersion) {
-       /* Major version mismatch - send a ConnFailed message */
-
-       rfbLog("Major version mismatch\n");
-       sprintf(failureReason,
-               "RFB protocol version mismatch - server %d.%d, client %d.%d",
-               rfbProtocolMajorVersion,rfbProtocolMinorVersion,major,minor);
-       rfbClientConnFailed(cl, failureReason);
-       return;
-    }
-
-    if (minor != rfbProtocolMinorVersion) {
-       /* Minor version mismatch - warn but try to continue */
-       rfbLog("Ignoring minor version mismatch\n");
-    }
-
-    rfbAuthNewClient(cl);
-}
-
-
-/*
- * rfbClientConnFailed is called when a client connection has failed either
- * because it talks the wrong protocol or it has failed authentication.
- */
-
-void
-rfbClientConnFailed(cl, reason)
-    rfbClientPtr cl;
-    char *reason;
-{
-    char *buf;
-    int len = strlen(reason);
-
-    buf = (char *)xalloc(8 + len);
-    ((CARD32 *)buf)[0] = Swap32IfLE(rfbConnFailed);
-    ((CARD32 *)buf)[1] = Swap32IfLE(len);
-    memcpy(buf + 8, reason, len);
-
-    if (WriteExact(cl->sock, buf, 8 + len) < 0)
-       rfbLogPerror("rfbClientConnFailed: write");
-    xfree(buf);
-    rfbCloseSock(cl->sock);
-}
-
-
-/*
- * rfbProcessClientInitMessage is called when the client sends its
- * initialisation message.
- */
-
-static void
-rfbProcessClientInitMessage(cl)
-    rfbClientPtr cl;
-{
-    rfbClientInitMsg ci;
-    char buf[256];
-    rfbServerInitMsg *si = (rfbServerInitMsg *)buf;
-    struct passwd *user;
-    int len, n;
-    rfbClientPtr otherCl, nextCl;
-
-    if ((n = ReadExact(cl->sock, (char *)&ci,sz_rfbClientInitMsg)) <= 0) {
-       if (n == 0)
-           rfbLog("rfbProcessClientInitMessage: client gone\n");
-       else
-           rfbLogPerror("rfbProcessClientInitMessage: read");
-       rfbCloseSock(cl->sock);
-       return;
-    }
-
-    si->framebufferWidth = Swap16IfLE(rfbScreen.width);
-    si->framebufferHeight = Swap16IfLE(rfbScreen.height);
-    si->format = rfbServerFormat;
-    si->format.redMax = Swap16IfLE(si->format.redMax);
-    si->format.greenMax = Swap16IfLE(si->format.greenMax);
-    si->format.blueMax = Swap16IfLE(si->format.blueMax);
-
-    user = getpwuid(getuid());
-
-    if (strlen(desktopName) > 128)     /* sanity check on desktop name len */
-       desktopName[128] = 0;
-
-    if (user) {
-       sprintf(buf + sz_rfbServerInitMsg, "%s's %s desktop (%s:%s)",
-               user->pw_name, desktopName, rfbThisHost, display);
-    } else {
-       sprintf(buf + sz_rfbServerInitMsg, "%s desktop (%s:%s)",
-               desktopName, rfbThisHost, display);
-    }
-    len = strlen(buf + sz_rfbServerInitMsg);
-    si->nameLength = Swap32IfLE(len);
-
-    if (WriteExact(cl->sock, buf, sz_rfbServerInitMsg + len) < 0) {
-       rfbLogPerror("rfbProcessClientInitMessage: write");
-       rfbCloseSock(cl->sock);
-       return;
-    }
-
-    cl->state = RFB_NORMAL;
-
-    if (!cl->reverseConnection &&
-                       (rfbNeverShared || (!rfbAlwaysShared && !ci.shared))) {
-
-       if (rfbDontDisconnect) {
-           for (otherCl = rfbClientHead; otherCl; otherCl = otherCl->next) {
-               if ((otherCl != cl) && (otherCl->state == RFB_NORMAL)) {
-                   rfbLog("-dontdisconnect: Not shared & existing client\n");
-                   rfbLog("  refusing new client %s\n", cl->host);
-                   rfbCloseSock(cl->sock);
-                   return;
-               }
-           }
-       } else {
-           for (otherCl = rfbClientHead; otherCl; otherCl = nextCl) {
-               nextCl = otherCl->next;
-               if ((otherCl != cl) && (otherCl->state == RFB_NORMAL)) {
-                   rfbLog("Not shared - closing connection to client %s\n",
-                          otherCl->host);
-                   rfbCloseSock(otherCl->sock);
-               }
-           }
-       }
-    }
-}
-
-
-/*
- * rfbProcessClientNormalMessage is called when the client has sent a normal
- * protocol message.
- */
-
-static void
-rfbProcessClientNormalMessage(cl)
-    rfbClientPtr cl;
-{
-    int n;
-    rfbClientToServerMsg msg;
-    char *str;
-
-    if ((n = ReadExact(cl->sock, (char *)&msg, 1)) <= 0) {
-       if (n != 0)
-           rfbLogPerror("rfbProcessClientNormalMessage: read");
-       rfbCloseSock(cl->sock);
-       return;
-    }
-
-    switch (msg.type) {
-
-    case rfbSetPixelFormat:
-
-       if ((n = ReadExact(cl->sock, ((char *)&msg) + 1,
-                          sz_rfbSetPixelFormatMsg - 1)) <= 0) {
-           if (n != 0)
-               rfbLogPerror("rfbProcessClientNormalMessage: read");
-           rfbCloseSock(cl->sock);
-           return;
-       }
-
-       cl->format.bitsPerPixel = msg.spf.format.bitsPerPixel;
-       cl->format.depth = msg.spf.format.depth;
-       cl->format.bigEndian = (msg.spf.format.bigEndian ? 1 : 0);
-       cl->format.trueColour = (msg.spf.format.trueColour ? 1 : 0);
-       cl->format.redMax = Swap16IfLE(msg.spf.format.redMax);
-       cl->format.greenMax = Swap16IfLE(msg.spf.format.greenMax);
-       cl->format.blueMax = Swap16IfLE(msg.spf.format.blueMax);
-       cl->format.redShift = msg.spf.format.redShift;
-       cl->format.greenShift = msg.spf.format.greenShift;
-       cl->format.blueShift = msg.spf.format.blueShift;
-
-       cl->readyForSetColourMapEntries = TRUE;
-
-       rfbSetTranslateFunction(cl);
-       return;
-
-
-    case rfbFixColourMapEntries:
-       if ((n = ReadExact(cl->sock, ((char *)&msg) + 1,
-                          sz_rfbFixColourMapEntriesMsg - 1)) <= 0) {
-           if (n != 0)
-               rfbLogPerror("rfbProcessClientNormalMessage: read");
-           rfbCloseSock(cl->sock);
-           return;
-       }
-       rfbLog("rfbProcessClientNormalMessage: %s",
-               "FixColourMapEntries unsupported\n");
-       rfbCloseSock(cl->sock);
-       return;
-
-
-    case rfbSetEncodings:
-    {
-       int i;
-       CARD32 enc;
-
-       if ((n = ReadExact(cl->sock, ((char *)&msg) + 1,
-                          sz_rfbSetEncodingsMsg - 1)) <= 0) {
-           if (n != 0)
-               rfbLogPerror("rfbProcessClientNormalMessage: read");
-           rfbCloseSock(cl->sock);
-           return;
-       }
-
-       msg.se.nEncodings = Swap16IfLE(msg.se.nEncodings);
-
-       cl->preferredEncoding = -1;
-       cl->useCopyRect = FALSE;
-
-       for (i = 0; i < msg.se.nEncodings; i++) {
-           if ((n = ReadExact(cl->sock, (char *)&enc, 4)) <= 0) {
-               if (n != 0)
-                   rfbLogPerror("rfbProcessClientNormalMessage: read");
-               rfbCloseSock(cl->sock);
-               return;
-           }
-           enc = Swap32IfLE(enc);
-
-           switch (enc) {
-
-           case rfbEncodingCopyRect:
-               cl->useCopyRect = TRUE;
-               break;
-           case rfbEncodingRaw:
-               if (cl->preferredEncoding == -1) {
-                   cl->preferredEncoding = enc;
-                   rfbLog("Using raw encoding for client %s\n",
-                          cl->host);
-               }
-               break;
-           case rfbEncodingRRE:
-               if (cl->preferredEncoding == -1) {
-                   cl->preferredEncoding = enc;
-                   rfbLog("Using rre encoding for client %s\n",
-                          cl->host);
-               }
-               break;
-           case rfbEncodingCoRRE:
-               if (cl->preferredEncoding == -1) {
-                   cl->preferredEncoding = enc;
-                   rfbLog("Using CoRRE encoding for client %s\n",
-                          cl->host);
-               }
-               break;
-           case rfbEncodingHextile:
-               if (cl->preferredEncoding == -1) {
-                   cl->preferredEncoding = enc;
-                   rfbLog("Using hextile encoding for client %s\n",
-                          cl->host);
-               }
-               break;
-           case rfbEncodingZRLE:
-               if (cl->preferredEncoding == -1) {
-                   cl->preferredEncoding = enc;
-                   rfbLog("Using ZRLE encoding for client %s\n",
-                          cl->host);
-               }
-               break;
-           default:
-               rfbLog("rfbProcessClientNormalMessage: ignoring unknown "
-                      "encoding type %d\n", (int)enc);
-           }
-       }
-
-       if (cl->preferredEncoding == -1) {
-           cl->preferredEncoding = rfbEncodingRaw;
-       }
-
-       return;
-    }
-
-
-    case rfbFramebufferUpdateRequest:
-    {
-       RegionRec tmpRegion;
-       BoxRec box;
-
-#ifdef CORBA
-       addCapability(cl, DISPLAY_DEVICE);
-#endif
-
-       if ((n = ReadExact(cl->sock, ((char *)&msg) + 1,
-                          sz_rfbFramebufferUpdateRequestMsg-1)) <= 0) {
-           if (n != 0)
-               rfbLogPerror("rfbProcessClientNormalMessage: read");
-           rfbCloseSock(cl->sock);
-           return;
-       }
-
-       box.x1 = Swap16IfLE(msg.fur.x);
-       box.y1 = Swap16IfLE(msg.fur.y);
-       box.x2 = box.x1 + Swap16IfLE(msg.fur.w);
-       box.y2 = box.y1 + Swap16IfLE(msg.fur.h);
-       SAFE_REGION_INIT(pScreen,&tmpRegion,&box,0);
-
-       REGION_UNION(pScreen, &cl->requestedRegion, &cl->requestedRegion,
-                    &tmpRegion);
-
-       if (!cl->readyForSetColourMapEntries) {
-           /* client hasn't sent a SetPixelFormat so is using server's */
-           cl->readyForSetColourMapEntries = TRUE;
-           if (!cl->format.trueColour) {
-               if (!rfbSetClientColourMap(cl, 0, 0)) {
-                   REGION_UNINIT(pScreen,&tmpRegion);
-                   return;
-               }
-           }
-       }
-
-       if (!msg.fur.incremental) {
-           REGION_UNION(pScreen,&cl->modifiedRegion,&cl->modifiedRegion,
-                        &tmpRegion);
-           REGION_SUBTRACT(pScreen,&cl->copyRegion,&cl->copyRegion,
-                           &tmpRegion);
-       }
-
-       if (FB_UPDATE_PENDING(cl)) {
-         if (!cl->deferredUpdateScheduled)
-            rfbScheduleDeferredUpdate(cl);
-       }
-
-       REGION_UNINIT(pScreen,&tmpRegion);
-       return;
-    }
-
-    case rfbKeyEvent:
-
-       cl->rfbKeyEventsRcvd++;
-
-       if ((n = ReadExact(cl->sock, ((char *)&msg) + 1,
-                          sz_rfbKeyEventMsg - 1)) <= 0) {
-           if (n != 0)
-               rfbLogPerror("rfbProcessClientNormalMessage: read");
-           rfbCloseSock(cl->sock);
-           return;
-       }
-
-#ifdef CORBA
-       addCapability(cl, KEYBOARD_DEVICE);
-
-       if (!isKeyboardEnabled(cl))
-           return;
-#endif
-       KbdAddEvent(msg.ke.down, (KeySym)Swap32IfLE(msg.ke.key), cl);
-       return;
-
-
-    case rfbPointerEvent:
-
-       cl->rfbPointerEventsRcvd++;
-
-       if ((n = ReadExact(cl->sock, ((char *)&msg) + 1,
-                          sz_rfbPointerEventMsg - 1)) <= 0) {
-           if (n != 0)
-               rfbLogPerror("rfbProcessClientNormalMessage: read");
-           rfbCloseSock(cl->sock);
-           return;
-       }
-
-#ifdef CORBA
-       addCapability(cl, POINTER_DEVICE);
-
-       if (!isPointerEnabled(cl))
-           return;
-#endif
-
-       if (pointerClient && (pointerClient != cl))
-           return;
-
-       if (msg.pe.buttonMask == 0)
-           pointerClient = NULL;
-       else
-           pointerClient = cl;
-
-       PtrAddEvent(msg.pe.buttonMask,
-                   Swap16IfLE(msg.pe.x), Swap16IfLE(msg.pe.y), cl);
-       return;
-
-
-    case rfbClientCutText:
-
-       if ((n = ReadExact(cl->sock, ((char *)&msg) + 1,
-                          sz_rfbClientCutTextMsg - 1)) <= 0) {
-           if (n != 0)
-               rfbLogPerror("rfbProcessClientNormalMessage: read");
-           rfbCloseSock(cl->sock);
-           return;
-       }
-
-       msg.cct.length = Swap32IfLE(msg.cct.length);
-
-       str = (char *)xalloc(msg.cct.length);
-
-       if ((n = ReadExact(cl->sock, str, msg.cct.length)) <= 0) {
-           if (n != 0)
-               rfbLogPerror("rfbProcessClientNormalMessage: read");
-           xfree(str);
-           rfbCloseSock(cl->sock);
-           return;
-       }
-
-       rfbSetXCutText(str, msg.cct.length);
-
-       xfree(str);
-       return;
-
-
-    default:
-
-       rfbLog("rfbProcessClientNormalMessage: unknown message type %d\n",
-               msg.type);
-       rfbLog(" ... closing connection\n");
-       rfbCloseSock(cl->sock);
-       return;
-    }
-}
-
-
-
-/*
- * rfbSendFramebufferUpdate - send the currently pending framebuffer update to
- * the RFB client.
- */
-
-Bool
-rfbSendFramebufferUpdate(cl)
-    rfbClientPtr cl;
-{
-    ScreenPtr pScreen = screenInfo.screens[0];
-    int i;
-    int nUpdateRegionRects;
-    rfbFramebufferUpdateMsg *fu = (rfbFramebufferUpdateMsg *)updateBuf;
-    RegionRec updateRegion, updateCopyRegion;
-    int dx, dy;
-    int bytesSent, rectsSent;
-
-    /*
-     * If the cursor isn't drawn, make sure it's put up.
-     */
-
-    if (!rfbScreen.cursorIsDrawn) {
-       rfbSpriteRestoreCursor(pScreen);
-    }
-
-    /*
-     * The modifiedRegion may overlap the destination copyRegion.  We remove
-     * any overlapping bits from the copyRegion (since they'd only be
-     * overwritten anyway).
-     */
-
-    REGION_SUBTRACT(pScreen, &cl->copyRegion, &cl->copyRegion,
-                   &cl->modifiedRegion);
-
-    /*
-     * The client is interested in the region requestedRegion.  The region
-     * which should be updated now is the intersection of requestedRegion
-     * and the union of modifiedRegion and copyRegion.  If it's empty then
-     * no update is needed.
-     */
-
-    REGION_INIT(pScreen,&updateRegion,NullBox,0);
-    REGION_UNION(pScreen, &updateRegion, &cl->copyRegion,
-                &cl->modifiedRegion);
-    REGION_INTERSECT(pScreen, &updateRegion, &cl->requestedRegion,
-                    &updateRegion);
-
-    if (!REGION_NOTEMPTY(pScreen,&updateRegion)) {
-       REGION_UNINIT(pScreen,&updateRegion);
-       return TRUE;
-    }
-
-    if (rfbTrace) {
-      rfbLog("Sending update...\n");
-      bytesSent = cl->rfbBytesSent[cl->preferredEncoding];
-      rectsSent = cl->rfbRectanglesSent[cl->preferredEncoding];
-    }
-
-    /*
-     * We assume that the client doesn't have any pixel data outside the
-     * requestedRegion.  In other words, both the source and destination of a
-     * copy must lie within requestedRegion.  So the region we can send as a
-     * copy is the intersection of the copyRegion with both the requestedRegion
-     * and the requestedRegion translated by the amount of the copy.  We set
-     * updateCopyRegion to this.
-     */
-
-    REGION_INIT(pScreen,&updateCopyRegion,NullBox,0);
-    REGION_INTERSECT(pScreen, &updateCopyRegion, &cl->copyRegion,
-                    &cl->requestedRegion);
-    REGION_TRANSLATE(pScreen, &cl->requestedRegion, cl->copyDX, cl->copyDY);
-    REGION_INTERSECT(pScreen, &updateCopyRegion, &updateCopyRegion,
-                    &cl->requestedRegion);
-    dx = cl->copyDX;
-    dy = cl->copyDY;
-
-    /*
-     * Next we remove updateCopyRegion from updateRegion so that updateRegion
-     * is the part of this update which is sent as ordinary pixel data (i.e not
-     * a copy).
-     */
-
-    REGION_SUBTRACT(pScreen, &updateRegion, &updateRegion, &updateCopyRegion);
-
-    /*
-     * Finally we leave modifiedRegion to be the remainder (if any) of parts of
-     * the screen which are modified but outside the requestedRegion.  We also
-     * empty both the requestedRegion and the copyRegion - note that we never
-     * carry over a copyRegion for a future update.
-     */
-
-    REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
-                &cl->copyRegion);
-    REGION_SUBTRACT(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
-                   &updateRegion);
-    REGION_SUBTRACT(pScreen, &cl->modifiedRegion, &cl->modifiedRegion,
-                   &updateCopyRegion);
-
-    REGION_EMPTY(pScreen, &cl->requestedRegion);
-    REGION_EMPTY(pScreen, &cl->copyRegion);
-    cl->copyDX = 0;
-    cl->copyDY = 0;
-
-    /*
-     * Now send the update.
-     */
-
-    cl->rfbFramebufferUpdateMessagesSent++;
-
-    if (cl->preferredEncoding == rfbEncodingCoRRE) {
-       nUpdateRegionRects = 0;
-
-       for (i = 0; i < REGION_NUM_RECTS(&updateRegion); i++) {
-           int x = REGION_RECTS(&updateRegion)[i].x1;
-           int y = REGION_RECTS(&updateRegion)[i].y1;
-           int w = REGION_RECTS(&updateRegion)[i].x2 - x;
-           int h = REGION_RECTS(&updateRegion)[i].y2 - y;
-           nUpdateRegionRects += (((w-1) / cl->correMaxWidth + 1)
-                                    * ((h-1) / cl->correMaxHeight + 1));
-       }
-    } else {
-       nUpdateRegionRects = REGION_NUM_RECTS(&updateRegion);
-    }
-
-    if (nUpdateRegionRects > rfbMaxRects) {
-      BoxRec boundingBox = *(REGION_EXTENTS(pScreen, &updateRegion));
-      REGION_RESET(pScreen, &updateRegion, &boundingBox);
-      nUpdateRegionRects = 1;
-    }
-
-    fu->type = rfbFramebufferUpdate;
-    fu->nRects = Swap16IfLE(REGION_NUM_RECTS(&updateCopyRegion)
-                           + nUpdateRegionRects);
-    ublen = sz_rfbFramebufferUpdateMsg;
-
-    if (REGION_NOTEMPTY(pScreen,&updateCopyRegion)) {
-       if (!rfbSendCopyRegion(cl,&updateCopyRegion,dx,dy)) {
-           REGION_UNINIT(pScreen,&updateRegion);
-           REGION_UNINIT(pScreen,&updateCopyRegion);
-           return FALSE;
-       }
-    }
-
-    REGION_UNINIT(pScreen,&updateCopyRegion);
-
-    for (i = 0; i < REGION_NUM_RECTS(&updateRegion); i++) {
-       int x = REGION_RECTS(&updateRegion)[i].x1;
-       int y = REGION_RECTS(&updateRegion)[i].y1;
-       int w = REGION_RECTS(&updateRegion)[i].x2 - x;
-       int h = REGION_RECTS(&updateRegion)[i].y2 - y;
-
-       cl->rfbRawBytesEquivalent += (sz_rfbFramebufferUpdateRectHeader
-                                     + w * (cl->format.bitsPerPixel / 8) * h);
-
-       switch (cl->preferredEncoding) {
-       case rfbEncodingRaw:
-           if (!rfbSendRectEncodingRaw(cl, x, y, w, h)) {
-               REGION_UNINIT(pScreen,&updateRegion);
-               return FALSE;
-           }
-           break;
-       case rfbEncodingRRE:
-           if (!rfbSendRectEncodingRRE(cl, x, y, w, h)) {
-               REGION_UNINIT(pScreen,&updateRegion);
-               return FALSE;
-           }
-           break;
-       case rfbEncodingCoRRE:
-           if (!rfbSendRectEncodingCoRRE(cl, x, y, w, h)) {
-               REGION_UNINIT(pScreen,&updateRegion);
-               return FALSE;
-           }
-           break;
-       case rfbEncodingHextile:
-           if (!rfbSendRectEncodingHextile(cl, x, y, w, h)) {
-               REGION_UNINIT(pScreen,&updateRegion);
-               return FALSE;
-           }
-           break;
-       case rfbEncodingZRLE:
-           if (!rfbSendRectEncodingZRLE(cl, x, y, w, h)) {
-               REGION_UNINIT(pScreen,&updateRegion);
-               return FALSE;
-           }
-           break;
-       }
-    }
-
-    REGION_UNINIT(pScreen,&updateRegion);
-
-    if (!rfbSendUpdateBuf(cl))
-       return FALSE;
-
-    if (rfbTrace) {
-      bytesSent = cl->rfbBytesSent[cl->preferredEncoding] - bytesSent;
-      rectsSent = cl->rfbRectanglesSent[cl->preferredEncoding] - rectsSent;
-      rfbLog("...sent %d bytes, %d rects\n",bytesSent,rectsSent);
-    }
-
-    return TRUE;
-}
-
-
-
-/*
- * Send the copy region as a string of CopyRect encoded rectangles.
- * The only slightly tricky thing is that we should send the messages in
- * the correct order so that an earlier CopyRect will not corrupt the source
- * of a later one.
- */
-
-static Bool
-rfbSendCopyRegion(cl, reg, dx, dy)
-    rfbClientPtr cl;
-    RegionPtr reg;
-    int dx, dy;
-{
-    int nrects, nrectsInBand, x_inc, y_inc, thisRect, firstInNextBand;
-    int x, y, w, h;
-    rfbFramebufferUpdateRectHeader rect;
-    rfbCopyRect cr;
-
-    nrects = REGION_NUM_RECTS(reg);
-
-    if (dx <= 0) {
-       x_inc = 1;
-    } else {
-       x_inc = -1;
-    }
-
-    if (dy <= 0) {
-       thisRect = 0;
-       y_inc = 1;
-    } else {
-       thisRect = nrects - 1;
-       y_inc = -1;
-    }
-
-    while (nrects > 0) {
-
-       firstInNextBand = thisRect;
-       nrectsInBand = 0;
-
-       while ((nrects > 0) &&
-              (REGION_RECTS(reg)[firstInNextBand].y1
-               == REGION_RECTS(reg)[thisRect].y1))
-       {
-           firstInNextBand += y_inc;
-           nrects--;
-           nrectsInBand++;
-       }
-
-       if (x_inc != y_inc) {
-           thisRect = firstInNextBand - y_inc;
-       }
-
-       while (nrectsInBand > 0) {
-           if ((ublen + sz_rfbFramebufferUpdateRectHeader
-                + sz_rfbCopyRect) > UPDATE_BUF_SIZE)
-           {
-               if (!rfbSendUpdateBuf(cl))
-                   return FALSE;
-           }
-
-           x = REGION_RECTS(reg)[thisRect].x1;
-           y = REGION_RECTS(reg)[thisRect].y1;
-           w = REGION_RECTS(reg)[thisRect].x2 - x;
-           h = REGION_RECTS(reg)[thisRect].y2 - y;
-
-           rect.r.x = Swap16IfLE(x);
-           rect.r.y = Swap16IfLE(y);
-           rect.r.w = Swap16IfLE(w);
-           rect.r.h = Swap16IfLE(h);
-           rect.encoding = Swap32IfLE(rfbEncodingCopyRect);
-
-           memcpy(&updateBuf[ublen], (char *)&rect,
-                  sz_rfbFramebufferUpdateRectHeader);
-           ublen += sz_rfbFramebufferUpdateRectHeader;
-
-           cr.srcX = Swap16IfLE(x - dx);
-           cr.srcY = Swap16IfLE(y - dy);
-
-           memcpy(&updateBuf[ublen], (char *)&cr, sz_rfbCopyRect);
-           ublen += sz_rfbCopyRect;
-
-           cl->rfbRectanglesSent[rfbEncodingCopyRect]++;
-           cl->rfbBytesSent[rfbEncodingCopyRect]
-               += sz_rfbFramebufferUpdateRectHeader + sz_rfbCopyRect;
-
-           thisRect += x_inc;
-           nrectsInBand--;
-       }
-
-       thisRect = firstInNextBand;
-    }
-
-    return TRUE;
-}
-
-
-/*
- * Send a given rectangle in raw encoding (rfbEncodingRaw).
- */
-
-Bool
-rfbSendRectEncodingRaw(cl, x, y, w, h)
-    rfbClientPtr cl;
-    int x, y, w, h;
-{
-    rfbFramebufferUpdateRectHeader rect;
-    int nlines;
-    int bytesPerLine = w * (cl->format.bitsPerPixel / 8);
-    char *fbptr = (rfbScreen.pfbMemory + (rfbScreen.paddedWidthInBytes * y)
-                  + (x * (rfbScreen.bitsPerPixel / 8)));
-
-    if (ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) {
-       if (!rfbSendUpdateBuf(cl))
-           return FALSE;
-    }
-
-    rect.r.x = Swap16IfLE(x);
-    rect.r.y = Swap16IfLE(y);
-    rect.r.w = Swap16IfLE(w);
-    rect.r.h = Swap16IfLE(h);
-    rect.encoding = Swap32IfLE(rfbEncodingRaw);
-
-    memcpy(&updateBuf[ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader);
-    ublen += sz_rfbFramebufferUpdateRectHeader;
-
-    cl->rfbRectanglesSent[rfbEncodingRaw]++;
-    cl->rfbBytesSent[rfbEncodingRaw]
-       += sz_rfbFramebufferUpdateRectHeader + bytesPerLine * h;
-
-    nlines = (UPDATE_BUF_SIZE - ublen) / bytesPerLine;
-
-    while (TRUE) {
-       if (nlines > h)
-           nlines = h;
-
-       (*cl->translateFn)(cl->translateLookupTable, &rfbServerFormat,
-                          &cl->format, fbptr, &updateBuf[ublen],
-                          rfbScreen.paddedWidthInBytes, w, nlines);
-
-       ublen += nlines * bytesPerLine;
-       h -= nlines;
-
-       if (h == 0)     /* rect fitted in buffer, do next one */
-           return TRUE;
-
-       /* buffer full - flush partial rect and do another nlines */
-
-       if (!rfbSendUpdateBuf(cl))
-           return FALSE;
-
-       fbptr += (rfbScreen.paddedWidthInBytes * nlines);
-
-       nlines = (UPDATE_BUF_SIZE - ublen) / bytesPerLine;
-       if (nlines == 0) {
-           rfbLog("rfbSendRectEncodingRaw: send buffer too small for %d "
-                  "bytes per line\n", bytesPerLine);
-           rfbCloseSock(cl->sock);
-           return FALSE;
-       }
-    }
-}
-
-
-
-/*
- * Send the contents of updateBuf.  Returns 1 if successful, -1 if
- * not (errno should be set).
- */
-
-Bool
-rfbSendUpdateBuf(cl)
-    rfbClientPtr cl;
-{
-    /*
-    int i;
-    for (i = 0; i < ublen; i++) {
-       fprintf(stderr,"%02x ",((unsigned char *)updateBuf)[i]);
-    }
-    fprintf(stderr,"\n");
-    */
-
-    if (WriteExact(cl->sock, updateBuf, ublen) < 0) {
-       rfbLogPerror("rfbSendUpdateBuf: write");
-       rfbCloseSock(cl->sock);
-       return FALSE;
-    }
-
-    ublen = 0;
-    return TRUE;
-}
-
-
-
-/*
- * rfbSendSetColourMapEntries sends a SetColourMapEntries message to the
- * client, using values from the currently installed colormap.
- */
-
-Bool
-rfbSendSetColourMapEntries(cl, firstColour, nColours)
-    rfbClientPtr cl;
-    int firstColour;
-    int nColours;
-{
-    char buf[sz_rfbSetColourMapEntriesMsg + 256 * 3 * 2];
-    rfbSetColourMapEntriesMsg *scme = (rfbSetColourMapEntriesMsg *)buf;
-    CARD16 *rgb = (CARD16 *)(&buf[sz_rfbSetColourMapEntriesMsg]);
-    EntryPtr pent;
-    int i, len;
-
-    scme->type = rfbSetColourMapEntries;
-
-    scme->firstColour = Swap16IfLE(firstColour);
-    scme->nColours = Swap16IfLE(nColours);
-
-    len = sz_rfbSetColourMapEntriesMsg;
-
-    pent = (EntryPtr)&rfbInstalledColormap->red[firstColour];
-    for (i = 0; i < nColours; i++) {
-       if (pent->fShared) {
-           rgb[i*3] = Swap16IfLE(pent->co.shco.red->color);
-           rgb[i*3+1] = Swap16IfLE(pent->co.shco.green->color);
-           rgb[i*3+2] = Swap16IfLE(pent->co.shco.blue->color);
-       } else {
-           rgb[i*3] = Swap16IfLE(pent->co.local.red);
-           rgb[i*3+1] = Swap16IfLE(pent->co.local.green);
-           rgb[i*3+2] = Swap16IfLE(pent->co.local.blue);
-       }
-       pent++;
-    }
-
-    len += nColours * 3 * 2;
-
-    if (WriteExact(cl->sock, buf, len) < 0) {
-       rfbLogPerror("rfbSendSetColourMapEntries: write");
-       rfbCloseSock(cl->sock);
-       return FALSE;
-    }
-    return TRUE;
-}
-
-
-/*
- * rfbSendBell sends a Bell message to all the clients.
- */
-
-void
-rfbSendBell()
-{
-    rfbClientPtr cl, nextCl;
-    rfbBellMsg b;
-
-    for (cl = rfbClientHead; cl; cl = nextCl) {
-       nextCl = cl->next;
-       b.type = rfbBell;
-       if (WriteExact(cl->sock, (char *)&b, sz_rfbBellMsg) < 0) {
-           rfbLogPerror("rfbSendBell: write");
-           rfbCloseSock(cl->sock);
-       }
-    }
-}
-
-
-/*
- * rfbSendServerCutText sends a ServerCutText message to all the clients.
- */
-
-void
-rfbSendServerCutText(char *str, int len)
-{
-    rfbClientPtr cl, nextCl;
-    rfbServerCutTextMsg sct;
-
-    for (cl = rfbClientHead; cl; cl = nextCl) {
-       nextCl = cl->next;
-       sct.type = rfbServerCutText;
-       sct.length = Swap32IfLE(len);
-       if (WriteExact(cl->sock, (char *)&sct,
-                      sz_rfbServerCutTextMsg) < 0) {
-           rfbLogPerror("rfbSendServerCutText: write");
-           rfbCloseSock(cl->sock);
-           continue;
-       }
-       if (WriteExact(cl->sock, str, len) < 0) {
-           rfbLogPerror("rfbSendServerCutText: write");
-           rfbCloseSock(cl->sock);
-       }
-    }
-}