diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-01-23 14:32:09 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-01-23 14:32:09 +0400 |
commit | 47f23c1372d332e223d99e317490c5fe3b5d5667 (patch) | |
tree | f74f16e555d2517d277de7fb1c2704c3dcf0b07a /intern/ghost | |
parent | 45fb9f9f098c36b5a7d5c5859c2f31f1b1818b31 (diff) |
fix for blender quitting in X11 if you start blender with a tablet, unplug it, then open a new window.
Diffstat (limited to 'intern/ghost')
-rw-r--r-- | intern/ghost/intern/GHOST_SystemX11.cpp | 29 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemX11.h | 3 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowX11.cpp | 16 |
3 files changed, 41 insertions, 7 deletions
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 90c01f8fea8..28a228b2777 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -69,8 +69,10 @@ #include <stdio.h> /* for fprintf only */ #include <cstdlib> /* for exit */ -static GHOST_TKey -convertXKey(KeySym key); +/* for debugging - so we can breakpoint X11 errors */ +// #define USE_X11_ERROR_HANDLERS + +static GHOST_TKey convertXKey(KeySym key); /* these are for copy and select copy */ static char *txt_cut_buffer = NULL; @@ -91,6 +93,11 @@ GHOST_SystemX11( abort(); /* was return before, but this would just mean it will crash later */ } +#ifdef USE_X11_ERROR_HANDLERS + (void) XSetErrorHandler(GHOST_X11_ApplicationErrorHandler); + (void) XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler); +#endif + #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) /* note -- don't open connection to XIM server here, because the locale * has to be set before opening the connection but setlocale() has not @@ -1726,7 +1733,7 @@ GHOST_TSuccess GHOST_SystemX11::pushDragDropEvent(GHOST_TEventType eventType, * Basically it will not crash blender now if you have a X device that * is configured but not plugged in. */ -static int ApplicationErrorHandler(Display *display, XErrorEvent *theEvent) +int GHOST_X11_ApplicationErrorHandler(Display *display, XErrorEvent *theEvent) { fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n", theEvent->error_code, theEvent->request_code); @@ -1735,6 +1742,14 @@ static int ApplicationErrorHandler(Display *display, XErrorEvent *theEvent) return 0; } +int GHOST_X11_ApplicationIOErrorHandler(Display *display) +{ + fprintf(stderr, "Ignoring Xlib error: error IO\n"); + + /* No exit! - but keep lint happy */ + return 0; +} + /* These C functions are copied from Wine 1.1.13's wintab.c */ #define BOOL int #define TRUE 1 @@ -1832,7 +1847,9 @@ static BOOL is_eraser(const char *name, const char *type) void GHOST_SystemX11::initXInputDevices() { - static XErrorHandler old_handler = (XErrorHandler) 0; + static XErrorHandler old_handler = (XErrorHandler) 0; + static XIOErrorHandler old_handler_io = (XIOErrorHandler) 0; + XExtensionVersion *version = XGetExtensionVersion(m_display, INAME); if (version && (version != (XExtensionVersion *)NoSuchExtension)) { @@ -1843,7 +1860,8 @@ void GHOST_SystemX11::initXInputDevices() m_xtablet.EraserDevice = NULL; /* Install our error handler to override Xlib's termination behavior */ - old_handler = XSetErrorHandler(ApplicationErrorHandler); + old_handler = XSetErrorHandler(GHOST_X11_ApplicationErrorHandler); + old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler); for (int i = 0; i < device_count; ++i) { char *device_type = device_info[i].type ? XGetAtomName(m_display, device_info[i].type) : NULL; @@ -1893,6 +1911,7 @@ void GHOST_SystemX11::initXInputDevices() /* Restore handler */ (void) XSetErrorHandler(old_handler); + (void) XSetIOErrorHandler(old_handler_io); XFreeDeviceList(device_info); } diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h index e49d6280b9c..a5d5d9b7a99 100644 --- a/intern/ghost/intern/GHOST_SystemX11.h +++ b/intern/ghost/intern/GHOST_SystemX11.h @@ -49,6 +49,9 @@ # define GHOST_X11_RES_CLASS "Blender" /* res_class */ #endif +/* generic error handlers */ +int GHOST_X11_ApplicationErrorHandler(Display *display, XErrorEvent *theEvent); +int GHOST_X11_ApplicationIOErrorHandler(Display *display); class GHOST_WindowX11; diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index fec43b558e6..3d1b61305b1 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -1210,6 +1210,13 @@ installDrawingContext( GHOST_TSuccess success; switch (type) { case GHOST_kDrawingContextTypeOpenGL: + { + /* use our own event handlers to avoid exiting blender, + * this would happen for eg: + * if you open blender, unplug a tablet, then open a new window. */ + XErrorHandler old_handler = XSetErrorHandler(GHOST_X11_ApplicationErrorHandler); + XIOErrorHandler old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler); + m_context = glXCreateContext(m_display, m_visual, s_firstContext, True); if (m_context != NULL) { if (!s_firstContext) { @@ -1224,12 +1231,17 @@ installDrawingContext( success = GHOST_kFailure; } - break; + /* Restore handler */ + (void) XSetErrorHandler(old_handler); + (void) XSetIOErrorHandler(old_handler_io); + break; + } case GHOST_kDrawingContextTypeNone: + { success = GHOST_kSuccess; break; - + } default: success = GHOST_kFailure; } |