From a7b728a8230a18f515509a17d1cb11566f07c9f8 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 13 Jun 2014 10:56:59 +0000 Subject: [PATCH] Add XDAMAGE support to x0vncserver. Makes it more efficient and more responsive to changes. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@5185 3789f03b-4d11-0410-bbf8-ca57d06f2519 --- unix/x0vncserver/CMakeLists.txt | 8 ++++ unix/x0vncserver/x0vncserver.cxx | 72 +++++++++++++++++++++++++------- 2 files changed, 65 insertions(+), 15 deletions(-) diff --git a/unix/x0vncserver/CMakeLists.txt b/unix/x0vncserver/CMakeLists.txt index 3f41db7d..64c9e779 100644 --- a/unix/x0vncserver/CMakeLists.txt +++ b/unix/x0vncserver/CMakeLists.txt @@ -16,6 +16,7 @@ add_executable(x0vncserver ) target_link_libraries(x0vncserver tx rfb network rdr ${X11_LIBRARIES}) + if(X11_FOUND AND X11_XTest_LIB) add_definitions(-DHAVE_XTEST) target_link_libraries(x0vncserver ${X11_XTest_LIB}) @@ -23,5 +24,12 @@ else() message(WARNING "No XTest extension. x0vncserver will be view-only.") endif() +if(X11_FOUND AND X11_Xdamage_LIB) + add_definitions(-DHAVE_XDAMAGE) + target_link_libraries(x0vncserver ${X11_Xdamage_LIB}) +else() + message(WARNING "No DAMAGE extension. x0vncserver will have to use the slower polling method.") +endif() + install(TARGETS x0vncserver DESTINATION ${BIN_DIR}) install(FILES x0vncserver.man DESTINATION ${MAN_DIR}/man1 RENAME x0vncserver.1) diff --git a/unix/x0vncserver/x0vncserver.cxx b/unix/x0vncserver/x0vncserver.cxx index b5498e18..f2067fba 100644 --- a/unix/x0vncserver/x0vncserver.cxx +++ b/unix/x0vncserver/x0vncserver.cxx @@ -42,6 +42,9 @@ #ifdef HAVE_XTEST #include #endif +#ifdef HAVE_XDAMAGE +#include +#endif #include #include @@ -132,12 +135,13 @@ private: }; -class XDesktop : public SDesktop, public ColourMap +class XDesktop : public SDesktop, public ColourMap, public TXGlobalEventHandler { public: XDesktop(Display* dpy_, Geometry *geometry_) : dpy(dpy_), geometry(geometry_), pb(0), server(0), - oldButtonMask(0), haveXtest(false), maxButtons(0), running(false) + oldButtonMask(0), haveXtest(false), haveDamage(false), + maxButtons(0), running(false) { #ifdef HAVE_XTEST int xtestEventBase; @@ -157,13 +161,26 @@ public: } #endif +#ifdef HAVE_XDAMAGE + int xdamageErrorBase; + + if (XDamageQueryExtension(dpy, &xdamageEventBase, &xdamageErrorBase)) { + TXWindow::setGlobalEventHandler(this); + haveDamage = true; + } else { +#endif + vlog.info("DAMAGE extension not present"); + vlog.info("Will have to poll screen for changes"); +#ifdef HAVE_XDAMAGE + } +#endif } virtual ~XDesktop() { stop(); } inline void poll() { - if (pb) + if (pb and not haveDamage) pb->poll(server); } @@ -188,12 +205,24 @@ public: server = (VNCServerST *)vs; server->setPixelBuffer(pb); +#ifdef HAVE_XDAMAGE + if (haveDamage) { + damage = XDamageCreate(dpy, DefaultRootWindow(dpy), + XDamageReportRawRectangles); + } +#endif + running = true; } virtual void stop() { running = false; +#ifdef HAVE_XDAMAGE + if (haveDamage) + XDamageDestroy(dpy, damage); +#endif + delete pb; pb = 0; } @@ -240,18 +269,25 @@ public: return Point(pb->width(), pb->height()); } - // -=- ColourMap callbacks - virtual void lookup(int index, int* r, int* g, int* b) { - XColor xc; - xc.pixel = index; - if (index < DisplayCells(dpy,DefaultScreen(dpy))) { - XQueryColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), &xc); - } else { - xc.red = xc.green = xc.blue = 0; - } - *r = xc.red; - *g = xc.green; - *b = xc.blue; + // -=- TXGlobalEventHandler interface + + virtual bool handleGlobalEvent(XEvent* ev) { +#ifdef HAVE_XDAMAGE + XDamageNotifyEvent* dev; + Rect rect; + + if (ev->type != xdamageEventBase) + return false; + + if (!running) + return true; + + dev = (XDamageNotifyEvent*)ev; + rect.setXYWH(dev->area.x, dev->area.y, dev->area.width, dev->area.height); + server->add_changed(rect); + + return true; +#endif } protected: @@ -261,8 +297,13 @@ protected: VNCServerST* server; int oldButtonMask; bool haveXtest; + bool haveDamage; int maxButtons; bool running; +#ifdef HAVE_XDAMAGE + Damage damage; + int xdamageEventBase; +#endif }; @@ -469,6 +510,7 @@ int main(int argc, char** argv) TXWindow::handleXEvents(dpy); FD_ZERO(&rfds); + FD_SET(ConnectionNumber(dpy), &rfds); FD_SET(listener.getFd(), &rfds); server.getSockets(&sockets); int clients_connected = 0; -- 2.39.5