diff options
author | gkiagia <gkiagia@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-11-10 18:57:17 +0000 |
---|---|---|
committer | gkiagia <gkiagia@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-11-10 18:57:17 +0000 |
commit | cf5842f784e98fb707726c27dc158a264af170b2 (patch) | |
tree | dfd3ea292cd424f587b946e19566c74462fc979d | |
parent | 1f129e8a9e2cc925db576d8af2c510fc5989298a (diff) | |
download | libvncserver-cf5842f784e98fb707726c27dc158a264af170b2.zip libvncserver-cf5842f784e98fb707726c27dc158a264af170b2.tar.gz |
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
-rw-r--r-- | main.c | 62 | ||||
-rw-r--r-- | rfb/rfb.h | 6 | ||||
-rwxr-xr-x | sockets.c | 79 |
3 files changed, 88 insertions, 59 deletions
@@ -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) { @@ -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) @@ -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) |