/*
 * MACDRV Cocoa window code
 *
 * Copyright 2011, 2012, 2013 Ken Thomases for CodeWeavers Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#import <Carbon/Carbon.h>
#import <CoreVideo/CoreVideo.h>

#import "cocoa_window.h"

#include "macdrv_cocoa.h"
#import "cocoa_app.h"
#import "cocoa_event.h"
#import "cocoa_opengl.h"


#if !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
enum {
    NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7,
    NSWindowCollectionBehaviorFullScreenAuxiliary = 1 << 8,
    NSWindowFullScreenButton = 7,
    NSFullScreenWindowMask = 1 << 14,
};

@interface NSWindow (WineFullScreenExtensions)
    - (void) toggleFullScreen:(id)sender;
@end
#endif


/* Additional Mac virtual keycode, to complement those in Carbon's <HIToolbox/Events.h>. */
enum {
    kVK_RightCommand              = 0x36, /* Invented for Wine; was unused */
};


static NSUInteger style_mask_for_features(const struct macdrv_window_features* wf)
{
    NSUInteger style_mask;

    if (wf->title_bar)
    {
        style_mask = NSTitledWindowMask;
        if (wf->close_button) style_mask |= NSClosableWindowMask;
        if (wf->minimize_button) style_mask |= NSMiniaturizableWindowMask;
        if (wf->resizable || wf->maximize_button) style_mask |= NSResizableWindowMask;
        if (wf->utility) style_mask |= NSUtilityWindowMask;
    }
    else style_mask = NSBorderlessWindowMask;

    return style_mask;
}


static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
{
    NSScreen* screen;
    for (screen in screens)
    {
        if (NSIntersectsRect(frame, [screen frame]))
            return TRUE;
    }
    return FALSE;
}


static NSScreen* screen_covered_by_rect(NSRect rect, NSArray* screens)
{
    for (NSScreen* screen in screens)
    {
        if (NSContainsRect(rect, [screen frame]))
            return screen;
    }
    return nil;
}


/* We rely on the supposedly device-dependent modifier flags to distinguish the
   keys on the left side of the keyboard from those on the right.  Some event
   sources don't set those device-depdendent flags.  If we see a device-independent
   flag for a modifier without either corresponding device-dependent flag, assume
   the left one. */
static inline void fix_device_modifiers_by_generic(NSUInteger* modifiers)
{
    if ((*modifiers & (NX_COMMANDMASK | NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK)) == NX_COMMANDMASK)
        *modifiers |= NX_DEVICELCMDKEYMASK;
    if ((*modifiers & (NX_SHIFTMASK | NX_DEVICELSHIFTKEYMASK | NX_DEVICERSHIFTKEYMASK)) == NX_SHIFTMASK)
        *modifiers |= NX_DEVICELSHIFTKEYMASK;
    if ((*modifiers & (NX_CONTROLMASK | NX_DEVICELCTLKEYMASK | NX_DEVICERCTLKEYMASK)) == NX_CONTROLMASK)
        *modifiers |= NX_DEVICELCTLKEYMASK;
    if ((*modifiers & (NX_ALTERNATEMASK | NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK)) == NX_ALTERNATEMASK)
        *modifiers |= NX_DEVICELALTKEYMASK;
}

/* As we manipulate individual bits of a modifier mask, we can end up with
   inconsistent sets of flags.  In particular, we might set or clear one of the
   left/right-specific bits, but not the corresponding non-side-specific bit.
   Fix that.  If either side-specific bit is set, set the non-side-specific bit,
   otherwise clear it. */
static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
{
    if (*modifiers & (NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK))
        *modifiers |= NX_COMMANDMASK;
    else
        *modifiers &= ~NX_COMMANDMASK;
    if (*modifiers & (NX_DEVICELSHIFTKEYMASK | NX_DEVICERSHIFTKEYMASK))
        *modifiers |= NX_SHIFTMASK;
    else
        *modifiers &= ~NX_SHIFTMASK;
    if (*modifiers & (NX_DEVICELCTLKEYMASK | NX_DEVICERCTLKEYMASK))
        *modifiers |= NX_CONTROLMASK;
    else
        *modifiers &= ~NX_CONTROLMASK;
    if (*modifiers & (NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK))
        *modifiers |= NX_ALTERNATEMASK;
    else
        *modifiers &= ~NX_ALTERNATEMASK;
}

static inline NSUInteger adjusted_modifiers_for_option_behavior(NSUInteger modifiers)
{
    fix_device_modifiers_by_generic(&modifiers);
    if (left_option_is_alt && (modifiers & NX_DEVICELALTKEYMASK))
    {
        modifiers |= NX_DEVICELCMDKEYMASK;
        modifiers &= ~NX_DEVICELALTKEYMASK;
    }
    if (right_option_is_alt && (modifiers & NX_DEVICERALTKEYMASK))
    {
        modifiers |= NX_DEVICERCMDKEYMASK;
        modifiers &= ~NX_DEVICERALTKEYMASK;
    }
    fix_generic_modifiers_by_device(&modifiers);

    return modifiers;
}


@interface NSWindow (WineAccessPrivateMethods)
    - (id) _displayChanged;
@end


@interface WineDisplayLink : NSObject
{
    CGDirectDisplayID _displayID;
    CVDisplayLinkRef _link;
    NSMutableSet* _windows;

    NSTimeInterval _actualRefreshPeriod;
    NSTimeInterval _nominalRefreshPeriod;
}

    - (id) initWithDisplayID:(CGDirectDisplayID)displayID;

    - (void) addWindow:(WineWindow*)window;
    - (void) removeWindow:(WineWindow*)window;

    - (NSTimeInterval) refreshPeriod;

    - (void) start;

@end

@implementation WineDisplayLink

static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* inNow, const CVTimeStamp* inOutputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext);

    - (id) initWithDisplayID:(CGDirectDisplayID)displayID
    {
        self = [super init];
        if (self)
        {
            CVReturn status = CVDisplayLinkCreateWithCGDisplay(displayID, &_link);
            if (status == kCVReturnSuccess && !_link)
                status = kCVReturnError;
            if (status == kCVReturnSuccess)
                status = CVDisplayLinkSetOutputCallback(_link, WineDisplayLinkCallback, self);
            if (status != kCVReturnSuccess)
            {
                [self release];
                return nil;
            }

            _displayID = displayID;
            _windows = [[NSMutableSet alloc] init];
        }
        return self;
    }

    - (void) dealloc
    {
        if (_link)
        {
            CVDisplayLinkStop(_link);
            CVDisplayLinkRelease(_link);
        }
        [_windows release];
        [super dealloc];
    }

    - (void) addWindow:(WineWindow*)window
    {
        @synchronized(self) {
            BOOL needsStart = !_windows.count;
            [_windows addObject:window];
            if (needsStart)
                CVDisplayLinkStart(_link);
        }
    }

    - (void) removeWindow:(WineWindow*)window
    {
        @synchronized(self) {
            BOOL wasRunning = _windows.count > 0;
            [_windows removeObject:window];
            if (wasRunning && !_windows.count)
                CVDisplayLinkStop(_link);
        }
    }

    - (void) fire
    {
        NSSet* windows;
        @synchronized(self) {
            windows = [_windows copy];
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            BOOL anyDisplayed = FALSE;
            for (WineWindow* window in windows)
            {
                if ([window viewsNeedDisplay])
                {
                    [window displayIfNeeded];
                    anyDisplayed = YES;
                }
            }
            if (!anyDisplayed)
                CVDisplayLinkStop(_link);
        });
        [windows release];
    }

    - (NSTimeInterval) refreshPeriod
    {
        if (_actualRefreshPeriod || (_actualRefreshPeriod = CVDisplayLinkGetActualOutputVideoRefreshPeriod(_link)))
            return _actualRefreshPeriod;

        if (_nominalRefreshPeriod)
            return _nominalRefreshPeriod;

        CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(_link);
        if (time.flags & kCVTimeIsIndefinite)
            return 1.0 / 60.0;
        _nominalRefreshPeriod = time.timeValue / (double)time.timeScale;
        return _nominalRefreshPeriod;
    }

    - (void) start
    {
        CVDisplayLinkStart(_link);
    }

static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* inNow, const CVTimeStamp* inOutputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
{
    WineDisplayLink* link = displayLinkContext;
    [link fire];
    return kCVReturnSuccess;
}

@end


@interface WineContentView : NSView <NSTextInputClient>
{
    NSMutableArray* glContexts;
    NSMutableArray* pendingGlContexts;
    BOOL _cachedHasGLDescendant;
    BOOL _cachedHasGLDescendantValid;
    BOOL clearedGlSurface;

    NSMutableAttributedString* markedText;
    NSRange markedTextSelection;

    int backingSize[2];
}

    - (void) addGLContext:(WineOpenGLContext*)context;
    - (void) removeGLContext:(WineOpenGLContext*)context;
    - (void) updateGLContexts;

    - (void) wine_getBackingSize:(int*)outBackingSize;
    - (void) wine_setBackingSize:(const int*)newBackingSize;

@end


@interface WineWindow ()

@property (readwrite, nonatomic) BOOL disabled;
@property (readwrite, nonatomic) BOOL noActivate;
@property (readwrite, nonatomic) BOOL floating;
@property (readwrite, getter=isFakingClose, nonatomic) BOOL fakingClose;
@property (retain, nonatomic) NSWindow* latentParentWindow;

@property (nonatomic) void* hwnd;
@property (retain, readwrite, nonatomic) WineEventQueue* queue;

@property (nonatomic) void* surface;
@property (nonatomic) pthread_mutex_t* surface_mutex;

@property (copy, nonatomic) NSBezierPath* shape;
@property (copy, nonatomic) NSData* shapeData;
@property (nonatomic) BOOL shapeChangedSinceLastDraw;
@property (readonly, nonatomic) BOOL needsTransparency;

@property (nonatomic) BOOL colorKeyed;
@property (nonatomic) CGFloat colorKeyRed, colorKeyGreen, colorKeyBlue;
@property (nonatomic) BOOL usePerPixelAlpha;

@property (assign, nonatomic) void* imeData;
@property (nonatomic) BOOL commandDone;

@property (readonly, copy, nonatomic) NSArray* childWineWindows;

    - (void) updateColorSpace;
    - (void) updateForGLSubviews;

    - (BOOL) becameEligibleParentOrChild;
    - (void) becameIneligibleChild;

@end


@implementation WineContentView

    - (void) dealloc
    {
        [markedText release];
        [glContexts release];
        [pendingGlContexts release];
        [super dealloc];
    }

    - (BOOL) isFlipped
    {
        return YES;
    }

    - (void) drawRect:(NSRect)rect
    {
        WineWindow* window = (WineWindow*)[self window];

        for (WineOpenGLContext* context in pendingGlContexts)
        {
            if (!clearedGlSurface)
            {
                context.shouldClearToBlack = TRUE;
                clearedGlSurface = TRUE;
            }
            context.needsUpdate = TRUE;
        }
        [glContexts addObjectsFromArray:pendingGlContexts];
        [pendingGlContexts removeAllObjects];

        if ([window contentView] != self)
            return;

        if (window.shapeChangedSinceLastDraw && window.shape && !window.colorKeyed && !window.usePerPixelAlpha)
        {
            [[NSColor clearColor] setFill];
            NSRectFill(rect);

            [window.shape addClip];

            [[NSColor windowBackgroundColor] setFill];
            NSRectFill(rect);
        }

        if (window.surface && window.surface_mutex &&
            !pthread_mutex_lock(window.surface_mutex))
        {
            const CGRect* rects;
            int count;

            if (get_surface_blit_rects(window.surface, &rects, &count) && count)
            {
                CGRect dirtyRect = cgrect_win_from_mac(NSRectToCGRect(rect));
                CGContextRef context;
                int i;

                [window.shape addClip];

                context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
                CGContextSetBlendMode(context, kCGBlendModeCopy);
                CGContextSetInterpolationQuality(context, retina_on ? kCGInterpolationHigh : kCGInterpolationNone);

                for (i = 0; i < count; i++)
                {
                    CGRect imageRect;
                    CGImageRef image;

                    imageRect = CGRectIntersection(rects[i], dirtyRect);
                    image = create_surface_image(window.surface, &imageRect, FALSE);

                    if (image)
                    {
                        if (window.colorKeyed)
                        {
                            CGImageRef maskedImage;
                            CGFloat components[] = { window.colorKeyRed - 0.5, window.colorKeyRed + 0.5,
                                                     window.colorKeyGreen - 0.5, window.colorKeyGreen + 0.5,
                                                     window.colorKeyBlue - 0.5, window.colorKeyBlue + 0.5 };
                            maskedImage = CGImageCreateWithMaskingColors(image, components);
                            if (maskedImage)
                            {
                                CGImageRelease(image);
                                image = maskedImage;
                            }
                        }

                        CGContextDrawImage(context, cgrect_mac_from_win(imageRect), image);

                        CGImageRelease(image);
                    }
                }
            }

            pthread_mutex_unlock(window.surface_mutex);
        }

        // If the window may be transparent, then we have to invalidate the
        // shadow every time we draw.  Also, if this is the first time we've
        // drawn since changing from transparent to opaque.
        if (window.colorKeyed || window.usePerPixelAlpha || window.shapeChangedSinceLastDraw)
        {
            window.shapeChangedSinceLastDraw = FALSE;
            [window invalidateShadow];
        }
    }

    - (void) addGLContext:(WineOpenGLContext*)context
    {
        BOOL hadContext = [self hasGLContext];
        if (!glContexts)
            glContexts = [[NSMutableArray alloc] init];
        if (!pendingGlContexts)
            pendingGlContexts = [[NSMutableArray alloc] init];

        if ([[self window] windowNumber] > 0 && !NSIsEmptyRect([self visibleRect]))
        {
            [glContexts addObject:context];
            if (!clearedGlSurface)
            {
                context.shouldClearToBlack = TRUE;
                clearedGlSurface = TRUE;
            }
            context.needsUpdate = TRUE;
        }
        else
        {
            [pendingGlContexts addObject:context];
            [self setNeedsDisplay:YES];
        }

        if (!hadContext)
            [self invalidateHasGLDescendant];
        [(WineWindow*)[self window] updateForGLSubviews];
    }

    - (void) removeGLContext:(WineOpenGLContext*)context
    {
        BOOL hadContext = [self hasGLContext];
        [glContexts removeObjectIdenticalTo:context];
        [pendingGlContexts removeObjectIdenticalTo:context];
        if (hadContext && ![self hasGLContext])
            [self invalidateHasGLDescendant];
        [(WineWindow*)[self window] updateForGLSubviews];
    }

    - (void) updateGLContexts
    {
        for (WineOpenGLContext* context in glContexts)
            context.needsUpdate = TRUE;
    }

    - (BOOL) hasGLContext
    {
        return [glContexts count] || [pendingGlContexts count];
    }

    - (BOOL) _hasGLDescendant
    {
        if ([self isHidden])
            return NO;
        if ([self hasGLContext])
            return YES;
        for (WineContentView* view in [self subviews])
        {
            if ([view hasGLDescendant])
                return YES;
        }
        return NO;
    }

    - (BOOL) hasGLDescendant
    {
        if (!_cachedHasGLDescendantValid)
        {
            _cachedHasGLDescendant = [self _hasGLDescendant];
            _cachedHasGLDescendantValid = YES;
        }
        return _cachedHasGLDescendant;
    }

    - (void) invalidateHasGLDescendant
    {
        BOOL invalidateAncestors = _cachedHasGLDescendantValid;
        _cachedHasGLDescendantValid = NO;
        if (invalidateAncestors && self != [[self window] contentView])
        {
            WineContentView* superview = (WineContentView*)[self superview];
            if ([superview isKindOfClass:[WineContentView class]])
                [superview invalidateHasGLDescendant];
        }
    }

    - (void) wine_getBackingSize:(int*)outBackingSize
    {
        @synchronized(self) {
            memcpy(outBackingSize, backingSize, sizeof(backingSize));
        }
    }
    - (void) wine_setBackingSize:(const int*)newBackingSize
    {
        @synchronized(self) {
            memcpy(backingSize, newBackingSize, sizeof(backingSize));
        }
    }

    - (void) setRetinaMode:(int)mode
    {
        double scale = mode ? 0.5 : 2.0;
        NSRect frame = self.frame;
        frame.origin.x *= scale;
        frame.origin.y *= scale;
        frame.size.width *= scale;
        frame.size.height *= scale;
        [self setFrame:frame];
        [self updateGLContexts];

        for (WineContentView* subview in [self subviews])
        {
            if ([subview isKindOfClass:[WineContentView class]])
                [subview setRetinaMode:mode];
        }
    }

    - (BOOL) acceptsFirstMouse:(NSEvent*)theEvent
    {
        return YES;
    }

    - (BOOL) preservesContentDuringLiveResize
    {
        // Returning YES from this tells Cocoa to keep our view's content during
        // a Cocoa-driven resize.  In theory, we're also supposed to override
        // -setFrameSize: to mark exposed sections as needing redisplay, but
        // user32 will take care of that in a roundabout way.  This way, we don't
        // redraw until the window surface is flushed.
        //
        // This doesn't do anything when we resize the window ourselves.
        return YES;
    }

    - (BOOL)acceptsFirstResponder
    {
        return [[self window] contentView] == self;
    }

    - (BOOL) mouseDownCanMoveWindow
    {
        return NO;
    }

    - (void) completeText:(NSString*)text
    {
        macdrv_event* event;
        WineWindow* window = (WineWindow*)[self window];

        event = macdrv_create_event(IM_SET_TEXT, window);
        event->im_set_text.data = [window imeData];
        event->im_set_text.text = (CFStringRef)[text copy];
        event->im_set_text.complete = TRUE;

        [[window queue] postEvent:event];

        macdrv_release_event(event);

        [markedText deleteCharactersInRange:NSMakeRange(0, [markedText length])];
        markedTextSelection = NSMakeRange(0, 0);
        [[self inputContext] discardMarkedText];
    }

    - (NSFocusRingType) focusRingType
    {
        return NSFocusRingTypeNone;
    }

    - (void) didAddSubview:(NSView*)subview
    {
        if ([subview isKindOfClass:[WineContentView class]])
        {
            WineContentView* view = (WineContentView*)subview;
            if (!view->_cachedHasGLDescendantValid || view->_cachedHasGLDescendant)
                [self invalidateHasGLDescendant];
        }
        [super didAddSubview:subview];
    }

    - (void) willRemoveSubview:(NSView*)subview
    {
        if ([subview isKindOfClass:[WineContentView class]])
        {
            WineContentView* view = (WineContentView*)subview;
            if (!view->_cachedHasGLDescendantValid || view->_cachedHasGLDescendant)
                [self invalidateHasGLDescendant];
        }
        [super willRemoveSubview:subview];
    }

    - (void) setHidden:(BOOL)hidden
    {
        [super setHidden:hidden];
        [self invalidateHasGLDescendant];
    }

    /*
     * ---------- NSTextInputClient methods ----------
     */
    - (NSTextInputContext*) inputContext
    {
        if (!markedText)
            markedText = [[NSMutableAttributedString alloc] init];
        return [super inputContext];
    }

    - (void) insertText:(id)string replacementRange:(NSRange)replacementRange
    {
        if ([string isKindOfClass:[NSAttributedString class]])
            string = [string string];

        if ([string isKindOfClass:[NSString class]])
            [self completeText:string];
    }

    - (void) doCommandBySelector:(SEL)aSelector
    {
        [(WineWindow*)[self window] setCommandDone:TRUE];
    }

    - (void) setMarkedText:(id)string selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
    {
        if ([string isKindOfClass:[NSAttributedString class]])
            string = [string string];

        if ([string isKindOfClass:[NSString class]])
        {
            macdrv_event* event;
            WineWindow* window = (WineWindow*)[self window];

            if (replacementRange.location == NSNotFound)
                replacementRange = NSMakeRange(0, [markedText length]);

            [markedText replaceCharactersInRange:replacementRange withString:string];
            markedTextSelection = selectedRange;
            markedTextSelection.location += replacementRange.location;

            event = macdrv_create_event(IM_SET_TEXT, window);
            event->im_set_text.data = [window imeData];
            event->im_set_text.text = (CFStringRef)[[markedText string] copy];
            event->im_set_text.complete = FALSE;
            event->im_set_text.cursor_pos = markedTextSelection.location + markedTextSelection.length;

            [[window queue] postEvent:event];

            macdrv_release_event(event);

            [[self inputContext] invalidateCharacterCoordinates];
        }
    }

    - (void) unmarkText
    {
        [self completeText:nil];
    }

    - (NSRange) selectedRange
    {
        return markedTextSelection;
    }

    - (NSRange) markedRange
    {
        NSRange range = NSMakeRange(0, [markedText length]);
        if (!range.length)
            range.location = NSNotFound;
        return range;
    }

    - (BOOL) hasMarkedText
    {
        return [markedText length] > 0;
    }

    - (NSAttributedString*) attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
    {
        if (aRange.location >= [markedText length])
            return nil;

        aRange = NSIntersectionRange(aRange, NSMakeRange(0, [markedText length]));
        if (actualRange)
            *actualRange = aRange;
        return [markedText attributedSubstringFromRange:aRange];
    }

    - (NSArray*) validAttributesForMarkedText
    {
        return [NSArray array];
    }

    - (NSRect) firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
    {
        macdrv_query* query;
        WineWindow* window = (WineWindow*)[self window];
        NSRect ret;

        aRange = NSIntersectionRange(aRange, NSMakeRange(0, [markedText length]));

        query = macdrv_create_query();
        query->type = QUERY_IME_CHAR_RECT;
        query->window = (macdrv_window)[window retain];
        query->ime_char_rect.data = [window imeData];
        query->ime_char_rect.range = CFRangeMake(aRange.location, aRange.length);

        if ([window.queue query:query timeout:0.3 flags:WineQueryNoPreemptWait])
        {
            aRange = NSMakeRange(query->ime_char_rect.range.location, query->ime_char_rect.range.length);
            ret = NSRectFromCGRect(cgrect_mac_from_win(query->ime_char_rect.rect));
            [[WineApplicationController sharedController] flipRect:&ret];
        }
        else
            ret = NSMakeRect(100, 100, aRange.length ? 1 : 0, 12);

        macdrv_release_query(query);

        if (actualRange)
            *actualRange = aRange;
        return ret;
    }

    - (NSUInteger) characterIndexForPoint:(NSPoint)aPoint
    {
        return NSNotFound;
    }

    - (NSInteger) windowLevel
    {
        return [[self window] level];
    }

@end


