glfw3.c 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/GLFW/CMakeLists.txt +368 -0
  2. package/GLFW/cocoa_init.m +694 -0
  3. package/GLFW/cocoa_joystick.h +49 -0
  4. package/GLFW/cocoa_joystick.m +485 -0
  5. package/GLFW/cocoa_monitor.m +643 -0
  6. package/GLFW/cocoa_platform.h +302 -0
  7. package/GLFW/cocoa_time.c +57 -0
  8. package/GLFW/cocoa_time.h +35 -0
  9. package/GLFW/cocoa_window.m +2072 -0
  10. package/GLFW/context.c +765 -0
  11. package/GLFW/egl_context.c +911 -0
  12. package/GLFW/glfw.rc.in +30 -0
  13. package/GLFW/glfw3.c +109 -0
  14. package/GLFW/glfw3.h +6564 -0
  15. package/GLFW/glfw3native.h +663 -0
  16. package/GLFW/glx_context.c +719 -0
  17. package/GLFW/init.c +528 -0
  18. package/GLFW/input.c +1505 -0
  19. package/GLFW/internal.h +1022 -0
  20. package/GLFW/linux_joystick.c +436 -0
  21. package/GLFW/linux_joystick.h +64 -0
  22. package/GLFW/mappings.h +1001 -0
  23. package/GLFW/mappings.h.in +82 -0
  24. package/GLFW/monitor.c +548 -0
  25. package/GLFW/nsgl_context.m +384 -0
  26. package/GLFW/null_init.c +264 -0
  27. package/GLFW/null_joystick.c +56 -0
  28. package/GLFW/null_joystick.h +32 -0
  29. package/GLFW/null_monitor.c +160 -0
  30. package/GLFW/null_platform.h +271 -0
  31. package/GLFW/null_window.c +719 -0
  32. package/GLFW/osmesa_context.c +383 -0
  33. package/GLFW/platform.c +214 -0
  34. package/GLFW/platform.h +212 -0
  35. package/GLFW/posix_module.c +53 -0
  36. package/GLFW/posix_poll.c +83 -0
  37. package/GLFW/posix_poll.h +30 -0
  38. package/GLFW/posix_thread.c +107 -0
  39. package/GLFW/posix_thread.h +49 -0
  40. package/GLFW/posix_time.c +65 -0
  41. package/GLFW/posix_time.h +41 -0
  42. package/GLFW/vulkan.c +328 -0
  43. package/GLFW/wgl_context.c +798 -0
  44. package/GLFW/win32_init.c +731 -0
  45. package/GLFW/win32_joystick.c +767 -0
  46. package/GLFW/win32_joystick.h +51 -0
  47. package/GLFW/win32_module.c +51 -0
  48. package/GLFW/win32_monitor.c +569 -0
  49. package/GLFW/win32_platform.h +631 -0
  50. package/GLFW/win32_thread.c +100 -0
  51. package/GLFW/win32_thread.h +53 -0
  52. package/GLFW/win32_time.c +54 -0
  53. package/GLFW/win32_time.h +43 -0
  54. package/GLFW/win32_window.c +2592 -0
  55. package/GLFW/window.c +1172 -0
  56. package/GLFW/wl_init.c +1003 -0
  57. package/GLFW/wl_monitor.c +274 -0
  58. package/GLFW/wl_platform.h +691 -0
  59. package/GLFW/wl_window.c +3308 -0
  60. package/GLFW/x11_init.c +1656 -0
  61. package/GLFW/x11_monitor.c +641 -0
  62. package/GLFW/x11_platform.h +1004 -0
  63. package/GLFW/x11_window.c +3357 -0
  64. package/GLFW/xkb_unicode.c +943 -0
  65. package/GLFW/xkb_unicode.h +30 -0
  66. package/LICENSE +22 -0
  67. package/README.md +236 -0
  68. package/package.json +32 -0
