From 13f2e54295dc9f4d4a4b6570432e55a2649ecf92 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 7 Jan 2017 19:55:29 -0500 Subject: [PATCH] x11: make the X11 target work on macOS with Xquartz. --- src/video/SDL_video.c | 54 +++++++++++++++++++---------------- src/video/x11/SDL_x11opengl.c | 51 ++++++++++++++++++++++++--------- 2 files changed, 67 insertions(+), 38 deletions(-) diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index dca9ff0b2..47385431c 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 (!_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; - } - window->last_fullscreen_flags = window->flags; + 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 (Cocoa_SetWindowFullscreenSpace(window, fullscreen)) { + if (Cocoa_IsWindowInFullscreenSpace(window) != fullscreen) { + return -1; + } + 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 b412dc7c8..e407c2922 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); + X11_GL_GetAttributes(_this,display,screen,glxAttribs,64,SDL_TRUE,&pvistypeattr); - if (!_this->gl_data->glXChooseFBConfig - || !(framebuffer_config = - _this->gl_data->glXChooseFBConfig(display, + if (_this->gl_data->glXChooseFBConfig) { + 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 && (pvistypeattr != NULL)) { + *pvistypeattr = None; + framebuffer_config = _this->gl_data->glXChooseFBConfig(display, + DefaultScreen(display), glxAttribs, + &fbcount); + } + + if (framebuffer_config) { + context = _this->gl_data->glXCreateContextAttribsARB(display, + framebuffer_config[0], + share_context, True, attribs); + X11_XFree(framebuffer_config); + } } } }