Annotation of hatari/src/gui-osx/SDLMain.m, revision 1.1.1.6

1.1       root        1: /*   SDLMain.m - main entry point for our Cocoa-ized SDL app
                      2:        Initial Version: Darrell Walisser <[email protected]>
                      3:        Non-NIB-Code & other changes: Max Horn <[email protected]>
                      4: 
                      5:     Feel free to customize this file to suit your needs
                      6: */
                      7: 
1.1.1.6 ! root        8: #include "SDL.h"
        !             9: #include "SDLMain.h"
        !            10: #include <sys/param.h> /* for MAXPATHLEN */
        !            11: #include <unistd.h>
        !            12: 
        !            13: // for Hatari
1.1       root       14: 
                     15: #include "dialog.h"
                     16: #include "floppy.h"
                     17: #include "reset.h"
                     18: #include "screenSnapShot.h"
                     19: #include "memorySnapShot.h"
                     20: #include "sound.h"
1.1.1.6 ! root       21: #include "video.h"
        !            22: #include "avi_record.h"
        !            23: 
        !            24: // for Hatari
        !            25: 
        !            26: 
        !            27: /* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
        !            28:  but the method still is there and works. To avoid warnings, we declare
        !            29:  it ourselves here. */
        !            30: @interface NSApplication(SDL_Missing_Methods)
        !            31: - (void)setAppleMenu:(NSMenu *)menu;
        !            32: @end
        !            33: 
        !            34: /* Use this flag to determine whether we use SDLMain.nib or not */
        !            35: #define                SDL_USE_NIB_FILE        1
        !            36: 
        !            37: /* Use this flag to determine whether we use CPS (docking) or not */
        !            38: #define                SDL_USE_CPS             1
        !            39: #ifdef SDL_USE_CPS
        !            40: /* Portions of CPS.h */
        !            41: typedef struct CPSProcessSerNum
        !            42: {
        !            43:        UInt32          lo;
        !            44:        UInt32          hi;
        !            45: } CPSProcessSerNum;
        !            46: 
        !            47: extern OSErr   CPSGetCurrentProcess( CPSProcessSerNum *psn);
        !            48: extern OSErr   CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
        !            49: extern OSErr   CPSSetFrontProcess( CPSProcessSerNum *psn);
        !            50: 
        !            51: #endif /* SDL_USE_CPS */
1.1       root       52: 
                     53: static int    gArgc;
                     54: static char  **gArgv;
                     55: static BOOL   gFinderLaunch;
1.1.1.6 ! root       56: static BOOL   gCalledAppMainline = FALSE;
        !            57: 
        !            58: static NSString *getApplicationName(void)
        !            59: {
        !            60:     const NSDictionary *dict;
        !            61:     NSString *appName = 0;
1.1       root       62: 
1.1.1.6 ! root       63:     /* Determine the application name */
        !            64:     dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
        !            65:     if (dict)
        !            66:         appName = [dict objectForKey: @"CFBundleName"];
        !            67:     
        !            68:     if (![appName length])
        !            69:         appName = [[NSProcessInfo processInfo] processName];
        !            70: 
        !            71:     return appName;
        !            72: }
        !            73: 
        !            74: #if SDL_USE_NIB_FILE
        !            75: /* A helper category for NSString */
        !            76: @interface NSString (ReplaceSubString)
        !            77: - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
1.1       root       78: @end
1.1.1.6 ! root       79: #endif
1.1       root       80: 
1.1.1.6 ! root       81: @interface NSApplication (SDLApplication)
        !            82: @end
        !            83: 
        !            84: @implementation NSApplication (SDLApplication)
1.1       root       85: /* Invoked from the Quit menu item */
                     86: - (void)terminate:(id)sender
                     87: {
                     88:     /* Post a SDL_QUIT event */
                     89:     SDL_Event event;
                     90:     event.type = SDL_QUIT;
                     91:     SDL_PushEvent(&event);
                     92: }
                     93: @end
                     94: 
                     95: /* The main class of the application, the application's delegate */
                     96: @implementation SDLMain
                     97: 
