Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-01-23 14:32:09 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-01-23 14:32:09 +0400
commit47f23c1372d332e223d99e317490c5fe3b5d5667 (patch)
treef74f16e555d2517d277de7fb1c2704c3dcf0b07a /intern
parent45fb9f9f098c36b5a7d5c5859c2f31f1b1818b31 (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')
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp29
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.h3
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp16
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;
}