summaryrefslogtreecommitdiffstats
path: root/unix
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2014-06-13 10:56:59 +0000
committerPierre Ossman <ossman@cendio.se>2014-06-25 14:45:52 +0200
commita7b728a8230a18f515509a17d1cb11566f07c9f8 (patch)
tree3832ca5f4ab5fdef77db132fa7feaabbe7d4d910 /unix
parentdf0f2832b407e811060291d0ab8a3bbae1fcf0eb (diff)
downloadtigervnc-a7b728a8230a18f515509a17d1cb11566f07c9f8.tar.gz
tigervnc-a7b728a8230a18f515509a17d1cb11566f07c9f8.zip
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
Diffstat (limited to 'unix')
-rw-r--r--unix/x0vncserver/CMakeLists.txt8
-rw-r--r--unix/x0vncserver/x0vncserver.cxx72
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 <X11/extensions/XTest.h>
#endif
+#ifdef HAVE_XDAMAGE
+#include <X11/extensions/Xdamage.h>
+#endif
#include <x0vncserver/Geometry.h>
#include <x0vncserver/Image.h>
@@ -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;