ohmu
·
2026-10-15
1#include "displayserver.h"
2#include "common/edidHelper.h"
3#include "common/windows/registry.h"
4#include "common/windows/unicode.h"
5
6#include <windows.h>
7#include <shellscalingapi.h>
8
9static inline void freeArgBuffer(FFArgBuffer* buffer) {
10 if (buffer->data) {
11 free(buffer->data);
12 }
13 buffer->data = nullptr;
14 buffer->length = 0;
15}\
16
17// http://undoc.airesoft.co.uk/user32.dll/IsThreadDesktopComposited.php
18BOOL WINAPI IsThreadDesktopComposited();
19BOOL WINAPI GetDpiForMonitorInternal(HMONITOR hmonitor, MONITOR_DPI_TYPE dpiType, UINT* dpiX, UINT* dpiY);
20
21static void detectDisplays(FFDisplayServerResult* ds) {
22 DISPLAYCONFIG_PATH_INFO paths[128];
23 uint32_t pathCount = ARRAY_SIZE(paths);
24 DISPLAYCONFIG_MODE_INFO modes[256];
25 uint32_t modeCount = ARRAY_SIZE(modes);
26
27 if (QueryDisplayConfig(
28 QDC_ONLY_ACTIVE_PATHS,
29 &pathCount,
30 paths,
31 &modeCount,
32 modes,
33 nullptr) == ERROR_SUCCESS) {
34 for (uint32_t i = 0; i < pathCount; ++i) {
35 const DISPLAYCONFIG_PATH_INFO* path = &paths[i];
36 const DISPLAYCONFIG_SOURCE_MODE* sourceMode = &modes[path->sourceInfo.modeInfoIdx].sourceMode;
37
38 FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
39 uint32_t physicalWidth = 0, physicalHeight = 0;
40
41 DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = {
42 .header = {
43 .type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME,
44 .size = sizeof(targetName),
45 .adapterId = path->targetInfo.adapterId,
46 .id = path->targetInfo.id,
47 },
48 };
49 [[gnu::cleanup(freeArgBuffer)]] FFArgBuffer edid = {};
50 if (DisplayConfigGetDeviceInfo(&targetName.header) == ERROR_SUCCESS) {
51 wchar_t regPath[256] = L"SYSTEM\\CurrentControlSet\\Enum";
52 wchar_t* pRegPath = regPath + strlen("SYSTEM\\CurrentControlSet\\Enum");
53 wchar_t* pDevPath = targetName.monitorDevicePath + strlen("\\\\?");
54 while (*pDevPath && *pDevPath != L'{') {
55 if (*pDevPath == L'#') {
56 *pRegPath = L'\\';
57 } else {
58 *pRegPath = *pDevPath;
59 }
60 ++pRegPath;
61 ++pDevPath;
62 assert(pRegPath < regPath + ARRAY_SIZE(regPath) + strlen("Device Parameters"));
63 }
64 wcscpy(pRegPath, L"Device Parameters");
65
66 FF_AUTO_CLOSE_FD HANDLE hKey = nullptr;
67 if (ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regPath, &hKey, nullptr) &&
68 ffRegReadData(hKey, L"EDID", &edid, nullptr) &&
69 ffEdidIsValid(edid.data, edid.length)) {
70 ffEdidGetName(edid.data, &name);
71 ffEdidGetPhysicalSize(edid.data, &physicalWidth, &physicalHeight);
72 } else {
73 edid.length = 0;
74 if (targetName.flags.friendlyNameFromEdid) {
75 ffStrbufSetWS(&name, targetName.monitorFriendlyDeviceName);
76 } else {
77 ffStrbufSetWS(&name, targetName.monitorDevicePath);
78 ffStrbufSubstrAfterFirstC(&name, '#');
79 ffStrbufSubstrBeforeFirstC(&name, '#');
80 }
81 }
82 }
83
84 uint32_t width = sourceMode->width;
85 uint32_t height = sourceMode->height;
86 uint32_t rotation;
87 switch (path->targetInfo.rotation) {
88 case DISPLAYCONFIG_ROTATION_ROTATE90:
89 rotation = 90;
90 break;
91 case DISPLAYCONFIG_ROTATION_ROTATE180:
92 rotation = 180;
93 break;
94 case DISPLAYCONFIG_ROTATION_ROTATE270:
95 rotation = 270;
96 break;
97 default:
98 rotation = 0;
99 break;
100 }
101
102 DISPLAYCONFIG_TARGET_PREFERRED_MODE preferredMode = {
103 .header = {
104 .type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE,
105 .size = sizeof(preferredMode),
106 .adapterId = path->targetInfo.adapterId,
107 .id = path->targetInfo.id,
108 }
109 };
110 double preferredRefreshRate = 0;
111 if (DisplayConfigGetDeviceInfo(&preferredMode.header) == ERROR_SUCCESS) {
112 DISPLAYCONFIG_RATIONAL freq = preferredMode.targetMode.targetVideoSignalInfo.vSyncFreq;
113 preferredRefreshRate = freq.Numerator / (double) freq.Denominator;
114 }
115
116 uint32_t systemDpi = 0;
117 HMONITOR hMonitor = MonitorFromPoint(*(POINT*) &sourceMode->position, MONITOR_DEFAULTTONULL);
118 if (hMonitor) {
119 UINT ignored;
120 GetDpiForMonitorInternal(hMonitor, MDT_EFFECTIVE_DPI, &systemDpi, &ignored);
121 }
122
123 if (systemDpi == 0) {
124 HDC hdc = GetDC(nullptr);
125 systemDpi = (uint32_t) GetDeviceCaps(hdc, LOGPIXELSX);
126 if (systemDpi == 0) {
127 systemDpi = 96;
128 }
129 ReleaseDC(nullptr, hdc);
130 }
131
132 if (path->targetInfo.rotation == DISPLAYCONFIG_ROTATION_ROTATE90 ||
133 path->targetInfo.rotation == DISPLAYCONFIG_ROTATION_ROTATE270) {
134 uint32_t temp = width;
135 width = height;
136 height = temp;
137 }
138
139 FFDisplayResult* display = ffdsAppendDisplay(ds,
140 width,
141 height,
142 path->targetInfo.refreshRate.Numerator / (double) path->targetInfo.refreshRate.Denominator,
143 systemDpi,
144 preferredMode.width,
145 preferredMode.height,
146 preferredRefreshRate,
147 rotation,
148 &name,
149 path->targetInfo.outputTechnology == DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER ? FF_DISPLAY_TYPE_UNKNOWN : path->targetInfo.outputTechnology == DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL || path->targetInfo.outputTechnology == DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED || path->targetInfo.outputTechnology == DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED ? FF_DISPLAY_TYPE_BUILTIN
150 : FF_DISPLAY_TYPE_EXTERNAL,
151 sourceMode->position.x == 0 && sourceMode->position.y == 0,
152 (uintptr_t) hMonitor,
153 physicalWidth,
154 physicalHeight,
155 "GDI");
156
157 if (display) {
158 DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO_2 advColorInfo2 = {
159 .header = {
160 .type = DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO_2,
161 .size = sizeof(advColorInfo2),
162 .adapterId = path->targetInfo.adapterId,
163 .id = path->targetInfo.id,
164 }
165 };
166 if (DisplayConfigGetDeviceInfo(&advColorInfo2.header) == ERROR_SUCCESS) {
167 if (advColorInfo2.highDynamicRangeUserEnabled) {
168 display->hdrStatus = FF_DISPLAY_HDR_STATUS_ENABLED;
169 } else if (advColorInfo2.highDynamicRangeSupported) {
170 display->hdrStatus = FF_DISPLAY_HDR_STATUS_SUPPORTED;
171 } else {
172 display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
173 }
174 display->bitDepth = (uint8_t) advColorInfo2.bitsPerColorChannel;
175 } else {
176 DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO advColorInfo = {
177 .header = {
178 .type = DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO,
179 .size = sizeof(advColorInfo),
180 .adapterId = path->targetInfo.adapterId,
181 .id = path->targetInfo.id,
182 }
183 };
184 if (DisplayConfigGetDeviceInfo(&advColorInfo.header) == ERROR_SUCCESS) {
185 if (advColorInfo.advancedColorEnabled) {
186 display->hdrStatus = FF_DISPLAY_HDR_STATUS_ENABLED;
187 } else if (advColorInfo.advancedColorSupported) {
188 display->hdrStatus = FF_DISPLAY_HDR_STATUS_SUPPORTED;
189 } else {
190 display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
191 }
192 display->bitDepth = (uint8_t) advColorInfo.bitsPerColorChannel;
193 } else {
194 display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNKNOWN;
195 }
196 }
197 if (edid.length > 0) {
198 ffEdidGetManufactureDate(edid.data, &display->manufactureYear, &display->manufactureWeek);
199 ffEdidGetSerial(edid.data, &display->serial);
200 }
201 display->drrStatus = path->flags & DISPLAYCONFIG_PATH_BOOST_REFRESH_RATE ? FF_DISPLAY_DRR_STATUS_ENABLED : FF_DISPLAY_DRR_STATUS_DISABLED;
202 }
203 }
204 }
205}
206
207void ffConnectDisplayServerImpl(FFDisplayServerResult* ds) {
208 if (IsThreadDesktopComposited()) {
209 ffStrbufSetStatic(&ds->wmProcessName, "dwm.exe");
210 ffStrbufSetStatic(&ds->wmPrettyName, "Desktop Window Manager");
211 } else {
212 // `explorer.exe` only provides a subset of WM functions, as well as the taskbar and desktop icons.
213 // While a window itself is drawn by kernel (GDI). Killing `explorer.exe` won't affect how windows are displayed generally.
214 ffStrbufSetStatic(&ds->wmProcessName, "explorer.exe");
215 ffStrbufSetStatic(&ds->wmPrettyName, "Internal");
216 }
217
218 detectDisplays(ds);
219}