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