comparison src/video/cocoa/SDL_cocoawindow.m @ 3506:e829b6098435

Added support for placing windows on different displays
author Sam Lantinga <slouken@libsdl.org>
date Tue, 01 Dec 2009 11:50:00 +0000
parents 1e45c3012a4f
children 3712547eac4f
comparison
equal deleted inserted replaced
3505:a1bf34bc2a58 3506:e829b6098435
29 29
30 #include "SDL_cocoavideo.h" 30 #include "SDL_cocoavideo.h"
31 31
32 static __inline__ void ConvertNSRect(NSRect *r) 32 static __inline__ void ConvertNSRect(NSRect *r)
33 { 33 {
34 /* FIXME: Cache the display used for this window */
35 r->origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - r->origin.y - r->size.height; 34 r->origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - r->origin.y - r->size.height;
36 } 35 }
37 36
38 @implementation Cocoa_WindowListener 37 @implementation Cocoa_WindowListener
39 38
97 } 96 }
98 97
99 - (void)windowDidMove:(NSNotification *)aNotification 98 - (void)windowDidMove:(NSNotification *)aNotification
100 { 99 {
101 int x, y; 100 int x, y;
101 NSRect disp = CGDisplayBounds(_data->display);
102 NSRect rect = [_data->window contentRectForFrameRect:[_data->window frame]]; 102 NSRect rect = [_data->window contentRectForFrameRect:[_data->window frame]];
103 ConvertNSRect(&rect); 103 ConvertNSRect(&rect);
104 x = (int)rect.origin.x; 104 x = (int)rect.origin.x - disp.origin.x;
105 y = (int)rect.origin.y; 105 y = (int)rect.origin.y - disp.origin.y;
106 SDL_SendWindowEvent(_data->windowID, SDL_WINDOWEVENT_MOVED, x, y); 106 SDL_SendWindowEvent(_data->windowID, SDL_WINDOWEVENT_MOVED, x, y);
107 } 107 }
108 108
109 - (void)windowDidResize:(NSNotification *)aNotification 109 - (void)windowDidResize:(NSNotification *)aNotification
110 { 110 {
307 static int 307 static int
308 SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created) 308 SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created)
309 { 309 {
310 NSAutoreleasePool *pool; 310 NSAutoreleasePool *pool;
311 SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; 311 SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
312 SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayFromWindow(window)->driverdata;
312 SDL_WindowData *data; 313 SDL_WindowData *data;
313 314
314 /* Allocate the window data */ 315 /* Allocate the window data */
315 data = (SDL_WindowData *) SDL_malloc(sizeof(*data)); 316 data = (SDL_WindowData *) SDL_malloc(sizeof(*data));
316 if (!data) { 317 if (!data) {
318 return -1; 319 return -1;
319 } 320 }
320 data->windowID = window->id; 321 data->windowID = window->id;
321 data->window = nswindow; 322 data->window = nswindow;
322 data->created = created; 323 data->created = created;
324 data->display = displaydata->display;
323 data->videodata = videodata; 325 data->videodata = videodata;
324 326
325 pool = [[NSAutoreleasePool alloc] init]; 327 pool = [[NSAutoreleasePool alloc] init];
326 328
327 /* Create an event listener for the window */ 329 /* Create an event listener for the window */
328 data->listener = [[Cocoa_WindowListener alloc] init]; 330 data->listener = [[Cocoa_WindowListener alloc] init];
329 [data->listener listen:data]; 331 [data->listener listen:data];
330 332
331 /* Fill in the SDL window with the window data */ 333 /* Fill in the SDL window with the window data */
332 { 334 {
335 NSRect disp = CGDisplayBounds(data->display);
333 NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]]; 336 NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
334 ConvertNSRect(&rect); 337 ConvertNSRect(&rect);
335 window->x = (int)rect.origin.x; 338 window->x = (int)rect.origin.x - disp.origin.x;
336 window->y = (int)rect.origin.y; 339 window->y = (int)rect.origin.y - disp.origin.y;
337 window->w = (int)rect.size.width; 340 window->w = (int)rect.size.width;
338 window->h = (int)rect.size.height; 341 window->h = (int)rect.size.height;
339 } 342 }
340 if ([nswindow isVisible]) { 343 if ([nswindow isVisible]) {
341 window->flags |= SDL_WINDOW_SHOWN; 344 window->flags |= SDL_WINDOW_SHOWN;
383 } 386 }
384 387
385 int 388 int
386 Cocoa_CreateWindow(_THIS, SDL_Window * window) 389 Cocoa_CreateWindow(_THIS, SDL_Window * window)
387 { 390 {
388 NSAutoreleasePool *pool; 391 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
389 NSWindow *nswindow; 392 NSWindow *nswindow;
393 SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayFromWindow(window)->driverdata;
390 NSRect rect; 394 NSRect rect;
391 unsigned int style; 395 unsigned int style;
392 NSString *title; 396 NSString *title;
393 int status; 397 int status;
394 398
395 pool = [[NSAutoreleasePool alloc] init]; 399 rect = CGDisplayBounds(displaydata->display);
396
397 if ((window->flags & SDL_WINDOW_FULLSCREEN) 400 if ((window->flags & SDL_WINDOW_FULLSCREEN)
398 || window->x == SDL_WINDOWPOS_CENTERED) { 401 || window->x == SDL_WINDOWPOS_CENTERED) {
399 rect.origin.x = (CGDisplayPixelsWide(kCGDirectMainDisplay) - window->w) / 2; 402 rect.origin.x += (rect.size.width - window->w) / 2;
400 } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { 403 } else if (window->x != SDL_WINDOWPOS_UNDEFINED) {
401 rect.origin.x = 0; 404 rect.origin.x += window->x;
402 } else {
403 rect.origin.x = window->x;
404 } 405 }
405 if ((window->flags & SDL_WINDOW_FULLSCREEN) 406 if ((window->flags & SDL_WINDOW_FULLSCREEN)
406 || window->y == SDL_WINDOWPOS_CENTERED) { 407 || window->y == SDL_WINDOWPOS_CENTERED) {
407 rect.origin.y = (CGDisplayPixelsHigh(kCGDirectMainDisplay) - window->h) / 2; 408 rect.origin.y += (rect.size.height - window->h) / 2;
408 } else if (window->y == SDL_WINDOWPOS_UNDEFINED) { 409 } else if (window->x != SDL_WINDOWPOS_UNDEFINED) {
409 rect.origin.y = 0; 410 rect.origin.y += window->y;
410 } else {
411 rect.origin.y = window->y;
412 } 411 }
413 rect.size.width = window->w; 412 rect.size.width = window->w;
414 rect.size.height = window->h; 413 rect.size.height = window->h;
415 ConvertNSRect(&rect); 414 ConvertNSRect(&rect);
416 415
421 } 420 }
422 if (window->flags & SDL_WINDOW_RESIZABLE) { 421 if (window->flags & SDL_WINDOW_RESIZABLE) {
423 style |= NSResizableWindowMask; 422 style |= NSResizableWindowMask;
424 } 423 }
425 424
426 nswindow = [[SDLWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:FALSE]; 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];
427 441
428 [pool release]; 442 [pool release];
429 443
430 if (SetupWindowData(_this, window, nswindow, SDL_TRUE) < 0) { 444 if (SetupWindowData(_this, window, nswindow, SDL_TRUE) < 0) {
431 [nswindow release]; 445 [nswindow release];
476 void 490 void
477 Cocoa_SetWindowPosition(_THIS, SDL_Window * window) 491 Cocoa_SetWindowPosition(_THIS, SDL_Window * window)
478 { 492 {
479 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 493 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
480 NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->window; 494 NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->window;
495 SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayFromWindow(window)->driverdata;
481 NSRect rect; 496 NSRect rect;
482 497
498 rect = CGDisplayBounds(displaydata->display);
483 if ((window->flags & SDL_WINDOW_FULLSCREEN) 499 if ((window->flags & SDL_WINDOW_FULLSCREEN)
484 || window->x == SDL_WINDOWPOS_CENTERED) { 500 || window->x == SDL_WINDOWPOS_CENTERED) {
485 rect.origin.x = (CGDisplayPixelsWide(kCGDirectMainDisplay) - window->w) / 2; 501 rect.origin.x += (rect.size.width - window->w) / 2;
486 } else { 502 } else {
487 rect.origin.x = window->x; 503 rect.origin.x += window->x;
488 } 504 }
489 if ((window->flags & SDL_WINDOW_FULLSCREEN) 505 if ((window->flags & SDL_WINDOW_FULLSCREEN)
490 || window->y == SDL_WINDOWPOS_CENTERED) { 506 || window->y == SDL_WINDOWPOS_CENTERED) {
491 rect.origin.y = (CGDisplayPixelsHigh(kCGDirectMainDisplay) - window->h) / 2; 507 rect.origin.y += (rect.size.height - window->h) / 2;
492 } else { 508 } else {
493 rect.origin.y = window->y; 509 rect.origin.y += window->y;
494 } 510 }
495 rect.size.width = window->w; 511 rect.size.width = window->w;
496 rect.size.height = window->h; 512 rect.size.height = window->h;
497 ConvertNSRect(&rect); 513 ConvertNSRect(&rect);
498 rect = [nswindow frameRectForContentRect:rect]; 514 rect = [nswindow frameRectForContentRect:rect];