static void X11_CheckWindowManager(_THIS) { SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; Display *display = data->display; Atom _NET_SUPPORTING_WM_CHECK; int status, real_format; Atom real_type; unsigned long items_read = 0, items_left = 0; unsigned char *propdata = NULL; Window wm_window = 0; #ifdef DEBUG_WINDOW_MANAGER char *wm_name; #endif /* Set up a handler to gracefully catch errors */ X11_XSync(display, False); handler = X11_XSetErrorHandler(X11_CheckWindowManagerErrorHandler); _NET_SUPPORTING_WM_CHECK = X11_XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", False); status = X11_XGetWindowProperty(display, DefaultRootWindow(display), _NET_SUPPORTING_WM_CHECK, 0L, 1L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &propdata); if (status == Success) { if (items_read) { wm_window = ((Window*)propdata)[0]; } if (propdata) { X11_XFree(propdata); propdata = NULL; } } if (wm_window) { status = X11_XGetWindowProperty(display, wm_window, _NET_SUPPORTING_WM_CHECK, 0L, 1L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &propdata); if (status != Success || !items_read || wm_window != ((Window*)propdata)[0]) { wm_window = None; } if (status == Success && propdata) { X11_XFree(propdata); propdata = NULL; } } /* Reset the error handler, we're done checking */ X11_XSync(display, False); X11_XSetErrorHandler(handler); if (!wm_window) { #ifdef DEBUG_WINDOW_MANAGER printf("Couldn't get _NET_SUPPORTING_WM_CHECK property\n"); #endif return; } data->net_wm = SDL_TRUE; #ifdef DEBUG_WINDOW_MANAGER wm_name = X11_GetWindowTitle(_this, wm_window); printf("Window manager: %s\n", wm_name); SDL_free(wm_name); #endif }
static void X11_ResetXIM(_THIS) { #ifdef X_HAVE_UTF8_STRING SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; int i; if (videodata && videodata->windowlist) { for (i = 0; i < videodata->numwindows; ++i) { SDL_WindowData *data = videodata->windowlist[i]; if (data && data->ic) { /* Clear any partially entered dead keys */ char *contents = X11_Xutf8ResetIC(data->ic); if (contents) { X11_XFree(contents); } } } } #endif }
/* Create and set up our X11 dialog box indow. */ static int X11_MessageBoxCreateWindow( SDL_MessageBoxDataX11 *data ) { int x, y; XSizeHints *sizehints; XSetWindowAttributes wnd_attr; Atom _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DIALOG, _NET_WM_NAME, UTF8_STRING; Display *display = data->display; SDL_WindowData *windowdata = NULL; const SDL_MessageBoxData *messageboxdata = data->messageboxdata; if ( messageboxdata->window ) { SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(messageboxdata->window)->driverdata; windowdata = (SDL_WindowData *)messageboxdata->window->driverdata; data->screen = displaydata->screen; } else { data->screen = DefaultScreen( display ); } data->event_mask = ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask | FocusChangeMask | PointerMotionMask; wnd_attr.event_mask = data->event_mask; data->window = X11_XCreateWindow( display, RootWindow(display, data->screen), 0, 0, data->dialog_width, data->dialog_height, 0, CopyFromParent, InputOutput, CopyFromParent, CWEventMask, &wnd_attr ); if ( data->window == None ) { return SDL_SetError("Couldn't create X window"); } if ( windowdata ) { /* http://tronche.com/gui/x/icccm/sec-4.html#WM_TRANSIENT_FOR */ X11_XSetTransientForHint( display, data->window, windowdata->xwindow ); } X11_XStoreName( display, data->window, messageboxdata->title ); _NET_WM_NAME = X11_XInternAtom(display, "_NET_WM_NAME", False); UTF8_STRING = X11_XInternAtom(display, "UTF8_STRING", False); X11_XChangeProperty(display, data->window, _NET_WM_NAME, UTF8_STRING, 8, PropModeReplace, (unsigned char *) messageboxdata->title, strlen(messageboxdata->title) + 1 ); /* Let the window manager know this is a dialog box */ _NET_WM_WINDOW_TYPE = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); _NET_WM_WINDOW_TYPE_DIALOG = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False); X11_XChangeProperty(display, data->window, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&_NET_WM_WINDOW_TYPE_DIALOG, 1); /* Allow the window to be deleted by the window manager */ data->wm_protocols = X11_XInternAtom( display, "WM_PROTOCOLS", False ); data->wm_delete_message = X11_XInternAtom( display, "WM_DELETE_WINDOW", False ); X11_XSetWMProtocols( display, data->window, &data->wm_delete_message, 1 ); if ( windowdata ) { XWindowAttributes attrib; Window dummy; X11_XGetWindowAttributes(display, windowdata->xwindow, &attrib); x = attrib.x + ( attrib.width - data->dialog_width ) / 2; y = attrib.y + ( attrib.height - data->dialog_height ) / 3 ; X11_XTranslateCoordinates(display, windowdata->xwindow, RootWindow(display, data->screen), x, y, &x, &y, &dummy); } else { const SDL_VideoDevice *dev = SDL_GetVideoDevice(); if ((dev) && (dev->displays) && (dev->num_displays > 0)) { const SDL_VideoDisplay *dpy = &dev->displays[0]; const SDL_DisplayData *dpydata = (SDL_DisplayData *) dpy->driverdata; x = dpydata->x + (( dpy->current_mode.w - data->dialog_width ) / 2); y = dpydata->y + (( dpy->current_mode.h - data->dialog_height ) / 3); } else { /* oh well. This will misposition on a multi-head setup. Init first next time. */ x = ( DisplayWidth( display, data->screen ) - data->dialog_width ) / 2; y = ( DisplayHeight( display, data->screen ) - data->dialog_height ) / 3 ; } } X11_XMoveWindow( display, data->window, x, y ); sizehints = X11_XAllocSizeHints(); if ( sizehints ) { sizehints->flags = USPosition | USSize | PMaxSize | PMinSize; sizehints->x = x; sizehints->y = y; sizehints->width = data->dialog_width; sizehints->height = data->dialog_height; sizehints->min_width = sizehints->max_width = data->dialog_width; sizehints->min_height = sizehints->max_height = data->dialog_height; X11_XSetWMNormalHints( display, data->window, sizehints ); X11_XFree( sizehints ); } X11_XMapRaised( display, data->window ); #if SDL_VIDEO_DRIVER_X11_XDBE /* Initialise a back buffer for double buffering */ if (SDL_X11_HAVE_XDBE) { int xdbe_major, xdbe_minor; if (X11_XdbeQueryExtension(display, &xdbe_major, &xdbe_minor) != 0) { data->xdbe = SDL_TRUE; data->buf = X11_XdbeAllocateBackBufferName(display, data->window, XdbeUndefined); } else { data->xdbe = SDL_FALSE; } } #endif return 0; }
SDL_GLContext X11_GL_CreateContext(_THIS, SDL_Window * window) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Display *display = data->videodata->display; int screen = ((SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata)->screen; XWindowAttributes xattr; XVisualInfo v, *vinfo; int n; GLXContext context = NULL, share_context; if (_this->gl_config.share_with_current_context) { share_context = (GLXContext)SDL_GL_GetCurrentContext(); } else { share_context = NULL; } /* 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_ErrorHandler); X11_XGetWindowAttributes(display, data->xwindow, &xattr); v.screen = screen; v.visualid = X11_XVisualIDFromVisual(xattr.visual); vinfo = X11_XGetVisualInfo(display, VisualScreenMask | VisualIDMask, &v, &n); if (vinfo) { if (_this->gl_config.major_version < 3 && _this->gl_config.profile_mask == 0 && _this->gl_config.flags == 0) { /* Create legacy context */ context = _this->gl_data->glXCreateContext(display, vinfo, share_context, True); } else { /* max 10 attributes plus terminator */ int attribs[11] = { GLX_CONTEXT_MAJOR_VERSION_ARB, _this->gl_config.major_version, GLX_CONTEXT_MINOR_VERSION_ARB, _this->gl_config.minor_version, 0 }; int iattr = 4; /* SDL profile bits match GLX profile bits */ if( _this->gl_config.profile_mask != 0 ) { attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB; attribs[iattr++] = _this->gl_config.profile_mask; } /* SDL flags match GLX flags */ if( _this->gl_config.flags != 0 ) { attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB; attribs[iattr++] = _this->gl_config.flags; } /* only set if glx extension is available */ if( _this->gl_data->HAS_GLX_ARB_context_flush_control ) { attribs[iattr++] = GLX_CONTEXT_RELEASE_BEHAVIOR_ARB; attribs[iattr++] = _this->gl_config.release_behavior ? GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB : GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB; } attribs[iattr++] = 0; /* Get a pointer to the context creation function for GL 3.0 */ if (!_this->gl_data->glXCreateContextAttribsARB) { SDL_SetError("OpenGL 3.0 and later are not supported by this system"); } else { int glxAttribs[64]; /* Create a GL 3.x context */ GLXFBConfig *framebuffer_config = NULL; int fbcount = 0; 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))) { 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); } } } X11_XFree(vinfo); } X11_XSync(display, False); X11_XSetErrorHandler(handler); if (!context) { if (errorCode == Success) { SDL_SetError("Could not create GL context"); } return NULL; } if (X11_GL_MakeCurrent(_this, window, context) < 0) { X11_GL_DeleteContext(_this, context); return NULL; } return context; }
static void X11_GL_InitExtensions(_THIS) { Display *display = ((SDL_VideoData *) _this->driverdata)->display; const int screen = DefaultScreen(display); XVisualInfo *vinfo = NULL; Window w = 0; GLXContext prev_ctx = 0; GLXDrawable prev_drawable = 0; GLXContext context = 0; const char *(*glXQueryExtensionsStringFunc) (Display *, int); const char *extensions; vinfo = X11_GL_GetVisual(_this, display, screen); if (vinfo) { GLXContext (*glXGetCurrentContextFunc) (void) = (GLXContext(*)(void)) X11_GL_GetProcAddress(_this, "glXGetCurrentContext"); GLXDrawable (*glXGetCurrentDrawableFunc) (void) = (GLXDrawable(*)(void)) X11_GL_GetProcAddress(_this, "glXGetCurrentDrawable"); if (glXGetCurrentContextFunc && glXGetCurrentDrawableFunc) { XSetWindowAttributes xattr; prev_ctx = glXGetCurrentContextFunc(); prev_drawable = glXGetCurrentDrawableFunc(); xattr.background_pixel = 0; xattr.border_pixel = 0; xattr.colormap = X11_XCreateColormap(display, RootWindow(display, screen), vinfo->visual, AllocNone); w = X11_XCreateWindow(display, RootWindow(display, screen), 0, 0, 32, 32, 0, vinfo->depth, InputOutput, vinfo->visual, (CWBackPixel | CWBorderPixel | CWColormap), &xattr); context = _this->gl_data->glXCreateContext(display, vinfo, NULL, True); if (context) { _this->gl_data->glXMakeCurrent(display, w, context); } } X11_XFree(vinfo); } glXQueryExtensionsStringFunc = (const char *(*)(Display *, int)) X11_GL_GetProcAddress(_this, "glXQueryExtensionsString"); if (glXQueryExtensionsStringFunc) { extensions = glXQueryExtensionsStringFunc(display, screen); } else { extensions = NULL; } /* Check for GLX_EXT_swap_control(_tear) */ _this->gl_data->HAS_GLX_EXT_swap_control_tear = SDL_FALSE; if (HasExtension("GLX_EXT_swap_control", extensions)) { _this->gl_data->glXSwapIntervalEXT = (void (*)(Display*,GLXDrawable,int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalEXT"); if (HasExtension("GLX_EXT_swap_control_tear", extensions)) { _this->gl_data->HAS_GLX_EXT_swap_control_tear = SDL_TRUE; } } /* Check for GLX_MESA_swap_control */ if (HasExtension("GLX_MESA_swap_control", extensions)) { _this->gl_data->glXSwapIntervalMESA = (int(*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalMESA"); _this->gl_data->glXGetSwapIntervalMESA = (int(*)(void)) X11_GL_GetProcAddress(_this, "glXGetSwapIntervalMESA"); } /* Check for GLX_SGI_swap_control */ if (HasExtension("GLX_SGI_swap_control", extensions)) { _this->gl_data->glXSwapIntervalSGI = (int (*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalSGI"); } /* Check for GLX_ARB_create_context */ if (HasExtension("GLX_ARB_create_context", extensions)) { _this->gl_data->glXCreateContextAttribsARB = (GLXContext (*)(Display*,GLXFBConfig,GLXContext,Bool,const int *)) X11_GL_GetProcAddress(_this, "glXCreateContextAttribsARB"); _this->gl_data->glXChooseFBConfig = (GLXFBConfig *(*)(Display *, int, const int *, int *)) X11_GL_GetProcAddress(_this, "glXChooseFBConfig"); } /* Check for GLX_EXT_visual_rating */ if (HasExtension("GLX_EXT_visual_rating", extensions)) { _this->gl_data->HAS_GLX_EXT_visual_rating = SDL_TRUE; } /* Check for GLX_EXT_visual_info */ if (HasExtension("GLX_EXT_visual_info", extensions)) { _this->gl_data->HAS_GLX_EXT_visual_info = SDL_TRUE; } /* Check for GLX_EXT_create_context_es2_profile */ if (HasExtension("GLX_EXT_create_context_es2_profile", extensions)) { /* this wants to call glGetString(), so it needs a context. */ /* !!! FIXME: it would be nice not to make a context here though! */ if (context) { SDL_GL_DeduceMaxSupportedESProfile( &_this->gl_data->es_profile_max_supported_version.major, &_this->gl_data->es_profile_max_supported_version.minor ); } } /* Check for GLX_ARB_context_flush_control */ if (HasExtension("GLX_ARB_context_flush_control", extensions)) { _this->gl_data->HAS_GLX_ARB_context_flush_control = SDL_TRUE; } /* Check for GLX_ARB_create_context_robustness */ if (HasExtension("GLX_ARB_create_context_robustness", extensions)) { _this->gl_data->HAS_GLX_ARB_create_context_robustness = SDL_TRUE; } /* Check for GLX_ARB_create_context_no_error */ if (HasExtension("GLX_ARB_create_context_no_error", extensions)) { _this->gl_data->HAS_GLX_ARB_create_context_no_error = SDL_TRUE; } if (context) { _this->gl_data->glXMakeCurrent(display, None, NULL); _this->gl_data->glXDestroyContext(display, context); if (prev_ctx && prev_drawable) { _this->gl_data->glXMakeCurrent(display, prev_drawable, prev_ctx); } } if (w) { X11_XDestroyWindow(display, w); } X11_PumpEvents(_this); }
/* Create and set up our X11 dialog box indow. */ static int X11_MessageBoxCreateWindow( SDL_MessageBoxDataX11 *data ) { int x, y; XSizeHints *sizehints; XSetWindowAttributes wnd_attr; Atom _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DIALOG; Display *display = data->display; SDL_WindowData *windowdata = NULL; const SDL_MessageBoxData *messageboxdata = data->messageboxdata; if ( messageboxdata->window ) { SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(messageboxdata->window)->driverdata; windowdata = (SDL_WindowData *)messageboxdata->window->driverdata; data->screen = displaydata->screen; } else { data->screen = DefaultScreen( display ); } data->event_mask = ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask | FocusChangeMask | PointerMotionMask; wnd_attr.event_mask = data->event_mask; data->window = X11_XCreateWindow( display, RootWindow(display, data->screen), 0, 0, data->dialog_width, data->dialog_height, 0, CopyFromParent, InputOutput, CopyFromParent, CWEventMask, &wnd_attr ); if ( data->window == None ) { return SDL_SetError("Couldn't create X window"); } if ( windowdata ) { /* http://tronche.com/gui/x/icccm/sec-4.html#WM_TRANSIENT_FOR */ X11_XSetTransientForHint( display, data->window, windowdata->xwindow ); } X11_XStoreName( display, data->window, messageboxdata->title ); /* Let the window manager know this is a dialog box */ _NET_WM_WINDOW_TYPE = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); _NET_WM_WINDOW_TYPE_DIALOG = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False); X11_XChangeProperty(display, data->window, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&_NET_WM_WINDOW_TYPE_DIALOG, 1); /* Allow the window to be deleted by the window manager */ data->wm_protocols = X11_XInternAtom( display, "WM_PROTOCOLS", False ); data->wm_delete_message = X11_XInternAtom( display, "WM_DELETE_WINDOW", False ); X11_XSetWMProtocols( display, data->window, &data->wm_delete_message, 1 ); if ( windowdata ) { XWindowAttributes attrib; Window dummy; X11_XGetWindowAttributes(display, windowdata->xwindow, &attrib); x = attrib.x + ( attrib.width - data->dialog_width ) / 2; y = attrib.y + ( attrib.height - data->dialog_height ) / 3 ; X11_XTranslateCoordinates(display, windowdata->xwindow, RootWindow(display, data->screen), x, y, &x, &y, &dummy); } else { x = ( DisplayWidth( display, data->screen ) - data->dialog_width ) / 2; y = ( DisplayHeight( display, data->screen ) - data->dialog_height ) / 3 ; } X11_XMoveWindow( display, data->window, x, y ); sizehints = X11_XAllocSizeHints(); if ( sizehints ) { sizehints->flags = USPosition | USSize | PMaxSize | PMinSize; sizehints->x = x; sizehints->y = y; sizehints->width = data->dialog_width; sizehints->height = data->dialog_height; sizehints->min_width = sizehints->max_width = data->dialog_width; sizehints->min_height = sizehints->max_height = data->dialog_height; X11_XSetWMNormalHints( display, data->window, sizehints ); X11_XFree( sizehints ); } X11_XMapRaised( display, data->window ); return 0; }
SDL_GLContext X11_GL_CreateContext(_THIS, SDL_Window * window) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Display *display = data->videodata->display; int screen = ((SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata)->screen; XWindowAttributes xattr; XVisualInfo v, *vinfo; int n; GLXContext context = NULL, share_context; PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs = NULL; if (_this->gl_config.share_with_current_context) { share_context = (GLXContext)SDL_GL_GetCurrentContext(); } else { share_context = NULL; } /* We do this to create a clean separation between X and GLX errors. */ X11_XSync(display, False); errorBase = _this->gl_data->errorBase; handler = X11_XSetErrorHandler(X11_GL_CreateContextErrorHandler); X11_XGetWindowAttributes(display, data->xwindow, &xattr); v.screen = screen; v.visualid = X11_XVisualIDFromVisual(xattr.visual); vinfo = X11_XGetVisualInfo(display, VisualScreenMask | VisualIDMask, &v, &n); if (vinfo) { if (_this->gl_config.major_version < 3 && _this->gl_config.profile_mask == 0 && _this->gl_config.flags == 0) { /* Create legacy context */ context = _this->gl_data->glXCreateContext(display, vinfo, share_context, True); } else { /* If we want a GL 3.0 context or later we need to get a temporary context to grab the new context creation function */ GLXContext temp_context = _this->gl_data->glXCreateContext(display, vinfo, NULL, True); if (temp_context) { /* max 8 attributes plus terminator */ int attribs[9] = { GLX_CONTEXT_MAJOR_VERSION_ARB, _this->gl_config.major_version, GLX_CONTEXT_MINOR_VERSION_ARB, _this->gl_config.minor_version, 0 }; int iattr = 4; /* SDL profile bits match GLX profile bits */ if( _this->gl_config.profile_mask != 0 ) { attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB; attribs[iattr++] = _this->gl_config.profile_mask; } /* SDL flags match GLX flags */ if( _this->gl_config.flags != 0 ) { attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB; attribs[iattr++] = _this->gl_config.flags; } attribs[iattr++] = 0; /* Get a pointer to the context creation function for GL 3.0 */ glXCreateContextAttribs = (PFNGLXCREATECONTEXTATTRIBSARBPROC) _this->gl_data-> glXGetProcAddress((GLubyte *) "glXCreateContextAttribsARB"); if (!glXCreateContextAttribs) { SDL_SetError("GL 3.x is not supported"); context = temp_context; } else { int glxAttribs[64]; /* Create a GL 3.x context */ GLXFBConfig *framebuffer_config = NULL; int fbcount = 0; GLXFBConfig *(*glXChooseFBConfig) (Display * disp, int screen, const int *attrib_list, int *nelements); glXChooseFBConfig = (GLXFBConfig * (*)(Display *, int, const int *, int *)) _this->gl_data-> glXGetProcAddress((GLubyte *) "glXChooseFBConfig"); X11_GL_GetAttributes(_this,display,screen,glxAttribs,64,SDL_TRUE); if (!glXChooseFBConfig || !(framebuffer_config = glXChooseFBConfig(display, DefaultScreen(display), glxAttribs, &fbcount))) { SDL_SetError ("No good framebuffers found. GL 3.x disabled"); context = temp_context; } else { context = glXCreateContextAttribs(display, framebuffer_config[0], share_context, True, attribs); _this->gl_data->glXDestroyContext(display, temp_context); } } } } X11_XFree(vinfo); } X11_XSync(display, False); X11_XSetErrorHandler(handler); if (!context) { SDL_SetError("Could not create GL context"); return NULL; } if (X11_GL_MakeCurrent(_this, window, context) < 0) { X11_GL_DeleteContext(_this, context); return NULL; } return context; }
static void X11_GL_InitExtensions(_THIS) { Display *display = ((SDL_VideoData *) _this->driverdata)->display; int screen = DefaultScreen(display); XVisualInfo *vinfo; XSetWindowAttributes xattr; Window w; GLXContext context; const char *(*glXQueryExtensionsStringFunc) (Display *, int); const char *extensions; vinfo = X11_GL_GetVisual(_this, display, screen); if (!vinfo) { return; } xattr.background_pixel = 0; xattr.border_pixel = 0; xattr.colormap = X11_XCreateColormap(display, RootWindow(display, screen), vinfo->visual, AllocNone); w = X11_XCreateWindow(display, RootWindow(display, screen), 0, 0, 32, 32, 0, vinfo->depth, InputOutput, vinfo->visual, (CWBackPixel | CWBorderPixel | CWColormap), &xattr); context = _this->gl_data->glXCreateContext(display, vinfo, NULL, True); if (context) { _this->gl_data->glXMakeCurrent(display, w, context); } X11_XFree(vinfo); glXQueryExtensionsStringFunc = (const char *(*)(Display *, int)) X11_GL_GetProcAddress(_this, "glXQueryExtensionsString"); if (glXQueryExtensionsStringFunc) { extensions = glXQueryExtensionsStringFunc(display, screen); } else { extensions = NULL; } /* Check for GLX_EXT_swap_control(_tear) */ _this->gl_data->HAS_GLX_EXT_swap_control_tear = SDL_FALSE; if (HasExtension("GLX_EXT_swap_control", extensions)) { _this->gl_data->glXSwapIntervalEXT = (void (*)(Display*,GLXDrawable,int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalEXT"); if (HasExtension("GLX_EXT_swap_control_tear", extensions)) { _this->gl_data->HAS_GLX_EXT_swap_control_tear = SDL_TRUE; } } /* Check for GLX_MESA_swap_control */ if (HasExtension("GLX_MESA_swap_control", extensions)) { _this->gl_data->glXSwapIntervalMESA = (int(*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalMESA"); _this->gl_data->glXGetSwapIntervalMESA = (int(*)(void)) X11_GL_GetProcAddress(_this, "glXGetSwapIntervalMESA"); } /* Check for GLX_SGI_swap_control */ if (HasExtension("GLX_SGI_swap_control", extensions)) { _this->gl_data->glXSwapIntervalSGI = (int (*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalSGI"); } /* Check for GLX_EXT_visual_rating */ if (HasExtension("GLX_EXT_visual_rating", extensions)) { _this->gl_data->HAS_GLX_EXT_visual_rating = SDL_TRUE; } /* Check for GLX_EXT_visual_info */ if (HasExtension("GLX_EXT_visual_info", extensions)) { _this->gl_data->HAS_GLX_EXT_visual_info = SDL_TRUE; } /* Check for GLX_EXT_create_context_es2_profile */ if (HasExtension("GLX_EXT_create_context_es2_profile", extensions)) { _this->gl_data->HAS_GLX_EXT_create_context_es2_profile = SDL_TRUE; } /* Check for GLX_MESA_query_renderer */ if (HasExtension("GLX_MESA_query_renderer", extensions)) { _this->gl_data->glXQueryRendererIntegerMESA = (int(*)(int)) X11_GL_GetProcAddress( _this, "glXQueryRendererIntegerMESA"); _this->gl_data->glXQueryCurrentRendererIntegerMESA = (int(*)(void)) X11_GL_GetProcAddress( _this, "glXQueryCurrentRendererIntegerMESA"); _this->gl_data->glXQueryRendererStringMESA = (int(*)(int)) X11_GL_GetProcAddress( _this, "glXQueryRendererStringMESA"); _this->gl_data->glXQueryCurrentRendererStringMESA = (int(*)(void)) X11_GL_GetProcAddress( _this, "glXQueryCurrentRendererStringMESA"); } /* Check for GL_NVX_gpu_memory_info */ if (HasExtension("GL_NVX_gpu_memory_info", extensions)) { _this->gl_data->HAS_GL_NVX_gpu_memory_info = SDL_TRUE; } /* Check for GL_NVX_gpu_memory_info */ if (HasExtension("GL_NVX_gpu_memory_info", extensions)) { _this->gl_data->HAS_GL_NVX_gpu_memory_info = SDL_TRUE; } if (context) { _this->gl_data->glXMakeCurrent(display, None, NULL); _this->gl_data->glXDestroyContext(display, context); } X11_XDestroyWindow(display, w); X11_PumpEvents(_this); }