summaryrefslogtreecommitdiffstats
path: root/libvncclient/rfbproto.c
diff options
context:
space:
mode:
authordscho <dscho>2005-10-06 19:26:41 +0000
committerdscho <dscho>2005-10-06 19:26:41 +0000
commit194a76df115db3b6fe62adbccfe4181ed46d2c52 (patch)
tree1b7e853cbd4c4482173d3b2f675580169dfd56d6 /libvncclient/rfbproto.c
parent11fc700c5db6afc6978211f5735707848b94ae8e (diff)
downloadlibtdevnc-194a76df115db3b6fe62adbccfe4181ed46d2c52.tar.gz
libtdevnc-194a76df115db3b6fe62adbccfe4181ed46d2c52.zip
add an extension mechanism for LibVNCClient, modify the client data handling
so that more than one data structure can be attached, and add an example to speak the client part of the back channel.
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;