Commit 7b88c898 authored by Sam Lantinga's avatar Sam Lantinga

Lots of cleanups by Darrell, added the ability to resize Cocoa windows.

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40502
parent 2ac69739
...@@ -19,16 +19,8 @@ ...@@ -19,16 +19,8 @@
Sam Lantinga Sam Lantinga
slouken@libsdl.org slouken@libsdl.org
*/ */
#include <sys/time.h>
#include "SDL_QuartzKeys.h" #include "SDL_QuartzKeys.h"
static SDLKey keymap[256];
static unsigned int currentMods = 0; /* Current keyboard modifiers, to track modifier state */
static int last_virtual_button = 0; /* Last virtual mouse button pressed */
static void QZ_InitOSKeymap (_THIS) { static void QZ_InitOSKeymap (_THIS) {
const void *KCHRPtr; const void *KCHRPtr;
UInt32 state; UInt32 state;
...@@ -147,11 +139,12 @@ static void QZ_InitOSKeymap (_THIS) { ...@@ -147,11 +139,12 @@ static void QZ_InitOSKeymap (_THIS) {
keymap[QZ_IBOOK_UP] = SDLK_UP; keymap[QZ_IBOOK_UP] = SDLK_UP;
keymap[QZ_IBOOK_LEFT] = SDLK_LEFT; keymap[QZ_IBOOK_LEFT] = SDLK_LEFT;
/* Up there we setup a static scancode->keysym map. However, it will not /*
* work very well on international keyboard. Hence we now query MacOS Up there we setup a static scancode->keysym map. However, it will not
* for its own keymap to adjust our own mapping table. However, this is work very well on international keyboard. Hence we now query MacOS
* bascially only useful for ascii char keys. This is also the reason for its own keymap to adjust our own mapping table. However, this is
* why we keep the static table, too. basically only useful for ascii char keys. This is also the reason
why we keep the static table, too.
*/ */
/* Get a pointer to the systems cached KCHR */ /* Get a pointer to the systems cached KCHR */
...@@ -180,13 +173,14 @@ static void QZ_InitOSKeymap (_THIS) { ...@@ -180,13 +173,14 @@ static void QZ_InitOSKeymap (_THIS) {
} }
} }
/* The keypad codes are re-setup here, because the loop above cannot /*
* distinguish between a key on the keypad and a regular key. We maybe The keypad codes are re-setup here, because the loop above cannot
* could get around this problem in another fashion: NSEvent's flags distinguish between a key on the keypad and a regular key. We maybe
* include a "NSNumericPadKeyMask" bit; we could check that and modify could get around this problem in another fashion: NSEvent's flags
* the symbol we return on the fly. However, this flag seems to exhibit include a "NSNumericPadKeyMask" bit; we could check that and modify
* some weird behaviour related to the num lock key the symbol we return on the fly. However, this flag seems to exhibit
*/ some weird behaviour related to the num lock key
*/
keymap[QZ_KP0] = SDLK_KP0; keymap[QZ_KP0] = SDLK_KP0;
keymap[QZ_KP1] = SDLK_KP1; keymap[QZ_KP1] = SDLK_KP1;
keymap[QZ_KP2] = SDLK_KP2; keymap[QZ_KP2] = SDLK_KP2;
...@@ -206,14 +200,18 @@ static void QZ_InitOSKeymap (_THIS) { ...@@ -206,14 +200,18 @@ static void QZ_InitOSKeymap (_THIS) {
keymap[QZ_KP_ENTER] = SDLK_KP_ENTER; keymap[QZ_KP_ENTER] = SDLK_KP_ENTER;
} }
static void QZ_DoKey (int state, NSEvent *event) { static void QZ_DoKey (_THIS, int state, NSEvent *event) {
NSString *chars; NSString *chars;
int i; int i;
SDL_keysym key; SDL_keysym key;
/* An event can contain multiple characters */ /*
/* I'll ignore this fact for now, since there is only one virtual key code per event */ An event can contain multiple characters
I'll ignore this fact for now, since there
is only one virtual key code per event, so
no good way to handle this.
*/
chars = [ event characters ]; chars = [ event characters ];
for (i =0; i < 1 /*[ chars length ] */; i++) { for (i =0; i < 1 /*[ chars length ] */; i++) {
...@@ -226,7 +224,7 @@ static void QZ_DoKey (int state, NSEvent *event) { ...@@ -226,7 +224,7 @@ static void QZ_DoKey (int state, NSEvent *event) {
} }
} }
static void QZ_DoModifiers (unsigned int newMods) { static void QZ_DoModifiers (_THIS, unsigned int newMods) {
const int mapping[] = { SDLK_CAPSLOCK, SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, SDLK_LMETA } ; const int mapping[] = { SDLK_CAPSLOCK, SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, SDLK_LMETA } ;
...@@ -244,8 +242,8 @@ static void QZ_DoModifiers (unsigned int newMods) { ...@@ -244,8 +242,8 @@ static void QZ_DoModifiers (unsigned int newMods) {
unsigned int currentMask, newMask; unsigned int currentMask, newMask;
currentMask = currentMods & bit; currentMask = current_mods & bit;
newMask = newMods & bit; newMask = newMods & bit;
if ( currentMask && if ( currentMask &&
currentMask != newMask ) { /* modifier up event */ currentMask != newMask ) { /* modifier up event */
...@@ -267,15 +265,15 @@ static void QZ_DoModifiers (unsigned int newMods) { ...@@ -267,15 +265,15 @@ static void QZ_DoModifiers (unsigned int newMods) {
} }
} }
currentMods = newMods; current_mods = newMods;
} }
static void QZ_DoActivate (_THIS) static void QZ_DoActivate (_THIS)
{ {
inForeground = YES; in_foreground = YES;
/* Regrab the mouse */ /* Regrab the mouse, only if it was previously grabbed */
if (currentGrabMode == SDL_GRAB_ON) { if ( current_grab_mode == SDL_GRAB_ON ) {
QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2); QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
CGAssociateMouseAndMouseCursorPosition (0); CGAssociateMouseAndMouseCursorPosition (0);
} }
...@@ -290,10 +288,10 @@ static void QZ_DoActivate (_THIS) ...@@ -290,10 +288,10 @@ static void QZ_DoActivate (_THIS)
static void QZ_DoDeactivate (_THIS) { static void QZ_DoDeactivate (_THIS) {
inForeground = NO; in_foreground = NO;
/* Ungrab mouse if it is grabbed */ /* Ungrab mouse if it is grabbed */
if (currentGrabMode == SDL_GRAB_ON) { if ( current_grab_mode == SDL_GRAB_ON ) {
CGAssociateMouseAndMouseCursorPosition (1); CGAssociateMouseAndMouseCursorPosition (1);
} }
...@@ -343,7 +341,7 @@ static void QZ_PumpEvents (_THIS) ...@@ -343,7 +341,7 @@ static void QZ_PumpEvents (_THIS)
BOOL isForGameWin; BOOL isForGameWin;
#define DO_MOUSE_DOWN(button, sendToWindow) do { \ #define DO_MOUSE_DOWN(button, sendToWindow) do { \
if ( inForeground ) { \ if ( in_foreground ) { \
if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \ if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \
NSPointInRect([event locationInWindow], winRect) ) \ NSPointInRect([event locationInWindow], winRect) ) \
SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \ SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \
...@@ -366,11 +364,11 @@ static void QZ_PumpEvents (_THIS) ...@@ -366,11 +364,11 @@ static void QZ_PumpEvents (_THIS)
switch (type) { switch (type) {
case NSLeftMouseDown: case NSLeftMouseDown:
if ( NSCommandKeyMask & currentMods ) { if ( NSCommandKeyMask & current_mods ) {
last_virtual_button = 3; last_virtual_button = 3;
DO_MOUSE_DOWN (3, 0); DO_MOUSE_DOWN (3, 0);
} }
else if ( NSAlternateKeyMask & currentMods ) { else if ( NSAlternateKeyMask & current_mods ) {
last_virtual_button = 2; last_virtual_button = 2;
DO_MOUSE_DOWN (2, 0); DO_MOUSE_DOWN (2, 0);
} }
...@@ -392,22 +390,24 @@ static void QZ_PumpEvents (_THIS) ...@@ -392,22 +390,24 @@ static void QZ_PumpEvents (_THIS)
case NSOtherMouseUp: DO_MOUSE_UP (2, 0); break; case NSOtherMouseUp: DO_MOUSE_UP (2, 0); break;
case NSRightMouseUp: DO_MOUSE_UP (3, 0); break; case NSRightMouseUp: DO_MOUSE_UP (3, 0); break;
case NSSystemDefined: case NSSystemDefined:
//if ([event subtype] == 7) { /*
// unsigned int buttons; // up to 32 mouse button states! Future: up to 32 "mouse" buttons can be handled.
// buttons = [ event data2 ]; if ([event subtype] == 7) {
//} unsigned int buttons;
buttons = [ event data2 ];
*/
break; break;
case NSLeftMouseDragged: case NSLeftMouseDragged:
case NSRightMouseDragged: case NSRightMouseDragged:
case NSOtherMouseDragged: /* usually middle mouse dragged */ case NSOtherMouseDragged: /* usually middle mouse dragged */
case NSMouseMoved: case NSMouseMoved:
if (currentGrabMode == SDL_GRAB_ON) { if (current_grab_mode == SDL_GRAB_ON) {
/** /*
* If input is grabbed, the cursor doesn't move, If input is grabbed, the cursor doesn't move,
* so we have to call the lowlevel window server so we have to call the lowlevel window server
* function. This is less accurate but works OK. function. This is less accurate but works OK.
**/ */
CGMouseDelta dx1, dy1; CGMouseDelta dx1, dy1;
CGGetLastMouseDelta (&dx1, &dy1); CGGetLastMouseDelta (&dx1, &dy1);
dx += dx1; dx += dx1;
...@@ -415,12 +415,14 @@ static void QZ_PumpEvents (_THIS) ...@@ -415,12 +415,14 @@ static void QZ_PumpEvents (_THIS)
} }
else if (warp_flag) { else if (warp_flag) {
/** /*
* If we just warped the mouse, the cursor is frozen for a while. If we just warped the mouse, the cursor is frozen for a while.
* So we have to use the lowlevel function until it So we have to use the lowlevel function until it
* unfreezes. This really helps apps that continuously unfreezes. This really helps apps that continuously
* warp the mouse to keep it in the game window. warp the mouse to keep it in the game window. Developers should
**/ really use GrabInput, but our GrabInput freezes the HW cursor,
which doesn't cut it for some apps.
*/
Uint32 ticks; Uint32 ticks;
ticks = SDL_GetTicks(); ticks = SDL_GetTicks();
...@@ -438,14 +440,14 @@ static void QZ_PumpEvents (_THIS) ...@@ -438,14 +440,14 @@ static void QZ_PumpEvents (_THIS)
} }
else if (firstMouseEvent) { else if (firstMouseEvent) {
/** /*
* Get the first mouse event in a possible Get the first mouse event in a possible
* sequence of mouse moved events. Since we sequence of mouse moved events. Since we
* use absolute coordinates, this serves to use absolute coordinates, this serves to
* compensate any inaccuracy in deltas, and compensate any inaccuracy in deltas, and
* provides the first known mouse position, provides the first known mouse position,
* since everything after this uses deltas since everything after this uses deltas
**/ */
NSPoint p = [ event locationInWindow ]; NSPoint p = [ event locationInWindow ];
QZ_PrivateCocoaToSDL(this, &p); QZ_PrivateCocoaToSDL(this, &p);
...@@ -455,12 +457,12 @@ static void QZ_PumpEvents (_THIS) ...@@ -455,12 +457,12 @@ static void QZ_PumpEvents (_THIS)
} }
else { else {
/** /*
* Get the amount moved since the last drag or move event, Get the amount moved since the last drag or move event,
* add it on for one big move event at the end. add it on for one big move event at the end.
**/ */
dx += [ event deltaX ]; dx += [ event deltaX ];
dy += [ event deltaY ]; dy += [ event deltaY ];
} }
break; break;
case NSScrollWheel: case NSScrollWheel:
...@@ -474,13 +476,13 @@ static void QZ_PumpEvents (_THIS) ...@@ -474,13 +476,13 @@ static void QZ_PumpEvents (_THIS)
} }
break; break;
case NSKeyUp: case NSKeyUp:
QZ_DoKey (SDL_RELEASED, event); QZ_DoKey (this, SDL_RELEASED, event);
break; break;
case NSKeyDown: case NSKeyDown:
QZ_DoKey (SDL_PRESSED, event); QZ_DoKey (this, SDL_PRESSED, event);
break; break;
case NSFlagsChanged: case NSFlagsChanged:
QZ_DoModifiers( [ event modifierFlags ] ); QZ_DoModifiers(this, [ event modifierFlags ] );
break; break;
case NSAppKitDefined: case NSAppKitDefined:
switch ( [ event subtype ] ) { switch ( [ event subtype ] ) {
...@@ -507,5 +509,4 @@ static void QZ_PumpEvents (_THIS) ...@@ -507,5 +509,4 @@ static void QZ_PumpEvents (_THIS)
SDL_PrivateMouseMotion (0, 1, dx, dy); SDL_PrivateMouseMotion (0, 1, dx, dy);
[ pool release ]; [ pool release ];
} }
\ No newline at end of file
...@@ -22,9 +22,9 @@ ...@@ -22,9 +22,9 @@
/* /*
@file SDL_QuartzVideo.h @file SDL_QuartzVideo.h
@author Darrell Walisser @author Darrell Walisser, Max Horn, et al.
@abstract SDL video driver for MacOS X. @abstract SDL video driver for Mac OS X.
@discussion @discussion
...@@ -33,17 +33,17 @@ ...@@ -33,17 +33,17 @@
- Keyboard repeat/mouse speed adjust (if needed) - Keyboard repeat/mouse speed adjust (if needed)
- Multiple monitor support (currently only main display) - Multiple monitor support (currently only main display)
- Accelerated blitting support - Accelerated blitting support
- Fix white OpenGL window on minimize (fixed) - Fix white OpenGL window on minimize (fixed) (update: broken again on 10.2)
- Find out what events should be sent/ignored if window is mimimized - Find out what events should be sent/ignored if window is minimized
- Find a way to deal with external resolution/depth switch while app is running - Find a way to deal with external resolution/depth switch while app is running
- Resizeable windows - Resizeable windows (done)
- Check accuracy of QZ_SetGamma() - Check accuracy of QZ_SetGamma()
Problems: Problems:
- OGL not working in full screen with software renderer - OGL not working in full screen with software renderer
- SetColors sets palette correctly but clears framebuffer - SetColors sets palette correctly but clears framebuffer
- Crash in CG after several mode switches (I think this has been fixed) - Crash in CG after several mode switches (I think this has been fixed)
- Retained windows don't draw their title bar quite right (OS Bug) (not using retained windows) - Retained windows don't draw their title bar quite right (OS Bug) (not using retained windows)
- Cursor in 8 bit modes is screwy (might just be Radeon PCI bug) - Cursor in 8 bit modes is screwy (might just be Radeon PCI bug) (update: not just Radeon)
- Warping cursor delays mouse events for a fraction of a second, - Warping cursor delays mouse events for a fraction of a second,
there is a hack around this that helps a bit there is a hack around this that helps a bit
*/ */
...@@ -62,11 +62,11 @@ ...@@ -62,11 +62,11 @@
#include "SDL_events_c.h" #include "SDL_events_c.h"
/* /*
Add methods to get at private members of NSScreen. Add methods to get at private members of NSScreen.
Since there is a bug in Apple's screen switching code Since there is a bug in Apple's screen switching code
that does not update this variable when switching that does not update this variable when switching
to fullscreen, we'll set it manually (but only for the to fullscreen, we'll set it manually (but only for the
main screen). main screen).
*/ */
@interface NSScreen (NSScreenAccess) @interface NSScreen (NSScreenAccess)
- (void) setFrame:(NSRect)frame; - (void) setFrame:(NSRect)frame;
...@@ -79,8 +79,10 @@ ...@@ -79,8 +79,10 @@
} }
@end @end
/* This is a workaround to directly access NSOpenGLContext's CGL context */ /*
/* We need to do this in order to check for errors */ 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) @interface NSOpenGLContext (CGLContextAccess)
- (CGLContextObj) cglContext; - (CGLContextObj) cglContext;
@end @end
...@@ -92,8 +94,10 @@ ...@@ -92,8 +94,10 @@
} }
@end @end
/* Structure for rez switch gamma fades */ /*
/* We can hide the monitor flicker by setting the gamma tables to 0 */ 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 #define QZ_GAMMA_TABLE_SIZE 256
typedef struct { typedef struct {
...@@ -112,14 +116,22 @@ typedef struct SDL_PrivateVideoData { ...@@ -112,14 +116,22 @@ typedef struct SDL_PrivateVideoData {
CFDictionaryRef save_mode; /* original mode of the display */ CFDictionaryRef save_mode; /* original mode of the display */
CFArrayRef mode_list; /* list of available fullscreen modes */ CFArrayRef mode_list; /* list of available fullscreen modes */
CGDirectPaletteRef palette; /* palette of an 8-bit display */ CGDirectPaletteRef palette; /* palette of an 8-bit display */
NSOpenGLContext *gl_context; /* object that represents an OpenGL rendering context */ NSOpenGLContext *gl_context; /* OpenGL rendering context */
Uint32 width, height, bpp; /* frequently used data about the display */ Uint32 width, height, bpp; /* frequently used data about the display */
Uint32 flags; /* flags for mode, for teardown purposes */ Uint32 flags; /* flags for current mode, for teardown purposes */
Uint32 video_set; /* boolean; indicates if video was set correctly */ Uint32 video_set; /* boolean; indicates if video was set correctly */
Uint32 warp_flag; /* boolean; notify to event loop that a warp just occured */ Uint32 warp_flag; /* boolean; notify to event loop that a warp just occured */
Uint32 warp_ticks; /* timestamp when the warp occured */ Uint32 warp_ticks; /* timestamp when the warp occured */
NSWindow *window; /* Cocoa window to implement the SDL window */ NSWindow *window; /* Cocoa window to implement the SDL window */
NSQuickDrawView *view; /* the window's view; draw 2D 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_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 */
SDLKey keymap[256]; /* Mac OS X to SDL key mapping */
Uint32 current_mods; /* current keyboard modifiers, to track modifier state */
Uint32 last_virtual_button;/* last virtual mouse button pressed */
ImageDescriptionHandle yuv_idh; ImageDescriptionHandle yuv_idh;
MatrixRecordPtr yuv_matrix; MatrixRecordPtr yuv_matrix;
DecompressorComponent yuv_codec; DecompressorComponent yuv_codec;
...@@ -146,6 +158,14 @@ typedef struct SDL_PrivateVideoData { ...@@ -146,6 +158,14 @@ typedef struct SDL_PrivateVideoData {
#define video_set (this->hidden->video_set) #define video_set (this->hidden->video_set)
#define warp_ticks (this->hidden->warp_ticks) #define warp_ticks (this->hidden->warp_ticks)
#define warp_flag (this->hidden->warp_flag) #define warp_flag (this->hidden->warp_flag)
#define resize_icon (this->hidden->resize_icon)
#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 keymap (this->hidden->keymap)
#define current_mods (this->hidden->current_mods)
#define last_virtual_button (this->hidden->last_virtual_button)
#define yuv_idh (this->hidden->yuv_idh) #define yuv_idh (this->hidden->yuv_idh)
#define yuv_matrix (this->hidden->yuv_matrix) #define yuv_matrix (this->hidden->yuv_matrix)
#define yuv_codec (this->hidden->yuv_codec) #define yuv_codec (this->hidden->yuv_codec)
...@@ -156,7 +176,13 @@ typedef struct SDL_PrivateVideoData { ...@@ -156,7 +176,13 @@ typedef struct SDL_PrivateVideoData {
#define yuv_height (this->hidden->yuv_height) #define yuv_height (this->hidden->yuv_height)
#define yuv_port (this->hidden->yuv_port) #define yuv_port (this->hidden->yuv_port)
/* Obscuring code: maximum number of windows above ours (inclusive) */ /*
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 #define kMaxWindows 256
/* Some of the Core Graphics Server API for obscuring code */ /* Some of the Core Graphics Server API for obscuring code */
...@@ -171,10 +197,11 @@ typedef struct SDL_PrivateVideoData { ...@@ -171,10 +197,11 @@ typedef struct SDL_PrivateVideoData {
#define kCGSWindowLevelUtility 3 #define kCGSWindowLevelUtility 3
#define kCGSWindowLevelNormal 0 #define kCGSWindowLevelNormal 0
/* For completeness; We never use these window levels, they are always below us /*
#define kCGSWindowLevelMBarShadow -20 For completeness; We never use these window levels, they are always below us
#define kCGSWindowLevelDesktopPicture -2147483647 #define kCGSWindowLevelMBarShadow -20
#define kCGSWindowLevelDesktop -2147483648 #define kCGSWindowLevelDesktopPicture -2147483647
#define kCGSWindowLevelDesktop -2147483648
*/ */
typedef CGError CGSError; typedef CGError CGSError;
...@@ -227,7 +254,7 @@ static int QZ_ToggleFullScreen (_THIS, int on); ...@@ -227,7 +254,7 @@ static int QZ_ToggleFullScreen (_THIS, int on);
static int QZ_SetColors (_THIS, int first_color, static int QZ_SetColors (_THIS, int first_color,
int num_colors, SDL_Color *colors); int num_colors, SDL_Color *colors);
static void QZ_DirectUpdate (_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 int QZ_LockWindow (_THIS, SDL_Surface *surface);
static void QZ_UnlockWindow (_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_UpdateRects (_THIS, int num_rects, SDL_Rect *rects);
static void QZ_VideoQuit (_THIS); static void QZ_VideoQuit (_THIS);
...@@ -246,8 +273,8 @@ static int QZ_SetGammaRamp (_THIS, Uint16 *ramp); ...@@ -246,8 +273,8 @@ static int QZ_SetGammaRamp (_THIS, Uint16 *ramp);
static int QZ_GetGammaRamp (_THIS, Uint16 *ramp); static int QZ_GetGammaRamp (_THIS, Uint16 *ramp);
/* OpenGL functions */ /* OpenGL functions */
static int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags); static int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags);
static void QZ_TearDownOpenGL (_THIS); static void QZ_TearDownOpenGL (_THIS);
static void* QZ_GL_GetProcAddress (_THIS, const char *proc); static void* QZ_GL_GetProcAddress (_THIS, const char *proc);
static int QZ_GL_GetAttribute (_THIS, SDL_GLattr attrib, int* value); static int QZ_GL_GetAttribute (_THIS, SDL_GLattr attrib, int* value);
static int QZ_GL_MakeCurrent (_THIS); static int QZ_GL_MakeCurrent (_THIS);
...@@ -271,13 +298,12 @@ static void QZ_InitOSKeymap (_THIS); ...@@ -271,13 +298,12 @@ static void QZ_InitOSKeymap (_THIS);
static void QZ_PumpEvents (_THIS); static void QZ_PumpEvents (_THIS);
/* Window Manager functions */ /* Window Manager functions */
static void QZ_SetCaption (_THIS, const char *title, const char *icon); static void QZ_SetCaption (_THIS, const char *title, const char *icon);
static void QZ_SetIcon (_THIS, SDL_Surface *icon, Uint8 *mask); static void QZ_SetIcon (_THIS, SDL_Surface *icon, Uint8 *mask);
static int QZ_IconifyWindow (_THIS); static int QZ_IconifyWindow (_THIS);
static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode); static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode);
/*static int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info);*/ /*static int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info);*/
/* YUV functions */ /* YUV functions */
static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height, static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
Uint32 format, SDL_Surface *display); Uint32 format, SDL_Surface *display);
\ No newline at end of file
...@@ -22,11 +22,6 @@ ...@@ -22,11 +22,6 @@
#include "SDL_QuartzVideo.h" #include "SDL_QuartzVideo.h"
/* Some variables to share among files, put in device structure eventually */
static SDL_GrabMode currentGrabMode = SDL_GRAB_OFF;
static BOOL inForeground = YES;
static char QZ_Error[255]; /* Global error buffer to temporarily store more informative error messages */
/* Include files into one compile unit...break apart eventually */ /* Include files into one compile unit...break apart eventually */
#include "SDL_QuartzWM.m" #include "SDL_QuartzWM.m"
#include "SDL_QuartzEvents.m" #include "SDL_QuartzEvents.m"
...@@ -132,6 +127,10 @@ static int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format) { ...@@ -132,6 +127,10 @@ static int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format) {
video_format->BitsPerPixel = device_bpp; video_format->BitsPerPixel = device_bpp;
/* Set misc globals */
current_grab_mode = SDL_GRAB_OFF;
in_foreground = YES;
return 0; return 0;
} }
...@@ -140,7 +139,6 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) { ...@@ -140,7 +139,6 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
CFIndex num_modes; CFIndex num_modes;
CFIndex i; CFIndex i;
static SDL_Rect **list = NULL;
int list_size = 0; int list_size = 0;
/* Any windowed mode is acceptable */ /* Any windowed mode is acceptable */
...@@ -148,15 +146,15 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) { ...@@ -148,15 +146,15 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
return (SDL_Rect**)-1; return (SDL_Rect**)-1;
/* Free memory from previous call, if any */ /* Free memory from previous call, if any */
if ( list != NULL ) { if ( client_mode_list != NULL ) {
int i; int i;
for (i = 0; list[i] != NULL; i++) for (i = 0; client_mode_list[i] != NULL; i++)
free (list[i]); free (client_mode_list[i]);
free (list); free (client_mode_list);
list = NULL; client_mode_list = NULL;
} }
num_modes = CFArrayGetCount (mode_list); num_modes = CFArrayGetCount (mode_list);
...@@ -191,7 +189,8 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) { ...@@ -191,7 +189,8 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
int i; int i;
hasMode = SDL_FALSE; hasMode = SDL_FALSE;
for (i = 0; i < list_size; i++) { for (i = 0; i < list_size; i++) {
if (list[i]->w == width && list[i]->h == height) { if (client_mode_list[i]->w == width &&
client_mode_list[i]->h == height) {
hasMode = SDL_TRUE; hasMode = SDL_TRUE;
break; break;
} }
...@@ -205,14 +204,16 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) { ...@@ -205,14 +204,16 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
list_size++; list_size++;
if (list == NULL) if (client_mode_list == NULL)
list = (SDL_Rect**) malloc (sizeof(*list) * (list_size+1) ); client_mode_list = (SDL_Rect**)
malloc (sizeof(*client_mode_list) * (list_size+1) );
else else
list = (SDL_Rect**) realloc (list, sizeof(*list) * (list_size+1)); client_mode_list = (SDL_Rect**)
realloc (client_mode_list, sizeof(*client_mode_list) * (list_size+1));
rect = (SDL_Rect*) malloc (sizeof(**list)); rect = (SDL_Rect*) malloc (sizeof(**client_mode_list));
if (list == NULL || rect == NULL) { if (client_mode_list == NULL || rect == NULL) {
SDL_OutOfMemory (); SDL_OutOfMemory ();
return NULL; return NULL;
} }
...@@ -220,8 +221,8 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) { ...@@ -220,8 +221,8 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
rect->w = width; rect->w = width;
rect->h = height; rect->h = height;
list[list_size-1] = rect; client_mode_list[list_size-1] = rect;
list[list_size] = NULL; client_mode_list[list_size] = NULL;
} }
} }
} }
...@@ -233,23 +234,25 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) { ...@@ -233,23 +234,25 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
for (j = 0; j < list_size-1; j++) { for (j = 0; j < list_size-1; j++) {
int area1, area2; int area1, area2;
area1 = list[j]->w * list[j]->h; area1 = client_mode_list[j]->w * client_mode_list[j]->h;
area2 = list[j+1]->w * list[j+1]->h; area2 = client_mode_list[j+1]->w * client_mode_list[j+1]->h;
if (area1 < area2) { if (area1 < area2) {
SDL_Rect *tmp = list[j]; SDL_Rect *tmp = client_mode_list[j];
list[j] = list[j+1]; client_mode_list[j] = client_mode_list[j+1];
list[j+1] = tmp; client_mode_list[j+1] = tmp;
} }
} }
} }
} }
return list; return client_mode_list;
} }
/* Gamma functions to try to hide the flash from a rez switch */ /*
/* Fade the display from normal to black */ Gamma functions to try to hide the flash from a rez switch
/* Save gamma tables for fade back to normal */ Fade the display from normal to black
Save gamma tables for fade back to normal
*/
static UInt32 QZ_FadeGammaOut (_THIS, SDL_QuartzGammaTable *table) { static UInt32 QZ_FadeGammaOut (_THIS, SDL_QuartzGammaTable *table) {
CGGammaValue redTable[QZ_GAMMA_TABLE_SIZE], CGGammaValue redTable[QZ_GAMMA_TABLE_SIZE],
...@@ -295,8 +298,10 @@ static UInt32 QZ_FadeGammaOut (_THIS, SDL_QuartzGammaTable *table) { ...@@ -295,8 +298,10 @@ static UInt32 QZ_FadeGammaOut (_THIS, SDL_QuartzGammaTable *table) {
return 0; return 0;
} }
/* Fade the display from black to normal */ /*
/* Restore previously saved gamma values */ Fade the display from black to normal
Restore previously saved gamma values
*/
static UInt32 QZ_FadeGammaIn (_THIS, SDL_QuartzGammaTable *table) { static UInt32 QZ_FadeGammaIn (_THIS, SDL_QuartzGammaTable *table) {
CGGammaValue redTable[QZ_GAMMA_TABLE_SIZE], CGGammaValue redTable[QZ_GAMMA_TABLE_SIZE],
...@@ -336,10 +341,12 @@ static UInt32 QZ_FadeGammaIn (_THIS, SDL_QuartzGammaTable *table) { ...@@ -336,10 +341,12 @@ static UInt32 QZ_FadeGammaIn (_THIS, SDL_QuartzGammaTable *table) {
static void QZ_UnsetVideoMode (_THIS) { static void QZ_UnsetVideoMode (_THIS) {
/* Reset values that may change between switches */ /* Reset values that may change between switches */
this->info.blit_fill = 0; this->info.blit_fill = 0;
this->FillHWRect = NULL; this->FillHWRect = NULL;
this->UpdateRects = NULL; this->UpdateRects = NULL;
this->LockHWSurface = NULL;
this->UnlockHWSurface = NULL;
/* Release fullscreen resources */ /* Release fullscreen resources */
if ( mode_flags & SDL_FULLSCREEN ) { if ( mode_flags & SDL_FULLSCREEN ) {
...@@ -349,22 +356,24 @@ static void QZ_UnsetVideoMode (_THIS) { ...@@ -349,22 +356,24 @@ static void QZ_UnsetVideoMode (_THIS) {
gamma_error = QZ_FadeGammaOut (this, &gamma_table); gamma_error = QZ_FadeGammaOut (this, &gamma_table);
/* Release the OpenGL context */ /*
/* Do this first to avoid trash on the display before fade */ Release the OpenGL context
if ( mode_flags & SDL_OPENGL ) Do this first to avoid trash on the display before fade
*/
if ( mode_flags & SDL_OPENGL ) {
QZ_TearDownOpenGL (this); QZ_TearDownOpenGL (this);
CGLSetFullScreen (NULL);
if (mode_flags & SDL_OPENGL) }
CGLSetFullScreen(NULL);
/* Restore original screen resolution/bpp */ /* Restore original screen resolution/bpp */
CGDisplaySwitchToMode (display_id, save_mode); CGDisplaySwitchToMode (display_id, save_mode);
CGDisplayRelease (display_id); CGDisplayRelease (display_id);
ShowMenuBar (); ShowMenuBar ();
/* /*
reset the main screen's rectangle, see comment Reset the main screen's rectangle
in QZ_SetVideoFullscreen See comment in QZ_SetVideoFullscreen for why we do this
*/ */
screen_rect = NSMakeRect(0,0,device_width,device_height); screen_rect = NSMakeRect(0,0,device_width,device_height);
[ [ NSScreen mainScreen ] setFrame:screen_rect ]; [ [ NSScreen mainScreen ] setFrame:screen_rect ];
...@@ -374,16 +383,12 @@ static void QZ_UnsetVideoMode (_THIS) { ...@@ -374,16 +383,12 @@ static void QZ_UnsetVideoMode (_THIS) {
} }
/* Release window mode resources */ /* Release window mode resources */
else { else {
if ( (mode_flags & SDL_OPENGL) == 0 ) {
UnlockPortBits ( [ window_view qdPort ] );
[ window_view release ];
}
[ qz_window setContentView:nil ];
[ qz_window setDelegate:nil ];
[ qz_window close ]; [ qz_window close ];
[ qz_window release ]; [ qz_window release ];
qz_window = nil; qz_window = nil;
window_view = nil;
/* Release the OpenGL context */ /* Release the OpenGL context */
if ( mode_flags & SDL_OPENGL ) if ( mode_flags & SDL_OPENGL )
QZ_TearDownOpenGL (this); QZ_TearDownOpenGL (this);
...@@ -392,10 +397,6 @@ static void QZ_UnsetVideoMode (_THIS) { ...@@ -392,10 +397,6 @@ static void QZ_UnsetVideoMode (_THIS) {
/* Restore gamma settings */ /* Restore gamma settings */
CGDisplayRestoreColorSyncSettings (); CGDisplayRestoreColorSyncSettings ();
/* Set pixels to null (so other code doesn't try to free it) */
if (this->screen != NULL)
this->screen->pixels = NULL;
/* Ensure the cursor will be visible and working when we quit */ /* Ensure the cursor will be visible and working when we quit */
CGDisplayShowCursor (display_id); CGDisplayShowCursor (display_id);
CGAssociateMouseAndMouseCursorPosition (1); CGAssociateMouseAndMouseCursorPosition (1);
...@@ -411,14 +412,17 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt ...@@ -411,14 +412,17 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
SDL_QuartzGammaTable gamma_table; SDL_QuartzGammaTable gamma_table;
NSRect screen_rect; NSRect screen_rect;
/* Destroy any previous mode */
if (video_set == SDL_TRUE)
QZ_UnsetVideoMode (this);
/* See if requested mode exists */ /* See if requested mode exists */
mode = CGDisplayBestModeForParameters (display_id, bpp, width, mode = CGDisplayBestModeForParameters (display_id, bpp, width,
height, &exact_match); height, &exact_match);
/* Require an exact match to the requested mode */ /* Require an exact match to the requested mode */
if ( ! exact_match ) { if ( ! exact_match ) {
sprintf (QZ_Error, "Failed to find display resolution: %dx%dx%d", width, height, bpp); SDL_SetError ("Failed to find display resolution: %dx%dx%d", width, height, bpp);
SDL_SetError (QZ_Error);
goto ERR_NO_MATCH; goto ERR_NO_MATCH;
} }
...@@ -431,7 +435,6 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt ...@@ -431,7 +435,6 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
goto ERR_NO_CAPTURE; goto ERR_NO_CAPTURE;
} }
/* Do the physical switch */ /* Do the physical switch */
if ( CGDisplayNoErr != CGDisplaySwitchToMode (display_id, mode) ) { if ( CGDisplayNoErr != CGDisplaySwitchToMode (display_id, mode) ) {
SDL_SetError ("Failed switching display resolution"); SDL_SetError ("Failed switching display resolution");
...@@ -446,9 +449,12 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt ...@@ -446,9 +449,12 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
current->h = height; current->h = height;
current->flags |= SDL_FULLSCREEN; current->flags |= SDL_FULLSCREEN;
current->flags |= SDL_HWSURFACE; current->flags |= SDL_HWSURFACE;
current->flags |= SDL_PREALLOC;
this->UpdateRects = QZ_DirectUpdate;
this->UpdateRects = QZ_DirectUpdate;
this->LockHWSurface = QZ_LockHWSurface;
this->UnlockHWSurface = QZ_UnlockHWSurface;
/* Setup some mode-dependant info */ /* Setup some mode-dependant info */
if ( CGSDisplayCanHWFill (display_id) ) { if ( CGSDisplayCanHWFill (display_id) ) {
this->info.blit_fill = 1; this->info.blit_fill = 1;
...@@ -472,8 +478,7 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt ...@@ -472,8 +478,7 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
err = CGLSetFullScreen (ctx); err = CGLSetFullScreen (ctx);
if (err) { if (err) {
sprintf (QZ_Error, "Error setting OpenGL fullscreen: %s", CGLErrorString(err)); SDL_SetError ("Error setting OpenGL fullscreen: %s", CGLErrorString(err));
SDL_SetError (QZ_Error);
goto ERR_NO_GL; goto ERR_NO_GL;
} }
...@@ -494,11 +499,11 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt ...@@ -494,11 +499,11 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
QZ_FadeGammaIn (this, &gamma_table); QZ_FadeGammaIn (this, &gamma_table);
/* /*
There is a bug in Cocoa where NSScreen doesn't synchronize There is a bug in Cocoa where NSScreen doesn't synchronize
with CGDirectDisplay, so the main screen's frame is wrong. with CGDirectDisplay, so the main screen's frame is wrong.
As a result, coordinate translation produces wrong results. As a result, coordinate translation produces incorrect results.
We can hack around this bug by setting the screen rect We can hack around this bug by setting the screen rect
ourselves. This hack should be removed if/when the bug is fixed. ourselves. This hack should be removed if/when the bug is fixed.
*/ */
screen_rect = NSMakeRect(0,0,width,height); screen_rect = NSMakeRect(0,0,width,height);
[ [ NSScreen mainScreen ] setFrame:screen_rect ]; [ [ NSScreen mainScreen ] setFrame:screen_rect ];
...@@ -518,79 +523,111 @@ ERR_NO_MATCH: return NULL; ...@@ -518,79 +523,111 @@ ERR_NO_MATCH: return NULL;
static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width, static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
int height, int bpp, Uint32 flags) { int height, int bpp, Uint32 flags) {
unsigned int style; unsigned int style;
NSRect rect; NSRect contentRect;
rect = NSMakeRect (0, 0, width, height);
#if 1 // FIXME - the resize button doesn't show? Also need resize events...
flags &= ~SDL_RESIZABLE;
#endif
/* Set the window style based on input flags */
if ( flags & SDL_NOFRAME ) {
style = NSBorderlessWindowMask;
} else {
style = NSTitledWindowMask;
style |= (NSMiniaturizableWindowMask | NSClosableWindowMask);
if ( flags & SDL_RESIZABLE )
style |= NSResizableWindowMask;
}
/* Manually create a window, avoids having a nib file resource */
qz_window = [ [ SDL_QuartzWindow alloc ] initWithContentRect:rect
styleMask:style backing:NSBackingStoreBuffered defer:NO ];
if (qz_window == nil) {
SDL_SetError ("Could not create the Cocoa window");
return NULL;
}
current->flags = 0; current->flags = 0;
current->w = width; current->w = width;
current->h = height; current->h = height;
contentRect = NSMakeRect (0, 0, width, height);
/*
Check if we should completely destroy the previous mode
- If it is fullscreen
- If it has different noframe or resizable attribute
- If it is OpenGL (since gl attributes could be different)
- If new mode is OpenGL, but previous mode wasn't
*/
if (video_set == SDL_TRUE)
if ( (mode_flags & SDL_FULLSCREEN) ||
((mode_flags ^ flags) & (SDL_NOFRAME|SDL_RESIZABLE)) ||
(mode_flags & SDL_OPENGL) ||
(flags & SDL_OPENGL) )
QZ_UnsetVideoMode (this);
/* Check if we should recreate the window */
if (qz_window == nil) {
/* Set the window style based on input flags */
if ( flags & SDL_NOFRAME ) {
style = NSBorderlessWindowMask;
current->flags |= SDL_NOFRAME;
} else {
style = NSTitledWindowMask;
style |= (NSMiniaturizableWindowMask | NSClosableWindowMask);
if ( flags & SDL_RESIZABLE ) {
style |= NSResizableWindowMask;
current->flags |= SDL_RESIZABLE;
}
}
/* Manually create a window, avoids having a nib file resource */
qz_window = [ [ SDL_QuartzWindow alloc ]
initWithContentRect:contentRect
styleMask:style
backing:NSBackingStoreBuffered
defer:NO ];
if (qz_window == nil) {
SDL_SetError ("Could not create the Cocoa window");
return NULL;
}
[ qz_window setReleasedWhenClosed:YES ];
QZ_SetCaption(this, this->wm_title, this->wm_icon);
[ qz_window setAcceptsMouseMovedEvents:YES ];
[ qz_window setViewsNeedDisplay:NO ];
[ qz_window center ];
[ qz_window setDelegate:
[ [ [ SDL_QuartzWindowDelegate alloc ] init ] autorelease ] ];
}
/* We already have a window, just change its size */
else {
[ qz_window setContentSize:contentRect.size ];
current->flags |= (SDL_NOFRAME|SDL_RESIZABLE) & mode_flags;
}
[ qz_window setReleasedWhenClosed:YES ]; /* For OpenGL, we bind the context to a subview */
QZ_SetCaption(this, this->wm_title, this->wm_icon);
[ qz_window setAcceptsMouseMovedEvents:YES ];
[ qz_window setViewsNeedDisplay:NO ];
[ qz_window center ];
[ qz_window setDelegate:
[ [ [ SDL_QuartzWindowDelegate alloc ] init ] autorelease ] ];
/* For OpenGL, we set the content view to a NSOpenGLView */
if ( flags & SDL_OPENGL ) { if ( flags & SDL_OPENGL ) {
if ( ! QZ_SetupOpenGL (this, bpp, flags) ) { if ( ! QZ_SetupOpenGL (this, bpp, flags) ) {
return NULL; return NULL;
} }
[ gl_context setView: [ qz_window contentView ] ]; window_view = [ [ NSView alloc ] initWithFrame:contentRect ];
[ window_view setAutoresizingMask: NSViewMinYMargin ];
[ [ qz_window contentView ] addSubview:window_view ];
[ gl_context setView: window_view ];
[ window_view release ];
[ gl_context makeCurrentContext]; [ gl_context makeCurrentContext];
[ qz_window makeKeyAndOrderFront:nil ]; [ qz_window makeKeyAndOrderFront:nil ];
current->flags |= SDL_OPENGL; current->flags |= SDL_OPENGL;
} }
/* For 2D, we set the content view to a NSQuickDrawView */ /* For 2D, we set the subview to an NSQuickDrawView */
else { else {
window_view = [ [ SDL_QuartzWindowView alloc ] init ]; /* Only recreate the view if it doesn't already exist */
[ qz_window setContentView:window_view ]; if (window_view == nil) {
[ qz_window makeKeyAndOrderFront:nil ];
window_view = [ [ SDL_QuartzWindowView alloc ] initWithFrame:contentRect ];
[ window_view setAutoresizingMask: NSViewMinYMargin ];
[ [ qz_window contentView ] addSubview:window_view ];
[ window_view release ];
[ qz_window makeKeyAndOrderFront:nil ];
}
LockPortBits ( [ window_view qdPort ] ); LockPortBits ( [ window_view qdPort ] );
current->pixels = GetPixBaseAddr ( GetPortPixMap ( [ window_view qdPort ] ) ); current->pixels = GetPixBaseAddr ( GetPortPixMap ( [ window_view qdPort ] ) );
current->pitch = GetPixRowBytes ( GetPortPixMap ( [ window_view qdPort ] ) ); current->pitch = GetPixRowBytes ( GetPortPixMap ( [ window_view qdPort ] ) );
UnlockPortBits ( [ window_view qdPort ] ); UnlockPortBits ( [ window_view qdPort ] );
current->flags |= SDL_SWSURFACE; current->flags |= SDL_SWSURFACE;
current->flags |= SDL_PREALLOC; current->flags |= SDL_PREALLOC;
current->flags |= SDL_ASYNCBLIT; current->flags |= SDL_ASYNCBLIT;
if ( flags & SDL_NOFRAME ) /* Offset below the title bar to fill the full content region */
current->flags |= SDL_NOFRAME; current->pixels += ((int)([ qz_window frame ].size.height) - height) * current->pitch;
if ( flags & SDL_RESIZABLE )
current->flags |= SDL_RESIZABLE;
/* Offset 22 pixels down to fill the full content region */
if ( ! (current->flags & SDL_NOFRAME) ) {
current->pixels += 22 * current->pitch;
}
this->UpdateRects = QZ_UpdateRects; this->UpdateRects = QZ_UpdateRects;
this->LockHWSurface = QZ_LockWindow; this->LockHWSurface = QZ_LockWindow;
...@@ -606,9 +643,6 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width, ...@@ -606,9 +643,6 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width, static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width,
int height, int bpp, Uint32 flags) { int height, int bpp, Uint32 flags) {
if (video_set == SDL_TRUE)
QZ_UnsetVideoMode (this);
current->flags = 0; current->flags = 0;
/* Setup full screen video */ /* Setup full screen video */
...@@ -696,17 +730,18 @@ static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects) { ...@@ -696,17 +730,18 @@ static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects) {
#pragma unused(this,num_rects,rects) #pragma unused(this,num_rects,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.
**/ */
static int QZ_IsWindowObscured (NSWindow *window) { static int QZ_IsWindowObscured (NSWindow *window) {
//#define TEST_OBSCURED 1 //#define TEST_OBSCURED 1
#if TEST_OBSCURED #if TEST_OBSCURED
/* In order to determine if a direct copy to the screen is possible, /*
In order to determine if a direct copy to the screen is possible,
we must figure out if there are any windows covering ours (including shadows). we must figure out if there are any windows covering ours (including shadows).
This can be done by querying the window server about the on screen This can be done by querying the window server about the on screen
windows for their screen rectangle and window level. windows for their screen rectangle and window level.
...@@ -753,11 +788,15 @@ static int QZ_IsWindowObscured (NSWindow *window) { ...@@ -753,11 +788,15 @@ static int QZ_IsWindowObscured (NSWindow *window) {
if ( [ window isVisible ] ) { if ( [ window isVisible ] ) {
/* walk the window list looking for windows over top of /*
(or casting a shadow on) ours */ walk the window list looking for windows over top of
(or casting a shadow on) ours
*/
/* Get a connection to the window server */ /*
/* Should probably be moved out into SetVideoMode() or InitVideo() */ Get a connection to the window server
Should probably be moved out into SetVideoMode() or InitVideo()
*/
if (cgsConnection == (CGSConnectionID) -1) { if (cgsConnection == (CGSConnectionID) -1) {
cgsConnection = (CGSConnectionID) 0; cgsConnection = (CGSConnectionID) 0;
cgsConnection = _CGSDefaultConnection (); cgsConnection = _CGSDefaultConnection ();
...@@ -785,8 +824,10 @@ static int QZ_IsWindowObscured (NSWindow *window) { ...@@ -785,8 +824,10 @@ static int QZ_IsWindowObscured (NSWindow *window) {
firstDockIcon = -1; firstDockIcon = -1;
dockIconCacheMiss = SDL_FALSE; dockIconCacheMiss = SDL_FALSE;
/* The first window is always an empty window with level kCGSWindowLevelTop /*
so start at index 1 */ The first window is always an empty window with level kCGSWindowLevelTop
so start at index 1
*/
for (i = 1; i < count; i++) { for (i = 1; i < count; i++) {
/* If we reach our window in the list, it cannot be obscured */ /* If we reach our window in the list, it cannot be obscured */
...@@ -856,8 +897,10 @@ static int QZ_IsWindowObscured (NSWindow *window) { ...@@ -856,8 +897,10 @@ static int QZ_IsWindowObscured (NSWindow *window) {
} }
else if (winLevel == kCGSWindowLevelNormal) { else if (winLevel == kCGSWindowLevelNormal) {
/* These numbers are for foreground windows, /*
they are too big (but will work) for background windows */ These numbers are for foreground windows,
they are too big (but will work) for background windows
*/
shadowSide = 20; shadowSide = 20;
shadowTop = 10; shadowTop = 10;
shadowBottom = 24; shadowBottom = 24;
...@@ -880,9 +923,11 @@ static int QZ_IsWindowObscured (NSWindow *window) { ...@@ -880,9 +923,11 @@ static int QZ_IsWindowObscured (NSWindow *window) {
} }
else { else {
/* kCGSWindowLevelDockLabel, /*
kCGSWindowLevelDock, kCGSWindowLevelDockLabel,
kOther??? */ kCGSWindowLevelDock,
kOther???
*/
/* no shadow */ /* no shadow */
shadowSide = 0; shadowSide = 0;
...@@ -917,6 +962,7 @@ static int QZ_IsWindowObscured (NSWindow *window) { ...@@ -917,6 +962,7 @@ static int QZ_IsWindowObscured (NSWindow *window) {
#endif #endif
} }
/* Locking functions for the software window buffer */ /* Locking functions for the software window buffer */
static int QZ_LockWindow (_THIS, SDL_Surface *surface) { static int QZ_LockWindow (_THIS, SDL_Surface *surface) {
...@@ -933,17 +979,11 @@ static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) { ...@@ -933,17 +979,11 @@ static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) {
if (SDL_VideoSurface->flags & SDL_OPENGLBLIT) { if (SDL_VideoSurface->flags & SDL_OPENGLBLIT) {
QZ_GL_SwapBuffers (this); QZ_GL_SwapBuffers (this);
} }
else if ( [ qz_window isMiniaturized ] && else if ( [ qz_window isMiniaturized ] ) {
! (SDL_VideoSurface->flags & SDL_OPENGL)) {
/* Do nothing if miniaturized */
/**
* Set port alpha opaque so deminiaturize looks right
* This isn't so nice, but there is no
* initial deminatureize notification (before demini starts)
**/
QZ_SetPortAlphaOpaque ([ [ qz_window contentView ] qdPort],
[ qz_window styleMask ] & NSBorderlessWindowMask);
} }
else if ( ! QZ_IsWindowObscured (qz_window) ) { else if ( ! QZ_IsWindowObscured (qz_window) ) {
/* Use direct copy to flush contents to the display */ /* Use direct copy to flush contents to the display */
...@@ -992,7 +1032,6 @@ static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) { ...@@ -992,7 +1032,6 @@ static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) {
SetPort (savePort); SetPort (savePort);
} }
else { else {
/* Use QDFlushPortBuffer() to flush content to display */ /* Use QDFlushPortBuffer() to flush content to display */
int i; int i;
RgnHandle dirty = NewRgn (); RgnHandle dirty = NewRgn ();
...@@ -1004,10 +1043,12 @@ static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) { ...@@ -1004,10 +1043,12 @@ static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) {
for (i = 0; i < numRects; i++) { for (i = 0; i < numRects; i++) {
MacSetRectRgn (temp, rects[i].x, rects[i].y, MacSetRectRgn (temp, rects[i].x, rects[i].y,
rects[i].x + rects[i].w, rects[i].y + rects[i].h); rects[i].x + rects[i].w, rects[i].y + rects[i].h);
MacUnionRgn (dirty, temp, dirty); MacUnionRgn (dirty, temp, dirty);
} }
QZ_DrawResizeIcon (this, dirty);
/* Flush the dirty region */ /* Flush the dirty region */
QDFlushPortBuffer ( [ window_view qdPort ], dirty ); QDFlushPortBuffer ( [ window_view qdPort ], dirty );
DisposeRgn (dirty); DisposeRgn (dirty);
...@@ -1363,15 +1404,10 @@ static void QZ_FreeHWYUV (_THIS, SDL_Overlay *overlay) { ...@@ -1363,15 +1404,10 @@ static void QZ_FreeHWYUV (_THIS, SDL_Overlay *overlay) {
#include "SDL_yuvfuncs.h" #include "SDL_yuvfuncs.h"
/** /* check for 16 byte alignment, bail otherwise */
* check for 16 byte alignment, bail otherwise
**/
#define CHECK_ALIGN(x) do { if ((Uint32)x & 15) { SDL_SetError("Alignment error"); return NULL; } } while(0) #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 */
* align a byte offset, return how much to add to make it
* a multiple of 16
**/
#define ALIGN(x) ((16 - (x & 15)) & 15) #define ALIGN(x) ((16 - (x & 15)) & 15)
static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height, static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
...@@ -1417,10 +1453,10 @@ static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height, ...@@ -1417,10 +1453,10 @@ static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
if (SDL_VideoSurface->flags & SDL_FULLSCREEN) { if (SDL_VideoSurface->flags & SDL_FULLSCREEN) {
/** /*
* Good acceleration requires a window to be present. Acceleration requires a window to be present.
* A CGrafPtr that points to the screen isn't good enough A CGrafPtr that points to the screen isn't good enough
**/ */
NSRect content = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h); NSRect content = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
qz_window = [ [ SDL_QuartzWindow alloc ] qz_window = [ [ SDL_QuartzWindow alloc ]
...@@ -1442,17 +1478,20 @@ static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height, ...@@ -1442,17 +1478,20 @@ static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
port = [ [ qz_window contentView ] qdPort ]; port = [ [ qz_window contentView ] qdPort ];
SetPort (port); SetPort (port);
// BUG: would like to remove white flash when window kicks in
//{ /*
// Rect r; BUG: would like to remove white flash when window kicks in
// SetRect (&r, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h); {
// PaintRect (&r); Rect r;
// QDFlushPortBuffer (port, nil); SetRect (&r, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
//} PaintRect (&r);
QDFlushPortBuffer (port, nil);
}
*/
} }
else { else {
port = [ [ qz_window contentView ] qdPort ]; port = [ window_view qdPort ];
SetPort (port); SetPort (port);
} }
...@@ -1544,13 +1583,13 @@ static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height, ...@@ -1544,13 +1583,13 @@ static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
return NULL; return NULL;
} }
//CHECK_ALIGN(yuv_pixmap); /* CHECK_ALIGN(yuv_pixmap); */
offset = sizeof(PlanarPixmapInfoYUV420); offset = sizeof(PlanarPixmapInfoYUV420);
//offset += ALIGN(offset); /* offset += ALIGN(offset); */
//CHECK_ALIGN(offset); /* CHECK_ALIGN(offset); */
pixels[0] = (Uint8*)yuv_pixmap + offset; pixels[0] = (Uint8*)yuv_pixmap + offset;
//CHECK_ALIGN(pixels[0]); /* CHECK_ALIGN(pixels[0]); */
pitches[0] = width; pitches[0] = width;
yuv_pixmap->componentInfoY.offset = offset; yuv_pixmap->componentInfoY.offset = offset;
...@@ -1587,5 +1626,4 @@ static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height, ...@@ -1587,5 +1626,4 @@ static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
yuv_height = overlay->h; yuv_height = overlay->h;
return overlay; return overlay;
} }
\ No newline at end of file
...@@ -87,13 +87,13 @@ static int QZ_ShowWMCursor (_THIS, WMcursor *cursor) { ...@@ -87,13 +87,13 @@ static int QZ_ShowWMCursor (_THIS, WMcursor *cursor) {
return 1; return 1;
} }
/** /*
* Coordinate conversion functions, for convenience Coordinate conversion functions, for convenience
* Cocoa sets the origin at the lower left corner of the window/screen Cocoa sets the origin at the lower left corner of the window/screen
* SDL, CoreGraphics/WindowServer, and QuickDraw use the origin at the upper left corner SDL, CoreGraphics/WindowServer, and QuickDraw use the origin at the upper left corner
* The routines were written so they could be called before SetVideoMode() has finished; The routines were written so they could be called before SetVideoMode() has finished;
* this might have limited usefulness at the moment, but the extra cost is trivial. this might have limited usefulness at the moment, but the extra cost is trivial.
**/ */
/* Convert Cocoa screen coordinate to Cocoa window coordinate */ /* Convert Cocoa screen coordinate to Cocoa window coordinate */
static void QZ_PrivateGlobalToLocal (_THIS, NSPoint *p) { static void QZ_PrivateGlobalToLocal (_THIS, NSPoint *p) {
...@@ -190,7 +190,7 @@ static void QZ_PrivateWarpCursor (_THIS, int x, int y) { ...@@ -190,7 +190,7 @@ static void QZ_PrivateWarpCursor (_THIS, int x, int y) {
static void QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y) { static void QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y) {
/* Only allow warping when in foreground */ /* Only allow warping when in foreground */
if ( ! inForeground ) if ( ! in_foreground )
return; return;
/* Do the actual warp */ /* Do the actual warp */
...@@ -219,59 +219,66 @@ static void QZ_SetCaption (_THIS, const char *title, const char *icon) { ...@@ -219,59 +219,66 @@ static void QZ_SetCaption (_THIS, const char *title, const char *icon) {
static void QZ_SetIcon (_THIS, SDL_Surface *icon, Uint8 *mask) static void QZ_SetIcon (_THIS, SDL_Surface *icon, Uint8 *mask)
{ {
NSBitmapImageRep *imgrep; NSBitmapImageRep *imgrep;
NSImage *img; NSImage *img;
SDL_Surface *mergedSurface; SDL_Surface *mergedSurface;
Uint8 *surfPtr; Uint8 *surfPtr;
int i,j,masksize; int i,j,masksize;
NSAutoreleasePool *pool; NSAutoreleasePool *pool;
SDL_Rect rrect; SDL_Rect rrect;
NSSize imgSize = {icon->w, icon->h}; NSSize imgSize = {icon->w, icon->h};
pool = [ [ NSAutoreleasePool alloc ] init ];
SDL_GetClipRect(icon, &rrect); pool = [ [ NSAutoreleasePool alloc ] init ];
/* create a big endian RGBA surface */ SDL_GetClipRect(icon, &rrect);
mergedSurface = SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA,
icon->w, icon->h, 32, 0xff<<24, 0xff<<16, 0xff<<8, 0xff<<0); /* create a big endian RGBA surface */
if (mergedSurface==NULL) { mergedSurface = SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA,
icon->w, icon->h, 32, 0xff<<24, 0xff<<16, 0xff<<8, 0xff<<0);
if (mergedSurface==NULL) {
NSLog(@"Error creating surface for merge"); NSLog(@"Error creating surface for merge");
goto freePool; goto freePool;
} }
if (SDL_BlitSurface(icon,&rrect,mergedSurface,&rrect)) {
NSLog(@"Error blitting to mergedSurface"); if (SDL_BlitSurface(icon,&rrect,mergedSurface,&rrect)) {
goto freePool; NSLog(@"Error blitting to mergedSurface");
} goto freePool;
if (mask) { }
masksize=icon->w*icon->h;
surfPtr = (Uint8 *)mergedSurface->pixels; if (mask) {
#define ALPHASHIFT 3 masksize=icon->w*icon->h;
for (i=0;i<masksize;i+=8) surfPtr = (Uint8 *)mergedSurface->pixels;
for (j=0;j<8;j++) #define ALPHASHIFT 3
surfPtr[ALPHASHIFT+((i+j)<<2)]=(mask[i>>3]&(1<<(7-j)))?0xFF:0x00; for (i=0;i<masksize;i+=8)
} for (j=0;j<8;j++)
imgrep = [ [ NSBitmapImageRep alloc] surfPtr[ALPHASHIFT+((i+j)<<2)]=(mask[i>>3]&(1<<(7-j)))?0xFF:0x00;
initWithBitmapDataPlanes:(unsigned char **)&mergedSurface->pixels }
pixelsWide:icon->w pixelsHigh:icon->h bitsPerSample:8 samplesPerPixel:4
hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace imgrep = [ [ NSBitmapImageRep alloc]
bytesPerRow:icon->w<<2 bitsPerPixel:32 ]; initWithBitmapDataPlanes:(unsigned char **)&mergedSurface->pixels
img = [ [ NSImage alloc ] initWithSize:imgSize ]; pixelsWide:icon->w pixelsHigh:icon->h bitsPerSample:8 samplesPerPixel:4
[ img addRepresentation: imgrep ]; hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace
[ NSApp setApplicationIconImage:img ]; bytesPerRow:icon->w<<2 bitsPerPixel:32 ];
[ img release ];
[ imgrep release ]; img = [ [ NSImage alloc ] initWithSize:imgSize ];
SDL_FreeSurface(mergedSurface);
[ img addRepresentation: imgrep ];
[ NSApp setApplicationIconImage:img ];
[ img release ];
[ imgrep release ];
SDL_FreeSurface(mergedSurface);
freePool: freePool:
[pool release]; [pool release];
} }
static int QZ_IconifyWindow (_THIS) { static int QZ_IconifyWindow (_THIS) {
/* Bug! minimize erases the framebuffer */
if ( ! [ qz_window isMiniaturized ] ) { if ( ! [ qz_window isMiniaturized ] ) {
[ qz_window miniaturize:nil ]; [ qz_window miniaturize:nil ];
return 1; return 1;
} }
else { else {
SDL_SetError ("qz_window already iconified"); SDL_SetError ("window already iconified");
return 0; return 0;
} }
} }
...@@ -289,16 +296,94 @@ static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode) { ...@@ -289,16 +296,94 @@ static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode) {
break; break;
case SDL_GRAB_OFF: case SDL_GRAB_OFF:
CGAssociateMouseAndMouseCursorPosition (1); CGAssociateMouseAndMouseCursorPosition (1);
currentGrabMode = SDL_GRAB_OFF; current_grab_mode = SDL_GRAB_OFF;
break; break;
case SDL_GRAB_ON: case SDL_GRAB_ON:
QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2); QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
CGAssociateMouseAndMouseCursorPosition (0); CGAssociateMouseAndMouseCursorPosition (0);
currentGrabMode = SDL_GRAB_ON; current_grab_mode = SDL_GRAB_ON;
break; break;
case SDL_GRAB_FULLSCREEN: case SDL_GRAB_FULLSCREEN:
break; break;
} }
return currentGrabMode; 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);
}
}
}
\ No newline at end of file
/* Subclass of NSWindow to allow customization if we need it */
@interface SDL_QuartzWindow : NSWindow /*
{} This function makes the *SDL region* of the window 100% opaque.
- (void)miniaturize:(id)sender; The genie effect uses the alpha component. Otherwise,
- (void)deminiaturize:(id)sender; it doesn't seem to matter what value it has.
- (void)display; */
@end static void QZ_SetPortAlphaOpaque () {
/**
* Function to set the opacity of window's pixels to 100%
* The opacity is only used by the window server code that does the minimize effect
**/
static void QZ_SetPortAlphaOpaque (CGrafPtr port, Uint32 noTitleBar) {
Uint32 *pixels; SDL_Surface *surface = current_video->screen;
Uint32 rowPixels; int bpp;
Uint32 width, height;
Uint32 bpp;
PixMapHandle pixMap;
Rect bounds;
int i, j;
pixMap = GetPortPixMap ( port ); bpp = surface->format->BitsPerPixel;
bpp = GetPixDepth ( pixMap );
if (bpp == 32) { if (bpp == 32) {
GetPortBounds ( port, &bounds ); Uint32 *pixels = (Uint32*) surface->pixels;
width = bounds.right - bounds.left; Uint32 rowPixels = surface->pitch / 4;
height = bounds.bottom - bounds.top; Uint32 i, j;
LockPortBits (port); for (i = 0; i < surface->h; i++)
for (j = 0; j < surface->w; j++) {
pixels = (Uint32*) GetPixBaseAddr ( pixMap );
rowPixels = GetPixRowBytes ( pixMap ) / 4;
if (! noTitleBar) {
/* offset for title bar */
pixels += rowPixels * 22;
}
for (i = 0; i < height; i++)
for (j = 0; j < width; j++) {
pixels[ (i * rowPixels) + j ] |= 0xFF000000; pixels[ (i * rowPixels) + j ] |= 0xFF000000;
} }
UnlockPortBits (port);
} }
} }
/* 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;
@end
@implementation SDL_QuartzWindow @implementation SDL_QuartzWindow
/* override these methods to fix the miniaturize animation/dock icon bug */ /* we override these methods to fix the miniaturize animation/dock icon bug */
- (void)miniaturize:(id)sender - (void)miniaturize:(id)sender
{ {
if (SDL_VideoSurface->flags & SDL_OPENGL) { if (SDL_VideoSurface->flags & SDL_OPENGL) {
/* Grab framebuffer and put into NSImage */ /*
/* [ qz_window setMiniwindowImage:image ]; */ Future: Grab framebuffer and put into NSImage
[ qz_window setMiniwindowImage:image ];
*/
} }
else { else {
QZ_SetPortAlphaOpaque ([ [ self contentView ] qdPort ], /* make the alpha channel opaque so anim won't have holes in it */
[ self styleMask ] & NSBorderlessWindowMask); QZ_SetPortAlphaOpaque ();
} }
[ super miniaturize:sender ]; [ super miniaturize:sender ];
} }
/* this routine fires *after* deminiaturizing, so it might be useless to us */ - (void)display
- (void)deminiaturize:(id)sender {
{ /*
[ super deminiaturize:sender ]; This method fires just before the window deminaturizes.
So, it's just the right place to fixup the alpha channel - which
makes the deminiaturize animation look right.
*/
if ( (SDL_VideoSurface->flags & SDL_OPENGL) == 0)
QZ_SetPortAlphaOpaque ();
} }
- (void)display - (void)setFrame:(NSRect)frameRect display:(BOOL)flag
{ {
/* Do nothing to keep pinstripe pattern from drawing */
/*
If the video surface is NULL, this originated from QZ_SetVideoMode,
so don't send the resize event.
*/
if (SDL_VideoSurface == NULL) {
[ super setFrame:frameRect display:flag ];
}
else {
SDL_VideoDevice *this = (SDL_VideoDevice*)current_video;
NSRect sdlRect = [ NSWindow contentRectForFrameRect:frameRect styleMask:[self styleMask] ];
[ super setFrame:frameRect display:flag ];
SDL_PrivateResize (sdlRect.size.width, sdlRect.size.height);
/* If not OpenGL, we have to update the pixels and pitch */
if ( ! this->screen->flags & SDL_OPENGL ) {
LockPortBits ( [ window_view qdPort ] );
SDL_VideoSurface->pixels = GetPixBaseAddr ( GetPortPixMap ( [ window_view qdPort ] ) );
SDL_VideoSurface->pitch = GetPixRowBytes ( GetPortPixMap ( [ window_view qdPort ] ) );
SDL_VideoSurface->pixels += ((int)[ self frame ].size.height - (int)sdlRect.size.height) * SDL_VideoSurface->pitch;
UnlockPortBits ( [ window_view qdPort ] );
}
}
} }
@end @end
/* Delegate for our NSWindow to send SDLQuit() on close */ /* Delegate for our NSWindow to send SDLQuit() on close */
...@@ -90,19 +109,17 @@ static void QZ_SetPortAlphaOpaque (CGrafPtr port, Uint32 noTitleBar) { ...@@ -90,19 +109,17 @@ static void QZ_SetPortAlphaOpaque (CGrafPtr port, Uint32 noTitleBar) {
@end @end
@implementation SDL_QuartzWindowDelegate @implementation SDL_QuartzWindowDelegate
- (BOOL)windowShouldClose:(id)sender { - (BOOL)windowShouldClose:(id)sender
{
SDL_PrivateQuit(); SDL_PrivateQuit();
return NO; return NO;
} }
@end @end
/* empty class; probably could be used to fix bugs in the future */ /* Subclass of NSQuickDrawView for the window's subview */
@interface SDL_QuartzWindowView : NSQuickDrawView @interface SDL_QuartzWindowView : NSQuickDrawView
{} {}
@end @end
@implementation SDL_QuartzWindowView @implementation SDL_QuartzWindowView
@end
@end
\ No newline at end of file
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