summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--libvncclient/rfbproto.c107
-rw-r--r--libvncserver/rfbserver.c280
-rw-r--r--rfb/rfb.h7
-rw-r--r--rfb/rfbproto.h41
-rw-r--r--x11vnc/screen.c2
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 <scarr@jsa-usa.com>
+ * 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 <scarr@jsa-usa.com>
* 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 <stdarg.h>
#include <scale.h>
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 <per setEncodings message received>
+ * (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 <per setEncodings message received>
+ * (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 <per setEncodings message received>
+ * (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) {