Commit 88fc8878 authored by Sam Lantinga's avatar Sam Lantinga

Date: Wed, 31 Dec 2003 21:55:30 +0100

From: Max Horn
Subject: SDL: video/quartz cleanup

while doing some experimental changes in the quartz code, I was annoyed
by having to recompile that one big .o file over and over again. So I
decided to finally realize one TODO: properly splitting the code over
multiple files :-).

With two exceptions, I didn't make code changes, only rearranged files
and added new headers. Since there are several new files, making a
patch didn't work out so well, so I decided to just send you all the
new & modified files.

The one source change I made is related to showing/hiding the mouse. I
renamed cursor_visible to cursor_should_be_visible and cursor_hidden to
cursor_visible; I think that makes reading the code easier.
Then I added two new functions: QZ_ShowMouse and QZ_HideMouse. They
help manage cursor_visible (the former 'cursor_hidden'). Finally I
replaced the Carbon ShowCursor/HiderCuror calls by [NSCursor hide] and
[NSCursor unhide]. The API docs are not conclusive, but it might be
that with those the "cursor_visible" (former 'cursor_hidden') hack may
not be necessary anymore; however so far I didn't test this hypothesis,
so I left that in.

The other change was to remove in_foreground and use [NSApp isActive]
instead: Manually keeping track of whether we are in the foreground is
error prone. This should work better in some corner cases.

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40762
parent 88753d4f
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2003 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@libsdl.org
*/
/*
Obscuring code: maximum number of windows above ours (inclusive)
Note: this doesn't work too well in practice and should be
phased out when we add OpenGL 2D acceleration. It was never
enabled in the first place, so this shouldn't be a problem ;-)
*/
#define kMaxWindows 256
/* Some of the Core Graphics Server API for obscuring code */
#define kCGSWindowLevelTop 2147483632
#define kCGSWindowLevelDockIconDrag 500
#define kCGSWindowLevelDockMenu 101
#define kCGSWindowLevelMenuIgnore 21
#define kCGSWindowLevelMenu 20
#define kCGSWindowLevelDockLabel 12
#define kCGSWindowLevelDockIcon 11
#define kCGSWindowLevelDock 10
#define kCGSWindowLevelUtility 3
#define kCGSWindowLevelNormal 0
/*
For completeness; We never use these window levels, they are always below us
#define kCGSWindowLevelMBarShadow -20
#define kCGSWindowLevelDesktopPicture -2147483647
#define kCGSWindowLevelDesktop -2147483648
*/
typedef CGError CGSError;
typedef long CGSWindowCount;
typedef void * CGSConnectionID;
typedef int CGSWindowID;
typedef CGSWindowID* CGSWindowIDList;
typedef CGWindowLevel CGSWindowLevel;
typedef NSRect CGSRect;
extern CGSConnectionID _CGSDefaultConnection ();
extern CGSError CGSGetOnScreenWindowList (CGSConnectionID cid,
CGSConnectionID owner,
CGSWindowCount listCapacity,
CGSWindowIDList list,
CGSWindowCount *listCount);
extern CGSError CGSGetScreenRectForWindow (CGSConnectionID cid,
CGSWindowID wid,
CGSRect *rect);
extern CGWindowLevel CGSGetWindowLevel (CGSConnectionID cid,
CGSWindowID wid,
CGSWindowLevel *level);
extern CGSError CGSDisplayHWFill (CGDirectDisplayID id, unsigned int x, unsigned int y,
unsigned int w, unsigned int h, unsigned int color);
extern CGSError CGSDisplayCanHWFill (CGDirectDisplayID id);
extern CGSError CGSGetMouseEnabledFlags (CGSConnectionID cid, CGSWindowID wid, int *flags);
int CGSDisplayHWSync (CGDirectDisplayID id);
...@@ -6,12 +6,13 @@ libvideo_quartz_la_SOURCES = $(QUARTZ_SRCS) ...@@ -6,12 +6,13 @@ libvideo_quartz_la_SOURCES = $(QUARTZ_SRCS)
# The SDL MacOS X Quartz video driver sources # The SDL MacOS X Quartz video driver sources
QUARTZ_SRCS = \ QUARTZ_SRCS = \
CGS.h \
SDL_QuartzEvents.m \
SDL_QuartzGL.m \
SDL_QuartzKeys.h \ SDL_QuartzKeys.h \
SDL_QuartzVideo.h \ SDL_QuartzVideo.h \
SDL_QuartzVideo.m SDL_QuartzVideo.m \
SDL_QuartzWindow.h \
# These files are included by SDL_QuartzVideo.m (is that right??) SDL_QuartzWindow.m \
noinst_HEADERS = \
SDL_QuartzEvents.m \
SDL_QuartzWM.m \ SDL_QuartzWM.m \
SDL_QuartzWindow.m SDL_QuartzYUV.m
/* /*
SDL - Simple DirectMedia Layer SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga Copyright (C) 1997-2003 Sam Lantinga
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public modify it under the terms of the GNU Library General Public
...@@ -19,12 +19,15 @@ ...@@ -19,12 +19,15 @@
Sam Lantinga Sam Lantinga
slouken@libsdl.org slouken@libsdl.org
*/ */
#include <stdlib.h> // For getenv()
#include "SDL_QuartzVideo.h"
#include <stdlib.h> // For getenv()
#include <IOKit/IOMessage.h> // For wake from sleep detection #include <IOKit/IOMessage.h> // For wake from sleep detection
#include <IOKit/pwr_mgt/IOPMLib.h> // For wake from sleep detection #include <IOKit/pwr_mgt/IOPMLib.h> // For wake from sleep detection
#include "SDL_QuartzKeys.h" #include "SDL_QuartzKeys.h"
static void QZ_InitOSKeymap (_THIS) { void QZ_InitOSKeymap (_THIS) {
const void *KCHRPtr; const void *KCHRPtr;
UInt32 state; UInt32 state;
UInt32 value; UInt32 value;
...@@ -283,7 +286,7 @@ static void QZ_DoModifiers (_THIS, unsigned int newMods) { ...@@ -283,7 +286,7 @@ static void QZ_DoModifiers (_THIS, unsigned int newMods) {
key.sym = mapping[i]; key.sym = mapping[i];
/* If this was Caps Lock, we need some additional voodoo to make SDL happy */ /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
if (bit == NSAlphaShiftKeyMask) if (bit == NSAlphaShiftKeyMask)
SDL_PrivateKeyboard (SDL_PRESSED, &key); SDL_PrivateKeyboard (SDL_PRESSED, &key);
SDL_PrivateKeyboard (SDL_RELEASED, &key); SDL_PrivateKeyboard (SDL_RELEASED, &key);
} }
else if ( newMask && else if ( newMask &&
...@@ -302,13 +305,9 @@ static void QZ_DoModifiers (_THIS, unsigned int newMods) { ...@@ -302,13 +305,9 @@ static void QZ_DoModifiers (_THIS, unsigned int newMods) {
static void QZ_DoActivate (_THIS) static void QZ_DoActivate (_THIS)
{ {
in_foreground = YES;
/* Hide the cursor if it was hidden by SDL_ShowCursor() */ /* Hide the cursor if it was hidden by SDL_ShowCursor() */
if (!cursor_visible && !cursor_hidden) { if (!cursor_should_be_visible)
HideCursor (); QZ_HideMouse (this);
cursor_hidden = YES;
}
/* Regrab input, only if it was previously grabbed */ /* Regrab input, only if it was previously grabbed */
if ( current_grab_mode == SDL_GRAB_ON ) { if ( current_grab_mode == SDL_GRAB_ON ) {
...@@ -323,8 +322,6 @@ static void QZ_DoActivate (_THIS) ...@@ -323,8 +322,6 @@ static void QZ_DoActivate (_THIS)
static void QZ_DoDeactivate (_THIS) { static void QZ_DoDeactivate (_THIS) {
in_foreground = NO;
/* Get the current cursor location, for restore on activate */ /* Get the current cursor location, for restore on activate */
cursor_loc = [ NSEvent mouseLocation ]; /* global coordinates */ cursor_loc = [ NSEvent mouseLocation ]; /* global coordinates */
if (qz_window) if (qz_window)
...@@ -335,10 +332,8 @@ static void QZ_DoDeactivate (_THIS) { ...@@ -335,10 +332,8 @@ static void QZ_DoDeactivate (_THIS) {
CGAssociateMouseAndMouseCursorPosition (1); CGAssociateMouseAndMouseCursorPosition (1);
/* Show the cursor if it was hidden by SDL_ShowCursor() */ /* Show the cursor if it was hidden by SDL_ShowCursor() */
if (!cursor_visible && cursor_hidden) { if (!cursor_should_be_visible)
ShowCursor (); QZ_ShowMouse (this);
cursor_hidden = NO;
}
SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS); SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS);
} }
...@@ -359,13 +354,13 @@ void QZ_SleepNotificationHandler (void * refcon, ...@@ -359,13 +354,13 @@ void QZ_SleepNotificationHandler (void * refcon,
IOAllowPowerChange(power_connection, (long) messageArgument); IOAllowPowerChange(power_connection, (long) messageArgument);
break; break;
case kIOMessageSystemHasPoweredOn: case kIOMessageSystemHasPoweredOn:
/* awake */ /* awake */
SDL_PrivateExpose(); SDL_PrivateExpose();
break; break;
} }
} }
static void QZ_RegisterForSleepNotifications (_THIS) void QZ_RegisterForSleepNotifications (_THIS)
{ {
CFRunLoopSourceRef rls; CFRunLoopSourceRef rls;
IONotificationPortRef thePortRef; IONotificationPortRef thePortRef;
...@@ -400,7 +395,7 @@ static int QZ_OtherMouseButtonToSDL(int button) ...@@ -400,7 +395,7 @@ static int QZ_OtherMouseButtonToSDL(int button)
} }
static void QZ_PumpEvents (_THIS) void QZ_PumpEvents (_THIS)
{ {
int firstMouseEvent; int firstMouseEvent;
CGMouseDelta dx, dy; CGMouseDelta dx, dy;
...@@ -445,7 +440,7 @@ static void QZ_PumpEvents (_THIS) ...@@ -445,7 +440,7 @@ static void QZ_PumpEvents (_THIS)
BOOL isInGameWin; BOOL isInGameWin;
#define DO_MOUSE_DOWN(button) do { \ #define DO_MOUSE_DOWN(button) do { \
if ( in_foreground ) { \ if ( [ NSApp isActive ] ) { \
if ( isInGameWin ) { \ if ( isInGameWin ) { \
SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \ SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \
expect_mouse_up |= 1<<button; \ expect_mouse_up |= 1<<button; \
......
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2003 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@libsdl.org
*/
#include "SDL_QuartzVideo.h"
/*
This is a workaround to directly access NSOpenGLContext's CGL context
We need this to check for errors NSOpenGLContext doesn't support
*/
@interface NSOpenGLContext (CGLContextAccess)
- (CGLContextObj) cglContext;
@end
@implementation NSOpenGLContext (CGLContextAccess)
- (CGLContextObj) cglContext;
{
return _contextAuxiliary;
}
@end
/* OpenGL helper functions (used internally) */
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.stereo ) {
attr[i++] = NSOpenGLPFAStereo;
}
if ( this->gl_config.stencil_size != 0 ) {
attr[i++] = NSOpenGLPFAStencilSize;
attr[i++] = this->gl_config.stencil_size;
}
#if NSOPENGL_CURRENT_VERSION > 1 /* What version should this be? */
if ( this->gl_config.multisamplebuffers != 0 ) {
attr[i++] = NSOpenGLPFASampleBuffers;
attr[i++] = this->gl_config.multisamplebuffers;
}
if ( this->gl_config.multisamplesamples != 0 ) {
attr[i++] = NSOpenGLPFASamples;
attr[i++] = this->gl_config.multisamplesamples;
}
#endif
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;
}
/*
* Wisdom from Apple engineer in reference to UT2003's OpenGL performance:
* "You are blowing a couple of the internal OpenGL function caches. This
* appears to be happening in the VAO case. You can tell OpenGL to up
* the cache size by issuing the following calls right after you create
* the OpenGL context. The default cache size is 16." --ryan.
*/
#ifndef GLI_ARRAY_FUNC_CACHE_MAX
#define GLI_ARRAY_FUNC_CACHE_MAX 284
#endif
#ifndef GLI_SUBMIT_FUNC_CACHE_MAX
#define GLI_SUBMIT_FUNC_CACHE_MAX 280
#endif
{
long cache_max = 64;
CGLContextObj ctx = [ gl_context cglContext ];
CGLSetParameter (ctx, GLI_SUBMIT_FUNC_CACHE_MAX, &cache_max);
CGLSetParameter (ctx, GLI_ARRAY_FUNC_CACHE_MAX, &cache_max);
}
/* End Wisdom from Apple Engineer section. --ryan. */
/* Convince SDL that the GL "driver" is loaded */
this->gl_config.driver_loaded = 1;
[ fmt release ];
return 1;
}
void QZ_TearDownOpenGL (_THIS) {
[ NSOpenGLContext clearCurrentContext ];
[ gl_context clearDrawable ];
[ gl_context release ];
}
/* SDL OpenGL functions */
int QZ_GL_LoadLibrary (_THIS, const char *location) {
this->gl_config.driver_loaded = 1;
return 1;
}
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;
}
int QZ_GL_GetAttribute (_THIS, SDL_GLattr attrib, int* value) {
GLenum attr = 0;
QZ_GL_MakeCurrent (this);
switch (attrib) {
case SDL_GL_RED_SIZE: attr = GL_RED_BITS; break;
case SDL_GL_BLUE_SIZE: attr = GL_BLUE_BITS; break;
case SDL_GL_GREEN_SIZE: attr = GL_GREEN_BITS; break;
case SDL_GL_ALPHA_SIZE: attr = GL_ALPHA_BITS; break;
case SDL_GL_DOUBLEBUFFER: attr = GL_DOUBLEBUFFER; break;
case SDL_GL_DEPTH_SIZE: attr = GL_DEPTH_BITS; break;
case SDL_GL_STENCIL_SIZE: attr = GL_STENCIL_BITS; break;
case SDL_GL_ACCUM_RED_SIZE: attr = GL_ACCUM_RED_BITS; break;
case SDL_GL_ACCUM_GREEN_SIZE: attr = GL_ACCUM_GREEN_BITS; break;
case SDL_GL_ACCUM_BLUE_SIZE: attr = GL_ACCUM_BLUE_BITS; break;
case SDL_GL_ACCUM_ALPHA_SIZE: attr = GL_ACCUM_ALPHA_BITS; break;
case SDL_GL_STEREO: attr = GL_STEREO; break;
case SDL_GL_MULTISAMPLEBUFFERS: attr = GL_SAMPLE_BUFFERS_ARB; break;
case SDL_GL_MULTISAMPLESAMPLES: attr = GL_SAMPLES_ARB; break;
case SDL_GL_BUFFER_SIZE:
{
GLint bits = 0;
GLint component;
/* there doesn't seem to be a single flag in OpenGL for this! */
glGetIntegerv (GL_RED_BITS, &component); bits += component;
glGetIntegerv (GL_GREEN_BITS,&component); bits += component;
glGetIntegerv (GL_BLUE_BITS, &component); bits += component;
glGetIntegerv (GL_ALPHA_BITS, &component); bits += component;
*value = bits;
}
return 0;
}
glGetIntegerv (attr, (GLint *)value);
return 0;
}
int QZ_GL_MakeCurrent (_THIS) {
[ gl_context makeCurrentContext ];
return 0;
}
void QZ_GL_SwapBuffers (_THIS) {
[ gl_context flushBuffer ];
}
/* /*
SDL - Simple DirectMedia Layer SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga Copyright (C) 1997-2003 Sam Lantinga
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version. version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details. Library General Public License for more details.
You should have received a copy of the GNU Library General Public You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga Sam Lantinga
slouken@libsdl.org slouken@libsdl.org
*/ */
/* These are the Macintosh key scancode constants -- from Inside Macintosh */ /* These are the Macintosh key scancode constants -- from Inside Macintosh */
......
/* /*
SDL - Simple DirectMedia Layer SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga Copyright (C) 1997-2003 Sam Lantinga
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public modify it under the terms of the GNU Library General Public
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
#include <OpenGL/glext.h> #include <OpenGL/glext.h>
#include <Carbon/Carbon.h> #include <Carbon/Carbon.h>
#include <QuickTime/QuickTime.h> #include <QuickTime/QuickTime.h>
#include <IOKit/IOKitLib.h> /* For powersave handling */ #include <IOKit/IOKitLib.h> /* For powersave handling */
#include <pthread.h> #include <pthread.h>
#include "SDL_thread.h" #include "SDL_thread.h"
...@@ -66,53 +66,6 @@ ...@@ -66,53 +66,6 @@
#include "SDL_pixels_c.h" #include "SDL_pixels_c.h"
#include "SDL_events_c.h" #include "SDL_events_c.h"
/*
Add methods to get at private members of NSScreen.
Since there is a bug in Apple's screen switching code
that does not update this variable when switching
to fullscreen, we'll set it manually (but only for the
main screen).
*/
@interface NSScreen (NSScreenAccess)
- (void) setFrame:(NSRect)frame;
@end
@implementation NSScreen (NSScreenAccess)
- (void) setFrame:(NSRect)frame;
{
_frame = frame;
}
@end
/*
This is a workaround to directly access NSOpenGLContext's CGL context
We need this to check for errors NSOpenGLContext doesn't support
*/
@interface NSOpenGLContext (CGLContextAccess)
- (CGLContextObj) cglContext;
@end
@implementation NSOpenGLContext (CGLContextAccess)
- (CGLContextObj) cglContext;
{
return _contextAuxiliary;
}
@end
/*
Structure for rez switch gamma fades
We can hide the monitor flicker by setting the gamma tables to 0
*/
#define QZ_GAMMA_TABLE_SIZE 256
typedef struct {
CGGammaValue red[QZ_GAMMA_TABLE_SIZE];
CGGammaValue green[QZ_GAMMA_TABLE_SIZE];
CGGammaValue blue[QZ_GAMMA_TABLE_SIZE];
} SDL_QuartzGammaTable;
/* Main driver structure to store required state information */ /* Main driver structure to store required state information */
typedef struct SDL_PrivateVideoData { typedef struct SDL_PrivateVideoData {
...@@ -131,7 +84,6 @@ typedef struct SDL_PrivateVideoData { ...@@ -131,7 +84,6 @@ typedef struct SDL_PrivateVideoData {
NSQuickDrawView *view; /* the window's view; draw 2D and OpenGL into this view */ NSQuickDrawView *view; /* the window's view; draw 2D and OpenGL into this view */
SDL_Surface *resize_icon; /* icon for the resize badge, we have to draw it by hand */ SDL_Surface *resize_icon; /* icon for the resize badge, we have to draw it by hand */
SDL_GrabMode current_grab_mode; /* default value is SDL_GRAB_OFF */ SDL_GrabMode current_grab_mode; /* default value is SDL_GRAB_OFF */
BOOL in_foreground; /* boolean; indicate if app is in foreground or not */
SDL_Rect **client_mode_list; /* resolution list to pass back to client */ SDL_Rect **client_mode_list; /* resolution list to pass back to client */
SDLKey keymap[256]; /* Mac OS X to SDL key mapping */ SDLKey keymap[256]; /* Mac OS X to SDL key mapping */
Uint32 current_mods; /* current keyboard modifiers, to track modifier state */ Uint32 current_mods; /* current keyboard modifiers, to track modifier state */
...@@ -140,8 +92,8 @@ typedef struct SDL_PrivateVideoData { ...@@ -140,8 +92,8 @@ typedef struct SDL_PrivateVideoData {
Uint8 expect_mouse_up; /* used to determine when to send mouse up events */ Uint8 expect_mouse_up; /* used to determine when to send mouse up events */
Uint8 grab_state; /* used to manage grab behavior */ Uint8 grab_state; /* used to manage grab behavior */
NSPoint cursor_loc; /* saved cursor coords, for activate/deactivate when grabbed */ NSPoint cursor_loc; /* saved cursor coords, for activate/deactivate when grabbed */
BOOL cursor_visible; /* tells if cursor was instructed to be hidden or not (SDL_ShowCursor) */ BOOL cursor_should_be_visible; /* tells if cursor is supposed to be visible (SDL_ShowCursor) */
BOOL cursor_hidden; /* tells if cursor is *actually* hidden or not */ BOOL cursor_visible; /* tells if cursor is *actually* visible or not */
Uint8* sw_buffers[2]; /* pointers to the two software buffers for double-buffer emulation */ Uint8* sw_buffers[2]; /* pointers to the two software buffers for double-buffer emulation */
SDL_Thread *thread; /* thread for async updates to the screen */ SDL_Thread *thread; /* thread for async updates to the screen */
SDL_sem *sem1, *sem2; /* synchronization for async screen updates */ SDL_sem *sem1, *sem2; /* synchronization for async screen updates */
...@@ -156,7 +108,7 @@ typedef struct SDL_PrivateVideoData { ...@@ -156,7 +108,7 @@ typedef struct SDL_PrivateVideoData {
Sint16 yuv_width, yuv_height; Sint16 yuv_width, yuv_height;
CGrafPtr yuv_port; CGrafPtr yuv_port;
} SDL_PrivateVideoData ; } SDL_PrivateVideoData;
#define _THIS SDL_VideoDevice *this #define _THIS SDL_VideoDevice *this
#define display_id (this->hidden->display) #define display_id (this->hidden->display)
...@@ -176,7 +128,6 @@ typedef struct SDL_PrivateVideoData { ...@@ -176,7 +128,6 @@ typedef struct SDL_PrivateVideoData {
#define warp_flag (this->hidden->warp_flag) #define warp_flag (this->hidden->warp_flag)
#define resize_icon (this->hidden->resize_icon) #define resize_icon (this->hidden->resize_icon)
#define current_grab_mode (this->hidden->current_grab_mode) #define current_grab_mode (this->hidden->current_grab_mode)
#define in_foreground (this->hidden->in_foreground)
#define client_mode_list (this->hidden->client_mode_list) #define client_mode_list (this->hidden->client_mode_list)
#define keymap (this->hidden->keymap) #define keymap (this->hidden->keymap)
#define current_mods (this->hidden->current_mods) #define current_mods (this->hidden->current_mods)
...@@ -185,8 +136,8 @@ typedef struct SDL_PrivateVideoData { ...@@ -185,8 +136,8 @@ typedef struct SDL_PrivateVideoData {
#define expect_mouse_up (this->hidden->expect_mouse_up) #define expect_mouse_up (this->hidden->expect_mouse_up)
#define grab_state (this->hidden->grab_state) #define grab_state (this->hidden->grab_state)
#define cursor_loc (this->hidden->cursor_loc) #define cursor_loc (this->hidden->cursor_loc)
#define cursor_should_be_visible (this->hidden->cursor_should_be_visible)
#define cursor_visible (this->hidden->cursor_visible) #define cursor_visible (this->hidden->cursor_visible)
#define cursor_hidden (this->hidden->cursor_hidden)
#define sw_buffers (this->hidden->sw_buffers) #define sw_buffers (this->hidden->sw_buffers)
#define thread (this->hidden->thread) #define thread (this->hidden->thread)
#define sem1 (this->hidden->sem1) #define sem1 (this->hidden->sem1)
...@@ -194,17 +145,6 @@ typedef struct SDL_PrivateVideoData { ...@@ -194,17 +145,6 @@ typedef struct SDL_PrivateVideoData {
#define current_buffer (this->hidden->current_buffer) #define current_buffer (this->hidden->current_buffer)
#define quit_thread (this->hidden->quit_thread) #define quit_thread (this->hidden->quit_thread)
#define yuv_idh (this->hidden->yuv_idh)
#define yuv_matrix (this->hidden->yuv_matrix)
#define yuv_codec (this->hidden->yuv_codec)
#define yuv_seq (this->hidden->yuv_seq)
#define yuv_pixmap (this->hidden->yuv_pixmap)
#define yuv_data (this->hidden->yuv_data)
#define yuv_width (this->hidden->yuv_width)
#define yuv_height (this->hidden->yuv_height)
#define yuv_port (this->hidden->yuv_port)
/* grab states - the input is in one of these states */ /* grab states - the input is in one of these states */
enum { enum {
QZ_UNGRABBED = 0, QZ_UNGRABBED = 0,
...@@ -220,145 +160,52 @@ enum { ...@@ -220,145 +160,52 @@ enum {
QZ_SHOWCURSOR QZ_SHOWCURSOR
}; };
/*
Obscuring code: maximum number of windows above ours (inclusive)
Note: this doesn't work too well in practice and should be
phased out when we add OpenGL 2D acceleration. It was never
enabled in the first place, so this shouldn't be a problem ;-)
*/
#define kMaxWindows 256
/* Some of the Core Graphics Server API for obscuring code */
#define kCGSWindowLevelTop 2147483632
#define kCGSWindowLevelDockIconDrag 500
#define kCGSWindowLevelDockMenu 101
#define kCGSWindowLevelMenuIgnore 21
#define kCGSWindowLevelMenu 20
#define kCGSWindowLevelDockLabel 12
#define kCGSWindowLevelDockIcon 11
#define kCGSWindowLevelDock 10
#define kCGSWindowLevelUtility 3
#define kCGSWindowLevelNormal 0
/*
For completeness; We never use these window levels, they are always below us
#define kCGSWindowLevelMBarShadow -20
#define kCGSWindowLevelDesktopPicture -2147483647
#define kCGSWindowLevelDesktop -2147483648
*/
typedef CGError CGSError;
typedef long CGSWindowCount;
typedef void * CGSConnectionID;
typedef int CGSWindowID;
typedef CGSWindowID* CGSWindowIDList;
typedef CGWindowLevel CGSWindowLevel;
typedef NSRect CGSRect;
extern CGSConnectionID _CGSDefaultConnection ();
extern CGSError CGSGetOnScreenWindowList (CGSConnectionID cid,
CGSConnectionID owner,
CGSWindowCount listCapacity,
CGSWindowIDList list,
CGSWindowCount *listCount);
extern CGSError CGSGetScreenRectForWindow (CGSConnectionID cid,
CGSWindowID wid,
CGSRect *rect);
extern CGWindowLevel CGSGetWindowLevel (CGSConnectionID cid,
CGSWindowID wid,
CGSWindowLevel *level);
extern CGSError CGSDisplayHWFill (CGDirectDisplayID id, unsigned int x, unsigned int y,
unsigned int w, unsigned int h, unsigned int color);
extern CGSError CGSDisplayCanHWFill (CGDirectDisplayID id);
extern CGSError CGSGetMouseEnabledFlags (CGSConnectionID cid, CGSWindowID wid, int *flags);
int CGSDisplayHWSync (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 int QZ_LockDoubleBuffer (_THIS, SDL_Surface *surface);
static void QZ_UnlockDoubleBuffer (_THIS, SDL_Surface *surface);
static int QZ_ThreadFlip (_THIS);
static int QZ_FlipDoubleBuffer (_THIS, SDL_Surface *surface);
static void QZ_DoubleBufferUpdate (_THIS, int num_rects, SDL_Rect *rects);
static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects);
static int QZ_LockWindow (_THIS, SDL_Surface *surface);
static void QZ_UnlockWindow (_THIS, SDL_Surface *surface);
static void QZ_UpdateRects (_THIS, int num_rects, SDL_Rect *rects);
static void QZ_VideoQuit (_THIS);
/* Hardware surface functions (for fullscreen mode only) */
#if 0 /* Not used (apparently, it's really slow) */
static int QZ_FillHWRect (_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color);
#endif
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 */ /* Gamma Functions */
static int QZ_SetGamma (_THIS, float red, float green, float blue); int QZ_SetGamma (_THIS, float red, float green, float blue);
static int QZ_GetGamma (_THIS, float *red, float *green, float *blue); int QZ_GetGamma (_THIS, float *red, float *green, float *blue);
static int QZ_SetGammaRamp (_THIS, Uint16 *ramp); int QZ_SetGammaRamp (_THIS, Uint16 *ramp);
static int QZ_GetGammaRamp (_THIS, Uint16 *ramp); int QZ_GetGammaRamp (_THIS, Uint16 *ramp);
/* OpenGL functions */ /* OpenGL functions */
static int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags); int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags);
static void QZ_TearDownOpenGL (_THIS); void QZ_TearDownOpenGL (_THIS);
static void* QZ_GL_GetProcAddress (_THIS, const char *proc); void* QZ_GL_GetProcAddress (_THIS, const char *proc);
static int QZ_GL_GetAttribute (_THIS, SDL_GLattr attrib, int* value); int QZ_GL_GetAttribute (_THIS, SDL_GLattr attrib, int* value);
static int QZ_GL_MakeCurrent (_THIS); int QZ_GL_MakeCurrent (_THIS);
static void QZ_GL_SwapBuffers (_THIS); void QZ_GL_SwapBuffers (_THIS);
static int QZ_GL_LoadLibrary (_THIS, const char *location); int QZ_GL_LoadLibrary (_THIS, const char *location);
/* Private function to warp the cursor (used internally) */
static void QZ_PrivateWarpCursor (_THIS, int x, int y);
/* Cursor and Mouse functions */ /* Cursor and Mouse functions */
static void QZ_FreeWMCursor (_THIS, WMcursor *cursor); void QZ_FreeWMCursor (_THIS, WMcursor *cursor);
static WMcursor* QZ_CreateWMCursor (_THIS, Uint8 *data, Uint8 *mask, WMcursor* QZ_CreateWMCursor (_THIS, Uint8 *data, Uint8 *mask,
int w, int h, int hot_x, int hot_y); int w, int h, int hot_x, int hot_y);
static int QZ_ShowWMCursor (_THIS, WMcursor *cursor); int QZ_ShowWMCursor (_THIS, WMcursor *cursor);
static void QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y); void QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y);
static void QZ_MoveWMCursor (_THIS, int x, int y); void QZ_MoveWMCursor (_THIS, int x, int y);
static void QZ_CheckMouseMode (_THIS); void QZ_CheckMouseMode (_THIS);
/* Event functions */ /* Event functions */
static void QZ_InitOSKeymap (_THIS); void QZ_InitOSKeymap (_THIS);
static void QZ_PumpEvents (_THIS); void QZ_PumpEvents (_THIS);
/* Window Manager functions */ /* Window Manager functions */
static void QZ_SetCaption (_THIS, const char *title, const char *icon); void QZ_SetCaption (_THIS, const char *title, const char *icon);
static void QZ_SetIcon (_THIS, SDL_Surface *icon, Uint8 *mask); void QZ_SetIcon (_THIS, SDL_Surface *icon, Uint8 *mask);
static int QZ_IconifyWindow (_THIS); int QZ_IconifyWindow (_THIS);
static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode); SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode);
/*static int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info);*/ /*int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info);*/
/* YUV functions */ /* YUV functions */
static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height, SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
Uint32 format, SDL_Surface *display); Uint32 format, SDL_Surface *display);
/* Private functions (used internally) */
void QZ_PrivateWarpCursor (_THIS, int x, int y);
void QZ_ChangeGrabState (_THIS, int action);
void QZ_RegisterForSleepNotifications (_THIS);
void QZ_ShowMouse (_THIS);
void QZ_HideMouse (_THIS);
void QZ_PrivateGlobalToLocal (_THIS, NSPoint *p);
void QZ_PrivateCocoaToSDL (_THIS, NSPoint *p);
/* /*
SDL - Simple DirectMedia Layer SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga Copyright (C) 1997-2003 Sam Lantinga
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public modify it under the terms of the GNU Library General Public
...@@ -21,11 +21,82 @@ ...@@ -21,11 +21,82 @@
*/ */
#include "SDL_QuartzVideo.h" #include "SDL_QuartzVideo.h"
#include "SDL_QuartzWindow.h"
/* Include files into one compile unit...break apart eventually */
#include "SDL_QuartzWM.m" /*
#include "SDL_QuartzEvents.m" Add methods to get at private members of NSScreen.
#include "SDL_QuartzWindow.m" Since there is a bug in Apple's screen switching code
that does not update this variable when switching
to fullscreen, we'll set it manually (but only for the
main screen).
*/
@interface NSScreen (NSScreenAccess)
- (void) setFrame:(NSRect)frame;
@end
@implementation NSScreen (NSScreenAccess)
- (void) setFrame:(NSRect)frame;
{
_frame = frame;
}
@end
/*
Structure for rez switch gamma fades
We can hide the monitor flicker by setting the gamma tables to 0
*/
#define QZ_GAMMA_TABLE_SIZE 256
typedef struct {
CGGammaValue red[QZ_GAMMA_TABLE_SIZE];
CGGammaValue green[QZ_GAMMA_TABLE_SIZE];
CGGammaValue blue[QZ_GAMMA_TABLE_SIZE];
} SDL_QuartzGammaTable;
/* 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 int QZ_LockDoubleBuffer (_THIS, SDL_Surface *surface);
static void QZ_UnlockDoubleBuffer (_THIS, SDL_Surface *surface);
static int QZ_ThreadFlip (_THIS);
static int QZ_FlipDoubleBuffer (_THIS, SDL_Surface *surface);
static void QZ_DoubleBufferUpdate (_THIS, int num_rects, SDL_Rect *rects);
static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects);
static int QZ_LockWindow (_THIS, SDL_Surface *surface);
static void QZ_UnlockWindow (_THIS, SDL_Surface *surface);
static void QZ_UpdateRects (_THIS, int num_rects, SDL_Rect *rects);
static void QZ_VideoQuit (_THIS);
/* Hardware surface functions (for fullscreen mode only) */
#if 0 /* Not used (apparently, it's really slow) */
static int QZ_FillHWRect (_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color);
#endif
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); */
/* Bootstrap binding, enables entry point into the driver */ /* Bootstrap binding, enables entry point into the driver */
VideoBootStrap QZ_bootstrap = { VideoBootStrap QZ_bootstrap = {
...@@ -130,8 +201,7 @@ static int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format) { ...@@ -130,8 +201,7 @@ static int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format) {
/* Set misc globals */ /* Set misc globals */
current_grab_mode = SDL_GRAB_OFF; current_grab_mode = SDL_GRAB_OFF;
in_foreground = YES; cursor_should_be_visible = YES;
cursor_visible = YES;
/* register for sleep notifications so wake from sleep generates SDL_VIDEOEXPOSE */ /* register for sleep notifications so wake from sleep generates SDL_VIDEOEXPOSE */
QZ_RegisterForSleepNotifications (this); QZ_RegisterForSleepNotifications (this);
...@@ -712,7 +782,7 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width, ...@@ -712,7 +782,7 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
/* Only recreate the view if it doesn't already exist */ /* Only recreate the view if it doesn't already exist */
if (window_view == nil) { if (window_view == nil) {
window_view = [ [ SDL_QuartzWindowView alloc ] initWithFrame:contentRect ]; window_view = [ [ NSQuickDrawView alloc ] initWithFrame:contentRect ];
[ window_view setAutoresizingMask: NSViewMinYMargin ]; [ window_view setAutoresizingMask: NSViewMinYMargin ];
[ [ qz_window contentView ] addSubview:window_view ]; [ [ qz_window contentView ] addSubview:window_view ];
[ window_view release ]; [ window_view release ];
...@@ -851,7 +921,7 @@ static void QZ_UnlockDoubleBuffer (_THIS, SDL_Surface *surface) { ...@@ -851,7 +921,7 @@ static void QZ_UnlockDoubleBuffer (_THIS, SDL_Surface *surface) {
union union
{ {
UInt64 i; UInt64 i;
Nanoseconds ns; Nanoseconds ns;
} temp; } temp;
...@@ -990,9 +1060,15 @@ static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects) { ...@@ -990,9 +1060,15 @@ static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects) {
The obscured code is based on work by Matt Slot fprefect@ambrosiasw.com, The obscured code is based on work by Matt Slot fprefect@ambrosiasw.com,
who supplied sample code for Carbon. who supplied sample code for Carbon.
*/ */
//#define TEST_OBSCURED 1
#if TEST_OBSCURED
#include "CGS.h"
#endif
static int QZ_IsWindowObscured (NSWindow *window) { static int QZ_IsWindowObscured (NSWindow *window) {
//#define TEST_OBSCURED 1
#if TEST_OBSCURED #if TEST_OBSCURED
...@@ -1230,6 +1306,84 @@ static void QZ_UnlockWindow (_THIS, SDL_Surface *surface) { ...@@ -1230,6 +1306,84 @@ static void QZ_UnlockWindow (_THIS, SDL_Surface *surface) {
UnlockPortBits ( [ window_view qdPort ] ); UnlockPortBits ( [ window_view qdPort ] );
} }
/* Resize icon, BMP format */
static const unsigned char QZ_ResizeIcon[] = {
0x42,0x4d,0x31,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x28,0x00,
0x00,0x00,0x0d,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x00,0x00,
0x00,0x00,0xfb,0x01,0x00,0x00,0x13,0x0b,0x00,0x00,0x13,0x0b,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0b,0xff,0xff,
0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,0xda,
0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,
0xe8,0xe8,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xda,0xda,0xda,0x87,
0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,0xe8,
0xe8,0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xff,0xff,0xff,0x0b,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd5,0xd5,0xd5,0x87,0x87,0x87,0xe8,0xe8,0xe8,
0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,
0xda,0xda,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xd7,0xd7,0xd7,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,
0xda,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xff,0xff,0xff,0x0b,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd7,0xd7,0xd7,
0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,
0xe8,0xe8,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd7,0xd7,0xd7,0x87,0x87,0x87,0xe8,0xe8,
0xe8,0xff,0xff,0xff,0xdc,0xdc,0xdc,0x87,0x87,0x87,0xff,0xff,0xff,0x0b,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xd9,0xd9,0xd9,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xdc,
0xdc,0xdc,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdb,0xdb,
0xdb,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xff,0xff,0xff,0x0b,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdb,0xdb,0xdb,0x87,0x87,0x87,0xe8,
0xe8,0xe8,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0x87,0x87,0x87,0xff,0xff,0xff,0x0b,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdc,
0xdc,0xdc,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0b
};
static void QZ_DrawResizeIcon (_THIS, RgnHandle dirtyRegion) {
/* Check if we should draw the resize icon */
if (SDL_VideoSurface->flags & SDL_RESIZABLE) {
Rect icon;
SetRect (&icon, SDL_VideoSurface->w - 13, SDL_VideoSurface->h - 13,
SDL_VideoSurface->w, SDL_VideoSurface->h);
if (RectInRgn (&icon, dirtyRegion)) {
SDL_Rect icon_rect;
/* Create the icon image */
if (resize_icon == NULL) {
SDL_RWops *rw;
SDL_Surface *tmp;
rw = SDL_RWFromMem (QZ_ResizeIcon, sizeof(QZ_ResizeIcon));
tmp = SDL_LoadBMP_RW (rw, SDL_TRUE);
resize_icon = SDL_ConvertSurface (tmp, SDL_VideoSurface->format, SDL_SRCCOLORKEY);
SDL_SetColorKey (resize_icon, SDL_SRCCOLORKEY, 0xFFFFFF);
SDL_FreeSurface (tmp);
}
icon_rect.x = SDL_VideoSurface->w - 13;
icon_rect.y = SDL_VideoSurface->h - 13;
icon_rect.w = 13;
icon_rect.h = 13;
SDL_BlitSurface (resize_icon, NULL, SDL_VideoSurface, &icon_rect);
}
}
}
static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) { static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) {
if (SDL_VideoSurface->flags & SDL_OPENGLBLIT) { if (SDL_VideoSurface->flags & SDL_OPENGLBLIT) {
...@@ -1353,7 +1507,7 @@ static void QZ_FreeHWSurface (_THIS, SDL_Surface *surface) { ...@@ -1353,7 +1507,7 @@ static void QZ_FreeHWSurface (_THIS, SDL_Surface *surface) {
*/ */
/* Gamma functions */ /* Gamma functions */
static int QZ_SetGamma (_THIS, float red, float green, float blue) { int QZ_SetGamma (_THIS, float red, float green, float blue) {
const CGGammaValue min = 0.0, max = 1.0; const CGGammaValue min = 0.0, max = 1.0;
...@@ -1383,7 +1537,7 @@ static int QZ_SetGamma (_THIS, float red, float green, float blue) { ...@@ -1383,7 +1537,7 @@ static int QZ_SetGamma (_THIS, float red, float green, float blue) {
} }
} }
static int QZ_GetGamma (_THIS, float *red, float *green, float *blue) { int QZ_GetGamma (_THIS, float *red, float *green, float *blue) {
CGGammaValue dummy; CGGammaValue dummy;
if ( CGDisplayNoErr == CGGetDisplayTransferByFormula if ( CGDisplayNoErr == CGGetDisplayTransferByFormula
...@@ -1395,7 +1549,7 @@ static int QZ_GetGamma (_THIS, float *red, float *green, float *blue) { ...@@ -1395,7 +1549,7 @@ static int QZ_GetGamma (_THIS, float *red, float *green, float *blue) {
return -1; return -1;
} }
static int QZ_SetGammaRamp (_THIS, Uint16 *ramp) { int QZ_SetGammaRamp (_THIS, Uint16 *ramp) {
const CGTableCount tableSize = 255; const CGTableCount tableSize = 255;
CGGammaValue redTable[tableSize]; CGGammaValue redTable[tableSize];
...@@ -1421,7 +1575,7 @@ static int QZ_SetGammaRamp (_THIS, Uint16 *ramp) { ...@@ -1421,7 +1575,7 @@ static int QZ_SetGammaRamp (_THIS, Uint16 *ramp) {
return -1; return -1;
} }
static int QZ_GetGammaRamp (_THIS, Uint16 *ramp) { int QZ_GetGammaRamp (_THIS, Uint16 *ramp) {
const CGTableCount tableSize = 255; const CGTableCount tableSize = 255;
CGGammaValue redTable[tableSize]; CGGammaValue redTable[tableSize];
...@@ -1449,484 +1603,3 @@ static int QZ_GetGammaRamp (_THIS, Uint16 *ramp) { ...@@ -1449,484 +1603,3 @@ static int QZ_GetGammaRamp (_THIS, Uint16 *ramp) {
return 0; return 0;
} }
/* OpenGL helper functions (used internally) */
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.stereo ) {
attr[i++] = NSOpenGLPFAStereo;
}
if ( this->gl_config.stencil_size != 0 ) {
attr[i++] = NSOpenGLPFAStencilSize;
attr[i++] = this->gl_config.stencil_size;
}
#if NSOPENGL_CURRENT_VERSION > 1 /* What version should this be? */
if ( this->gl_config.multisamplebuffers != 0 ) {
attr[i++] = NSOpenGLPFASampleBuffers;
attr[i++] = this->gl_config.multisamplebuffers;
}
if ( this->gl_config.multisamplesamples != 0 ) {
attr[i++] = NSOpenGLPFASamples;
attr[i++] = this->gl_config.multisamplesamples;
}
#endif
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;
}
/*
* Wisdom from Apple engineer in reference to UT2003's OpenGL performance:
* "You are blowing a couple of the internal OpenGL function caches. This
* appears to be happening in the VAO case. You can tell OpenGL to up
* the cache size by issuing the following calls right after you create
* the OpenGL context. The default cache size is 16." --ryan.
*/
#ifndef GLI_ARRAY_FUNC_CACHE_MAX
#define GLI_ARRAY_FUNC_CACHE_MAX 284
#endif
#ifndef GLI_SUBMIT_FUNC_CACHE_MAX
#define GLI_SUBMIT_FUNC_CACHE_MAX 280
#endif
{
long cache_max = 64;
CGLContextObj ctx = [ gl_context cglContext ];
CGLSetParameter (ctx, GLI_SUBMIT_FUNC_CACHE_MAX, &cache_max);
CGLSetParameter (ctx, GLI_ARRAY_FUNC_CACHE_MAX, &cache_max);
}
/* End Wisdom from Apple Engineer section. --ryan. */
/* 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) {
this->gl_config.driver_loaded = 1;
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) {
GLenum attr = 0;
QZ_GL_MakeCurrent (this);
switch (attrib) {
case SDL_GL_RED_SIZE: attr = GL_RED_BITS; break;
case SDL_GL_BLUE_SIZE: attr = GL_BLUE_BITS; break;
case SDL_GL_GREEN_SIZE: attr = GL_GREEN_BITS; break;
case SDL_GL_ALPHA_SIZE: attr = GL_ALPHA_BITS; break;
case SDL_GL_DOUBLEBUFFER: attr = GL_DOUBLEBUFFER; break;
case SDL_GL_DEPTH_SIZE: attr = GL_DEPTH_BITS; break;
case SDL_GL_STENCIL_SIZE: attr = GL_STENCIL_BITS; break;
case SDL_GL_ACCUM_RED_SIZE: attr = GL_ACCUM_RED_BITS; break;
case SDL_GL_ACCUM_GREEN_SIZE: attr = GL_ACCUM_GREEN_BITS; break;
case SDL_GL_ACCUM_BLUE_SIZE: attr = GL_ACCUM_BLUE_BITS; break;
case SDL_GL_ACCUM_ALPHA_SIZE: attr = GL_ACCUM_ALPHA_BITS; break;
case SDL_GL_STEREO: attr = GL_STEREO; break;
case SDL_GL_MULTISAMPLEBUFFERS: attr = GL_SAMPLE_BUFFERS_ARB; break;
case SDL_GL_MULTISAMPLESAMPLES: attr = GL_SAMPLES_ARB; break;
case SDL_GL_BUFFER_SIZE:
{
GLint bits = 0;
GLint component;
/* there doesn't seem to be a single flag in OpenGL for this! */
glGetIntegerv (GL_RED_BITS, &component); bits += component;
glGetIntegerv (GL_GREEN_BITS,&component); bits += component;
glGetIntegerv (GL_BLUE_BITS, &component); bits += component;
glGetIntegerv (GL_ALPHA_BITS, &component); bits += component;
*value = bits;
}
return 0;
}
glGetIntegerv (attr, (GLint *)value);
return 0;
}
static int QZ_GL_MakeCurrent (_THIS) {
[ gl_context makeCurrentContext ];
return 0;
}
static void QZ_GL_SwapBuffers (_THIS) {
[ gl_context flushBuffer ];
}
static int QZ_LockYUV (_THIS, SDL_Overlay *overlay) {
return 0;
}
static void QZ_UnlockYUV (_THIS, SDL_Overlay *overlay) {
;
}
static int QZ_DisplayYUV (_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect) {
OSErr err;
CodecFlags flags;
if (dstrect->x != 0 || dstrect->y != 0) {
SDL_SetError ("Need a dstrect at (0,0)");
return -1;
}
if (dstrect->w != yuv_width || dstrect->h != yuv_height) {
Fixed scale_x, scale_y;
scale_x = FixDiv ( Long2Fix (dstrect->w), Long2Fix (overlay->w) );
scale_y = FixDiv ( Long2Fix (dstrect->h), Long2Fix (overlay->h) );
SetIdentityMatrix (yuv_matrix);
ScaleMatrix (yuv_matrix, scale_x, scale_y, Long2Fix (0), Long2Fix (0));
SetDSequenceMatrix (yuv_seq, yuv_matrix);
yuv_width = dstrect->w;
yuv_height = dstrect->h;
}
if( ( err = DecompressSequenceFrameS(
yuv_seq,
(void*)yuv_pixmap,
sizeof (PlanarPixmapInfoYUV420),
codecFlagUseImageBuffer, &flags, nil ) != noErr ) )
{
SDL_SetError ("DecompressSequenceFrameS failed");
}
return err == noErr;
}
static void QZ_FreeHWYUV (_THIS, SDL_Overlay *overlay) {
CDSequenceEnd (yuv_seq);
ExitMovies();
free (overlay->hwfuncs);
free (overlay->pitches);
free (overlay->pixels);
if (SDL_VideoSurface->flags & SDL_FULLSCREEN) {
[ qz_window close ];
qz_window = nil;
}
free (yuv_matrix);
DisposeHandle ((Handle)yuv_idh);
}
#include "SDL_yuvfuncs.h"
/* check for 16 byte alignment, bail otherwise */
#define CHECK_ALIGN(x) do { if ((Uint32)x & 15) { SDL_SetError("Alignment error"); return NULL; } } while(0)
/* align a byte offset, return how much to add to make it a multiple of 16 */
#define ALIGN(x) ((16 - (x & 15)) & 15)
static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
Uint32 format, SDL_Surface *display) {
Uint32 codec;
OSStatus err;
CGrafPtr port;
SDL_Overlay *overlay;
if (format == SDL_YV12_OVERLAY ||
format == SDL_IYUV_OVERLAY) {
codec = kYUV420CodecType;
}
else {
SDL_SetError ("Hardware: unsupported video format");
return NULL;
}
yuv_idh = (ImageDescriptionHandle) NewHandleClear (sizeof(ImageDescription));
if (yuv_idh == NULL) {
SDL_OutOfMemory();
return NULL;
}
yuv_matrix = (MatrixRecordPtr) malloc (sizeof(MatrixRecord));
if (yuv_matrix == NULL) {
SDL_OutOfMemory();
return NULL;
}
if ( EnterMovies() != noErr ) {
SDL_SetError ("Could not init QuickTime for YUV playback");
return NULL;
}
err = FindCodec (codec, bestSpeedCodec, nil, &yuv_codec);
if (err != noErr) {
SDL_SetError ("Could not find QuickTime codec for format");
return NULL;
}
if (SDL_VideoSurface->flags & SDL_FULLSCREEN) {
/*
Acceleration requires a window to be present.
A CGrafPtr that points to the screen isn't good enough
*/
NSRect content = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
qz_window = [ [ SDL_QuartzWindow alloc ]
initWithContentRect:content
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered defer:NO ];
if (qz_window == nil) {
SDL_SetError ("Could not create the Cocoa window");
return NULL;
}
[ qz_window setContentView:[ [ SDL_QuartzWindowView alloc ] init ] ];
[ qz_window setReleasedWhenClosed:YES ];
[ qz_window center ];
[ qz_window setAcceptsMouseMovedEvents:YES ];
[ qz_window setLevel:CGShieldingWindowLevel() ];
[ qz_window makeKeyAndOrderFront:nil ];
port = [ [ qz_window contentView ] qdPort ];
SetPort (port);
/*
BUG: would like to remove white flash when window kicks in
{
Rect r;
SetRect (&r, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
PaintRect (&r);
QDFlushPortBuffer (port, nil);
}
*/
}
else {
port = [ window_view qdPort ];
SetPort (port);
}
SetIdentityMatrix (yuv_matrix);
HLock ((Handle)yuv_idh);
(**yuv_idh).idSize = sizeof(ImageDescription);
(**yuv_idh).cType = codec;
(**yuv_idh).version = 1;
(**yuv_idh).revisionLevel = 0;
(**yuv_idh).width = width;
(**yuv_idh).height = height;
(**yuv_idh).hRes = Long2Fix(72);
(**yuv_idh).vRes = Long2Fix(72);
(**yuv_idh).spatialQuality = codecLosslessQuality;
(**yuv_idh).frameCount = 1;
(**yuv_idh).clutID = -1;
(**yuv_idh).dataSize = 0;
(**yuv_idh).depth = 24;
HUnlock ((Handle)yuv_idh);
err = DecompressSequenceBeginS (
&yuv_seq,
yuv_idh,
NULL,
0,
port,
NULL,
NULL,
yuv_matrix,
0,
NULL,
codecFlagUseImageBuffer,
codecLosslessQuality,
yuv_codec);
if (err != noErr) {
SDL_SetError ("Error trying to start YUV codec.");
return NULL;
}
overlay = (SDL_Overlay*) malloc (sizeof(*overlay));
if (overlay == NULL) {
SDL_OutOfMemory();
return NULL;
}
overlay->format = format;
overlay->w = width;
overlay->h = height;
overlay->planes = 3;
overlay->hw_overlay = 1;
{
int offset;
Uint8 **pixels;
Uint16 *pitches;
int plane2, plane3;
if (format == SDL_IYUV_OVERLAY) {
plane2 = 1; /* Native codec format */
plane3 = 2;
}
else if (format == SDL_YV12_OVERLAY) {
/* switch the U and V planes */
plane2 = 2; /* U plane maps to plane 3 */
plane3 = 1; /* V plane maps to plane 2 */
}
else {
SDL_SetError("Unsupported YUV format");
return NULL;
}
pixels = (Uint8**) malloc (sizeof(*pixels) * 3);
pitches = (Uint16*) malloc (sizeof(*pitches) * 3);
if (pixels == NULL || pitches == NULL) {
SDL_OutOfMemory();
return NULL;
}
yuv_pixmap = (PlanarPixmapInfoYUV420*)
malloc (sizeof(PlanarPixmapInfoYUV420) +
(width * height * 2));
if (yuv_pixmap == NULL) {
SDL_OutOfMemory ();
return NULL;
}
/* CHECK_ALIGN(yuv_pixmap); */
offset = sizeof(PlanarPixmapInfoYUV420);
/* offset += ALIGN(offset); */
/* CHECK_ALIGN(offset); */
pixels[0] = (Uint8*)yuv_pixmap + offset;
/* CHECK_ALIGN(pixels[0]); */
pitches[0] = width;
yuv_pixmap->componentInfoY.offset = offset;
yuv_pixmap->componentInfoY.rowBytes = width;
offset += width * height;
pixels[plane2] = (Uint8*)yuv_pixmap + offset;
pitches[plane2] = width / 2;
yuv_pixmap->componentInfoCb.offset = offset;
yuv_pixmap->componentInfoCb.rowBytes = width / 2;
offset += (width * height / 4);
pixels[plane3] = (Uint8*)yuv_pixmap + offset;
pitches[plane3] = width / 2;
yuv_pixmap->componentInfoCr.offset = offset;
yuv_pixmap->componentInfoCr.rowBytes = width / 2;
overlay->pixels = pixels;
overlay->pitches = pitches;
}
overlay->hwfuncs = malloc (sizeof(*overlay->hwfuncs));
if (overlay->hwfuncs == NULL) {
SDL_OutOfMemory();
return NULL;
}
overlay->hwfuncs->Lock = QZ_LockYUV;
overlay->hwfuncs->Unlock = QZ_UnlockYUV;
overlay->hwfuncs->Display = QZ_DisplayYUV;
overlay->hwfuncs->FreeHW = QZ_FreeHWYUV;
yuv_width = overlay->w;
yuv_height = overlay->h;
return overlay;
}
/* /*
SDL - Simple DirectMedia Layer SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga Copyright (C) 1997-2003 Sam Lantinga
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public modify it under the terms of the GNU Library General Public
...@@ -20,20 +20,21 @@ ...@@ -20,20 +20,21 @@
slouken@libsdl.org slouken@libsdl.org
*/ */
static void QZ_ChangeGrabState (_THIS, int action); #include "SDL_QuartzVideo.h"
struct WMcursor { struct WMcursor {
Cursor curs; Cursor curs;
}; };
static void QZ_FreeWMCursor (_THIS, WMcursor *cursor) { void QZ_FreeWMCursor (_THIS, WMcursor *cursor) {
if ( cursor != NULL ) if ( cursor != NULL )
free (cursor); free (cursor);
} }
/* Use the Carbon cursor routines for now */ /* Use the Carbon cursor routines for now */
static WMcursor* QZ_CreateWMCursor (_THIS, Uint8 *data, Uint8 *mask, WMcursor* QZ_CreateWMCursor (_THIS, Uint8 *data, Uint8 *mask,
int w, int h, int hot_x, int hot_y) { int w, int h, int hot_x, int hot_y) {
WMcursor *cursor; WMcursor *cursor;
int row, bytes; int row, bytes;
...@@ -68,26 +69,34 @@ static WMcursor* QZ_CreateWMCursor (_THIS, Uint8 *data, Uint8 *mask, ...@@ -68,26 +69,34 @@ static WMcursor* QZ_CreateWMCursor (_THIS, Uint8 *data, Uint8 *mask,
return(cursor); return(cursor);
} }
static int QZ_ShowWMCursor (_THIS, WMcursor *cursor) { void QZ_ShowMouse (_THIS) {
if (!cursor_visible) {
[ NSCursor unhide ];
cursor_visible = YES;
}
}
void QZ_HideMouse (_THIS) {
if (cursor_visible) {
[ NSCursor hide ];
cursor_visible = NO;
}
}
int QZ_ShowWMCursor (_THIS, WMcursor *cursor) {
if ( cursor == NULL) { if ( cursor == NULL) {
if ( cursor_visible ) { if ( cursor_should_be_visible ) {
if (!cursor_hidden) { QZ_HideMouse (this);
HideCursor (); cursor_should_be_visible = NO;
cursor_hidden = YES;
}
cursor_visible = NO;
QZ_ChangeGrabState (this, QZ_HIDECURSOR); QZ_ChangeGrabState (this, QZ_HIDECURSOR);
} }
} }
else { else {
SetCursor(&cursor->curs); SetCursor(&cursor->curs);
if ( ! cursor_visible ) { if ( ! cursor_should_be_visible ) {
if (cursor_hidden) { QZ_ShowMouse (this);
ShowCursor (); cursor_should_be_visible = YES;
cursor_hidden = NO;
}
cursor_visible = YES;
QZ_ChangeGrabState (this, QZ_SHOWCURSOR); QZ_ChangeGrabState (this, QZ_SHOWCURSOR);
} }
} }
...@@ -104,20 +113,20 @@ static int QZ_ShowWMCursor (_THIS, WMcursor *cursor) { ...@@ -104,20 +113,20 @@ static int QZ_ShowWMCursor (_THIS, WMcursor *cursor) {
*/ */
/* Convert Cocoa screen coordinate to Cocoa window coordinate */ /* Convert Cocoa screen coordinate to Cocoa window coordinate */
static void QZ_PrivateGlobalToLocal (_THIS, NSPoint *p) { void QZ_PrivateGlobalToLocal (_THIS, NSPoint *p) {
*p = [ qz_window convertScreenToBase:*p ]; *p = [ qz_window convertScreenToBase:*p ];
} }
/* Convert Cocoa window coordinate to Cocoa screen coordinate */ /* Convert Cocoa window coordinate to Cocoa screen coordinate */
static void QZ_PrivateLocalToGlobal (_THIS, NSPoint *p) { void QZ_PrivateLocalToGlobal (_THIS, NSPoint *p) {
*p = [ qz_window convertBaseToScreen:*p ]; *p = [ qz_window convertBaseToScreen:*p ];
} }
/* Convert SDL coordinate to Cocoa coordinate */ /* Convert SDL coordinate to Cocoa coordinate */
static void QZ_PrivateSDLToCocoa (_THIS, NSPoint *p) { void QZ_PrivateSDLToCocoa (_THIS, NSPoint *p) {
if ( CGDisplayIsCaptured (display_id) ) { /* capture signals fullscreen */ if ( CGDisplayIsCaptured (display_id) ) { /* capture signals fullscreen */
...@@ -134,7 +143,7 @@ static void QZ_PrivateSDLToCocoa (_THIS, NSPoint *p) { ...@@ -134,7 +143,7 @@ static void QZ_PrivateSDLToCocoa (_THIS, NSPoint *p) {
} }
/* Convert Cocoa coordinate to SDL coordinate */ /* Convert Cocoa coordinate to SDL coordinate */
static void QZ_PrivateCocoaToSDL (_THIS, NSPoint *p) { void QZ_PrivateCocoaToSDL (_THIS, NSPoint *p) {
if ( CGDisplayIsCaptured (display_id) ) { /* capture signals fullscreen */ if ( CGDisplayIsCaptured (display_id) ) { /* capture signals fullscreen */
...@@ -151,7 +160,7 @@ static void QZ_PrivateCocoaToSDL (_THIS, NSPoint *p) { ...@@ -151,7 +160,7 @@ static void QZ_PrivateCocoaToSDL (_THIS, NSPoint *p) {
} }
/* Convert SDL coordinate to window server (CoreGraphics) coordinate */ /* Convert SDL coordinate to window server (CoreGraphics) coordinate */
static CGPoint QZ_PrivateSDLToCG (_THIS, NSPoint *p) { CGPoint QZ_PrivateSDLToCG (_THIS, NSPoint *p) {
CGPoint cgp; CGPoint cgp;
...@@ -174,7 +183,7 @@ static CGPoint QZ_PrivateSDLToCG (_THIS, NSPoint *p) { ...@@ -174,7 +183,7 @@ static CGPoint QZ_PrivateSDLToCG (_THIS, NSPoint *p) {
#if 0 /* Dead code */ #if 0 /* Dead code */
/* Convert window server (CoreGraphics) coordinate to SDL coordinate */ /* Convert window server (CoreGraphics) coordinate to SDL coordinate */
static void QZ_PrivateCGToSDL (_THIS, NSPoint *p) { void QZ_PrivateCGToSDL (_THIS, NSPoint *p) {
if ( ! CGDisplayIsCaptured (display_id) ) { /* not captured => not fullscreen => local coord */ if ( ! CGDisplayIsCaptured (display_id) ) { /* not captured => not fullscreen => local coord */
...@@ -190,7 +199,7 @@ static void QZ_PrivateCGToSDL (_THIS, NSPoint *p) { ...@@ -190,7 +199,7 @@ static void QZ_PrivateCGToSDL (_THIS, NSPoint *p) {
} }
#endif /* Dead code */ #endif /* Dead code */
static void QZ_PrivateWarpCursor (_THIS, int x, int y) { void QZ_PrivateWarpCursor (_THIS, int x, int y) {
NSPoint p; NSPoint p;
CGPoint cgp; CGPoint cgp;
...@@ -203,10 +212,10 @@ static void QZ_PrivateWarpCursor (_THIS, int x, int y) { ...@@ -203,10 +212,10 @@ static void QZ_PrivateWarpCursor (_THIS, int x, int y) {
CGWarpMouseCursorPosition (cgp); CGWarpMouseCursorPosition (cgp);
} }
static void QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y) { void QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y) {
/* Only allow warping when in foreground */ /* Only allow warping when in foreground */
if ( ! in_foreground ) if ( ! [ NSApp isActive ] )
return; return;
/* Do the actual warp */ /* Do the actual warp */
...@@ -216,10 +225,10 @@ static void QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y) { ...@@ -216,10 +225,10 @@ static void QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y) {
SDL_PrivateMouseMotion (0, 0, x, y); SDL_PrivateMouseMotion (0, 0, x, y);
} }
static void QZ_MoveWMCursor (_THIS, int x, int y) { } void QZ_MoveWMCursor (_THIS, int x, int y) { }
static void QZ_CheckMouseMode (_THIS) { } void QZ_CheckMouseMode (_THIS) { }
static void QZ_SetCaption (_THIS, const char *title, const char *icon) { void QZ_SetCaption (_THIS, const char *title, const char *icon) {
if ( qz_window != nil ) { if ( qz_window != nil ) {
NSString *string; NSString *string;
...@@ -236,7 +245,7 @@ static void QZ_SetCaption (_THIS, const char *title, const char *icon) { ...@@ -236,7 +245,7 @@ static void QZ_SetCaption (_THIS, const char *title, const char *icon) {
} }
} }
static void QZ_SetIcon (_THIS, SDL_Surface *icon, Uint8 *mask) void QZ_SetIcon (_THIS, SDL_Surface *icon, Uint8 *mask)
{ {
NSBitmapImageRep *imgrep; NSBitmapImageRep *imgrep;
NSImage *img; NSImage *img;
...@@ -305,7 +314,7 @@ freePool: ...@@ -305,7 +314,7 @@ freePool:
[pool release]; [pool release];
} }
static int QZ_IconifyWindow (_THIS) { int QZ_IconifyWindow (_THIS) {
if ( ! [ qz_window isMiniaturized ] ) { if ( ! [ qz_window isMiniaturized ] ) {
[ qz_window miniaturize:nil ]; [ qz_window miniaturize:nil ];
...@@ -318,12 +327,12 @@ static int QZ_IconifyWindow (_THIS) { ...@@ -318,12 +327,12 @@ static int QZ_IconifyWindow (_THIS) {
} }
/* /*
static int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info) { int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info) {
info->nsWindowPtr = qz_window; info->nsWindowPtr = qz_window;
return 0; return 0;
}*/ }*/
static void QZ_ChangeGrabState (_THIS, int action) { void QZ_ChangeGrabState (_THIS, int action) {
/* /*
Figure out what the next state should be based on the action. Figure out what the next state should be based on the action.
...@@ -331,7 +340,7 @@ static void QZ_ChangeGrabState (_THIS, int action) { ...@@ -331,7 +340,7 @@ static void QZ_ChangeGrabState (_THIS, int action) {
*/ */
if ( grab_state == QZ_UNGRABBED ) { if ( grab_state == QZ_UNGRABBED ) {
if ( action == QZ_ENABLE_GRAB ) { if ( action == QZ_ENABLE_GRAB ) {
if ( cursor_visible ) if ( cursor_should_be_visible )
grab_state = QZ_VISIBLE_GRAB; grab_state = QZ_VISIBLE_GRAB;
else else
grab_state = QZ_INVISIBLE_GRAB; grab_state = QZ_INVISIBLE_GRAB;
...@@ -369,7 +378,7 @@ static void QZ_ChangeGrabState (_THIS, int action) { ...@@ -369,7 +378,7 @@ static void QZ_ChangeGrabState (_THIS, int action) {
} }
} }
static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode) { SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode) {
int doGrab = grab_mode & SDL_GRAB_ON; int doGrab = grab_mode & SDL_GRAB_ON;
/*int fullscreen = grab_mode & SDL_GRAB_FULLSCREEN;*/ /*int fullscreen = grab_mode & SDL_GRAB_FULLSCREEN;*/
...@@ -396,81 +405,3 @@ static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode) { ...@@ -396,81 +405,3 @@ static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode) {
return current_grab_mode; return current_grab_mode;
} }
/* Resize icon, BMP format */
static unsigned char QZ_ResizeIcon[] = {
0x42,0x4d,0x31,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x28,0x00,
0x00,0x00,0x0d,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x00,0x00,
0x00,0x00,0xfb,0x01,0x00,0x00,0x13,0x0b,0x00,0x00,0x13,0x0b,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0b,0xff,0xff,
0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,0xda,
0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,
0xe8,0xe8,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xda,0xda,0xda,0x87,
0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,0xe8,
0xe8,0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xff,0xff,0xff,0x0b,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd5,0xd5,0xd5,0x87,0x87,0x87,0xe8,0xe8,0xe8,
0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,
0xda,0xda,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xd7,0xd7,0xd7,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,
0xda,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xff,0xff,0xff,0x0b,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd7,0xd7,0xd7,
0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xda,0xda,0xda,0x87,0x87,0x87,0xe8,
0xe8,0xe8,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd7,0xd7,0xd7,0x87,0x87,0x87,0xe8,0xe8,
0xe8,0xff,0xff,0xff,0xdc,0xdc,0xdc,0x87,0x87,0x87,0xff,0xff,0xff,0x0b,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xd9,0xd9,0xd9,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xdc,
0xdc,0xdc,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdb,0xdb,
0xdb,0x87,0x87,0x87,0xe8,0xe8,0xe8,0xff,0xff,0xff,0xff,0xff,0xff,0x0b,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdb,0xdb,0xdb,0x87,0x87,0x87,0xe8,
0xe8,0xe8,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xdc,0xdc,0xdc,0x87,0x87,0x87,0xff,0xff,0xff,0x0b,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdc,
0xdc,0xdc,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0b
};
static void QZ_DrawResizeIcon (_THIS, RgnHandle dirtyRegion) {
/* Check if we should draw the resize icon */
if (SDL_VideoSurface->flags & SDL_RESIZABLE) {
Rect icon;
SetRect (&icon, SDL_VideoSurface->w - 13, SDL_VideoSurface->h - 13,
SDL_VideoSurface->w, SDL_VideoSurface->h);
if (RectInRgn (&icon, dirtyRegion)) {
SDL_Rect icon_rect;
/* Create the icon image */
if (resize_icon == NULL) {
SDL_RWops *rw;
SDL_Surface *tmp;
rw = SDL_RWFromMem (QZ_ResizeIcon, sizeof(QZ_ResizeIcon));
tmp = SDL_LoadBMP_RW (rw, SDL_TRUE);
resize_icon = SDL_ConvertSurface (tmp, SDL_VideoSurface->format, SDL_SRCCOLORKEY);
SDL_SetColorKey (resize_icon, SDL_SRCCOLORKEY, 0xFFFFFF);
SDL_FreeSurface (tmp);
}
icon_rect.x = SDL_VideoSurface->w - 13;
icon_rect.y = SDL_VideoSurface->h - 13;
icon_rect.w = 13;
icon_rect.h = 13;
SDL_BlitSurface (resize_icon, NULL, SDL_VideoSurface, &icon_rect);
}
}
}
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2003 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@libsdl.org
*/
/* Subclass of NSWindow to fix genie effect and support resize events */
@interface SDL_QuartzWindow : NSWindow
- (void)miniaturize:(id)sender;
- (void)display;
- (void)setFrame:(NSRect)frameRect display:(BOOL)flag;
- (void)appDidHide:(NSNotification*)note;
- (void)appWillUnhide:(NSNotification*)note;
- (void)appDidUnhide:(NSNotification*)note;
- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag;
@end
/* Delegate for our NSWindow to send SDLQuit() on close */
@interface SDL_QuartzWindowDelegate : NSObject
- (BOOL)windowShouldClose:(id)sender;
@end
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2003 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@libsdl.org
*/
#include "SDL_QuartzVideo.h"
#include "SDL_QuartzWindow.h"
/* /*
This function makes the *SDL region* of the window 100% opaque. This function makes the *SDL region* of the window 100% opaque.
...@@ -25,18 +49,6 @@ static void QZ_SetPortAlphaOpaque () { ...@@ -25,18 +49,6 @@ static void QZ_SetPortAlphaOpaque () {
} }
} }
/* Subclass of NSWindow to fix genie effect and support resize events */
@interface SDL_QuartzWindow : NSWindow
{}
- (void)miniaturize:(id)sender;
- (void)display;
- (void)setFrame:(NSRect)frameRect display:(BOOL)flag;
- (void)appDidHide:(NSNotification*)note;
- (void)appWillUnhide:(NSNotification*)note;
- (void)appDidUnhide:(NSNotification*)note;
- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag;
@end
@implementation SDL_QuartzWindow @implementation SDL_QuartzWindow
/* we override these methods to fix the miniaturize animation/dock icon bug */ /* we override these methods to fix the miniaturize animation/dock icon bug */
...@@ -186,12 +198,6 @@ static void QZ_SetPortAlphaOpaque () { ...@@ -186,12 +198,6 @@ static void QZ_SetPortAlphaOpaque () {
@end @end
/* Delegate for our NSWindow to send SDLQuit() on close */
@interface SDL_QuartzWindowDelegate : NSObject
{}
- (BOOL)windowShouldClose:(id)sender;
@end
@implementation SDL_QuartzWindowDelegate @implementation SDL_QuartzWindowDelegate
- (BOOL)windowShouldClose:(id)sender - (BOOL)windowShouldClose:(id)sender
{ {
...@@ -199,11 +205,3 @@ static void QZ_SetPortAlphaOpaque () { ...@@ -199,11 +205,3 @@ static void QZ_SetPortAlphaOpaque () {
return NO; return NO;
} }
@end @end
/* Subclass of NSQuickDrawView for the window's subview */
@interface SDL_QuartzWindowView : NSQuickDrawView
{}
@end
@implementation SDL_QuartzWindowView
@end
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2003 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@libsdl.org
*/
#include "SDL_QuartzVideo.h"
#include "SDL_QuartzWindow.h"
#include "SDL_yuvfuncs.h"
#define yuv_idh (this->hidden->yuv_idh)
#define yuv_matrix (this->hidden->yuv_matrix)
#define yuv_codec (this->hidden->yuv_codec)
#define yuv_seq (this->hidden->yuv_seq)
#define yuv_pixmap (this->hidden->yuv_pixmap)
#define yuv_data (this->hidden->yuv_data)
#define yuv_width (this->hidden->yuv_width)
#define yuv_height (this->hidden->yuv_height)
#define yuv_port (this->hidden->yuv_port)
static int QZ_LockYUV (_THIS, SDL_Overlay *overlay) {
return 0;
}
static void QZ_UnlockYUV (_THIS, SDL_Overlay *overlay) {
;
}
static int QZ_DisplayYUV (_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect) {
OSErr err;
CodecFlags flags;
if (dstrect->x != 0 || dstrect->y != 0) {
SDL_SetError ("Need a dstrect at (0,0)");
return -1;
}
if (dstrect->w != yuv_width || dstrect->h != yuv_height) {
Fixed scale_x, scale_y;
scale_x = FixDiv ( Long2Fix (dstrect->w), Long2Fix (overlay->w) );
scale_y = FixDiv ( Long2Fix (dstrect->h), Long2Fix (overlay->h) );
SetIdentityMatrix (yuv_matrix);
ScaleMatrix (yuv_matrix, scale_x, scale_y, Long2Fix (0), Long2Fix (0));
SetDSequenceMatrix (yuv_seq, yuv_matrix);
yuv_width = dstrect->w;
yuv_height = dstrect->h;
}
if( ( err = DecompressSequenceFrameS(
yuv_seq,
(void*)yuv_pixmap,
sizeof (PlanarPixmapInfoYUV420),
codecFlagUseImageBuffer, &flags, nil ) != noErr ) )
{
SDL_SetError ("DecompressSequenceFrameS failed");
}
return err == noErr;
}
static void QZ_FreeHWYUV (_THIS, SDL_Overlay *overlay) {
CDSequenceEnd (yuv_seq);
ExitMovies();
free (overlay->hwfuncs);
free (overlay->pitches);
free (overlay->pixels);
if (SDL_VideoSurface->flags & SDL_FULLSCREEN) {
[ qz_window close ];
qz_window = nil;
}
free (yuv_matrix);
DisposeHandle ((Handle)yuv_idh);
}
/* check for 16 byte alignment, bail otherwise */
#define CHECK_ALIGN(x) do { if ((Uint32)x & 15) { SDL_SetError("Alignment error"); return NULL; } } while(0)
/* align a byte offset, return how much to add to make it a multiple of 16 */
#define ALIGN(x) ((16 - (x & 15)) & 15)
SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
Uint32 format, SDL_Surface *display) {
Uint32 codec;
OSStatus err;
CGrafPtr port;
SDL_Overlay *overlay;
if (format == SDL_YV12_OVERLAY ||
format == SDL_IYUV_OVERLAY) {
codec = kYUV420CodecType;
}
else {
SDL_SetError ("Hardware: unsupported video format");
return NULL;
}
yuv_idh = (ImageDescriptionHandle) NewHandleClear (sizeof(ImageDescription));
if (yuv_idh == NULL) {
SDL_OutOfMemory();
return NULL;
}
yuv_matrix = (MatrixRecordPtr) malloc (sizeof(MatrixRecord));
if (yuv_matrix == NULL) {
SDL_OutOfMemory();
return NULL;
}
if ( EnterMovies() != noErr ) {
SDL_SetError ("Could not init QuickTime for YUV playback");
return NULL;
}
err = FindCodec (codec, bestSpeedCodec, nil, &yuv_codec);
if (err != noErr) {
SDL_SetError ("Could not find QuickTime codec for format");
return NULL;
}
if (SDL_VideoSurface->flags & SDL_FULLSCREEN) {
/*
Acceleration requires a window to be present.
A CGrafPtr that points to the screen isn't good enough
*/
NSRect content = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
qz_window = [ [ SDL_QuartzWindow alloc ]
initWithContentRect:content
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered defer:NO ];
if (qz_window == nil) {
SDL_SetError ("Could not create the Cocoa window");
return NULL;
}
[ qz_window setContentView:[ [ NSQuickDrawView alloc ] init ] ];
[ qz_window setReleasedWhenClosed:YES ];
[ qz_window center ];
[ qz_window setAcceptsMouseMovedEvents:YES ];
[ qz_window setLevel:CGShieldingWindowLevel() ];
[ qz_window makeKeyAndOrderFront:nil ];
port = [ [ qz_window contentView ] qdPort ];
SetPort (port);
/*
BUG: would like to remove white flash when window kicks in
{
Rect r;
SetRect (&r, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
PaintRect (&r);
QDFlushPortBuffer (port, nil);
}
*/
}
else {
port = [ window_view qdPort ];
SetPort (port);
}
SetIdentityMatrix (yuv_matrix);
HLock ((Handle)yuv_idh);
(**yuv_idh).idSize = sizeof(ImageDescription);
(**yuv_idh).cType = codec;
(**yuv_idh).version = 1;
(**yuv_idh).revisionLevel = 0;
(**yuv_idh).width = width;
(**yuv_idh).height = height;
(**yuv_idh).hRes = Long2Fix(72);
(**yuv_idh).vRes = Long2Fix(72);
(**yuv_idh).spatialQuality = codecLosslessQuality;
(**yuv_idh).frameCount = 1;
(**yuv_idh).clutID = -1;
(**yuv_idh).dataSize = 0;
(**yuv_idh).depth = 24;
HUnlock ((Handle)yuv_idh);
err = DecompressSequenceBeginS (
&yuv_seq,
yuv_idh,
NULL,
0,
port,
NULL,
NULL,
yuv_matrix,
0,
NULL,
codecFlagUseImageBuffer,
codecLosslessQuality,
yuv_codec);
if (err != noErr) {
SDL_SetError ("Error trying to start YUV codec.");
return NULL;
}
overlay = (SDL_Overlay*) malloc (sizeof(*overlay));
if (overlay == NULL) {
SDL_OutOfMemory();
return NULL;
}
overlay->format = format;
overlay->w = width;
overlay->h = height;
overlay->planes = 3;
overlay->hw_overlay = 1;
{
int offset;
Uint8 **pixels;
Uint16 *pitches;
int plane2, plane3;
if (format == SDL_IYUV_OVERLAY) {
plane2 = 1; /* Native codec format */
plane3 = 2;
}
else if (format == SDL_YV12_OVERLAY) {
/* switch the U and V planes */
plane2 = 2; /* U plane maps to plane 3 */
plane3 = 1; /* V plane maps to plane 2 */
}
else {
SDL_SetError("Unsupported YUV format");
return NULL;
}
pixels = (Uint8**) malloc (sizeof(*pixels) * 3);
pitches = (Uint16*) malloc (sizeof(*pitches) * 3);
if (pixels == NULL || pitches == NULL) {
SDL_OutOfMemory();
return NULL;
}
yuv_pixmap = (PlanarPixmapInfoYUV420*)
malloc (sizeof(PlanarPixmapInfoYUV420) +
(width * height * 2));
if (yuv_pixmap == NULL) {
SDL_OutOfMemory ();
return NULL;
}
/* CHECK_ALIGN(yuv_pixmap); */
offset = sizeof(PlanarPixmapInfoYUV420);
/* offset += ALIGN(offset); */
/* CHECK_ALIGN(offset); */
pixels[0] = (Uint8*)yuv_pixmap + offset;
/* CHECK_ALIGN(pixels[0]); */
pitches[0] = width;
yuv_pixmap->componentInfoY.offset = offset;
yuv_pixmap->componentInfoY.rowBytes = width;
offset += width * height;
pixels[plane2] = (Uint8*)yuv_pixmap + offset;
pitches[plane2] = width / 2;
yuv_pixmap->componentInfoCb.offset = offset;
yuv_pixmap->componentInfoCb.rowBytes = width / 2;
offset += (width * height / 4);
pixels[plane3] = (Uint8*)yuv_pixmap + offset;
pitches[plane3] = width / 2;
yuv_pixmap->componentInfoCr.offset = offset;
yuv_pixmap->componentInfoCr.rowBytes = width / 2;
overlay->pixels = pixels;
overlay->pitches = pitches;
}
overlay->hwfuncs = malloc (sizeof(*overlay->hwfuncs));
if (overlay->hwfuncs == NULL) {
SDL_OutOfMemory();
return NULL;
}
overlay->hwfuncs->Lock = QZ_LockYUV;
overlay->hwfuncs->Unlock = QZ_UnlockYUV;
overlay->hwfuncs->Display = QZ_DisplayYUV;
overlay->hwfuncs->FreeHW = QZ_FreeHWYUV;
yuv_width = overlay->w;
yuv_height = overlay->h;
return overlay;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment