From d4a0764464b2e274b2378f4523e6546c58192e3d Mon Sep 17 00:00:00 2001 From: Felipe Ferreira da Silva Date: Thu, 6 Apr 2017 16:48:08 -0300 Subject: [PATCH] Query work area for X11 The function ```glfwGetMonitorWorkarea``` retrieves the rectangle work area of the specified monitor. --- examples/simple.c | 3 +++ include/GLFW/glfw3.h | 25 +++++++++++++++++++++++++ src/internal.h | 1 + src/monitor.c | 19 +++++++++++++++++++ src/null_monitor.c | 4 ++++ src/x11_monitor.c | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 84 insertions(+) diff --git a/examples/simple.c b/examples/simple.c index 7752a3655..ce9c22d7d 100644 --- a/examples/simple.c +++ b/examples/simple.c @@ -79,6 +79,7 @@ int main(void) GLFWwindow* window; GLuint vertex_buffer, vertex_shader, fragment_shader, program; GLint mvp_location, vpos_location, vcol_location; + int workarea_x, workarea_y, workarea_width, workarea_height; glfwSetErrorCallback(error_callback); @@ -131,6 +132,8 @@ int main(void) glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE, sizeof(vertices[0]), (void*) (sizeof(float) * 2)); + glfwGetMonitorWorkarea(glfwGetPrimaryMonitor(), &workarea_x, &workarea_y, &workarea_width, &workarea_height); + printf("Monitor work area: %d, %d, %d, %d\n", workarea_x, workarea_y, workarea_width, workarea_height); while (!glfwWindowShouldClose(window)) { float ratio; diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 5436b9b48..db3f9d9c1 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1719,6 +1719,31 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void); */ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); +/*! @brief Returns the work area of the monitor. + * + * This function returns the position, in screen coordinates, of the upper-left + * corner of the specified monitor. + * + * Any or all of the position arguments may be `NULL`. If an error occurs, all + * non-`NULL` position arguments will be set to zero. + * + * @param[in] monitor The monitor to query. + * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`. + * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref monitor_properties + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height); + /*! @brief Returns the physical size of the monitor. * * This function returns the size, in millimetres, of the display area of the diff --git a/src/internal.h b/src/internal.h index be9ced898..35b5a6f60 100644 --- a/src/internal.h +++ b/src/internal.h @@ -597,6 +597,7 @@ const char* _glfwPlatformGetKeyName(int key, int scancode); int _glfwPlatformGetKeyScancode(int key); void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos); +void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height); GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count); void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode); void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp); diff --git a/src/monitor.c b/src/monitor.c index 4acecd588..b2ebe9e54 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -296,6 +296,25 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos) _glfwPlatformGetMonitorPos(monitor, xpos, ypos); } +GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle, int* xpos, int* ypos, int* width, int* height) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + + if (xpos) + *xpos = 0; + if (ypos) + *ypos = 0; + if (width) + *width = 0; + if (width) + *width = 0; + + _GLFW_REQUIRE_INIT(); + + _glfwPlatformGetMonitorWorkarea(monitor, xpos, ypos, width, height); +} + GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle; diff --git a/src/null_monitor.c b/src/null_monitor.c index f5678bbc3..1ca682bf1 100644 --- a/src/null_monitor.c +++ b/src/null_monitor.c @@ -36,6 +36,10 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) { } +void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height) +{ +} + GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) { return NULL; diff --git a/src/x11_monitor.c b/src/x11_monitor.c index 5c0516e67..02f9e7314 100644 --- a/src/x11_monitor.c +++ b/src/x11_monitor.c @@ -338,6 +338,38 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) } } +void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height) +{ + if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) + { + Atom workarea = XInternAtom(_glfw.x11.display, "_NET_WORKAREA", True); + Atom type; + int format; + unsigned long num; + unsigned long bytesLeft; + unsigned long *workareaValues; + unsigned char *data = NULL; + + if(workarea == None) + return; + + if (XGetWindowProperty(_glfw.x11.display, _glfw.x11.root, workarea, 0, + 4 * 32, False, AnyPropertyType, &type, &format, + &num, &bytesLeft, &data) != Success) { + return; + } + + if(type == None || format == 0 || bytesLeft || num % 4) + return; + + workareaValues = (unsigned long*)data; + *xpos = workareaValues[0]; + *ypos = workareaValues[1]; + *width = workareaValues[2]; + *height = workareaValues[3]; + } +} + GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) { GLFWvidmode* result;