Skip to content

Commit

Permalink
Date: Tue, 21 Aug 2001 03:50:01 +0200
Browse files Browse the repository at this point in the history
From: Max Horn <max@quendi.de>
Subject: New patch for OS X

Attached a .patch file for SDL/OSX with some nice bug fixes / enhancments.

* fixes the activation issues, which also caused the window to be
always drawn like an inactive. The close/minimize widgets now are
animated properly, too.

* the menu items are automatically adjusted to use the app name
instead of just "SDL App". I did this so that we really can use one
central SDLMain.nib file, w/o requiring developers to make a copy of
it and adjust it.

* libSDLMain now contains the proper cocoa code, not as before the
carbon code. This means apps no longer have to carry a copy of
SDLMain.m/SDLMain.h

* revamped configure.in to properly build a Cocoa/Quartz SDL lib, not
a Carbon based SDL lib
  • Loading branch information
slouken committed Aug 21, 2001
1 parent c9d1c42 commit f7d7e14
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 62 deletions.
48 changes: 36 additions & 12 deletions configure.in
Expand Up @@ -63,10 +63,6 @@ case "$target" in
*-*-linux*)
AC_PROG_CXX
;;
*-*-darwin*)
OBJC="???"
AC_SUBST(OBJC)
;;
esac
AC_PROG_INSTALL
AC_FUNC_ALLOCA
Expand Down Expand Up @@ -1192,6 +1188,21 @@ CheckCARBON()
VIDEO_DRIVERS="$VIDEO_DRIVERS macrom/libvideo_macrom.la"
}

dnl Set up the Mac toolbox video driver for Mac OS X
CheckQUARTZ()
{
# "MACOSX" is not an official definition, but it's commonly
# accepted as a way to differentiate between what runs on X
# and what runs on older Macs - while in theory "Carbon" defns
# are consistent between the two, in practice Carbon is still
# changing. -sts Aug 2000
CFLAGS="$CFLAGS -I/System/Library/Frameworks/Carbon.framework/Headers \
-I/System/Library/Frameworks/Cocoa.framework/Headers -fpascal-strings \
-DENABLE_QUARTZ -DMACOSX -DTARGET_API_MAC_CARBON=1 -I\$(top_srcdir)/src/video/quartz"
VIDEO_SUBDIRS="$VIDEO_SUBDIRS quartz"
VIDEO_DRIVERS="$VIDEO_DRIVERS quartz/libvideo_quartz.la"
}

dnl Set up the kernel statistics library for Solaris
CheckKSTAT()
{
Expand Down Expand Up @@ -1994,17 +2005,17 @@ case "$target" in
;;
*-*-darwin* )
# Strictly speaking, we want "Mac OS X", not "Darwin", which is
# just the OS X kernel sans upper layers like Carbon. But
# config.guess comes back with "darwin", so go with the flow.
ARCH=macos
# just the OS X kernel sans upper layers like Carbon and Cocoa.
# But config.guess comes back with "darwin", so go with the flow.
ARCH=macosx
CheckDummyVideo
CheckDiskAudio
CheckCARBON
CheckQUARTZ
CheckMacGL
CheckPTHREAD
# Set up files for the main() stub
# COPY_ARCH_SRC(src/main, macos, SDL_main.c)
COPY_ARCH_SRC(src/main, linux, SDL_main.c)
COPY_ARCH_SRC(src/main, macosx, SDLmain.m)
COPY_ARCH_SRC(src/main, macosx, SDLmain.h)
# Set up files for the audio library
if test x$enable_audio = xyes; then
AUDIO_SUBDIRS="$AUDIO_SUBDIRS macrom"
Expand Down Expand Up @@ -2040,8 +2051,8 @@ case "$target" in
COPY_ARCH_SRC(src/timer, linux, SDL_systimer.c)
fi
# The MacOS X platform requires special setup
SDL_CFLAGS="$SDL_CFLAGS -F/System/Library/Frameworks/Carbon.framework"
SDL_LIBS="-lSDLmain $SDL_LIBS -framework Carbon"
SDL_CFLAGS="$SDL_CFLAGS -F/System/Library/Frameworks/Carbon.framework -F/System/Library/Frameworks/Cocoa.framework"
SDL_LIBS="-lSDLmain $SDL_LIBS -framework Carbon -framework Cocoa"
;;
*)
AC_MSG_ERROR(Unsupported target: Please add to configure.in)
Expand All @@ -2061,6 +2072,7 @@ AM_CONDITIONAL(TARGET_AIX, test $ARCH = aix)
AM_CONDITIONAL(TARGET_WIN32, test $ARCH = win32)
AM_CONDITIONAL(TARGET_BEOS, test $ARCH = beos)
AM_CONDITIONAL(TARGET_MACOS, test $ARCH = macos)
AM_CONDITIONAL(TARGET_MACOSX, test $ARCH = macosx)

