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 | |