os_macosx/SDLMain.m

Go to the documentation of this file.
00001 /*   SDLMain.m - main entry point for our Cocoa-ized SDL app
00002        Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
00003        Non-NIB-Code & other changes: Max Horn <max@quendi.de>
00004 
00005     Feel free to customize this file to suit your needs
00006 */
00007 
00008 #import "SDL.h"
00009 #import "SDLMain.h"
00010 #import <sys/param.h> /* for MAXPATHLEN */
00011 #import <unistd.h>
00012 
00013 #import "SmartCrashReportsInstall.h"
00014 
00015 /* Portions of CPS.h */
00016 typedef struct CPSProcessSerNum
00017 {
00018     UInt32      lo;
00019     UInt32      hi;
00020 } CPSProcessSerNum;
00021 
00022 extern OSErr    CPSGetCurrentProcess( CPSProcessSerNum *psn);
00023 extern OSErr    CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
00024 extern OSErr    CPSSetFrontProcess( CPSProcessSerNum *psn);
00025 
00026 
00027 static int    gArgc;
00028 static char  **gArgv;
00029 static BOOL   gFinderLaunch;
00030 static BOOL   gCalledAppMainline = FALSE;
00031 
00032 @interface SDLApplication : NSApplication
00033 @end
00034 
00035 @implementation SDLApplication
00036 /* Invoked from the Quit menu item */
00037 - (void)terminate:(id)sender
00038 {
00039     /* Post a SDL_QUIT event */
00040     SDL_Event event;
00041     event.type = SDL_QUIT;
00042     SDL_PushEvent(&event);
00043 }
00044 @end
00045 
00046 /* The main class of the application, the application's delegate */
00047 @implementation SDLMain
00048 
00049 - (IBAction)prefsMenu:(id)sender
00050 {
00051     /* TODO */
00052 }
00053 
00054 - (IBAction)help:(id)sender
00055 {
00056     /* TODO */
00057 }
00058 
00059 - (IBAction)enableCrashReporting:(id)sender
00060 {
00061     if (UnsanitySCR_InstalledVersion(NULL) < UnsanitySCR_InstallableVersion()) {
00062         BOOL retry;
00063         do {
00064             retry = FALSE;
00065             
00066             switch (UnsanitySCR_Install(0)) {
00067                 case kUnsanitySCR_Install_NoError:
00068                     NSRunInformationalAlertPanel(@"Crash Reporting Enabled", @"The crash reporting tool was installed successfully. If Race Into Space crashes, please click the Report... button to submit a detailed crash report.", @"Great!", nil, nil);
00069                     break;
00070                     
00071                 case kUnsanitySCR_Install_InstalledGlobally:
00072                     NSRunCriticalAlertPanel(@"Crash Reporting Problem", @"An earlier version of SmartCrashReports was installed into /Library manually or by another application. Please upgrade this by hand, by downloading the latest version from http://www.smartcrashreports.com/ and running the installer.", @"All right", nil, nil);
00073                     break;
00074                     
00075                 case kUnsanitySCR_Install_UserCancelled:
00076                     // The user cancelled in a dialog already, so we can silently eat this without further bothering them
00077                     break;
00078                     
00079                 case kUnsanitySCR_Install_NoPermissions:
00080                     NSRunAlertPanel(@"Crash Reporting Problem", @"The crash reporter installer failed because of a permissions error, but was not any more specific. If it happens persistently, please contact the Race Into Space developers.", @"All right", nil, nil);
00081                     
00082                 case kUnsanitySCR_Install_AuthFailure:
00083                     if (NSRunAlertPanel(@"Crash Reporting Problem", @"Enabling crash reporting requires you to authenticate yourself.", @"Authenticate again", @"Give up", nil) == 1)
00084                         retry = TRUE;
00085                     else
00086                         retry = FALSE;
00087                     break;
00088                     
00089                 case kUnsanitySCR_Install_WillNotInstall:
00090                 case kUnsanitySCR_Install_OutOfMemory:
00091                 default:
00092                     NSRunCriticalAlertPanel(@"Crash Reporting Problem", @"Something unusual happened that prevented installing the crash reporter. If it happens persistently, please contact the Race Into Space developers.", @"All right", nil, nil);
00093                     break;
00094             }           
00095         } while (retry);
00096     } else {
00097         NSRunInformationalAlertPanel(@"Crash Reporting Enabled", @"The crash reporting tool is installed. If Race Into Space crashes, please click the Report... button to submit a detailed crash report.", @"Great!", nil, nil);
00098     }
00099 }
00100 
00101 /* Set the working directory to the .app directory */
00102 - (void) setupWorkingDirectory
00103 {
00104     char appdir;
00105     CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
00106     if (CFURLGetFileSystemRepresentation(url, true, (UInt8 *)appdir, MAXPATHLEN)) {
00107         chdir(appdir);
00108     }
00109     CFRelease(url);
00110 }
00111 
00112 /*
00113  * Catch document open requests...this lets us notice files when the app
00114  *  was launched by double-clicking a document, or when a document was
00115  *  dragged/dropped on the app's icon. You need to have a
00116  *  CFBundleDocumentsType section in your Info.plist to get this message,
00117  *  apparently.
00118  *
00119  * Files are added to gArgv, so to the app, they'll look like command line
00120  *  arguments. Previously, apps launched from the finder had nothing but
00121  *  an argv[0].
00122  *
00123  * This message may be received multiple times to open several docs on launch.
00124  *
00125  * This message is ignored once the app's mainline has been called.
00126  */
00127 - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
00128 {
00129     const char *temparg;
00130     size_t arglen;
00131     char *arg;
00132     char **newargv;
00133 
00134     if (!gFinderLaunch)  /* MacOS is passing command line args. */
00135         return FALSE;
00136 
00137     if (gCalledAppMainline)  /* app has started, ignore this document. */
00138         return FALSE;
00139 
00140     temparg = [filename UTF8String];
00141     arglen = SDL_strlen(temparg) + 1;
00142     arg = (char *) SDL_malloc(arglen);
00143     if (arg == NULL)
00144         return FALSE;
00145 
00146     newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
00147     if (newargv == NULL)
00148     {
00149         SDL_free(arg);
00150         return FALSE;
00151     }
00152     gArgv = newargv;
00153 
00154     SDL_strlcpy(arg, temparg, arglen);
00155     gArgv = arg;
00156     gArgv = NULL;
00157     return TRUE;
00158 }
00159 
00160 
00161 /* Called when the internal event loop has just started running */
00162 - (void) applicationDidFinishLaunching: (NSNotification *) note
00163 {
00164     int status;
00165 
00166     [self setupWorkingDirectory];
00167 
00168     gCalledAppMainline = TRUE;
00169     status = SDL_main(gArgc, gArgv);
00170 
00171     exit(status);
00172 }
00173 @end
00174 
00175 #ifdef main
00176 #  undef main
00177 #endif
00178 
00179 /* Main entry point to executable - should *not* be SDL_main! */
00180 int main (int argc, char **argv)
00181 {
00182     /* Copy the arguments into a global variable */
00183     /* This is passed if we are launched by double-clicking */
00184     if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
00185         gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
00186         gArgv = argv;
00187         gArgv = NULL;
00188         gArgc = 1;
00189         gFinderLaunch = YES;
00190     } else {
00191         int i;
00192         gArgc = argc;
00193         gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
00194         for (i = 0; i <= argc; i++)
00195             gArgv[i] = argv[i];
00196         gFinderLaunch = NO;
00197     }
00198 
00199     [SDLApplication poseAsClass:[NSApplication class]];
00200     NSApplicationMain (argc, argv);
00201 
00202     return 0;
00203 }

Generated on Fri Sep 28 00:35:45 2007 for raceintospace by  doxygen 1.5.3