godot/platform/osx/godot_osx.mm

209 lines
7.0 KiB
Plaintext
Raw Normal View History

2014-02-10 01:10:30 +00:00
/*************************************************************************/
/* godot_osx.mm */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
2014-02-10 01:10:30 +00:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "godot_osx.h"
2014-02-10 01:10:30 +00:00
#include <sys/param.h> /* for MAXPATHLEN */
#include <unistd.h>
/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
but the method still is there and works. To avoid warnings, we declare
it ourselves here. */
@interface NSApplication ()
2014-02-10 01:10:30 +00:00
- (void)setAppleMenu:(NSMenu *)menu;
@end
static int global_argc;
static char **global_argv;
static BOOL gCalledAppMainline = FALSE;
2014-02-10 01:10:30 +00:00
static NSString *getApplicationName(void) {
const NSDictionary *dict;
NSString *appName = 0;
2014-02-10 01:10:30 +00:00
/* Determine the application name */
dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
if (dict)
appName = [dict objectForKey:@"CFBundleName"];
2016-04-02 18:26:12 +00:00
if (![appName length])
appName = [[NSProcessInfo processInfo] processName];
2014-02-10 01:10:30 +00:00
return appName;
2014-02-10 01:10:30 +00:00
}
/* The main class of the application, the application's delegate */
@implementation GodotMain
static void setApplicationMenu(void) {
/* warning: this code is very odd */
NSMenu *appleMenu;
NSMenuItem *menuItem;
NSString *title;
NSString *appName;
2016-04-02 18:26:12 +00:00
appName = getApplicationName();
appleMenu = [[NSMenu alloc] initWithTitle:@""];
2016-04-02 18:26:12 +00:00
/* Add menu items */
title = [@"About " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
2014-02-10 01:10:30 +00:00
[appleMenu addItem:[NSMenuItem separatorItem]];
2014-02-10 01:10:30 +00:00
title = [@"Hide " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
2014-02-10 01:10:30 +00:00
menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
[menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)];
2014-02-10 01:10:30 +00:00
[appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
2014-02-10 01:10:30 +00:00
[appleMenu addItem:[NSMenuItem separatorItem]];
2014-02-10 01:10:30 +00:00
title = [@"Quit " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
2014-02-10 01:10:30 +00:00
/* Put menu into the menubar */
menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
[menuItem setSubmenu:appleMenu];
[[NSApp mainMenu] addItem:menuItem];
2014-02-10 01:10:30 +00:00
/* Tell the application object that this is now the application menu */
[NSApp setAppleMenu:appleMenu];
2014-02-10 01:10:30 +00:00
/* Finally give up our references to the objects */
[appleMenu release];
[menuItem release];
2014-02-10 01:10:30 +00:00
}
/* Create a window menu */
static void setupWindowMenu(void) {
NSMenu *windowMenu;
NSMenuItem *windowMenuItem;
NSMenuItem *menuItem;
2014-02-10 01:10:30 +00:00
windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
2016-04-02 18:26:12 +00:00
/* "Minimize" item */
menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
[windowMenu addItem:menuItem];
[menuItem release];
2016-04-02 18:26:12 +00:00
/* Put menu into the menubar */
windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
[windowMenuItem setSubmenu:windowMenu];
[[NSApp mainMenu] addItem:windowMenuItem];
2016-04-02 18:26:12 +00:00
/* Tell the application object that this is now the window menu */
[NSApp setWindowsMenu:windowMenu];
2014-02-10 01:10:30 +00:00
/* Finally give up our references to the objects */
[windowMenu release];
[windowMenuItem release];
2014-02-10 01:10:30 +00:00
}
/* Replacement for NSApplicationMain */
static void CustomApplicationMain(int argc, char **argv) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
GodotMain *main;
2014-02-10 01:10:30 +00:00
/* Ensure the application object is initialised */
[NSApplication sharedApplication];
2016-04-02 18:26:12 +00:00
/* Set up the menubar */
[NSApp setMainMenu:[[NSMenu alloc] init]];
setApplicationMenu();
setupWindowMenu();
2014-02-10 01:10:30 +00:00
main = [[main alloc] init];
[NSApp setDelegate:main];
2016-04-02 18:26:12 +00:00
/* Start the main event loop */
[NSApp run];
2016-04-02 18:26:12 +00:00
2014-02-10 01:10:30 +00:00
[main release];
[pool release];
2014-02-10 01:10:30 +00:00
}
extern int godot_main(int argc, char **argv);
2014-02-10 01:10:30 +00:00
/* Called when the internal event loop has just started running */
- (void)applicationDidFinishLaunching:(NSNotification *)note {
int status;
2014-02-10 01:10:30 +00:00
/* Hand off to main application code */
gCalledAppMainline = TRUE;
2014-02-10 01:10:30 +00:00
int ret = godot_main(global_argc, global_argv);
exit(ret);
}
@end
#ifdef main
#undef main
2014-02-10 01:10:30 +00:00
#endif
int main(int argc, char **argv) {
/* Copy the arguments into a global variable */
/* This is passed if we are launched by double-clicking */
if (argc >= 2 && strncmp(argv[1], "-psn", 4) == 0) {
global_argv = (char **)malloc(sizeof(char *) * 2);
global_argv[0] = argv[0];
global_argv[1] = NULL;
global_argc = 1;
// chdir to binary's dir when launched from finder
int len = strlen(global_argv[0]);
while (len--) {
if (global_argv[0][len] == '/') break;
}
if (len >= 0) {
char *path = (char *)malloc(len + 1);
memcpy(path, global_argv[0], len);
path[len] = 0;
printf("Path: %s\n", path);
chdir(path);
}
} else {
int i;
global_argc = argc;
global_argv = (char **)malloc(sizeof(char *) * (argc + 1));
for (i = 0; i <= argc; i++)
global_argv[i] = argv[i];
}
CustomApplicationMain(argc, argv);
return 0;
2014-02-10 01:10:30 +00:00
}