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,643 @@
1
+ //========================================================================
2
+ // GLFW 3.4 macOS - 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
+ #if defined(_GLFW_COCOA)
31
+
32
+ #include <stdlib.h>
33
+ #include <limits.h>
34
+ #include <math.h>
35
+
36
+ #include <IOKit/graphics/IOGraphicsLib.h>
37
+ #include <ApplicationServices/ApplicationServices.h>
38
+
39
+
40
+ // Get the name of the specified display, or NULL
41
+ //
42
+ static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen)
43
+ {
44
+ // IOKit doesn't work on Apple Silicon anymore
45
+ // Luckily, 10.15 introduced -[NSScreen localizedName].
46
+ // Use it if available, and fall back to IOKit otherwise.
47
+ if (screen)
48
+ {
49
+ if ([screen respondsToSelector:@selector(localizedName)])
50
+ {
51
+ NSString* name = [screen valueForKey:@"localizedName"];
52
+ if (name)
53
+ return _glfw_strdup([name UTF8String]);
54
+ }
55
+ }
56
+
57
+ io_iterator_t it;
58
+ io_service_t service;
59
+ CFDictionaryRef info;
60
+
61
+ if (IOServiceGetMatchingServices(MACH_PORT_NULL,
62
+ IOServiceMatching("IODisplayConnect"),
63
+ &it) != 0)
64
+ {
65
+ // This may happen if a desktop Mac is running headless
66
+ return _glfw_strdup("Display");
67
+ }
68
+
69
+ while ((service = IOIteratorNext(it)) != 0)
70
+ {
71
+ info = IODisplayCreateInfoDictionary(service,
72
+ kIODisplayOnlyPreferredName);
73
+
74
+ CFNumberRef vendorIDRef =
75
+ CFDictionaryGetValue(info, CFSTR(kDisplayVendorID));
76
+ CFNumberRef productIDRef =
77
+ CFDictionaryGetValue(info, CFSTR(kDisplayProductID));
78
+ if (!vendorIDRef || !productIDRef)
79
+ {
80
+ CFRelease(info);
81
+ continue;
82
+ }
83
+
84
+ unsigned int vendorID, productID;
85
+ CFNumberGetValue(vendorIDRef, kCFNumberIntType, &vendorID);
86
+ CFNumberGetValue(productIDRef, kCFNumberIntType, &productID);
87
+
88
+ if (CGDisplayVendorNumber(displayID) == vendorID &&
89
+ CGDisplayModelNumber(displayID) == productID)
90
+ {
91
+ // Info dictionary is used and freed below
92
+ break;
93
+ }
94
+
95
+ CFRelease(info);
96
+ }
97
+
98
+ IOObjectRelease(it);
99
+
100
+ if (!service)
101
+ return _glfw_strdup("Display");
102
+
103
+ CFDictionaryRef names =
104
+ CFDictionaryGetValue(info, CFSTR(kDisplayProductName));
105
+
106
+ CFStringRef nameRef;
107
+
108
+ if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"),
109
+ (const void**) &nameRef))
110
+ {
111
+ // This may happen if a desktop Mac is running headless
112
+ CFRelease(info);
113
+ return _glfw_strdup("Display");
114
+ }
115
+
116
+ const CFIndex size =
117
+ CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef),
118
+ kCFStringEncodingUTF8);
119
+ char* name = _glfw_calloc(size + 1, 1);
120
+ CFStringGetCString(nameRef, name, size, kCFStringEncodingUTF8);
121
+
122
+ CFRelease(info);
123
+ return name;
124
+ }
125
+
126
+ // Check whether the display mode should be included in enumeration
127
+ //
128
+ static GLFWbool modeIsGood(CGDisplayModeRef mode)
129
+ {
130
+ uint32_t flags = CGDisplayModeGetIOFlags(mode);
131
+
132
+ if (!(flags & kDisplayModeValidFlag) || !(flags & kDisplayModeSafeFlag))
133
+ return GLFW_FALSE;
134
+ if (flags & kDisplayModeInterlacedFlag)
135
+ return GLFW_FALSE;
136
+ if (flags & kDisplayModeStretchedFlag)
137
+ return GLFW_FALSE;
138
+
139
+ #if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
140
+ CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
141
+ if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) &&
142
+ CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0))
143
+ {
144
+ CFRelease(format);
145
+ return GLFW_FALSE;
146
+ }
147
+
148
+ CFRelease(format);
149
+ #endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
150
+ return GLFW_TRUE;
151
+ }
152
+
153
+ // Convert Core Graphics display mode to GLFW video mode
154
+ //
155
+ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
156
+ double fallbackRefreshRate)
157
+ {
158
+ GLFWvidmode result;
159
+ result.width = (int) CGDisplayModeGetWidth(mode);
160
+ result.height = (int) CGDisplayModeGetHeight(mode);
161
+ result.refreshRate = (int) round(CGDisplayModeGetRefreshRate(mode));
162
+
163
+ if (result.refreshRate == 0)
164
+ result.refreshRate = (int) round(fallbackRefreshRate);
165
+
166
+ #if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
167
+ CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
168
+ if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0)
169
+ {
170
+ result.redBits = 5;
171
+ result.greenBits = 5;
172
+ result.blueBits = 5;
173
+ }
174
+ else
175
+ #endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
176
+ {
177
+ result.redBits = 8;
178
+ result.greenBits = 8;
179
+ result.blueBits = 8;
180
+ }
181
+
182
+ #if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
183
+ CFRelease(format);
184
+ #endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
185
+ return result;
186
+ }
187
+
188
+ // Starts reservation for display fading
189
+ //
190
+ static CGDisplayFadeReservationToken beginFadeReservation(void)
191
+ {
192
+ CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken;
193
+
194
+ if (CGAcquireDisplayFadeReservation(5, &token) == kCGErrorSuccess)
195
+ {
196
+ CGDisplayFade(token, 0.3,
197
+ kCGDisplayBlendNormal,
198
+ kCGDisplayBlendSolidColor,
199
+ 0.0, 0.0, 0.0,
200
+ TRUE);
201
+ }
202
+
203
+ return token;
204
+ }
205
+
206
+ // Ends reservation for display fading
207
+ //
208
+ static void endFadeReservation(CGDisplayFadeReservationToken token)
209
+ {
210
+ if (token != kCGDisplayFadeReservationInvalidToken)
211
+ {
212
+ CGDisplayFade(token, 0.5,
213
+ kCGDisplayBlendSolidColor,
214
+ kCGDisplayBlendNormal,
215
+ 0.0, 0.0, 0.0,
216
+ FALSE);
217
+ CGReleaseDisplayFadeReservation(token);
218
+ }
219
+ }
220
+
221
+ // Returns the display refresh rate queried from the I/O registry
222
+ //
223
+ static double getFallbackRefreshRate(CGDirectDisplayID displayID)
224
+ {
225
+ double refreshRate = 60.0;
226
+
227
+ io_iterator_t it;
228
+ io_service_t service;
229
+
230
+ if (IOServiceGetMatchingServices(MACH_PORT_NULL,
231
+ IOServiceMatching("IOFramebuffer"),
232
+ &it) != 0)
233
+ {
234
+ return refreshRate;
235
+ }
236
+
237
+ while ((service = IOIteratorNext(it)) != 0)
238
+ {
239
+ const CFNumberRef indexRef =
240
+ IORegistryEntryCreateCFProperty(service,
241
+ CFSTR("IOFramebufferOpenGLIndex"),
242
+ kCFAllocatorDefault,
243
+ kNilOptions);
244
+ if (!indexRef)
245
+ continue;
246
+
247
+ uint32_t index = 0;
248
+ CFNumberGetValue(indexRef, kCFNumberIntType, &index);
249
+ CFRelease(indexRef);
250
+
251
+ if (CGOpenGLDisplayMaskToDisplayID(1 << index) != displayID)
252
+ continue;
253
+
254
+ const CFNumberRef clockRef =
255
+ IORegistryEntryCreateCFProperty(service,
256
+ CFSTR("IOFBCurrentPixelClock"),
257
+ kCFAllocatorDefault,
258
+ kNilOptions);
259
+ const CFNumberRef countRef =
260
+ IORegistryEntryCreateCFProperty(service,
261
+ CFSTR("IOFBCurrentPixelCount"),
262
+ kCFAllocatorDefault,
263
+ kNilOptions);
264
+
265
+ uint32_t clock = 0, count = 0;
266
+
267
+ if (clockRef)
268
+ {
269
+ CFNumberGetValue(clockRef, kCFNumberIntType, &clock);
270
+ CFRelease(clockRef);
271
+ }
272
+
273
+ if (countRef)
274
+ {
275
+ CFNumberGetValue(countRef, kCFNumberIntType, &count);
276
+ CFRelease(countRef);
277
+ }
278
+
279
+ if (clock > 0 && count > 0)
280
+ refreshRate = clock / (double) count;
281
+
282
+ break;
283
+ }
284
+
285
+ IOObjectRelease(it);
286
+ return refreshRate;
287
+ }
288
+
289
+
290
+ //////////////////////////////////////////////////////////////////////////
291
+ ////// GLFW internal API //////
292
+ //////////////////////////////////////////////////////////////////////////
293
+
294
+ // Poll for changes in the set of connected monitors
295
+ //
296
+ void _glfwPollMonitorsCocoa(void)
297
+ {
298
+ uint32_t displayCount;
299
+ CGGetOnlineDisplayList(0, NULL, &displayCount);
300
+ CGDirectDisplayID* displays = _glfw_calloc(displayCount, sizeof(CGDirectDisplayID));
301
+ CGGetOnlineDisplayList(displayCount, displays, &displayCount);
302
+
303
+ for (int i = 0; i < _glfw.monitorCount; i++)
304
+ _glfw.monitors[i]->ns.screen = nil;
305
+
306
+ _GLFWmonitor** disconnected = NULL;
307
+ uint32_t disconnectedCount = _glfw.monitorCount;
308
+ if (disconnectedCount)
309
+ {
310
+ disconnected = _glfw_calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
311
+ memcpy(disconnected,
312
+ _glfw.monitors,
313
+ _glfw.monitorCount * sizeof(_GLFWmonitor*));
314
+ }
315
+
316
+ for (uint32_t i = 0; i < displayCount; i++)
317
+ {
318
+ if (CGDisplayIsAsleep(displays[i]))
319
+ continue;
320
+
321
+ const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
322
+ NSScreen* screen = nil;
323
+
324
+ for (screen in [NSScreen screens])
325
+ {
326
+ NSNumber* screenNumber = [screen deviceDescription][@"NSScreenNumber"];
327
+
328
+ // HACK: Compare unit numbers instead of display IDs to work around
329
+ // display replacement on machines with automatic graphics
330
+ // switching
331
+ if (CGDisplayUnitNumber([screenNumber unsignedIntValue]) == unitNumber)
332
+ break;
333
+ }
334
+
335
+ // HACK: Compare unit numbers instead of display IDs to work around
336
+ // display replacement on machines with automatic graphics
337
+ // switching
338
+ uint32_t j;
339
+ for (j = 0; j < disconnectedCount; j++)
340
+ {
341
+ if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber)
342
+ {
343
+ disconnected[j]->ns.screen = screen;
344
+ disconnected[j] = NULL;
345
+ break;
346
+ }
347
+ }
348
+
349
+ if (j < disconnectedCount)
350
+ continue;
351
+
352
+ const CGSize size = CGDisplayScreenSize(displays[i]);
353
+ char* name = getMonitorName(displays[i], screen);
354
+ if (!name)
355
+ continue;
356
+
357
+ _GLFWmonitor* monitor = _glfwAllocMonitor(name, size.width, size.height);
358
+ monitor->ns.displayID = displays[i];
359
+ monitor->ns.unitNumber = unitNumber;
360
+ monitor->ns.screen = screen;
361
+
362
+ _glfw_free(name);
363
+
364
+ CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displays[i]);
365
+ if (CGDisplayModeGetRefreshRate(mode) == 0.0)
366
+ monitor->ns.fallbackRefreshRate = getFallbackRefreshRate(displays[i]);
367
+ CGDisplayModeRelease(mode);
368
+
369
+ _glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
370
+ }
371
+
372
+ for (uint32_t i = 0; i < disconnectedCount; i++)
373
+ {
374
+ if (disconnected[i])
375
+ _glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
376
+ }
377
+
378
+ _glfw_free(disconnected);
379
+ _glfw_free(displays);
380
+ }
381
+
382
+ // Change the current video mode
383
+ //
384
+ void _glfwSetVideoModeCocoa(_GLFWmonitor* monitor, const GLFWvidmode* desired)
385
+ {
386
+ GLFWvidmode current;
387
+ _glfwGetVideoModeCocoa(monitor, &current);
388
+
389
+ const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
390
+ if (_glfwCompareVideoModes(&current, best) == 0)
391
+ return;
392
+
393
+ CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
394
+ const CFIndex count = CFArrayGetCount(modes);
395
+ CGDisplayModeRef native = NULL;
396
+
397
+ for (CFIndex i = 0; i < count; i++)
398
+ {
399
+ CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
400
+ if (!modeIsGood(dm))
401
+ continue;
402
+
403
+ const GLFWvidmode mode =
404
+ vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate);
405
+ if (_glfwCompareVideoModes(best, &mode) == 0)
406
+ {
407
+ native = dm;
408
+ break;
409
+ }
410
+ }
411
+
412
+ if (native)
413
+ {
414
+ if (monitor->ns.previousMode == NULL)
415
+ monitor->ns.previousMode = CGDisplayCopyDisplayMode(monitor->ns.displayID);
416
+
417
+ CGDisplayFadeReservationToken token = beginFadeReservation();
418
+ CGDisplaySetDisplayMode(monitor->ns.displayID, native, NULL);
419
+ endFadeReservation(token);
420
+ }
421
+
422
+ CFRelease(modes);
423
+ }
424
+
425
+ // Restore the previously saved (original) video mode
426
+ //
427
+ void _glfwRestoreVideoModeCocoa(_GLFWmonitor* monitor)
428
+ {
429
+ if (monitor->ns.previousMode)
430
+ {
431
+ CGDisplayFadeReservationToken token = beginFadeReservation();
432
+ CGDisplaySetDisplayMode(monitor->ns.displayID,
433
+ monitor->ns.previousMode, NULL);
434
+ endFadeReservation(token);
435
+
436
+ CGDisplayModeRelease(monitor->ns.previousMode);
437
+ monitor->ns.previousMode = NULL;
438
+ }
439
+ }
440
+
441
+
442
+ //////////////////////////////////////////////////////////////////////////
443
+ ////// GLFW platform API //////
444
+ //////////////////////////////////////////////////////////////////////////
445
+
446
+ void _glfwFreeMonitorCocoa(_GLFWmonitor* monitor)
447
+ {
448
+ }
449
+
450
+ void _glfwGetMonitorPosCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos)
451
+ {
452
+ @autoreleasepool {
453
+
454
+ const CGRect bounds = CGDisplayBounds(monitor->ns.displayID);
455
+
456
+ if (xpos)
457
+ *xpos = (int) bounds.origin.x;
458
+ if (ypos)
459
+ *ypos = (int) bounds.origin.y;
460
+
461
+ } // autoreleasepool
462
+ }
463
+
464
+ void _glfwGetMonitorContentScaleCocoa(_GLFWmonitor* monitor,
465
+ float* xscale, float* yscale)
466
+ {
467
+ @autoreleasepool {
468
+
469
+ if (!monitor->ns.screen)
470
+ {
471
+ _glfwInputError(GLFW_PLATFORM_ERROR,
472
+ "Cocoa: Cannot query content scale without screen");
473
+ }
474
+
475
+ const NSRect points = [monitor->ns.screen frame];
476
+ const NSRect pixels = [monitor->ns.screen convertRectToBacking:points];
477
+
478
+ if (xscale)
479
+ *xscale = (float) (pixels.size.width / points.size.width);
480
+ if (yscale)
481
+ *yscale = (float) (pixels.size.height / points.size.height);
482
+
483
+ } // autoreleasepool
484
+ }
485
+
486
+ void _glfwGetMonitorWorkareaCocoa(_GLFWmonitor* monitor,
487
+ int* xpos, int* ypos,
488
+ int* width, int* height)
489
+ {
490
+ @autoreleasepool {
491
+
492
+ if (!monitor->ns.screen)
493
+ {
494
+ _glfwInputError(GLFW_PLATFORM_ERROR,
495
+ "Cocoa: Cannot query workarea without screen");
496
+ }
497
+
498
+ const NSRect frameRect = [monitor->ns.screen visibleFrame];
499
+
500
+ if (xpos)
501
+ *xpos = frameRect.origin.x;
502
+ if (ypos)
503
+ *ypos = _glfwTransformYCocoa(frameRect.origin.y + frameRect.size.height - 1);
504
+ if (width)
505
+ *width = frameRect.size.width;
506
+ if (height)
507
+ *height = frameRect.size.height;
508
+
509
+ } // autoreleasepool
510
+ }
511
+
512
+ GLFWvidmode* _glfwGetVideoModesCocoa(_GLFWmonitor* monitor, int* count)
513
+ {
514
+ @autoreleasepool {
515
+
516
+ *count = 0;
517
+
518
+ CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
519
+ const CFIndex found = CFArrayGetCount(modes);
520
+ GLFWvidmode* result = _glfw_calloc(found, sizeof(GLFWvidmode));
521
+
522
+ for (CFIndex i = 0; i < found; i++)
523
+ {
524
+ CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
525
+ if (!modeIsGood(dm))
526
+ continue;
527
+
528
+ const GLFWvidmode mode =
529
+ vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate);
530
+ CFIndex j;
531
+
532
+ for (j = 0; j < *count; j++)
533
+ {
534
+ if (_glfwCompareVideoModes(result + j, &mode) == 0)
535
+ break;
536
+ }
537
+
538
+ // Skip duplicate modes
539
+ if (j < *count)
540
+ continue;
541
+
542
+ (*count)++;
543
+ result[*count - 1] = mode;
544
+ }
545
+
546
+ CFRelease(modes);
547
+ return result;
548
+
549
+ } // autoreleasepool
550
+ }
551
+
552
+ GLFWbool _glfwGetVideoModeCocoa(_GLFWmonitor* monitor, GLFWvidmode *mode)
553
+ {
554
+ @autoreleasepool {
555
+
556
+ CGDisplayModeRef native = CGDisplayCopyDisplayMode(monitor->ns.displayID);
557
+ if (!native)
558
+ {
559
+ _glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to query display mode");
560
+ return GLFW_FALSE;
561
+ }
562
+
563
+ *mode = vidmodeFromCGDisplayMode(native, monitor->ns.fallbackRefreshRate);
564
+ CGDisplayModeRelease(native);
565
+ return GLFW_TRUE;
566
+
567
+ } // autoreleasepool
568
+ }
569
+
570
+ GLFWbool _glfwGetGammaRampCocoa(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
571
+ {
572
+ @autoreleasepool {
573
+
574
+ uint32_t size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
575
+ CGGammaValue* values = _glfw_calloc(size * 3, sizeof(CGGammaValue));
576
+
577
+ CGGetDisplayTransferByTable(monitor->ns.displayID,
578
+ size,
579
+ values,
580
+ values + size,
581
+ values + size * 2,
582
+ &size);
583
+
584
+ _glfwAllocGammaArrays(ramp, size);
585
+
586
+ for (uint32_t i = 0; i < size; i++)
587
+ {
588
+ ramp->red[i] = (unsigned short) (values[i] * 65535);
589
+ ramp->green[i] = (unsigned short) (values[i + size] * 65535);
590
+ ramp->blue[i] = (unsigned short) (values[i + size * 2] * 65535);
591
+ }
592
+
593
+ _glfw_free(values);
594
+ return GLFW_TRUE;
595
+
596
+ } // autoreleasepool
597
+ }
598
+
599
+ void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
600
+ {
601
+ @autoreleasepool {
602
+
603
+ CGGammaValue* values = _glfw_calloc(ramp->size * 3, sizeof(CGGammaValue));
604
+
605
+ for (unsigned int i = 0; i < ramp->size; i++)
606
+ {
607
+ values[i] = ramp->red[i] / 65535.f;
608
+ values[i + ramp->size] = ramp->green[i] / 65535.f;
609
+ values[i + ramp->size * 2] = ramp->blue[i] / 65535.f;
610
+ }
611
+
612
+ CGSetDisplayTransferByTable(monitor->ns.displayID,
613
+ ramp->size,
614
+ values,
615
+ values + ramp->size,
616
+ values + ramp->size * 2);
617
+
618
+ _glfw_free(values);
619
+
620
+ } // autoreleasepool
621
+ }
622
+
623
+
624
+ //////////////////////////////////////////////////////////////////////////
625
+ ////// GLFW native API //////
626
+ //////////////////////////////////////////////////////////////////////////
627
+
628
+ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle)
629
+ {
630
+ _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
631
+ _GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay);
632
+
633
+ if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)
634
+ {
635
+ _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Cocoa: Platform not initialized");
636
+ return kCGNullDirectDisplay;
637
+ }
638
+
639
+ return monitor->ns.displayID;
640
+ }
641
+
642
+ #endif // _GLFW_COCOA
643
+