|
|
1.1 ! root 1: /* SDLMain.m - main entry point for our Cocoa-ized SDL app ! 2: Initial Version: Darrell Walisser <[email protected]> ! 3: Non-NIB-Code & other changes: Max Horn <[email protected]> ! 4: ! 5: Feel free to customize this file to suit your needs ! 6: */ ! 7: ! 8: #import "SDL.h" ! 9: #import "SDLMain.h" ! 10: #import <sys/param.h> /* for MAXPATHLEN */ ! 11: #import <unistd.h> ! 12: ! 13: /* Use this flag to determine whether we use SDLMain.nib or not */ ! 14: #define SDL_USE_NIB_FILE 0 ! 15: ! 16: ! 17: static int gArgc; ! 18: static char **gArgv; ! 19: static BOOL gFinderLaunch; ! 20: ! 21: #if SDL_USE_NIB_FILE ! 22: /* A helper category for NSString */ ! 23: @interface NSString (ReplaceSubString) ! 24: - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; ! 25: @end ! 26: #else ! 27: /* An internal Apple class used to setup Apple menus */ ! 28: @interface NSAppleMenuController:NSObject {} ! 29: - (void)controlMenu:(NSMenu *)aMenu; ! 30: @end ! 31: #endif ! 32: ! 33: @interface SDLApplication : NSApplication ! 34: @end ! 35: ! 36: @implementation SDLApplication ! 37: /* Invoked from the Quit menu item */ ! 38: - (void)terminate:(id)sender ! 39: { ! 40: /* Post a SDL_QUIT event */ ! 41: SDL_Event event; ! 42: event.type = SDL_QUIT; ! 43: SDL_PushEvent(&event); ! 44: } ! 45: @end ! 46: ! 47: ! 48: /* The main class of the application, the application's delegate */ ! 49: @implementation SDLMain ! 50: ! 51: /* Set the working directory to the .app's parent directory */ ! 52: - (void) setupWorkingDirectory:(BOOL)shouldChdir ! 53: { ! 54: char parentdir[MAXPATHLEN]; ! 55: char *c; ! 56: ! 57: strncpy ( parentdir, gArgv[0], sizeof(parentdir) ); ! 58: c = (char*) parentdir; ! 59: ! 60: while (*c != '\0') /* go to end */ ! 61: c++; ! 62: ! 63: while (*c != '/') /* back up to parent */ ! 64: c--; ! 65: ! 66: *c++ = '\0'; /* cut off last part (binary name) */ ! 67: ! 68: if (shouldChdir) ! 69: { ! 70: assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */ ! 71: assert ( chdir ("../../../") == 0 ); /* chdir to the .app's parent */ ! 72: } ! 73: } ! 74: ! 75: #if SDL_USE_NIB_FILE ! 76: ! 77: /* Fix menu to contain the real app name instead of "SDL App" */ ! 78: - (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName ! 79: { ! 80: NSRange aRange; ! 81: NSEnumerator *enumerator; ! 82: NSMenuItem *menuItem; ! 83: ! 84: aRange = [[aMenu title] rangeOfString:@"SDL App"]; ! 85: if (aRange.length != 0) ! 86: [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; ! 87: ! 88: enumerator = [[aMenu itemArray] objectEnumerator]; ! 89: while ((menuItem = [enumerator nextObject])) ! 90: { ! 91: aRange = [[menuItem title] rangeOfString:@"SDL App"]; ! 92: if (aRange.length != 0) ! 93: [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; ! 94: if ([menuItem hasSubmenu]) ! 95: [self fixMenu:[menuItem submenu] withAppName:appName]; ! 96: } ! 97: [ aMenu sizeToFit ]; ! 98: } ! 99: ! 100: #else ! 101: ! 102: void setupAppleMenu(void) ! 103: { ! 104: /* warning: this code is very odd */ ! 105: NSAppleMenuController *appleMenuController; ! 106: NSMenu *appleMenu; ! 107: NSMenuItem *appleMenuItem; ! 108: ! 109: appleMenuController = [[NSAppleMenuController alloc] init]; ! 110: appleMenu = [[NSMenu alloc] initWithTitle:@""]; ! 111: appleMenuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; ! 112: ! 113: [appleMenuItem setSubmenu:appleMenu]; ! 114: ! 115: /* yes, we do need to add it and then remove it -- ! 116: if you don't add it, it doesn't get displayed ! 117: if you don't remove it, you have an extra, titleless item in the menubar ! 118: when you remove it, it appears to stick around ! 119: very, very odd */ ! 120: [[NSApp mainMenu] addItem:appleMenuItem]; ! 121: [appleMenuController controlMenu:appleMenu]; ! 122: [[NSApp mainMenu] removeItem:appleMenuItem]; ! 123: [appleMenu release]; ! 124: [appleMenuItem release]; ! 125: } ! 126: ! 127: /* Create a window menu */ ! 128: void setupWindowMenu(void) ! 129: { ! 130: NSMenu *windowMenu; ! 131: NSMenuItem *windowMenuItem; ! 132: NSMenuItem *menuItem; ! 133: ! 134: ! 135: windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; ! 136: ! 137: /* "Minimize" item */ ! 138: menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; ! 139: [windowMenu addItem:menuItem]; ! 140: [menuItem release]; ! 141: ! 142: /* Put menu into the menubar */ ! 143: windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; ! 144: [windowMenuItem setSubmenu:windowMenu]; ! 145: [[NSApp mainMenu] addItem:windowMenuItem]; ! 146: ! 147: /* Tell the application object that this is now the window menu */ ! 148: [NSApp setWindowsMenu:windowMenu]; ! 149: ! 150: /* Finally give up our references to the objects */ ! 151: [windowMenu release]; ! 152: [windowMenuItem release]; ! 153: } ! 154: ! 155: extern char **environ; ! 156: ! 157: /* Replacement for NSApplicationMain */ ! 158: void CustomApplicationMain (argc, argv) ! 159: { ! 160: NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; ! 161: SDLMain *sdlMain; ! 162: ! 163: /* Ensure the application object is initialised */ ! 164: [SDLApplication sharedApplication]; ! 165: ! 166: /* Set up the menubar */ ! 167: [NSApp setMainMenu:[[NSMenu alloc] init]]; ! 168: setupAppleMenu(); ! 169: setupWindowMenu(); ! 170: ! 171: /* Create SDLMain and make it the app delegate */ ! 172: sdlMain = [[SDLMain alloc] init]; ! 173: [NSApp setDelegate:sdlMain]; ! 174: ! 175: /* Start the main event loop */ ! 176: [NSApp run]; ! 177: ! 178: [sdlMain release]; ! 179: [pool release]; ! 180: } ! 181: ! 182: #endif ! 183: ! 184: /* Called when the internal event loop has just started running */ ! 185: - (void) applicationDidFinishLaunching: (NSNotification *) note ! 186: { ! 187: int status; ! 188: ! 189: /* Set the working directory to the .app's parent directory */ ! 190: [self setupWorkingDirectory:gFinderLaunch]; ! 191: ! 192: #if SDL_USE_NIB_FILE ! 193: /* Set the main menu to contain the real app name instead of "SDL App" */ ! 194: [self fixMenu:[NSApp mainMenu] withAppName:[[NSProcessInfo processInfo] processName]]; ! 195: #endif ! 196: ! 197: /* Hand off to main application code */ ! 198: status = SDL_main_env (gArgc, gArgv, environ); ! 199: ! 200: /* We're done, thank you for playing */ ! 201: exit(status); ! 202: } ! 203: @end ! 204: ! 205: ! 206: @implementation NSString (ReplaceSubString) ! 207: ! 208: - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString ! 209: { ! 210: unsigned int bufferSize; ! 211: unsigned int selfLen = [self length]; ! 212: unsigned int aStringLen = [aString length]; ! 213: unichar *buffer; ! 214: NSRange localRange; ! 215: NSString *result; ! 216: ! 217: bufferSize = selfLen + aStringLen - aRange.length; ! 218: buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar)); ! 219: ! 220: /* Get first part into buffer */ ! 221: localRange.location = 0; ! 222: localRange.length = aRange.location; ! 223: [self getCharacters:buffer range:localRange]; ! 224: ! 225: /* Get middle part into buffer */ ! 226: localRange.location = 0; ! 227: localRange.length = aStringLen; ! 228: [aString getCharacters:(buffer+aRange.location) range:localRange]; ! 229: ! 230: /* Get last part into buffer */ ! 231: localRange.location = aRange.location + aRange.length; ! 232: localRange.length = selfLen - localRange.location; ! 233: [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; ! 234: ! 235: /* Build output string */ ! 236: result = [NSString stringWithCharacters:buffer length:bufferSize]; ! 237: ! 238: NSDeallocateMemoryPages(buffer, bufferSize); ! 239: ! 240: return result; ! 241: } ! 242: ! 243: @end ! 244: ! 245: ! 246: ! 247: #ifdef main ! 248: # undef main ! 249: #endif ! 250: ! 251: ! 252: /* Main entry point to executable - should *not* be SDL_main! */ ! 253: int main (int argc, char **argv) ! 254: { ! 255: ! 256: /* Copy the arguments into a global variable */ ! 257: int i; ! 258: ! 259: /* This is passed if we are launched by double-clicking */ ! 260: if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { ! 261: gArgc = 1; ! 262: gFinderLaunch = YES; ! 263: } else { ! 264: gArgc = argc; ! 265: gFinderLaunch = NO; ! 266: } ! 267: gArgv = (char**) malloc (sizeof(*gArgv) * (gArgc+1)); ! 268: assert (gArgv != NULL); ! 269: for (i = 0; i < gArgc; i++) ! 270: gArgv[i] = argv[i]; ! 271: gArgv[i] = NULL; ! 272: ! 273: #if SDL_USE_NIB_FILE ! 274: [SDLApplication poseAsClass:[NSApplication class]]; ! 275: NSApplicationMain (argc, argv); ! 276: #else ! 277: CustomApplicationMain (argc, argv); ! 278: #endif ! 279: return 0; ! 280: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.