diff --git a/src/utils/Makefile b/src/utils/Makefile index 08fc7bc5..b3a8b8f4 100644 --- a/src/utils/Makefile +++ b/src/utils/Makefile @@ -80,6 +80,13 @@ trconftree.o : conftree.cpp $(CXX) $(ALL_CXXFLAGS) -DTEST_CONFTREE -c -o trconftree.o \ conftree.cpp +X11MON_OBJS= trx11mon.o x11mon.o +trx11mon : $(X11MON_OBJS) + $(CXX) $(ALL_CXXFLAGS) -o trx11mon $(X11MON_OBJS) -L/usr/X11R6/lib -lX11 +trx11mon.o : x11mon.cpp x11mon.h + $(CXX) -o trx11mon.o -c $(ALL_CXXFLAGS) -DTEST_X11MON x11mon.cpp +x11mon.o: x11mon.cpp + $(CXX) -c -I/usr/X11R6/include $(ALL_CXXFLAGS) x11mon.cpp clean: rm -f *.o $(PROGS) diff --git a/src/utils/x11mon.cpp b/src/utils/x11mon.cpp new file mode 100644 index 00000000..9244eeb6 --- /dev/null +++ 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 +#include +#include +#include + +#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 +#include +#include + +#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 diff --git a/src/utils/x11mon.h b/src/utils/x11mon.h new file mode 100644 index 00000000..72f15c90 --- /dev/null +++ b/src/utils/x11mon.h @@ -0,0 +1,8 @@ +#ifndef _X11MON_H_INCLUDED_ +#define _X11MON_H_INCLUDED_ +/* @(#$Id: x11mon.h,v 1.1 2006-12-23 12:23:15 dockes Exp $ (C) 2006 J.F.Dockes */ + +/** Poll X11 server status and connectivity */ +extern bool x11IsAlive(); + +#endif /* _X11MON_H_INCLUDED_ */