Mercurial > sdl-ios-xcode
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]; |