diff --git a/cmake/Modules/FindXCB.cmake b/cmake/Modules/FindXCB.cmake index 823d1678fa049c607586e0c43835c9e6d36ea982..efeea58afa0ec8708953d0a576a9590eb9e7b334 100644 --- a/cmake/Modules/FindXCB.cmake +++ b/cmake/Modules/FindXCB.cmake @@ -53,7 +53,8 @@ set(knownComponents XCB UTIL XFIXES XTEST - XV) + XV + XINERAMA) unset(unknownComponents) @@ -111,6 +112,8 @@ foreach(comp ${comps}) list(APPEND pkgConfigModules "xcb-xtest") elseif("${comp}" STREQUAL "XV") list(APPEND pkgConfigModules "xcb-xv") + elseif("${comp}" STREQUAL "XINERAMA") + list(APPEND pkgConfigModules "xcb-xinerama") endif() endif() endforeach() @@ -187,6 +190,9 @@ macro(_XCB_HANDLE_COMPONENT _comp) elseif("${_comp}" STREQUAL "XV") set(_header "xcb/xv.h") set(_lib "xcb-xv") + elseif("${_comp}" STREQUAL "XINERAMA") + set(_header "xcb/xinerama.h") + set(_lib "xcb-xinerama") endif() find_path(XCB_${_comp}_INCLUDE_DIR NAMES ${_header} HINTS ${PKG_XCB_INCLUDE_DIRS}) diff --git a/obs/CMakeLists.txt b/obs/CMakeLists.txt index 43c6f90f78410c575a05e6265ba20cf4eed7fd02..3818eecb5bbb92bc6277359379274f660fb709d5 100644 --- a/obs/CMakeLists.txt +++ b/obs/CMakeLists.txt @@ -70,16 +70,19 @@ elseif(UNIX) set(obs_PLATFORM_SOURCES platform-x11.cpp) - find_package(X11) - include_directories(${X11_INCLUDE_DIRS} ${X11_Xinerama_INCLUDE_PATH}) - - if(NOT X11_Xinerama_FOUND) - message(FATAL_ERROR "Xinerama not found!") - endif() + find_package(XCB COMPONENTS XCB REQUIRED RANDR REQUIRED XINERAMA REQUIRED) + + include_directories( + ${XCB_INCLUDE_DIRS} + ${X11_XCB_INCLUDE_DIRS}) + + add_definitions( + ${XCB_DEFINITIONS} + ${X11_XCB_DEFINITIONS}) set(obs_PLATFORM_LIBRARIES - ${X11_LIBRARIES} - ${X11_Xinerama_LIB} + ${XCB_LIBRARIES} + ${X11_XCB_LIBRARIES} Qt5::X11Extras) endif() diff --git a/obs/platform-x11.cpp b/obs/platform-x11.cpp index 715f5073b292f0e7a3184f3c55ec3cb69ae8608b..65e0a621debe135d20ecc0f038edb74e57001180 100644 --- a/obs/platform-x11.cpp +++ b/obs/platform-x11.cpp @@ -23,8 +23,9 @@ #include #include "obs-app.hpp" -#include -#include +#include +#include +#include #include #include #include @@ -64,41 +65,54 @@ bool GetDataFilePath(const char *data, string &output) void GetMonitors(vector &monitors) { - int num_screens; - XineramaScreenInfo *screens; - int event_code = 0, error_code = 0; - Display* display = XOpenDisplay(NULL); - - if (!XineramaQueryExtension(display, &event_code, &error_code)) { - printf("Xinerama extension unavailable. We don't handle this " - "yet.\n"); - return; - } - - /* Do I need to make a call to XineramaQueryVersion...? */ - - screens = XineramaQueryScreens(display, &num_screens); - - if (num_screens == 0 || !screens) { - printf("Xinerama isn't active on this screen.\n"); - return; - } + xcb_connection_t* xcb_conn; monitors.clear(); + xcb_conn = xcb_connect(NULL, NULL); + + if (xcb_get_extension_data(xcb_conn, &xcb_xinerama_id)->present) { + xcb_xinerama_is_active_cookie_t xinerama_cookie; + xcb_xinerama_is_active_reply_t* xinerama_reply = NULL; + xcb_xinerama_query_screens_cookie_t screens_cookie; + xcb_xinerama_query_screens_reply_t* screens_reply = NULL; + xcb_xinerama_screen_info_iterator_t iter; + + xinerama_cookie = xcb_xinerama_is_active(xcb_conn); + xinerama_reply = xcb_xinerama_is_active_reply(xcb_conn, + xinerama_cookie, NULL); + + if (xinerama_reply == NULL || xinerama_reply->state == 0) { + free(xinerama_reply); + goto err; + } + + screens_cookie = xcb_xinerama_query_screens(xcb_conn); + screens_reply = xcb_xinerama_query_screens_reply(xcb_conn, + screens_cookie, NULL); + iter = xcb_xinerama_query_screens_screen_info_iterator( + screens_reply); + + for(; iter.rem; xcb_xinerama_screen_info_next(&iter)) { + monitors.emplace_back(iter.data->x_org, + iter.data->y_org, + iter.data->width, + iter.data->height); + } + free(xinerama_reply); + free(screens_reply); + } else { + // no xinerama so fall back to basic x11 calls + xcb_screen_iterator_t iter; + + iter = xcb_setup_roots_iterator(xcb_get_setup(xcb_conn)); + for(; iter.rem; xcb_screen_next(&iter)) { + monitors.emplace_back(0,0,iter.data->width_in_pixels, + iter.data->height_in_pixels); + } + } - do { - --num_screens; - - monitors.emplace_back( - screens[num_screens].x_org, - screens[num_screens].y_org, - screens[num_screens].width, - screens[num_screens].height - ); - } while (num_screens > 0); - - XFree(screens); - XCloseDisplay(display); +err: + xcb_disconnect(xcb_conn); } bool InitApplicationBundle()