Преглед изворни кода

UI: Get actual projector monitor name on windows

jp9000 пре 5 година
родитељ
комит
e93d44dd18
3 измењених фајлова са 91 додато и 9 уклоњено
  1. 84 0
      UI/platform-windows.cpp
  2. 1 0
      UI/platform.hpp
  3. 6 9
      UI/window-basic-main.cpp

+ 84 - 0
UI/platform-windows.cpp

@@ -19,6 +19,7 @@
 #include <sstream>
 #include "obs-config.h"
 #include "obs-app.hpp"
+#include "qt-wrappers.hpp"
 #include "platform.hpp"
 
 #include <util/windows/win-version.h>
@@ -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<DISPLAYCONFIG_PATH_INFO> paths(numPath);
+	std::vector<DISPLAYCONFIG_MODE_INFO> 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);
+}

+ 1 - 0
UI/platform.hpp

@@ -60,6 +60,7 @@ public:
 };
 
 RunOnceMutex GetRunOnceMutex(bool &already_running);
+QString GetMonitorName(const QString &id);
 #endif
 
 #ifdef __APPLE__

+ 6 - 9
UI/window-basic-main.cpp

@@ -29,6 +29,7 @@
 #include <QColorDialog>
 #include <QSizePolicy>
 #include <QScrollBar>
+#include <QTextStream>
 
 #include <util/dstr.h>
 #include <util/util.hpp>
@@ -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<wchar_t> wideName;
-		os_utf8_to_wcs_ptr(screen->name().toStdString().c_str(), 0,
-				   &wideName);
-		EnumDisplayDevices(wideName, 0, &ddev, 1);
-		BPtr<char> 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)