From 48eb9b22c7097c4af61760ce3fdc7f5135e657bc Mon Sep 17 00:00:00 2001
From: dscho <dscho>
Date: Thu, 4 Oct 2001 18:03:37 +0000
Subject: rfbDoCopyRect/Region and rfbScheduleCopyRect/Region.

---
 CHANGES     |  2 ++
 Makefile    |  4 ++--
 TODO        |  7 ++++--
 main.c      | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 rfb.h       | 11 +++++++--
 rfbserver.c |  5 ++--
 6 files changed, 96 insertions(+), 13 deletions(-)

diff --git a/CHANGES b/CHANGES
index b15441c..6632674 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,6 @@
 0.2
+   flag backgroundLoop in rfbScreenInfo
+   rfbCopyRect & rfbCopyRegion (really copies rectangle in frameBuffer)
    added flag to optionally not send XCursor updates.
    fixed java viewer on server side:
 	SendCursorUpdate would send data even before the client pixel format
diff --git a/Makefile b/Makefile
index c456673..08b972e 100644
--- a/Makefile
+++ b/Makefile
@@ -2,8 +2,8 @@ INCLUDES=-I.
 VNCSERVERLIB=-L. -lvncserver -L/usr/local/lib -lz -ljpeg
 
 # Uncomment these two lines to enable use of PThreads
-PTHREADDEF = -DHAVE_PTHREADS
-PTHREADLIB = -lpthread
+#PTHREADDEF = -DHAVE_PTHREADS
+#PTHREADLIB = -lpthread
 
 # Comment the following line to disable the use of 3 Bytes/Pixel.
 # The code for 3 Bytes/Pixel is not very efficient!
diff --git a/TODO b/TODO
index 97dd04b..28562e4 100644
--- a/TODO
+++ b/TODO
@@ -1,10 +1,13 @@
 immediate:
 ----------
 
+copyRect and pthreads possible problem.
+authentification schemes (secure vnc)
 udp
 documentation
-	perhaps the option (or just hint) not to mark very tiny regions as
-	modified, because that is inefficient for the encodings.
+	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).
 
 later:
 ------
diff --git a/main.c b/main.c
index e7c80fd..372bdb9 100644
--- a/main.c
+++ b/main.c
@@ -23,9 +23,6 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
-#ifdef HAVE_PTHREADS
-#include <pthread.h>
-#endif
 #include <unistd.h>
 #include <signal.h>
 #include <time.h>
@@ -33,9 +30,7 @@
 #include "rfb.h"
 #include "sraRegion.h"
 
-#ifdef HAVE_PTHREADS
 MUTEX(logMutex);
