Add a safety net X11 error handler, to reset the vidmodes before crashing.
authorRyan C. Gordon
Fri, 28 Sep 2012 14:12:45 -0400
changeset 649893d9b2a2eb0e
parent 6497 e844e2632149
child 6499 a34024340f54
Add a safety net X11 error handler, to reset the vidmodes before crashing.
src/video/x11/SDL_x11video.c
     1.1 --- a/src/video/x11/SDL_x11video.c	Fri Sep 28 04:09:06 2012 -0700
     1.2 +++ b/src/video/x11/SDL_x11video.c	Fri Sep 28 14:12:45 2012 -0400
     1.3 @@ -116,6 +116,35 @@
     1.4      SDL_X11_UnloadSymbols();
     1.5  }
     1.6  
     1.7 +/* An error handler to reset the vidmode and then call the default handler. */
     1.8 +static SDL_bool safety_net_triggered = SDL_FALSE;
     1.9 +static int (*orig_x11_errhandler) (Display *, XErrorEvent *) = NULL;
    1.10 +static int
    1.11 +X11_SafetyNetErrHandler(Display * d, XErrorEvent * e)
    1.12 +{
    1.13 +    /* if we trigger an error in our error handler, don't try again. */
    1.14 +    if (!safety_net_triggered) {
    1.15 +        safety_net_triggered = SDL_TRUE;
    1.16 +        SDL_VideoDevice *device = SDL_GetVideoDevice();
    1.17 +        if (device != NULL) {
    1.18 +            int i;
    1.19 +            for (i = 0; i < device->num_displays; i++) {
    1.20 +                SDL_VideoDisplay *display = &device->displays[i];
    1.21 +                if (SDL_memcmp(&display->current_mode, &display->desktop_mode,
    1.22 +                               sizeof (SDL_DisplayMode)) != 0) {
    1.23 +                    X11_SetDisplayMode(device, display, &display->desktop_mode);
    1.24 +                }
    1.25 +            }
    1.26 +        }
    1.27 +    }
    1.28 +
    1.29 +    if (orig_x11_errhandler != NULL) {
    1.30 +        return orig_x11_errhandler(d, e);  /* probably terminate. */
    1.31 +    }
    1.32 +
    1.33 +    return 0;
    1.34 +}
    1.35 +
    1.36  static SDL_VideoDevice *
    1.37  X11_CreateDevice(int devindex)
    1.38  {
    1.39 @@ -173,6 +202,10 @@
    1.40      XSynchronize(data->display, True);
    1.41  #endif
    1.42  
    1.43 +    /* Hook up an X11 error handler to recover the desktop resolution. */
    1.44 +    safety_net_triggered = SDL_FALSE;
    1.45 +    orig_x11_errhandler = XSetErrorHandler(X11_SafetyNetErrHandler);
    1.46 +
    1.47      /* Set the function pointers */
    1.48      device->VideoInit = X11_VideoInit;
    1.49      device->VideoQuit = X11_VideoQuit;