00001
00002
00003
00004
00005
00006
00007
00008 #import "SDL.h"
00009 #import "SDLMain.h"
00010 #import <sys/param.h>
00011 #import <unistd.h>
00012
00013
00014
00015
00016 @interface NSApplication(SDL_Missing_Methods)
00017 - (void)setAppleMenu:(NSMenu *)menu;
00018 @end
00019
00020
00021 #define SDL_USE_NIB_FILE 0
00022
00023
00024 #define SDL_USE_CPS 1
00025 #ifdef SDL_USE_CPS
00026
00027 typedef struct CPSProcessSerNum
00028 {
00029 UInt32 lo;
00030 UInt32 hi;
00031 } CPSProcessSerNum;
00032
00033 extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
00034 extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
00035 extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
00036
00037 #endif
00038
00039 static int gArgc;
00040 static char **gArgv;
00041 static BOOL gFinderLaunch;
00042 static BOOL gCalledAppMainline = FALSE;
00043
00044 static NSString *getApplicationName(void)
00045 {
00046 NSDictionary *dict;
00047 NSString *appName = 0;
00048
00049
00050 dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
00051 if (dict)
00052 appName = [dict objectForKey: @"CFBundleName"];
00053
00054 if (![appName length])
00055 appName = [[NSProcessInfo processInfo] processName];
00056
00057 return appName;
00058 }
00059
00060 #if SDL_USE_NIB_FILE
00061
00062 @interface NSString (ReplaceSubString)
00063 - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
00064 @end
00065 #endif
00066
00067 @interface SDLApplication : NSApplication
00068 @end
00069
00070 @implementation SDLApplication
00071
00072 - (void)terminate:(id)sender
00073 {
00074
00075 SDL_Event event;
00076 event.type = SDL_QUIT;
00077 SDL_PushEvent(&event);
00078 }
00079 @end
00080
00081
00082 @implementation SDLMain
00083
00084
00085 - (void) setupWorkingDirectory:(BOOL)shouldChdir
00086 {
00087 if (shouldChdir)
00088 {
00089 char parentdir;
00090 CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
00091 CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
00092 if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) {
00093 assert ( chdir (parentdir) == 0 );
00094 }
00095 CFRelease(url);
00096 CFRelease(url2);
00097 }
00098
00099 }
00100
00101 #if SDL_USE_NIB_FILE
00102
00103
00104 - (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
00105 {
00106 NSRange aRange;
00107 NSEnumerator *enumerator;
00108 NSMenuItem *menuItem;
00109
00110 aRange = [[aMenu title] rangeOfString:@"SDL App"];
00111 if (aRange.length != 0)
00112 [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
00113
00114 enumerator = [[aMenu itemArray] objectEnumerator];
00115 while ((menuItem = [enumerator nextObject]))
00116 {
00117 aRange = [[menuItem title] rangeOfString:@"SDL App"];
00118 if (aRange.length != 0)
00119 [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
00120 if ([menuItem hasSubmenu])
00121 [self fixMenu:[menuItem submenu] withAppName:appName];
00122 }
00123 [ aMenu sizeToFit ];
00124 }
00125
00126 #else
00127
00128 static void setApplicationMenu(void)
00129 {
00130
00131 NSMenu *appleMenu;
00132 NSMenuItem *menuItem;
00133 NSString *title;
00134 NSString *appName;
00135
00136 appName = getApplicationName();
00137 appleMenu = [[NSMenu alloc] initWithTitle:@""];
00138
00139
00140 title = [@"About " stringByAppendingString:appName];
00141 [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
00142
00143 [appleMenu addItem:[NSMenuItem separatorItem]];
00144
00145 title = [@"Hide " stringByAppendingString:appName];
00146 [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
00147
00148 menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
00149 [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
00150
00151 [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
00152
00153 [appleMenu addItem:[NSMenuItem separatorItem]];
00154
00155 title = [@"Quit " stringByAppendingString:appName];
00156 [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
00157
00158
00159
00160 menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
00161 [menuItem setSubmenu:appleMenu];
00162 [[NSApp mainMenu] addItem:menuItem];
00163
00164
00165 [NSApp setAppleMenu:appleMenu];
00166
00167
00168 [appleMenu release];
00169 [menuItem release];
00170 }
00171
00172
00173 static void setupWindowMenu(void)
00174 {
00175 NSMenu *windowMenu;
00176 NSMenuItem *windowMenuItem;
00177 NSMenuItem *menuItem;
00178
00179 windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
00180
00181
00182 menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
00183 [windowMenu addItem:menuItem];
00184 [menuItem release];
00185
00186
00187 windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
00188 [windowMenuItem setSubmenu:windowMenu];
00189 [[NSApp mainMenu] addItem:windowMenuItem];
00190
00191
00192 [NSApp setWindowsMenu:windowMenu];
00193
00194
00195 [windowMenu release];
00196 [windowMenuItem release];
00197 }
00198
00199
00200 static void CustomApplicationMain (int argc, char **argv)
00201 {
00202 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
00203 SDLMain *sdlMain;
00204
00205
00206 [SDLApplication sharedApplication];
00207
00208 #ifdef SDL_USE_CPS
00209 {
00210 CPSProcessSerNum PSN;
00211
00212 if (!CPSGetCurrentProcess(&PSN))
00213 if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
00214 if (!CPSSetFrontProcess(&PSN))
00215 [SDLApplication sharedApplication];
00216 }
00217 #endif
00218
00219
00220 [NSApp setMainMenu:[[NSMenu alloc] init]];
00221 setApplicationMenu();
00222 setupWindowMenu();
00223
00224
00225 sdlMain = [[SDLMain alloc] init];
00226 [NSApp setDelegate:sdlMain];
00227
00228
00229 [NSApp run];
00230
00231 [sdlMain release];
00232 [pool release];
00233 }
00234
00235 #endif
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
00254 {
00255 const char *temparg;
00256 size_t arglen;
00257 char *arg;
00258 char **newargv;
00259
00260 if (!gFinderLaunch)
00261 return FALSE;
00262
00263 if (gCalledAppMainline)
00264 return FALSE;
00265
00266 temparg = [filename UTF8String];
00267 arglen = SDL_strlen(temparg) + 1;
00268 arg = (char *) SDL_malloc(arglen);
00269 if (arg == NULL)
00270 return FALSE;
00271
00272 newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
00273 if (newargv == NULL)
00274 {
00275 SDL_free(arg);
00276 return FALSE;
00277 }
00278 gArgv = newargv;
00279
00280 SDL_strlcpy(arg, temparg, arglen);
00281 gArgv = arg;
00282 gArgv = NULL;
00283 return TRUE;
00284 }
00285
00286
00287
00288 - (void) applicationDidFinishLaunching: (NSNotification *) note
00289 {
00290 int status;
00291
00292
00293 [self setupWorkingDirectory:gFinderLaunch];
00294
00295 #if SDL_USE_NIB_FILE
00296
00297 [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
00298 #endif
00299
00300
00301 gCalledAppMainline = TRUE;
00302 status = SDL_main (gArgc, gArgv);
00303
00304
00305 exit(status);
00306 }
00307 @end
00308
00309
00310 @implementation NSString (ReplaceSubString)
00311
00312 - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
00313 {
00314 unsigned int bufferSize;
00315 unsigned int selfLen = [self length];
00316 unsigned int aStringLen = [aString length];
00317 unichar *buffer;
00318 NSRange localRange;
00319 NSString *result;
00320
00321 bufferSize = selfLen + aStringLen - aRange.length;
00322 buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
00323
00324
00325 localRange.location = 0;
00326 localRange.length = aRange.location;
00327 [self getCharacters:buffer range:localRange];
00328
00329
00330 localRange.location = 0;
00331 localRange.length = aStringLen;
00332 [aString getCharacters:(buffer+aRange.location) range:localRange];
00333
00334
00335 localRange.location = aRange.location + aRange.length;
00336 localRange.length = selfLen - localRange.location;
00337 [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
00338
00339
00340 result = [NSString stringWithCharacters:buffer length:bufferSize];
00341
00342 NSDeallocateMemoryPages(buffer, bufferSize);
00343
00344 return result;
00345 }
00346
00347 @end
00348
00349
00350
00351 #ifdef main
00352 # undef main
00353 #endif
00354
00355
00356
00357 int main (int argc, char **argv)
00358 {
00359
00360
00361 if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
00362 gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
00363 gArgv = argv;
00364 gArgv = NULL;
00365 gArgc = 1;
00366 gFinderLaunch = YES;
00367 } else {
00368 int i;
00369 gArgc = argc;
00370 gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
00371 for (i = 0; i <= argc; i++)
00372 gArgv[i] = argv[i];
00373 gFinderLaunch = NO;
00374 }
00375
00376 #if SDL_USE_NIB_FILE
00377 [SDLApplication poseAsClass:[NSApplication class]];
00378 NSApplicationMain (argc, argv);
00379 #else
00380 CustomApplicationMain (argc, argv);
00381 #endif
00382 return 0;
00383 }