| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 | 
							- /*   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_Cocoa.h"
 
- #import <sys/param.h> /* for MAXPATHLEN */
 
- #import <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
 
- {
 
- 	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 BOOL   gCalledAppMainline = FALSE;
 
- 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
 
- {
 
-     /* Post a SDL_QUIT event */
 
-     SDL_Event event;
 
-     event.type = SDL_QUIT;
 
-     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, true, (UInt8 *)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 ];
 
- }
 
- #else
 
- static 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 (int argc, char **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
 
- /*
 
-  * 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
 
- {
 
-     const char *temparg;
 
-     size_t arglen;
 
-     char *arg;
 
-     char **newargv;
 
-     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);
 
-     if (arg == NULL)
 
-         return FALSE;
 
-     newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
 
-     if (newargv == NULL)
 
-     {
 
-         SDL_free(arg);
 
-         return FALSE;
 
-     }
 
-     gArgv = newargv;
 
-     SDL_strlcpy(arg, temparg, arglen);
 
-     gArgv[gArgc++] = arg;
 
-     gArgv[gArgc] = NULL;
 
-     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 = 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 ) {
 
-         gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
 
-         gArgv[0] = argv[0];
 
-         gArgv[1] = NULL;
 
-         gArgc = 1;
 
-         gFinderLaunch = YES;
 
-     } else {
 
-         int i;
 
-         gArgc = argc;
 
-         gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
 
-         for (i = 0; i <= argc; i++)
 
-             gArgv[i] = argv[i];
 
-         gFinderLaunch = NO;
 
-     }
 
- #if SDL_USE_NIB_FILE
 
-     [SDLApplication poseAsClass:[NSApplication class]];
 
-     NSApplicationMain (argc, argv);
 
- #else
 
-     CustomApplicationMain (argc, argv);
 
- #endif
 
-     return 0;
 
- }
 
 
  |