--- a
+++ b/src/utils/x11mon.cpp
@@ -0,0 +1,84 @@
+#ifndef TEST_X11MON
+#ifndef lint
+static char rcsid[] = "@(#$Id: x11mon.cpp,v 1.1 2006-12-23 12:23:15 dockes Exp $ (C) 2006 J.F.Dockes";
+#endif
+// Poll state of X11 connectibility (to detect end of user session).
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <signal.h>
+#include <setjmp.h>
+
+#define DODEBUG
+#ifdef DODEBUG
+#define DEBUG(X) fprintf X
+#else
+#define DEBUG(X) fprintf X
+#endif
+
+static Display *m_display;
+static bool m_ok;
+static jmp_buf env;
+
+static int errorHandler(Display *, XErrorEvent*)
+{
+    DEBUG((stderr, "x11mon: error handler: Got X11 error\n"));
+    m_ok = false;
+    return 0;
+}
+static int ioErrorHandler(Display *)
+{
+    DEBUG((stderr, "x11mon: error handler: Got X11 IO error\n"));
+    m_ok = false;
+    m_display = 0;
+    longjmp(env, 1);
+}
+
+bool x11IsAlive()
+{
+    // Xlib always exits on IO errors. Need a setjmp to avoid this (will jump
+    // from IO error handler instead of returning).
+    if (setjmp(env)) {
+	DEBUG((stderr, "x11IsAlive: Long jump\n"));
+	return false;
+    }
+    if (m_display == 0) {
+	signal(SIGPIPE, SIG_IGN);
+	XSetErrorHandler(errorHandler);
+	XSetIOErrorHandler(ioErrorHandler);
+	if ((m_display = XOpenDisplay(0)) == 0) {
+	    DEBUG((stderr, "x11IsAlive: cant connect\n"));
+	    m_ok = false;
+	    return false;
+	}
+    }
+    m_ok = true;
+    bool sync= XSynchronize(m_display, true);
+    XNoOp(m_display);
+    XSynchronize(m_display, sync);
+    return m_ok;
+}
+
+
+#else
+
+// Test driver
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "x11mon.h"
+
+int main(int argc, char **argv)
+{
+    for (;;) {
+	if (!x11IsAlive()) {
+	    fprintf(stderr, "x11IsAlive failed\n");
+	} else {
+	    fprintf(stderr, "x11IsAlive Ok\n");
+	}
+	sleep(1);
+    }
+}
+#endif