X11: Added a test for a weird X11 error we get with Xinerama, rarely.
authorRyan C. Gordon <icculus@icculus.org>
Tue, 30 Jun 2015 15:00:48 -0400
changeset 9789 137993bad5c7
parent 9788 ecda7d71342e
child 9790 d968c87f2a5d
X11: Added a test for a weird X11 error we get with Xinerama, rarely.
src/video/x11/SDL_x11modes.c
--- a/src/video/x11/SDL_x11modes.c	Tue Jun 30 14:41:17 2015 -0400
+++ b/src/video/x11/SDL_x11modes.c	Tue Jun 30 15:00:48 2015 -0400
@@ -192,6 +192,21 @@
 #endif
     return SDL_TRUE;
 }
+
+/* !!! FIXME: remove this later. */
+/* we have a weird bug where XineramaQueryScreens() throws an X error, so this
+   is here to help track it down (and not crash, too!). */
+static SDL_bool xinerama_triggered_error = SDL_FALSE;
+static int
+X11_XineramaFailed(Display * d, XErrorEvent * e)
+{
+    xinerama_triggered_error = SDL_TRUE;
+    fprintf(stderr, "XINERAMA X ERROR: type=%d serial=%lu err=%u req=%u minor=%u\n",
+            e->type, e->serial, (unsigned int) e->error_code,
+            (unsigned int) e->request_code, (unsigned int) e->minor_code);
+    fflush(stderr);
+    return 0;
+}
 #endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */
 
 #if SDL_VIDEO_DRIVER_X11_XRANDR
@@ -398,7 +413,15 @@
      *       or newer of the Nvidia binary drivers
      */
     if (CheckXinerama(data->display, &xinerama_major, &xinerama_minor)) {
+        int (*handler) (Display *, XErrorEvent *);
+        X11_XSync(data->display, False);
+        handler = X11_XSetErrorHandler(X11_XineramaFailed);
         xinerama = X11_XineramaQueryScreens(data->display, &screencount);
+        X11_XSync(data->display, False);
+        X11_XSetErrorHandler(handler);
+        if (xinerama_triggered_error) {
+            xinerama = 0;
+        }
         if (xinerama) {
             use_xinerama = xinerama_major * 100 + xinerama_minor;
         }