# Set conditional variables for shared and static library selection.
# These are not used in any Makefile.am but in sdl-config.in.
Expand Down Expand Up @@ -2122,6 +2134,18 @@ CFLAGS="$CFLAGS -I\$(top_srcdir)/src/endian"
CFLAGS="$CFLAGS -I\$(top_srcdir)/src/file"
CXXFLAGS="$CFLAGS"


# Check for darwin at the very end and set up the Objective C compiler
# We do this here so that we get the full CFLAGS into OBJCFLAGS
case "$target" in
*-*-darwin*)
OBJC="cc"
OBJCFLAGS="$CFLAGS"
AC_SUBST(OBJC)
AC_SUBST(OBJCFLAGS)
;;
esac

# Finally create all the generated files
dnl Important: Any directory that you want to be in the distcheck should
dnl have a file listed here, so that configure generates the
Expand Down
4 changes: 4 additions & 0 deletions src/main/Makefile.am
Expand Up @@ -10,7 +10,11 @@ ARCH_SUBDIRS = $(srcdir)/beos $(srcdir)/linux \
# Build a separate library containing the main() entry point.
lib_LIBRARIES = libSDLmain.a

if TARGET_MACOSX
MAINLIB_ARCH_SRCS = SDLmain.m SDLmain.h
else
MAINLIB_ARCH_SRCS = SDL_main.c
endif

libSDLmain_a_SOURCES = $(MAINLIB_ARCH_SRCS)

Expand Down
7 changes: 7 additions & 0 deletions src/main/macosx/SDLMain.h
@@ -1,7 +1,14 @@
/* SDLMain.h - main entry point for our Cocoa-ized SDL app
Darrell Walisser - dwaliss1@purdue.edu
Feel free to customize this file to suit your needs
*/

#import <Cocoa/Cocoa.h>

@interface SDLMain : NSObject
{
}
- (IBAction)quit:(id)sender;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;
@end
85 changes: 80 additions & 5 deletions src/main/macosx/SDLMain.m
Expand Up @@ -11,16 +11,22 @@

static int gArgc;
static char **gArgv;
static NSString *gAppName = 0;

@interface NSString (ReplaceSubString)
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
@end


/* The main class of the application, the application's delegate */
@implementation SDLMain

/* Invoked from the Quit menu item */
- (void) quit:(id)sender
{
SDL_Event event;
event.type = SDL_QUIT;
SDL_PushEvent(&event);
SDL_Event event;
event.type = SDL_QUIT;
SDL_PushEvent(&event);
}

/* Set the working directory to the .app's parent directory */
Expand All @@ -29,7 +35,7 @@ - (void) setupWorkingDirectory
char parentdir[MAXPATHLEN];
char *c;

strncpy ( parentdir, gArgv[0], MAXPATHLEN );
strncpy ( parentdir, gArgv[0], sizeof(parentdir) );
c = (char*) parentdir;

while (*c != '\0') /* go to end */
Expand All @@ -38,10 +44,35 @@ - (void) setupWorkingDirectory
while (*c != '/') /* back up to parent */
c--;

*c = '\0'; /* cut off last part (binary name) */
*c++ = '\0'; /* cut off last part (binary name) */

assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */
assert ( chdir ("../../../") == 0 ); /* chdir to the .app's parent */

gAppName = [ NSString stringWithCString: c ];
}

/* Fix menu to contain the real app name instead of "SDL App" */
- (void) fixMenu:(NSMenu *)aMenu
{
NSRange aRange;
NSEnumerator *enumerator;
NSMenuItem *menuItem;

aRange = [[aMenu title] rangeOfString:@"SDL App"];
if (aRange.length != 0)
[aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:gAppName]];

enumerator = [[aMenu itemArray] objectEnumerator];
while ((menuItem = [enumerator nextObject]))
{
aRange = [[menuItem title] rangeOfString:@"SDL App"];
if (aRange.length != 0)
[menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:gAppName]];
if ([menuItem hasSubmenu])
[self fixMenu: [menuItem submenu]];
}
[ aMenu sizeToFit ];
}

/* Called when the internal event loop has just started running */
Expand All @@ -52,6 +83,9 @@ - (void) applicationDidFinishLaunching: (NSNotification *) note
/* Set the working directory to the .app's parent directory */
[ self setupWorkingDirectory ];

/* Set the main menu to contain the real app name instead of "SDL App" */
[ self fixMenu: [ NSApp mainMenu ] ];

/* Hand off to main application code */
status = SDL_main (gArgc, gArgv);

