1b877906bSopenharmony_ci//======================================================================== 2b877906bSopenharmony_ci// GLFW 3.5 GLX - www.glfw.org 3b877906bSopenharmony_ci//------------------------------------------------------------------------ 4b877906bSopenharmony_ci// Copyright (c) 2002-2006 Marcus Geelnard 5b877906bSopenharmony_ci// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org> 6b877906bSopenharmony_ci// 7b877906bSopenharmony_ci// This software is provided 'as-is', without any express or implied 8b877906bSopenharmony_ci// warranty. In no event will the authors be held liable for any damages 9b877906bSopenharmony_ci// arising from the use of this software. 10b877906bSopenharmony_ci// 11b877906bSopenharmony_ci// Permission is granted to anyone to use this software for any purpose, 12b877906bSopenharmony_ci// including commercial applications, and to alter it and redistribute it 13b877906bSopenharmony_ci// freely, subject to the following restrictions: 14b877906bSopenharmony_ci// 15b877906bSopenharmony_ci// 1. The origin of this software must not be misrepresented; you must not 16b877906bSopenharmony_ci// claim that you wrote the original software. If you use this software 17b877906bSopenharmony_ci// in a product, an acknowledgment in the product documentation would 18b877906bSopenharmony_ci// be appreciated but is not required. 19b877906bSopenharmony_ci// 20b877906bSopenharmony_ci// 2. Altered source versions must be plainly marked as such, and must not 21b877906bSopenharmony_ci// be misrepresented as being the original software. 22b877906bSopenharmony_ci// 23b877906bSopenharmony_ci// 3. This notice may not be removed or altered from any source 24b877906bSopenharmony_ci// distribution. 25b877906bSopenharmony_ci// 26b877906bSopenharmony_ci//======================================================================== 27b877906bSopenharmony_ci 28b877906bSopenharmony_ci#include "internal.h" 29b877906bSopenharmony_ci 30b877906bSopenharmony_ci#if defined(_GLFW_X11) 31b877906bSopenharmony_ci 32b877906bSopenharmony_ci#include <string.h> 33b877906bSopenharmony_ci#include <stdlib.h> 34b877906bSopenharmony_ci#include <assert.h> 35b877906bSopenharmony_ci 36b877906bSopenharmony_ci#ifndef GLXBadProfileARB 37b877906bSopenharmony_ci #define GLXBadProfileARB 13 38b877906bSopenharmony_ci#endif 39b877906bSopenharmony_ci 40b877906bSopenharmony_ci 41b877906bSopenharmony_ci// Returns the specified attribute of the specified GLXFBConfig 42b877906bSopenharmony_ci// 43b877906bSopenharmony_cistatic int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib) 44b877906bSopenharmony_ci{ 45b877906bSopenharmony_ci int value; 46b877906bSopenharmony_ci glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value); 47b877906bSopenharmony_ci return value; 48b877906bSopenharmony_ci} 49b877906bSopenharmony_ci 50b877906bSopenharmony_ci// Return the GLXFBConfig most closely matching the specified hints 51b877906bSopenharmony_ci// 52b877906bSopenharmony_cistatic GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, 53b877906bSopenharmony_ci GLXFBConfig* result) 54b877906bSopenharmony_ci{ 55b877906bSopenharmony_ci GLXFBConfig* nativeConfigs; 56b877906bSopenharmony_ci _GLFWfbconfig* usableConfigs; 57b877906bSopenharmony_ci const _GLFWfbconfig* closest; 58b877906bSopenharmony_ci int nativeCount, usableCount; 59b877906bSopenharmony_ci const char* vendor; 60b877906bSopenharmony_ci GLFWbool trustWindowBit = GLFW_TRUE; 61b877906bSopenharmony_ci 62b877906bSopenharmony_ci // HACK: This is a (hopefully temporary) workaround for Chromium 63b877906bSopenharmony_ci // (VirtualBox GL) not setting the window bit on any GLXFBConfigs 64b877906bSopenharmony_ci vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR); 65b877906bSopenharmony_ci if (vendor && strcmp(vendor, "Chromium") == 0) 66b877906bSopenharmony_ci trustWindowBit = GLFW_FALSE; 67b877906bSopenharmony_ci 68b877906bSopenharmony_ci nativeConfigs = 69b877906bSopenharmony_ci glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount); 70b877906bSopenharmony_ci if (!nativeConfigs || !nativeCount) 71b877906bSopenharmony_ci { 72b877906bSopenharmony_ci _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned"); 73b877906bSopenharmony_ci return GLFW_FALSE; 74b877906bSopenharmony_ci } 75b877906bSopenharmony_ci 76b877906bSopenharmony_ci usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig)); 77b877906bSopenharmony_ci usableCount = 0; 78b877906bSopenharmony_ci 79b877906bSopenharmony_ci for (int i = 0; i < nativeCount; i++) 80b877906bSopenharmony_ci { 81b877906bSopenharmony_ci const GLXFBConfig n = nativeConfigs[i]; 82b877906bSopenharmony_ci _GLFWfbconfig* u = usableConfigs + usableCount; 83b877906bSopenharmony_ci 84b877906bSopenharmony_ci // Only consider RGBA GLXFBConfigs 85b877906bSopenharmony_ci if (!(getGLXFBConfigAttrib(n, GLX_RENDER_TYPE) & GLX_RGBA_BIT)) 86b877906bSopenharmony_ci continue; 87b877906bSopenharmony_ci 88b877906bSopenharmony_ci // Only consider window GLXFBConfigs 89b877906bSopenharmony_ci if (!(getGLXFBConfigAttrib(n, GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT)) 90b877906bSopenharmony_ci { 91b877906bSopenharmony_ci if (trustWindowBit) 92b877906bSopenharmony_ci continue; 93b877906bSopenharmony_ci } 94b877906bSopenharmony_ci 95b877906bSopenharmony_ci if (getGLXFBConfigAttrib(n, GLX_DOUBLEBUFFER) != desired->doublebuffer) 96b877906bSopenharmony_ci continue; 97b877906bSopenharmony_ci 98b877906bSopenharmony_ci if (desired->transparent) 99b877906bSopenharmony_ci { 100b877906bSopenharmony_ci XVisualInfo* vi = glXGetVisualFromFBConfig(_glfw.x11.display, n); 101b877906bSopenharmony_ci if (vi) 102b877906bSopenharmony_ci { 103b877906bSopenharmony_ci u->transparent = _glfwIsVisualTransparentX11(vi->visual); 104b877906bSopenharmony_ci XFree(vi); 105b877906bSopenharmony_ci } 106b877906bSopenharmony_ci } 107b877906bSopenharmony_ci 108b877906bSopenharmony_ci u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE); 109b877906bSopenharmony_ci u->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE); 110b877906bSopenharmony_ci u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE); 111b877906bSopenharmony_ci 112b877906bSopenharmony_ci u->alphaBits = getGLXFBConfigAttrib(n, GLX_ALPHA_SIZE); 113b877906bSopenharmony_ci u->depthBits = getGLXFBConfigAttrib(n, GLX_DEPTH_SIZE); 114b877906bSopenharmony_ci u->stencilBits = getGLXFBConfigAttrib(n, GLX_STENCIL_SIZE); 115b877906bSopenharmony_ci 116b877906bSopenharmony_ci u->accumRedBits = getGLXFBConfigAttrib(n, GLX_ACCUM_RED_SIZE); 117b877906bSopenharmony_ci u->accumGreenBits = getGLXFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE); 118b877906bSopenharmony_ci u->accumBlueBits = getGLXFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE); 119b877906bSopenharmony_ci u->accumAlphaBits = getGLXFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE); 120b877906bSopenharmony_ci 121b877906bSopenharmony_ci u->auxBuffers = getGLXFBConfigAttrib(n, GLX_AUX_BUFFERS); 122b877906bSopenharmony_ci 123b877906bSopenharmony_ci if (getGLXFBConfigAttrib(n, GLX_STEREO)) 124b877906bSopenharmony_ci u->stereo = GLFW_TRUE; 125b877906bSopenharmony_ci 126b877906bSopenharmony_ci if (_glfw.glx.ARB_multisample) 127b877906bSopenharmony_ci u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES); 128b877906bSopenharmony_ci 129b877906bSopenharmony_ci if (_glfw.glx.ARB_framebuffer_sRGB || _glfw.glx.EXT_framebuffer_sRGB) 130b877906bSopenharmony_ci u->sRGB = getGLXFBConfigAttrib(n, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB); 131b877906bSopenharmony_ci 132b877906bSopenharmony_ci u->handle = (uintptr_t) n; 133b877906bSopenharmony_ci usableCount++; 134b877906bSopenharmony_ci } 135b877906bSopenharmony_ci 136b877906bSopenharmony_ci closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); 137b877906bSopenharmony_ci if (closest) 138b877906bSopenharmony_ci *result = (GLXFBConfig) closest->handle; 139b877906bSopenharmony_ci 140b877906bSopenharmony_ci XFree(nativeConfigs); 141b877906bSopenharmony_ci _glfw_free(usableConfigs); 142b877906bSopenharmony_ci 143b877906bSopenharmony_ci return closest != NULL; 144b877906bSopenharmony_ci} 145b877906bSopenharmony_ci 146b877906bSopenharmony_ci// Create the OpenGL context using legacy API 147b877906bSopenharmony_ci// 148b877906bSopenharmony_cistatic GLXContext createLegacyContextGLX(_GLFWwindow* window, 149b877906bSopenharmony_ci GLXFBConfig fbconfig, 150b877906bSopenharmony_ci GLXContext share) 151b877906bSopenharmony_ci{ 152b877906bSopenharmony_ci return glXCreateNewContext(_glfw.x11.display, 153b877906bSopenharmony_ci fbconfig, 154b877906bSopenharmony_ci GLX_RGBA_TYPE, 155b877906bSopenharmony_ci share, 156b877906bSopenharmony_ci True); 157b877906bSopenharmony_ci} 158b877906bSopenharmony_ci 159b877906bSopenharmony_cistatic void makeContextCurrentGLX(_GLFWwindow* window) 160b877906bSopenharmony_ci{ 161b877906bSopenharmony_ci if (window) 162b877906bSopenharmony_ci { 163b877906bSopenharmony_ci if (!glXMakeCurrent(_glfw.x11.display, 164b877906bSopenharmony_ci window->context.glx.window, 165b877906bSopenharmony_ci window->context.glx.handle)) 166b877906bSopenharmony_ci { 167b877906bSopenharmony_ci _glfwInputError(GLFW_PLATFORM_ERROR, 168b877906bSopenharmony_ci "GLX: Failed to make context current"); 169b877906bSopenharmony_ci return; 170b877906bSopenharmony_ci } 171b877906bSopenharmony_ci } 172b877906bSopenharmony_ci else 173b877906bSopenharmony_ci { 174b877906bSopenharmony_ci if (!glXMakeCurrent(_glfw.x11.display, None, NULL)) 175b877906bSopenharmony_ci { 176b877906bSopenharmony_ci _glfwInputError(GLFW_PLATFORM_ERROR, 177b877906bSopenharmony_ci "GLX: Failed to clear current context"); 178b877906bSopenharmony_ci return; 179b877906bSopenharmony_ci } 180b877906bSopenharmony_ci } 181b877906bSopenharmony_ci 182b877906bSopenharmony_ci _glfwPlatformSetTls(&_glfw.contextSlot, window); 183b877906bSopenharmony_ci} 184b877906bSopenharmony_ci 185b877906bSopenharmony_cistatic void swapBuffersGLX(_GLFWwindow* window) 186b877906bSopenharmony_ci{ 187b877906bSopenharmony_ci glXSwapBuffers(_glfw.x11.display, window->context.glx.window); 188b877906bSopenharmony_ci} 189b877906bSopenharmony_ci 190b877906bSopenharmony_cistatic void swapIntervalGLX(int interval) 191b877906bSopenharmony_ci{ 192b877906bSopenharmony_ci _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); 193b877906bSopenharmony_ci assert(window != NULL); 194b877906bSopenharmony_ci 195b877906bSopenharmony_ci if (_glfw.glx.EXT_swap_control) 196b877906bSopenharmony_ci { 197b877906bSopenharmony_ci _glfw.glx.SwapIntervalEXT(_glfw.x11.display, 198b877906bSopenharmony_ci window->context.glx.window, 199b877906bSopenharmony_ci interval); 200b877906bSopenharmony_ci } 201b877906bSopenharmony_ci else if (_glfw.glx.MESA_swap_control) 202b877906bSopenharmony_ci _glfw.glx.SwapIntervalMESA(interval); 203b877906bSopenharmony_ci else if (_glfw.glx.SGI_swap_control) 204b877906bSopenharmony_ci { 205b877906bSopenharmony_ci if (interval > 0) 206b877906bSopenharmony_ci _glfw.glx.SwapIntervalSGI(interval); 207b877906bSopenharmony_ci } 208b877906bSopenharmony_ci} 209b877906bSopenharmony_ci 210b877906bSopenharmony_cistatic int extensionSupportedGLX(const char* extension) 211b877906bSopenharmony_ci{ 212b877906bSopenharmony_ci const char* extensions = 213b877906bSopenharmony_ci glXQueryExtensionsString(_glfw.x11.display, _glfw.x11.screen); 214b877906bSopenharmony_ci if (extensions) 215b877906bSopenharmony_ci { 216b877906bSopenharmony_ci if (_glfwStringInExtensionString(extension, extensions)) 217b877906bSopenharmony_ci return GLFW_TRUE; 218b877906bSopenharmony_ci } 219b877906bSopenharmony_ci 220b877906bSopenharmony_ci return GLFW_FALSE; 221b877906bSopenharmony_ci} 222b877906bSopenharmony_ci 223b877906bSopenharmony_cistatic GLFWglproc getProcAddressGLX(const char* procname) 224b877906bSopenharmony_ci{ 225b877906bSopenharmony_ci if (_glfw.glx.GetProcAddress) 226b877906bSopenharmony_ci return _glfw.glx.GetProcAddress((const GLubyte*) procname); 227b877906bSopenharmony_ci else if (_glfw.glx.GetProcAddressARB) 228b877906bSopenharmony_ci return _glfw.glx.GetProcAddressARB((const GLubyte*) procname); 229b877906bSopenharmony_ci else 230b877906bSopenharmony_ci { 231b877906bSopenharmony_ci // NOTE: glvnd provides GLX 1.4, so this can only happen with libGL 232b877906bSopenharmony_ci return _glfwPlatformGetModuleSymbol(_glfw.glx.handle, procname); 233b877906bSopenharmony_ci } 234b877906bSopenharmony_ci} 235b877906bSopenharmony_ci 236b877906bSopenharmony_cistatic void destroyContextGLX(_GLFWwindow* window) 237b877906bSopenharmony_ci{ 238b877906bSopenharmony_ci if (window->context.glx.window) 239b877906bSopenharmony_ci { 240b877906bSopenharmony_ci glXDestroyWindow(_glfw.x11.display, window->context.glx.window); 241b877906bSopenharmony_ci window->context.glx.window = None; 242b877906bSopenharmony_ci } 243b877906bSopenharmony_ci 244b877906bSopenharmony_ci if (window->context.glx.handle) 245b877906bSopenharmony_ci { 246b877906bSopenharmony_ci glXDestroyContext(_glfw.x11.display, window->context.glx.handle); 247b877906bSopenharmony_ci window->context.glx.handle = NULL; 248b877906bSopenharmony_ci } 249b877906bSopenharmony_ci} 250b877906bSopenharmony_ci 251b877906bSopenharmony_ci 252b877906bSopenharmony_ci////////////////////////////////////////////////////////////////////////// 253b877906bSopenharmony_ci////// GLFW internal API ////// 254b877906bSopenharmony_ci////////////////////////////////////////////////////////////////////////// 255b877906bSopenharmony_ci 256b877906bSopenharmony_ci// Initialize GLX 257b877906bSopenharmony_ci// 258b877906bSopenharmony_ciGLFWbool _glfwInitGLX(void) 259b877906bSopenharmony_ci{ 260b877906bSopenharmony_ci const char* sonames[] = 261b877906bSopenharmony_ci { 262b877906bSopenharmony_ci#if defined(_GLFW_GLX_LIBRARY) 263b877906bSopenharmony_ci _GLFW_GLX_LIBRARY, 264b877906bSopenharmony_ci#elif defined(__CYGWIN__) 265b877906bSopenharmony_ci "libGL-1.so", 266b877906bSopenharmony_ci#elif defined(__OpenBSD__) || defined(__NetBSD__) 267b877906bSopenharmony_ci "libGL.so", 268b877906bSopenharmony_ci#else 269b877906bSopenharmony_ci "libGLX.so.0", 270b877906bSopenharmony_ci "libGL.so.1", 271b877906bSopenharmony_ci "libGL.so", 272b877906bSopenharmony_ci#endif 273b877906bSopenharmony_ci NULL 274b877906bSopenharmony_ci }; 275b877906bSopenharmony_ci 276b877906bSopenharmony_ci if (_glfw.glx.handle) 277b877906bSopenharmony_ci return GLFW_TRUE; 278b877906bSopenharmony_ci 279b877906bSopenharmony_ci for (int i = 0; sonames[i]; i++) 280b877906bSopenharmony_ci { 281b877906bSopenharmony_ci _glfw.glx.handle = _glfwPlatformLoadModule(sonames[i]); 282b877906bSopenharmony_ci if (_glfw.glx.handle) 283b877906bSopenharmony_ci break; 284b877906bSopenharmony_ci } 285b877906bSopenharmony_ci 286b877906bSopenharmony_ci if (!_glfw.glx.handle) 287b877906bSopenharmony_ci { 288b877906bSopenharmony_ci _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: Failed to load GLX"); 289b877906bSopenharmony_ci return GLFW_FALSE; 290b877906bSopenharmony_ci } 291b877906bSopenharmony_ci 292b877906bSopenharmony_ci _glfw.glx.GetFBConfigs = (PFNGLXGETFBCONFIGSPROC) 293b877906bSopenharmony_ci _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetFBConfigs"); 294b877906bSopenharmony_ci _glfw.glx.GetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC) 295b877906bSopenharmony_ci _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetFBConfigAttrib"); 296b877906bSopenharmony_ci _glfw.glx.GetClientString = (PFNGLXGETCLIENTSTRINGPROC) 297b877906bSopenharmony_ci _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetClientString"); 298b877906bSopenharmony_ci _glfw.glx.QueryExtension = (PFNGLXQUERYEXTENSIONPROC) 299b877906bSopenharmony_ci _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXQueryExtension"); 300b877906bSopenharmony_ci _glfw.glx.QueryVersion = (PFNGLXQUERYVERSIONPROC) 301b877906bSopenharmony_ci _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXQueryVersion"); 302b877906bSopenharmony_ci _glfw.glx.DestroyContext = (PFNGLXDESTROYCONTEXTPROC) 303b877906bSopenharmony_ci _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXDestroyContext"); 304b877906bSopenharmony_ci _glfw.glx.MakeCurrent = (PFNGLXMAKECURRENTPROC) 305b877906bSopenharmony_ci _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXMakeCurrent"); 306b877906bSopenharmony_ci _glfw.glx.SwapBuffers = (PFNGLXSWAPBUFFERSPROC) 307b877906bSopenharmony_ci _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXSwapBuffers"); 308b877906bSopenharmony_ci _glfw.glx.QueryExtensionsString = (PFNGLXQUERYEXTENSIONSSTRINGPROC) 309b877906bSopenharmony_ci _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXQueryExtensionsString"); 310b877906bSopenharmony_ci _glfw.glx.CreateNewContext = (PFNGLXCREATENEWCONTEXTPROC) 311b877906bSopenharmony_ci _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXCreateNewContext"); 312b877906bSopenharmony_ci _glfw.glx.CreateWindow = (PFNGLXCREATEWINDOWPROC) 313b877906bSopenharmony_ci _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXCreateWindow"); 314b877906bSopenharmony_ci _glfw.glx.DestroyWindow = (PFNGLXDESTROYWINDOWPROC) 315b877906bSopenharmony_ci _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXDestroyWindow"); 316b877906bSopenharmony_ci _glfw.glx.GetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC) 317b877906bSopenharmony_ci _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetVisualFromFBConfig"); 318b877906bSopenharmony_ci 319b877906bSopenharmony_ci if (!_glfw.glx.GetFBConfigs || 320b877906bSopenharmony_ci !_glfw.glx.GetFBConfigAttrib || 321b877906bSopenharmony_ci !_glfw.glx.GetClientString || 322b877906bSopenharmony_ci !_glfw.glx.QueryExtension || 323b877906bSopenharmony_ci !_glfw.glx.QueryVersion || 324b877906bSopenharmony_ci !_glfw.glx.DestroyContext || 325b877906bSopenharmony_ci !_glfw.glx.MakeCurrent || 326b877906bSopenharmony_ci !_glfw.glx.SwapBuffers || 327b877906bSopenharmony_ci !_glfw.glx.QueryExtensionsString || 328b877906bSopenharmony_ci !_glfw.glx.CreateNewContext || 329b877906bSopenharmony_ci !_glfw.glx.CreateWindow || 330b877906bSopenharmony_ci !_glfw.glx.DestroyWindow || 331b877906bSopenharmony_ci !_glfw.glx.GetVisualFromFBConfig) 332b877906bSopenharmony_ci { 333b877906bSopenharmony_ci _glfwInputError(GLFW_PLATFORM_ERROR, 334b877906bSopenharmony_ci "GLX: Failed to load required entry points"); 335b877906bSopenharmony_ci return GLFW_FALSE; 336b877906bSopenharmony_ci } 337b877906bSopenharmony_ci 338b877906bSopenharmony_ci // NOTE: Unlike GLX 1.3 entry points these are not required to be present 339b877906bSopenharmony_ci _glfw.glx.GetProcAddress = (PFNGLXGETPROCADDRESSPROC) 340b877906bSopenharmony_ci _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetProcAddress"); 341b877906bSopenharmony_ci _glfw.glx.GetProcAddressARB = (PFNGLXGETPROCADDRESSPROC) 342b877906bSopenharmony_ci _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetProcAddressARB"); 343b877906bSopenharmony_ci 344b877906bSopenharmony_ci if (!glXQueryExtension(_glfw.x11.display, 345b877906bSopenharmony_ci &_glfw.glx.errorBase, 346b877906bSopenharmony_ci &_glfw.glx.eventBase)) 347b877906bSopenharmony_ci { 348b877906bSopenharmony_ci _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: GLX extension not found"); 349b877906bSopenharmony_ci return GLFW_FALSE; 350b877906bSopenharmony_ci } 351b877906bSopenharmony_ci 352b877906bSopenharmony_ci if (!glXQueryVersion(_glfw.x11.display, &_glfw.glx.major, &_glfw.glx.minor)) 353b877906bSopenharmony_ci { 354b877906bSopenharmony_ci _glfwInputError(GLFW_API_UNAVAILABLE, 355b877906bSopenharmony_ci "GLX: Failed to query GLX version"); 356b877906bSopenharmony_ci return GLFW_FALSE; 357b877906bSopenharmony_ci } 358b877906bSopenharmony_ci 359b877906bSopenharmony_ci if (_glfw.glx.major == 1 && _glfw.glx.minor < 3) 360b877906bSopenharmony_ci { 361b877906bSopenharmony_ci _glfwInputError(GLFW_API_UNAVAILABLE, 362b877906bSopenharmony_ci "GLX: GLX version 1.3 is required"); 363b877906bSopenharmony_ci return GLFW_FALSE; 364b877906bSopenharmony_ci } 365b877906bSopenharmony_ci 366b877906bSopenharmony_ci if (extensionSupportedGLX("GLX_EXT_swap_control")) 367b877906bSopenharmony_ci { 368b877906bSopenharmony_ci _glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) 369b877906bSopenharmony_ci getProcAddressGLX("glXSwapIntervalEXT"); 370b877906bSopenharmony_ci 371b877906bSopenharmony_ci if (_glfw.glx.SwapIntervalEXT) 372b877906bSopenharmony_ci _glfw.glx.EXT_swap_control = GLFW_TRUE; 373b877906bSopenharmony_ci } 374b877906bSopenharmony_ci 375b877906bSopenharmony_ci if (extensionSupportedGLX("GLX_SGI_swap_control")) 376b877906bSopenharmony_ci { 377b877906bSopenharmony_ci _glfw.glx.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) 378b877906bSopenharmony_ci getProcAddressGLX("glXSwapIntervalSGI"); 379b877906bSopenharmony_ci 380b877906bSopenharmony_ci if (_glfw.glx.SwapIntervalSGI) 381b877906bSopenharmony_ci _glfw.glx.SGI_swap_control = GLFW_TRUE; 382b877906bSopenharmony_ci } 383b877906bSopenharmony_ci 384b877906bSopenharmony_ci if (extensionSupportedGLX("GLX_MESA_swap_control")) 385b877906bSopenharmony_ci { 386b877906bSopenharmony_ci _glfw.glx.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC) 387b877906bSopenharmony_ci getProcAddressGLX("glXSwapIntervalMESA"); 388b877906bSopenharmony_ci 389b877906bSopenharmony_ci if (_glfw.glx.SwapIntervalMESA) 390b877906bSopenharmony_ci _glfw.glx.MESA_swap_control = GLFW_TRUE; 391b877906bSopenharmony_ci } 392b877906bSopenharmony_ci 393b877906bSopenharmony_ci if (extensionSupportedGLX("GLX_ARB_multisample")) 394b877906bSopenharmony_ci _glfw.glx.ARB_multisample = GLFW_TRUE; 395b877906bSopenharmony_ci 396b877906bSopenharmony_ci if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB")) 397b877906bSopenharmony_ci _glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE; 398b877906bSopenharmony_ci 399b877906bSopenharmony_ci if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB")) 400b877906bSopenharmony_ci _glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE; 401b877906bSopenharmony_ci 402b877906bSopenharmony_ci if (extensionSupportedGLX("GLX_ARB_create_context")) 403b877906bSopenharmony_ci { 404b877906bSopenharmony_ci _glfw.glx.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) 405b877906bSopenharmony_ci getProcAddressGLX("glXCreateContextAttribsARB"); 406b877906bSopenharmony_ci 407b877906bSopenharmony_ci if (_glfw.glx.CreateContextAttribsARB) 408b877906bSopenharmony_ci _glfw.glx.ARB_create_context = GLFW_TRUE; 409b877906bSopenharmony_ci } 410b877906bSopenharmony_ci 411b877906bSopenharmony_ci if (extensionSupportedGLX("GLX_ARB_create_context_robustness")) 412b877906bSopenharmony_ci _glfw.glx.ARB_create_context_robustness = GLFW_TRUE; 413b877906bSopenharmony_ci 414b877906bSopenharmony_ci if (extensionSupportedGLX("GLX_ARB_create_context_profile")) 415b877906bSopenharmony_ci _glfw.glx.ARB_create_context_profile = GLFW_TRUE; 416b877906bSopenharmony_ci 417b877906bSopenharmony_ci if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile")) 418b877906bSopenharmony_ci _glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE; 419b877906bSopenharmony_ci 420b877906bSopenharmony_ci if (extensionSupportedGLX("GLX_ARB_create_context_no_error")) 421b877906bSopenharmony_ci _glfw.glx.ARB_create_context_no_error = GLFW_TRUE; 422b877906bSopenharmony_ci 423b877906bSopenharmony_ci if (extensionSupportedGLX("GLX_ARB_context_flush_control")) 424b877906bSopenharmony_ci _glfw.glx.ARB_context_flush_control = GLFW_TRUE; 425b877906bSopenharmony_ci 426b877906bSopenharmony_ci return GLFW_TRUE; 427b877906bSopenharmony_ci} 428b877906bSopenharmony_ci 429b877906bSopenharmony_ci// Terminate GLX 430b877906bSopenharmony_ci// 431b877906bSopenharmony_civoid _glfwTerminateGLX(void) 432b877906bSopenharmony_ci{ 433b877906bSopenharmony_ci // NOTE: This function must not call any X11 functions, as it is called 434b877906bSopenharmony_ci // after XCloseDisplay (see _glfwTerminateX11 for details) 435b877906bSopenharmony_ci 436b877906bSopenharmony_ci if (_glfw.glx.handle) 437b877906bSopenharmony_ci { 438b877906bSopenharmony_ci _glfwPlatformFreeModule(_glfw.glx.handle); 439b877906bSopenharmony_ci _glfw.glx.handle = NULL; 440b877906bSopenharmony_ci } 441b877906bSopenharmony_ci} 442b877906bSopenharmony_ci 443b877906bSopenharmony_ci#define SET_ATTRIB(a, v) \ 444b877906bSopenharmony_ci{ \ 445b877906bSopenharmony_ci assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ 446b877906bSopenharmony_ci attribs[index++] = a; \ 447b877906bSopenharmony_ci attribs[index++] = v; \ 448b877906bSopenharmony_ci} 449b877906bSopenharmony_ci 450b877906bSopenharmony_ci// Create the OpenGL or OpenGL ES context 451b877906bSopenharmony_ci// 452b877906bSopenharmony_ciGLFWbool _glfwCreateContextGLX(_GLFWwindow* window, 453b877906bSopenharmony_ci const _GLFWctxconfig* ctxconfig, 454b877906bSopenharmony_ci const _GLFWfbconfig* fbconfig) 455b877906bSopenharmony_ci{ 456b877906bSopenharmony_ci int attribs[40]; 457b877906bSopenharmony_ci GLXFBConfig native = NULL; 458b877906bSopenharmony_ci GLXContext share = NULL; 459b877906bSopenharmony_ci 460b877906bSopenharmony_ci if (ctxconfig->share) 461b877906bSopenharmony_ci share = ctxconfig->share->context.glx.handle; 462b877906bSopenharmony_ci 463b877906bSopenharmony_ci if (!chooseGLXFBConfig(fbconfig, &native)) 464b877906bSopenharmony_ci { 465b877906bSopenharmony_ci _glfwInputError(GLFW_FORMAT_UNAVAILABLE, 466b877906bSopenharmony_ci "GLX: Failed to find a suitable GLXFBConfig"); 467b877906bSopenharmony_ci return GLFW_FALSE; 468b877906bSopenharmony_ci } 469b877906bSopenharmony_ci 470b877906bSopenharmony_ci if (ctxconfig->client == GLFW_OPENGL_ES_API) 471b877906bSopenharmony_ci { 472b877906bSopenharmony_ci if (!_glfw.glx.ARB_create_context || 473b877906bSopenharmony_ci !_glfw.glx.ARB_create_context_profile || 474b877906bSopenharmony_ci !_glfw.glx.EXT_create_context_es2_profile) 475b877906bSopenharmony_ci { 476b877906bSopenharmony_ci _glfwInputError(GLFW_API_UNAVAILABLE, 477b877906bSopenharmony_ci "GLX: OpenGL ES requested but GLX_EXT_create_context_es2_profile is unavailable"); 478b877906bSopenharmony_ci return GLFW_FALSE; 479b877906bSopenharmony_ci } 480b877906bSopenharmony_ci } 481b877906bSopenharmony_ci 482b877906bSopenharmony_ci if (ctxconfig->forward) 483b877906bSopenharmony_ci { 484b877906bSopenharmony_ci if (!_glfw.glx.ARB_create_context) 485b877906bSopenharmony_ci { 486b877906bSopenharmony_ci _glfwInputError(GLFW_VERSION_UNAVAILABLE, 487b877906bSopenharmony_ci "GLX: Forward compatibility requested but GLX_ARB_create_context_profile is unavailable"); 488b877906bSopenharmony_ci return GLFW_FALSE; 489b877906bSopenharmony_ci } 490b877906bSopenharmony_ci } 491b877906bSopenharmony_ci 492b877906bSopenharmony_ci if (ctxconfig->profile) 493b877906bSopenharmony_ci { 494b877906bSopenharmony_ci if (!_glfw.glx.ARB_create_context || 495b877906bSopenharmony_ci !_glfw.glx.ARB_create_context_profile) 496b877906bSopenharmony_ci { 497b877906bSopenharmony_ci _glfwInputError(GLFW_VERSION_UNAVAILABLE, 498b877906bSopenharmony_ci "GLX: An OpenGL profile requested but GLX_ARB_create_context_profile is unavailable"); 499b877906bSopenharmony_ci return GLFW_FALSE; 500b877906bSopenharmony_ci } 501b877906bSopenharmony_ci } 502b877906bSopenharmony_ci 503b877906bSopenharmony_ci _glfwGrabErrorHandlerX11(); 504b877906bSopenharmony_ci 505b877906bSopenharmony_ci if (_glfw.glx.ARB_create_context) 506b877906bSopenharmony_ci { 507b877906bSopenharmony_ci int index = 0, mask = 0, flags = 0; 508b877906bSopenharmony_ci 509b877906bSopenharmony_ci if (ctxconfig->client == GLFW_OPENGL_API) 510b877906bSopenharmony_ci { 511b877906bSopenharmony_ci if (ctxconfig->forward) 512b877906bSopenharmony_ci flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; 513b877906bSopenharmony_ci 514b877906bSopenharmony_ci if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) 515b877906bSopenharmony_ci mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB; 516b877906bSopenharmony_ci else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) 517b877906bSopenharmony_ci mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; 518b877906bSopenharmony_ci } 519b877906bSopenharmony_ci else 520b877906bSopenharmony_ci mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT; 521b877906bSopenharmony_ci 522b877906bSopenharmony_ci if (ctxconfig->debug) 523b877906bSopenharmony_ci flags |= GLX_CONTEXT_DEBUG_BIT_ARB; 524b877906bSopenharmony_ci 525b877906bSopenharmony_ci if (ctxconfig->robustness) 526b877906bSopenharmony_ci { 527b877906bSopenharmony_ci if (_glfw.glx.ARB_create_context_robustness) 528b877906bSopenharmony_ci { 529b877906bSopenharmony_ci if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) 530b877906bSopenharmony_ci { 531b877906bSopenharmony_ci SET_ATTRIB(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, 532b877906bSopenharmony_ci GLX_NO_RESET_NOTIFICATION_ARB); 533b877906bSopenharmony_ci } 534b877906bSopenharmony_ci else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) 535b877906bSopenharmony_ci { 536b877906bSopenharmony_ci SET_ATTRIB(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, 537b877906bSopenharmony_ci GLX_LOSE_CONTEXT_ON_RESET_ARB); 538b877906bSopenharmony_ci } 539b877906bSopenharmony_ci 540b877906bSopenharmony_ci flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB; 541b877906bSopenharmony_ci } 542b877906bSopenharmony_ci } 543b877906bSopenharmony_ci 544b877906bSopenharmony_ci if (ctxconfig->release) 545b877906bSopenharmony_ci { 546b877906bSopenharmony_ci if (_glfw.glx.ARB_context_flush_control) 547b877906bSopenharmony_ci { 548b877906bSopenharmony_ci if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) 549b877906bSopenharmony_ci { 550b877906bSopenharmony_ci SET_ATTRIB(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, 551b877906bSopenharmony_ci GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); 552b877906bSopenharmony_ci } 553b877906bSopenharmony_ci else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) 554b877906bSopenharmony_ci { 555b877906bSopenharmony_ci SET_ATTRIB(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, 556b877906bSopenharmony_ci GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); 557b877906bSopenharmony_ci } 558b877906bSopenharmony_ci } 559b877906bSopenharmony_ci } 560b877906bSopenharmony_ci 561b877906bSopenharmony_ci if (ctxconfig->noerror) 562b877906bSopenharmony_ci { 563b877906bSopenharmony_ci if (_glfw.glx.ARB_create_context_no_error) 564b877906bSopenharmony_ci SET_ATTRIB(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE); 565b877906bSopenharmony_ci } 566b877906bSopenharmony_ci 567b877906bSopenharmony_ci // NOTE: Only request an explicitly versioned context when necessary, as 568b877906bSopenharmony_ci // explicitly requesting version 1.0 does not always return the 569b877906bSopenharmony_ci // highest version supported by the driver 570b877906bSopenharmony_ci if (ctxconfig->major != 1 || ctxconfig->minor != 0) 571b877906bSopenharmony_ci { 572b877906bSopenharmony_ci SET_ATTRIB(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); 573b877906bSopenharmony_ci SET_ATTRIB(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); 574b877906bSopenharmony_ci } 575b877906bSopenharmony_ci 576b877906bSopenharmony_ci if (mask) 577b877906bSopenharmony_ci SET_ATTRIB(GLX_CONTEXT_PROFILE_MASK_ARB, mask); 578b877906bSopenharmony_ci 579b877906bSopenharmony_ci if (flags) 580b877906bSopenharmony_ci SET_ATTRIB(GLX_CONTEXT_FLAGS_ARB, flags); 581b877906bSopenharmony_ci 582b877906bSopenharmony_ci SET_ATTRIB(None, None); 583b877906bSopenharmony_ci 584b877906bSopenharmony_ci window->context.glx.handle = 585b877906bSopenharmony_ci _glfw.glx.CreateContextAttribsARB(_glfw.x11.display, 586b877906bSopenharmony_ci native, 587b877906bSopenharmony_ci share, 588b877906bSopenharmony_ci True, 589b877906bSopenharmony_ci attribs); 590b877906bSopenharmony_ci 591b877906bSopenharmony_ci // HACK: This is a fallback for broken versions of the Mesa 592b877906bSopenharmony_ci // implementation of GLX_ARB_create_context_profile that fail 593b877906bSopenharmony_ci // default 1.0 context creation with a GLXBadProfileARB error in 594b877906bSopenharmony_ci // violation of the extension spec 595b877906bSopenharmony_ci if (!window->context.glx.handle) 596b877906bSopenharmony_ci { 597b877906bSopenharmony_ci if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB && 598b877906bSopenharmony_ci ctxconfig->client == GLFW_OPENGL_API && 599b877906bSopenharmony_ci ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE && 600b877906bSopenharmony_ci ctxconfig->forward == GLFW_FALSE) 601b877906bSopenharmony_ci { 602b877906bSopenharmony_ci window->context.glx.handle = 603b877906bSopenharmony_ci createLegacyContextGLX(window, native, share); 604b877906bSopenharmony_ci } 605b877906bSopenharmony_ci } 606b877906bSopenharmony_ci } 607b877906bSopenharmony_ci else 608b877906bSopenharmony_ci { 609b877906bSopenharmony_ci window->context.glx.handle = 610b877906bSopenharmony_ci createLegacyContextGLX(window, native, share); 611b877906bSopenharmony_ci } 612b877906bSopenharmony_ci 613b877906bSopenharmony_ci _glfwReleaseErrorHandlerX11(); 614b877906bSopenharmony_ci 615b877906bSopenharmony_ci if (!window->context.glx.handle) 616b877906bSopenharmony_ci { 617b877906bSopenharmony_ci _glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context"); 618b877906bSopenharmony_ci return GLFW_FALSE; 619b877906bSopenharmony_ci } 620b877906bSopenharmony_ci 621b877906bSopenharmony_ci window->context.glx.window = 622b877906bSopenharmony_ci glXCreateWindow(_glfw.x11.display, native, window->x11.handle, NULL); 623b877906bSopenharmony_ci if (!window->context.glx.window) 624b877906bSopenharmony_ci { 625b877906bSopenharmony_ci _glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window"); 626b877906bSopenharmony_ci return GLFW_FALSE; 627b877906bSopenharmony_ci } 628b877906bSopenharmony_ci 629b877906bSopenharmony_ci window->context.makeCurrent = makeContextCurrentGLX; 630b877906bSopenharmony_ci window->context.swapBuffers = swapBuffersGLX; 631b877906bSopenharmony_ci window->context.swapInterval = swapIntervalGLX; 632b877906bSopenharmony_ci window->context.extensionSupported = extensionSupportedGLX; 633b877906bSopenharmony_ci window->context.getProcAddress = getProcAddressGLX; 634b877906bSopenharmony_ci window->context.destroy = destroyContextGLX; 635b877906bSopenharmony_ci 636b877906bSopenharmony_ci return GLFW_TRUE; 637b877906bSopenharmony_ci} 638b877906bSopenharmony_ci 639b877906bSopenharmony_ci#undef SET_ATTRIB 640b877906bSopenharmony_ci 641b877906bSopenharmony_ci// Returns the Visual and depth of the chosen GLXFBConfig 642b877906bSopenharmony_ci// 643b877906bSopenharmony_ciGLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig, 644b877906bSopenharmony_ci const _GLFWctxconfig* ctxconfig, 645b877906bSopenharmony_ci const _GLFWfbconfig* fbconfig, 646b877906bSopenharmony_ci Visual** visual, int* depth) 647b877906bSopenharmony_ci{ 648b877906bSopenharmony_ci GLXFBConfig native; 649b877906bSopenharmony_ci XVisualInfo* result; 650b877906bSopenharmony_ci 651b877906bSopenharmony_ci if (!chooseGLXFBConfig(fbconfig, &native)) 652b877906bSopenharmony_ci { 653b877906bSopenharmony_ci _glfwInputError(GLFW_FORMAT_UNAVAILABLE, 654b877906bSopenharmony_ci "GLX: Failed to find a suitable GLXFBConfig"); 655b877906bSopenharmony_ci return GLFW_FALSE; 656b877906bSopenharmony_ci } 657b877906bSopenharmony_ci 658b877906bSopenharmony_ci result = glXGetVisualFromFBConfig(_glfw.x11.display, native); 659b877906bSopenharmony_ci if (!result) 660b877906bSopenharmony_ci { 661b877906bSopenharmony_ci _glfwInputError(GLFW_PLATFORM_ERROR, 662b877906bSopenharmony_ci "GLX: Failed to retrieve Visual for GLXFBConfig"); 663b877906bSopenharmony_ci return GLFW_FALSE; 664b877906bSopenharmony_ci } 665b877906bSopenharmony_ci 666b877906bSopenharmony_ci *visual = result->visual; 667b877906bSopenharmony_ci *depth = result->depth; 668b877906bSopenharmony_ci 669b877906bSopenharmony_ci XFree(result); 670b877906bSopenharmony_ci return GLFW_TRUE; 671b877906bSopenharmony_ci} 672b877906bSopenharmony_ci 673b877906bSopenharmony_ci 674b877906bSopenharmony_ci////////////////////////////////////////////////////////////////////////// 675b877906bSopenharmony_ci////// GLFW native API ////// 676b877906bSopenharmony_ci////////////////////////////////////////////////////////////////////////// 677b877906bSopenharmony_ci 678b877906bSopenharmony_ciGLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle) 679b877906bSopenharmony_ci{ 680b877906bSopenharmony_ci _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 681b877906bSopenharmony_ci 682b877906bSopenharmony_ci if (_glfw.platform.platformID != GLFW_PLATFORM_X11) 683b877906bSopenharmony_ci { 684b877906bSopenharmony_ci _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "GLX: Platform not initialized"); 685b877906bSopenharmony_ci return NULL; 686b877906bSopenharmony_ci } 687b877906bSopenharmony_ci 688b877906bSopenharmony_ci _GLFWwindow* window = (_GLFWwindow*) handle; 689b877906bSopenharmony_ci assert(window != NULL); 690b877906bSopenharmony_ci 691b877906bSopenharmony_ci if (window->context.source != GLFW_NATIVE_CONTEXT_API) 692b877906bSopenharmony_ci { 693b877906bSopenharmony_ci _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); 694b877906bSopenharmony_ci return NULL; 695b877906bSopenharmony_ci } 696b877906bSopenharmony_ci 697b877906bSopenharmony_ci return window->context.glx.handle; 698b877906bSopenharmony_ci} 699b877906bSopenharmony_ci 700b877906bSopenharmony_ciGLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle) 701b877906bSopenharmony_ci{ 702b877906bSopenharmony_ci _GLFW_REQUIRE_INIT_OR_RETURN(None); 703b877906bSopenharmony_ci 704b877906bSopenharmony_ci if (_glfw.platform.platformID != GLFW_PLATFORM_X11) 705b877906bSopenharmony_ci { 706b877906bSopenharmony_ci _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "GLX: Platform not initialized"); 707b877906bSopenharmony_ci return None; 708b877906bSopenharmony_ci } 709b877906bSopenharmony_ci 710b877906bSopenharmony_ci _GLFWwindow* window = (_GLFWwindow*) handle; 711b877906bSopenharmony_ci assert(window != NULL); 712b877906bSopenharmony_ci 713b877906bSopenharmony_ci if (window->context.source != GLFW_NATIVE_CONTEXT_API) 714b877906bSopenharmony_ci { 715b877906bSopenharmony_ci _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); 716b877906bSopenharmony_ci return None; 717b877906bSopenharmony_ci } 718b877906bSopenharmony_ci 719b877906bSopenharmony_ci return window->context.glx.window; 720b877906bSopenharmony_ci} 721b877906bSopenharmony_ci 722b877906bSopenharmony_ci#endif // _GLFW_X11 723b877906bSopenharmony_ci 724