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
package/GLFW/context.c ADDED
@@ -0,0 +1,765 @@
1
+ //========================================================================
2
+ // GLFW 3.4 - www.glfw.org
3
+ //------------------------------------------------------------------------
4
+ // Copyright (c) 2002-2006 Marcus Geelnard
5
+ // Copyright (c) 2006-2016 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 <assert.h>
31
+ #include <stdio.h>
32
+ #include <string.h>
33
+ #include <limits.h>
34
+ #include <stdio.h>
35
+
36
+
37
+ //////////////////////////////////////////////////////////////////////////
38
+ ////// GLFW internal API //////
39
+ //////////////////////////////////////////////////////////////////////////
40
+
41
+ // Checks whether the desired context attributes are valid
42
+ //
43
+ // This function checks things like whether the specified client API version
44
+ // exists and whether all relevant options have supported and non-conflicting
45
+ // values
46
+ //
47
+ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
48
+ {
49
+ if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API &&
50
+ ctxconfig->source != GLFW_EGL_CONTEXT_API &&
51
+ ctxconfig->source != GLFW_OSMESA_CONTEXT_API)
52
+ {
53
+ _glfwInputError(GLFW_INVALID_ENUM,
54
+ "Invalid context creation API 0x%08X",
55
+ ctxconfig->source);
56
+ return GLFW_FALSE;
57
+ }
58
+
59
+ if (ctxconfig->client != GLFW_NO_API &&
60
+ ctxconfig->client != GLFW_OPENGL_API &&
61
+ ctxconfig->client != GLFW_OPENGL_ES_API)
62
+ {
63
+ _glfwInputError(GLFW_INVALID_ENUM,
64
+ "Invalid client API 0x%08X",
65
+ ctxconfig->client);
66
+ return GLFW_FALSE;
67
+ }
68
+
69
+ if (ctxconfig->share)
70
+ {
71
+ if (ctxconfig->client == GLFW_NO_API ||
72
+ ctxconfig->share->context.client == GLFW_NO_API)
73
+ {
74
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
75
+ return GLFW_FALSE;
76
+ }
77
+
78
+ if (ctxconfig->source != ctxconfig->share->context.source)
79
+ {
80
+ _glfwInputError(GLFW_INVALID_ENUM,
81
+ "Context creation APIs do not match between contexts");
82
+ return GLFW_FALSE;
83
+ }
84
+ }
85
+
86
+ if (ctxconfig->client == GLFW_OPENGL_API)
87
+ {
88
+ if ((ctxconfig->major < 1 || ctxconfig->minor < 0) ||
89
+ (ctxconfig->major == 1 && ctxconfig->minor > 5) ||
90
+ (ctxconfig->major == 2 && ctxconfig->minor > 1) ||
91
+ (ctxconfig->major == 3 && ctxconfig->minor > 3))
92
+ {
93
+ // OpenGL 1.0 is the smallest valid version
94
+ // OpenGL 1.x series ended with version 1.5
95
+ // OpenGL 2.x series ended with version 2.1
96
+ // OpenGL 3.x series ended with version 3.3
97
+ // For now, let everything else through
98
+
99
+ _glfwInputError(GLFW_INVALID_VALUE,
100
+ "Invalid OpenGL version %i.%i",
101
+ ctxconfig->major, ctxconfig->minor);
102
+ return GLFW_FALSE;
103
+ }
104
+
105
+ if (ctxconfig->profile)
106
+ {
107
+ if (ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE &&
108
+ ctxconfig->profile != GLFW_OPENGL_COMPAT_PROFILE)
109
+ {
110
+ _glfwInputError(GLFW_INVALID_ENUM,
111
+ "Invalid OpenGL profile 0x%08X",
112
+ ctxconfig->profile);
113
+ return GLFW_FALSE;
114
+ }
115
+
116
+ if (ctxconfig->major <= 2 ||
117
+ (ctxconfig->major == 3 && ctxconfig->minor < 2))
118
+ {
119
+ // Desktop OpenGL context profiles are only defined for version 3.2
120
+ // and above
121
+
122
+ _glfwInputError(GLFW_INVALID_VALUE,
123
+ "Context profiles are only defined for OpenGL version 3.2 and above");
124
+ return GLFW_FALSE;
125
+ }
126
+ }
127
+
128
+ if (ctxconfig->forward && ctxconfig->major <= 2)
129
+ {
130
+ // Forward-compatible contexts are only defined for OpenGL version 3.0 and above
131
+ _glfwInputError(GLFW_INVALID_VALUE,
132
+ "Forward-compatibility is only defined for OpenGL version 3.0 and above");
133
+ return GLFW_FALSE;
134
+ }
135
+ }
136
+ else if (ctxconfig->client == GLFW_OPENGL_ES_API)
137
+ {
138
+ if (ctxconfig->major < 1 || ctxconfig->minor < 0 ||
139
+ (ctxconfig->major == 1 && ctxconfig->minor > 1) ||
140
+ (ctxconfig->major == 2 && ctxconfig->minor > 0))
141
+ {
142
+ // OpenGL ES 1.0 is the smallest valid version
143
+ // OpenGL ES 1.x series ended with version 1.1
144
+ // OpenGL ES 2.x series ended with version 2.0
145
+ // For now, let everything else through
146
+
147
+ _glfwInputError(GLFW_INVALID_VALUE,
148
+ "Invalid OpenGL ES version %i.%i",
149
+ ctxconfig->major, ctxconfig->minor);
150
+ return GLFW_FALSE;
151
+ }
152
+ }
153
+
154
+ if (ctxconfig->robustness)
155
+ {
156
+ if (ctxconfig->robustness != GLFW_NO_RESET_NOTIFICATION &&
157
+ ctxconfig->robustness != GLFW_LOSE_CONTEXT_ON_RESET)
158
+ {
159
+ _glfwInputError(GLFW_INVALID_ENUM,
160
+ "Invalid context robustness mode 0x%08X",
161
+ ctxconfig->robustness);
162
+ return GLFW_FALSE;
163
+ }
164
+ }
165
+
166
+ if (ctxconfig->release)
167
+ {
168
+ if (ctxconfig->release != GLFW_RELEASE_BEHAVIOR_NONE &&
169
+ ctxconfig->release != GLFW_RELEASE_BEHAVIOR_FLUSH)
170
+ {
171
+ _glfwInputError(GLFW_INVALID_ENUM,
172
+ "Invalid context release behavior 0x%08X",
173
+ ctxconfig->release);
174
+ return GLFW_FALSE;
175
+ }
176
+ }
177
+
178
+ return GLFW_TRUE;
179
+ }
180
+
181
+ // Chooses the framebuffer config that best matches the desired one
182
+ //
183
+ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
184
+ const _GLFWfbconfig* alternatives,
185
+ unsigned int count)
186
+ {
187
+ unsigned int i;
188
+ unsigned int missing, leastMissing = UINT_MAX;
189
+ unsigned int colorDiff, leastColorDiff = UINT_MAX;
190
+ unsigned int extraDiff, leastExtraDiff = UINT_MAX;
191
+ const _GLFWfbconfig* current;
192
+ const _GLFWfbconfig* closest = NULL;
193
+
194
+ for (i = 0; i < count; i++)
195
+ {
196
+ current = alternatives + i;
197
+
198
+ if (desired->stereo > 0 && current->stereo == 0)
199
+ {
200
+ // Stereo is a hard constraint
201
+ continue;
202
+ }
203
+
204
+ // Count number of missing buffers
205
+ {
206
+ missing = 0;
207
+
208
+ if (desired->alphaBits > 0 && current->alphaBits == 0)
209
+ missing++;
210
+
211
+ if (desired->depthBits > 0 && current->depthBits == 0)
212
+ missing++;
213
+
214
+ if (desired->stencilBits > 0 && current->stencilBits == 0)
215
+ missing++;
216
+
217
+ if (desired->auxBuffers > 0 &&
218
+ current->auxBuffers < desired->auxBuffers)
219
+ {
220
+ missing += desired->auxBuffers - current->auxBuffers;
221
+ }
222
+
223
+ if (desired->samples > 0 && current->samples == 0)
224
+ {
225
+ // Technically, several multisampling buffers could be
226
+ // involved, but that's a lower level implementation detail and
227
+ // not important to us here, so we count them as one
228
+ missing++;
229
+ }
230
+
231
+ if (desired->transparent != current->transparent)
232
+ missing++;
233
+ }
234
+
235
+ // These polynomials make many small channel size differences matter
236
+ // less than one large channel size difference
237
+
238
+ // Calculate color channel size difference value
239
+ {
240
+ colorDiff = 0;
241
+
242
+ if (desired->redBits != GLFW_DONT_CARE)
243
+ {
244
+ colorDiff += (desired->redBits - current->redBits) *
245
+ (desired->redBits - current->redBits);
246
+ }
247
+
248
+ if (desired->greenBits != GLFW_DONT_CARE)
249
+ {
250
+ colorDiff += (desired->greenBits - current->greenBits) *
251
+ (desired->greenBits - current->greenBits);
252
+ }
253
+
254
+ if (desired->blueBits != GLFW_DONT_CARE)
255
+ {
256
+ colorDiff += (desired->blueBits - current->blueBits) *
257
+ (desired->blueBits - current->blueBits);
258
+ }
259
+ }
260
+
261
+ // Calculate non-color channel size difference value
262
+ {
263
+ extraDiff = 0;
264
+
265
+ if (desired->alphaBits != GLFW_DONT_CARE)
266
+ {
267
+ extraDiff += (desired->alphaBits - current->alphaBits) *
268
+ (desired->alphaBits - current->alphaBits);
269
+ }
270
+
271
+ if (desired->depthBits != GLFW_DONT_CARE)
272
+ {
273
+ extraDiff += (desired->depthBits - current->depthBits) *
274
+ (desired->depthBits - current->depthBits);
275
+ }
276
+
277
+ if (desired->stencilBits != GLFW_DONT_CARE)
278
+ {
279
+ extraDiff += (desired->stencilBits - current->stencilBits) *
280
+ (desired->stencilBits - current->stencilBits);
281
+ }
282
+
283
+ if (desired->accumRedBits != GLFW_DONT_CARE)
284
+ {
285
+ extraDiff += (desired->accumRedBits - current->accumRedBits) *
286
+ (desired->accumRedBits - current->accumRedBits);
287
+ }
288
+
289
+ if (desired->accumGreenBits != GLFW_DONT_CARE)
290
+ {
291
+ extraDiff += (desired->accumGreenBits - current->accumGreenBits) *
292
+ (desired->accumGreenBits - current->accumGreenBits);
293
+ }
294
+
295
+ if (desired->accumBlueBits != GLFW_DONT_CARE)
296
+ {
297
+ extraDiff += (desired->accumBlueBits - current->accumBlueBits) *
298
+ (desired->accumBlueBits - current->accumBlueBits);
299
+ }
300
+
301
+ if (desired->accumAlphaBits != GLFW_DONT_CARE)
302
+ {
303
+ extraDiff += (desired->accumAlphaBits - current->accumAlphaBits) *
304
+ (desired->accumAlphaBits - current->accumAlphaBits);
305
+ }
306
+
307
+ if (desired->samples != GLFW_DONT_CARE)
308
+ {
309
+ extraDiff += (desired->samples - current->samples) *
310
+ (desired->samples - current->samples);
311
+ }
312
+
313
+ if (desired->sRGB && !current->sRGB)
314
+ extraDiff++;
315
+ }
316
+
317
+ // Figure out if the current one is better than the best one found so far
318
+ // Least number of missing buffers is the most important heuristic,
319
+ // then color buffer size match and lastly size match for other buffers
320
+
321
+ if (missing < leastMissing)
322
+ closest = current;
323
+ else if (missing == leastMissing)
324
+ {
325
+ if ((colorDiff < leastColorDiff) ||
326
+ (colorDiff == leastColorDiff && extraDiff < leastExtraDiff))
327
+ {
328
+ closest = current;
329
+ }
330
+ }
331
+
332
+ if (current == closest)
333
+ {
334
+ leastMissing = missing;
335
+ leastColorDiff = colorDiff;
336
+ leastExtraDiff = extraDiff;
337
+ }
338
+ }
339
+
340
+ return closest;
341
+ }
342
+
343
+ // Retrieves the attributes of the current context
344
+ //
345
+ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
346
+ const _GLFWctxconfig* ctxconfig)
347
+ {
348
+ int i;
349
+ _GLFWwindow* previous;
350
+ const char* version;
351
+ const char* prefixes[] =
352
+ {
353
+ "OpenGL ES-CM ",
354
+ "OpenGL ES-CL ",
355
+ "OpenGL ES ",
356
+ NULL
357
+ };
358
+
359
+ window->context.source = ctxconfig->source;
360
+ window->context.client = GLFW_OPENGL_API;
361
+
362
+ previous = _glfwPlatformGetTls(&_glfw.contextSlot);
363
+ glfwMakeContextCurrent((GLFWwindow*) window);
364
+ if (_glfwPlatformGetTls(&_glfw.contextSlot) != window)
365
+ return GLFW_FALSE;
366
+
367
+ window->context.GetIntegerv = (PFNGLGETINTEGERVPROC)
368
+ window->context.getProcAddress("glGetIntegerv");
369
+ window->context.GetString = (PFNGLGETSTRINGPROC)
370
+ window->context.getProcAddress("glGetString");
371
+ if (!window->context.GetIntegerv || !window->context.GetString)
372
+ {
373
+ _glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken");
374
+ glfwMakeContextCurrent((GLFWwindow*) previous);
375
+ return GLFW_FALSE;
376
+ }
377
+
378
+ version = (const char*) window->context.GetString(GL_VERSION);
379
+ if (!version)
380
+ {
381
+ if (ctxconfig->client == GLFW_OPENGL_API)
382
+ {
383
+ _glfwInputError(GLFW_PLATFORM_ERROR,
384
+ "OpenGL version string retrieval is broken");
385
+ }
386
+ else
387
+ {
388
+ _glfwInputError(GLFW_PLATFORM_ERROR,
389
+ "OpenGL ES version string retrieval is broken");
390
+ }
391
+
392
+ glfwMakeContextCurrent((GLFWwindow*) previous);
393
+ return GLFW_FALSE;
394
+ }
395
+
396
+ for (i = 0; prefixes[i]; i++)
397
+ {
398
+ const size_t length = strlen(prefixes[i]);
399
+
400
+ if (strncmp(version, prefixes[i], length) == 0)
401
+ {
402
+ version += length;
403
+ window->context.client = GLFW_OPENGL_ES_API;
404
+ break;
405
+ }
406
+ }
407
+
408
+ if (!sscanf(version, "%d.%d.%d",
409
+ &window->context.major,
410
+ &window->context.minor,
411
+ &window->context.revision))
412
+ {
413
+ if (window->context.client == GLFW_OPENGL_API)
414
+ {
415
+ _glfwInputError(GLFW_PLATFORM_ERROR,
416
+ "No version found in OpenGL version string");
417
+ }
418
+ else
419
+ {
420
+ _glfwInputError(GLFW_PLATFORM_ERROR,
421
+ "No version found in OpenGL ES version string");
422
+ }
423
+
424
+ glfwMakeContextCurrent((GLFWwindow*) previous);
425
+ return GLFW_FALSE;
426
+ }
427
+
428
+ if (window->context.major < ctxconfig->major ||
429
+ (window->context.major == ctxconfig->major &&
430
+ window->context.minor < ctxconfig->minor))
431
+ {
432
+ // The desired OpenGL version is greater than the actual version
433
+ // This only happens if the machine lacks {GLX|WGL}_ARB_create_context
434
+ // /and/ the user has requested an OpenGL version greater than 1.0
435
+
436
+ // For API consistency, we emulate the behavior of the
437
+ // {GLX|WGL}_ARB_create_context extension and fail here
438
+
439
+ if (window->context.client == GLFW_OPENGL_API)
440
+ {
441
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
442
+ "Requested OpenGL version %i.%i, got version %i.%i",
443
+ ctxconfig->major, ctxconfig->minor,
444
+ window->context.major, window->context.minor);
445
+ }
446
+ else
447
+ {
448
+ _glfwInputError(GLFW_VERSION_UNAVAILABLE,
449
+ "Requested OpenGL ES version %i.%i, got version %i.%i",
450
+ ctxconfig->major, ctxconfig->minor,
451
+ window->context.major, window->context.minor);
452
+ }
453
+
454
+ glfwMakeContextCurrent((GLFWwindow*) previous);
455
+ return GLFW_FALSE;
456
+ }
457
+
458
+ if (window->context.major >= 3)
459
+ {
460
+ // OpenGL 3.0+ uses a different function for extension string retrieval
461
+ // We cache it here instead of in glfwExtensionSupported mostly to alert
462
+ // users as early as possible that their build may be broken
463
+
464
+ window->context.GetStringi = (PFNGLGETSTRINGIPROC)
465
+ window->context.getProcAddress("glGetStringi");
466
+ if (!window->context.GetStringi)
467
+ {
468
+ _glfwInputError(GLFW_PLATFORM_ERROR,
469
+ "Entry point retrieval is broken");
470
+ glfwMakeContextCurrent((GLFWwindow*) previous);
471
+ return GLFW_FALSE;
472
+ }
473
+ }
474
+
475
+ if (window->context.client == GLFW_OPENGL_API)
476
+ {
477
+ // Read back context flags (OpenGL 3.0 and above)
478
+ if (window->context.major >= 3)
479
+ {
480
+ GLint flags;
481
+ window->context.GetIntegerv(GL_CONTEXT_FLAGS, &flags);
482
+
483
+ if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
484
+ window->context.forward = GLFW_TRUE;
485
+
486
+ if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)
487
+ window->context.debug = GLFW_TRUE;
488
+ else if (glfwExtensionSupported("GL_ARB_debug_output") &&
489
+ ctxconfig->debug)
490
+ {
491
+ // HACK: This is a workaround for older drivers (pre KHR_debug)
492
+ // not setting the debug bit in the context flags for
493
+ // debug contexts
494
+ window->context.debug = GLFW_TRUE;
495
+ }
496
+
497
+ if (flags & GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR)
498
+ window->context.noerror = GLFW_TRUE;
499
+ }
500
+
501
+ // Read back OpenGL context profile (OpenGL 3.2 and above)
502
+ if (window->context.major >= 4 ||
503
+ (window->context.major == 3 && window->context.minor >= 2))
504
+ {
505
+ GLint mask;
506
+ window->context.GetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
507
+
508
+ if (mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
509
+ window->context.profile = GLFW_OPENGL_COMPAT_PROFILE;
510
+ else if (mask & GL_CONTEXT_CORE_PROFILE_BIT)
511
+ window->context.profile = GLFW_OPENGL_CORE_PROFILE;
512
+ else if (glfwExtensionSupported("GL_ARB_compatibility"))
513
+ {
514
+ // HACK: This is a workaround for the compatibility profile bit
515
+ // not being set in the context flags if an OpenGL 3.2+
516
+ // context was created without having requested a specific
517
+ // version
518
+ window->context.profile = GLFW_OPENGL_COMPAT_PROFILE;
519
+ }
520
+ }
521
+
522
+ // Read back robustness strategy
523
+ if (glfwExtensionSupported("GL_ARB_robustness"))
524
+ {
525
+ // NOTE: We avoid using the context flags for detection, as they are
526
+ // only present from 3.0 while the extension applies from 1.1
527
+
528
+ GLint strategy;
529
+ window->context.GetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB,
530
+ &strategy);
531
+
532
+ if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB)
533
+ window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET;
534
+ else if (strategy == GL_NO_RESET_NOTIFICATION_ARB)
535
+ window->context.robustness = GLFW_NO_RESET_NOTIFICATION;
536
+ }
537
+ }
538
+ else
539
+ {
540
+ // Read back robustness strategy
541
+ if (glfwExtensionSupported("GL_EXT_robustness"))
542
+ {
543
+ // NOTE: The values of these constants match those of the OpenGL ARB
544
+ // one, so we can reuse them here
545
+
546
+ GLint strategy;
547
+ window->context.GetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB,
548
+ &strategy);
549
+
550
+ if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB)
551
+ window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET;
552
+ else if (strategy == GL_NO_RESET_NOTIFICATION_ARB)
553
+ window->context.robustness = GLFW_NO_RESET_NOTIFICATION;
554
+ }
555
+ }
556
+
557
+ if (glfwExtensionSupported("GL_KHR_context_flush_control"))
558
+ {
559
+ GLint behavior;
560
+ window->context.GetIntegerv(GL_CONTEXT_RELEASE_BEHAVIOR, &behavior);
561
+
562
+ if (behavior == GL_NONE)
563
+ window->context.release = GLFW_RELEASE_BEHAVIOR_NONE;
564
+ else if (behavior == GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH)
565
+ window->context.release = GLFW_RELEASE_BEHAVIOR_FLUSH;
566
+ }
567
+
568
+ // Clearing the front buffer to black to avoid garbage pixels left over from
569
+ // previous uses of our bit of VRAM
570
+ {
571
+ PFNGLCLEARPROC glClear = (PFNGLCLEARPROC)
572
+ window->context.getProcAddress("glClear");
573
+ glClear(GL_COLOR_BUFFER_BIT);
574
+
575
+ if (window->doublebuffer)
576
+ window->context.swapBuffers(window);
577
+ }
578
+
579
+ glfwMakeContextCurrent((GLFWwindow*) previous);
580
+ return GLFW_TRUE;
581
+ }
582
+
583
+ // Searches an extension string for the specified extension
584
+ //
585
+ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions)
586
+ {
587
+ const char* start = extensions;
588
+
589
+ for (;;)
590
+ {
591
+ const char* where;
592
+ const char* terminator;
593
+
594
+ where = strstr(start, string);
595
+ if (!where)
596
+ return GLFW_FALSE;
597
+
598
+ terminator = where + strlen(string);
599
+ if (where == start || *(where - 1) == ' ')
600
+ {
601
+ if (*terminator == ' ' || *terminator == '\0')
602
+ break;
603
+ }
604
+
605
+ start = terminator;
606
+ }
607
+
608
+ return GLFW_TRUE;
609
+ }
610
+
611
+
612
+ //////////////////////////////////////////////////////////////////////////
613
+ ////// GLFW public API //////
614
+ //////////////////////////////////////////////////////////////////////////
615
+
616
+ GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
617
+ {
618
+ _GLFWwindow* window = (_GLFWwindow*) handle;
619
+ _GLFWwindow* previous;
620
+
621
+ _GLFW_REQUIRE_INIT();
622
+
623
+ previous = _glfwPlatformGetTls(&_glfw.contextSlot);
624
+
625
+ if (window && window->context.client == GLFW_NO_API)
626
+ {
627
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT,
628
+ "Cannot make current with a window that has no OpenGL or OpenGL ES context");
629
+ return;
630
+ }
631
+
632
+ if (previous)
633
+ {
634
+ if (!window || window->context.source != previous->context.source)
635
+ previous->context.makeCurrent(NULL);
636
+ }
637
+
638
+ if (window)
639
+ window->context.makeCurrent(window);
640
+ }
641
+
642
+ GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
643
+ {
644
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
645
+ return _glfwPlatformGetTls(&_glfw.contextSlot);
646
+ }
647
+
648
+ GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
649
+ {
650
+ _GLFWwindow* window = (_GLFWwindow*) handle;
651
+ assert(window != NULL);
652
+
653
+ _GLFW_REQUIRE_INIT();
654
+
655
+ if (window->context.client == GLFW_NO_API)
656
+ {
657
+ _glfwInputError(GLFW_NO_WINDOW_CONTEXT,
658
+ "Cannot swap buffers of a window that has no OpenGL or OpenGL ES context");
659
+ return;
660
+ }
661
+
662
+ window->context.swapBuffers(window);
663
+ }
664
+
665
+ GLFWAPI void glfwSwapInterval(int interval)
666
+ {
667
+ _GLFWwindow* window;
668
+
669
+ _GLFW_REQUIRE_INIT();
670
+
671
+ window = _glfwPlatformGetTls(&_glfw.contextSlot);
672
+ if (!window)
673
+ {
674
+ _glfwInputError(GLFW_NO_CURRENT_CONTEXT,
675
+ "Cannot set swap interval without a current OpenGL or OpenGL ES context");
676
+ return;
677
+ }
678
+
679
+ window->context.swapInterval(interval);
680
+ }
681
+
682
+ GLFWAPI int glfwExtensionSupported(const char* extension)
683
+ {
684
+ _GLFWwindow* window;
685
+ assert(extension != NULL);
686
+
687
+ _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
688
+
689
+ window = _glfwPlatformGetTls(&_glfw.contextSlot);
690
+ if (!window)
691
+ {
692
+ _glfwInputError(GLFW_NO_CURRENT_CONTEXT,
693
+ "Cannot query extension without a current OpenGL or OpenGL ES context");
694
+ return GLFW_FALSE;
695
+ }
696
+
697
+ if (*extension == '\0')
698
+ {
699
+ _glfwInputError(GLFW_INVALID_VALUE, "Extension name cannot be an empty string");
700
+ return GLFW_FALSE;
701
+ }
702
+
703
+ if (window->context.major >= 3)
704
+ {
705
+ int i;
706
+ GLint count;
707
+
708
+ // Check if extension is in the modern OpenGL extensions string list
709
+
710
+ window->context.GetIntegerv(GL_NUM_EXTENSIONS, &count);
711
+
712
+ for (i = 0; i < count; i++)
713
+ {
714
+ const char* en = (const char*)
715
+ window->context.GetStringi(GL_EXTENSIONS, i);
716
+ if (!en)
717
+ {
718
+ _glfwInputError(GLFW_PLATFORM_ERROR,
719
+ "Extension string retrieval is broken");
720
+ return GLFW_FALSE;
721
+ }
722
+
723
+ if (strcmp(en, extension) == 0)
724
+ return GLFW_TRUE;
725
+ }
726
+ }
727
+ else
728
+ {
729
+ // Check if extension is in the old style OpenGL extensions string
730
+
731
+ const char* extensions = (const char*)
732
+ window->context.GetString(GL_EXTENSIONS);
733
+ if (!extensions)
734
+ {
735
+ _glfwInputError(GLFW_PLATFORM_ERROR,
736
+ "Extension string retrieval is broken");
737
+ return GLFW_FALSE;
738
+ }
739
+
740
+ if (_glfwStringInExtensionString(extension, extensions))
741
+ return GLFW_TRUE;
742
+ }
743
+
744
+ // Check if extension is in the platform-specific string
745
+ return window->context.extensionSupported(extension);
746
+ }
747
+
748
+ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
749
+ {
750
+ _GLFWwindow* window;
751
+ assert(procname != NULL);
752
+
753
+ _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
754
+
755
+ window = _glfwPlatformGetTls(&_glfw.contextSlot);
756
+ if (!window)
757
+ {
758
+ _glfwInputError(GLFW_NO_CURRENT_CONTEXT,
759
+ "Cannot query entry point without a current OpenGL or OpenGL ES context");
760
+ return NULL;
761
+ }
762
+
763
+ return window->context.getProcAddress(procname);
764
+ }
765
+