@@ -0,0 +1,911 @@
1
+ //========================================================================
2
+ // GLFW 3.4 EGL - www.glfw.org
3
+ //------------------------------------------------------------------------
4
+ // Copyright (c) 2002-2006 Marcus Geelnard
5
+ // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
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
+ #include <stdio.h>
31
+ #include <string.h>
32
+ #include <stdlib.h>
33
+ #include <assert.h>
34
+
35
+
36
+ // Return a description of the specified EGL error
37
+ //
38
+ static const char* getEGLErrorString(EGLint error)
39
+ {
40
+ switch (error)
41
+ {
42
+ case EGL_SUCCESS:
43
+ return "Success";
44
+ case EGL_NOT_INITIALIZED:
45
+ return "EGL is not or could not be initialized";
46
+ case EGL_BAD_ACCESS:
47
+ return "EGL cannot access a requested resource";
48
+ case EGL_BAD_ALLOC:
49
+ return "EGL failed to allocate resources for the requested operation";
50
+ case EGL_BAD_ATTRIBUTE:
51
+ return "An unrecognized attribute or attribute value was passed in the attribute list";
52
+ case EGL_BAD_CONTEXT:
53
+ return "An EGLContext argument does not name a valid EGL rendering context";
54
+ case EGL_BAD_CONFIG:
55
+ return "An EGLConfig argument does not name a valid EGL frame buffer configuration";
56
+ case EGL_BAD_CURRENT_SURFACE:
57
+ return "The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer valid";
58
+ case EGL_BAD_DISPLAY:
59
+ return "An EGLDisplay argument does not name a valid EGL display connection";
60
+ case EGL_BAD_SURFACE:
61
+ return "An EGLSurface argument does not name a valid surface configured for GL rendering";
62
+ case EGL_BAD_MATCH:
63
+ return "Arguments are inconsistent";
64
+ case EGL_BAD_PARAMETER:
65
+ return "One or more argument values are invalid";
66
+ case EGL_BAD_NATIVE_PIXMAP:
67
+ return "A NativePixmapType argument does not refer to a valid native pixmap";
68
+ case EGL_BAD_NATIVE_WINDOW:
69
+ return "A NativeWindowType argument does not refer to a valid native window";
70
+ case EGL_CONTEXT_LOST:
71
+ return "The application must destroy all contexts and reinitialise";
72
+ default:
73
+ return "ERROR: UNKNOWN EGL ERROR";
74
+ }
75
+ }
76
+
77
+ // Returns the specified attribute of the specified EGLConfig
78
+ //
79
+ static int getEGLConfigAttrib(EGLConfig config, int attrib)
80
+ {
81
+ int value;
82
+ eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value);
83
+ return value;
84
+ }
85
+
86
+ // Return the EGLConfig most closely matching the specified hints
87
+ //
88
+ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
89
+ const _GLFWfbconfig* fbconfig,
90
+ EGLConfig* result)
91
+ {
92
+ EGLConfig* nativeConfigs;
93
+ _GLFWfbconfig* usableConfigs;
94
+ const _GLFWfbconfig* closest;
95
+ int i, nativeCount, usableCount, apiBit;
96
+ GLFWbool wrongApiAvailable = GLFW_FALSE;
97
+
98
+ if (ctxconfig->client == GLFW_OPENGL_ES_API)
99
+ {
100
+ if (ctxconfig->major == 1)
101
+ apiBit = EGL_OPENGL_ES_BIT;
102
+ else
103
+ apiBit = EGL_OPENGL_ES2_BIT;
104
+ }
105
+ else
106
+ apiBit = EGL_OPENGL_BIT;
107
+
108
+ if (fbconfig->stereo)
109
+ {
110
+ _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Stereo rendering not supported");
111
+ return GLFW_FALSE;
112
+ }
113
+
114
+ eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount);
115
+ if (!nativeCount)
116
+ {
117
+ _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned");
118
+ return GLFW_FALSE;
119
+ }
120
+
121
+ nativeConfigs = _glfw_calloc(nativeCount, sizeof(EGLConfig));
122
+ eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount);
123
+
124
+ usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
125
+ usableCount = 0;
126
+
127
+ for (i = 0; i < nativeCount; i++)
128
+ {
129
+ const EGLConfig n = nativeConfigs[i];
130
+ _GLFWfbconfig* u = usableConfigs + usableCount;
131
+
132
+ // Only consider RGB(A) EGLConfigs
133
+ if (getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER)
134
+ continue;
135
+
136
+ // Only consider window EGLConfigs
137
+ if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT))
138
+ continue;
139
+
140
+ #if defined(_GLFW_X11)
141
+ if (_glfw.platform.platformID == GLFW_PLATFORM_X11)
142
+ {
143
+ XVisualInfo vi = {0};
144
+
145
+ // Only consider EGLConfigs with associated Visuals
146
+ vi.visualid = getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID);
147
+ if (!vi.visualid)
148
+ continue;
149
+
150
+ if (fbconfig->transparent)
151
+ {
152
+ int count;
153
+ XVisualInfo* vis =
154
+ XGetVisualInfo(_glfw.x11.display, VisualIDMask, &vi, &count);
155
+ if (vis)
156
+ {
157
+ u->transparent = _glfwIsVisualTransparentX11(vis[0].visual);
158
+ XFree(vis);
159
+ }
160
+ }
161
+ }
162
+ #endif // _GLFW_X11
163
+
164
+ if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & apiBit))
165
+ {
166
+ wrongApiAvailable = GLFW_TRUE;
167
+ continue;
168
+ }
169
+
170
+ u->redBits = getEGLConfigAttrib(n, EGL_RED_SIZE);
171
+ u->greenBits = getEGLConfigAttrib(n, EGL_GREEN_SIZE);
172
+ u->blueBits = getEGLConfigAttrib(n, EGL_BLUE_SIZE);
173
+
174
+ u->alphaBits = getEGLConfigAttrib(n, EGL_ALPHA_SIZE);
175
+ u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_SIZE);
176
+ u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE);
177
+
178
+ #if defined(_GLFW_WAYLAND)
179
+ if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
180
+ {
181
+ // NOTE: The wl_surface opaque region is no guarantee that its buffer
182
+ // is presented as opaque, if it also has an alpha channel
183
+ // HACK: If EGL_EXT_present_opaque is unavailable, ignore any config
184
+ // with an alpha channel to ensure the buffer is opaque
185
+ if (!_glfw.egl.EXT_present_opaque)
186
+ {
187
+ if (!fbconfig->transparent && u->alphaBits > 0)
188
+ continue;
189
+ }
190
+ }
191
+ #endif // _GLFW_WAYLAND
192
+
193
+ u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);
194
+ u->doublebuffer = fbconfig->doublebuffer;
195
+
196
+ u->handle = (uintptr_t) n;
197
+ usableCount++;
198
+ }
199
+
200
+ closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
201
+ if (closest)
202
+ *result = (EGLConfig) closest->handle;
203
+ else
204
+ {
205
+ if (wrongApiAvailable)
206
+ {
207
+ if (ctxconfig->client == GLFW_OPENGL_ES_API)
208
+ {
209
+ if (ctxconfig->major == 1)
210
+ {
211
+ _glfwInputError(GLFW_API_UNAVAILABLE,
212
+ "EGL: Failed to find support for OpenGL ES 1.x");
213
+ }
214
+ else
215
+ {
216
+ _glfwInputError(GLFW_API_UNAVAILABLE,
217
+ "EGL: Failed to find support for OpenGL ES 2 or later");
218
+ }
219
+ }
220
+ else
221
+ {
222
+ _glfwInputError(GLFW_API_UNAVAILABLE,
223
+ "EGL: Failed to find support for OpenGL");
224
+ }
225
+ }
226
+ else
227
+ {
228
+ _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
229
+ "EGL: Failed to find a suitable EGLConfig");
230
+ }
231
+ }
232
+
233
+ _glfw_free(nativeConfigs);
234
+ _glfw_free(usableConfigs);
235
+
236
+ return closest != NULL;
237
+ }
238
+
239
+ static void makeContextCurrentEGL(_GLFWwindow* window)
240
+ {
241
+ if (window)
242
+ {
243
+ if (!eglMakeCurrent(_glfw.egl.display,
244
+ window->context.egl.surface,
245
+ window->context.egl.surface,
246
+ window->context.egl.handle))
247
+ {
248
+ _glfwInputError(GLFW_PLATFORM_ERROR,
249
+ "EGL: Failed to make context current: %s",
250
+ getEGLErrorString(eglGetError()));
251
+ return;
252
+ }
253
+ }
254
+ else
255
+ {
256
+ if (!eglMakeCurrent(_glfw.egl.display,
257
+ EGL_NO_SURFACE,
258
+ EGL_NO_SURFACE,
259
+ EGL_NO_CONTEXT))
260
+ {
261
+ _glfwInputError(GLFW_PLATFORM_ERROR,
262
+ "EGL: Failed to clear current context: %s",
263
+ getEGLErrorString(eglGetError()));
264
+ return;
265
+ }
266
+ }
267
+
268
+ _glfwPlatformSetTls(&_glfw.contextSlot, window);
269
+ }
270
+
271
+ static void swapBuffersEGL(_GLFWwindow* window)
272
+ {
273
+ if (window != _glfwPlatformGetTls(&_glfw.contextSlot))
274
+ {
275
+ _glfwInputError(GLFW_PLATFORM_ERROR,
276
+ "EGL: The context must be current on the calling thread when swapping buffers");
277
+ return;
278
+ }
279
+
280
+ #if defined(_GLFW_WAYLAND)
281
+ if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
282
+ {
283
+ // NOTE: Swapping buffers on a hidden window on Wayland makes it visible
284
+ if (!window->wl.visible)
285
+ return;
286
+ }
287
+ #endif
288
+
289
+ eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);
290
+ }
291
+
292
+ static void swapIntervalEGL(int interval)
293
+ {
294
+ eglSwapInterval(_glfw.egl.display, interval);
295
+ }
296
+
297
+ static int extensionSupportedEGL(const char* extension)
298
+ {
299
+ const char* extensions = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS);
300
+ if (extensions)
301
+ {
302
+ if (_glfwStringInExtensionString(extension, extensions))
303
+ return GLFW_TRUE;
304
+ }
305
+
306
+ return GLFW_FALSE;
307
+ }
308
+
309
+ static GLFWglproc getProcAddressEGL(const char* procname)
310
+ {
311
+ _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
312
+ assert(window != NULL);
313
+
314
+ if (window->context.egl.client)
315
+ {
316
+ GLFWglproc proc = (GLFWglproc)
317
+ _glfwPlatformGetModuleSymbol(window->context.egl.client, procname);
318
+ if (proc)
319
+ return proc;
320
+ }
321
+
322
+ return eglGetProcAddress(procname);
323
+ }
324
+
325
+ static void destroyContextEGL(_GLFWwindow* window)
326
+ {
327
+ // NOTE: Do not unload libGL.so.1 while the X11 display is still open,
328
+ // as it will make XCloseDisplay segfault
329
+ if (_glfw.platform.platformID != GLFW_PLATFORM_X11 ||
330
+ window->context.client != GLFW_OPENGL_API)
331
+ {
332
+ if (window->context.egl.client)
333
+ {
334
+ _glfwPlatformFreeModule(window->context.egl.client);
335
+ window->context.egl.client = NULL;
336
+ }
337
+ }
338
+
339
+ if (window->context.egl.surface)
340
+ {
341
+ eglDestroySurface(_glfw.egl.display, window->context.egl.surface);
342
+ window->context.egl.surface = EGL_NO_SURFACE;
343
+ }
344
+
345
+ if (window->context.egl.handle)
346
+ {
347
+ eglDestroyContext(_glfw.egl.display, window->context.egl.handle);
348
+ window->context.egl.handle = EGL_NO_CONTEXT;
349
+ }
350
+ }
351
+
352
+
353
+ //////////////////////////////////////////////////////////////////////////
354
+ ////// GLFW internal API //////
355
+ //////////////////////////////////////////////////////////////////////////
356
+
357
+ // Initialize EGL
358
+ //
359
+ GLFWbool _glfwInitEGL(void)
360
+ {
361
+ int i;
362
+ EGLint* attribs = NULL;
363
+ const char* extensions;
364
+ const char* sonames[] =
365
+ {
366
+ #if defined(_GLFW_EGL_LIBRARY)
367
+ _GLFW_EGL_LIBRARY,
368
+ #elif defined(_GLFW_WIN32)
369
+ "libEGL.dll",
370
+ "EGL.dll",
371
+ #elif defined(_GLFW_COCOA)
372
+ "libEGL.dylib",
373
+ #elif defined(__CYGWIN__)
374
+ "libEGL-1.so",
375
+ #elif defined(__OpenBSD__) || defined(__NetBSD__)
376
+ "libEGL.so",
377
+ #else
378
+ "libEGL.so.1",
379
+ #endif
380
+ NULL
381
+ };
382
+
383
+ if (_glfw.egl.handle)
384
+ return GLFW_TRUE;
385
+
386
+ for (i = 0; sonames[i]; i++)
387
+ {
388
+ _glfw.egl.handle = _glfwPlatformLoadModule(sonames[i]);
389
+ if (_glfw.egl.handle)
390
+ break;
391
+ }
392
+
393
+ if (!_glfw.egl.handle)
394
+ {
395
+ _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Library not found");
396
+ return GLFW_FALSE;
397
+ }
398
+
399
+ _glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0);
400
+
401
+ _glfw.egl.GetConfigAttrib = (PFN_eglGetConfigAttrib)
402
+ _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetConfigAttrib");
403
+ _glfw.egl.GetConfigs = (PFN_eglGetConfigs)
404
+ _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetConfigs");
405
+ _glfw.egl.GetDisplay = (PFN_eglGetDisplay)
406
+ _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetDisplay");
407
+ _glfw.egl.GetError = (PFN_eglGetError)
408
+ _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetError");
409
+ _glfw.egl.Initialize = (PFN_eglInitialize)
410
+ _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglInitialize");
411
+ _glfw.egl.Terminate = (PFN_eglTerminate)
412
+ _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglTerminate");
413
+ _glfw.egl.BindAPI = (PFN_eglBindAPI)
414
+ _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglBindAPI");
415
+ _glfw.egl.CreateContext = (PFN_eglCreateContext)
416
+ _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateContext");
417
+ _glfw.egl.DestroySurface = (PFN_eglDestroySurface)
418
+ _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroySurface");
419
+ _glfw.egl.DestroyContext = (PFN_eglDestroyContext)
420
+ _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroyContext");
421
+ _glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface)
422
+ _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateWindowSurface");
423
+ _glfw.egl.MakeCurrent = (PFN_eglMakeCurrent)
424
+ _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglMakeCurrent");
425
+ _glfw.egl.SwapBuffers = (PFN_eglSwapBuffers)
426
+ _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglSwapBuffers");
427
+ _glfw.egl.SwapInterval = (PFN_eglSwapInterval)
428
+ _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglSwapInterval");
429
+ _glfw.egl.QueryString = (PFN_eglQueryString)
430
+ _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglQueryString");
431
+ _glfw.egl.GetProcAddress = (PFN_eglGetProcAddress)
432
+ _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetProcAddress");
433
+
434
+ if (!_glfw.egl.GetConfigAttrib ||
435
+ !_glfw.egl.GetConfigs ||
436
+ !_glfw.egl.GetDisplay ||
437
+ !_glfw.egl.GetError ||
438
+ !_glfw.egl.Initialize ||
439
+ !_glfw.egl.Terminate ||
440
+ !_glfw.egl.BindAPI ||
441
+ !_glfw.egl.CreateContext ||
442
+ !_glfw.egl.DestroySurface ||
443
+ !_glfw.egl.DestroyContext ||
444
+ !_glfw.egl.CreateWindowSurface ||
445
+ !_glfw.egl.MakeCurrent ||
446
+ !_glfw.egl.SwapBuffers ||
447
+ !_glfw.egl.SwapInterval ||
448
+ !_glfw.egl.QueryString ||
449
+ !_glfw.egl.GetProcAddress)
450
+ {
451
+ _glfwInputError(GLFW_PLATFORM_ERROR,
452
+ "EGL: Failed to load required entry points");
453
+
454
+ _glfwTerminateEGL();
455
+ return GLFW_FALSE;
456
+ }
457
+
458
+ extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
459
+ if (extensions && eglGetError() == EGL_SUCCESS)
460
+ _glfw.egl.EXT_client_extensions = GLFW_TRUE;
461
+
462
+ if (_glfw.egl.EXT_client_extensions)
463
+ {
464
+ _glfw.egl.EXT_platform_base =
465
+ _glfwStringInExtensionString("EGL_EXT_platform_base", extensions);
466
+ _glfw.egl.EXT_platform_x11 =
467
+ _glfwStringInExtensionString("EGL_EXT_platform_x11", extensions);
468
+ _glfw.egl.EXT_platform_wayland =
469
+ _glfwStringInExtensionString("EGL_EXT_platform_wayland", extensions);
470
+ _glfw.egl.ANGLE_platform_angle =
471
+ _glfwStringInExtensionString("EGL_ANGLE_platform_angle", extensions);
472
+ _glfw.egl.ANGLE_platform_angle_opengl =
473
+ _glfwStringInExtensionString("EGL_ANGLE_platform_angle_opengl", extensions);
474
+ _glfw.egl.ANGLE_platform_angle_d3d =
475
+ _glfwStringInExtensionString("EGL_ANGLE_platform_angle_d3d", extensions);
476
+ _glfw.egl.ANGLE_platform_angle_vulkan =
477
+ _glfwStringInExtensionString("EGL_ANGLE_platform_angle_vulkan", extensions);
478
+ _glfw.egl.ANGLE_platform_angle_metal =
479
+ _glfwStringInExtensionString("EGL_ANGLE_platform_angle_metal", extensions);
480
+ }
481
+
482
+ if (_glfw.egl.EXT_platform_base)
483
+ {
484
+ _glfw.egl.GetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)
485
+ eglGetProcAddress("eglGetPlatformDisplayEXT");
486
+ _glfw.egl.CreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)
487
+ eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT");
488
+ }
489
+
490
+ _glfw.egl.platform = _glfw.platform.getEGLPlatform(&attribs);
491
+ if (_glfw.egl.platform)
492
+ {
493
+ _glfw.egl.display =
494
+ eglGetPlatformDisplayEXT(_glfw.egl.platform,
495
+ _glfw.platform.getEGLNativeDisplay(),
496
+ attribs);
497
+ }
498
+ else
499
+ _glfw.egl.display = eglGetDisplay(_glfw.platform.getEGLNativeDisplay());
500
+
501
+ _glfw_free(attribs);
502
+
503
+ if (_glfw.egl.display == EGL_NO_DISPLAY)
504
+ {
505
+ _glfwInputError(GLFW_API_UNAVAILABLE,
506
+ "EGL: Failed to get EGL display: %s",
507
+ getEGLErrorString(eglGetError()));
508
+
509
+ _glfwTerminateEGL();
510
+ return GLFW_FALSE;
511
+ }
512
+
513
+ if (!eglInitialize(_glfw.egl.display, &_glfw.egl.major, &_glfw.egl.minor))
514
+ {
515
+ _glfwInputError(GLFW_API_UNAVAILABLE,
516
+ "EGL: Failed to initialize EGL: %s",
517
+ getEGLErrorString(eglGetError()));
518
+
519
+ _glfwTerminateEGL();
520
+ return GLFW_FALSE;
521
+ }
522
+
523
+ _glfw.egl.KHR_create_context =
524
+ extensionSupportedEGL("EGL_KHR_create_context");
525
+ _glfw.egl.KHR_create_context_no_error =
526
+ extensionSupportedEGL("EGL_KHR_create_context_no_error");
527
+ _glfw.egl.KHR_gl_colorspace =
528
+ extensionSupportedEGL("EGL_KHR_gl_colorspace");
529
+ _glfw.egl.KHR_get_all_proc_addresses =
530
+ extensionSupportedEGL("EGL_KHR_get_all_proc_addresses");
531
+ _glfw.egl.KHR_context_flush_control =
532
+ extensionSupportedEGL("EGL_KHR_context_flush_control");
533
+ _glfw.egl.EXT_present_opaque =
534
+ extensionSupportedEGL("EGL_EXT_present_opaque");
535
+
536
+ return GLFW_TRUE;
537
+ }
538
+
539
+ // Terminate EGL
540
+ //
541
+ void _glfwTerminateEGL(void)
542
+ {
543
+ if (_glfw.egl.display)
544
+ {
545
+ eglTerminate(_glfw.egl.display);
546
+ _glfw.egl.display = EGL_NO_DISPLAY;
547
+ }
548
+
549
+ if (_glfw.egl.handle)
550
+ {
551
+ _glfwPlatformFreeModule(_glfw.egl.handle);
552
+ _glfw.egl.handle = NULL;
553
+ }
554
+ }
555
+
556
+ #define SET_ATTRIB(a, v) \
557
+ { \
558
+ assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
559
+ attribs[index++] = a; \
560
+ attribs[index++] = v; \
561
+ }
562
+
563
+ // Create the OpenGL or OpenGL ES context
564
+ //
565
+ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
566
+ const _GLFWctxconfig* ctxconfig,
567
+ const _GLFWfbconfig* fbconfig)
568
+ {
569
+ EGLint attribs[40];
570
+ EGLConfig config;
571
+ EGLContext share = NULL;
572
+ EGLNativeWindowType native;
573
+ int index = 0;
574
+
575
+ if (!_glfw.egl.display)
576
+ {
577
+ _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: API not available");
578
+ return GLFW_FALSE;
579
+ }
580
+
581
+ if (ctxconfig->share)
582
+ share = ctxconfig->share->context.egl.handle;
583
+
584
+ if (!chooseEGLConfig(ctxconfig, fbconfig, &config))
585
+ return GLFW_FALSE;
586
+
587
+ if (ctxconfig->client == GLFW_OPENGL_ES_API)
588
+ {
589
+ if (!eglBindAPI(EGL_OPENGL_ES_API))
590
+ {
591
+ _glfwInputError(GLFW_API_UNAVAILABLE,
592
+ "EGL: Failed to bind OpenGL ES: %s",
593
+ getEGLErrorString(eglGetError()));
594
+ return GLFW_FALSE;
595
+ }
596
+ }
597
+ else
598
+ {
599
+ if (!eglBindAPI(EGL_OPENGL_API))
600
+ {
601
+ _glfwInputError(GLFW_API_UNAVAILABLE,
602
+ "EGL: Failed to bind OpenGL: %s",
603
+ getEGLErrorString(eglGetError()));
604
+ return GLFW_FALSE;
605
+ }
606
+ }
607
+
608
+ if (_glfw.egl.KHR_create_context)
609
+ {
610
+ int mask = 0, flags = 0;
611
+
612
+ if (ctxconfig->client == GLFW_OPENGL_API)
613
+ {
614
+ if (ctxconfig->forward)
615
+ flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
616
+
617
+ if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
618
+ mask |= EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
619
+ else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
620
+ mask |= EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR;
621
+ }
622
+
623
+ if (ctxconfig->debug)
624
+ flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
625
+
626
+ if (ctxconfig->robustness)
627
+ {
628
+ if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
629
+ {
630
+ SET_ATTRIB(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
631
+ EGL_NO_RESET_NOTIFICATION_KHR);
632
+ }
633
+ else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
634
+ {
635
+ SET_ATTRIB(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
636
+ EGL_LOSE_CONTEXT_ON_RESET_KHR);
637
+ }
638
+
639
+ flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
640
+ }
641
+
642
+ if (ctxconfig->major != 1 || ctxconfig->minor != 0)
643
+ {
644
+ SET_ATTRIB(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
645
+ SET_ATTRIB(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor);
646
+ }
647
+
648
+ if (ctxconfig->noerror)
649
+ {
650
+ if (_glfw.egl.KHR_create_context_no_error)
651
+ SET_ATTRIB(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
652
+ }
653
+
654
+ if (mask)
655
+ SET_ATTRIB(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
656
+
657
+ if (flags)
658
+ SET_ATTRIB(EGL_CONTEXT_FLAGS_KHR, flags);
659
+ }
660
+ else
661
+ {
662
+ if (ctxconfig->client == GLFW_OPENGL_ES_API)
663
+ SET_ATTRIB(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major);
664
+ }
665
+
666
+ if (_glfw.egl.KHR_context_flush_control)
667
+ {
668
+ if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
669
+ {
670
+ SET_ATTRIB(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
671
+ EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR);
672
+ }
673
+ else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
674
+ {
675
+ SET_ATTRIB(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
676
+ EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR);
677
+ }
678
+ }
679
+
680
+ SET_ATTRIB(EGL_NONE, EGL_NONE);
681
+
682
+ window->context.egl.handle = eglCreateContext(_glfw.egl.display,
683
+ config, share, attribs);
684
+
685
+ if (window->context.egl.handle == EGL_NO_CONTEXT)
686
+ {
687
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
688
+ "EGL: Failed to create context: %s",
689
+ getEGLErrorString(eglGetError()));
690
+ return GLFW_FALSE;
691
+ }
692
+
693
+ // Set up attributes for surface creation
694
+ index = 0;
695
+
696
+ if (fbconfig->sRGB)
697
+ {
698
+ if (_glfw.egl.KHR_gl_colorspace)
699
+ SET_ATTRIB(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
700
+ }
701
+
702
+ if (!fbconfig->doublebuffer)
703
+ SET_ATTRIB(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
704
+
705
+ if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
706
+ {
707
+ if (_glfw.egl.EXT_present_opaque)
708
+ SET_ATTRIB(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);
709
+ }
710
+
711
+ SET_ATTRIB(EGL_NONE, EGL_NONE);
712
+
713
+ native = _glfw.platform.getEGLNativeWindow(window);
714
+ // HACK: ANGLE does not implement eglCreatePlatformWindowSurfaceEXT
715
+ // despite reporting EGL_EXT_platform_base
716
+ if (_glfw.egl.platform && _glfw.egl.platform != EGL_PLATFORM_ANGLE_ANGLE)
717
+ {
718
+ window->context.egl.surface =
719
+ eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, config, native, attribs);
720
+ }
721
+ else
722
+ {
723
+ window->context.egl.surface =
724
+ eglCreateWindowSurface(_glfw.egl.display, config, native, attribs);
725
+ }
726
+
727
+ if (window->context.egl.surface == EGL_NO_SURFACE)
728
+ {
729
+ _glfwInputError(GLFW_PLATFORM_ERROR,
730
+ "EGL: Failed to create window surface: %s",
731
+ getEGLErrorString(eglGetError()));
732
+ return GLFW_FALSE;
733
+ }
734
+
735
+ window->context.egl.config = config;
736
+
737
+ // Load the appropriate client library
738
+ if (!_glfw.egl.KHR_get_all_proc_addresses)
739
+ {
740
+ int i;
741
+ const char** sonames;
742
+ const char* es1sonames[] =
743
+ {
744
+ #if defined(_GLFW_GLESV1_LIBRARY)
745
+ _GLFW_GLESV1_LIBRARY,
746
+ #elif defined(_GLFW_WIN32)
747
+ "GLESv1_CM.dll",
748
+ "libGLES_CM.dll",
749
+ #elif defined(_GLFW_COCOA)
750
+ "libGLESv1_CM.dylib",
751
+ #elif defined(__OpenBSD__) || defined(__NetBSD__)
752
+ "libGLESv1_CM.so",
753
+ #else
754
+ "libGLESv1_CM.so.1",
755
+ "libGLES_CM.so.1",
756
+ #endif
757
+ NULL
758
+ };
759
+ const char* es2sonames[] =
760
+ {
761
+ #if defined(_GLFW_GLESV2_LIBRARY)
762
+ _GLFW_GLESV2_LIBRARY,
763
+ #elif defined(_GLFW_WIN32)
764
+ "GLESv2.dll",
765
+ "libGLESv2.dll",
766
+ #elif defined(_GLFW_COCOA)
767
+ "libGLESv2.dylib",
768
+ #elif defined(__CYGWIN__)
769
+ "libGLESv2-2.so",
770
+ #elif defined(__OpenBSD__) || defined(__NetBSD__)
771
+ "libGLESv2.so",
772
+ #else
773
+ "libGLESv2.so.2",
774
+ #endif
775
+ NULL
776
+ };
777
+ const char* glsonames[] =
778
+ {
779
+ #if defined(_GLFW_OPENGL_LIBRARY)
780
+ _GLFW_OPENGL_LIBRARY,
781
+ #elif defined(_GLFW_WIN32)
782
+ #elif defined(_GLFW_COCOA)
783
+ #elif defined(__OpenBSD__) || defined(__NetBSD__)
784
+ "libGL.so",
785
+ #else
786
+ "libOpenGL.so.0",
787
+ "libGL.so.1",
788
+ #endif
789
+ NULL
790
+ };
791
+
792
+ if (ctxconfig->client == GLFW_OPENGL_ES_API)
793
+ {
794
+ if (ctxconfig->major == 1)
795
+ sonames = es1sonames;
796
+ else
797
+ sonames = es2sonames;
798
+ }
799
+ else
800
+ sonames = glsonames;
801
+
802
+ for (i = 0; sonames[i]; i++)
803
+ {
804
+ // HACK: Match presence of lib prefix to increase chance of finding
805
+ // a matching pair in the jungle that is Win32 EGL/GLES
806
+ if (_glfw.egl.prefix != (strncmp(sonames[i], "lib", 3) == 0))
807
+ continue;
808
+
809
+ window->context.egl.client = _glfwPlatformLoadModule(sonames[i]);
810
+ if (window->context.egl.client)
811
+ break;
812
+ }
813
+
814
+ if (!window->context.egl.client)
815
+ {
816
+ _glfwInputError(GLFW_API_UNAVAILABLE,
817
+ "EGL: Failed to load client library");
818
+ return GLFW_FALSE;
819
+ }
820
+ }
821
+
822
+ window->context.makeCurrent = makeContextCurrentEGL;
823
+ window->context.swapBuffers = swapBuffersEGL;
824
+ window->context.swapInterval = swapIntervalEGL;
825
+ window->context.extensionSupported = extensionSupportedEGL;
826
+ window->context.getProcAddress = getProcAddressEGL;
827
+ window->context.destroy = destroyContextEGL;
828
+
829
+ return GLFW_TRUE;
830
+ }
831
+
832
+ #undef SET_ATTRIB
833
+
834
+ // Returns the Visual and depth of the chosen EGLConfig
835
+ //
836
+ #if defined(_GLFW_X11)
837
+ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
838
+ const _GLFWctxconfig* ctxconfig,
839
+ const _GLFWfbconfig* fbconfig,
840
+ Visual** visual, int* depth)
841
+ {
842
+ XVisualInfo* result;
843
+ XVisualInfo desired;
844
+ EGLConfig native;
845
+ EGLint visualID = 0, count = 0;
846
+ const long vimask = VisualScreenMask | VisualIDMask;
847
+
848
+ if (!chooseEGLConfig(ctxconfig, fbconfig, &native))
849
+ return GLFW_FALSE;
850
+
851
+ eglGetConfigAttrib(_glfw.egl.display, native,
852
+ EGL_NATIVE_VISUAL_ID, &visualID);
853
+
854
+ desired.screen = _glfw.x11.screen;
855
+ desired.visualid = visualID;
856
+
857
+ result = XGetVisualInfo(_glfw.x11.display, vimask, &desired, &count);
858
+ if (!result)
859
+ {
860
+ _glfwInputError(GLFW_PLATFORM_ERROR,
861
+ "EGL: Failed to retrieve Visual for EGLConfig");
862
+ return GLFW_FALSE;
863
+ }
864
+
865
+ *visual = result->visual;
866
+ *depth = result->depth;
867
+
868
+ XFree(result);
869
+ return GLFW_TRUE;
870
+ }
871
+ #endif // _GLFW_X11
872
+
873
+
874
+ //////////////////////////////////////////////////////////////////////////
875
+ ////// GLFW native API //////
876
+ //////////////////////////////////////////////////////////////////////////
877
+
878
+ GLFWAPI EGLDisplay glfwGetEGLDisplay(void)
879
+ {
880
+ _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_DISPLAY);
881
+ return _glfw.egl.display;
882
+ }
883
+
884
+ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle)
885
+ {
886
+ _GLFWwindow* window = (_GLFWwindow*) handle;
887
+ _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT);
888
+
889
+ if (window->context.source != GLFW_EGL_CONTEXT_API)
890
+ {
891
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
892
+ return EGL_NO_CONTEXT;
893
+ }
894
+
895
+ return window->context.egl.handle;
896
+ }
897
+
898
+ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
899
+ {
900
+ _GLFWwindow* window = (_GLFWwindow*) handle;
901
+ _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE);
902
+
903
+ if (window->context.source != GLFW_EGL_CONTEXT_API)
904
+ {
905
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
906
+ return EGL_NO_SURFACE;
907
+ }
908
+
909
+ return window->context.egl.surface;
910
+ }
911
+