C1: deny drops into black holes
[openc2e.git] / SDLMain.m
blobb6eb9c8ad680a83377a7584a0903cdfdc4542baa
1 /*   SDLMain.m - main entry point for our Cocoa-ized SDL app
2        Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
3        Non-NIB-Code & other changes: Max Horn <max@quendi.de>
5     Feel free to customize this file to suit your needs
6 */
8 #import <SDL/SDL.h>
9 #import "SDLMain.h"
10 #import <sys/param.h> /* for MAXPATHLEN */
11 #import <unistd.h>
13 /* Use this flag to determine whether we use SDLMain.nib or not */
14 #define         SDL_USE_NIB_FILE        0
17 static int    gArgc;
18 static char  **gArgv;
19 static BOOL   gFinderLaunch;
21 #if SDL_USE_NIB_FILE
22 /* A helper category for NSString */
23 @interface NSString (ReplaceSubString)
24 - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
25 @end
26 #else
27 /* An internal Apple class used to setup Apple menus */
28 @interface NSAppleMenuController:NSObject {}
29 - (void)controlMenu:(NSMenu *)aMenu;
30 @end
31 #endif
33 @interface SDLApplication : NSApplication
34 @end
36 @implementation SDLApplication
37 /* Invoked from the Quit menu item */
38 - (void)terminate:(id)sender
40     /* Post a SDL_QUIT event */
41     SDL_Event event;
42     event.type = SDL_QUIT;
43     SDL_PushEvent(&event);
45 @end
48 /* The main class of the application, the application's delegate */
49 @implementation SDLMain
51 /* Set the working directory to the .app's parent directory */
52 - (void) setupWorkingDirectory:(BOOL)shouldChdir
54     char parentdir[MAXPATHLEN];
55     char *c;
56     
57     strncpy ( parentdir, gArgv[0], sizeof(parentdir) );
58     c = (char*) parentdir;
60     while (*c != '\0')     /* go to end */
61         c++;
62     
63     while (*c != '/')      /* back up to parent */
64         c--;
65     
66     *c++ = '\0';             /* cut off last part (binary name) */
67   
68     if (shouldChdir)
69     {
70       assert ( chdir (parentdir) == 0 );   /* chdir to the binary app's parent */
71       assert ( chdir ("../../../") == 0 ); /* chdir to the .app's parent */
72     }
75 #if SDL_USE_NIB_FILE
77 /* Fix menu to contain the real app name instead of "SDL App" */
78 - (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
80     NSRange aRange;
81     NSEnumerator *enumerator;
82     NSMenuItem *menuItem;
84     aRange = [[aMenu title] rangeOfString:@"SDL App"];
85     if (aRange.length != 0)
86         [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
88     enumerator = [[aMenu itemArray] objectEnumerator];
89     while ((menuItem = [enumerator nextObject]))
90     {
91         aRange = [[menuItem title] rangeOfString:@"SDL App"];
92         if (aRange.length != 0)
93             [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
94         if ([menuItem hasSubmenu])
95             [self fixMenu:[menuItem submenu] withAppName:appName];
96     }
97     [ aMenu sizeToFit ];
100 #else
102 void setupAppleMenu(void)
104     /* warning: this code is very odd */
105     NSAppleMenuController *appleMenuController;
106     NSMenu *appleMenu;
107     NSMenuItem *appleMenuItem;
109     appleMenuController = [[NSAppleMenuController alloc] init];
110     appleMenu = [[NSMenu alloc] initWithTitle:@""];
111     appleMenuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
112     
113     [appleMenuItem setSubmenu:appleMenu];
115     /* yes, we do need to add it and then remove it --
116        if you don't add it, it doesn't get displayed
117        if you don't remove it, you have an extra, titleless item in the menubar
118        when you remove it, it appears to stick around
119        very, very odd */
120     [[NSApp mainMenu] addItem:appleMenuItem];
121     [appleMenuController controlMenu:appleMenu];
122     [[NSApp mainMenu] removeItem:appleMenuItem];
123     [appleMenu release];
124     [appleMenuItem release];
127 /* Create a window menu */
128 void setupWindowMenu(void)
130     NSMenu              *windowMenu;
131     NSMenuItem  *windowMenuItem;
132     NSMenuItem  *menuItem;
135     windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
136     
137     /* "Minimize" item */
138     menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
139     [windowMenu addItem:menuItem];
140     [menuItem release];
141     
142     /* Put menu into the menubar */
143     windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
144     [windowMenuItem setSubmenu:windowMenu];
145     [[NSApp mainMenu] addItem:windowMenuItem];
146     
147     /* Tell the application object that this is now the window menu */
148     [NSApp setWindowsMenu:windowMenu];
150     /* Finally give up our references to the objects */
151     [windowMenu release];
152     [windowMenuItem release];
155 /* Replacement for NSApplicationMain */
156 void CustomApplicationMain (argc, argv)
158     NSAutoreleasePool   *pool = [[NSAutoreleasePool alloc] init];
159     SDLMain                             *sdlMain;
161     /* Ensure the application object is initialised */
162     [SDLApplication sharedApplication];
163     
164     /* Set up the menubar */
165     [NSApp setMainMenu:[[NSMenu alloc] init]];
166     setupAppleMenu();
167         /* TODO: Disabled because breaks on tiger */
168     /* setupWindowMenu(); */
169     
170     /* Create SDLMain and make it the app delegate */
171     sdlMain = [[SDLMain alloc] init];
172     [NSApp setDelegate:sdlMain];
173     
174     /* Start the main event loop */
175     [NSApp run];
176     
177     [sdlMain release];
178     [pool release];
181 #endif
183 /* Called when the internal event loop has just started running */
184 - (void) applicationDidFinishLaunching: (NSNotification *) note
186     int status;
188     /* Set the working directory to the .app's parent directory */
189     [self setupWorkingDirectory:gFinderLaunch];
191 #if SDL_USE_NIB_FILE
192     /* Set the main menu to contain the real app name instead of "SDL App" */
193     [self fixMenu:[NSApp mainMenu] withAppName:[[NSProcessInfo processInfo] processName]];
194 #endif
196     /* Hand off to main application code */
197     status = SDL_main (gArgc, gArgv);
199     /* We're done, thank you for playing */
200     exit(status);
202 @end
205 @implementation NSString (ReplaceSubString)
207 - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
209     unsigned int bufferSize;
210     unsigned int selfLen = [self length];
211     unsigned int aStringLen = [aString length];
212     unichar *buffer;
213     NSRange localRange;
214     NSString *result;
216     bufferSize = selfLen + aStringLen - aRange.length;
217     buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
218     
219     /* Get first part into buffer */
220     localRange.location = 0;
221     localRange.length = aRange.location;
222     [self getCharacters:buffer range:localRange];
223     
224     /* Get middle part into buffer */
225     localRange.location = 0;
226     localRange.length = aStringLen;
227     [aString getCharacters:(buffer+aRange.location) range:localRange];
228      
229     /* Get last part into buffer */
230     localRange.location = aRange.location + aRange.length;
231     localRange.length = selfLen - localRange.location;
232     [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
233     
234     /* Build output string */
235     result = [NSString stringWithCharacters:buffer length:bufferSize];
236     
237     NSDeallocateMemoryPages(buffer, bufferSize);
238     
239     return result;
242 @end
246 #ifdef main
247 #  undef main
248 #endif
251 /* Main entry point to executable - should *not* be SDL_main! */
252 int main (int argc, char **argv)
255     /* Copy the arguments into a global variable */
256     int i;
257     
258     /* This is passed if we are launched by double-clicking */
259     if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
260         gArgc = 1;
261         gFinderLaunch = YES;
262     } else {
263         gArgc = argc;
264         gFinderLaunch = NO;
265     }
266     gArgv = (char**) malloc (sizeof(*gArgv) * (gArgc+1));
267     assert (gArgv != NULL);
268     for (i = 0; i < gArgc; i++)
269         gArgv[i] = argv[i];
270     gArgv[i] = NULL;
272 #if SDL_USE_NIB_FILE
273     [SDLApplication poseAsClass:[NSApplication class]];
274     NSApplicationMain (argc, argv);
275 #else
276     CustomApplicationMain (argc, argv);
277 #endif
278     return 0;