]> source.dussan.org Git - tigervnc.git/commitdiff
Add xorg-xserver 1.19 support
authorHans de Goede <hdegoede@redhat.com>
Wed, 5 Oct 2016 09:15:27 +0000 (11:15 +0200)
committerPierre Ossman <ossman@cendio.se>
Wed, 5 Oct 2016 09:15:27 +0000 (11:15 +0200)
unix/xserver/hw/vnc/XserverDesktop.cc
unix/xserver/hw/vnc/XserverDesktop.h
unix/xserver/hw/vnc/vncBlockHandler.c
unix/xserver/hw/vnc/vncExtInit.cc
unix/xserver/hw/vnc/vncExtInit.h
unix/xserver/hw/vnc/vncHooks.c
unix/xserver/hw/vnc/xorg-version.h
unix/xserver119.patch [new file with mode: 0644]

index 4f82a54425089725b0476282e2dd5d4840cd926a..8cc0b0b7f0a28f39ae1573e5dd46fd9a69a8513e 100644 (file)
@@ -90,6 +90,30 @@ public:
   XserverDesktop* desktop;
 };
 
+#if XORG >= 119
+extern "C" {
+/*
+ * xserver NotifyFd callbacks. Note we also expect write notifies to work,
+ * which only works with xserver >= 1.19.
+ */
+#include "os.h"
+
+static void HandleListenFd(int fd, int xevents, void *data)
+{
+  XserverDesktop *desktop = (XserverDesktop *)data;
+
+  desktop->handleListenFd(fd);
+}
+
+static void HandleSocketFd(int fd, int xevents, void *data)
+{
+  XserverDesktop *desktop = (XserverDesktop *)data;
+
+  desktop->handleSocketFd(fd, xevents);
+}
+
+}
+#endif
 
 XserverDesktop::XserverDesktop(int screenIndex_,
                                std::list<network::TcpListener*> listeners_,
@@ -111,15 +135,35 @@ XserverDesktop::XserverDesktop(int screenIndex_,
 
   if (!httpListeners.empty ())
     httpServer = new FileHTTPServer(this);
+
+#if XORG >= 119
+  for (std::list<TcpListener*>::iterator i = listeners.begin();
+       i != listeners.end();
+       i++) {
+    SetNotifyFd((*i)->getFd(), HandleListenFd, X_NOTIFY_READ, this);
+  }
+
+  for (std::list<TcpListener*>::iterator i = httpListeners.begin();
+       i != httpListeners.end();
+       i++) {
+    SetNotifyFd((*i)->getFd(), HandleListenFd, X_NOTIFY_READ, this);
+  }
+#endif
 }
 
 XserverDesktop::~XserverDesktop()
 {
   while (!listeners.empty()) {
+#if XORG >= 119
+    RemoveNotifyFd(listeners.back()->getFd());
+#endif
     delete listeners.back();
     listeners.pop_back();
   }
   while (!httpListeners.empty()) {
+#if XORG >= 119
+    RemoveNotifyFd(listeners.back()->getFd());
+#endif
     delete httpListeners.back();
     httpListeners.pop_back();
   }
@@ -389,6 +433,140 @@ void XserverDesktop::add_copied(const rfb::Region &dest, const rfb::Point &delta
   }
 }
 
+#if XORG >= 119
+void XserverDesktop::handleListenFd(int fd)
+{
+  std::list<TcpListener*>::iterator i;
+  SocketServer *fd_server = NULL;
+  bool is_http = false;
+
+  for (i = listeners.begin(); i != listeners.end(); i++) {
+    if ((*i)->getFd() == fd) {
+      fd_server = server;
+      break;
+    }
+  }
+  if (httpServer && !fd_server) {
+    for (i = httpListeners.begin(); i != httpListeners.end(); i++) {
+      if ((*i)->getFd() == fd) {
+        fd_server = httpServer;
+        is_http = true;
+        break;
+      }
+    }
+  }
+  if (!fd_server) {
+    vlog.error("XserverDesktop::handleListenFd: Error cannot find fd");
+    return;
+  }
+
+  Socket* sock = (*i)->accept();
+  sock->outStream().setBlocking(false);
+  vlog.debug("new %sclient, sock %d", is_http ? "http " : "", sock->getFd());
+  fd_server->addSocket(sock);
+  SetNotifyFd(sock->getFd(), HandleSocketFd, X_NOTIFY_READ, this);
+}
+
+void XserverDesktop::handleSocketFd(int fd, int xevents)
+{
+  std::list<Socket*> sockets;
+  std::list<Socket*>::iterator i;
+  SocketServer *fd_server = NULL;
+  bool is_http = false;
+
+  server->getSockets(&sockets);
+  for (i = sockets.begin(); i != sockets.end(); i++) {
+    if ((*i)->getFd() == fd) {
+      fd_server = server;
+      break;
+    }
+  }
+  if (httpServer && !fd_server) {
+    httpServer->getSockets(&sockets);
+    for (i = sockets.begin(); i != sockets.end(); i++) {
+      if ((*i)->getFd() == fd) {
+        fd_server = httpServer;
+        is_http = true;
+        break;
+      }
+    }
+  }
+  if (!fd_server) {
+    vlog.error("XserverDesktop::handleSocketFd: Error cannot find fd");
+    return;
+  }
+
+  if (xevents & X_NOTIFY_READ)
+    fd_server->processSocketReadEvent(*i);
+
+  if (xevents & X_NOTIFY_WRITE)
+    fd_server->processSocketWriteEvent(*i);
+
+  if ((*i)->isShutdown()) {
+    vlog.debug("%sclient gone, sock %d", is_http ? "http " : "", fd);
+    RemoveNotifyFd(fd);
+    fd_server->removeSocket(*i);
+    if (!is_http)
+      vncClientGone(fd);
+    delete (*i);
+  }
+}
+
+void XserverDesktop::blockHandler(int* timeout)
+{
+  // We don't have a good callback for when we can init input devices[1],
+  // so we abuse the fact that this routine will be called first thing
+  // once the dix is done initialising.
+  // [1] Technically Xvnc has InitInput(), but libvnc.so has nothing.
+  vncInitInputDevice();
+
+  try {
+    std::list<Socket*> sockets;
+    std::list<Socket*>::iterator i;
+    server->getSockets(&sockets);
+    for (i = sockets.begin(); i != sockets.end(); i++) {
+      int fd = (*i)->getFd();
+      if ((*i)->isShutdown()) {
+        vlog.debug("client gone, sock %d",fd);
+        server->removeSocket(*i);
+        vncClientGone(fd);
+        delete (*i);
+      } else {
+        /* Update existing NotifyFD to listen for write (or not) */
+        if ((*i)->outStream().bufferUsage() > 0)
+          SetNotifyFd(fd, HandleSocketFd, X_NOTIFY_READ | X_NOTIFY_WRITE, this);
+        else
+          SetNotifyFd(fd, HandleSocketFd, X_NOTIFY_READ, this);
+      }
+    }
+    if (httpServer) {
+      httpServer->getSockets(&sockets);
+      for (i = sockets.begin(); i != sockets.end(); i++) {
+        int fd = (*i)->getFd();
+        if ((*i)->isShutdown()) {
+          vlog.debug("http client gone, sock %d",fd);
+          httpServer->removeSocket(*i);
+          delete (*i);
+        } else {
+          /* Update existing NotifyFD to listen for write (or not) */
+          if ((*i)->outStream().bufferUsage() > 0)
+            SetNotifyFd(fd, HandleSocketFd, X_NOTIFY_READ | X_NOTIFY_WRITE, this);
+          else
+            SetNotifyFd(fd, HandleSocketFd, X_NOTIFY_READ, this);
+        }
+      }
+    }
+
+    int nextTimeout = server->checkTimeouts();
+    if (nextTimeout > 0 && (*timeout == -1 || nextTimeout < *timeout))
+      *timeout = nextTimeout;
+  } catch (rdr::Exception& e) {
+    vlog.error("XserverDesktop::blockHandler: %s",e.str());
+  }
+}
+
+#else
+
 void XserverDesktop::readBlockHandler(fd_set* fds, struct timeval ** timeout)
 {
   // We don't have a good callback for when we can init input devices[1],
@@ -603,10 +781,15 @@ void XserverDesktop::writeWakeupHandler(fd_set* fds, int nfds)
   }
 }
 
