Added initial support for Quartz video (thanks Darrell!)
authorSam Lantinga <slouken@lokigames.com>
Thu, 07 Jun 2001 14:28:11 +0000
changeset 47 45b1c4303f87
parent 46 3dcf26fa9d15
child 48 f97decee03a9
Added initial support for Quartz video (thanks Darrell!)
BUGS
README.MacOSX
configure.in
docs.html
include/SDL_main.h
include/SDL_video.h
src/audio/macrom/SDL_romaudio.c
src/main/macosx/SDLMain.h
src/main/macosx/SDLMain.m
src/main/macosx/exports/Makefile
src/main/macosx/exports/SDL.x
src/main/macosx/exports/gendef.pl
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/macrom/SDL_romvideo.c
src/video/quartz/Makefile.am
src/video/quartz/SDL_QuartzEvents.m
src/video/quartz/SDL_QuartzKeys.h
src/video/quartz/SDL_QuartzVideo.h
src/video/quartz/SDL_QuartzVideo.m
src/video/quartz/SDL_QuartzWM.m
src/video/quartz/SDL_QuartzWindow.m
test/testtypes.c
--- a/BUGS	Thu Jun 07 13:53:51 2001 +0000
+++ b/BUGS	Thu Jun 07 14:28:11 2001 +0000
@@ -70,22 +70,35 @@
 	Not all of the keys are properly recognized on the keyboard.
 
 MacOS X:
-	Fullscreen mode doesn't work - it requires the QuickTime framework
-	and that the new SDL window gets raised to the top of the Z order.
+	Joystick and CD-ROM functions are not implemented yet.
 
+	Closing window from window's close widget not implemented yet.
+	
+	Minimizing the window erases the framebuffer to the pinstripe pattern.
+	
+	Window may not close when unsetting video mode and resetting.
+	
+	Depth switching for windowed mode isn't implemented yet.
+	
 	Palette handling isn't implemented in windowed mode yet.
-
-	Native sound and video routines are not finished, though Carbon
-	seems to work fairly well.
+	
+	Command-line arguments Dialog is not implemented yet.
 
-	Joysticks and CD-ROM functions are not implemented yet.
+	Fullscreen drawing has some artifacts.
+	
+	Fullscreen window covers *all* other windows - even force quit.
+	
+	Fullscreen OpenGL for the software renderer is broken.
 
-	SDL_WM_GrabInput() is not implemented.
-	Does anyone know how to do this?  SDL_WM_GrabInput() is designed
-	to prevent the user from switching input and mouse focus away from
-	the SDL application.
+	Some OpenGL parameters are not accounted for, for example color bits customization.
+	
+	Getting OpenGL context parameters is not implemented.
+	
+	Continuous mouse motion perhaps is not as smooth as it should be.
 
-	Continuous relative mouse motion is not implemented.
+	SDL_WM_GrabInput() is implemented, but it "freezes" the hardware
+	cursor in the center of the window/screen.  Also, mouse moved events
+	are not generated, and the keyboard cannot be grabbed.
 
 	Not all of the keys are properly recognized on the keyboard.
 
--- a/README.MacOSX	Thu Jun 07 13:53:51 2001 +0000
+++ b/README.MacOSX	Thu Jun 07 14:28:11 2001 +0000
@@ -34,11 +34,80 @@
 sdl-config knows about the linking path and -framework, so it's
 recommended to use it to fill in your Makefile variables.
 
-[Add instructions for how to build using PB]
+==============================================================================
+Using the Simple DirectMedia Layer with Project Builder
+==============================================================================
+
+These instructions are for using Apple's Project Builder IDE to build SDL applications.
+
+- Building the Framework
+
+The SDL Library is packaged as a framework bundle, an organized
+relocatable folder heirarchy of executible code, interface headers, 
+and additional resources. For practical purposes, you can think of a 
+framework as a more user and system-friendly shared library, whose library
+file behaves more or less like a standard UNIX shared library.
+
+To build the framework, simply open the framework project and build it. 
+By default, the framework bundle "SDL.framework" is installed in 
+~/Library/Frameworks. Therefore, the testers and project stationary expect
+it to be located there. However, it will function the same in any of the
+following locations:
+
+    ~/Library/Frameworks
+    /Local/Library/Frameworks
+    /System/Library/Frameworks
+
+- Build Options
+    There are two "Build Styles" (See the "Targets" tab) for SDL.
+    "Deployment" should be used if you aren't tweaking the SDL library.
+    "Development" should be used to debug SDL apps or the library itself.
+
+- Building the Testers
+    Open the SDLTest project and build away!
+
+- Using the Project Stationary
+    Copy the stationary to the indicated folders to access it from
+    the "New Project" and "Add target" menus. What could be easier?
 
-As of this writing (Sep 2000), OS X is in public beta.  This means
-that while most of the APIs are frozen, things are still subject to
-change, and many of the known problems will be resolved before the
-final release comes out.
+- Setting up a new project by hand
+    Some of you won't want to use the Stationary so I'll give some tips:
+    * Create a new "Cocoa Application"
+    * Add src/main/macosx/SDLMain.m , .h and .nib to your project
+    * Remove "main.c" from your project
+    * Remove "MainMenu.nib" from your project
+    * Add "$(HOME)/Library/Frameworks/SDL.framework/Headers" to include path
+    * Add "$(HOME)/Library/Frameworks" to the frameworks search path
+    * Add "-framework SDL" to the "OTHER_LDFLAGS" variable
+    * Set the "Main Nib File" under "Application Settings" to "SDLMain.nib"
+    * Add your files
+    * Clean and build
 
+- Building from command line
+    Use pbxbuild in the same directory as your .pbproj file
+         
+- Running your app
+    You can send command line args to your app by either invoking it from
+    the command line (in *.app/Contents/MacOS) or by entering them in the
+    "Executibles" panel of the target settings.
+    
+- Implementation Notes
+    Some things that may be of interest about how it all works...
+    * Working directory
+        As defined in the SDLMain.m file, the working directory of your SDL app
+        is by default set to its parent. You may wish to change this to better
+        suit your needs.
+    * You have a Cocoa App!
+        Your SDL app is essentially a Cocoa application. When your app
+        starts up and the libraries finish loading, a Cocoa procedure is called,
+        which sets up the working directory and calls your main() method.
+        You are free to modify your Cocoa app with generally no consequence 
+        to SDL. You cannot, however, easily change the SDL window itself.
+        Functionality may be added in the future to help this.
+    * My development setup:
+        I am using version 1.0.1 (v63.0) of Project Builder on MacOS X 10.0.3,
+        from the Developer Tools CD for May 2001.
+        As of May 31 2001, Apple hasn't released this version of the tools to the public, 
+        but I expect that things will still work on older versions.
+        
 Known bugs are listed in the file "BUGS"
--- a/configure.in	Thu Jun 07 13:53:51 2001 +0000
+++ b/configure.in	Thu Jun 07 14:28:11 2001 +0000
@@ -63,6 +63,10 @@
     *-*-linux*)
         AC_PROG_CXX
         ;;
+    *-*-darwin*)
+        OBJC="???"
+        AC_SUBST(OBJC)
+        ;;
 esac
 AC_PROG_INSTALL
 AC_FUNC_ALLOCA
@@ -1979,6 +1983,7 @@
 src/video/maccommon/Makefile
 src/video/macdsp/Makefile
 src/video/macrom/Makefile
+src/video/quartz/Makefile
 src/video/svga/Makefile
 src/video/aalib/Makefile
 src/video/wincommon/Makefile
--- a/docs.html	Thu Jun 07 13:53:51 2001 +0000
+++ b/docs.html	Thu Jun 07 14:28:11 2001 +0000
@@ -16,6 +16,7 @@
 Major changes since SDL 1.0.0:
 </H2>
 <UL>
+	<LI> 1.2.1: Added initial support for Quartz video (thanks Darrell!)
 	<LI> 1.2.1: Added native OpenBSD audio driver (thanks vedge!)
 	<LI> 1.2.1: Added detection of Open Sound System on Solaris x86
 	<LI> 1.2.1: Added initial support for Nano-X (thanks Hsieh-Fu!)
--- a/include/SDL_main.h	Thu Jun 07 13:53:51 2001 +0000
+++ b/include/SDL_main.h	Thu Jun 07 14:28:11 2001 +0000
@@ -31,7 +31,7 @@
 /* Redefine main() on Win32 and MacOS so that it is called by winmain.c */
 
 #if defined(WIN32) || (defined(__MWERKS__) && !defined(__BEOS__)) || \
-    defined(macintosh)
+    defined(macintosh) || defined(__APPLE__)
 
 #ifdef __cplusplus
 #define C_LINKAGE	"C"
--- a/include/SDL_video.h	Thu Jun 07 13:53:51 2001 +0000
+++ b/include/SDL_video.h	Thu Jun 07 14:28:11 2001 +0000
@@ -878,6 +878,10 @@
  */
 extern DECLSPEC SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode);
 
+/* Not in public API at the moment - do not use! */
+extern DECLSPEC int SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect,
+                                    SDL_Surface *dst, SDL_Rect *dstrect);
+                    
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
 }
--- a/src/audio/macrom/SDL_romaudio.c	Thu Jun 07 13:53:51 2001 +0000
+++ b/src/audio/macrom/SDL_romaudio.c	Thu Jun 07 14:28:11 2001 +0000
@@ -105,9 +105,8 @@
    UInt32 fill_me, play_me;
    SndCommand cmd; 
    SDL_AudioDevice *audio = (SDL_AudioDevice *)chan->userInfo;
