diff --git a/UI/platform-windows.cpp b/UI/platform-windows.cpp index 2ea812704..61ac6bc82 100644 --- a/UI/platform-windows.cpp +++ b/UI/platform-windows.cpp @@ -19,6 +19,7 @@ #include #include "obs-config.h" #include "obs-app.hpp" +#include "qt-wrappers.hpp" #include "platform.hpp" #include @@ -330,3 +331,86 @@ RunOnceMutex GetRunOnceMutex(bool &already_running) RunOnceMutex rom(h ? new RunOnceMutexData(h) : nullptr); return rom; } + +struct MonitorData { + const wchar_t *id; + MONITORINFOEX info; + bool found; +}; + +static BOOL CALLBACK GetMonitorCallback(HMONITOR monitor, HDC, LPRECT, + LPARAM param) +{ + MonitorData *data = (MonitorData *)param; + + if (GetMonitorInfoW(monitor, &data->info)) { + if (wcscmp(data->info.szDevice, data->id) == 0) { + data->found = true; + return false; + } + } + + return true; +} + +#define GENERIC_MONITOR_NAME QStringLiteral("Generic PnP Monitor") + +QString GetMonitorName(const QString &id) +{ + MonitorData data = {}; + data.id = (const wchar_t *)id.utf16(); + data.info.cbSize = sizeof(data.info); + + EnumDisplayMonitors(nullptr, nullptr, GetMonitorCallback, + (LPARAM)&data); + if (!data.found) { + return GENERIC_MONITOR_NAME; + } + + UINT32 numPath, numMode; + if (!GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &numPath, + &numMode) == ERROR_SUCCESS) { + return GENERIC_MONITOR_NAME; + } + + std::vector paths(numPath); + std::vector modes(numMode); + + if (!QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &numPath, paths.data(), + &numMode, modes.data(), + nullptr) == ERROR_SUCCESS) { + return GENERIC_MONITOR_NAME; + } + + DISPLAYCONFIG_TARGET_DEVICE_NAME target; + bool found = false; + + paths.resize(numPath); + for (size_t i = 0; i < numPath; ++i) { + const DISPLAYCONFIG_PATH_INFO &path = paths[i]; + + DISPLAYCONFIG_SOURCE_DEVICE_NAME s; + s.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; + s.header.size = sizeof(s); + s.header.adapterId = path.sourceInfo.adapterId; + s.header.id = path.sourceInfo.id; + + if (DisplayConfigGetDeviceInfo(&s.header) == ERROR_SUCCESS && + wcscmp(data.info.szDevice, s.viewGdiDeviceName) == 0) { + target.header.type = + DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME; + target.header.size = sizeof(target); + target.header.adapterId = path.sourceInfo.adapterId; + target.header.id = path.targetInfo.id; + found = DisplayConfigGetDeviceInfo(&target.header) == + ERROR_SUCCESS; + break; + } + } + + if (!found) { + return GENERIC_MONITOR_NAME; + } + + return QString::fromWCharArray(target.monitorFriendlyDeviceName); +} diff --git a/UI/platform.hpp b/UI/platform.hpp index f1ab78191..6100e6fc2 100644 --- a/UI/platform.hpp +++ b/UI/platform.hpp @@ -60,6 +60,7 @@ public: }; RunOnceMutex GetRunOnceMutex(bool &already_running); +QString GetMonitorName(const QString &id); #endif #ifdef __APPLE__ diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index 495258afd..8de00ebf4 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -4173,15 +4174,11 @@ void OBSBasic::AddProjectorMenuMonitors(QMenu *parent, QObject *target, QRect screenGeometry = screen->geometry(); QString name = ""; #ifdef _WIN32 - DISPLAY_DEVICE ddev; - ddev.cb = sizeof(ddev); - BPtr wideName; - os_utf8_to_wcs_ptr(screen->name().toStdString().c_str(), 0, - &wideName); - EnumDisplayDevices(wideName, 0, &ddev, 1); - BPtr newName; - os_wcs_to_utf8_ptr(ddev.DeviceString, 0, &newName); - name = newName; + QTextStream fullname(&name); + fullname << GetMonitorName(screen->name()); + fullname << " ("; + fullname << (i + 1); + fullname << ")"; #elif defined(__APPLE__) name = screen->name(); #elif QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)