[Commits] SDL: x11: Catch fatal X errors when calling glXMakeCurrent().

libsdl.org revision control commits-owner at libsdl.org
Mon Jul 27 21:13:08 PDT 2015


details:   https://hg.libsdl.org/SDL/rev/9b4dd9efb04e
changeset: 9812:9b4dd9efb04e
user:      Ryan C. Gordon <icculus at icculus.org>
date:      Tue Jul 28 00:12:50 2015 -0400
description:
x11: Catch fatal X errors when calling glXMakeCurrent().

In extremely rare cases, probably due to misconfigured drivers, one might
see this happen, and rather than terminate the process, we try to recover
by reporting an error to the app.

Fixes Bugzilla #3068.

diffstat:

 src/video/x11/SDL_x11opengl.c |  24 +++++++++++++++++++-----
 1 files changed, 19 insertions(+), 5 deletions(-)

diffs (69 lines):

diff -r 9d44e8794a9b -r 9b4dd9efb04e src/video/x11/SDL_x11opengl.c
--- a/src/video/x11/SDL_x11opengl.c	Sun Jul 19 19:56:16 2015 -0300
+++ b/src/video/x11/SDL_x11opengl.c	Tue Jul 28 00:12:50 2015 -0400
@@ -529,10 +529,11 @@
 #define GLXBadProfileARB 13
 #endif
 static int (*handler) (Display *, XErrorEvent *) = NULL;
+static const char *errorHandlerOperation = NULL;
 static int errorBase = 0;
 static int errorCode = 0;
 static int
-X11_GL_CreateContextErrorHandler(Display * d, XErrorEvent * e)
+X11_GL_ErrorHandler(Display * d, XErrorEvent * e)
 {
     char *x11_error = NULL;
     char x11_error_locale[256];
@@ -545,12 +546,12 @@
 
     if (x11_error)
     {
-        SDL_SetError("Could not create GL context: %s", x11_error);
+        SDL_SetError("Could not %s: %s", errorHandlerOperation, x11_error);
         SDL_free(x11_error);
     }
     else
     {
-        SDL_SetError("Could not create GL context: %i (Base %i)\n", errorCode, errorBase);
+        SDL_SetError("Could not %s: %i (Base %i)\n", errorHandlerOperation, errorCode, errorBase);
     }
 
     return (0);
@@ -576,9 +577,10 @@
 
     /* We do this to create a clean separation between X and GLX errors. */
     X11_XSync(display, False);
+    errorHandlerOperation = "create GL context";
     errorBase = _this->gl_data->errorBase;
     errorCode = Success;
-    handler = X11_XSetErrorHandler(X11_GL_CreateContextErrorHandler);
+    handler = X11_XSetErrorHandler(X11_GL_ErrorHandler);
     X11_XGetWindowAttributes(display, data->xwindow, &xattr);
     v.screen = screen;
     v.visualid = X11_XVisualIDFromVisual(xattr.visual);
@@ -676,12 +678,24 @@
     Window drawable =
         (context ? ((SDL_WindowData *) window->driverdata)->xwindow : None);
     GLXContext glx_context = (GLXContext) context;
+    int rc;
 
     if (!_this->gl_data) {
         return SDL_SetError("OpenGL not initialized");
     }
 
-    if (!_this->gl_data->glXMakeCurrent(display, drawable, glx_context)) {
+    /* We do this to create a clean separation between X and GLX errors. */
+    X11_XSync(display, False);
+    errorHandlerOperation = "make GL context current";
+    errorBase = _this->gl_data->errorBase;
+    errorCode = Success;
+    handler = X11_XSetErrorHandler(X11_GL_ErrorHandler);
+    rc = _this->gl_data->glXMakeCurrent(display, drawable, glx_context);
+    X11_XSetErrorHandler(handler);
+
+    if (errorCode != Success) {   /* uhoh, an X error was thrown! */
+        return -1;  /* the error handler called SDL_SetError() already. */
+    } else if (!rc) {  /* glxMakeCurrent() failed without throwing an X error */
         return SDL_SetError("Unable to make GL context current");
     }
 


More information about the commits mailing list