From 9f8d8d4ef38951767aa428796df127ff80de9b6e Mon Sep 17 00:00:00 2001 From: George Kiagiadakis Date: Wed, 10 Nov 2010 18:57:17 +0000 Subject: [PATCH] Split two event-loop related functions out of the rfbProcessEvents() mechanism. This is required to be able to do proper event loop integration with Qt. Idea was taken from vino's libvncserver fork. Signed-off-by: Christian Beier --- libvncserver/main.c | 62 ++++++++++++++++++++--------------- libvncserver/sockets.c | 73 ++++++++++++++++++++++++------------------ rfb/rfb.h | 6 ++++ 3 files changed, 85 insertions(+), 56 deletions(-) diff --git a/libvncserver/main.c b/libvncserver/main.c index eab4c84..bae4db4 100644 --- a/libvncserver/main.c +++ b/libvncserver/main.c @@ -1085,24 +1085,44 @@ rfbProcessEvents(rfbScreenInfoPtr screen,long usec) i = rfbGetClientIteratorWithClosed(screen); cl=rfbClientIteratorHead(i); while(cl) { - if (cl->sock >= 0 && !cl->onHold && FB_UPDATE_PENDING(cl) && + result = rfbUpdateClient(cl); + clPrev=cl; + cl=rfbClientIteratorNext(i); + if(clPrev->sock==-1) { + rfbClientConnectionGone(clPrev); + result=TRUE; + } + } + rfbReleaseClientIterator(i); + + return result; +} + +rfbBool +rfbUpdateClient(rfbClientPtr cl) +{ + struct timeval tv; + rfbBool result=FALSE; + rfbScreenInfoPtr screen = cl->screen; + + if (cl->sock >= 0 && !cl->onHold && FB_UPDATE_PENDING(cl) && !sraRgnEmpty(cl->requestedRegion)) { result=TRUE; if(screen->deferUpdateTime == 0) { - rfbSendFramebufferUpdate(cl,cl->modifiedRegion); + rfbSendFramebufferUpdate(cl,cl->modifiedRegion); } else if(cl->startDeferring.tv_usec == 0) { - gettimeofday(&cl->startDeferring,NULL); - if(cl->startDeferring.tv_usec == 0) - cl->startDeferring.tv_usec++; + 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) - > screen->deferUpdateTime) { - cl->startDeferring.tv_usec = 0; - rfbSendFramebufferUpdate(cl,cl->modifiedRegion); - } + 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) + > screen->deferUpdateTime) { + cl->startDeferring.tv_usec = 0; + rfbSendFramebufferUpdate(cl,cl->modifiedRegion); + } } } @@ -1119,23 +1139,15 @@ rfbProcessEvents(rfbScreenInfoPtr screen,long usec) +(tv.tv_usec-cl->startPtrDeferring.tv_usec)/1000) > cl->screen->deferPtrUpdateTime) { cl->startPtrDeferring.tv_usec = 0; - cl->screen->ptrAddEvent(cl->lastPtrButtons, - cl->lastPtrX, + cl->screen->ptrAddEvent(cl->lastPtrButtons, + cl->lastPtrX, cl->lastPtrY, cl); - cl->lastPtrX = -1; + cl->lastPtrX = -1; } } } - clPrev=cl; - cl=rfbClientIteratorNext(i); - if(clPrev->sock==-1) { - rfbClientConnectionGone(clPrev); - result=TRUE; - } - } - rfbReleaseClientIterator(i); - return result; + return result; } rfbBool rfbIsActive(rfbScreenInfoPtr screenInfo) { diff --git a/libvncserver/sockets.c b/libvncserver/sockets.c index e1c5a7f..b7ea8c1 100644 --- a/libvncserver/sockets.c +++ b/libvncserver/sockets.c @@ -260,37 +260,7 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec) if (rfbScreen->listenSock != -1 && FD_ISSET(rfbScreen->listenSock, &fds)) { - if ((sock = accept(rfbScreen->listenSock, - (struct sockaddr *)&addr, &addrlen)) < 0) { - rfbLogPerror("rfbCheckFds: accept"); - return -1; - } - - if(!rfbSetNonBlocking(sock)) { - closesocket(sock); - return -1; - } - - if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, - (char *)&one, sizeof(one)) < 0) { - rfbLogPerror("rfbCheckFds: setsockopt"); - closesocket(sock); - return -1; - } - -#ifdef USE_LIBWRAP - if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr), - STRING_UNKNOWN)) { - rfbLog("Rejected connection from client %s\n", - inet_ntoa(addr.sin_addr)); - closesocket(sock); - return -1; - } -#endif - - rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr)); - - rfbNewClient(rfbScreen,sock); + rfbProcessNewConnection(rfbScreen); FD_CLR(rfbScreen->listenSock, &fds); if (--nfds == 0) @@ -352,6 +322,47 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec) return result; } +void +rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen) +{ + const int one = 1; + int sock = -1; + struct sockaddr_in addr; + socklen_t addrlen = sizeof(addr); + + if ((sock = accept(rfbScreen->listenSock, + (struct sockaddr *)&addr, &addrlen)) < 0) { + rfbLogPerror("rfbCheckFds: accept"); + return -1; + } + + if(!rfbSetNonBlocking(sock)) { + closesocket(sock); + return -1; + } + + if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, + (char *)&one, sizeof(one)) < 0) { + rfbLogPerror("rfbCheckFds: setsockopt"); + closesocket(sock); + return -1; + } + +#ifdef USE_LIBWRAP + if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr), + STRING_UNKNOWN)) { + rfbLog("Rejected connection from client %s\n", + inet_ntoa(addr.sin_addr)); + closesocket(sock); + return -1; + } +#endif + + rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr)); + + rfbNewClient(rfbScreen,sock); +} + void rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen) diff --git a/rfb/rfb.h b/rfb/rfb.h index fb8d892..12c5278 100644 --- a/rfb/rfb.h +++ b/rfb/rfb.h @@ -1003,6 +1003,12 @@ extern void rfbSetProtocolVersion(rfbScreenInfoPtr rfbScreen, int major_, int mi extern rfbBool rfbSendTextChatMessage(rfbClientPtr cl, uint32_t length, char *buffer); +/* + * Additions for Qt event loop integration + * Original idea taken from vino. + */ +void rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen); +rfbBool rfbUpdateClient(rfbClientPtr cl); #if(defined __cplusplus)