src/video/cocoa/SDL_cocoawindow.m
author Sam Lantinga <slouken@libsdl.org>
Thu, 20 Jan 2011 16:05:59 -0800
changeset 5056 8b7988f42fcb
parent 4937 24d44c7c4c63
child 5057 bdff53ed6c8b
permissions -rw-r--r--
Added the ability to get the UIKit window through the SDL API.
You can also do this through the native API:
UIWindow *window = [[UIApplication sharedApplication] keyWindow];

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