Skip to content

Commit

Permalink
Added SDL_GetDisplaySafeInsets()
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Jul 23, 2024
1 parent 29f0fd3 commit 651ee3e
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 0 deletions.
19 changes: 19 additions & 0 deletions include/SDL3/SDL_video.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,25 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetDisplayBounds(SDL_DisplayID displayID, SD
*/
extern SDL_DECLSPEC int SDLCALL SDL_GetDisplayUsableBounds(SDL_DisplayID displayID, SDL_Rect *rect);

/**
* Get the safe insets of this display, in screen coordinates.
*
* Some displays have portions of the edge which are partially obscured, possibly due to curved edges, camera housing, TV overscan, etc. This function provides the areas on the edge of the display which may be obscured. You should continue rendering into these areas, but it should not be visually important or interactible content.
*
* These areas take current orientation into account and may change if the display changes orientation.
*
* \param displayID the instance ID of the display to query.
* \param left a pointer filled in with the width of the partially obscured area on the left side of the display, in screen coordinates, may be NULL.
* \param right a pointer filled in with the width of the partially obscured area on the right side of the display, in screen coordinates, may be NULL.
* \param top a pointer filled in with the height of the partially obscured area on the top side of the display, in screen coordinates, may be NULL.
* \param bottom a pointer filled in with the height of the partially obscured area on the bottom side of the display, in screen coordinates, may be NULL.
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*/
extern SDL_DECLSPEC int SDLCALL SDL_GetDisplaySafeInsets(SDL_DisplayID displayID, int *left, int *right, int *top, int *bottom);

/**
* Get the orientation of a display when it is unrotated.
*
Expand Down
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi.sym
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ SDL3_0.0.0 {
SDL_GetDisplayForWindow;
SDL_GetDisplayName;
SDL_GetDisplayProperties;
SDL_GetDisplaySafeInsets;
SDL_GetDisplayUsableBounds;
SDL_GetDisplays;
SDL_GetError;
Expand Down
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@
#define SDL_GetDisplayForWindow SDL_GetDisplayForWindow_REAL
#define SDL_GetDisplayName SDL_GetDisplayName_REAL
#define SDL_GetDisplayProperties SDL_GetDisplayProperties_REAL
#define SDL_GetDisplaySafeInsets SDL_GetDisplaySafeInsets_REAL
#define SDL_GetDisplayUsableBounds SDL_GetDisplayUsableBounds_REAL
#define SDL_GetDisplays SDL_GetDisplays_REAL
#define SDL_GetError SDL_GetError_REAL
Expand Down
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ SDL_DYNAPI_PROC(SDL_DisplayID,SDL_GetDisplayForRect,(const SDL_Rect *a),(a),retu
SDL_DYNAPI_PROC(SDL_DisplayID,SDL_GetDisplayForWindow,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(const char*,SDL_GetDisplayName,(SDL_DisplayID a),(a),return)
SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetDisplayProperties,(SDL_DisplayID a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GetDisplaySafeInsets,(SDL_DisplayID a, int *b, int *c, int *d, int *e),(a,b,c,d,e),return)
SDL_DYNAPI_PROC(int,SDL_GetDisplayUsableBounds,(SDL_DisplayID a, SDL_Rect *b),(a,b),return)
SDL_DYNAPI_PROC(const SDL_DisplayID*,SDL_GetDisplays,(int *a),(a),return)
SDL_DYNAPI_PROC(const char*,SDL_GetError,(void),(),return)
Expand Down
13 changes: 13 additions & 0 deletions src/test/SDL_test_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,7 @@ SDL_bool SDLTest_CommonInit(SDLTest_CommonState *state)
displays = SDL_GetDisplays(&n);
SDL_Log("Number of displays: %d\n", n);
for (i = 0; i < n; ++i) {
int inset_left = 0, inset_right = 0, inset_top = 0, inset_bottom = 0;
SDL_DisplayID displayID = displays[i];
SDL_Log("Display %" SDL_PRIu32 ": %s\n", displayID, SDL_GetDisplayName(displayID));

Expand All @@ -1214,8 +1215,11 @@ SDL_bool SDLTest_CommonInit(SDLTest_CommonState *state)
SDL_zero(usablebounds);
SDL_GetDisplayUsableBounds(displayID, &usablebounds);

SDL_GetDisplaySafeInsets(displayID, &inset_left, &inset_right, &inset_top, &inset_bottom);

SDL_Log("Bounds: %dx%d at %d,%d\n", bounds.w, bounds.h, bounds.x, bounds.y);
SDL_Log("Usable bounds: %dx%d at %d,%d\n", usablebounds.w, usablebounds.h, usablebounds.x, usablebounds.y);
SDL_Log("Safe insets: left: %d right: %d top: %d bottom: %d\n", inset_left, inset_right, inset_top, inset_bottom);

mode = SDL_GetDesktopDisplayMode(displayID);
SDL_GetMasksForPixelFormat(mode->format, &bpp, &Rmask, &Gmask,
Expand Down Expand Up @@ -2518,6 +2522,10 @@ void SDLTest_CommonDrawWindowInfo(SDL_Renderer *renderer, SDL_Window *window, fl
const char *name;
SDL_RendererLogicalPresentation logical_presentation;
SDL_ScaleMode logical_scale_mode;
int safe_inset_left = 0;
int safe_inset_right = 0;
int safe_inset_top = 0;
int safe_inset_bottom = 0;

/* Video */

Expand Down Expand Up @@ -2656,6 +2664,11 @@ void SDLTest_CommonDrawWindowInfo(SDL_Renderer *renderer, SDL_Window *window, fl
SDLTest_DrawString(renderer, 0.0f, textY, text);
textY += lineHeight;

SDL_GetDisplaySafeInsets(windowDisplayID, &safe_inset_left, &safe_inset_right, &safe_inset_top, &safe_inset_bottom);
(void)SDL_snprintf(text, sizeof(text), "SDL_GetDisplaySafeInsets: left: %d, right: %d, top: %d, bottom: %d", safe_inset_left, safe_inset_right, safe_inset_top, safe_inset_bottom);
SDLTest_DrawString(renderer, 0.0f, textY, text);
textY += lineHeight;

/* Mouse */

SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
Expand Down
9 changes: 9 additions & 0 deletions src/video/SDL_sysvideo.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ typedef struct SDL_VideoData SDL_VideoData;
typedef struct SDL_DisplayData SDL_DisplayData;
typedef struct SDL_WindowData SDL_WindowData;

typedef struct
{
int left;
int right;
int top;
int bottom;
} SDL_RectInsets;

typedef struct
{
float SDR_white_level;
Expand Down Expand Up @@ -145,6 +153,7 @@ struct SDL_VideoDisplay
SDL_DisplayOrientation natural_orientation;
SDL_DisplayOrientation current_orientation;
float content_scale;
SDL_RectInsets safe_insets;
SDL_HDROutputProperties HDR;

SDL_Window *fullscreen_window;
Expand Down
34 changes: 34 additions & 0 deletions src/video/SDL_video.c
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,40 @@ int SDL_GetDisplayUsableBounds(SDL_DisplayID displayID, SDL_Rect *rect)
return SDL_GetDisplayBounds(displayID, rect);
}

int SDL_GetDisplaySafeInsets(SDL_DisplayID displayID, int *left, int *right, int *top, int *bottom)
{
SDL_VideoDisplay *display = SDL_GetVideoDisplay(displayID);

if (left) {
*left = 0;
}
if (right) {
*right = 0;
}
if (top) {
*top = 0;
}
if (bottom) {
*bottom = 0;
}

CHECK_DISPLAY_MAGIC(display, -1);

if (left) {
*left = display->safe_insets.left;
}
if (right) {
*right = display->safe_insets.right;
}
if (top) {
*top = display->safe_insets.top;
}
if (bottom) {
*bottom = display->safe_insets.bottom;
}
return 0;
}

SDL_DisplayOrientation SDL_GetNaturalDisplayOrientation(SDL_DisplayID displayID)
{
SDL_VideoDisplay *display = SDL_GetVideoDisplay(displayID);
Expand Down
14 changes: 14 additions & 0 deletions src/video/cocoa/SDL_cocoamodes.m
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,19 @@ static SDL_bool GetDisplayMode(SDL_VideoDevice *_this, CGDisplayModeRef vidmode,
return displayName;
}

static void Cocoa_GetSafeInsets(CGDirectDisplayID displayID, SDL_RectInsets *insets)
{
if (@available(macOS 10.12, *)) {
NSScreen *screen = GetNSScreenForDisplayID(displayID);
if (screen) {
insets->left = (int)SDL_ceilf(screen.safeAreaInsets.left);
insets->right = (int)SDL_ceilf(screen.safeAreaInsets.right);
insets->top = (int)SDL_ceilf(screen.safeAreaInsets.top);
insets->bottom = (int)SDL_ceilf(screen.safeAreaInsets.bottom);
}
}
}

static void Cocoa_GetHDRProperties(CGDirectDisplayID displayID, SDL_HDROutputProperties *HDR)
{
HDR->SDR_white_level = 1.0f;
Expand Down Expand Up @@ -383,6 +396,7 @@ void Cocoa_InitModes(SDL_VideoDevice *_this)
CVDisplayLinkRelease(link);
CGDisplayModeRelease(moderef);

Cocoa_GetSafeInsets(displaydata->display, &display.safe_insets);
Cocoa_GetHDRProperties(displaydata->display, &display.HDR);

display.desktop_mode = mode;
Expand Down
2 changes: 2 additions & 0 deletions src/video/uikit/SDL_uikitview.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,6 @@
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)safeAreaInsetsDidChange;

@end
13 changes: 13 additions & 0 deletions src/video/uikit/SDL_uikitview.m
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,19 @@ - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
}
}

- (void)safeAreaInsetsDidChange
{
// Update the safe area insets
if (@available(iOS 11.0, tvOS 11.0, *)) {
SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(sdlwindow);

display->safe_insets.left = (int)SDL_ceilf(self.safeAreaInsets.left);
display->safe_insets.right = (int)SDL_ceilf(self.safeAreaInsets.right);
display->safe_insets.top = (int)SDL_ceilf(self.safeAreaInsets.top);
display->safe_insets.bottom = (int)SDL_ceilf(self.safeAreaInsets.bottom);
}
}

#if defined(SDL_PLATFORM_TVOS) || defined(__IPHONE_9_1)
- (SDL_Scancode)scancodeFromPress:(UIPress *)press
{
Expand Down

0 comments on commit 651ee3e

Please sign in to comment.