# HG changeset patch # User Sam Lantinga # Date 1260086618 0 # Node ID 59ff7a2beb57333f473f807818c6da3d6f80ded8 # Parent 444cb12cadb600dff2f2f28c257b736448176676 Added an API function to query geometry of multiple monitors: SDL_GetDisplayBounds() Implemented multi-monitor window positions on Windows diff -r 444cb12cadb6 -r 59ff7a2beb57 include/SDL_video.h --- a/include/SDL_video.h Sun Dec 06 06:21:39 2009 +0000 +++ b/include/SDL_video.h Sun Dec 06 08:03:38 2009 +0000 @@ -343,11 +343,22 @@ /** * \brief Returns the number of available video displays. * + * \sa SDL_GetDisplayBounds() * \sa SDL_SelectVideoDisplay() */ extern DECLSPEC int SDLCALL SDL_GetNumVideoDisplays(void); /** + * \brief Get the desktop area represented by a display, with the primary + * display located at 0,0 + * + * \return 0 on success, or -1 if the index is out of range. + * + * \sa SDL_GetNumVideoDisplays() + */ +extern DECLSPEC int SDLCALL SDL_GetDisplayBounds(int index, SDL_Rect * rect); + +/** * \brief Set the index of the currently selected display. * * \return 0 on success, or -1 if the index is out of range. diff -r 444cb12cadb6 -r 59ff7a2beb57 src/video/SDL_sysvideo.h --- a/src/video/SDL_sysvideo.h Sun Dec 06 06:21:39 2009 +0000 +++ b/src/video/SDL_sysvideo.h Sun Dec 06 08:03:38 2009 +0000 @@ -213,6 +213,11 @@ */ /* + * Get the bounds of a display + */ + int (*GetDisplayBounds) (_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); + + /* * Get a list of the available display modes. e.g. * SDL_AddDisplayMode(_this->current_display, mode) */ diff -r 444cb12cadb6 -r 59ff7a2beb57 src/video/SDL_video.c --- a/src/video/SDL_video.c Sun Dec 06 06:21:39 2009 +0000 +++ b/src/video/SDL_video.c Sun Dec 06 08:03:38 2009 +0000 @@ -335,6 +335,41 @@ } int +SDL_GetDisplayBounds(int index, SDL_Rect * rect) +{ + if (!_this) { + SDL_UninitializedVideo(); + return -1; + } + if (index < 0 || index >= _this->num_displays) { + SDL_SetError("index must be in the range 0 - %d", + _this->num_displays - 1); + return -1; + } + if (rect) { + SDL_VideoDisplay *display = &_this->displays[index]; + + if (_this->GetDisplayBounds) { + if (_this->GetDisplayBounds(_this, display, rect) < 0) { + return -1; + } + } else { + /* Assume that the displays are left to right */ + if (index == 0) { + rect->x = 0; + rect->y = 0; + } else { + SDL_GetDisplayBounds(index-1, rect); + rect->x += rect->w; + } + rect->w = display->desktop_mode.w; + rect->h = display->desktop_mode.h; + } + } + return 0; +} + +int SDL_SelectVideoDisplay(int index) { if (!_this) { diff -r 444cb12cadb6 -r 59ff7a2beb57 src/video/cocoa/SDL_cocoamodes.h --- a/src/video/cocoa/SDL_cocoamodes.h Sun Dec 06 06:21:39 2009 +0000 +++ b/src/video/cocoa/SDL_cocoamodes.h Sun Dec 06 08:03:38 2009 +0000 @@ -35,7 +35,7 @@ } SDL_DisplayModeData; extern void Cocoa_InitModes(_THIS); -extern NSRect Cocoa_DisplayBounds(CGDirectDisplayID display); +extern int Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); extern void Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display); extern int Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); extern void Cocoa_QuitModes(_THIS); diff -r 444cb12cadb6 -r 59ff7a2beb57 src/video/cocoa/SDL_cocoamodes.m --- a/src/video/cocoa/SDL_cocoamodes.m Sun Dec 06 06:21:39 2009 +0000 +++ b/src/video/cocoa/SDL_cocoamodes.m Sun Dec 06 08:03:38 2009 +0000 @@ -200,19 +200,18 @@ SDL_stack_free(displays); } -/* This is needed on 10.4, where NSRect and CGRect are different */ -NSRect -Cocoa_DisplayBounds(CGDirectDisplayID display) +int +Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) { - NSRect nsrect; + SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; CGRect cgrect; - cgrect = CGDisplayBounds(display); - nsrect.origin.x = cgrect.origin.x; - nsrect.origin.y = cgrect.origin.y; - nsrect.size.width = cgrect.size.width; - nsrect.size.height = cgrect.size.height; - return nsrect; + cgrect = CGDisplayBounds(displaydata->display); + rect->x = (int)cgrect.origin.x; + rect->y = (int)cgrect.origin.y; + rect->w = (int)cgrect.size.width; + rect->h = (int)cgrect.size.height; + return 0; } static void diff -r 444cb12cadb6 -r 59ff7a2beb57 src/video/cocoa/SDL_cocoamouse.m --- a/src/video/cocoa/SDL_cocoamouse.m Sun Dec 06 06:21:39 2009 +0000 +++ b/src/video/cocoa/SDL_cocoamouse.m Sun Dec 06 08:03:38 2009 +0000 @@ -67,12 +67,12 @@ SDL_Window *candidate = display->fullscreen_window; if (candidate) { - SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata; - NSRect rect = Cocoa_DisplayBounds(displaydata->display); + SDL_Rect bounds; + Cocoa_GetDisplayBounds(_this, display, &bounds); point = [NSEvent mouseLocation]; - point.x = point.x - rect.origin.x; - point.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - point.y - rect.origin.y; + point.x = point.x - bounds.x; + point.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - point.y - bounds.y; if (point.x < 0 || point.x >= candidate->w || point.y < 0 || point.y >= candidate->h) { /* The mouse is out of this fullscreen display */ diff -r 444cb12cadb6 -r 59ff7a2beb57 src/video/cocoa/SDL_cocoavideo.m --- a/src/video/cocoa/SDL_cocoavideo.m Sun Dec 06 06:21:39 2009 +0000 +++ b/src/video/cocoa/SDL_cocoavideo.m Sun Dec 06 08:03:38 2009 +0000 @@ -72,6 +72,7 @@ /* Set the function pointers */ device->VideoInit = Cocoa_VideoInit; device->VideoQuit = Cocoa_VideoQuit; + device->GetDisplayBounds = Cocoa_GetDisplayBounds; device->GetDisplayModes = Cocoa_GetDisplayModes; device->SetDisplayMode = Cocoa_SetDisplayMode; device->PumpEvents = Cocoa_PumpEvents; diff -r 444cb12cadb6 -r 59ff7a2beb57 src/video/cocoa/SDL_cocoawindow.m --- a/src/video/cocoa/SDL_cocoawindow.m Sun Dec 06 06:21:39 2009 +0000 +++ b/src/video/cocoa/SDL_cocoawindow.m Sun Dec 06 08:03:38 2009 +0000 @@ -378,23 +378,28 @@ { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSWindow *nswindow; - SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayFromWindow(window)->driverdata; + SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); NSRect rect; + SDL_Rect bounds; unsigned int style; NSString *title; int status; - rect = Cocoa_DisplayBounds(displaydata->display); + Cocoa_GetDisplayBounds(_this, display, &bounds); if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->x == SDL_WINDOWPOS_CENTERED) { - rect.origin.x += (rect.size.width - window->w) / 2; - } else if (window->x != SDL_WINDOWPOS_UNDEFINED) { + rect.origin.x = bounds.x + (bounds.w - window->w) / 2; + } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { + rect.origin.x = bounds.x; + } else { rect.origin.x = window->x; } if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->y == SDL_WINDOWPOS_CENTERED) { - rect.origin.y += (rect.size.height - window->h) / 2; - } else if (window->x != SDL_WINDOWPOS_UNDEFINED) { + rect.origin.y = bounds.y + (bounds.h - window->h) / 2; + } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { + rect.origin.y = bounds.y; + } else { rect.origin.y = window->y; } rect.size.width = window->w; @@ -482,19 +487,20 @@ { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->window; - SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayFromWindow(window)->driverdata; + SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); NSRect rect; + SDL_Rect bounds; - rect = Cocoa_DisplayBounds(displaydata->display); + Cocoa_GetDisplayBounds(_this, display, &bounds); if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->x == SDL_WINDOWPOS_CENTERED) { - rect.origin.x += (rect.size.width - window->w) / 2; + rect.origin.x = bounds.x + (bounds.w - window->w) / 2; } else { rect.origin.x = window->x; } if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->y == SDL_WINDOWPOS_CENTERED) { - rect.origin.y += (rect.size.height - window->h) / 2; + rect.origin.y = bounds.y + (bounds.h - window->h) / 2; } else { rect.origin.y = window->y; } diff -r 444cb12cadb6 -r 59ff7a2beb57 src/video/win32/SDL_win32modes.c --- a/src/video/win32/SDL_win32modes.c Sun Dec 06 06:21:39 2009 +0000 +++ b/src/video/win32/SDL_win32modes.c Sun Dec 06 08:03:38 2009 +0000 @@ -54,7 +54,7 @@ mode->driverdata = data; #ifdef _WIN32_WCE /* In WinCE EnumDisplaySettings(ENUM_CURRENT_SETTINGS) doesn't take the user defined orientation - into account but GetSystemMetrixs does. */ + into account but GetSystemMetrics does. */ if (index == ENUM_CURRENT_SETTINGS) { mode->w = GetSystemMetrics(SM_CXSCREEN); mode->h = GetSystemMetrics(SM_CYSCREEN); @@ -199,6 +199,18 @@ return 0; } +int +WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) +{ + SDL_DisplayModeData *data = (SDL_DisplayModeData *) display->desktop_mode.driverdata; + + rect->x = (int)data->DeviceMode.dmPosition.x; + rect->y = (int)data->DeviceMode.dmPosition.y; + rect->w = data->DeviceMode.dmPelsWidth; + rect->h = data->DeviceMode.dmPelsHeight; + return 0; +} + void WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display) { diff -r 444cb12cadb6 -r 59ff7a2beb57 src/video/win32/SDL_win32modes.h --- a/src/video/win32/SDL_win32modes.h Sun Dec 06 06:21:39 2009 +0000 +++ b/src/video/win32/SDL_win32modes.h Sun Dec 06 08:03:38 2009 +0000 @@ -35,6 +35,7 @@ } SDL_DisplayModeData; extern int WIN_InitModes(_THIS); +extern int WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); extern void WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display); extern int WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); extern void WIN_QuitModes(_THIS); diff -r 444cb12cadb6 -r 59ff7a2beb57 src/video/win32/SDL_win32video.c --- a/src/video/win32/SDL_win32video.c Sun Dec 06 06:21:39 2009 +0000 +++ b/src/video/win32/SDL_win32video.c Sun Dec 06 08:03:38 2009 +0000 @@ -160,6 +160,7 @@ /* Set the function pointers */ device->VideoInit = WIN_VideoInit; device->VideoQuit = WIN_VideoQuit; + device->GetDisplayBounds = WIN_GetDisplayBounds; device->GetDisplayModes = WIN_GetDisplayModes; device->SetDisplayMode = WIN_SetDisplayMode; device->SetDisplayGammaRamp = WIN_SetDisplayGammaRamp; diff -r 444cb12cadb6 -r 59ff7a2beb57 src/video/win32/SDL_win32window.c --- a/src/video/win32/SDL_win32window.c Sun Dec 06 06:21:39 2009 +0000 +++ b/src/video/win32/SDL_win32window.c Sun Dec 06 08:03:38 2009 +0000 @@ -185,12 +185,14 @@ WIN_CreateWindow(_THIS, SDL_Window * window) { SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); RAWINPUTDEVICE Rid; AXIS TabX, TabY; LOGCONTEXTA lc; HWND hwnd; HWND top; RECT rect; + SDL_Rect bounds; DWORD style = (WS_CLIPSIBLINGS | WS_CLIPCHILDREN); int x, y; int w, h; @@ -219,19 +221,28 @@ w = (rect.right - rect.left); h = (rect.bottom - rect.top); + WIN_GetDisplayBounds(_this, display, &bounds); if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->x == SDL_WINDOWPOS_CENTERED) { - x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2; + x = bounds.x + (bounds.w - window->w) / 2; } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { - x = CW_USEDEFAULT; + if (bounds.x == 0) { + x = CW_USEDEFAULT; + } else { + x = bounds.x; + } } else { x = window->x + rect.left; } if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->y == SDL_WINDOWPOS_CENTERED) { - y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2; - } else if (window->y == SDL_WINDOWPOS_UNDEFINED) { - y = CW_USEDEFAULT; + y = bounds.y + (bounds.h - window->h) / 2; + } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { + if (bounds.x == 0) { + y = CW_USEDEFAULT; + } else { + y = bounds.y; + } } else { y = window->y + rect.top; } @@ -416,8 +427,10 @@ void WIN_SetWindowPosition(_THIS, SDL_Window * window) { + SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; RECT rect; + SDL_Rect bounds; DWORD style; HWND top; BOOL menu; @@ -441,15 +454,16 @@ #endif AdjustWindowRectEx(&rect, style, menu, 0); + WIN_GetDisplayBounds(_this, display, &bounds); if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->x == SDL_WINDOWPOS_CENTERED) { - x = (GetSystemMetrics(SM_CXSCREEN) - window->w) / 2; + x = bounds.x + (bounds.w - window->w) / 2; } else { x = window->x + rect.left; } if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->y == SDL_WINDOWPOS_CENTERED) { - y = (GetSystemMetrics(SM_CYSCREEN) - window->h) / 2; + y = bounds.y + (bounds.h - window->h) / 2; } else { y = window->y + rect.top; } diff -r 444cb12cadb6 -r 59ff7a2beb57 test/testvidinfo.c --- a/test/testvidinfo.c Sun Dec 06 06:21:39 2009 +0000 +++ b/test/testvidinfo.c Sun Dec 06 08:03:38 2009 +0000 @@ -449,7 +449,12 @@ } printf("Number of displays: %d\n", SDL_GetNumVideoDisplays()); for (d = 0; d < SDL_GetNumVideoDisplays(); ++d) { - printf("Display %d:\n", d); + SDL_Rect bounds; + + SDL_GetDisplayBounds(d, &bounds); + printf("Display %d: %dx%d at %d,%d\n", d, + bounds.w, bounds.h, bounds.x, bounds.y); + SDL_SelectVideoDisplay(d); SDL_GetDesktopDisplayMode(&mode);