)
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})
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)
#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>
};
-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;
}
#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);
}
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;
}
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:
VNCServerST* server;
int oldButtonMask;
bool haveXtest;
+ bool haveDamage;
int maxButtons;
bool running;
+#ifdef HAVE_XDAMAGE
+ Damage damage;
+ int xdamageEventBase;
+#endif
};
TXWindow::handleXEvents(dpy);
FD_ZERO(&rfds);
+ FD_SET(ConnectionNumber(dpy), &rfds);
FD_SET(listener.getFd(), &rfds);
server.getSockets(&sockets);
int clients_connected = 0;