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