Mercurial > sdl-ios-xcode
changeset 47:45b1c4303f87
Added initial support for Quartz video (thanks Darrell!)
author | Sam Lantinga <slouken@lokigames.com> |
---|---|
date | Thu, 07 Jun 2001 14:28:11 +0000 |
parents | 3dcf26fa9d15 |
children | f97decee03a9 |
files | 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 |
diffstat | 23 files changed, 2127 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- 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