diff --git a/ChangeLog b/ChangeLog index 2d8b5ae..8a02c14 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ * do not send unneccessary updates when drawing a cursor * ignore SIGPIPE; it is handled by EPIPE * add an example how to use rfbDoCopyRect + * add experimental progressive updating (off by default) 2004-01-19 Karl Runge * handle mouse button number mismatch diff --git a/cargs.c b/cargs.c index f393698..22ce9ad 100644 --- a/cargs.c +++ b/cargs.c @@ -35,6 +35,7 @@ rfbUsage(void) fprintf(stderr, "-httpdir dir-path enable http server using dir-path home\n"); fprintf(stderr, "-httpport portnum use portnum for http connection\n"); fprintf(stderr, "-enablehttpproxy enable http proxy support\n"); + fprintf(stderr, "-progressive height enable progressive updating for slow links\n"); } /* purges COUNT arguments from ARGV at POSITION and decrements ARGC. @@ -119,6 +120,12 @@ rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[]) rfbScreen->httpPort = atoi(argv[++i]); } else if (strcmp(argv[i], "-enablehttpproxy") == 0) { rfbScreen->httpEnableProxyConnect = TRUE; + } else if (strcmp(argv[i], "-progressive") == 0) { /* -httpport portnum */ + if (i + 1 >= *argc) { + rfbUsage(); + return FALSE; + } + rfbScreen->progressiveSliceHeight = atoi(argv[++i]); } else { /* we just remove the processed arguments from the list */ if(i != i1) diff --git a/main.c b/main.c index 6eded98..e6d7969 100644 --- a/main.c +++ b/main.c @@ -589,6 +589,11 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv, rfbScreen->passwordCheck = defaultPasswordCheck; + rfbScreen->ignoreSIGPIPE = TRUE; + + /* disable progressive updating per default */ + rfbScreen->progressiveSliceHeight = 0; + if(!rfbProcessArguments(rfbScreen,argc,argv)) { free(rfbScreen); return 0; @@ -638,8 +643,6 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv, /* initialize client list and iterator mutex */ rfbClientListInit(rfbScreen); - rfbScreen->ignoreSIGPIPE = TRUE; - return(rfbScreen); } @@ -801,7 +804,7 @@ rfbProcessEvents(rfbScreenInfoPtr rfbScreen,long usec) while(cl) { if (cl->sock >= 0 && !cl->onHold && FB_UPDATE_PENDING(cl) && !sraRgnEmpty(cl->requestedRegion)) { - if(cl->screen->rfbDeferUpdateTime == 0) { + if(rfbScreen->rfbDeferUpdateTime == 0) { rfbSendFramebufferUpdate(cl,cl->modifiedRegion); } else if(cl->startDeferring.tv_usec == 0) { gettimeofday(&cl->startDeferring,NULL); @@ -812,7 +815,7 @@ rfbProcessEvents(rfbScreenInfoPtr rfbScreen,long usec) 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) { + > rfbScreen->rfbDeferUpdateTime) { cl->startDeferring.tv_usec = 0; rfbSendFramebufferUpdate(cl,cl->modifiedRegion); } diff --git a/rfb/rfb.h b/rfb/rfb.h index a571235..d472684 100644 --- a/rfb/rfb.h +++ b/rfb/rfb.h @@ -274,7 +274,13 @@ typedef struct _rfbScreenInfo rfbBool backgroundLoop; #endif + /* if TRUE, an ignoring signal handler is installed for SIGPIPE */ rfbBool ignoreSIGPIPE; + + /* if not zero, only a slice of this height is processed every time + * an update should be sent. This should make working on a slow + * link more interactive. */ + int progressiveSliceHeight; } rfbScreenInfo, *rfbScreenInfoPtr; @@ -469,6 +475,9 @@ typedef struct _rfbClientRec { void* zrleData; #endif + /* if progressive updating is on, this variable holds the current + * y coordinate of the progressive slice. */ + int progressiveSliceY; } rfbClientRec, *rfbClientPtr; /* diff --git a/rfbserver.c b/rfbserver.c index 914aa0b..1b11e6b 100644 --- a/rfbserver.c +++ b/rfbserver.c @@ -340,6 +340,8 @@ rfbNewTCPOrUDPClient(rfbScreen,sock,isUDP) cl->zlibCompressLevel = 5; #endif + cl->progressiveSliceY = 0; + sprintf(pv,rfbProtocolVersionFormat,rfbProtocolMajorVersion, rfbProtocolMinorVersion); @@ -1109,6 +1111,26 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion) */ updateRegion = sraRgnCreateRgn(givenUpdateRegion); + if(cl->screen->progressiveSliceHeight>0) { + int height=cl->screen->progressiveSliceHeight, + y=cl->progressiveSliceY; + sraRegionPtr bbox=sraRgnBBox(updateRegion); + sraRect rect; + if(sraRgnPopRect(bbox,&rect,0)) { + sraRegionPtr slice; + if(y=rect.y2) + y=rect.y1; + slice=sraRgnCreateRect(0,y,cl->screen->width,y+height); + sraRgnAnd(updateRegion,slice); + sraRgnDestroy(slice); + } + sraRgnDestroy(bbox); + y+=height; + if(y>=cl->screen->height) + y=0; + cl->progressiveSliceY=y; + } + sraRgnOr(updateRegion,cl->copyRegion); if(!sraRgnAnd(updateRegion,cl->requestedRegion) && !sendCursorShape && !sendCursorPos) {