+#endif
+
 void XserverDesktop::addClient(Socket* sock, bool reverse)
 {
   vlog.debug("new client, sock %d reverse %d",sock->getFd(),reverse);
   server->addSocket(sock, reverse);
+#if XORG >= 119
+  SetNotifyFd(sock->getFd(), HandleSocketFd, X_NOTIFY_READ, this);
+#endif
 }
 
 void XserverDesktop::disconnectClients()
index c0690286c30b8c0ecf63c6bd1006c808e89bf824..9e776274ebfb4be973c9a96916080278d376be89 100644 (file)
@@ -38,6 +38,7 @@
 #include <rfb/VNCServerST.h>
 #include <rdr/SubstitutingInStream.h>
 #include "Input.h"
+#include "xorg-version.h"
 
 namespace rfb {
   class VNCServerST;
@@ -69,10 +70,16 @@ public:
                  const unsigned char *rgbaData);
   void add_changed(const rfb::Region &region);
   void add_copied(const rfb::Region &dest, const rfb::Point &delta);
+#if XORG >= 119
+  void handleListenFd(int fd);
+  void handleSocketFd(int fd, int xevents);
+  void blockHandler(int* timeout);
+#else
   void readBlockHandler(fd_set* fds, struct timeval ** timeout);
   void readWakeupHandler(fd_set* fds, int nfds);
   void writeBlockHandler(fd_set* fds, struct timeval ** timeout);
   void writeWakeupHandler(fd_set* fds, int nfds);
