From 5696e88e6bd5a5ec28ce066a500b5949e6e10060 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 5 Jan 2016 02:29:06 -0500 Subject: [PATCH] Added SDL_GetWindowBordersSize(). This is currently only implemented for X11. This patch is based on work in Unreal Engine 4's fork of SDL, compliments of Epic Games. --- include/SDL_video.h | 19 +++++++++++++++++++ src/dynapi/SDL_dynapi_overrides.h | 1 + src/dynapi/SDL_dynapi_procs.h | 1 + src/video/SDL_sysvideo.h | 1 + src/video/SDL_video.c | 22 ++++++++++++++++++++++ src/video/x11/SDL_x11video.c | 1 + src/video/x11/SDL_x11window.c | 28 ++++++++++++++++++++++++++++ src/video/x11/SDL_x11window.h | 1 + 8 files changed, 74 insertions(+) diff --git a/include/SDL_video.h b/include/SDL_video.h index 3365ab886919d..b439ef9f64e46 100644 --- a/include/SDL_video.h +++ b/include/SDL_video.h @@ -611,6 +611,25 @@ extern DECLSPEC void SDLCALL SDL_SetWindowSize(SDL_Window * window, int w, extern DECLSPEC void SDLCALL SDL_GetWindowSize(SDL_Window * window, int *w, int *h); +/** + * \brief Get the size of a window's borders (decorations) around the client area. + * + * \param window The window to query. + * \param top Pointer to variable for storing the size of the top border. NULL is permitted. + * \param left Pointer to variable for storing the size of the left border. NULL is permitted. + * \param bottom Pointer to variable for storing the size of the bottom border. NULL is permitted. + * \param right Pointer to variable for storing the size of the right border. NULL is permitted. + * + * \return 0 on success, or -1 if getting this information is not supported. + * + * \note if this function fails (returns -1), the size values will be + * initialized to 0, 0, 0, 0 (if a non-NULL pointer is provided), as + * if the window in question was borderless. + */ +extern DECLSPEC int SDLCALL SDL_GetWindowBordersSize(SDL_Window * window, + int *top, int *left, + int *bottom, int *right); + /** * \brief Set the minimum size of a window's client area. * diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 9292582329e1f..a4dcf7825a9f9 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -598,3 +598,4 @@ #define SDL_GameControllerFromInstanceID SDL_GameControllerFromInstanceID_REAL #define SDL_JoystickFromInstanceID SDL_JoystickFromInstanceID_REAL #define SDL_GetDisplayUsableBounds SDL_GetDisplayUsableBounds_REAL +#define SDL_GetWindowBordersSize SDL_GetWindowBordersSize_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 7146492e38f67..a0191c4803876 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -632,3 +632,4 @@ SDL_DYNAPI_PROC(SDL_JoystickPowerLevel,SDL_JoystickCurrentPowerLevel,(SDL_Joysti 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) +SDL_DYNAPI_PROC(int,SDL_GetWindowBordersSize,(SDL_Window *a, int *b, int *c, int *d, int *e),(a,b,c,d,e),return) diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 09e5613bd2d6d..25436ca747a48 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -206,6 +206,7 @@ struct SDL_VideoDevice void (*SetWindowSize) (_THIS, SDL_Window * window); void (*SetWindowMinimumSize) (_THIS, SDL_Window * window); void (*SetWindowMaximumSize) (_THIS, SDL_Window * window); + int (*GetWindowBordersSize) (_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right); void (*ShowWindow) (_THIS, SDL_Window * window); void (*HideWindow) (_THIS, SDL_Window * window); void (*RaiseWindow) (_THIS, SDL_Window * window); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 8a0e20ec9240f..826e9fdc26c41 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -1907,6 +1907,28 @@ SDL_SetWindowMinimumSize(SDL_Window * window, int min_w, int min_h) } } +int +SDL_GetWindowBordersSize(SDL_Window * window, int *top, int *left, int *bottom, int *right) +{ + int dummy = 0; + + if (!top) { top = &dummy; } + if (!left) { left = &dummy; } + if (!right) { right = &dummy; } + if (!bottom) { bottom = &dummy; } + + /* Always initialize, so applications don't have to care */ + *top = *left = *bottom = *right = 0; + + CHECK_WINDOW_MAGIC(window, -1); + + if (!_this->GetWindowBordersSize) { + return SDL_Unsupported(); + } + + return _this->GetWindowBordersSize(_this, window, top, left, bottom, right); +} + void SDL_GetWindowMinimumSize(SDL_Window * window, int *min_w, int *min_h) { diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index a2ea05695c9f7..e085cf7a835b7 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -232,6 +232,7 @@ X11_CreateDevice(int devindex) device->SetWindowSize = X11_SetWindowSize; device->SetWindowMinimumSize = X11_SetWindowMinimumSize; device->SetWindowMaximumSize = X11_SetWindowMaximumSize; + device->GetWindowBordersSize = X11_GetWindowBordersSize; device->ShowWindow = X11_ShowWindow; device->HideWindow = X11_HideWindow; device->RaiseWindow = X11_RaiseWindow; diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index 47731cd1977b3..9c1fc6421be31 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -895,6 +895,34 @@ X11_SetWindowSize(_THIS, SDL_Window * window) X11_XFlush(display); } +int +X11_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + Display *display = data->videodata->display; + Atom _NET_FRAME_EXTENTS = X11_XInternAtom(display, "_NET_FRAME_EXTENTS", 0); + Atom type; + int format; + unsigned long nitems, bytes_after; + unsigned char *property; + int result = -1; + + if (X11_XGetWindowProperty(display, data->xwindow, _NET_FRAME_EXTENTS, + 0, 16, 0, XA_CARDINAL, &type, &format, + &nitems, &bytes_after, &property) == Success) { + if (type != None && nitems == 4) { + *left = (int) (((long*)property)[0]); + *right = (int) (((long*)property)[1]); + *top = (int) (((long*)property)[2]); + *bottom = (int) (((long*)property)[3]); + result = 0; + } + X11_XFree(property); + } + + return result; +} + void X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) { diff --git a/src/video/x11/SDL_x11window.h b/src/video/x11/SDL_x11window.h index ce19499db2f6c..24e443896be5a 100644 --- a/src/video/x11/SDL_x11window.h +++ b/src/video/x11/SDL_x11window.h @@ -79,6 +79,7 @@ extern void X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); extern void X11_SetWindowPosition(_THIS, SDL_Window * window); extern void X11_SetWindowMinimumSize(_THIS, SDL_Window * window); extern void X11_SetWindowMaximumSize(_THIS, SDL_Window * window); +extern int X11_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right); extern void X11_SetWindowSize(_THIS, SDL_Window * window); extern void X11_ShowWindow(_THIS, SDL_Window * window); extern void X11_HideWindow(_THIS, SDL_Window * window);