From 2c4869fc9a8f2c72e6f8631b25894246a0a90701 Mon Sep 17 00:00:00 2001
From: dscho <dscho>
Date: Tue, 16 Oct 2001 20:57:26 +0000
Subject: deferUpdate

---
 CHANGES     |  2 ++
 TODO        |  2 +-
 main.c      | 24 ++++++++++++++++++++----
 rfb.h       |  8 ++++++--
 rfbserver.c |  2 +-
 5 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/CHANGES b/CHANGES
index 2b5d91e..09eae0d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,6 @@
 0.2
+   inserted a deferUpdate mechanism (X11 independent).
+   removed deletion of requestedRegion
    added rfbLoadConsoleFont
    fixed font colour handling.
    added rfbSelectBox
diff --git a/TODO b/TODO
index 16bac26..4e6b3de 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,6 @@
 immediate:
 ----------
 
-DeferUpdateTime (timing problems!)
 cursor drawing: set optional grain to mark bigger rectangles as drawn (else
 	you end up with thousands of one-pixel-rectangles to encode).
 selectbox: scroll bars
@@ -26,6 +25,7 @@ internal HTTP tunnelling feature (needs a special GET target and a few
 done:
 -----
 
+.DeferUpdateTime (timing problems!)
 .empty cursor sending doesn't work.
 .udp (need an rfbClientPtr udpClient in rfbScreen)
 	input only; nearly untested (don't have the clients).
diff --git a/main.c b/main.c
index 96f335e..7be9191 100644
--- a/main.c
+++ b/main.c
@@ -471,6 +471,7 @@ rfbScreenInfoPtr rfbGetScreen(int argc,char** argv,
    rfbScreen->rfbAlwaysShared = FALSE;
    rfbScreen->rfbNeverShared = FALSE;
    rfbScreen->rfbDontDisconnect = FALSE;
+   rfbScreen->rfbAuthPasswdData = 0;
    
    processArguments(rfbScreen,argc,argv);
 
@@ -580,6 +581,7 @@ rfbProcessEvents(rfbScreenInfoPtr rfbScreen,long usec)
 {
   rfbClientIteratorPtr i;
   rfbClientPtr cl,clPrev;
+  struct timeval tv;
 
   rfbCheckFds(rfbScreen,usec);
   httpCheckFds(rfbScreen);
@@ -590,10 +592,24 @@ rfbProcessEvents(rfbScreenInfoPtr rfbScreen,long usec)
   i = rfbGetClientIterator(rfbScreen);
   cl=rfbClientIteratorNext(i);
   while(cl) {
-    if(cl->sock>=0 && FB_UPDATE_PENDING(cl))
-      rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
-	clPrev=cl;
-	cl=rfbClientIteratorNext(i);
+    if(cl->sock>=0 && FB_UPDATE_PENDING(cl)) {
+      if(cl->startDeferring.tv_usec == 0) {
+	gettimeofday(&cl->startDeferring,NULL);
+	if(cl->startDeferring.tv_usec == 0)
+	  cl->startDeferring.tv_usec++;
+      } else {
+	gettimeofday(&tv,NULL);
+	if(tv.tv_sec < cl->startDeferring.tv_sec /* at midnight */
+	   || ((tv.tv_sec-cl->startDeferring.tv_sec)*1000
+	       +(tv.tv_usec-cl->startDeferring.tv_usec)/1000)
+	     > cl->screen->rfbDeferUpdateTime) {
+	  cl->startDeferring.tv_usec = 0;
+	  rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
+	}
+      }
+    }
+    clPrev=cl;
+    cl=rfbClientIteratorNext(i);
     if(clPrev->sock==-1)
       rfbClientConnectionGone(clPrev);
   }
diff --git a/rfb.h b/rfb.h
index ad78490..eac85e2 100644
--- a/rfb.h
+++ b/rfb.h
@@ -26,6 +26,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/time.h>
 #include <zlib.h>
 #include "keysym.h"
 
@@ -269,6 +270,8 @@ typedef struct
     PasswordCheckProcPtr passwordCheck;
     char* rfbAuthPasswdData;
 
+    /* this is the amount of milliseconds to wait at least before sending
+     * an update. */
     int rfbDeferUpdateTime;
     char* rfbScreen;
     Bool rfbAlwaysShared;
@@ -406,13 +409,14 @@ typedef struct rfbClientRec {
 
     sraRegionPtr requestedRegion;
 
-    /* TODO: */
-    /* The following members represent the state of the "deferred update" timer
+    /* The following member represents the state of the "deferred update" timer
        - when the framebuffer is modified and the client is ready, in most
        cases it is more efficient to defer sending the update by a few
        milliseconds so that several changes to the framebuffer can be combined
        into a single update. */
 
+      struct timeval startDeferring;
+
     /* translateFn points to the translation function which is used to copy
        and translate a rectangle from the framebuffer to an output buffer. */
 
diff --git a/rfbserver.c b/rfbserver.c
index 3c3c858..a4decae 100644
--- a/rfbserver.c
+++ b/rfbserver.c
@@ -185,7 +185,7 @@ rfbNewTCPOrUDPClient(rfbScreen,sock,isUDP)
     int addrlen = sizeof(struct sockaddr_in);
     int i;
 
-    cl = (rfbClientPtr)malloc(sizeof(rfbClientRec));
+    cl = (rfbClientPtr)calloc(sizeof(rfbClientRec),1);
 
     cl->screen = rfbScreen;
     cl->sock = sock;
-- 
cgit v1.2.3

