Mac OS X and SDL - no Cocoa

Hi,

As a relative newbie to Mac and SDL I’m trying to compile a program
which needs to use the libSDL as a normal C shared library without the
libSDLmain provided for Project Builder apps (as mentioned in an earlier
post)…

I’m trying to find a way to get round the missing _main problem - even
to the point of hacking configure.in to remove the Cocoa parts and make
it look more like linux - unsuccessfully …

For info the program is the wings3d application mentioned recently on
this list.

Any and all assistance much appreciated.

Rgds,
Sean

Put

#undef main

before you define the main procedure. In one of the SDL headers we put

#define main SDL_main

To insert startup code in the real main which then calls SDL_main to
start your program.

If you choose to do this, you must understand that you lose the Mac OS
"face" on the application. It will have no dock icon, and will have to
be launched from the command line. For these reasons I recommend
avoiding this change if at all possible.

Also remember you can statically link libsdlmain.a so that libSDL is the
only runtime dependency. Our revised sdlmain code does not require a
.app bundle or various other standard resources, so the app will work as
a stand-alone binary or in an app bundle. You can edit the configure
script to link to libsdlmain.a on MacOS X target and the app will
probably work just fine.

Cheers,
DarrellOn Sunday, December 2, 2001, at 08:07 PM, Sean Hinde wrote:

Hi,

As a relative newbie to Mac and SDL I’m trying to compile a program
which needs to use the libSDL as a normal C shared library without the
libSDLmain provided for Project Builder apps (as mentioned in an
earlier post)…

I’m trying to find a way to get round the missing _main problem - even
to the point of hacking configure.in to remove the Cocoa parts and make
it look more like linux - unsuccessfully …

For info the program is the wings3d application mentioned recently on
this list.

Any and all assistance much appreciated.

Rgds,
Sean


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

At 21:15 Uhr -0500 02.12.2001, Darrell Walisser wrote:

Put

#undef main

before you define the main procedure. In one of the SDL headers we put

#define main SDL_main

To insert startup code in the real main which then calls SDL_main to
start your program.

If you choose to do this, you must understand that you lose the Mac
OS “face” on the application. It will have no dock icon, and will
have to be launched from the command line.

Uhm, I think it would not work right at all, unless you add mac
specific code to your own main (basically, you would copy the code
from libsdlmain… where is the point in that?!?). There are various
setup steps done in our main() that are rather critical (like setting
up an auto release pool).

For these reasons I recommend avoiding this change if at all possible.

I agree. In fact, for maximum portability, you should always use
libsdlmain, otherwise you will run into troubles on other systems,
too, like BeOS.

Also remember you can statically link libsdlmain.a so that libSDL is
the only runtime dependency. Our revised sdlmain code does not
require a .app bundle or various other standard resources,

Just to clarify this - it does require an .app bundle if you want it
to be double-clickable from the Finder.

Max–

Max Horn
Software Developer

email: mailto:Max_Horn
phone: (+49) 6151-494890

Hi,

At 21:15 Uhr -0500 02.12.2001, Darrell Walisser wrote:

Put

#undef main

If you choose to do this, you must understand that you lose the Mac OS
"face" on the application. It will have no dock icon, and will have to
be launched from the command line.

Uhm, I think it would not work right at all, unless you add mac
specific code to your own main (basically, you would copy the code from
libsdlmain… where is the point in that?!?). There are various setup
steps done in our main() that are rather critical (like setting up an
auto release pool).

Yes, I am getting a bunch of errors related to those - mainly
complaining of:

2001-12-03 21:38:13.978 beam[341] *** _NSAutoreleaseNoPool(): Object
0x1039d30 of class NSCFArray autoreleased with no pool in place - just
leaking.

I agree. In fact, for maximum portability, you should always use
libsdlmain, otherwise you will run into troubles on other systems, too,
like BeOS.

Also remember you can statically link libsdlmain.a so that libSDL is
the only runtime dependency. Our revised sdlmain code does not require
a .app bundle or various other standard resources,

OK, maybe this is what I need to do. Is this the 1.2.3 version? Any
pointers on what I need to change (is it enough to get rid of -framework
Cocoa everywhere)?

Just to clarify this - it does require an .app bundle if you want it to
be double-clickable from the Finder.

I hear you both, i just don’t think that you are describing what I want
to achieve.

That is: compile a shared library (esdl from sourceforge) which will be
loaded into the Virtual Machine of the erlang language at runtime and
provide access to SDL functions which will create a window at some point
later and do cool stuff with it.