@implementation WineWindow

    static WineWindow* causing_becomeKeyWindow;

    @synthesize disabled, noActivate, floating, fullscreen, fakingClose, latentParentWindow, hwnd, queue;
    @synthesize surface, surface_mutex;
    @synthesize shape, shapeData, shapeChangedSinceLastDraw;
    @synthesize colorKeyed, colorKeyRed, colorKeyGreen, colorKeyBlue;
    @synthesize usePerPixelAlpha;
    @synthesize imeData, commandDone;

    + (WineWindow*) createWindowWithFeatures:(const struct macdrv_window_features*)wf
                                 windowFrame:(NSRect)window_frame
                                        hwnd:(void*)hwnd
                                       queue:(WineEventQueue*)queue
    {
        WineWindow* window;
        WineContentView* contentView;
        NSTrackingArea* trackingArea;
        NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];

        [[WineApplicationController sharedController] flipRect:&window_frame];

        window = [[[self alloc] initWithContentRect:window_frame
                                          styleMask:style_mask_for_features(wf)
                                            backing:NSBackingStoreBuffered
                                              defer:YES] autorelease];

        if (!window) return nil;

        /* Standardize windows to eliminate differences between titled and
           borderless windows and between NSWindow and NSPanel. */
        [window setHidesOnDeactivate:NO];
        [window setReleasedWhenClosed:NO];

        [window setOneShot:YES];
        [window disableCursorRects];
        [window setShowsResizeIndicator:NO];
        [window setHasShadow:wf->shadow];
        [window setAcceptsMouseMovedEvents:YES];
        [window setColorSpace:[NSColorSpace genericRGBColorSpace]];
        [window setDelegate:window];
        [window setAutodisplay:NO];
        window.hwnd = hwnd;
        window.queue = queue;
        window->savedContentMinSize = NSZeroSize;
        window->savedContentMaxSize = NSMakeSize(FLT_MAX, FLT_MAX);
        window->resizable = wf->resizable;
        window->_lastDisplayTime = [[NSDate distantPast] timeIntervalSinceReferenceDate];

        [window registerForDraggedTypes:[NSArray arrayWithObjects:(NSString*)kUTTypeData,
                                                                  (NSString*)kUTTypeContent,
                                                                  nil]];

        contentView = [[[WineContentView alloc] initWithFrame:NSZeroRect] autorelease];
        if (!contentView)
            return nil;
        [contentView setAutoresizesSubviews:NO];

        /* We use tracking areas in addition to setAcceptsMouseMovedEvents:YES
           because they give us mouse moves in the background. */
        trackingArea = [[[NSTrackingArea alloc] initWithRect:[contentView bounds]
                                                     options:(NSTrackingMouseMoved |
                                                              NSTrackingActiveAlways |
                                                              NSTrackingInVisibleRect)
                                                       owner:window
                                                    userInfo:nil] autorelease];
        if (!trackingArea)
            return nil;
        [contentView addTrackingArea:trackingArea];

        [window setContentView:contentView];
        [window setInitialFirstResponder:contentView];

        [nc addObserver:window
               selector:@selector(updateFullscreen)
                   name:NSApplicationDidChangeScreenParametersNotification
                 object:NSApp];
        [window updateFullscreen];

        [nc addObserver:window
               selector:@selector(applicationWillHide)
                   name:NSApplicationWillHideNotification
                 object:NSApp];
        [nc addObserver:window
               selector:@selector(applicationDidUnhide)
                   name:NSApplicationDidUnhideNotification
                 object:NSApp];

        [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:window
                                                              selector:@selector(checkWineDisplayLink)
                                                                  name:NSWorkspaceActiveSpaceDidChangeNotification
                                                                object:[NSWorkspace sharedWorkspace]];

        [window setFrameAndWineFrame:[window frameRectForContentRect:window_frame]];

        return window;
    }

    - (void) dealloc
    {
        [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
        [[NSNotificationCenter defaultCenter] removeObserver:self];
        [queue release];
        [latentChildWindows release];
        [latentParentWindow release];
        [shape release];
        [shapeData release];
        [super dealloc];
    }

    - (BOOL) preventResizing
    {
        BOOL preventForClipping = cursor_clipping_locks_windows && [[WineApplicationController sharedController] clippingCursor];
        return ([self styleMask] & NSResizableWindowMask) && (disabled || !resizable || preventForClipping);
    }

    - (BOOL) allowsMovingWithMaximized:(BOOL)inMaximized
    {
        if (allow_immovable_windows && (disabled || inMaximized))
            return NO;
        else if (cursor_clipping_locks_windows && [[WineApplicationController sharedController] clippingCursor])
            return NO;
        else
            return YES;
    }

    - (void) adjustFeaturesForState
    {
        NSUInteger style = [self styleMask];

        if (style & NSClosableWindowMask)
            [[self standardWindowButton:NSWindowCloseButton] setEnabled:!self.disabled];
        if (style & NSMiniaturizableWindowMask)
            [[self standardWindowButton:NSWindowMiniaturizeButton] setEnabled:!self.disabled];
        if (style & NSResizableWindowMask)
            [[self standardWindowButton:NSWindowZoomButton] setEnabled:!self.disabled];
        if ([self respondsToSelector:@selector(toggleFullScreen:)])
        {
            if ([self collectionBehavior] & NSWindowCollectionBehaviorFullScreenPrimary)
                [[self standardWindowButton:NSWindowFullScreenButton] setEnabled:!self.disabled];
        }

        if ([self preventResizing])
        {
            NSSize size = [self contentRectForFrameRect:self.wine_fractionalFrame].size;
            [self setContentMinSize:size];
            [self setContentMaxSize:size];
        }
        else
        {
            [self setContentMaxSize:savedContentMaxSize];
            [self setContentMinSize:savedContentMinSize];
        }

        if (allow_immovable_windows || cursor_clipping_locks_windows)
            [self setMovable:[self allowsMovingWithMaximized:maximized]];
    }

    - (void) adjustFullScreenBehavior:(NSWindowCollectionBehavior)behavior
    {
        if ([self respondsToSelector:@selector(toggleFullScreen:)])
        {
            NSUInteger style = [self styleMask];

            if (behavior & NSWindowCollectionBehaviorParticipatesInCycle &&
                style & NSResizableWindowMask && !(style & NSUtilityWindowMask) && !maximized)
            {
                behavior |= NSWindowCollectionBehaviorFullScreenPrimary;
                behavior &= ~NSWindowCollectionBehaviorFullScreenAuxiliary;
            }
            else
            {
                behavior &= ~NSWindowCollectionBehaviorFullScreenPrimary;
                behavior |= NSWindowCollectionBehaviorFullScreenAuxiliary;
                if (style & NSFullScreenWindowMask)
                    [super toggleFullScreen:nil];
            }
        }

        if (behavior != [self collectionBehavior])
        {
            [self setCollectionBehavior:behavior];
            [self adjustFeaturesForState];
        }
    }

    - (void) setWindowFeatures:(const struct macdrv_window_features*)wf
    {
        static const NSUInteger usedStyles = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask |
                                             NSResizableWindowMask | NSUtilityWindowMask | NSBorderlessWindowMask;
        NSUInteger currentStyle = [self styleMask];
        NSUInteger newStyle = style_mask_for_features(wf) | (currentStyle & ~usedStyles);

        if (newStyle != currentStyle)
        {
            NSString* title = [[[self title] copy] autorelease];
            BOOL showingButtons = (currentStyle & (NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)) != 0;
            BOOL shouldShowButtons = (newStyle & (NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)) != 0;
            if (shouldShowButtons != showingButtons && !((newStyle ^ currentStyle) & NSClosableWindowMask))
            {
                // -setStyleMask: is buggy on 10.7+ with respect to NSResizableWindowMask.
                // If transitioning from NSTitledWindowMask | NSResizableWindowMask to
                // just NSTitledWindowMask, the window buttons should disappear rather
                // than just being disabled.  But they don't.  Similarly in reverse.
                // The workaround is to also toggle NSClosableWindowMask at the same time.
                [self setStyleMask:newStyle ^ NSClosableWindowMask];
            }
            [self setStyleMask:newStyle];

            // -setStyleMask: resets the firstResponder to the window.  Set it
            // back to the content view.
            if ([[self contentView] acceptsFirstResponder])
                [self makeFirstResponder:[self contentView]];

            [self adjustFullScreenBehavior:[self collectionBehavior]];

            if ([[self title] length] == 0 && [title length] > 0)
                [self setTitle:title];
        }

        resizable = wf->resizable;
        [self adjustFeaturesForState];
        [self setHasShadow:wf->shadow];
    }

    // Indicates if the window would be visible if the app were not hidden.
    - (BOOL) wouldBeVisible
    {
        return [NSApp isHidden] ? savedVisibleState : [self isVisible];
    }

    - (BOOL) isOrderedIn
    {
        return [self wouldBeVisible] || [self isMiniaturized];
    }

    - (NSInteger) minimumLevelForActive:(BOOL)active
    {
        NSInteger level;

        if (self.floating && (active || topmost_float_inactive == TOPMOST_FLOAT_INACTIVE_ALL ||
                              (topmost_float_inactive == TOPMOST_FLOAT_INACTIVE_NONFULLSCREEN && !fullscreen)))
            level = NSFloatingWindowLevel;
        else
            level = NSNormalWindowLevel;

        if (active)
        {
            BOOL captured;

            captured = (fullscreen || [self screen]) && [[WineApplicationController sharedController] areDisplaysCaptured];

            if (captured || fullscreen)
            {
                if (captured)
                    level = CGShieldingWindowLevel() + 1; /* Need +1 or we don't get mouse moves */
                else
                    level = NSStatusWindowLevel + 1;

                if (self.floating)
                    level++;
            }
        }

        return level;
    }

    - (void) postDidUnminimizeEvent
    {
        macdrv_event* event;

        /* Coalesce events by discarding any previous ones still in the queue. */
        [queue discardEventsMatchingMask:event_mask_for_type(WINDOW_DID_UNMINIMIZE)
                               forWindow:self];

        event = macdrv_create_event(WINDOW_DID_UNMINIMIZE, self);
        [queue postEvent:event];
        macdrv_release_event(event);
    }

    - (void) sendResizeStartQuery
    {
        macdrv_query* query = macdrv_create_query();
        query->type = QUERY_RESIZE_START;
        query->window = (macdrv_window)[self retain];

        [self.queue query:query timeout:0.3];
        macdrv_release_query(query);
    }

    - (void) setMacDrvState:(const struct macdrv_window_state*)state
    {
        NSWindowCollectionBehavior behavior;

        self.disabled = state->disabled;
        self.noActivate = state->no_activate;

        if (self.floating != state->floating)
        {
            self.floating = state->floating;
            if (state->floating)
            {
                // Became floating.  If child of non-floating window, make that
                // relationship latent.
                WineWindow* parent = (WineWindow*)[self parentWindow];
                if (parent && !parent.floating)
                    [self becameIneligibleChild];
            }
            else
            {
                // Became non-floating.  If parent of floating children, make that
                // relationship latent.
                WineWindow* child;
                for (child in [self childWineWindows])
                {
                    if (child.floating)
                        [child becameIneligibleChild];
                }
            }

            // Check our latent relationships.  If floating status was the only
            // reason they were latent, then make them active.
            if ([self isVisible])
                [self becameEligibleParentOrChild];

            [[WineApplicationController sharedController] adjustWindowLevels];
        }

        if (state->minimized_valid)
        {
            macdrv_event_mask discard = event_mask_for_type(WINDOW_DID_UNMINIMIZE);

            pendingMinimize = FALSE;
            if (state->minimized && ![self isMiniaturized])
            {
                if ([self wouldBeVisible])
                {
                    if ([self styleMask] & NSFullScreenWindowMask)
                    {
                        [self postDidUnminimizeEvent];
                        discard &= ~event_mask_for_type(WINDOW_DID_UNMINIMIZE);
                    }
                    else
                    {
                        [super miniaturize:nil];
                        discard |= event_mask_for_type(WINDOW_BROUGHT_FORWARD) |
                                   event_mask_for_type(WINDOW_GOT_FOCUS) |
                                   event_mask_for_type(WINDOW_LOST_FOCUS);
                    }
                }
                else
                    pendingMinimize = TRUE;
            }
            else if (!state->minimized && [self isMiniaturized])
            {
                ignore_windowDeminiaturize = TRUE;
                [self deminiaturize:nil];
                discard |= event_mask_for_type(WINDOW_LOST_FOCUS);
            }

            if (discard)
                [queue discardEventsMatchingMask:discard forWindow:self];
        }

        if (state->maximized != maximized)
        {
            maximized = state->maximized;
            [self adjustFeaturesForState];

            if (!maximized && [self inLiveResize])
                [self sendResizeStartQuery];
        }

        behavior = NSWindowCollectionBehaviorDefault;
        if (state->excluded_by_expose)
            behavior |= NSWindowCollectionBehaviorTransient;
        else
            behavior |= NSWindowCollectionBehaviorManaged;
        if (state->excluded_by_cycle)
        {
            behavior |= NSWindowCollectionBehaviorIgnoresCycle;
            if ([self isOrderedIn])
                [NSApp removeWindowsItem:self];
        }
        else
        {
            behavior |= NSWindowCollectionBehaviorParticipatesInCycle;
            if ([self isOrderedIn])
                [NSApp addWindowsItem:self title:[self title] filename:NO];
        }
        [self adjustFullScreenBehavior:behavior];
    }

    - (BOOL) addChildWineWindow:(WineWindow*)child assumeVisible:(BOOL)assumeVisible
    {
        BOOL reordered = FALSE;

        if ([self isVisible] && (assumeVisible || [child isVisible]) && (self.floating || !child.floating))
        {
            if ([self level] > [child level])
                [child setLevel:[self level]];
            [self addChildWindow:child ordered:NSWindowAbove];
            [child checkWineDisplayLink];
            [latentChildWindows removeObjectIdenticalTo:child];
            child.latentParentWindow = nil;
            reordered = TRUE;
        }
        else
        {
            if (!latentChildWindows)
                latentChildWindows = [[NSMutableArray alloc] init];
            if (![latentChildWindows containsObject:child])
                [latentChildWindows addObject:child];
            child.latentParentWindow = self;
        }

        return reordered;
    }

    - (BOOL) addChildWineWindow:(WineWindow*)child
    {
        return [self addChildWineWindow:child assumeVisible:FALSE];
    }

    - (void) removeChildWineWindow:(WineWindow*)child
    {
        [self removeChildWindow:child];
        if (child.latentParentWindow == self)
            child.latentParentWindow = nil;
        [latentChildWindows removeObjectIdenticalTo:child];
    }

    - (BOOL) becameEligibleParentOrChild
    {
        BOOL reordered = FALSE;
        NSUInteger count;

        if (latentParentWindow.floating || !self.floating)
        {
            // If we aren't visible currently, we assume that we should be and soon
            // will be.  So, if the latent parent is visible that's enough to assume
            // we can establish the parent-child relationship in Cocoa.  That will
            // actually make us visible, which is fine.
            if ([latentParentWindow addChildWineWindow:self assumeVisible:TRUE])
                reordered = TRUE;
        }

        // Here, though, we may not actually be visible yet and adding a child
        // won't make us visible.  The caller will have to call this method
        // again after actually making us visible.
        if ([self isVisible] && (count = [latentChildWindows count]))
        {
            NSMutableIndexSet* indexesToRemove = [NSMutableIndexSet indexSet];
            NSUInteger i;

            for (i = 0; i < count; i++)
            {
                WineWindow* child = [latentChildWindows objectAtIndex:i];
                if ([child isVisible] && (self.floating || !child.floating))
                {
                    if (child.latentParentWindow == self)
                    {
                        if ([self level] > [child level])
                            [child setLevel:[self level]];
                        [self addChildWindow:child ordered:NSWindowAbove];
                        child.latentParentWindow = nil;
                        reordered = TRUE;
                    }
                    else
                        ERR(@"shouldn't happen: %@ thinks %@ is a latent child, but it doesn't agree\n", self, child);
                    [indexesToRemove addIndex:i];
                }
            }

            [latentChildWindows removeObjectsAtIndexes:indexesToRemove];
        }

        return reordered;
    }

    - (void) becameIneligibleChild
    {
        WineWindow* parent = (WineWindow*)[self parentWindow];
        if (parent)
        {
            if (!parent->latentChildWindows)
                parent->latentChildWindows = [[NSMutableArray alloc] init];
            [parent->latentChildWindows insertObject:self atIndex:0];
            self.latentParentWindow = parent;
            [parent removeChildWindow:self];
        }
    }

    - (void) becameIneligibleParentOrChild
    {
        NSArray* childWindows = [self childWineWindows];

        [self becameIneligibleChild];

        if ([childWindows count])
        {
            WineWindow* child;

            for (child in childWindows)
            {
                child.latentParentWindow = self;
                [self removeChildWindow:child];
            }

            if (latentChildWindows)
                [latentChildWindows replaceObjectsInRange:NSMakeRange(0, 0) withObjectsFromArray:childWindows];
            else
                latentChildWindows = [childWindows mutableCopy];
        }
    }

    // Determine if, among Wine windows, this window is directly above or below
    // a given other Wine window with no other Wine window intervening.
    // Intervening non-Wine windows are ignored.
    - (BOOL) isOrdered:(NSWindowOrderingMode)orderingMode relativeTo:(WineWindow*)otherWindow
    {
        NSNumber* windowNumber;
        NSNumber* otherWindowNumber;
        NSArray* windowNumbers;
        NSUInteger windowIndex, otherWindowIndex, lowIndex, highIndex, i;

        if (![self isVisible] || ![otherWindow isVisible])
            return FALSE;

        windowNumber = [NSNumber numberWithInteger:[self windowNumber]];
        otherWindowNumber = [NSNumber numberWithInteger:[otherWindow windowNumber]];
        windowNumbers = [[self class] windowNumbersWithOptions:0];
        windowIndex = [windowNumbers indexOfObject:windowNumber];
        otherWindowIndex = [windowNumbers indexOfObject:otherWindowNumber];

        if (windowIndex == NSNotFound || otherWindowIndex == NSNotFound)
            return FALSE;

        if (orderingMode == NSWindowAbove)
        {
            lowIndex = windowIndex;
            highIndex = otherWindowIndex;
        }
        else if (orderingMode == NSWindowBelow)
        {
            lowIndex = otherWindowIndex;
            highIndex = windowIndex;
        }
        else
            return FALSE;

        if (highIndex <= lowIndex)
            return FALSE;

        for (i = lowIndex + 1; i < highIndex; i++)
        {
            NSInteger interveningWindowNumber = [[windowNumbers objectAtIndex:i] integerValue];
            NSWindow* interveningWindow = [NSApp windowWithWindowNumber:interveningWindowNumber];
            if ([interveningWindow isKindOfClass:[WineWindow class]])
                return FALSE;
        }

        return TRUE;
    }

    - (void) order:(NSWindowOrderingMode)mode childWindow:(WineWindow*)child relativeTo:(WineWindow*)other
    {
        NSMutableArray* windowNumbers;
        NSNumber* childWindowNumber;
        NSUInteger otherIndex, limit;
        NSArray* origChildren;
        NSMutableArray* children;

        // Get the z-order from the window server and modify it to reflect the
        // requested window ordering.
        windowNumbers = [[[[self class] windowNumbersWithOptions:NSWindowNumberListAllSpaces] mutableCopy] autorelease];
        childWindowNumber = [NSNumber numberWithInteger:[child windowNumber]];
        [windowNumbers removeObject:childWindowNumber];
        otherIndex = [windowNumbers indexOfObject:[NSNumber numberWithInteger:[other windowNumber]]];
        [windowNumbers insertObject:childWindowNumber atIndex:otherIndex + (mode == NSWindowAbove ? 0 : 1)];

        // Get our child windows and sort them in the reverse of the desired
        // z-order (back-to-front).
        origChildren = [self childWineWindows];
        children = [[origChildren mutableCopy] autorelease];
        [children sortWithOptions:NSSortStable
                  usingComparator:^NSComparisonResult(id obj1, id obj2){
            NSNumber* window1Number = [NSNumber numberWithInteger:[obj1 windowNumber]];
            NSNumber* window2Number = [NSNumber numberWithInteger:[obj2 windowNumber]];
            NSUInteger index1 = [windowNumbers indexOfObject:window1Number];
            NSUInteger index2 = [windowNumbers indexOfObject:window2Number];
            if (index1 == NSNotFound)
            {
                if (index2 == NSNotFound)
                    return NSOrderedSame;
                else
                    return NSOrderedAscending;
            }
            else if (index2 == NSNotFound)
                return NSOrderedDescending;
            else if (index1 < index2)
                return NSOrderedDescending;
            else if (index2 < index1)
                return NSOrderedAscending;

            return NSOrderedSame;
        }];

        // If the current and desired children arrays match up to a point, leave
        // those matching children alone.
        limit = MIN([origChildren count], [children count]);
        for (otherIndex = 0; otherIndex < limit; otherIndex++)
        {
            if ([origChildren objectAtIndex:otherIndex] != [children objectAtIndex:otherIndex])
                break;
        }
        [children removeObjectsInRange:NSMakeRange(0, otherIndex)];

        // Remove all of the child windows and re-add them back-to-front so they
        // are in the desired order.
        for (other in children)
            [self removeChildWindow:other];
        for (other in children)
            [self addChildWindow:other ordered:NSWindowAbove];
    }

    /* Returns whether or not the window was ordered in, which depends on if
       its frame intersects any screen. */
    - (void) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next activate:(BOOL)activate
    {
        WineApplicationController* controller = [WineApplicationController sharedController];
        if (![self isMiniaturized])
        {
            BOOL needAdjustWindowLevels = FALSE;
            BOOL wasVisible;

            [controller transformProcessToForeground];
            [NSApp unhide:nil];
            wasVisible = [self isVisible];

            if (activate)
                [NSApp activateIgnoringOtherApps:YES];

            NSDisableScreenUpdates();

            if ([self becameEligibleParentOrChild])
                needAdjustWindowLevels = TRUE;

            if (prev || next)
            {
                WineWindow* other = [prev isVisible] ? prev : next;
                NSWindowOrderingMode orderingMode = [prev isVisible] ? NSWindowBelow : NSWindowAbove;

                if (![self isOrdered:orderingMode relativeTo:other])
                {
                    WineWindow* parent = (WineWindow*)[self parentWindow];
                    WineWindow* otherParent = (WineWindow*)[other parentWindow];

                    // This window level may not be right for this window based
                    // on floating-ness, fullscreen-ness, etc.  But we set it
                    // temporarily to allow us to order the windows properly.
                    // Then the levels get fixed by -adjustWindowLevels.
                    if ([self level] != [other level])
                        [self setLevel:[other level]];
                    [self orderWindow:orderingMode relativeTo:[other windowNumber]];
                    [self checkWineDisplayLink];

                    // The above call to -[NSWindow orderWindow:relativeTo:] won't
                    // reorder windows which are both children of the same parent
                    // relative to each other, so do that separately.
                    if (parent && parent == otherParent)
                        [parent order:orderingMode childWindow:self relativeTo:other];

                    needAdjustWindowLevels = TRUE;
                }
            }
            else
            {
                // Again, temporarily set level to make sure we can order to
                // the right place.
                next = [controller frontWineWindow];
                if (next && [self level] < [next level])
                    [self setLevel:[next level]];
                [self orderFront:nil];
                [self checkWineDisplayLink];
                needAdjustWindowLevels = TRUE;
            }

            if ([self becameEligibleParentOrChild])
                needAdjustWindowLevels = TRUE;

            if (needAdjustWindowLevels)
            {
                if (!wasVisible && fullscreen && [self isOnActiveSpace])
                    [controller updateFullscreenWindows];
                [controller adjustWindowLevels];
            }

            if (pendingMinimize)
            {
                [super miniaturize:nil];
                pendingMinimize = FALSE;
            }

            NSEnableScreenUpdates();

            /* Cocoa may adjust the frame when the window is ordered onto the screen.
               Generate a frame-changed event just in case.  The back end will ignore
               it if nothing actually changed. */
            [self windowDidResize:nil];

            if (![self isExcludedFromWindowsMenu])
                [NSApp addWindowsItem:self title:[self title] filename:NO];
        }
    }

    - (void) doOrderOut
    {
        WineApplicationController* controller = [WineApplicationController sharedController];
        BOOL wasVisible = [self isVisible];
        BOOL wasOnActiveSpace = [self isOnActiveSpace];

        if ([self isMiniaturized])
            pendingMinimize = TRUE;

        WineWindow* parent = (WineWindow*)self.parentWindow;
        if ([parent isKindOfClass:[WineWindow class]])
            [parent grabDockIconSnapshotFromWindow:self force:NO];

        [self becameIneligibleParentOrChild];
        if ([self isMiniaturized])
        {
            fakingClose = TRUE;
            [self close];
            fakingClose = FALSE;
        }
        else
            [self orderOut:nil];
        [self checkWineDisplayLink];
        savedVisibleState = FALSE;
        if (wasVisible && wasOnActiveSpace && fullscreen)
            [controller updateFullscreenWindows];
        [controller adjustWindowLevels];
        [NSApp removeWindowsItem:self];

        [queue discardEventsMatchingMask:event_mask_for_type(WINDOW_BROUGHT_FORWARD) |
                                         event_mask_for_type(WINDOW_GOT_FOCUS) |
                                         event_mask_for_type(WINDOW_LOST_FOCUS) |
                                         event_mask_for_type(WINDOW_MAXIMIZE_REQUESTED) |
                                         event_mask_for_type(WINDOW_MINIMIZE_REQUESTED) |
                                         event_mask_for_type(WINDOW_RESTORE_REQUESTED)
                               forWindow:self];
    }

    - (void) updateFullscreen
    {
        NSRect contentRect = [self contentRectForFrameRect:self.wine_fractionalFrame];
        BOOL nowFullscreen = !([self styleMask] & NSFullScreenWindowMask) && screen_covered_by_rect(contentRect, [NSScreen screens]);

        if (nowFullscreen != fullscreen)
        {
            WineApplicationController* controller = [WineApplicationController sharedController];

            fullscreen = nowFullscreen;
            if ([self isVisible] && [self isOnActiveSpace])
                [controller updateFullscreenWindows];

            [controller adjustWindowLevels];
        }
    }

    - (void) setFrameAndWineFrame:(NSRect)frame
    {
        [self setFrame:frame display:YES];

        wineFrame = frame;
        roundedWineFrame = self.frame;
        CGFloat junk;
#if CGFLOAT_IS_DOUBLE
        if ((!modf(wineFrame.origin.x, &junk) && !modf(wineFrame.origin.y, &junk) &&
             !modf(wineFrame.size.width, &junk) && !modf(wineFrame.size.height, &junk)) ||
            fabs(wineFrame.origin.x - roundedWineFrame.origin.x) >= 1 ||
            fabs(wineFrame.origin.y - roundedWineFrame.origin.y) >= 1 ||
            fabs(wineFrame.size.width - roundedWineFrame.size.width) >= 1 ||
            fabs(wineFrame.size.height - roundedWineFrame.size.height) >= 1)
            roundedWineFrame = wineFrame;
#else
        if ((!modff(wineFrame.origin.x, &junk) && !modff(wineFrame.origin.y, &junk) &&
             !modff(wineFrame.size.width, &junk) && !modff(wineFrame.size.height, &junk)) ||
            fabsf(wineFrame.origin.x - roundedWineFrame.origin.x) >= 1 ||
            fabsf(wineFrame.origin.y - roundedWineFrame.origin.y) >= 1 ||
            fabsf(wineFrame.size.width - roundedWineFrame.size.width) >= 1 ||
            fabsf(wineFrame.size.height - roundedWineFrame.size.height) >= 1)
            roundedWineFrame = wineFrame;
#endif
    }

    - (void) setFrameFromWine:(NSRect)contentRect
    {
        /* Origin is (left, top) in a top-down space.  Need to convert it to
           (left, bottom) in a bottom-up space. */
        [[WineApplicationController sharedController] flipRect:&contentRect];

        /* The back end is establishing a new window size and position.  It's
           not interested in any stale events regarding those that may be sitting
           in the queue. */
        [queue discardEventsMatchingMask:event_mask_for_type(WINDOW_FRAME_CHANGED)
                               forWindow:self];

        if (!NSIsEmptyRect(contentRect))
        {
            NSRect frame, oldFrame;

            oldFrame = self.wine_fractionalFrame;
            frame = [self frameRectForContentRect:contentRect];
            if (!NSEqualRects(frame, oldFrame))
            {
                BOOL equalSizes = NSEqualSizes(frame.size, oldFrame.size);
                BOOL needEnableScreenUpdates = FALSE;

                if ([self preventResizing])
                {
                    // Allow the following calls to -setFrame:display: to work even
                    // if they would violate the content size constraints. This
                    // shouldn't be necessary since the content size constraints are
                    // documented to not constrain that method, but it seems to be.
                    [self setContentMinSize:NSZeroSize];
                    [self setContentMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
                }

                if (equalSizes && [[self childWineWindows] count])
                {
                    // If we change the window frame such that the origin moves
                    // but the size doesn't change, then Cocoa moves child
                    // windows with the parent.  We don't want that so we fake
                    // a change of the size and then change it back.
                    NSRect bogusFrame = frame;
                    bogusFrame.size.width++;

                    NSDisableScreenUpdates();
                    needEnableScreenUpdates = TRUE;

                    ignore_windowResize = TRUE;
                    [self setFrame:bogusFrame display:NO];
                    ignore_windowResize = FALSE;
                }

                [self setFrameAndWineFrame:frame];
                if ([self preventResizing])
                {
                    [self setContentMinSize:contentRect.size];
                    [self setContentMaxSize:contentRect.size];
                }

                if (needEnableScreenUpdates)
                    NSEnableScreenUpdates();

                if (!equalSizes)
                    [self updateColorSpace];

                if (!enteringFullScreen &&
                    [[NSProcessInfo processInfo] systemUptime] - enteredFullScreenTime > 1.0)
                    nonFullscreenFrame = frame;

                [self updateFullscreen];

                if ([self isOrderedIn])
                {
                    /* In case Cocoa adjusted the frame we tried to set, generate a frame-changed
                       event.  The back end will ignore it if nothing actually changed. */
                    [self windowDidResize:nil];
                }
            }
        }
    }

    - (NSRect) wine_fractionalFrame
    {
        NSRect frame = self.frame;
        if (NSEqualRects(frame, roundedWineFrame))
            frame = wineFrame;
        return frame;
    }

    - (void) setMacDrvParentWindow:(WineWindow*)parent
    {
        WineWindow* oldParent = (WineWindow*)[self parentWindow];
        if ((oldParent && oldParent != parent) || (!oldParent && latentParentWindow != parent))
        {
            [oldParent removeChildWineWindow:self];
            [latentParentWindow removeChildWineWindow:self];
            if ([parent addChildWineWindow:self])
                [[WineApplicationController sharedController] adjustWindowLevels];
        }
    }

    - (void) setDisabled:(BOOL)newValue
    {
        if (disabled != newValue)
        {
            disabled = newValue;
            [self adjustFeaturesForState];
        }
    }

    - (BOOL) needsTransparency
    {
        return self.shape || self.colorKeyed || self.usePerPixelAlpha ||
                (gl_surface_mode == GL_SURFACE_BEHIND && [(WineContentView*)self.contentView hasGLDescendant]);
    }

    - (void) checkTransparency
    {
        if (![self isOpaque] && !self.needsTransparency)
        {
            self.shapeChangedSinceLastDraw = TRUE;
            [[self contentView] setNeedsDisplay:YES];
            [self setBackgroundColor:[NSColor windowBackgroundColor]];
            [self setOpaque:YES];
        }
        else if ([self isOpaque] && self.needsTransparency)
        {
            self.shapeChangedSinceLastDraw = TRUE;
            [[self contentView] setNeedsDisplay:YES];
            [self setBackgroundColor:[NSColor clearColor]];
            [self setOpaque:NO];
        }
    }

    - (void) setShape:(NSBezierPath*)newShape
    {
        if (shape == newShape) return;

        if (shape)
        {
            [[self contentView] setNeedsDisplayInRect:[shape bounds]];
            [shape release];
        }
        if (newShape)
            [[self contentView] setNeedsDisplayInRect:[newShape bounds]];

        shape = [newShape copy];
        self.shapeChangedSinceLastDraw = TRUE;

        [self checkTransparency];
    }

    - (void) makeFocused:(BOOL)activate
    {
        if (activate)
        {
            [[WineApplicationController sharedController] transformProcessToForeground];
            [NSApp activateIgnoringOtherApps:YES];
        }

        causing_becomeKeyWindow = self;
        [self makeKeyWindow];
        causing_becomeKeyWindow = nil;

        [queue discardEventsMatchingMask:event_mask_for_type(WINDOW_GOT_FOCUS) |
                                         event_mask_for_type(WINDOW_LOST_FOCUS)
                               forWindow:self];
    }

    - (void) postKey:(uint16_t)keyCode
             pressed:(BOOL)pressed
           modifiers:(NSUInteger)modifiers
               event:(NSEvent*)theEvent
    {
        macdrv_event* event;
        CGEventRef cgevent;
        WineApplicationController* controller = [WineApplicationController sharedController];

        event = macdrv_create_event(pressed ? KEY_PRESS : KEY_RELEASE, self);
        event->key.keycode   = keyCode;
        event->key.modifiers = modifiers;
        event->key.time_ms   = [controller ticksForEventTime:[theEvent timestamp]];

        if ((cgevent = [theEvent CGEvent]))
        {
            CGEventSourceKeyboardType keyboardType = CGEventGetIntegerValueField(cgevent,
                                                        kCGKeyboardEventKeyboardType);
            if (keyboardType != controller.keyboardType)
            {
                controller.keyboardType = keyboardType;
                [controller keyboardSelectionDidChange];
            }
        }

        [queue postEvent:event];

        macdrv_release_event(event);

        [controller noteKey:keyCode pressed:pressed];
    }

    - (void) postKeyEvent:(NSEvent *)theEvent
    {
        [self flagsChanged:theEvent];
        [self postKey:[theEvent keyCode]
              pressed:[theEvent type] == NSKeyDown
            modifiers:adjusted_modifiers_for_option_behavior([theEvent modifierFlags])
                event:theEvent];
    }

    - (void) setWineMinSize:(NSSize)minSize maxSize:(NSSize)maxSize
    {
        savedContentMinSize = minSize;
        savedContentMaxSize = maxSize;
        if (![self preventResizing])
        {
            [self setContentMinSize:minSize];
            [self setContentMaxSize:maxSize];
        }
    }

    - (WineWindow*) ancestorWineWindow
    {
        WineWindow* ancestor = self;
        for (;;)
        {
            WineWindow* parent = (WineWindow*)[ancestor parentWindow];
            if ([parent isKindOfClass:[WineWindow class]])
                ancestor = parent;
            else
                break;
        }
        return ancestor;
    }

    - (void) postBroughtForwardEvent
    {
        macdrv_event* event = macdrv_create_event(WINDOW_BROUGHT_FORWARD, self);
        [queue postEvent:event];
        macdrv_release_event(event);
    }

    - (void) updateForCursorClipping
    {
        [self adjustFeaturesForState];
    }

    - (void) endWindowDragging
    {
        if (draggingPhase)
        {
            if (draggingPhase == 3)
            {
                macdrv_event* event = macdrv_create_event(WINDOW_DRAG_END, self);
                [queue postEvent:event];
                macdrv_release_event(event);
            }

            draggingPhase = 0;
            [[WineApplicationController sharedController] window:self isBeingDragged:NO];
        }
    }

    - (NSMutableDictionary*) displayIDToDisplayLinkMap
    {
        static NSMutableDictionary* displayIDToDisplayLinkMap;
        if (!displayIDToDisplayLinkMap)
        {
            displayIDToDisplayLinkMap = [[NSMutableDictionary alloc] init];

            [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationDidChangeScreenParametersNotification
                                                              object:NSApp
                                                               queue:nil
                                                          usingBlock:^(NSNotification *note){
                NSMutableSet* badDisplayIDs = [NSMutableSet setWithArray:displayIDToDisplayLinkMap.allKeys];
                NSSet* validDisplayIDs = [NSSet setWithArray:[[NSScreen screens] valueForKeyPath:@"deviceDescription.NSScreenNumber"]];
                [badDisplayIDs minusSet:validDisplayIDs];
                [displayIDToDisplayLinkMap removeObjectsForKeys:[badDisplayIDs allObjects]];
            }];
        }
        return displayIDToDisplayLinkMap;
    }

    - (WineDisplayLink*) wineDisplayLink
    {
        if (!_lastDisplayID)
            return nil;

        NSMutableDictionary* displayIDToDisplayLinkMap = [self displayIDToDisplayLinkMap];
        return [displayIDToDisplayLinkMap objectForKey:[NSNumber numberWithUnsignedInt:_lastDisplayID]];
    }

    - (void) checkWineDisplayLink
    {
        NSScreen* screen = self.screen;
        if (![self isVisible] || ![self isOnActiveSpace] || [self isMiniaturized] || [self isEmptyShaped])
            screen = nil;
#if defined(MAC_OS_X_VERSION_10_9) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9
        if ([self respondsToSelector:@selector(occlusionState)] && !(self.occlusionState & NSWindowOcclusionStateVisible))
            screen = nil;
#endif

        NSNumber* displayIDNumber = [screen.deviceDescription objectForKey:@"NSScreenNumber"];
        CGDirectDisplayID displayID = [displayIDNumber unsignedIntValue];
        if (displayID == _lastDisplayID)
            return;

        NSMutableDictionary* displayIDToDisplayLinkMap = [self displayIDToDisplayLinkMap];

        if (_lastDisplayID)
        {
            WineDisplayLink* link = [displayIDToDisplayLinkMap objectForKey:[NSNumber numberWithUnsignedInt:_lastDisplayID]];
            [link removeWindow:self];
        }
        if (displayID)
        {
            WineDisplayLink* link = [displayIDToDisplayLinkMap objectForKey:displayIDNumber];
            if (!link)
            {
                link = [[[WineDisplayLink alloc] initWithDisplayID:displayID] autorelease];
                [displayIDToDisplayLinkMap setObject:link forKey:displayIDNumber];
            }
            [link addWindow:self];
            [self displayIfNeeded];
        }
        _lastDisplayID = displayID;
    }

    - (BOOL) isEmptyShaped
    {
        return (self.shapeData.length == sizeof(CGRectZero) && !memcmp(self.shapeData.bytes, &CGRectZero, sizeof(CGRectZero)));
    }

    - (BOOL) canProvideSnapshot
    {
        return (self.windowNumber > 0 && ![self isEmptyShaped]);
    }

    - (void) grabDockIconSnapshotFromWindow:(WineWindow*)window force:(BOOL)force
    {
        if (![self isEmptyShaped])
            return;

        NSTimeInterval now = [[NSProcessInfo processInfo] systemUptime];
        if (!force && now < lastDockIconSnapshot + 1)
            return;

        if (window)
        {
            if (![window canProvideSnapshot])
                return;
        }
        else
        {
            CGFloat bestArea;
            for (WineWindow* childWindow in self.childWindows)
            {
                if (![childWindow isKindOfClass:[WineWindow class]] || ![childWindow canProvideSnapshot])
                    continue;

                NSSize size = childWindow.frame.size;
                CGFloat area = size.width * size.height;
                if (!window || area > bestArea)
                {
                    window = childWindow;
                    bestArea = area;
                }
            }

            if (!window)
                return;
        }

        const void* windowID = (const void*)(CGWindowID)window.windowNumber;
        CFArrayRef windowIDs = CFArrayCreate(NULL, &windowID, 1, NULL);
        CGImageRef windowImage = CGWindowListCreateImageFromArray(CGRectNull, windowIDs, kCGWindowImageBoundsIgnoreFraming);
        CFRelease(windowIDs);
        if (!windowImage)
            return;

        NSImage* appImage = [NSApp applicationIconImage];
        if (!appImage)
            appImage = [NSImage imageNamed:NSImageNameApplicationIcon];

        NSImage* dockIcon = [[[NSImage alloc] initWithSize:NSMakeSize(256, 256)] autorelease];
        [dockIcon lockFocus];

        CGContextRef cgcontext = [[NSGraphicsContext currentContext] graphicsPort];

        CGRect rect = CGRectMake(8, 8, 240, 240);
        size_t width = CGImageGetWidth(windowImage);
        size_t height = CGImageGetHeight(windowImage);
        if (width > height)
        {
            rect.size.height *= height / (double)width;
            rect.origin.y += (CGRectGetWidth(rect) - CGRectGetHeight(rect)) / 2;
        }
        else if (width != height)
        {
            rect.size.width *= width / (double)height;
            rect.origin.x += (CGRectGetHeight(rect) - CGRectGetWidth(rect)) / 2;
        }

        CGContextDrawImage(cgcontext, rect, windowImage);
        [appImage drawInRect:NSMakeRect(156, 4, 96, 96)
                    fromRect:NSZeroRect
                   operation:NSCompositeSourceOver
                    fraction:1
              respectFlipped:YES
                       hints:nil];

        [dockIcon unlockFocus];

        CGImageRelease(windowImage);

        NSImageView* imageView = (NSImageView*)self.dockTile.contentView;
        if (![imageView isKindOfClass:[NSImageView class]])
        {
            imageView = [[[NSImageView alloc] initWithFrame:NSMakeRect(0, 0, 256, 256)] autorelease];
            imageView.imageScaling = NSImageScaleProportionallyUpOrDown;
            self.dockTile.contentView = imageView;
        }
        imageView.image = dockIcon;
        [self.dockTile display];
        lastDockIconSnapshot = now;
    }

    - (void) checkEmptyShaped
    {
        if (self.dockTile.contentView && ![self isEmptyShaped])
        {
            self.dockTile.contentView = nil;
            lastDockIconSnapshot = 0;
        }
        [self checkWineDisplayLink];
    }


    /*
     * ---------- NSWindow method overrides ----------
     */
    - (BOOL) canBecomeKeyWindow
    {
        if (causing_becomeKeyWindow == self) return YES;
        if (self.disabled || self.noActivate) return NO;
        return [self isKeyWindow];
    }

    - (BOOL) canBecomeMainWindow
    {
        return [self canBecomeKeyWindow];
    }

    - (NSRect) constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen
    {
        // If a window is sized to completely cover a screen, then it's in
        // full-screen mode.  In that case, we don't allow NSWindow to constrain
        // it.
        NSArray* screens = [NSScreen screens];
        NSRect contentRect = [self contentRectForFrameRect:frameRect];
        if (!screen_covered_by_rect(contentRect, screens) &&
            frame_intersects_screens(frameRect, screens))
            frameRect = [super constrainFrameRect:frameRect toScreen:screen];
        return frameRect;
    }

    // This private method of NSWindow is called as Cocoa reacts to the display
    // configuration changing.  Among other things, it adjusts the window's
    // frame based on how the screen(s) changed size.  That tells Wine that the
    // window has been moved.  We don't want that.  Rather, we want to make
    // sure that the WinAPI notion of the window position is maintained/
    // restored, possibly undoing or overriding Cocoa's adjustment.
    //
    // So, we queue a REASSERT_WINDOW_POSITION event to the back end before
    // Cocoa has a chance to adjust the frame, thus preceding any resulting
    // WINDOW_FRAME_CHANGED event that may get queued.  The back end will
    // reassert its notion of the position.  That call won't get processed
    // until after this method returns, so it will override whatever this
    // method does to the window position.  It will also discard any pending
    // WINDOW_FRAME_CHANGED events.
    //
    // Unfortunately, the only way I've found to know when Cocoa is _about to_
    // adjust the window's position due to a display change is to hook into
    // this private method.  This private method has remained stable from 10.6
    // through 10.11.  If it does change, the most likely thing is that it
    // will be removed and no longer called and this fix will simply stop
    // working.  The only real danger would be if Apple changed the return type
    // to a struct or floating-point type, which would change the calling
    // convention.
    - (id) _displayChanged
    {
        macdrv_event* event = macdrv_create_event(REASSERT_WINDOW_POSITION, self);
        [queue postEvent:event];
        macdrv_release_event(event);

        return [super _displayChanged];
    }

    - (BOOL) isExcludedFromWindowsMenu
    {
        return !([self collectionBehavior] & NSWindowCollectionBehaviorParticipatesInCycle);
    }

    - (BOOL) validateMenuItem:(NSMenuItem *)menuItem
    {
        BOOL ret = [super validateMenuItem:menuItem];

        if ([menuItem action] == @selector(makeKeyAndOrderFront:))
            ret = [self isKeyWindow] || (!self.disabled && !self.noActivate);
        if ([menuItem action] == @selector(toggleFullScreen:) && (self.disabled || maximized))
            ret = NO;

        return ret;
    }

    /* We don't call this.  It's the action method of the items in the Window menu. */
    - (void) makeKeyAndOrderFront:(id)sender
    {
        if ([self isMiniaturized])
            [self deminiaturize:nil];
        [self orderBelow:nil orAbove:nil activate:NO];
        [[self ancestorWineWindow] postBroughtForwardEvent];

        if (![self isKeyWindow] && !self.disabled && !self.noActivate)
            [[WineApplicationController sharedController] windowGotFocus:self];
    }

    - (void) sendEvent:(NSEvent*)event
    {
        NSEventType type = event.type;

        /* NSWindow consumes certain key-down events as part of Cocoa's keyboard
           interface control.  For example, Control-Tab switches focus among
           views.  We want to bypass that feature, so directly route key-down
           events to -keyDown:. */
        if (type == NSKeyDown)
            [[self firstResponder] keyDown:event];
        else
        {
            if (!draggingPhase && maximized && ![self isMovable] &&
                ![self allowsMovingWithMaximized:YES] && [self allowsMovingWithMaximized:NO] &&
                type == NSLeftMouseDown && (self.styleMask & NSTitledWindowMask))
            {
                NSRect titleBar = self.frame;
                NSRect contentRect = [self contentRectForFrameRect:titleBar];
                titleBar.size.height = NSMaxY(titleBar) - NSMaxY(contentRect);
                titleBar.origin.y = NSMaxY(contentRect);

                dragStartPosition = [self convertBaseToScreen:event.locationInWindow];

                if (NSMouseInRect(dragStartPosition, titleBar, NO))
                {
                    static const NSWindowButton buttons[] = {
                        NSWindowCloseButton,
                        NSWindowMiniaturizeButton,
                        NSWindowZoomButton,
                        NSWindowFullScreenButton,
                    };
                    BOOL hitButton = NO;
                    int i;

                    for (i = 0; i < sizeof(buttons) / sizeof(buttons[0]); i++)
                    {
                        NSButton* button;

                        if (buttons[i] == NSWindowFullScreenButton && ![self respondsToSelector:@selector(toggleFullScreen:)])
                            continue;

                        button = [self standardWindowButton:buttons[i]];
                        if ([button hitTest:[button.superview convertPoint:event.locationInWindow fromView:nil]])
                        {
                            hitButton = YES;
                            break;
                        }
                    }

                    if (!hitButton)
                    {
                        draggingPhase = 1;
                        dragWindowStartPosition = NSMakePoint(NSMinX(titleBar), NSMaxY(titleBar));
                        [[WineApplicationController sharedController] window:self isBeingDragged:YES];
                    }
                }
            }
            else if (draggingPhase && (type == NSLeftMouseDragged || type == NSLeftMouseUp))
            {
                if ([self isMovable])
                {
                    NSPoint point = [self convertBaseToScreen:event.locationInWindow];
                    NSPoint newTopLeft = dragWindowStartPosition;

                    newTopLeft.x += point.x - dragStartPosition.x;
                    newTopLeft.y += point.y - dragStartPosition.y;

                    if (draggingPhase == 2)
                    {
                        macdrv_event* event = macdrv_create_event(WINDOW_DRAG_BEGIN, self);
                        [queue postEvent:event];
                        macdrv_release_event(event);

                        draggingPhase = 3;
                    }

                    [self setFrameTopLeftPoint:newTopLeft];
                }
                else if (draggingPhase == 1 && type == NSLeftMouseDragged)
                {
                    macdrv_event* event;
                    NSRect frame = [self contentRectForFrameRect:self.frame];

                    [[WineApplicationController sharedController] flipRect:&frame];

                    event = macdrv_create_event(WINDOW_RESTORE_REQUESTED, self);
                    event->window_restore_requested.keep_frame = TRUE;
                    event->window_restore_requested.frame = cgrect_win_from_mac(NSRectToCGRect(frame));
                    [queue postEvent:event];
                    macdrv_release_event(event);

                    draggingPhase = 2;
                }

                if (type == NSLeftMouseUp)
                    [self endWindowDragging];
            }

            [super sendEvent:event];
        }
    }

    - (void) miniaturize:(id)sender
    {
        macdrv_event* event = macdrv_create_event(WINDOW_MINIMIZE_REQUESTED, self);
        [queue postEvent:event];
        macdrv_release_event(event);

        WineWindow* parent = (WineWindow*)self.parentWindow;
        if ([parent isKindOfClass:[WineWindow class]])
            [parent grabDockIconSnapshotFromWindow:self force:YES];
    }

    - (void) toggleFullScreen:(id)sender
    {
        if (!self.disabled && !maximized)
            [super toggleFullScreen:sender];
    }

    - (void) setViewsNeedDisplay:(BOOL)value
    {
        if (value && ![self viewsNeedDisplay])
        {
            WineDisplayLink* link = [self wineDisplayLink];
            if (link)
            {
                NSTimeInterval now = [[NSProcessInfo processInfo] systemUptime];
                if (_lastDisplayTime + [link refreshPeriod] < now)
                    [self setAutodisplay:YES];
                else
                {
                    [link start];
                    _lastDisplayTime = now;
                }
            }
        }
        [super setViewsNeedDisplay:value];
    }

    - (void) display
    {
        _lastDisplayTime = [[NSProcessInfo processInfo] systemUptime];
        [super display];
        [self setAutodisplay:NO];
    }

    - (void) displayIfNeeded
    {
        _lastDisplayTime = [[NSProcessInfo processInfo] systemUptime];
        [super displayIfNeeded];
        [self setAutodisplay:NO];
    }

    - (NSArray*) childWineWindows
    {
        NSArray* childWindows = self.childWindows;
        NSIndexSet* indexes = [childWindows indexesOfObjectsPassingTest:^BOOL(id child, NSUInteger idx, BOOL *stop){
            return [child isKindOfClass:[WineWindow class]];
        }];
        return [childWindows objectsAtIndexes:indexes];
    }

    // We normally use the generic/calibrated RGB color space for the window,
    // rather than the device color space, to avoid expensive color conversion
    // which slows down drawing.  However, for windows displaying OpenGL, having
    // a different color space than the screen greatly reduces frame rates, often
    // limiting it to the display refresh rate.
    //
    // To avoid this, we switch back to the screen color space whenever the
    // window is covered by a view with an attached OpenGL context.
    - (void) updateColorSpace
    {
        NSRect contentRect = [[self contentView] frame];
        BOOL coveredByGLView = FALSE;
        WineContentView* view = (WineContentView*)[[self contentView] hitTest:NSMakePoint(NSMidX(contentRect), NSMidY(contentRect))];
        if ([view isKindOfClass:[WineContentView class]] && [view hasGLContext])
        {
            NSRect frame = [view convertRect:[view bounds] toView:nil];
            if (NSContainsRect(frame, contentRect))
                coveredByGLView = TRUE;
        }

        if (coveredByGLView)
            [self setColorSpace:nil];
        else
            [self setColorSpace:[NSColorSpace genericRGBColorSpace]];
    }

    - (void) updateForGLSubviews
    {
        [self updateColorSpace];
        if (gl_surface_mode == GL_SURFACE_BEHIND)
            [self checkTransparency];
    }

    - (void) setRetinaMode:(int)mode
    {
        NSRect frame;
        double scale = mode ? 0.5 : 2.0;
        NSAffineTransform* transform = [NSAffineTransform transform];

        [transform scaleBy:scale];

        if (shape)
            [shape transformUsingAffineTransform:transform];

        for (WineContentView* subview in [self.contentView subviews])
        {
            if ([subview isKindOfClass:[WineContentView class]])
                [subview setRetinaMode:mode];
        }

        frame = [self contentRectForFrameRect:self.wine_fractionalFrame];
        frame.origin.x *= scale;
        frame.origin.y *= scale;
        frame.size.width *= scale;
        frame.size.height *= scale;
        frame = [self frameRectForContentRect:frame];

        savedContentMinSize = [transform transformSize:savedContentMinSize];
        if (savedContentMaxSize.width != FLT_MAX && savedContentMaxSize.width != CGFLOAT_MAX)
            savedContentMaxSize.width *= scale;
        if (savedContentMaxSize.height != FLT_MAX && savedContentMaxSize.height != CGFLOAT_MAX)
            savedContentMaxSize.height *= scale;

        self.contentMinSize = [transform transformSize:self.contentMinSize];
        NSSize temp = self.contentMaxSize;
        if (temp.width != FLT_MAX && temp.width != CGFLOAT_MAX)
            temp.width *= scale;
        if (temp.height != FLT_MAX && temp.height != CGFLOAT_MAX)
            temp.height *= scale;
        self.contentMaxSize = temp;

        ignore_windowResize = TRUE;
        [self setFrameAndWineFrame:frame];
        ignore_windowResize = FALSE;
    }


    /*
     * ---------- NSResponder method overrides ----------
     */
    - (void) keyDown:(NSEvent *)theEvent { [self postKeyEvent:theEvent]; }

    - (void) flagsChanged:(NSEvent *)theEvent
    {
        static const struct {
            NSUInteger  mask;
            uint16_t    keycode;
        } modifiers[] = {
            { NX_ALPHASHIFTMASK,        kVK_CapsLock },
            { NX_DEVICELSHIFTKEYMASK,   kVK_Shift },
            { NX_DEVICERSHIFTKEYMASK,   kVK_RightShift },
            { NX_DEVICELCTLKEYMASK,     kVK_Control },
            { NX_DEVICERCTLKEYMASK,     kVK_RightControl },
            { NX_DEVICELALTKEYMASK,     kVK_Option },
            { NX_DEVICERALTKEYMASK,     kVK_RightOption },
            { NX_DEVICELCMDKEYMASK,     kVK_Command },
            { NX_DEVICERCMDKEYMASK,     kVK_RightCommand },
        };

        NSUInteger modifierFlags = adjusted_modifiers_for_option_behavior([theEvent modifierFlags]);
        NSUInteger changed;
        int i, last_changed;

        fix_device_modifiers_by_generic(&modifierFlags);
        changed = modifierFlags ^ lastModifierFlags;

        last_changed = -1;
        for (i = 0; i < sizeof(modifiers)/sizeof(modifiers[0]); i++)
            if (changed & modifiers[i].mask)
                last_changed = i;

        for (i = 0; i <= last_changed; i++)
        {
            if (changed & modifiers[i].mask)
            {
                BOOL pressed = (modifierFlags & modifiers[i].mask) != 0;

                if (i == last_changed)
                    lastModifierFlags = modifierFlags;
                else
                {
                    lastModifierFlags ^= modifiers[i].mask;
                    fix_generic_modifiers_by_device(&lastModifierFlags);
                }

                // Caps lock generates one event for each press-release action.
                // We need to simulate a pair of events for each actual event.
                if (modifiers[i].mask == NX_ALPHASHIFTMASK)
                {
                    [self postKey:modifiers[i].keycode
                          pressed:TRUE
                        modifiers:lastModifierFlags
                            event:(NSEvent*)theEvent];
                    pressed = FALSE;
                }

                [self postKey:modifiers[i].keycode
                      pressed:pressed
                    modifiers:lastModifierFlags
                        event:(NSEvent*)theEvent];
            }
        }
    }

    - (void) applicationWillHide
    {
        savedVisibleState = [self isVisible];
    }

    - (void) applicationDidUnhide
    {
        if ([self isVisible])
            [self becameEligibleParentOrChild];
    }


    /*
     * ---------- NSWindowDelegate methods ----------
     */
    - (NSSize) window:(NSWindow*)window willUseFullScreenContentSize:(NSSize)proposedSize
    {
        macdrv_query* query;
        NSSize size;

        query = macdrv_create_query();
        query->type = QUERY_MIN_MAX_INFO;
        query->window = (macdrv_window)[self retain];
        [self.queue query:query timeout:0.5];
        macdrv_release_query(query);

        size = [self contentMaxSize];
        if (proposedSize.width < size.width)
            size.width = proposedSize.width;
        if (proposedSize.height < size.height)
            size.height = proposedSize.height;
        return size;
    }

    - (void)windowDidBecomeKey:(NSNotification *)notification
    {
        WineApplicationController* controller = [WineApplicationController sharedController];
        NSEvent* event = [controller lastFlagsChanged];
        if (event)
            [self flagsChanged:event];

        if (causing_becomeKeyWindow == self) return;

        [controller windowGotFocus:self];
    }

    - (void) windowDidChangeOcclusionState:(NSNotification*)notification
    {
        [self checkWineDisplayLink];
    }

    - (void) windowDidChangeScreen:(NSNotification*)notification
    {
        [self checkWineDisplayLink];
    }

    - (void)windowDidDeminiaturize:(NSNotification *)notification
    {
        WineApplicationController* controller = [WineApplicationController sharedController];

        if (!ignore_windowDeminiaturize)
            [self postDidUnminimizeEvent];
        ignore_windowDeminiaturize = FALSE;

        [self becameEligibleParentOrChild];

        if (fullscreen && [self isOnActiveSpace])
            [controller updateFullscreenWindows];
        [controller adjustWindowLevels];

        if (![self parentWindow])
            [self postBroughtForwardEvent];

        if (!self.disabled && !self.noActivate)
        {
            causing_becomeKeyWindow = self;
            [self makeKeyWindow];
            causing_becomeKeyWindow = nil;
            [controller windowGotFocus:self];
        }

        [self windowDidResize:notification];
        [self checkWineDisplayLink];
    }

    - (void) windowDidEndLiveResize:(NSNotification *)notification
    {
        if (!maximized)
        {
            macdrv_event* event = macdrv_create_event(WINDOW_RESIZE_ENDED, self);
            [queue postEvent:event];
            macdrv_release_event(event);
        }
    }

    - (void) windowDidEnterFullScreen:(NSNotification*)notification
    {
        enteringFullScreen = FALSE;
        enteredFullScreenTime = [[NSProcessInfo processInfo] systemUptime];
    }

    - (void) windowDidExitFullScreen:(NSNotification*)notification
    {
        exitingFullScreen = FALSE;
        [self setFrameAndWineFrame:nonFullscreenFrame];
        [self windowDidResize:nil];
    }

    - (void) windowDidFailToEnterFullScreen:(NSWindow*)window
    {
        enteringFullScreen = FALSE;
        enteredFullScreenTime = 0;
    }

    - (void) windowDidFailToExitFullScreen:(NSWindow*)window
    {
        exitingFullScreen = FALSE;
        [self windowDidResize:nil];
    }

    - (void)windowDidMiniaturize:(NSNotification *)notification
    {
        if (fullscreen && [self isOnActiveSpace])
            [[WineApplicationController sharedController] updateFullscreenWindows];
        [self checkWineDisplayLink];
    }

    - (void)windowDidMove:(NSNotification *)notification
    {
        [self windowDidResize:notification];
    }

    - (void)windowDidResignKey:(NSNotification *)notification
    {
        macdrv_event* event;

        if (causing_becomeKeyWindow) return;

        event = macdrv_create_event(WINDOW_LOST_FOCUS, self);
        [queue postEvent:event];
        macdrv_release_event(event);
    }

    - (void)windowDidResize:(NSNotification *)notification
    {
        macdrv_event* event;
        NSRect frame = self.wine_fractionalFrame;

        if ([self inLiveResize])
        {
            if (NSMinX(frame) != NSMinX(frameAtResizeStart))
                resizingFromLeft = TRUE;
            if (NSMaxY(frame) != NSMaxY(frameAtResizeStart))
                resizingFromTop = TRUE;
        }

        frame = [self contentRectForFrameRect:frame];

        if (ignore_windowResize || exitingFullScreen) return;

        if ([self preventResizing])
        {
            [self setContentMinSize:frame.size];
            [self setContentMaxSize:frame.size];
        }

        [[WineApplicationController sharedController] flipRect:&frame];

        /* Coalesce events by discarding any previous ones still in the queue. */
        [queue discardEventsMatchingMask:event_mask_for_type(WINDOW_FRAME_CHANGED)
                               forWindow:self];

        event = macdrv_create_event(WINDOW_FRAME_CHANGED, self);
        event->window_frame_changed.frame = cgrect_win_from_mac(NSRectToCGRect(frame));
        event->window_frame_changed.fullscreen = ([self styleMask] & NSFullScreenWindowMask) != 0;
        event->window_frame_changed.in_resize = [self inLiveResize];
        [queue postEvent:event];
        macdrv_release_event(event);

        [[[self contentView] inputContext] invalidateCharacterCoordinates];
        [self updateFullscreen];
    }

    - (BOOL)windowShouldClose:(id)sender
    {
        macdrv_event* event = macdrv_create_event(WINDOW_CLOSE_REQUESTED, self);
        [queue postEvent:event];
        macdrv_release_event(event);
        return NO;
    }

    - (BOOL) windowShouldZoom:(NSWindow*)window toFrame:(NSRect)newFrame
    {
        if (maximized)
        {
            macdrv_event* event = macdrv_create_event(WINDOW_RESTORE_REQUESTED, self);
            [queue postEvent:event];
            macdrv_release_event(event);
            return NO;
        }
        else if (!resizable)
        {
            macdrv_event* event = macdrv_create_event(WINDOW_MAXIMIZE_REQUESTED, self);
            [queue postEvent:event];
            macdrv_release_event(event);
            return NO;
        }

        return YES;
    }

    - (void) windowWillClose:(NSNotification*)notification
    {
        WineWindow* child;

        if (fakingClose) return;
        if (latentParentWindow)
        {
            [latentParentWindow->latentChildWindows removeObjectIdenticalTo:self];
            self.latentParentWindow = nil;
        }

        for (child in latentChildWindows)
        {
            if (child.latentParentWindow == self)
                child.latentParentWindow = nil;
        }
        [latentChildWindows removeAllObjects];
    }

    - (void) windowWillEnterFullScreen:(NSNotification*)notification
    {
        enteringFullScreen = TRUE;
        nonFullscreenFrame = self.wine_fractionalFrame;
    }

    - (void) windowWillExitFullScreen:(NSNotification*)notification
    {
        exitingFullScreen = TRUE;
    }

    - (void)windowWillMiniaturize:(NSNotification *)notification
    {
        [self becameIneligibleParentOrChild];
        [self grabDockIconSnapshotFromWindow:nil force:NO];
    }

    - (NSSize) windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize
    {
        if ([self inLiveResize])
        {
            if (maximized)
                return self.wine_fractionalFrame.size;

            NSRect rect;
            macdrv_query* query;

            rect = [self frame];
            if (resizingFromLeft)
                rect.origin.x = NSMaxX(rect) - frameSize.width;
            if (!resizingFromTop)
                rect.origin.y = NSMaxY(rect) - frameSize.height;
            rect.size = frameSize;
            rect = [self contentRectForFrameRect:rect];
            [[WineApplicationController sharedController] flipRect:&rect];

            query = macdrv_create_query();
            query->type = QUERY_RESIZE_SIZE;
            query->window = (macdrv_window)[self retain];
            query->resize_size.rect = cgrect_win_from_mac(NSRectToCGRect(rect));
            query->resize_size.from_left = resizingFromLeft;
            query->resize_size.from_top = resizingFromTop;

            if ([self.queue query:query timeout:0.1])
            {
                rect = NSRectFromCGRect(cgrect_mac_from_win(query->resize_size.rect));
                rect = [self frameRectForContentRect:rect];
                frameSize = rect.size;
            }

            macdrv_release_query(query);
        }

        return frameSize;
    }

    - (void) windowWillStartLiveResize:(NSNotification *)notification
    {
        [self endWindowDragging];

        if (maximized)
        {
            macdrv_event* event;
            NSRect frame = [self contentRectForFrameRect:self.frame];

            [[WineApplicationController sharedController] flipRect:&frame];

            event = macdrv_create_event(WINDOW_RESTORE_REQUESTED, self);
            event->window_restore_requested.keep_frame = TRUE;
            event->window_restore_requested.frame = cgrect_win_from_mac(NSRectToCGRect(frame));
            [queue postEvent:event];
            macdrv_release_event(event);
        }
        else
            [self sendResizeStartQuery];

        frameAtResizeStart = [self frame];
        resizingFromLeft = resizingFromTop = FALSE;
    }

    - (NSRect) windowWillUseStandardFrame:(NSWindow*)window defaultFrame:(NSRect)proposedFrame
    {
        macdrv_query* query;
        NSRect currentContentRect, proposedContentRect, newContentRect, screenRect;
        NSSize maxSize;

        query = macdrv_create_query();
        query->type = QUERY_MIN_MAX_INFO;
        query->window = (macdrv_window)[self retain];
        [self.queue query:query timeout:0.5];
        macdrv_release_query(query);

        currentContentRect = [self contentRectForFrameRect:[self frame]];
        proposedContentRect = [self contentRectForFrameRect:proposedFrame];

        maxSize = [self contentMaxSize];
        newContentRect.size.width = MIN(NSWidth(proposedContentRect), maxSize.width);
        newContentRect.size.height = MIN(NSHeight(proposedContentRect), maxSize.height);

        // Try to keep the top-left corner where it is.
        newContentRect.origin.x = NSMinX(currentContentRect);
        newContentRect.origin.y = NSMaxY(currentContentRect) - NSHeight(newContentRect);

        // If that pushes the bottom or right off the screen, pull it up and to the left.
        screenRect = [self contentRectForFrameRect:[[self screen] visibleFrame]];
        if (NSMaxX(newContentRect) > NSMaxX(screenRect))
            newContentRect.origin.x = NSMaxX(screenRect) - NSWidth(newContentRect);
        if (NSMinY(newContentRect) < NSMinY(screenRect))
            newContentRect.origin.y = NSMinY(screenRect);

        // If that pushes the top or left off the screen, push it down and the right
        // again.  Do this last because the top-left corner is more important than the
        // bottom-right.
        if (NSMinX(newContentRect) < NSMinX(screenRect))
            newContentRect.origin.x = NSMinX(screenRect);
        if (NSMaxY(newContentRect) > NSMaxY(screenRect))
            newContentRect.origin.y = NSMaxY(screenRect) - NSHeight(newContentRect);

        return [self frameRectForContentRect:newContentRect];
    }


    /*
     * ---------- NSPasteboardOwner methods ----------
     */
    - (void) pasteboard:(NSPasteboard *)sender provideDataForType:(NSString *)type
    {
        macdrv_query* query = macdrv_create_query();
        query->type = QUERY_PASTEBOARD_DATA;
        query->window = (macdrv_window)[self retain];
        query->pasteboard_data.type = (CFStringRef)[type copy];

        [self.queue query:query timeout:3];
        macdrv_release_query(query);
    }


    /*
     * ---------- NSDraggingDestination methods ----------
     */
    - (NSDragOperation) draggingEntered:(id <NSDraggingInfo>)sender
    {
        return [self draggingUpdated:sender];
    }

    - (void) draggingExited:(id <NSDraggingInfo>)sender
    {
        // This isn't really a query.  We don't need any response.  However, it
        // has to be processed in a similar manner as the other drag-and-drop
        // queries in order to maintain the proper order of operations.
        macdrv_query* query = macdrv_create_query();
        query->type = QUERY_DRAG_EXITED;
        query->window = (macdrv_window)[self retain];

        [self.queue query:query timeout:0.1];
        macdrv_release_query(query);
    }

    - (NSDragOperation) draggingUpdated:(id <NSDraggingInfo>)sender
    {
        NSDragOperation ret;
        NSPoint pt = [[self contentView] convertPoint:[sender draggingLocation] fromView:nil];
        CGPoint cgpt = cgpoint_win_from_mac(NSPointToCGPoint(pt));
        NSPasteboard* pb = [sender draggingPasteboard];

        macdrv_query* query = macdrv_create_query();
        query->type = QUERY_DRAG_OPERATION;
        query->window = (macdrv_window)[self retain];
        query->drag_operation.x = floor(cgpt.x);
        query->drag_operation.y = floor(cgpt.y);
        query->drag_operation.offered_ops = [sender draggingSourceOperationMask];
        query->drag_operation.accepted_op = NSDragOperationNone;
        query->drag_operation.pasteboard = (CFTypeRef)[pb retain];

        [self.queue query:query timeout:3];
        ret = query->status ? query->drag_operation.accepted_op : NSDragOperationNone;
        macdrv_release_query(query);

        return ret;
    }

    - (BOOL) performDragOperation:(id <NSDraggingInfo>)sender
    {
        BOOL ret;
        NSPoint pt = [[self contentView] convertPoint:[sender draggingLocation] fromView:nil];
        CGPoint cgpt = cgpoint_win_from_mac(NSPointToCGPoint(pt));
        NSPasteboard* pb = [sender draggingPasteboard];

        macdrv_query* query = macdrv_create_query();
        query->type = QUERY_DRAG_DROP;
        query->window = (macdrv_window)[self retain];
        query->drag_drop.x = floor(cgpt.x);
        query->drag_drop.y = floor(cgpt.y);
        query->drag_drop.op = [sender draggingSourceOperationMask];
        query->drag_drop.pasteboard = (CFTypeRef)[pb retain];

        [self.queue query:query timeout:3 * 60 flags:WineQueryProcessEvents];
        ret = query->status;
        macdrv_release_query(query);

        return ret;
    }

    - (BOOL) wantsPeriodicDraggingUpdates
    {
        return NO;
    }

@end


/***********************************************************************
 *              macdrv_create_cocoa_window
 *
 * Create a Cocoa window with the given content frame and features (e.g.
 * title bar, close box, etc.).
 */
macdrv_window macdrv_create_cocoa_window(const struct macdrv_window_features* wf,
        CGRect frame, void* hwnd, macdrv_event_queue queue)
{
    __block WineWindow* window;

    OnMainThread(^{
        window = [[WineWindow createWindowWithFeatures:wf
                                           windowFrame:NSRectFromCGRect(cgrect_mac_from_win(frame))
                                                  hwnd:hwnd
                                                 queue:(WineEventQueue*)queue] retain];
    });

    return (macdrv_window)window;
}

/***********************************************************************
 *              macdrv_destroy_cocoa_window
 *
 * Destroy a Cocoa window.
 */
void macdrv_destroy_cocoa_window(macdrv_window w)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineWindow* window = (WineWindow*)w;

    OnMainThread(^{
        [window doOrderOut];
        [window close];
    });
    [window.queue discardEventsMatchingMask:-1 forWindow:window];
    [window release];

    [pool release];
}

/***********************************************************************
 *              macdrv_get_window_hwnd
 *
 * Get the hwnd that was set for the window at creation.
 */
void* macdrv_get_window_hwnd(macdrv_window w)
{
    WineWindow* window = (WineWindow*)w;
    return window.hwnd;
}

/***********************************************************************
 *              macdrv_set_cocoa_window_features
 *
 * Update a Cocoa window's features.
 */
void macdrv_set_cocoa_window_features(macdrv_window w,
        const struct macdrv_window_features* wf)
{
    WineWindow* window = (WineWindow*)w;

    OnMainThread(^{
        [window setWindowFeatures:wf];
    });
}

/***********************************************************************
 *              macdrv_set_cocoa_window_state
 *
 * Update a Cocoa window's state.
 */
void macdrv_set_cocoa_window_state(macdrv_window w,
        const struct macdrv_window_state* state)
{
    WineWindow* window = (WineWindow*)w;

    OnMainThread(^{
        [window setMacDrvState:state];
    });
}

/***********************************************************************
 *              macdrv_set_cocoa_window_title
 *
 * Set a Cocoa window's title.
 */
void macdrv_set_cocoa_window_title(macdrv_window w, const unsigned short* title,
        size_t length)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineWindow* window = (WineWindow*)w;
    NSString* titleString;

    if (title)
        titleString = [NSString stringWithCharacters:title length:length];
    else
        titleString = @"";
    OnMainThreadAsync(^{
        [window setTitle:titleString];
        if ([window isOrderedIn] && ![window isExcludedFromWindowsMenu])
            [NSApp changeWindowsItem:window title:titleString filename:NO];
    });

    [pool release];
}