Expand All @@ -60,6 +94,47 @@ - (void) applicationDidFinishLaunching: (NSNotification *) note
}
@end


@implementation NSString (ReplaceSubString)

- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
{
unsigned int bufferSize;
unsigned int selfLen = [self length];
unsigned int aStringLen = [aString length];
unichar *buffer;
NSRange localRange;
NSString *result;

bufferSize = selfLen + aStringLen - aRange.length;
buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));

// Get first part into buffer
localRange.location = 0;
localRange.length = aRange.location;
[self getCharacters:buffer range:localRange];

// Get middle part into buffer
localRange.location = 0;
localRange.length = aStringLen;
[aString getCharacters:(buffer+aRange.location) range:localRange];

// Get last part into buffer
localRange.location = aRange.location + aRange.length;
localRange.length = selfLen - localRange.location;
[self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];

// Build output string
result = [NSString stringWithCharacters:buffer length:bufferSize];

NSDeallocateMemoryPages(buffer, bufferSize);

return result;
}

@end


#ifdef main
# undef main
#endif
Expand Down
38 changes: 20 additions & 18 deletions src/video/quartz/SDL_QuartzEvents.m
Expand Up @@ -223,7 +223,7 @@ static void QZ_DoDeactivate (_THIS) {
}

static void QZ_PumpEvents (_THIS)
{
{
NSDate *distantPast;
NSEvent *event;
NSRect winRect;
Expand All @@ -247,27 +247,29 @@ static void QZ_PumpEvents (_THIS)

if (event != nil) {
unsigned int type;
BOOL isForGameWin;

#define DO_MOUSE_DOWN(button, sendToWindow) \
#define DO_MOUSE_DOWN(button, sendToWindow) do { \
if ( inForeground ) { \
if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \
NSPointInRect([event locationInWindow], winRect) ) \
SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \
else if (sendToWindow) \
[ window sendEvent:event ]; \
} \
else { \
QZ_DoActivate (this); \
}

#define DO_MOUSE_UP(button, sendToWindow) \
} \
[ NSApp sendEvent:event ]; \
} while(0)

#define DO_MOUSE_UP(button, sendToWindow) do { \
if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \
!NSPointInRect([event locationInWindow], titleBarRect) )\
SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); \
if (sendToWindow) \
[ window sendEvent:event ]
[ NSApp sendEvent:event ]; \
} while(0)

type = [ event type ];
isForGameWin = (qz_window == [ event window ]);
switch (type) {

case NSLeftMouseDown:
Expand Down Expand Up @@ -351,8 +353,8 @@ static void QZ_PumpEvents (_THIS)
case NSFlagsChanged:
QZ_DoModifiers( [ event modifierFlags ] );
break;
case NSMouseEntered: break;
case NSMouseExited: break;
// case NSMouseEntered: break;
// case NSMouseExited: break;
case NSAppKitDefined:
switch ( [ event subtype ] ) {
case NSApplicationActivatedEventType:
Expand All @@ -361,14 +363,14 @@ static void QZ_PumpEvents (_THIS)
case NSApplicationDeactivatedEventType:
QZ_DoDeactivate (this);
break;
case NSWindowMovedEventType:
[ window sendEvent:event ];
break;
}
[ NSApp sendEvent:event ];
break;
case NSApplicationDefined: break;
case NSPeriodic: break;
case NSCursorUpdate: break;
// case NSApplicationDefined: break;
// case NSPeriodic: break;
// case NSCursorUpdate: break;
default:
[ NSApp sendEvent:event ];
}
}
} while (event != nil);
Expand Down
6 changes: 1 addition & 5 deletions src/video/quartz/SDL_QuartzVideo.h
Expand Up @@ -44,10 +44,6 @@
- Launch times are slow, maybe prebinding will help
- Direct framebuffer access has some artifacts, maybe a driver issue
- Cursor in 8 bit modes is screwy
- Modifier + mouse-down maps alternate mouse button, but if modifier is released
before mouse button, corresponding mouse-up event is not generated.
- Clicking in content activates app, but doesn't generate the activate event,
and subsequent switches generate no activate/deactivate events! (OS Bug I hope)
*/

#include <ApplicationServices/ApplicationServices.h>
Expand Down Expand Up @@ -107,7 +103,7 @@ typedef struct SDL_PrivateVideoData {
#define device_bpp (this->hidden->bpp)
#define mode_flags (this->hidden->flags)
#define video_set (this->hidden->video_is_set)
#define window (this->hidden->window)
#define qz_window (this->hidden->window)
#define windowView (this->hidden->view)

/* Interface for hardware fill not (yet) in the public API */
Expand Down

0 comments on commit f7d7e14

Please sign in to comment.