diff options
author | dscho <dscho> | 2005-10-06 19:26:41 +0000 |
---|---|---|
committer | dscho <dscho> | 2005-10-06 19:26:41 +0000 |
commit | 194a76df115db3b6fe62adbccfe4181ed46d2c52 (patch) | |
tree | 1b7e853cbd4c4482173d3b2f675580169dfd56d6 /libvncclient/rfbproto.c | |
parent | 11fc700c5db6afc6978211f5735707848b94ae8e (diff) | |
download | libtdevnc-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.c | 101 |
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; |