From cf5842f784e98fb707726c27dc158a264af170b2 Mon Sep 17 00:00:00 2001 From: gkiagia <gkiagia@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> Date: Wed, 10 Nov 2010 18:57:17 +0000 Subject: 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. git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/KDE/kdenetwork/krfb/libvncserver@1195286 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- main.c | 62 +++++++++++++++++++++++++++++-------------------- rfb/rfb.h | 6 +++++ sockets.c | 79 ++++++++++++++++++++++++++++++++++++--------------------------- 3 files changed, 88 insertions(+), 59 deletions(-) diff --git a/main.c b/main.c index 52bd4e7..f73cef3 100644 --- a/main.c +++ b/main.c @@ -1070,24 +1070,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); + } } } @@ -1104,23 +1124,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/rfb/rfb.h b/rfb/rfb.h index cfa6b80..9546cad 100644 --- a/rfb/rfb.h +++ b/rfb/rfb.h @@ -967,6 +967,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) diff --git a/sockets.c b/sockets.c index 0d04f0a..cd5b669 100755 --- a/sockets.c +++ b/sockets.c @@ -264,40 +264,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; - } - -#ifndef WIN32 - if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { - rfbLogPerror("rfbCheckFds: fcntl"); - closesocket(sock); - return -1; - } -#endif - - 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) @@ -359,6 +326,50 @@ 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; + } + +#ifndef WIN32 + if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { + rfbLogPerror("rfbCheckFds: fcntl"); + closesocket(sock); + return -1; + } +#endif + + 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) -- cgit v1.1