sharkcz / rpms / tigervnc

Forked from rpms/tigervnc 4 years ago
Clone
5feba83
diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/vncBlockHandler.c.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/vncBlockHandler.c
5feba83
--- tigervnc-1.7.0/unix/xserver/hw/vnc/vncBlockHandler.c.xserver119	2016-09-08 12:31:18.000000000 +0200
5feba83
+++ tigervnc-1.7.0/unix/xserver/hw/vnc/vncBlockHandler.c	2016-10-04 17:17:35.618889747 +0200
5feba83
@@ -30,6 +30,23 @@
5feba83
 
5feba83
 #include "vncExtInit.h"
5feba83
 #include "vncBlockHandler.h"
5feba83
+#include "xorg-version.h"
5feba83
+
5feba83
+#if XORG >= 119
5feba83
+
5feba83
+static void vncBlockHandler(void* data, void* timeout)
5feba83
+{
5feba83
+  vncCallBlockHandlers(timeout);
5feba83
+}
5feba83
+
5feba83
+void vncRegisterBlockHandlers(void)
5feba83
+{
5feba83
+  if (!RegisterBlockAndWakeupHandlers(vncBlockHandler,
5feba83
+                                      (ServerWakeupHandlerProcPtr)NoopDDA, 0))
5feba83
+    FatalError("RegisterBlockAndWakeupHandlers() failed\n");
5feba83
+}
5feba83
+
5feba83
+#else
5feba83
 
5feba83
 static void vncBlockHandler(void * data, OSTimePtr t, void * readmask);
5feba83
 static void vncWakeupHandler(void * data, int nfds, void * readmask);
5feba83
@@ -144,3 +161,5 @@ static void vncWriteWakeupHandlerFallbac
5feba83
 
5feba83
   vncWriteWakeupHandler(ret, &fallbackFds);
5feba83
 }
5feba83
+
5feba83
+#endif
5feba83
diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.cc.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.cc
5feba83
--- tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.cc.xserver119	2016-09-08 12:31:18.000000000 +0200
5feba83
+++ tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.cc	2016-10-04 17:17:35.618889747 +0200
5feba83
@@ -241,6 +241,17 @@ int vncExtensionIsActive(int scrIdx)
5feba83
   return (desktop[scrIdx] != NULL);
5feba83
 }
5feba83
 
5feba83
+#if XORG >= 119
5feba83
+
5feba83
+void vncCallBlockHandlers(int* timeout)
5feba83
+{
5feba83
+  for (int scr = 0; scr < vncGetScreenCount(); scr++)
5feba83
+    if (desktop[scr])
5feba83
+      desktop[scr]->blockHandler(timeout);
5feba83
+}
5feba83
+
5feba83
+#else
5feba83
+
5feba83
 void vncCallReadBlockHandlers(fd_set * fds, struct timeval ** timeout)