There is already an OS X Makefile with the existing esdl distro which I
am told by the guy who wrote it worked against libsdl-1.2.1. From a
quick look through cvsweb this was before all the extra stuff for
Project Builder and Cocoa was added.

Anyhow - I have managed to get esdl to compile using the Downloaded
SDL-1.2.3 binary dev kit. This loads successfully into the erlang VM but
running the test routine (beginning with a call to SDL setVideoMode)
results in a stream of errors:

kCGErrorInvalidConnection : CGSNewWindow: Invalid connection
2001-12-03
21:38:13.958 beam[341] _NXCreateWindow: error creating window (1002)

kCGErrorInvalidConnection : CGSSetWindowProperty: Invalid connection

kCGErrorInvalidConnection : CGSInvalidateWindowShadow: Invalid connection
kCGErrorInvalidConnection :
CGSSetWindowAlpha: Invalid connection
kCGErrorIllegalArgument :
CGSLockWindowRectBits: Invalid window
kCGErrorFailure : Cannot create window/bitmap context device.

and so on.

I’ve traced these calls back into the Cocoa Appkit so either I need to
go without Cocoa or add supporting code for this lot. I think I’d like
to have the option, starting with no Cocoa.

I’ll try going back to 1.2.1 and see if I can get anything working. I’l
also have another go at removing the Cocoa stuff from configure.in using
the one from 1.2.1 as a guide.

Hmm, this is looking trickier than it appeared.

Thanks,
SeanOn Monday, December 3, 2001, at 07:14 pm, Max Horn wrote:

At 22:07 Uhr +0000 03.12.2001, Sean Hinde wrote:

[…]

I agree. In fact, for maximum portability, you should always use
libsdlmain, otherwise you will run into troubles on other systems,
too, like BeOS.

Also remember you can statically link libsdlmain.a so that libSDL
is the only runtime dependency. Our revised sdlmain code does not
require a .app bundle or various other standard resources,

OK, maybe this is what I need to do. Is this the 1.2.3 version? Any
pointers on what I need to change (is it enough to get rid of
-framework Cocoa everywhere)?

No! That will only give you linker errors. That’s as if you asked on
Linux: “Can I just not link against X11?” when you are using X11 in
your app. That’s not how it works :slight_smile:

Just to clarify this - it does require an .app bundle if you want
it to be double-clickable from the Finder.

I hear you both, i just don’t think that you are describing what I
want to achieve.

It is not our task to describe what you want to achieve. That is your job. :slight_smile:

That is: compile a shared library (esdl from sourceforge) which will
be loaded into the Virtual Machine of the erlang language at runtime
and provide access to SDL functions which will create a window at
some point later and do cool stuff with it.

Will be very hard to do that. Not just on OS X. SDL is not designed
to be used like that, face it. It is certainly possible, but you will
have to incorporate code from SDLMain.m into your real main() (or in
another function that wraps around your main app loop).

There is already an OS X Makefile with the existing esdl distro
which I am told by the guy who wrote it worked against libsdl-1.2.1.

sdl 1.2.1 is quite different. It used a rather crude approach by
using the carbon port of SDL when built from command line, but this
had various issues.

From a quick look through cvsweb this was before all the extra stuff
for Project Builder and Cocoa was added.

That doesn’t matter at all.

Anyhow - I have managed to get esdl to compile using the Downloaded
SDL-1.2.3 binary dev kit. This loads successfully into the erlang VM
but running the test routine (beginning with a call to SDL
setVideoMode) results in a stream of errors:

kCGErrorInvalidConnection : CGSNewWindow: Invalid connection

2001-12-03 21:38:13.958 beam[341] _NXCreateWindow: error creating
window (1002)

kCGErrorInvalidConnection : CGSSetWindowProperty: Invalid connection

kCGErrorInvalidConnection : CGSInvalidateWindowShadow: Invalid connection
kCGErrorInvalidConnection :
CGSSetWindowAlpha: Invalid connection
kCGErrorIllegalArgument :
CGSLockWindowRectBits: Invalid window
kCGErrorFailure : Cannot create window/bitmap context device.

and so on.

I’ve traced these calls back into the Cocoa Appkit so either I need
to go without Cocoa or add supporting code for this lot. I think I’d
like to have the option, starting with no Cocoa.

I’ll try going back to 1.2.1 and see if I can get anything working.
I’l also have another go at removing the Cocoa stuff from
configure.in using the one from 1.2.1 as a guide.

