rfbproto: Add StartingFramebufferUpdate callback

pull/12/head
Andri Yngvason 2022-07-02 22:01:12 +00:00
parent 178a10853c
commit 73310b5669
2 changed files with 65 additions and 51 deletions

View File

@ -197,6 +197,8 @@ typedef void (*GotFrameBufferUpdateProc)(struct _rfbClient* client, int x, int y
@param client The client which finished processing an rfbFramebufferUpdate @param client The client which finished processing an rfbFramebufferUpdate
*/ */
typedef void (*FinishedFrameBufferUpdateProc)(struct _rfbClient* client); typedef void (*FinishedFrameBufferUpdateProc)(struct _rfbClient* client);
typedef void (*StartingFrameBufferUpdateProc)(struct _rfbClient* client);
typedef void (*CancelledFrameBufferUpdateProc)(struct _rfbClient* client);
typedef char* (*GetPasswordProc)(struct _rfbClient* client); typedef char* (*GetPasswordProc)(struct _rfbClient* client);
typedef rfbCredential* (*GetCredentialProc)(struct _rfbClient* client, int credentialType); typedef rfbCredential* (*GetCredentialProc)(struct _rfbClient* client, int credentialType);
typedef rfbBool (*MallocFrameBufferProc)(struct _rfbClient* client); typedef rfbBool (*MallocFrameBufferProc)(struct _rfbClient* client);
@ -461,6 +463,9 @@ typedef struct _rfbClient {
* Used for intended dimensions, rfbClient.width and rfbClient.height are used to manage the real framebuffer dimensions. * Used for intended dimensions, rfbClient.width and rfbClient.height are used to manage the real framebuffer dimensions.
*/ */
rfbExtDesktopScreen screen; rfbExtDesktopScreen screen;
StartingFrameBufferUpdateProc StartingFrameBufferUpdate;
CancelledFrameBufferUpdateProc CancelledFrameBufferUpdate;
} rfbClient; } rfbClient;
/* cursor.c */ /* cursor.c */

View File