+#endif
   void addClient(network::Socket* sock, bool reverse);
   void disconnectClients();
 
index 4e444783a493307211f5c267d7d44eb7004847e7..baebc3df29712446242673d0ab5ae81e02361c17 100644 (file)
 
 #include "vncExtInit.h"
 #include "vncBlockHandler.h"
+#include "xorg-version.h"
+
+#if XORG >= 119
+
+static void vncBlockHandler(void* data, void* timeout)
+{
+  vncCallBlockHandlers(timeout);
+}
+
+void vncRegisterBlockHandlers(void)
+{
+  if (!RegisterBlockAndWakeupHandlers(vncBlockHandler,
+                                      (ServerWakeupHandlerProcPtr)NoopDDA, 0))
+    FatalError("RegisterBlockAndWakeupHandlers() failed\n");
+}
+
+#else
 
 static void vncBlockHandler(void * data, OSTimePtr t, void * readmask);
 static void vncWakeupHandler(void * data, int nfds, void * readmask);
@@ -144,3 +161,5 @@ static void vncWriteWakeupHandlerFallback(void)
 
   vncWriteWakeupHandler(ret, &fallbackFds);
 }
+
+#endif
index dea3cb8bd054f266be465a3ab912ec8f1343ba57..9d70e44b647047faeb3c287de0f2bbd9edc38b26 100644 (file)
@@ -249,6 +249,17 @@ int vncExtensionIsActive(int scrIdx)
   return (desktop[scrIdx] != NULL);
 }
 
+#if XORG >= 119
+
+void vncCallBlockHandlers(int* timeout)
+{
+  for (int scr = 0; scr < vncGetScreenCount(); scr++)
+    if (desktop[scr])
+      desktop[scr]->blockHandler(timeout);
+}
+
+#else
+
 void vncCallReadBlockHandlers(fd_set * fds, struct timeval ** timeout)
 {
   for (int scr = 0; scr < vncGetScreenCount(); scr++)
@@ -277,6 +288,8 @@ void vncCallWriteWakeupHandlers(fd_set * fds, int nfds)
       desktop[scr]->writeWakeupHandler(fds, nfds);
 }
 
