| 1 | /** |
| 2 | * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 |
| 3 | */ |
| 4 | #include <stdio.h> |
| 5 | #include <stdlib.h> |
| 6 | #include <string.h> |
| 7 | #include <glad/glx.h> |
| 8 | |
| 9 | #ifndef GLAD_IMPL_UTIL_C_ |
| 10 | #define GLAD_IMPL_UTIL_C_ |
| 11 | |
| 12 | #ifdef _MSC_VER |
| 13 | #define GLAD_IMPL_UTIL_SSCANF sscanf_s |
| 14 | #else |
| 15 | #define GLAD_IMPL_UTIL_SSCANF sscanf |
| 16 | #endif |
| 17 | |
| 18 | #endif /* GLAD_IMPL_UTIL_C_ */ |
| 19 | |
| 20 | #ifdef __cplusplus |
| 21 | extern "C" { |
| 22 | #endif |
| 23 | |
| 24 | |
| 25 | |
| 26 | int GLAD_GLX_VERSION_1_0 = 0; |
| 27 | int GLAD_GLX_VERSION_1_1 = 0; |
| 28 | int GLAD_GLX_VERSION_1_2 = 0; |
| 29 | int GLAD_GLX_VERSION_1_3 = 0; |
| 30 | int GLAD_GLX_VERSION_1_4 = 0; |
| 31 | int GLAD_GLX_ARB_create_context = 0; |
| 32 | int GLAD_GLX_ARB_create_context_profile = 0; |
| 33 | int GLAD_GLX_ARB_get_proc_address = 0; |
| 34 | int GLAD_GLX_EXT_swap_control = 0; |
| 35 | int GLAD_GLX_MESA_swap_control = 0; |
| 36 | int GLAD_GLX_SGI_swap_control = 0; |
| 37 | |
| 38 | |
| 39 | |
| 40 | PFNGLXCHOOSEFBCONFIGPROC glad_glXChooseFBConfig = NULL; |
| 41 | PFNGLXCHOOSEVISUALPROC glad_glXChooseVisual = NULL; |
| 42 | PFNGLXCOPYCONTEXTPROC glad_glXCopyContext = NULL; |
| 43 | PFNGLXCREATECONTEXTPROC glad_glXCreateContext = NULL; |
| 44 | PFNGLXCREATECONTEXTATTRIBSARBPROC glad_glXCreateContextAttribsARB = NULL; |
| 45 | PFNGLXCREATEGLXPIXMAPPROC glad_glXCreateGLXPixmap = NULL; |
| 46 | PFNGLXCREATENEWCONTEXTPROC glad_glXCreateNewContext = NULL; |
| 47 | PFNGLXCREATEPBUFFERPROC glad_glXCreatePbuffer = NULL; |
| 48 | PFNGLXCREATEPIXMAPPROC glad_glXCreatePixmap = NULL; |
| 49 | PFNGLXCREATEWINDOWPROC glad_glXCreateWindow = NULL; |
| 50 | PFNGLXDESTROYCONTEXTPROC glad_glXDestroyContext = NULL; |
| 51 | PFNGLXDESTROYGLXPIXMAPPROC glad_glXDestroyGLXPixmap = NULL; |
| 52 | PFNGLXDESTROYPBUFFERPROC glad_glXDestroyPbuffer = NULL; |
| 53 | PFNGLXDESTROYPIXMAPPROC glad_glXDestroyPixmap = NULL; |
| 54 | PFNGLXDESTROYWINDOWPROC glad_glXDestroyWindow = NULL; |
| 55 | PFNGLXGETCLIENTSTRINGPROC glad_glXGetClientString = NULL; |
| 56 | PFNGLXGETCONFIGPROC glad_glXGetConfig = NULL; |
| 57 | PFNGLXGETCURRENTCONTEXTPROC glad_glXGetCurrentContext = NULL; |
| 58 | PFNGLXGETCURRENTDISPLAYPROC glad_glXGetCurrentDisplay = NULL; |
| 59 | PFNGLXGETCURRENTDRAWABLEPROC glad_glXGetCurrentDrawable = NULL; |
| 60 | PFNGLXGETCURRENTREADDRAWABLEPROC glad_glXGetCurrentReadDrawable = NULL; |
| 61 | PFNGLXGETFBCONFIGATTRIBPROC glad_glXGetFBConfigAttrib = NULL; |
| 62 | PFNGLXGETFBCONFIGSPROC glad_glXGetFBConfigs = NULL; |
| 63 | PFNGLXGETPROCADDRESSPROC glad_glXGetProcAddress = NULL; |
| 64 | PFNGLXGETPROCADDRESSARBPROC glad_glXGetProcAddressARB = NULL; |
| 65 | PFNGLXGETSELECTEDEVENTPROC glad_glXGetSelectedEvent = NULL; |
| 66 | PFNGLXGETSWAPINTERVALMESAPROC glad_glXGetSwapIntervalMESA = NULL; |
| 67 | PFNGLXGETVISUALFROMFBCONFIGPROC glad_glXGetVisualFromFBConfig = NULL; |
| 68 | PFNGLXISDIRECTPROC glad_glXIsDirect = NULL; |
| 69 | PFNGLXMAKECONTEXTCURRENTPROC glad_glXMakeContextCurrent = NULL; |
| 70 | PFNGLXMAKECURRENTPROC glad_glXMakeCurrent = NULL; |
| 71 | PFNGLXQUERYCONTEXTPROC glad_glXQueryContext = NULL; |
| 72 | PFNGLXQUERYDRAWABLEPROC glad_glXQueryDrawable = NULL; |
| 73 | PFNGLXQUERYEXTENSIONPROC glad_glXQueryExtension = NULL; |
| 74 | PFNGLXQUERYEXTENSIONSSTRINGPROC glad_glXQueryExtensionsString = NULL; |
| 75 | PFNGLXQUERYSERVERSTRINGPROC glad_glXQueryServerString = NULL; |
| 76 | PFNGLXQUERYVERSIONPROC glad_glXQueryVersion = NULL; |
| 77 | PFNGLXSELECTEVENTPROC glad_glXSelectEvent = NULL; |
| 78 | PFNGLXSWAPBUFFERSPROC glad_glXSwapBuffers = NULL; |
| 79 | PFNGLXSWAPINTERVALEXTPROC glad_glXSwapIntervalEXT = NULL; |
| 80 | PFNGLXSWAPINTERVALMESAPROC glad_glXSwapIntervalMESA = NULL; |
| 81 | PFNGLXSWAPINTERVALSGIPROC glad_glXSwapIntervalSGI = NULL; |
| 82 | PFNGLXUSEXFONTPROC glad_glXUseXFont = NULL; |
| 83 | PFNGLXWAITGLPROC glad_glXWaitGL = NULL; |
| 84 | PFNGLXWAITXPROC glad_glXWaitX = NULL; |
| 85 | |
| 86 | |
| 87 | static void glad_glx_load_GLX_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) { |
| 88 | if(!GLAD_GLX_VERSION_1_0) return; |
| 89 | glad_glXChooseVisual = (PFNGLXCHOOSEVISUALPROC) load(userptr, "glXChooseVisual" ); |
| 90 | glad_glXCopyContext = (PFNGLXCOPYCONTEXTPROC) load(userptr, "glXCopyContext" ); |
| 91 | glad_glXCreateContext = (PFNGLXCREATECONTEXTPROC) load(userptr, "glXCreateContext" ); |
| 92 | glad_glXCreateGLXPixmap = (PFNGLXCREATEGLXPIXMAPPROC) load(userptr, "glXCreateGLXPixmap" ); |
| 93 | glad_glXDestroyContext = (PFNGLXDESTROYCONTEXTPROC) load(userptr, "glXDestroyContext" ); |
| 94 | glad_glXDestroyGLXPixmap = (PFNGLXDESTROYGLXPIXMAPPROC) load(userptr, "glXDestroyGLXPixmap" ); |
| 95 | glad_glXGetConfig = (PFNGLXGETCONFIGPROC) load(userptr, "glXGetConfig" ); |
| 96 | glad_glXGetCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC) load(userptr, "glXGetCurrentContext" ); |
| 97 | glad_glXGetCurrentDrawable = (PFNGLXGETCURRENTDRAWABLEPROC) load(userptr, "glXGetCurrentDrawable" ); |
| 98 | glad_glXIsDirect = (PFNGLXISDIRECTPROC) load(userptr, "glXIsDirect" ); |
| 99 | glad_glXMakeCurrent = (PFNGLXMAKECURRENTPROC) load(userptr, "glXMakeCurrent" ); |
| 100 | glad_glXQueryExtension = (PFNGLXQUERYEXTENSIONPROC) load(userptr, "glXQueryExtension" ); |
| 101 | glad_glXQueryVersion = (PFNGLXQUERYVERSIONPROC) load(userptr, "glXQueryVersion" ); |
| 102 | glad_glXSwapBuffers = (PFNGLXSWAPBUFFERSPROC) load(userptr, "glXSwapBuffers" ); |
| 103 | glad_glXUseXFont = (PFNGLXUSEXFONTPROC) load(userptr, "glXUseXFont" ); |
| 104 | glad_glXWaitGL = (PFNGLXWAITGLPROC) load(userptr, "glXWaitGL" ); |
| 105 | glad_glXWaitX = (PFNGLXWAITXPROC) load(userptr, "glXWaitX" ); |
| 106 | } |
| 107 | static void glad_glx_load_GLX_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) { |
| 108 | if(!GLAD_GLX_VERSION_1_1) return; |
| 109 | glad_glXGetClientString = (PFNGLXGETCLIENTSTRINGPROC) load(userptr, "glXGetClientString" ); |
| 110 | glad_glXQueryExtensionsString = (PFNGLXQUERYEXTENSIONSSTRINGPROC) load(userptr, "glXQueryExtensionsString" ); |
| 111 | glad_glXQueryServerString = (PFNGLXQUERYSERVERSTRINGPROC) load(userptr, "glXQueryServerString" ); |
| 112 | } |
| 113 | static void glad_glx_load_GLX_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) { |
| 114 | if(!GLAD_GLX_VERSION_1_2) return; |
| 115 | glad_glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC) load(userptr, "glXGetCurrentDisplay" ); |
| 116 | } |
| 117 | static void glad_glx_load_GLX_VERSION_1_3( GLADuserptrloadfunc load, void* userptr) { |
| 118 | if(!GLAD_GLX_VERSION_1_3) return; |
| 119 | glad_glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) load(userptr, "glXChooseFBConfig" ); |
| 120 | glad_glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC) load(userptr, "glXCreateNewContext" ); |
| 121 | glad_glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC) load(userptr, "glXCreatePbuffer" ); |
| 122 | glad_glXCreatePixmap = (PFNGLXCREATEPIXMAPPROC) load(userptr, "glXCreatePixmap" ); |
| 123 | glad_glXCreateWindow = (PFNGLXCREATEWINDOWPROC) load(userptr, "glXCreateWindow" ); |
| 124 | glad_glXDestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) load(userptr, "glXDestroyPbuffer" ); |
| 125 | glad_glXDestroyPixmap = (PFNGLXDESTROYPIXMAPPROC) load(userptr, "glXDestroyPixmap" ); |
| 126 | glad_glXDestroyWindow = (PFNGLXDESTROYWINDOWPROC) load(userptr, "glXDestroyWindow" ); |
| 127 | glad_glXGetCurrentReadDrawable = (PFNGLXGETCURRENTREADDRAWABLEPROC) load(userptr, "glXGetCurrentReadDrawable" ); |
| 128 | glad_glXGetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC) load(userptr, "glXGetFBConfigAttrib" ); |
| 129 | glad_glXGetFBConfigs = (PFNGLXGETFBCONFIGSPROC) load(userptr, "glXGetFBConfigs" ); |
| 130 | glad_glXGetSelectedEvent = (PFNGLXGETSELECTEDEVENTPROC) load(userptr, "glXGetSelectedEvent" ); |
| 131 | glad_glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC) load(userptr, "glXGetVisualFromFBConfig" ); |
| 132 | glad_glXMakeContextCurrent = (PFNGLXMAKECONTEXTCURRENTPROC) load(userptr, "glXMakeContextCurrent" ); |
| 133 | glad_glXQueryContext = (PFNGLXQUERYCONTEXTPROC) load(userptr, "glXQueryContext" ); |
| 134 | glad_glXQueryDrawable = (PFNGLXQUERYDRAWABLEPROC) load(userptr, "glXQueryDrawable" ); |
| 135 | glad_glXSelectEvent = (PFNGLXSELECTEVENTPROC) load(userptr, "glXSelectEvent" ); |
| 136 | } |
| 137 | static void glad_glx_load_GLX_VERSION_1_4( GLADuserptrloadfunc load, void* userptr) { |
| 138 | if(!GLAD_GLX_VERSION_1_4) return; |
| 139 | glad_glXGetProcAddress = (PFNGLXGETPROCADDRESSPROC) load(userptr, "glXGetProcAddress" ); |
| 140 | } |
| 141 | static void glad_glx_load_GLX_ARB_create_context( GLADuserptrloadfunc load, void* userptr) { |
| 142 | if(!GLAD_GLX_ARB_create_context) return; |
| 143 | glad_glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) load(userptr, "glXCreateContextAttribsARB" ); |
| 144 | } |
| 145 | static void glad_glx_load_GLX_ARB_get_proc_address( GLADuserptrloadfunc load, void* userptr) { |
| 146 | if(!GLAD_GLX_ARB_get_proc_address) return; |
| 147 | glad_glXGetProcAddressARB = (PFNGLXGETPROCADDRESSARBPROC) load(userptr, "glXGetProcAddressARB" ); |
| 148 | } |
| 149 | static void glad_glx_load_GLX_EXT_swap_control( GLADuserptrloadfunc load, void* userptr) { |
| 150 | if(!GLAD_GLX_EXT_swap_control) return; |
| 151 | glad_glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) load(userptr, "glXSwapIntervalEXT" ); |
| 152 | } |
| 153 | static void glad_glx_load_GLX_MESA_swap_control( GLADuserptrloadfunc load, void* userptr) { |
| 154 | if(!GLAD_GLX_MESA_swap_control) return; |
| 155 | glad_glXGetSwapIntervalMESA = (PFNGLXGETSWAPINTERVALMESAPROC) load(userptr, "glXGetSwapIntervalMESA" ); |
| 156 | glad_glXSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC) load(userptr, "glXSwapIntervalMESA" ); |
| 157 | } |
| 158 | static void glad_glx_load_GLX_SGI_swap_control( GLADuserptrloadfunc load, void* userptr) { |
| 159 | if(!GLAD_GLX_SGI_swap_control) return; |
| 160 | glad_glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) load(userptr, "glXSwapIntervalSGI" ); |
| 161 | } |
| 162 | |
| 163 | |
| 164 | |
| 165 | static int glad_glx_has_extension(Display *display, int screen, const char *ext) { |
| 166 | #ifndef GLX_VERSION_1_1 |
| 167 | GLAD_UNUSED(display); |
| 168 | GLAD_UNUSED(screen); |
| 169 | GLAD_UNUSED(ext); |
| 170 | #else |
| 171 | const char *terminator; |
| 172 | const char *loc; |
| 173 | const char *extensions; |
| 174 | |
| 175 | if (glXQueryExtensionsString == NULL) { |
| 176 | return 0; |
| 177 | } |
| 178 | |
| 179 | extensions = glXQueryExtensionsString(display, screen); |
| 180 | |
| 181 | if(extensions == NULL || ext == NULL) { |
| 182 | return 0; |
| 183 | } |
| 184 | |
| 185 | while(1) { |
| 186 | loc = strstr(extensions, ext); |
| 187 | if(loc == NULL) |
| 188 | break; |
| 189 | |
| 190 | terminator = loc + strlen(ext); |
| 191 | if((loc == extensions || *(loc - 1) == ' ') && |
| 192 | (*terminator == ' ' || *terminator == '\0')) { |
| 193 | return 1; |
| 194 | } |
| 195 | extensions = terminator; |
| 196 | } |
| 197 | #endif |
| 198 | |
| 199 | return 0; |
| 200 | } |
| 201 | |
| 202 | static GLADapiproc glad_glx_get_proc_from_userptr(void *userptr, const char* name) { |
| 203 | return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); |
| 204 | } |
| 205 | |
| 206 | static int glad_glx_find_extensions(Display *display, int screen) { |
| 207 | GLAD_GLX_ARB_create_context = glad_glx_has_extension(display, screen, "GLX_ARB_create_context" ); |
| 208 | GLAD_GLX_ARB_create_context_profile = glad_glx_has_extension(display, screen, "GLX_ARB_create_context_profile" ); |
| 209 | GLAD_GLX_ARB_get_proc_address = glad_glx_has_extension(display, screen, "GLX_ARB_get_proc_address" ); |
| 210 | GLAD_GLX_EXT_swap_control = glad_glx_has_extension(display, screen, "GLX_EXT_swap_control" ); |
| 211 | GLAD_GLX_MESA_swap_control = glad_glx_has_extension(display, screen, "GLX_MESA_swap_control" ); |
| 212 | GLAD_GLX_SGI_swap_control = glad_glx_has_extension(display, screen, "GLX_SGI_swap_control" ); |
| 213 | return 1; |
| 214 | } |
| 215 | |
| 216 | static int glad_glx_find_core_glx(Display **display, int *screen) { |
| 217 | int major = 0, minor = 0; |
| 218 | if(*display == NULL) { |
| 219 | #ifdef GLAD_GLX_NO_X11 |
| 220 | GLAD_UNUSED(screen); |
| 221 | return 0; |
| 222 | #else |
| 223 | *display = XOpenDisplay(0); |
| 224 | if (*display == NULL) { |
| 225 | return 0; |
| 226 | } |
| 227 | *screen = XScreenNumberOfScreen(XDefaultScreenOfDisplay(*display)); |
| 228 | #endif |
| 229 | } |
| 230 | glXQueryVersion(*display, &major, &minor); |
| 231 | GLAD_GLX_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; |
| 232 | GLAD_GLX_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; |
| 233 | GLAD_GLX_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; |
| 234 | GLAD_GLX_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; |
| 235 | GLAD_GLX_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; |
| 236 | return GLAD_MAKE_VERSION(major, minor); |
| 237 | } |
| 238 | |
| 239 | int gladLoadGLXUserPtr(Display *display, int screen, GLADuserptrloadfunc load, void *userptr) { |
| 240 | int version; |
| 241 | glXQueryVersion = (PFNGLXQUERYVERSIONPROC) load(userptr, "glXQueryVersion" ); |
| 242 | if(glXQueryVersion == NULL) return 0; |
| 243 | version = glad_glx_find_core_glx(&display, &screen); |
| 244 | |
| 245 | glad_glx_load_GLX_VERSION_1_0(load, userptr); |
| 246 | glad_glx_load_GLX_VERSION_1_1(load, userptr); |
| 247 | glad_glx_load_GLX_VERSION_1_2(load, userptr); |
| 248 | glad_glx_load_GLX_VERSION_1_3(load, userptr); |
| 249 | glad_glx_load_GLX_VERSION_1_4(load, userptr); |
| 250 | |
| 251 | if (!glad_glx_find_extensions(display, screen)) return 0; |
| 252 | glad_glx_load_GLX_ARB_create_context(load, userptr); |
| 253 | glad_glx_load_GLX_ARB_get_proc_address(load, userptr); |
| 254 | glad_glx_load_GLX_EXT_swap_control(load, userptr); |
| 255 | glad_glx_load_GLX_MESA_swap_control(load, userptr); |
| 256 | glad_glx_load_GLX_SGI_swap_control(load, userptr); |
| 257 | |
| 258 | |
| 259 | return version; |
| 260 | } |
| 261 | |
| 262 | int gladLoadGLX(Display *display, int screen, GLADloadfunc load) { |
| 263 | return gladLoadGLXUserPtr(display, screen, glad_glx_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); |
| 264 | } |
| 265 | |
| 266 | |
| 267 | |
| 268 | #ifdef GLAD_GLX |
| 269 | |
| 270 | #ifndef GLAD_LOADER_LIBRARY_C_ |
| 271 | #define GLAD_LOADER_LIBRARY_C_ |
| 272 | |
| 273 | #include <stddef.h> |
| 274 | #include <stdlib.h> |
| 275 | |
| 276 | #if GLAD_PLATFORM_WIN32 |
| 277 | #include <windows.h> |
| 278 | #else |
| 279 | #include <dlfcn.h> |
| 280 | #endif |
| 281 | |
| 282 | |
| 283 | static void* glad_get_dlopen_handle(const char *lib_names[], int length) { |
| 284 | void *handle = NULL; |
| 285 | int i; |
| 286 | |
| 287 | for (i = 0; i < length; ++i) { |
| 288 | #if GLAD_PLATFORM_WIN32 |
| 289 | #if GLAD_PLATFORM_UWP |
| 290 | size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR); |
| 291 | LPWSTR buffer = (LPWSTR) malloc(buffer_size); |
| 292 | if (buffer != NULL) { |
| 293 | int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size); |
| 294 | if (ret != 0) { |
| 295 | handle = (void*) LoadPackagedLibrary(buffer, 0); |
| 296 | } |
| 297 | free((void*) buffer); |
| 298 | } |
| 299 | #else |
| 300 | handle = (void*) LoadLibraryA(lib_names[i]); |
| 301 | #endif |
| 302 | #else |
| 303 | handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL); |
| 304 | #endif |
| 305 | if (handle != NULL) { |
| 306 | return handle; |
| 307 | } |
| 308 | } |
| 309 | |
| 310 | return NULL; |
| 311 | } |
| 312 | |
| 313 | static void glad_close_dlopen_handle(void* handle) { |
| 314 | if (handle != NULL) { |
| 315 | #if GLAD_PLATFORM_WIN32 |
| 316 | FreeLibrary((HMODULE) handle); |
| 317 | #else |
| 318 | dlclose(handle); |
| 319 | #endif |
| 320 | } |
| 321 | } |
| 322 | |
| 323 | static GLADapiproc glad_dlsym_handle(void* handle, const char *name) { |
| 324 | if (handle == NULL) { |
| 325 | return NULL; |
| 326 | } |
| 327 | |
| 328 | #if GLAD_PLATFORM_WIN32 |
| 329 | return (GLADapiproc) GetProcAddress((HMODULE) handle, name); |
| 330 | #else |
| 331 | return GLAD_GNUC_EXTENSION (GLADapiproc) dlsym(handle, name); |
| 332 | #endif |
| 333 | } |
| 334 | |
| 335 | #endif /* GLAD_LOADER_LIBRARY_C_ */ |
| 336 | |
| 337 | typedef void* (GLAD_API_PTR *GLADglxprocaddrfunc)(const char*); |
| 338 | |
| 339 | static GLADapiproc glad_glx_get_proc(void *userptr, const char *name) { |
| 340 | return GLAD_GNUC_EXTENSION ((GLADapiproc (*)(const char *name)) userptr)(name); |
| 341 | } |
| 342 | |
| 343 | static void* _glx_handle; |
| 344 | |
| 345 | static void* glad_glx_dlopen_handle(void) { |
| 346 | static const char *NAMES[] = { |
| 347 | #if defined __CYGWIN__ |
| 348 | "libGL-1.so" , |
| 349 | #endif |
| 350 | "libGL.so.1" , |
| 351 | "libGL.so" |
| 352 | }; |
| 353 | |
| 354 | if (_glx_handle == NULL) { |
| 355 | _glx_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0])); |
| 356 | } |
| 357 | |
| 358 | return _glx_handle; |
| 359 | } |
| 360 | |
| 361 | int gladLoaderLoadGLX(Display *display, int screen) { |
| 362 | int version = 0; |
| 363 | void *handle = NULL; |
| 364 | int did_load = 0; |
| 365 | GLADglxprocaddrfunc loader; |
| 366 | |
| 367 | did_load = _glx_handle == NULL; |
| 368 | handle = glad_glx_dlopen_handle(); |
| 369 | if (handle != NULL) { |
| 370 | loader = (GLADglxprocaddrfunc) glad_dlsym_handle(handle, "glXGetProcAddressARB" ); |
| 371 | if (loader != NULL) { |
| 372 | version = gladLoadGLXUserPtr(display, screen, glad_glx_get_proc, GLAD_GNUC_EXTENSION (void*) loader); |
| 373 | } |
| 374 | |
| 375 | if (!version && did_load) { |
| 376 | gladLoaderUnloadGLX(); |
| 377 | } |
| 378 | } |
| 379 | |
| 380 | return version; |
| 381 | } |
| 382 | |
| 383 | |
| 384 | void gladLoaderUnloadGLX() { |
| 385 | if (_glx_handle != NULL) { |
| 386 | glad_close_dlopen_handle(_glx_handle); |
| 387 | _glx_handle = NULL; |
| 388 | } |
| 389 | } |
| 390 | |
| 391 | #endif /* GLAD_GLX */ |
| 392 | |
| 393 | #ifdef __cplusplus |
| 394 | } |
| 395 | #endif |
| 396 | |