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,694 @@
1
+ //========================================================================
2
+ // GLFW 3.4 macOS - www.glfw.org
3
+ //------------------------------------------------------------------------
4
+ // Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
5
+ //
6
+ // This software is provided 'as-is', without any express or implied
7
+ // warranty. In no event will the authors be held liable for any damages
8
+ // arising from the use of this software.
9
+ //
10
+ // Permission is granted to anyone to use this software for any purpose,
11
+ // including commercial applications, and to alter it and redistribute it
12
+ // freely, subject to the following restrictions:
13
+ //
14
+ // 1. The origin of this software must not be misrepresented; you must not
15
+ // claim that you wrote the original software. If you use this software
16
+ // in a product, an acknowledgment in the product documentation would
17
+ // be appreciated but is not required.
18
+ //
19
+ // 2. Altered source versions must be plainly marked as such, and must not
20
+ // be misrepresented as being the original software.
21
+ //
22
+ // 3. This notice may not be removed or altered from any source
23
+ // distribution.
24
+ //
25
+ //========================================================================
26
+
27
+ #include "internal.h"
28
+
29
+ #if defined(_GLFW_COCOA)
30
+
31
+ #include <sys/param.h> // For MAXPATHLEN
32
+
33
+ // Needed for _NSGetProgname
34
+ #include <crt_externs.h>
35
+
36
+ // Change to our application bundle's resources directory, if present
37
+ //
38
+ static void changeToResourcesDirectory(void)
39
+ {
40
+ char resourcesPath[MAXPATHLEN];
41
+
42
+ CFBundleRef bundle = CFBundleGetMainBundle();
43
+ if (!bundle)
44
+ return;
45
+
46
+ CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(bundle);
47
+
48
+ CFStringRef last = CFURLCopyLastPathComponent(resourcesURL);
49
+ if (CFStringCompare(CFSTR("Resources"), last, 0) != kCFCompareEqualTo)
50
+ {
51
+ CFRelease(last);
52
+ CFRelease(resourcesURL);
53
+ return;
54
+ }
55
+
56
+ CFRelease(last);
57
+
58
+ if (!CFURLGetFileSystemRepresentation(resourcesURL,
59
+ true,
60
+ (UInt8*) resourcesPath,
61
+ MAXPATHLEN))
62
+ {
63
+ CFRelease(resourcesURL);
64
+ return;
65
+ }
66
+
67
+ CFRelease(resourcesURL);
68
+
69
+ chdir(resourcesPath);
70
+ }
71
+
72
+ // Set up the menu bar (manually)
73
+ // This is nasty, nasty stuff -- calls to undocumented semi-private APIs that
74
+ // could go away at any moment, lots of stuff that really should be
75
+ // localize(d|able), etc. Add a nib to save us this horror.
76
+ //
77
+ static void createMenuBar(void)
78
+ {
79
+ NSString* appName = nil;
80
+ NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary];
81
+ NSString* nameKeys[] =
82
+ {
83
+ @"CFBundleDisplayName",
84
+ @"CFBundleName",
85
+ @"CFBundleExecutable",
86
+ };
87
+
88
+ // Try to figure out what the calling application is called
89
+
90
+ for (size_t i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++)
91
+ {
92
+ id name = bundleInfo[nameKeys[i]];
93
+ if (name &&
94
+ [name isKindOfClass:[NSString class]] &&
95
+ ![name isEqualToString:@""])
96
+ {
97
+ appName = name;
98
+ break;
99
+ }
100
+ }
101
+
102
+ if (!appName)
103
+ {
104
+ char** progname = _NSGetProgname();
105
+ if (progname && *progname)
106
+ appName = @(*progname);
107
+ else
108
+ appName = @"GLFW Application";
109
+ }
110
+
111
+ NSMenu* bar = [[NSMenu alloc] init];
112
+ [NSApp setMainMenu:bar];
113
+
114
+ NSMenuItem* appMenuItem =
115
+ [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
116
+ NSMenu* appMenu = [[NSMenu alloc] init];
117
+ [appMenuItem setSubmenu:appMenu];
118
+
119
+ [appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName]
120
+ action:@selector(orderFrontStandardAboutPanel:)
121
+ keyEquivalent:@""];
122
+ [appMenu addItem:[NSMenuItem separatorItem]];
123
+ NSMenu* servicesMenu = [[NSMenu alloc] init];
124
+ [NSApp setServicesMenu:servicesMenu];
125
+ [[appMenu addItemWithTitle:@"Services"
126
+ action:NULL
127
+ keyEquivalent:@""] setSubmenu:servicesMenu];
128
+ [servicesMenu release];
129
+ [appMenu addItem:[NSMenuItem separatorItem]];
130
+ [appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName]
131
+ action:@selector(hide:)
132
+ keyEquivalent:@"h"];
133
+ [[appMenu addItemWithTitle:@"Hide Others"
134
+ action:@selector(hideOtherApplications:)
135
+ keyEquivalent:@"h"]
136
+ setKeyEquivalentModifierMask:NSEventModifierFlagOption | NSEventModifierFlagCommand];
137
+ [appMenu addItemWithTitle:@"Show All"
138
+ action:@selector(unhideAllApplications:)
139
+ keyEquivalent:@""];
140
+ [appMenu addItem:[NSMenuItem separatorItem]];
141
+ [appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName]
142
+ action:@selector(terminate:)
143
+ keyEquivalent:@"q"];
144
+
145
+ NSMenuItem* windowMenuItem =
146
+ [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
147
+ [bar release];
148
+ NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
149
+ [NSApp setWindowsMenu:windowMenu];
150
+ [windowMenuItem setSubmenu:windowMenu];
151
+
152
+ [windowMenu addItemWithTitle:@"Minimize"
153
+ action:@selector(performMiniaturize:)
154
+ keyEquivalent:@"m"];
155
+ [windowMenu addItemWithTitle:@"Zoom"
156
+ action:@selector(performZoom:)
157
+ keyEquivalent:@""];
158
+ [windowMenu addItem:[NSMenuItem separatorItem]];
159
+ [windowMenu addItemWithTitle:@"Bring All to Front"
160
+ action:@selector(arrangeInFront:)
161
+ keyEquivalent:@""];
162
+
163
+ // TODO: Make this appear at the bottom of the menu (for consistency)
164
+ [windowMenu addItem:[NSMenuItem separatorItem]];
165
+ [[windowMenu addItemWithTitle:@"Enter Full Screen"
166
+ action:@selector(toggleFullScreen:)
167
+ keyEquivalent:@"f"]
168
+ setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand];
169
+
170
+ // Prior to Snow Leopard, we need to use this oddly-named semi-private API
171
+ // to get the application menu working properly.
172
+ SEL setAppleMenuSelector = NSSelectorFromString(@"setAppleMenu:");
173
+ [NSApp performSelector:setAppleMenuSelector withObject:appMenu];
174
+ }
175
+
176
+ // Create key code translation tables
177
+ //
178
+ static void createKeyTables(void)
179
+ {
180
+ memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes));
181
+ memset(_glfw.ns.scancodes, -1, sizeof(_glfw.ns.scancodes));
182
+
183
+ _glfw.ns.keycodes[0x1D] = GLFW_KEY_0;
184
+ _glfw.ns.keycodes[0x12] = GLFW_KEY_1;
185
+ _glfw.ns.keycodes[0x13] = GLFW_KEY_2;
186
+ _glfw.ns.keycodes[0x14] = GLFW_KEY_3;
187
+ _glfw.ns.keycodes[0x15] = GLFW_KEY_4;
188
+ _glfw.ns.keycodes[0x17] = GLFW_KEY_5;
189
+ _glfw.ns.keycodes[0x16] = GLFW_KEY_6;
190
+ _glfw.ns.keycodes[0x1A] = GLFW_KEY_7;
191
+ _glfw.ns.keycodes[0x1C] = GLFW_KEY_8;
192
+ _glfw.ns.keycodes[0x19] = GLFW_KEY_9;
193
+ _glfw.ns.keycodes[0x00] = GLFW_KEY_A;
194
+ _glfw.ns.keycodes[0x0B] = GLFW_KEY_B;
195
+ _glfw.ns.keycodes[0x08] = GLFW_KEY_C;
196
+ _glfw.ns.keycodes[0x02] = GLFW_KEY_D;
197
+ _glfw.ns.keycodes[0x0E] = GLFW_KEY_E;
198
+ _glfw.ns.keycodes[0x03] = GLFW_KEY_F;
199
+ _glfw.ns.keycodes[0x05] = GLFW_KEY_G;
200
+ _glfw.ns.keycodes[0x04] = GLFW_KEY_H;
201
+ _glfw.ns.keycodes[0x22] = GLFW_KEY_I;
202
+ _glfw.ns.keycodes[0x26] = GLFW_KEY_J;
203
+ _glfw.ns.keycodes[0x28] = GLFW_KEY_K;
204
+ _glfw.ns.keycodes[0x25] = GLFW_KEY_L;
205
+ _glfw.ns.keycodes[0x2E] = GLFW_KEY_M;
206
+ _glfw.ns.keycodes[0x2D] = GLFW_KEY_N;
207
+ _glfw.ns.keycodes[0x1F] = GLFW_KEY_O;
208
+ _glfw.ns.keycodes[0x23] = GLFW_KEY_P;
209
+ _glfw.ns.keycodes[0x0C] = GLFW_KEY_Q;
210
+ _glfw.ns.keycodes[0x0F] = GLFW_KEY_R;
211
+ _glfw.ns.keycodes[0x01] = GLFW_KEY_S;
212
+ _glfw.ns.keycodes[0x11] = GLFW_KEY_T;
213
+ _glfw.ns.keycodes[0x20] = GLFW_KEY_U;
214
+ _glfw.ns.keycodes[0x09] = GLFW_KEY_V;
215
+ _glfw.ns.keycodes[0x0D] = GLFW_KEY_W;
216
+ _glfw.ns.keycodes[0x07] = GLFW_KEY_X;
217
+ _glfw.ns.keycodes[0x10] = GLFW_KEY_Y;
218
+ _glfw.ns.keycodes[0x06] = GLFW_KEY_Z;
219
+
220
+ _glfw.ns.keycodes[0x27] = GLFW_KEY_APOSTROPHE;
221
+ _glfw.ns.keycodes[0x2A] = GLFW_KEY_BACKSLASH;
222
+ _glfw.ns.keycodes[0x2B] = GLFW_KEY_COMMA;
223
+ _glfw.ns.keycodes[0x18] = GLFW_KEY_EQUAL;
224
+ _glfw.ns.keycodes[0x32] = GLFW_KEY_GRAVE_ACCENT;
225
+ _glfw.ns.keycodes[0x21] = GLFW_KEY_LEFT_BRACKET;
226
+ _glfw.ns.keycodes[0x1B] = GLFW_KEY_MINUS;
227
+ _glfw.ns.keycodes[0x2F] = GLFW_KEY_PERIOD;
228
+ _glfw.ns.keycodes[0x1E] = GLFW_KEY_RIGHT_BRACKET;
229
+ _glfw.ns.keycodes[0x29] = GLFW_KEY_SEMICOLON;
230
+ _glfw.ns.keycodes[0x2C] = GLFW_KEY_SLASH;
231
+ _glfw.ns.keycodes[0x0A] = GLFW_KEY_WORLD_1;
232
+
233
+ _glfw.ns.keycodes[0x33] = GLFW_KEY_BACKSPACE;
234
+ _glfw.ns.keycodes[0x39] = GLFW_KEY_CAPS_LOCK;
235
+ _glfw.ns.keycodes[0x75] = GLFW_KEY_DELETE;
236
+ _glfw.ns.keycodes[0x7D] = GLFW_KEY_DOWN;
237
+ _glfw.ns.keycodes[0x77] = GLFW_KEY_END;
238
+ _glfw.ns.keycodes[0x24] = GLFW_KEY_ENTER;
239
+ _glfw.ns.keycodes[0x35] = GLFW_KEY_ESCAPE;
240
+ _glfw.ns.keycodes[0x7A] = GLFW_KEY_F1;
241
+ _glfw.ns.keycodes[0x78] = GLFW_KEY_F2;
242
+ _glfw.ns.keycodes[0x63] = GLFW_KEY_F3;
243
+ _glfw.ns.keycodes[0x76] = GLFW_KEY_F4;
244
+ _glfw.ns.keycodes[0x60] = GLFW_KEY_F5;
245
+ _glfw.ns.keycodes[0x61] = GLFW_KEY_F6;
246
+ _glfw.ns.keycodes[0x62] = GLFW_KEY_F7;
247
+ _glfw.ns.keycodes[0x64] = GLFW_KEY_F8;
248
+ _glfw.ns.keycodes[0x65] = GLFW_KEY_F9;
249
+ _glfw.ns.keycodes[0x6D] = GLFW_KEY_F10;
250
+ _glfw.ns.keycodes[0x67] = GLFW_KEY_F11;
251
+ _glfw.ns.keycodes[0x6F] = GLFW_KEY_F12;
252
+ _glfw.ns.keycodes[0x69] = GLFW_KEY_PRINT_SCREEN;
253
+ _glfw.ns.keycodes[0x6B] = GLFW_KEY_F14;
254
+ _glfw.ns.keycodes[0x71] = GLFW_KEY_F15;
255
+ _glfw.ns.keycodes[0x6A] = GLFW_KEY_F16;
256
+ _glfw.ns.keycodes[0x40] = GLFW_KEY_F17;
257
+ _glfw.ns.keycodes[0x4F] = GLFW_KEY_F18;
258
+ _glfw.ns.keycodes[0x50] = GLFW_KEY_F19;
259
+ _glfw.ns.keycodes[0x5A] = GLFW_KEY_F20;
260
+ _glfw.ns.keycodes[0x73] = GLFW_KEY_HOME;
261
+ _glfw.ns.keycodes[0x72] = GLFW_KEY_INSERT;
262
+ _glfw.ns.keycodes[0x7B] = GLFW_KEY_LEFT;
263
+ _glfw.ns.keycodes[0x3A] = GLFW_KEY_LEFT_ALT;
264
+ _glfw.ns.keycodes[0x3B] = GLFW_KEY_LEFT_CONTROL;
265
+ _glfw.ns.keycodes[0x38] = GLFW_KEY_LEFT_SHIFT;
266
+ _glfw.ns.keycodes[0x37] = GLFW_KEY_LEFT_SUPER;
267
+ _glfw.ns.keycodes[0x6E] = GLFW_KEY_MENU;
268
+ _glfw.ns.keycodes[0x47] = GLFW_KEY_NUM_LOCK;
269
+ _glfw.ns.keycodes[0x79] = GLFW_KEY_PAGE_DOWN;
270
+ _glfw.ns.keycodes[0x74] = GLFW_KEY_PAGE_UP;
271
+ _glfw.ns.keycodes[0x7C] = GLFW_KEY_RIGHT;
272
+ _glfw.ns.keycodes[0x3D] = GLFW_KEY_RIGHT_ALT;
273
+ _glfw.ns.keycodes[0x3E] = GLFW_KEY_RIGHT_CONTROL;
274
+ _glfw.ns.keycodes[0x3C] = GLFW_KEY_RIGHT_SHIFT;
275
+ _glfw.ns.keycodes[0x36] = GLFW_KEY_RIGHT_SUPER;
276
+ _glfw.ns.keycodes[0x31] = GLFW_KEY_SPACE;
277
+ _glfw.ns.keycodes[0x30] = GLFW_KEY_TAB;
278
+ _glfw.ns.keycodes[0x7E] = GLFW_KEY_UP;
279
+
280
+ _glfw.ns.keycodes[0x52] = GLFW_KEY_KP_0;
281
+ _glfw.ns.keycodes[0x53] = GLFW_KEY_KP_1;
282
+ _glfw.ns.keycodes[0x54] = GLFW_KEY_KP_2;
283
+ _glfw.ns.keycodes[0x55] = GLFW_KEY_KP_3;
284
+ _glfw.ns.keycodes[0x56] = GLFW_KEY_KP_4;
285
+ _glfw.ns.keycodes[0x57] = GLFW_KEY_KP_5;
286
+ _glfw.ns.keycodes[0x58] = GLFW_KEY_KP_6;
287
+ _glfw.ns.keycodes[0x59] = GLFW_KEY_KP_7;
288
+ _glfw.ns.keycodes[0x5B] = GLFW_KEY_KP_8;
289
+ _glfw.ns.keycodes[0x5C] = GLFW_KEY_KP_9;
290
+ _glfw.ns.keycodes[0x45] = GLFW_KEY_KP_ADD;
291
+ _glfw.ns.keycodes[0x41] = GLFW_KEY_KP_DECIMAL;
292
+ _glfw.ns.keycodes[0x4B] = GLFW_KEY_KP_DIVIDE;
293
+ _glfw.ns.keycodes[0x4C] = GLFW_KEY_KP_ENTER;
294
+ _glfw.ns.keycodes[0x51] = GLFW_KEY_KP_EQUAL;
295
+ _glfw.ns.keycodes[0x43] = GLFW_KEY_KP_MULTIPLY;
296
+ _glfw.ns.keycodes[0x4E] = GLFW_KEY_KP_SUBTRACT;
297
+
298
+ for (int scancode = 0; scancode < 256; scancode++)
299
+ {
300
+ // Store the reverse translation for faster key name lookup
301
+ if (_glfw.ns.keycodes[scancode] >= 0)
302
+ _glfw.ns.scancodes[_glfw.ns.keycodes[scancode]] = scancode;
303
+ }
304
+ }
305
+
306
+ // Retrieve Unicode data for the current keyboard layout
307
+ //
308
+ static GLFWbool updateUnicodeData(void)
309
+ {
310
+ if (_glfw.ns.inputSource)
311
+ {
312
+ CFRelease(_glfw.ns.inputSource);
313
+ _glfw.ns.inputSource = NULL;
314
+ _glfw.ns.unicodeData = nil;
315
+ }
316
+
317
+ _glfw.ns.inputSource = TISCopyCurrentKeyboardLayoutInputSource();
318
+ if (!_glfw.ns.inputSource)
319
+ {
320
+ _glfwInputError(GLFW_PLATFORM_ERROR,
321
+ "Cocoa: Failed to retrieve keyboard layout input source");
322
+ return GLFW_FALSE;
323
+ }
324
+
325
+ _glfw.ns.unicodeData =
326
+ TISGetInputSourceProperty(_glfw.ns.inputSource,
327
+ kTISPropertyUnicodeKeyLayoutData);
328
+ if (!_glfw.ns.unicodeData)
329
+ {
330
+ _glfwInputError(GLFW_PLATFORM_ERROR,
331
+ "Cocoa: Failed to retrieve keyboard layout Unicode data");
332
+ return GLFW_FALSE;
333
+ }
334
+
335
+ return GLFW_TRUE;
336
+ }
337
+
338
+ // Load HIToolbox.framework and the TIS symbols we need from it
339
+ //
340
+ static GLFWbool initializeTIS(void)
341
+ {
342
+ // This works only because Cocoa has already loaded it properly
343
+ _glfw.ns.tis.bundle =
344
+ CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));
345
+ if (!_glfw.ns.tis.bundle)
346
+ {
347
+ _glfwInputError(GLFW_PLATFORM_ERROR,
348
+ "Cocoa: Failed to load HIToolbox.framework");
349
+ return GLFW_FALSE;
350
+ }
351
+
352
+ CFStringRef* kPropertyUnicodeKeyLayoutData =
353
+ CFBundleGetDataPointerForName(_glfw.ns.tis.bundle,
354
+ CFSTR("kTISPropertyUnicodeKeyLayoutData"));
355
+ _glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource =
356
+ CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
357
+ CFSTR("TISCopyCurrentKeyboardLayoutInputSource"));
358
+ _glfw.ns.tis.GetInputSourceProperty =
359
+ CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
360
+ CFSTR("TISGetInputSourceProperty"));
361
+ _glfw.ns.tis.GetKbdType =
362
+ CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
363
+ CFSTR("LMGetKbdType"));
364
+
365
+ if (!kPropertyUnicodeKeyLayoutData ||
366
+ !TISCopyCurrentKeyboardLayoutInputSource ||
367
+ !TISGetInputSourceProperty ||
368
+ !LMGetKbdType)
369
+ {
370
+ _glfwInputError(GLFW_PLATFORM_ERROR,
371
+ "Cocoa: Failed to load TIS API symbols");
372
+ return GLFW_FALSE;
373
+ }
374
+
375
+ _glfw.ns.tis.kPropertyUnicodeKeyLayoutData =
376
+ *kPropertyUnicodeKeyLayoutData;
377
+
378
+ return updateUnicodeData();
379
+ }
380
+
381
+ @interface GLFWHelper : NSObject
382
+ @end
383
+
384
+ @implementation GLFWHelper
385
+
386
+ - (void)selectedKeyboardInputSourceChanged:(NSObject* )object
387
+ {
388
+ updateUnicodeData();
389
+ }
390
+
391
+ - (void)doNothing:(id)object
392
+ {
393
+ }
394
+
395
+ @end // GLFWHelper
396
+
397
+ @interface GLFWApplicationDelegate : NSObject <NSApplicationDelegate>
398
+ @end
399
+
400
+ @implementation GLFWApplicationDelegate
401
+
402
+ - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
403
+ {
404
+ for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
405
+ _glfwInputWindowCloseRequest(window);
406
+
407
+ return NSTerminateCancel;
408
+ }
409
+
410
+ - (void)applicationDidChangeScreenParameters:(NSNotification *) notification
411
+ {
412
+ for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
413
+ {
414
+ if (window->context.client != GLFW_NO_API)
415
+ [window->context.nsgl.object update];
416
+ }
417
+
418
+ _glfwPollMonitorsCocoa();
419
+ }
420
+
421
+ - (void)applicationWillFinishLaunching:(NSNotification *)notification
422
+ {
423
+ if (_glfw.hints.init.ns.menubar)
424
+ {
425
+ // Menu bar setup must go between sharedApplication and finishLaunching
426
+ // in order to properly emulate the behavior of NSApplicationMain
427
+
428
+ if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"])
429
+ {
430
+ [[NSBundle mainBundle] loadNibNamed:@"MainMenu"
431
+ owner:NSApp
432
+ topLevelObjects:&_glfw.ns.nibObjects];
433
+ }
434
+ else
435
+ createMenuBar();
436
+ }
437
+ }
438
+
439
+ - (void)applicationDidFinishLaunching:(NSNotification *)notification
440
+ {
441
+ _glfwPostEmptyEventCocoa();
442
+ [NSApp stop:nil];
443
+ }
444
+
445
+ - (void)applicationDidHide:(NSNotification *)notification
446
+ {
447
+ for (int i = 0; i < _glfw.monitorCount; i++)
448
+ _glfwRestoreVideoModeCocoa(_glfw.monitors[i]);
449
+ }
450
+
451
+ @end // GLFWApplicationDelegate
452
+
453
+
454
+ //////////////////////////////////////////////////////////////////////////
455
+ ////// GLFW internal API //////
456
+ //////////////////////////////////////////////////////////////////////////
457
+
458
+ void* _glfwLoadLocalVulkanLoaderCocoa(void)
459
+ {
460
+ CFBundleRef bundle = CFBundleGetMainBundle();
461
+ if (!bundle)
462
+ return NULL;
463
+
464
+ CFURLRef frameworksUrl = CFBundleCopyPrivateFrameworksURL(bundle);
465
+ if (!frameworksUrl)
466
+ return NULL;
467
+
468
+ CFURLRef loaderUrl = CFURLCreateCopyAppendingPathComponent(
469
+ kCFAllocatorDefault, frameworksUrl, CFSTR("libvulkan.1.dylib"), false);
470
+ if (!loaderUrl)
471
+ {
472
+ CFRelease(frameworksUrl);
473
+ return NULL;
474
+ }
475
+
476
+ char path[PATH_MAX];
477
+ void* handle = NULL;
478
+
479
+ if (CFURLGetFileSystemRepresentation(loaderUrl, true, (UInt8*) path, sizeof(path) - 1))
480
+ handle = _glfwPlatformLoadModule(path);
481
+
482
+ CFRelease(loaderUrl);
483
+ CFRelease(frameworksUrl);
484
+ return handle;
485
+ }
486
+
487
+
488
+ //////////////////////////////////////////////////////////////////////////
489
+ ////// GLFW platform API //////
490
+ //////////////////////////////////////////////////////////////////////////
491
+
492
+ GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform)
493
+ {
494
+ const _GLFWplatform cocoa =
495
+ {
496
+ .platformID = GLFW_PLATFORM_COCOA,
497
+ .init = _glfwInitCocoa,
498
+ .terminate = _glfwTerminateCocoa,
499
+ .getCursorPos = _glfwGetCursorPosCocoa,
500
+ .setCursorPos = _glfwSetCursorPosCocoa,
501
+ .setCursorMode = _glfwSetCursorModeCocoa,
502
+ .setRawMouseMotion = _glfwSetRawMouseMotionCocoa,
503
+ .rawMouseMotionSupported = _glfwRawMouseMotionSupportedCocoa,
504
+ .createCursor = _glfwCreateCursorCocoa,
505
+ .createStandardCursor = _glfwCreateStandardCursorCocoa,
506
+ .destroyCursor = _glfwDestroyCursorCocoa,
507
+ .setCursor = _glfwSetCursorCocoa,
508
+ .getScancodeName = _glfwGetScancodeNameCocoa,
509
+ .getKeyScancode = _glfwGetKeyScancodeCocoa,
510
+ .setClipboardString = _glfwSetClipboardStringCocoa,
511
+ .getClipboardString = _glfwGetClipboardStringCocoa,
512
+ .initJoysticks = _glfwInitJoysticksCocoa,
513
+ .terminateJoysticks = _glfwTerminateJoysticksCocoa,
514
+ .pollJoystick = _glfwPollJoystickCocoa,
515
+ .getMappingName = _glfwGetMappingNameCocoa,
516
+ .updateGamepadGUID = _glfwUpdateGamepadGUIDCocoa,
517
+ .freeMonitor = _glfwFreeMonitorCocoa,
518
+ .getMonitorPos = _glfwGetMonitorPosCocoa,
519
+ .getMonitorContentScale = _glfwGetMonitorContentScaleCocoa,
520
+ .getMonitorWorkarea = _glfwGetMonitorWorkareaCocoa,
521
+ .getVideoModes = _glfwGetVideoModesCocoa,
522
+ .getVideoMode = _glfwGetVideoModeCocoa,
523
+ .getGammaRamp = _glfwGetGammaRampCocoa,
524
+ .setGammaRamp = _glfwSetGammaRampCocoa,
525
+ .createWindow = _glfwCreateWindowCocoa,
526
+ .destroyWindow = _glfwDestroyWindowCocoa,
527
+ .setWindowTitle = _glfwSetWindowTitleCocoa,
528
+ .setWindowIcon = _glfwSetWindowIconCocoa,
529
+ .getWindowPos = _glfwGetWindowPosCocoa,
530
+ .setWindowPos = _glfwSetWindowPosCocoa,
531
+ .getWindowSize = _glfwGetWindowSizeCocoa,
532
+ .setWindowSize = _glfwSetWindowSizeCocoa,
533
+ .setWindowSizeLimits = _glfwSetWindowSizeLimitsCocoa,
534
+ .setWindowAspectRatio = _glfwSetWindowAspectRatioCocoa,
535
+ .getFramebufferSize = _glfwGetFramebufferSizeCocoa,
536
+ .getWindowFrameSize = _glfwGetWindowFrameSizeCocoa,
537
+ .getWindowContentScale = _glfwGetWindowContentScaleCocoa,
538
+ .iconifyWindow = _glfwIconifyWindowCocoa,
539
+ .restoreWindow = _glfwRestoreWindowCocoa,
540
+ .maximizeWindow = _glfwMaximizeWindowCocoa,
541
+ .showWindow = _glfwShowWindowCocoa,
542
+ .hideWindow = _glfwHideWindowCocoa,
543
+ .requestWindowAttention = _glfwRequestWindowAttentionCocoa,
544
+ .focusWindow = _glfwFocusWindowCocoa,
545
+ .setWindowMonitor = _glfwSetWindowMonitorCocoa,
546
+ .windowFocused = _glfwWindowFocusedCocoa,
547
+ .windowIconified = _glfwWindowIconifiedCocoa,
548
+ .windowVisible = _glfwWindowVisibleCocoa,
549
+ .windowMaximized = _glfwWindowMaximizedCocoa,
550
+ .windowHovered = _glfwWindowHoveredCocoa,
551
+ .framebufferTransparent = _glfwFramebufferTransparentCocoa,
552
+ .getWindowOpacity = _glfwGetWindowOpacityCocoa,
553
+ .setWindowResizable = _glfwSetWindowResizableCocoa,
554
+ .setWindowDecorated = _glfwSetWindowDecoratedCocoa,
555
+ .setWindowFloating = _glfwSetWindowFloatingCocoa,
556
+ .setWindowOpacity = _glfwSetWindowOpacityCocoa,
557
+ .setWindowMousePassthrough = _glfwSetWindowMousePassthroughCocoa,
558
+ .pollEvents = _glfwPollEventsCocoa,
559
+ .waitEvents = _glfwWaitEventsCocoa,
560
+ .waitEventsTimeout = _glfwWaitEventsTimeoutCocoa,
561
+ .postEmptyEvent = _glfwPostEmptyEventCocoa,
562
+ .getEGLPlatform = _glfwGetEGLPlatformCocoa,
563
+ .getEGLNativeDisplay = _glfwGetEGLNativeDisplayCocoa,
564
+ .getEGLNativeWindow = _glfwGetEGLNativeWindowCocoa,
565
+ .getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsCocoa,
566
+ .getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportCocoa,
567
+ .createWindowSurface = _glfwCreateWindowSurfaceCocoa
568
+ };
569
+
570
+ *platform = cocoa;
571
+ return GLFW_TRUE;
572
+ }
573
+
574
+ int _glfwInitCocoa(void)
575
+ {
576
+ @autoreleasepool {
577
+
578
+ _glfw.ns.helper = [[GLFWHelper alloc] init];
579
+
580
+ [NSThread detachNewThreadSelector:@selector(doNothing:)
581
+ toTarget:_glfw.ns.helper
582
+ withObject:nil];
583
+
584
+ [NSApplication sharedApplication];
585
+
586
+ _glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init];
587
+ if (_glfw.ns.delegate == nil)
588
+ {
589
+ _glfwInputError(GLFW_PLATFORM_ERROR,
590
+ "Cocoa: Failed to create application delegate");
591
+ return GLFW_FALSE;
592
+ }
593
+
594
+ [NSApp setDelegate:_glfw.ns.delegate];
595
+
596
+ NSEvent* (^block)(NSEvent*) = ^ NSEvent* (NSEvent* event)
597
+ {
598
+ if ([event modifierFlags] & NSEventModifierFlagCommand)
599
+ [[NSApp keyWindow] sendEvent:event];
600
+
601
+ return event;
602
+ };
603
+
604
+ _glfw.ns.keyUpMonitor =
605
+ [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyUp
606
+ handler:block];
607
+
608
+ if (_glfw.hints.init.ns.chdir)
609
+ changeToResourcesDirectory();
610
+
611
+ // Press and Hold prevents some keys from emitting repeated characters
612
+ NSDictionary* defaults = @{@"ApplePressAndHoldEnabled":@NO};
613
+ [[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
614
+
615
+ [[NSNotificationCenter defaultCenter]
616
+ addObserver:_glfw.ns.helper
617
+ selector:@selector(selectedKeyboardInputSourceChanged:)
618
+ name:NSTextInputContextKeyboardSelectionDidChangeNotification
619
+ object:nil];
620
+
621
+ createKeyTables();
622
+
623
+ _glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
624
+ if (!_glfw.ns.eventSource)
625
+ return GLFW_FALSE;
626
+
627
+ CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0);
628
+
629
+ if (!initializeTIS())
630
+ return GLFW_FALSE;
631
+
632
+ _glfwPollMonitorsCocoa();
633
+
634
+ if (![[NSRunningApplication currentApplication] isFinishedLaunching])
635
+ [NSApp run];
636
+
637
+ // In case we are unbundled, make us a proper UI application
638
+ if (_glfw.hints.init.ns.menubar)
639
+ [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
640
+
641
+ return GLFW_TRUE;
642
+
643
+ } // autoreleasepool
644
+ }
645
+
646
+ void _glfwTerminateCocoa(void)
647
+ {
648
+ @autoreleasepool {
649
+
650
+ if (_glfw.ns.inputSource)
651
+ {
652
+ CFRelease(_glfw.ns.inputSource);
653
+ _glfw.ns.inputSource = NULL;
654
+ _glfw.ns.unicodeData = nil;
655
+ }
656
+
657
+ if (_glfw.ns.eventSource)
658
+ {
659
+ CFRelease(_glfw.ns.eventSource);
660
+ _glfw.ns.eventSource = NULL;
661
+ }
662
+
663
+ if (_glfw.ns.delegate)
664
+ {
665
+ [NSApp setDelegate:nil];
666
+ [_glfw.ns.delegate release];
667
+ _glfw.ns.delegate = nil;
668
+ }
669
+
670
+ if (_glfw.ns.helper)
671
+ {
672
+ [[NSNotificationCenter defaultCenter]
673
+ removeObserver:_glfw.ns.helper
674
+ name:NSTextInputContextKeyboardSelectionDidChangeNotification
675
+ object:nil];
676
+ [[NSNotificationCenter defaultCenter]
677
+ removeObserver:_glfw.ns.helper];
678
+ [_glfw.ns.helper release];
679
+ _glfw.ns.helper = nil;
680
+ }
681
+
682
+ if (_glfw.ns.keyUpMonitor)
683
+ [NSEvent removeMonitor:_glfw.ns.keyUpMonitor];
684
+
685
+ _glfw_free(_glfw.ns.clipboardString);
686
+
687
+ _glfwTerminateNSGL();
688
+ _glfwTerminateEGL();
689
+ _glfwTerminateOSMesa();
690
+
691
+ } // autoreleasepool
692
+ }
693
+
694
+ #endif // _GLFW_COCOA