SDL_main issues on Mac OS X

SDL’s stomping all over my main function has been a recurring annoyance
for me. It’s particularly hard to deal with when I don’t have control
over main - such as when most of my code is not written in C.

On OS X, SDL’s main does some initialization, does [NSApp run], and
then catches control flow again through the
applicationDidFinishLaunching method. It then calls the user’s main.
When that returns, it exits.

I’ve rewritten this so that rather than calling [NSApp run], it calls
[NSApp finishLaunching];
[NSApp updateWindows];
[NSApp activateIgnoringOtherApps: YES];

In this way, we never lose control flow to begin with, and so this
initalization stuff can be called via a regular function (from
SDL_Init), and there would be no need to hijack my program’s entry
point.

I’ve implemented this and it works just fine on my system, but I don’t
really know anything about Cocoa or Objective C so it would be nice if
someone who does could comment on this approach. Why does SDL not
already do it this way?

There is one thing I’m not able to figure out:
I can’t release the memory pool I created. I try to do it from
SDL_Quit, but my program crashes when I do. Of course, in SDL’s current
implementation, the memory pool isn’t released either. The code to do
it is there, but that code is never reached. exit() is called from
within applicationDidFinishLaunching.

Thanks,

Mike Benfield

SDL’s stomping all over my main function has been a recurring annoyance
for me. It’s particularly hard to deal with when I don’t have control
over main - such as when most of my code is not written in C.

I?m facing the same problem while using SDL with D (on Mac OS X), and
found your post while looking for a solution.

On OS X, SDL’s main does some initialization, does [NSApp run], and
then catches control flow again through the
applicationDidFinishLaunching method. It then calls the user’s main.
When that returns, it exits.

I’ve rewritten this so that rather than calling [NSApp run], it calls
[NSApp finishLaunching];
[NSApp updateWindows];
[NSApp activateIgnoringOtherApps: YES];

In this way, we never lose control flow to begin with, and so this
initalization stuff can be called via a regular function (from
SDL_Init), and there would be no need to hijack my program’s entry
point.

I’ve implemented this and it works just fine on my system, but I don’t
really know anything about Cocoa or Objective C so it would be nice if
someone who does could comment on this approach. Why does SDL not
already do it this way?

I tried your solution and it works, but it gives a slightly different
result than the ?standard? way. If the application is hidden by choosing
Hide in the menu, when switching back to it, the window doesn?t come to
the foreground (depending on the current active application). There is
maybe some code in the run method before finishLaunching that normally
handles this.

I found another method. The code still calls [NSApp run], but in
applicationDidFinishLaunching, instead of launching the user’s main()
function it calls [NSApp stop:nil]. This stops the main loop. The result
is the same as with your solution but everything seems to be correctly
initialized. The application behaves exactly as with the original
SDLmain code.

With this is mind, why wouldn’t that code be included into SDL directly
(e.g. in SDL_Init())? Actually, the SDLmain code doesn’t only handle
proper Cocoa initialization. It also uses the contents of the command
line (argc & argv) to find out if the application was launched by the
Finder. Finally, it creates new argc and argv variables that it passes
to the user?s main() function. Those new arguments contain the names of
the files that the application is supposed to open because they have
been dropped on the application icon or have been opened in the Finder
after having been associated with the application.

For the next version of SDL, the initialization function could maybe
take argc and argv as arguments and allow arguments as file open
requests to be retrieved in a platform-independent manner (e.g. as an
event)?

There is one thing I’m not able to figure out:
I can’t release the memory pool I created. I try to do it from
SDL_Quit, but my program crashes when I do. Of course, in SDL’s current
implementation, the memory pool isn’t released either. The code to do
it is there, but that code is never reached. exit() is called from
within applicationDidFinishLaunching.

This problem seems to have disappeared with newer SDL revisions (it
works with 1.2.13).

Hugues De KeyzerOn 2005-08-23, Michael Benfield wrote:


The only constant in life is change
www.wikipedia.org