summaryrefslogtreecommitdiffstats
path: root/libvncserver/rfbserver.c
diff options
context:
space:
mode:
authordscho <dscho>2005-01-18 23:18:04 +0000
committerdscho <dscho>2005-01-18 23:18:04 +0000
commita84b3d072a89e05c5aa5f702d223cfe304379293 (patch)
tree6e8b11537f0fe91e5a62b2dc559521ce8c9a9a13 /libvncserver/rfbserver.c
parentdd923e866021418379ee88b8a927597f616fbc84 (diff)
downloadlibtdevnc-a84b3d072a89e05c5aa5f702d223cfe304379293.tar.gz
libtdevnc-a84b3d072a89e05c5aa5f702d223cfe304379293.zip
pointerClient was still static.
do not make requestedRegion empty without reason. the cursor handling for clients which don't handle CursorShape updates was completely broken. It originally was very complicated for performance reasons, however, in most cases it made performance even worse, because at idle times there was way too much checking going on, and furthermore, sometimes unnecessary updates were inevitable. The code now is much more elegant: the ClientRec structure knows exactly where it last painted the cursor, and the ScreenInfo structure knows where the cursor shall be. As a consequence there is no more rfbDrawCursor()/rfbUndrawCursor(), no more dontSendFramebufferUpdate, and no more isCursorDrawn. It is now possible to have clients which understand CursorShape updates and clients which don't at the same time. rfbSetCursor no longer has the option freeOld; this is obsolete, as the cursor structure knows what to free and what not.
Diffstat (limited to 'libvncserver/rfbserver.c')
-rw-r--r--libvncserver/rfbserver.c156
1 files changed, 72 insertions, 84 deletions
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
index 84b5035..f9ab595 100644
--- a/libvncserver/rfbserver.c
+++ b/libvncserver/rfbserver.c
@@ -60,7 +60,11 @@
#define DEBUGPROTO(x)
#endif
-static rfbClientPtr pointerClient = NULL; /* "Mutex" for pointer events */
+/* from cursor.c */
+
+void rfbShowCursor(rfbClientPtr cl);
+void rfbHideCursor(rfbClientPtr cl);
+void rfbRedrawAfterHideCursor(rfbClientPtr cl);
static void rfbProcessClientProtocolVersion(rfbClientPtr cl);
static void rfbProcessClientNormalMessage(rfbClientPtr cl);
@@ -327,6 +331,8 @@ rfbNewTCPOrUDPClient(rfbScreen,sock,isUDP)
cl->enableCursorPosUpdates = FALSE;
cl->useRichCursorEncoding = FALSE;
cl->enableLastRectEncoding = FALSE;
+ cl->cursorX = rfbScreen->cursorX;
+ cl->cursorY = rfbScreen->cursorY;
cl->useNewFBSize = FALSE;
#ifdef LIBVNCSERVER_HAVE_LIBZ
@@ -452,8 +458,8 @@ rfbClientConnectionGone(cl)
#endif
#endif
- if (pointerClient == cl)
- pointerClient = NULL;
+ if (cl->screen->pointerClient == cl)
+ cl->screen->pointerClient = 0;
sraRgnDestroy(cl->modifiedRegion);
sraRgnDestroy(cl->requestedRegion);
@@ -756,13 +762,6 @@ rfbProcessClientNormalMessage(cl)
msg.se.nEncodings = Swap16IfLE(msg.se.nEncodings);
- cl->preferredEncoding = -1;
- cl->useCopyRect = FALSE;
- cl->enableCursorShapeUpdates = FALSE;
- cl->enableCursorPosUpdates = FALSE;
- cl->enableLastRectEncoding = FALSE;
- cl->useNewFBSize = FALSE;
-
for (i = 0; i < msg.se.nEncodings; i++) {
if ((n = rfbReadExact(cl, (char *)&enc, 4)) <= 0) {
if (n != 0)
@@ -827,6 +826,10 @@ rfbProcessClientNormalMessage(cl)
if(!cl->screen->dontConvertRichCursorToXCursor) {
rfbLog("Enabling X-style cursor updates for client %s\n",
cl->host);
+ /* if cursor was drawn, hide the cursor */
+ if(!cl->enableCursorShapeUpdates)
+ rfbRedrawAfterHideCursor(cl);
+
cl->enableCursorShapeUpdates = TRUE;
cl->cursorWasChanged = TRUE;
}
@@ -834,6 +837,10 @@ rfbProcessClientNormalMessage(cl)
case rfbEncodingRichCursor:
rfbLog("Enabling full-color cursor updates for client %s\n",
cl->host);
+ /* if cursor was drawn, hide the cursor */
+ if(!cl->enableCursorShapeUpdates)
+ rfbRedrawAfterHideCursor(cl);
+
cl->enableCursorShapeUpdates = TRUE;
cl->useRichCursorEncoding = TRUE;
cl->cursorWasChanged = TRUE;
@@ -994,13 +1001,13 @@ rfbProcessClientNormalMessage(cl)
return;
}
- if (pointerClient && (pointerClient != cl))
+ if (cl->screen->pointerClient && cl->screen->pointerClient != cl)
return;
if (msg.pe.buttonMask == 0)
- pointerClient = NULL;
+ cl->screen->pointerClient = 0;
else
- pointerClient = cl;
+ cl->screen->pointerClient = cl;
if(!cl->viewOnly) {
cl->screen->ptrAddEvent(msg.pe.buttonMask,
@@ -1066,7 +1073,7 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
rfbClientPtr cl;
sraRegionPtr givenUpdateRegion;
{
- sraRectangleIterator* i;
+ sraRectangleIterator* i=0;
sraRect rect;
int nUpdateRegionRects;
rfbFramebufferUpdateMsg *fu = (rfbFramebufferUpdateMsg *)cl->updateBuf;
@@ -1074,6 +1081,7 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
int dx, dy;
rfbBool sendCursorShape = FALSE;
rfbBool sendCursorPos = FALSE;
+ rfbBool result = TRUE;
if(cl->screen->displayHook)
cl->screen->displayHook(cl);
@@ -1103,16 +1111,8 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
*/
if (cl->enableCursorShapeUpdates) {
- if (cl->screen->cursorIsDrawn) {
- rfbUndrawCursor(cl->screen);
- }
- if (!cl->screen->cursorIsDrawn && cl->cursorWasChanged &&
- cl->readyForSetColourMapEntries)
+ if (cl->cursorWasChanged && cl->readyForSetColourMapEntries)
sendCursorShape = TRUE;
- } else {
- if (!cl->screen->cursorIsDrawn) {
- rfbDrawCursor(cl->screen);
- }
}
/*
@@ -1162,6 +1162,9 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
sraRgnOr(updateRegion,cl->copyRegion);
if(!sraRgnAnd(updateRegion,cl->requestedRegion) &&
+ sraRgnEmpty(updateRegion) &&
+ (cl->enableCursorShapeUpdates ||
+ (cl->cursorX == cl->screen->cursorX && cl->cursorY == cl->screen->cursorY)) &&
!sendCursorShape && !sendCursorPos) {
sraRgnDestroy(updateRegion);
UNLOCK(cl->updateMutex);
@@ -1201,22 +1204,32 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
* carry over a copyRegion for a future update.
*/
-
sraRgnOr(cl->modifiedRegion,cl->copyRegion);
sraRgnSubtract(cl->modifiedRegion,updateRegion);
sraRgnSubtract(cl->modifiedRegion,updateCopyRegion);
- sraRgnMakeEmpty(cl->requestedRegion);
+ /* TODO: is this sensible? sraRgnMakeEmpty(cl->requestedRegion); */
sraRgnMakeEmpty(cl->copyRegion);
cl->copyDX = 0;
cl->copyDY = 0;
UNLOCK(cl->updateMutex);
+ if (!cl->enableCursorShapeUpdates) {
+ if(cl->cursorX != cl->screen->cursorX || cl->cursorY != cl->screen->cursorY) {
+ rfbRedrawAfterHideCursor(cl);
+ LOCK(cl->screen->cursorMutex);
+ cl->cursorX = cl->screen->cursorX;
+ cl->cursorY = cl->screen->cursorY;
+ UNLOCK(cl->screen->cursorMutex);
+ rfbRedrawAfterHideCursor(cl);
+ }
+ rfbShowCursor(cl);
+ }
+
/*
* Now send the update.
*/
-
cl->framebufferUpdateMessagesSent++;
if (cl->preferredEncoding == rfbEncodingCoRRE) {
@@ -1291,26 +1304,19 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
if (sendCursorShape) {
cl->cursorWasChanged = FALSE;
- if (!rfbSendCursorShape(cl)) {
- sraRgnDestroy(updateRegion);
- return FALSE;
- }
+ if (!rfbSendCursorShape(cl))
+ goto updateFailed;
}
if (sendCursorPos) {
cl->cursorWasMoved = FALSE;
- if (!rfbSendCursorPos(cl)) {
- sraRgnDestroy(updateRegion);
- return FALSE;
- }
- }
+ if (!rfbSendCursorPos(cl))
+ goto updateFailed;
+ }
if (!sraRgnEmpty(updateCopyRegion)) {
- if (!rfbSendCopyRegion(cl,updateCopyRegion,dx,dy)) {
- sraRgnDestroy(updateRegion);
- sraRgnDestroy(updateCopyRegion);
- return FALSE;
- }
+ if (!rfbSendCopyRegion(cl,updateCopyRegion,dx,dy))
+ goto updateFailed;
}
sraRgnDestroy(updateCopyRegion);
@@ -1326,77 +1332,59 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion)
switch (cl->preferredEncoding) {
case rfbEncodingRaw:
- if (!rfbSendRectEncodingRaw(cl, x, y, w, h)) {
- sraRgnDestroy(updateRegion);
- sraRgnReleaseIterator(i);
- return FALSE;
- }
+ if (!rfbSendRectEncodingRaw(cl, x, y, w, h))
+ goto updateFailed;
break;
case rfbEncodingRRE:
- if (!rfbSendRectEncodingRRE(cl, x, y, w, h)) {
- sraRgnDestroy(updateRegion);
- sraRgnReleaseIterator(i);
- return FALSE;
- }
+ if (!rfbSendRectEncodingRRE(cl, x, y, w, h))
+ goto updateFailed;
break;
case rfbEncodingCoRRE:
- if (!rfbSendRectEncodingCoRRE(cl, x, y, w, h)) {
- sraRgnDestroy(updateRegion);
- sraRgnReleaseIterator(i);
- return FALSE;
- }
- break;
+ if (!rfbSendRectEncodingCoRRE(cl, x, y, w, h))
+ goto updateFailed;
+ break;
case rfbEncodingHextile:
- if (!rfbSendRectEncodingHextile(cl, x, y, w, h)) {
- sraRgnDestroy(updateRegion);
- sraRgnReleaseIterator(i);
- return FALSE;
- }
+ if (!rfbSendRectEncodingHextile(cl, x, y, w, h))
+ goto updateFailed;
break;
#ifdef LIBVNCSERVER_HAVE_LIBZ
case rfbEncodingZlib:
- if (!rfbSendRectEncodingZlib(cl, x, y, w, h)) {
- sraRgnDestroy(updateRegion);
- sraRgnReleaseIterator(i);
- return FALSE;
- }
+ if (!rfbSendRectEncodingZlib(cl, x, y, w, h))
+ goto updateFailed;
break;
#ifdef LIBVNCSERVER_HAVE_LIBJPEG
case rfbEncodingTight:
- if (!rfbSendRectEncodingTight(cl, x, y, w, h)) {
- sraRgnDestroy(updateRegion);
- sraRgnReleaseIterator(i);
- return FALSE;
- }
+ if (!rfbSendRectEncodingTight(cl, x, y, w, h))
+ goto updateFailed;
break;
#endif
#endif
#ifdef LIBVNCSERVER_HAVE_LIBZ
case rfbEncodingZRLE:
- if (!rfbSendRectEncodingZRLE(cl, x, y, w, h)) {
- sraRgnDestroy(updateRegion);
- sraRgnReleaseIterator(i);
- return FALSE;
- }
+ if (!rfbSendRectEncodingZRLE(cl, x, y, w, h))
+ goto updateFailed;
break;
#endif
}
}
- sraRgnReleaseIterator(i);
if ( nUpdateRegionRects == 0xFFFF &&
- !rfbSendLastRectMarker(cl) ) {
- sraRgnDestroy(updateRegion);
- return FALSE;
- }
+ !rfbSendLastRectMarker(cl) )
+ goto updateFailed;
if (!rfbSendUpdateBuf(cl)) {
- sraRgnDestroy(updateRegion);
- return FALSE;
+updateFailed:
+ result = FALSE;
+ }
+
+ if (!cl->enableCursorShapeUpdates) {
+ rfbHideCursor(cl);
}
+ if(i)
+ sraRgnReleaseIterator(i);
sraRgnDestroy(updateRegion);
- return TRUE;
+ return result;
}