/***********************************************************************
 *              macdrv_order_cocoa_window
 *
 * Reorder a Cocoa window relative to other windows.  If prev is
 * non-NULL, it is ordered below that window.  Else, if next is non-NULL,
 * it is ordered above that window.  Otherwise, it is ordered to the
 * front.
 */
void macdrv_order_cocoa_window(macdrv_window w, macdrv_window p,
        macdrv_window n, int activate)
{
    WineWindow* window = (WineWindow*)w;
    WineWindow* prev = (WineWindow*)p;
    WineWindow* next = (WineWindow*)n;

    OnMainThreadAsync(^{
        [window orderBelow:prev
                   orAbove:next
                  activate:activate];
    });
    [window.queue discardEventsMatchingMask:event_mask_for_type(WINDOW_BROUGHT_FORWARD)
                                  forWindow:window];
    [next.queue discardEventsMatchingMask:event_mask_for_type(WINDOW_BROUGHT_FORWARD)
                                forWindow:next];
}

/***********************************************************************
 *              macdrv_hide_cocoa_window
 *
 * Hides a Cocoa window.
 */
void macdrv_hide_cocoa_window(macdrv_window w)
{
    WineWindow* window = (WineWindow*)w;

    OnMainThread(^{
        [window doOrderOut];
    });
}

