From 519a8e0e399bf44893f2d61a3676f3257ab8d201 Mon Sep 17 00:00:00 2001
From: dscho <dscho>
Date: Wed, 10 Oct 2001 23:56:04 +0000
Subject: copyrect corrections, fd_set in rfbNewClient, dox in rfb.h for
 pthreads problem

---
 CHANGES     | 21 ++++++++++++++++++---
 TODO        | 13 ++++++++++---
 main.c      |  8 ++++++++
 rfb.h       | 13 +++++++++----
 rfbserver.c |  2 +-
 5 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/CHANGES b/CHANGES
index c507bfb..f1b8982 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,14 @@
 0.2
+   rfbNewClient now sets the socket in the fd_set (for the select() call)
+   when compiling the library with HAVE_PTHREADS and an application
+	which includes "rfb.h" without, the structures got mixed up.
+	So, the pthreads section is now always at the end, and also
+	you get a linker error for rfbInitServer when using two different
+	pthread setups.
+   fixed two deadlocks: when setting a cursor and when using CopyRect
+   fixed CopyRect when copying modified regions (they lost the modified
+	 property)
+   WIN32 target compiles and works for example :-)
    fixed CopyRect (was using the wrong order of rectangles...)
    	 should also work with pthreads, because copyrects are
 	 always sent immediately (so that two consecutive copy rects
@@ -6,11 +16,16 @@
    changed rfbUndrawCursor(rfbClientPtr) to (rfbScreenInfoPtr), because
    	   this makes more sense!
    flag backgroundLoop in rfbScreenInfo (if having pthreads)
-   rfbCopyRect & rfbCopyRegion (really copies rectangle in frameBuffer)
-   added flag to optionally not send XCursor updates.
+   CopyRect & CopyRegion were implemented.
+	if you use a rfbDoCopyR* function, it copies the data in the
+	framebuffer. If you prefer to do that yourself, use rfbScheduleCopyR*
+	instead; this doesn't modify the frameBuffer.
+   added flag to optionally not send XCursor updates, but only RichCursor,
+	or if that is not possible, fall back to server side cursor.
+	This is useful if your cursor has many nice colours.
    fixed java viewer on server side:
 	SendCursorUpdate would send data even before the client pixel format
-	was set.
+	was set, but the java applet doesn't like the server's format.
    fixed two pthread issues:
 	rfbSendFramebuffer was sent by a ProcessClientMessage function
 	(unprotected by updateMutex).
diff --git a/TODO b/TODO
index 50926ab..53b3fa1 100644
--- a/TODO
+++ b/TODO
@@ -1,23 +1,25 @@
 immediate:
 ----------
 
-test copyRect and pthreads.
 authentification schemes (secure vnc)
-udp
+udp (need an rfbClientPtr udpClient in rfbScreen)
 documentation
 	hint that to mark very tiny regions as
 	modified is possibly inefficient for the encodings.
-	(a trail of points could be better a small rectangle).
+	(a trail of points could better be a small rectangle).
 
 later:
 ------
 
 autoconf? at least Sun Solaris and Windows compilation
+	(maybe Michael makes that)
+using Hermes library for fast colour translations.
 CORBA
 
 done:
 -----
 
+.test copyRect and pthreads.
 .optionally dont draw rich cursors as xcursors
 .cursor smears on IRIX with pthreads, then has bus error. has to be a mutex
 	problem in cursor routines.
@@ -56,3 +58,8 @@ fix bug with odd width (depends on client depth: width has to be multiple of ser
 	  three have to be warned that this is happening.
 	-> rfbClientConnectionGone can only be called by the outer loop
 	(with background loop, it is input, else it is processEvents).
+. fixed pthreads issues:
+	cursor deadlock,
+	CopyRect deadlock.
+. when copying a region with modified parts, they were not marked
+	as modified
diff --git a/main.c b/main.c
index ea85123..478d8d8 100644
--- a/main.c
+++ b/main.c
@@ -75,6 +75,7 @@ void rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,in
    while((cl=rfbClientIteratorNext(iterator))) {
      LOCK(cl->updateMutex);
      if(cl->useCopyRect) {
+       sraRegionPtr modifiedRegionBackup;
        if(!sraRgnEmpty(cl->copyRegion) && (cl->copyDX!=dx || cl->copyDY!=dy)) {
 	 sraRgnOr(cl->copyRegion,cl->modifiedRegion);
 	 sraRgnMakeEmpty(cl->copyRegion);
@@ -83,6 +84,13 @@ void rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,in
        cl->copyDX = dx;
        cl->copyDY = dy;
 
+       /* if there were modified regions, which are now copied: */
+       modifiedRegionBackup=sraRgnCreateRgn(cl->modifiedRegion);
+       sraRgnOffset(modifiedRegionBackup,dx,dy);
+       sraRgnAnd(modifiedRegionBackup,cl->copyRegion);
+       sraRgnOr(cl->modifiedRegion,modifiedRegionBackup);
+       sraRgnDestroy(modifiedRegionBackup);
+
        /* while(!sraRgnEmpty(cl->copyRegion)) */ {
 #ifdef HAVE_PTHREADS
 	 if(!cl->screen->backgroundLoop)
diff --git a/rfb.h b/rfb.h
index 2914a85..ae9660e 100644
--- a/rfb.h
+++ b/rfb.h
@@ -738,15 +738,20 @@ void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y
 void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion);
 void doNothingWithClient(rfbClientPtr cl);
 
-/* functions to make a vnc server */
-extern rfbScreenInfoPtr rfbGetScreen(int argc,char** argv,
- int width,int height,int bitsPerSample,int samplesPerPixel,
- int bytesPerPixel);
+/* if you use pthreads, but don't define HAVE_PTHREADS, the structs
+   get all mixed up. So this gives a linker error reminding you to compile
+   the library and your application (at least the parts including rfb.h)
+   with the same support for pthreads. */
 #ifdef HAVE_PTHREADS
 #define rfbInitServer rfbInitServerWithPthreads
 #else
 #define rfbInitServer rfbInitServerWithoutPthreads
 #endif
+
+/* functions to make a vnc server */
+extern rfbScreenInfoPtr rfbGetScreen(int argc,char** argv,
+ int width,int height,int bitsPerSample,int samplesPerPixel,
+ int bytesPerPixel);
 extern void rfbInitServer(rfbScreenInfoPtr rfbScreen);
 extern void rfbScreenCleanup(rfbScreenInfoPtr screenInfo);
 
diff --git a/rfbserver.c b/rfbserver.c
index 16cf8d6..51daae4 100644
--- a/rfbserver.c
+++ b/rfbserver.c
@@ -137,7 +137,6 @@ rfbNewClientConnection(rfbScreen,sock)
     if(cl!=NULL)
       newConnection(cl, (KEYBOARD_DEVICE|POINTER_DEVICE),1,1,1);
 #endif
-    FD_SET(sock,&(rfbScreen->allFds));
 }
 
 
@@ -194,6 +193,7 @@ rfbNewClient(rfbScreen,sock)
 
     cl = (rfbClientPtr)xalloc(sizeof(rfbClientRec));
 
+    FD_SET(sock,&(rfbScreen->allFds));
     cl->screen = rfbScreen;
     cl->sock = sock;
     getpeername(sock, (struct sockaddr *)&addr, &addrlen);
-- 
cgit v1.2.3