1.1.1.6 ! root       98: /* Set the working directory to the .app's parent directory */
        !            99: - (void) setupWorkingDirectory:(BOOL)shouldChdir
        !           100: {
        !           101:     if (shouldChdir)
        !           102:     {
        !           103:         char parentdir[MAXPATHLEN];
        !           104:         CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
        !           105:         CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
        !           106:         if (CFURLGetFileSystemRepresentation(url2, 1, (UInt8 *)parentdir, MAXPATHLEN)) {
        !           107:             chdir(parentdir);   /* chdir to the binary app's parent */
        !           108:         }
        !           109:         CFRelease(url);
        !           110:         CFRelease(url2);
        !           111:     }
        !           112: }
        !           113: 
        !           114: #if SDL_USE_NIB_FILE
        !           115: 
        !           116: /* Fix menu to contain the real app name instead of "SDL App" */
        !           117: - (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
        !           118: {
        !           119:     NSRange aRange;
        !           120:     NSEnumerator *enumerator;
        !           121:     NSMenuItem *menuItem;
        !           122: 
        !           123:     aRange = [[aMenu title] rangeOfString:@"SDL App"];
        !           124:     if (aRange.length != 0)
        !           125:         [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
        !           126: 
        !           127:     enumerator = [[aMenu itemArray] objectEnumerator];
        !           128:     while ((menuItem = [enumerator nextObject]))
        !           129:     {
        !           130:         aRange = [[menuItem title] rangeOfString:@"SDL App"];
        !           131:         if (aRange.length != 0)
        !           132:             [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
        !           133:         if ([menuItem hasSubmenu])
        !           134:             [self fixMenu:[menuItem submenu] withAppName:appName];
        !           135:     }
        !           136: }
        !           137: 
        !           138: #else
        !           139: 
        !           140: static void setApplicationMenu(void)
        !           141: {
        !           142:     /* warning: this code is very odd */
        !           143:     NSMenu *appleMenu;
        !           144:     NSMenuItem *menuItem;
        !           145:     NSString *title;
        !           146:     NSString *appName;
        !           147:     
        !           148:     appName = getApplicationName();
        !           149:     appleMenu = [[NSMenu alloc] initWithTitle:@""];
        !           150:     
        !           151:     /* Add menu items */
        !           152:     title = [@"About " stringByAppendingString:appName];
        !           153:     [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
        !           154: 
        !           155:     [appleMenu addItem:[NSMenuItem separatorItem]];
        !           156: 
        !           157:     title = [@"Hide " stringByAppendingString:appName];
        !           158:     [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
        !           159: 
        !           160:     menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
        !           161:     [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
        !           162: 
        !           163:     [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
        !           164: 
        !           165:     [appleMenu addItem:[NSMenuItem separatorItem]];
        !           166: 
        !           167:     title = [@"Quit " stringByAppendingString:appName];
        !           168:     [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
        !           169: 
        !           170:     
        !           171:     /* Put menu into the menubar */
        !           172:     menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
        !           173:     [menuItem setSubmenu:appleMenu];
        !           174:     [[NSApp mainMenu] addItem:menuItem];
        !           175: 
        !           176:     /* Tell the application object that this is now the application menu */
        !           177:     [NSApp setAppleMenu:appleMenu];
        !           178: 
        !           179:     /* Finally give up our references to the objects */
        !           180:     [appleMenu release];
        !           181:     [menuItem release];
        !           182: }
        !           183: 
        !           184: /* Create a window menu */
        !           185: static void setupWindowMenu(void)
        !           186: {
        !           187:     NSMenu      *windowMenu;
        !           188:     NSMenuItem  *windowMenuItem;
        !           189:     NSMenuItem  *menuItem;
        !           190: 
        !           191:     windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
        !           192:     
        !           193:     /* "Minimize" item */
        !           194:     menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
        !           195:     [windowMenu addItem:menuItem];
        !           196:     [menuItem release];
        !           197:     
        !           198:     /* Put menu into the menubar */
        !           199:     windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
        !           200:     [windowMenuItem setSubmenu:windowMenu];
        !           201:     [[NSApp mainMenu] addItem:windowMenuItem];
        !           202:     
        !           203:     /* Tell the application object that this is now the window menu */
        !           204:     [NSApp setWindowsMenu:windowMenu];
        !           205: 
        !           206:     /* Finally give up our references to the objects */
        !           207:     [windowMenu release];
        !           208:     [windowMenuItem release];
        !           209: }
        !           210: 
        !           211: /* Replacement for NSApplicationMain */
        !           212: static void CustomApplicationMain (int argc, char **argv)
        !           213: {
        !           214:     NSAutoreleasePool  *pool = [[NSAutoreleasePool alloc] init];
        !           215:     SDLMain                            *sdlMain;
        !           216: 
        !           217:     /* Ensure the application object is initialised */
        !           218:     [NSApplication sharedApplication];
        !           219:     
        !           220: #ifdef SDL_USE_CPS
        !           221:     {
        !           222:         CPSProcessSerNum PSN;
        !           223:         /* Tell the dock about us */
        !           224:         if (!CPSGetCurrentProcess(&PSN))
        !           225:             if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
        !           226:                 if (!CPSSetFrontProcess(&PSN))
        !           227:                     [NSApplication sharedApplication];
        !           228:     }
        !           229: #endif /* SDL_USE_CPS */
        !           230: 
        !           231:     /* Set up the menubar */
        !           232:     [NSApp setMainMenu:[[NSMenu alloc] init]];
        !           233:     setApplicationMenu();
        !           234:     setupWindowMenu();
        !           235: 
        !           236:     /* Create SDLMain and make it the app delegate */
        !           237:     sdlMain = [[SDLMain alloc] init];
        !           238:     [NSApp setDelegate:sdlMain];
        !           239:     
        !           240:     /* Start the main event loop */
        !           241:     [NSApp run];
        !           242:     
        !           243:     [sdlMain release];
        !           244:     [pool release];
        !           245: }
        !           246: 
        !           247: #endif
        !           248: 
        !           249: 
        !           250: /*
        !           251:  * Catch document open requests...this lets us notice files when the app
        !           252:  *  was launched by double-clicking a document, or when a document was
        !           253:  *  dragged/dropped on the app's icon. You need to have a
        !           254:  *  CFBundleDocumentsType section in your Info.plist to get this message,
        !           255:  *  apparently.
        !           256:  *
        !           257:  * Files are added to gArgv, so to the app, they'll look like command line
        !           258:  *  arguments. Previously, apps launched from the finder had nothing but
        !           259:  *  an argv[0].
        !           260:  *
        !           261:  * This message may be received multiple times to open several docs on launch.
        !           262:  *
        !           263:  * This message is ignored once the app's mainline has been called.
        !           264:  */
        !           265: - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
        !           266: {
        !           267:     const char *temparg;
        !           268:     size_t arglen;
        !           269:     char *arg;
        !           270:     char **newargv;
        !           271: 
        !           272:     if (!gFinderLaunch)  /* MacOS is passing command line args. */
        !           273:         return FALSE;
        !           274: 
        !           275:     if (gCalledAppMainline)  /* app has started, ignore this document. */
        !           276:         return FALSE;
        !           277: 
        !           278:     temparg = [filename UTF8String];
        !           279:     arglen = SDL_strlen(temparg) + 1;
        !           280:     arg = (char *) SDL_malloc(arglen);
        !           281:     if (arg == NULL)
        !           282:         return FALSE;
        !           283: 
        !           284:     newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
        !           285:     if (newargv == NULL)
        !           286:     {
        !           287:         SDL_free(arg);
        !           288:         return FALSE;
        !           289:     }
        !           290:     gArgv = newargv;
        !           291: 
        !           292:     SDL_strlcpy(arg, temparg, arglen);
        !           293:     gArgv[gArgc++] = arg;
        !           294:     gArgv[gArgc] = NULL;
        !           295:     return TRUE;
        !           296: }
        !           297: 
        !           298: 
        !           299: /* Called when the internal event loop has just started running */
        !           300: - (void) applicationDidFinishLaunching: (NSNotification *) note
        !           301: {
        !           302:     int status;
        !           303: 
        !           304:     /* Set the working directory to the .app's parent directory */
        !           305:     [self setupWorkingDirectory:gFinderLaunch];
        !           306: 
        !           307: #if SDL_USE_NIB_FILE
        !           308:     /* Set the main menu to contain the real app name instead of "SDL App" */
        !           309:     [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
        !           310: #endif
        !           311: 
        !           312:     /* Hand off to main application code */
        !           313:     gCalledAppMainline = TRUE;
        !           314:     status = SDL_main (gArgc, gArgv);
        !           315: 
        !           316:     /* We're done, thank you for playing */
        !           317:     exit(status);
        !           318: }
        !           319: 
        !           320: // Hatari Stuff
1.1       root      321: - (IBAction)prefsMenu:(id)sender
                    322: {
                    323:        static int in_propdialog =  0;
1.1.1.6 ! root      324: 
1.1       root      325:        if (in_propdialog)
                    326:                return;
                    327:        ++in_propdialog;
1.1.1.6 ! root      328:        Dialog_DoProperty();
1.1       root      329:        --in_propdialog;
                    330: }
                    331: 
1.1.1.6 ! root      332: - (IBAction)debugUI:(id)sender
        !           333: {
        !           334:        DebugUI();
        !           335: }
        !           336: 
1.1       root      337: - (IBAction)warmReset:(id)sender
                    338: {
                    339:        int b;
1.1.1.6 ! root      340: 
        !           341:        b = NSRunAlertPanel (
        !           342:                                                 NSLocalizedStringFromTable(@"Warm reset",@"Localizable",@"comment"),
        !           343:                                                 NSLocalizedStringFromTable(@"Really reset the emulator?",@"Localizable",@"comment"),
        !           344:                                                 NSLocalizedStringFromTable(@"OK",@"Localizable",@"comment"), 
        !           345:                                                 NSLocalizedStringFromTable(@"Cancel",@"Localizable",@"comment"), nil);
1.1       root      346:        //printf("b=%i\n",b);
                    347:        if (b == 1)
                    348:                Reset_Warm();
                    349: }
                    350: 
                    351: - (IBAction)coldReset:(id)sender
                    352: {
                    353:        int b;
1.1.1.6 ! root      354: 
        !           355:        b = NSRunAlertPanel (
        !           356:                                                 NSLocalizedStringFromTable(@"Cold reset!",@"Localizable",@"comment"), 
        !           357:                                                 NSLocalizedStringFromTable(@"Really reset the emulator?",@"Localizable",@"comment") ,
        !           358:                                                 NSLocalizedStringFromTable(@"OK",@"Localizable",@"comment"), 
        !           359:                                                 NSLocalizedStringFromTable(@"Cancel",@"Localizable",@"comment"), nil);
1.1       root      360:        //printf("b=%i\n",b);
                    361:        if (b == 1)
                    362:                Reset_Cold();
                    363: }
                    364: 
                    365: - (IBAction)insertDiskA:(id)sender
                    366: {
1.1.1.6 ! root      367:        NSString *path = nil;
        !           368:        NSOpenPanel *openPanel = [ NSOpenPanel openPanel ];
        !           369: 
        !           370:        if ( [ openPanel runModalForDirectory:nil
        !           371:                                                                         file:@"SavedGame" types:nil ] )
        !           372:        {
        !           373:                path = [ [ openPanel filenames ] objectAtIndex:0 ];
        !           374:        }
        !           375: 
1.1       root      376:        if (path != nil)
                    377:        {
                    378:                // Make a non-const C string out of it
1.1.1.6 ! root      379:                const char* constSzPath = [path cStringUsingEncoding:NSASCIIStringEncoding];
1.1       root      380:                size_t cbPath = strlen(constSzPath) + 1;
                    381:                char szPath[cbPath];
1.1.1.6 ! root      382:                strncpy(szPath, constSzPath, cbPath);
1.1.1.3   root      383: 
                    384:                Floppy_SetDiskFileName(0, szPath, NULL);
                    385:                Floppy_InsertDiskIntoDrive(0);
1.1       root      386:        }
                    387: }
                    388: 
                    389: - (IBAction)insertDiskB:(id)sender
                    390: {
1.1.1.6 ! root      391:        NSString *path = nil;
        !           392:        NSOpenPanel *openPanel = [ NSOpenPanel openPanel ];
        !           393: 
        !           394:        if ( [ openPanel runModalForDirectory:nil
        !           395:                                                                         file:@"SavedGame" types:nil ] )
        !           396:        {
        !           397:                path = [ [ openPanel filenames ] objectAtIndex:0 ];
        !           398:        }
        !           399: 
1.1       root      400:        if (path != nil)
                    401:        {
                    402:                // Make a non-const C string out of it
1.1.1.6 ! root      403:                const char* constSzPath = [path cStringUsingEncoding:NSASCIIStringEncoding];
1.1       root      404:                size_t cbPath = strlen(constSzPath) + 1;
                    405:                char szPath[cbPath];
                    406:                strncpy(szPath, constSzPath, cbPath);   
1.1.1.6 ! root      407: 
1.1.1.3   root      408:                Floppy_SetDiskFileName(1, szPath, NULL);
                    409:                Floppy_InsertDiskIntoDrive(1);
1.1       root      410:        }
                    411: }
                    412: 
                    413: /*-----------------------------------------------------------------------*/
                    414: /*
1.1.1.6 ! root      415:  Controls the enabled state of the menu items
        !           416:  */
1.1       root      417: - (BOOL)validateMenuItem:(NSMenuItem*)item
                    418: {
                    419:        if (item == beginCaptureAnim)
                    420:        {
1.1.1.6 ! root      421:                return !Avi_AreWeRecording();
1.1       root      422:        }
                    423:        if (item == endCaptureAnim)
                    424:        {
1.1.1.6 ! root      425:                return Avi_AreWeRecording();
1.1       root      426:        }
                    427:        if (item == beginCaptureSound)
                    428:        {
                    429:                return !Sound_AreWeRecording();
                    430:        }
                    431:        if (item == endCaptureSound)
                    432:        {
                    433:                return Sound_AreWeRecording();
                    434:        }
                    435: 
                    436:        return YES;
                    437: }
                    438: 
                    439: - (IBAction)captureScreen:(id)sender
                    440: {
1.1.1.5   root      441:        GuiOsx_Pause();
1.1       root      442:        ScreenSnapShot_SaveScreen();
1.1.1.5   root      443:        GuiOsx_Resume();
1.1       root      444: }
                    445: 
                    446: - (IBAction)captureAnimation:(id)sender
                    447: {
1.1.1.5   root      448:        GuiOsx_Pause();
1.1.1.6 ! root      449:        Avi_StartRecording ( AviRecordFile , AviRecordDefaultCrop , nScreenRefreshRate , AviRecordDefaultVcodec );
1.1.1.5   root      450:        GuiOsx_Resume();
1.1       root      451: }
                    452: 
                    453: - (IBAction)endCaptureAnimation:(id)sender
                    454: {
1.1.1.5   root      455:        GuiOsx_Pause();
1.1.1.6 ! root      456:        Avi_StopRecording();
1.1.1.5   root      457:        GuiOsx_Resume();
1.1       root      458: }
                    459: 
                    460: - (IBAction)captureSound:(id)sender
                    461: {
1.1.1.5   root      462:        GuiOsx_Pause();
1.1       root      463: 
                    464:        // Get the path from the user settings
1.1.1.6 ! root      465:        NSString *preferredPath = [[NSString stringWithCString:(ConfigureParams.Sound.szYMCaptureFileName) encoding:NSASCIIStringEncoding] stringByAbbreviatingWithTildeInPath];
1.1       root      466: 
                    467:        // Determine the directory and filename
                    468:        NSString *directoryToOpen;
                    469:        NSString *fileToPreselect;
                    470:        if ((preferredPath != nil) && ([preferredPath length] > 0))
                    471:        {
                    472:                // There is existing path: we will open its directory with its file pre-selected.
                    473:                directoryToOpen = [preferredPath stringByDeletingLastPathComponent];
                    474:                fileToPreselect = [preferredPath lastPathComponent];
                    475:        }
                    476:        else
                    477:        {
                    478:                // Currently no path: we will open the user's directory with no file selected.
                    479:                directoryToOpen = [@"~" stringByExpandingTildeInPath];
                    480:                fileToPreselect = @"hatari.wav";
                    481:        }       
                    482: 
                    483:        // Create and configure a SavePanel for choosing what file to write
                    484:        NSSavePanel *savePanel = [NSSavePanel savePanel];
                    485:        [savePanel setAllowedFileTypes:[NSArray arrayWithObjects:@"ym", @"wav", nil]];
                    486:        [savePanel setExtensionHidden:NO];
                    487:        [savePanel setMessage:@"Please specify an .ym or a .wav file."];        // TODO: Move to localizable resources
                    488:        
                    489:        // Run the SavePanel, then check if the user clicked OK and selected at least one file
1.1.1.6 ! root      490:        if (NSFileHandlingPanelOKButton == [savePanel runModalForDirectory:directoryToOpen file:fileToPreselect] )
1.1       root      491:        {
                    492:                // Get the path to the selected file
                    493:                NSString *path = [savePanel filename];
                    494:                
                    495:                // Store the path in the user settings
                    496:                GuiOsx_ExportPathString(path, ConfigureParams.Sound.szYMCaptureFileName, sizeof(ConfigureParams.Sound.szYMCaptureFileName));
1.1.1.6 ! root      497:                
1.1       root      498:                // Begin capture
                    499:                Sound_BeginRecording(ConfigureParams.Sound.szYMCaptureFileName);
1.1.1.6 ! root      500:        }
1.1       root      501: 
1.1.1.5   root      502:        GuiOsx_Resume();
1.1       root      503: }
                    504: 
                    505: - (IBAction)endCaptureSound:(id)sender
                    506: {
1.1.1.5   root      507:        GuiOsx_Pause();
1.1       root      508:        Sound_EndRecording();
1.1.1.5   root      509:        GuiOsx_Resume();
1.1       root      510: }
                    511: 
                    512: - (IBAction)saveMemorySnap:(id)sender
                    513: {
1.1.1.5   root      514:        GuiOsx_Pause();
1.1       root      515: 
                    516:        // Get the path from the user settings
1.1.1.6 ! root      517:        NSString *preferredPath = [[NSString stringWithCString:(ConfigureParams.Memory.szMemoryCaptureFileName) encoding:NSASCIIStringEncoding] stringByAbbreviatingWithTildeInPath];
1.1       root      518: 
                    519:        // Determine the directory and filename
                    520:        NSString *directoryToOpen;
                    521:        NSString *fileToPreselect;
                    522:        if ((preferredPath != nil) && ([preferredPath length] > 0))
                    523:        {
                    524:                // There is existing path: we will open its directory with its file pre-selected.
                    525:                directoryToOpen = [preferredPath stringByDeletingLastPathComponent];
                    526:                fileToPreselect = [preferredPath lastPathComponent];
                    527:        }
                    528:        else
                    529:        {
                    530:                // Currently no path: we will open the user's directory with the default filename.
                    531:                directoryToOpen = [@"~" stringByExpandingTildeInPath];
                    532:                fileToPreselect = @"hatari.sav";
1.1.1.6 ! root      533:        }
1.1       root      534: 
                    535:        // Create and configure a SavePanel for choosing what file to write
                    536:        NSSavePanel *savePanel = [NSSavePanel savePanel];
                    537:        [savePanel setExtensionHidden:NO];
1.1.1.6 ! root      538: 
1.1       root      539:        // Run the SavePanel, then check if the user clicked OK and selected at least one file
1.1.1.6 ! root      540:        if (NSFileHandlingPanelOKButton == [savePanel runModalForDirectory:directoryToOpen file:fileToPreselect] )
1.1       root      541:        {
                    542:                // Get the path to the selected file
                    543:                NSString *path = [savePanel filename];
1.1.1.6 ! root      544: 
1.1       root      545:                // Store the path in the user settings
                    546:                GuiOsx_ExportPathString(path, ConfigureParams.Memory.szMemoryCaptureFileName, sizeof(ConfigureParams.Memory.szMemoryCaptureFileName));
1.1.1.6 ! root      547:                
1.1       root      548:                // Perform the memory snapshot save
1.1.1.2   root      549:                MemorySnapShot_Capture(ConfigureParams.Memory.szMemoryCaptureFileName, TRUE);
1.1.1.6 ! root      550:        }
1.1       root      551: 
1.1.1.5   root      552:        GuiOsx_Resume();
1.1       root      553: }
                    554: 
                    555: - (IBAction)restoreMemorySnap:(id)sender
                    556: {
1.1.1.5   root      557:        GuiOsx_Pause();
1.1       root      558: 
                    559:        // Create and configure an OpenPanel
1.1.1.6 ! root      560:        NSOpenPanel *openPanel = [NSOpenPanel openPanel];
1.1       root      561: 
                    562:        // Get the path from the user settings
1.1.1.6 ! root      563:        NSString *oldPath = [NSString stringWithCString:(ConfigureParams.Memory.szMemoryCaptureFileName) encoding:NSASCIIStringEncoding];
1.1       root      564: 
                    565:        // Determine the directory and filename
                    566:        NSString *directoryToOpen;
                    567:        NSString *fileToPreselect;
                    568:        if ((oldPath != nil) && ([oldPath length] > 0))
                    569:        {
                    570:                // There is existing path: we will open its directory with its file pre-selected.
                    571:                directoryToOpen = [oldPath stringByDeletingLastPathComponent];
                    572:                fileToPreselect = [oldPath lastPathComponent];
                    573:        }
                    574:        else
                    575:        {
                    576:                // Currently no path: we will open the user's directory with no file selected.
                    577:                directoryToOpen = [@"~" stringByExpandingTildeInPath];
                    578:                fileToPreselect = nil;
                    579:        }
1.1.1.6 ! root      580: 
1.1       root      581:        // Run the OpenPanel, then check if the user clicked OK and selected at least one file
1.1.1.6 ! root      582:        if ( (NSOKButton == [openPanel runModalForDirectory:directoryToOpen file:fileToPreselect types:nil] )
1.1       root      583:            && ([[openPanel filenames] count] > 0) )
                    584:        {
                    585:                // Get the path to the selected file
                    586:                NSString *path = [[openPanel filenames] objectAtIndex:0];
                    587:                
                    588:                // Perform the memory snapshot load
1.1.1.6 ! root      589:                MemorySnapShot_Restore([path cStringUsingEncoding:NSASCIIStringEncoding], TRUE);
        !           590:        }
        !           591: 
1.1.1.5   root      592:        GuiOsx_Resume();
1.1       root      593: }
                    594: 
                    595: - (IBAction)doFullScreen:(id)sender
                    596: {
                    597:        // 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.
                    598:        // Therefore we simulate the fullscreen key press instead
                    599:        
                    600:        SDL_KeyboardEvent event;
1.1.1.6 ! root      601:        event.type = SDL_KEYDOWN;
        !           602:        event.which = 0;
        !           603:        event.state = SDL_PRESSED;
        !           604:        event.keysym.sym = SDLK_F11;
        !           605:        SDL_PushEvent((SDL_Event*)&event);      // Send the F11 key press
        !           606:        event.type = SDL_KEYUP;
        !           607:        event.state = SDL_RELEASED;
        !           608:        SDL_PushEvent((SDL_Event*)&event);      // Send the F11 key release
1.1       root      609: }
                    610: 
                    611: - (IBAction)help:(id)sender
                    612: {
1.1.1.6 ! root      613:        [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://hatari.berlios.de/docs.html"]];
1.1       root      614: }
                    615: 
                    616: 
1.1.1.6 ! root      617: - (IBAction)openConfig:(id)sender {
1.1       root      618: }
                    619: 
1.1.1.6 ! root      620: - (IBAction)saveConfig:(id)sender {
1.1       root      621: }
                    622: 
                    623: @end
                    624: 
                    625: 
                    626: @implementation NSString (ReplaceSubString)
                    627: 
                    628: - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
                    629: {
                    630:     unsigned int bufferSize;
                    631:     unsigned int selfLen = [self length];
                    632:     unsigned int aStringLen = [aString length];
                    633:     unichar *buffer;
                    634:     NSRange localRange;
                    635:     NSString *result;
                    636: 
                    637:     bufferSize = selfLen + aStringLen - aRange.length;
1.1.1.6 ! root      638:     buffer = (unichar *)NSAllocateMemoryPages(bufferSize*sizeof(unichar));
1.1       root      639:     
                    640:     /* Get first part into buffer */
                    641:     localRange.location = 0;
                    642:     localRange.length = aRange.location;
                    643:     [self getCharacters:buffer range:localRange];
                    644:     
                    645:     /* Get middle part into buffer */
                    646:     localRange.location = 0;
                    647:     localRange.length = aStringLen;
                    648:     [aString getCharacters:(buffer+aRange.location) range:localRange];
                    649:      
                    650:     /* Get last part into buffer */
                    651:     localRange.location = aRange.location + aRange.length;
                    652:     localRange.length = selfLen - localRange.location;
                    653:     [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
                    654:     
                    655:     /* Build output string */
                    656:     result = [NSString stringWithCharacters:buffer length:bufferSize];
                    657:     
                    658:     NSDeallocateMemoryPages(buffer, bufferSize);
                    659:     
                    660:     return result;
                    661: }
                    662: 
                    663: @end
                    664: 
                    665: 
                    666: 
                    667: #ifdef main
                    668: #  undef main
                    669: #endif
                    670: 
                    671: 
                    672: /* Main entry point to executable - should *not* be SDL_main! */
                    673: int main (int argc, char **argv)
                    674: {
                    675:     /* Copy the arguments into a global variable */
                    676:     /* This is passed if we are launched by double-clicking */
                    677:     if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
1.1.1.6 ! root      678:         gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
        !           679:         gArgv[0] = argv[0];
        !           680:         gArgv[1] = NULL;
1.1       root      681:         gArgc = 1;
1.1.1.6 ! root      682:         gFinderLaunch = YES;
1.1       root      683:     } else {
1.1.1.6 ! root      684:         int i;
1.1       root      685:         gArgc = argc;
1.1.1.6 ! root      686:         gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
        !           687:         for (i = 0; i <= argc; i++)
        !           688:             gArgv[i] = argv[i];
        !           689:         gFinderLaunch = NO;
1.1       root      690:     }
                    691: 
1.1.1.6 ! root      692: #if SDL_USE_NIB_FILE
        !           693:     NSApplicationMain (argc, argv);
        !           694: #else
        !           695:     CustomApplicationMain (argc, argv);
        !           696: #endif
1.1       root      697:     return 0;
                    698: }
1.1.1.6 ! root      699: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.