From 0d734ad8967eafab1fb058280a0db04e7470e569 Mon Sep 17 00:00:00 2001 From: steven_carr Date: Thu, 4 May 2006 19:19:13 +0000 Subject: [PATCH] Server Capability Encodings rfbEncodingSupportedEncodings - What encodings are supported? rfbEncodingSupportedMessages - What message types are supported? rfbEncodingServerIdentity - What is the servers version string? ie: "x11vnc: 0.8.1 lastmod: 2006-04-25 (LibVNCServer 0.9pre)" --- ChangeLog | 8 ++ libvncclient/rfbproto.c | 107 +++++++++++---- libvncserver/rfbserver.c | 280 ++++++++++++++++++++++++++++++++++++++- rfb/rfb.h | 7 + rfb/rfbproto.h | 41 +++++- x11vnc/screen.c | 2 + 6 files changed, 413 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index da59b24..4c1916a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-05-04 Steven Carr + * rfbEncodingSupportedEncodings - What encodings are supported? + * rfbEncodingSupportedMessages - What message types are supported? + This way a client can identify if a particular server supports a + specific message types. + * rfbEncodingServerIdentity - What is the servers version string? + ie: "x11vnc: 0.8.1 lastmod: 2006-04-25 (LibVNCServer 0.9pre)" + 2006-05-03 Steven Carr * Server Side Scaling is now supported in libvncserver Both PalmVNC and UltraVNC SetScale messages are supported diff --git a/libvncclient/rfbproto.c b/libvncclient/rfbproto.c index 3a325ee..a7ad216 100644 --- a/libvncclient/rfbproto.c +++ b/libvncclient/rfbproto.c @@ -532,25 +532,6 @@ SetFormatAndEncodings(rfbClient* client) encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel + rfbEncodingQualityLevel0); } - - - if (client->appData.useRemoteCursor) { - if (se->nEncodings < MAX_ENCODINGS) - encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingXCursor); - if (se->nEncodings < MAX_ENCODINGS) - encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRichCursor); - if (se->nEncodings < MAX_ENCODINGS) - encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPointerPos); - } - - /* Let's receive keyboard state encoding if available */ - if (se->nEncodings < MAX_ENCODINGS) { - encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingKeyboardLedState); - } - - if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) { - encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect); - } } else { if (SameMachine(client->sock)) { @@ -570,6 +551,7 @@ SetFormatAndEncodings(rfbClient* client) #ifdef LIBVNCSERVER_HAVE_LIBZ #ifdef LIBVNCSERVER_HAVE_LIBJPEG encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTight); + requestLastRectEncoding = TRUE; #endif #endif encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingHextile); @@ -599,24 +581,42 @@ SetFormatAndEncodings(rfbClient* client) encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel + rfbEncodingQualityLevel0); } + } - if (client->appData.useRemoteCursor) { + + + /* Remote Cursor Support (local to viewer) */ + if (client->appData.useRemoteCursor) { + if (se->nEncodings < MAX_ENCODINGS) encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingXCursor); + if (se->nEncodings < MAX_ENCODINGS) encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRichCursor); - encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPointerPos); - } - if (se->nEncodings < MAX_ENCODINGS) - encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect); + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPointerPos); } /* Keyboard State Encodings */ if (se->nEncodings < MAX_ENCODINGS) encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingKeyboardLedState); + /* New Frame Buffer Size */ if (se->nEncodings < MAX_ENCODINGS && client->canHandleNewFBSize) encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingNewFBSize); + /* Last Rect */ + if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect); + + /* Server Capabilities */ + if (se->nEncodings < MAX_ENCODINGS) + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedMessages); + if (se->nEncodings < MAX_ENCODINGS) + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedEncodings); + if (se->nEncodings < MAX_ENCODINGS) + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingServerIdentity); + + + /* client extensions */ for(e = rfbClientExtensions; e; e = e->next) if(e->encodings) { int* enc; @@ -856,6 +856,65 @@ HandleRFBServerMessage(rfbClient* client) continue; } + /* rect.r.w=byte count */ + if (rect.encoding == rfbEncodingSupportedMessages) { + rfbSupportedMessages msgs; + int loop; + if (!ReadFromRFBServer(client, (char *)&msgs, sz_rfbSupportedMessages)) + return FALSE; + + /* msgs is two sets of bit flags of supported messages client2server[] and server2client[] */ + /* currently ignored by this library */ + + rfbClientLog("client2server supported messages (bit flags)\n"); + for (loop=0;loop<32;loop+=8) + rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop, + msgs.client2server[loop], msgs.client2server[loop+1], + msgs.client2server[loop+2], msgs.client2server[loop+3], + msgs.client2server[loop+4], msgs.client2server[loop+5], + msgs.client2server[loop+6], msgs.client2server[loop+7]); + + rfbClientLog("server2client supported messages (bit flags)\n"); + for (loop=0;loop<32;loop+=8) + rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop, + msgs.server2client[loop], msgs.server2client[loop+1], + msgs.server2client[loop+2], msgs.server2client[loop+3], + msgs.server2client[loop+4], msgs.server2client[loop+5], + msgs.server2client[loop+6], msgs.server2client[loop+7]); + continue; + } + + /* rect.r.w=byte count, rect.r.h=# of encodings */ + if (rect.encoding == rfbEncodingSupportedEncodings) { + char *buffer; + buffer = malloc(rect.r.w); + if (!ReadFromRFBServer(client, buffer, rect.r.w)) + { + free(buffer); + return FALSE; + } + + /* buffer now contains rect.r.h # of uint32_t encodings that the server supports */ + /* currently ignored by this library */ + free(buffer); + continue; + } + + /* rect.r.w=byte count */ + if (rect.encoding == rfbEncodingServerIdentity) { + char *buffer; + buffer = malloc(rect.r.w+1); + if (!ReadFromRFBServer(client, buffer, rect.r.w)) + { + free(buffer); + return FALSE; + } + buffer[rect.r.w]=0; /* null terminate, just in case */ + rfbClientLog("Connected to Server \"%s\"\n", buffer); + free(buffer); + continue; + } + /* rfbEncodingUltraZip is a collection of subrects. x = # of subrects, and h is always 0 */ if (rect.encoding != rfbEncodingUltraZip) { diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c index d3e1fbb..89bf0ca 100644 --- a/libvncserver/rfbserver.c +++ b/libvncserver/rfbserver.c @@ -64,7 +64,7 @@ #else #define DEBUGPROTO(x) #endif - +#include #include static void rfbProcessClientProtocolVersion(rfbClientPtr cl); @@ -353,6 +353,9 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen, cl->useRichCursorEncoding = FALSE; cl->enableLastRectEncoding = FALSE; cl->enableKeyboardLedState = FALSE; + cl->enableSupportedMessages = FALSE; + cl->enableSupportedEncodings = FALSE; + cl->enableServerIdentity = FALSE; cl->lastKeyboardLedState = -1; cl->cursorX = rfbScreen->cursorX; cl->cursorY = rfbScreen->cursorY; @@ -782,6 +785,204 @@ rfbSendKeyboardLedState(rfbClientPtr cl) } +#define rfbSetBit(buffer, position) (buffer[(position & 255) / 8] |= (1 << (position % 8))) + +/* + * Send rfbEncodingSupportedMessages. + */ + +rfbBool +rfbSendSupportedMessages(rfbClientPtr cl) +{ + rfbFramebufferUpdateRectHeader rect; + rfbSupportedMessages msgs; + + if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + + sz_rfbSupportedMessages > UPDATE_BUF_SIZE) { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + rect.encoding = Swap32IfLE(rfbEncodingSupportedMessages); + rect.r.x = 0; + rect.r.y = 0; + rect.r.w = Swap16IfLE(sz_rfbFramebufferUpdateRectHeader); + rect.r.h = 0; + + memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, + sz_rfbFramebufferUpdateRectHeader); + cl->ublen += sz_rfbFramebufferUpdateRectHeader; + + memset((char *)&msgs, 0, sz_rfbSupportedMessages); + rfbSetBit(msgs.client2server, rfbSetPixelFormat); + rfbSetBit(msgs.client2server, rfbFixColourMapEntries); + rfbSetBit(msgs.client2server, rfbSetEncodings); + rfbSetBit(msgs.client2server, rfbFramebufferUpdateRequest); + rfbSetBit(msgs.client2server, rfbKeyEvent); + rfbSetBit(msgs.client2server, rfbPointerEvent); + rfbSetBit(msgs.client2server, rfbClientCutText); + rfbSetBit(msgs.client2server, rfbFileTransfer); + rfbSetBit(msgs.client2server, rfbSetScale); + //rfbSetBit(msgs.client2server, rfbSetServerInput); + //rfbSetBit(msgs.client2server, rfbSetSW); + //rfbSetBit(msgs.client2server, rfbTextChat); + //rfbSetBit(msgs.client2server, rfbKeyFrameRequest); + rfbSetBit(msgs.client2server, rfbPalmVNCSetScaleFactor); + + rfbSetBit(msgs.server2client, rfbFramebufferUpdate); + rfbSetBit(msgs.server2client, rfbSetColourMapEntries); + rfbSetBit(msgs.server2client, rfbBell); + rfbSetBit(msgs.server2client, rfbServerCutText); + rfbSetBit(msgs.server2client, rfbResizeFrameBuffer); + //rfbSetBit(msgs.server2client, rfbKeyFrameUpdate); + rfbSetBit(msgs.server2client, rfbPalmVNCReSizeFrameBuffer); + + memcpy(&cl->updateBuf[cl->ublen], (char *)&msgs, sz_rfbSupportedMessages); + cl->ublen += sz_rfbSupportedMessages; + + if (!rfbSendUpdateBuf(cl)) + return FALSE; + + return TRUE; +} + + + +static void rfbSendSupporteddEncodings_SendEncoding(rfbClientPtr cl, uint32_t enc) +{ + uint32_t nSwapped=0; + nSwapped = Swap32IfLE(enc); + memcpy(&cl->updateBuf[cl->ublen], (char *)&nSwapped, sizeof(nSwapped)); + cl->ublen+=sizeof(nSwapped); +} + + +/* + * Send rfbEncodingSupportedEncodings. + */ + +rfbBool +rfbSendSupportedEncodings(rfbClientPtr cl) +{ + rfbFramebufferUpdateRectHeader rect; + uint16_t nEncodings=0; + + /* think rfbSetEncodingsMsg */ + + /* TODO: dynamic way of doing this */ + nEncodings=16; +#ifdef LIBVNCSERVER_HAVE_LIBZ + nEncodings += 2; +#endif +#ifdef LIBVNCSERVER_HAVE_LIBZ + nEncodings++; +#endif + + if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + + (nEncodings*sizeof(uint32_t)) > UPDATE_BUF_SIZE) { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + rect.encoding = Swap32IfLE(rfbEncodingSupportedEncodings); + rect.r.x = 0; + rect.r.y = 0; + rect.r.w = Swap16IfLE(nEncodings * sizeof(uint32_t)); + rect.r.h = Swap16IfLE(nEncodings); + + memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, + sz_rfbFramebufferUpdateRectHeader); + cl->ublen += sz_rfbFramebufferUpdateRectHeader; + + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingRaw); + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingCopyRect); + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingRRE); + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingCoRRE); + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingHextile); +#ifdef LIBVNCSERVER_HAVE_LIBZ + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingZlib); + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingTight); +#endif +#ifdef LIBVNCSERVER_HAVE_LIBZ + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingZRLE); +#endif + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingUltra); + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingUltraZip); + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingXCursor); + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingRichCursor); + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingPointerPos); + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingLastRect); + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingNewFBSize); + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingKeyboardLedState); + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingSupportedMessages); + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingSupportedEncodings); + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingServerIdentity); + + if (!rfbSendUpdateBuf(cl)) + return FALSE; + + return TRUE; +} + + +void +rfbSetServerVersionIdentity(rfbScreenInfoPtr screen, char *fmt, ...) +{ + char buffer[256]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(buffer, sizeof(buffer)-1, fmt, ap); + va_end(ap); + + if (screen->versionString!=NULL) free(screen->versionString); + screen->versionString = strdup(buffer); +} + +/* + * Send rfbEncodingServerIdentity. + */ + +rfbBool +rfbSendServerIdentity(rfbClientPtr cl) +{ + rfbFramebufferUpdateRectHeader rect; + char buffer[512]; + + /* tack on our library version */ + snprintf(buffer,sizeof(buffer)-1, "%s (%s)", + (cl->screen->versionString==NULL ? "unknown" : cl->screen->versionString), + LIBVNCSERVER_PACKAGE_STRING); + + if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + + (strlen(buffer)+1) > UPDATE_BUF_SIZE) { + if (!rfbSendUpdateBuf(cl)) + return FALSE; + } + + rect.encoding = Swap32IfLE(rfbEncodingServerIdentity); + rect.r.x = 0; + rect.r.y = 0; + rect.r.w = Swap16IfLE(strlen(buffer)+1); + rect.r.h = 0; + + memcpy(&cl->updateBuf[cl->ublen], (char *)&rect, + sz_rfbFramebufferUpdateRectHeader); + cl->ublen += sz_rfbFramebufferUpdateRectHeader; + + memcpy(&cl->updateBuf[cl->ublen], buffer, strlen(buffer)+1); + cl->ublen += strlen(buffer)+1; + + if (!rfbSendUpdateBuf(cl)) + return FALSE; + + return TRUE; +} + + + + + /* * rfbProcessClientNormalMessage is called when the client has sent a normal * protocol message. @@ -978,6 +1179,27 @@ rfbProcessClientNormalMessage(rfbClientPtr cl) cl->enableKeyboardLedState = TRUE; } break; + case rfbEncodingSupportedMessages: + if (!cl->enableSupportedMessages) { + rfbLog("Enabling SupportedMessages protocol extension for client " + "%s\n", cl->host); + cl->enableSupportedMessages = TRUE; + } + break; + case rfbEncodingSupportedEncodings: + if (!cl->enableSupportedEncodings) { + rfbLog("Enabling SupportedEncodings protocol extension for client " + "%s\n", cl->host); + cl->enableSupportedEncodings = TRUE; + } + break; + case rfbEncodingServerIdentity: + if (!cl->enableServerIdentity) { + rfbLog("Enabling ServerIdentity protocol extension for client " + "%s\n", cl->host); + cl->enableServerIdentity = TRUE; + } + break; #ifdef LIBVNCSERVER_HAVE_LIBZ case rfbEncodingZRLE: if (cl->preferredEncoding == -1) { @@ -1268,6 +1490,9 @@ rfbSendFramebufferUpdate(rfbClientPtr cl, rfbBool sendCursorShape = FALSE; rfbBool sendCursorPos = FALSE; rfbBool sendKeyboardLedState = FALSE; + rfbBool sendSupportedMessages = FALSE; + rfbBool sendSupportedEncodings = FALSE; + rfbBool sendServerIdentity = FALSE; rfbBool result = TRUE; @@ -1325,6 +1550,40 @@ rfbSendFramebufferUpdate(rfbClientPtr cl, } } + /* + * Do we plan to send a rfbEncodingSupportedMessages? + */ + if (cl->enableSupportedMessages) + { + sendSupportedMessages = TRUE; + /* We only send this message ONCE + * (We disable it here) + */ + cl->enableSupportedMessages = FALSE; + } + /* + * Do we plan to send a rfbEncodingSupportedEncodings? + */ + if (cl->enableSupportedEncodings) + { + sendSupportedEncodings = TRUE; + /* We only send this message ONCE + * (We disable it here) + */ + cl->enableSupportedEncodings = FALSE; + } + /* + * Do we plan to send a rfbEncodingServerIdentity? + */ + if (cl->enableServerIdentity) + { + sendServerIdentity = TRUE; + /* We only send this message ONCE + * (We disable it here) + */ + cl->enableServerIdentity = FALSE; + } + LOCK(cl->updateMutex); /* @@ -1368,7 +1627,8 @@ rfbSendFramebufferUpdate(rfbClientPtr cl, sraRgnEmpty(updateRegion) && (cl->enableCursorShapeUpdates || (cl->cursorX == cl->screen->cursorX && cl->cursorY == cl->screen->cursorY)) && - !sendCursorShape && !sendCursorPos && !sendKeyboardLedState) { + !sendCursorShape && !sendCursorPos && !sendKeyboardLedState && + !sendSupportedMessages && !sendSupportedEncodings && !sendServerIdentity) { sraRgnDestroy(updateRegion); UNLOCK(cl->updateMutex); return TRUE; @@ -1529,7 +1789,8 @@ rfbSendFramebufferUpdate(rfbClientPtr cl, } fu->nRects = Swap16IfLE((uint16_t)(sraRgnCountRects(updateCopyRegion) + nUpdateRegionRects + - !!sendCursorShape + !!sendCursorPos + !!sendKeyboardLedState)); + !!sendCursorShape + !!sendCursorPos + !!sendKeyboardLedState + + !!sendSupportedMessages + !!sendSupportedEncodings + !!sendServerIdentity)); } else { fu->nRects = 0xFFFF; } @@ -1551,6 +1812,19 @@ rfbSendFramebufferUpdate(rfbClientPtr cl, if (!rfbSendKeyboardLedState(cl)) goto updateFailed; } + + if (sendSupportedMessages) { + if (!rfbSendSupportedMessages(cl)) + goto updateFailed; + } + if (sendSupportedEncodings) { + if (!rfbSendSupportedEncodings(cl)) + goto updateFailed; + } + if (sendServerIdentity) { + if (!rfbSendServerIdentity(cl)) + goto updateFailed; + } if (!sraRgnEmpty(updateCopyRegion)) { if (!rfbSendCopyRegion(cl,updateCopyRegion,dx,dy)) diff --git a/rfb/rfb.h b/rfb/rfb.h index 23d64d4..39abe77 100644 --- a/rfb/rfb.h +++ b/rfb/rfb.h @@ -323,6 +323,9 @@ typedef struct _rfbScreenInfo /* handle as many input events as possible (default off) */ rfbBool handleEventsEagerly; + + /* rfbEncodingServerIdentity */ + char *versionString; } rfbScreenInfo, *rfbScreenInfoPtr; @@ -501,6 +504,9 @@ typedef struct _rfbClientRec { int lastKeyboardLedState; /* keep track of last value so we can send *change* events */ + rfbBool enableSupportedMessages; /* client supports SupportedMessages encoding */ + rfbBool enableSupportedEncodings; /* client supports SupportedEncodings encoding */ + rfbBool enableServerIdentity; /* client supports ServerIdentity encoding */ rfbBool enableKeyboardLedState; /* client supports KeyboardState encoding */ rfbBool enableLastRectEncoding; /* client supports LastRect encoding */ rfbBool enableCursorShapeUpdates; /* client supports cursor shape updates */ @@ -852,6 +858,7 @@ extern void rfbNewFramebuffer(rfbScreenInfoPtr rfbScreen,char *framebuffer, int bytesPerPixel); extern void rfbScreenCleanup(rfbScreenInfoPtr screenInfo); +extern void rfbSetServerVersionIdentity(rfbScreenInfoPtr screen, char *fmt, ...); /* functions to accept/refuse a client that has been put on hold by a NewClientHookPtr function. Must not be called in other diff --git a/rfb/rfbproto.h b/rfb/rfbproto.h index 7e9d9fd..c642f61 100644 --- a/rfb/rfbproto.h +++ b/rfb/rfbproto.h @@ -401,8 +401,8 @@ typedef struct { #define rfbEncodingZlib 6 #define rfbEncodingTight 7 #define rfbEncodingZlibHex 8 -#define rfbEncodingUltra 9 #endif +#define rfbEncodingUltra 9 #ifdef LIBVNCSERVER_HAVE_LIBZ #define rfbEncodingZRLE 16 #endif @@ -446,9 +446,12 @@ typedef struct { #define rfbEncodingRichCursor 0xFFFFFF11 #define rfbEncodingPointerPos 0xFFFFFF18 -#define rfbEncodingLastRect 0xFFFFFF20 -#define rfbEncodingNewFBSize 0xFFFFFF21 -#define rfbEncodingKeyboardLedState 0xFFFFFF22 +#define rfbEncodingLastRect 0xFFFFFF20 +#define rfbEncodingNewFBSize 0xFFFFFF21 +#define rfbEncodingKeyboardLedState 0xFFFFFF22 +#define rfbEncodingSupportedMessages 0xFFFFFF23 +#define rfbEncodingSupportedEncodings 0xFFFFFF24 +#define rfbEncodingServerIdentity 0xFFFFFF25 #define rfbEncodingQualityLevel0 0xFFFFFFE0 #define rfbEncodingQualityLevel1 0xFFFFFFE1 @@ -514,6 +517,34 @@ typedef struct { #define sz_rfbFramebufferUpdateRectHeader (sz_rfbRectangle + 4) +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Supported Messages Encoding. This encoding does not contain any pixel data. + * Instead, it contains 2 sets of bitflags. These bitflags indicate what messages + * are supported by the server. + * rect->w contains byte count + */ + +typedef struct { + uint8_t client2server[32]; /* maximum of 256 message types (256/8)=32 */ + uint8_t server2client[32]; /* maximum of 256 message types (256/8)=32 */ +} rfbSupportedMessages; + +#define sz_rfbSupportedMessages 64 + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Supported Encodings Encoding. This encoding does not contain any pixel data. + * Instead, it contains a list of (uint32_t) Encodings supported by this server. + * rect->w contains byte count + * rect->h contains encoding count + */ + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Server Identity Encoding. This encoding does not contain any pixel data. + * Instead, it contains a text string containing information about the server. + * ie: "x11vnc: 0.8.1 lastmod: 2006-04-25 (libvncserver 0.9pre)\0" + * rect->w contains byte count + */ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Raw Encoding. Pixels are sent in top-to-bottom scanline order, @@ -1244,7 +1275,7 @@ typedef struct _rfbSetScaleMsg { * client buffer. */ typedef struct { - uint8_t type; /* always rfbSetScaleFactor */ + uint8_t type; /* always rfbPalmVNCSetScaleFactor */ uint8_t scale; /* Scale factor (positive non-zero integer) */ uint16_t pad2; diff --git a/x11vnc/screen.c b/x11vnc/screen.c index 3eaeb87..e85f2f1 100644 --- a/x11vnc/screen.c +++ b/x11vnc/screen.c @@ -1966,6 +1966,8 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { screen->deferUpdateTime = defer_update; } + rfbSetServerVersionIdentity(screen, "x11vnc: %s", lastmod); + rfbInitServer(screen); if (use_openssl) {