Commit 52f2433c authored by Sam Lantinga's avatar Sam Lantinga

Added an API function to query geometry of multiple monitors:

	SDL_GetDisplayBounds()

Implemented multi-monitor window positions on Windows

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%404271
parent 540357e2
...@@ -343,10 +343,21 @@ extern DECLSPEC const char *SDLCALL SDL_GetCurrentVideoDriver(void); ...@@ -343,10 +343,21 @@ extern DECLSPEC const char *SDLCALL SDL_GetCurrentVideoDriver(void);
/** /**
* \brief Returns the number of available video displays. * \brief Returns the number of available video displays.
* *
* \sa SDL_GetDisplayBounds()
* \sa SDL_SelectVideoDisplay() * \sa SDL_SelectVideoDisplay()
*/ */
extern DECLSPEC int SDLCALL SDL_GetNumVideoDisplays(void); 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. * \brief Set the index of the currently selected display.
* *
......
...@@ -212,6 +212,11 @@ struct SDL_VideoDevice ...@@ -212,6 +212,11 @@ struct SDL_VideoDevice
* Display functions * Display functions
*/ */
/*
* 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. * Get a list of the available display modes. e.g.
* SDL_AddDisplayMode(_this->current_display, mode) * SDL_AddDisplayMode(_this->current_display, mode)
......
...@@ -334,6 +334,41 @@ SDL_GetNumVideoDisplays(void) ...@@ -334,6 +334,41 @@ SDL_GetNumVideoDisplays(void)
return _this->num_displays; return _this->num_displays;
} }
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 int
SDL_SelectVideoDisplay(int index) SDL_SelectVideoDisplay(int index)
{ {
......
...@@ -35,7 +35,7 @@ typedef struct ...@@ -35,7 +35,7 @@ typedef struct
} SDL_DisplayModeData; } SDL_DisplayModeData;
extern void Cocoa_InitModes(_THIS); 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 void Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
extern int Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); extern int Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
extern void Cocoa_QuitModes(_THIS); extern void Cocoa_QuitModes(_THIS);
......
...@@ -200,19 +200,18 @@ Cocoa_InitModes(_THIS) ...@@ -200,19 +200,18 @@ Cocoa_InitModes(_THIS)
SDL_stack_free(displays); SDL_stack_free(displays);
} }
/* This is needed on 10.4, where NSRect and CGRect are different */ int
NSRect Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
Cocoa_DisplayBounds(CGDirectDisplayID display)
{ {
NSRect nsrect; SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
CGRect cgrect; CGRect cgrect;
cgrect = CGDisplayBounds(display); cgrect = CGDisplayBounds(displaydata->display);
nsrect.origin.x = cgrect.origin.x; rect->x = (int)cgrect.origin.x;
nsrect.origin.y = cgrect.origin.y; rect->y = (int)cgrect.origin.y;
nsrect.size.width = cgrect.size.width; rect->w = (int)cgrect.size.width;
nsrect.size.height = cgrect.size.height; rect->h = (int)cgrect.size.height;
return nsrect; return 0;
} }
static void static void
......
...@@ -67,12 +67,12 @@ Cocoa_HandleMouseEvent(_THIS, NSEvent *event) ...@@ -67,12 +67,12 @@ Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
SDL_Window *candidate = display->fullscreen_window; SDL_Window *candidate = display->fullscreen_window;
if (candidate) { if (candidate) {
SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata; SDL_Rect bounds;
NSRect rect = Cocoa_DisplayBounds(displaydata->display);
Cocoa_GetDisplayBounds(_this, display, &bounds);
point = [NSEvent mouseLocation]; point = [NSEvent mouseLocation];
point.x = point.x - rect.origin.x; point.x = point.x - bounds.x;
point.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - point.y - rect.origin.y; point.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - point.y - bounds.y;
if (point.x < 0 || point.x >= candidate->w || if (point.x < 0 || point.x >= candidate->w ||
point.y < 0 || point.y >= candidate->h) { point.y < 0 || point.y >= candidate->h) {
/* The mouse is out of this fullscreen display */ /* The mouse is out of this fullscreen display */
......
...@@ -72,6 +72,7 @@ Cocoa_CreateDevice(int devindex) ...@@ -72,6 +72,7 @@ Cocoa_CreateDevice(int devindex)
/* Set the function pointers */ /* Set the function pointers */
device->VideoInit = Cocoa_VideoInit; device->VideoInit = Cocoa_VideoInit;
device->VideoQuit = Cocoa_VideoQuit; device->VideoQuit = Cocoa_VideoQuit;
device->GetDisplayBounds = Cocoa_GetDisplayBounds;
device->GetDisplayModes = Cocoa_GetDisplayModes; device->GetDisplayModes = Cocoa_GetDisplayModes;
device->SetDisplayMode = Cocoa_SetDisplayMode; device->SetDisplayMode = Cocoa_SetDisplayMode;
device->PumpEvents = Cocoa_PumpEvents; device->PumpEvents = Cocoa_PumpEvents;
......
...@@ -378,23 +378,28 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window) ...@@ -378,23 +378,28 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window)
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSWindow *nswindow; NSWindow *nswindow;
SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayFromWindow(window)->driverdata; SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
NSRect rect; NSRect rect;
SDL_Rect bounds;
unsigned int style; unsigned int style;
NSString *title; NSString *title;
int status; int status;
rect = Cocoa_DisplayBounds(displaydata->display); Cocoa_GetDisplayBounds(_this, display, &bounds);
if ((window->flags & SDL_WINDOW_FULLSCREEN) if ((window->flags & SDL_WINDOW_FULLSCREEN)
|| window->x == SDL_WINDOWPOS_CENTERED) { || 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 if (window->x != SDL_WINDOWPOS_UNDEFINED) { } else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
rect.origin.x = bounds.x;
} else {
rect.origin.x = window->x; rect.origin.x = window->x;
} }
if ((window->flags & SDL_WINDOW_FULLSCREEN) if ((window->flags & SDL_WINDOW_FULLSCREEN)
|| window->y == SDL_WINDOWPOS_CENTERED) { || 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 if (window->x != SDL_WINDOWPOS_UNDEFINED) { } else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
rect.origin.y = bounds.y;
} else {
rect.origin.y = window->y; rect.origin.y = window->y;
} }
rect.size.width = window->w; rect.size.width = window->w;
...@@ -482,19 +487,20 @@ Cocoa_SetWindowPosition(_THIS, SDL_Window * window) ...@@ -482,19 +487,20 @@ Cocoa_SetWindowPosition(_THIS, SDL_Window * window)
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->window; NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->window;
SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayFromWindow(window)->driverdata; SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
NSRect rect; NSRect rect;
SDL_Rect bounds;
rect = Cocoa_DisplayBounds(displaydata->display); Cocoa_GetDisplayBounds(_this, display, &bounds);
if ((window->flags & SDL_WINDOW_FULLSCREEN) if ((window->flags & SDL_WINDOW_FULLSCREEN)
|| window->x == SDL_WINDOWPOS_CENTERED) { || 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 { } else {
rect.origin.x = window->x; rect.origin.x = window->x;
} }
if ((window->flags & SDL_WINDOW_FULLSCREEN) if ((window->flags & SDL_WINDOW_FULLSCREEN)
|| window->y == SDL_WINDOWPOS_CENTERED) { || 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 { } else {
rect.origin.y = window->y; rect.origin.y = window->y;
} }
......
...@@ -54,7 +54,7 @@ WIN_GetDisplayMode(LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode) ...@@ -54,7 +54,7 @@ WIN_GetDisplayMode(LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode)
mode->driverdata = data; mode->driverdata = data;
#ifdef _WIN32_WCE #ifdef _WIN32_WCE
/* In WinCE EnumDisplaySettings(ENUM_CURRENT_SETTINGS) doesn't take the user defined orientation /* 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) { if (index == ENUM_CURRENT_SETTINGS) {
mode->w = GetSystemMetrics(SM_CXSCREEN); mode->w = GetSystemMetrics(SM_CXSCREEN);
mode->h = GetSystemMetrics(SM_CYSCREEN); mode->h = GetSystemMetrics(SM_CYSCREEN);
...@@ -199,6 +199,18 @@ WIN_InitModes(_THIS) ...@@ -199,6 +199,18 @@ WIN_InitModes(_THIS)
return 0; 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 void
WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display) WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
{ {
......
...@@ -35,6 +35,7 @@ typedef struct ...@@ -35,6 +35,7 @@ typedef struct
} SDL_DisplayModeData; } SDL_DisplayModeData;
extern int WIN_InitModes(_THIS); 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 void WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
extern int WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); extern int WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
extern void WIN_QuitModes(_THIS); extern void WIN_QuitModes(_THIS);
......
...@@ -160,6 +160,7 @@ WIN_CreateDevice(int devindex) ...@@ -160,6 +160,7 @@ WIN_CreateDevice(int devindex)
/* Set the function pointers */ /* Set the function pointers */
device->VideoInit = WIN_VideoInit; device->VideoInit = WIN_VideoInit;
device->VideoQuit = WIN_VideoQuit; device->VideoQuit = WIN_VideoQuit;
device->GetDisplayBounds = WIN_GetDisplayBounds;
device->GetDisplayModes = WIN_GetDisplayModes; device->GetDisplayModes = WIN_GetDisplayModes;
device->SetDisplayMode = WIN_SetDisplayMode; device->SetDisplayMode = WIN_SetDisplayMode;
device->SetDisplayGammaRamp = WIN_SetDisplayGammaRamp; device->SetDisplayGammaRamp = WIN_SetDisplayGammaRamp;
......
...@@ -185,12 +185,14 @@ int ...@@ -185,12 +185,14 @@ int
WIN_CreateWindow(_THIS, SDL_Window * window) WIN_CreateWindow(_THIS, SDL_Window * window)
{ {
SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
RAWINPUTDEVICE Rid; RAWINPUTDEVICE Rid;
AXIS TabX, TabY; AXIS TabX, TabY;
LOGCONTEXTA lc; LOGCONTEXTA lc;
HWND hwnd; HWND hwnd;
HWND top; HWND top;
RECT rect; RECT rect;
SDL_Rect bounds;
DWORD style = (WS_CLIPSIBLINGS | WS_CLIPCHILDREN); DWORD style = (WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
int x, y; int x, y;
int w, h; int w, h;
...@@ -219,19 +221,28 @@ WIN_CreateWindow(_THIS, SDL_Window * window) ...@@ -219,19 +221,28 @@ WIN_CreateWindow(_THIS, SDL_Window * window)
w = (rect.right - rect.left); w = (rect.right - rect.left);
h = (rect.bottom - rect.top); h = (rect.bottom - rect.top);
WIN_GetDisplayBounds(_this, display, &bounds);
if ((window->flags & SDL_WINDOW_FULLSCREEN) if ((window->flags & SDL_WINDOW_FULLSCREEN)
|| window->x == SDL_WINDOWPOS_CENTERED) { || 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) { } else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
if (bounds.x == 0) {
x = CW_USEDEFAULT; x = CW_USEDEFAULT;
} else {
x = bounds.x;
}
} else { } else {
x = window->x + rect.left; x = window->x + rect.left;
} }
if ((window->flags & SDL_WINDOW_FULLSCREEN) if ((window->flags & SDL_WINDOW_FULLSCREEN)
|| window->y == SDL_WINDOWPOS_CENTERED) { || window->y == SDL_WINDOWPOS_CENTERED) {
y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2; y = bounds.y + (bounds.h - window->h) / 2;
} else if (window->y == SDL_WINDOWPOS_UNDEFINED) { } else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
if (bounds.x == 0) {
y = CW_USEDEFAULT; y = CW_USEDEFAULT;
} else {
y = bounds.y;
}
} else { } else {
y = window->y + rect.top; y = window->y + rect.top;
} }
...@@ -416,8 +427,10 @@ WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) ...@@ -416,8 +427,10 @@ WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
void void
WIN_SetWindowPosition(_THIS, SDL_Window * window) WIN_SetWindowPosition(_THIS, SDL_Window * window)
{ {
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
RECT rect; RECT rect;
SDL_Rect bounds;
DWORD style; DWORD style;
HWND top; HWND top;
BOOL menu; BOOL menu;
...@@ -441,15 +454,16 @@ WIN_SetWindowPosition(_THIS, SDL_Window * window) ...@@ -441,15 +454,16 @@ WIN_SetWindowPosition(_THIS, SDL_Window * window)
#endif #endif
AdjustWindowRectEx(&rect, style, menu, 0); AdjustWindowRectEx(&rect, style, menu, 0);
WIN_GetDisplayBounds(_this, display, &bounds);
if ((window->flags & SDL_WINDOW_FULLSCREEN) if ((window->flags & SDL_WINDOW_FULLSCREEN)
|| window->x == SDL_WINDOWPOS_CENTERED) { || window->x == SDL_WINDOWPOS_CENTERED) {
x = (GetSystemMetrics(SM_CXSCREEN) - window->w) / 2; x = bounds.x + (bounds.w - window->w) / 2;
} else { } else {
x = window->x + rect.left; x = window->x + rect.left;
} }
if ((window->flags & SDL_WINDOW_FULLSCREEN) if ((window->flags & SDL_WINDOW_FULLSCREEN)
|| window->y == SDL_WINDOWPOS_CENTERED) { || window->y == SDL_WINDOWPOS_CENTERED) {
y = (GetSystemMetrics(SM_CYSCREEN) - window->h) / 2; y = bounds.y + (bounds.h - window->h) / 2;
} else { } else {
y = window->y + rect.top; y = window->y + rect.top;
} }
......
...@@ -449,7 +449,12 @@ main(int argc, char *argv[]) ...@@ -449,7 +449,12 @@ main(int argc, char *argv[])
} }
printf("Number of displays: %d\n", SDL_GetNumVideoDisplays()); printf("Number of displays: %d\n", SDL_GetNumVideoDisplays());
for (d = 0; d < SDL_GetNumVideoDisplays(); ++d) { 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_SelectVideoDisplay(d);
SDL_GetDesktopDisplayMode(&mode); SDL_GetDesktopDisplayMode(&mode);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment