1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/display/win/display_config_helper.h"
#include <vector>
#include "base/compiler_specific.h"
namespace display::win {
namespace {
std::vector<DISPLAYCONFIG_PATH_INFO> GetDisplayConfigPathInfos() {
for (LONG result = ERROR_INSUFFICIENT_BUFFER;
result == ERROR_INSUFFICIENT_BUFFER;) {
uint32_t path_elements, mode_elements;
if (::GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &path_elements,
&mode_elements) != ERROR_SUCCESS) {
return {};
}
std::vector<DISPLAYCONFIG_PATH_INFO> path_infos(path_elements);
std::vector<DISPLAYCONFIG_MODE_INFO> mode_infos(mode_elements);
result = ::QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &path_elements,
path_infos.data(), &mode_elements,
mode_infos.data(), nullptr);
if (result == ERROR_SUCCESS) {
path_infos.resize(path_elements);
return path_infos;
}
}
return {};
}
bool GetTargetDeviceName(const DISPLAYCONFIG_PATH_INFO& path,
DISPLAYCONFIG_TARGET_DEVICE_NAME* device_name) {
device_name->header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME;
device_name->header.size = sizeof(DISPLAYCONFIG_TARGET_DEVICE_NAME);
device_name->header.adapterId = path.targetInfo.adapterId;
device_name->header.id = path.targetInfo.id;
LONG result = DisplayConfigGetDeviceInfo(&device_name->header);
return result == ERROR_SUCCESS;
}
} // namespace
std::optional<DISPLAYCONFIG_PATH_INFO> GetDisplayConfigPathInfo(
HMONITOR monitor) {
// Get the monitor name.
MONITORINFOEX monitor_info = {};
monitor_info.cbSize = sizeof(monitor_info);
if (!::GetMonitorInfo(monitor, &monitor_info)) {
return std::nullopt;
}
return GetDisplayConfigPathInfo(monitor_info);
}
DISPLAY_EXPORT std::optional<DISPLAYCONFIG_PATH_INFO> GetDisplayConfigPathInfo(
MONITORINFOEX monitor_info) {
// Look for a path info with a matching name.
for (const auto& info : GetDisplayConfigPathInfos()) {
DISPLAYCONFIG_SOURCE_DEVICE_NAME device_name = {};
device_name.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME;
device_name.header.size = sizeof(device_name);
device_name.header.adapterId = info.sourceInfo.adapterId;
device_name.header.id = info.sourceInfo.id;
if ((::DisplayConfigGetDeviceInfo(&device_name.header) == ERROR_SUCCESS) &&
(UNSAFE_TODO(wcscmp(monitor_info.szDevice,
device_name.viewGdiDeviceName)) == 0)) {
return info;
}
}
return std::nullopt;
}
UINT16 GetDisplayManufacturerId(
const std::optional<DISPLAYCONFIG_PATH_INFO>& path) {
DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = {};
if (path && GetTargetDeviceName(*path, &targetName)) {
return targetName.edidManufactureId;
}
return 0;
}
UINT16 GetDisplayProductCode(
const std::optional<DISPLAYCONFIG_PATH_INFO>& path) {
DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = {};
if (path && GetTargetDeviceName(*path, &targetName)) {
return targetName.edidProductCodeId;
}
return 0;
}
} // namespace display::win
|