src/video/quartz/SDL_QuartzWindow.m
author Sam Lantinga <slouken@libsdl.org>
Thu, 29 May 2003 04:52:36 +0000
changeset 631 52864d66d168
parent 501 74262d2647ca
child 683 5d2f027b3349
permissions -rw-r--r--
Date: Mon, 5 May 2003 00:08:51 -0400 From: Darrell Walisser Subject: SDL Active Events Patch Hi Guys, I was reading sdl-devel the other day and remembered we don't handle SDL_APPACTIVE and SDL_APPMOUSEFOCUS. I hacked together a quick patch to do just this. One thing to note - there are actually two ways to "iconify" the SDL window (which sets SDL_APPACTIVE): hiding the entire application (for example, option-click on some other window) and minimizing the window to the dock. I treat both as SDL_APPACTIVE, since the window is no longer visible. Cheers, Darrell


/*
    This function makes the *SDL region* of the window 100% opaque. 
    The genie effect uses the alpha component. Otherwise,
    it doesn't seem to matter what value it has.
*/
static void QZ_SetPortAlphaOpaque () {
    
    SDL_Surface *surface = current_video->screen;
    int bpp;
    
    bpp = surface->format->BitsPerPixel;
    
    if (bpp == 32) {
    
        Uint32    *pixels = (Uint32*) surface->pixels;
        Uint32    rowPixels = surface->pitch / 4;
        Uint32    i, j;
        
        for (i = 0; i < surface->h; i++)
            for (j = 0; j < surface->w; j++) {
        
                pixels[ (i * rowPixels) + j ] |= 0xFF000000;
            }
    }
}

/* Subclass of NSWindow to fix genie effect and support resize events  */
@interface SDL_QuartzWindow : NSWindow
{}
- (void)miniaturize:(id)sender;
- (void)display;
- (void)setFrame:(NSRect)frameRect display:(BOOL)flag;
- (void)appDidHide:(NSNotification*)note;
- (void)appDidUnhide:(NSNotification*)note;
- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag;
@end

@implementation SDL_QuartzWindow

/* we override these methods to fix the miniaturize animation/dock icon bug */
- (void)miniaturize:(id)sender
{
    if (SDL_VideoSurface->flags & SDL_OPENGL) {
    
        /* 
            Future: Grab framebuffer and put into NSImage
            [ qz_window setMiniwindowImage:image ];
        */
    }
    else {
        
        /* make the alpha channel opaque so anim won't have holes in it */
        QZ_SetPortAlphaOpaque ();
    }
    
    /* window is hidden now */
    SDL_PrivateAppActive (0, SDL_APPACTIVE);
    
    [ super miniaturize:sender ];
}

- (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.
    */
    if ( (SDL_VideoSurface->flags & SDL_OPENGL) == 0)
        QZ_SetPortAlphaOpaque ();

    /* window is visible again */
    SDL_PrivateAppActive (1, SDL_APPACTIVE);
}

- (void)setFrame:(NSRect)frameRect display:(BOOL)flag
{

    /*
        If the video surface is NULL, this originated from QZ_SetVideoMode,
        so don't send the resize event. 
    */
    if (SDL_VideoSurface == NULL) {

        [ super setFrame:frameRect display:flag ];
    }
    else {

        SDL_VideoDevice *this = (SDL_VideoDevice*)current_video;
        
        NSRect sdlRect = [ NSWindow contentRectForFrameRect:frameRect styleMask:[self styleMask] ];

        [ super setFrame:frameRect display:flag ];
        SDL_PrivateResize (sdlRect.size.width, sdlRect.size.height);

        /* If not OpenGL, we have to update the pixels and pitch */
        if ( ! this->screen->flags & SDL_OPENGL ) {
            
            LockPortBits ( [ window_view qdPort ] );
            
            SDL_VideoSurface->pixels = GetPixBaseAddr ( GetPortPixMap ( [ window_view qdPort ] ) );
            SDL_VideoSurface->pitch  = GetPixRowBytes ( GetPortPixMap ( [ window_view qdPort ] ) );
            
            SDL_VideoSurface->pixels += ((int)[ self frame ].size.height - (int)sdlRect.size.height) * SDL_VideoSurface->pitch;
    
            UnlockPortBits ( [ window_view qdPort ] );
        }
    }
}

- (void)appDidHide:(NSNotification*)note
{
    SDL_PrivateAppActive (0, SDL_APPACTIVE);
}

- (void)appDidUnhide:(NSNotification*)note
{
    SDL_PrivateAppActive (1, SDL_APPACTIVE);
}

- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag
{
    /* Make our window subclass receive these application notifications */
    [ [ NSNotificationCenter defaultCenter ] addObserver:self
        selector:@selector(appDidHide:) name:NSApplicationDidHideNotification object:NSApp ];
    
    [ [ NSNotificationCenter defaultCenter ] addObserver:self
        selector:@selector(appDidUnhide:) name:NSApplicationDidUnhideNotification object:NSApp ];
        
    return [ super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag ];
}

@end

/* Delegate for our NSWindow to send SDLQuit() on close */
@interface SDL_QuartzWindowDelegate : NSObject
{}
- (BOOL)windowShouldClose:(id)sender;
@end

@implementation SDL_QuartzWindowDelegate
- (BOOL)windowShouldClose:(id)sender
{
    SDL_PrivateQuit();
    return NO;
}
@end

/* Subclass of NSQuickDrawView for the window's subview */
@interface SDL_QuartzWindowView : NSQuickDrawView
{}
@end

@implementation SDL_QuartzWindowView
@end