src/video/cocoa/SDL_cocoawindow.m
author Sam Lantinga <slouken@libsdl.org>
Tue, 01 Dec 2009 11:50:00 +0000
changeset 3506 e829b6098435
parent 3414 1e45c3012a4f
child 3507 3712547eac4f
permissions -rw-r--r--
Added support for placing windows on different displays
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2009 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_windowevents_c.h"
    29 
    30 #include "SDL_cocoavideo.h"
    31 
    32 static __inline__ void ConvertNSRect(NSRect *r)
    33 {
    34     r->origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - r->origin.y - r->size.height;
    35 }
    36 
    37 @implementation Cocoa_WindowListener
    38 
    39 - (void)listen:(SDL_WindowData *)data
    40 {
    41     NSNotificationCenter *center;
    42 
    43     _data = data;
    44 
    45     center = [NSNotificationCenter defaultCenter];
    46 
    47     [_data->window setNextResponder:self];
    48     if ([_data->window delegate] != nil) {
    49         [center addObserver:self selector:@selector(windowDisExpose:) name:NSWindowDidExposeNotification object:_data->window];
    50         [center addObserver:self selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:_data->window];
    51         [center addObserver:self selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:_data->window];
    52         [center addObserver:self selector:@selector(windowDidMiniaturize:) name:NSWindowDidMiniaturizeNotification object:_data->window];
    53         [center addObserver:self selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification object:_data->window];
    54         [center addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:_data->window];
    55         [center addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:_data->window];
    56     } else {
    57         [_data->window setDelegate:self];
    58     }
    59     [center addObserver:self selector:@selector(windowDidHide:) name:NSApplicationDidHideNotification object:NSApp];
    60     [center addObserver:self selector:@selector(windowDidUnhide:) name:NSApplicationDidUnhideNotification object:NSApp];
    61 
    62     [_data->window setAcceptsMouseMovedEvents:YES];
    63 }
    64 
    65 - (void)close
    66 {
    67     NSNotificationCenter *center;
    68 
    69     center = [NSNotificationCenter defaultCenter];
    70 
    71     [_data->window setNextResponder:nil];
    72     if ([_data->window delegate] != self) {
    73         [center removeObserver:self name:NSWindowDidExposeNotification object:_data->window];
    74         [center removeObserver:self name:NSWindowDidMoveNotification object:_data->window];
    75         [center removeObserver:self name:NSWindowDidResizeNotification object:_data->window];
    76         [center removeObserver:self name:NSWindowDidMiniaturizeNotification object:_data->window];
    77         [center removeObserver:self name:NSWindowDidDeminiaturizeNotification object:_data->window];
    78         [center removeObserver:self name:NSWindowDidBecomeKeyNotification object:_data->window];
    79         [center removeObserver:self name:NSWindowDidResignKeyNotification object:_data->window];
    80     } else {
    81         [_data->window setDelegate:nil];
    82     }
    83     [center removeObserver:self name:NSApplicationDidHideNotification object:NSApp];
    84     [center removeObserver:self name:NSApplicationDidUnhideNotification object:NSApp];
    85 }
    86 
    87 - (BOOL)windowShouldClose:(id)sender
    88 {
    89     SDL_SendWindowEvent(_data->windowID, SDL_WINDOWEVENT_CLOSE, 0, 0);
    90     return NO;
    91 }
    92 
    93 - (void)windowDidExpose:(NSNotification *)aNotification
    94 {
    95     SDL_SendWindowEvent(_data->windowID, SDL_WINDOWEVENT_EXPOSED, 0, 0);
    96 }
    97 
    98 - (void)windowDidMove:(NSNotification *)aNotification
    99 {
   100     int x, y;
   101     NSRect disp = CGDisplayBounds(_data->display);
   102     NSRect rect = [_data->window contentRectForFrameRect:[_data->window frame]];
   103     ConvertNSRect(&rect);
   104     x = (int)rect.origin.x - disp.origin.x;
   105     y = (int)rect.origin.y - disp.origin.y;
   106     SDL_SendWindowEvent(_data->windowID, SDL_WINDOWEVENT_MOVED, x, y);
   107 }
   108 
   109 - (void)windowDidResize:(NSNotification *)aNotification
   110 {
   111     int w, h;
   112     NSRect rect = [_data->window contentRectForFrameRect:[_data->window frame]];
   113     w = (int)rect.size.width;
   114     h = (int)rect.size.height;
   115     SDL_SendWindowEvent(_data->windowID, SDL_WINDOWEVENT_RESIZED, w, h);
   116 }
   117 
   118 - (void)windowDidMiniaturize:(NSNotification *)aNotification
   119 {
   120     SDL_SendWindowEvent(_data->windowID, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
   121 }
   122 
   123 - (void)windowDidDeminiaturize:(NSNotification *)aNotification
   124 {
   125     SDL_SendWindowEvent(_data->windowID, SDL_WINDOWEVENT_RESTORED, 0, 0);
   126 }
   127 
   128 - (void)windowDidBecomeKey:(NSNotification *)aNotification
   129 {
   130     int index;
   131 
   132     /* We're going to get keyboard events, since we're key. */
   133     index = _data->videodata->keyboard;
   134     SDL_SetKeyboardFocus(index, _data->windowID);
   135 }
   136 
   137 - (void)windowDidResignKey:(NSNotification *)aNotification
   138 {
   139     int index;
   140     SDL_Mouse *mouse;
   141 
   142     /* Some other window will get mouse events, since we're not key. */
   143     index = _data->videodata->mouse;
   144     mouse = SDL_GetMouse(index);
   145     if (mouse->focus == _data->windowID) {
   146         SDL_SetMouseFocus(index, 0);
   147     }
   148 
   149     /* Some other window will get keyboard events, since we're not key. */
   150     index = _data->videodata->keyboard;
   151     SDL_SetKeyboardFocus(index, 0);
   152 }
   153 
   154 - (void)windowDidHide:(NSNotification *)aNotification
   155 {
   156     SDL_SendWindowEvent(_data->windowID, SDL_WINDOWEVENT_HIDDEN, 0, 0);
   157 }
   158 
   159 - (void)windowDidUnhide:(NSNotification *)aNotification
   160 {
   161     SDL_SendWindowEvent(_data->windowID, SDL_WINDOWEVENT_SHOWN, 0, 0);
   162 }
   163 
   164 - (void)mouseDown:(NSEvent *)theEvent
   165 {
   166     int index;
   167     int button;
   168 
   169     index = _data->videodata->mouse;
   170     switch ([theEvent buttonNumber]) {
   171     case 0:
   172         button = SDL_BUTTON_LEFT;
   173         break;
   174     case 1:
   175         button = SDL_BUTTON_RIGHT;
   176         break;
   177     case 2:
   178         button = SDL_BUTTON_MIDDLE;
   179         break;
   180     default:
   181         button = [theEvent buttonNumber];
   182         break;
   183     }
   184     SDL_SendMouseButton(index, SDL_PRESSED, button);
   185 }
   186 
   187 - (void)rightMouseDown:(NSEvent *)theEvent
   188 {
   189     [self mouseDown:theEvent];
   190 }
   191 
   192 - (void)otherMouseDown:(NSEvent *)theEvent
   193 {
   194     [self mouseDown:theEvent];
   195 }
   196 
   197 - (void)mouseUp:(NSEvent *)theEvent
   198 {
   199     int index;
   200     int button;
   201 
   202     index = _data->videodata->mouse;
   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];
   215         break;
   216     }
   217     SDL_SendMouseButton(index, 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 = SDL_GetWindowFromID(_data->windowID);
   233     int index;
   234     SDL_Mouse *mouse;
   235     NSPoint point;
   236     NSRect rect;
   237 
   238     index = _data->videodata->mouse;
   239     mouse = SDL_GetMouse(index);
   240 
   241     point = [NSEvent mouseLocation];
   242     if ( (window->flags & SDL_WINDOW_FULLSCREEN) ) {
   243         rect.size.width = CGDisplayPixelsWide(kCGDirectMainDisplay);
   244         rect.size.height = CGDisplayPixelsHigh(kCGDirectMainDisplay);
   245         point.x = point.x - rect.origin.x;
   246         point.y = rect.size.height - point.y;
   247     } else {
   248         rect = [_data->window contentRectForFrameRect:[_data->window frame]];
   249         point.y = rect.size.height - (point.y - rect.origin.y);
   250     }
   251     if ( point.x < 0 || point.x >= rect.size.width ||
   252          point.y < 0 || point.y >= rect.size.height ) {
   253         if (mouse->focus != 0) {
   254             SDL_SetMouseFocus(index, 0);
   255         }
   256     } else {
   257         if (mouse->focus != _data->windowID) {
   258             SDL_SetMouseFocus(index, _data->windowID);
   259         }
   260         SDL_SendMouseMotion(index, 0, (int)point.x, (int)point.y, 0);
   261     }
   262 }
   263 
   264 - (void)mouseDragged:(NSEvent *)theEvent
   265 {
   266     [self mouseMoved:theEvent];
   267 }
   268 
   269 - (void)rightMouseDragged:(NSEvent *)theEvent
   270 {
   271     [self mouseMoved:theEvent];
   272 }
   273 
   274 - (void)otherMouseDragged:(NSEvent *)theEvent
   275 {
   276     [self mouseMoved:theEvent];
   277 }
   278 
   279 - (void)scrollWheel:(NSEvent *)theEvent
   280 {
   281     int index;
   282 
   283     index = _data->videodata->mouse;
   284     SDL_SendMouseWheel(index, (int)([theEvent deltaX]+0.9f), (int)([theEvent deltaY]+0.9f));
   285 }
   286 
   287 @end
   288 
   289 @interface SDLWindow : NSWindow
   290 /* These are needed for borderless/fullscreen windows */
   291 - (BOOL)canBecomeKeyWindow;
   292 - (BOOL)canBecomeMainWindow;
   293 @end
   294 
   295 @implementation SDLWindow
   296 - (BOOL)canBecomeKeyWindow
   297 {
   298     return YES;
   299 }
   300 
   301 - (BOOL)canBecomeMainWindow
   302 {
   303     return YES;
   304 }
   305 @end
   306 
   307 static int
   308 SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created)
   309 {
   310     NSAutoreleasePool *pool;
   311     SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
   312     SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayFromWindow(window)->driverdata;
   313     SDL_WindowData *data;
   314 
   315     /* Allocate the window data */
   316     data = (SDL_WindowData *) SDL_malloc(sizeof(*data));
   317     if (!data) {
   318         SDL_OutOfMemory();
   319         return -1;
   320     }
   321     data->windowID = window->id;
   322     data->window = nswindow;
   323     data->created = created;
   324     data->display = displaydata->display;
   325     data->videodata = videodata;
   326 
   327     pool = [[NSAutoreleasePool alloc] init];
   328 
   329     /* Create an event listener for the window */
   330     data->listener = [[Cocoa_WindowListener alloc] init];
   331     [data->listener listen:data];
   332 
   333     /* Fill in the SDL window with the window data */
   334     {
   335         NSRect disp = CGDisplayBounds(data->display);
   336         NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
   337         ConvertNSRect(&rect);
   338         window->x = (int)rect.origin.x - disp.origin.x;
   339         window->y = (int)rect.origin.y - disp.origin.y;
   340         window->w = (int)rect.size.width;
   341         window->h = (int)rect.size.height;
   342     }
   343     if ([nswindow isVisible]) {
   344         window->flags |= SDL_WINDOW_SHOWN;
   345     } else {
   346         window->flags &= ~SDL_WINDOW_SHOWN;
   347     }
   348     {
   349         unsigned int style = [nswindow styleMask];
   350 
   351         if ((style & ~NSResizableWindowMask) == NSBorderlessWindowMask) {
   352             window->flags |= SDL_WINDOW_BORDERLESS;
   353         } else {
   354             window->flags &= ~SDL_WINDOW_BORDERLESS;
   355         }
   356         if (style & NSResizableWindowMask) {
   357             window->flags |= SDL_WINDOW_RESIZABLE;
   358         } else {
   359             window->flags &= ~SDL_WINDOW_RESIZABLE;
   360         }
   361     }
   362     if ([nswindow isZoomed]) {
   363         window->flags |= SDL_WINDOW_MAXIMIZED;
   364     } else {
   365         window->flags &= ~SDL_WINDOW_MAXIMIZED;
   366     }
   367     if ([nswindow isMiniaturized]) {
   368         window->flags |= SDL_WINDOW_MINIMIZED;
   369     } else {
   370         window->flags &= ~SDL_WINDOW_MINIMIZED;
   371     }
   372     if ([nswindow isKeyWindow]) {
   373         int index = data->videodata->keyboard;
   374         window->flags |= SDL_WINDOW_INPUT_FOCUS;
   375         SDL_SetKeyboardFocus(index, data->windowID);
   376 
   377         if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
   378             /* FIXME */
   379         }
   380     }
   381 
   382     /* All done! */
   383     [pool release];
   384     window->driverdata = data;
   385     return 0;
   386 }
   387 
   388 int
   389 Cocoa_CreateWindow(_THIS, SDL_Window * window)
   390 {
   391     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   392     NSWindow *nswindow;
   393     SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayFromWindow(window)->driverdata;
   394     NSRect rect;
   395     unsigned int style;
   396     NSString *title;
   397     int status;
   398 
   399     rect = CGDisplayBounds(displaydata->display);
   400     if ((window->flags & SDL_WINDOW_FULLSCREEN)
   401         || window->x == SDL_WINDOWPOS_CENTERED) {
   402         rect.origin.x += (rect.size.width - window->w) / 2;
   403     } else if (window->x != SDL_WINDOWPOS_UNDEFINED) {
   404         rect.origin.x += window->x;
   405     }
   406     if ((window->flags & SDL_WINDOW_FULLSCREEN)
   407         || window->y == SDL_WINDOWPOS_CENTERED) {
   408         rect.origin.y += (rect.size.height - window->h) / 2;
   409     } else if (window->x != SDL_WINDOWPOS_UNDEFINED) {
   410         rect.origin.y += window->y;
   411     }
   412     rect.size.width = window->w;
   413     rect.size.height = window->h;
   414     ConvertNSRect(&rect);
   415 
   416     if (window->flags & SDL_WINDOW_BORDERLESS) {
   417         style = NSBorderlessWindowMask;
   418     } else {
   419         style = (NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask);
   420     }
   421     if (window->flags & SDL_WINDOW_RESIZABLE) {
   422         style |= NSResizableWindowMask;
   423     }
   424 
   425     /* Figure out which screen to place this window */
   426     NSArray *screens = [NSScreen screens];
   427     NSScreen *screen = nil;
   428     NSScreen *candidate;
   429     for (candidate in screens) {
   430         NSRect screenRect = [candidate frame];
   431         if (rect.origin.x >= screenRect.origin.x &&
   432             rect.origin.x < screenRect.origin.x + screenRect.size.width &&
   433             rect.origin.y >= screenRect.origin.y &&
   434             rect.origin.y < screenRect.origin.y + screenRect.size.height) {
   435             screen = candidate;
   436             rect.origin.x -= screenRect.origin.x;
   437             rect.origin.y -= screenRect.origin.y;
   438         }
   439     }
   440     nswindow = [[SDLWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:FALSE screen:screen];
   441 
   442     [pool release];
   443 
   444     if (SetupWindowData(_this, window, nswindow, SDL_TRUE) < 0) {
   445         [nswindow release];
   446         return -1;
   447     }
   448     return 0;
   449 }
   450 
   451 int
   452 Cocoa_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
   453 {
   454     NSAutoreleasePool *pool;
   455     NSWindow *nswindow = (NSWindow *) data;
   456     NSString *title;
   457     int status;
   458 
   459     pool = [[NSAutoreleasePool alloc] init];
   460 
   461     /* Query the title from the existing window */
   462     title = [nswindow title];
   463     if (title) {
   464         window->title = SDL_strdup([title UTF8String]);
   465     }
   466 
   467     [pool release];
   468 
   469     return SetupWindowData(_this, window, nswindow, SDL_FALSE);
   470 }
   471 
   472 void
   473 Cocoa_SetWindowTitle(_THIS, SDL_Window * window)
   474 {
   475     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   476     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->window;
   477     NSString *string;
   478 
   479     if(window->title) {
   480         string = [[NSString alloc] initWithUTF8String:window->title];
   481     } else {
   482         string = [[NSString alloc] init];
   483     }
   484     [nswindow setTitle:string];
   485     [string release];
   486 
   487     [pool release];
   488 }
   489 
   490 void
   491 Cocoa_SetWindowPosition(_THIS, SDL_Window * window)
   492 {
   493     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   494     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->window;
   495     SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayFromWindow(window)->driverdata;
   496     NSRect rect;
   497 
   498     rect = CGDisplayBounds(displaydata->display);
   499     if ((window->flags & SDL_WINDOW_FULLSCREEN)
   500         || window->x == SDL_WINDOWPOS_CENTERED) {
   501         rect.origin.x += (rect.size.width - window->w) / 2;
   502     } else {
   503         rect.origin.x += window->x;
   504     }
   505     if ((window->flags & SDL_WINDOW_FULLSCREEN)
   506         || window->y == SDL_WINDOWPOS_CENTERED) {
   507         rect.origin.y += (rect.size.height - window->h) / 2;
   508     } else {
   509         rect.origin.y += window->y;
   510     }
   511     rect.size.width = window->w;
   512     rect.size.height = window->h;
   513     ConvertNSRect(&rect);
   514     rect = [nswindow frameRectForContentRect:rect];
   515     [nswindow setFrameOrigin:rect.origin];
   516     [pool release];
   517 }
   518 
   519 void
   520 Cocoa_SetWindowSize(_THIS, SDL_Window * window)
   521 {
   522     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   523     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->window;
   524     NSSize size;
   525 
   526     size.width = window->w;
   527     size.height = window->h;
   528     [nswindow setContentSize:size];
   529     [pool release];
   530 }
   531 
   532 void
   533 Cocoa_ShowWindow(_THIS, SDL_Window * window)
   534 {
   535     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   536     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->window;
   537 
   538     if (![nswindow isMiniaturized]) {
   539         [nswindow makeKeyAndOrderFront:nil];
   540     }
   541     [pool release];
   542 }
   543 
   544 void
   545 Cocoa_HideWindow(_THIS, SDL_Window * window)
   546 {
   547     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   548     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->window;
   549 
   550     [nswindow orderOut:nil];
   551     [pool release];
   552 }
   553 
   554 void
   555 Cocoa_RaiseWindow(_THIS, SDL_Window * window)
   556 {
   557     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   558     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->window;
   559 
   560     [nswindow makeKeyAndOrderFront:nil];
   561     [pool release];
   562 }
   563 
   564 void
   565 Cocoa_MaximizeWindow(_THIS, SDL_Window * window)
   566 {
   567     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   568     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->window;
   569 
   570     [nswindow zoom:nil];
   571     [pool release];
   572 }
   573 
   574 void
   575 Cocoa_MinimizeWindow(_THIS, SDL_Window * window)
   576 {
   577     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   578     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->window;
   579 
   580     [nswindow miniaturize:nil];
   581     [pool release];
   582 }
   583 
   584 void
   585 Cocoa_RestoreWindow(_THIS, SDL_Window * window)
   586 {
   587     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   588     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->window;
   589 
   590     if ([nswindow isMiniaturized]) {
   591         [nswindow deminiaturize:nil];
   592     } else if ([nswindow isZoomed]) {
   593         [nswindow zoom:nil];
   594     }
   595     [pool release];
   596 }
   597 
   598 void
   599 Cocoa_SetWindowGrab(_THIS, SDL_Window * window)
   600 {
   601     if ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&
   602         (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
   603         /* FIXME: Grab mouse */
   604     } else {
   605         /* FIXME: Release mouse */
   606     }
   607 }
   608 
   609 void
   610 Cocoa_DestroyWindow(_THIS, SDL_Window * window)
   611 {
   612     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   613     SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
   614 
   615     if (data) {
   616         [data->listener close];
   617         [data->listener release];
   618         if (data->created) {
   619             [data->window close];
   620         }
   621         SDL_free(data);
   622     }
   623     [pool release];
   624 }
   625 
   626 SDL_bool
   627 Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
   628 {
   629     NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->window;
   630 
   631     if (info->version.major <= SDL_MAJOR_VERSION) {
   632         //info->window = nswindow;
   633         return SDL_TRUE;
   634     } else {
   635         SDL_SetError("Application not compiled with SDL %d.%d\n",
   636                      SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
   637         return SDL_FALSE;
   638     }
   639 }
   640 
   641 /* vi: set ts=4 sw=4 expandtab: */