From 2c4869fc9a8f2c72e6f8631b25894246a0a90701 Mon Sep 17 00:00:00 2001 From: dscho Date: Tue, 16 Oct 2001 20:57:26 +0000 Subject: [PATCH] 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 #include #include +#include #include #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;