|
|
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.7 root 21: #include "screen.h"
22: #include "PrefsController.h"
23: #include "Shared.h"
1.1.1.6 root 24: #include "video.h"
25: #include "avi_record.h"
1.1.1.7 root 26: #include "../debug/debugui.h"
27: #include "clocks_timings.h"
1.1.1.10! root 28: #include "change.h"
1.1.1.6 root 29:
30: // for Hatari
31:
32:
33: /* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
34: but the method still is there and works. To avoid warnings, we declare
35: it ourselves here. */
36: @interface NSApplication(SDL_Missing_Methods)
37: - (void)setAppleMenu:(NSMenu *)menu;
38: @end
39:
40: /* Use this flag to determine whether we use SDLMain.nib or not */
41: #define SDL_USE_NIB_FILE 1
42:
43: /* Use this flag to determine whether we use CPS (docking) or not */
44: #define SDL_USE_CPS 1
45: #ifdef SDL_USE_CPS
46: /* Portions of CPS.h */
47: typedef struct CPSProcessSerNum
48: {
49: UInt32 lo;
50: UInt32 hi;
51: } CPSProcessSerNum;
52:
53: extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
54: extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
55: extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
56:
57: #endif /* SDL_USE_CPS */
1.1 root 58:
59: static int gArgc;
60: static char **gArgv;
61: static BOOL gFinderLaunch;
1.1.1.6 root 62: static BOOL gCalledAppMainline = FALSE;
63:
64: static NSString *getApplicationName(void)
65: {
66: const NSDictionary *dict;
67: NSString *appName = 0;
1.1 root 68:
1.1.1.6 root 69: /* Determine the application name */
70: dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
71: if (dict)
72: appName = [dict objectForKey: @"CFBundleName"];
73:
74: if (![appName length])
75: appName = [[NSProcessInfo processInfo] processName];
76:
77: return appName;
78: }
79:
80: #if SDL_USE_NIB_FILE
81: /* A helper category for NSString */
82: @interface NSString (ReplaceSubString)
83: - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
1.1 root 84: @end
1.1.1.6 root 85: #endif
1.1 root 86:
1.1.1.6 root 87: @interface NSApplication (SDLApplication)
88: @end
89:
90: @implementation NSApplication (SDLApplication)
1.1 root 91: /* Invoked from the Quit menu item */
92: - (void)terminate:(id)sender
93: {
94: /* Post a SDL_QUIT event */
95: SDL_Event event;
96: event.type = SDL_QUIT;
97: SDL_PushEvent(&event);
98: }
99: @end
100:
101: /* The main class of the application, the application's delegate */
102: @implementation SDLMain
103:
1.1.1.7 root 104:
1.1.1.6 root 105: /* Set the working directory to the .app's parent directory */
106: - (void) setupWorkingDirectory:(BOOL)shouldChdir
107: {
108: if (shouldChdir)
109: {
110: char parentdir[MAXPATHLEN];
111: CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
112: CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
113: if (CFURLGetFileSystemRepresentation(url2, 1, (UInt8 *)parentdir, MAXPATHLEN)) {
114: chdir(parentdir); /* chdir to the binary app's parent */
115: }
116: CFRelease(url);
117: CFRelease(url2);
118: }
119: }
120:
121: #if SDL_USE_NIB_FILE
122:
123: /* Fix menu to contain the real app name instead of "SDL App" */
124: - (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
125: {
126: NSRange aRange;
127: NSEnumerator *enumerator;
128: NSMenuItem *menuItem;
129:
130: aRange = [[aMenu title] rangeOfString:@"SDL App"];
131: if (aRange.length != 0)
132: [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
133:
134: enumerator = [[aMenu itemArray] objectEnumerator];
135: while ((menuItem = [enumerator nextObject]))
136: {
137: aRange = [[menuItem title] rangeOfString:@"SDL App"];
138: if (aRange.length != 0)
139: [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
140: if ([menuItem hasSubmenu])
141: [self fixMenu:[menuItem submenu] withAppName:appName];
142: }
143: }
144:
145: #else
146:
147: static void setApplicationMenu(void)
148: {
149: /* warning: this code is very odd */
150: NSMenu *appleMenu;
151: NSMenuItem *menuItem;
152: NSString *title;
153: NSString *appName;
154:
155: appName = getApplicationName();
156: appleMenu = [[NSMenu alloc] initWithTitle:@""];
157:
158: /* Add menu items */
159: title = [@"About " stringByAppendingString:appName];
160: [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
161:
162: [appleMenu addItem:[NSMenuItem separatorItem]];
163:
164: title = [@"Hide " stringByAppendingString:appName];
165: [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
166:
167: menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
168: [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
169:
170: [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
171:
172: [appleMenu addItem:[NSMenuItem separatorItem]];
173:
174: title = [@"Quit " stringByAppendingString:appName];
175: [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
176:
177:
178: /* Put menu into the menubar */
179: menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
180: [menuItem setSubmenu:appleMenu];
181: [[NSApp mainMenu] addItem:menuItem];
182:
183: /* Tell the application object that this is now the application menu */
184: [NSApp setAppleMenu:appleMenu];
185:
186: /* Finally give up our references to the objects */
187: [appleMenu release];
188: [menuItem release];
189: }
190:
191: /* Create a window menu */
192: static void setupWindowMenu(void)
193: {
194: NSMenu *windowMenu;
195: NSMenuItem *windowMenuItem;
196: NSMenuItem *menuItem;
197:
198: windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
199:
200: /* "Minimize" item */
201: menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
202: [windowMenu addItem:menuItem];
203: [menuItem release];
204:
205: /* Put menu into the menubar */
206: windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
207: [windowMenuItem setSubmenu:windowMenu];
208: [[NSApp mainMenu] addItem:windowMenuItem];
209:
210: /* Tell the application object that this is now the window menu */
211: [NSApp setWindowsMenu:windowMenu];
212:
213: /* Finally give up our references to the objects */
214: [windowMenu release];
215: [windowMenuItem release];
216: }
217:
218: /* Replacement for NSApplicationMain */
219: static void CustomApplicationMain (int argc, char **argv)
220: {
221: NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
222: SDLMain *sdlMain;
223:
224: /* Ensure the application object is initialised */
225: [NSApplication sharedApplication];
226:
227: #ifdef SDL_USE_CPS
228: {
229: CPSProcessSerNum PSN;
230: /* Tell the dock about us */
231: if (!CPSGetCurrentProcess(&PSN))
232: if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
233: if (!CPSSetFrontProcess(&PSN))
234: [NSApplication sharedApplication];
235: }
236: #endif /* SDL_USE_CPS */
237:
238: /* Set up the menubar */
239: [NSApp setMainMenu:[[NSMenu alloc] init]];
240: setApplicationMenu();
241: setupWindowMenu();
242:
243: /* Create SDLMain and make it the app delegate */
244: sdlMain = [[SDLMain alloc] init];
245: [NSApp setDelegate:sdlMain];
246:
247: /* Start the main event loop */
248: [NSApp run];
249:
250: [sdlMain release];
251: [pool release];
252: }
253:
254: #endif
255:
256:
257: /*
258: * Catch document open requests...this lets us notice files when the app
259: * was launched by double-clicking a document, or when a document was
260: * dragged/dropped on the app's icon. You need to have a
261: * CFBundleDocumentsType section in your Info.plist to get this message,
262: * apparently.
263: *
264: * Files are added to gArgv, so to the app, they'll look like command line
265: * arguments. Previously, apps launched from the finder had nothing but
266: * an argv[0].
267: *
268: * This message may be received multiple times to open several docs on launch.
269: *
270: * This message is ignored once the app's mainline has been called.
271: */
272: - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
273: {
274: const char *temparg;
275: size_t arglen;
276: char *arg;
277: char **newargv;
278:
279: if (!gFinderLaunch) /* MacOS is passing command line args. */
280: return FALSE;
281:
282: if (gCalledAppMainline) /* app has started, ignore this document. */
283: return FALSE;
284:
285: temparg = [filename UTF8String];
286: arglen = SDL_strlen(temparg) + 1;
287: arg = (char *) SDL_malloc(arglen);
288: if (arg == NULL)
289: return FALSE;
290:
291: newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
292: if (newargv == NULL)
293: {
294: SDL_free(arg);
295: return FALSE;
296: }
297: gArgv = newargv;
298:
299: SDL_strlcpy(arg, temparg, arglen);
300: gArgv[gArgc++] = arg;
301: gArgv[gArgc] = NULL;
302: return TRUE;
303: }
304:
305:
306: /* Called when the internal event loop has just started running */
307: - (void) applicationDidFinishLaunching: (NSNotification *) note
308: {
309: int status;
310:
311: /* Set the working directory to the .app's parent directory */
312: [self setupWorkingDirectory:gFinderLaunch];
313:
314: #if SDL_USE_NIB_FILE
315: /* Set the main menu to contain the real app name instead of "SDL App" */
316: [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
317: #endif
318:
319: /* Hand off to main application code */
320: gCalledAppMainline = TRUE;
321: status = SDL_main (gArgc, gArgv);
322:
323: /* We're done, thank you for playing */
324: exit(status);
325: }
326:
327: // Hatari Stuff
1.1 root 328: - (IBAction)prefsMenu:(id)sender
329: {
330: static int in_propdialog = 0;
1.1.1.6 root 331:
1.1 root 332: if (in_propdialog)
333: return;
334: ++in_propdialog;
1.1.1.6 root 335: Dialog_DoProperty();
1.1 root 336: --in_propdialog;
337: }
338:
1.1.1.9 root 339: - (IBAction) openPreferences:(id)sender
340: {
341: [[PrefsController prefs] loadPrefs:sender];
342: }
343:
344:
1.1.1.6 root 345: - (IBAction)debugUI:(id)sender
346: {
1.1.1.8 root 347: DebugUI(REASON_USER);
1.1.1.6 root 348: }
349:
1.1 root 350: - (IBAction)warmReset:(id)sender
351: {
352: int b;
1.1.1.6 root 353:
354: b = NSRunAlertPanel (
355: NSLocalizedStringFromTable(@"Warm reset",@"Localizable",@"comment"),
356: NSLocalizedStringFromTable(@"Really reset the emulator?",@"Localizable",@"comment"),
357: NSLocalizedStringFromTable(@"OK",@"Localizable",@"comment"),
358: NSLocalizedStringFromTable(@"Cancel",@"Localizable",@"comment"), nil);
1.1 root 359: //printf("b=%i\n",b);
360: if (b == 1)
361: Reset_Warm();
1.1.1.10! root 362: }
1.1 root 363:
364: - (IBAction)coldReset:(id)sender
365: {
366: int b;
1.1.1.6 root 367:
368: b = NSRunAlertPanel (
369: NSLocalizedStringFromTable(@"Cold reset!",@"Localizable",@"comment"),
370: NSLocalizedStringFromTable(@"Really reset the emulator?",@"Localizable",@"comment") ,
371: NSLocalizedStringFromTable(@"OK",@"Localizable",@"comment"),
372: NSLocalizedStringFromTable(@"Cancel",@"Localizable",@"comment"), nil);
1.1 root 373: //printf("b=%i\n",b);
374: if (b == 1)
375: Reset_Cold();
376: }
377:
378: - (IBAction)insertDiskA:(id)sender
379: {
1.1.1.6 root 380: NSString *path = nil;
381: NSOpenPanel *openPanel = [ NSOpenPanel openPanel ];
382:
383: if ( [ openPanel runModalForDirectory:nil
384: file:@"SavedGame" types:nil ] )
385: {
386: path = [ [ openPanel filenames ] objectAtIndex:0 ];
387: }
388:
1.1 root 389: if (path != nil)
390: {
391: // Make a non-const C string out of it
1.1.1.6 root 392: const char* constSzPath = [path cStringUsingEncoding:NSASCIIStringEncoding];
1.1 root 393: size_t cbPath = strlen(constSzPath) + 1;
394: char szPath[cbPath];
1.1.1.6 root 395: strncpy(szPath, constSzPath, cbPath);
1.1.1.3 root 396:
397: Floppy_SetDiskFileName(0, szPath, NULL);
398: Floppy_InsertDiskIntoDrive(0);
1.1 root 399: }
400: }
401:
402: - (IBAction)insertDiskB:(id)sender
403: {
1.1.1.6 root 404: NSString *path = nil;
405: NSOpenPanel *openPanel = [ NSOpenPanel openPanel ];
406:
407: if ( [ openPanel runModalForDirectory:nil
408: file:@"SavedGame" types:nil ] )
409: {
410: path = [ [ openPanel filenames ] objectAtIndex:0 ];
411: }
412:
1.1 root 413: if (path != nil)
414: {
415: // Make a non-const C string out of it
1.1.1.6 root 416: const char* constSzPath = [path cStringUsingEncoding:NSASCIIStringEncoding];
1.1 root 417: size_t cbPath = strlen(constSzPath) + 1;
418: char szPath[cbPath];
419: strncpy(szPath, constSzPath, cbPath);
1.1.1.6 root 420:
1.1.1.3 root 421: Floppy_SetDiskFileName(1, szPath, NULL);
422: Floppy_InsertDiskIntoDrive(1);
1.1 root 423: }
424: }
425:
426: /*-----------------------------------------------------------------------*/
427: /*
1.1.1.6 root 428: Controls the enabled state of the menu items
429: */
1.1 root 430: - (BOOL)validateMenuItem:(NSMenuItem*)item
431: {
432: if (item == beginCaptureAnim)
433: {
1.1.1.6 root 434: return !Avi_AreWeRecording();
1.1 root 435: }
436: if (item == endCaptureAnim)
437: {
1.1.1.6 root 438: return Avi_AreWeRecording();
1.1 root 439: }
440: if (item == beginCaptureSound)
441: {
442: return !Sound_AreWeRecording();
443: }
444: if (item == endCaptureSound)
445: {
446: return Sound_AreWeRecording();
447: }
448:
449: return YES;
450: }
451:
1.1.1.7 root 452: - (NSString*)displayFileSelection:(const char*)pathInParams preferredFileName:(NSString*)preferredFileName allowedExtensions:(NSArray*)allowedExtensions
1.1 root 453: {
1.1.1.7 root 454:
1.1 root 455: // Get the path from the user settings
1.1.1.7 root 456: NSString *preferredPath = [[NSString stringWithCString:(pathInParams) encoding:NSASCIIStringEncoding] stringByAbbreviatingWithTildeInPath];
457:
1.1 root 458: // Determine the directory and filename
459: NSString *directoryToOpen;
460: NSString *fileToPreselect;
461: if ((preferredPath != nil) && ([preferredPath length] > 0))
462: {
463: // There is existing path: we will open its directory with its file pre-selected.
464: directoryToOpen = [preferredPath stringByDeletingLastPathComponent];
465: fileToPreselect = [preferredPath lastPathComponent];
466: }
467: else
468: {
469: // Currently no path: we will open the user's directory with no file selected.
470: directoryToOpen = [@"~" stringByExpandingTildeInPath];
1.1.1.7 root 471: fileToPreselect = preferredFileName;
1.1 root 472: }
1.1.1.7 root 473:
1.1 root 474: // Create and configure a SavePanel for choosing what file to write
475: NSSavePanel *savePanel = [NSSavePanel savePanel];
1.1.1.7 root 476: [savePanel setAllowedFileTypes:allowedExtensions];
1.1 root 477: [savePanel setExtensionHidden:NO];
1.1.1.7 root 478: NSString* extensionList = [allowedExtensions componentsJoinedByString:@" or a ."];
1.1 root 479:
1.1.1.7 root 480: [savePanel setMessage:[NSString stringWithFormat:@"Please specify a .%@ file",extensionList]]; // TODO: Move to localizable resources
1.1 root 481: // Run the SavePanel, then check if the user clicked OK and selected at least one file
1.1.1.6 root 482: if (NSFileHandlingPanelOKButton == [savePanel runModalForDirectory:directoryToOpen file:fileToPreselect] )
1.1.1.7 root 483: return [[savePanel URL] path];
484: return nil;
485: }
486:
487: - (IBAction)captureScreen:(id)sender
488: {
489: GuiOsx_Pause();
490: ScreenSnapShot_SaveScreen();
491: GuiOsx_Resume();
492: }
493:
494: - (IBAction)captureAnimation:(id)sender
495: {
496: GuiOsx_Pause();
497: if(!Avi_AreWeRecording()) {
498: NSString* path = [self displayFileSelection:ConfigureParams.Video.AviRecordFile preferredFileName:@"hatari.avi"
499: allowedExtensions:[NSArray arrayWithObjects:@"avi", nil]];
1.1 root 500:
1.1.1.7 root 501: if(path) {
502: GuiOsx_ExportPathString(path, ConfigureParams.Video.AviRecordFile, sizeof(ConfigureParams.Video.AviRecordFile));
503: Avi_StartRecording ( ConfigureParams.Video.AviRecordFile , ConfigureParams.Screen.bCrop ,
504: ConfigureParams.Video.AviRecordFps == 0 ?
505: ClocksTimings_GetVBLPerSec ( ConfigureParams.System.nMachineType , nScreenRefreshRate ) :
506: (Uint32)ConfigureParams.Video.AviRecordFps << CLOCKS_TIMINGS_SHIFT_VBL ,
507: 1 << CLOCKS_TIMINGS_SHIFT_VBL ,
508: ConfigureParams.Video.AviRecordVcodec );
509: }
1.1.1.6 root 510:
1.1.1.7 root 511: } else {
512: Avi_StopRecording();
1.1.1.6 root 513: }
1.1.1.7 root 514: GuiOsx_Resume();
515: }
1.1 root 516:
1.1.1.7 root 517: - (IBAction)endCaptureAnimation:(id)sender
518: {
519: //?
520: }
521:
522: - (IBAction)captureSound:(id)sender
523: {
524: GuiOsx_Pause();
525: NSString* path = [self displayFileSelection:ConfigureParams.Sound.szYMCaptureFileName preferredFileName:@"hatari.wav"
526: allowedExtensions:[NSArray arrayWithObjects:@"ym", @"wav", nil]];
527: if(path) {
528: GuiOsx_ExportPathString(path, ConfigureParams.Sound.szYMCaptureFileName, sizeof(ConfigureParams.Sound.szYMCaptureFileName));
529: Sound_BeginRecording(ConfigureParams.Sound.szYMCaptureFileName);
530: }
1.1.1.5 root 531: GuiOsx_Resume();
1.1 root 532: }
533:
534: - (IBAction)endCaptureSound:(id)sender
535: {
1.1.1.5 root 536: GuiOsx_Pause();
1.1 root 537: Sound_EndRecording();
1.1.1.5 root 538: GuiOsx_Resume();
1.1 root 539: }
540:
541: - (IBAction)saveMemorySnap:(id)sender
542: {
1.1.1.5 root 543: GuiOsx_Pause();
1.1 root 544:
1.1.1.7 root 545: NSString* path = [self displayFileSelection:ConfigureParams.Memory.szMemoryCaptureFileName preferredFileName:@"hatari.sav"
546: allowedExtensions:[NSArray arrayWithObjects:@"sav",nil]];
547: if(path) {
1.1 root 548: GuiOsx_ExportPathString(path, ConfigureParams.Memory.szMemoryCaptureFileName, sizeof(ConfigureParams.Memory.szMemoryCaptureFileName));
1.1.1.2 root 549: MemorySnapShot_Capture(ConfigureParams.Memory.szMemoryCaptureFileName, TRUE);
1.1.1.6 root 550: }
1.1.1.7 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:
1.1.1.9 root 611:
1.1 root 612: - (IBAction)help:(id)sender
613: {
1.1.1.10! root 614: NSString *l_aide ;
! 615:
! 616: l_aide = [[NSBundle mainBundle] pathForResource:@"manual" ofType:@"html" inDirectory:@"AideHatari"] ;
! 617:
! 618: if (![[NSWorkspace sharedWorkspace] openFile:l_aide withApplication:@"HelpViewer"])
! 619: if (![[NSWorkspace sharedWorkspace] openFile:l_aide withApplication:@"Help Viewer"])
! 620: [[NSWorkspace sharedWorkspace] openFile:l_aide] ;
1.1 root 621: }
622:
1.1.1.10! root 623: - (IBAction)compat:(id)sender
! 624: {
! 625: NSString *C_aide ;
! 626:
! 627: C_aide = [[NSBundle mainBundle] pathForResource:@"compatibility" ofType:@"html" inDirectory:@"AideHatari"] ;
! 628:
! 629: if (![[NSWorkspace sharedWorkspace] openFile:C_aide withApplication:@"HelpViewer"])
! 630: if (![[NSWorkspace sharedWorkspace] openFile:C_aide withApplication:@"Help Viewer"])
! 631: [[NSWorkspace sharedWorkspace] openFile:C_aide] ;
! 632: }
1.1 root 633:
1.1.1.9 root 634: - (IBAction)openConfig:(id)sender
635: {
636: BOOL applyChanges = true;
637: NSString *ConfigFile = [NSString stringWithCString:(sConfigFileName) encoding:NSASCIIStringEncoding];
638: NSOpenPanel *openPanel = [ NSOpenPanel openPanel ];
639:
640: CNF_PARAMS CurrentParams;
641:
642:
643: // Backup of configuration settings to CurrentParams (which we will only
644: // commit back to the configuration settings if choosing user confirm)
645: CurrentParams = ConfigureParams;
646:
647: GuiOsx_Pause();
648:
649: if ( [ openPanel runModalForDirectory:nil file:ConfigFile types:nil ] )
650: {
651: ConfigFile = [ [ openPanel filenames ] objectAtIndex:0 ];
652: }
653: else
654: {
655: ConfigFile = nil;
656: }
657:
658: //[openPanel release];
659:
660: if (ConfigFile != nil)
661: {
662: // Make a non-const C string out of it
663: const char* constSzPath = [ConfigFile cStringUsingEncoding:NSASCIIStringEncoding];
664: size_t cbPath = strlen(constSzPath) + 1;
665: char szPath[cbPath];
666: strncpy(szPath, constSzPath, cbPath);
667:
668: // Load the config into ConfigureParams
669: Configuration_Load(szPath);
670: strcpy(sConfigFileName,szPath);
671: // Refresh all the controls to match ConfigureParams
672:
673: if (Change_DoNeedReset(&CurrentParams, &ConfigureParams))
674: {
675: applyChanges = ( 0 == NSRunAlertPanel (
676: NSLocalizedStringFromTable(@"Reset the emulator",@"Localizable",@"comment"),
677: NSLocalizedStringFromTable(@"Must be reset",@"Localizable",@"comment"),
678: NSLocalizedStringFromTable(@"Don't reset",@"Localizable",@"comment"),
679: NSLocalizedStringFromTable(@"Reset",@"Localizable",@"comment"), nil) );
680: }
681:
682: // Commit the new configuration
683: if (applyChanges)
684: {
1.1.1.10! root 685: Change_CopyChangedParamsToConfiguration(&CurrentParams, &ConfigureParams, true);
1.1.1.9 root 686: }
687: else
688: {
689: ConfigureParams = CurrentParams;
690: }
691:
692:
693: }
694:
695: GuiOsx_Resume();
696: //[ConfigFile release];
1.1 root 697: }
698:
1.1.1.9 root 699:
1.1.1.6 root 700: - (IBAction)saveConfig:(id)sender {
1.1 root 701: }
702:
703: @end
704:
705:
706: @implementation NSString (ReplaceSubString)
707:
708: - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
709: {
710: unsigned int bufferSize;
711: unsigned int selfLen = [self length];
712: unsigned int aStringLen = [aString length];
713: unichar *buffer;
714: NSRange localRange;
715: NSString *result;
716:
717: bufferSize = selfLen + aStringLen - aRange.length;
1.1.1.6 root 718: buffer = (unichar *)NSAllocateMemoryPages(bufferSize*sizeof(unichar));
1.1 root 719:
720: /* Get first part into buffer */
721: localRange.location = 0;
722: localRange.length = aRange.location;
723: [self getCharacters:buffer range:localRange];
724:
725: /* Get middle part into buffer */
726: localRange.location = 0;
727: localRange.length = aStringLen;
728: [aString getCharacters:(buffer+aRange.location) range:localRange];
729:
730: /* Get last part into buffer */
731: localRange.location = aRange.location + aRange.length;
732: localRange.length = selfLen - localRange.location;
733: [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
734:
735: /* Build output string */
736: result = [NSString stringWithCharacters:buffer length:bufferSize];
737:
738: NSDeallocateMemoryPages(buffer, bufferSize);
739:
740: return result;
741: }
742:
743: @end
744:
745:
746:
747: #ifdef main
748: # undef main
749: #endif
750:
751:
752: /* Main entry point to executable - should *not* be SDL_main! */
753: int main (int argc, char **argv)
754: {
755: /* Copy the arguments into a global variable */
756: /* This is passed if we are launched by double-clicking */
757: if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
1.1.1.6 root 758: gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
759: gArgv[0] = argv[0];
760: gArgv[1] = NULL;
1.1 root 761: gArgc = 1;
1.1.1.6 root 762: gFinderLaunch = YES;
1.1 root 763: } else {
1.1.1.6 root 764: int i;
1.1 root 765: gArgc = argc;
1.1.1.6 root 766: gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
767: for (i = 0; i <= argc; i++)
768: gArgv[i] = argv[i];
769: gFinderLaunch = NO;
1.1 root 770: }
771:
1.1.1.6 root 772: #if SDL_USE_NIB_FILE
1.1.1.7 root 773: NSApplicationMain (argc, (const char**)argv);
1.1.1.6 root 774: #else
775: CustomApplicationMain (argc, argv);
776: #endif
1.1 root 777: return 0;
778: }
1.1.1.6 root 779:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.