I repeat: you are not fixing the problem this way. You are only
fighting the symptoms, not the problem :slight_smile:

Max–

Max Horn
Software Developer

email: mailto:Max_Horn
phone: (+49) 6151-494890

OK, maybe this is what I need to do. Is this the 1.2.3 version? Any
pointers on what I need to change (is it enough to get rid of
-framework Cocoa everywhere)?

No! That will only give you linker errors. That’s as if you asked on
Linux: “Can I just not link against X11?” when you are using X11 in
your app. That’s not how it works :slight_smile:

I’m starting to understand.

That is: compile a shared library (esdl from sourceforge) which will
be loaded into the Virtual Machine of the erlang language at runtime
and provide access to SDL functions which will create a window at some
point later and do cool stuff with it.

Will be very hard to do that. Not just on OS X. SDL is not designed to
be used like that, face it. It is certainly possible, but you will have
to incorporate code from SDLMain.m into your real main() (or in another
function that wraps around your main app loop).

This is what the esdl library does (did) already - it runs great on
Win32 and X11. All I’m trying to do is compile it for OS X. If in the
process I can improve the way it works then that is a side benefit. I’ll
peer into SDLMain.m and see if I can make any sense of it and how it
might relate to what esdl needs to do. I’m sure there is a solution
somewhere between the two!

sdl 1.2.1 is quite different. It used a rather crude approach by using
the carbon port of SDL when built from command line, but this had
various issues.

Well I just gave it a go and lo and behold it works. Wings3d
(www.wings3d.com) under OS X in all it’s glory.

I’ll try going back to 1.2.1 and see if I can get anything working.
I’l also have another go at removing the Cocoa stuff from configure.in
using the one from 1.2.1 as a guide.

I repeat: you are not fixing the problem this way. You are only
fighting the symptoms, not the problem :slight_smile:

I know, I know, but lack of symptoms is not that dissimilar to well
being :slight_smile:

Conceptually I have to agree that your solution is much nicer from an OS
X point of view. But I like hacking in Erlang, and wings3d is pretty
cool as well.

Thanks again for your help

Rgds,
Sean

(Not a programmer - occasional Erlang hacker)On Monday, December 3, 2001, at 10:34 pm, Max Horn wrote:

sdl 1.2.1 is quite different. It used a rather crude approach by using
the carbon port of SDL when built from command line, but this had
various issues.

Well I just gave it a go and lo and behold it works. Wings3d
(www.wings3d.com) under OS X in all it’s glory.

Hum. Is it possible to enable Carbon and not Cocoa from the command line
build anymore?

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment

At 0:00 Uhr -0800 04.12.2001, Sam Lantinga wrote:

sdl 1.2.1 is quite different. It used a rather crude approach by using
the carbon port of SDL when built from command line, but this had
various issues.

Well I just gave it a go and lo and behold it works. Wings3d
(www.wings3d.com) under OS X in all it’s glory.

Hum. Is it possible to enable Carbon and not Cocoa from the command line
build anymore?

Not at the moment. We could try to make it possible to termine at
build time of SDL which target should be used.

Max–

Max Horn
Software Developer

email: mailto:Max_Horn
phone: (+49) 6151-494890

At 0:00 Uhr -0800 04.12.2001, Sam Lantinga wrote:

sdl 1.2.1 is quite different. It used a rather crude approach by
using

the carbon port of SDL when built from command line, but this had
various issues.

Well I just gave it a go and lo and behold it works. Wings3d
(www.wings3d.com) under OS X in all it’s glory.

Hum. Is it possible to enable Carbon and not Cocoa from the command
line
build anymore?

Not at the moment. We could try to make it possible to termine at build
time of SDL which target should be used.

If I am reading some of the earlier posts correctly, it sounds as though
it should be possible to make a version which allows linking and an API
exactly as per 1.2.1, while also taking advantage of a nice standard
menu bar with default handling of certain events.

The 1.2.1 Carbon version simply provides a single window with
functioning “traffic lights” - all we are talking about is adding a
standard menu bar with “Quit” functionality I guess.

I do like the idea of being able to choose whether or not to have this
added functionality though.

Thanks for doing all the hard stuff already :slight_smile:

Best Regards,
SeanOn Tuesday, December 4, 2001, at 03:43 pm, Max Horn wrote:

Hi,

I’ve been chugging away trying to understand how this all might fit into
the erlang esdl driver.

