Added initial support for Quartz video (thanks Darrell!)
--HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%4048
This commit is contained in:
parent
d9a2eb5ef1
commit
72f7279bf8
23 changed files with 2127 additions and 29 deletions
35
BUGS
35
BUGS
|
@ -70,22 +70,35 @@ MacOS:
|
|||
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.
|
||||
|
||||
Command-line arguments Dialog is not implemented yet.
|
||||
|
||||
Native sound and video routines are not finished, though Carbon
|
||||
seems to work fairly well.
|
||||
Fullscreen drawing has some artifacts.
|
||||
|
||||
Fullscreen window covers *all* other windows - even force quit.
|
||||
|
||||
Fullscreen OpenGL for the software renderer is broken.
|
||||
|
||||
Joysticks and CD-ROM functions are not implemented yet.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
|
|
|
@ -34,11 +34,80 @@ and linking, respectively:
|
|||
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
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
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?
|
||||
|
||||
- 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"
|
||||
|
|
|
@ -63,6 +63,10 @@ case "$target" in
|
|||
*-*-linux*)
|
||||
AC_PROG_CXX
|
||||
;;
|
||||
*-*-darwin*)
|
||||
OBJC="???"
|
||||
AC_SUBST(OBJC)
|
||||
;;
|
||||
esac
|
||||
AC_PROG_INSTALL
|
||||
AC_FUNC_ALLOCA
|
||||
|
@ -1979,6 +1983,7 @@ src/video/ggi/Makefile
|
|||
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
|
||||
|
|
|
@ -16,6 +16,7 @@ be found at the <A HREF="http://www.libsdl.org/"> main SDL page</A>.
|
|||
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!)
|
||||
|
|
|
@ -31,7 +31,7 @@ static char rcsid =
|
|||
/* 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"
|
||||
|
|
|
@ -878,6 +878,10 @@ typedef enum {
|
|||
*/
|
||||
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
|
||||
}
|
||||
|
|
|
@ -105,9 +105,8 @@ static void callBackProc (SndChannel *chan, SndCommand *cmd_passed ) {
|
|||
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 @@ so fill it */
|
|||
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 @@ so fill it */
|
|||
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 @@ so fill it */
|
|||
|
||||
SndDoCommand (chan, &cmd, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int Mac_OpenAudio(_THIS, SDL_AudioSpec *spec) {
|
||||
|
|
8
src/main/macosx/SDLMain.h
Normal file
8
src/main/macosx/SDLMain.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface SDLMain : NSObject
|
||||
{
|
||||
}
|
||||
- (IBAction)quit:(id)sender;
|
||||
- (IBAction)makeFullscreen:(id)sender;
|
||||
@end
|
88
src/main/macosx/SDLMain.m
Normal file
88
src/main/macosx/SDLMain.m
Normal file
|
@ -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;
|
||||
}
|
35
src/main/macosx/exports/Makefile
Normal file
35
src/main/macosx/exports/Makefile
Normal file
|
@ -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)
|
177
src/main/macosx/exports/SDL.x
Normal file
177
src/main/macosx/exports/SDL.x
Normal file
|
@ -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
|
20
src/main/macosx/exports/gendef.pl
Normal file
20
src/main/macosx/exports/gendef.pl
Normal file
|
@ -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);
|
||||
}
|
|
@ -63,7 +63,7 @@ typedef struct SDL_VideoDevice SDL_VideoDevice;
|
|||
#endif
|
||||
struct SDL_VideoDevice {
|
||||
/* * * */
|
||||
/* The name of this audio driver */
|
||||
/* The name of this video driver */
|
||||
const char *name;
|
||||
|
||||
/* * * */
|
||||
|
@ -377,10 +377,12 @@ extern VideoBootStrap TOOLBOX_bootstrap;
|
|||
#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;
|
||||
|
||||
|
|
|
@ -84,6 +84,9 @@ static VideoBootStrap *bootstrap[] = {
|
|||
#ifdef ENABLE_DRAWSPROCKET
|
||||
&DSp_bootstrap,
|
||||
#endif
|
||||
#ifdef ENABLE_QUARTZ
|
||||
&QZ_bootstrap,
|
||||
#endif
|
||||
#ifdef ENABLE_CYBERGRAPHICS
|
||||
&CGX_bootstrap,
|
||||
#endif
|
||||
|
|
|
@ -34,7 +34,7 @@ static char rcsid =
|
|||
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>
|
||||
|
|
14
src/video/quartz/Makefile.am
Normal file
14
src/video/quartz/Makefile.am
Normal file
|
@ -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
|
368
src/video/quartz/SDL_QuartzEvents.m
Normal file
368
src/video/quartz/SDL_QuartzEvents.m
Normal file
|
@ -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);
|
||||
}
|
||||
|
140
src/video/quartz/SDL_QuartzKeys.h
Normal file
140
src/video/quartz/SDL_QuartzKeys.h
Normal file
|
@ -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
|
183
src/video/quartz/SDL_QuartzVideo.h
Normal file
183
src/video/quartz/SDL_QuartzVideo.h
Normal file
|
@ -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);*/
|
756
src/video/quartz/SDL_QuartzVideo.m
Normal file
756
src/video/quartz/SDL_QuartzVideo.m
Normal file
|
@ -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 ];
|
||||
}
|
175
src/video/quartz/SDL_QuartzWM.m
Normal file
175
src/video/quartz/SDL_QuartzWM.m
Normal file
|
@ -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;
|
||||
}
|
25
src/video/quartz/SDL_QuartzWindow.m
Normal file
25
src/video/quartz/SDL_QuartzWindow.m
Normal file
|
@ -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
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "SDL_main.h"
|
||||
#include "SDL_types.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue