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);
|
||||
}
|
||||
}
|
||||
|
||||
if (getenv ("SDL_ENABLEAPPEVENTS"))
|
||||
[ NSApp sendEvent:event ];
|
||||
}
|
||||
|
||||
static void QZ_DoModifiers (_THIS, unsigned int newMods) {
|
||||
|
@ -464,7 +467,7 @@ static void QZ_PumpEvents (_THIS)
|
|||
|
||||
type = [ event type ];
|
||||
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) {
|
||||
case NSLeftMouseDown:
|
||||
if ( getenv("SDL_HAS3BUTTONMOUSE") ) {
|
||||
|
|
|
@ -396,7 +396,6 @@ static void QZ_UnsetVideoMode (_THIS) {
|
|||
CGDisplaySwitchToMode (display_id, save_mode);
|
||||
CGReleaseAllDisplays ();
|
||||
ShowMenuBar ();
|
||||
|
||||
/*
|
||||
Reset the main screen's rectangle
|
||||
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) {
|
||||
unsigned int style;
|
||||
NSRect contentRect;
|
||||
BOOL isCustom = NO;
|
||||
int center_window = 1;
|
||||
int origin_x, origin_y;
|
||||
|
||||
|
@ -602,7 +602,41 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
|
|||
(mode_flags & SDL_OPENGL) ||
|
||||
(flags & SDL_OPENGL) )
|
||||
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 */
|
||||
if (qz_window == nil) {
|
||||
|
||||
|
@ -650,8 +684,10 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
|
|||
/* We already have a window, just change its size */
|
||||
else {
|
||||
|
||||
[ qz_window setContentSize:contentRect.size ];
|
||||
current->flags |= (SDL_NOFRAME|SDL_RESIZABLE) & mode_flags;
|
||||
if (!isCustom) {
|
||||
[ qz_window setContentSize:contentRect.size ];
|
||||
current->flags |= (SDL_NOFRAME|SDL_RESIZABLE) & mode_flags;
|
||||
}
|
||||
}
|
||||
|
||||
/* For OpenGL, we bind the context to a subview */
|
||||
|
@ -692,9 +728,18 @@ static SDL_Surface* QZ_SetVideoWindowed (_THIS, SDL_Surface *current, int width,
|
|||
current->flags |= SDL_PREALLOC;
|
||||
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->LockHWSurface = QZ_LockWindow;
|
||||
this->UnlockHWSurface = QZ_UnlockWindow;
|
||||
|
|
|
@ -119,28 +119,35 @@ static void QZ_PrivateLocalToGlobal (_THIS, NSPoint *p) {
|
|||
/* Convert SDL coordinate to Cocoa coordinate */
|
||||
static void QZ_PrivateSDLToCocoa (_THIS, NSPoint *p) {
|
||||
|
||||
int height;
|
||||
|
||||
if ( CGDisplayIsCaptured (display_id) ) { /* capture signals fullscreen */
|
||||
|
||||
height = CGDisplayPixelsHigh (display_id);
|
||||
p->y = CGDisplayPixelsHigh (display_id) - p->y - 1;
|
||||
}
|
||||
else {
|
||||
|
||||
height = NSHeight ( [ qz_window frame ] );
|
||||
if ( [ qz_window styleMask ] & NSTitledWindowMask ) {
|
||||
NSPoint newPoint;
|
||||
|
||||
height -= 22;
|
||||
}
|
||||
newPoint = [ window_view convertPoint:*p toView:[ qz_window contentView ] ];
|
||||
|
||||
*p = newPoint;
|
||||
}
|
||||
|
||||
p->y = height - p->y - 1;
|
||||
}
|
||||
|
||||
/* Convert Cocoa coordinate to SDL coordinate */
|
||||
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 */
|
||||
|
@ -165,6 +172,7 @@ static CGPoint QZ_PrivateSDLToCG (_THIS, NSPoint *p) {
|
|||
return cgp;
|
||||
}
|
||||
|
||||
#if 0 /* Dead code */
|
||||
/* Convert window server (CoreGraphics) coordinate to SDL coordinate */
|
||||
static void QZ_PrivateCGToSDL (_THIS, NSPoint *p) {
|
||||
|
||||
|
@ -180,6 +188,7 @@ static void QZ_PrivateCGToSDL (_THIS, NSPoint *p) {
|
|||
QZ_PrivateCocoaToSDL (this, p);
|
||||
}
|
||||
}
|
||||
#endif /* Dead code */
|
||||
|
||||
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);
|
||||
cgp = QZ_PrivateSDLToCG (this, &p);
|
||||
QZ_PrivateCGToSDL (this, &p);
|
||||
|
||||
/* this is the magic call that fixes cursor "freezing" after warp */
|
||||
CGSetLocalEventsSuppressionInterval (0.0);
|
||||
|
|
|
@ -32,6 +32,7 @@ static void QZ_SetPortAlphaOpaque () {
|
|||
- (void)display;
|
||||
- (void)setFrame:(NSRect)frameRect display:(BOOL)flag;
|
||||
- (void)appDidHide:(NSNotification*)note;
|
||||
- (void)appWillUnhide:(NSNotification*)note;
|
||||
- (void)appDidUnhide:(NSNotification*)note;
|
||||
- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag;
|
||||
@end
|
||||
|
@ -63,13 +64,27 @@ static void QZ_SetPortAlphaOpaque () {
|
|||
- (void)display
|
||||
{
|
||||
/*
|
||||
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.
|
||||
This method fires just before the window deminaturizes from the Dock.
|
||||
|
||||
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 ();
|
||||
|
||||
|
||||
/* 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 */
|
||||
SDL_PrivateAppActive (1, SDL_APPACTIVE);
|
||||
}
|
||||
|
@ -81,30 +96,45 @@ static void QZ_SetPortAlphaOpaque () {
|
|||
If the video surface is NULL, this originated from QZ_SetVideoMode,
|
||||
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 ];
|
||||
}
|
||||
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 ];
|
||||
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 ( ! 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->pitch = GetPixRowBytes ( GetPortPixMap ( [ window_view qdPort ] ) );
|
||||
SDL_VideoSurface->pixels = GetPixBaseAddr ( GetPortPixMap ( thePort ) );
|
||||
SDL_VideoSurface->pitch = GetPixRowBytes ( GetPortPixMap ( thePort ) );
|
||||
|
||||
/*
|
||||
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;
|
||||
|
||||
int hOffset = newViewFrame.origin.x;
|
||||
|
||||
SDL_VideoSurface->pixels += (vOffset * SDL_VideoSurface->pitch) + hOffset * (device_bpp/8);
|
||||
}
|
||||
|
||||
SDL_VideoSurface->pixels += ((int)[ self frame ].size.height - (int)sdlRect.size.height) * SDL_VideoSurface->pitch;
|
||||
|
||||
UnlockPortBits ( [ window_view qdPort ] );
|
||||
UnlockPortBits ( thePort );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,8 +144,28 @@ static void QZ_SetPortAlphaOpaque () {
|
|||
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
|
||||
{
|
||||
/* restore cached image, since it may not be current, post expose event too */
|
||||
[ self restoreCachedImage ];
|
||||
|
||||
//SDL_PrivateExpose ();
|
||||
|
||||
SDL_PrivateAppActive (1, SDL_APPACTIVE);
|
||||
}
|
||||
|
||||
|
@ -127,6 +177,9 @@ static void QZ_SetPortAlphaOpaque () {
|
|||
|
||||
[ [ NSNotificationCenter defaultCenter ] addObserver:self
|
||||
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 ];
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue