Skip to content
Permalink
Browse files
Added SDL_GetDisplayUsableBounds().
  • Loading branch information
icculus committed Jan 5, 2016
1 parent 8875a40 commit c3114975db76b4288122975e235fa2708908c3f4
@@ -116,6 +116,7 @@ test/testtimer
test/testver
test/testviewport
test/testwm2
test/testbounds
test/torturethread
test/testdisplayinfo
test/*.exe
@@ -311,6 +311,25 @@ extern DECLSPEC int SDLCALL SDL_GetDisplayBounds(int displayIndex, SDL_Rect * re
*/
extern DECLSPEC int SDLCALL SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi);

/**
* \brief Get the usable desktop area represented by a display, with the
* primary display located at 0,0
*
* This is the same area as SDL_GetDisplayBounds() reports, but with portions
* reserved by the system removed. For example, on Mac OS X, this subtracts
* the area occupied by the menu bar and dock.
*
* Setting a window to be fullscreen generally bypasses these unusable areas,
* so these are good guidelines for the maximum space available to a
* non-fullscreen window.
*
* \return 0 on success, or -1 if the index is out of range.
*
* \sa SDL_GetDisplayBounds()
* \sa SDL_GetNumVideoDisplays()
*/
extern DECLSPEC int SDLCALL SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect * rect);

/**
* \brief Returns the number of available display modes.
*
@@ -597,3 +597,4 @@
#define SDL_JoystickCurrentPowerLevel SDL_JoystickCurrentPowerLevel_REAL
#define SDL_GameControllerFromInstanceID SDL_GameControllerFromInstanceID_REAL
#define SDL_JoystickFromInstanceID SDL_JoystickFromInstanceID_REAL
#define SDL_GetDisplayUsableBounds SDL_GetDisplayUsableBounds_REAL
@@ -631,3 +631,4 @@ SDL_DYNAPI_PROC(int,SDL_GetDisplayDPI,(int a, float *b, float *c, float *d),(a,b
SDL_DYNAPI_PROC(SDL_JoystickPowerLevel,SDL_JoystickCurrentPowerLevel,(SDL_Joystick *a),(a),return)
SDL_DYNAPI_PROC(SDL_GameController*,SDL_GameControllerFromInstanceID,(SDL_JoystickID a),(a),return)
SDL_DYNAPI_PROC(SDL_Joystick*,SDL_JoystickFromInstanceID,(SDL_JoystickID a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GetDisplayUsableBounds,(int a, SDL_Rect *b),(a,b),return)
@@ -175,6 +175,11 @@ struct SDL_VideoDevice
*/
int (*GetDisplayDPI) (_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi);

/*
* Get the usable bounds of a display (bounds minus menubar or whatever)
*/
int (*GetDisplayUsableBounds) (_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);

/*
* Get a list of the available display modes for a display.
*/
@@ -684,7 +684,26 @@ SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect)
rect->w = display->current_mode.w;
rect->h = display->current_mode.h;
}
return 0;
return 0; /* !!! FIXME: should this be an error if (rect==NULL) ? */
}

int SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect * rect)
{
CHECK_DISPLAY_INDEX(displayIndex, -1);

if (rect) {
SDL_VideoDisplay *display = &_this->displays[displayIndex];

if (_this->GetDisplayUsableBounds) {
if (_this->GetDisplayUsableBounds(_this, display, rect) == 0) {
return 0;
}
}

/* Oh well, just give the entire display bounds. */
return SDL_GetDisplayBounds(displayIndex, rect);
}
return 0; /* !!! FIXME: should this be an error if (rect==NULL) ? */
}

int
@@ -35,6 +35,7 @@ typedef struct

extern void Cocoa_InitModes(_THIS);
extern int Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
extern int Cocoa_GetDisplayUsableBounds(_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);
@@ -19,6 +19,7 @@
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#include "SDL_assert.h"

#if SDL_VIDEO_DRIVER_COCOA

@@ -338,6 +339,41 @@
return 0;
}

int
Cocoa_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
{
SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
const CGDirectDisplayID cgdisplay = displaydata->display;
NSArray *screens = [NSScreen screens];
NSScreen *screen = nil;

/* !!! FIXME: maybe track the NSScreen in SDL_DisplayData? */
for (NSScreen *i in screens) {
const CGDirectDisplayID thisDisplay = (CGDirectDisplayID) [[[i deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue];
if (thisDisplay == cgdisplay) {
screen = i;
break;
}
}

SDL_assert(screen != nil); /* didn't find it?! */
if (screen == nil) {
return -1;
}

const CGRect cgrect = CGDisplayBounds(cgdisplay);
const NSRect frame = [screen visibleFrame];

// !!! FIXME: I assume -[NSScreen visibleFrame] is relative to the origin of the screen in question and not the whole desktop.
// !!! FIXME: The math vs CGDisplayBounds might be incorrect if that's not the case, though. Check this.
rect->x = (int)(cgrect.origin.x + frame.origin.x);
rect->y = (int)(cgrect.origin.y + frame.origin.y);
rect->w = (int)frame.size.width;
rect->h = (int)frame.size.height;

return 0;
}

void
Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
{
@@ -73,6 +73,7 @@
device->VideoInit = Cocoa_VideoInit;
device->VideoQuit = Cocoa_VideoQuit;
device->GetDisplayBounds = Cocoa_GetDisplayBounds;
device->GetDisplayUsableBounds = Cocoa_GetDisplayUsableBounds;
device->GetDisplayModes = Cocoa_GetDisplayModes;
device->SetDisplayMode = Cocoa_SetDisplayMode;
device->PumpEvents = Cocoa_PumpEvents;
@@ -43,6 +43,7 @@ extern int UIKit_InitModes(_THIS);
extern void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
extern int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
extern void UIKit_QuitModes(_THIS);
extern int UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);

#endif /* _SDL_uikitmodes_h */

@@ -242,6 +242,26 @@ @implementation SDL_DisplayModeData
return 0;
}

int
UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
{
/* the default function iterates displays to make a fake offset,
as if all the displays were side-by-side, which is fine for iOS. */
const int displayIndex = (int) (display - _this->displays);
if (SDL_GetDisplayBounds(displayIndex, rect) < 0) {
return -1;
}

SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
const CGRect frame = [data->uiscreen applicationFrame];
const float scale = (float) data->scale;
rect->x += (int) (frame.origin.x * scale);
rect->y += (int) (frame.origin.y * scale);
rect->w = (int) (frame.size.width * scale);
rect->h = (int) (frame.size.height * scale);
return 0;
}

void
UIKit_QuitModes(_THIS)
{
@@ -85,6 +85,7 @@ static void UIKit_DeleteDevice(SDL_VideoDevice * device)
device->SetWindowFullscreen = UIKit_SetWindowFullscreen;
device->DestroyWindow = UIKit_DestroyWindow;
device->GetWindowWMInfo = UIKit_GetWindowWMInfo;
device->GetDisplayUsableBounds = UIKit_GetDisplayUsableBounds;

#if SDL_IPHONE_KEYBOARD
device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport;
@@ -332,6 +332,43 @@ WIN_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi,
return data->DiagDPI != 0.0f ? 0 : -1;
}

int
WIN_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
{
const SDL_DisplayModeData *data = (const SDL_DisplayModeData *) display->current_mode.driverdata;
const DEVMODE *pDevMode = &data->DeviceMode;
POINT pt = {
/* !!! FIXME: no scale, right? */
(LONG) (pDevMode->dmPosition.x + (pDevMode->dmPelsWidth / 2)),
(LONG) (pDevMode->dmPosition.y + (pDevMode->dmPelsHeight / 2))
};
HMONITOR hmon = MonitorFromPoint(&pt, MONITOR_DEFAULTTONULL);
MONITORINFO minfo;
const RECT *work;
BOOL rc = FALSE;

SDL_assert(hmon != NULL);

if (hmon != NULL) {
SDL_zero(minfo);
minfo.cbSize = sizeof (MONITORINFO);
rc = GetMonitorInfo(hmon, &minfo);
SDL_assert(rc);
}

if (!rc) {
return SDL_SetError("Couldn't find monitor data");
}

work = &minfo->rcWork;
rect->x = (int)SDL_ceil(work->left * data->ScaleX);
rect->y = (int)SDL_ceil(work->top * data->ScaleY);
rect->w = (int)SDL_ceil((work->right - work->left) * data->ScaleX);
rect->h = (int)SDL_ceil((work->bottom - work->top) * data->ScaleY);

return 0;
}

void
WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
{
@@ -40,6 +40,7 @@ typedef struct

extern int WIN_InitModes(_THIS);
extern int WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
extern int WIN_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
extern int WIN_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi);
extern void WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
extern int WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
@@ -124,6 +124,7 @@ WIN_CreateDevice(int devindex)
device->VideoInit = WIN_VideoInit;
device->VideoQuit = WIN_VideoQuit;
device->GetDisplayBounds = WIN_GetDisplayBounds;
device->GetDisplayUsableBounds = WIN_GetDisplayUsableBounds;
device->GetDisplayDPI = WIN_GetDisplayDPI;
device->GetDisplayModes = WIN_GetDisplayModes;
device->SetDisplayMode = WIN_SetDisplayMode;
@@ -1073,6 +1073,43 @@ X11_GetDisplayDPI(_THIS, SDL_VideoDisplay * sdl_display, float * ddpi, float * h
return data->ddpi != 0.0f ? 0 : -1;
}

int
X11_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect)
{
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
Display *display = data->display;
Atom _NET_WORKAREA;
int status, real_format;
int retval = -1;
Atom real_type;
unsigned long items_read = 0, items_left = 0;
unsigned char *propdata = NULL;

if (X11_GetDisplayBounds(_this, sdl_display, rect) < 0) {
return -1;
}

_NET_WORKAREA = X11_XInternAtom(display, "_NET_WORKAREA", False);
status = X11_XGetWindowProperty(display, DefaultRootWindow(display),
_NET_WORKAREA, 0L, 4L, False, XA_CARDINAL,
&real_type, &real_format, &items_read,
&items_left, &propdata);
if ((status == Success) && (items_read >= 4)) {
retval = 0;
const long *p = (long*) propdata;
const SDL_Rect usable = { (int)p[0], (int)p[1], (int)p[2], (int)p[3] };
if (!SDL_IntersectRect(rect, &usable, rect)) {
SDL_zerop(rect);
}
}

if (propdata) {
X11_XFree(propdata);
}

return retval;
}