5feba83
 {
5feba83
   for (int scr = 0; scr < vncGetScreenCount(); scr++)
5feba83
@@ -269,6 +280,8 @@ void vncCallWriteWakeupHandlers(fd_set *
5feba83
       desktop[scr]->writeWakeupHandler(fds, nfds);
5feba83
 }
5feba83
 
5feba83
+#endif
5feba83
+
5feba83
 int vncGetAvoidShiftNumLock(void)
5feba83
 {
5feba83
   return (bool)avoidShiftNumLock;
5feba83
diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.h.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.h
5feba83
--- tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.h.xserver119	2016-09-08 12:31:18.000000000 +0200
5feba83
+++ tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.h	2016-10-04 17:17:35.618889747 +0200
5feba83
@@ -22,6 +22,7 @@
5feba83
 #include <stdint.h>
5feba83
 #include <stddef.h>
5feba83
 #include <sys/select.h>
5feba83
+#include "xorg-version.h"
5feba83
 
5feba83
 // Only from C++
5feba83
 #ifdef __cplusplus
5feba83
@@ -52,10 +53,14 @@ extern int vncInetdSock;
5feba83
 void vncExtensionInit(void);
5feba83
 int vncExtensionIsActive(int scrIdx);
5feba83
 
5feba83
+#if XORG >= 119
5feba83
+void vncCallBlockHandlers(int* timeout);
5feba83
+#else
5feba83
 void vncCallReadBlockHandlers(fd_set * fds, struct timeval ** timeout);
5feba83
 void vncCallReadWakeupHandlers(fd_set * fds, int nfds);
5feba83
 void vncCallWriteBlockHandlers(fd_set * fds, struct timeval ** timeout);
5feba83
 void vncCallWriteWakeupHandlers(fd_set * fds, int nfds);
5feba83
+#endif
5feba83
 
5feba83
 int vncGetAvoidShiftNumLock(void);
5feba83
 
5feba83
diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/vncHooks.c.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/vncHooks.c
5feba83
--- tigervnc-1.7.0/unix/xserver/hw/vnc/vncHooks.c.xserver119	2016-09-08 12:31:18.000000000 +0200
5feba83
+++ tigervnc-1.7.0/unix/xserver/hw/vnc/vncHooks.c	2016-10-04 17:17:35.618889747 +0200
5feba83
@@ -128,9 +128,11 @@ static Bool vncHooksDisplayCursor(Device
5feba83
 #if XORG <= 112
5feba83
 static void vncHooksBlockHandler(int i, pointer blockData, pointer pTimeout,
5feba83
                                  pointer pReadmask);
5feba83
-#else
5feba83
+#elif XORG <= 118
5feba83
 static void vncHooksBlockHandler(ScreenPtr pScreen, void * pTimeout,
5feba83
                                  void * pReadmask);
5feba83
+#else
5feba83
+static void vncHooksBlockHandler(ScreenPtr pScreen, void * pTimeout);
5feba83
 #endif
5feba83
 #ifdef RENDER
5feba83
 static void vncHooksComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, 
5feba83
@@ -716,9 +718,11 @@ out:
5feba83
 #if XORG <= 112
5feba83
 static void vncHooksBlockHandler(int i, pointer blockData, pointer pTimeout,
5feba83
                                  pointer pReadmask)
5feba83
-#else
5feba83
+#elif XORG <= 118
5feba83
 static void vncHooksBlockHandler(ScreenPtr pScreen_, void * pTimeout,
5feba83
                                  void * pReadmask)
5feba83
+#else
5feba83
+static void vncHooksBlockHandler(ScreenPtr pScreen_, void * pTimeout)
5feba83
 #endif
5feba83
 {
5feba83
 #if XORG <= 112
5feba83
@@ -731,8 +735,10 @@ static void vncHooksBlockHandler(ScreenP
5feba83
 
5feba83
 #if XORG <= 112
5feba83
   (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
5feba83
-#else
5feba83
+#elif XORG <= 118
5feba83
   (*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask);
5feba83
+#else
5feba83
+  (*pScreen->BlockHandler) (pScreen, pTimeout);
5feba83
 #endif
5feba83
 
5feba83
   vncHooksScreen->ignoreHooks--;
5feba83
@@ -1033,12 +1039,21 @@ static void vncHooksCopyClip(GCPtr dst,
5feba83
 
5feba83
 // Unwrap and rewrap helpers
5feba83
 
5feba83
+#if XORG >= 116
5feba83
+#define GC_OP_PROLOGUE(pGC, name)\
5feba83
+    vncHooksGCPtr pGCPriv = vncHooksGCPrivate(pGC);\
5feba83
+    const GCFuncs *oldFuncs = pGC->funcs;\
5feba83
+    pGC->funcs = pGCPriv->wrappedFuncs;\
5feba83
+    pGC->ops = pGCPriv->wrappedOps; \
5feba83
+    DBGPRINT((stderr,"vncHooks" #name " called\n"))
5feba83
+#else
5feba83
 #define GC_OP_PROLOGUE(pGC, name)\
5feba83
     vncHooksGCPtr pGCPriv = vncHooksGCPrivate(pGC);\
5feba83
     GCFuncs *oldFuncs = pGC->funcs;\
5feba83
     pGC->funcs = pGCPriv->wrappedFuncs;\
5feba83
     pGC->ops = pGCPriv->wrappedOps; \
5feba83
     DBGPRINT((stderr,"vncHooks" #name " called\n"))
5feba83
+#endif
5feba83
 
5feba83
 #define GC_OP_EPILOGUE(pGC)\
5feba83
     pGCPriv->wrappedOps = pGC->ops;\
5feba83
diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/xorg-version.h.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/xorg-version.h
5feba83
--- tigervnc-1.7.0/unix/xserver/hw/vnc/xorg-version.h.xserver119	2016-09-08 12:31:18.000000000 +0200
5feba83
+++ tigervnc-1.7.0/unix/xserver/hw/vnc/xorg-version.h	2016-10-04 17:24:51.640654527 +0200
5feba83
@@ -50,8 +50,10 @@
5feba83
 #define XORG 117
5feba83
 #elif XORG_VERSION_CURRENT < ((1 * 10000000) + (18 * 100000) + (99 * 1000))
5feba83
 #define XORG 118
5feba83
+#elif XORG_VERSION_CURRENT < ((1 * 10000000) + (19 * 100000) + (99 * 1000))
5feba83
+#define XORG 119
5feba83
 #else
5feba83
-#error "X.Org newer than 1.18 is not supported"
5feba83
+#error "X.Org newer than 1.19 is not supported"
5feba83
 #endif
5feba83
 
5feba83
 #endif
5feba83
diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.cc.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.cc
5feba83
--- tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.cc.xserver119	2016-09-08 12:31:18.000000000 +0200
5feba83
+++ tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.cc	2016-10-04 17:23:47.171977905 +0200
5feba83
@@ -89,6 +89,30 @@ public:
c3e0f5c
   XserverDesktop* desktop;
c3e0f5c
 };
c3e0f5c
 
c3e0f5c
+#if XORG >= 119
c3e0f5c
+extern "C" {
c3e0f5c
+/*
c3e0f5c
+ * xserver NotifyFd callbacks. Note we also expect write notifies to work,
c3e0f5c
+ * which only works with xserver >= 1.19.
c3e0f5c
+ */
c3e0f5c
+#include "os.h"
c3e0f5c
+
c3e0f5c
+static void HandleListenFd(int fd, int xevents, void *data)
c3e0f5c
+{
c3e0f5c
+  XserverDesktop *desktop = (XserverDesktop *)data;
c3e0f5c
+
c3e0f5c
+  desktop->handleListenFd(fd);
c3e0f5c
+}
c3e0f5c
+
c3e0f5c
+static void HandleSocketFd(int fd, int xevents, void *data)
c3e0f5c
+{
c3e0f5c
+  XserverDesktop *desktop = (XserverDesktop *)data;
c3e0f5c
+
c3e0f5c
+  desktop->handleSocketFd(fd, xevents);
c3e0f5c
+}
c3e0f5c
+
c3e0f5c
+}
c3e0f5c
+#endif
c3e0f5c
 
c3e0f5c
 XserverDesktop::XserverDesktop(int screenIndex_,
c3e0f5c
                                std::list<network::TcpListener*> listeners_,
5feba83
@@ -110,15 +134,35 @@ XserverDesktop::XserverDesktop(int scree
c3e0f5c
 
c3e0f5c
   if (!httpListeners.empty ())
c3e0f5c
     httpServer = new FileHTTPServer(this);
c3e0f5c
+
c3e0f5c
+#if XORG >= 119
c3e0f5c
+  for (std::list<TcpListener*>::iterator i = listeners.begin();
c3e0f5c
+       i != listeners.end();
c3e0f5c
+       i++) {
c3e0f5c
+    SetNotifyFd((*i)->getFd(), HandleListenFd, X_NOTIFY_READ, this);
c3e0f5c
+  }
c3e0f5c
+
c3e0f5c
+  for (std::list<TcpListener*>::iterator i = httpListeners.begin();
c3e0f5c
+       i != httpListeners.end();
c3e0f5c
+       i++) {
c3e0f5c
+    SetNotifyFd((*i)->getFd(), HandleListenFd, X_NOTIFY_READ, this);
c3e0f5c
+  }
c3e0f5c
+#endif
c3e0f5c
 }
c3e0f5c
 
c3e0f5c
 XserverDesktop::~XserverDesktop()
c3e0f5c
 {
c3e0f5c
   while (!listeners.empty()) {
c3e0f5c
+#if XORG >= 119
c3e0f5c
+    RemoveNotifyFd(listeners.back()->getFd());
c3e0f5c
+#endif
c3e0f5c
     delete listeners.back();
c3e0f5c
     listeners.pop_back();
c3e0f5c
   }
c3e0f5c
   while (!httpListeners.empty()) {
c3e0f5c
+#if XORG >= 119
c3e0f5c
+    RemoveNotifyFd(listeners.back()->getFd());
c3e0f5c
+#endif
c3e0f5c
     delete httpListeners.back();
c3e0f5c
     httpListeners.pop_back();
c3e0f5c
   }
5feba83
@@ -388,6 +432,140 @@ void XserverDesktop::add_copied(const rf
c3e0f5c
   }
c3e0f5c
 }
c3e0f5c
 
c3e0f5c
+#if XORG >= 119
c3e0f5c
+void XserverDesktop::handleListenFd(int fd)
c3e0f5c
+{
c3e0f5c
+  std::list<TcpListener*>::iterator i;
c3e0f5c
+  SocketServer *fd_server = NULL;
c3e0f5c
+  bool is_http = false;
c3e0f5c
+
c3e0f5c
+  for (i = listeners.begin(); i != listeners.end(); i++) {
c3e0f5c
+    if ((*i)->getFd() == fd) {
c3e0f5c
+      fd_server = server;
c3e0f5c
+      break;
c3e0f5c
+    }
c3e0f5c
+  }
c3e0f5c
+  if (httpServer && !fd_server) {
c3e0f5c
+    for (i = httpListeners.begin(); i != httpListeners.end(); i++) {
c3e0f5c
+      if ((*i)->getFd() == fd) {
c3e0f5c
+        fd_server = httpServer;
c3e0f5c
+        is_http = true;
c3e0f5c
+        break;
c3e0f5c
+      }
c3e0f5c
+    }
c3e0f5c
+  }
c3e0f5c
+  if (!fd_server) {
c3e0f5c
+    vlog.error("XserverDesktop::handleListenFd: Error cannot find fd");
c3e0f5c
+    return;
c3e0f5c
+  }
c3e0f5c
+
c3e0f5c
+  Socket* sock = (*i)->accept();
c3e0f5c
+  sock->outStream().setBlocking(false);
c3e0f5c
+  vlog.debug("new %sclient, sock %d", is_http ? "http " : "", sock->getFd());
c3e0f5c
+  fd_server->addSocket(sock);
c3e0f5c
+  SetNotifyFd(sock->getFd(), HandleSocketFd, X_NOTIFY_READ, this);
c3e0f5c
+}
c3e0f5c
+
c3e0f5c
+void XserverDesktop::handleSocketFd(int fd, int xevents)
c3e0f5c
+{
c3e0f5c
+  std::list<Socket*> sockets;
c3e0f5c
+  std::list<Socket*>::iterator i;
c3e0f5c
+  SocketServer *fd_server = NULL;
c3e0f5c
+  bool is_http = false;
c3e0f5c
+
c3e0f5c
+  server->getSockets(&sockets);
c3e0f5c
+  for (i = sockets.begin(); i != sockets.end(); i++) {
c3e0f5c
+    if ((*i)->getFd() == fd) {
c3e0f5c
+      fd_server = server;
c3e0f5c
+      break;
c3e0f5c
+    }
c3e0f5c
+  }
c3e0f5c
+  if (httpServer && !fd_server) {
c3e0f5c
+    httpServer->getSockets(&sockets);
c3e0f5c
+    for (i = sockets.begin(); i != sockets.end(); i++) {
c3e0f5c
+      if ((*i)->getFd() == fd) {
c3e0f5c
+        fd_server = httpServer;
c3e0f5c
+        is_http = true;
c3e0f5c
+        break;
c3e0f5c
+      }
c3e0f5c
+    }
c3e0f5c
+  }
c3e0f5c
+  if (!fd_server) {
c3e0f5c
+    vlog.error("XserverDesktop::handleSocketFd: Error cannot find fd");
c3e0f5c
+    return;
c3e0f5c
+  }
c3e0f5c
+
c3e0f5c
+  if (xevents & X_NOTIFY_READ)
c3e0f5c
+    fd_server->processSocketReadEvent(*i);
c3e0f5c
+
c3e0f5c
+  if (xevents & X_NOTIFY_WRITE)
c3e0f5c
+    fd_server->processSocketWriteEvent(*i);
c3e0f5c
+
c3e0f5c
+  if ((*i)->isShutdown()) {
c3e0f5c
+    vlog.debug("%sclient gone, sock %d", is_http ? "http " : "", fd);
c3e0f5c
+    RemoveNotifyFd(fd);
c3e0f5c
+    fd_server->removeSocket(*i);
c3e0f5c
+    if (!is_http)
c3e0f5c
+      vncClientGone(fd);
c3e0f5c
+    delete (*i);
c3e0f5c
+  }
c3e0f5c
+}
c3e0f5c
+
c3e0f5c
+void XserverDesktop::blockHandler(int* timeout)
c3e0f5c
+{
c3e0f5c
+  // We don't have a good callback for when we can init input devices[1],
c3e0f5c
+  // so we abuse the fact that this routine will be called first thing
c3e0f5c
+  // once the dix is done initialising.
c3e0f5c
+  // [1] Technically Xvnc has InitInput(), but libvnc.so has nothing.
c3e0f5c
+  vncInitInputDevice();
c3e0f5c
+
5feba83
+  try {
5feba83
+    std::list<Socket*> sockets;
5feba83
+    std::list<Socket*>::iterator i;
5feba83
+    server->getSockets(&sockets);
5feba83
+    for (i = sockets.begin(); i != sockets.end(); i++) {
5feba83
+      int fd = (*i)->getFd();
5feba83
+      if ((*i)->isShutdown()) {
5feba83
+        vlog.debug("client gone, sock %d",fd);
5feba83
+        server->removeSocket(*i);
5feba83
+        vncClientGone(fd);
5feba83
+        delete (*i);
5feba83
+      } else {
5feba83
+        /* Update existing NotifyFD to listen for write (or not) */
5feba83
+        if ((*i)->outStream().bufferUsage() > 0)
5feba83
+          SetNotifyFd(fd, HandleSocketFd, X_NOTIFY_READ | X_NOTIFY_WRITE, this);
5feba83
+        else
5feba83
+          SetNotifyFd(fd, HandleSocketFd, X_NOTIFY_READ, this);
5feba83
+      }
5feba83
+    }
5feba83
+    if (httpServer) {
5feba83
+      httpServer->getSockets(&sockets);
5feba83
+      for (i = sockets.begin(); i != sockets.end(); i++) {
5feba83
+        int fd = (*i)->getFd();
5feba83
+        if ((*i)->isShutdown()) {
5feba83
+          vlog.debug("http client gone, sock %d",fd);
5feba83
+          httpServer->removeSocket(*i);
5feba83
+          delete (*i);
5feba83
+        } else {
5feba83
+          /* Update existing NotifyFD to listen for write (or not) */
5feba83
+          if ((*i)->outStream().bufferUsage() > 0)
5feba83
+            SetNotifyFd(fd, HandleSocketFd, X_NOTIFY_READ | X_NOTIFY_WRITE, this);
5feba83
+          else
5feba83
+            SetNotifyFd(fd, HandleSocketFd, X_NOTIFY_READ, this);
5feba83
+        }
5feba83
+      }
5feba83
+    }
5feba83
+
5feba83
+    int nextTimeout = server->checkTimeouts();
5feba83
+    if (nextTimeout > 0 && (*timeout == -1 || nextTimeout < *timeout))
c3e0f5c
+      *timeout = nextTimeout;
5feba83
+  } catch (rdr::Exception& e) {
5feba83
+    vlog.error("XserverDesktop::blockHandler: %s",e.str());
5feba83
+  }
c3e0f5c
+}
c3e0f5c
+
c3e0f5c
+#else
c3e0f5c
+
c3e0f5c
 void XserverDesktop::readBlockHandler(fd_set* fds, struct timeval ** timeout)
c3e0f5c
 {
c3e0f5c
   // We don't have a good callback for when we can init input devices[1],
5feba83
@@ -600,10 +778,15 @@ void XserverDesktop::writeWakeupHandler(
c3e0f5c
   }
c3e0f5c
 }
c3e0f5c
 
c3e0f5c
+#endif
c3e0f5c
+
c3e0f5c
 void XserverDesktop::addClient(Socket* sock, bool reverse)
c3e0f5c
 {
c3e0f5c
   vlog.debug("new client, sock %d reverse %d",sock->getFd(),reverse);
c3e0f5c
   server->addSocket(sock, reverse);
c3e0f5c
+#if XORG >= 119
c3e0f5c
+  SetNotifyFd(sock->getFd(), HandleSocketFd, X_NOTIFY_READ, this);
c3e0f5c
+#endif
c3e0f5c
 }
c3e0f5c
 
c3e0f5c
 void XserverDesktop::disconnectClients()
5feba83
diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.h.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.h
5feba83
--- tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.h.xserver119	2016-09-08 12:31:18.000000000 +0200
5feba83
+++ tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.h	2016-10-04 17:17:35.617889712 +0200
c3e0f5c
@@ -38,6 +38,7 @@
c3e0f5c
 #include <rfb/VNCServerST.h>
c3e0f5c
 #include <rdr/SubstitutingInStream.h>
c3e0f5c
 #include "Input.h"
c3e0f5c
+#include "xorg-version.h"
c3e0f5c
 
c3e0f5c
 namespace rfb {
c3e0f5c
   class VNCServerST;
5feba83
@@ -69,10 +70,16 @@ public:
c3e0f5c
                  const unsigned char *rgbaData);
c3e0f5c
   void add_changed(const rfb::Region &region);
c3e0f5c
   void add_copied(const rfb::Region &dest, const rfb::Point &delta);
c3e0f5c
+#if XORG >= 119
c3e0f5c
+  void handleListenFd(int fd);
c3e0f5c
+  void handleSocketFd(int fd, int xevents);
c3e0f5c
+  void blockHandler(int* timeout);
c3e0f5c
+#else
c3e0f5c
   void readBlockHandler(fd_set* fds, struct timeval ** timeout);
c3e0f5c
   void readWakeupHandler(fd_set* fds, int nfds);
c3e0f5c
   void writeBlockHandler(fd_set* fds, struct timeval ** timeout);
c3e0f5c
   void writeWakeupHandler(fd_set* fds, int nfds);
c3e0f5c
+#endif
c3e0f5c
   void addClient(network::Socket* sock, bool reverse);
c3e0f5c
   void disconnectClients();
c3e0f5c