- /*   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 
- */ 
-   
- #include "SDL.h" 
- #include "SDLMain.h" 
- #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(SDL_Missing_Methods) 
- -  (- void )- setAppleMenu: (- NSMenu * )menu- ; 
- @end 
-   
- /* Use this  flag-  to determine whether we use SDLMain. nib-  or not */ 
- #define         SDL_USE_NIB_FILE        0 
-   
- /* 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 
- { 
- } 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 BOOL   gFinderLaunch; 
- static BOOL   gCalledAppMainline = FALSE; 
-   
- static NSString *getApplicationName(void) 
- { 
-     const NSDictionary *dict; 
-     NSString *appName = 0; 
-   
-     /* Determine the application name */ 
-     dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); 
-     if (dict) 
-         appName = [dict objectForKey: @"CFBundleName"]; 
-      
-         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 NSApplication (SDLApplication) 
- @end 
-   
- @implementation NSApplication (SDLApplication) 
- - (void)terminate:(id)sender 
- { 
-     /* Post a SDL_QUIT event */ 
-     SDL_Event event; 
-     SDL_PushEvent(&event); 
- } 
- @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,  1- ,  (UInt8-  * )- parentdir, MAXPATHLEN )) {
 
-             chdir(parentdir);   /* 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" ]- ; 
-         [- aMenu setTitle:  [[- aMenu  title]-  stringByReplacingRange:aRange with:appName ]]- ; 
 
-   
-     enumerator = [[aMenu itemArray] objectEnumerator]; 
-     while ((menuItem = [enumerator nextObject])) 
-     { 
-         aRange =  [[- menuItem  title]-  rangeOfString:@"SDL App" ]- ; 
-             [- menuItem setTitle:  [[- menuItem  title]-  stringByReplacingRange:aRange with:appName ]]- ; 
 
-         if ([menuItem hasSubmenu]) 
-             [self fixMenu:[menuItem submenu] withAppName:appName]; 
-     } 
- } 
-   
- #else 
-   
- static void setApplicationMenu(void) 
- { 
-     NSMenu *appleMenu; 
-     NSMenuItem *menuItem; 
-     NSString *appName; 
-      
-     appName = getApplicationName(); 
-     appleMenu = [[NSMenu alloc] initWithTitle:@""]; 
-      
-     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:(NSEventModifierFlagOption|NSEventModifierFlagCommand)]; 
-   
-     [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  (- int argc,  char-  **argv )
- { 
-     NSAutoreleasePool   *pool = [[NSAutoreleasePool alloc] init]; 
-     SDLMain                             *sdlMain; 
-   
-     /* Ensure the application object  is-  initialised */ 
-     [NSApplication 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)) 
-                     [NSApplication sharedApplication]; 
-     } 
- #endif /* SDL_USE_CPS */ 
-   
-     [NSApp setMainMenu:[[NSMenu alloc] init]]; 
-     setApplicationMenu(); 
-     setupWindowMenu(); 
-   
-     /* Create SDLMain and make it the app delegate */ 
-     sdlMain = [[SDLMain alloc] init]; 
-     [- NSApp setDelegate: (- id )- sdlMain ]- ; // Pierre-Marie Baty -- added  type-  cast 
 
-      
-     /* Start the main event loop */ 
-     [NSApp run]; 
-      
-     [sdlMain release]; 
-     [pool release]; 
- } 
-   
- #endif 
-   
-   
- /* 
-  *  Catch-  document  open-  requests ...this-  lets us notice files when the app 
-  *  was launched by double-clicking a document, or when a document was 
-  *  dragged/dropped on the app's icon. You need to have a 
-  *  CFBundleDocumentsType section in your Info. plist-  to  get-  this message, 
-  *  apparently. 
-  * 
-  * Files are added to gArgv, so to the app, they'll look like command  line
-  *  arguments. Previously, apps launched from the finder had nothing but 
-  *  an argv[0]. 
-  * 
-  * This message may be received multiple times to  open-  several docs on launch. 
-  * 
-  * This message  is-  ignored once the app's mainline has been called. 
-  */ 
- - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename 
- { 
-     size_t arglen; 
-   
-     if (- !gFinderLaunch )-   /* MacOS  is-  passing command  line-  args. */ 
 
-         return FALSE; 
-   
-     if (gCalledAppMainline)  /* app has started, ignore this document. */ 
-         return FALSE; 
-   
-     temparg = [filename UTF8String]; 
-     arglen = SDL_strlen(temparg) + 1; 
-     arg =  (char-  * )-  SDL_malloc (- arglen )- ; 
-         return FALSE; 
-   
-     newargv =  (char-  ** )-  realloc (- gArgv, sizeof  (char-  * )-  *  (- gArgc +  2))- ; 
-     { 
-         SDL_free(arg); 
-         return FALSE; 
-     } 
-     gArgv = newargv; 
-   
-     SDL_strlcpy(arg, temparg, arglen); 
-     gArgv[gArgc++] = arg; 
-     return TRUE; 
- } 
-   
-   
- /* 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 
-   
-     /* Hand off to main application code */ 
-     gCalledAppMainline = TRUE; 
-     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 = (unichar *)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]; 
-      
-     result =  [- NSString stringWithCharacters:buffer  length- :bufferSize ]- ; 
-      
-     NSDeallocateMemoryPages(buffer, bufferSize); 
-      
-     return result; 
- } 
-   
- @end 
-   
-   
-   
- #ifdef main 
- #  undef main 
- #endif 
-   
-   
- static int IsRootCwd() 
- { 
-     char-  *cwd = getcwd (- buf, sizeof  (- buf ))- ; 
 
-     return (- cwd &&  (strcmp(- cwd, "/" )-  ==  0))- ; 
 
- } 
-   
- static int IsFinderLaunch (- const int argc,  char-  **argv )
- { 
-     if ((argc == 1) && IsRootCwd()) { 
-         /* we might still be launched from the Finder; on 10.9+, you might not 
-         command  line- , and  if-  our current working directory  is-  "/". */ 
-         return 1; 
-     } 
-     return 0;  /* not a Finder launch. */ 
- } 
-   
- /* 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 ( IsFinderLaunch(argc, argv) ) { 
-         gArgv =  (char-  ** )-  SDL_malloc (- sizeof  (char-  * )-  *  2)- ; 
-         gArgv[0] = argv[0]; 
-         gArgc = 1; 
-         gFinderLaunch = YES; 
-     } else { 
-         gArgc = argc; 
-         gArgv =  (char-  ** )-  SDL_malloc (- sizeof  (char-  * )-  *  (- argc+ 1))- ; 
-         for (i-  =  0- ;  i-  <= argc;  i- ++ )
 
-         gFinderLaunch = NO; 
-     } 
-   
- #if SDL_USE_NIB_FILE 
-     NSApplicationMain (argc, argv); 
- #else 
-     CustomApplicationMain (argc, argv); 
- #endif 
-     return 0; 
- } 
-   
-