/***********************************************************************
 *              macdrv_set_cocoa_window_frame
 *
 * Move a Cocoa window.
 */
void macdrv_set_cocoa_window_frame(macdrv_window w, const CGRect* new_frame)
{
    WineWindow* window = (WineWindow*)w;

    OnMainThread(^{
        [window setFrameFromWine:NSRectFromCGRect(cgrect_mac_from_win(*new_frame))];
    });
}

/***********************************************************************
 *              macdrv_get_cocoa_window_frame
 *
 * Gets the frame of a Cocoa window.
 */
void macdrv_get_cocoa_window_frame(macdrv_window w, CGRect* out_frame)
{
    WineWindow* window = (WineWindow*)w;

    OnMainThread(^{
        NSRect frame;

        frame = [window contentRectForFrameRect:[window wine_fractionalFrame]];
        [[WineApplicationController sharedController] flipRect:&frame];
        *out_frame = cgrect_win_from_mac(NSRectToCGRect(frame));
    });
}

/***********************************************************************
 *              macdrv_set_cocoa_parent_window
 *
 * Sets the parent window for a Cocoa window.  If parent is NULL, clears
 * the parent window.
 */
void macdrv_set_cocoa_parent_window(macdrv_window w, macdrv_window parent)
{
    WineWindow* window = (WineWindow*)w;

    OnMainThread(^{
        [window setMacDrvParentWindow:(WineWindow*)parent];
    });
}

