ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/SDL/SDLMain.m
Revision: 1.1
Committed: 2009-03-03T08:04:42Z (15 years, 8 months ago) by asvitkine
Branch: MAIN
Log Message:
[patch by Mike Sliczniak]

Here is a patch to allow compiling of SS and B2 with an SDL Framework. You can
get this by downloading from:

http://www.libsdl.org/release/SDL-1.2.13.dmg

Here is how I tested on an intel 32-bit mac with Mac OS X 10.5.6:

SS ./autogen.sh --disable-standalone-gui --enable-vosf --enable-sdl-framework --enable-sdl-framework-prefix=/Users/mzs/Library/Frameworks --enable-sdl-video --disable-sdl-audio --enable-addressing=real
--without-esd --without-gtk --without-mon --without-x

SS /autogen.sh --disable-standalone-gui --enable-vosf --disable-sdl-framework --disable-sdl-video --disable-sdl-audio --enable-addressing=real --without-esd --without-gtk --without-mon --with-x

B2 ./autogen.sh --disable-standalone-gui --enable-vosf --enable-sdl-framework --enable-sdl-framework-prefix=/Users/mzs/Library/Frameworks --enable-sdl-video --enable-sdl-audio --enable-addressing=real --without-esd --without-gtk --without-mon --without-x --enable-jit-compiler

B2 ./autogen.sh --disable-standalone-gui --enable-vosf --disable-sdl-framework --disable-sdl-video --disable-sdl-audio --enable-addressing=real --with-esd --without-gtk --without-mon --with-x --enable-jit-compiler

(esound does not really work on mac, it needs some better coreaudio patches.)

configure.ac for SS has two little additional fixes so that the Cocoa prefs gui
does not get built if you are building for X11 and so that you can use esd, sdl,
or coreaudio for sound.

File Contents

