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
This commit is contained in:
parent
540357e23a
commit
52f2433c29
13 changed files with 124 additions and 34 deletions
|
@ -343,10 +343,21 @@ extern DECLSPEC const char *SDLCALL SDL_GetCurrentVideoDriver(void);
|
|||
/**
|
||||
* \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.
|
||||
*
|
||||
|
|
|
@ -212,6 +212,11 @@ struct SDL_VideoDevice
|
|||
* 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.
|
||||
* SDL_AddDisplayMode(_this->current_display, mode)
|
||||
|
|
|
@ -334,6 +334,41 @@ SDL_GetNumVideoDisplays(void)
|
|||
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
|
||||
SDL_SelectVideoDisplay(int index)
|
||||
{
|
||||
|
|
|
@ -35,7 +35,7 @@ typedef struct
|
|||
} 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);
|
||||
|
|
|
@ -200,19 +200,18 @@ Cocoa_InitModes(_THIS)
|
|||
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
|
||||
|
|
|
@ -67,12 +67,12 @@ Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
|
|||
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 */
|
||||
|
|
|
@ -72,6 +72,7 @@ Cocoa_CreateDevice(int devindex)
|
|||
/* 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;
|
||||
|
|
|
@ -378,23 +378,28 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window)
|
|||
{
|
||||
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 @@ Cocoa_SetWindowPosition(_THIS, SDL_Window * window)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ WIN_GetDisplayMode(LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode)
|
|||
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 @@ WIN_InitModes(_THIS)
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -35,6 +35,7 @@ typedef struct
|
|||
} 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);
|
||||
|
|
|
@ -160,6 +160,7 @@ WIN_CreateDevice(int devindex)
|
|||
/* 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;
|
||||
|
|
|
@ -185,12 +185,14 @@ int
|
|||
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 @@ WIN_CreateWindow(_THIS, SDL_Window * window)
|
|||
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 @@ WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
|
|||
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 @@ WIN_SetWindowPosition(_THIS, SDL_Window * window)
|
|||
#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;
|
||||
}
|
||||
|
|
|
@ -449,7 +449,12 @@ main(int argc, char *argv[])
|
|||
}
|
||||
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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue