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