diff options
Diffstat (limited to 'libvncclient/vncviewer.c')
-rw-r--r-- | libvncclient/vncviewer.c | 147 |
1 files changed, 142 insertions, 5 deletions
diff --git a/libvncclient/vncviewer.c b/libvncclient/vncviewer.c index 8a59c6d..486390e 100644 --- a/libvncclient/vncviewer.c +++ b/libvncclient/vncviewer.c @@ -109,6 +109,125 @@ static rfbBool MallocFrameBuffer(rfbClient* client) { return client->frameBuffer?TRUE:FALSE; } +/* messages */ + +static rfbBool CheckRect(rfbClient* client, int x, int y, int w, int h) { + return x + w <= client->width && y + h <= client->height; +} + +static void FillRectangle(rfbClient* client, int x, int y, int w, int h, uint32_t colour) { + int i,j; + + if (client->frameBuffer == NULL) { + return; + } + + if (!CheckRect(client, x, y, w, h)) { + rfbClientLog("Rect out of bounds: %dx%d at (%d, %d)\n", x, y, w, h); + return; + } + +#define FILL_RECT(BPP) \ + for(j=y*client->width;j<(y+h)*client->width;j+=client->width) \ + for(i=x;i<x+w;i++) \ + ((uint##BPP##_t*)client->frameBuffer)[j+i]=colour; + + switch(client->format.bitsPerPixel) { + case 8: FILL_RECT(8); break; + case 16: FILL_RECT(16); break; + case 32: FILL_RECT(32); break; + default: + rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel); + } +} + +static void CopyRectangle(rfbClient* client, const uint8_t* buffer, int x, int y, int w, int h) { + int j; + + if (client->frameBuffer == NULL) { + return; + } + + if (!CheckRect(client, x, y, w, h)) { + rfbClientLog("Rect out of bounds: %dx%d at (%d, %d)\n", x, y, w, h); + return; + } + +#define COPY_RECT(BPP) \ + { \ + int rs = w * BPP / 8, rs2 = client->width * BPP / 8; \ + for (j = ((x * (BPP / 8)) + (y * rs2)); j < (y + h) * rs2; j += rs2) { \ + memcpy(client->frameBuffer + j, buffer, rs); \ + buffer += rs; \ + } \ + } + + switch(client->format.bitsPerPixel) { + case 8: COPY_RECT(8); break; + case 16: COPY_RECT(16); break; + case 32: COPY_RECT(32); break; + default: + rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel); + } +} + +/* TODO: test */ +static void CopyRectangleFromRectangle(rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y) { + int i,j; + + if (client->frameBuffer == NULL) { + return; + } + + if (!CheckRect(client, src_x, src_y, w, h)) { + rfbClientLog("Source rect out of bounds: %dx%d at (%d, %d)\n", src_x, src_y, w, h); + return; + } + + if (!CheckRect(client, dest_x, dest_y, w, h)) { + rfbClientLog("Dest rect out of bounds: %dx%d at (%d, %d)\n", dest_x, dest_y, w, h); + return; + } + +#define COPY_RECT_FROM_RECT(BPP) \ + { \ + uint##BPP##_t* _buffer=((uint##BPP##_t*)client->frameBuffer)+(src_y-dest_y)*client->width+src_x-dest_x; \ + if (dest_y < src_y) { \ + for(j = dest_y*client->width; j < (dest_y+h)*client->width; j += client->width) { \ + if (dest_x < src_x) { \ + for(i = dest_x; i < dest_x+w; i++) { \ + ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \ + } \ + } else { \ + for(i = dest_x+w-1; i >= dest_x; i--) { \ + ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \ + } \ + } \ + } \ + } else { \ + for(j = (dest_y+h-1)*client->width; j >= dest_y*client->width; j-=client->width) { \ + if (dest_x < src_x) { \ + for(i = dest_x; i < dest_x+w; i++) { \ + ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \ + } \ + } else { \ + for(i = dest_x+w-1; i >= dest_x; i--) { \ + ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \ + } \ + } \ + } \ + } \ + } + + switch(client->format.bitsPerPixel) { + case 8: COPY_RECT_FROM_RECT(8); break; + case 16: COPY_RECT_FROM_RECT(16); break; + case 32: COPY_RECT_FROM_RECT(32); break; + default: + rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel); + } +} + static void initAppData(AppData* data) { data->shareDesktop=TRUE; data->viewOnly=FALSE; @@ -157,7 +276,7 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel, client->format.depth = bitsPerSample*samplesPerPixel; client->appData.requestedDepth=client->format.depth; client->format.bigEndian = *(char *)&client->endianTest?FALSE:TRUE; - client->format.trueColour = TRUE; + client->format.trueColour = 1; if (client->format.bitsPerPixel == 8) { client->format.redMax = 7; @@ -196,7 +315,6 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel, #ifdef LIBVNCSERVER_HAVE_LIBJPEG memset(client->zlibStreamActive,0,sizeof(rfbBool)*4); - client->jpegSrcManager = NULL; #endif #endif @@ -204,6 +322,9 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel, client->SoftCursorLockArea = DummyRect; client->SoftCursorUnlockScreen = Dummy; client->GotFrameBufferUpdate = DummyRect; + client->GotCopyRect = CopyRectangleFromRectangle; + client->GotFillRect = FillRectangle; + client->GotBitmap = CopyRectangle; client->FinishedFrameBufferUpdate = NULL; client->GetPassword = ReadPassword; client->MallocFrameBuffer = MallocFrameBuffer; @@ -224,6 +345,13 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel, client->listen6Sock = -1; client->listen6Address = NULL; client->clientAuthSchemes = NULL; + +#ifdef LIBVNCSERVER_HAVE_SASL + client->GetSASLMechanism = NULL; + client->GetUser = NULL; + client->saslSecret = NULL; +#endif /* LIBVNCSERVER_HAVE_SASL */ + return client; } @@ -390,12 +518,15 @@ void rfbClientCleanup(rfbClient* client) { client->decompStream.msg != NULL) rfbClientLog("inflateEnd: %s\n", client->decompStream.msg ); } - - if (client->jpegSrcManager) - free(client->jpegSrcManager); #endif #endif + if (client->ultra_buffer) + free(client->ultra_buffer); + + if (client->raw_buffer) + free(client->raw_buffer); + FreeTLS(client); while (client->clientData) { @@ -414,5 +545,11 @@ void rfbClientCleanup(rfbClient* client) { free(client->destHost); if (client->clientAuthSchemes) free(client->clientAuthSchemes); + +#ifdef LIBVNCSERVER_HAVE_SASL + if (client->saslSecret) + free(client->saslSecret); +#endif /* LIBVNCSERVER_HAVE_SASL */ + free(client); } |