summaryrefslogtreecommitdiffstats
path: root/libvncclient/vncviewer.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvncclient/vncviewer.c')
-rw-r--r--libvncclient/vncviewer.c147
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);
}