summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libvncclient/corre.c4
-rw-r--r--libvncclient/hextile.c8
-rw-r--r--libvncclient/rfbproto.c106
-rw-r--r--libvncclient/rre.c4
-rw-r--r--libvncclient/tight.c11
-rw-r--r--libvncclient/ultra.c4
-rw-r--r--libvncclient/vncviewer.c98
-rw-r--r--libvncclient/zlib.c2
-rw-r--r--libvncclient/zrle.c4
-rw-r--r--rfb/rfbclient.h15
10 files changed, 136 insertions, 120 deletions
diff --git a/libvncclient/corre.c b/libvncclient/corre.c
index baf91cc..66e3b08 100644
--- a/libvncclient/corre.c
+++ b/libvncclient/corre.c
@@ -46,7 +46,7 @@ HandleCoRREBPP (rfbClient* client, int rx, int ry, int rw, int rh)
if (!ReadFromRFBServer(client, (char *)&pix, sizeof(pix)))
return FALSE;
- FillRectangle(client, rx, ry, rw, rh, pix);
+ client->GotFillRect(client, rx, ry, rw, rh, pix);
if (!ReadFromRFBServer(client, client->buffer, hdr.nSubrects * (4 + (BPP / 8))))
return FALSE;
@@ -61,7 +61,7 @@ HandleCoRREBPP (rfbClient* client, int rx, int ry, int rw, int rh)
w = *ptr++;
h = *ptr++;
- FillRectangle(client, rx+x, ry+y, w, h, pix);
+ client->GotFillRect(client, rx+x, ry+y, w, h, pix);
}
return TRUE;
diff --git a/libvncclient/hextile.c b/libvncclient/hextile.c
index 8698445..05a7cf5 100644
--- a/libvncclient/hextile.c
+++ b/libvncclient/hextile.c
@@ -55,7 +55,7 @@ HandleHextileBPP (rfbClient* client, int rx, int ry, int rw, int rh)
if (!ReadFromRFBServer(client, client->buffer, w * h * (BPP / 8)))
return FALSE;
- CopyRectangle(client, (uint8_t *)client->buffer, x, y, w, h);
+ client->GotBitmap(client, (uint8_t *)client->buffer, x, y, w, h);
continue;
}
@@ -64,7 +64,7 @@ HandleHextileBPP (rfbClient* client, int rx, int ry, int rw, int rh)
if (!ReadFromRFBServer(client, (char *)&bg, sizeof(bg)))
return FALSE;
- FillRectangle(client, x, y, w, h, bg);
+ client->GotFillRect(client, x, y, w, h, bg);
if (subencoding & rfbHextileForegroundSpecified)
if (!ReadFromRFBServer(client, (char *)&fg, sizeof(fg)))
@@ -100,7 +100,7 @@ HandleHextileBPP (rfbClient* client, int rx, int ry, int rw, int rh)
sh = rfbHextileExtractH(*ptr);
ptr++;
- FillRectangle(client, x+sx, y+sy, sw, sh, fg);
+ client->GotFillRect(client, x+sx, y+sy, sw, sh, fg);
}
} else {
@@ -115,7 +115,7 @@ HandleHextileBPP (rfbClient* client, int rx, int ry, int rw, int rh)
sh = rfbHextileExtractH(*ptr);
ptr++;
- FillRectangle(client, x+sx, y+sy, sw, sh, fg);
+ client->GotFillRect(client, x+sx, y+sy, sw, sh, fg);
}
}
}
diff --git a/libvncclient/rfbproto.c b/libvncclient/rfbproto.c
index 94b9bdb..e099f1a 100644
--- a/libvncclient/rfbproto.c
+++ b/libvncclient/rfbproto.c
@@ -145,101 +145,6 @@ void* rfbClientGetClientData(rfbClient* client, void* tag)
return NULL;
}
-/* messages */
-
-static void FillRectangle(rfbClient* client, int x, int y, int w, int h, uint32_t colour) {
- int i,j;
-
- if (client->frameBuffer == NULL) {
- 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, uint8_t* buffer, int x, int y, int w, int h) {
- int j;
-
- if (client->frameBuffer == NULL) {
- 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;
- }
-
-#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 rfbBool HandleRRE8(rfbClient* client, int rx, int ry, int rw, int rh);
static rfbBool HandleRRE16(rfbClient* client, int rx, int ry, int rw, int rh);
static rfbBool HandleRRE32(rfbClient* client, int rx, int ry, int rw, int rh);
@@ -1956,7 +1861,7 @@ HandleRFBServerMessage(rfbClient* client)
if (!ReadFromRFBServer(client, client->buffer,bytesPerLine * linesToRead))
return FALSE;
- CopyRectangle(client, (uint8_t *)client->buffer,
+ client->GotBitmap(client, (uint8_t *)client->buffer,
rect.r.x, y, rect.r.w,linesToRead);
h -= linesToRead;
@@ -1982,13 +1887,8 @@ HandleRFBServerMessage(rfbClient* client)
client->SoftCursorLockArea(client,
cr.srcX, cr.srcY, rect.r.w, rect.r.h);
- if (client->GotCopyRect != NULL) {
- client->GotCopyRect(client, cr.srcX, cr.srcY, rect.r.w, rect.r.h,
- rect.r.x, rect.r.y);
- } else
- CopyRectangleFromRectangle(client,
- cr.srcX, cr.srcY, rect.r.w, rect.r.h,
- rect.r.x, rect.r.y);
+ client->GotCopyRect(client, cr.srcX, cr.srcY, rect.r.w, rect.r.h,
+ rect.r.x, rect.r.y);
break;
}
diff --git a/libvncclient/rre.c b/libvncclient/rre.c
index 94158c9..752d7cc 100644
--- a/libvncclient/rre.c
+++ b/libvncclient/rre.c
@@ -45,7 +45,7 @@ HandleRREBPP (rfbClient* client, int rx, int ry, int rw, int rh)
if (!ReadFromRFBServer(client, (char *)&pix, sizeof(pix)))
return FALSE;
- FillRectangle(client, rx, ry, rw, rh, pix);
+ client->GotFillRect(client, rx, ry, rw, rh, pix);
for (i = 0; i < hdr.nSubrects; i++) {
if (!ReadFromRFBServer(client, (char *)&pix, sizeof(pix)))
@@ -59,7 +59,7 @@ HandleRREBPP (rfbClient* client, int rx, int ry, int rw, int rh)
subrect.w = rfbClientSwap16IfLE(subrect.w);
subrect.h = rfbClientSwap16IfLE(subrect.h);
- FillRectangle(client, rx+subrect.x, ry+subrect.y, subrect.w, subrect.h, pix);
+ client->GotFillRect(client, rx+subrect.x, ry+subrect.y, subrect.w, subrect.h, pix);
}
return TRUE;
diff --git a/libvncclient/tight.c b/libvncclient/tight.c
index 2f9fbab..2447ad8 100644
--- a/libvncclient/tight.c
+++ b/libvncclient/tight.c
@@ -131,7 +131,7 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh)
return FALSE;
#endif
- FillRectangle(client, rx, ry, rw, rh, fill_colour);
+ client->GotFillRect(client, rx, ry, rw, rh, fill_colour);
return TRUE;
}
@@ -198,7 +198,7 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh)
buffer2 = &client->buffer[TIGHT_MIN_TO_COMPRESS * 4];
filterFn(client, rh, (CARDBPP *)buffer2);
- CopyRectangle(client, (uint8_t *)buffer2, rx, ry, rw, rh);
+ client->GotBitmap(client, (uint8_t *)buffer2, rx, ry, rw, rh);
return TRUE;
}
@@ -277,7 +277,7 @@ HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh)
if (extraBytes > 0)
memcpy(client->buffer, &client->buffer[numRows * rowSize], extraBytes);
- CopyRectangle(client, (uint8_t *)buffer2, rx, ry+rowsProcessed, rw, numRows);
+ client->GotBitmap(client, (uint8_t *)buffer2, rx, ry+rowsProcessed, rw, numRows);
rowsProcessed += numRows;
}
@@ -547,6 +547,9 @@ DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h)
return FALSE;
}
+ if(client->GotJpeg != NULL)
+ return client->GotJpeg(client, compressedData, compressedLen, x, y, w, h);
+
cinfo.err = jpeg_std_error(&jerr);
cinfo.client_data = client;
jpeg_create_decompress(&cinfo);
@@ -577,7 +580,7 @@ DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h)
*pixelPtr++ =
RGB24_TO_PIXEL(BPP, client->buffer[dx*3], client->buffer[dx*3+1], client->buffer[dx*3+2]);
}
- CopyRectangle(client, (uint8_t *)&client->buffer[RFB_BUFFER_SIZE / 2], x, y + dy, w, 1);
+ client->GotBitmap(client, (uint8_t *)&client->buffer[RFB_BUFFER_SIZE / 2], x, y + dy, w, 1);
dy++;
}
diff --git a/libvncclient/ultra.c b/libvncclient/ultra.c
index dac89b5..d816368 100644
--- a/libvncclient/ultra.c
+++ b/libvncclient/ultra.c
@@ -98,7 +98,7 @@ HandleUltraBPP (rfbClient* client, int rx, int ry, int rw, int rh)
/* Put the uncompressed contents of the update on the screen. */
if ( inflateResult == LZO_E_OK )
{
- CopyRectangle(client, (unsigned char *)client->raw_buffer, rx, ry, rw, rh);
+ client->GotBitmap(client, (unsigned char *)client->raw_buffer, rx, ry, rw, rh);
}
else
{
@@ -199,7 +199,7 @@ HandleUltraZipBPP (rfbClient* client, int rx, int ry, int rw, int rh)
if (se == rfbEncodingRaw)
{
- CopyRectangle(client, (unsigned char *)ptr, sx, sy, sw, sh);
+ client->GotBitmap(client, (unsigned char *)ptr, sx, sy, sw, sh);
ptr += ((sw * sh) * (BPP / 8));
}
}
diff --git a/libvncclient/vncviewer.c b/libvncclient/vncviewer.c
index d81e298..2028bcd 100644
--- a/libvncclient/vncviewer.c
+++ b/libvncclient/vncviewer.c
@@ -113,6 +113,101 @@ static rfbBool MallocFrameBuffer(rfbClient* client) {
return client->frameBuffer?TRUE:FALSE;
}
+/* messages */
+
+static void FillRectangle(rfbClient* client, int x, int y, int w, int h, uint32_t colour) {
+ int i,j;
+
+ if (client->frameBuffer == NULL) {
+ 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, uint8_t* buffer, int x, int y, int w, int h) {
+ int j;
+
+ if (client->frameBuffer == NULL) {
+ 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;
+ }
+
+#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;
@@ -208,6 +303,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;
diff --git a/libvncclient/zlib.c b/libvncclient/zlib.c
index e872d40..fc6f138 100644
--- a/libvncclient/zlib.c
+++ b/libvncclient/zlib.c
@@ -142,7 +142,7 @@ HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh)
if ( inflateResult == Z_OK ) {
/* Put the uncompressed contents of the update on the screen. */
- CopyRectangle(client, (uint8_t *)client->raw_buffer, rx, ry, rw, rh);
+ client->GotBitmap(client, (uint8_t *)client->raw_buffer, rx, ry, rw, rh);
}
else {
diff --git a/libvncclient/zrle.c b/libvncclient/zrle.c
index 0128146..e732046 100644
--- a/libvncclient/zrle.c
+++ b/libvncclient/zrle.c
@@ -278,7 +278,7 @@ static int HandleZRLETile(rfbClient* client,
for(i=x; i<x+w; i++,buffer+=REALBPP/8)
((CARDBPP*)client->frameBuffer)[j+i] = UncompressCPixel(buffer);
#else
- CopyRectangle(client, buffer, x, y, w, h);
+ client->GotBitmap(client, buffer, x, y, w, h);
buffer+=w*h*REALBPP/8;
#endif
}
@@ -289,7 +289,7 @@ static int HandleZRLETile(rfbClient* client,
if(1+REALBPP/8>buffer_length)
return -4;
- FillRectangle(client, x, y, w, h, color);
+ client->GotFillRect(client, x, y, w, h, color);
buffer+=REALBPP/8;
diff --git a/rfb/rfbclient.h b/rfb/rfbclient.h
index 4f6f4f4..d90342b 100644
--- a/rfb/rfbclient.h
+++ b/rfb/rfbclient.h
@@ -182,6 +182,9 @@ typedef void (*BellProc)(struct _rfbClient* client);
*/
typedef void (*GotCursorShapeProc)(struct _rfbClient* client, int xhot, int yhot, int width, int height, int bytesPerPixel);
typedef void (*GotCopyRectProc)(struct _rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y);
+typedef void (*GotFillRectProc)(struct _rfbClient* client, int x, int y, int w, int h, uint32_t colour);
+typedef void (*GotBitmapProc)(struct _rfbClient* client, const uint8_t* buffer, int x, int y, int w, int h);
+typedef rfbBool (*GotJpegProc)(struct _rfbClient* client, const uint8_t* buffer, int length, int x, int y, int w, int h);
typedef rfbBool (*LockWriteToTLSProc)(struct _rfbClient* client);
typedef rfbBool (*UnlockWriteToTLSProc)(struct _rfbClient* client);
@@ -367,6 +370,18 @@ typedef struct _rfbClient {
LockWriteToTLSProc LockWriteToTLS;
UnlockWriteToTLSProc UnlockWriteToTLS;
+ /** Hooks for custom rendering
+ *
+ * VNC rendering boils down to 3 activities:
+ * - GotCopyRect: copy an area of the framebuffer
+ * - GotFillRect: fill an area of the framebuffer with a solid color
+ * - GotBitmap: copy the bitmap in the buffer into the framebuffer
+ * The client application should either set all three of these or none!
+ */
+ GotFillRectProc GotFillRect;
+ GotBitmapProc GotBitmap;
+ /** Hook for custom JPEG decoding and rendering */
+ GotJpegProc GotJpeg;
} rfbClient;
/* cursor.c */