/***********************************************************************
 *              macdrv_set_window_surface
 */
void macdrv_set_window_surface(macdrv_window w, void *surface, pthread_mutex_t *mutex)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineWindow* window = (WineWindow*)w;

    OnMainThread(^{
        window.surface = surface;
        window.surface_mutex = mutex;
    });

    [pool release];
}

/***********************************************************************
 *              macdrv_window_needs_display
 *
 * Mark a window as needing display in a specified rect (in non-client
 * area coordinates).
 */
void macdrv_window_needs_display(macdrv_window w, CGRect rect)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineWindow* window = (WineWindow*)w;

    OnMainThreadAsync(^{
        [[window contentView] setNeedsDisplayInRect:NSRectFromCGRect(cgrect_mac_from_win(rect))];
    });

    [pool release];
}

/***********************************************************************
 *              macdrv_set_window_shape
 *
 * Sets the shape of a Cocoa window from an array of rectangles.  If
 * rects is NULL, resets the window's shape to its frame.
 */
void macdrv_set_window_shape(macdrv_window w, const CGRect *rects, int count)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineWindow* window = (WineWindow*)w;

    OnMainThread(^{
        if (!rects || !count)
        {
            window.shape = nil;
            window.shapeData = nil;
            [window checkEmptyShaped];
        }
        else
        {
            size_t length = sizeof(*rects) * count;
            if (window.shapeData.length != length || memcmp(window.shapeData.bytes, rects, length))
            {
                NSBezierPath* path;
                unsigned int i;

                path = [NSBezierPath bezierPath];
                for (i = 0; i < count; i++)
                    [path appendBezierPathWithRect:NSRectFromCGRect(cgrect_mac_from_win(rects[i]))];
                window.shape = path;
                window.shapeData = [NSData dataWithBytes:rects length:length];
                [window checkEmptyShaped];
            }
        }
    });

    [pool release];
}