#endif /* SDL_VIDEO_DRIVER_X11 */

/* vi: set ts=4 sw=4 expandtab: */
@@ -77,6 +77,7 @@ extern int X11_GetVisualInfoFromVisual(Display * display, Visual * visual,
extern Uint32 X11_GetPixelFormatFromVisualInfo(Display * display,
XVisualInfo * vinfo);
extern int X11_GetDisplayBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect);
extern int X11_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect);
extern int X11_GetDisplayDPI(_THIS, SDL_VideoDisplay * sdl_display, float * ddpi, float * hdpi, float * vdpi);

#endif /* _SDL_x11modes_h */
@@ -218,6 +218,7 @@ X11_CreateDevice(int devindex)
device->VideoQuit = X11_VideoQuit;
device->GetDisplayModes = X11_GetDisplayModes;
device->GetDisplayBounds = X11_GetDisplayBounds;
device->GetDisplayUsableBounds = X11_GetDisplayUsableBounds;
device->GetDisplayDPI = X11_GetDisplayDPI;
device->SetDisplayMode = X11_SetDisplayMode;
device->SuspendScreenSaver = X11_SuspendScreenSaver;
@@ -14,6 +14,7 @@ TARGETS = \
testatomic$(EXE) \
testaudioinfo$(EXE) \
testautomation$(EXE) \
testbounds$(EXE) \
testdraw2$(EXE) \
testdrawchessboard$(EXE) \
testdropfile$(EXE) \
@@ -270,6 +271,9 @@ testmessage$(EXE): $(srcdir)/testmessage.c
testdisplayinfo$(EXE): $(srcdir)/testdisplayinfo.c
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)

testbounds$(EXE): $(srcdir)/testbounds.c
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)

controllermap$(EXE): $(srcdir)/controllermap.c
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)

@@ -0,0 +1,39 @@
/*
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/

#include "SDL.h"

int main(int argc, char **argv)
{
int total, i;

if (SDL_Init(SDL_INIT_VIDEO) < 0) {
SDL_Log("SDL_Init(SDL_INIT_VIDEO) failed: %s", SDL_GetError());
}

total = SDL_GetNumVideoDisplays();
for (i = 0; i < total; i++) {
SDL_Rect bounds = { -1,-1,-1,-1 }, usable = { -1,-1,-1,-1 };
SDL_GetDisplayBounds(i, &bounds);
SDL_GetDisplayUsableBounds(i, &usable);
SDL_Log("Display #%d ('%s'): bounds={(%d,%d),%dx%d}, usable={(%d,%d),%dx%d}",
i, SDL_GetDisplayName(i),
bounds.x, bounds.y, bounds.w, bounds.h,
usable.x, usable.y, usable.w, usable.h);
}

SDL_Quit();
return 0;
}

/* vi: set ts=4 sw=4 expandtab: */

0 comments on commit c311497

Please sign in to comment.