Date: Sat, 9 Aug 2003 20:14:06 -0400
From: Darrell Walisser Subject: Re: Updated projects? >> Did you get a chance to look at my "Custom Cocoa" demo? I have a few >> minor patches that enable SDL/Cocoa integration, and a project >> template. > > I didn't yet, but go ahead and send me the patches. :) > I updated the patch for current CVS. There are a lot of changes, but I don't think I've broken anything. This patch also improves the behavior of window minimize/deminimize. --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40684
This commit is contained in:
parent
518fbbf676
commit
f6e2eb2782
4 changed files with 146 additions and 37 deletions
|
@ -251,6 +251,9 @@ static void QZ_DoKey (_THIS, int state, NSEvent *event) {
|
||||||
SDL_PrivateKeyboard (state, &key);
|
SDL_PrivateKeyboard (state, &key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getenv ("SDL_ENABLEAPPEVENTS"))
|
||||||
|
[ NSApp sendEvent:event ];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void QZ_DoModifiers (_THIS, unsigned int newMods) {
|
static void QZ_DoModifiers (_THIS, unsigned int newMods) {
|
||||||
|
@ -464,7 +467,7 @@ static void QZ_PumpEvents (_THIS)
|
||||||
|
|
||||||
type = [ event type ];
|
type = [ event type ];
|
||||||
isForGameWin = (qz_window == [ event window ]);
|
isForGameWin = (qz_window == [ event window ]);
|
||||||
isInGameWin = (mode_flags & SDL_FULLSCREEN) ? true : NSPointInRect([event locationInWindow], winRect);
|
isInGameWin = (mode_flags & SDL_FULLSCREEN) ? true : NSPointInRect([event locationInWindow], [ window_view frame ]);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NSLeftMouseDown:
|
case NSLeftMouseDown:
|
||||||
if ( getenv("SDL_HAS3BUTTONMOUSE") ) {
|
if ( getenv("SDL_HAS3BUTTONMOUSE") ) {
|
||||||
|
|
|
@ -396,7 +396,6 @@ static void QZ_UnsetVideoMode (_THIS) {
|
||||||
CGDisplaySwitchToMode (display_id, save_mode);
|
CGDisplaySwitchToMode (display_id, save_mode);
|
||||||
CGReleaseAllDisplays ();
|
CGReleaseAllDisplays ();
|
||||||
ShowMenuBar ();
|
ShowMenuBar ();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Reset the main screen's rectangle
|
Reset the main screen's rectangle
|
||||||
See comment in QZ_SetVideoFullscreen for why we do this
|
See comment in QZ_SetVideoFullscreen for why we do this
|
||||||
|
@ -580,6 +579,7 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
|
||||||
int height, int bpp, Uint32 flags) {
|
int height, int bpp, Uint32 flags) {
|
||||||
unsigned int style;
|
unsigned int style;
|
||||||
NSRect contentRect;
|
NSRect contentRect;
|
||||||
|
BOOL isCustom = NO;
|
||||||
int center_window = 1;
|
int center_window = 1;
|
||||||
int origin_x, origin_y;
|
int origin_x, origin_y;
|
||||||
|
|
||||||
|
@ -603,6 +603,40 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
|
||||||
(flags & SDL_OPENGL) )
|
(flags & SDL_OPENGL) )
|
||||||
QZ_UnsetVideoMode (this);
|
QZ_UnsetVideoMode (this);
|
||||||
|
|
||||||
|
/* Check for user-specified window and view */
|
||||||
|
{
|
||||||
|
char *windowPtrString = getenv ("SDL_NSWindowPointer");
|
||||||
|
char *viewPtrString = getenv ("SDL_NSQuickDrawViewPointer");
|
||||||
|
|
||||||
|
if (windowPtrString && viewPtrString) {
|
||||||
|
|
||||||
|
/* Release any previous window */
|
||||||
|
if ( qz_window ) {
|
||||||
|
[ qz_window release ];
|
||||||
|
qz_window = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
qz_window = (NSWindow*)atoi(windowPtrString);
|
||||||
|
window_view = (NSQuickDrawView*)atoi(viewPtrString);
|
||||||
|
isCustom = YES;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Retain reference to window because we
|
||||||
|
might release it in QZ_UnsetVideoMode
|
||||||
|
*/
|
||||||
|
[ qz_window retain ];
|
||||||
|
|
||||||
|
style = [ qz_window styleMask ];
|
||||||
|
/* Check resizability */
|
||||||
|
if ( style & NSResizableWindowMask )
|
||||||
|
current->flags |= SDL_RESIZABLE;
|
||||||
|
|
||||||
|
/* Check frame */
|
||||||
|
if ( style & NSBorderlessWindowMask )
|
||||||
|
current->flags |= SDL_NOFRAME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if we should recreate the window */
|
/* Check if we should recreate the window */
|
||||||
if (qz_window == nil) {
|
if (qz_window == nil) {
|
||||||
|
|
||||||
|
@ -650,9 +684,11 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
|
||||||
/* We already have a window, just change its size */
|
/* We already have a window, just change its size */
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
if (!isCustom) {
|
||||||
[ qz_window setContentSize:contentRect.size ];
|
[ qz_window setContentSize:contentRect.size ];
|
||||||
current->flags |= (SDL_NOFRAME|SDL_RESIZABLE) & mode_flags;
|
current->flags |= (SDL_NOFRAME|SDL_RESIZABLE) & mode_flags;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* For OpenGL, we bind the context to a subview */
|
/* For OpenGL, we bind the context to a subview */
|
||||||
if ( flags & SDL_OPENGL ) {
|
if ( flags & SDL_OPENGL ) {
|
||||||
|
@ -692,9 +728,18 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
|
||||||
current->flags |= SDL_PREALLOC;
|
current->flags |= SDL_PREALLOC;
|
||||||
current->flags |= SDL_ASYNCBLIT;
|
current->flags |= SDL_ASYNCBLIT;
|
||||||
|
|
||||||
/* Offset below the title bar to fill the full content region */
|
/*
|
||||||
current->pixels += ((int)([ qz_window frame ].size.height) - height) * current->pitch;
|
current->pixels now points to the window's pixels
|
||||||
|
We want it to point to the *view's* pixels
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int vOffset = [ qz_window frame ].size.height -
|
||||||
|
[ window_view frame ].size.height - [ window_view frame ].origin.y;
|
||||||
|
|
||||||
|
int hOffset = [ window_view frame ].origin.x;
|
||||||
|
|
||||||
|
current->pixels += (vOffset * current->pitch) + hOffset * (device_bpp/8);
|
||||||
|
}
|
||||||
this->UpdateRects = QZ_UpdateRects;
|
this->UpdateRects = QZ_UpdateRects;
|
||||||
this->LockHWSurface = QZ_LockWindow;
|
this->LockHWSurface = QZ_LockWindow;
|
||||||
this->UnlockHWSurface = QZ_UnlockWindow;
|
this->UnlockHWSurface = QZ_UnlockWindow;
|
||||||
|
|
|
@ -119,28 +119,35 @@ static void QZ_PrivateLocalToGlobal (_THIS, NSPoint *p) {
|
||||||
/* Convert SDL coordinate to Cocoa coordinate */
|
/* Convert SDL coordinate to Cocoa coordinate */
|
||||||
static void QZ_PrivateSDLToCocoa (_THIS, NSPoint *p) {
|
static void QZ_PrivateSDLToCocoa (_THIS, NSPoint *p) {
|
||||||
|
|
||||||
int height;
|
|
||||||
|
|
||||||
if ( CGDisplayIsCaptured (display_id) ) { /* capture signals fullscreen */
|
if ( CGDisplayIsCaptured (display_id) ) { /* capture signals fullscreen */
|
||||||
|
|
||||||
height = CGDisplayPixelsHigh (display_id);
|
p->y = CGDisplayPixelsHigh (display_id) - p->y - 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
height = NSHeight ( [ qz_window frame ] );
|
NSPoint newPoint;
|
||||||
if ( [ qz_window styleMask ] & NSTitledWindowMask ) {
|
|
||||||
|
|
||||||
height -= 22;
|
newPoint = [ window_view convertPoint:*p toView:[ qz_window contentView ] ];
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p->y = height - p->y - 1;
|
*p = newPoint;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert Cocoa coordinate to SDL coordinate */
|
/* Convert Cocoa coordinate to SDL coordinate */
|
||||||
static void QZ_PrivateCocoaToSDL (_THIS, NSPoint *p) {
|
static void QZ_PrivateCocoaToSDL (_THIS, NSPoint *p) {
|
||||||
|
|
||||||
QZ_PrivateSDLToCocoa (this, p);
|
if ( CGDisplayIsCaptured (display_id) ) { /* capture signals fullscreen */
|
||||||
|
|
||||||
|
p->y = CGDisplayPixelsHigh (display_id) - p->y - 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
NSPoint newPoint;
|
||||||
|
|
||||||
|
newPoint = [ window_view convertPoint:*p fromView:[ qz_window contentView ] ];
|
||||||
|
|
||||||
|
*p = newPoint;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert SDL coordinate to window server (CoreGraphics) coordinate */
|
/* Convert SDL coordinate to window server (CoreGraphics) coordinate */
|
||||||
|
@ -165,6 +172,7 @@ static CGPoint QZ_PrivateSDLToCG (_THIS, NSPoint *p) {
|
||||||
return cgp;
|
return cgp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 /* Dead code */
|
||||||
/* Convert window server (CoreGraphics) coordinate to SDL coordinate */
|
/* Convert window server (CoreGraphics) coordinate to SDL coordinate */
|
||||||
static void QZ_PrivateCGToSDL (_THIS, NSPoint *p) {
|
static void QZ_PrivateCGToSDL (_THIS, NSPoint *p) {
|
||||||
|
|
||||||
|
@ -180,6 +188,7 @@ static void QZ_PrivateCGToSDL (_THIS, NSPoint *p) {
|
||||||
QZ_PrivateCocoaToSDL (this, p);
|
QZ_PrivateCocoaToSDL (this, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* Dead code */
|
||||||
|
|
||||||
static void QZ_PrivateWarpCursor (_THIS, int x, int y) {
|
static void QZ_PrivateWarpCursor (_THIS, int x, int y) {
|
||||||
|
|
||||||
|
@ -188,7 +197,6 @@ static void QZ_PrivateWarpCursor (_THIS, int x, int y) {
|
||||||
|
|
||||||
p = NSMakePoint (x, y);
|
p = NSMakePoint (x, y);
|
||||||
cgp = QZ_PrivateSDLToCG (this, &p);
|
cgp = QZ_PrivateSDLToCG (this, &p);
|
||||||
QZ_PrivateCGToSDL (this, &p);
|
|
||||||
|
|
||||||
/* this is the magic call that fixes cursor "freezing" after warp */
|
/* this is the magic call that fixes cursor "freezing" after warp */
|
||||||
CGSetLocalEventsSuppressionInterval (0.0);
|
CGSetLocalEventsSuppressionInterval (0.0);
|
||||||
|
|
|
@ -32,6 +32,7 @@ static void QZ_SetPortAlphaOpaque () {
|
||||||
- (void)display;
|
- (void)display;
|
||||||
- (void)setFrame:(NSRect)frameRect display:(BOOL)flag;
|
- (void)setFrame:(NSRect)frameRect display:(BOOL)flag;
|
||||||
- (void)appDidHide:(NSNotification*)note;
|
- (void)appDidHide:(NSNotification*)note;
|
||||||
|
- (void)appWillUnhide:(NSNotification*)note;
|
||||||
- (void)appDidUnhide:(NSNotification*)note;
|
- (void)appDidUnhide:(NSNotification*)note;
|
||||||
- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag;
|
- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag;
|
||||||
@end
|
@end
|
||||||
|
@ -63,13 +64,27 @@ static void QZ_SetPortAlphaOpaque () {
|
||||||
- (void)display
|
- (void)display
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
This method fires just before the window deminaturizes.
|
This method fires just before the window deminaturizes from the Dock.
|
||||||
So, it's just the right place to fixup the alpha channel - which
|
|
||||||
makes the deminiaturize animation look right.
|
We'll save the current visible surface, let the window manager redraw any
|
||||||
|
UI elements, and restore the SDL surface. This way, no expose event
|
||||||
|
is required, and the deminiaturize works perfectly.
|
||||||
*/
|
*/
|
||||||
if ( (SDL_VideoSurface->flags & SDL_OPENGL) == 0)
|
SDL_VideoDevice *this = (SDL_VideoDevice*)current_video;
|
||||||
|
|
||||||
|
/* make sure pixels are fully opaque */
|
||||||
|
if (! ( SDL_VideoSurface->flags & SDL_OPENGL ) )
|
||||||
QZ_SetPortAlphaOpaque ();
|
QZ_SetPortAlphaOpaque ();
|
||||||
|
|
||||||
|
/* save current visible SDL surface */
|
||||||
|
[ self cacheImageInRect:[ window_view frame ] ];
|
||||||
|
|
||||||
|
/* let the window manager redraw controls, border, etc */
|
||||||
|
[ super display ];
|
||||||
|
|
||||||
|
/* restore visible SDL surface */
|
||||||
|
[ self restoreCachedImage ];
|
||||||
|
|
||||||
/* window is visible again */
|
/* window is visible again */
|
||||||
SDL_PrivateAppActive (1, SDL_APPACTIVE);
|
SDL_PrivateAppActive (1, SDL_APPACTIVE);
|
||||||
}
|
}
|
||||||
|
@ -81,30 +96,45 @@ static void QZ_SetPortAlphaOpaque () {
|
||||||
If the video surface is NULL, this originated from QZ_SetVideoMode,
|
If the video surface is NULL, this originated from QZ_SetVideoMode,
|
||||||
so don't send the resize event.
|
so don't send the resize event.
|
||||||
*/
|
*/
|
||||||
if (SDL_VideoSurface == NULL) {
|
SDL_VideoDevice *this = (SDL_VideoDevice*)current_video;
|
||||||
|
|
||||||
|
if (this && SDL_VideoSurface == NULL) {
|
||||||
|
|
||||||
[ super setFrame:frameRect display:flag ];
|
[ super setFrame:frameRect display:flag ];
|
||||||
}
|
}
|
||||||
else {
|
else if (this && qz_window) {
|
||||||
|
|
||||||
SDL_VideoDevice *this = (SDL_VideoDevice*)current_video;
|
NSRect newViewFrame;
|
||||||
|
|
||||||
NSRect sdlRect = [ NSWindow contentRectForFrameRect:frameRect styleMask:[self styleMask] ];
|
|
||||||
|
|
||||||
[ super setFrame:frameRect display:flag ];
|
[ super setFrame:frameRect display:flag ];
|
||||||
SDL_PrivateResize (sdlRect.size.width, sdlRect.size.height);
|
|
||||||
|
newViewFrame = [ window_view frame ];
|
||||||
|
|
||||||
|
SDL_PrivateResize (newViewFrame.size.width, newViewFrame.size.height);
|
||||||
|
|
||||||
/* If not OpenGL, we have to update the pixels and pitch */
|
/* If not OpenGL, we have to update the pixels and pitch */
|
||||||
if ( ! this->screen->flags & SDL_OPENGL ) {
|
if ( ! ( SDL_VideoSurface->flags & SDL_OPENGL ) ) {
|
||||||
|
|
||||||
LockPortBits ( [ window_view qdPort ] );
|
CGrafPtr thePort = [ window_view qdPort ];
|
||||||
|
LockPortBits ( thePort );
|
||||||
|
|
||||||
SDL_VideoSurface->pixels = GetPixBaseAddr ( GetPortPixMap ( [ window_view qdPort ] ) );
|
SDL_VideoSurface->pixels = GetPixBaseAddr ( GetPortPixMap ( thePort ) );
|
||||||
SDL_VideoSurface->pitch = GetPixRowBytes ( GetPortPixMap ( [ window_view qdPort ] ) );
|
SDL_VideoSurface->pitch = GetPixRowBytes ( GetPortPixMap ( thePort ) );
|
||||||
|
|
||||||
SDL_VideoSurface->pixels += ((int)[ self frame ].size.height - (int)sdlRect.size.height) * SDL_VideoSurface->pitch;
|
/*
|
||||||
|
SDL_VideoSurface->pixels now points to the window's pixels
|
||||||
|
We want it to point to the *view's* pixels
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int vOffset = [ qz_window frame ].size.height -
|
||||||
|
newViewFrame.size.height - newViewFrame.origin.y;
|
||||||
|
|
||||||
UnlockPortBits ( [ window_view qdPort ] );
|
int hOffset = newViewFrame.origin.x;
|
||||||
|
|
||||||
|
SDL_VideoSurface->pixels += (vOffset * SDL_VideoSurface->pitch) + hOffset * (device_bpp/8);
|
||||||
|
}
|
||||||
|
|
||||||
|
UnlockPortBits ( thePort );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,8 +144,28 @@ static void QZ_SetPortAlphaOpaque () {
|
||||||
SDL_PrivateAppActive (0, SDL_APPACTIVE);
|
SDL_PrivateAppActive (0, SDL_APPACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)appWillUnhide:(NSNotification*)note
|
||||||
|
{
|
||||||
|
SDL_VideoDevice *this = (SDL_VideoDevice*)current_video;
|
||||||
|
|
||||||
|
if ( this ) {
|
||||||
|
|
||||||
|
/* make sure pixels are fully opaque */
|
||||||
|
if (! ( SDL_VideoSurface->flags & SDL_OPENGL ) )
|
||||||
|
QZ_SetPortAlphaOpaque ();
|
||||||
|
|
||||||
|
/* save current visible SDL surface */
|
||||||
|
[ self cacheImageInRect:[ window_view frame ] ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)appDidUnhide:(NSNotification*)note
|
- (void)appDidUnhide:(NSNotification*)note
|
||||||
{
|
{
|
||||||
|
/* restore cached image, since it may not be current, post expose event too */
|
||||||
|
[ self restoreCachedImage ];
|
||||||
|
|
||||||
|
//SDL_PrivateExpose ();
|
||||||
|
|
||||||
SDL_PrivateAppActive (1, SDL_APPACTIVE);
|
SDL_PrivateAppActive (1, SDL_APPACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,6 +178,9 @@ static void QZ_SetPortAlphaOpaque () {
|
||||||
[ [ NSNotificationCenter defaultCenter ] addObserver:self
|
[ [ NSNotificationCenter defaultCenter ] addObserver:self
|
||||||
selector:@selector(appDidUnhide:) name:NSApplicationDidUnhideNotification object:NSApp ];
|
selector:@selector(appDidUnhide:) name:NSApplicationDidUnhideNotification object:NSApp ];
|
||||||
|
|
||||||
|
[ [ NSNotificationCenter defaultCenter ] addObserver:self
|
||||||
|
selector:@selector(appWillUnhide:) name:NSApplicationWillUnhideNotification object:NSApp ];
|
||||||
|
|
||||||
return [ super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag ];
|
return [ super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue