--- hatari/src/gui-osx/SDLMain.m 2019/04/09 08:54:10 1.1.1.11 +++ hatari/src/gui-osx/SDLMain.m 2019/04/09 08:55:22 1.1.1.12 @@ -1,18 +1,10 @@ -// -// HatariAppDelegate.m -// Hatari -// -// Créé le 12/06/13 par Miguel Saro. -// Tout droits réservés, - Cocoa Pod -, 2013. -// - -/* SDLMain.m - main entry point for our Cocoa-ized SDL app +/* + SDLMain.m - main entry point for our Cocoa-ized SDL app Initial Version: Darrell Walisser Non-NIB-Code & other changes: Max Horn + Modifications for Hatari by Miguel Saro and Jerome Vernet Feel free to customize this file to suit your needs - - */ /* Use this flag to determine whether we use SDLMain.nib or not */ @@ -72,7 +64,7 @@ char szPath[FILENAME_MAX] ; // // Set the working directory to the .app's parent directory - (void) setupWorkingDirectory:(BOOL)shouldChdir { - if (shouldChdir) + if (shouldChdir) chdir([[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] cStringUsingEncoding:NSASCIIStringEncoding]) ; } @@ -94,35 +86,35 @@ char szPath[FILENAME_MAX] ; // */ - (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; + 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; } @@ -171,15 +163,15 @@ char szPath[FILENAME_MAX] ; // - (IBAction)warmReset:(id)sender { - if (NSRunAlertPanel (localize(@"Warm reset"), localize(@"Really reset the emulator?"), - localize(@"OK"), localize(@"Cancel"), nil) == NSAlertDefaultReturn ) + if ([NSApp myAlerte:NSInformationalAlertStyle Txt:localize(@"Warm reset!") firstB:localize(@"OK") alternateB:localize(@"Cancel") + otherB:nil informativeTxt:localize(@"Really reset the emulator?")] == NSAlertDefaultReturn) Reset_Warm(); } - (IBAction)coldReset:(id)sender { - if (NSRunAlertPanel (localize(@"Cold reset!"), localize(@"Really reset the emulator?"), - localize(@"OK"),localize(@"Cancel"), nil) == NSAlertDefaultReturn ) + if ([NSApp myAlerte:NSInformationalAlertStyle Txt:localize(@"Cold reset") firstB:localize(@"OK") alternateB:localize(@"Cancel") + otherB:nil informativeTxt:localize(@"Really reset the emulator?")] == NSAlertDefaultReturn) Reset_Cold(); } @@ -240,11 +232,10 @@ char szPath[FILENAME_MAX] ; // NSString *preferredPath; NSString *extensionText; NSString *selectFile; - + // Get the path from the user settings preferredPath = [[NSString stringWithCString:pathInParams encoding:NSASCIIStringEncoding] stringByAbbreviatingWithTildeInPath]; - if ((preferredPath != nil) && ([preferredPath length] > 0)) // Determine the directory and filename { directoryToOpen = [preferredPath stringByDeletingLastPathComponent]; // Existing path: we use it @@ -255,16 +246,16 @@ char szPath[FILENAME_MAX] ; // directoryToOpen = [@"~" stringByExpandingTildeInPath]; // No path: we use the user's directory fileToPreselect = preferredFileName; } ; - + if(bInFullScreen) Screen_ReturnFromFullScreen(); // SavePanel for choosing what file to write extensionText = [NSString stringWithFormat:localize(@"Please specify a .%@ file"), [allowedExtensions componentsJoinedByString:localize(@" or a .")] ]; - + selectFile = [NSApp hsavefile:YES defoDir:directoryToOpen defoFile:fileToPreselect types:allowedExtensions titre:extensionText ] ; if ([selectFile length] != 0 ) return selectFile ; - + return nil; } @@ -279,9 +270,9 @@ char szPath[FILENAME_MAX] ; // { GuiOsx_Pause(); if(!Avi_AreWeRecording()) { - NSString* path = [self displayFileSelection:ConfigureParams.Video.AviRecordFile preferredFileName:@"hatari.avi" + NSString* path = [self displayFileSelection:ConfigureParams.Video.AviRecordFile preferredFileName:@"hatari.avi" allowedExtensions:[NSArray arrayWithObject:@"avi"]]; - + if(path) { GuiOsx_ExportPathString(path, ConfigureParams.Video.AviRecordFile, sizeof(ConfigureParams.Video.AviRecordFile)); Avi_StartRecording ( ConfigureParams.Video.AviRecordFile , ConfigureParams.Screen.bCrop , @@ -291,7 +282,6 @@ char szPath[FILENAME_MAX] ; // 1 << CLOCKS_TIMINGS_SHIFT_VBL , ConfigureParams.Video.AviRecordVcodec ); } - } else { Avi_StopRecording(); } @@ -308,7 +298,7 @@ char szPath[FILENAME_MAX] ; // - (IBAction)captureSound:(id)sender { GuiOsx_Pause(); - NSString* path = [self displayFileSelection:ConfigureParams.Sound.szYMCaptureFileName preferredFileName:@"hatari.wav" + NSString* path = [self displayFileSelection:ConfigureParams.Sound.szYMCaptureFileName preferredFileName:@"hatari.wav" allowedExtensions:[NSArray arrayWithObjects:@"ym", @"wav", nil]]; if(path) { GuiOsx_ExportPathString(path, ConfigureParams.Sound.szYMCaptureFileName, sizeof(ConfigureParams.Sound.szYMCaptureFileName)); @@ -328,28 +318,28 @@ char szPath[FILENAME_MAX] ; // { GuiOsx_Pause(); - NSString* path = [self displayFileSelection:ConfigureParams.Memory.szMemoryCaptureFileName preferredFileName:@"hatari.sav" + NSString* path = [self displayFileSelection:ConfigureParams.Memory.szMemoryCaptureFileName preferredFileName:@"hatari.sav" allowedExtensions:[NSArray arrayWithObject:@"sav"]]; if(path) { GuiOsx_ExportPathString(path, ConfigureParams.Memory.szMemoryCaptureFileName, sizeof(ConfigureParams.Memory.szMemoryCaptureFileName)); MemorySnapShot_Capture(ConfigureParams.Memory.szMemoryCaptureFileName, TRUE); } - + GuiOsx_Resume(); } - (IBAction)restoreMemorySnap:(id)sender { -NSString *directoryToOpen; -NSString *fileToPreselect; -NSString *oldPath ; -NSString *newPath ; + NSString *directoryToOpen; + NSString *fileToPreselect; + NSString *oldPath ; + NSString *newPath ; GuiOsx_Pause(); // Get the path from the user settings oldPath = [NSString stringWithCString:(ConfigureParams.Memory.szMemoryCaptureFileName) encoding:NSASCIIStringEncoding]; - + if ((oldPath != nil) && ([oldPath length] > 0)) // Determine directory and filename { directoryToOpen = [oldPath stringByDeletingLastPathComponent]; // existing path: we use it. fileToPreselect = [oldPath lastPathComponent]; } @@ -366,13 +356,13 @@ NSString *newPath ; - (IBAction)doFullScreen:(id)sender { - // A call to Screen_EnterFullScreen() would be required, but this causes a crash when using + // A call to Screen_EnterFullScreen() would be required, but this causes a crash when using // SDL runtime 1.2.11, probably due to conflicts between Cocoa and SDL. // Therefore we simulate the fullscreen key press instead - + SDL_KeyboardEvent event; + memset(&event, 0, sizeof(event)); event.type = SDL_KEYDOWN; - event.which = 0; event.state = SDL_PRESSED; event.keysym.sym = SDLK_F11; SDL_PushEvent((SDL_Event*)&event); // Send the F11 key press @@ -385,9 +375,9 @@ NSString *newPath ; - (IBAction)help:(id)sender { NSString *the_help; - + the_help = [[NSBundle mainBundle] pathForResource:@"manual" ofType:@"html" inDirectory:@"HatariHelp"]; - + if (![[NSWorkspace sharedWorkspace] openFile:the_help withApplication:@"HelpViewer"]) if (![[NSWorkspace sharedWorkspace] openFile:the_help withApplication:@"Help Viewer"]) [[NSWorkspace sharedWorkspace] openFile:the_help]; @@ -395,49 +385,48 @@ NSString *newPath ; - (IBAction)compat:(id)sender { -NSString *C_aide ; - + NSString *C_aide ; + C_aide = [[NSBundle mainBundle] pathForResource:@"compatibility" ofType:@"html" inDirectory:@"HatariHelp"] ; - + if (![[NSWorkspace sharedWorkspace] openFile:C_aide withApplication:@"HelpViewer"]) if (![[NSWorkspace sharedWorkspace] openFile:C_aide withApplication:@"Help Viewer"]) - [[NSWorkspace sharedWorkspace] openFile:C_aide] ; + [[NSWorkspace sharedWorkspace] openFile:C_aide] ; } -- (IBAction)openConfig:(id)sender +- (IBAction)openConfig:(id)sender { -BOOL applyChanges ; -NSString *ConfigFile, *newCfg ; -CNF_PARAMS CurrentParams; + BOOL applyChanges ; + NSString *ConfigFile, *newCfg ; + CNF_PARAMS CurrentParams; applyChanges = true ; - ConfigFile = [NSString stringWithCString:(sConfigFileName) encoding:NSASCIIStringEncoding]; - + ConfigFile = [NSString stringWithCString:(sConfigFileName) encoding:NSASCIIStringEncoding]; + // Backup of configuration settings to CurrentParams (which we will only // commit back to the configuration settings if choosing user confirm) CurrentParams = ConfigureParams; - + GuiOsx_Pause(); - + newCfg = [NSApp hopenfile:NO defoDir:nil defoFile:ConfigFile types:[NSArray arrayWithObject:@"cfg"] ] ; - + if ([newCfg length] != 0) - { + { [newCfg getCString:szPath maxLength:FILENAME_MAX-1 encoding:NSASCIIStringEncoding] ; // get Cstring szPath Configuration_Load(szPath) ; // Load the config into ConfigureParams strcpy(sConfigFileName,szPath) ; - // Refresh all the controls to match ConfigureParams + // Refresh all the controls to match ConfigureParams if (Change_DoNeedReset(&CurrentParams, &ConfigureParams)) - applyChanges = NSRunAlertPanel(localize(@"Reset the emulator"), localize(@"Must be reset"), - localize(@"Don't reset"), localize(@"Reset"), nil) == NSAlertAlternateReturn ; - + applyChanges = [NSApp myAlerte:NSInformationalAlertStyle Txt:localize(@"Reset the emulator") firstB:localize(@"Don't reset") + alternateB:localize(@"Reset") otherB:nil informativeTxt:@"" ] == NSAlertAlternateReturn ; if (applyChanges) Change_CopyChangedParamsToConfiguration(&CurrentParams, &ConfigureParams, true); // Ok with Reset - else + else ConfigureParams = CurrentParams; //Restore previous Params. - } ; - + } ; + GuiOsx_Resume(); } @@ -447,34 +436,64 @@ CNF_PARAMS CurrentParams; @end +static int IsRootCwd() +{ + char buf[MAXPATHLEN]; + char *cwd = getcwd(buf, sizeof (buf)); + return (cwd && (strcmp(cwd, "/") == 0)); +} + +static int IsTenPointNineOrLater() +{ + /* Gestalt() is deprecated in 10.8 ... TODO: replace with better test? */ + SInt32 major, minor; + Gestalt(gestaltSystemVersionMajor, &major); + Gestalt(gestaltSystemVersionMinor, &minor); + return ( ((major << 16) | minor) >= ((10 << 16) | 9) ); +} + +static int IsFinderLaunch(const int argc, char **argv) +{ + /* -psn_XXX is passed if we are launched from Finder in 10.8 and earlier */ + if (argc >= 2 && strncmp(argv[1], "-psn", 4) == 0) { + return 1; + } + if (IsTenPointNineOrLater() && argc == 1 && IsRootCwd()) { + /* we might still be launched from the Finder; on 10.9+, you might not + get the -psn command line anymore. Check version, if there's no + command line, and if our current working directory is "/". */ + return 1; + } + return 0; /* not a Finder launch. */ +} + #ifdef main # undef main #endif -// Main entry point to executable - should *not* be SDL_main! +// 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; - } // */ + // Copy the arguments into a global variable + if (IsFinderLaunch(argc, argv)) { + 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 - NSApplicationMain (argc, (const char**)argv); + NSApplicationMain (argc, (const char**)argv); #else - CustomApplicationMain (argc, argv); + CustomApplicationMain (argc, argv); #endif - return 0; -} // */ + return 0; +}