From e064aa6a99f4396a15dc02b039a94d200bf5287b Mon Sep 17 00:00:00 2001 From: David Fort Date: Fri, 24 Nov 2017 14:06:35 +0100 Subject: [PATCH] xfreerdp: when available use xrandr to get display infos --- client/X11/CMakeLists.txt | 11 +++++ client/X11/xf_monitor.c | 119 ++++++++++++++++++++++++++++------------------ 2 files changed, 85 insertions(+), 45 deletions(-) diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt index bde78f7..fdd5e9d 100644 --- a/client/X11/CMakeLists.txt +++ b/client/X11/CMakeLists.txt @@ -145,6 +145,10 @@ set(XRENDER_FEATURE_TYPE "RECOMMENDED") set(XRENDER_FEATURE_PURPOSE "rendering") set(XRENDER_FEATURE_DESCRIPTION "X11 render extension") +set(XRANDR_FEATURE_TYPE "RECOMMENDED") +set(XRANDR_FEATURE_PURPOSE "tracking output configuration") +set(XRANDR_FEATURE_DESCRIPTION "X11 randr extension") + set(XFIXES_FEATURE_TYPE "RECOMMENDED") set(XFIXES_FEATURE_PURPOSE "X11 xfixes extension") set(XFIXES_FEATURE_DESCRIPTION "Useful additions to the X11 core protocol") @@ -156,6 +160,7 @@ find_feature(Xcursor ${XCURSOR_FEATURE_TYPE} ${XCURSOR_FEATURE_PURPOSE} ${XCURSO find_feature(Xv ${XV_FEATURE_TYPE} ${XV_FEATURE_PURPOSE} ${XV_FEATURE_DESCRIPTION}) find_feature(Xi ${XI_FEATURE_TYPE} ${XI_FEATURE_PURPOSE} ${XI_FEATURE_DESCRIPTION}) find_feature(Xrender ${XRENDER_FEATURE_TYPE} ${XRENDER_FEATURE_PURPOSE} ${XRENDER_FEATURE_DESCRIPTION}) +find_feature(XRandR ${XRANDR_FEATURE_TYPE} ${XRANDR_FEATURE_PURPOSE} ${XRANDR_FEATURE_DESCRIPTION}) find_feature(Xfixes ${XFIXES_FEATURE_TYPE} ${XFIXES_FEATURE_PURPOSE} ${XFIXES_FEATURE_DESCRIPTION}) if(WITH_XINERAMA) @@ -194,6 +199,12 @@ if(WITH_XRENDER) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XRENDER_LIBRARIES}) endif() +if(NOT APPLE AND WITH_XRANDR) + add_definitions(-DWITH_XRANDR) + include_directories(${XRANDR_INCLUDE_DIRS}) + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XRANDR_LIBRARIES}) +endif() + if(WITH_XFIXES) add_definitions(-DWITH_XFIXES) include_directories(${XFIXES_INCLUDE_DIRS}) diff --git a/client/X11/xf_monitor.c b/client/X11/xf_monitor.c index ee8b696..47715a4 100644 --- a/client/X11/xf_monitor.c +++ b/client/X11/xf_monitor.c @@ -3,6 +3,7 @@ * X11 Monitor Handling * * Copyright 2011 Marc-Andre Moreau + * Copyright 2017 David Fort * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,30 +38,50 @@ #include #endif +#ifdef WITH_XRANDR +#include +#include +#endif + #include "xf_monitor.h" /* See MSDN Section on Multiple Display Monitors: http://msdn.microsoft.com/en-us/library/dd145071 */ int xf_list_monitors(xfContext* xfc) { -#ifdef WITH_XINERAMA Display* display; int major, minor; int i, nmonitors = 0; - XineramaScreenInfo* screen = NULL; - display = XOpenDisplay(NULL); + display = XOpenDisplay(NULL); if (!display) { WLog_ERR(TAG, "failed to open X display"); return -1; } +#ifdef WITH_XRANDR + if (XRRQueryExtension(xfc->display, &major, &minor)) + { + XRRMonitorInfo *monitors = XRRGetMonitors(xfc->display, DefaultRootWindow(xfc->display), 1, &nmonitors); + + for (i = 0; i < nmonitors; i++) + { + printf(" %s [%d] %hdx%hd\t+%hd+%hd\n", + monitors[i].primary ? "*" : " ", i, + monitors[i].width, monitors[i].height, + monitors[i].x, monitors[i].y); + } + XRRFreeMonitors(monitors); + } else +#endif + +#ifdef WITH_XINERAMA if (XineramaQueryExtension(display, &major, &minor)) { if (XineramaIsActive(display)) { - screen = XineramaQueryScreens(display, &nmonitors); + XineramaScreenInfo* screen = XineramaQueryScreens(display, &nmonitors); for (i = 0; i < nmonitors; i++) { @@ -72,25 +93,16 @@ int xf_list_monitors(xfContext* xfc) XFree(screen); } - } + } else - XCloseDisplay(display); #else - Screen* screen; - Display* display; - display = XOpenDisplay(NULL); - - if (!display) { - WLog_ERR(TAG, "failed to open X display"); - return -1; + Screen* screen = ScreenOfDisplay(display, DefaultScreen(display)); + printf(" * [0] %dx%d\t+0+0\n", WidthOfScreen(screen), HeightOfScreen(screen)); } +#endif - screen = ScreenOfDisplay(display, DefaultScreen(display)); - printf(" * [0] %dx%d\t+0+0\n", WidthOfScreen(screen), - HeightOfScreen(screen)); XCloseDisplay(display); -#endif return 0; } @@ -123,9 +135,8 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) Window _dummy_w; int current_monitor = 0; Screen* screen; -#ifdef WITH_XINERAMA +#if defined WITH_XINERAMA || defined WITH_XRANDR int major, minor; - XineramaScreenInfo* screenInfo = NULL; #endif vscreen = &xfc->vscreen; *pMaxWidth = settings->DesktopWidth; @@ -137,41 +148,59 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) &_dummy_i, &_dummy_i, (void*) &_dummy_i)) mouse_x = mouse_y = 0; -#ifdef WITH_XINERAMA - - if (XineramaQueryExtension(xfc->display, &major, &minor)) +#ifdef WITH_XRANDR + if (XRRQueryExtension(xfc->display, &major, &minor)) { - if (XineramaIsActive(xfc->display)) - { - screenInfo = XineramaQueryScreens(xfc->display, &vscreen->nmonitors); + XRRMonitorInfo *monitors = XRRGetMonitors(xfc->display, DefaultRootWindow(xfc->display), 1, &vscreen->nmonitors); - if (vscreen->nmonitors > 16) - vscreen->nmonitors = 0; + if (vscreen->nmonitors > 16) + vscreen->nmonitors = 0; - if (vscreen->nmonitors) + if (vscreen->nmonitors) + { + for (i = 0; i < vscreen->nmonitors; i++) { - for (i = 0; i < vscreen->nmonitors; i++) - { - vscreen->monitors[i].area.left = screenInfo[i].x_org; - vscreen->monitors[i].area.top = screenInfo[i].y_org; - vscreen->monitors[i].area.right = screenInfo[i].x_org + screenInfo[i].width - 1; - vscreen->monitors[i].area.bottom = screenInfo[i].y_org + screenInfo[i].height - - 1; - - /* Determine which monitor that the mouse cursor is on */ - if ((mouse_x >= vscreen->monitors[i].area.left) && - (mouse_x <= vscreen->monitors[i].area.right) && - (mouse_y >= vscreen->monitors[i].area.top) && - (mouse_y <= vscreen->monitors[i].area.bottom)) - current_monitor = i; - } + vscreen->monitors[i].area.left = monitors[i].x; + vscreen->monitors[i].area.top = monitors[i].y; + vscreen->monitors[i].area.right = monitors[i].x + monitors[i].width - 1; + vscreen->monitors[i].area.bottom = monitors[i].y + monitors[i].height - 1; + vscreen->monitors[i].primary = monitors[i].primary > 0; } + } + XRRFreeMonitors(monitors); + } else +#endif - XFree(screenInfo); +#ifdef WITH_XINERAMA + if (XineramaQueryExtension(xfc->display, &major, &minor) && XineramaIsActive(xfc->display)) + { + XineramaScreenInfo* screenInfo = XineramaQueryScreens(xfc->display, &vscreen->nmonitors); + + if (vscreen->nmonitors > 16) + vscreen->nmonitors = 0; + + if (vscreen->nmonitors) + { + for (i = 0; i < vscreen->nmonitors; i++) + { + vscreen->monitors[i].area.left = screenInfo[i].x_org; + vscreen->monitors[i].area.top = screenInfo[i].y_org; + vscreen->monitors[i].area.right = screenInfo[i].x_org + screenInfo[i].width - 1; + vscreen->monitors[i].area.bottom = screenInfo[i].y_org + screenInfo[i].height - 1; + + /* Determine which monitor that the mouse cursor is on */ + if ((mouse_x >= vscreen->monitors[i].area.left) && + (mouse_x <= vscreen->monitors[i].area.right) && + (mouse_y >= vscreen->monitors[i].area.top) && + (mouse_y <= vscreen->monitors[i].area.bottom)) + current_monitor = i; + } } - } + XFree(screenInfo); + } #endif + xfc->fullscreenMonitors.top = xfc->fullscreenMonitors.bottom = xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = 0; -- 2.7.4