diff --git a/AUTHORS b/AUTHORS index 8813d17..8d572c5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -28,7 +28,7 @@ email!): Akira Hatakeyama, Karl J. Runge, Justin "Zippy" Dearing, Oliver Mihatsch, Greg Sternberg, Werner Hofer, Giampiero Giancipoli, Glenn Mabutt, Paul Kreiner, Erik Kunze, Mike Frysinger, Martin Waitz, Mark McLoughlin, Paul Fox, Juan Jose Costello, Andre Leiadella, -Alberto Lusiani. +Alberto Lusiani, Malvina Mazin, Dave Stuart. Probably I forgot quite a few people sending a patch here and there, which really made a difference. Without those, some obscure bugs still would diff --git a/ChangeLog b/ChangeLog index 8303149..b5e5a1a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2005-12-19 Dave Stuart + * libvncserver/{main.c,rfbserver.c,cargs.c}, rfb/rfb.h: introduce + deferPtrUpdateTime, which defers the handling of pointer events + for a couple of milliseconds. + +2005-12-19 Johannes E. Schindelin + * client_examples/SDLvncviewer.c, libvncclient/{sockets.c,vncviewer.c}, + libvncserver/{main.c,rfbserver.c,sockets.c}: fix MinGW32 compilation + 2005-12-08 "Mazin, Malvina" * configure.ac, libvncserver/sockets.c: on Solaris 2.7, write may return ENOENT when it really means EAGAIN. diff --git a/libvncserver/cargs.c b/libvncserver/cargs.c index 96b9f84..26f03d6 100644 --- a/libvncserver/cargs.c +++ b/libvncserver/cargs.c @@ -29,6 +29,8 @@ rfbUsage(void) " (use plain-password as password, USE AT YOUR RISK)\n"); fprintf(stderr, "-deferupdate time time in ms to defer updates " "(default 40)\n"); + fprintf(stderr, "-deferptrupdate time time in ms to defer pointer updates" + " (default none)\n"); fprintf(stderr, "-desktop name VNC desktop name (default \"LibVNCServer\")\n"); fprintf(stderr, "-alwaysshared always treat new clients as shared\n"); fprintf(stderr, "-nevershared never treat new clients as shared\n"); @@ -104,6 +106,12 @@ rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[]) return FALSE; } rfbScreen->deferUpdateTime = atoi(argv[++i]); + } else if (strcmp(argv[i], "-deferptrupdate") == 0) { /* -deferptrupdate milliseconds */ + if (i + 1 >= *argc) { + rfbUsage(); + return FALSE; + } + rfbScreen->deferPtrUpdateTime = atoi(argv[++i]); } else if (strcmp(argv[i], "-desktop") == 0) { /* -desktop desktop-name */ if (i + 1 >= *argc) { rfbUsage(); diff --git a/libvncserver/main.c b/libvncserver/main.c index cdf2bfc..41d70ea 100644 --- a/libvncserver/main.c +++ b/libvncserver/main.c @@ -931,6 +931,27 @@ rfbProcessEvents(rfbScreenInfoPtr screen,long usec) } } } + + if (!cl->viewOnly && cl->lastPtrX >= 0) { + if(cl->startPtrDeferring.tv_usec == 0) { + gettimeofday(&cl->startPtrDeferring,NULL); + if(cl->startPtrDeferring.tv_usec == 0) + cl->startPtrDeferring.tv_usec++; + } else { + struct timeval tv; + gettimeofday(&tv,NULL); + if(tv.tv_sec < cl->startPtrDeferring.tv_sec /* at midnight */ + || ((tv.tv_sec-cl->startPtrDeferring.tv_sec)*1000 + +(tv.tv_usec-cl->startPtrDeferring.tv_usec)/1000) + > cl->screen->deferPtrUpdateTime) { + cl->startPtrDeferring.tv_usec = 0; + cl->screen->ptrAddEvent(cl->lastPtrButtons, + cl->lastPtrX, + cl->lastPtrY, cl); + cl->lastPtrX = -1; + } + } + } clPrev=cl; cl=rfbClientIteratorNext(i); if(clPrev->sock==-1) { diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c index 2b61375..e60aadc 100644 --- a/libvncserver/rfbserver.c +++ b/libvncserver/rfbserver.c @@ -353,6 +353,8 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen, cl->extensions = NULL; + cl->lastPtrX = -1; + sprintf(pv,rfbProtocolVersionFormat,rfbProtocolMajorVersion, rfbProtocolMinorVersion); @@ -1071,11 +1073,19 @@ rfbProcessClientNormalMessage(rfbClientPtr cl) cl->screen->pointerClient = cl; if(!cl->viewOnly) { - cl->screen->ptrAddEvent(msg.pe.buttonMask, - Swap16IfLE(msg.pe.x), Swap16IfLE(msg.pe.y), cl); - } + if (msg.pe.buttonMask != cl->lastPtrButtons || + cl->screen->deferPtrUpdateTime == 0) { + cl->screen->ptrAddEvent(msg.pe.buttonMask, + Swap16IfLE(msg.pe.x), Swap16IfLE(msg.pe.y), cl); + cl->lastPtrButtons = msg.pe.buttonMask; + } else { + cl->lastPtrX = Swap16IfLE(msg.pe.x); + cl->lastPtrY = Swap16IfLE(msg.pe.y); + cl->lastPtrButtons = msg.pe.buttonMask; + } + } + return; - return; case rfbClientCutText: diff --git a/rfb/rfb.h b/rfb/rfb.h index caec018..c2abb0e 100644 --- a/rfb/rfb.h +++ b/rfb/rfb.h @@ -62,8 +62,10 @@ extern "C" #define TINI_COND(cond) (rfbLog("%s:%d TINI_COND(%s)\n",__FILE__,__LINE__,#cond), pthread_cond_destroy(&(cond))) #define IF_PTHREADS(x) x #else +#if !NONETWORK #define LOCK(mutex) pthread_mutex_lock(&(mutex)); #define UNLOCK(mutex) pthread_mutex_unlock(&(mutex)); +#endif #define MUTEX(mutex) pthread_mutex_t (mutex) #define INIT_MUTEX(mutex) pthread_mutex_init(&(mutex),NULL) #define TINI_MUTEX(mutex) pthread_mutex_destroy(&(mutex)) @@ -307,6 +309,7 @@ typedef struct _rfbScreenInfo int progressiveSliceHeight; in_addr_t listenInterface; + int deferPtrUpdateTime; } rfbScreenInfo, *rfbScreenInfoPtr; @@ -418,6 +421,10 @@ typedef struct _rfbClientRec { into a single update. */ struct timeval startDeferring; + struct timeval startPtrDeferring; + int lastPtrX; + int lastPtrY; + int lastPtrButtons; /* translateFn points to the translation function which is used to copy and translate a rectangle from the framebuffer to an output buffer. */