- 
-   fill_me = cmd_passed->param2;  /* buffer that has just finished playing,
-so fill it */      
+   
+   fill_me = cmd_passed->param2;  /* buffer that has just finished playing, so fill it */      
    play_me = ! fill_me;           /* filled buffer to play _now_ */
 
    if ( ! audio->enabled ) {
@@ -119,15 +118,21 @@
    cmd.cmd = bufferCmd;
    cmd.param1 = 0; 
    cmd.param2 = (long)&header;
-   
-    SndDoCommand (chan, &cmd, 0);
+
+   SndDoCommand (chan, &cmd, 0);
    
    memset (buffer[fill_me], 0, audio->spec.size);
    
    if ( ! audio->paused ) {
         if ( audio->convert.needed ) {
-            audio->spec.callback(audio->spec.userdata,
-                (Uint8 *)audio->convert.buf,audio->convert.len);
+            #if MACOSX
+                SDL_mutexP(audio->mixer_lock);
+            #endif
+                audio->spec.callback(audio->spec.userdata,
+                    (Uint8 *)audio->convert.buf,audio->convert.len);
+            #if MACOSX
+                SDL_mutexV(audio->mixer_lock);
+            #endif 
                SDL_ConvertAudio(&audio->convert);
 #if 0
             if ( audio->convert.len_cvt != audio->spec.size ) {
@@ -137,11 +142,17 @@
             memcpy(buffer[fill_me], audio->convert.buf,
                             audio->convert.len_cvt);
         } else {
+            #if MACOSX
+                SDL_mutexP(audio->mixer_lock);
+            #endif
             audio->spec.callback(audio->spec.userdata,
                 (Uint8 *)buffer[fill_me], audio->spec.size);
+            #if MACOSX
+                SDL_mutexV(audio->mixer_lock);
+            #endif
         }
     }
-    
+
     if ( running ) {
          
       cmd.cmd = callBackCmd;
@@ -150,6 +161,7 @@
    
       SndDoCommand (chan, &cmd, 0);
    }
+
 }
 
 static int Mac_OpenAudio(_THIS, SDL_AudioSpec *spec) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/macosx/SDLMain.h	Thu Jun 07 14:28:11 2001 +0000
@@ -0,0 +1,8 @@
+#import <Cocoa/Cocoa.h>
+
+@interface SDLMain : NSObject
+{
+}
+- (IBAction)quit:(id)sender;
+- (IBAction)makeFullscreen:(id)sender;
+@end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/macosx/SDLMain.m	Thu Jun 07 14:28:11 2001 +0000
@@ -0,0 +1,88 @@
+/*   SDLMain.m - 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 "SDL.h"
+#import "SDLMain.h"
+#import <sys/param.h> /* for MAXPATHLEN */
+#import <unistd.h>
+
+static int    gArgc;
+static char  **gArgv;
+
+/* 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);
+}
+
+/* Invoked from the "Make fulllscreen" menu item */
+- (void) makeFullscreen:(id)sender
+{
+    
+}
+
+/* Set the working directory to the .app's parent directory */
+- (void) setupWorkingDirectory
+{
+    char parentdir[MAXPATHLEN];
+    char *c;
+    
+    strncpy ( parentdir, gArgv[0], MAXPATHLEN );
+    c = (char*) parentdir;
+    
+    while (*c != '\0')     /* go to end */
+        c++;
+    
+    while (*c != '/')      /* back up to parent */
+        c--;
+    
+    *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 */
+}
+
+/* Called when the internal event loop has just started running */
+- (void) applicationDidFinishLaunching: (NSNotification *) note
+{
+    /* Set the working directory to the .app's parent directory */
+    [ self setupWorkingDirectory ];
+    
+    /* This is passed if we are launched by double-clicking */
+    if ( gArgc >= 2 && strncmp (gArgv[1], "-psn", 4) == 0 )
+        gArgc = 1;
+    
+    /* Hand off to main application code */
+    SDL_main (gArgc, gArgv);
+    exit(0);
+}
+@end
+
+#ifdef main
+#  undef main
+#endif
+
+/* Main entry point to executible - should *not* be SDL_main! */
+int main (int argc, char **argv) {
+
+    /* Copy the arguments into a global variable */
+    int i;
+    
+    gArgc = argc;
+    gArgv = (char**) malloc (sizeof(*gArgv) * gArgc);
+    assert (gArgv != NULL);
+    for (i = 0; i < gArgc; i++) {
+        gArgv[i] = strdup (argv[i]);
+    }
+    
+    NSApplicationMain (argc, argv);
+    return 0;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/macosx/exports/Makefile	Thu Jun 07 14:28:11 2001 +0000
@@ -0,0 +1,35 @@
+
+EXPORTS = SDL.x
+HEADERS = \
+	../../../../include/SDL.h \
+	../../../../include/SDL_active.h \
+	../../../../include/SDL_audio.h \
+	../../../../include/SDL_byteorder.h \
+	../../../../include/SDL_cdrom.h \
+	../../../../include/SDL_copying.h \
+	../../../../include/SDL_endian.h \
+	../../../../include/SDL_error.h \
+	../../../../include/SDL_events.h \
+	../../../../include/SDL_getenv.h \
+	../../../../include/SDL_joystick.h \
+	../../../../include/SDL_keyboard.h \
+	../../../../include/SDL_keysym.h \
+	../../../../include/SDL_mouse.h \
+	../../../../include/SDL_mutex.h \
+	../../../../include/SDL_quit.h \
+	../../../../include/SDL_rwops.h \
+	../../../../include/SDL_syswm.h \
+	../../../../include/SDL_thread.h \
+	../../../../include/SDL_timer.h \
+	../../../../include/SDL_types.h \
+	../../../../include/SDL_version.h \
+	../../../../include/SDL_video.h
+
+
+all: $(EXPORTS)
+
+$(EXPORTS): $(HEADERS)
+	perl gendef.pl $(HEADERS) >$@ || rm $@
+
+clean:
+	rm -f $(EXPORTS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/macosx/exports/SDL.x	Thu Jun 07 14:28:11 2001 +0000
@@ -0,0 +1,177 @@
+	_SDL_Init
+	_SDL_InitSubSystem
+	_SDL_QuitSubSystem
+	_SDL_WasInit
+	_SDL_Quit
+	_SDL_GetAppState
+	_SDL_AudioInit
+	_SDL_AudioQuit
+	_SDL_AudioDriverName
+	_SDL_OpenAudio
+	_SDL_GetAudioStatus
+	_SDL_PauseAudio
+	_SDL_LoadWAV_RW
+	_SDL_FreeWAV
+	_SDL_BuildAudioCVT
+	_SDL_ConvertAudio
+	_SDL_MixAudio
+	_SDL_LockAudio
+	_SDL_UnlockAudio
+	_SDL_CloseAudio
+	_SDL_CDNumDrives
+	_SDL_CDName
+	_SDL_CDOpen
+	_SDL_CDStatus
+	_SDL_CDPlayTracks
+	_SDL_CDPlay
+	_SDL_CDPause
+	_SDL_CDResume
+	_SDL_CDStop
+	_SDL_CDEject
+	_SDL_CDClose
+	_SDL_ReadLE16
+	_SDL_ReadBE16
+	_SDL_ReadLE32
+	_SDL_ReadBE32
+	_SDL_ReadLE64
+	_SDL_ReadBE64
+	_SDL_WriteLE16
+	_SDL_WriteBE16
+	_SDL_WriteLE32
+	_SDL_WriteBE32
+	_SDL_WriteLE64
+	_SDL_WriteBE64
+	_SDL_SetError
+	_SDL_GetError
+	_SDL_ClearError
+	_SDL_PumpEvents
+	_SDL_PeepEvents
+	_SDL_PollEvent
+	_SDL_WaitEvent
+	_SDL_PushEvent
+	_SDL_SetEventFilter
+	_SDL_GetEventFilter
+	_SDL_EventState
+	_SDL_putenv
+	_SDL_getenv
+	_SDL_NumJoysticks
+	_SDL_JoystickName
+	_SDL_JoystickOpen
+	_SDL_JoystickOpened
+	_SDL_JoystickIndex
+	_SDL_JoystickNumAxes
+	_SDL_JoystickNumBalls
+	_SDL_JoystickNumHats
+	_SDL_JoystickNumButtons
+	_SDL_JoystickUpdate
+	_SDL_JoystickEventState
+	_SDL_JoystickGetAxis
+	_SDL_JoystickGetHat
+	_SDL_JoystickGetBall
+	_SDL_JoystickGetButton
+	_SDL_JoystickClose
+	_SDL_EnableUNICODE
+	_SDL_EnableKeyRepeat
+	_SDL_GetKeyState
+	_SDL_GetModState
+	_SDL_SetModState
+	_SDL_GetKeyName
+	_SDL_GetMouseState
+	_SDL_GetRelativeMouseState
+	_SDL_WarpMouse
+	_SDL_CreateCursor
+	_SDL_SetCursor
+	_SDL_GetCursor
+	_SDL_FreeCursor
+	_SDL_ShowCursor
+	_SDL_CreateMutex
+	_SDL_mutexP
+	_SDL_mutexV
+	_SDL_DestroyMutex
+	_SDL_CreateSemaphore
+	_SDL_DestroySemaphore
+	_SDL_SemWait
+	_SDL_SemTryWait
+	_SDL_SemWaitTimeout
+	_SDL_SemPost
+	_SDL_SemValue
+	_SDL_CreateCond
+	_SDL_DestroyCond
+	_SDL_CondSignal
+	_SDL_CondBroadcast
+	_SDL_CondWait
+	_SDL_CondWaitTimeout
+	_SDL_RWFromFile
+	_SDL_RWFromFP
+	_SDL_RWFromMem
+	_SDL_AllocRW
+	_SDL_FreeRW
+	_SDL_GetWMInfo
+	_SDL_CreateThread
+	_SDL_ThreadID
+	_SDL_GetThreadID
+	_SDL_WaitThread
+	_SDL_KillThread
+	_SDL_GetTicks
+	_SDL_Delay
+	_SDL_SetTimer
+	_SDL_AddTimer
+	_SDL_RemoveTimer
+	_SDL_Linked_Version
+	_SDL_VideoInit
+	_SDL_VideoQuit
+	_SDL_VideoDriverName
+	_SDL_GetVideoSurface
+	_SDL_GetVideoInfo
+	_SDL_VideoModeOK
+	_SDL_ListModes
+	_SDL_SetVideoMode
+	_SDL_UpdateRects
+	_SDL_UpdateRect
+	_SDL_Flip
+	_SDL_SetGamma
+	_SDL_SetGammaRamp
+	_SDL_GetGammaRamp
+	_SDL_SetColors
+	_SDL_SetPalette
+	_SDL_MapRGB
+	_SDL_MapRGBA
+	_SDL_GetRGB
+	_SDL_GetRGBA
+	_SDL_CreateRGBSurface
+	_SDL_CreateRGBSurfaceFrom
+	_SDL_FreeSurface
+	_SDL_LockSurface
+	_SDL_UnlockSurface
+	_SDL_LoadBMP_RW
+	_SDL_SaveBMP_RW
+	_SDL_SetColorKey
+	_SDL_SetAlpha
+	_SDL_SetClipRect
+	_SDL_GetClipRect
+	_SDL_ConvertSurface
+	_SDL_UpperBlit
+	_SDL_LowerBlit
+	_SDL_FillRect
+	_SDL_DisplayFormat
+	_SDL_DisplayFormatAlpha
+	_SDL_CreateYUVOverlay
+	_SDL_LockYUVOverlay
+	_SDL_UnlockYUVOverlay
+	_SDL_DisplayYUVOverlay
+	_SDL_FreeYUVOverlay
+	_SDL_GL_LoadLibrary
+	_SDL_GL_GetProcAddress
+	_SDL_GL_SetAttribute
+	_SDL_GL_GetAttribute
+	_SDL_GL_SwapBuffers
+	_SDL_GL_UpdateRects
+	_SDL_GL_Lock
+	_SDL_GL_Unlock
+	_SDL_WM_SetCaption
+	_SDL_WM_GetCaption
+	_SDL_WM_SetIcon
+	_SDL_WM_IconifyWindow
+	_SDL_WM_ToggleFullScreen
+	_SDL_WM_GrabInput
+	_SDL_SoftStretch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/macosx/exports/gendef.pl	Thu Jun 07 14:28:11 2001 +0000
@@ -0,0 +1,20 @@
+#!/usr/bin/perl
+#
+# Program to take a set of header files and generate DLL export definitions
+
+while ( ($file = shift(@ARGV)) ) {
+	if ( ! defined(open(FILE, $file)) ) {
+		warn "Couldn't open $file: $!\n";
+		next;
+	}
+	$printed_header = 0;
+	$file =~ s,.*/,,;
+	while (<FILE>) {
+		if ( /DECLSPEC.*\s\**([^\s\(]+)\(/ ) {
+			print "\t_$1\n";
+		} elsif ( /DECLSPEC.*\s\**([^\s\(]+)$/ ) {
+			print "\t_$1\n";
+		}
+	}
+	close(FILE);
+}
--- a/src/video/SDL_sysvideo.h	Thu Jun 07 13:53:51 2001 +0000
+++ b/src/video/SDL_sysvideo.h	Thu Jun 07 14:28:11 2001 +0000
@@ -63,7 +63,7 @@
 #endif
 struct SDL_VideoDevice {
 	/* * * */
-	/* The name of this audio driver */
+	/* The name of this video driver */
 	const char *name;
 
 	/* * * */
@@ -377,10 +377,12 @@
 #ifdef ENABLE_DRAWSPROCKET
 extern VideoBootStrap DSp_bootstrap;
 #endif
+#ifdef ENABLE_QUARTZ
+extern VideoBootStrap QZ_bootstrap;
+#endif
 #ifdef ENABLE_CYBERGRAPHICS
 extern VideoBootStrap CGX_bootstrap;
 #endif
-
 /* This is the current video device */
 extern SDL_VideoDevice *current_video;
 
--- a/src/video/SDL_video.c	Thu Jun 07 13:53:51 2001 +0000
+++ b/src/video/SDL_video.c	Thu Jun 07 14:28:11 2001 +0000
@@ -84,6 +84,9 @@
 #ifdef ENABLE_DRAWSPROCKET
 	&DSp_bootstrap,
 #endif
+#ifdef ENABLE_QUARTZ
+	&QZ_bootstrap,
+#endif
 #ifdef ENABLE_CYBERGRAPHICS
 	&CGX_bootstrap,
 #endif
--- a/src/video/macrom/SDL_romvideo.c	Thu Jun 07 13:53:51 2001 +0000
+++ b/src/video/macrom/SDL_romvideo.c	Thu Jun 07 14:28:11 2001 +0000
@@ -34,7 +34,7 @@
    is still at the back on MacOS X, which is where this code is needed.
  */
 #if USE_QUICKTIME
-#include <Movies.h>
+#include <QuickTime/Movies.h>
 #endif
 #else
 #include <LowMem.h>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/quartz/Makefile.am	Thu Jun 07 14:28:11 2001 +0000
@@ -0,0 +1,14 @@
+
+## Makefile.am for SDL using the MacOS X Quartz video driver
+
+noinst_LTLIBRARIES = libvideo_quartz.la
+libvideo_quartz_la_SOURCES = $(QUARTZ_SRCS)
+
+# The SDL MacOS X Quartz video driver sources
+QUARTZ_SRCS = 			\
+	SDL_QuartzEvents.m	\
+	SDL_QuartzKeys.h	\
+	SDL_QuartzVideo.h	\
+	SDL_QuartzVideo.m	\
+	SDL_QuartzWM.m		\
+	SDL_QuartzWindow.m
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/quartz/SDL_QuartzEvents.m	Thu Jun 07 14:28:11 2001 +0000
@@ -0,0 +1,368 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@devolution.com
+*/
+
+#include "SDL_QuartzKeys.h"
+
+static void  QZ_InitOSKeymap (_THIS) {
+	int i;
+
+	for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
+		keymap[i] = SDLK_UNKNOWN;
+
+	// This keymap is almost exactly the same as the OS 9 one
+        keymap[QZ_ESCAPE] = SDLK_ESCAPE;
+	keymap[QZ_F1] = SDLK_F1;
+	keymap[QZ_F2] = SDLK_F2;
+	keymap[QZ_F3] = SDLK_F3;
+	keymap[QZ_F4] = SDLK_F4;
+	keymap[QZ_F5] = SDLK_F5;
+	keymap[QZ_F6] = SDLK_F6;
+	keymap[QZ_F7] = SDLK_F7;
+	keymap[QZ_F8] = SDLK_F8;
+	keymap[QZ_F9] = SDLK_F9;
+	keymap[QZ_F10] = SDLK_F10;
+	keymap[QZ_F11] = SDLK_F11;
+	keymap[QZ_F12] = SDLK_F12;
+	keymap[QZ_PRINT] = SDLK_PRINT;
+	keymap[QZ_SCROLLOCK] = SDLK_SCROLLOCK;
+	keymap[QZ_PAUSE] = SDLK_PAUSE;
+	keymap[QZ_POWER] = SDLK_POWER;
+	keymap[QZ_BACKQUOTE] = SDLK_BACKQUOTE;
+	keymap[QZ_1] = SDLK_1;
+	keymap[QZ_2] = SDLK_2;
+	keymap[QZ_3] = SDLK_3;
+	keymap[QZ_4] = SDLK_4;
+	keymap[QZ_5] = SDLK_5;
+	keymap[QZ_6] = SDLK_6;
+	keymap[QZ_7] = SDLK_7;
+	keymap[QZ_8] = SDLK_8;
+	keymap[QZ_9] = SDLK_9;
+	keymap[QZ_0] = SDLK_0;
+	keymap[QZ_MINUS] = SDLK_MINUS;
+	keymap[QZ_EQUALS] = SDLK_EQUALS;
+	keymap[QZ_BACKSPACE] = SDLK_BACKSPACE;
+	keymap[QZ_INSERT] = SDLK_INSERT;
+	keymap[QZ_HOME] = SDLK_HOME;
+	keymap[QZ_PAGEUP] = SDLK_PAGEUP;
+	keymap[QZ_NUMLOCK] = SDLK_NUMLOCK;
+	keymap[QZ_KP_EQUALS] = SDLK_KP_EQUALS;
+	keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE;
+	keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
+	keymap[QZ_TAB] = SDLK_TAB;
+	keymap[QZ_q] = SDLK_q;
+	keymap[QZ_w] = SDLK_w;
+	keymap[QZ_e] = SDLK_e;
+	keymap[QZ_r] = SDLK_r;
+	keymap[QZ_t] = SDLK_t;
+	keymap[QZ_y] = SDLK_y;
+	keymap[QZ_u] = SDLK_u;
+	keymap[QZ_i] = SDLK_i;
+	keymap[QZ_o] = SDLK_o;
+	keymap[QZ_p] = SDLK_p;
+	keymap[QZ_LEFTBRACKET] = SDLK_LEFTBRACKET;
+	keymap[QZ_RIGHTBRACKET] = SDLK_RIGHTBRACKET;
+	keymap[QZ_BACKSLASH] = SDLK_BACKSLASH;
+	keymap[QZ_DELETE] = SDLK_DELETE;
+	keymap[QZ_END] = SDLK_END;
+	keymap[QZ_PAGEDOWN] = SDLK_PAGEDOWN;
+	keymap[QZ_KP7] = SDLK_KP7;
+	keymap[QZ_KP8] = SDLK_KP8;
+	keymap[QZ_KP9] = SDLK_KP9;
+	keymap[QZ_KP_MINUS] = SDLK_KP_MINUS;
+	keymap[QZ_CAPSLOCK] = SDLK_CAPSLOCK;
+	keymap[QZ_a] = SDLK_a;
+	keymap[QZ_s] = SDLK_s;
+	keymap[QZ_d] = SDLK_d;
+	keymap[QZ_f] = SDLK_f;
+	keymap[QZ_g] = SDLK_g;
+	keymap[QZ_h] = SDLK_h;
+	keymap[QZ_j] = SDLK_j;
+	keymap[QZ_k] = SDLK_k;
+	keymap[QZ_l] = SDLK_l;
+	keymap[QZ_SEMICOLON] = SDLK_SEMICOLON;
+	keymap[QZ_QUOTE] = SDLK_QUOTE;
+	keymap[QZ_RETURN] = SDLK_RETURN;
+	keymap[QZ_KP4] = SDLK_KP4;
+	keymap[QZ_KP5] = SDLK_KP5;
+	keymap[QZ_KP6] = SDLK_KP6;
+	keymap[QZ_KP_PLUS] = SDLK_KP_PLUS;
+	keymap[QZ_LSHIFT] = SDLK_LSHIFT;
+	keymap[QZ_z] = SDLK_z;
+	keymap[QZ_x] = SDLK_x;
+	keymap[QZ_c] = SDLK_c;
+	keymap[QZ_v] = SDLK_v;
+	keymap[QZ_b] = SDLK_b;
+	keymap[QZ_n] = SDLK_n;
+	keymap[QZ_m] = SDLK_m;
+	keymap[QZ_COMMA] = SDLK_COMMA;
+	keymap[QZ_PERIOD] = SDLK_PERIOD;
+	keymap[QZ_SLASH] = SDLK_SLASH;
+	keymap[QZ_UP] = SDLK_UP;
+	keymap[QZ_KP1] = SDLK_KP1;
+	keymap[QZ_KP2] = SDLK_KP2;
+	keymap[QZ_KP3] = SDLK_KP3;
+	keymap[QZ_KP_ENTER] = SDLK_KP_ENTER;
+	keymap[QZ_LCTRL] = SDLK_LCTRL;
+	keymap[QZ_LALT] = SDLK_LALT;
+	keymap[QZ_LMETA] = SDLK_LMETA;
+	keymap[QZ_SPACE] = SDLK_SPACE;
+	keymap[QZ_LEFT] = SDLK_LEFT;
+	keymap[QZ_DOWN] = SDLK_DOWN;
+	keymap[QZ_RIGHT] = SDLK_RIGHT;
+	keymap[QZ_KP0] = SDLK_KP0;
+	keymap[QZ_KP_PERIOD] = SDLK_KP_PERIOD;
+	keymap[QZ_IBOOK_ENTER] = SDLK_KP_ENTER;
+	keymap[QZ_IBOOK_RIGHT] = SDLK_RIGHT;
+	keymap[QZ_IBOOK_DOWN] = SDLK_DOWN;
+	keymap[QZ_IBOOK_UP]   = SDLK_UP;
+	keymap[QZ_IBOOK_LEFT] = SDLK_LEFT;
+}
+
+static void QZ_DoKey (int state, NSEvent *event) {
+
+        NSString *chars;
+        int i;
+        SDL_keysym key;
+        
+        /* An event can contain multiple characters */
+        /* I'll ignore this fact for now, since there is only one virtual key code per event */
+        chars = [ event characters ];
+        for (i =0; i < 1 /*[ chars length ] */; i++) {
+                    
+            key.scancode = [ event keyCode ];
+            key.sym      = keymap [ key.scancode ];
+            key.unicode  = [ chars characterAtIndex:i];
+            key.mod      = KMOD_NONE;
+                        
+            SDL_PrivateKeyboard (state, &key);
+        }
+}
+
+static void QZ_DoModifiers (unsigned int newMods) {
+
+    const int offset = 18;
+    const int mapping[] = { SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, 0, SDLK_LMETA } ;
+
+    int bit;
+    SDL_keysym key;
+    key.scancode = 0;
+    key.sym      = SDLK_UNKNOWN;
+    key.unicode  = 0;
+    key.mod      = KMOD_NONE;
+    
+    /* Iterate through the bits, testing each against the current modifiers */
+    for (bit = NSShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1) {
+    
+        unsigned int currentMask, newMask;
+        
+        currentMask = currentMods & bit;
+        newMask     = newMods & bit;
+        
+        if ( currentMask && 
+             currentMask != newMask ) {  /* modifier up event */
+
+            key.sym = mapping[ currentMask >> offset ];
+            SDL_PrivateKeyboard (SDL_RELEASED, &key);
+        }
+        else
+        if ( newMask &&
+             currentMask != newMask ) {  /* modifier down event */
+         
+            key.sym = mapping [ newMask >> offset ];
+            SDL_PrivateKeyboard (SDL_PRESSED, &key);
+        }
+    }
+    
+    currentMods = newMods;
+}
+
+static void QZ_DoActivate (_THIS, NSPoint p) {
+    
+    inForeground = YES;
+
+    /* Regrab the mouse */
+    if (currentGrabMode == SDL_GRAB_ON) {
+        QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
+        CGAssociateMouseAndMouseCursorPosition (0);
+    }
+    
+    SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS);
+}
+
+static void QZ_DoDeactivate (_THIS) {
+    
+    inForeground = NO;
+
+    /* Ungrab mouse if it is grabbed */
+    if (currentGrabMode == SDL_GRAB_ON) {
+        CGAssociateMouseAndMouseCursorPosition (1);
+    }
+    
+    SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS);
+}
+
+static void QZ_PumpEvents (_THIS) { 
+
+    NSDate *distantPast = [ NSDate distantPast ];
+    
+    //NSAutoreleasePool *pool;
+    //pool = [ [ NSAutoreleasePool alloc ] init ];
+    
+    NSEvent *event;
+    NSRect winRect;
+    NSRect titleBarRect;
+            
+    winRect = NSMakeRect (0, 0, SDL_VideoSurface->w + 1, SDL_VideoSurface->h + 1);
+    titleBarRect = NSMakeRect ( 0, SDL_VideoSurface->h, SDL_VideoSurface->w,
+        SDL_VideoSurface->h + 22 );
+            
+    do {
+    
+        /* Poll for an event. This will not block */
+        event = [ NSApp nextEventMatchingMask:NSAnyEventMask
+                    untilDate:distantPast
+                    inMode: NSDefaultRunLoopMode dequeue:YES ];
+    
+        if (event != nil) {
+            unsigned int type;
+            NSPoint p;
+            
+            type = [ event type ];
+            p = [ event locationInWindow ];
+            
+            #define DO_MOUSE_DOWN(button, sendToWindow)                                                \
+                if ( inForeground ) {                                                                  \
+                    if ( NSPointInRect(p,winRect))                                                     \
+                        SDL_PrivateMouseButton (SDL_PRESSED, button, p.x, SDL_VideoSurface->h - p.y);  \
+                    else if (sendToWindow)                                                             \
+                            [ window sendEvent:event ];                                                   \
+                }                                                                                      \
+                else {                                                                                 \
+                    QZ_DoActivate (this, p);                                                           \
+                }       
+            
+            #define DO_MOUSE_UP(button, sendToWindow)                                          \
+                if ( ! NSPointInRect (p, titleBarRect) ) \
+                    SDL_PrivateMouseButton (SDL_RELEASED, button, p.x, SDL_VideoSurface->h - p.y); \
+                if (sendToWindow)                                                              \
+                    [ window sendEvent:event ]
+                    
+            switch ( type) {
+            
+            case NSLeftMouseDown:  
+                if ( NSCommandKeyMask & currentMods ) {
+                        DO_MOUSE_DOWN (3, 0);
+                } 
+                else if ( NSAlternateKeyMask & currentMods ) {
+                    DO_MOUSE_DOWN (2, 0);
+                } 
+                else {
+                    DO_MOUSE_DOWN (1, 1);
+                }
+                break;
+            case 25:               DO_MOUSE_DOWN (2, 0); break;
+            case NSRightMouseDown: DO_MOUSE_DOWN (3, 0); break;   
+            case NSLeftMouseUp:    
+            if ( NSCommandKeyMask & currentMods ) {
+                        DO_MOUSE_UP (3, 0);
+                } 
+                else if ( NSAlternateKeyMask & currentMods ) {
+                    DO_MOUSE_UP (2, 0);
+                } 
+                else
+                    DO_MOUSE_UP (1, 1);
+                break;
+            case 26:               DO_MOUSE_UP (2, 0);   break;
+            case NSRightMouseUp:   DO_MOUSE_UP (3, 0);   break;
+            case NSSystemDefined:
+                //if ([event subtype] == 7) {
+                //    unsigned int buttons;   // up to 32 mouse button states!
+                //    buttons = [ event data2 ];
+                //}
+                break;
+            case NSLeftMouseDragged:
+            case NSRightMouseDragged:
+            case 27:
+                SDL_PrivateMouseMotion (SDL_PRESSED, 0, p.x, SDL_VideoSurface->h - p.y);
+                break;
+            case NSMouseMoved:
+                {
+                   static int moves = 0;
+                    
+                   if ( (moves % 10) == 0 ) {
+                        SDL_PrivateMouseMotion (SDL_RELEASED, 0, p.x, SDL_VideoSurface->h - p.y);
+                        moves = 0;
+                   }
+                   else {
+                        CGMouseDelta dx, dy;
+                        CGGetLastMouseDelta (&dx, &dy);
+                        SDL_PrivateMouseMotion (SDL_RELEASED, 1, dx, dy);
+                        moves++;
+                   }
+                }
+                break;
+            case NSScrollWheel:
+                {
+                    if (NSPointInRect(p, winRect)) {
+                        float dy;
+                        dy = [ event deltaY ];
+                        if ( dy > 0.0 ) /* Scroll up */
+                            SDL_PrivateMouseButton (SDL_PRESSED, 4, p.x, SDL_VideoSurface->h - p.y);
+                        else /* Scroll down */
+                            SDL_PrivateMouseButton (SDL_PRESSED, 5, p.x, SDL_VideoSurface->h - p.y);
+                    }
+                }
+                break;
+            case NSKeyUp:
+                QZ_DoKey (SDL_RELEASED, event);
+                break;
+            case NSKeyDown:
+                QZ_DoKey (SDL_PRESSED, event);
+                break;
+            case NSFlagsChanged:
+                QZ_DoModifiers( [ event modifierFlags ] );
+                break;
+            case NSMouseEntered: break;
+            case NSMouseExited: break;
+            case NSAppKitDefined:
+                switch ( [ event subtype ] ) {
+                case NSApplicationActivatedEventType:
+                    QZ_DoActivate (this, p);
+                    break;
+                case NSApplicationDeactivatedEventType:
+                    QZ_DoDeactivate (this);
+                    break;
+                case NSWindowMovedEventType:
+                    [ window sendEvent:event ];
+                    break;
+                }
+                break;
+            case NSApplicationDefined: break;
+            case NSPeriodic: break;
+            case NSCursorUpdate: break;
+            }
+        }
+       // [ pool release ];
+
+      } while (event != nil);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/quartz/SDL_QuartzKeys.h	Thu Jun 07 14:28:11 2001 +0000
@@ -0,0 +1,140 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@devolution.com
+*/
+
+/* These are the Macintosh key scancode constants -- from Inside Macintosh */
+
+#define QZ_ESCAPE		0x35
+#define QZ_F1			0x7A
+#define QZ_F2			0x78
+#define QZ_F3			0x63
+#define QZ_F4			0x76
+#define QZ_F5			0x60
+#define QZ_F6			0x61
+#define QZ_F7			0x62
+#define QZ_F8			0x64
+#define QZ_F9			0x65
+#define QZ_F10			0x6D
+#define QZ_F11			0x67
+#define QZ_F12			0x6F
+#define QZ_PRINT		0x69
+#define QZ_SCROLLOCK		0x6B
+#define QZ_PAUSE		0x71
+#define QZ_POWER		0x7F
+#define QZ_BACKQUOTE		0x32
+#define QZ_1			0x12
+#define QZ_2			0x13
+#define QZ_3			0x14
+#define QZ_4			0x15
+#define QZ_5			0x17
+#define QZ_6			0x16
+#define QZ_7			0x1A
+#define QZ_8			0x1C
+#define QZ_9			0x19
+#define QZ_0			0x1D
+#define QZ_MINUS		0x1B
+#define QZ_EQUALS		0x18
+#define QZ_BACKSPACE		0x33
+#define QZ_INSERT		0x72
+#define QZ_HOME			0x73
+#define QZ_PAGEUP		0x74
+#define QZ_NUMLOCK		0x47
+#define QZ_KP_EQUALS		0x51
+#define QZ_KP_DIVIDE		0x4B
+#define QZ_KP_MULTIPLY		0x43
+#define QZ_TAB			0x30
+#define QZ_q			0x0C
+#define QZ_w			0x0D
+#define QZ_e			0x0E
+#define QZ_r			0x0F
+#define QZ_t			0x11
+#define QZ_y			0x10
+#define QZ_u			0x20
+#define QZ_i			0x22
+#define QZ_o			0x1F
+#define QZ_p			0x23
+#define QZ_LEFTBRACKET		0x21
+#define QZ_RIGHTBRACKET		0x1E
+#define QZ_BACKSLASH		0x2A
+#define QZ_DELETE		0x75
+#define QZ_END			0x77
+#define QZ_PAGEDOWN		0x79
+#define QZ_KP7			0x59
+#define QZ_KP8			0x5B
+#define QZ_KP9			0x5C
+#define QZ_KP_MINUS		0x4E
+#define QZ_CAPSLOCK		0x39
+#define QZ_a			0x00
+#define QZ_s			0x01
+#define QZ_d			0x02
+#define QZ_f			0x03
+#define QZ_g			0x05
+#define QZ_h			0x04
+#define QZ_j			0x26
+#define QZ_k			0x28
+#define QZ_l			0x25
+#define QZ_SEMICOLON		0x29
+#define QZ_QUOTE		0x27
+#define QZ_RETURN		0x24
+#define QZ_KP4			0x56
+#define QZ_KP5			0x57
+#define QZ_KP6			0x58
+#define QZ_KP_PLUS		0x45
+#define QZ_LSHIFT		0x38
+#define QZ_z			0x06
+#define QZ_x			0x07
+#define QZ_c			0x08
+#define QZ_v			0x09
+#define QZ_b			0x0B
+#define QZ_n			0x2D
+#define QZ_m			0x2E
+#define QZ_COMMA		0x2B
+#define QZ_PERIOD		0x2F
+#define QZ_SLASH		0x2C
+#if 0	/* These are the same as the left versions - use left by default */
+#define QZ_RSHIFT		0x38
+#endif
+#define QZ_UP			0x7E
+#define QZ_KP1			0x53
+#define QZ_KP2			0x54
+#define QZ_KP3			0x55
+#define QZ_KP_ENTER		0x4C
+#define QZ_LCTRL		0x3B
+#define QZ_LALT			0x3A
+#define QZ_LMETA		0x37
+#define QZ_SPACE		0x31
+#if 0	/* These are the same as the left versions - use left by default */
+#define QZ_RMETA		0x37
+#define QZ_RALT			0x3A
+#define QZ_RCTRL		0x3B
+#endif
+#define QZ_LEFT			0x7B
+#define QZ_DOWN			0x7D
+#define QZ_RIGHT		0x7C
+#define QZ_KP0			0x52
+#define QZ_KP_PERIOD		0x41
+
+/* Wierd, these keys are on my iBook under MacOS X */
+#define QZ_IBOOK_ENTER		0x34
+#define QZ_IBOOK_LEFT		0x3B
+#define QZ_IBOOK_RIGHT		0x3C
+#define QZ_IBOOK_DOWN		0x3D
+#define QZ_IBOOK_UP		0x3E
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/quartz/SDL_QuartzVideo.h	Thu Jun 07 14:28:11 2001 +0000
@@ -0,0 +1,183 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@devolution.com
+*/
+
+/*	
+    @file   SDL_QuartzVideo.h
+    @author Darrell Walisser
+    
+    @abstract SDL video driver for MacOS X.
+    
+    @discussion
+    
+    TODO
+        - Hardware Cursor support with NSCursor instead of Carbon
+        - Keyboard repeat/mouse speed adjust (if needed)
+        - Multiple monitor support (currently only main display)
+        - Accelerated blitting support
+        - Set the window icon (dock icon when API is available)
+        - Avoid erasing window on minimize, or disable minimize
+    Problems:
+        - OGL not working in full screen with software renderer
+        - SetColors sets palette correctly but clears framebuffer
+        - Crash in CG after several mode switches
+        - Retained windows don't draw their title bar quite right (OS Bug)
+        - Should I do depth switching for windowed modes?
+        - 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>
+#include <OpenGL/OpenGL.h>
+#include <Cocoa/Cocoa.h>
+#include <Carbon/Carbon.h>
+
+#include "SDL_video.h"
+#include "SDL_error.h"
+#include "SDL_syswm.h"
+#include "SDL_sysvideo.h"
+#include "SDL_pixels_c.h"
+#include "SDL_events_c.h"
+
+/* This is a workaround to directly access NSOpenGLContext's CGL context */
+/* We need to do this in order to check for errors */
+@interface NSOpenGLContext (CGLContextAccess)
+- (CGLContextObj) cglContext;
+@end
+
+@implementation NSOpenGLContext (CGLContextAccess)
+- (CGLContextObj) cglContext;
+{
+    return _contextAuxiliary;
+}
+@end
+
+typedef struct SDL_PrivateVideoData {
+
+    CGDirectDisplayID  display; /* 0 == main display */
+    CFDictionaryRef    mode;
+    CFDictionaryRef    save_mode;
+    CFArrayRef         mode_list;
+    CGDirectPaletteRef palette;
+    NSOpenGLContext    *gl_context;
+    int                width, height, bpp;
+    Uint32             flags;
+    
+    /* Window-only fields */
+    NSWindow        *window;
+    NSQuickDrawView *view;
+    NSString        *title;
+    
+} SDL_PrivateVideoData ;
+
+#define _THIS	SDL_VideoDevice *this
+#define display_id (this->hidden->display)
+#define mode (this->hidden->mode)
+#define save_mode (this->hidden->save_mode)
+#define mode_list (this->hidden->mode_list)
+#define palette (this->hidden->palette)
+#define glcontext (this->hidden->glcontext)
+#define objc_video (this->hidden->objc_video)
+#define gl_context (this->hidden->gl_context)
+#define device_width (this->hidden->width)
+#define device_height (this->hidden->height)
+#define device_bpp (this->hidden->bpp)
+#define mode_flags (this->hidden->flags)
+#define window (this->hidden->window)
+#define windowView (this->hidden->view)
+#define windowTitle (this->hidden->title)
+
+/* Interface for hardware fill not (yet) in the public API */
+int CGSDisplayHWFill (CGDirectDisplayID id, unsigned int x, unsigned int y, 
+                      unsigned int w, unsigned int h, unsigned int color);
+int CGSDisplayCanHWFill (CGDirectDisplayID id);
+
+/* Bootstrap functions */
+static int              QZ_Available ();
+static SDL_VideoDevice* QZ_CreateDevice (int device_index);
+static void             QZ_DeleteDevice (SDL_VideoDevice *device);
+
+/* Initialization, Query, Setup, and Redrawing functions */
+static int          QZ_VideoInit        (_THIS, SDL_PixelFormat *video_format);
+
+static SDL_Rect**   QZ_ListModes        (_THIS, SDL_PixelFormat *format, 
+					 Uint32 flags);
+static void         QZ_UnsetVideoMode   (_THIS);
+
+static SDL_Surface* QZ_SetVideoMode     (_THIS, SDL_Surface *current, 
+					 int width, int height, int bpp, 
+					 Uint32 flags);
+static int          QZ_ToggleFullScreen (_THIS, int on);
+static int          QZ_SetColors        (_THIS, int first_color, 
+					 int num_colors, SDL_Color *colors);
+static void         QZ_DirectUpdate     (_THIS, int num_rects, SDL_Rect *rects);
+static void         QZ_UpdateRects      (_THIS, int num_rects, SDL_Rect *rects);
+static void         QZ_VideoQuit        (_THIS);
+
+/* Hardware surface functions (for fullscreen mode only) */
+static int  QZ_FillHWRect (_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color);
+static int  QZ_LockHWSurface(_THIS, SDL_Surface *surface);
+static void QZ_UnlockHWSurface(_THIS, SDL_Surface *surface);
+static void QZ_FreeHWSurface (_THIS, SDL_Surface *surface);
+/* static int  QZ_FlipHWSurface (_THIS, SDL_Surface *surface); */
+
+/* Gamma Functions */
+static int QZ_SetGamma     (_THIS, float red, float green, float blue);
+static int QZ_GetGamma     (_THIS, float *red, float *green, float *blue);
+static int QZ_SetGammaRamp (_THIS, Uint16 *ramp);
+static int QZ_GetGammaRamp (_THIS, Uint16 *ramp);
+
+/* OpenGL functions */
+static int    QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags);
+static void   QZ_TearDownOpenGL (_THIS);
+static void*  QZ_GL_GetProcAddress (_THIS, const char *proc);
+static int    QZ_GL_GetAttribute   (_THIS, SDL_GLattr attrib, int* value);
+static int    QZ_GL_MakeCurrent    (_THIS);
+static void   QZ_GL_SwapBuffers    (_THIS);
+static int    QZ_GL_LoadLibrary    (_THIS, const char *location);
+
+/* Private function to warp the cursor (used internally) */
+static void  QZ_PrivateWarpCursor (_THIS, int fullscreen, int h, int x, int y);
+
+/* Cursor and Mouse functions */
+static void         QZ_FreeWMCursor     (_THIS, WMcursor *cursor);
+static WMcursor*    QZ_CreateWMCursor   (_THIS, Uint8 *data, Uint8 *mask, 
+                                          int w, int h, int hot_x, int hot_y);
+static int          QZ_ShowWMCursor     (_THIS, WMcursor *cursor);
+static void         QZ_WarpWMCursor     (_THIS, Uint16 x, Uint16 y);
+static void         QZ_MoveWMCursor     (_THIS, int x, int y);
+static void         QZ_CheckMouseMode   (_THIS);
+
+/* Event functions */
+static void         QZ_InitOSKeymap     (_THIS);
+static void         QZ_PumpEvents       (_THIS);
+
+/* Window Manager functions */
+static void QZ_SetCaption    (_THIS, const char *title, const char *icon);
+static void QZ_SetIcon       (_THIS, SDL_Surface *icon, Uint8 *mask);
+static int  QZ_IconifyWindow (_THIS);
+static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode);
+/*static int  QZ_GetWMInfo     (_THIS, SDL_SysWMinfo *info);*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/quartz/SDL_QuartzVideo.m	Thu Jun 07 14:28:11 2001 +0000
@@ -0,0 +1,756 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@devolution.com
+*/
+
+#include "SDL_QuartzVideo.h"
+
+/* Some variables to share among files, put in device structure eventually */
+static SDL_GrabMode currentGrabMode = SDL_GRAB_OFF;
+static BOOL   inForeground = YES;
+static SDLKey keymap[256];
+static unsigned int currentMods = 0; /* Current keyboard modifiers, to track modifier state */
+
+/* Include files into one compile unit...break apart eventually */
+#include "SDL_QuartzWM.m"
+#include "SDL_QuartzEvents.m"
+#include "SDL_QuartzWindow.m"
+
+char QZ_Error[255]; /* Global error buffer to temporarily store more informative error messages */
+
+/* Bootstrap binding, enables entry point into the driver */
+VideoBootStrap QZ_bootstrap = {
+    "Quartz", "MacOS X CoreGraphics", QZ_Available, QZ_CreateDevice
+};
+
+/* Bootstrap functions */
+static int QZ_Available () {
+    return 1;
+}
+
+static SDL_VideoDevice* QZ_CreateDevice (int device_index) {
+
+   #pragma unused (device_index)
+
+    SDL_VideoDevice *device;
+    SDL_PrivateVideoData *hidden;
+
+    device = (SDL_VideoDevice*) malloc (sizeof (*device) );
+    hidden = (SDL_PrivateVideoData*) malloc (sizeof (*hidden) );
+
+    if (device == NULL || hidden == NULL)
+        SDL_OutOfMemory ();
+
+    memset (device, 0, sizeof (*device) );
+    memset (hidden, 0, sizeof (*hidden) );
+    
+    device->hidden = hidden;
+
+    device->VideoInit        = QZ_VideoInit;
+    device->ListModes        = QZ_ListModes;
+    device->SetVideoMode     = QZ_SetVideoMode;
+    device->ToggleFullScreen = QZ_ToggleFullScreen;
+    device->SetColors        = QZ_SetColors;
+    /* device->UpdateRects      = QZ_UpdateRects; this is determined by SetVideoMode() */
+    device->VideoQuit        = QZ_VideoQuit;
+    
+    device->LockHWSurface   = QZ_LockHWSurface;
+    device->UnlockHWSurface = QZ_UnlockHWSurface;
+    device->FreeHWSurface   = QZ_FreeHWSurface;
+    /* device->FlipHWSurface   = QZ_FlipHWSurface */;
+
+    device->SetGamma     = QZ_SetGamma;
+    device->GetGamma     = QZ_GetGamma;
+    device->SetGammaRamp = QZ_SetGammaRamp;
+    device->GetGammaRamp = QZ_GetGammaRamp;
+
+    device->GL_GetProcAddress = QZ_GL_GetProcAddress;
+    device->GL_GetAttribute   = QZ_GL_GetAttribute;
+    device->GL_MakeCurrent    = QZ_GL_MakeCurrent;
+    device->GL_SwapBuffers    = QZ_GL_SwapBuffers;
+    device->GL_LoadLibrary    = QZ_GL_LoadLibrary;
+    
+    device->FreeWMCursor   = QZ_FreeWMCursor;
+    device->CreateWMCursor = QZ_CreateWMCursor;
+    device->ShowWMCursor   = QZ_ShowWMCursor;
+    device->WarpWMCursor   = QZ_WarpWMCursor;
+    device->MoveWMCursor   = QZ_MoveWMCursor;
+    device->CheckMouseMode = QZ_CheckMouseMode;
+    device->InitOSKeymap   = QZ_InitOSKeymap;
+    device->PumpEvents     = QZ_PumpEvents;
+
+    device->SetCaption    = QZ_SetCaption;
+    device->SetIcon       = QZ_SetIcon;
+    device->IconifyWindow = QZ_IconifyWindow;
+    /*device->GetWMInfo     = QZ_GetWMInfo;*/
+    device->GrabInput     = QZ_GrabInput;
+    
+    device->free = QZ_DeleteDevice;
+    
+    return device;
+}
+
+static void QZ_DeleteDevice (SDL_VideoDevice *device) {
+
+    free (device->hidden);
+    free (device);
+}
+
+static int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format) {
+
+  /* Initialize the video settings; this data persists between mode switches */
+  display_id = kCGDirectMainDisplay; 
+  save_mode  = CGDisplayCurrentMode    (display_id);
+  mode_list  = CGDisplayAvailableModes (display_id);
+  palette    = CGPaletteCreateDefaultColorPalette ();
+  
+  /* Gather some information that is useful to know about the display */
+  CFNumberGetValue (CFDictionaryGetValue (save_mode, kCGDisplayBitsPerPixel), 
+		    kCFNumberSInt32Type, &device_bpp);
+
+  CFNumberGetValue (CFDictionaryGetValue (save_mode, kCGDisplayWidth),
+                    kCFNumberSInt32Type, &device_width);
+  
+  CFNumberGetValue (CFDictionaryGetValue (save_mode, kCGDisplayHeight),
+                    kCFNumberSInt32Type, &device_height);
+
+  video_format->BitsPerPixel = device_bpp;
+  windowTitle = @"";
+  
+  return 0;
+}
+
+static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
+    
+    CFIndex num_modes = CFArrayGetCount (mode_list);
+    CFIndex i;
+
+    static SDL_Rect **list = NULL;
+    int list_size = 0;
+
+    /* Any windowed mode is acceptable */
+    if ( (flags & SDL_FULLSCREEN) == 0 )
+        return (SDL_Rect**)-1;
+        
+    /* Free memory from previous call, if any */
+    if ( list != NULL ) {
+
+      int i = 0;
+
+      for (i = 0; list[i] != NULL; i++)
+	free (list[i]);
+
+      free (list);
+      list = NULL;
+    }
+
+    /* Build list of modes with the requested bpp */
+    for (i = num_modes-1; i >= 0; i--) {
+   
+        CFDictionaryRef onemode = CFArrayGetValueAtIndex (mode_list, i);
+	CFNumberRef     number;
+	int bpp;
+	
+	number = CFDictionaryGetValue (onemode, kCGDisplayBitsPerPixel);
+	CFNumberGetValue (number, kCFNumberSInt32Type, &bpp);
+
+	if (bpp == format->BitsPerPixel) {
+	  
+	  int       intvalue;
+	  SDL_Rect *rect;
+          int       lastwidth = 0, lastheight = 0, width, height;
+
+	  number = CFDictionaryGetValue (onemode, kCGDisplayWidth);
+	  CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue);
+	  width = (Uint16) intvalue;
+	  
+	  number = CFDictionaryGetValue (onemode, kCGDisplayHeight);
+	  CFNumberGetValue (number, kCFNumberSInt32Type, &intvalue);
+	  height = (Uint16) intvalue;
+          
+          /* We'll get a lot of modes with the same size, so ignore them */
+          if ( width != lastwidth && height != lastheight ) {
+
+            lastwidth  = width;
+            lastheight = height;
+	  
+            list_size++;
+
+            if ( list == NULL)
+                list = (SDL_Rect**) malloc (sizeof(*list) * list_size+1);
+            else
+                list = (SDL_Rect**) realloc (list, sizeof(*list) * list_size+1);
+            
+            rect = (SDL_Rect*) malloc (sizeof(**list));
+            
+            if (list == NULL || rect == NULL)
+                SDL_OutOfMemory ();
+    
+            rect->w = width;
+            rect->h = height;
+    
+            list[list_size-1] = rect;
+            list[list_size]   = NULL;
+        }
+      }
+    }
+    
+    return list;
+}
+
+static void QZ_UnsetVideoMode (_THIS) {
+
+    if ( mode_flags & SDL_OPENGL )
+        QZ_TearDownOpenGL (this);
+
+    /* Reset values that may change between switches */
+    this->info.blit_fill = 0;
+    this->FillHWRect     = NULL;
+    this->UpdateRects    = NULL;
+    
+    /* Restore gamma settings */
+    CGDisplayRestoreColorSyncSettings ();
+   
+    /* Restore original screen resolution */
+    if ( mode_flags & SDL_FULLSCREEN ) {
+        CGDisplaySwitchToMode (display_id, save_mode);
+        CGDisplayRelease (display_id);
+    }
+    /* Release window mode data structures */
+    else { 
+        if ( (mode_flags & SDL_OPENGL) == 0 ) {
+            UnlockPortBits ( [ windowView qdPort ] );
+            [ windowView release  ];
+        }
+        [ window setContentView:nil ];
+        [ window close ];
+        [ window release ];
+    }
+    
+    /* Ensure the cursor will be visible and working when we quit */
+    CGDisplayShowCursor (display_id);
+    CGAssociateMouseAndMouseCursorPosition (1);
+}
+
+static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int width,
+                                           int height, int bpp, Uint32 flags) {
+    int exact_match;
+
+    /* See if requested mode exists */
+    mode = CGDisplayBestModeForParameters (display_id, bpp, width, 
+					   height, &exact_match);
+    
+    /* Require an exact match to the requested mode */
+    if ( ! exact_match ) {
+        sprintf (QZ_Error, "Failed to find display resolution: %dx%dx%d", width, height, bpp);
+        SDL_SetError (QZ_Error);
+        goto ERR_NO_MATCH;
+    }
+    
+    /* Put up the blanking window (a window above all other windows) */
+    if ( CGDisplayNoErr != CGDisplayCapture (display_id) ) {
+        SDL_SetError ("Failed capturing display");
+        goto ERR_NO_CAPTURE;
+    }
+    
+    /* Do the physical switch */
+    if ( CGDisplayNoErr != CGDisplaySwitchToMode (display_id, mode) ) {
+        SDL_SetError ("Failed switching display resolution");
+        goto ERR_NO_SWITCH;
+    }
+    
+    /* None of these methods seem to fix the fullscreen artifacts bug(s) */
+#if USE_GDHANDLE
+    SetGDevice(GetMainDevice());
+    current->pitch = (**(**  GetMainDevice() ).gdPMap).rowBytes & 0x3FFF;
+    current->pixels = (**(** GetMainDevice() ).gdPMap).baseAddr;
+#elif USE_CREATEPORT
+    device_port = CreateNewPortForCGDisplayID((Uint32*)display_id);
+    SetPort (device_port);
+    LockPortBits ( device_port );
+    current->pixels = GetPixBaseAddr ( GetPortPixMap ( device_port ) );
+    current->pitch  = GetPixRowBytes ( GetPortPixMap ( device_port ) );
+    UnlockPortBits ( device_port );
+#else
+    current->pixels = (Uint32*) CGDisplayBaseAddress (display_id);
+    current->pitch  = CGDisplayBytesPerRow (display_id);
+#endif
+
+    current->w = width;
+    current->h = height;
+    current->flags |= SDL_FULLSCREEN;  
+    current->flags |= SDL_HWSURFACE;
+   
+    this->UpdateRects = QZ_DirectUpdate;
+    
+    /* Setup some mode-dependant info */
+    if ( CGSDisplayCanHWFill (display_id) ) {
+         this->info.blit_fill = 1;
+         this->FillHWRect = QZ_FillHWRect;
+    }
+        
+    if ( CGDisplayCanSetPalette (display_id) )
+        current->flags |= SDL_HWPALETTE;
+    
+    /* Setup OpenGL for a fullscreen context */
+    if (flags & SDL_OPENGL) {
+
+        CGLError err;
+        CGLContextObj ctx;
+        
+        if ( ! QZ_SetupOpenGL (this, bpp, flags) ) {
+            return NULL;
+        }
+       
+        ctx = [ gl_context cglContext ];
+        err = CGLSetFullScreen (ctx);
+        
+        if (err) {
+            sprintf (QZ_Error, "Error setting OpenGL fullscreen: %s", CGLErrorString(err));
+            SDL_SetError (QZ_Error);
+            goto ERR_NO_GL;
+        }
+         
+        [ gl_context makeCurrentContext];
+        
+        current->flags |= SDL_OPENGL;
+    }
+
+    /* If we don't hide menu bar, it will get events and interrupt the program */
+    HideMenuBar ();
+    
+    /* Save the flags to ensure correct tear-down */
+    mode_flags = current->flags;
+    
+    return current;
+
+ /* Since the blanking window covers *all* windows (even force quit) correct recovery is crutial */
+ ERR_NO_GL:      CGDisplaySwitchToMode (display_id, save_mode);
+ ERR_NO_SWITCH:  CGDisplayRelease (display_id);
+ ERR_NO_CAPTURE:
+ ERR_NO_MATCH:	return NULL;
+}
+
+static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
+                                           int height, int bpp, Uint32 flags) {    
+    NSRect rect;    
+    rect = NSMakeRect (0, 0, width, height);
+    
+    /* Manually create a window, avoids having a nib file resource */
+    window = [ [ SDL_QuartzWindow alloc ] initWithContentRect:rect 
+        styleMask:(NSTitledWindowMask | NSMiniaturizableWindowMask)
+        backing: //NSBackingStoreBuffered
+            NSBackingStoreRetained
+          defer:NO ];
+    
+    if (window == nil) {
+        SDL_SetError ("Could not create the Cocoa window");
+        return NULL;
+    }
+    
+    current->w  = width;
+    current->h = height;
+    
+    [ window setTitle:windowTitle ];
+    [ window setAcceptsMouseMovedEvents:YES ];
+    [ window center ];
+        
+    /* For OpenGL, we set the content view to a NSOpenGLView */
+    if ( flags & SDL_OPENGL ) {
+    
+        if ( ! QZ_SetupOpenGL (this, bpp, flags) ) {
+            return NULL;
+        }
+        
+        [ gl_context setView: [ window contentView ] ];
+        [ gl_context makeCurrentContext];
+        [ window orderFront:nil ];
+        current->flags |= SDL_OPENGL;
+    }
+    /* For 2D, we set the content view to a NSQuickDrawView */
+    else {
+    
+        windowView = [ [ NSQuickDrawView alloc ] init ];
+        [ window setContentView:windowView ];
+        [ window orderFront:nil ];    
+        
+        LockPortBits ( [ windowView qdPort ] );
+        current->pixels = GetPixBaseAddr ( GetPortPixMap ( [ windowView qdPort ] ) );
+        current->pitch  = GetPixRowBytes ( GetPortPixMap ( [ windowView qdPort ] ) );
+            
+        /* Offset 22 pixels down to fill the full content region */
+        current->pixels += 22 * current->pitch;
+        
+        current->flags |= SDL_SWSURFACE;
+        current->flags |= SDL_PREALLOC;
+
+        this->UpdateRects = QZ_UpdateRects;
+    }
+    return current;
+}
+
+static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width, 
+				     int height, int bpp, Uint32 flags) {
+
+    if (SDL_VideoSurface != NULL)
+        QZ_UnsetVideoMode (this);
+       
+    current->flags = 0;
+    
+    /* Setup full screen video */
+    if ( flags & SDL_FULLSCREEN ) {
+        current = QZ_SetVideoFullScreen (this, current, width, height, bpp, flags );
+        if (current == NULL)
+            return NULL;
+    }
+    /* Setup windowed video */
+    else {
+        /* Force bpp to the device's bpp */
+        bpp = current->format->BitsPerPixel;
+        current = QZ_SetVideoWindowed (this, current, width, height, bpp, flags);
+        if (current == NULL)
+            return NULL;
+    }
+    
+    /* Setup the new pixel format */
+    {
+        int amask = 0, 
+            rmask = 0, 
+            gmask = 0,
+            bmask = 0;
+            
+        switch (bpp) {
+            case 16:   /* (1)-5-5-5 RGB */
+                amask = 0; 
+                rmask = 0x7c00;
+                gmask = 0x3e0;
+                bmask = 0x1f;
+                break;
+            case 24:
+                SDL_SetError ("24bpp is not available");
+                return NULL;
+            case 32:   /* (8)-8-8-8 ARGB */
+                amask = 0xFF000000;
+                rmask = 0x00FF0000;
+                gmask = 0x0000FF00;
+                bmask = 0x000000FF;
+                break;
+        }
+        
+        if ( ! SDL_ReallocFormat (current, bpp,
+                                  rmask, gmask, bmask, amask ) ) {
+       	   SDL_SetError ("Couldn't reallocate pixel format");
+           return NULL;
+       	}
+    }
+    
+    /* Warp mouse to origin in order to get passive mouse motion events started correctly */
+    QZ_PrivateWarpCursor (this, current->flags & SDL_FULLSCREEN, height, 0, 0);
+    
+    return current;
+}
+
+static int QZ_ToggleFullScreen (_THIS, int on) { 
+    return -1;
+}
+
+static int QZ_SetColors (_THIS, int first_color, int num_colors, 
+			 SDL_Color *colors) {
+
+    CGTableCount  index;
+    CGDeviceColor color;
+    
+    for (index = first_color; index < first_color+num_colors; index++) {
+    
+        /* Clamp colors between 0.0 and 1.0 */
+        color.red   = colors->r / 255.0;
+        color.blue  = colors->b / 255.0;
+        color.green = colors->g / 255.0;
+        
+        colors++;
+        
+        CGPaletteSetColorAtIndex (palette, color, index);
+    }
+     
+    if ( CGDisplayNoErr != CGDisplaySetPalette (display_id, palette) )
+        return 0;
+        
+    return 1;
+}
+
+static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects) {
+    #pragma unused(this,num_rects,rects)
+}
+
+static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) { 
+    
+    if (SDL_VideoSurface->flags & SDL_OPENGLBLIT) {
+        QZ_GL_SwapBuffers (this);
+    }
+    else {
+        int i;
+        RgnHandle dirty = NewRgn ();
+        RgnHandle temp  = NewRgn ();
+        
+        SetEmptyRgn (dirty);
+        
+        /* Build the region of dirty rectangles */
+        for (i = 0; i < numRects; i++) {
+        
+            MacSetRectRgn (temp, rects[i].x, rects[i].y, 
+                rects[i].x + rects[i].w, rects[i].y + rects[i].h);
+            MacUnionRgn (dirty, temp, dirty);
+        }
+        
+        /* Flush the dirty region */
+        QDFlushPortBuffer ( [ windowView qdPort ], dirty );
+        DisposeRgn (dirty);
+        DisposeRgn (temp);
+    }
+}
+
+static void QZ_VideoQuit (_THIS) {
+
+    QZ_UnsetVideoMode (this);
+    CGPaletteRelease (palette);
+}
+
+static int  QZ_FillHWRect (_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color) {
+
+    CGSDisplayHWFill (display_id, rect->x, rect->y, rect->w, rect->h, color);
+    return 0;
+}
+
+static int  QZ_LockHWSurface(_THIS, SDL_Surface *surface) { 
+
+    return 1;
+}
+
+static void QZ_UnlockHWSurface(_THIS, SDL_Surface *surface) { 
+}
+
+static void QZ_FreeHWSurface (_THIS, SDL_Surface *surface) {
+}
+
+/*
+int QZ_FlipHWSurface (_THIS, SDL_Surface *surface) {
+    return 0;
+}
+*/
+
+/* Gamma functions */
+static int QZ_SetGamma (_THIS, float red, float green, float blue) {
+
+    const CGGammaValue min = 0.0, max = 1.0;
+    
+    if ( CGDisplayNoErr != CGSetDisplayTransferByFormula 
+        (display_id, min, max, red, min, max, green, min, max, blue) )
+        return -1;
+    
+    return 0;
+}
+
+static int QZ_GetGamma (_THIS, float *red, float *green, float *blue) {
+
+    CGGammaValue dummy;
+    if ( CGDisplayNoErr != CGGetDisplayTransferByFormula
+        (display_id, &dummy, &dummy, red, 
+	 &dummy, &dummy, green, &dummy, &dummy, blue) )
+        
+        return -1;
+    
+    return 0;
+}
+
+static int QZ_SetGammaRamp (_THIS, Uint16 *ramp) {
+ 
+   const CGTableCount tableSize = 255;
+   CGGammaValue redTable[tableSize];
+   CGGammaValue greenTable[tableSize];
+   CGGammaValue blueTable[tableSize];
+   
+   int i;
+   
+   /* Extract gamma values into separate tables, convert to floats between 0.0 and 1.0 */
+   for (i = 0; i < 256; i++)
+    redTable[i % 256] = ramp[i] / 65535.0;
+   
+   for (i=256; i < 512; i++)
+    greenTable[i % 256] = ramp[i] / 65535.0;
+   
+   for (i=512; i < 768; i++)
+     blueTable[i % 256] = ramp[i] / 65535.0;
+     
+    if ( CGDisplayNoErr != CGSetDisplayTransferByTable 
+            (display_id, tableSize, redTable, greenTable, blueTable) )        
+        return -1;
+    
+    return 0;
+}
+
+static int QZ_GetGammaRamp (_THIS, Uint16 *ramp) {
+    
+    const CGTableCount tableSize = 255;
+    CGGammaValue redTable[tableSize];
+    CGGammaValue greenTable[tableSize];
+    CGGammaValue blueTable[tableSize];
+    CGTableCount actual;
+    int i;
+    
+    if ( CGDisplayNoErr != CGGetDisplayTransferByTable 
+            (display_id, tableSize, redTable, greenTable, blueTable, &actual) ||
+          actual != tableSize)
+        
+        return -1;
+    
+    /* Pack tables into one array, with values from 0 to 65535 */
+    for (i = 0; i < 256; i++)
+        ramp[i] = redTable[i % 256] * 65535.0;
+   
+    for (i=256; i < 512; i++)
+        ramp[i] = greenTable[i % 256] * 65535.0;
+   
+    for (i=512; i < 768; i++)
+        ramp[i] = blueTable[i % 256] * 65535.0;
+      
+    return 0;    
+}
+
+/* OpenGL helper functions */
+static int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags) {
+
+    NSOpenGLPixelFormatAttribute attr[32];
+    NSOpenGLPixelFormat *fmt;
+    int i = 0;
+    int colorBits = bpp;
+
+    if ( flags & SDL_FULLSCREEN ) {
+    
+        attr[i++] = NSOpenGLPFAFullScreen;
+    }
+    /* In windowed mode, the OpenGL pixel depth must match device pixel depth */
+    else if ( colorBits != device_bpp ) { 
+
+        colorBits = device_bpp;
+    }
+    
+    attr[i++] = NSOpenGLPFAColorSize;
+    attr[i++] = colorBits;
+    
+    attr[i++] = NSOpenGLPFADepthSize;
+    attr[i++] = this->gl_config.depth_size;
+
+    if ( this->gl_config.double_buffer ) {
+        attr[i++] = NSOpenGLPFADoubleBuffer;
+    }
+    
+    if ( this->gl_config.stencil_size != 0 ) {
+        attr[i++] = NSOpenGLPFAStencilSize;
+        attr[i++] = this->gl_config.stencil_size;
+    }
+    
+    attr[i++] = NSOpenGLPFAScreenMask;
+    attr[i++] = CGDisplayIDToOpenGLDisplayMask (display_id);
+    attr[i] = 0;
+    
+    fmt = [ [ NSOpenGLPixelFormat alloc ] initWithAttributes:attr ];
+    if (fmt == nil) {
+        SDL_SetError ("Failed creating OpenGL pixel format");
+        return 0;
+    }
+    
+    gl_context = [ [ NSOpenGLContext alloc ] initWithFormat:fmt 
+        shareContext:nil];
+    
+    if (gl_context == nil) {
+        SDL_SetError ("Failed creating OpenGL context");
+        return 0;
+    }	
+    
+    /* Convince SDL that the GL "driver" is loaded */
+    this->gl_config.driver_loaded = 1;
+    
+    [ fmt release ];
+    
+    return 1;
+}
+
+static void QZ_TearDownOpenGL (_THIS) {
+
+    [ NSOpenGLContext clearCurrentContext ];
+    [ gl_context clearDrawable ];
+    [ gl_context release ];
+}
+
+/* SDL OpenGL functions */
+
+static int    QZ_GL_LoadLibrary    (_THIS, const char *location) {
+    return 1;
+}
+
+static void*  QZ_GL_GetProcAddress (_THIS, const char *proc) {
+
+    /* We may want to cache the bundleRef at some point */
+    CFBundleRef bundle;
+    CFURLRef bundleURL = CFURLCreateWithFileSystemPath (kCFAllocatorDefault, 
+        CFSTR("/System/Library/Frameworks/OpenGL.framework"), kCFURLPOSIXPathStyle, true);
+    
+    CFStringRef functionName = CFStringCreateWithCString 
+        (kCFAllocatorDefault, proc, kCFStringEncodingASCII);
+    
+    void *function;
+    
+    bundle = CFBundleCreate (kCFAllocatorDefault, bundleURL);
+    assert (bundle != NULL);
+    
+    function = CFBundleGetFunctionPointerForName (bundle, functionName);
+
+    CFRelease ( bundleURL );
+    CFRelease ( functionName );
+    CFRelease ( bundle );
+    
+    return function;
+}
+
+static int    QZ_GL_GetAttribute   (_THIS, SDL_GLattr attrib, int* value) {
+
+/*
+    CGLContextRef ctx = [ gl_context cglContext ];
+    CGLContextParameter param;
+    
+    switch (attrib) {
+    case SDL_GL_RED_SIZE: param = CGLContextParameter break;
+    
+    }
+    
+    CGLGetParameter (ctx, param, (long*)value);
+*/
+    *value = -1;
+    return -1;
+}
+
+static int    QZ_GL_MakeCurrent    (_THIS) {
+    [ gl_context makeCurrentContext ];
+    return 0;
+}
+
+static void   QZ_GL_SwapBuffers    (_THIS) {
+    [ gl_context flushBuffer ];
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/quartz/SDL_QuartzWM.m	Thu Jun 07 14:28:11 2001 +0000
@@ -0,0 +1,175 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@devolution.com
+*/
+
+struct WMcursor {
+    Cursor curs;
+};
+
+static void QZ_FreeWMCursor     (_THIS, WMcursor *cursor) { 
+
+    if ( cursor != NULL )
+        free (cursor);
+}
+
+/* Use the Carbon cursor routines for now */
+static WMcursor*    QZ_CreateWMCursor   (_THIS, Uint8 *data, Uint8 *mask, 
+                                          int w, int h, int hot_x, int hot_y) { 
+	WMcursor *cursor;
+	int row, bytes;
+	cursor = (WMcursor *)malloc(sizeof(WMcursor));
+	if ( cursor == NULL ) {
+		SDL_OutOfMemory();
+		return(NULL);
+	}
+	memset(cursor, 0, sizeof(*cursor));
+		
+	bytes = (w/8);
+	if ( bytes > 2 ) {
+		bytes = 2;
+	}
+	for ( row=0; row<h && (row < 16); ++row ) {
+		memcpy(&cursor->curs.data[row], data, bytes);
+		data += w/8;
+	}
+	for ( row=0; row<h && (row < 16); ++row ) {
+		memcpy(&cursor->curs.mask[row], mask, bytes);
+		mask += w/8;
+	}
+	cursor->curs.hotSpot.h = hot_x;
+	cursor->curs.hotSpot.v = hot_y;
+	
+        return(cursor);
+}
+
+static int QZ_ShowWMCursor (_THIS, WMcursor *cursor) { 
+
+    static int visible = 1;
+    
+    if ( cursor == NULL) {
+        if ( visible ) {
+            HideCursor ();
+            visible = 0;
+        }
+    }
+    else {
+        SetCursor(&cursor->curs);
+        if ( ! visible ) {
+            ShowCursor ();
+            visible = 1;
+        }
+    }
+
+    return 1;
+}
+
+static void  QZ_PrivateWarpCursor (_THIS, int fullscreen, int h, int x, int y) {
+
+    CGPoint p;
+    
+    /* We require absolute screen coordiates for our warp */
+    p.x = x;
+    p.y = h - y;
+        
+    if ( fullscreen )
+        /* Already absolute coordinates */
+        CGDisplayMoveCursorToPoint(display_id, p);
+    else {
+        /* Convert to absolute screen coordinates */
+        NSPoint base, screen;
+        base = NSMakePoint (p.x, p.y);
+        screen = [ window convertBaseToScreen:base ];
+        p.x = screen.x;
+        p.y = device_height - screen.y;
+        CGDisplayMoveCursorToPoint (display_id, p);
+    }
+}
+
+static void QZ_WarpWMCursor     (_THIS, Uint16 x, Uint16 y) {
+    
+    /* Only allow warping when in foreground */
+    if ( ! inForeground )
+        return;
+            
+    /* Do the actual warp */
+    QZ_PrivateWarpCursor (this, SDL_VideoSurface->flags & SDL_FULLSCREEN, 
+        SDL_VideoSurface->h, x, y);
+    
+    /* Generate mouse moved event */
+    SDL_PrivateMouseMotion (SDL_RELEASED, 0, x, y);
+}
+
+static void QZ_MoveWMCursor     (_THIS, int x, int y) { }
+static void QZ_CheckMouseMode   (_THIS) { }
+
+static void QZ_SetCaption    (_THIS, const char *title, const char *icon) {
+
+    NSString *str = [ [ NSString alloc ] initWithCString:title ];
+    if (window != nil)
+        [ window setTitle:str ];
+
+    [ windowTitle release ];
+    windowTitle = str;
+}
+
+static void QZ_SetIcon       (_THIS, SDL_Surface *icon, Uint8 *mask) {
+/* Convert icon/mask to NSImage, assign with NSWindow's setMiniwindowImage method */
+}
+
+static int  QZ_IconifyWindow (_THIS) { 
+
+    /* Bug! minimize erases the framebuffer */
+    if ( ! [ window isMiniaturized ] ) {
+        [ window miniaturize:nil ];
+        return 1;
+    }
+    else {
+        SDL_SetError ("window already iconified");
+        return 0;
+    }
+}
+
+/*
+static int  QZ_GetWMInfo  (_THIS, SDL_SysWMinfo *info) { 
+    info->nsWindowPtr = window;
+    return 0; 
+}*/
+
+static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode) {
+
+    switch (grab_mode) {
+	case SDL_GRAB_QUERY:
+            break;
+	case SDL_GRAB_OFF:
+            CGAssociateMouseAndMouseCursorPosition (1);
+            currentGrabMode = SDL_GRAB_OFF;
+            break;
+	case SDL_GRAB_ON:
+            QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
+            CGAssociateMouseAndMouseCursorPosition (0);
+            currentGrabMode = SDL_GRAB_ON;
+            break;
+        case SDL_GRAB_FULLSCREEN:
+            break;
+    }
+        
+    return currentGrabMode;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/quartz/SDL_QuartzWindow.m	Thu Jun 07 14:28:11 2001 +0000
@@ -0,0 +1,25 @@
+/* Subclass of NSWindow to allow customization if we need it */
+
+@interface SDL_QuartzWindow : NSWindow
+{}
+- (void)miniaturize:(id)sender;
+- (void)deminiaturize:(id)sender;
+@end
+
+@implementation SDL_QuartzWindow
+
+/* These methods should be rewritten to fix the miniaturize bug */
+- (void)miniaturize:(id)sender
+{
+    [ super miniaturize:sender ];
+}
+
+- (void)deminiaturize:(id)sender
+{
+    /* Let the app know they have to redraw everything */
+    SDL_PrivateExpose ();
+    
+    [ super deminiaturize:sender ];
+}
+
+@end
--- a/test/testtypes.c	Thu Jun 07 13:53:51 2001 +0000
+++ b/test/testtypes.c	Thu Jun 07 14:28:11 2001 +0000
@@ -1,6 +1,6 @@
 
 #include <stdio.h>
-
+#include "SDL_main.h"
 #include "SDL_types.h"
 
 int main(int argc, char *argv[])