Writing error-safe code that uses Xlib is too obnoxious, and using XCB is tedious and not performant, as we can't catch events on a giant stream -- we have to check every operation manually.
In my specific case (writing a GL driver), it would be enough to simply have a Display-specific error handler, since our driver re-opens the Display in our own code, but a better approach might be TLS storage for the global handler. Signed-off-by: Jasper St. Pierre <[email protected]> --- include/X11/Xlib.h | 4 ++++ include/X11/Xlibint.h | 3 +++ src/ErrHndlr.c | 15 +++++++++++++++ src/XlibInt.c | 12 +++++++++++- 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/include/X11/Xlib.h b/include/X11/Xlib.h index 2bffa76..772e88c 100644 --- a/include/X11/Xlib.h +++ b/include/X11/Xlib.h @@ -1849,6 +1849,10 @@ extern XErrorHandler XSetErrorHandler ( XErrorHandler /* handler */ ); +extern XErrorHandler XDisplaySetErrorHandler( + Display* /* display */, + XErrorHandler /* handler */ +); typedef int (*XIOErrorHandler) ( /* WARNING, this type not in Xlib spec */ Display* /* display */ diff --git a/include/X11/Xlibint.h b/include/X11/Xlibint.h index 4431559..e05792f 100644 --- a/include/X11/Xlibint.h +++ b/include/X11/Xlibint.h @@ -205,6 +205,9 @@ struct _XDisplay XGenericEventCookie * /* in */, XGenericEventCookie * /* out*/); void *cookiejar; /* cookie events returned but not claimed */ + + /* display-specific error handler */ + XErrorHandler err_handler; }; #define XAllocIDs(dpy,ids,n) (*(dpy)->idlist_alloc)(dpy,ids,n) diff --git a/src/ErrHndlr.c b/src/ErrHndlr.c index 167a68b..a8e1eee 100644 --- a/src/ErrHndlr.c +++ b/src/ErrHndlr.c @@ -84,3 +84,18 @@ XSetIOErrorHandler(XIOErrorHandler handler) return (XIOErrorHandler) oldhandler; } + +XErrorHandler +XDisplaySetErrorHandler(Display *dpy, XErrorHandler handler) +{ + XErrorHandler old_handler; +#ifdef XTHREADS + LockDisplay(dpy); +#endif + old_handler = dpy->err_handler; + dpy->err_handler = handler; +#ifdef XTHREADS + UnlockDisplay(dpy); +#endif + return old_handler; +} diff --git a/src/XlibInt.c b/src/XlibInt.c index 80c1298..d720e7b 100644 --- a/src/XlibInt.c +++ b/src/XlibInt.c @@ -1387,6 +1387,16 @@ Bool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we) return True; } +static int +DispatchDisplayErrorEvent (Display *dpy, + XErrorEvent *event) +{ + if (dpy->err_handler) + return dpy->err_handler(dpy, event); + else + return _XErrorFunction(dpy, event); +} + /* * _XError - upcall internal or user protocol error handler */ @@ -1426,7 +1436,7 @@ int _XError ( (*dpy->lock->user_lock_display)(dpy); UnlockDisplay(dpy); #endif - rtn_val = (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */ + rtn_val = DispatchDisplayErrorEvent(dpy, (XErrorEvent *)&event); /* upcall */ #ifdef XTHREADS LockDisplay(dpy); if (dpy->lock) -- 2.4.3 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
