Lots of cleanups by Darrell, added the ability to resize Cocoa windows.
--HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40502
This commit is contained in:
parent
2ac6973950
commit
7b88c89815
5 changed files with 548 additions and 381 deletions
|
@ -19,16 +19,8 @@
|
|||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
*/
|
||||
#include <sys/time.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) {
|
||||
const void *KCHRPtr;
|
||||
UInt32 state;
|
||||
|
@ -147,11 +139,12 @@ static void QZ_InitOSKeymap (_THIS) {
|
|||
keymap[QZ_IBOOK_UP] = SDLK_UP;
|
||||
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
|
||||
* for its own keymap to adjust our own mapping table. However, this is
|
||||
* bascially only useful for ascii char keys. This is also the reason
|
||||
* why we keep the static table, too.
|
||||
/*
|
||||
Up there we setup a static scancode->keysym map. However, it will not
|
||||
work very well on international keyboard. Hence we now query MacOS
|
||||
for its own keymap to adjust our own mapping table. However, this is
|
||||
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 */
|
||||
|
@ -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
|
||||
* could get around this problem in another fashion: NSEvent's flags
|
||||
* include a "NSNumericPadKeyMask" bit; we could check that and modify
|
||||
* the symbol we return on the fly. However, this flag seems to exhibit
|
||||
* some weird behaviour related to the num lock key
|
||||
*/
|
||||
/*
|
||||
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
|
||||
could get around this problem in another fashion: NSEvent's flags
|
||||
include a "NSNumericPadKeyMask" bit; we could check that and modify
|
||||
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_KP1] = SDLK_KP1;
|
||||
keymap[QZ_KP2] = SDLK_KP2;
|
||||
|
@ -206,14 +200,18 @@ static void QZ_InitOSKeymap (_THIS) {
|
|||
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;
|
||||
int i;
|
||||
SDL_keysym key;
|
||||
|
||||
/* An event can contain multiple characters */
|
||||
/* I'll ignore this fact for now, since there is only one virtual key code per event */
|
||||
/*
|
||||
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 ];
|
||||
for (i =0; i < 1 /*[ chars length ] */; i++) {
|
||||
|
||||
|
@ -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 } ;
|
||||
|
||||
|
@ -244,8 +242,8 @@ static void QZ_DoModifiers (unsigned int newMods) {
|
|||
|
||||
unsigned int currentMask, newMask;
|
||||
|
||||
currentMask = currentMods & bit;
|
||||
newMask = newMods & bit;
|
||||
currentMask = current_mods & bit;
|
||||
newMask = newMods & bit;
|
||||
|
||||
if ( currentMask &&
|
||||
currentMask != newMask ) { /* modifier up event */
|
||||
|
@ -267,15 +265,15 @@ static void QZ_DoModifiers (unsigned int newMods) {
|
|||
}
|
||||
}
|
||||
|
||||
currentMods = newMods;
|
||||
current_mods = newMods;
|
||||
}
|
||||
|
||||
static void QZ_DoActivate (_THIS)
|
||||
{
|
||||
inForeground = YES;
|
||||
in_foreground = YES;
|
||||
|
||||
/* Regrab the mouse */
|
||||
if (currentGrabMode == SDL_GRAB_ON) {
|
||||
/* Regrab the mouse, only if it was previously grabbed */
|
||||
if ( current_grab_mode == SDL_GRAB_ON ) {
|
||||
QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
|
||||
CGAssociateMouseAndMouseCursorPosition (0);
|
||||
}
|
||||
|
@ -290,10 +288,10 @@ static void QZ_DoActivate (_THIS)
|
|||
|
||||
static void QZ_DoDeactivate (_THIS) {
|
||||
|
||||
inForeground = NO;
|
||||
in_foreground = NO;
|
||||
|
||||
/* Ungrab mouse if it is grabbed */
|
||||
if (currentGrabMode == SDL_GRAB_ON) {
|
||||
if ( current_grab_mode == SDL_GRAB_ON ) {
|
||||
CGAssociateMouseAndMouseCursorPosition (1);
|
||||
}
|
||||
|
||||
|
@ -343,7 +341,7 @@ static void QZ_PumpEvents (_THIS)
|
|||
BOOL isForGameWin;
|
||||
|
||||
#define DO_MOUSE_DOWN(button, sendToWindow) do { \
|
||||
if ( inForeground ) { \
|
||||
if ( in_foreground ) { \
|
||||
if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \
|
||||
NSPointInRect([event locationInWindow], winRect) ) \
|
||||
SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0); \
|
||||
|
@ -366,11 +364,11 @@ static void QZ_PumpEvents (_THIS)
|
|||
switch (type) {
|
||||
|
||||
case NSLeftMouseDown:
|
||||
if ( NSCommandKeyMask & currentMods ) {
|
||||
if ( NSCommandKeyMask & current_mods ) {
|
||||
last_virtual_button = 3;
|
||||
DO_MOUSE_DOWN (3, 0);
|
||||
}
|
||||
else if ( NSAlternateKeyMask & currentMods ) {
|
||||
else if ( NSAlternateKeyMask & current_mods ) {
|
||||
last_virtual_button = 2;
|
||||
DO_MOUSE_DOWN (2, 0);
|
||||
}
|
||||
|
@ -392,22 +390,24 @@ static void QZ_PumpEvents (_THIS)
|
|||
case NSOtherMouseUp: DO_MOUSE_UP (2, 0); break;
|
||||
case NSRightMouseUp: DO_MOUSE_UP (3, 0); break;
|
||||
case NSSystemDefined:
|
||||
//if ([event subtype] == 7) {
|
||||
// unsigned int buttons; // up to 32 mouse button states!
|
||||
// buttons = [ event data2 ];
|
||||
//}
|
||||
/*
|
||||
Future: up to 32 "mouse" buttons can be handled.
|
||||
if ([event subtype] == 7) {
|
||||
unsigned int buttons;
|
||||
buttons = [ event data2 ];
|
||||
*/
|
||||
break;
|
||||
case NSLeftMouseDragged:
|
||||
case NSRightMouseDragged:
|
||||
case NSOtherMouseDragged: /* usually middle mouse dragged */
|
||||
case NSMouseMoved:
|
||||
if (currentGrabMode == SDL_GRAB_ON) {
|
||||
if (current_grab_mode == SDL_GRAB_ON) {
|
||||
|
||||
/**
|
||||
* If input is grabbed, the cursor doesn't move,
|
||||
* so we have to call the lowlevel window server
|
||||
* function. This is less accurate but works OK.
|
||||
**/
|
||||
/*
|
||||
If input is grabbed, the cursor doesn't move,
|
||||
so we have to call the lowlevel window server
|
||||
function. This is less accurate but works OK.
|
||||
*/
|
||||
CGMouseDelta dx1, dy1;
|
||||
CGGetLastMouseDelta (&dx1, &dy1);
|
||||
dx += dx1;
|
||||
|
@ -415,12 +415,14 @@ static void QZ_PumpEvents (_THIS)
|
|||
}
|
||||
else if (warp_flag) {
|
||||
|
||||
/**
|
||||
* If we just warped the mouse, the cursor is frozen for a while.
|
||||
* So we have to use the lowlevel function until it
|
||||
* unfreezes. This really helps apps that continuously
|
||||
* warp the mouse to keep it in the game window.
|
||||
**/
|
||||
/*
|
||||
If we just warped the mouse, the cursor is frozen for a while.
|
||||
So we have to use the lowlevel function until it
|
||||
unfreezes. This really helps apps that continuously
|
||||
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;
|
||||
|
||||
ticks = SDL_GetTicks();
|
||||
|
@ -438,14 +440,14 @@ static void QZ_PumpEvents (_THIS)
|
|||
}
|
||||
else if (firstMouseEvent) {
|
||||
|
||||
/**
|
||||
* Get the first mouse event in a possible
|
||||
* sequence of mouse moved events. Since we
|
||||
* use absolute coordinates, this serves to
|
||||
* compensate any inaccuracy in deltas, and
|
||||
* provides the first known mouse position,
|
||||
* since everything after this uses deltas
|
||||
**/
|
||||
/*
|
||||
Get the first mouse event in a possible
|
||||
sequence of mouse moved events. Since we
|
||||
use absolute coordinates, this serves to
|
||||
compensate any inaccuracy in deltas, and
|
||||
provides the first known mouse position,
|
||||
since everything after this uses deltas
|
||||
*/
|
||||
NSPoint p = [ event locationInWindow ];
|
||||
QZ_PrivateCocoaToSDL(this, &p);
|
||||
|
||||
|
@ -455,12 +457,12 @@ static void QZ_PumpEvents (_THIS)
|
|||
}
|
||||
else {
|
||||
|
||||
/**
|
||||
* Get the amount moved since the last drag or move event,
|
||||
* add it on for one big move event at the end.
|
||||
**/
|
||||
dx += [ event deltaX ];
|
||||
dy += [ event deltaY ];
|
||||
/*
|
||||
Get the amount moved since the last drag or move event,
|
||||
add it on for one big move event at the end.
|
||||
*/
|
||||
dx += [ event deltaX ];
|
||||
dy += [ event deltaY ];
|
||||
}
|
||||
break;
|
||||
case NSScrollWheel:
|
||||
|
@ -474,13 +476,13 @@ static void QZ_PumpEvents (_THIS)
|
|||
}
|
||||
break;
|
||||
case NSKeyUp:
|
||||
QZ_DoKey (SDL_RELEASED, event);
|
||||
QZ_DoKey (this, SDL_RELEASED, event);
|
||||
break;
|
||||
case NSKeyDown:
|
||||
QZ_DoKey (SDL_PRESSED, event);
|
||||
QZ_DoKey (this, SDL_PRESSED, event);
|
||||
break;
|
||||
case NSFlagsChanged:
|
||||
QZ_DoModifiers( [ event modifierFlags ] );
|
||||
QZ_DoModifiers(this, [ event modifierFlags ] );
|
||||
break;
|
||||
case NSAppKitDefined:
|
||||
switch ( [ event subtype ] ) {
|
||||
|
@ -508,4 +510,3 @@ static void QZ_PumpEvents (_THIS)
|
|||
|
||||
[ pool release ];
|
||||
}
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
|
||||
/*
|
||||
@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
|
||||
|
||||
|
@ -33,17 +33,17 @@
|
|||
- Keyboard repeat/mouse speed adjust (if needed)
|
||||
- Multiple monitor support (currently only main display)
|
||||
- Accelerated blitting support
|
||||
- Fix white OpenGL window on minimize (fixed)
|
||||
- Find out what events should be sent/ignored if window is mimimized
|
||||
- Fix white OpenGL window on minimize (fixed) (update: broken again on 10.2)
|
||||
- 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
|
||||
- Resizeable windows
|
||||
- Resizeable windows (done)
|
||||
- Check accuracy of QZ_SetGamma()
|
||||
Problems:
|
||||
- OGL not working in full screen with software renderer
|
||||
- SetColors sets palette correctly but clears framebuffer
|
||||
- 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)
|
||||
- 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,
|
||||
there is a hack around this that helps a bit
|
||||
*/
|
||||
|
@ -62,11 +62,11 @@
|
|||
#include "SDL_events_c.h"
|
||||
|
||||
/*
|
||||
Add methods to get at private members of NSScreen.
|
||||
Since there is a bug in Apple's screen switching code
|
||||
that does not update this variable when switching
|
||||
to fullscreen, we'll set it manually (but only for the
|
||||
main screen).
|
||||
Add methods to get at private members of NSScreen.
|
||||
Since there is a bug in Apple's screen switching code
|
||||
that does not update this variable when switching
|
||||
to fullscreen, we'll set it manually (but only for the
|
||||
main screen).
|
||||
*/
|
||||
@interface NSScreen (NSScreenAccess)
|
||||
- (void) setFrame:(NSRect)frame;
|
||||
|
@ -79,8 +79,10 @@
|
|||
}
|
||||
@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)
|
||||
- (CGLContextObj) cglContext;
|
||||
@end
|
||||
|
@ -92,8 +94,10 @@
|
|||
}
|
||||
@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
|
||||
|
||||
typedef struct {
|
||||
|
@ -112,14 +116,22 @@ typedef struct SDL_PrivateVideoData {
|
|||
CFDictionaryRef save_mode; /* original mode of the display */
|
||||
CFArrayRef mode_list; /* list of available fullscreen modes */
|
||||
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 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 warp_flag; /* boolean; notify to event loop that a warp just occured */
|
||||
Uint32 warp_ticks; /* timestamp when the warp occured */
|
||||
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;
|
||||
MatrixRecordPtr yuv_matrix;
|
||||
DecompressorComponent yuv_codec;
|
||||
|
@ -146,6 +158,14 @@ typedef struct SDL_PrivateVideoData {
|
|||
#define video_set (this->hidden->video_set)
|
||||
#define warp_ticks (this->hidden->warp_ticks)
|
||||
#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_matrix (this->hidden->yuv_matrix)
|
||||
#define yuv_codec (this->hidden->yuv_codec)
|
||||
|
@ -156,7 +176,13 @@ typedef struct SDL_PrivateVideoData {
|
|||
#define yuv_height (this->hidden->yuv_height)
|
||||
#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
|
||||
|
||||
/* Some of the Core Graphics Server API for obscuring code */
|
||||
|
@ -171,10 +197,11 @@ typedef struct SDL_PrivateVideoData {
|
|||
#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
|
||||
/*
|
||||
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;
|
||||
|
@ -227,7 +254,7 @@ static int QZ_ToggleFullScreen (_THIS, int on);
|
|||
static int QZ_SetColors (_THIS, int first_color,
|
||||
int num_colors, SDL_Color *colors);
|
||||
static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects);
|
||||
static 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_UpdateRects (_THIS, int num_rects, SDL_Rect *rects);
|
||||
static void QZ_VideoQuit (_THIS);
|
||||
|
@ -246,8 +273,8 @@ static int QZ_SetGammaRamp (_THIS, Uint16 *ramp);
|
|||
static int QZ_GetGammaRamp (_THIS, Uint16 *ramp);
|
||||
|
||||
/* OpenGL functions */
|
||||
static int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags);
|
||||
static void QZ_TearDownOpenGL (_THIS);
|
||||
static int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags);
|
||||
static void QZ_TearDownOpenGL (_THIS);
|
||||
static void* QZ_GL_GetProcAddress (_THIS, const char *proc);
|
||||
static int QZ_GL_GetAttribute (_THIS, SDL_GLattr attrib, int* value);
|
||||
static int QZ_GL_MakeCurrent (_THIS);
|
||||
|
@ -271,13 +298,12 @@ static void QZ_InitOSKeymap (_THIS);
|
|||
static void QZ_PumpEvents (_THIS);
|
||||
|
||||
/* Window Manager functions */
|
||||
static void QZ_SetCaption (_THIS, const char *title, const char *icon);
|
||||
static void QZ_SetIcon (_THIS, SDL_Surface *icon, Uint8 *mask);
|
||||
static int QZ_IconifyWindow (_THIS);
|
||||
static void QZ_SetCaption (_THIS, const char *title, const char *icon);
|
||||
static void QZ_SetIcon (_THIS, SDL_Surface *icon, Uint8 *mask);
|
||||
static int QZ_IconifyWindow (_THIS);
|
||||
static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode);
|
||||
/*static int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info);*/
|
||||
|
||||
/* YUV functions */
|
||||
static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
|
||||
Uint32 format, SDL_Surface *display);
|
||||
|
||||
|
|
|
@ -22,11 +22,6 @@
|
|||
|
||||
#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 "SDL_QuartzWM.m"
|
||||
#include "SDL_QuartzEvents.m"
|
||||
|
@ -132,6 +127,10 @@ static int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format) {
|
|||
|
||||
video_format->BitsPerPixel = device_bpp;
|
||||
|
||||
/* Set misc globals */
|
||||
current_grab_mode = SDL_GRAB_OFF;
|
||||
in_foreground = YES;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -140,7 +139,6 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
|
|||
CFIndex num_modes;
|
||||
CFIndex i;
|
||||
|
||||
static SDL_Rect **list = NULL;
|
||||
int list_size = 0;
|
||||
|
||||
/* Any windowed mode is acceptable */
|
||||
|
@ -148,15 +146,15 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
|
|||
return (SDL_Rect**)-1;
|
||||
|
||||
/* Free memory from previous call, if any */
|
||||
if ( list != NULL ) {
|
||||
if ( client_mode_list != NULL ) {
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; list[i] != NULL; i++)
|
||||
free (list[i]);
|
||||
for (i = 0; client_mode_list[i] != NULL; i++)
|
||||
free (client_mode_list[i]);
|
||||
|
||||
free (list);
|
||||
list = NULL;
|
||||
free (client_mode_list);
|
||||
client_mode_list = NULL;
|
||||
}
|
||||
|
||||
num_modes = CFArrayGetCount (mode_list);
|
||||
|
@ -191,7 +189,8 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
|
|||
int i;
|
||||
hasMode = SDL_FALSE;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
@ -205,14 +204,16 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
|
|||
|
||||
list_size++;
|
||||
|
||||
if (list == NULL)
|
||||
list = (SDL_Rect**) malloc (sizeof(*list) * (list_size+1) );
|
||||
if (client_mode_list == NULL)
|
||||
client_mode_list = (SDL_Rect**)
|
||||
malloc (sizeof(*client_mode_list) * (list_size+1) );
|
||||
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 ();
|
||||
return NULL;
|
||||
}
|
||||
|
@ -220,8 +221,8 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
|
|||
rect->w = width;
|
||||
rect->h = height;
|
||||
|
||||
list[list_size-1] = rect;
|
||||
list[list_size] = NULL;
|
||||
client_mode_list[list_size-1] = rect;
|
||||
client_mode_list[list_size] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -233,23 +234,25 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
|
|||
for (j = 0; j < list_size-1; j++) {
|
||||
|
||||
int area1, area2;
|
||||
area1 = list[j]->w * list[j]->h;
|
||||
area2 = list[j+1]->w * list[j+1]->h;
|
||||
area1 = client_mode_list[j]->w * client_mode_list[j]->h;
|
||||
area2 = client_mode_list[j+1]->w * client_mode_list[j+1]->h;
|
||||
|
||||
if (area1 < area2) {
|
||||
SDL_Rect *tmp = list[j];
|
||||
list[j] = list[j+1];
|
||||
list[j+1] = tmp;
|
||||
SDL_Rect *tmp = client_mode_list[j];
|
||||
client_mode_list[j] = client_mode_list[j+1];
|
||||
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 */
|
||||
/* Save gamma tables for fade back to normal */
|
||||
/*
|
||||
Gamma functions to try to hide the flash from a rez switch
|
||||
Fade the display from normal to black
|
||||
Save gamma tables for fade back to normal
|
||||
*/
|
||||
static UInt32 QZ_FadeGammaOut (_THIS, SDL_QuartzGammaTable *table) {
|
||||
|
||||
CGGammaValue redTable[QZ_GAMMA_TABLE_SIZE],
|
||||
|
@ -295,8 +298,10 @@ static UInt32 QZ_FadeGammaOut (_THIS, SDL_QuartzGammaTable *table) {
|
|||
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) {
|
||||
|
||||
CGGammaValue redTable[QZ_GAMMA_TABLE_SIZE],
|
||||
|
@ -336,9 +341,11 @@ static UInt32 QZ_FadeGammaIn (_THIS, SDL_QuartzGammaTable *table) {
|
|||
static void QZ_UnsetVideoMode (_THIS) {
|
||||
|
||||
/* Reset values that may change between switches */
|
||||
this->info.blit_fill = 0;
|
||||
this->FillHWRect = NULL;
|
||||
this->UpdateRects = NULL;
|
||||
this->info.blit_fill = 0;
|
||||
this->FillHWRect = NULL;
|
||||
this->UpdateRects = NULL;
|
||||
this->LockHWSurface = NULL;
|
||||
this->UnlockHWSurface = NULL;
|
||||
|
||||
/* Release fullscreen resources */
|
||||
if ( mode_flags & SDL_FULLSCREEN ) {
|
||||
|
@ -349,13 +356,15 @@ static void QZ_UnsetVideoMode (_THIS) {
|
|||
|
||||
gamma_error = QZ_FadeGammaOut (this, &gamma_table);
|
||||
|
||||
/* Release the OpenGL context */
|
||||
/* Do this first to avoid trash on the display before fade */
|
||||
if ( mode_flags & SDL_OPENGL )
|
||||
QZ_TearDownOpenGL (this);
|
||||
/*
|
||||
Release the OpenGL context
|
||||
Do this first to avoid trash on the display before fade
|
||||
*/
|
||||
if ( mode_flags & SDL_OPENGL ) {
|
||||
|
||||
if (mode_flags & SDL_OPENGL)
|
||||
CGLSetFullScreen(NULL);
|
||||
QZ_TearDownOpenGL (this);
|
||||
CGLSetFullScreen (NULL);
|
||||
}
|
||||
|
||||
/* Restore original screen resolution/bpp */
|
||||
CGDisplaySwitchToMode (display_id, save_mode);
|
||||
|
@ -363,8 +372,8 @@ static void QZ_UnsetVideoMode (_THIS) {
|
|||
ShowMenuBar ();
|
||||
|
||||
/*
|
||||
reset the main screen's rectangle, see comment
|
||||
in QZ_SetVideoFullscreen
|
||||
Reset the main screen's rectangle
|
||||
See comment in QZ_SetVideoFullscreen for why we do this
|
||||
*/
|
||||
screen_rect = NSMakeRect(0,0,device_width,device_height);
|
||||
[ [ NSScreen mainScreen ] setFrame:screen_rect ];
|
||||
|
@ -374,15 +383,11 @@ static void QZ_UnsetVideoMode (_THIS) {
|
|||
}
|
||||
/* Release window mode resources */
|
||||
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 release ];
|
||||
qz_window = nil;
|
||||
window_view = nil;
|
||||
|
||||
/* Release the OpenGL context */
|
||||
if ( mode_flags & SDL_OPENGL )
|
||||
|
@ -392,10 +397,6 @@ static void QZ_UnsetVideoMode (_THIS) {
|
|||
/* Restore gamma settings */
|
||||
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 */
|
||||
CGDisplayShowCursor (display_id);
|
||||
CGAssociateMouseAndMouseCursorPosition (1);
|
||||
|
@ -411,14 +412,17 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
|
|||
SDL_QuartzGammaTable gamma_table;
|
||||
NSRect screen_rect;
|
||||
|
||||
/* Destroy any previous mode */
|
||||
if (video_set == SDL_TRUE)
|
||||
QZ_UnsetVideoMode (this);
|
||||
|
||||
/* See if requested mode exists */
|
||||
mode = CGDisplayBestModeForParameters (display_id, bpp, width,
|
||||
height, &exact_match);
|
||||
|
||||
/* Require an exact match to the requested mode */
|
||||
if ( ! exact_match ) {
|
||||
sprintf (QZ_Error, "Failed to find display resolution: %dx%dx%d", width, height, bpp);
|
||||
SDL_SetError (QZ_Error);
|
||||
SDL_SetError ("Failed to find display resolution: %dx%dx%d", width, height, bpp);
|
||||
goto ERR_NO_MATCH;
|
||||
}
|
||||
|
||||
|
@ -431,7 +435,6 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
|
|||
goto ERR_NO_CAPTURE;
|
||||
}
|
||||
|
||||
|
||||
/* Do the physical switch */
|
||||
if ( CGDisplayNoErr != CGDisplaySwitchToMode (display_id, mode) ) {
|
||||
SDL_SetError ("Failed switching display resolution");
|
||||
|
@ -446,8 +449,11 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
|
|||
current->h = height;
|
||||
current->flags |= SDL_FULLSCREEN;
|
||||
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 */
|
||||
if ( CGSDisplayCanHWFill (display_id) ) {
|
||||
|
@ -472,8 +478,7 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
|
|||
err = CGLSetFullScreen (ctx);
|
||||
|
||||
if (err) {
|
||||
sprintf (QZ_Error, "Error setting OpenGL fullscreen: %s", CGLErrorString(err));
|
||||
SDL_SetError (QZ_Error);
|
||||
SDL_SetError ("Error setting OpenGL fullscreen: %s", CGLErrorString(err));
|
||||
goto ERR_NO_GL;
|
||||
}
|
||||
|
||||
|
@ -494,11 +499,11 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
|
|||
QZ_FadeGammaIn (this, &gamma_table);
|
||||
|
||||
/*
|
||||
There is a bug in Cocoa where NSScreen doesn't synchronize
|
||||
with CGDirectDisplay, so the main screen's frame is wrong.
|
||||
As a result, coordinate translation produces wrong results.
|
||||
We can hack around this bug by setting the screen rect
|
||||
ourselves. This hack should be removed if/when the bug is fixed.
|
||||
There is a bug in Cocoa where NSScreen doesn't synchronize
|
||||
with CGDirectDisplay, so the main screen's frame is wrong.
|
||||
As a result, coordinate translation produces incorrect results.
|
||||
We can hack around this bug by setting the screen rect
|
||||
ourselves. This hack should be removed if/when the bug is fixed.
|
||||
*/
|
||||
screen_rect = NSMakeRect(0,0,width,height);
|
||||
[ [ NSScreen mainScreen ] setFrame:screen_rect ];
|
||||
|
@ -518,60 +523,99 @@ ERR_NO_MATCH: return NULL;
|
|||
static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
|
||||
int height, int bpp, Uint32 flags) {
|
||||
unsigned int style;
|
||||
NSRect rect;
|
||||
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;
|
||||
}
|
||||
NSRect contentRect;
|
||||
|
||||
current->flags = 0;
|
||||
current->w = width;
|
||||
current->h = height;
|
||||
|
||||
[ 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 ] ];
|
||||
contentRect = NSMakeRect (0, 0, width, height);
|
||||
|
||||
/* For OpenGL, we set the content view to a NSOpenGLView */
|
||||
/*
|
||||
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;
|
||||
}
|
||||
|
||||
/* For OpenGL, we bind the context to a subview */
|
||||
if ( flags & SDL_OPENGL ) {
|
||||
|
||||
if ( ! QZ_SetupOpenGL (this, bpp, flags) ) {
|
||||
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];
|
||||
[ qz_window makeKeyAndOrderFront:nil ];
|
||||
current->flags |= SDL_OPENGL;
|
||||
}
|
||||
/* For 2D, we set the content view to a NSQuickDrawView */
|
||||
/* For 2D, we set the subview to an NSQuickDrawView */
|
||||
else {
|
||||
|
||||
window_view = [ [ SDL_QuartzWindowView alloc ] init ];
|
||||
[ qz_window setContentView:window_view ];
|
||||
[ qz_window makeKeyAndOrderFront:nil ];
|
||||
/* Only recreate the view if it doesn't already exist */
|
||||
if (window_view == 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 ] );
|
||||
current->pixels = GetPixBaseAddr ( GetPortPixMap ( [ window_view qdPort ] ) );
|
||||
|
@ -582,15 +626,8 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
|
|||
current->flags |= SDL_PREALLOC;
|
||||
current->flags |= SDL_ASYNCBLIT;
|
||||
|
||||
if ( flags & SDL_NOFRAME )
|
||||
current->flags |= SDL_NOFRAME;
|
||||
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;
|
||||
}
|
||||
/* Offset below the title bar to fill the full content region */
|
||||
current->pixels += ((int)([ qz_window frame ].size.height) - height) * current->pitch;
|
||||
|
||||
this->UpdateRects = QZ_UpdateRects;
|
||||
this->LockHWSurface = QZ_LockWindow;
|
||||
|
@ -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,
|
||||
int height, int bpp, Uint32 flags) {
|
||||
|
||||
if (video_set == SDL_TRUE)
|
||||
QZ_UnsetVideoMode (this);
|
||||
|
||||
current->flags = 0;
|
||||
|
||||
/* Setup full screen video */
|
||||
|
@ -696,17 +730,18 @@ static void QZ_DirectUpdate (_THIS, int num_rects, SDL_Rect *rects) {
|
|||
#pragma unused(this,num_rects,rects)
|
||||
}
|
||||
|
||||
/**
|
||||
* The obscured code is based on work by Matt Slot fprefect@ambrosiasw.com,
|
||||
* who supplied sample code for Carbon.
|
||||
**/
|
||||
/*
|
||||
The obscured code is based on work by Matt Slot fprefect@ambrosiasw.com,
|
||||
who supplied sample code for Carbon.
|
||||
*/
|
||||
static int QZ_IsWindowObscured (NSWindow *window) {
|
||||
|
||||
//#define TEST_OBSCURED 1
|
||||
|
||||
#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).
|
||||
This can be done by querying the window server about the on screen
|
||||
windows for their screen rectangle and window level.
|
||||
|
@ -753,11 +788,15 @@ static int QZ_IsWindowObscured (NSWindow *window) {
|
|||
|
||||
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) {
|
||||
cgsConnection = (CGSConnectionID) 0;
|
||||
cgsConnection = _CGSDefaultConnection ();
|
||||
|
@ -785,8 +824,10 @@ static int QZ_IsWindowObscured (NSWindow *window) {
|
|||
firstDockIcon = -1;
|
||||
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++) {
|
||||
|
||||
/* If we reach our window in the list, it cannot be obscured */
|
||||
|
@ -856,8 +897,10 @@ static int QZ_IsWindowObscured (NSWindow *window) {
|
|||
}
|
||||
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;
|
||||
shadowTop = 10;
|
||||
shadowBottom = 24;
|
||||
|
@ -880,9 +923,11 @@ static int QZ_IsWindowObscured (NSWindow *window) {
|
|||
}
|
||||
else {
|
||||
|
||||
/* kCGSWindowLevelDockLabel,
|
||||
kCGSWindowLevelDock,
|
||||
kOther??? */
|
||||
/*
|
||||
kCGSWindowLevelDockLabel,
|
||||
kCGSWindowLevelDock,
|
||||
kOther???
|
||||
*/
|
||||
|
||||
/* no shadow */
|
||||
shadowSide = 0;
|
||||
|
@ -917,6 +962,7 @@ static int QZ_IsWindowObscured (NSWindow *window) {
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Locking functions for the software window buffer */
|
||||
static int QZ_LockWindow (_THIS, SDL_Surface *surface) {
|
||||
|
||||
|
@ -933,17 +979,11 @@ static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) {
|
|||
if (SDL_VideoSurface->flags & SDL_OPENGLBLIT) {
|
||||
QZ_GL_SwapBuffers (this);
|
||||
}
|
||||
else if ( [ qz_window isMiniaturized ] &&
|
||||
! (SDL_VideoSurface->flags & SDL_OPENGL)) {
|
||||
else if ( [ qz_window isMiniaturized ] ) {
|
||||
|
||||
/**
|
||||
* 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);
|
||||
/* Do nothing if miniaturized */
|
||||
}
|
||||
|
||||
else if ( ! QZ_IsWindowObscured (qz_window) ) {
|
||||
|
||||
/* Use direct copy to flush contents to the display */
|
||||
|
@ -992,7 +1032,6 @@ static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) {
|
|||
SetPort (savePort);
|
||||
}
|
||||
else {
|
||||
|
||||
/* Use QDFlushPortBuffer() to flush content to display */
|
||||
int i;
|
||||
RgnHandle dirty = NewRgn ();
|
||||
|
@ -1004,10 +1043,12 @@ static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) {
|
|||
for (i = 0; i < numRects; i++) {
|
||||
|
||||
MacSetRectRgn (temp, rects[i].x, rects[i].y,
|
||||
rects[i].x + rects[i].w, rects[i].y + rects[i].h);
|
||||
rects[i].x + rects[i].w, rects[i].y + rects[i].h);
|
||||
MacUnionRgn (dirty, temp, dirty);
|
||||
}
|
||||
|
||||
QZ_DrawResizeIcon (this, dirty);
|
||||
|
||||
/* Flush the dirty region */
|
||||
QDFlushPortBuffer ( [ window_view qdPort ], dirty );
|
||||
DisposeRgn (dirty);
|
||||
|
@ -1363,15 +1404,10 @@ static void QZ_FreeHWYUV (_THIS, SDL_Overlay *overlay) {
|
|||
|
||||
#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)
|
||||
|
||||
/**
|
||||
* 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)
|
||||
|
||||
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) {
|
||||
|
||||
/**
|
||||
* Good acceleration requires a window to be present.
|
||||
* A CGrafPtr that points to the screen isn't good enough
|
||||
**/
|
||||
/*
|
||||
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 ]
|
||||
|
@ -1442,17 +1478,20 @@ static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
|
|||
|
||||
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);
|
||||
//}
|
||||
|
||||
/*
|
||||
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 = [ [ qz_window contentView ] qdPort ];
|
||||
port = [ window_view qdPort ];
|
||||
SetPort (port);
|
||||
}
|
||||
|
||||
|
@ -1544,13 +1583,13 @@ static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
//CHECK_ALIGN(yuv_pixmap);
|
||||
/* CHECK_ALIGN(yuv_pixmap); */
|
||||
offset = sizeof(PlanarPixmapInfoYUV420);
|
||||
//offset += ALIGN(offset);
|
||||
//CHECK_ALIGN(offset);
|
||||
/* offset += ALIGN(offset); */
|
||||
/* CHECK_ALIGN(offset); */
|
||||
|
||||
pixels[0] = (Uint8*)yuv_pixmap + offset;
|
||||
//CHECK_ALIGN(pixels[0]);
|
||||
/* CHECK_ALIGN(pixels[0]); */
|
||||
|
||||
pitches[0] = width;
|
||||
yuv_pixmap->componentInfoY.offset = offset;
|
||||
|
@ -1588,4 +1627,3 @@ static SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
|
|||
|
||||
return overlay;
|
||||
}
|
||||
|
||||
|
|
|
@ -87,13 +87,13 @@ static int QZ_ShowWMCursor (_THIS, WMcursor *cursor) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Coordinate conversion functions, for convenience
|
||||
* 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
|
||||
* 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.
|
||||
**/
|
||||
/*
|
||||
Coordinate conversion functions, for convenience
|
||||
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
|
||||
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.
|
||||
*/
|
||||
|
||||
/* Convert Cocoa screen coordinate to Cocoa window coordinate */
|
||||
static void QZ_PrivateGlobalToLocal (_THIS, NSPoint *p) {
|
||||
|
@ -190,7 +190,7 @@ static void QZ_PrivateWarpCursor (_THIS, int x, int y) {
|
|||
static void QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y) {
|
||||
|
||||
/* Only allow warping when in foreground */
|
||||
if ( ! inForeground )
|
||||
if ( ! in_foreground )
|
||||
return;
|
||||
|
||||
/* Do the actual warp */
|
||||
|
@ -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)
|
||||
{
|
||||
NSBitmapImageRep *imgrep;
|
||||
NSImage *img;
|
||||
SDL_Surface *mergedSurface;
|
||||
Uint8 *surfPtr;
|
||||
int i,j,masksize;
|
||||
NSAutoreleasePool *pool;
|
||||
SDL_Rect rrect;
|
||||
NSSize imgSize = {icon->w, icon->h};
|
||||
pool = [ [ NSAutoreleasePool alloc ] init ];
|
||||
SDL_GetClipRect(icon, &rrect);
|
||||
/* create a big endian RGBA surface */
|
||||
mergedSurface = SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA,
|
||||
icon->w, icon->h, 32, 0xff<<24, 0xff<<16, 0xff<<8, 0xff<<0);
|
||||
if (mergedSurface==NULL) {
|
||||
NSBitmapImageRep *imgrep;
|
||||
NSImage *img;
|
||||
SDL_Surface *mergedSurface;
|
||||
Uint8 *surfPtr;
|
||||
int i,j,masksize;
|
||||
NSAutoreleasePool *pool;
|
||||
SDL_Rect rrect;
|
||||
NSSize imgSize = {icon->w, icon->h};
|
||||
|
||||
pool = [ [ NSAutoreleasePool alloc ] init ];
|
||||
SDL_GetClipRect(icon, &rrect);
|
||||
|
||||
/* create a big endian RGBA surface */
|
||||
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");
|
||||
goto freePool;
|
||||
}
|
||||
if (SDL_BlitSurface(icon,&rrect,mergedSurface,&rrect)) {
|
||||
NSLog(@"Error blitting to mergedSurface");
|
||||
goto freePool;
|
||||
}
|
||||
if (mask) {
|
||||
masksize=icon->w*icon->h;
|
||||
surfPtr = (Uint8 *)mergedSurface->pixels;
|
||||
#define ALPHASHIFT 3
|
||||
for (i=0;i<masksize;i+=8)
|
||||
for (j=0;j<8;j++)
|
||||
surfPtr[ALPHASHIFT+((i+j)<<2)]=(mask[i>>3]&(1<<(7-j)))?0xFF:0x00;
|
||||
}
|
||||
imgrep = [ [ NSBitmapImageRep alloc]
|
||||
initWithBitmapDataPlanes:(unsigned char **)&mergedSurface->pixels
|
||||
pixelsWide:icon->w pixelsHigh:icon->h bitsPerSample:8 samplesPerPixel:4
|
||||
hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace
|
||||
bytesPerRow:icon->w<<2 bitsPerPixel:32 ];
|
||||
img = [ [ NSImage alloc ] initWithSize:imgSize ];
|
||||
[ img addRepresentation: imgrep ];
|
||||
[ NSApp setApplicationIconImage:img ];
|
||||
[ img release ];
|
||||
[ imgrep release ];
|
||||
SDL_FreeSurface(mergedSurface);
|
||||
|
||||
if (SDL_BlitSurface(icon,&rrect,mergedSurface,&rrect)) {
|
||||
NSLog(@"Error blitting to mergedSurface");
|
||||
goto freePool;
|
||||
}
|
||||
|
||||
if (mask) {
|
||||
masksize=icon->w*icon->h;
|
||||
surfPtr = (Uint8 *)mergedSurface->pixels;
|
||||
#define ALPHASHIFT 3
|
||||
for (i=0;i<masksize;i+=8)
|
||||
for (j=0;j<8;j++)
|
||||
surfPtr[ALPHASHIFT+((i+j)<<2)]=(mask[i>>3]&(1<<(7-j)))?0xFF:0x00;
|
||||
}
|
||||
|
||||
imgrep = [ [ NSBitmapImageRep alloc]
|
||||
initWithBitmapDataPlanes:(unsigned char **)&mergedSurface->pixels
|
||||
pixelsWide:icon->w pixelsHigh:icon->h bitsPerSample:8 samplesPerPixel:4
|
||||
hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace
|
||||
bytesPerRow:icon->w<<2 bitsPerPixel:32 ];
|
||||
|
||||
img = [ [ NSImage alloc ] initWithSize:imgSize ];
|
||||
|
||||
[ img addRepresentation: imgrep ];
|
||||
[ NSApp setApplicationIconImage:img ];
|
||||
|
||||
[ img release ];
|
||||
[ imgrep release ];
|
||||
SDL_FreeSurface(mergedSurface);
|
||||
freePool:
|
||||
[pool release];
|
||||
[pool release];
|
||||
}
|
||||
|
||||
static int QZ_IconifyWindow (_THIS) {
|
||||
|
||||
/* Bug! minimize erases the framebuffer */
|
||||
if ( ! [ qz_window isMiniaturized ] ) {
|
||||
[ qz_window miniaturize:nil ];
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
SDL_SetError ("qz_window already iconified");
|
||||
SDL_SetError ("window already iconified");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -289,16 +296,94 @@ static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode) {
|
|||
break;
|
||||
case SDL_GRAB_OFF:
|
||||
CGAssociateMouseAndMouseCursorPosition (1);
|
||||
currentGrabMode = SDL_GRAB_OFF;
|
||||
current_grab_mode = SDL_GRAB_OFF;
|
||||
break;
|
||||
case SDL_GRAB_ON:
|
||||
QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
|
||||
CGAssociateMouseAndMouseCursorPosition (0);
|
||||
currentGrabMode = SDL_GRAB_ON;
|
||||
current_grab_mode = SDL_GRAB_ON;
|
||||
break;
|
||||
case SDL_GRAB_FULLSCREEN:
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,86 +1,105 @@
|
|||
/* Subclass of NSWindow to allow customization if we need it */
|
||||
|
||||
@interface SDL_QuartzWindow : NSWindow
|
||||
{}
|
||||
- (void)miniaturize:(id)sender;
|
||||
- (void)deminiaturize:(id)sender;
|
||||
- (void)display;
|
||||
@end
|
||||
/*
|
||||
This function makes the *SDL region* of the window 100% opaque.
|
||||
The genie effect uses the alpha component. Otherwise,
|
||||
it doesn't seem to matter what value it has.
|
||||
*/
|
||||
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) {
|
||||
SDL_Surface *surface = current_video->screen;
|
||||
int bpp;
|
||||
|
||||
Uint32 *pixels;
|
||||
Uint32 rowPixels;
|
||||
Uint32 width, height;
|
||||
Uint32 bpp;
|
||||
PixMapHandle pixMap;
|
||||
Rect bounds;
|
||||
int i, j;
|
||||
|
||||
pixMap = GetPortPixMap ( port );
|
||||
bpp = GetPixDepth ( pixMap );
|
||||
bpp = surface->format->BitsPerPixel;
|
||||
|
||||
if (bpp == 32) {
|
||||
|
||||
GetPortBounds ( port, &bounds );
|
||||
width = bounds.right - bounds.left;
|
||||
height = bounds.bottom - bounds.top;
|
||||
Uint32 *pixels = (Uint32*) surface->pixels;
|
||||
Uint32 rowPixels = surface->pitch / 4;
|
||||
Uint32 i, j;
|
||||
|
||||
LockPortBits (port);
|
||||
|
||||
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++) {
|
||||
for (i = 0; i < surface->h; i++)
|
||||
for (j = 0; j < surface->w; j++) {
|
||||
|
||||
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
|
||||
|
||||
/* 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
|
||||
{
|
||||
|
||||
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 {
|
||||
|
||||
QZ_SetPortAlphaOpaque ([ [ self contentView ] qdPort ],
|
||||
[ self styleMask ] & NSBorderlessWindowMask);
|
||||
/* make the alpha channel opaque so anim won't have holes in it */
|
||||
QZ_SetPortAlphaOpaque ();
|
||||
}
|
||||
|
||||
[ super miniaturize:sender ];
|
||||
}
|
||||
|
||||
/* this routine fires *after* deminiaturizing, so it might be useless to us */
|
||||
- (void)deminiaturize:(id)sender
|
||||
{
|
||||
[ super deminiaturize:sender ];
|
||||
}
|
||||
|
||||
- (void)display
|
||||
{
|
||||
/* Do nothing to keep pinstripe pattern from drawing */
|
||||
/*
|
||||
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)setFrame:(NSRect)frameRect display:(BOOL)flag
|
||||
{
|
||||
|
||||
/*
|
||||
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
|
||||
|
||||
/* Delegate for our NSWindow to send SDLQuit() on close */
|
||||
|
@ -90,19 +109,17 @@ static void QZ_SetPortAlphaOpaque (CGrafPtr port, Uint32 noTitleBar) {
|
|||
@end
|
||||
|
||||
@implementation SDL_QuartzWindowDelegate
|
||||
- (BOOL)windowShouldClose:(id)sender {
|
||||
|
||||
- (BOOL)windowShouldClose:(id)sender
|
||||
{
|
||||
SDL_PrivateQuit();
|
||||
return NO;
|
||||
}
|
||||
|
||||
@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
|
||||
{}
|
||||
@end
|
||||
|
||||
@implementation SDL_QuartzWindowView
|
||||
|
||||
@end
|
Loading…
Add table
Add a link
Reference in a new issue