+#endif
+
 int vncGetAvoidShiftNumLock(void)
 {
   return (bool)avoidShiftNumLock;
index 9785d1126a191c61564e145c2ac1e5d826ca4612..316452810f37949a56384b8575cc3e9dc2caf94a 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdint.h>
 #include <stddef.h>
 #include <sys/select.h>
+#include "xorg-version.h"
 
 // Only from C++
 #ifdef __cplusplus
@@ -50,10 +51,14 @@ extern int vncInetdSock;
 void vncExtensionInit(void);
 int vncExtensionIsActive(int scrIdx);
 
+#if XORG >= 119
+void vncCallBlockHandlers(int* timeout);
+#else
 void vncCallReadBlockHandlers(fd_set * fds, struct timeval ** timeout);
 void vncCallReadWakeupHandlers(fd_set * fds, int nfds);
 void vncCallWriteBlockHandlers(fd_set * fds, struct timeval ** timeout);
 void vncCallWriteWakeupHandlers(fd_set * fds, int nfds);
+#endif
 
 int vncGetAvoidShiftNumLock(void);
 
index 22ea9ea87b5c667aeda966f39349995041d665f8..29f3f8b86cac7461f4374d441b61a45207b68c0d 100644 (file)
@@ -128,9 +128,11 @@ static Bool vncHooksDisplayCursor(DeviceIntPtr pDev,
 #if XORG <= 112
 static void vncHooksBlockHandler(int i, pointer blockData, pointer pTimeout,
                                  pointer pReadmask);
-#else
+#elif XORG <= 118
 static void vncHooksBlockHandler(ScreenPtr pScreen, void * pTimeout,
                                  void * pReadmask);
+#else
+static void vncHooksBlockHandler(ScreenPtr pScreen, void * pTimeout);
 #endif
 #ifdef RENDER
 static void vncHooksComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, 
@@ -716,9 +718,11 @@ out:
 #if XORG <= 112
 static void vncHooksBlockHandler(int i, pointer blockData, pointer pTimeout,
                                  pointer pReadmask)
-#else
+#elif XORG <= 118
 static void vncHooksBlockHandler(ScreenPtr pScreen_, void * pTimeout,
                                  void * pReadmask)
+#else
+static void vncHooksBlockHandler(ScreenPtr pScreen_, void * pTimeout)
 #endif
 {
 #if XORG <= 112
@@ -731,8 +735,10 @@ static void vncHooksBlockHandler(ScreenPtr pScreen_, void * pTimeout,
 
 #if XORG <= 112
   (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
-#else
+#elif XORG <= 118
   (*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask);
+#else
+  (*pScreen->BlockHandler) (pScreen, pTimeout);
 #endif
 
   vncHooksScreen->ignoreHooks--;
@@ -1033,12 +1039,21 @@ static void vncHooksCopyClip(GCPtr dst, GCPtr src) {
 
 // Unwrap and rewrap helpers
 
+#if XORG >= 116
+#define GC_OP_PROLOGUE(pGC, name)\
+    vncHooksGCPtr pGCPriv = vncHooksGCPrivate(pGC);\
+    const GCFuncs *oldFuncs = pGC->funcs;\
+    pGC->funcs = pGCPriv->wrappedFuncs;\
+    pGC->ops = pGCPriv->wrappedOps; \
+    DBGPRINT((stderr,"vncHooks" #name " called\n"))
+#else
 #define GC_OP_PROLOGUE(pGC, name)\
     vncHooksGCPtr pGCPriv = vncHooksGCPrivate(pGC);\
     GCFuncs *oldFuncs = pGC->funcs;\
     pGC->funcs = pGCPriv->wrappedFuncs;\
     pGC->ops = pGCPriv->wrappedOps; \
     DBGPRINT((stderr,"vncHooks" #name " called\n"))
+#endif
 
 #define GC_OP_EPILOGUE(pGC)\
     pGCPriv->wrappedOps = pGC->ops;\
index 60610cbd69387e7d3952c817f436d3825125d049..9d1c0eb8021586c92b934dae987d68d6941a95bf 100644 (file)
 #define XORG 117
 #elif XORG_VERSION_CURRENT < ((1 * 10000000) + (18 * 100000) + (99 * 1000))
 #define XORG 118
+#elif XORG_VERSION_CURRENT < ((1 * 10000000) + (19 * 100000) + (99 * 1000))
+#define XORG 119
 #else
-#error "X.Org newer than 1.18 is not supported"
+#error "X.Org newer than 1.19 is not supported"
 #endif
 
 #endif
diff --git a/unix/xserver119.patch b/unix/xserver119.patch
new file mode 100644 (file)
index 0000000..614f104
--- /dev/null
@@ -0,0 +1,95 @@
+diff -up xserver/configure.ac.xserver116-rebased xserver/configure.ac
+--- xserver/configure.ac.xserver116-rebased    2016-09-29 13:14:45.595441590 +0200
++++ xserver/configure.ac       2016-09-29 13:14:45.631442006 +0200
+@@ -74,6 +74,7 @@ dnl forcing an entire recompile.x
+ AC_CONFIG_HEADERS(include/version-config.h)
+ AM_PROG_AS
++AC_PROG_CXX
+ AC_PROG_LN_S
+ LT_PREREQ([2.2])
+ LT_INIT([disable-static win32-dll])
+@@ -1863,6 +1864,10 @@ if test "x$XVFB" = xyes; then
+       AC_SUBST([XVFB_SYS_LIBS])
+ fi
++dnl Xvnc DDX
++AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XSERVER_CFLAGS"])
++AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $PRESENT_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB"])
++AC_SUBST([XVNC_SYS_LIBS], ["$GLX_SYS_LIBS"])
+ dnl Xnest DDX
+@@ -1898,6 +1903,8 @@ if test "x$XORG" = xauto; then
+ fi
+ AC_MSG_RESULT([$XORG])
++AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
++
+ if test "x$XORG" = xyes; then
+       XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common'
+       XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
+@@ -2116,7 +2123,6 @@ if test "x$XORG" = xyes; then
+       AC_DEFINE(XORG_SERVER, 1, [Building Xorg server])
+       AC_DEFINE(XORGSERVER, 1, [Building Xorg server])
+       AC_DEFINE(XFree86Server, 1, [Building XFree86 server])
+-      AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
+       AC_DEFINE(NEED_XF86_TYPES, 1, [Need XFree86 typedefs])
+       AC_DEFINE(NEED_XF86_PROTOTYPES, 1, [Need XFree86 helper functions])
+       AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
+@@ -2691,6 +2697,7 @@ hw/dmx/Makefile
+ hw/dmx/man/Makefile
+ hw/vfb/Makefile
+ hw/vfb/man/Makefile
++hw/vnc/Makefile
+ hw/xnest/Makefile
+ hw/xnest/man/Makefile
+ hw/xwin/Makefile
+diff -up xserver/hw/Makefile.am.xserver116-rebased xserver/hw/Makefile.am
+--- xserver/hw/Makefile.am.xserver116-rebased  2016-09-29 13:14:45.601441659 +0200
++++ xserver/hw/Makefile.am     2016-09-29 13:14:45.631442006 +0200
+@@ -38,7 +38,8 @@ SUBDIRS =                    \
+       $(DMX_SUBDIRS)          \
+       $(KDRIVE_SUBDIRS)       \
+       $(XQUARTZ_SUBDIRS)      \
+-      $(XWAYLAND_SUBDIRS)
++      $(XWAYLAND_SUBDIRS)     \
++      vnc
+ DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive xwayland
+diff -up xserver/mi/miinitext.c.xserver116-rebased xserver/mi/miinitext.c
+--- xserver/mi/miinitext.c.xserver116-rebased  2016-09-29 13:14:45.618441855 +0200
++++ xserver/mi/miinitext.c     2016-09-29 13:14:45.631442006 +0200
+@@ -114,6 +114,10 @@ SOFTWARE.
+ #include "micmap.h"
+ #include "globals.h"
++#ifdef TIGERVNC
++extern void vncExtensionInit(INITARGS);
++#endif
++
+ /* The following is only a small first step towards run-time
+  * configurable extensions.
+  */
+@@ -238,6 +242,9 @@ EnableDisableExtensionError(const char *
+ /* List of built-in (statically linked) extensions */
+ static const ExtensionModule staticExtensions[] = {
++#ifdef TIGERVNC
++    {vncExtensionInit, "VNC-EXTENSION", NULL},
++#endif
+     {GEExtensionInit, "Generic Event Extension", &noGEExtension},
+     {ShapeExtensionInit, "SHAPE", NULL},
+ #ifdef MITSHM
+--- xserver/include/os.h~      2016-10-03 09:07:29.000000000 +0200
++++ xserver/include/os.h       2016-10-03 14:13:00.013654506 +0200
+@@ -621,7 +621,7 @@
+ extern _X_EXPORT void
+ LogClose(enum ExitCode error);
+ extern _X_EXPORT Bool
+-LogSetParameter(LogParameter param, int value);
++LogSetParameter(enum _LogParameter param, int value);
+ extern _X_EXPORT void
+ LogVWrite(int verb, const char *f, va_list args)
+ _X_ATTRIBUTE_PRINTF(2, 0);