📄 sdlmain.m
字号:
/* SDLMain.m - main entry point for our Cocoa-ized SDL app Initial Version: Darrell Walisser <dwaliss1@purdue.edu> Non-NIB-Code & other changes: Max Horn <max@quendi.de> Feel free to customize this file to suit your needs*/#import "SDL.h"#import "SDLMain.h"#import <sys/param.h> /* for MAXPATHLEN */#import <unistd.h>/* Use this flag to determine whether we use SDLMain.nib or not */#ifndef SDL_USE_NIB_FILE#define SDL_USE_NIB_FILE 1#endif/* Use this flag to determine whether we use CPS (docking) or not */#define SDL_USE_CPS 1#ifdef SDL_USE_CPS/* Portions of CPS.h */typedef struct CPSProcessSerNum{ UInt32 lo; UInt32 hi;} CPSProcessSerNum;extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);#endif /* SDL_USE_CPS */static int gArgc;static char **gArgv;static BOOL gFinderLaunch;static NSString *getApplicationName(void){ NSDictionary *dict; NSString *appName = 0; /* Determine the application name */ dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); if (dict) appName = [dict objectForKey: @"CFBundleName"]; if (![appName length]) appName = [[NSProcessInfo processInfo] processName]; return appName;}#if SDL_USE_NIB_FILE/* A helper category for NSString */@interface NSString (ReplaceSubString)- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;@end#endif@interface SDLApplication : NSApplication@end@implementation SDLApplication/* Invoked from the Quit menu item */- (void)terminate:(id)sender{ if (SDL_GetVideoSurface() == NULL) { [super terminate: sender]; return; } /* Post a SDL_QUIT event */ SDL_Event event; event.type = SDL_QUIT; SDL_PushEvent(&event);}- (void)sendEvent:(NSEvent *)anEvent{ if ( !getenv("SDL_ENABLEAPPEVENTS") ) { [super sendEvent: anEvent]; return; } if( NSKeyDown == [anEvent type] || NSKeyUp == [anEvent type] ) { if( [anEvent modifierFlags] & NSCommandKeyMask ) [super sendEvent: anEvent]; } else [super sendEvent: anEvent];}@end/* The main class of the application, the application's delegate */@implementation SDLMain/* Set the working directory to the .app's parent directory */- (void) setupWorkingDirectory:(BOOL)shouldChdir{ if (shouldChdir) { char parentdir[MAXPATHLEN]; CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); if (CFURLGetFileSystemRepresentation(url2, true, parentdir, MAXPATHLEN)) { assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */ } CFRelease(url); CFRelease(url2); }}#if SDL_USE_NIB_FILE/* Fix menu to contain the real app name instead of "SDL App" */- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName{ NSRange aRange; NSEnumerator *enumerator; NSMenuItem *menuItem; aRange = [[aMenu title] rangeOfString:@"SDL App"]; if (aRange.length != 0) [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; enumerator = [[aMenu itemArray] objectEnumerator]; while ((menuItem = [enumerator nextObject])) { aRange = [[menuItem title] rangeOfString:@"SDL App"]; if (aRange.length != 0) [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; if ([menuItem hasSubmenu]) [self fixMenu:[menuItem submenu] withAppName:appName]; } [ aMenu sizeToFit ];}#elsestatic void setApplicationMenu(void){ /* warning: this code is very odd */ NSMenu *appleMenu; NSMenuItem *menuItem; NSString *title; NSString *appName; appName = getApplicationName(); appleMenu = [[NSMenu alloc] initWithTitle:@""]; /* Add menu items */ title = [@"About " stringByAppendingString:appName]; [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; [appleMenu addItem:[NSMenuItem separatorItem]]; title = [@"Hide " stringByAppendingString:appName]; [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; [appleMenu addItem:[NSMenuItem separatorItem]]; title = [@"Quit " stringByAppendingString:appName]; [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; /* Put menu into the menubar */ menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; [menuItem setSubmenu:appleMenu]; [[NSApp mainMenu] addItem:menuItem]; /* Tell the application object that this is now the application menu */ [NSApp setAppleMenu:appleMenu]; /* Finally give up our references to the objects */ [appleMenu release]; [menuItem release];}/* Create a window menu */static void setupWindowMenu(void){ NSMenu *windowMenu; NSMenuItem *windowMenuItem; NSMenuItem *menuItem; windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; /* "Minimize" item */ menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; [windowMenu addItem:menuItem]; [menuItem release]; /* Put menu into the menubar */ windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; [windowMenuItem setSubmenu:windowMenu]; [[NSApp mainMenu] addItem:windowMenuItem]; /* Tell the application object that this is now the window menu */ [NSApp setWindowsMenu:windowMenu]; /* Finally give up our references to the objects */ [windowMenu release]; [windowMenuItem release];}/* Replacement for NSApplicationMain */static void CustomApplicationMain (argc, argv){ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; SDLMain *sdlMain; /* Ensure the application object is initialised */ [SDLApplication sharedApplication]; #ifdef SDL_USE_CPS { CPSProcessSerNum PSN; /* Tell the dock about us */ if (!CPSGetCurrentProcess(&PSN)) if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) if (!CPSSetFrontProcess(&PSN)) [SDLApplication sharedApplication]; }#endif /* SDL_USE_CPS */ /* Set up the menubar */ [NSApp setMainMenu:[[NSMenu alloc] init]]; setApplicationMenu(); setupWindowMenu(); /* Create SDLMain and make it the app delegate */ sdlMain = [[SDLMain alloc] init]; [NSApp setDelegate:sdlMain]; /* Start the main event loop */ [NSApp run]; [sdlMain release]; [pool release];}#endif/* Called when the internal event loop has just started running */- (void) applicationDidFinishLaunching: (NSNotification *) note{ int status; /* Set the working directory to the .app's parent directory */ [self setupWorkingDirectory:gFinderLaunch];#if SDL_USE_NIB_FILE /* Set the main menu to contain the real app name instead of "SDL App" */ [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];#endif setenv ("SDL_ENABLEAPPEVENTS", "1", 1); /* Hand off to main application code */ status = SDL_main (gArgc, gArgv); /* We're done, thank you for playing */ exit(status);}@end@implementation NSString (ReplaceSubString)- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString{ unsigned int bufferSize; unsigned int selfLen = [self length]; unsigned int aStringLen = [aString length]; unichar *buffer; NSRange localRange; NSString *result; bufferSize = selfLen + aStringLen - aRange.length; buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar)); /* Get first part into buffer */ localRange.location = 0; localRange.length = aRange.location; [self getCharacters:buffer range:localRange]; /* Get middle part into buffer */ localRange.location = 0; localRange.length = aStringLen; [aString getCharacters:(buffer+aRange.location) range:localRange]; /* Get last part into buffer */ localRange.location = aRange.location + aRange.length; localRange.length = selfLen - localRange.location; [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; /* Build output string */ result = [NSString stringWithCharacters:buffer length:bufferSize]; NSDeallocateMemoryPages(buffer, bufferSize); return result;}@end#ifdef main# undef main#endif/* Main entry point to executable - should *not* be SDL_main! */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 ) { gArgc = 1; gFinderLaunch = YES; } else { gArgc = argc; gFinderLaunch = NO; } gArgv = argv;#if SDL_USE_NIB_FILE [SDLApplication poseAsClass:[NSApplication class]]; NSApplicationMain (argc, argv);#else CustomApplicationMain (argc, argv);#endif return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -