summaryrefslogtreecommitdiffstats
path: root/libvncclient/rfbproto.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvncclient/rfbproto.c')
-rw-r--r--libvncclient/rfbproto.c101
1 files changed, 86 insertions, 15 deletions
diff --git a/libvncclient/rfbproto.c b/libvncclient/rfbproto.c
index 0e8ccfe..1a491a9 100644
--- a/libvncclient/rfbproto.c
+++ b/libvncclient/rfbproto.c
@@ -77,6 +77,49 @@ rfbDefaultClientLog(const char *format, ...)
rfbClientLogProc rfbClientLog=rfbDefaultClientLog;
rfbClientLogProc rfbClientErr=rfbDefaultClientLog;
+/* extensions */
+
+rfbClientProtocolExtension* rfbClientExtensions = NULL;
+
+void rfbClientRegisterExtension(rfbClientProtocolExtension* e)
+{
+ e->next = rfbClientExtensions;
+ rfbClientExtensions = e;
+}
+
+/* client data */
+
+void rfbClientSetClientData(rfbClient* client, void* tag, void* data)
+{
+ rfbClientData* clientData = client->clientData;
+
+ while(clientData && clientData->tag != tag)
+ clientData = clientData->next;
+ if(clientData == NULL) {
+ clientData = calloc(sizeof(rfbClientData), 1);
+ clientData->next = client->clientData;
+ client->clientData = clientData;
+ clientData->tag = tag;
+ }
+
+ clientData->data = data;
+}
+
+void* rfbClientGetClientData(rfbClient* client, void* tag)
+{
+ rfbClientData* clientData = client->clientData;
+
+ while(clientData) {
+ if(clientData->tag == tag)
+ return clientData->data;
+ clientData = clientData->next;
+ }
+
+ return NULL;
+}
+
+/* messages */
+
static void FillRectangle(rfbClient* client, int x, int y, int w, int h, uint32_t colour) {
int i,j;
@@ -259,6 +302,12 @@ InitialiseRFBConnection(rfbClient* client)
return FALSE;
}
+#if rfbProtocolMinorVersion == 7
+ /* work around LibVNCClient not yet speaking RFB 3.7 */
+#undef rfbProtocolMinorVersion
+#define rfbProtocolMinorVersion 3
+#endif
+
rfbClientLog("VNC server supports protocol version %d.%d (viewer %d.%d)\n",
major, minor, rfbProtocolMajorVersion, rfbProtocolMinorVersion);
@@ -394,6 +443,7 @@ SetFormatAndEncodings(rfbClient* client)
rfbBool requestCompressLevel = FALSE;
rfbBool requestQualityLevel = FALSE;
rfbBool requestLastRectEncoding = FALSE;
+ rfbClientProtocolExtension* e;
spf.type = rfbSetPixelFormat;
spf.format = client->format;
@@ -535,6 +585,13 @@ SetFormatAndEncodings(rfbClient* client)
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect);
}
+ for(e = rfbClientExtensions; e; e = e->next)
+ if(e->encodings) {
+ int* enc;
+ for(enc = e->encodings; *enc; enc++)
+ encs[se->nEncodings++] = rfbClientSwap32IfLE(*enc);
+ }
+
len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
se->nEncodings = rfbClientSwap16IfLE(se->nEncodings);
@@ -923,9 +980,20 @@ HandleRFBServerMessage(rfbClient* client)
#endif
default:
- rfbClientLog("Unknown rect encoding %d\n",
- (int)rect.encoding);
- return FALSE;
+ {
+ rfbBool handled = FALSE;
+ rfbClientProtocolExtension* e;
+
+ for(e = rfbClientExtensions; !handled && e; e = e->next)
+ if(e->handleEncoding && e->handleEncoding(client, &rect))
+ handled = TRUE;
+
+ if(!handled) {
+ rfbClientLog("Unknown rect encoding %d\n",
+ (int)rect.encoding);
+ return FALSE;
+ }
+ }
}
/* Now we may discard "soft cursor locks". */
@@ -934,16 +1002,6 @@ HandleRFBServerMessage(rfbClient* client)
client->GotFrameBufferUpdate(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
}
-#ifdef MITSHM
- /* if using shared memory PutImage, make sure that the X server has
- updated its framebuffer before we reuse the shared memory. This is
- mainly to avoid copyrect using invalid screen contents - not sure
- if we'd need it otherwise. */
-
- if (client->appData.useShm)
- XSync(dpy, FALSE);
-#endif
-
if (!SendIncrementalFramebufferUpdateRequest(client))
return FALSE;
@@ -981,8 +1039,21 @@ HandleRFBServerMessage(rfbClient* client)
}
default:
- rfbClientLog("Unknown message type %d from VNC server\n",msg.type);
- return FALSE;
+ {
+ rfbBool handled = FALSE;
+ rfbClientProtocolExtension* e;
+
+ for(e = rfbClientExtensions; !handled && e; e = e->next)
+ if(e->handleMessage && e->handleMessage(client, &msg))
+ handled = TRUE;
+
+ if(!handled) {
+ char buffer[256];
+ ReadFromRFBServer(client, buffer, 256);
+ rfbClientLog("Unknown message type %d from VNC server\n",msg.type);
+ return FALSE;
+ }
+ }
}
return TRUE;