-#endif
 
 /*
  * rfbLog prints a time-stamped message to the log file (stderr).
@@ -67,6 +62,77 @@ void rfbLogPerror(char *str)
     rfbLog("%s: %s\n", str, strerror(errno));
 }
 
+void rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy)
+{  
+   rfbClientIteratorPtr iterator;
+   rfbClientPtr cl;
+
+  iterator=rfbGetClientIterator(rfbScreen);
+   while((cl=rfbClientIteratorNext(iterator))) {
+     LOCK(cl->updateMutex);
+     if(cl->useCopyRect) {
+       while(!sraRgnEmpty(cl->copyRegion) && (cl->copyDX!=dx || cl->copyDY!=dy)) {
+#ifdef HAVE_PTHREADS
+	 if(cl->screen->backgroundLoop) {
+	   SIGNAL(cl->updateCond);
+	   UNLOCK(cl->updateMutex);
+	   LOCK(cl->updateMutex);
+	 } else
+#endif
+	   rfbSendFramebufferUpdate(cl,cl->copyRegion);
+       }
+       sraRgnOr(cl->copyRegion,copyRegion);
+       cl->copyDX = dx;
+       cl->copyDY = dy;
+     } else {
+       sraRgnOr(cl->modifiedRegion,copyRegion);
+     }
+     SIGNAL(cl->updateCond);
+     UNLOCK(cl->updateMutex);
+   }
+
+   rfbReleaseClientIterator(iterator);
+}
+
+void rfbDoCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy)
+{
+   sraRectangleIterator* i;
+   sraRect rect;
+   int j,widthInBytes,bpp=rfbScreen->rfbServerFormat.bitsPerPixel/8,
+    rowstride=rfbScreen->paddedWidthInBytes;
+   char *in,*out;
+
+   /* copy it, really */
+   i = sraRgnGetReverseIterator(copyRegion,dx<0,dy<0);
+   while(sraRgnIteratorNext(i,&rect)) {
+     widthInBytes = (rect.x2-rect.x1)*bpp;
+     out = rfbScreen->frameBuffer+rect.x1*bpp+rect.y1*rowstride;
+     in = rfbScreen->frameBuffer+(rect.x1-dx)*bpp+(rect.y1-dy)*rowstride;
+     if(dy<0)
+       for(j=rect.y1;j<rect.y2;j++,out+=rowstride,in+=rowstride)
+	 memmove(out,in,widthInBytes);
+     else {
+       out += rowstride*(rect.y2-rect.y1-1);
+       in += rowstride*(rect.y2-rect.y1-1);
+       for(j=rect.y2-1;j>=rect.y1;j--,out-=rowstride,in-=rowstride)
+	 memmove(out,in,widthInBytes);
+     }
+   }
+  
+   rfbScheduleCopyRegion(rfbScreen,copyRegion,dx,dy);
+}
+
+void rfbDoCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy)
+{
+  sraRegionPtr region = sraRgnCreateRect(x1,y1,x2,y2);
+  rfbDoCopyRegion(rfbScreen,region,dx,dy);
+}
+
+void rfbScheduleCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy)
+{
+  sraRegionPtr region = sraRgnCreateRect(x1,y1,x2,y2);
+  rfbScheduleCopyRegion(rfbScreen,region,dx,dy);
+}
 
 void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion)
 {
@@ -395,6 +461,8 @@ rfbScreenInfoPtr rfbGetScreen(int argc,char** argv,
    rfbScreen->cursor = &myCursor;
    INIT_MUTEX(rfbScreen->cursorMutex);
 
+   IF_PTHREADS(rfbScreen->backgroundLoop = FALSE);
+
    /* proc's and hook's */
 
    rfbScreen->kbdAddEvent = defaultKbdAddEvent;
@@ -456,6 +524,8 @@ void rfbRunEventLoop(rfbScreenInfoPtr rfbScreen, long usec, Bool runInBackground
 #ifdef HAVE_PTHREADS
        pthread_t listener_thread;
 
+       rfbScreen->backgroundLoop = TRUE;
+
        pthread_create(&listener_thread, NULL, listenerRun, rfbScreen);
     return;
 #else
diff --git a/rfb.h b/rfb.h
index e5722a7..c1313f5 100644
--- a/rfb.h
+++ b/rfb.h
@@ -118,7 +118,7 @@ int max(int,int);
 #define MUTEX(mutex)
 #define INIT_MUTEX(mutex)
 #define TINI_MUTEX(mutex)
-#define SIGNAL(cond) this_is_unsupported
+#define SIGNAL(cond)
 #define WAIT(cond,mutex) this_is_unsupported
 #define COND(cond)
 #define INIT_COND(cond)
@@ -256,6 +256,8 @@ typedef struct
     struct rfbCursor* cursor;
     MUTEX(cursorMutex);
    
+    IF_PTHREADS(Bool backgroundLoop);
+
     /* the following members have to be supplied by the serving process */
     char* frameBuffer;
     KbdAddEventProcPtr kbdAddEvent;
@@ -516,7 +518,12 @@ static const int rfbEndianTest = (_BYTE_ORDER == _LITTLE_ENDIAN);
 
 extern void rfbLog(char *format, ...);
 extern void rfbLogPerror(char *str);
-extern int runVNCServer(int argc, char *argv[]);
+
+void rfbScheduleCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy);
+void rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy);
+
+void rfbDoCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy);
+void rfbDoCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy);
 
 
 /* sockets.c */
diff --git a/rfbserver.c b/rfbserver.c
index 2695170..5266e5a 100644
--- a/rfbserver.c
+++ b/rfbserver.c
@@ -225,7 +225,7 @@ rfbNewClient(rfbScreen,sock)
 
     LOCK(rfbClientListMutex);
 
-    cl->refCount = 0;
+    IF_PTHREADS(cl->refCount = 0);
     cl->next = rfbScreen->rfbClientHead;
     cl->prev = NULL;
     if (rfbScreen->rfbClientHead)
@@ -834,6 +834,7 @@ rfbProcessClientNormalMessage(cl)
 /*
  * rfbSendFramebufferUpdate - send the currently pending framebuffer update to
  * the RFB client.
+ * givenUpdateRegion is not changed.
  */
 
 Bool
@@ -1112,7 +1113,7 @@ rfbSendCopyRegion(cl, reg, dx, dy)
 
       cr.srcX = Swap16IfLE(x - dx);
       cr.srcY = Swap16IfLE(y - dy);
-
+fprintf(stderr,"sent copyrect (%d,%d) (%d,%d) (%d,%d)\n",x,y,w,h,x-dx,y-dy);
       memcpy(&cl->updateBuf[cl->ublen], (char *)&cr, sz_rfbCopyRect);
       cl->ublen += sz_rfbCopyRect;
 
-- 
cgit v1.2.3

