Atlas - glx_context.c

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