From fefcb9188a0810577ee8d17a384af19c39d8a49e Mon Sep 17 00:00:00 2001
From: dscho <dscho>
Date: Mon, 7 Jun 2004 11:43:00 +0000
Subject: fix cursor trails (when not using cursor encoding and moving the
 cursor, the redrawn part of the screen didn't get updated, and so left cursor
 trails).

---
 ChangeLog             |  1 +
 TODO                  |  2 +-
 libvncserver/cursor.c | 16 ++++++++++++++--
 rfb/rfb.h             |  2 +-
 4 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 959b536..e2858fa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,5 @@
 2004-06-07  Johannes E. Schindelin  <Johannes.Schindelin@gmx.de>
+	* libvncserver/cursor.c, rfb/rfb.h: fix cursor trails
 	* */Makefile.am: stop automake nagging
 	* libvncclient/*, client_examples/*: streamline API, SDLvncviewer added
 	* examples/, libvncclient/, test/: moved tests to test/
diff --git a/TODO b/TODO
index 8f6d0f9..a1e5d67 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,6 @@
 immediate:
 ----------
 
-cursor drawing does not get undone prior to sending
 TightVNC encoding!!! Regression!!!
 extra_bytes in rfbDrawCharWithClip.
 tested mouse buttons make copy rect, but text is not marked as mod.
@@ -19,6 +18,7 @@ CORBA
 done:
 -----
 
+.cursor drawing does not get undone prior to sending
 .following two items overridden by RealVNC's idea: if there are too many
 	rectangles (like >50), just use the bounding box.
   cursor drawing: set optional grain to mark bigger rectangles as drawn (else
diff --git a/libvncserver/cursor.c b/libvncserver/cursor.c
index 4f290da..9f8f9d6 100644
--- a/libvncserver/cursor.c
+++ b/libvncserver/cursor.c
@@ -390,7 +390,7 @@ void rfbUndrawCursor(rfbScreenInfoPtr s)
    int j,x1,x2,y1,y2,bpp=s->rfbServerFormat.bitsPerPixel/8,
      rowstride=s->paddedWidthInBytes;
    LOCK(s->cursorMutex);
-   if(!s->cursorIsDrawn) {
+   if(!s->cursorIsDrawn || !c) {
      UNLOCK(s->cursorMutex);
      return;
    }
@@ -421,6 +421,8 @@ void rfbUndrawCursor(rfbScreenInfoPtr s)
    
    /* rfbMarkRectAsModified(s,x1,y1,x1+x2,y1+y2); */
    s->cursorIsDrawn = FALSE;
+   s->oldCursorX=s->cursorX;
+   s->oldCursorY=s->cursorY;
    UNLOCK(s->cursorMutex);
 }
 
@@ -431,7 +433,7 @@ void rfbDrawCursor(rfbScreenInfoPtr s)
      rowstride=s->paddedWidthInBytes,
      bufSize,w;
    rfbBool wasChanged=FALSE;
-   
+
    if(!c) return;
    LOCK(s->cursorMutex);
    if(s->cursorIsDrawn) {
@@ -439,6 +441,13 @@ void rfbDrawCursor(rfbScreenInfoPtr s)
      UNLOCK(s->cursorMutex);
      return;
    }
+
+   if(s->cursor && s->underCursorBuffer &&
+		   (s->cursorX!=s->oldCursorX || s->cursorY!=s->oldCursorY)) {
+	   int x1=s->oldCursorX-s->cursor->xhot,x2=x1+s->cursor->width;
+	   int y1=s->oldCursorY-s->cursor->yhot,y2=y1+s->cursor->height;
+	   rfbMarkRectAsModified(s,x1,y1,x2,y2);
+   }
    bufSize=c->width*c->height*bpp;
    w=(c->width+7)/8;
    if(s->underCursorBufferLen<bufSize) {
@@ -518,6 +527,9 @@ void rfbSetCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr c,rfbBool freeOld)
     LOCK(rfbScreen->cursorMutex);
   }
 
+  free(rfbScreen->underCursorBuffer);
+  rfbScreen->underCursorBuffer=0;
+
   if(rfbScreen->cursor && (freeOld || rfbScreen->cursor->cleanup))
     rfbFreeCursor(rfbScreen->cursor);
 
diff --git a/rfb/rfb.h b/rfb/rfb.h
index d472684..ae62fb2 100644
--- a/rfb/rfb.h
+++ b/rfb/rfb.h
@@ -248,7 +248,7 @@ typedef struct _rfbScreenInfo
     struct _rfbClientRec* rfbClientHead;
 
     /* cursor */
-    int cursorX, cursorY,underCursorBufferLen;
+    int cursorX, cursorY,oldCursorX,oldCursorY,underCursorBufferLen;
     char* underCursorBuffer;
     rfbBool dontConvertRichCursorToXCursor;
     struct rfbCursor* cursor;
-- 
cgit v1.2.3

