From f3eb8aacfeb9c1f2f93b1bea0003e1279f23adc6 Mon Sep 17 00:00:00 2001 From: Warren Turkal Date: Mon, 3 Oct 2016 23:50:13 -0700 Subject: [PATCH] UI: Use Qt lib for screen info instead of x11 libs All of the monitor discovery logic can be implemented with Qt. This change removes all the x11 implementations in favor of Qt and removes a fair amount of platform specific code. --- UI/CMakeLists.txt | 14 +------- UI/obs-app.cpp | 16 +++------ UI/platform-osx.mm | 11 ------- UI/platform-windows.cpp | 22 ------------- UI/platform-x11.cpp | 63 ++---------------------------------- UI/platform.hpp | 11 ------- UI/window-basic-main.cpp | 31 +++++++++--------- UI/window-basic-settings.cpp | 12 +++---- UI/window-projector.cpp | 9 +++--- 9 files changed, 33 insertions(+), 156 deletions(-) diff --git a/UI/CMakeLists.txt b/UI/CMakeLists.txt index 69cd69376..99a67a845 100644 --- a/UI/CMakeLists.txt +++ b/UI/CMakeLists.txt @@ -83,19 +83,7 @@ elseif(UNIX) set(obs_PLATFORM_SOURCES platform-x11.cpp) - 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 - ${XCB_LIBRARIES} - ${X11_XCB_LIBRARIES} + set(obs_PLATFORM_LIBRARIES Qt5::X11Extras) endif() diff --git a/UI/obs-app.cpp b/UI/obs-app.cpp index e7bb8f643..84496f22e 100644 --- a/UI/obs-app.cpp +++ b/UI/obs-app.cpp @@ -29,7 +29,9 @@ #include #include +#include #include +#include #include "qt-wrappers.hpp" #include "obs-app.hpp" @@ -1520,20 +1522,10 @@ bool GetClosestUnusedFileName(std::string &path, const char *extension) bool WindowPositionValid(QRect rect) { - vector monitors; - GetMonitors(monitors); - - for (auto &monitor : monitors) { - int left = int(monitor.x); - int top = int(monitor.y); - int right = left + int(monitor.cx); - int bottom = top + int(monitor.cy); - - if ((rect.left() - right) < 0 && (left - rect.right()) < 0 && - (rect.top() - bottom) < 0 && (top - rect.bottom()) < 0) + for (QScreen* screen: QGuiApplication::screens()) { + if (screen->availableGeometry().intersects(rect)) return true; } - return false; } diff --git a/UI/platform-osx.mm b/UI/platform-osx.mm index d60f8ab92..19b1a9cdc 100644 --- a/UI/platform-osx.mm +++ b/UI/platform-osx.mm @@ -36,17 +36,6 @@ bool GetDataFilePath(const char *data, string &output) return !access(output.c_str(), R_OK); } -void GetMonitors(vector &monitors) -{ - monitors.clear(); - for(NSScreen *screen : [NSScreen screens]) - { - NSRect frame = [screen convertRectToBacking:[screen frame]]; - monitors.emplace_back(frame.origin.x, frame.origin.y, - frame.size.width, frame.size.height); - } -} - bool InitApplicationBundle() { #ifdef OBS_OSX_BUNDLE diff --git a/UI/platform-windows.cpp b/UI/platform-windows.cpp index 8edde6ec3..73863753b 100644 --- a/UI/platform-windows.cpp +++ b/UI/platform-windows.cpp @@ -51,28 +51,6 @@ bool GetDataFilePath(const char *data, string &output) return check_path(data, OBS_DATA_PATH "/obs-studio/", output); } -static BOOL CALLBACK OBSMonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, - LPRECT rect, LPARAM param) -{ - vector &monitors = *(vector *)param; - - monitors.emplace_back( - rect->left, - rect->top, - rect->right - rect->left, - rect->bottom - rect->top); - - UNUSED_PARAMETER(hMonitor); - UNUSED_PARAMETER(hdcMonitor); - return true; -} - -void GetMonitors(vector &monitors) -{ - monitors.clear(); - EnumDisplayMonitors(NULL, NULL, OBSMonitorEnumProc, (LPARAM)&monitors); -} - bool InitApplicationBundle() { return true; diff --git a/UI/platform-x11.cpp b/UI/platform-x11.cpp index 1cca5da51..c6b02b9b3 100644 --- a/UI/platform-x11.cpp +++ b/UI/platform-x11.cpp @@ -16,16 +16,12 @@ along with this program. If not, see . ******************************************************************************/ -/* Here we use xinerama to fetch data about monitor geometry - * Even if there are not multiple monitors, this should still work. - */ - #include #include "obs-app.hpp" -#include -#include -#include +#include +#include + #include #include #include @@ -63,59 +59,6 @@ bool GetDataFilePath(const char *data, string &output) return false; } -void GetMonitors(vector &monitors) -{ - xcb_connection_t* xcb_conn; - - monitors.clear(); - xcb_conn = xcb_connect(NULL, NULL); - - bool use_xinerama = false; - 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; - - xinerama_cookie = xcb_xinerama_is_active(xcb_conn); - xinerama_reply = xcb_xinerama_is_active_reply(xcb_conn, - xinerama_cookie, NULL); - - if (xinerama_reply && xinerama_reply->state != 0) - use_xinerama = true; - free(xinerama_reply); - } - - if (use_xinerama) { - xcb_xinerama_query_screens_cookie_t screens_cookie; - xcb_xinerama_query_screens_reply_t* screens_reply = NULL; - xcb_xinerama_screen_info_iterator_t iter; - - 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(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); - } - } - - xcb_disconnect(xcb_conn); -} - bool InitApplicationBundle() { return true; diff --git a/UI/platform.hpp b/UI/platform.hpp index ad579d625..1b1344be5 100644 --- a/UI/platform.hpp +++ b/UI/platform.hpp @@ -24,19 +24,8 @@ class QWidget; -struct MonitorInfo { - int32_t x, y; - uint32_t cx, cy; - - inline MonitorInfo() {} - inline MonitorInfo(int32_t x, int32_t y, uint32_t cx, uint32_t cy) - : x(x), y(y), cx(cx), cy(cy) - {} -}; - /* Gets the path of obs-studio specific data files (such as locale) */ bool GetDataFilePath(const char *data, std::string &path); -void GetMonitors(std::vector &monitors); /* Updates the working directory for OSX application bundles */ bool InitApplicationBundle(); diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index e7754615c..da5369a95 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -19,11 +19,14 @@ #include #include +#include #include #include #include #include #include +#include +#include #include #include @@ -780,17 +783,18 @@ static const double scaled_vals[] = bool OBSBasic::InitBasicConfigDefaults() { - vector monitors; - GetMonitors(monitors); + QList screens = QGuiApplication::screens(); - if (!monitors.size()) { + if (!screens.size()) { OBSErrorBox(NULL, "There appears to be no monitors. Er, this " "technically shouldn't be possible."); return false; } - uint32_t cx = monitors[0].cx; - uint32_t cy = monitors[0].cy; + QScreen *primaryScreen = QGuiApplication::primaryScreen(); + + uint32_t cx = primaryScreen->size().width(); + uint32_t cy = primaryScreen->size().height(); /* ----------------------------------------------------- */ /* move over mixer values in advanced if older config */ @@ -2768,19 +2772,16 @@ static void AddProjectorMenuMonitors(QMenu *parent, QObject *target, const char *slot) { QAction *action; - std::vector monitors; - GetMonitors(monitors); - - for (int i = 0; (size_t)i < monitors.size(); i++) { - const MonitorInfo &monitor = monitors[i]; - + QList screens = QGuiApplication::screens(); + for (int i = 0; i < screens.size(); i++) { + QRect screenGeometry = screens[i]->availableGeometry(); QString str = QString("%1 %2: %3x%4 @ %5,%6"). arg(QTStr("Display"), QString::number(i), - QString::number((int)monitor.cx), - QString::number((int)monitor.cy), - QString::number((int)monitor.x), - QString::number((int)monitor.y)); + QString::number((int)screenGeometry.width()), + QString::number((int)screenGeometry.height()), + QString::number((int)screenGeometry.x()), + QString::number((int)screenGeometry.y())); action = parent->addAction(str, target, slot); action->setProperty("monitor", i); diff --git a/UI/window-basic-settings.cpp b/UI/window-basic-settings.cpp index aab5c16fe..f2b9a6217 100644 --- a/UI/window-basic-settings.cpp +++ b/UI/window-basic-settings.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,7 @@ #include #include #include +#include #include #include @@ -950,8 +952,6 @@ void OBSBasicSettings::LoadRendererList() #endif } -Q_DECLARE_METATYPE(MonitorInfo); - static string ResString(uint32_t cx, uint32_t cy) { stringstream res; @@ -1097,14 +1097,12 @@ void OBSBasicSettings::LoadResolutionLists() uint32_t cy = config_get_uint(main->Config(), "Video", "BaseCY"); uint32_t out_cx = config_get_uint(main->Config(), "Video", "OutputCX"); uint32_t out_cy = config_get_uint(main->Config(), "Video", "OutputCY"); - vector monitors; ui->baseResolution->clear(); - GetMonitors(monitors); - - for (MonitorInfo &monitor : monitors) { - string res = ResString(monitor.cx, monitor.cy); + for (QScreen* screen: QGuiApplication::screens()) { + QSize as = screen->availableSize(); + string res = ResString(as.width(), as.height()); ui->baseResolution->addItem(res.c_str()); } diff --git a/UI/window-projector.cpp b/UI/window-projector.cpp index 5e3ecf972..1adf791b0 100644 --- a/UI/window-projector.cpp +++ b/UI/window-projector.cpp @@ -1,6 +1,8 @@ #include +#include #include #include +#include #include "window-projector.hpp" #include "display-helpers.hpp" #include "qt-wrappers.hpp" @@ -47,11 +49,8 @@ OBSProjector::~OBSProjector() void OBSProjector::Init(int monitor) { - std::vector monitors; - GetMonitors(monitors); - MonitorInfo &mi = monitors[monitor]; - - setGeometry(mi.x, mi.y, mi.cx, mi.cy); + QScreen *screen = QGuiApplication::screens()[monitor]; + setGeometry(screen->availableGeometry()); bool alwaysOnTop = config_get_bool(GetGlobalConfig(), "BasicWindow", "ProjectorAlwaysOnTop");