Commit f6e2eb27 authored by Sam Lantinga's avatar Sam Lantinga

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
parent 518fbbf6
...@@ -251,6 +251,9 @@ static void QZ_DoKey (_THIS, int state, NSEvent *event) { ...@@ -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) ...@@ -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) { ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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 () { ...@@ -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 () { ...@@ -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 () { ...@@ -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 sdlRect = [ NSWindow contentRectForFrameRect:frameRect styleMask:[self styleMask] ]; NSRect newViewFrame;
[ 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 ) ) {
CGrafPtr thePort = [ window_view qdPort ];
LockPortBits ( thePort );
LockPortBits ( [ window_view qdPort ] ); SDL_VideoSurface->pixels = GetPixBaseAddr ( GetPortPixMap ( thePort ) );
SDL_VideoSurface->pitch = GetPixRowBytes ( GetPortPixMap ( thePort ) );
SDL_VideoSurface->pixels = GetPixBaseAddr ( GetPortPixMap ( [ window_view qdPort ] ) ); /*
SDL_VideoSurface->pitch = GetPixRowBytes ( GetPortPixMap ( [ window_view qdPort ] ) ); 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;
SDL_VideoSurface->pixels += ((int)[ self frame ].size.height - (int)sdlRect.size.height) * SDL_VideoSurface->pitch; int hOffset = newViewFrame.origin.x;
UnlockPortBits ( [ window_view qdPort ] ); SDL_VideoSurface->pixels += (vOffset * SDL_VideoSurface->pitch) + hOffset * (device_bpp/8);
}
UnlockPortBits ( thePort );
} }
} }
} }
...@@ -114,8 +144,28 @@ static void QZ_SetPortAlphaOpaque () { ...@@ -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 () { ...@@ -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 ];
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment