diff options
author | Jay Sorg <jay.sorg@gmail.com> | 2015-04-29 09:54:30 +0300 |
---|---|---|
committer | Jay Sorg <jay.sorg@gmail.com> | 2015-04-29 09:54:30 +0300 |
commit | 0d7b35d5b3416e66f135969062e9a0d9d2752283 (patch) | |
tree | 68dcc52669321c261d6f5224050b9ddea72fb51a | |
parent | bc87e36e4608dce6e435d0069b08e8079513839c (diff) |
add xrandr support for multimon
-rw-r--r-- | client/X11/CMakeLists.txt | 7 | ||||
-rw-r--r-- | client/X11/xf_monitor.c | 68 | ||||
-rw-r--r-- | cmake/ConfigOptions.cmake | 3 | ||||
-rw-r--r-- | cmake/FindXrandr.cmake | 20 | ||||
-rw-r--r-- | libfreerdp-core/gcc.c | 2 |
5 files changed, 87 insertions, 13 deletions
diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt index 29f9ad8..25eb418 100644 --- a/client/X11/CMakeLists.txt +++ b/client/X11/CMakeLists.txt @@ -85,6 +85,13 @@ if(WITH_XV) target_link_libraries(xfreerdp ${XV_LIBRARIES}) endif() +find_suggested_package(Xrandr) +if(WITH_XRANDR) + add_definitions(-DWITH_XRANDR) + include_directories(${XRANDR_INCLUDE_DIRS}) + target_link_libraries(xfreerdp ${XRANDR_LIBRARIES}) +endif() + include_directories(${CMAKE_SOURCE_DIR}/resources) target_link_libraries(xfreerdp freerdp-core) diff --git a/client/X11/xf_monitor.c b/client/X11/xf_monitor.c index afd71f9..96e58bd 100644 --- a/client/X11/xf_monitor.c +++ b/client/X11/xf_monitor.c @@ -23,7 +23,9 @@ #include <X11/Xlib.h> #include <X11/Xutil.h> -#ifdef WITH_XINERAMA +#if defined(WITH_XRANDR) +#include <X11/extensions/Xrandr.h> +#elif defined(WITH_XINERAMA) #include <X11/extensions/Xinerama.h> #endif @@ -36,11 +38,22 @@ tbool xf_detect_monitors(xfInfo* xfi, rdpSettings* settings) int i; VIRTUAL_SCREEN* vscreen; -#ifdef WITH_XINERAMA +#if defined(WITH_XRANDR) + int ignored, ignored2; + RROutput primary_output; + XRRScreenResources *screen_resources; + Window root; + XRROutputInfo *oi; + XRRCrtcInfo *ci; + RROutput output; + int count; +#elif defined(WITH_XINERAMA) int ignored, ignored2; XineramaScreenInfo* screen_info = NULL; #endif + printf("xf_detect_monitors:\n"); + if (settings->num_monitors > 0) { /* already setup */ @@ -76,19 +89,52 @@ tbool xf_detect_monitors(xfInfo* xfi, rdpSettings* settings) if (settings->fullscreen == false && settings->workarea == false) return true; -#ifdef WITH_XINERAMA + vscreen->monitors = xzalloc(sizeof(MONITOR_INFO) * 16); + +#if defined(WITH_XRANDR) + if (XRRQueryExtension(xfi->display, &ignored, &ignored2)) + { + root = RootWindowOfScreen(xfi->screen); + primary_output = XRRGetOutputPrimary(xfi->display, root); + screen_resources = XRRGetScreenResources(xfi->display, root); + if (screen_resources != NULL) + { + count = 0; + for (i = 0; i < screen_resources->noutput; i++) + { + output = screen_resources->outputs[i]; + oi = XRRGetOutputInfo(xfi->display, screen_resources, output); + if (oi != NULL) + { + if (oi->connection == RR_Connected) + { + ci = XRRGetCrtcInfo(xfi->display, screen_resources, oi->crtc); + if (ci != NULL && count < 16) + { + vscreen->monitors[count].area.left = ci->x; + vscreen->monitors[count].area.top = ci->y; + vscreen->monitors[count].area.right = ci->x + ci->width - 1; + vscreen->monitors[count].area.bottom = ci->y + ci->height - 1; + vscreen->monitors[count].primary = output == primary_output; + XRRFreeCrtcInfo(ci); + count++; + } + } + XRRFreeOutputInfo(oi); + } + } + vscreen->nmonitors = count; + XRRFreeScreenResources(screen_resources); + } + } +#elif defined(WITH_XINERAMA) if (XineramaQueryExtension(xfi->display, &ignored, &ignored2)) { if (XineramaIsActive(xfi->display)) { screen_info = XineramaQueryScreens(xfi->display, &vscreen->nmonitors); - - if (vscreen->nmonitors > 16) - vscreen->nmonitors = 0; - - vscreen->monitors = xzalloc(sizeof(MONITOR_INFO) * vscreen->nmonitors); - - if (vscreen->nmonitors) + vscreen->nmonitors = MIN(16, vscreen->nmonitors); + if (vscreen->nmonitors > 0) { for (i = 0; i < vscreen->nmonitors; i++) { @@ -96,12 +142,10 @@ tbool xf_detect_monitors(xfInfo* xfi, rdpSettings* settings) vscreen->monitors[i].area.top = screen_info[i].y_org; vscreen->monitors[i].area.right = screen_info[i].x_org + screen_info[i].width - 1; vscreen->monitors[i].area.bottom = screen_info[i].y_org + screen_info[i].height - 1; - if ((screen_info[i].x_org == 0) && (screen_info[i].y_org == 0)) vscreen->monitors[i].primary = true; } } - XFree(screen_info); } } diff --git a/cmake/ConfigOptions.cmake b/cmake/ConfigOptions.cmake index f652eb7..e9045ba 100644 --- a/cmake/ConfigOptions.cmake +++ b/cmake/ConfigOptions.cmake @@ -30,3 +30,6 @@ option(WITH_H264 "Use H264 decoding." OFF) option(WITH_CUPS "Use CUPS printing." OFF) option(WITH_XRDPVR "Use xrdp video redirection." ON) option(WITH_TCUTILS "Use Thinclient utilities." ON) +option(WITH_XINERAMA "Use xinerama extension" OFF) +option(WITH_XRANDR "Use xrandr extension" ON) + diff --git a/cmake/FindXrandr.cmake b/cmake/FindXrandr.cmake new file mode 100644 index 0000000..8ba132c --- /dev/null +++ b/cmake/FindXrandr.cmake @@ -0,0 +1,20 @@ + +find_path(XRANDR_INCLUDE_DIR NAMES X11/extensions/Xrandr.h + PATH_SUFFIXES X11/extensions + DOC "The Xrandr include directory" +) + +find_library(XRANDR_LIBRARY NAMES Xrandr + DOC "The Xrandr library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xrandr DEFAULT_MSG XRANDR_LIBRARY XRANDR_INCLUDE_DIR) + +if(XRANDR_FOUND) + set( XRANDR_LIBRARIES ${XRANDR_LIBRARY} ) + set( XRANDR_INCLUDE_DIRS ${XRANDR_INCLUDE_DIR} ) +endif() + +mark_as_advanced(XRANDR_INCLUDE_DIR XRANDR_LIBRARY) + diff --git a/libfreerdp-core/gcc.c b/libfreerdp-core/gcc.c index 7070c88..6721937 100644 --- a/libfreerdp-core/gcc.c +++ b/libfreerdp-core/gcc.c @@ -359,7 +359,7 @@ void gcc_write_client_data_blocks(STREAM* s, rdpSettings* settings) /* extended client data supported */ - if (settings->negotiationFlags) + //if (settings->negotiationFlags) gcc_write_client_monitor_data(s, settings); } |