# User Rev Content
1 asvitkine 1.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>
4    
5     Feel free to customize this file to suit your needs
6     */
7    
8     #import "SDL.h"
9     #import "SDLMain.h"
10     #import <sys/param.h> /* for MAXPATHLEN */
11     #import <unistd.h>
12    
13     /* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
14     but the method still is there and works. To avoid warnings, we declare
15     it ourselves here. */
16     @interface NSApplication(SDL_Missing_Methods)
17     - (void)setAppleMenu:(NSMenu *)menu;
18     @end
19    
20     /* Use this flag to determine whether we use SDLMain.nib or not */
21     #define SDL_USE_NIB_FILE 0
22    
23     /* Use this flag to determine whether we use CPS (docking) or not */
24     #define SDL_USE_CPS 1
25     #ifdef SDL_USE_CPS
26     /* Portions of CPS.h */
27     typedef struct CPSProcessSerNum
28     {
29     UInt32 lo;
30     UInt32 hi;
31     } CPSProcessSerNum;
32    
33     extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
34     extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
35     extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
36    
37     #endif /* SDL_USE_CPS */
38    
39     static int gArgc;
40     static char **gArgv;
41     static BOOL gFinderLaunch;
42     static BOOL gCalledAppMainline = FALSE;
43    
44     static NSString *getApplicationName(void)
45     {
46     NSDictionary *dict;
47     NSString *appName = 0;
48    
49     /* Determine the application name */
50     dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
51     if (dict)
52     appName = [dict objectForKey: @"CFBundleName"];
53    
54     if (![appName length])
55     appName = [[NSProcessInfo processInfo] processName];
56    
57     return appName;
58     }
59    
60     #if SDL_USE_NIB_FILE
61     /* A helper category for NSString */
62     @interface NSString (ReplaceSubString)
63     - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
64     @end
65     #endif
66    
67     @interface SDLApplication : NSApplication
68     @end
69    
70     @implementation SDLApplication
71     /* Invoked from the Quit menu item */
72     - (void)terminate:(id)sender
73     {
74     /* Post a SDL_QUIT event */
75     SDL_Event event;
76     event.type = SDL_QUIT;
77     SDL_PushEvent(&event);
78     }
79     @end
80    
81     /* The main class of the application, the application's delegate */
82     @implementation SDLMain
83    
84     /* Set the working directory to the .app's parent directory */
85     - (void) setupWorkingDirectory:(BOOL)shouldChdir
86     {
87     if (shouldChdir)
88     {
89     char parentdir[MAXPATHLEN];
90     CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
91     CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
92     if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) {
93     assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */
94     }
95     CFRelease(url);
96     CFRelease(url2);
97     }
98    
99     }
100    
101     #if SDL_USE_NIB_FILE
102    
103     /* Fix menu to contain the real app name instead of "SDL App" */
104     - (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
105     {
106     NSRange aRange;
107     NSEnumerator *enumerator;
108     NSMenuItem *menuItem;
109    
110     aRange = [[aMenu title] rangeOfString:@"SDL App"];
111     if (aRange.length != 0)
112     [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
113    
114     enumerator = [[aMenu itemArray] objectEnumerator];
115     while ((menuItem = [enumerator nextObject]))
116     {
117     aRange = [[menuItem title] rangeOfString:@"SDL App"];
118     if (aRange.length != 0)
119     [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
120     if ([menuItem hasSubmenu])
121     [self fixMenu:[menuItem submenu] withAppName:appName];
122     }
123     [ aMenu sizeToFit ];
124     }
125    
126     #else
127    
128     static void setApplicationMenu(void)
129     {
130     /* warning: this code is very odd */
131     NSMenu *appleMenu;
132     NSMenuItem *menuItem;
133     NSString *title;
134     NSString *appName;
135    
136     appName = getApplicationName();
137     appleMenu = [[NSMenu alloc] initWithTitle:@""];
138    
139     /* Add menu items */
140     title = [@"About " stringByAppendingString:appName];
141     [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
142    
143     [appleMenu addItem:[NSMenuItem separatorItem]];
144    
145     title = [@"Hide " stringByAppendingString:appName];
146     [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
147    
148     menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
149     [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
150    
151     [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
152    
153     [appleMenu addItem:[NSMenuItem separatorItem]];
154    
155     title = [@"Quit " stringByAppendingString:appName];
156     [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
157    
158    
159     /* Put menu into the menubar */
160     menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
161     [menuItem setSubmenu:appleMenu];
162     [[NSApp mainMenu] addItem:menuItem];
163    
164     /* Tell the application object that this is now the application menu */
165     [NSApp setAppleMenu:appleMenu];
166    
167     /* Finally give up our references to the objects */
168     [appleMenu release];
169     [menuItem release];
170     }
171    
172     /* Create a window menu */
173     static void setupWindowMenu(void)
174     {
175     NSMenu *windowMenu;
176     NSMenuItem *windowMenuItem;
177     NSMenuItem *menuItem;
178    
179     windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
180    
181     /* "Minimize" item */
182     menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
183     [windowMenu addItem:menuItem];
184     [menuItem release];
185    
186     /* Put menu into the menubar */
187     windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
188     [windowMenuItem setSubmenu:windowMenu];
189     [[NSApp mainMenu] addItem:windowMenuItem];
190    
191     /* Tell the application object that this is now the window menu */
192     [NSApp setWindowsMenu:windowMenu];
193    
194     /* Finally give up our references to the objects */
195     [windowMenu release];
196     [windowMenuItem release];
197     }
198    
199     /* Replacement for NSApplicationMain */
200     static void CustomApplicationMain (int argc, char **argv)
201     {
202     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
203     SDLMain *sdlMain;
204    
205     /* Ensure the application object is initialised */
206     [SDLApplication sharedApplication];
207    
208     #ifdef SDL_USE_CPS
209     {
210     CPSProcessSerNum PSN;
211     /* Tell the dock about us */
212     if (!CPSGetCurrentProcess(&PSN))
213     if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
214     if (!CPSSetFrontProcess(&PSN))
215     [SDLApplication sharedApplication];
216     }
217     #endif /* SDL_USE_CPS */
218    
219     /* Set up the menubar */
220     [NSApp setMainMenu:[[NSMenu alloc] init]];
221     setApplicationMenu();
222     setupWindowMenu();
223    
224     /* Create SDLMain and make it the app delegate */
225     sdlMain = [[SDLMain alloc] init];
226     [NSApp setDelegate:sdlMain];
227    
228     /* Start the main event loop */
229     [NSApp run];
230    
231     [sdlMain release];
232     [pool release];
233     }
234    
235     #endif
236    
237    
238     /*
239     * Catch document open requests...this lets us notice files when the app
240     * was launched by double-clicking a document, or when a document was
241     * dragged/dropped on the app's icon. You need to have a
242     * CFBundleDocumentsType section in your Info.plist to get this message,
243     * apparently.
244     *
245     * Files are added to gArgv, so to the app, they'll look like command line
246     * arguments. Previously, apps launched from the finder had nothing but
247     * an argv[0].
248     *
249     * This message may be received multiple times to open several docs on launch.
250     *
251     * This message is ignored once the app's mainline has been called.
252     */
253     - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
254     {
255     const char *temparg;
256     size_t arglen;
257     char *arg;
258     char **newargv;
259    
260     if (!gFinderLaunch) /* MacOS is passing command line args. */
261     return FALSE;
262    
263     if (gCalledAppMainline) /* app has started, ignore this document. */
264     return FALSE;
265    
266     temparg = [filename UTF8String];
267     arglen = SDL_strlen(temparg) + 1;
268     arg = (char *) SDL_malloc(arglen);
269     if (arg == NULL)
270     return FALSE;
271    
272     newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
273     if (newargv == NULL)
274     {
275     SDL_free(arg);
276     return FALSE;
277     }
278     gArgv = newargv;
279    
280     SDL_strlcpy(arg, temparg, arglen);
281     gArgv[gArgc++] = arg;
282     gArgv[gArgc] = NULL;
283     return TRUE;
284     }
285    
286    
287     /* Called when the internal event loop has just started running */
288     - (void) applicationDidFinishLaunching: (NSNotification *) note
289     {
290     int status;
291    
292     /* Set the working directory to the .app's parent directory */
293     [self setupWorkingDirectory:gFinderLaunch];
294    
295     #if SDL_USE_NIB_FILE
296     /* Set the main menu to contain the real app name instead of "SDL App" */
297     [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
298     #endif
299    
300     /* Hand off to main application code */
301     gCalledAppMainline = TRUE;
302     status = SDL_main (gArgc, gArgv);
303    
304     /* We're done, thank you for playing */
305     exit(status);
306     }
307     @end
308    
309    
310     @implementation NSString (ReplaceSubString)
311    
312     - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
313     {
314     unsigned int bufferSize;
315     unsigned int selfLen = [self length];
316     unsigned int aStringLen = [aString length];
317     unichar *buffer;
318     NSRange localRange;
319     NSString *result;
320    
321     bufferSize = selfLen + aStringLen - aRange.length;
322     buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
323    
324     /* Get first part into buffer */
325     localRange.location = 0;
326     localRange.length = aRange.location;
327     [self getCharacters:buffer range:localRange];
328    
329     /* Get middle part into buffer */
330     localRange.location = 0;
331     localRange.length = aStringLen;
332     [aString getCharacters:(buffer+aRange.location) range:localRange];
333    
334     /* Get last part into buffer */
335     localRange.location = aRange.location + aRange.length;
336     localRange.length = selfLen - localRange.location;
337     [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
338    
339     /* Build output string */
340     result = [NSString stringWithCharacters:buffer length:bufferSize];
341    
342     NSDeallocateMemoryPages(buffer, bufferSize);
343    
344     return result;
345     }
346    
347     @end
348    
349    
350    
351     #ifdef main
352     # undef main
353     #endif
354    
355    
356     /* Main entry point to executable - should *not* be SDL_main! */
357     int main (int argc, char **argv)
358     {
359     /* Copy the arguments into a global variable */
360     /* This is passed if we are launched by double-clicking */
361     if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
362     gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
363     gArgv[0] = argv[0];
364     gArgv[1] = NULL;
365     gArgc = 1;
366     gFinderLaunch = YES;
367     } else {
368     int i;
369     gArgc = argc;
370     gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
371     for (i = 0; i <= argc; i++)
372     gArgv[i] = argv[i];
373     gFinderLaunch = NO;
374     }
375    
376     #if SDL_USE_NIB_FILE
377     [SDLApplication poseAsClass:[NSApplication class]];
378     NSApplicationMain (argc, argv);
379     #else
380     CustomApplicationMain (argc, argv);
381     #endif
382     return 0;
383     }
384