Date: Sat, 19 Jan 2002 17:24:32 -0500 (EST)
From: Darrell Walisser <dwaliss1@purdue.edu> Subject: SDL Quartz video update -better mouse motion events -fixed minification bugs (except OpenGL) -fixed QZ_SetGamma for correct semantics -fade/unfade display before/after rez switch -experimental obscured-check/blind-copy code The obscured code, while it speeds up window drawing substantially, isn't ready yet. The reason is that there doesn't (yet) seem to be a way to know when the window is dragged or when the window suddenly comes to the foreground. Since Carbon windows seem to allow detection of such things, I suspect it is possible through some window server API. Cocoa(NSWindow) has no functions for such things, AFAIK. --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40273
This commit is contained in:
parent
d8881664ba
commit
06db61e1a0
5 changed files with 855 additions and 180 deletions
|
@ -19,6 +19,7 @@
|
||||||
Sam Lantinga
|
Sam Lantinga
|
||||||
slouken@libsdl.org
|
slouken@libsdl.org
|
||||||
*/
|
*/
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include "SDL_QuartzKeys.h"
|
#include "SDL_QuartzKeys.h"
|
||||||
|
|
||||||
|
@ -305,6 +306,12 @@ static void QZ_DoDeactivate (_THIS) {
|
||||||
|
|
||||||
static void QZ_PumpEvents (_THIS)
|
static void QZ_PumpEvents (_THIS)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static NSPoint lastMouse;
|
||||||
|
NSPoint mouse, saveMouse;
|
||||||
|
Point qdMouse;
|
||||||
|
CGMouseDelta dx, dy;
|
||||||
|
|
||||||
NSDate *distantPast;
|
NSDate *distantPast;
|
||||||
NSEvent *event;
|
NSEvent *event;
|
||||||
NSRect winRect;
|
NSRect winRect;
|
||||||
|
@ -314,10 +321,36 @@ static void QZ_PumpEvents (_THIS)
|
||||||
pool = [ [ NSAutoreleasePool alloc ] init ];
|
pool = [ [ NSAutoreleasePool alloc ] init ];
|
||||||
distantPast = [ NSDate distantPast ];
|
distantPast = [ NSDate distantPast ];
|
||||||
|
|
||||||
winRect = NSMakeRect (0, 0, SDL_VideoSurface->w + 1, SDL_VideoSurface->h + 1);
|
winRect = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
|
||||||
titleBarRect = NSMakeRect ( 0, SDL_VideoSurface->h, SDL_VideoSurface->w,
|
titleBarRect = NSMakeRect ( 0, SDL_VideoSurface->h, SDL_VideoSurface->w,
|
||||||
SDL_VideoSurface->h + 22 );
|
SDL_VideoSurface->h + 22 );
|
||||||
|
|
||||||
|
if (currentGrabMode != SDL_GRAB_ON) { /* if grabbed, the cursor can't move! (see fallback below) */
|
||||||
|
|
||||||
|
/* 1/2 second after a warp, the mouse cannot move (don't ask me why) */
|
||||||
|
/* So, approximate motion with CGGetLastMouseDelta, which still works, somehow */
|
||||||
|
if (! warp_flag) {
|
||||||
|
|
||||||
|
GetGlobalMouse (&qdMouse); /* use Carbon since [ NSEvent mouseLocation ] is broken */
|
||||||
|
mouse = NSMakePoint (qdMouse.h, qdMouse.v);
|
||||||
|
saveMouse = mouse;
|
||||||
|
|
||||||
|
if (mouse.x != lastMouse.x || mouse.y != lastMouse.y) {
|
||||||
|
|
||||||
|
QZ_PrivateCGToSDL (this, &mouse);
|
||||||
|
if (inForeground && NSPointInRect (mouse, winRect)) {
|
||||||
|
//printf ("Mouse Loc: (%f, %f)\n", mouse.x, mouse.y);
|
||||||
|
SDL_PrivateMouseMotion (0, 0, mouse.x, mouse.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastMouse = saveMouse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* accumulate any mouse events into one SDL mouse event */
|
||||||
|
dx = 0;
|
||||||
|
dy = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
/* Poll for an event. This will not block */
|
/* Poll for an event. This will not block */
|
||||||
|
@ -343,7 +376,7 @@ static void QZ_PumpEvents (_THIS)
|
||||||
|
|
||||||
#define DO_MOUSE_UP(button, sendToWindow) do { \
|
#define DO_MOUSE_UP(button, sendToWindow) do { \
|
||||||
if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \
|
if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) || \
|
||||||
!NSPointInRect([event locationInWindow], titleBarRect) )\
|
!NSPointInRect([event locationInWindow], titleBarRect) ) \
|
||||||
SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); \
|
SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0); \
|
||||||
[ NSApp sendEvent:event ]; \
|
[ NSApp sendEvent:event ]; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
@ -365,7 +398,7 @@ static void QZ_PumpEvents (_THIS)
|
||||||
DO_MOUSE_DOWN (1, 1);
|
DO_MOUSE_DOWN (1, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 25: DO_MOUSE_DOWN (2, 0); break;
|
case NSOtherMouseDown: DO_MOUSE_DOWN (2, 0); break;
|
||||||
case NSRightMouseDown: DO_MOUSE_DOWN (3, 0); break;
|
case NSRightMouseDown: DO_MOUSE_DOWN (3, 0); break;
|
||||||
case NSLeftMouseUp:
|
case NSLeftMouseUp:
|
||||||
|
|
||||||
|
@ -377,7 +410,7 @@ static void QZ_PumpEvents (_THIS)
|
||||||
DO_MOUSE_UP (1, 1);
|
DO_MOUSE_UP (1, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 26: 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) {
|
//if ([event subtype] == 7) {
|
||||||
|
@ -389,30 +422,37 @@ static void QZ_PumpEvents (_THIS)
|
||||||
case NSRightMouseDragged:
|
case NSRightMouseDragged:
|
||||||
case 27:
|
case 27:
|
||||||
case NSMouseMoved:
|
case NSMouseMoved:
|
||||||
if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN)
|
|
||||||
|| NSPointInRect([event locationInWindow], winRect) )
|
|
||||||
{
|
|
||||||
static int moves = 0;
|
|
||||||
NSPoint p;
|
|
||||||
|
|
||||||
if ( SDL_VideoSurface->flags & SDL_FULLSCREEN ) {
|
if (currentGrabMode == SDL_GRAB_ON) {
|
||||||
p = [ NSEvent mouseLocation ];
|
|
||||||
p.y = [[NSScreen mainScreen] frame].size.height - p.y;
|
/**
|
||||||
} else {
|
* If input is grabbed, we'll wing it and try to send some mouse
|
||||||
p = [ event locationInWindow ];
|
* moved events with CGGetLastMouseDelta(). Not optimal, but better
|
||||||
p.y = SDL_VideoSurface->h - p.y;
|
* than nothing.
|
||||||
|
**/
|
||||||
|
CGMouseDelta dx1, dy1;
|
||||||
|
CGGetLastMouseDelta (&dx1, &dy1);
|
||||||
|
dx += dx1;
|
||||||
|
dy += dy1;
|
||||||
}
|
}
|
||||||
|
else if (warp_flag) {
|
||||||
|
|
||||||
if ( (moves % 10) == 0 ) {
|
Uint32 ticks;
|
||||||
SDL_PrivateMouseMotion (0, 0, p.x, p.y);
|
|
||||||
|
ticks = SDL_GetTicks();
|
||||||
|
if (ticks - warp_ticks < 150) {
|
||||||
|
|
||||||
|
CGMouseDelta dx1, dy1;
|
||||||
|
CGGetLastMouseDelta (&dx1, &dy1);
|
||||||
|
dx += dx1;
|
||||||
|
dy += dy1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CGMouseDelta dx, dy;
|
|
||||||
CGGetLastMouseDelta (&dx, &dy);
|
warp_flag = 0;
|
||||||
SDL_PrivateMouseMotion (0, 1, dx, dy);
|
|
||||||
}
|
}
|
||||||
moves++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case NSScrollWheel:
|
case NSScrollWheel:
|
||||||
{
|
{
|
||||||
|
@ -435,8 +475,6 @@ static void QZ_PumpEvents (_THIS)
|
||||||
case NSFlagsChanged:
|
case NSFlagsChanged:
|
||||||
QZ_DoModifiers( [ event modifierFlags ] );
|
QZ_DoModifiers( [ event modifierFlags ] );
|
||||||
break;
|
break;
|
||||||
/* case NSMouseEntered: break; */
|
|
||||||
/* case NSMouseExited: break; */
|
|
||||||
case NSAppKitDefined:
|
case NSAppKitDefined:
|
||||||
switch ( [ event subtype ] ) {
|
switch ( [ event subtype ] ) {
|
||||||
case NSApplicationActivatedEventType:
|
case NSApplicationActivatedEventType:
|
||||||
|
@ -451,12 +489,17 @@ static void QZ_PumpEvents (_THIS)
|
||||||
/* case NSApplicationDefined: break; */
|
/* case NSApplicationDefined: break; */
|
||||||
/* case NSPeriodic: break; */
|
/* case NSPeriodic: break; */
|
||||||
/* case NSCursorUpdate: break; */
|
/* case NSCursorUpdate: break; */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
[ NSApp sendEvent:event ];
|
[ NSApp sendEvent:event ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (event != nil);
|
} while (event != nil);
|
||||||
|
|
||||||
|
/* check for accumulated mouse events */
|
||||||
|
if (dx != 0 || dy != 0)
|
||||||
|
SDL_PrivateMouseMotion (0, 1, dx, dy);
|
||||||
|
|
||||||
[ pool release ];
|
[ pool release ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,25 +34,28 @@
|
||||||
- Multiple monitor support (currently only main display)
|
- Multiple monitor support (currently only main display)
|
||||||
- Accelerated blitting support
|
- Accelerated blitting support
|
||||||
- Set the window icon (dock icon when API is available)
|
- Set the window icon (dock icon when API is available)
|
||||||
- Avoid erasing window on minimize, or disable minimize
|
- Fix white OpenGL window on minimize
|
||||||
|
- Find out what events should be sent/ignored if window is mimimized
|
||||||
|
- Find a better way to deal with resolution/depth switch while app is running
|
||||||
|
- Resizeable windows
|
||||||
|
- 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
|
- Crash in CG after several mode switches
|
||||||
- Retained windows don't draw their title bar quite right (OS Bug)
|
- Retained windows don't draw their title bar quite right (OS Bug) (not using retained windows)
|
||||||
- Should I do depth switching for windowed modes? - No, not usually.
|
- Cursor in 8 bit modes is screwy (might just be Radeon PCI bug)
|
||||||
- Launch times are slow, maybe prebinding will help
|
- Warping cursor delays mouse events for a fraction of a second,
|
||||||
- Direct framebuffer access has some artifacts, maybe a driver issue
|
there is a hack around this that helps a bit
|
||||||
- Cursor in 8 bit modes is screwy
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ApplicationServices/ApplicationServices.h>
|
|
||||||
#include <OpenGL/OpenGL.h>
|
|
||||||
#include <Cocoa/Cocoa.h>
|
#include <Cocoa/Cocoa.h>
|
||||||
|
#include <OpenGL/OpenGL.h>
|
||||||
#include <Carbon/Carbon.h>
|
#include <Carbon/Carbon.h>
|
||||||
|
|
||||||
#include "SDL_video.h"
|
#include "SDL_video.h"
|
||||||
#include "SDL_error.h"
|
#include "SDL_error.h"
|
||||||
|
#include "SDL_timer.h"
|
||||||
#include "SDL_syswm.h"
|
#include "SDL_syswm.h"
|
||||||
#include "SDL_sysvideo.h"
|
#include "SDL_sysvideo.h"
|
||||||
#include "SDL_pixels_c.h"
|
#include "SDL_pixels_c.h"
|
||||||
|
@ -71,21 +74,34 @@
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
/* Structure for rez switch gamma fades */
|
||||||
|
/* We can hide the monitor flicker by setting the gamma tables to 0 */
|
||||||
|
#define QZ_GAMMA_TABLE_SIZE 256
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
CGGammaValue red[QZ_GAMMA_TABLE_SIZE];
|
||||||
|
CGGammaValue green[QZ_GAMMA_TABLE_SIZE];
|
||||||
|
CGGammaValue blue[QZ_GAMMA_TABLE_SIZE];
|
||||||
|
|
||||||
|
} SDL_QuartzGammaTable;
|
||||||
|
|
||||||
|
/* Main driver structure to store required state information */
|
||||||
typedef struct SDL_PrivateVideoData {
|
typedef struct SDL_PrivateVideoData {
|
||||||
|
|
||||||
CGDirectDisplayID display; /* 0 == main display */
|
CGDirectDisplayID display; /* 0 == main display (only support single display) */
|
||||||
CFDictionaryRef mode;
|
CFDictionaryRef mode; /* current mode of the display */
|
||||||
CFDictionaryRef save_mode;
|
CFDictionaryRef save_mode; /* original mode of the display */
|
||||||
CFArrayRef mode_list;
|
CFArrayRef mode_list; /* list of available fullscreen modes */
|
||||||
CGDirectPaletteRef palette;
|
CGDirectPaletteRef palette; /* palette of an 8-bit display */
|
||||||
NSOpenGLContext *gl_context;
|
NSOpenGLContext *gl_context; /* object that represents an OpenGL rendering context */
|
||||||
Uint32 width, height, bpp;
|
Uint32 width, height, bpp; /* frequently used data about the display */
|
||||||
Uint32 flags;
|
Uint32 flags; /* flags for mode, for teardown purposes */
|
||||||
SDL_bool video_is_set; /* tell if the video mode was set */
|
Uint32 video_set; /* boolean; indicates if video was set correctly */
|
||||||
|
Uint32 warp_flag; /* boolean; notify to event loop that a warp just occured */
|
||||||
/* Window-only fields */
|
Uint32 warp_ticks; /* timestamp when the warp occured */
|
||||||
NSWindow *window;
|
NSWindow *window; /* Cocoa window to implement the SDL window */
|
||||||
NSQuickDrawView *view;
|
NSQuickDrawView *view; /* the window's view; draw 2D into this view */
|
||||||
|
|
||||||
} SDL_PrivateVideoData ;
|
} SDL_PrivateVideoData ;
|
||||||
|
|
||||||
|
@ -95,21 +111,68 @@ typedef struct SDL_PrivateVideoData {
|
||||||
#define save_mode (this->hidden->save_mode)
|
#define save_mode (this->hidden->save_mode)
|
||||||
#define mode_list (this->hidden->mode_list)
|
#define mode_list (this->hidden->mode_list)
|
||||||
#define palette (this->hidden->palette)
|
#define palette (this->hidden->palette)
|
||||||
#define glcontext (this->hidden->glcontext)
|
|
||||||
#define objc_video (this->hidden->objc_video)
|
|
||||||
#define gl_context (this->hidden->gl_context)
|
#define gl_context (this->hidden->gl_context)
|
||||||
#define device_width (this->hidden->width)
|
#define device_width (this->hidden->width)
|
||||||
#define device_height (this->hidden->height)
|
#define device_height (this->hidden->height)
|
||||||
#define device_bpp (this->hidden->bpp)
|
#define device_bpp (this->hidden->bpp)
|
||||||
#define mode_flags (this->hidden->flags)
|
#define mode_flags (this->hidden->flags)
|
||||||
#define video_set (this->hidden->video_is_set)
|
|
||||||
#define qz_window (this->hidden->window)
|
#define qz_window (this->hidden->window)
|
||||||
#define windowView (this->hidden->view)
|
#define window_view (this->hidden->view)
|
||||||
|
#define video_set (this->hidden->video_set)
|
||||||
|
#define warp_ticks (this->hidden->warp_ticks)
|
||||||
|
#define warp_flag (this->hidden->warp_flag)
|
||||||
|
|
||||||
/* Interface for hardware fill not (yet) in the public API */
|
/* Obscuring code: maximum number of windows above ours (inclusive) */
|
||||||
int CGSDisplayHWFill (CGDirectDisplayID id, unsigned int x, unsigned int y,
|
#define kMaxWindows 256
|
||||||
|
|
||||||
|
/* Some of the Core Graphics Server API for obscuring code */
|
||||||
|
#define kCGSWindowLevelTop 2147483632
|
||||||
|
#define kCGSWindowLevelDockIconDrag 500
|
||||||
|
#define kCGSWindowLevelDockMenu 101
|
||||||
|
#define kCGSWindowLevelMenuIgnore 21
|
||||||
|
#define kCGSWindowLevelMenu 20
|
||||||
|
#define kCGSWindowLevelDockLabel 12
|
||||||
|
#define kCGSWindowLevelDockIcon 11
|
||||||
|
#define kCGSWindowLevelDock 10
|
||||||
|
#define kCGSWindowLevelUtility 3
|
||||||
|
#define kCGSWindowLevelNormal 0
|
||||||
|
|
||||||
|
/* For completeness; We never use these window levels, they are always below us
|
||||||
|
#define kCGSWindowLevelMBarShadow -20
|
||||||
|
#define kCGSWindowLevelDesktopPicture -2147483647
|
||||||
|
#define kCGSWindowLevelDesktop -2147483648
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef CGError CGSError;
|
||||||
|
typedef long CGSWindowCount;
|
||||||
|
typedef void * CGSConnectionID;
|
||||||
|
typedef int CGSWindowID;
|
||||||
|
typedef CGSWindowID* CGSWindowIDList;
|
||||||
|
typedef CGWindowLevel CGSWindowLevel;
|
||||||
|
typedef NSRect CGSRect;
|
||||||
|
|
||||||
|
extern CGSConnectionID _CGSDefaultConnection ();
|
||||||
|
|
||||||
|
extern CGSError CGSGetOnScreenWindowList (CGSConnectionID cid,
|
||||||
|
CGSConnectionID owner,
|
||||||
|
CGSWindowCount listCapacity,
|
||||||
|
CGSWindowIDList list,
|
||||||
|
CGSWindowCount *listCount);
|
||||||
|
|
||||||
|
extern CGSError CGSGetScreenRectForWindow (CGSConnectionID cid,
|
||||||
|
CGSWindowID wid,
|
||||||
|
CGSRect *rect);
|
||||||
|
|
||||||
|
extern CGWindowLevel CGSGetWindowLevel (CGSConnectionID cid,
|
||||||
|
CGSWindowID wid,
|
||||||
|
CGSWindowLevel *level);
|
||||||
|
|
||||||
|
extern CGSError CGSDisplayHWFill (CGDirectDisplayID id, unsigned int x, unsigned int y,
|
||||||
unsigned int w, unsigned int h, unsigned int color);
|
unsigned int w, unsigned int h, unsigned int color);
|
||||||
int CGSDisplayCanHWFill (CGDirectDisplayID id);
|
|
||||||
|
extern CGSError CGSDisplayCanHWFill (CGDirectDisplayID id);
|
||||||
|
|
||||||
|
extern CGSError CGSGetMouseEnabledFlags (CGSConnectionID cid, CGSWindowID wid, int *flags);
|
||||||
|
|
||||||
/* Bootstrap functions */
|
/* Bootstrap functions */
|
||||||
static int QZ_Available ();
|
static int QZ_Available ();
|
||||||
|
@ -156,7 +219,7 @@ static void QZ_GL_SwapBuffers (_THIS);
|
||||||
static int QZ_GL_LoadLibrary (_THIS, const char *location);
|
static int QZ_GL_LoadLibrary (_THIS, const char *location);
|
||||||
|
|
||||||
/* Private function to warp the cursor (used internally) */
|
/* Private function to warp the cursor (used internally) */
|
||||||
static void QZ_PrivateWarpCursor (_THIS, int fullscreen, int h, int x, int y);
|
static void QZ_PrivateWarpCursor (_THIS, int x, int y);
|
||||||
|
|
||||||
/* Cursor and Mouse functions */
|
/* Cursor and Mouse functions */
|
||||||
static void QZ_FreeWMCursor (_THIS, WMcursor *cursor);
|
static void QZ_FreeWMCursor (_THIS, WMcursor *cursor);
|
||||||
|
@ -177,3 +240,4 @@ 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);*/
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,10 @@ static char QZ_Error[255]; /* Global error buffer to temporarily store more info
|
||||||
#include "SDL_QuartzEvents.m"
|
#include "SDL_QuartzEvents.m"
|
||||||
#include "SDL_QuartzWindow.m"
|
#include "SDL_QuartzWindow.m"
|
||||||
|
|
||||||
|
|
||||||
/* Bootstrap binding, enables entry point into the driver */
|
/* Bootstrap binding, enables entry point into the driver */
|
||||||
VideoBootStrap QZ_bootstrap = {
|
VideoBootStrap QZ_bootstrap = {
|
||||||
"Quartz", "MacOS X CoreGraphics", QZ_Available, QZ_CreateDevice
|
"Quartz", "Mac OS X CoreGraphics", QZ_Available, QZ_CreateDevice
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Bootstrap functions */
|
/* Bootstrap functions */
|
||||||
|
@ -44,7 +45,7 @@ static int QZ_Available () {
|
||||||
|
|
||||||
static SDL_VideoDevice* QZ_CreateDevice (int device_index) {
|
static SDL_VideoDevice* QZ_CreateDevice (int device_index) {
|
||||||
|
|
||||||
#pragma unused (device_index)
|
#pragma unused (device_index)
|
||||||
|
|
||||||
SDL_VideoDevice *device;
|
SDL_VideoDevice *device;
|
||||||
SDL_PrivateVideoData *hidden;
|
SDL_PrivateVideoData *hidden;
|
||||||
|
@ -135,7 +136,7 @@ static int QZ_VideoInit (_THIS, SDL_PixelFormat *video_format) {
|
||||||
|
|
||||||
static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
|
static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
|
||||||
|
|
||||||
CFIndex num_modes = CFArrayGetCount (mode_list);
|
CFIndex num_modes;
|
||||||
CFIndex i;
|
CFIndex i;
|
||||||
|
|
||||||
static SDL_Rect **list = NULL;
|
static SDL_Rect **list = NULL;
|
||||||
|
@ -157,6 +158,8 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
|
||||||
list = NULL;
|
list = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
num_modes = CFArrayGetCount (mode_list);
|
||||||
|
|
||||||
/* Build list of modes with the requested bpp */
|
/* Build list of modes with the requested bpp */
|
||||||
for (i = 0; i < num_modes; i++) {
|
for (i = 0; i < num_modes; i++) {
|
||||||
|
|
||||||
|
@ -201,15 +204,17 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
|
||||||
|
|
||||||
list_size++;
|
list_size++;
|
||||||
|
|
||||||
if ( list == NULL)
|
if (list == NULL)
|
||||||
list = (SDL_Rect**) malloc (sizeof(*list) * list_size+1);
|
list = (SDL_Rect**) malloc (sizeof(*list) * (list_size+1) );
|
||||||
else
|
else
|
||||||
list = (SDL_Rect**) realloc (list, sizeof(*list) * list_size+1);
|
list = (SDL_Rect**) realloc (list, sizeof(*list) * (list_size+1));
|
||||||
|
|
||||||
rect = (SDL_Rect*) malloc (sizeof(**list));
|
rect = (SDL_Rect*) malloc (sizeof(**list));
|
||||||
|
|
||||||
if (list == NULL || rect == NULL)
|
if (list == NULL || rect == NULL) {
|
||||||
SDL_OutOfMemory ();
|
SDL_OutOfMemory ();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
rect->w = width;
|
rect->w = width;
|
||||||
rect->h = height;
|
rect->h = height;
|
||||||
|
@ -241,6 +246,92 @@ static SDL_Rect** QZ_ListModes (_THIS, SDL_PixelFormat *format, Uint32 flags) {
|
||||||
return list;
|
return 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 */
|
||||||
|
static UInt32 QZ_FadeGammaOut (_THIS, SDL_QuartzGammaTable *table) {
|
||||||
|
|
||||||
|
CGGammaValue redTable[QZ_GAMMA_TABLE_SIZE],
|
||||||
|
greenTable[QZ_GAMMA_TABLE_SIZE],
|
||||||
|
blueTable[QZ_GAMMA_TABLE_SIZE];
|
||||||
|
|
||||||
|
float percent;
|
||||||
|
int j;
|
||||||
|
int actual;
|
||||||
|
|
||||||
|
if ( (CGDisplayNoErr != CGGetDisplayTransferByTable
|
||||||
|
(display_id, QZ_GAMMA_TABLE_SIZE,
|
||||||
|
table->red, table->green, table->blue, &actual)) ||
|
||||||
|
actual != QZ_GAMMA_TABLE_SIZE) {
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (redTable, table->red, sizeof(redTable));
|
||||||
|
memcpy (greenTable, table->green, sizeof(greenTable));
|
||||||
|
memcpy (blueTable, table->blue, sizeof(greenTable));
|
||||||
|
|
||||||
|
for (percent = 1.0; percent >= 0.0; percent -= 0.01) {
|
||||||
|
|
||||||
|
for (j = 0; j < QZ_GAMMA_TABLE_SIZE; j++) {
|
||||||
|
|
||||||
|
redTable[j] = redTable[j] * percent;
|
||||||
|
greenTable[j] = greenTable[j] * percent;
|
||||||
|
blueTable[j] = blueTable[j] * percent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CGDisplayNoErr != CGSetDisplayTransferByTable
|
||||||
|
(display_id, QZ_GAMMA_TABLE_SIZE,
|
||||||
|
redTable, greenTable, blueTable)) {
|
||||||
|
|
||||||
|
CGDisplayRestoreColorSyncSettings();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Delay (10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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],
|
||||||
|
greenTable[QZ_GAMMA_TABLE_SIZE],
|
||||||
|
blueTable[QZ_GAMMA_TABLE_SIZE];
|
||||||
|
|
||||||
|
float percent;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
memset (redTable, 0, sizeof(redTable));
|
||||||
|
memset (greenTable, 0, sizeof(greenTable));
|
||||||
|
memset (blueTable, 0, sizeof(greenTable));
|
||||||
|
|
||||||
|
for (percent = 0.0; percent <= 1.0; percent += 0.01) {
|
||||||
|
|
||||||
|
for (j = 0; j < QZ_GAMMA_TABLE_SIZE; j++) {
|
||||||
|
|
||||||
|
redTable[j] = table->red[j] * percent;
|
||||||
|
greenTable[j] = table->green[j] * percent;
|
||||||
|
blueTable[j] = table->blue[j] * percent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CGDisplayNoErr != CGSetDisplayTransferByTable
|
||||||
|
(display_id, QZ_GAMMA_TABLE_SIZE,
|
||||||
|
redTable, greenTable, blueTable)) {
|
||||||
|
|
||||||
|
CGDisplayRestoreColorSyncSettings();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Delay (10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void QZ_UnsetVideoMode (_THIS) {
|
static void QZ_UnsetVideoMode (_THIS) {
|
||||||
|
|
||||||
/* Reset values that may change between switches */
|
/* Reset values that may change between switches */
|
||||||
|
@ -248,35 +339,52 @@ static void QZ_UnsetVideoMode (_THIS) {
|
||||||
this->FillHWRect = NULL;
|
this->FillHWRect = NULL;
|
||||||
this->UpdateRects = NULL;
|
this->UpdateRects = NULL;
|
||||||
|
|
||||||
/* Restore gamma settings */
|
/* Release fullscreen resources */
|
||||||
CGDisplayRestoreColorSyncSettings ();
|
|
||||||
|
|
||||||
/* Restore original screen resolution */
|
|
||||||
if ( mode_flags & SDL_FULLSCREEN ) {
|
if ( mode_flags & SDL_FULLSCREEN ) {
|
||||||
|
|
||||||
|
SDL_QuartzGammaTable gamma_table;
|
||||||
|
int gamma_error;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
if (mode_flags & SDL_OPENGL)
|
if (mode_flags & SDL_OPENGL)
|
||||||
CGLSetFullScreen(NULL);
|
CGLSetFullScreen(NULL);
|
||||||
|
|
||||||
|
/* Restore original screen resolution/bpp */
|
||||||
CGDisplaySwitchToMode (display_id, save_mode);
|
CGDisplaySwitchToMode (display_id, save_mode);
|
||||||
CGDisplayRelease (display_id);
|
CGDisplayRelease (display_id);
|
||||||
|
ShowMenuBar ();
|
||||||
|
|
||||||
|
if (! gamma_error)
|
||||||
|
QZ_FadeGammaIn (this, &gamma_table);
|
||||||
}
|
}
|
||||||
/* Release window mode data structures */
|
/* Release window mode resources */
|
||||||
else {
|
else {
|
||||||
if ( (mode_flags & SDL_OPENGL) == 0 ) {
|
if ( (mode_flags & SDL_OPENGL) == 0 ) {
|
||||||
UnlockPortBits ( [ windowView qdPort ] );
|
UnlockPortBits ( [ window_view qdPort ] );
|
||||||
[ windowView release ];
|
[ window_view release ];
|
||||||
}
|
}
|
||||||
[ qz_window setContentView:nil ];
|
[ qz_window setContentView:nil ];
|
||||||
[ qz_window setDelegate:nil ];
|
[ qz_window setDelegate:nil ];
|
||||||
[ qz_window close ];
|
[ qz_window close ];
|
||||||
}
|
[ qz_window release ];
|
||||||
|
|
||||||
/* Set pixels to null (so other code doesn't try to free it) */
|
|
||||||
if (this->screen != NULL)
|
|
||||||
this->screen->pixels = NULL;
|
|
||||||
|
|
||||||
/* Release the OpenGL context */
|
/* Release the OpenGL context */
|
||||||
if ( mode_flags & SDL_OPENGL )
|
if ( mode_flags & SDL_OPENGL )
|
||||||
QZ_TearDownOpenGL (this);
|
QZ_TearDownOpenGL (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 */
|
/* Ensure the cursor will be visible and working when we quit */
|
||||||
CGDisplayShowCursor (display_id);
|
CGDisplayShowCursor (display_id);
|
||||||
|
@ -289,6 +397,8 @@ static void QZ_UnsetVideoMode (_THIS) {
|
||||||
static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int width,
|
static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int width,
|
||||||
int height, int bpp, Uint32 flags) {
|
int height, int bpp, Uint32 flags) {
|
||||||
int exact_match;
|
int exact_match;
|
||||||
|
int gamma_error;
|
||||||
|
SDL_QuartzGammaTable gamma_table;
|
||||||
|
|
||||||
/* See if requested mode exists */
|
/* See if requested mode exists */
|
||||||
mode = CGDisplayBestModeForParameters (display_id, bpp, width,
|
mode = CGDisplayBestModeForParameters (display_id, bpp, width,
|
||||||
|
@ -301,34 +411,24 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
|
||||||
goto ERR_NO_MATCH;
|
goto ERR_NO_MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fade display to zero gamma */
|
||||||
|
gamma_error = QZ_FadeGammaOut (this, &gamma_table);
|
||||||
|
|
||||||
/* Put up the blanking window (a window above all other windows) */
|
/* Put up the blanking window (a window above all other windows) */
|
||||||
if ( CGDisplayNoErr != CGDisplayCapture (display_id) ) {
|
if ( CGDisplayNoErr != CGDisplayCapture (display_id) ) {
|
||||||
SDL_SetError ("Failed capturing display");
|
SDL_SetError ("Failed capturing display");
|
||||||
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");
|
||||||
goto ERR_NO_SWITCH;
|
goto ERR_NO_SWITCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* None of these methods seem to fix the fullscreen artifacts bug(s) */
|
|
||||||
#if USE_GDHANDLE
|
|
||||||
SetGDevice(GetMainDevice());
|
|
||||||
current->pitch = (**(** GetMainDevice() ).gdPMap).rowBytes & 0x3FFF;
|
|
||||||
current->pixels = (**(** GetMainDevice() ).gdPMap).baseAddr;
|
|
||||||
#elif USE_CREATEPORT
|
|
||||||
device_port = CreateNewPortForCGDisplayID((Uint32*)display_id);
|
|
||||||
SetPort (device_port);
|
|
||||||
LockPortBits ( device_port );
|
|
||||||
current->pixels = GetPixBaseAddr ( GetPortPixMap ( device_port ) );
|
|
||||||
current->pitch = GetPixRowBytes ( GetPortPixMap ( device_port ) );
|
|
||||||
UnlockPortBits ( device_port );
|
|
||||||
#else
|
|
||||||
current->pixels = (Uint32*) CGDisplayBaseAddress (display_id);
|
current->pixels = (Uint32*) CGDisplayBaseAddress (display_id);
|
||||||
current->pitch = CGDisplayBytesPerRow (display_id);
|
current->pitch = CGDisplayBytesPerRow (display_id);
|
||||||
#endif
|
|
||||||
|
|
||||||
current->flags = 0;
|
current->flags = 0;
|
||||||
current->w = width;
|
current->w = width;
|
||||||
|
@ -354,7 +454,7 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
|
||||||
CGLContextObj ctx;
|
CGLContextObj ctx;
|
||||||
|
|
||||||
if ( ! QZ_SetupOpenGL (this, bpp, flags) ) {
|
if ( ! QZ_SetupOpenGL (this, bpp, flags) ) {
|
||||||
return NULL;
|
goto ERR_NO_GL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = [ gl_context cglContext ];
|
ctx = [ gl_context cglContext ];
|
||||||
|
@ -368,21 +468,29 @@ static SDL_Surface* QZ_SetVideoFullScreen (_THIS, SDL_Surface *current, int widt
|
||||||
|
|
||||||
[ gl_context makeCurrentContext];
|
[ gl_context makeCurrentContext];
|
||||||
|
|
||||||
|
glClear (GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
[ gl_context flushBuffer ];
|
||||||
|
|
||||||
current->flags |= SDL_OPENGL;
|
current->flags |= SDL_OPENGL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we don't hide menu bar, it will get events and interrupt the program */
|
/* If we don't hide menu bar, it will get events and interrupt the program */
|
||||||
HideMenuBar ();
|
HideMenuBar ();
|
||||||
|
|
||||||
|
/* Fade the display to original gamma */
|
||||||
|
if (! gamma_error )
|
||||||
|
QZ_FadeGammaIn (this, &gamma_table);
|
||||||
|
|
||||||
/* Save the flags to ensure correct tear-down */
|
/* Save the flags to ensure correct tear-down */
|
||||||
mode_flags = current->flags;
|
mode_flags = current->flags;
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
|
|
||||||
/* Since the blanking window covers *all* windows (even force quit) correct recovery is crutial */
|
/* Since the blanking window covers *all* windows (even force quit) correct recovery is crucial */
|
||||||
ERR_NO_GL: CGDisplaySwitchToMode (display_id, save_mode);
|
ERR_NO_GL: CGDisplaySwitchToMode (display_id, save_mode);
|
||||||
ERR_NO_SWITCH: CGDisplayRelease (display_id);
|
ERR_NO_SWITCH: CGDisplayRelease (display_id);
|
||||||
ERR_NO_CAPTURE:
|
ERR_NO_CAPTURE: if (!gamma_error) { QZ_FadeGammaIn (this, &gamma_table); }
|
||||||
ERR_NO_MATCH: return NULL;
|
ERR_NO_MATCH: return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,16 +548,17 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
|
||||||
/* For 2D, we set the content view to a NSQuickDrawView */
|
/* For 2D, we set the content view to a NSQuickDrawView */
|
||||||
else {
|
else {
|
||||||
|
|
||||||
windowView = [ [ NSQuickDrawView alloc ] init ];
|
window_view = [ [ SDL_QuartzWindowView alloc ] init ];
|
||||||
[ qz_window setContentView:windowView ];
|
[ qz_window setContentView:window_view ];
|
||||||
[ qz_window makeKeyAndOrderFront:nil ];
|
[ qz_window makeKeyAndOrderFront:nil ];
|
||||||
|
|
||||||
LockPortBits ( [ windowView qdPort ] );
|
LockPortBits ( [ window_view qdPort ] );
|
||||||
current->pixels = GetPixBaseAddr ( GetPortPixMap ( [ windowView qdPort ] ) );
|
current->pixels = GetPixBaseAddr ( GetPortPixMap ( [ window_view qdPort ] ) );
|
||||||
current->pitch = GetPixRowBytes ( GetPortPixMap ( [ windowView qdPort ] ) );
|
current->pitch = GetPixRowBytes ( GetPortPixMap ( [ window_view qdPort ] ) );
|
||||||
|
|
||||||
current->flags |= SDL_SWSURFACE;
|
current->flags |= SDL_SWSURFACE;
|
||||||
current->flags |= SDL_PREALLOC;
|
current->flags |= SDL_PREALLOC;
|
||||||
|
|
||||||
if ( flags & SDL_NOFRAME )
|
if ( flags & SDL_NOFRAME )
|
||||||
current->flags |= SDL_NOFRAME;
|
current->flags |= SDL_NOFRAME;
|
||||||
if ( flags & SDL_RESIZABLE )
|
if ( flags & SDL_RESIZABLE )
|
||||||
|
@ -462,6 +571,10 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
|
||||||
|
|
||||||
this->UpdateRects = QZ_UpdateRects;
|
this->UpdateRects = QZ_UpdateRects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save flags to ensure correct teardown */
|
||||||
|
mode_flags = current->flags;
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,7 +595,7 @@ static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width,
|
||||||
/* Setup windowed video */
|
/* Setup windowed video */
|
||||||
else {
|
else {
|
||||||
/* Force bpp to the device's bpp */
|
/* Force bpp to the device's bpp */
|
||||||
bpp = current->format->BitsPerPixel;
|
bpp = device_bpp;
|
||||||
current = QZ_SetVideoWindowed (this, current, width, height, bpp, flags);
|
current = QZ_SetVideoWindowed (this, current, width, height, bpp, flags);
|
||||||
if (current == NULL)
|
if (current == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -520,10 +633,7 @@ static SDL_Surface* QZ_SetVideoMode (_THIS, SDL_Surface *current, int width,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Warp mouse to origin in order to get passive mouse motion events started correctly */
|
/* Signal successful completion (used internally) */
|
||||||
QZ_PrivateWarpCursor (this, current->flags & SDL_FULLSCREEN, height, 0, 0);
|
|
||||||
|
|
||||||
/* Signal successful completion */
|
|
||||||
video_set = SDL_TRUE;
|
video_set = SDL_TRUE;
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
|
@ -561,12 +671,293 @@ 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,
|
||||||
|
* 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,
|
||||||
|
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.
|
||||||
|
The procedure used below is puts accuracy before speed; however, it aims to call
|
||||||
|
the window server the fewest number of times possible to keep things reasonable.
|
||||||
|
In my testing on a 300mhz G3, this routine typically takes < 2 ms. -DW
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
-Calls into the Window Server involve IPC which is slow.
|
||||||
|
-Getting a rectangle seems slower than getting the window level
|
||||||
|
-The window list we get back is in sorted order, top to bottom
|
||||||
|
-On average, I suspect, most windows above ours are dock icon windows (hence optimization)
|
||||||
|
-Some windows above ours are always there, and cannot move or obscure us (menu bar)
|
||||||
|
|
||||||
|
Bugs:
|
||||||
|
-no way (yet) to deactivate direct drawing when a window is dragged,
|
||||||
|
or suddenly obscured, so drawing continues and can produce garbage
|
||||||
|
We need some kind of locking mechanism on window movement to prevent this
|
||||||
|
|
||||||
|
-deactivated normal windows use activated normal
|
||||||
|
window shadows (slight inaccuraccy)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Cache the connection to the window server */
|
||||||
|
static CGSConnectionID cgsConnection = (CGSConnectionID) -1;
|
||||||
|
|
||||||
|
/* Cache the dock icon windows */
|
||||||
|
static CGSWindowID dockIcons[kMaxWindows];
|
||||||
|
static int numCachedDockIcons = 0;
|
||||||
|
|
||||||
|
CGSWindowID windows[kMaxWindows];
|
||||||
|
CGSWindowCount i, count;
|
||||||
|
CGSWindowLevel winLevel;
|
||||||
|
CGSRect winRect;
|
||||||
|
|
||||||
|
CGSRect contentRect;
|
||||||
|
int windowNumber;
|
||||||
|
//int isMainWindow;
|
||||||
|
int firstDockIcon;
|
||||||
|
int dockIconCacheMiss;
|
||||||
|
int windowContentOffset;
|
||||||
|
|
||||||
|
int obscured = SDL_TRUE;
|
||||||
|
|
||||||
|
if ( [ window isVisible ] ) {
|
||||||
|
|
||||||
|
/* 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() */
|
||||||
|
if (cgsConnection == (CGSConnectionID) -1) {
|
||||||
|
cgsConnection = (CGSConnectionID) 0;
|
||||||
|
cgsConnection = _CGSDefaultConnection ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cgsConnection) {
|
||||||
|
|
||||||
|
if ( ! [ window styleMask ] & NSBorderlessWindowMask )
|
||||||
|
windowContentOffset = 22;
|
||||||
|
else
|
||||||
|
windowContentOffset = 0;
|
||||||
|
|
||||||
|
windowNumber = [ window windowNumber ];
|
||||||
|
//isMainWindow = [ window isMainWindow ];
|
||||||
|
|
||||||
|
/* The window list is sorted according to order on the screen */
|
||||||
|
count = 0;
|
||||||
|
CGSGetOnScreenWindowList (cgsConnection, 0, kMaxWindows, windows, &count);
|
||||||
|
CGSGetScreenRectForWindow (cgsConnection, windowNumber, &contentRect);
|
||||||
|
|
||||||
|
/* adjust rect for window title bar (if present) */
|
||||||
|
contentRect.origin.y += windowContentOffset;
|
||||||
|
contentRect.size.height -= windowContentOffset;
|
||||||
|
|
||||||
|
firstDockIcon = -1;
|
||||||
|
dockIconCacheMiss = SDL_FALSE;
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
if (windows[i] == windowNumber) {
|
||||||
|
|
||||||
|
obscured = SDL_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
float shadowSide;
|
||||||
|
float shadowTop;
|
||||||
|
float shadowBottom;
|
||||||
|
|
||||||
|
CGSGetWindowLevel (cgsConnection, windows[i], &winLevel);
|
||||||
|
|
||||||
|
if (winLevel == kCGSWindowLevelDockIcon) {
|
||||||
|
|
||||||
|
int j;
|
||||||
|
|
||||||
|
if (firstDockIcon < 0) {
|
||||||
|
|
||||||
|
firstDockIcon = i;
|
||||||
|
|
||||||
|
if (numCachedDockIcons > 0) {
|
||||||
|
|
||||||
|
for (j = 0; j < numCachedDockIcons; j++) {
|
||||||
|
|
||||||
|
if (windows[i] == dockIcons[j])
|
||||||
|
i++;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j != 0) {
|
||||||
|
|
||||||
|
i--;
|
||||||
|
|
||||||
|
if (j < numCachedDockIcons) {
|
||||||
|
|
||||||
|
dockIconCacheMiss = SDL_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (winLevel == kCGSWindowLevelMenuIgnore
|
||||||
|
/* winLevel == kCGSWindowLevelTop */) {
|
||||||
|
|
||||||
|
continue; /* cannot obscure window */
|
||||||
|
}
|
||||||
|
else if (winLevel == kCGSWindowLevelDockMenu ||
|
||||||
|
winLevel == kCGSWindowLevelMenu) {
|
||||||
|
|
||||||
|
shadowSide = 18;
|
||||||
|
shadowTop = 4;
|
||||||
|
shadowBottom = 22;
|
||||||
|
}
|
||||||
|
else if (winLevel == kCGSWindowLevelUtility) {
|
||||||
|
|
||||||
|
shadowSide = 8;
|
||||||
|
shadowTop = 4;
|
||||||
|
shadowBottom = 12;
|
||||||
|
}
|
||||||
|
else if (winLevel == kCGSWindowLevelNormal) {
|
||||||
|
|
||||||
|
/* These numbers are for foreground windows,
|
||||||
|
they are too big (but will work) for background windows */
|
||||||
|
shadowSide = 20;
|
||||||
|
shadowTop = 10;
|
||||||
|
shadowBottom = 24;
|
||||||
|
}
|
||||||
|
else if (winLevel == kCGSWindowLevelDock) {
|
||||||
|
|
||||||
|
/* Create dock icon cache */
|
||||||
|
if (numCachedDockIcons != (i-firstDockIcon) ||
|
||||||
|
dockIconCacheMiss) {
|
||||||
|
|
||||||
|
numCachedDockIcons = i - firstDockIcon;
|
||||||
|
memcpy (dockIcons, &(windows[firstDockIcon]),
|
||||||
|
numCachedDockIcons * sizeof(*windows));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no shadow */
|
||||||
|
shadowSide = 0;
|
||||||
|
shadowTop = 0;
|
||||||
|
shadowBottom = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
/* kCGSWindowLevelDockLabel,
|
||||||
|
kCGSWindowLevelDock,
|
||||||
|
kOther??? */
|
||||||
|
|
||||||
|
/* no shadow */
|
||||||
|
shadowSide = 0;
|
||||||
|
shadowTop = 0;
|
||||||
|
shadowBottom = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGSGetScreenRectForWindow (cgsConnection, windows[i], &winRect);
|
||||||
|
|
||||||
|
winRect.origin.x -= shadowSide;
|
||||||
|
winRect.origin.y -= shadowTop;
|
||||||
|
winRect.size.width += shadowSide;
|
||||||
|
winRect.size.height += shadowBottom;
|
||||||
|
|
||||||
|
if (NSIntersectsRect (contentRect, winRect)) {
|
||||||
|
|
||||||
|
obscured = SDL_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* window was not our window */
|
||||||
|
|
||||||
|
} /* iterate over windows */
|
||||||
|
|
||||||
|
} /* get cgsConnection */
|
||||||
|
|
||||||
|
} /* window is visible */
|
||||||
|
|
||||||
|
return obscured;
|
||||||
|
#else
|
||||||
|
return SDL_TRUE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) {
|
static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) {
|
||||||
|
|
||||||
if (SDL_VideoSurface->flags & SDL_OPENGLBLIT) {
|
if (SDL_VideoSurface->flags & SDL_OPENGLBLIT) {
|
||||||
QZ_GL_SwapBuffers (this);
|
QZ_GL_SwapBuffers (this);
|
||||||
}
|
}
|
||||||
|
else if ( [ qz_window isMiniaturized ] &&
|
||||||
|
! (SDL_VideoSurface->flags & SDL_OPENGL)) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) ) {
|
||||||
|
|
||||||
|
/* Use direct copy to flush contents to the display */
|
||||||
|
CGrafPtr savePort;
|
||||||
|
CGrafPtr dstPort, srcPort;
|
||||||
|
const BitMap *dstBits, *srcBits;
|
||||||
|
Rect dstRect, srcRect;
|
||||||
|
Point offset;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
GetPort (&savePort);
|
||||||
|
|
||||||
|
dstPort = CreateNewPortForCGDisplayID ((UInt32)display_id);
|
||||||
|
srcPort = [ window_view qdPort ];
|
||||||
|
|
||||||
|
offset.h = 0;
|
||||||
|
offset.v = 0;
|
||||||
|
SetPort (srcPort);
|
||||||
|
LocalToGlobal (&offset);
|
||||||
|
|
||||||
|
SetPort (dstPort);
|
||||||
|
|
||||||
|
LockPortBits (dstPort);
|
||||||
|
LockPortBits (srcPort);
|
||||||
|
|
||||||
|
dstBits = GetPortBitMapForCopyBits (dstPort);
|
||||||
|
srcBits = GetPortBitMapForCopyBits (srcPort);
|
||||||
|
|
||||||
|
for (i = 0; i < numRects; i++) {
|
||||||
|
|
||||||
|
SetRect (&srcRect, rects[i].x, rects[i].y,
|
||||||
|
rects[i].x + rects[i].w,
|
||||||
|
rects[i].y + rects[i].h);
|
||||||
|
|
||||||
|
SetRect (&dstRect,
|
||||||
|
rects[i].x + offset.h,
|
||||||
|
rects[i].y + offset.v,
|
||||||
|
rects[i].x + rects[i].w + offset.h,
|
||||||
|
rects[i].y + rects[i].h + offset.v);
|
||||||
|
|
||||||
|
CopyBits (srcBits, dstBits,
|
||||||
|
&srcRect, &dstRect, srcCopy, NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SetPort (savePort);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
/* Use QDFlushPortBuffer() to flush content to display */
|
||||||
int i;
|
int i;
|
||||||
RgnHandle dirty = NewRgn ();
|
RgnHandle dirty = NewRgn ();
|
||||||
RgnHandle temp = NewRgn ();
|
RgnHandle temp = NewRgn ();
|
||||||
|
@ -582,7 +973,7 @@ static void QZ_UpdateRects (_THIS, int numRects, SDL_Rect *rects) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush the dirty region */
|
/* Flush the dirty region */
|
||||||
QDFlushPortBuffer ( [ windowView qdPort ], dirty );
|
QDFlushPortBuffer ( [ window_view qdPort ], dirty );
|
||||||
DisposeRgn (dirty);
|
DisposeRgn (dirty);
|
||||||
DisposeRgn (temp);
|
DisposeRgn (temp);
|
||||||
}
|
}
|
||||||
|
@ -597,6 +988,7 @@ static void QZ_VideoQuit (_THIS) {
|
||||||
static int QZ_FillHWRect (_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color) {
|
static int QZ_FillHWRect (_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color) {
|
||||||
|
|
||||||
CGSDisplayHWFill (display_id, rect->x, rect->y, rect->w, rect->h, color);
|
CGSDisplayHWFill (display_id, rect->x, rect->y, rect->w, rect->h, color);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,6 +998,7 @@ static int QZ_LockHWSurface(_THIS, SDL_Surface *surface) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void QZ_UnlockHWSurface(_THIS, SDL_Surface *surface) {
|
static void QZ_UnlockHWSurface(_THIS, SDL_Surface *surface) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void QZ_FreeHWSurface (_THIS, SDL_Surface *surface) {
|
static void QZ_FreeHWSurface (_THIS, SDL_Surface *surface) {
|
||||||
|
@ -622,23 +1015,42 @@ static int QZ_SetGamma (_THIS, float red, float green, float blue) {
|
||||||
|
|
||||||
const CGGammaValue min = 0.0, max = 1.0;
|
const CGGammaValue min = 0.0, max = 1.0;
|
||||||
|
|
||||||
if ( CGDisplayNoErr != CGSetDisplayTransferByFormula
|
if (red == 0.0)
|
||||||
(display_id, min, max, red, min, max, green, min, max, blue) )
|
red = FLT_MAX;
|
||||||
return -1;
|
else
|
||||||
|
red = 1.0 / red;
|
||||||
|
|
||||||
|
if (green == 0.0)
|
||||||
|
green = FLT_MAX;
|
||||||
|
else
|
||||||
|
green = 1.0 / green;
|
||||||
|
|
||||||
|
if (blue == 0.0)
|
||||||
|
blue = FLT_MAX;
|
||||||
|
else
|
||||||
|
blue = 1.0 / blue;
|
||||||
|
|
||||||
|
if ( CGDisplayNoErr == CGSetDisplayTransferByFormula
|
||||||
|
(display_id, min, max, red, min, max, green, min, max, blue) ) {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int QZ_GetGamma (_THIS, float *red, float *green, float *blue) {
|
static int QZ_GetGamma (_THIS, float *red, float *green, float *blue) {
|
||||||
|
|
||||||
CGGammaValue dummy;
|
CGGammaValue dummy;
|
||||||
if ( CGDisplayNoErr != CGGetDisplayTransferByFormula
|
if ( CGDisplayNoErr == CGGetDisplayTransferByFormula
|
||||||
(display_id, &dummy, &dummy, red,
|
(display_id, &dummy, &dummy, red,
|
||||||
&dummy, &dummy, green, &dummy, &dummy, blue) )
|
&dummy, &dummy, green, &dummy, &dummy, blue) )
|
||||||
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int QZ_SetGammaRamp (_THIS, Uint16 *ramp) {
|
static int QZ_SetGammaRamp (_THIS, Uint16 *ramp) {
|
||||||
|
@ -660,11 +1072,11 @@ static int QZ_SetGammaRamp (_THIS, Uint16 *ramp) {
|
||||||
for (i=512; i < 768; i++)
|
for (i=512; i < 768; i++)
|
||||||
blueTable[i % 256] = ramp[i] / 65535.0;
|
blueTable[i % 256] = ramp[i] / 65535.0;
|
||||||
|
|
||||||
if ( CGDisplayNoErr != CGSetDisplayTransferByTable
|
if ( CGDisplayNoErr == CGSetDisplayTransferByTable
|
||||||
(display_id, tableSize, redTable, greenTable, blueTable) )
|
(display_id, tableSize, redTable, greenTable, blueTable) )
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int QZ_GetGammaRamp (_THIS, Uint16 *ramp) {
|
static int QZ_GetGammaRamp (_THIS, Uint16 *ramp) {
|
||||||
|
@ -695,7 +1107,8 @@ static int QZ_GetGammaRamp (_THIS, Uint16 *ramp) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OpenGL helper functions */
|
/* OpenGL helper functions (used internally) */
|
||||||
|
|
||||||
static int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags) {
|
static int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags) {
|
||||||
|
|
||||||
NSOpenGLPixelFormatAttribute attr[32];
|
NSOpenGLPixelFormatAttribute attr[32];
|
||||||
|
@ -761,6 +1174,7 @@ static void QZ_TearDownOpenGL (_THIS) {
|
||||||
[ gl_context release ];
|
[ gl_context release ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* SDL OpenGL functions */
|
/* SDL OpenGL functions */
|
||||||
|
|
||||||
static int QZ_GL_LoadLibrary (_THIS, const char *location) {
|
static int QZ_GL_LoadLibrary (_THIS, const char *location) {
|
||||||
|
@ -805,6 +1219,7 @@ static int QZ_GL_GetAttribute (_THIS, SDL_GLattr attrib, int* value) {
|
||||||
|
|
||||||
CGLGetParameter (ctx, param, (long*)value);
|
CGLGetParameter (ctx, param, (long*)value);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
*value = -1;
|
*value = -1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -817,3 +1232,5 @@ static int QZ_GL_MakeCurrent (_THIS) {
|
||||||
static void QZ_GL_SwapBuffers (_THIS) {
|
static void QZ_GL_SwapBuffers (_THIS) {
|
||||||
[ gl_context flushBuffer ];
|
[ gl_context flushBuffer ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -87,26 +87,102 @@ static int QZ_ShowWMCursor (_THIS, WMcursor *cursor) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void QZ_PrivateWarpCursor (_THIS, int fullscreen, int h, int x, int y) {
|
/**
|
||||||
|
* 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.
|
||||||
|
**/
|
||||||
|
|
||||||
CGPoint p;
|
/* Convert Cocoa screen coordinate to Cocoa window coordinate */
|
||||||
|
static void QZ_PrivateGlobalToLocal (_THIS, NSPoint *p) {
|
||||||
|
|
||||||
/* We require absolute screen coordiates for our warp */
|
*p = [ qz_window convertScreenToBase:*p ];
|
||||||
p.x = x;
|
}
|
||||||
p.y = h - y;
|
|
||||||
|
|
||||||
if ( fullscreen )
|
|
||||||
/* Already absolute coordinates */
|
/* Convert Cocoa window coordinate to Cocoa screen coordinate */
|
||||||
CGDisplayMoveCursorToPoint(display_id, p);
|
static void QZ_PrivateLocalToGlobal (_THIS, NSPoint *p) {
|
||||||
else {
|
|
||||||
/* Convert to absolute screen coordinates */
|
*p = [ qz_window convertBaseToScreen:*p ];
|
||||||
NSPoint base, screen;
|
}
|
||||||
base = NSMakePoint (p.x, p.y);
|
|
||||||
screen = [ qz_window convertBaseToScreen:base ];
|
/* Convert SDL coordinate to Cocoa coordinate */
|
||||||
p.x = screen.x;
|
static void QZ_PrivateSDLToCocoa (_THIS, NSPoint *p) {
|
||||||
p.y = device_height - screen.y;
|
|
||||||
CGDisplayMoveCursorToPoint (display_id, p);
|
int height;
|
||||||
|
|
||||||
|
if ( CGDisplayIsCaptured (display_id) ) { /* capture signals fullscreen */
|
||||||
|
|
||||||
|
height = CGDisplayPixelsHigh (display_id);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
height = NSHeight ( [ qz_window frame ] );
|
||||||
|
if ( [ qz_window styleMask ] & NSTitledWindowMask ) {
|
||||||
|
|
||||||
|
height -= 22;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p->y = height - p->y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert Cocoa coordinate to SDL coordinate */
|
||||||
|
static void QZ_PrivateCocoaToSDL (_THIS, NSPoint *p) {
|
||||||
|
|
||||||
|
QZ_PrivateSDLToCocoa (this, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert SDL coordinate to window server (CoreGraphics) coordinate */
|
||||||
|
static CGPoint QZ_PrivateSDLToCG (_THIS, NSPoint *p) {
|
||||||
|
|
||||||
|
CGPoint cgp;
|
||||||
|
|
||||||
|
if ( ! CGDisplayIsCaptured (display_id) ) { /* not captured => not fullscreen => local coord */
|
||||||
|
|
||||||
|
int height;
|
||||||
|
|
||||||
|
QZ_PrivateSDLToCocoa (this, p);
|
||||||
|
QZ_PrivateLocalToGlobal (this, p);
|
||||||
|
|
||||||
|
height = CGDisplayPixelsHigh (display_id);
|
||||||
|
p->y = height - p->y;
|
||||||
|
}
|
||||||
|
|
||||||
|
cgp.x = p->x;
|
||||||
|
cgp.y = p->y;
|
||||||
|
|
||||||
|
return cgp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert window server (CoreGraphics) coordinate to SDL coordinate */
|
||||||
|
static void QZ_PrivateCGToSDL (_THIS, NSPoint *p) {
|
||||||
|
|
||||||
|
if ( ! CGDisplayIsCaptured (display_id) ) { /* not captured => not fullscreen => local coord */
|
||||||
|
|
||||||
|
int height;
|
||||||
|
|
||||||
|
/* Convert CG Global to Cocoa Global */
|
||||||
|
height = CGDisplayPixelsHigh (display_id);
|
||||||
|
p->y = height - p->y;
|
||||||
|
|
||||||
|
QZ_PrivateGlobalToLocal (this, p);
|
||||||
|
QZ_PrivateCocoaToSDL (this, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void QZ_PrivateWarpCursor (_THIS, int x, int y) {
|
||||||
|
|
||||||
|
NSPoint p;
|
||||||
|
CGPoint cgp;
|
||||||
|
|
||||||
|
p = NSMakePoint (x, y);
|
||||||
|
cgp = QZ_PrivateSDLToCG (this, &p);
|
||||||
|
CGDisplayMoveCursorToPoint (display_id, cgp);
|
||||||
|
warp_ticks = SDL_GetTicks();
|
||||||
|
warp_flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y) {
|
static void QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y) {
|
||||||
|
@ -116,11 +192,7 @@ static void QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Do the actual warp */
|
/* Do the actual warp */
|
||||||
QZ_PrivateWarpCursor (this, SDL_VideoSurface->flags & SDL_FULLSCREEN,
|
QZ_PrivateWarpCursor (this, x, y);
|
||||||
SDL_VideoSurface->h, x, y);
|
|
||||||
|
|
||||||
/* Generate mouse moved event */
|
|
||||||
SDL_PrivateMouseMotion (SDL_RELEASED, 0, x, y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void QZ_MoveWMCursor (_THIS, int x, int y) { }
|
static void QZ_MoveWMCursor (_THIS, int x, int y) { }
|
||||||
|
@ -199,6 +271,17 @@ static int QZ_IconifyWindow (_THIS) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static int QZ_IconifyWindow (_THIS) {
|
||||||
|
|
||||||
|
if ( ! [ qz_window isMiniaturized ] ) {
|
||||||
|
[ qz_window miniaturize:nil ];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_SetError ("Quartz window already iconified");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info) {
|
static int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info) {
|
||||||
|
@ -221,6 +304,7 @@ static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode) {
|
||||||
currentGrabMode = SDL_GRAB_ON;
|
currentGrabMode = SDL_GRAB_ON;
|
||||||
break;
|
break;
|
||||||
case SDL_GRAB_FULLSCREEN:
|
case SDL_GRAB_FULLSCREEN:
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,71 @@
|
||||||
- (void)display;
|
- (void)display;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
Uint32 rowPixels;
|
||||||
|
Uint32 width, height;
|
||||||
|
Uint32 bpp;
|
||||||
|
PixMapHandle pixMap;
|
||||||
|
Rect bounds;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
pixMap = GetPortPixMap ( port );
|
||||||
|
bpp = GetPixDepth ( pixMap );
|
||||||
|
|
||||||
|
if (bpp == 32) {
|
||||||
|
|
||||||
|
GetPortBounds ( port, &bounds );
|
||||||
|
width = bounds.right - bounds.left;
|
||||||
|
height = bounds.bottom - bounds.top;
|
||||||
|
|
||||||
|
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++) {
|
||||||
|
|
||||||
|
pixels[ (i * rowPixels) + j ] |= 0xFF000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnlockPortBits (port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@implementation SDL_QuartzWindow
|
@implementation SDL_QuartzWindow
|
||||||
|
|
||||||
/* These methods should be rewritten to fix the miniaturize bug */
|
/* 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) {
|
||||||
|
|
||||||
|
/* Grab framebuffer and put into NSImage */
|
||||||
|
/* [ qz_window setMiniwindowImage:image ]; */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
QZ_SetPortAlphaOpaque ([ [ self contentView ] qdPort ],
|
||||||
|
[ self styleMask ] & NSBorderlessWindowMask);
|
||||||
|
}
|
||||||
|
|
||||||
[ super miniaturize:sender ];
|
[ super miniaturize:sender ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* this routine fires *after* deminiaturizing, so it might be useless to us */
|
||||||
- (void)deminiaturize:(id)sender
|
- (void)deminiaturize:(id)sender
|
||||||
{
|
{
|
||||||
[ super deminiaturize:sender ];
|
[ super deminiaturize:sender ];
|
||||||
|
@ -38,4 +95,14 @@
|
||||||
SDL_PrivateQuit();
|
SDL_PrivateQuit();
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/* empty class; probably could be used to fix bugs in the future */
|
||||||
|
@interface SDL_QuartzWindowView : NSQuickDrawView
|
||||||
|
{}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation SDL_QuartzWindowView
|
||||||
|
|
||||||
@end
|
@end
|
Loading…
Add table
Add a link
Reference in a new issue