@ -1833,16 +1833,19 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
int bytesPerLine; int bytesPerLine;
int i; int i;
if (client->StartingFrameBufferUpdate)
client->StartingFrameBufferUpdate(client);
if (!ReadFromRFBServer(client, ((char*)&msg->fu) + 1, if (!ReadFromRFBServer(client, ((char*)&msg->fu) + 1,
sz_rfbFramebufferUpdateMsg - 1)) sz_rfbFramebufferUpdateMsg - 1))
return FALSE; goto failure;
msg->fu.nRects = rfbClientSwap16IfLE(msg->fu.nRects); msg->fu.nRects = rfbClientSwap16IfLE(msg->fu.nRects);
for (i = 0; i < msg->fu.nRects; i++) { for (i = 0; i < msg->fu.nRects; i++) {
if (!ReadFromRFBServer(client, (char*)&rect, if (!ReadFromRFBServer(client, (char*)&rect,
sz_rfbFramebufferUpdateRectHeader)) sz_rfbFramebufferUpdateRectHeader))
return FALSE; goto failure;
rect.encoding = rfbClientSwap32IfLE(rect.encoding); rect.encoding = rfbClientSwap32IfLE(rect.encoding);
if (rect.encoding == rfbEncodingLastRect) if (rect.encoding == rfbEncodingLastRect)
@ -1859,14 +1862,14 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
if (!HandleCursorShape(client, rect.r.x, rect.r.y, if (!HandleCursorShape(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h, rect.r.w, rect.r.h,
rect.encoding)) { rect.encoding)) {
return FALSE; goto failure;
} }
continue; continue;
} }
if (rect.encoding == rfbEncodingPointerPos) { if (rect.encoding == rfbEncodingPointerPos) {
if (!client->HandleCursorPos(client, rect.r.x, rect.r.y)) { if (!client->HandleCursorPos(client, rect.r.x, rect.r.y)) {
return FALSE; goto failure;
} }
continue; continue;
} }
@ -1884,7 +1887,7 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
if (rect.encoding == rfbEncodingNewFBSize) { if (rect.encoding == rfbEncodingNewFBSize) {
if (!ResizeClientBuffer(client, rect.r.w, rect.r.h)) if (!ResizeClientBuffer(client, rect.r.w, rect.r.h))
return FALSE; goto failure;
SendFramebufferUpdateRequest(client, 0, 0, rect.r.w, SendFramebufferUpdateRequest(client, 0, 0, rect.r.w,
rect.r.h, FALSE); rect.r.h, FALSE);
rfbClientLog("Got new framebuffer size: %dx%d\n", rfbClientLog("Got new framebuffer size: %dx%d\n",
@ -1901,14 +1904,14 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
rfbExtDesktopSizeMsg eds; rfbExtDesktopSizeMsg eds;
if (!ReadFromRFBServer(client, ((char*)&eds), if (!ReadFromRFBServer(client, ((char*)&eds),
sz_rfbExtDesktopSizeMsg)) { sz_rfbExtDesktopSizeMsg)) {
return FALSE; goto failure;
} }
screens = eds.numberOfScreens; screens = eds.numberOfScreens;
for (loop = 0; loop < screens; loop++) { for (loop = 0; loop < screens; loop++) {
if (!ReadFromRFBServer(client, ((char*)&screen), if (!ReadFromRFBServer(client, ((char*)&screen),
sz_rfbExtDesktopScreen)) { sz_rfbExtDesktopScreen)) {
return FALSE; goto failure;
} }
if (screen.id != 0) { if (screen.id != 0) {
client->screen = screen; client->screen = screen;
@ -1921,7 +1924,7 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
client->height != rect.r.h)) { client->height != rect.r.h)) {
if (!ResizeClientBuffer(client, rect.r.w, if (!ResizeClientBuffer(client, rect.r.w,
rect.r.h)) { rect.r.h)) {
return FALSE; goto failure;
} }
rfbClientLog("Updated desktop size: %dx%d\n", rfbClientLog("Updated desktop size: %dx%d\n",
rect.r.w, rect.r.h); rect.r.w, rect.r.h);
@ -1937,7 +1940,7 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
if (!ReadFromRFBServer(client, if (!ReadFromRFBServer(client,
(char*)&client->supportedMessages, (char*)&client->supportedMessages,
sz_rfbSupportedMessages)) sz_rfbSupportedMessages))
return FALSE; goto failure;
/* msgs is two sets of bit flags of supported /* msgs is two sets of bit flags of supported
* messages client2server[] and server2client[] */ * messages client2server[] and server2client[] */
@ -1997,7 +2000,7 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
buffer = malloc(rect.r.w); buffer = malloc(rect.r.w);
if (!ReadFromRFBServer(client, buffer, rect.r.w)) { if (!ReadFromRFBServer(client, buffer, rect.r.w)) {
free(buffer); free(buffer);
return FALSE; goto failure;
} }
/* buffer now contains rect.r.h # of uint32_t /* buffer now contains rect.r.h # of uint32_t
@ -2014,7 +2017,7 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
if (!buffer || if (!buffer ||
!ReadFromRFBServer(client, buffer, rect.r.w)) { !ReadFromRFBServer(client, buffer, rect.r.w)) {
free(buffer); free(buffer);
return FALSE; goto failure;
} }
buffer[rect.r.w] = 0; /* null terminate, just in case */ buffer[rect.r.w] = 0; /* null terminate, just in case */
rfbClientLog("Connected to Server \"%s\"\n", buffer); rfbClientLog("Connected to Server \"%s\"\n", buffer);
@ -2031,7 +2034,7 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
"(%d, %d)\n", "(%d, %d)\n",
rect.r.w, rect.r.h, rect.r.x, rect.r.w, rect.r.h, rect.r.x,
rect.r.y); rect.r.y);
return FALSE; goto failure;
} }
/* UltraVNC with scaling, will send rectangles /* UltraVNC with scaling, will send rectangles
@ -2073,7 +2076,7 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
if (!ReadFromRFBServer(client, client->buffer, if (!ReadFromRFBServer(client, client->buffer,
bytesPerLine * linesToRead)) bytesPerLine * linesToRead))
return FALSE; goto failure;
client->GotBitmap( client->GotBitmap(
client, (uint8_t*)client->buffer, client, (uint8_t*)client->buffer,
@ -2089,7 +2092,7 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
rfbCopyRect cr; rfbCopyRect cr;
if (!ReadFromRFBServer(client, (char*)&cr, sz_rfbCopyRect)) if (!ReadFromRFBServer(client, (char*)&cr, sz_rfbCopyRect))
return FALSE; goto failure;
cr.srcX = rfbClientSwap16IfLE(cr.srcX); cr.srcX = rfbClientSwap16IfLE(cr.srcX);
cr.srcY = rfbClientSwap16IfLE(cr.srcY); cr.srcY = rfbClientSwap16IfLE(cr.srcY);
@ -2111,17 +2114,17 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
case 8: case 8:
if (!HandleRRE8(client, rect.r.x, rect.r.y, if (!HandleRRE8(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
case 16: case 16:
if (!HandleRRE16(client, rect.r.x, rect.r.y, if (!HandleRRE16(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
case 32: case 32:
if (!HandleRRE32(client, rect.r.x, rect.r.y, if (!HandleRRE32(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
} }
break; break;
@ -2132,17 +2135,17 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
case 8: case 8:
if (!HandleCoRRE8(client, rect.r.x, rect.r.y, if (!HandleCoRRE8(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
case 16: case 16:
if (!HandleCoRRE16(client, rect.r.x, rect.r.y, if (!HandleCoRRE16(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
case 32: case 32:
if (!HandleCoRRE32(client, rect.r.x, rect.r.y, if (!HandleCoRRE32(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
} }
break; break;
@ -2153,17 +2156,17 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
case 8: case 8:
if (!HandleHextile8(client, rect.r.x, rect.r.y, if (!HandleHextile8(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
case 16: case 16:
if (!HandleHextile16(client, rect.r.x, rect.r.y, if (!HandleHextile16(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
case 32: case 32:
if (!HandleHextile32(client, rect.r.x, rect.r.y, if (!HandleHextile32(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
} }
break; break;
@ -2174,17 +2177,17 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
case 8: case 8:
if (!HandleUltra8(client, rect.r.x, rect.r.y, if (!HandleUltra8(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
case 16: case 16:
if (!HandleUltra16(client, rect.r.x, rect.r.y, if (!HandleUltra16(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
case 32: case 32:
if (!HandleUltra32(client, rect.r.x, rect.r.y, if (!HandleUltra32(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
} }
break; break;
@ -2194,17 +2197,17 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
case 8: case 8:
if (!HandleUltraZip8(client, rect.r.x, rect.r.y, if (!HandleUltraZip8(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
case 16: case 16:
if (!HandleUltraZip16(client, rect.r.x, rect.r.y, if (!HandleUltraZip16(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
case 32: case 32:
if (!HandleUltraZip32(client, rect.r.x, rect.r.y, if (!HandleUltraZip32(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
} }
break; break;
@ -2215,19 +2218,19 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
case 8: case 8:
if (!HandleTRLE8(client, rect.r.x, rect.r.y, if (!HandleTRLE8(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
case 16: case 16:
if (client->si.format.greenMax > 0x1F) { if (client->si.format.greenMax > 0x1F) {
if (!HandleTRLE16(client, rect.r.x, if (!HandleTRLE16(client, rect.r.x,
rect.r.y, rect.r.w, rect.r.y, rect.r.w,
rect.r.h)) rect.r.h))
return FALSE; goto failure;
} else { } else {
if (!HandleTRLE15(client, rect.r.x, if (!HandleTRLE15(client, rect.r.x,
rect.r.y, rect.r.w, rect.r.y, rect.r.w,
rect.r.h)) rect.r.h))
return FALSE; goto failure;
} }
break; break;
case 32: { case 32: {
@ -2245,23 +2248,23 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
if (!HandleTRLE24(client, rect.r.x, if (!HandleTRLE24(client, rect.r.x,
rect.r.y, rect.r.w, rect.r.y, rect.r.w,
rect.r.h)) rect.r.h))
return FALSE; goto failure;
} else if (!client->format.bigEndian && } else if (!client->format.bigEndian &&
(maxColor & 0xff) == 0) { (maxColor & 0xff) == 0) {
if (!HandleTRLE24Up(client, rect.r.x, if (!HandleTRLE24Up(client, rect.r.x,
rect.r.y, rect.r.w, rect.r.y, rect.r.w,
rect.r.h)) rect.r.h))
return FALSE; goto failure;
} else if (client->format.bigEndian && } else if (client->format.bigEndian &&
(maxColor & 0xff000000) == 0) { (maxColor & 0xff000000) == 0) {
if (!HandleTRLE24Down(client, rect.r.x, if (!HandleTRLE24Down(client, rect.r.x,
rect.r.y, rect.r.w, rect.r.y, rect.r.w,
rect.r.h)) rect.r.h))
return FALSE; goto failure;
} else if (!HandleTRLE32(client, rect.r.x, } else if (!HandleTRLE32(client, rect.r.x,
rect.r.y, rect.r.w, rect.r.y, rect.r.w,
rect.r.h)) rect.r.h))
return FALSE; goto failure;
break; break;
} }
} }
@ -2274,17 +2277,17 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
case 8: case 8:
if (!HandleZlib8(client, rect.r.x, rect.r.y, if (!HandleZlib8(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
case 16: case 16:
if (!HandleZlib16(client, rect.r.x, rect.r.y, if (!HandleZlib16(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
case 32: case 32:
if (!HandleZlib32(client, rect.r.x, rect.r.y, if (!HandleZlib32(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
} }
break; break;
@ -2296,17 +2299,17 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
case 8: case 8:
if (!HandleTight8(client, rect.r.x, rect.r.y, if (!HandleTight8(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
case 16: case 16:
if (!HandleTight16(client, rect.r.x, rect.r.y, if (!HandleTight16(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
case 32: case 32:
if (!HandleTight32(client, rect.r.x, rect.r.y, if (!HandleTight32(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
} }
break; break;
@ -2321,19 +2324,19 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
case 8: case 8:
if (!HandleZRLE8(client, rect.r.x, rect.r.y, if (!HandleZRLE8(client, rect.r.x, rect.r.y,
rect.r.w, rect.r.h)) rect.r.w, rect.r.h))
return FALSE; goto failure;
break; break;
case 16: case 16:
if (client->si.format.greenMax > 0x1F) { if (client->si.format.greenMax > 0x1F) {
if (!HandleZRLE16(client, rect.r.x, if (!HandleZRLE16(client, rect.r.x,
rect.r.y, rect.r.w, rect.r.y, rect.r.w,
rect.r.h)) rect.r.h))
return FALSE; goto failure;
} else { } else {
if (!HandleZRLE15(client, rect.r.x, if (!HandleZRLE15(client, rect.r.x,
rect.r.y, rect.r.w, rect.r.y, rect.r.w,
rect.r.h)) rect.r.h))
return FALSE; goto failure;
} }
break; break;
case 32: { case 32: {
@ -2351,23 +2354,23 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
if (!HandleZRLE24(client, rect.r.x, if (!HandleZRLE24(client, rect.r.x,
rect.r.y, rect.r.w, rect.r.y, rect.r.w,
rect.r.h)) rect.r.h))
return FALSE; goto failure;
} else if (!client->format.bigEndian && } else if (!client->format.bigEndian &&
(maxColor & 0xff) == 0) { (maxColor & 0xff) == 0) {
if (!HandleZRLE24Up(client, rect.r.x, if (!HandleZRLE24Up(client, rect.r.x,
rect.r.y, rect.r.w, rect.r.y, rect.r.w,
rect.r.h)) rect.r.h))
return FALSE; goto failure;
} else if (client->format.bigEndian && } else if (client->format.bigEndian &&
(maxColor & 0xff000000) == 0) { (maxColor & 0xff000000) == 0) {
if (!HandleZRLE24Down(client, rect.r.x, if (!HandleZRLE24Down(client, rect.r.x,
rect.r.y, rect.r.w, rect.r.y, rect.r.w,
rect.r.h)) rect.r.h))
return FALSE; goto failure;
} else if (!HandleZRLE32(client, rect.r.x, } else if (!HandleZRLE32(client, rect.r.x,
rect.r.y, rect.r.w, rect.r.y, rect.r.w,
rect.r.h)) rect.r.h))
return FALSE; goto failure;
break; break;
} }
} }
@ -2392,7 +2395,7 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
if (!handled) { if (!handled) {
rfbClientLog("Unknown rect encoding %d\n", rfbClientLog("Unknown rect encoding %d\n",
(int)rect.encoding); (int)rect.encoding);
return FALSE; goto failure;
} }
} }
} }
@ -2405,12 +2408,18 @@ static rfbBool HandleFramebufferUpdate(rfbClient* client,
} }
if (!SendIncrementalFramebufferUpdateRequest(client)) if (!SendIncrementalFramebufferUpdateRequest(client))
return FALSE; goto failure;
if (client->FinishedFrameBufferUpdate) if (client->FinishedFrameBufferUpdate)
client->FinishedFrameBufferUpdate(client); client->FinishedFrameBufferUpdate(client);
return TRUE; return TRUE;
failure:
if (client->CancelledFrameBufferUpdate)
client->CancelledFrameBufferUpdate(client);
return FALSE;
} }
/* /*