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 */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
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