00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00036
00037
00038
00039
00040
00041
00042
00043 #import "SDL.h"
00044 #import "SDLMain.h"
00045 #import <sys/param.h>
00046 #import <unistd.h>
00047
00048
00049
00050
00051 @interface NSApplication(SDL_Missing_Methods)
00052 - (void)setAppleMenu:(NSMenu *)menu;
00053 @end
00054
00055
00056 #define SDL_USE_NIB_FILE 0
00057
00058
00059 #define SDL_USE_CPS 1
00060 #ifdef SDL_USE_CPS
00061
00062 typedef struct CPSProcessSerNum
00063 {
00064 UInt32 lo;
00065 UInt32 hi;
00066 } CPSProcessSerNum;
00067
00068 extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
00069 extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
00070 extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
00071
00072 #endif
00073
00074 static int gArgc;
00075 static char **gArgv;
00076 static BOOL gFinderLaunch;
00077 static BOOL gCalledAppMainline = FALSE;
00078
00079 static NSString *getApplicationName(void)
00080 {
00081 NSDictionary *dict;
00082 NSString *appName = 0;
00083
00084
00085 dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
00086 if (dict)
00087 appName = [dict objectForKey: @"CFBundleName"];
00088
00089 if (![appName length])
00090 appName = [[NSProcessInfo processInfo] processName];
00091
00092 return appName;
00093 }
00094
00095 #if SDL_USE_NIB_FILE
00096
00097 @interface NSString (ReplaceSubString)
00098 - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
00099 @end
00100 #endif
00101
00102 @interface SDLApplication : NSApplication
00103 @end
00104
00105 @implementation SDLApplication
00106
00107 - (void)terminate:(id)sender
00108 {
00109
00110 SDL_Event event;
00111 event.type = SDL_QUIT;
00112 SDL_PushEvent(&event);
00113 }
00114 @end
00115
00116
00117 @implementation SDLMain
00118
00119 - (IBAction)prefsMenu:(id)sender
00120 {
00121 printf ("prefs menu\n");
00122 }
00123
00124 - (IBAction)newGame:(id)sender
00125 {
00126 printf ("new game\n");
00127
00128 NSRunAlertPanel (@"Get ready to blow up some... stuff!",
00129 @"Click OK to begin total carnage. Click Cancel to prevent total carnage.", @"OK", @"Cancel", nil);
00130 }
00131
00132 - (IBAction)openGame:(id)sender
00133 {
00134 NSString *path = nil;
00135 NSOpenPanel *openPanel = [ NSOpenPanel openPanel ];
00136
00137 if ( [ openPanel runModalForDirectory:nil
00138 file:@"SavedGame" types:nil ] ) {
00139
00140 path = [ [ openPanel filenames ] objectAtIndex:0 ];
00141 }
00142
00143
00144 NSLog (@"open game: %@", path);
00145 }
00146
00147 - (IBAction)saveGame:(id)sender
00148 {
00149 NSString *path = nil;
00150 NSSavePanel *savePanel = [ NSSavePanel savePanel ];
00151
00152 if ( [ savePanel runModalForDirectory:nil
00153 file:@"SaveGameFile" ] ) {
00154
00155 path = [ savePanel filename ];
00156 }
00157
00158
00159 NSLog (@"save game: %@", path);
00160 }
00161
00162 - (IBAction)saveGameAs:(id)sender
00163 {
00164 printf ("save game as\n");
00165 }
00166
00167 - (IBAction)help:(id)sender
00168 {
00169 NSRunAlertPanel (@"Oh help, where have ye gone?",
00170 @"Sorry, there is no help available.\n\nThis message brought to you by We Don't Document, Inc.\n\n", @"Rats", @"Good, I never read it anyway", nil);
00171 }
00172
00173
00174
00175 - (void) setupWorkingDirectory:(BOOL)shouldChdir
00176 {
00177 if (shouldChdir)
00178 {
00179 char parentdir;
00180 CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
00181 CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
00182 if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) {
00183 assert ( chdir (parentdir) == 0 );
00184 }
00185 CFRelease(url);
00186 CFRelease(url2);
00187 }
00188
00189 }
00190
00191 #if SDL_USE_NIB_FILE
00192
00193
00194 - (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
00195 {
00196 NSRange aRange;
00197 NSEnumerator *enumerator;
00198 NSMenuItem *menuItem;
00199
00200 aRange = [[aMenu title] rangeOfString:@"SDL App"];
00201 if (aRange.length != 0)
00202 [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
00203
00204 enumerator = [[aMenu itemArray] objectEnumerator];
00205 while ((menuItem = [enumerator nextObject]))
00206 {
00207 aRange = [[menuItem title] rangeOfString:@"SDL App"];
00208 if (aRange.length != 0)
00209 [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
00210 if ([menuItem hasSubmenu])
00211 [self fixMenu:[menuItem submenu] withAppName:appName];
00212 }
00213 [ aMenu sizeToFit ];
00214 }
00215
00216 #else
00217
00218 static void setApplicationMenu(void)
00219 {
00220
00221 NSMenu *appleMenu;
00222 NSMenuItem *menuItem;
00223 NSString *title;
00224 NSString *appName;
00225
00226 appName = getApplicationName();
00227 appleMenu = [[NSMenu alloc] initWithTitle:@""];
00228
00229
00230 title = [@"About " stringByAppendingString:appName];
00231 [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
00232
00233 [appleMenu addItem:[NSMenuItem separatorItem]];
00234
00235 title = [@"Hide " stringByAppendingString:appName];
00236 [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
00237
00238 menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
00239 [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
00240
00241 [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
00242
00243 [appleMenu addItem:[NSMenuItem separatorItem]];
00244
00245 title = [@"Quit " stringByAppendingString:appName];
00246 [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
00247
00248
00249
00250 menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
00251 [menuItem setSubmenu:appleMenu];
00252 [[NSApp mainMenu] addItem:menuItem];
00253
00254
00255 [NSApp setAppleMenu:appleMenu];
00256
00257
00258 [appleMenu release];
00259 [menuItem release];
00260 }
00261
00262
00263 static void setupWindowMenu(void)
00264 {
00265 NSMenu *windowMenu;
00266 NSMenuItem *windowMenuItem;
00267 NSMenuItem *menuItem;
00268
00269 windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
00270
00271
00272 menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
00273 [windowMenu addItem:menuItem];
00274 [menuItem release];
00275
00276
00277 windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
00278 [windowMenuItem setSubmenu:windowMenu];
00279 [[NSApp mainMenu] addItem:windowMenuItem];
00280
00281
00282 [NSApp setWindowsMenu:windowMenu];
00283
00284
00285 [windowMenu release];
00286 [windowMenuItem release];
00287 }
00288
00289
00290 static void CustomApplicationMain (int argc, char **argv)
00291 {
00292 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
00293 SDLMain *sdlMain;
00294
00295
00296 [SDLApplication sharedApplication];
00297
00298 #ifdef SDL_USE_CPS
00299 {
00300 CPSProcessSerNum PSN;
00301
00302 if (!CPSGetCurrentProcess(&PSN))
00303 if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
00304 if (!CPSSetFrontProcess(&PSN))
00305 [SDLApplication sharedApplication];
00306 }
00307 #endif
00308
00309
00310 [NSApp setMainMenu:[[NSMenu alloc] init]];
00311 setApplicationMenu();
00312 setupWindowMenu();
00313
00314
00315 sdlMain = [[SDLMain alloc] init];
00316 [NSApp setDelegate:sdlMain];
00317
00318
00319 [NSApp run];
00320
00321 [sdlMain release];
00322 [pool release];
00323 }
00324
00325 #endif
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
00344 {
00345 const char *temparg;
00346 size_t arglen;
00347 char *arg;
00348 char **newargv;
00349
00350 if (!gFinderLaunch)
00351 return FALSE;
00352
00353 if (gCalledAppMainline)
00354 return FALSE;
00355
00356 temparg = [filename UTF8String];
00357 arglen = SDL_strlen(temparg) + 1;
00358 arg = (char *) SDL_malloc(arglen);
00359 if (arg == NULL)
00360 return FALSE;
00361
00362 newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
00363 if (newargv == NULL)
00364 {
00365 SDL_free(arg);
00366 return FALSE;
00367 }
00368 gArgv = newargv;
00369
00370 SDL_strlcpy(arg, temparg, arglen);
00371 gArgv = arg;
00372 gArgv = NULL;
00373 return TRUE;
00374 }
00375
00376
00377
00378 - (void) applicationDidFinishLaunching: (NSNotification *) note
00379 {
00380 int status;
00381
00382
00383 [self setupWorkingDirectory:gFinderLaunch];
00384
00385 #if SDL_USE_NIB_FILE
00386
00387 [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
00388 #endif
00389
00390
00391 gCalledAppMainline = TRUE;
00392 status = SDL_main (gArgc, gArgv);
00393
00394
00395 exit(status);
00396 }
00397 @end
00398
00399
00400 @implementation NSString (ReplaceSubString)
00401
00402 - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
00403 {
00404 unsigned int bufferSize;
00405 unsigned int selfLen = [self length];
00406 unsigned int aStringLen = [aString length];
00407 unichar *buffer;
00408 NSRange localRange;
00409 NSString *result;
00410
00411 bufferSize = selfLen + aStringLen - aRange.length;
00412 buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
00413
00414
00415 localRange.location = 0;
00416 localRange.length = aRange.location;
00417 [self getCharacters:buffer range:localRange];
00418
00419
00420 localRange.location = 0;
00421 localRange.length = aStringLen;
00422 [aString getCharacters:(buffer+aRange.location) range:localRange];
00423
00424
00425 localRange.location = aRange.location + aRange.length;
00426 localRange.length = selfLen - localRange.location;
00427 [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
00428
00429
00430 result = [NSString stringWithCharacters:buffer length:bufferSize];
00431
00432 NSDeallocateMemoryPages(buffer, bufferSize);
00433
00434 return result;
00435 }
00436
00437 @end
00438
00439
00440
00441 #ifdef main
00442 # undef main
00443 #endif
00444
00445
00446
00447 int main (int argc, char **argv)
00448 {
00449
00450
00451 if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
00452 gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
00453 gArgv = argv;
00454 gArgv = NULL;
00455 gArgc = 1;
00456 gFinderLaunch = YES;
00457 } else {
00458 int i;
00459 gArgc = argc;
00460 gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
00461 for (i = 0; i <= argc; i++)
00462 gArgv[i] = argv[i];
00463 gFinderLaunch = NO;
00464 }
00465
00466 #if SDL_USE_NIB_FILE
00467 [SDLApplication poseAsClass:[NSApplication class]];
00468 NSApplicationMain (argc, argv);
00469 #else
00470 CustomApplicationMain (argc, argv);
00471 #endif
00472 return 0;
00473 }