/***********************************************************************
 *              macdrv_set_window_alpha
 */
void macdrv_set_window_alpha(macdrv_window w, CGFloat alpha)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineWindow* window = (WineWindow*)w;

    [window setAlphaValue:alpha];

    [pool release];
}

/***********************************************************************
 *              macdrv_set_window_color_key
 */
void macdrv_set_window_color_key(macdrv_window w, CGFloat keyRed, CGFloat keyGreen,
                                 CGFloat keyBlue)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineWindow* window = (WineWindow*)w;

    OnMainThread(^{
        window.colorKeyed       = TRUE;
        window.colorKeyRed      = keyRed;
        window.colorKeyGreen    = keyGreen;
        window.colorKeyBlue     = keyBlue;
        [window checkTransparency];
    });

    [pool release];
}

/***********************************************************************
 *              macdrv_clear_window_color_key
 */
void macdrv_clear_window_color_key(macdrv_window w)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineWindow* window = (WineWindow*)w;

    OnMainThread(^{
        window.colorKeyed = FALSE;
        [window checkTransparency];
    });

    [pool release];
}

/***********************************************************************
 *              macdrv_window_use_per_pixel_alpha
 */
void macdrv_window_use_per_pixel_alpha(macdrv_window w, int use_per_pixel_alpha)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineWindow* window = (WineWindow*)w;

    OnMainThread(^{
        window.usePerPixelAlpha = use_per_pixel_alpha;
        [window checkTransparency];
    });

    [pool release];
}