I don’t think your suggestion below is quite achievable as the erlang
interpreter is already running before we load the driver and call
SDL_Init(). I think that what will probably happen is that SDL_main will
hang in it’s main event loop. This means I will probably have to put
some minimum code from SDL_main into the driver startup routines.

But, I know that 1.2.1 will startup fine without including anything from
SDL_main - all that esdl does is call SDL_Init() and setvideomode which
creates the window…

As a minimum it looks like I will need to create an NSAutoreleasepool,
but there is no top loop to create it - all I have are driver callbacks
from Erlang - do you know if it matters if *pool goes out of scope? or
is it a problem if I store it in a C struct in the driver and call some
new Objective C function to create it?

Alternatively I can’t quite see how 1.2.1 got away without creating such
pools - unless the Cocoa code in 1.2.1 is never actually called??

Other pointers welcome :slight_smile:

Thanks,
SeanOn Tuesday, December 4, 2001, at 12:04 am, Darrell Walisser wrote:

Just to clarify, the call sequence should be:

main() - (from libsdlmain.a)
sdl_main()
(from the interpreter’s main procedure
esdl_init () (from esdl)
SDL_Init() (from libsdl)
interpretCode ()
(interpreter loop, whatever)
ESDL_SetVideoMode ()
SDL_SetVideoMode()

At 18:29 Uhr +0000 12.12.2001, Sean Hinde wrote:

Hi,

I’ve been chugging away trying to understand how this all might fit
into the erlang esdl driver.

I don’t think your suggestion below is quite achievable as the
erlang interpreter is already running before we load the driver and
call SDL_Init(). I think that what will probably happen is that
SDL_main will hang in it’s main event loop. This means I will
probably have to put some minimum code from SDL_main into the driver
startup routines.

But, I know that 1.2.1 will startup fine without including anything
from SDL_main - all that esdl does is call SDL_Init() and
setvideomode which creates the window…

Were you building from command line or via ProjectBuilder ?

As a minimum it looks like I will need to create an
NSAutoreleasepool, but there is no top loop to create it - all I
have are driver callbacks from Erlang - do you know if it matters if
*pool goes out of scope? or is it a problem if I store it in a C
struct in the driver and call some new Objective C function to
create it?

There is no such thing as “scope” here, we are not talking stack
variables after all :slight_smile:
Only thing you have to be carefuly about are threads.

Actually… that is something I am suddenly realizing… Darrell,
AppKit is by default running in non-reentrant mode, so anybody using
pthreads potentially will run into big problems! IIRC Apple suggests
as a workaround to create a NSThread once (which you can immediatly
dispose thereaftter to activate the threading support.

Alternatively I can’t quite see how 1.2.1 got away without creating
such pools - unless the Cocoa code in 1.2.1 is never actually
called??

In the command line built version, the Cocoa code never was called.

The Cocoa version in 1.2.1 built using Project Builder used
NSApplication, which did this and a lot of other work for us, but
required a .nib file, that’s why I wrote our own code to replace it.

Max–

Max Horn
Software Developer

email: mailto:Max_Horn
phone: (+49) 6151-494890

Hi,

But, I know that 1.2.1 will startup fine without including anything
from SDL_main - all that esdl does is call SDL_Init() and setvideomode
which creates the window…

Were you building from command line or via ProjectBuilder

Yes, command line.

As a minimum it looks like I will need to create an NSAutoreleasepool,
but there is no top loop to create it - all I have are driver
callbacks from Erlang - do you know if it matters if *pool goes out of
scope? or is it a problem if I store it in a C struct in the driver
and call some new Objective C function to create it?

There is no such thing as “scope” here, we are not talking stack
variables after all :slight_smile:
Only thing you have to be carefuly about are threads.

Yes, I’m not familiar with Objective C… yet - though the docs seem to
be OK…

Alternatively I can’t quite see how 1.2.1 got away without creating
such pools - unless the Cocoa code in 1.2.1 is never actually called??

In the command line built version, the Cocoa code never was called.

Yes, I just traced it all through with gdb and saw that it used code
from the macrom directory.

The Cocoa version in 1.2.1 built using Project Builder used
NSApplication, which did this and a lot of other work for us, but
required a .nib file, that’s why I wrote our own code to replace it.

So if I understand correctly, your CustomApplicationMain sets up some
nice stuff from scratch and then remains in [NSApp run] until the user
quits. So if I want to create a standard window without menus etc in a
library only mode where I can’t use your main I can just create a *pool
and then call setVideoMode and things should work?

At the moment I bomb out at:

qz_window = [ [ SDL_QuartzWindow alloc ] initWithContentRect:rect
styleMask:style backing:NSBackingStoreBuffered defer:NO ];

in non SDL_main mode.

If that it all it needs I wonder if it would be sensible to put some
pool creation stuff in SDL_init (ifdef’d out) so that library only users
could at least create a window using the framework binary…?

BTW, I have managed to build the Carbon target from the command line
with some minor tweaks (rollbacks) to configure.in and It works OK…

Regards,
Sean

At 21:09 Uhr +0000 12.12.2001, Sean Hinde wrote:

[…]

The Cocoa version in 1.2.1 built using Project Builder used
NSApplication, which did this and a lot of other work for us, but
required a .nib file, that’s why I wrote our own code to replace it.

So if I understand correctly, your CustomApplicationMain sets up
some nice stuff from scratch and then remains in [NSApp run] until
the user quits. So if I want to create a standard window without
menus etc in a library only mode where I can’t use your main I can
just create a *pool and then call setVideoMode and things should
work?

No, not at all. If you wanted to not go with [NSApp run], you would
have to create your own NSRunLoop, call it repeatedly, and do many
many other things. I don’t even want to think to much about it, it
will be quite a hassle, simply to reverse engineer what you all have
to do.

At the moment I bomb out at:

qz_window = [ [ SDL_QuartzWindow alloc ] initWithContentRect:rect
styleMask:style backing:NSBackingStoreBuffered defer:NO ];

in non SDL_main mode.

Of course :slight_smile: It just can’t work without the setup code.

If that it all it needs I wonder if it would be sensible to put some
pool creation stuff in SDL_init (ifdef’d out) so that library only
users could at least create a window using the framework binary…?

BTW, I have managed to build the Carbon target from the command line
with some minor tweaks (rollbacks) to configure.in and It works OK…

Sure, it should still be possible. But as Darrell said, the carbon
version is not really tested much.

Max–

Max Horn
Software Developer

email: mailto:Max_Horn
phone: (+49) 6151-494890

BTW, I have managed to build the Carbon target from the command line
with some minor tweaks (rollbacks) to configure.in and It works OK…

Sure, it should still be possible. But as Darrell said, the carbon
version is not really tested much.

Hi SDL’ers,

I just thought I’d update you with the latest on getting SDL to work
with the Erlang language and the wings3d application…

Someone with much more savvy in these things than me (David Wallin) has
figured out a way to make the Cocoa SDL build work fine from the Erlang
language emulator. The magic lines of code are below (and they do indeed
seem to work - notwithstanding the comments in the code …).

Check it out…
http://sourceforge.net/projects/esdl for the Erlang/SDL binding,

and http://www.wings3d.com for a nice 3D modeller using the whole thing.

Cheers,
Sean

#ifdef _OSX_COCOA
#include “CPS.h”
#include “SDLMain.h”
#include <Cocoa/Cocoa.h>
#include <objc/objc-runtime.h>
#endif

and

#ifdef _OSX_COCOA
CPSProcessSerNum PSN;
OSErr err;
#endif _OSX_COCOA

#ifdef _OSX_COCOA
// Removes the warnings about memory leakage
// (not sure it actually works, though)
data->release_pool =
objc_msgSend(objc_msgSend(objc_getClass(“NSAutoreleasePool”),
@selector(alloc)), @selector(init));

   data->app = objc_msgSend(objc_getClass("NSApplication"),
		       @selector(sharedApplication));

   // To get a Menu & a dock icon :
   err = CPSGetCurrentProcess(&PSN);
   assert(!(err = CPSSetProcessName(&PSN,"ESDL")));
   assert(!(err = 

CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)));
assert(!(err = CPSSetFrontProcess(&PSN)));

   // Makes the SDL window respond to keyboard events (???)
   //[NSAppleEventManager sharedAppleEventManager];

#endif _OSX_COCOAOn Wednesday, December 12, 2001, at 09:18 pm, Max Horn wrote:

Someone with much more savvy in these things than me (David Wallin) has
figured out a way to make the Cocoa SDL build work fine from the Erlang
language emulator. The magic lines of code are below (and they do indeed
seem to work - notwithstanding the comments in the code …).

Great. Where do these lines go?

Thanks,
-Sam Lantinga, Software Engineer, Blizzard Entertainment