Commit 13f2e54295dc9f4d4a4b6570432e55a2649ecf92

Ryan C. Gordon 2017-01-07T19:55:29

x11: make the X11 target work on macOS with Xquartz.

diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index dca9ff0..4738543 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -202,7 +202,7 @@ ShouldUseTextureFramebuffer()
     return SDL_FALSE;
 
 #elif defined(__MACOSX__)
-    /* Mac OS X uses OpenGL as the native fast path */
+    /* Mac OS X uses OpenGL as the native fast path (for cocoa and X11) */
     return SDL_TRUE;
 
 #elif defined(__LINUX__)
@@ -1177,29 +1177,31 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen)
     /* if the window is going away and no resolution change is necessary,
        do nothing, or else we may trigger an ugly double-transition
      */
-    if (window->is_destroying && (window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP)
-        return 0;
+    if (SDL_strcmp(_this->name, "cocoa") == 0) {  /* don't do this for X11, etc */
+        if (window->is_destroying && (window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP)
+            return 0;
     
-    if (!_this->is_dummy) {
-        /* If we're switching between a fullscreen Space and "normal" fullscreen, we need to get back to normal first. */
-        if (fullscreen && ((window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP) && ((window->flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN)) {
-            if (!Cocoa_SetWindowFullscreenSpace(window, SDL_FALSE)) {
-                return -1;
-            }
-        } else if (fullscreen && ((window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN) && ((window->flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP)) {
-            display = SDL_GetDisplayForWindow(window);
-            SDL_SetDisplayModeForDisplay(display, NULL);
-            if (_this->SetWindowFullscreen) {
-                _this->SetWindowFullscreen(_this, window, display, SDL_FALSE);
+        if (!_this->is_dummy) {
+            /* If we're switching between a fullscreen Space and "normal" fullscreen, we need to get back to normal first. */
+            if (fullscreen && ((window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP) && ((window->flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN)) {
+                if (!Cocoa_SetWindowFullscreenSpace(window, SDL_FALSE)) {
+                    return -1;
+                }
+            } else if (fullscreen && ((window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN) && ((window->flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP)) {
+                display = SDL_GetDisplayForWindow(window);
+                SDL_SetDisplayModeForDisplay(display, NULL);
+                if (_this->SetWindowFullscreen) {
+                    _this->SetWindowFullscreen(_this, window, display, SDL_FALSE);
+                }
             }
-        }
 
-        if (Cocoa_SetWindowFullscreenSpace(window, fullscreen)) {
-            if (Cocoa_IsWindowInFullscreenSpace(window) != fullscreen) {
-                return -1;
+            if (Cocoa_SetWindowFullscreenSpace(window, fullscreen)) {
+                if (Cocoa_IsWindowInFullscreenSpace(window) != fullscreen) {
+                    return -1;
+                }
+                window->last_fullscreen_flags = window->flags;
+                return 0;
             }
-            window->last_fullscreen_flags = window->flags;
-            return 0;
         }
     }
 #elif __WINRT__ && (NTDDI_VERSION < NTDDI_WIN10)
@@ -2521,8 +2523,10 @@ ShouldMinimizeOnFocusLoss(SDL_Window * window)
     }
 
 #ifdef __MACOSX__
-    if (Cocoa_IsWindowInFullscreenSpace(window)) {
-        return SDL_FALSE;
+    if (SDL_strcmp(_this->name, "cocoa") == 0) {  /* don't do this for X11, etc */
+        if (Cocoa_IsWindowInFullscreenSpace(window)) {
+            return SDL_FALSE;
+        }
     }
 #endif
 
diff --git a/src/video/x11/SDL_x11opengl.c b/src/video/x11/SDL_x11opengl.c
index b412dc7..e407c29 100644
--- a/src/video/x11/SDL_x11opengl.c
+++ b/src/video/x11/SDL_x11opengl.c
@@ -391,12 +391,17 @@ X11_GL_InitExtensions(_THIS)
 
 /* glXChooseVisual and glXChooseFBConfig have some small differences in
  * the attribute encoding, it can be chosen with the for_FBConfig parameter.
+ * Some targets fail if you use GLX_X_VISUAL_TYPE_EXT/GLX_DIRECT_COLOR_EXT,
+ *  so it gets specified last if used and is pointed to by *_pvistypeattr.
+ *  In case of failure, if that pointer is not NULL, set that pointer to None
+ *  and try again.
  */
 static int
-X11_GL_GetAttributes(_THIS, Display * display, int screen, int * attribs, int size, Bool for_FBConfig)
+X11_GL_GetAttributes(_THIS, Display * display, int screen, int * attribs, int size, Bool for_FBConfig, int **_pvistypeattr)
 {
     int i = 0;
     const int MAX_ATTRIBUTES = 64;
+    int *pvistypeattr = NULL;
 
     /* assert buffer is large enough to hold all SDL attributes. */
     SDL_assert(size >= MAX_ATTRIBUTES);
@@ -488,6 +493,7 @@ X11_GL_GetAttributes(_THIS, Display * display, int screen, int * attribs, int si
        EXT_visual_info extension, then add GLX_X_VISUAL_TYPE_EXT. */
     if (X11_UseDirectColorVisuals() &&
         _this->gl_data->HAS_GLX_EXT_visual_info) {
+        pvistypeattr = &attribs[i];
         attribs[i++] = GLX_X_VISUAL_TYPE_EXT;
         attribs[i++] = GLX_DIRECT_COLOR_EXT;
     }
@@ -496,6 +502,10 @@ X11_GL_GetAttributes(_THIS, Display * display, int screen, int * attribs, int si
 
     SDL_assert(i <= MAX_ATTRIBUTES);
 
+    if (_pvistypeattr) {
+        *_pvistypeattr = pvistypeattr;
+    }
+
     return i;
 }
 
@@ -505,14 +515,21 @@ X11_GL_GetVisual(_THIS, Display * display, int screen)
     /* 64 seems nice. */
     int attribs[64];
     XVisualInfo *vinfo;
+    int *pvistypeattr = NULL;
 
     if (!_this->gl_data) {
         /* The OpenGL library wasn't loaded, SDL_GetError() should have info */
         return NULL;
     }
 
-    X11_GL_GetAttributes(_this, display, screen, attribs, 64, SDL_FALSE);
+    X11_GL_GetAttributes(_this, display, screen, attribs, 64, SDL_FALSE, &pvistypeattr);
     vinfo = _this->gl_data->glXChooseVisual(display, screen, attribs);
+
+    if (!vinfo && (pvistypeattr != NULL)) {
+        *pvistypeattr = None;
+        vinfo = _this->gl_data->glXChooseVisual(display, screen, attribs);
+    }
+
     if (!vinfo) {
         SDL_SetError("Couldn't find matching GLX visual");
     }
@@ -626,20 +643,28 @@ X11_GL_CreateContext(_THIS, SDL_Window * window)
                 /* Create a GL 3.x context */
                 GLXFBConfig *framebuffer_config = NULL;
                 int fbcount = 0;
+                int *pvistypeattr = NULL;
+
+                X11_GL_GetAttributes(_this,display,screen,glxAttribs,64,SDL_TRUE,&pvistypeattr);
 
-                X11_GL_GetAttributes(_this,display,screen,glxAttribs,64,SDL_TRUE);
+                if (_this->gl_data->glXChooseFBConfig) {
+                    framebuffer_config = _this->gl_data->glXChooseFBConfig(display,
+                                          DefaultScreen(display), glxAttribs,
+                                          &fbcount);
 
-                if (!_this->gl_data->glXChooseFBConfig
-                    || !(framebuffer_config =
-                        _this->gl_data->glXChooseFBConfig(display,
+                    if (!framebuffer_config && (pvistypeattr != NULL)) {
+                        *pvistypeattr = None;
+                        framebuffer_config = _this->gl_data->glXChooseFBConfig(display,
                                           DefaultScreen(display), glxAttribs,
-                                          &fbcount))) {
-                    SDL_SetError("No good framebuffers found. OpenGL 3.0 and later unavailable");
-                } else {
-                    context = _this->gl_data->glXCreateContextAttribsARB(display,
-                                                    framebuffer_config[0],
-                                                    share_context, True, attribs);
-                    X11_XFree(framebuffer_config);
+                                          &fbcount);
+                    }
+            
+                    if (framebuffer_config) {
+                        context = _this->gl_data->glXCreateContextAttribsARB(display,
+                                                        framebuffer_config[0],
+                                                        share_context, True, attribs);
+                        X11_XFree(framebuffer_config);
+                    }
                 }
             }
         }