/***********************************************************************
 *              macdrv_give_cocoa_window_focus
 *
 * Makes the Cocoa window "key" (gives it keyboard focus).  This also
 * orders it front and, if its frame was not within the desktop bounds,
 * Cocoa will typically move it on-screen.
 */
void macdrv_give_cocoa_window_focus(macdrv_window w, int activate)
{
    WineWindow* window = (WineWindow*)w;

    OnMainThread(^{
        [window makeFocused:activate];
    });
}

/***********************************************************************
 *              macdrv_set_window_min_max_sizes
 *
 * Sets the window's minimum and maximum content sizes.
 */
void macdrv_set_window_min_max_sizes(macdrv_window w, CGSize min_size, CGSize max_size)
{
    WineWindow* window = (WineWindow*)w;

    OnMainThread(^{
        [window setWineMinSize:NSSizeFromCGSize(cgsize_mac_from_win(min_size)) maxSize:NSSizeFromCGSize(cgsize_mac_from_win(max_size))];
    });
}

/***********************************************************************
 *              macdrv_create_view
 *
 * Creates and returns a view with the specified frame rect.  The
 * caller is responsible for calling macdrv_dispose_view() on the view
 * when it is done with it.
 */
macdrv_view macdrv_create_view(CGRect rect)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    __block WineContentView* view;

    if (CGRectIsNull(rect)) rect = CGRectZero;

    OnMainThread(^{
        NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];

        view = [[WineContentView alloc] initWithFrame:NSRectFromCGRect(cgrect_mac_from_win(rect))];
        [view setAutoresizesSubviews:NO];
        [view setHidden:YES];
        [nc addObserver:view
               selector:@selector(updateGLContexts)
                   name:NSViewGlobalFrameDidChangeNotification
                 object:view];
        [nc addObserver:view
               selector:@selector(updateGLContexts)
                   name:NSApplicationDidChangeScreenParametersNotification
                 object:NSApp];
    });

    [pool release];
    return (macdrv_view)view;
}

/***********************************************************************
 *              macdrv_dispose_view
 *
 * Destroys a view previously returned by macdrv_create_view.
 */
void macdrv_dispose_view(macdrv_view v)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineContentView* view = (WineContentView*)v;

    OnMainThread(^{
        NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
        WineWindow* window = (WineWindow*)[view window];

        [nc removeObserver:view
                      name:NSViewGlobalFrameDidChangeNotification
                    object:view];
        [nc removeObserver:view
                      name:NSApplicationDidChangeScreenParametersNotification
                    object:NSApp];
        [view removeFromSuperview];
        [view release];
        [window updateForGLSubviews];
    });

    [pool release];
}

/***********************************************************************
 *              macdrv_set_view_frame
 */
void macdrv_set_view_frame(macdrv_view v, CGRect rect)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineContentView* view = (WineContentView*)v;

    if (CGRectIsNull(rect)) rect = CGRectZero;

    OnMainThread(^{
        NSRect newFrame = NSRectFromCGRect(cgrect_mac_from_win(rect));
        NSRect oldFrame = [view frame];

        if (!NSEqualRects(oldFrame, newFrame))
        {
            [[view superview] setNeedsDisplayInRect:oldFrame];
            if (NSEqualPoints(oldFrame.origin, newFrame.origin))
                [view setFrameSize:newFrame.size];
            else if (NSEqualSizes(oldFrame.size, newFrame.size))
                [view setFrameOrigin:newFrame.origin];
            else
                [view setFrame:newFrame];
            [view setNeedsDisplay:YES];

            if (retina_enabled)
            {
                int backing_size[2] = { 0 };
                [view wine_setBackingSize:backing_size];
            }
            [(WineWindow*)[view window] updateForGLSubviews];
        }
    });

    [pool release];
}

/***********************************************************************
 *              macdrv_set_view_superview
 *
 * Move a view to a new superview and position it relative to its
 * siblings.  If p is non-NULL, the view is ordered behind it.
 * Otherwise, the view is ordered above n.  If s is NULL, use the
 * content view of w as the new superview.
 */
void macdrv_set_view_superview(macdrv_view v, macdrv_view s, macdrv_window w, macdrv_view p, macdrv_view n)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineContentView* view = (WineContentView*)v;
    WineContentView* superview = (WineContentView*)s;
    WineWindow* window = (WineWindow*)w;
    WineContentView* prev = (WineContentView*)p;
    WineContentView* next = (WineContentView*)n;

    if (!superview)
        superview = [window contentView];

    OnMainThread(^{
        if (superview == [view superview])
        {
            NSArray* subviews = [superview subviews];
            NSUInteger index = [subviews indexOfObjectIdenticalTo:view];
            if (!prev && !next && index == [subviews count] - 1)
                return;
            if (prev && index + 1 < [subviews count] && [subviews objectAtIndex:index + 1] == prev)
                return;
            if (!prev && next && index > 0 && [subviews objectAtIndex:index - 1] == next)
                return;
        }

        WineWindow* oldWindow = (WineWindow*)[view window];
        WineWindow* newWindow = (WineWindow*)[superview window];

        if (prev)
            [superview addSubview:view positioned:NSWindowBelow relativeTo:prev];
        else
            [superview addSubview:view positioned:NSWindowAbove relativeTo:next];

        if (oldWindow != newWindow)
        {
            [oldWindow updateForGLSubviews];
            [newWindow updateForGLSubviews];
        }
    });

    [pool release];
}

/***********************************************************************
 *              macdrv_set_view_hidden
 */
void macdrv_set_view_hidden(macdrv_view v, int hidden)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineContentView* view = (WineContentView*)v;

    OnMainThread(^{
        [view setHidden:hidden];
    });

    [pool release];
}

/***********************************************************************
 *              macdrv_add_view_opengl_context
 *
 * Add an OpenGL context to the list being tracked for each view.
 */
void macdrv_add_view_opengl_context(macdrv_view v, macdrv_opengl_context c)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineContentView* view = (WineContentView*)v;
    WineOpenGLContext *context = (WineOpenGLContext*)c;

    OnMainThread(^{
        [view addGLContext:context];
    });

    [pool release];
}

/***********************************************************************
 *              macdrv_remove_view_opengl_context
 *
 * Add an OpenGL context to the list being tracked for each view.
 */
void macdrv_remove_view_opengl_context(macdrv_view v, macdrv_opengl_context c)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineContentView* view = (WineContentView*)v;
    WineOpenGLContext *context = (WineOpenGLContext*)c;

    OnMainThreadAsync(^{
        [view removeGLContext:context];
    });

    [pool release];
}

int macdrv_get_view_backing_size(macdrv_view v, int backing_size[2])
{
    WineContentView* view = (WineContentView*)v;

    if (![view isKindOfClass:[WineContentView class]])
        return FALSE;

    [view wine_getBackingSize:backing_size];
    return TRUE;
}

void macdrv_set_view_backing_size(macdrv_view v, const int backing_size[2])
{
    WineContentView* view = (WineContentView*)v;

    if ([view isKindOfClass:[WineContentView class]])
        [view wine_setBackingSize:backing_size];
}

/***********************************************************************
 *              macdrv_window_background_color
 *
 * Returns the standard Mac window background color as a 32-bit value of
 * the form 0x00rrggbb.
 */
uint32_t macdrv_window_background_color(void)
{
    static uint32_t result;
    static dispatch_once_t once;

    // Annoyingly, [NSColor windowBackgroundColor] refuses to convert to other
    // color spaces (RGB or grayscale).  So, the only way to get RGB values out
    // of it is to draw with it.
    dispatch_once(&once, ^{
        OnMainThread(^{
            unsigned char rgbx[4];
            unsigned char *planes = rgbx;
            NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&planes
                                                                               pixelsWide:1
                                                                               pixelsHigh:1
                                                                            bitsPerSample:8
                                                                          samplesPerPixel:3
                                                                                 hasAlpha:NO
                                                                                 isPlanar:NO
                                                                           colorSpaceName:NSCalibratedRGBColorSpace
                                                                             bitmapFormat:0
                                                                              bytesPerRow:4
                                                                             bitsPerPixel:32];
            [NSGraphicsContext saveGraphicsState];
            [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:bitmap]];
            [[NSColor windowBackgroundColor] set];
            NSRectFill(NSMakeRect(0, 0, 1, 1));
            [NSGraphicsContext restoreGraphicsState];
            [bitmap release];
            result = rgbx[0] << 16 | rgbx[1] << 8 | rgbx[2];
        });
    });

    return result;
}

/***********************************************************************
 *              macdrv_send_text_input_event
 */
void macdrv_send_text_input_event(int pressed, unsigned int flags, int repeat, int keyc, void* data, int* done)
{
    OnMainThreadAsync(^{
        BOOL ret;
        macdrv_event* event;
        WineWindow* window = (WineWindow*)[NSApp keyWindow];
        if (![window isKindOfClass:[WineWindow class]])
        {
            window = (WineWindow*)[NSApp mainWindow];
            if (![window isKindOfClass:[WineWindow class]])
                window = [[WineApplicationController sharedController] frontWineWindow];
        }

        if (window)
        {
            NSUInteger localFlags = flags;
            CGEventRef c;
            NSEvent* event;

            window.imeData = data;
            fix_device_modifiers_by_generic(&localFlags);

            // An NSEvent created with +keyEventWithType:... is internally marked
            // as synthetic and doesn't get sent through input methods.  But one
            // created from a CGEvent doesn't have that problem.
            c = CGEventCreateKeyboardEvent(NULL, keyc, pressed);
            CGEventSetFlags(c, localFlags);
            CGEventSetIntegerValueField(c, kCGKeyboardEventAutorepeat, repeat);
            event = [NSEvent eventWithCGEvent:c];
            CFRelease(c);

            window.commandDone = FALSE;
            ret = [[[window contentView] inputContext] handleEvent:event] && !window.commandDone;
        }
        else
            ret = FALSE;

        event = macdrv_create_event(SENT_TEXT_INPUT, window);
        event->sent_text_input.handled = ret;
        event->sent_text_input.done = done;
        [[window queue] postEvent:event];
        macdrv_release_event(event);
    });
}
