src/video/cocoa/SDL_cocoawindow.m
author Sam Lantinga <slouken@libsdl.org>
Thu, 10 Feb 2011 14:44:25 -0800
changeset 5246 58265e606e4e
parent 5061 9e9940eae455
child 5249 7a963be087ef
permissions -rw-r--r--
Window coordinates are in the global space and windows are not tied to a particular display.
Also added Ctrl-Enter keybinding to the test code to toggle fullscreen mode for testing.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2010 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #include "SDL_syswm.h"
    25 #include "../SDL_sysvideo.h"
    26 #include "../../events/SDL_keyboard_c.h"
    27 #include "../../events/SDL_mouse_c.h"
    28 #include "../../events/SDL_touch_c.h"
    29 #include "../../events/SDL_windowevents_c.h"
    30 #include "SDL_cocoavideo.h"
    31 #include "SDL_cocoashape.h"
    32 #include "SDL_cocoamouse.h"
    33 
    34 static __inline__ void ConvertNSRect(NSRect *r)
    35 {
    36     r->origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - r->origin.y - r->size.height;
    37 }
    38 
    39 @implementation Cocoa_WindowListener
    40 
    41 - (void)listen:(SDL_WindowData *)data
    42 {
    43     NSNotificationCenter *center;
    44 
    45     _data = data;
    46 
    47     center = [NSNotificationCenter defaultCenter];
    48 
    49     [_data->nswindow setNextResponder:self];
    50     if ([_data->nswindow delegate] != nil) {
    51         [center addObserver:self selector:@selector(windowDisExpose:) name:NSWindowDidExposeNotification object:_data->nswindow];
    52         [center addObserver:self selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:_data->nswindow];
    53         [center addObserver:self selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:_data->nswindow];
    54         [center addObserver:self selector:@selector(windowDidMiniaturize:) name:NSWindowDidMiniaturizeNotification object:_data->nswindow];
    55         [center addObserver:self selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification object:_data->nswindow];
    56         [center addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:_data->nswindow];
    57         [center addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:_data->nswindow];
    58     } else {
    59         [_data->nswindow setDelegate:self];
    60     }
    61 // FIXME: Why doesn't this work?
    62 //    [center addObserver:self selector:@selector(rightMouseDown:) name:[NSString stringWithCString:"rightMouseDown" encoding:NSUTF8StringEncoding] object:[_data->nswindow contentView]];
    63     [center addObserver:self selector:@selector(windowDidHide:) name:NSApplicationDidHideNotification object:NSApp];
    64     [center addObserver:self selector:@selector(windowDidUnhide:) name:NSApplicationDidUnhideNotification object:NSApp];
    65 
    66     [_data->nswindow setAcceptsMouseMovedEvents:YES];
    67 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
    68     [[_data->nswindow contentView] setAcceptsTouchEvents:YES];
    69 #endif
    70 }
    71 
    72 - (void)close
    73 {
    74     NSNotificationCenter *center;
    75 
    76     center = [NSNotificationCenter defaultCenter];
    77 
    78     [_data->nswindow setNextResponder:nil];
    79     if ([_data->nswindow delegate] != self) {
    80         [center removeObserver:self name:NSWindowDidExposeNotification object:_data->nswindow];
    81         [center removeObserver:self name:NSWindowDidMoveNotification object:_data->nswindow];
    82         [center removeObserver:self name:NSWindowDidResizeNotification object:_data->nswindow];
    83         [center removeObserver:self name:NSWindowDidMiniaturizeNotification object:_data->nswindow];
    84         [center removeObserver:self name:NSWindowDidDeminiaturizeNotification object:_data->nswindow];
    85         [center removeObserver:self name:NSWindowDidBecomeKeyNotification object:_data->nswindow];
    86         [center removeObserver:self name:NSWindowDidResignKeyNotification object:_data->nswindow];
    87     } else {
    88         [_data->nswindow setDelegate:nil];
    89     }
    90     [center removeObserver:self name:NSApplicationDidHideNotification object:NSApp];
    91     [center removeObserver:self name:NSApplicationDidUnhideNotification object:NSApp];
    92 }
    93 
    94 - (BOOL)windowShouldClose:(id)sender
    95 {
    96     SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
    97     return NO;
    98 }
    99 
   100 - (void)windowDidExpose:(NSNotification *)aNotification
   101 {
   102     SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0);
   103 }
   104 
   105 - (void)windowDidMove:(NSNotification *)aNotification
   106 {
   107     int x, y;
   108     NSRect rect = [_data->nswindow contentRectForFrameRect:[_data->nswindow frame]];
   109     ConvertNSRect(&rect);
   110     x = (int)rect.origin.x;
   111     y = (int)rect.origin.y;
   112     SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_MOVED, x, y);
   113 }
   114 
   115 - (void)windowDidResize:(NSNotification *)aNotification
   116 {
   117     int w, h;
   118     NSRect rect = [_data->nswindow contentRectForFrameRect:[_data->nswindow frame]];
   119     w = (int)rect.size.width;
   120     h = (int)rect.size.height;
   121     if (SDL_IsShapedWindow(_data->window))
   122         Cocoa_ResizeWindowShape(_data->window);
   123     SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_RESIZED, w, h);
   124 }
   125 
   126 - (void)windowDidMiniaturize:(NSNotification *)aNotification
   127 {
   128     SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
   129 }
   130 
   131 - (void)windowDidDeminiaturize:(NSNotification *)aNotification
   132 {
   133     SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_RESTORED, 0, 0);
   134 }
   135 
   136 - (void)windowDidBecomeKey:(NSNotification *)aNotification
   137 {
   138     /* We're going to get keyboard events, since we're key. */
   139     SDL_SetKeyboardFocus(_data->window);
   140 
   141     /* Check to see if someone updated the clipboard */
   142     Cocoa_CheckClipboardUpdate(_data->videodata);
   143 }
   144 
   145 - (void)windowDidResignKey:(NSNotification *)aNotification
   146 {
   147     /* Some other window will get mouse events, since we're not key. */
   148     if (SDL_GetMouseFocus() == _data->window) {
   149         SDL_SetMouseFocus(NULL);
   150     }
   151 
   152     /* Some other window will get keyboard events, since we're not key. */
   153     if (SDL_GetKeyboardFocus() == _data->window) {
   154         SDL_SetKeyboardFocus(NULL);
   155     }
   156 }
   157 
   158 - (void)windowDidHide:(NSNotification *)aNotification
   159 {
   160     SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
   161 }
   162 
   163 - (void)windowDidUnhide:(NSNotification *)aNotification
   164 {
   165     SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
   166 }
   167 
   168 - (void)mouseDown:(NSEvent *)theEvent
   169 {
   170     int button;
   171 
   172     switch ([theEvent buttonNumber]) {
   173     case 0:
   174         button = SDL_BUTTON_LEFT;
   175         break;
   176     case 1:
   177         button = SDL_BUTTON_RIGHT;
   178         break;
   179     case 2:
   180         button = SDL_BUTTON_MIDDLE;
   181         break;
   182     default:
   183         button = [theEvent buttonNumber] + 1;
   184         break;
   185     }
   186     SDL_SendMouseButton(_data->window, SDL_PRESSED, button);
   187 }
   188 
   189 - (void)rightMouseDown:(NSEvent *)theEvent
   190 {
   191     [self mouseDown:theEvent];
   192 }
   193 
   194 - (void)otherMouseDown:(NSEvent *)theEvent
   195 {
   196     [self mouseDown:theEvent];
   197 }
   198 
   199 - (void)mouseUp:(NSEvent *)theEvent
   200 {
   201     int button;
   202 
   203     switch ([theEvent buttonNumber]) {
   204     case 0:
   205         button = SDL_BUTTON_LEFT;
   206         break;
   207     case 1:
   208         button = SDL_BUTTON_RIGHT;
   209         break;
   210     case 2:
   211         button = SDL_BUTTON_MIDDLE;
   212         break;
   213     default:
   214         button = [theEvent buttonNumber] + 1;
   215         break;
   216     }
   217     SDL_SendMouseButton(_data->window, SDL_RELEASED, button);
   218 }
   219 
   220 - (void)rightMouseUp:(NSEvent *)theEvent
   221 {
   222     [self mouseUp:theEvent];
   223 }
   224 
   225 - (void)otherMouseUp:(NSEvent *)theEvent
   226 {
   227     [self mouseUp:theEvent];
   228 }
   229 
   230 - (void)mouseMoved:(NSEvent *)theEvent
   231 {
   232     SDL_Window *window = _data->window;
   233     NSPoint point;
   234 
   235     if (window->flags & SDL_WINDOW_FULLSCREEN)
   236         return;
   237 
   238     point = [theEvent locationInWindow];
   239     point.y = window->h - point.y;
   240     if ( point.x < 0 || point.x >= window->w ||
   241          point.y < 0 || point.y >= window->h ) {
   242         if (SDL_GetMouseFocus() == window) {
   243             SDL_SetMouseFocus(NULL);
   244         }
   245     } else {
   246         SDL_SendMouseMotion(window, 0, (int)point.x, (int)point.y);
   247     }
   248 }
   249 
   250 - (void)mouseDragged:(NSEvent *)theEvent
   251 {
   252     [self mouseMoved:theEvent];
   253 }
   254 
   255 - (void)rightMouseDragged:(NSEvent *)theEvent
   256 {
   257     [self mouseMoved:theEvent];
   258 }
   259 
   260 - (void)otherMouseDragged:(NSEvent *)theEvent
   261 {
   262     [self mouseMoved:theEvent];
   263 }
   264 
   265 - (void)scrollWheel:(NSEvent *)theEvent
   266 {
   267     Cocoa_HandleMouseWheel(_data->window, theEvent);
   268 }
   269 
   270 - (void)touchesBeganWithEvent:(NSEvent *) theEvent
   271 {
   272     [self handleTouches:COCOA_TOUCH_DOWN withEvent:theEvent];
   273 }
   274 
   275 - (void)touchesMovedWithEvent:(NSEvent *) theEvent
   276 {
   277     [self handleTouches:COCOA_TOUCH_MOVE withEvent:theEvent];
   278 }
   279 
   280 - (void)touchesEndedWithEvent:(NSEvent *) theEvent
   281 {
   282     [self handleTouches:COCOA_TOUCH_UP withEvent:theEvent];
   283 }
   284 
   285 - (void)touchesCancelledWithEvent:(NSEvent *) theEvent
   286 {
   287     [self handleTouches:COCOA_TOUCH_CANCELLED withEvent:theEvent];
   288 }
   289 
   290 - (void)handleTouches:(cocoaTouchType)type withEvent:(NSEvent *)event
   291 {
   292 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
   293     NSSet *touches = 0;
   294     NSEnumerator *enumerator;
   295     NSTouch *touch;
   296 
   297     switch (type) {
   298         case COCOA_TOUCH_DOWN:
   299             touches = [event touchesMatchingPhase:NSTouchPhaseBegan inView:nil];
   300             break;
   301         case COCOA_TOUCH_UP:
   302         case COCOA_TOUCH_CANCELLED:
   303             touches = [event touchesMatchingPhase:NSTouchPhaseEnded inView:nil];
   304             break;
   305         case COCOA_TOUCH_MOVE:
   306             touches = [event touchesMatchingPhase:NSTouchPhaseMoved inView:nil];
   307             break;
   308     }
   309 
   310     enumerator = [touches objectEnumerator];
   311     touch = (NSTouch*)[enumerator nextObject];
   312     while (touch) {
   313         SDL_TouchID touchId = (SDL_TouchID)[touch device];
   314         if (!SDL_GetTouch(touchId)) {
   315             SDL_Touch touch;
   316 
   317             touch.id = touchId;
   318             touch.x_min = 0;
   319             touch.x_max = 1;
   320             touch.native_xres = touch.x_max - touch.x_min;
   321             touch.y_min = 0;
   322             touch.y_max = 1;
   323             touch.native_yres = touch.y_max - touch.y_min;
   324             touch.pressure_min = 0;
   325             touch.pressure_max = 1;
   326             touch.native_pressureres = touch.pressure_max - touch.pressure_min;
   327             
   328             if (SDL_AddTouch(&touch, "") < 0) {
   329                 return;
   330             }
   331         } 
   332 
   333         SDL_FingerID fingerId = (SDL_FingerID)[touch identity];
   334         float x = [touch normalizedPosition].x;
   335         float y = [touch normalizedPosition].y;
   336 	/* Make the origin the upper left instead of the lower left */
   337 	y = 1.0f - y;
   338 
   339         switch (type) {
   340         case COCOA_TOUCH_DOWN:
   341             SDL_SendFingerDown(touchId, fingerId, SDL_TRUE, x, y, 1);
   342             break;
   343         case COCOA_TOUCH_UP:
   344         case COCOA_TOUCH_CANCELLED:
   345             SDL_SendFingerDown(touchId, fingerId, SDL_FALSE, x, y, 1);
   346             break;
   347         case COCOA_TOUCH_MOVE:
   348             SDL_SendTouchMotion(touchId, fingerId, SDL_FALSE, x, y, 1);
   349             break;
   350         }
   351         
   352         touch = (NSTouch*)[enumerator nextObject];
   353     }
   354 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 */
   355 }
   356 
   357 @end
   358 
   359 @interface SDLWindow : NSWindow
   360 /* These are needed for borderless/fullscreen windows */
   361 - (BOOL)canBecomeKeyWindow;
   362 - (BOOL)canBecomeMainWindow;
   363 @end
   364 
   365 @implementation SDLWindow
   366 - (BOOL)canBecomeKeyWindow
   367 {
   368     return YES;
   369 }
   370 
   371 - (BOOL)canBecomeMainWindow
   372 {
   373     return YES;
   374 }
   375 @end
   376 
   377 @interface SDLView : NSView {
   378     Cocoa_WindowListener *listener;
   379 }
   380 @end
   381 
   382 @implementation SDLView
   383 
   384 - (id) initWithFrame: (NSRect) rect
   385             listener: (Cocoa_WindowListener *) theListener
   386 {
   387     if (self = [super initWithFrame:rect]) {
   388         listener = theListener;
   389     }
   390 
   391     return self;
   392 }
   393 
   394 - (void)rightMouseDown:(NSEvent *)theEvent
   395 {
   396     [listener mouseDown:theEvent];
   397 }
   398 
   399 @end
   400 
   401 static int
   402 SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created)
   403 {
   404     NSAutoreleasePool *pool;
   405     SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
   406     SDL_WindowData *data;
   407 
   408     /* Allocate the window data */
   409     data = (SDL_WindowData *) SDL_malloc(sizeof(*data));
   410     if (!data) {
   411         SDL_OutOfMemory();
   412         return -1;
   413     }
   414     data->window = window;
   415     data->nswindow = nswindow;
   416     data->created = created;
   417     data->videodata = videodata;
   418 
   419     pool = [[NSAutoreleasePool alloc] init];
   420 
   421     /* Create an event listener for the window */
   422     data->listener = [[Cocoa_WindowListener alloc] init];
   423     [data->listener listen:data];
   424 
   425     /* Fill in the SDL window with the window data */
   426     {
   427         SDL_Rect bounds;
   428         NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
   429         NSView *contentView = [[SDLView alloc] initWithFrame: rect
   430                                                     listener: data->listener];
   431 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
   432         [contentView setAcceptsTouchEvents:YES];
   433 #endif
   434         [nswindow setContentView: contentView];
   435         [contentView release];
   436 
   437         ConvertNSRect(&rect);
   438         window->x = (int)rect.origin.x;
   439         window->y = (int)rect.origin.y;
   440         window->w = (int)rect.size.width;
   441         window->h = (int)rect.size.height;
   442     }
   443     if ([nswindow isVisible]) {
   444         window->flags |= SDL_WINDOW_SHOWN;
   445     } else {
   446         window->flags &= ~SDL_WINDOW_SHOWN;
   447     }
   448     {
   449         unsigned int style = [nswindow styleMask];
   450 
   451         if ((style & ~NSResizableWindowMask) == NSBorderlessWindowMask) {
   452             window->flags |= SDL_WINDOW_BORDERLESS;
   453         } else {
   454             window->flags &= ~SDL_WINDOW_BORDERLESS;
   455         }
   456         if (style & NSResizableWindowMask) {
   457             window->flags |= SDL_WINDOW_RESIZABLE;
   458         } else {
   459             window->flags &= ~SDL_WINDOW_RESIZABLE;
   460         }
   461     }
   462     if ([nswindow isZoomed]) {
   463         window->flags |= SDL_WINDOW_MAXIMIZED;
   464     } else {
   465         window->flags &= ~SDL_WINDOW_MAXIMIZED;
   466     }
   467     if ([nswindow isMiniaturized]) {
   468         window->flags |= SDL_WINDOW_MINIMIZED;
   469     } else {
   470         window->flags &= ~SDL_WINDOW_MINIMIZED;
   471     }
   472     if ([nswindow isKeyWindow]) {
   473         window->flags |= SDL_WINDOW_INPUT_FOCUS;
   474         SDL_SetKeyboardFocus(data->window);
   475 
   476         if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
   477             /* FIXME */
   478         }
   479     }
   480 
   481     /* All done! */
   482     [pool release];
   483     window->driverdata = data;
   484     return 0;
   485 }
   486 
   487 int
   488 Cocoa_CreateWindow(_THIS, SDL_Window * window)
   489 {
   490     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   491     NSWindow *nswindow;
   492     SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
   493     NSRect rect;
   494     SDL_Rect bounds;
   495     unsigned int style;
   496 
   497     Cocoa_GetDisplayBounds(_this, display, &bounds);
   498     if ((window->flags & SDL_WINDOW_FULLSCREEN)
   499         || SDL_WINDOWPOS_ISCENTERED(window->x)) {
   500         rect.origin.x = bounds.x + (bounds.w - window->w) / 2;
   501     } else if (SDL_WINDOWPOS_ISUNDEFINED(window->x)) {
   502         rect.origin.x = bounds.x;
   503     } else {
   504         rect.origin.x = window->x;
   505     }
   506     if ((window->flags & SDL_WINDOW_FULLSCREEN)
   507         || SDL_WINDOWPOS_ISCENTERED(window->y)) {
   508         rect.origin.y = bounds.y + (bounds.h - window->h) / 2;
   509     } else if (SDL_WINDOWPOS_ISUNDEFINED(window->y)) {
   510         rect.origin.y = bounds.y;
   511     } else {
   512         rect.origin.y = window->y;
   513     }
   514     rect.size.width = window->w;
   515     rect.size.height = window->h;
   516     ConvertNSRect(&rect);
   517 
   518     if (window->flags & SDL_WINDOW_BORDERLESS) {
   519         style = NSBorderlessWindowMask;
   520     } else {
   521         style = (NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask);
   522     }
   523     if (window->flags & SDL_WINDOW_RESIZABLE) {
   524         style |= NSResizableWindowMask;
   525     }
   526 
   527     /* Figure out which screen to place this window */
   528     NSArray *screens = [NSScreen screens];
   529     NSScreen *screen = nil;
   530     NSScreen *candidate;
   531     int i, count = [screens count];
   532     for (i = 0; i < count; ++i) {
   533         candidate = [screens objectAtIndex:i];
   534         NSRect screenRect = [candidate frame];
   535         if (rect.origin.x >= screenRect.origin.x &&
   536             rect.origin.x < screenRect.origin.x + screenRect.size.width &&
   537             rect.origin.y >= screenRect.origin.y &&
   538             rect.origin.y < screenRect.origin.y + screenRect.size.height) {
   539             screen = candidate;
   540             rect.origin.x -= screenRect.origin.x;
   541             rect.origin.y -= screenRect.origin.y;
   542         }
   543     }
   544     nswindow = [[SDLWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:FALSE screen:screen];
   545 
   546     [pool release];
   547 
   548     if (SetupWindowData(_this, window, nswindow, SDL_TRUE) < 0) {
   549         [nswindow release];
   550         return -1;
   551     }
   552     return 0;
   553 }
   554 
   555 int
   556 Cocoa_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
   557 {
   558     NSAutoreleasePool *pool;
   559     NSWindow *nswindow = (NSWindow *) data;
   560     NSString *title;
   561 
   562     pool = [[NSAutoreleasePool alloc] init];
   563 
   564     /* Query the title from the existing window */
   565     title = [nswindow title];
   566     if (title) {
   567         window->title = SDL_strdup([title UTF8String]);
   568     }
   569 
   570     [pool release];
   571 
   572     return SetupWindowData(_this, window, nswindow, SDL_FALSE);
   573 }
   574 
   575 void
   576 Cocoa_SetWindowTitle(_THIS, SDL_Window * window)
   577 {
   578     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   579     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
   580     NSString *string;
   581 
   582     if(window->title) {
   583         string = [[NSString alloc] initWithUTF8String:window->title];
   584     } else {
   585         string = [[NSString alloc] init];
   586     }
   587     [nswindow setTitle:string];
   588     [string release];
   589 
   590     [pool release];
   591 }
   592 
   593 void
   594 Cocoa_SetWindowPosition(_THIS, SDL_Window * window)
   595 {
   596     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   597     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
   598     SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
   599     NSRect rect;
   600     SDL_Rect bounds;
   601 
   602     Cocoa_GetDisplayBounds(_this, display, &bounds);
   603     if ((window->flags & SDL_WINDOW_FULLSCREEN)
   604         || SDL_WINDOWPOS_ISCENTERED(window->x)) {
   605         rect.origin.x = bounds.x + (bounds.w - window->w) / 2;
   606     } else {
   607         rect.origin.x = window->x;
   608     }
   609     if ((window->flags & SDL_WINDOW_FULLSCREEN)
   610         || SDL_WINDOWPOS_ISCENTERED(window->y)) {
   611         rect.origin.y = bounds.y + (bounds.h - window->h) / 2;
   612     } else {
   613         rect.origin.y = window->y;
   614     }
   615     rect.size.width = window->w;
   616     rect.size.height = window->h;
   617     ConvertNSRect(&rect);
   618     rect = [nswindow frameRectForContentRect:rect];
   619     [nswindow setFrameOrigin:rect.origin];
   620     [pool release];
   621 }
   622 
   623 void
   624 Cocoa_SetWindowSize(_THIS, SDL_Window * window)
   625 {
   626     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   627     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
   628     NSSize size;
   629 
   630     size.width = window->w;
   631     size.height = window->h;
   632     [nswindow setContentSize:size];
   633     [pool release];
   634 }
   635 
   636 void
   637 Cocoa_ShowWindow(_THIS, SDL_Window * window)
   638 {
   639     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   640     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
   641 
   642     if (![nswindow isMiniaturized]) {
   643         [nswindow makeKeyAndOrderFront:nil];
   644     }
   645     [pool release];
   646 }
   647 
   648 void
   649 Cocoa_HideWindow(_THIS, SDL_Window * window)
   650 {
   651     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   652     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
   653 
   654     [nswindow orderOut:nil];
   655     [pool release];
   656 }
   657 
   658 void
   659 Cocoa_RaiseWindow(_THIS, SDL_Window * window)
   660 {
   661     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   662     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
   663 
   664     [nswindow makeKeyAndOrderFront:nil];
   665     [pool release];
   666 }
   667 
   668 void
   669 Cocoa_MaximizeWindow(_THIS, SDL_Window * window)
   670 {
   671     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   672     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
   673 
   674     [nswindow zoom:nil];
   675     [pool release];
   676 }
   677 
   678 void
   679 Cocoa_MinimizeWindow(_THIS, SDL_Window * window)
   680 {
   681     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   682     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
   683 
   684     [nswindow miniaturize:nil];
   685     [pool release];
   686 }
   687 
   688 void
   689 Cocoa_RestoreWindow(_THIS, SDL_Window * window)
   690 {
   691     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   692     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
   693 
   694     if ([nswindow isMiniaturized]) {
   695         [nswindow deminiaturize:nil];
   696     } else if ([nswindow isZoomed]) {
   697         [nswindow zoom:nil];
   698     }
   699     [pool release];
   700 }
   701 
   702 void
   703 Cocoa_SetWindowGrab(_THIS, SDL_Window * window)
   704 {
   705     if ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&
   706         (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
   707         /* FIXME: Grab mouse */
   708     } else {
   709         /* FIXME: Release mouse */
   710     }
   711 }
   712 
   713 void
   714 Cocoa_DestroyWindow(_THIS, SDL_Window * window)
   715 {
   716     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   717     SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
   718 
   719     if (data) {
   720         [data->listener close];
   721         [data->listener release];
   722         if (data->created) {
   723             [data->nswindow close];
   724         }
   725         SDL_free(data);
   726     }
   727     [pool release];
   728 }
   729 
   730 SDL_bool
   731 Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
   732 {
   733     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
   734 
   735     if (info->version.major <= SDL_MAJOR_VERSION) {
   736         info->subsystem = SDL_SYSWM_COCOA;
   737         info->info.cocoa.window = nswindow;
   738         return SDL_TRUE;
   739     } else {
   740         SDL_SetError("Application not compiled with SDL %d.%d\n",
   741                      SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
   742         return SDL_FALSE;
   743     }
   744 }
   745 
   746 /* vi: set ts=4 sw=4 expandtab: */