summaryrefslogtreecommitdiffstats
path: root/krfb/libvncserver/rfbserver.c
diff options
context:
space:
mode:
Diffstat (limited to 'krfb/libvncserver/rfbserver.c')
-rw-r--r--krfb/libvncserver/rfbserver.c1590
1 files changed, 0 insertions, 1590 deletions
diff --git a/krfb/libvncserver/rfbserver.c b/krfb/libvncserver/rfbserver.c
deleted file mode 100644
index 66cc4ee3..00000000
--- a/krfb/libvncserver/rfbserver.c
+++ /dev/null
@@ -1,1590 +0,0 @@
-/*
- * rfbserver.c - deal with server-side of the RFB protocol.
- */
-
-/*
- * OSXvnc Copyright (C) 2001 Dan McGuirk <[email protected]>.
- * Original Xvnc code 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "rfb.h"
-#include "sraRegion.h"
-#ifdef WIN32
-#define write(sock,buf,len) send(sock,buf,len,0)
-#else
-#include <unistd.h>
-#include <pwd.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#endif
-#include <sys/types.h>
-#ifdef __osf__
-typedef int socklen_t;
-#endif
-
-#ifdef CORBA
-#include <vncserverctrl.h>
-#endif
-
-#ifdef DEBUGPROTO
-#undef DEBUGPROTO
-#define DEBUGPROTO(x) x
-#else
-#define DEBUGPROTO(x)
-#endif
-
-rfbClientPtr pointerClient = NULL; /* Mutex for pointer events */
-
-static void rfbProcessClientProtocolVersion(rfbClientPtr cl);
-static void rfbProcessClientNormalMessage(rfbClientPtr cl);
-static void rfbProcessClientInitMessage(rfbClientPtr cl);
-
-#ifdef HAVE_PTHREADS
-void rfbIncrClientRef(rfbClientPtr cl)
-{
- LOCK(cl->refCountMutex);
- cl->refCount++;
- UNLOCK(cl->refCountMutex);
-}
-
-void rfbDecrClientRef(rfbClientPtr cl)
-{
- LOCK(cl->refCountMutex);
- cl->refCount--;
- if(cl->refCount<=0) /* just to be sure also < 0 */
- TSIGNAL(cl->deleteCond);
- UNLOCK(cl->refCountMutex);
-}
-#else
-void rfbIncrClientRef(rfbClientPtr cl)
-{
-}
-
-void rfbDecrClientRef(rfbClientPtr cl)
-{
-}
-#endif
-
-MUTEX(rfbClientListMutex);
-
-struct rfbClientIterator {
- rfbClientPtr next;
- rfbScreenInfoPtr screen;
-};
-
-void
-rfbClientListInit(rfbScreenInfoPtr rfbScreen)
-{
- rfbScreen->rfbClientHead = NULL;
- INIT_MUTEX(rfbClientListMutex);
-}
-
-rfbClientIteratorPtr
-rfbGetClientIterator(rfbScreenInfoPtr rfbScreen)
-{
- rfbClientIteratorPtr i =
- (rfbClientIteratorPtr)malloc(sizeof(struct rfbClientIterator));
- i->next = 0;
- i->screen = rfbScreen;
- return i;
-}
-
-rfbClientPtr
-rfbClientIteratorNext(rfbClientIteratorPtr i)
-{
- if(i->next == 0) {
- LOCK(rfbClientListMutex);
- i->next = i->screen->rfbClientHead;
- UNLOCK(rfbClientListMutex);
- } else {
- IF_PTHREADS(rfbClientPtr cl = i->next);
- i->next = i->next->next;
- IF_PTHREADS(rfbDecrClientRef(cl));
- }
-
-#ifdef HAVE_PTHREADS
- while(i->next && i->next->sock<0)
- i->next = i->next->next;
- if(i->next)
- rfbIncrClientRef(i->next);
-#endif
-
- return i->next;
-}
-
-void
-rfbReleaseClientIterator(rfbClientIteratorPtr iterator)
-{
- IF_PTHREADS(if(iterator->next) rfbDecrClientRef(iterator->next));
-}
-
-
-/*
- * rfbNewClientConnection is called from sockets.c when a new connection
- * comes in.
- */
-
-void
-rfbNewClientConnection(rfbScreen,sock)
- rfbScreenInfoPtr rfbScreen;
- int sock;
-{
- rfbClientPtr cl;
-
- cl = rfbNewClient(rfbScreen,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(rfbScreen,host, port)
- rfbScreenInfoPtr rfbScreen;
- char *host;
- int port;
-{
- int sock;
- rfbClientPtr cl;
-
- if ((sock = rfbConnect(rfbScreen, host, port)) < 0)
- return (rfbClientPtr)NULL;
-
- cl = rfbNewClient(rfbScreen, sock);
-
- if (cl) {
- cl->reverseConnection = TRUE;
- }
-
- return cl;
-}
-
-
-/*
- * rfbNewClient is called when a new connection has been made by whatever
- * means.
- */
-
-static rfbClientPtr
-rfbNewTCPOrUDPClient(rfbScreen,sock,isUDP)
- rfbScreenInfoPtr rfbScreen;
- int sock;
- Bool isUDP;
-{
- rfbProtocolVersionMsg pv;
- rfbClientIteratorPtr iterator;
- rfbClientPtr cl,cl_;
- struct sockaddr_in addr;
- size_t addrlen = sizeof(struct sockaddr_in);
- int i;
-
- cl = (rfbClientPtr)calloc(sizeof(rfbClientRec),1);
-
- cl->screen = rfbScreen;
- cl->sock = sock;
- rfbResetStats(cl);
-
- if(isUDP) {
- rfbLog(" accepted UDP client\n");
- } else {
- getpeername(sock, (struct sockaddr *)&addr, &addrlen);
- cl->host = strdup(inet_ntoa(addr.sin_addr));
-
- rfbLog(" other clients:\n");
- iterator = rfbGetClientIterator(rfbScreen);
- while ((cl_ = rfbClientIteratorNext(iterator)) != NULL) {
- rfbLog(" %s\n",cl_->host);
- }
- rfbReleaseClientIterator(iterator);
-
- FD_SET(sock,&(rfbScreen->allFds));
- rfbScreen->maxFd = max(sock,rfbScreen->maxFd);
-
- INIT_MUTEX(cl->outputMutex);
- INIT_MUTEX(cl->refCountMutex);
- INIT_COND(cl->deleteCond);
-
- cl->state = RFB_PROTOCOL_VERSION;
-
- cl->reverseConnection = FALSE;
- cl->readyForSetColourMapEntries = FALSE;
- cl->useCopyRect = FALSE;
- cl->preferredEncoding = rfbEncodingRaw;
- cl->correMaxWidth = 48;
- cl->correMaxHeight = 48;
-
- cl->copyRegion = sraRgnCreate();
- cl->copyDX = 0;
- cl->copyDY = 0;
-
- cl->modifiedRegion =
- sraRgnCreateRect(0,0,rfbScreen->width,rfbScreen->height);
-
- INIT_MUTEX(cl->updateMutex);
- INIT_COND(cl->updateCond);
-
- cl->requestedRegion = sraRgnCreate();
-
- cl->format = cl->screen->rfbServerFormat;
- cl->translateFn = rfbTranslateNone;
- cl->translateLookupTable = NULL;
-
- LOCK(rfbClientListMutex);
-
- IF_PTHREADS(cl->refCount = 0);
- cl->next = rfbScreen->rfbClientHead;
- cl->prev = NULL;
- if (rfbScreen->rfbClientHead)
- rfbScreen->rfbClientHead->prev = cl;
-
- rfbScreen->rfbClientHead = cl;
- UNLOCK(rfbClientListMutex);
-
- cl->tightCompressLevel = TIGHT_DEFAULT_COMPRESSION;
- cl->tightQualityLevel = -1;
- for (i = 0; i < 4; i++)
- cl->zsActive[i] = FALSE;
-
- cl->enableCursorShapeUpdates = FALSE;
- cl->useRichCursorEncoding = FALSE;
- cl->enableLastRectEncoding = FALSE;
- cl->disableBackground = FALSE;
-
- cl->compStreamInited = FALSE;
- cl->compStream.total_in = 0;
- cl->compStream.total_out = 0;
- cl->compStream.zalloc = Z_NULL;
- cl->compStream.zfree = Z_NULL;
- cl->compStream.opaque = Z_NULL;
-
- cl->zlibCompressLevel = 5;
-
- sprintf(pv,rfbProtocolVersionFormat,rfbProtocolMajorVersion,
- rfbProtocolMinorVersion);
-
- if (WriteExact(cl, pv, sz_rfbProtocolVersionMsg) < 0) {
- rfbLogPerror("rfbNewClient: write");
- rfbCloseClient(cl);
- /* TODO: memory leak here (cl is never freed)
- * can rfbClientConnectionGone called at this time?
- */
- return NULL;
- }
- }
-
- cl->clientData = NULL;
- cl->clientGoneHook = doNothingWithClient;
- cl->negotiationFinishedHook = doNothingWithClient;
- switch (cl->screen->newClientHook(cl)) {
- case RFB_CLIENT_ON_HOLD:
- cl->onHold = TRUE;
- break;
- case RFB_CLIENT_ACCEPT:
- cl->onHold = FALSE;
- break;
- case RFB_CLIENT_REFUSE:
- rfbCloseClient(cl);
- rfbClientConnectionGone(cl);
- cl = NULL;
- break;
- }
- return cl;
-}
-
-rfbClientPtr
-rfbNewClient(rfbScreen,sock)
- rfbScreenInfoPtr rfbScreen;
- int sock;
-{
- return(rfbNewTCPOrUDPClient(rfbScreen,sock,FALSE));
-}
-
-rfbClientPtr
-rfbNewUDPClient(rfbScreen)
- rfbScreenInfoPtr rfbScreen;
-{
- return((rfbScreen->udpClient=
- rfbNewTCPOrUDPClient(rfbScreen,rfbScreen->udpSock,TRUE)));
-}
-
-/*
- * rfbClientConnectionGone is called from sockets.c just after a connection
- * has gone away.
- */
-
-void
-rfbClientConnectionGone(cl)
- rfbClientPtr cl;
-{
- int i;
-
- LOCK(rfbClientListMutex);
-
- if (cl->prev)
- cl->prev->next = cl->next;
- else
- cl->screen->rfbClientHead = cl->next;
- if (cl->next)
- cl->next->prev = cl->prev;
-
-#ifdef HAVE_PTHREADS
- LOCK(cl->refCountMutex);
- if(cl->refCount) {
- UNLOCK(cl->refCountMutex);
- WAIT(cl->deleteCond,cl->refCountMutex);
- } else {
- UNLOCK(cl->refCountMutex);
- }
-#endif
-
- if(cl->sock>=0)
- FD_CLR(cl->sock,&(cl->screen->allFds));
-
- cl->clientGoneHook(cl);
-
- rfbLog("Client %s gone\n",cl->host);
- free(cl->host);
-
- /* Release the compression state structures if any. */
- if ( cl->compStreamInited ) {
- deflateEnd( &(cl->compStream) );
- }
-
- for (i = 0; i < 4; i++) {
- if (cl->zsActive[i])
- deflateEnd(&cl->zsStruct[i]);
- }
-
- if (pointerClient == cl)
- pointerClient = NULL;
-
- sraRgnDestroy(cl->modifiedRegion);
-
- UNLOCK(rfbClientListMutex);
-
- if (cl->translateLookupTable) free(cl->translateLookupTable);
-
- TINI_COND(cl->updateCond);
- TINI_MUTEX(cl->updateMutex);
-
- LOCK(cl->outputMutex);
- TINI_MUTEX(cl->outputMutex);
-
-#ifdef CORBA
- destroyConnection(cl);
-#endif
-
- rfbPrintStats(cl);
-
- free(cl);
-}
-
-
-/*
- * rfbProcessClientMessage is called when there is data to read from a client.
- */
-
-void
-rfbProcessClientMessage(cl)
- rfbClientPtr cl;
-{
- 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, pv, sz_rfbProtocolVersionMsg)) <= 0) {
- if (n == 0)
- rfbLog("rfbProcessClientProtocolVersion: client gone\n");
- else
- rfbLogPerror("rfbProcessClientProtocolVersion: read");
- rfbCloseClient(cl);
- return;
- }
-
- pv[sz_rfbProtocolVersionMsg] = 0;
- if (sscanf(pv,rfbProtocolVersionFormat,&major_,&minor_) != 2) {
- rfbLog("rfbProcessClientProtocolVersion: not a valid RFB client\n");
- rfbCloseClient(cl);
- 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 *)malloc(8 + len);
- ((CARD32 *)buf)[0] = Swap32IfLE(rfbConnFailed);
- ((CARD32 *)buf)[1] = Swap32IfLE(len);
- memcpy(buf + 8, reason, len);
-
- if (WriteExact(cl, buf, 8 + len) < 0)
- rfbLogPerror("rfbClientConnFailed: write");
- free(buf);
- rfbCloseClient(cl);
-}
-
-
-/*
- * 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;
- int len, n;
- rfbClientIteratorPtr iterator;
- rfbClientPtr otherCl;
-
- if ((n = ReadExact(cl, (char *)&ci,sz_rfbClientInitMsg)) <= 0) {
- if (n == 0)
- rfbLog("rfbProcessClientInitMessage: client gone\n");
- else
- rfbLogPerror("rfbProcessClientInitMessage: read");
- rfbCloseClient(cl);
- return;
- }
-
- si->framebufferWidth = Swap16IfLE(cl->screen->width);
- si->framebufferHeight = Swap16IfLE(cl->screen->height);
- si->format = cl->screen->rfbServerFormat;
- si->format.redMax = Swap16IfLE(si->format.redMax);
- si->format.greenMax = Swap16IfLE(si->format.greenMax);
- si->format.blueMax = Swap16IfLE(si->format.blueMax);
-
- if (strlen(cl->screen->desktopName) > 128) /* sanity check on desktop name len */
- ((char*)cl->screen->desktopName)[128] = 0;
-
- strcpy(buf + sz_rfbServerInitMsg, cl->screen->desktopName);
- len = strlen(buf + sz_rfbServerInitMsg);
- si->nameLength = Swap32IfLE(len);
-
- if (WriteExact(cl, buf, sz_rfbServerInitMsg + len) < 0) {
- rfbLogPerror("rfbProcessClientInitMessage: write");
- rfbCloseClient(cl);
- return;
- }
-
- cl->state = RFB_NORMAL;
-
- if (!cl->reverseConnection &&
- (cl->screen->rfbNeverShared || (!cl->screen->rfbAlwaysShared && !ci.shared))) {
-
- if (cl->screen->rfbDontDisconnect) {
- iterator = rfbGetClientIterator(cl->screen);
- while ((otherCl = rfbClientIteratorNext(iterator)) != NULL) {
- if ((otherCl != cl) && (otherCl->state == RFB_NORMAL)) {
- rfbLog("-dontdisconnect: Not shared & existing client\n");
- rfbLog(" refusing new client %s\n", cl->host);
- rfbCloseClient(cl);
- rfbReleaseClientIterator(iterator);
- return;
- }
- }
- rfbReleaseClientIterator(iterator);
- } else {
- iterator = rfbGetClientIterator(cl->screen);
- while ((otherCl = rfbClientIteratorNext(iterator)) != NULL) {
- if ((otherCl != cl) && (otherCl->state == RFB_NORMAL)) {
- rfbLog("Not shared - closing connection to client %s\n",
- otherCl->host);
- rfbCloseClient(otherCl);
- }
- }
- rfbReleaseClientIterator(iterator);
- }
- }
-}
-
-
-/*
- * rfbProcessClientNormalMessage is called when the client has sent a normal
- * protocol message.
- */
-
-static void
-rfbProcessClientNormalMessage(cl)
- rfbClientPtr cl;
-{
- int n=0;
- rfbClientToServerMsg msg;
- char *str;
-
- if ((n = ReadExact(cl, (char *)&msg, 1)) <= 0) {
- if (n != 0)
- rfbLogPerror("rfbProcessClientNormalMessage: read");
- rfbCloseClient(cl);
- return;
- }
-
- switch (msg.type) {
-
- case rfbSetPixelFormat:
-
- if ((n = ReadExact(cl, ((char *)&msg) + 1,
- sz_rfbSetPixelFormatMsg - 1)) <= 0) {
- if (n != 0)
- rfbLogPerror("rfbProcessClientNormalMessage: read");
- rfbCloseClient(cl);
- return;
- }
-
- cl->format.bitsPerPixel = msg.spf.format.bitsPerPixel;
- cl->format.depth = msg.spf.format.depth;
- cl->format.bigEndian = (msg.spf.format.bigEndian ? TRUE : FALSE);
- cl->format.trueColour = (msg.spf.format.trueColour ? TRUE : FALSE);
- 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;
- cl->screen->setTranslateFunction(cl);
-
- return;
-
-
- case rfbFixColourMapEntries:
- if ((n = ReadExact(cl, ((char *)&msg) + 1,
- sz_rfbFixColourMapEntriesMsg - 1)) <= 0) {
- if (n != 0)
- rfbLogPerror("rfbProcessClientNormalMessage: read");
- rfbCloseClient(cl);
- return;
- }
- rfbLog("rfbProcessClientNormalMessage: %s",
- "FixColourMapEntries unsupported\n");
- rfbCloseClient(cl);
- return;
-
-
- case rfbSetEncodings:
- {
- int i;
- CARD32 enc;
-
- if ((n = ReadExact(cl, ((char *)&msg) + 1,
- sz_rfbSetEncodingsMsg - 1)) <= 0) {
- if (n != 0)
- rfbLogPerror("rfbProcessClientNormalMessage: read");
- rfbCloseClient(cl);
- return;
- }
-
- msg.se.nEncodings = Swap16IfLE(msg.se.nEncodings);
-
- cl->preferredEncoding = -1;
- cl->useCopyRect = FALSE;
- cl->enableCursorShapeUpdates = FALSE;
- cl->enableLastRectEncoding = FALSE;
- cl->disableBackground = FALSE;
-
- for (i = 0; i < msg.se.nEncodings; i++) {
- if ((n = ReadExact(cl, (char *)&enc, 4)) <= 0) {
- if (n != 0)
- rfbLogPerror("rfbProcessClientNormalMessage: read");
- rfbCloseClient(cl);
- 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 rfbEncodingZlib:
- if (cl->preferredEncoding == -1) {
- cl->preferredEncoding = enc;
- rfbLog("Using zlib encoding for client %s\n",
- cl->host);
- }
- break;
- case rfbEncodingTight:
- if (cl->preferredEncoding == -1) {
- cl->preferredEncoding = enc;
- rfbLog("Using tight encoding for client %s\n",
- cl->host);
- }
- break;
- case rfbEncodingXCursor:
- if (cl->enableSoftCursorUpdates)
- break;
- if(!cl->screen->dontConvertRichCursorToXCursor) {
- rfbLog("Enabling X-style cursor updates for client %s\n",
- cl->host);
- cl->enableCursorShapeUpdates = TRUE;
- cl->cursorWasChanged = TRUE;
- }
- break;
- case rfbEncodingRichCursor:
- rfbLog("Enabling full-color cursor updates for client "
- "%s\n", cl->host);
- if (cl->enableSoftCursorUpdates)
- break;
- cl->enableCursorShapeUpdates = TRUE;
- cl->useRichCursorEncoding = TRUE;
- cl->cursorWasChanged = TRUE;
- break;
- case rfbEncodingSoftCursor:
- rfbLog("Enabling soft cursor updates for client "
- "%s\n", cl->host);
- cl->enableSoftCursorUpdates = TRUE;
- cl->cursorWasChanged = TRUE;
- cl->cursorWasMoved = TRUE;
- cl->enableCursorShapeUpdates = FALSE;
- cl->useRichCursorEncoding = FALSE;
- break;
- case rfbEncodingLastRect:
- if (!cl->enableLastRectEncoding) {
- rfbLog("Enabling LastRect protocol extension for client "
- "%s\n", cl->host);
- cl->enableLastRectEncoding = TRUE;
- }
- break;
- case rfbEncodingBackground:
- rfbLog("Disabling background for client "
- "%s\n", cl->host);
- cl->disableBackground = TRUE;
- break;
-#ifdef BACKCHANNEL
- case rfbEncodingBackChannel:
- if (!cl->enableBackChannel) {
- rfbLog("Enabling BackChannel protocol extension for "
- "client %s\n", cl->host);
- cl->enableBackChannel = TRUE;
- }
- break;
-#endif
- default:
- if ( enc >= (CARD32)rfbEncodingCompressLevel0 &&
- enc <= (CARD32)rfbEncodingCompressLevel9 ) {
- cl->zlibCompressLevel = enc & 0x0F;
- cl->tightCompressLevel = enc & 0x0F;
- rfbLog("Using compression level %d for client %s\n",
- cl->tightCompressLevel, cl->host);
- } else if ( enc >= (CARD32)rfbEncodingQualityLevel0 &&
- enc <= (CARD32)rfbEncodingQualityLevel9 ) {
- cl->tightQualityLevel = enc & 0x0F;
- rfbLog("Using image quality level %d for client %s\n",
- cl->tightQualityLevel, cl->host);
- } else
- rfbLog("rfbProcessClientNormalMessage: ignoring unknown "
- "encoding type %d\n", (int)enc);
- }
- }
-
- if (cl->preferredEncoding == -1) {
- cl->preferredEncoding = rfbEncodingRaw;
- }
-
- cl->negotiationFinishedHook(cl);
-
- return;
- }
-
-
- case rfbFramebufferUpdateRequest:
- {
- sraRegionPtr tmpRegion;
-
- if ((n = ReadExact(cl, ((char *)&msg) + 1,
- sz_rfbFramebufferUpdateRequestMsg-1)) <= 0) {
- if (n != 0)
- rfbLogPerror("rfbProcessClientNormalMessage: read");
- rfbCloseClient(cl);
- return;
- }
-
- tmpRegion =
- sraRgnCreateRect(Swap16IfLE(msg.fur.x),
- Swap16IfLE(msg.fur.y),
- Swap16IfLE(msg.fur.x)+Swap16IfLE(msg.fur.w),
- Swap16IfLE(msg.fur.y)+Swap16IfLE(msg.fur.h));
-
- LOCK(cl->updateMutex);
- sraRgnOr(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)) {
- sraRgnDestroy(tmpRegion);
- UNLOCK(cl->updateMutex);
- return;
- }
- }
- }
-
- if (!msg.fur.incremental) {
- sraRgnOr(cl->modifiedRegion,tmpRegion);
- sraRgnSubtract(cl->copyRegion,tmpRegion);
- }
- TSIGNAL(cl->updateCond);
- UNLOCK(cl->updateMutex);
-
- sraRgnDestroy(tmpRegion);
-
- return;
- }
-
- case rfbKeyEvent:
-
- cl->rfbKeyEventsRcvd++;
-
- if ((n = ReadExact(cl, ((char *)&msg) + 1,
- sz_rfbKeyEventMsg - 1)) <= 0) {
- if (n != 0)
- rfbLogPerror("rfbProcessClientNormalMessage: read");
- rfbCloseClient(cl);
- return;
- }
-
- cl->screen->kbdAddEvent(msg.ke.down, (KeySym)Swap32IfLE(msg.ke.key), cl);
- return;
-
-
- case rfbPointerEvent:
-
- cl->rfbPointerEventsRcvd++;
-
- if ((n = ReadExact(cl, ((char *)&msg) + 1,
- sz_rfbPointerEventMsg - 1)) <= 0) {
- if (n != 0)
- rfbLogPerror("rfbProcessClientNormalMessage: read");
- rfbCloseClient(cl);
- return;
- }
-
- if (pointerClient && (pointerClient != cl))
- return;
-
- if (msg.pe.buttonMask == 0)
- pointerClient = NULL;
- else
- pointerClient = cl;
-
- cl->screen->ptrAddEvent(msg.pe.buttonMask,
- Swap16IfLE(msg.pe.x), Swap16IfLE(msg.pe.y), cl);
- return;
-
-
- case rfbClientCutText:
-
- if ((n = ReadExact(cl, ((char *)&msg) + 1,
- sz_rfbClientCutTextMsg - 1)) <= 0) {
- if (n != 0)
- rfbLogPerror("rfbProcessClientNormalMessage: read");
- rfbCloseClient(cl);
- return;
- }
-
- msg.cct.length = Swap32IfLE(msg.cct.length);
-
- str = (char *)malloc(msg.cct.length);
-
- if ((n = ReadExact(cl, str, msg.cct.length)) <= 0) {
- if (n != 0)
- rfbLogPerror("rfbProcessClientNormalMessage: read");
- free(str);
- rfbCloseClient(cl);
- return;
- }
-
- cl->screen->setXCutText(str, msg.cct.length, cl);
-
- free(str);
- return;
-
-
- default:
-
- rfbLog("rfbProcessClientNormalMessage: unknown message type %d\n",
- msg.type);
- rfbLog(" ... closing connection\n");
- rfbCloseClient(cl);
- return;
- }
-}
-
-
-/*
- * rfbSendPing - send an empty framebuffer request
- */
-
-Bool
-rfbSendPing(cl)
- rfbClientPtr cl;
-{
- rfbFramebufferUpdateMsg *fu = (rfbFramebufferUpdateMsg *)cl->updateBuf;
- cl->rfbFramebufferUpdateMessagesSent++;
- fu->type = rfbFramebufferUpdate;
- fu->nRects = Swap16IfLE((CARD16)0);
- cl->ublen = sz_rfbFramebufferUpdateMsg;
- return TRUE;
-}
-
-
-/*
- * rfbSendFramebufferUpdate - send the currently pending framebuffer update to
- * the RFB client.
- * givenUpdateRegion is not changed.
- */
-
-Bool
-rfbSendFramebufferUpdate(cl, givenUpdateRegion)
- rfbClientPtr cl;
- sraRegionPtr givenUpdateRegion;
-{
- sraRectangleIterator* i;
- sraRect rect;
- int nUpdateRegionRects;
- rfbFramebufferUpdateMsg *fu = (rfbFramebufferUpdateMsg *)cl->updateBuf;
- sraRegionPtr updateRegion,updateCopyRegion,tmpRegion;
- int dx, dy;
- Bool sendCursorShape = FALSE;
- int sendSoftCursorRects = 0;
-
- if(cl->screen->displayHook)
- cl->screen->displayHook(cl);
-
- /*
- * If this client understands cursor shape updates, cursor should be
- * removed from the framebuffer. Otherwise, make sure it's put up.
- */
-
- if (cl->enableCursorShapeUpdates) {
- if (cl->screen->cursorIsDrawn) {
- rfbUndrawCursor(cl->screen);
- }
- if (!cl->screen->cursorIsDrawn && cl->cursorWasChanged &&
- cl->readyForSetColourMapEntries)
- sendCursorShape = TRUE;
- }
- else if (cl->enableSoftCursorUpdates) {
- if (cl->screen->cursorIsDrawn) {
- rfbUndrawCursor(cl->screen);
- }
- if (cl->cursorWasChanged)
- sendSoftCursorRects=2;
- else if (cl->cursorWasMoved)
- sendSoftCursorRects=1;
- } else {
- if (!cl->screen->cursorIsDrawn) {
- rfbDrawCursor(cl->screen);
- }
- }
-
- LOCK(cl->updateMutex);
-
- /*
- * The modifiedRegion may overlap the destination copyRegion. We remove
- * any overlapping bits from the copyRegion (since they'd only be
- * overwritten anyway).
- */
-
- sraRgnSubtract(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.
- */
-
- updateRegion = sraRgnCreateRgn(givenUpdateRegion);
- sraRgnOr(updateRegion,cl->copyRegion);
- if(!sraRgnAnd(updateRegion,cl->requestedRegion) &&
- !(sendCursorShape || sendSoftCursorRects)) {
- sraRgnDestroy(updateRegion);
- UNLOCK(cl->updateMutex);
- return TRUE;
- }
-
- /*
- * 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.
- */
-
- updateCopyRegion = sraRgnCreateRgn(cl->copyRegion);
- sraRgnAnd(updateCopyRegion,cl->requestedRegion);
- tmpRegion = sraRgnCreateRgn(cl->requestedRegion);
- sraRgnOffset(tmpRegion,cl->copyDX,cl->copyDY);
- sraRgnAnd(updateCopyRegion,tmpRegion);
- sraRgnDestroy(tmpRegion);
- 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).
- */
-
- sraRgnSubtract(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.
- */
-
-
- sraRgnOr(cl->modifiedRegion,cl->copyRegion);
- sraRgnSubtract(cl->modifiedRegion,updateRegion);
- sraRgnSubtract(cl->modifiedRegion,updateCopyRegion);
-
- /* sraRgnMakeEmpty(cl->requestedRegion); */
- sraRgnMakeEmpty(cl->copyRegion);
- cl->copyDX = 0;
- cl->copyDY = 0;
-
- UNLOCK(cl->updateMutex);
-
- /*
- * Now send the update.
- */
-
- cl->rfbFramebufferUpdateMessagesSent++;
-
- if (cl->preferredEncoding == rfbEncodingCoRRE) {
- nUpdateRegionRects = 0;
-
- for(i = sraRgnGetIterator(updateRegion); sraRgnIteratorNext(i,&rect);){
- int x = rect.x1;
- int y = rect.y1;
- int w = rect.x2 - x;
- int h = rect.y2 - y;
- nUpdateRegionRects += (((w-1) / cl->correMaxWidth + 1)
- * ((h-1) / cl->correMaxHeight + 1));
- }
- } else if (cl->preferredEncoding == rfbEncodingZlib) {
- nUpdateRegionRects = 0;
-
- for(i = sraRgnGetIterator(updateRegion); sraRgnIteratorNext(i,&rect);){
- int x = rect.x1;
- int y = rect.y1;
- int w = rect.x2 - x;
- int h = rect.y2 - y;
- nUpdateRegionRects += (((h-1) / (ZLIB_MAX_SIZE( w ) / w)) + 1);
- }
- } else if (cl->preferredEncoding == rfbEncodingTight) {
- nUpdateRegionRects = 0;
-
- for(i = sraRgnGetIterator(updateRegion); sraRgnIteratorNext(i,&rect);){
- int x = rect.x1;
- int y = rect.y1;
- int w = rect.x2 - x;
- int h = rect.y2 - y;
- int n = rfbNumCodedRectsTight(cl, x, y, w, h);
- if (n == 0) {
- nUpdateRegionRects = 0xFFFF;
- break;
- }
- nUpdateRegionRects += n;
- }
- } else {
- nUpdateRegionRects = sraRgnCountRects(updateRegion);
- }
-
- fu->type = rfbFramebufferUpdate;
- if (nUpdateRegionRects != 0xFFFF) {
- fu->nRects = Swap16IfLE((CARD16)(sraRgnCountRects(updateCopyRegion)
- + nUpdateRegionRects
- + !!sendCursorShape + sendSoftCursorRects));
- } else {
- fu->nRects = 0xFFFF;
- }
- cl->ublen = sz_rfbFramebufferUpdateMsg;
-
- if (sendCursorShape) {
- cl->cursorWasChanged = FALSE;
- if (!rfbSendCursorShape(cl)) {
- sraRgnDestroy(updateRegion);
- return FALSE;
- }
- }
-
- if (sendSoftCursorRects) {
- if (!rfbSendSoftCursor(cl, cl->cursorWasChanged)) {
- sraRgnDestroy(updateRegion);
- return FALSE;
- }
- cl->cursorWasChanged = FALSE;
- cl->cursorWasMoved = FALSE;
- }
-
- if (!sraRgnEmpty(updateCopyRegion)) {
- if (!rfbSendCopyRegion(cl,updateCopyRegion,dx,dy)) {
- sraRgnDestroy(updateRegion);
- sraRgnDestroy(updateCopyRegion);
- return FALSE;
- }
- }
-
- sraRgnDestroy(updateCopyRegion);
-
- for(i = sraRgnGetIterator(updateRegion); sraRgnIteratorNext(i,&rect);){
- int x = rect.x1;
- int y = rect.y1;
- int w = rect.x2 - x;
- int h = rect.y2 - y;
-
- cl->rfbRawBytesEquivalent += (sz_rfbFramebufferUpdateRectHeader
- + w * (cl->format.bitsPerPixel / 8) * h);
-
- switch (cl->preferredEncoding) {
- case rfbEncodingRaw:
- if (!rfbSendRectEncodingRaw(cl, x, y, w, h)) {
- sraRgnDestroy(updateRegion);
- return FALSE;
- }
- break;
- case rfbEncodingRRE:
- if (!rfbSendRectEncodingRRE(cl, x, y, w, h)) {
- sraRgnDestroy(updateRegion);
- return FALSE;
- }
- break;
- case rfbEncodingCoRRE:
- if (!rfbSendRectEncodingCoRRE(cl, x, y, w, h)) {
- sraRgnDestroy(updateRegion);
- return FALSE;
- }
- break;
- case rfbEncodingHextile:
- if (!rfbSendRectEncodingHextile(cl, x, y, w, h)) {
- sraRgnDestroy(updateRegion);
- return FALSE;
- }
- break;
- case rfbEncodingZlib:
- if (!rfbSendRectEncodingZlib(cl, x, y, w, h)) {
- sraRgnDestroy(updateRegion);
- return FALSE;
- }
- break;
- case rfbEncodingTight:
- if (!rfbSendRectEncodingTight(cl, x, y, w, h)) {
- sraRgnDestroy(updateRegion);
- return FALSE;
- }
- break;
- }
- }
-
- if ( nUpdateRegionRects == 0xFFFF &&
- !rfbSendLastRectMarker(cl) ) {
- sraRgnDestroy(updateRegion);
- return FALSE;
- }
-
- if (!rfbSendUpdateBuf(cl)) {
- sraRgnDestroy(updateRegion);
- return FALSE;
- }
-
- sraRgnDestroy(updateRegion);
- 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.
- */
-
-Bool
-rfbSendCopyRegion(cl, reg, dx, dy)
- rfbClientPtr cl;
- sraRegionPtr reg;
- int dx, dy;
-{
- int x, y, w, h;
- rfbFramebufferUpdateRectHeader rect;
- rfbCopyRect cr;
- sraRectangleIterator* i;
- sraRect rect1;
-
- /* printf("copyrect: "); sraRgnPrint(reg); putchar('\n');fflush(stdout); */
- i = sraRgnGetReverseIterator(reg,dx>0,dy>0);
-
- while(sraRgnIteratorNext(i,&rect1)) {
- x = rect1.x1;
- y = rect1.y1;
- w = rect1.x2 - x;
- h = rect1.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(&cl->updateBuf[cl->ublen], (char *)&rect,
- sz_rfbFramebufferUpdateRectHeader);
- cl->ublen += sz_rfbFramebufferUpdateRectHeader;
-
- cr.srcX = Swap16IfLE(x - dx);
- cr.srcY = Swap16IfLE(y - dy);
-
- memcpy(&cl->updateBuf[cl->ublen], (char *)&cr, sz_rfbCopyRect);
- cl->ublen += sz_rfbCopyRect;
-
- cl->rfbRectanglesSent[rfbEncodingCopyRect]++;
- cl->rfbBytesSent[rfbEncodingCopyRect]
- += sz_rfbFramebufferUpdateRectHeader + sz_rfbCopyRect;
-
- }
-
- 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 = (cl->screen->frameBuffer + (cl->screen->paddedWidthInBytes * y)
- + (x * (cl->screen->bitsPerPixel / 8)));
-
- if (cl->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(&cl->updateBuf[cl->ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader);
- cl->ublen += sz_rfbFramebufferUpdateRectHeader;
-
- cl->rfbRectanglesSent[rfbEncodingRaw]++;
- cl->rfbBytesSent[rfbEncodingRaw]
- += sz_rfbFramebufferUpdateRectHeader + bytesPerLine * h;
-
- nlines = (UPDATE_BUF_SIZE - cl->ublen) / bytesPerLine;
-
- while (TRUE) {
- if (nlines > h)
- nlines = h;
-
- (*cl->translateFn)(cl->translateLookupTable,
- &(cl->screen->rfbServerFormat),
- &cl->format, fbptr, &cl->updateBuf[cl->ublen],
- cl->screen->paddedWidthInBytes, w, nlines);
-
- cl->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 += (cl->screen->paddedWidthInBytes * nlines);
-
- nlines = (UPDATE_BUF_SIZE - cl->ublen) / bytesPerLine;
- if (nlines == 0) {
- rfbLog("rfbSendRectEncodingRaw: send buffer too small for %d "
- "bytes per line\n", bytesPerLine);
- rfbCloseClient(cl);
- return FALSE;
- }
- }
-}
-
-
-
-/*
- * Send an empty rectangle with encoding field set to value of
- * rfbEncodingLastRect to notify client that this is the last
- * rectangle in framebuffer update ("LastRect" extension of RFB
- * protocol).
- */
-
-Bool
-rfbSendLastRectMarker(cl)
- rfbClientPtr cl;
-{
- rfbFramebufferUpdateRectHeader rect;
-
- if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) {
- if (!rfbSendUpdateBuf(cl))
- return FALSE;
- }
-
- rect.encoding = Swap32IfLE(rfbEncodingLastRect);
- rect.r.x = 0;
- rect.r.y = 0;
- rect.r.w = 0;
- rect.r.h = 0;
-
- memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader);
- cl->ublen += sz_rfbFramebufferUpdateRectHeader;
-
- cl->rfbLastRectMarkersSent++;
- cl->rfbLastRectBytesSent += sz_rfbFramebufferUpdateRectHeader;
-
- return TRUE;
-}
-
-
-/*
- * Send the contents of cl->updateBuf. Returns 1 if successful, -1 if
- * not (errno should be set).
- */
-
-Bool
-rfbSendUpdateBuf(cl)
- rfbClientPtr cl;
-{
- if(cl->sock<0)
- return FALSE;
-
- if (WriteExact(cl, cl->updateBuf, cl->ublen) < 0) {
- rfbLogPerror("rfbSendUpdateBuf: write");
- rfbCloseClient(cl);
- return FALSE;
- }
-
- cl->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]);
- rfbColourMap* cm = &cl->screen->colourMap;
-
- int i, len;
-
- scme->type = rfbSetColourMapEntries;
-
- scme->firstColour = Swap16IfLE(firstColour);
- scme->nColours = Swap16IfLE(nColours);
-
- len = sz_rfbSetColourMapEntriesMsg;
-
- for (i = 0; i < nColours; i++) {
- if(i<(int)cm->count) {
- if(cm->is16) {
- rgb[i*3] = Swap16IfLE(cm->data.shorts[i*3]);
- rgb[i*3+1] = Swap16IfLE(cm->data.shorts[i*3+1]);
- rgb[i*3+2] = Swap16IfLE(cm->data.shorts[i*3+2]);
- } else {
- rgb[i*3] = Swap16IfLE(cm->data.bytes[i*3]);
- rgb[i*3+1] = Swap16IfLE(cm->data.bytes[i*3+1]);
- rgb[i*3+2] = Swap16IfLE(cm->data.bytes[i*3+2]);
- }
- }
- }
-
- len += nColours * 3 * 2;
-
- if (WriteExact(cl, buf, len) < 0) {
- rfbLogPerror("rfbSendSetColourMapEntries: write");
- rfbCloseClient(cl);
- return FALSE;
- }
- return TRUE;
-}
-
-/*
- * rfbSendBell sends a Bell message to all the clients.
- */
-
-void
-rfbSendBell(rfbScreenInfoPtr rfbScreen)
-{
- rfbClientIteratorPtr i;
- rfbClientPtr cl;
- rfbBellMsg b;
-
- i = rfbGetClientIterator(rfbScreen);
- while((cl=rfbClientIteratorNext(i))) {
- b.type = rfbBell;
- if (WriteExact(cl, (char *)&b, sz_rfbBellMsg) < 0) {
- rfbLogPerror("rfbSendBell: write");
- rfbCloseClient(cl);
- }
- }
- rfbReleaseClientIterator(i);
-}
-
-
-/*
- * rfbSendServerCutText sends a ServerCutText message to all the clients.
- */
-
-void
-rfbSendServerCutText(rfbScreenInfoPtr rfbScreen,char *str, int len)
-{
- rfbClientPtr cl;
- rfbServerCutTextMsg sct;
- rfbClientIteratorPtr iterator;
-
- iterator = rfbGetClientIterator(rfbScreen);
- while ((cl = rfbClientIteratorNext(iterator)) != NULL) {
- sct.type = rfbServerCutText;
- sct.length = Swap32IfLE(len);
- if (WriteExact(cl, (char *)&sct,
- sz_rfbServerCutTextMsg) < 0) {
- rfbLogPerror("rfbSendServerCutText: write");
- rfbCloseClient(cl);
- continue;
- }
- if (WriteExact(cl, str, len) < 0) {
- rfbLogPerror("rfbSendServerCutText: write");
- rfbCloseClient(cl);
- }
- }
- rfbReleaseClientIterator(iterator);
-}
-
-/*****************************************************************************
- *
- * UDP can be used for keyboard and pointer events when the underlying
- * network is highly reliable. This is really here to support ORL's
- * videotile, whose TCP implementation doesn't like sending lots of small
- * packets (such as 100s of pen readings per second!).
- */
-
-unsigned char ptrAcceleration = 50;
-
-void
-rfbNewUDPConnection(rfbScreenInfoPtr rfbScreen, int sock)
-{
- if (write(sock, &ptrAcceleration, 1) < 0) {
- rfbLogPerror("rfbNewUDPConnection: write");
- }
-}
-
-/*
- * Because UDP is a message based service, we can't read the first byte and
- * then the rest of the packet separately like we do with TCP. We will always
- * get a whole packet delivered in one go, so we ask read() for the maximum
- * number of bytes we can possibly get.
- */
-
-void
-rfbProcessUDPInput(rfbScreenInfoPtr rfbScreen)
-{
- int n;
- rfbClientPtr cl=rfbScreen->udpClient;
- rfbClientToServerMsg msg;
-
- if((!cl) || cl->onHold)
- return;
-
- if ((n = read(rfbScreen->udpSock, (char *)&msg, sizeof(msg))) <= 0) {
- if (n < 0) {
- rfbLogPerror("rfbProcessUDPInput: read");
- }
- rfbDisconnectUDPSock(rfbScreen);
- return;
- }
-
- switch (msg.type) {
-
- case rfbKeyEvent:
- if (n != sz_rfbKeyEventMsg) {
- rfbLog("rfbProcessUDPInput: key event incorrect length\n");
- rfbDisconnectUDPSock(rfbScreen);
- return;
- }
- cl->screen->kbdAddEvent(msg.ke.down, (KeySym)Swap32IfLE(msg.ke.key), cl);
- break;
-
- case rfbPointerEvent:
- if (n != sz_rfbPointerEventMsg) {
- rfbLog("rfbProcessUDPInput: ptr event incorrect length\n");
- rfbDisconnectUDPSock(rfbScreen);
- return;
- }
- cl->screen->ptrAddEvent(msg.pe.buttonMask,
- Swap16IfLE(msg.pe.x), Swap16IfLE(msg.pe.y), cl);
- break;
-
- default:
- rfbLog("rfbProcessUDPInput: unknown message type %d\n",
- msg.type);
- rfbDisconnectUDPSock(rfbScreen);
- }
-}
-
-#ifdef BACKCHANNEL
-void rfbSendBackChannel(rfbScreenInfoPtr rfbScreen,char* str,int len)
-{
- rfbClientPtr cl;
- rfbBackChannelMsg sct;
- rfbClientIteratorPtr iterator;
-
- iterator = rfbGetClientIterator(rfbScreen);
- while ((cl = rfbClientIteratorNext(iterator)) != NULL) {
- if (cl->enableBackChannel) {
- sct.type = rfbBackChannel;
- sct.length = Swap32IfLE(len);
- if (WriteExact(cl, (char *)&sct,
- sz_rfbBackChannelMsg) < 0) {
- rfbLogPerror("rfbSendBackChannel: write");
- rfbCloseClient(cl);
- continue;
- }
- if (WriteExact(cl, str, len) < 0) {
- rfbLogPerror("rfbSendBackChannel: write");
- rfbCloseClient(cl);
- }
- }
- }
- rfbReleaseClientIterator(iterator);
-}
-#endif