1 diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/vncBlockHandler.c.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/vncBlockHandler.c
2 --- tigervnc-1.7.0/unix/xserver/hw/vnc/vncBlockHandler.c.xserver119 2016-09-08 12:31:18.000000000 +0200
3 +++ tigervnc-1.7.0/unix/xserver/hw/vnc/vncBlockHandler.c 2016-10-04 17:17:35.618889747 +0200
6 #include "vncExtInit.h"
7 #include "vncBlockHandler.h"
8 +#include "xorg-version.h"
12 +static void vncBlockHandler(void* data, void* timeout)
14 + vncCallBlockHandlers(timeout);
17 +void vncRegisterBlockHandlers(void)
19 + if (!RegisterBlockAndWakeupHandlers(vncBlockHandler,
20 + (ServerWakeupHandlerProcPtr)NoopDDA, 0))
21 + FatalError("RegisterBlockAndWakeupHandlers() failed\n");
26 static void vncBlockHandler(void * data, OSTimePtr t, void * readmask);
27 static void vncWakeupHandler(void * data, int nfds, void * readmask);
28 @@ -144,3 +161,5 @@ static void vncWriteWakeupHandlerFallbac
30 vncWriteWakeupHandler(ret, &fallbackFds);
34 diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.cc.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.cc
35 --- tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.cc.xserver119 2016-09-08 12:31:18.000000000 +0200
36 +++ tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.cc 2016-10-04 17:17:35.618889747 +0200
37 @@ -241,6 +241,17 @@ int vncExtensionIsActive(int scrIdx)
38 return (desktop[scrIdx] != NULL);
43 +void vncCallBlockHandlers(int* timeout)
45 + for (int scr = 0; scr < vncGetScreenCount(); scr++)
47 + desktop[scr]->blockHandler(timeout);
52 void vncCallReadBlockHandlers(fd_set * fds, struct timeval ** timeout)
54 for (int scr = 0; scr < vncGetScreenCount(); scr++)
55 @@ -269,6 +280,8 @@ void vncCallWriteWakeupHandlers(fd_set *
56 desktop[scr]->writeWakeupHandler(fds, nfds);
61 int vncGetAvoidShiftNumLock(void)
63 return (bool)avoidShiftNumLock;
64 diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.h.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.h
65 --- tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.h.xserver119 2016-09-08 12:31:18.000000000 +0200
66 +++ tigervnc-1.7.0/unix/xserver/hw/vnc/vncExtInit.h 2016-10-04 17:17:35.618889747 +0200
70 #include <sys/select.h>
71 +#include "xorg-version.h"
75 @@ -52,10 +53,14 @@ extern int vncInetdSock;
76 void vncExtensionInit(void);
77 int vncExtensionIsActive(int scrIdx);
80 +void vncCallBlockHandlers(int* timeout);
82 void vncCallReadBlockHandlers(fd_set * fds, struct timeval ** timeout);
83 void vncCallReadWakeupHandlers(fd_set * fds, int nfds);
84 void vncCallWriteBlockHandlers(fd_set * fds, struct timeval ** timeout);
85 void vncCallWriteWakeupHandlers(fd_set * fds, int nfds);
88 int vncGetAvoidShiftNumLock(void);
90 diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/vncHooks.c.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/vncHooks.c
91 --- tigervnc-1.7.0/unix/xserver/hw/vnc/vncHooks.c.xserver119 2016-09-08 12:31:18.000000000 +0200
92 +++ tigervnc-1.7.0/unix/xserver/hw/vnc/vncHooks.c 2016-10-04 17:17:35.618889747 +0200
93 @@ -128,9 +128,11 @@ static Bool vncHooksDisplayCursor(Device
95 static void vncHooksBlockHandler(int i, pointer blockData, pointer pTimeout,
99 static void vncHooksBlockHandler(ScreenPtr pScreen, void * pTimeout,
102 +static void vncHooksBlockHandler(ScreenPtr pScreen, void * pTimeout);
105 static void vncHooksComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
106 @@ -716,9 +718,11 @@ out:
108 static void vncHooksBlockHandler(int i, pointer blockData, pointer pTimeout,
112 static void vncHooksBlockHandler(ScreenPtr pScreen_, void * pTimeout,
115 +static void vncHooksBlockHandler(ScreenPtr pScreen_, void * pTimeout)
119 @@ -731,8 +735,10 @@ static void vncHooksBlockHandler(ScreenP
122 (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
125 (*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask);
127 + (*pScreen->BlockHandler) (pScreen, pTimeout);
130 vncHooksScreen->ignoreHooks--;
131 @@ -1033,12 +1039,21 @@ static void vncHooksCopyClip(GCPtr dst,
133 // Unwrap and rewrap helpers
136 +#define GC_OP_PROLOGUE(pGC, name)\
137 + vncHooksGCPtr pGCPriv = vncHooksGCPrivate(pGC);\
138 + const GCFuncs *oldFuncs = pGC->funcs;\
139 + pGC->funcs = pGCPriv->wrappedFuncs;\
140 + pGC->ops = pGCPriv->wrappedOps; \
141 + DBGPRINT((stderr,"vncHooks" #name " called\n"))
143 #define GC_OP_PROLOGUE(pGC, name)\
144 vncHooksGCPtr pGCPriv = vncHooksGCPrivate(pGC);\
145 GCFuncs *oldFuncs = pGC->funcs;\
146 pGC->funcs = pGCPriv->wrappedFuncs;\
147 pGC->ops = pGCPriv->wrappedOps; \
148 DBGPRINT((stderr,"vncHooks" #name " called\n"))
151 #define GC_OP_EPILOGUE(pGC)\
152 pGCPriv->wrappedOps = pGC->ops;\
153 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
154 --- tigervnc-1.7.0/unix/xserver/hw/vnc/xorg-version.h.xserver119 2016-09-08 12:31:18.000000000 +0200
155 +++ tigervnc-1.7.0/unix/xserver/hw/vnc/xorg-version.h 2016-10-04 17:24:51.640654527 +0200
158 #elif XORG_VERSION_CURRENT < ((1 * 10000000) + (18 * 100000) + (99 * 1000))
160 +#elif XORG_VERSION_CURRENT < ((1 * 10000000) + (19 * 100000) + (99 * 1000))
163 -#error "X.Org newer than 1.18 is not supported"
164 +#error "X.Org newer than 1.19 is not supported"
168 diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.cc.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.cc
169 --- tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.cc.xserver119 2016-09-08 12:31:18.000000000 +0200
170 +++ tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.cc 2016-10-04 17:23:47.171977905 +0200
171 @@ -89,6 +89,30 @@ public:
172 XserverDesktop* desktop;
178 + * xserver NotifyFd callbacks. Note we also expect write notifies to work,
179 + * which only works with xserver >= 1.19.
183 +static void HandleListenFd(int fd, int xevents, void *data)
185 + XserverDesktop *desktop = (XserverDesktop *)data;
187 + desktop->handleListenFd(fd);
190 +static void HandleSocketFd(int fd, int xevents, void *data)
192 + XserverDesktop *desktop = (XserverDesktop *)data;
194 + desktop->handleSocketFd(fd, xevents);
200 XserverDesktop::XserverDesktop(int screenIndex_,
201 std::list<network::TcpListener*> listeners_,
202 @@ -110,15 +134,35 @@ XserverDesktop::XserverDesktop(int scree
204 if (!httpListeners.empty ())
205 httpServer = new FileHTTPServer(this);
208 + for (std::list<TcpListener*>::iterator i = listeners.begin();
209 + i != listeners.end();
211 + SetNotifyFd((*i)->getFd(), HandleListenFd, X_NOTIFY_READ, this);
214 + for (std::list<TcpListener*>::iterator i = httpListeners.begin();
215 + i != httpListeners.end();
217 + SetNotifyFd((*i)->getFd(), HandleListenFd, X_NOTIFY_READ, this);
222 XserverDesktop::~XserverDesktop()
224 while (!listeners.empty()) {
226 + RemoveNotifyFd(listeners.back()->getFd());
228 delete listeners.back();
229 listeners.pop_back();
231 while (!httpListeners.empty()) {
233 + RemoveNotifyFd(listeners.back()->getFd());
235 delete httpListeners.back();
236 httpListeners.pop_back();
238 @@ -388,6 +432,140 @@ void XserverDesktop::add_copied(const rf
243 +void XserverDesktop::handleListenFd(int fd)
245 + std::list<TcpListener*>::iterator i;
246 + SocketServer *fd_server = NULL;
247 + bool is_http = false;
249 + for (i = listeners.begin(); i != listeners.end(); i++) {
250 + if ((*i)->getFd() == fd) {
251 + fd_server = server;
255 + if (httpServer && !fd_server) {
256 + for (i = httpListeners.begin(); i != httpListeners.end(); i++) {
257 + if ((*i)->getFd() == fd) {
258 + fd_server = httpServer;
265 + vlog.error("XserverDesktop::handleListenFd: Error cannot find fd");
269 + Socket* sock = (*i)->accept();
270 + sock->outStream().setBlocking(false);
271 + vlog.debug("new %sclient, sock %d", is_http ? "http " : "", sock->getFd());
272 + fd_server->addSocket(sock);
273 + SetNotifyFd(sock->getFd(), HandleSocketFd, X_NOTIFY_READ, this);
276 +void XserverDesktop::handleSocketFd(int fd, int xevents)
278 + std::list<Socket*> sockets;
279 + std::list<Socket*>::iterator i;
280 + SocketServer *fd_server = NULL;
281 + bool is_http = false;
283 + server->getSockets(&sockets);
284 + for (i = sockets.begin(); i != sockets.end(); i++) {
285 + if ((*i)->getFd() == fd) {
286 + fd_server = server;
290 + if (httpServer && !fd_server) {
291 + httpServer->getSockets(&sockets);
292 + for (i = sockets.begin(); i != sockets.end(); i++) {
293 + if ((*i)->getFd() == fd) {
294 + fd_server = httpServer;
301 + vlog.error("XserverDesktop::handleSocketFd: Error cannot find fd");
305 + if (xevents & X_NOTIFY_READ)
306 + fd_server->processSocketReadEvent(*i);
308 + if (xevents & X_NOTIFY_WRITE)
309 + fd_server->processSocketWriteEvent(*i);
311 + if ((*i)->isShutdown()) {
312 + vlog.debug("%sclient gone, sock %d", is_http ? "http " : "", fd);
313 + RemoveNotifyFd(fd);
314 + fd_server->removeSocket(*i);
321 +void XserverDesktop::blockHandler(int* timeout)
323 + // We don't have a good callback for when we can init input devices[1],
324 + // so we abuse the fact that this routine will be called first thing
325 + // once the dix is done initialising.
326 + // [1] Technically Xvnc has InitInput(), but libvnc.so has nothing.
327 + vncInitInputDevice();
330 + std::list<Socket*> sockets;
331 + std::list<Socket*>::iterator i;
332 + server->getSockets(&sockets);
333 + for (i = sockets.begin(); i != sockets.end(); i++) {
334 + int fd = (*i)->getFd();
335 + if ((*i)->isShutdown()) {
336 + vlog.debug("client gone, sock %d",fd);
337 + server->removeSocket(*i);
341 + /* Update existing NotifyFD to listen for write (or not) */
342 + if ((*i)->outStream().bufferUsage() > 0)
343 + SetNotifyFd(fd, HandleSocketFd, X_NOTIFY_READ | X_NOTIFY_WRITE, this);
345 + SetNotifyFd(fd, HandleSocketFd, X_NOTIFY_READ, this);
349 + httpServer->getSockets(&sockets);
350 + for (i = sockets.begin(); i != sockets.end(); i++) {
351 + int fd = (*i)->getFd();
352 + if ((*i)->isShutdown()) {
353 + vlog.debug("http client gone, sock %d",fd);
354 + httpServer->removeSocket(*i);
357 + /* Update existing NotifyFD to listen for write (or not) */
358 + if ((*i)->outStream().bufferUsage() > 0)
359 + SetNotifyFd(fd, HandleSocketFd, X_NOTIFY_READ | X_NOTIFY_WRITE, this);
361 + SetNotifyFd(fd, HandleSocketFd, X_NOTIFY_READ, this);
366 + int nextTimeout = server->checkTimeouts();
367 + if (nextTimeout > 0 && (*timeout == -1 || nextTimeout < *timeout))
368 + *timeout = nextTimeout;
369 + } catch (rdr::Exception& e) {
370 + vlog.error("XserverDesktop::blockHandler: %s",e.str());
376 void XserverDesktop::readBlockHandler(fd_set* fds, struct timeval ** timeout)
378 // We don't have a good callback for when we can init input devices[1],
379 @@ -600,10 +778,15 @@ void XserverDesktop::writeWakeupHandler(
385 void XserverDesktop::addClient(Socket* sock, bool reverse)
387 vlog.debug("new client, sock %d reverse %d",sock->getFd(),reverse);
388 server->addSocket(sock, reverse);
390 + SetNotifyFd(sock->getFd(), HandleSocketFd, X_NOTIFY_READ, this);
394 void XserverDesktop::disconnectClients()
395 diff -up tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.h.xserver119 tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.h
396 --- tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.h.xserver119 2016-09-08 12:31:18.000000000 +0200
397 +++ tigervnc-1.7.0/unix/xserver/hw/vnc/XserverDesktop.h 2016-10-04 17:17:35.617889712 +0200
399 #include <rfb/VNCServerST.h>
400 #include <rdr/SubstitutingInStream.h>
402 +#include "xorg-version.h"
406 @@ -69,10 +70,16 @@ public:
407 const unsigned char *rgbaData);
408 void add_changed(const rfb::Region ®ion);
409 void add_copied(const rfb::Region &dest, const rfb::Point &delta);
411 + void handleListenFd(int fd);
412 + void handleSocketFd(int fd, int xevents);
413 + void blockHandler(int* timeout);
415 void readBlockHandler(fd_set* fds, struct timeval ** timeout);
416 void readWakeupHandler(fd_set* fds, int nfds);
417 void writeBlockHandler(fd_set* fds, struct timeval ** timeout);
418 void writeWakeupHandler(fd_set* fds, int nfds);
420 void addClient(network::Socket* sock, bool reverse);
421 void disconnectClients();