Signed-off-by: Jacek Caban jacek@codeweavers.com --- dlls/winex11.drv/Makefile.in | 2 +- dlls/winex11.drv/display.c | 537 ++------------------------------- dlls/winex11.drv/init.c | 1 + dlls/winex11.drv/x11drv.h | 2 + dlls/winex11.drv/x11drv_main.c | 2 +- 5 files changed, 32 insertions(+), 512 deletions(-)
Hi Jacek,
There are many X11DRV_EnumDisplaySettingsEx() failures after this patch when running user32/tests/monitor.c tests that doesn't appear before. Also the monitor resolution doesn't get restored after finishing the tests.
... 0080:err:x11settings:X11DRV_EnumDisplaySettingsEx Failed to get L"\\.\DISPLAY1" registry display settings. 0080:err:x11settings:X11DRV_EnumDisplaySettingsEx Failed to get L"\\.\DISPLAY2" registry display settings. 0080:err:x11settings:X11DRV_EnumDisplaySettingsEx Failed to get L"\\.\DISPLAY1" registry display settings. 0080:err:x11settings:X11DRV_EnumDisplaySettingsEx Failed to get L"\\.\DISPLAY2" registry display settings. 0020:monitor: 942 tests executed (31 marked as todo, 0 failures), 1 skipped.
Thanks, Zhiyi
On 11/25/21 22:54, Jacek Caban wrote:
Signed-off-by: Jacek Caban jacek@codeweavers.com
dlls/winex11.drv/Makefile.in | 2 +- dlls/winex11.drv/display.c | 537 ++------------------------------- dlls/winex11.drv/init.c | 1 + dlls/winex11.drv/x11drv.h | 2 + dlls/winex11.drv/x11drv_main.c | 2 +- 5 files changed, 32 insertions(+), 512 deletions(-)
v2-0009-winex11-Use-UpdateDisplayDevices-driver-entry-point.txt
diff --git a/dlls/winex11.drv/Makefile.in b/dlls/winex11.drv/Makefile.in index e6451c849c8..c64a8464914 100644 --- a/dlls/winex11.drv/Makefile.in +++ b/dlls/winex11.drv/Makefile.in @@ -1,5 +1,5 @@ MODULE = winex11.drv -IMPORTS = uuid setupapi rpcrt4 user32 gdi32 advapi32 +IMPORTS = uuid setupapi rpcrt4 user32 gdi32 advapi32 win32u DELAYIMPORTS = comctl32 ole32 shell32 imm32 EXTRAINCL = $(X_CFLAGS) EXTRALIBS = $(X_LIBS) $(X_EXTRA_LIBS) diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 245c6b8a68d..04380ff660f 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -40,78 +40,14 @@
WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
-DEFINE_DEVPROPKEY(DEVPROPKEY_GPU_LUID, 0x60b193cb, 0x5276, 0x4d0f, 0x96, 0xfc, 0xf1, 0x73, 0xab, 0xad, 0x3e, 0xc6, 2); -DEFINE_DEVPROPKEY(DEVPROPKEY_MONITOR_GPU_LUID, 0xca085853, 0x16ce, 0x48aa, 0xb1, 0x14, 0xde, 0x9c, 0x72, 0x33, 0x42, 0x23, 1); -DEFINE_DEVPROPKEY(DEVPROPKEY_MONITOR_OUTPUT_ID, 0xca085853, 0x16ce, 0x48aa, 0xb1, 0x14, 0xde, 0x9c, 0x72, 0x33, 0x42, 0x23, 2);
/* Wine specific properties */ -DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_GPU_VULKAN_UUID, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5c, 2); -DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2); DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCMONITOR, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 3); -DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCWORK, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 4); -DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 5);
-static const WCHAR driver_date_dataW[] = {'D','r','i','v','e','r','D','a','t','e','D','a','t','a',0}; -static const WCHAR driver_dateW[] = {'D','r','i','v','e','r','D','a','t','e',0}; -static const WCHAR driver_descW[] = {'D','r','i','v','e','r','D','e','s','c',0}; static const WCHAR displayW[] = {'D','I','S','P','L','A','Y',0}; -static const WCHAR pciW[] = {'P','C','I',0}; -static const WCHAR video_idW[] = {'V','i','d','e','o','I','D',0}; -static const WCHAR symbolic_link_valueW[]= {'S','y','m','b','o','l','i','c','L','i','n','k','V','a','l','u','e',0}; -static const WCHAR gpu_idW[] = {'G','P','U','I','D',0}; -static const WCHAR monitor_id_fmtW[] = {'M','o','n','i','t','o','r','I','D','%','d',0}; -static const WCHAR adapter_name_fmtW[] = {'\','\','.','\','D','I','S','P','L','A','Y','%','d',0}; -static const WCHAR state_flagsW[] = {'S','t','a','t','e','F','l','a','g','s',0}; -static const WCHAR guid_fmtW[] = {
- '{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-','%','0','2','x','%','0','2','x','-',
- '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','}',0};
-static const WCHAR gpu_instance_fmtW[] = {
- 'P','C','I','\',
- 'V','E','N','_','%','0','4','X','&',
- 'D','E','V','_','%','0','4','X','&',
- 'S','U','B','S','Y','S','_','%','0','8','X','&',
- 'R','E','V','_','%','0','2','X','\',
- '%','0','8','X',0};
-static const WCHAR gpu_hardware_id_fmtW[] = {
- 'P','C','I','\',
- 'V','E','N','_','%','0','4','X','&',
- 'D','E','V','_','%','0','4','X','&',
- 'S','U','B','S','Y','S','_','0','0','0','0','0','0','0','0','&',
- 'R','E','V','_','0','0',0};
static const WCHAR video_keyW[] = { 'H','A','R','D','W','A','R','E','\', 'D','E','V','I','C','E','M','A','P','\', 'V','I','D','E','O',0}; -static const WCHAR adapter_key_fmtW[] = {
- 'S','y','s','t','e','m','\',
- 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\',
- 'C','o','n','t','r','o','l','\',
- 'V','i','d','e','o','\',
- '%','s','\',
- '%','0','4','x',0};
-static const WCHAR device_video_fmtW[] = {
- '\','D','e','v','i','c','e','\',
- 'V','i','d','e','o','%','d',0};
-static const WCHAR machine_prefixW[] = {
- '\','R','e','g','i','s','t','r','y','\',
- 'M','a','c','h','i','n','e','\',0};
-static const WCHAR nt_classW[] = {
- '\','R','e','g','i','s','t','r','y','\',
- 'M','a','c','h','i','n','e','\',
- 'S','y','s','t','e','m','\',
- 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\',
- 'C','o','n','t','r','o','l','\',
- 'C','l','a','s','s','\',0};
-static const WCHAR monitor_instance_fmtW[] = {
- 'D','I','S','P','L','A','Y','\',
- 'D','e','f','a','u','l','t','_','M','o','n','i','t','o','r','\',
- '%','0','4','X','&','%','0','4','X',0};
-static const WCHAR monitor_hardware_idW[] = {
- 'M','O','N','I','T','O','R','\',
- 'D','e','f','a','u','l','t','_','M','o','n','i','t','o','r',0,0};
-static const WCHAR driver_date_fmtW[] = {'%','u','-','%','u','-','%','u',0}; -static const WCHAR edidW[] = {'E','D','I','D',0}; -static const WCHAR bad_edidW[] = {'B','A','D','_','E','D','I','D',0};
static struct x11drv_display_device_handler host_handler; struct x11drv_display_device_handler desktop_handler; @@ -406,484 +342,65 @@ void X11DRV_DisplayDevices_Update(BOOL send_display_change) } }
-/* Set device interface link state to enabled. The link state should be set via
- IoSetDeviceInterfaceState(). However, IoSetDeviceInterfaceState() requires a PnP driver, which
- currently doesn't exist for display devices. */
-static BOOL link_device(const WCHAR *instance, const GUID *guid) -{
- static const WCHAR device_instanceW[] = {'D','e','v','i','c','e','I','n','s','t','a','n','c','e',0};
- static const WCHAR hash_controlW[] = {'#','\','C','o','n','t','r','o','l',0};
- static const WCHAR linkedW[] = {'L','i','n','k','e','d',0};
- static const DWORD enabled = 1;
- WCHAR device_key_name[MAX_PATH], device_instance[MAX_PATH];
- HKEY iface_key, device_key, control_key;
- DWORD length, index = 0;
- BOOL ret = FALSE;
- LSTATUS lr;
- iface_key = SetupDiOpenClassRegKeyExW(guid, KEY_ALL_ACCESS, DIOCR_INTERFACE, NULL, NULL);
- while (1)
- {
length = ARRAY_SIZE(device_key_name);
lr = RegEnumKeyExW(iface_key, index++, device_key_name, &length, NULL, NULL, NULL, NULL);
if (lr)
break;
lr = RegOpenKeyExW(iface_key, device_key_name, 0, KEY_ALL_ACCESS, &device_key);
if (lr)
continue;
length = sizeof(device_instance);
lr = RegQueryValueExW(device_key, device_instanceW, NULL, NULL, (BYTE *)device_instance, &length);
if (lr || lstrcmpiW(device_instance, instance))
{
RegCloseKey(device_key);
continue;
}
lr = RegCreateKeyExW(device_key, hash_controlW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &control_key, NULL);
RegCloseKey(device_key);
if (lr)
break;
lr = RegSetValueExW(control_key, linkedW, 0, REG_DWORD, (const BYTE *)&enabled, sizeof(enabled));
if (!lr)
ret = TRUE;
RegCloseKey(control_key);
break;
- }
- RegCloseKey(iface_key);
- return ret;
-}
-/* Initialize a GPU instance.
- Return its GUID string in guid_string, driver value in driver parameter and LUID in gpu_luid */
-static BOOL X11DRV_InitGpu(HDEVINFO devinfo, const struct gdi_gpu *gpu, INT gpu_index, WCHAR *guid_string,
WCHAR *driver, LUID *gpu_luid)
-{
- static const WCHAR adapter_stringW[] = {'H','a','r','d','w','a','r','e','I','n','f','o','r','m','a','t','i','o','n','.','A','d','a','p','t','e','r','S','t','r','i','n','g',0};
- static const WCHAR bios_stringW[] = {'H','a','r','d','w','a','r','e','I','n','f','o','r','m','a','t','i','o','n','.','B','i','o','s','S','t','r','i','n','g',0};
- static const WCHAR chip_typeW[] = {'H','a','r','d','w','a','r','e','I','n','f','o','r','m','a','t','i','o','n','.','C','h','i','p','T','y','p','e',0};
- static const WCHAR dac_typeW[] = {'H','a','r','d','w','a','r','e','I','n','f','o','r','m','a','t','i','o','n','.','D','a','c','T','y','p','e',0};
- static const WCHAR ramdacW[] = {'I','n','t','e','r','g','r','a','t','e','d',' ','R','A','M','D','A','C',0};
- static const BOOL present = TRUE;
- SP_DEVINFO_DATA device_data = {sizeof(device_data)};
- WCHAR instanceW[MAX_PATH];
- DEVPROPTYPE property_type;
- SYSTEMTIME systemtime;
- WCHAR bufferW[1024];
- FILETIME filetime;
- HKEY hkey = NULL;
- GUID guid;
- LUID luid;
- INT written;
- DWORD size;
- BOOL ret = FALSE;
- TRACE("GPU id:0x%s name:%s.\n", wine_dbgstr_longlong(gpu->id), wine_dbgstr_w(gpu->name));
- sprintfW(instanceW, gpu_instance_fmtW, gpu->vendor_id, gpu->device_id, gpu->subsys_id, gpu->revision_id, gpu_index);
- if (!SetupDiOpenDeviceInfoW(devinfo, instanceW, NULL, 0, &device_data))
- {
SetupDiCreateDeviceInfoW(devinfo, instanceW, &GUID_DEVCLASS_DISPLAY, gpu->name, NULL, 0, &device_data);
if (!SetupDiRegisterDeviceInfo(devinfo, &device_data, 0, NULL, NULL, NULL))
goto done;
- }
- /* Register GUID_DEVINTERFACE_DISPLAY_ADAPTER */
- if (!SetupDiCreateDeviceInterfaceW(devinfo, &device_data, &GUID_DEVINTERFACE_DISPLAY_ADAPTER, NULL, 0, NULL))
goto done;
- if (!link_device(instanceW, &GUID_DEVINTERFACE_DISPLAY_ADAPTER))
goto done;
- /* Register GUID_DISPLAY_DEVICE_ARRIVAL */
- if (!SetupDiCreateDeviceInterfaceW(devinfo, &device_data, &GUID_DISPLAY_DEVICE_ARRIVAL, NULL, 0, NULL))
goto done;
- if (!link_device(instanceW, &GUID_DISPLAY_DEVICE_ARRIVAL))
goto done;
- /* Write HardwareID registry property, REG_MULTI_SZ */
- written = sprintfW(bufferW, gpu_hardware_id_fmtW, gpu->vendor_id, gpu->device_id);
- bufferW[written + 1] = 0;
- if (!SetupDiSetDeviceRegistryPropertyW(devinfo, &device_data, SPDRP_HARDWAREID, (const BYTE *)bufferW,
(written + 2) * sizeof(WCHAR)))
goto done;
- /* Write DEVPKEY_Device_IsPresent property */
- if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &DEVPKEY_Device_IsPresent, DEVPROP_TYPE_BOOLEAN,
(const BYTE *)&present, sizeof(present), 0))
goto done;
- /* Write DEVPROPKEY_GPU_LUID property */
- if (!SetupDiGetDevicePropertyW(devinfo, &device_data, &DEVPROPKEY_GPU_LUID, &property_type,
(BYTE *)&luid, sizeof(luid), NULL, 0))
- {
if (!AllocateLocallyUniqueId(&luid))
goto done;
if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &DEVPROPKEY_GPU_LUID,
DEVPROP_TYPE_UINT64, (const BYTE *)&luid, sizeof(luid), 0))
goto done;
- }
- *gpu_luid = luid;
- TRACE("LUID:%08x:%08x.\n", luid.HighPart, luid.LowPart);
- /* Write WINE_DEVPROPKEY_GPU_VULKAN_UUID property */
- if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_GPU_VULKAN_UUID,
DEVPROP_TYPE_GUID, (const BYTE *)&gpu->vulkan_uuid,
sizeof(gpu->vulkan_uuid), 0))
goto done;
- TRACE("Vulkan UUID:%s.\n", wine_dbgstr_guid(&gpu->vulkan_uuid));
- /* Open driver key.
* This is where HKLM\System\CurrentControlSet\Control\Video\{GPU GUID}\{Adapter Index} links to */
- hkey = SetupDiCreateDevRegKeyW(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL);
- size = (strlenW(gpu->name) + 1) * sizeof(WCHAR);
- /* Write DriverDesc value */
- if (RegSetValueExW(hkey, driver_descW, 0, REG_SZ, (const BYTE *)gpu->name, size))
goto done;
- /* Write DriverDateData value, using current time as driver date, needed by Evoland */
- GetSystemTimeAsFileTime(&filetime);
- if (RegSetValueExW(hkey, driver_date_dataW, 0, REG_BINARY, (BYTE *)&filetime, sizeof(filetime)))
goto done;
- GetSystemTime(&systemtime);
- sprintfW(bufferW, driver_date_fmtW, systemtime.wMonth, systemtime.wDay, systemtime.wYear);
- if (RegSetValueExW(hkey, driver_dateW, 0, REG_SZ, (BYTE *)bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR)))
goto done;
- /* The following hardware information value type may be REG_BINARY or REG_SZ */
- if (RegSetValueExW(hkey, adapter_stringW, 0, REG_BINARY, (const BYTE *)gpu->name, size))
goto done;
- if (RegSetValueExW(hkey, bios_stringW, 0, REG_BINARY, (const BYTE *)gpu->name, size))
goto done;
- if (RegSetValueExW(hkey, chip_typeW, 0, REG_BINARY, (const BYTE *)gpu->name, size))
goto done;
- if (RegSetValueExW(hkey, dac_typeW, 0, REG_BINARY, (const BYTE *)ramdacW, sizeof(ramdacW)))
goto done;
- RegCloseKey(hkey);
- hkey = NULL;
- /* Retrieve driver value for adapters */
- if (!SetupDiGetDeviceRegistryPropertyW(devinfo, &device_data, SPDRP_DRIVER, NULL, (BYTE *)bufferW, sizeof(bufferW),
NULL))
goto done;
- lstrcpyW(driver, nt_classW);
- lstrcatW(driver, bufferW);
- /* Write GUID in VideoID in .../instance/Device Parameters, reuse the GUID if it's existent */
- hkey = SetupDiCreateDevRegKeyW(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, NULL, NULL);
- size = sizeof(bufferW);
- if (RegQueryValueExW(hkey, video_idW, 0, NULL, (BYTE *)bufferW, &size))
- {
UuidCreate(&guid);
sprintfW(bufferW, guid_fmtW, guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2],
guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
if (RegSetValueExW(hkey, video_idW, 0, REG_SZ, (const BYTE *)bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR)))
goto done;
- }
- lstrcpyW(guid_string, bufferW);
- ret = TRUE;
-done:
- RegCloseKey(hkey);
- if (!ret)
ERR("Failed to initialize GPU\n");
- return ret;
-}
-static BOOL X11DRV_InitAdapter(HKEY video_hkey, INT video_index, INT gpu_index, INT adapter_index, INT monitor_count,
const struct gdi_gpu *gpu, const WCHAR *guid_string,
const WCHAR *gpu_driver, const struct gdi_adapter *adapter)
-{
- WCHAR adapter_keyW[MAX_PATH];
- WCHAR key_nameW[MAX_PATH];
- WCHAR bufferW[1024];
- HKEY hkey = NULL;
- BOOL ret = FALSE;
- LSTATUS ls;
- INT i;
- sprintfW(key_nameW, device_video_fmtW, video_index);
- lstrcpyW(bufferW, machine_prefixW);
- sprintfW(adapter_keyW, adapter_key_fmtW, guid_string, adapter_index);
- lstrcatW(bufferW, adapter_keyW);
- /* Write value of \Device\Video? (adapter key) in HKLM\HARDWARE\DEVICEMAP\VIDEO\ */
- if (RegSetValueExW(video_hkey, key_nameW, 0, REG_SZ, (const BYTE *)bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR)))
goto done;
- /* Create HKLM\System\CurrentControlSet\Control\Video{GPU GUID}{Adapter Index} link to GPU driver */
- ls = RegCreateKeyExW(HKEY_LOCAL_MACHINE, adapter_keyW, 0, NULL, REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK,
KEY_ALL_ACCESS, NULL, &hkey, NULL);
- if (ls == ERROR_ALREADY_EXISTS)
RegCreateKeyExW(HKEY_LOCAL_MACHINE, adapter_keyW, 0, NULL, REG_OPTION_VOLATILE | REG_OPTION_OPEN_LINK,
KEY_ALL_ACCESS, NULL, &hkey, NULL);
- if (RegSetValueExW(hkey, symbolic_link_valueW, 0, REG_LINK, (const BYTE *)gpu_driver,
strlenW(gpu_driver) * sizeof(WCHAR)))
goto done;
- RegCloseKey(hkey);
- hkey = NULL;
- /* FIXME:
* Following information is Wine specific, it doesn't really exist on Windows. It is used so that we can
* implement EnumDisplayDevices etc by querying registry only. This information is most likely reported by the
* device driver on Windows */
- RegCreateKeyExW(HKEY_CURRENT_CONFIG, adapter_keyW, 0, NULL, REG_OPTION_VOLATILE, KEY_WRITE, NULL, &hkey, NULL);
- /* Write GPU instance path so that we can find the GPU instance via adapters quickly. Another way is trying to match
* them via the GUID in Device Parameters/VideoID, but it would require enumerating all GPU instances */
- sprintfW(bufferW, gpu_instance_fmtW, gpu->vendor_id, gpu->device_id, gpu->subsys_id, gpu->revision_id, gpu_index);
- if (RegSetValueExW(hkey, gpu_idW, 0, REG_SZ, (const BYTE *)bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR)))
goto done;
- /* Write all monitor instances paths under this adapter */
- for (i = 0; i < monitor_count; i++)
- {
sprintfW(key_nameW, monitor_id_fmtW, i);
sprintfW(bufferW, monitor_instance_fmtW, video_index, i);
if (RegSetValueExW(hkey, key_nameW, 0, REG_SZ, (const BYTE *)bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR)))
goto done;
- }
+static BOOL force_display_devices_refresh;
- /* Write StateFlags */
- if (RegSetValueExW(hkey, state_flagsW, 0, REG_DWORD, (const BYTE *)&adapter->state_flags,
sizeof(adapter->state_flags)))
goto done;
- ret = TRUE;
-done:
- RegCloseKey(hkey);
- if (!ret)
ERR("Failed to initialize adapter\n");
- return ret;
-}
-static BOOL X11DRV_InitMonitor(HDEVINFO devinfo, const struct gdi_monitor *monitor, int monitor_index,
int video_index, const LUID *gpu_luid, UINT output_id)
+void CDECL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manager,
BOOL force, void *param )
{
- SP_DEVINFO_DATA device_data = {sizeof(SP_DEVINFO_DATA)};
- WCHAR bufferW[MAX_PATH];
- DWORD length;
- HKEY hkey;
- BOOL ret = FALSE;
- /* Create GUID_DEVCLASS_MONITOR instance */
- sprintfW(bufferW, monitor_instance_fmtW, video_index, monitor_index);
- SetupDiCreateDeviceInfoW(devinfo, bufferW, &GUID_DEVCLASS_MONITOR, monitor->name, NULL, 0, &device_data);
- if (!SetupDiRegisterDeviceInfo(devinfo, &device_data, 0, NULL, NULL, NULL))
goto done;
- /* Register GUID_DEVINTERFACE_MONITOR */
- if (!SetupDiCreateDeviceInterfaceW(devinfo, &device_data, &GUID_DEVINTERFACE_MONITOR, NULL, 0, NULL))
goto done;
- if (!link_device(bufferW, &GUID_DEVINTERFACE_MONITOR))
goto done;
- /* Write HardwareID registry property */
- if (!SetupDiSetDeviceRegistryPropertyW(devinfo, &device_data, SPDRP_HARDWAREID,
(const BYTE *)monitor_hardware_idW, sizeof(monitor_hardware_idW)))
goto done;
- /* Write DEVPROPKEY_MONITOR_GPU_LUID */
- if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &DEVPROPKEY_MONITOR_GPU_LUID,
DEVPROP_TYPE_INT64, (const BYTE *)gpu_luid, sizeof(*gpu_luid), 0))
goto done;
- /* Write DEVPROPKEY_MONITOR_OUTPUT_ID */
- if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &DEVPROPKEY_MONITOR_OUTPUT_ID,
DEVPROP_TYPE_UINT32, (const BYTE *)&output_id, sizeof(output_id), 0))
goto done;
- hkey = SetupDiCreateDevRegKeyW(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, NULL, NULL);
- if (monitor->edid)
RegSetValueExW(hkey, edidW, 0, REG_BINARY, monitor->edid, monitor->edid_len);
- else
RegSetValueExW(hkey, bad_edidW, 0, REG_BINARY, NULL, 0);
- RegCloseKey(hkey);
- /* Create driver key */
- hkey = SetupDiCreateDevRegKeyW(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL);
- RegCloseKey(hkey);
- /* FIXME:
* Following properties are Wine specific, see comments in X11DRV_InitAdapter for details */
- /* StateFlags */
- if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_STATEFLAGS, DEVPROP_TYPE_UINT32,
(const BYTE *)&monitor->state_flags, sizeof(monitor->state_flags), 0))
goto done;
- /* RcMonitor */
- if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCMONITOR, DEVPROP_TYPE_BINARY,
(const BYTE *)&monitor->rc_monitor, sizeof(monitor->rc_monitor), 0))
goto done;
- /* RcWork */
- if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCWORK, DEVPROP_TYPE_BINARY,
(const BYTE *)&monitor->rc_work, sizeof(monitor->rc_work), 0))
goto done;
- /* Adapter name */
- length = sprintfW(bufferW, adapter_name_fmtW, video_index + 1);
- if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, DEVPROP_TYPE_STRING,
(const BYTE *)bufferW, (length + 1) * sizeof(WCHAR), 0))
goto done;
- ret = TRUE;
-done:
- if (!ret)
ERR("Failed to initialize monitor\n");
- return ret;
-}
-static void prepare_devices(HKEY video_hkey) -{
- static const BOOL not_present = FALSE;
- SP_DEVINFO_DATA device_data = {sizeof(device_data)};
- HDEVINFO devinfo;
- DWORD i = 0;
- /* Remove all monitors */
- devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_MONITOR, displayW, NULL, 0);
- while (SetupDiEnumDeviceInfo(devinfo, i++, &device_data))
- {
if (!SetupDiRemoveDevice(devinfo, &device_data))
ERR("Failed to remove monitor\n");
- }
- SetupDiDestroyDeviceInfoList(devinfo);
- /* Clean up old adapter keys for reinitialization */
- RegDeleteTreeW(video_hkey, NULL);
- /* FIXME:
* Currently SetupDiGetClassDevsW with DIGCF_PRESENT is unsupported, So we need to clean up not present devices in
* case application uses SetupDiGetClassDevsW to enumerate devices. Wrong devices could exist in registry as a result
* of prefix copying or having devices unplugged. But then we couldn't simply delete GPUs because we need to retain
* the same GUID for the same GPU. */
- i = 0;
- devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_DISPLAY, pciW, NULL, 0);
- while (SetupDiEnumDeviceInfo(devinfo, i++, &device_data))
- {
if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &DEVPKEY_Device_IsPresent, DEVPROP_TYPE_BOOLEAN,
(const BYTE *)¬_present, sizeof(not_present), 0))
ERR("Failed to set GPU present property\n");
- }
- SetupDiDestroyDeviceInfoList(devinfo);
-}
-static void cleanup_devices(void) -{
- SP_DEVINFO_DATA device_data = {sizeof(device_data)};
- HDEVINFO devinfo;
- DWORD type;
- DWORD i = 0;
- BOOL present;
- devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_DISPLAY, pciW, NULL, 0);
- while (SetupDiEnumDeviceInfo(devinfo, i++, &device_data))
- {
present = FALSE;
SetupDiGetDevicePropertyW(devinfo, &device_data, &DEVPKEY_Device_IsPresent, &type, (BYTE *)&present,
sizeof(present), NULL, 0);
if (!present && !SetupDiRemoveDevice(devinfo, &device_data))
ERR("Failed to remove GPU\n");
- }
- SetupDiDestroyDeviceInfoList(devinfo);
-}
-void X11DRV_DisplayDevices_Init(BOOL force) -{
- HANDLE mutex;
- struct x11drv_display_device_handler *handler = is_virtual_desktop() ? &desktop_handler : &host_handler;
- struct gdi_gpu *gpus = NULL;
- struct gdi_adapter *adapters = NULL;
- struct gdi_monitor *monitors = NULL;
- struct x11drv_display_device_handler *handler;
- struct gdi_adapter *adapters;
- struct gdi_monitor *monitors;
- struct gdi_gpu *gpus; INT gpu_count, adapter_count, monitor_count; INT gpu, adapter, monitor;
HDEVINFO gpu_devinfo = NULL, monitor_devinfo = NULL;
HKEY video_hkey = NULL;
INT video_index = 0;
DWORD disposition = 0;
WCHAR guidW[40];
WCHAR driverW[1024];
LUID gpu_luid;
UINT output_id = 0;
mutex = get_display_device_init_mutex();
if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, video_keyW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &video_hkey,
&disposition))
{
ERR("Failed to create video device key\n");
goto done;
}
/* Avoid unnecessary reinit */
if (!force && disposition != REG_CREATED_NEW_KEY)
goto done;
if (!force && !force_display_devices_refresh) return;
force_display_devices_refresh = FALSE;
handler = is_virtual_desktop() ? &desktop_handler : &host_handler;
TRACE("via %s\n", wine_dbgstr_a(handler->name));
- prepare_devices(video_hkey);
- gpu_devinfo = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_DISPLAY, NULL);
- monitor_devinfo = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_MONITOR, NULL);
- /* Initialize GPUs */ if (!handler->get_gpus(&gpus, &gpu_count))
goto done;
return;
TRACE("GPU count: %d\n", gpu_count);
for (gpu = 0; gpu < gpu_count; gpu++) {
if (!X11DRV_InitGpu(gpu_devinfo, &gpus[gpu], gpu, guidW, driverW, &gpu_luid))
goto done;
device_manager->add_gpu( &gpus[gpu], param ); /* Initialize adapters */
if (!handler->get_adapters(gpus[gpu].id, &adapters, &adapter_count))
goto done;
if (!handler->get_adapters(gpus[gpu].id, &adapters, &adapter_count)) break; TRACE("GPU: %#lx %s, adapter count: %d\n", gpus[gpu].id, wine_dbgstr_w(gpus[gpu].name), adapter_count); for (adapter = 0; adapter < adapter_count; adapter++) {
if (!handler->get_monitors(adapters[adapter].id, &monitors, &monitor_count))
goto done;
TRACE("adapter: %#lx, monitor count: %d\n", adapters[adapter].id, monitor_count);
device_manager->add_adapter( &adapters[adapter], param );
if (!X11DRV_InitAdapter(video_hkey, video_index, gpu, adapter, monitor_count,
&gpus[gpu], guidW, driverW, &adapters[adapter]))
goto done;
if (!handler->get_monitors(adapters[adapter].id, &monitors, &monitor_count)) break;
TRACE("adapter: %#lx, monitor count: %d\n", adapters[adapter].id, monitor_count); /* Initialize monitors */ for (monitor = 0; monitor < monitor_count; monitor++) { TRACE("monitor: %#x %s\n", monitor, wine_dbgstr_w(monitors[monitor].name));
if (!X11DRV_InitMonitor(monitor_devinfo, &monitors[monitor], monitor, video_index, &gpu_luid, output_id++))
goto done;
device_manager->add_monitor( &monitors[monitor], param ); } handler->free_monitors(monitors, monitor_count);
monitors = NULL;
video_index++; } handler->free_adapters(adapters);
adapters = NULL;
}
-done:
- cleanup_devices();
- SetupDiDestroyDeviceInfoList(monitor_devinfo);
- SetupDiDestroyDeviceInfoList(gpu_devinfo);
- RegCloseKey(video_hkey);
- release_display_device_init_mutex(mutex);
- if (gpus)
handler->free_gpus(gpus);
- if (adapters)
handler->free_adapters(adapters);
- if (monitors)
handler->free_monitors(monitors, monitor_count);
- handler->free_gpus(gpus);
+}
+void X11DRV_DisplayDevices_Init(BOOL force) +{
- UINT32 num_path, num_mode;
- if (force) force_display_devices_refresh = TRUE;
- /* trigger refresh in win32u */
- NtUserGetDisplayConfigBufferSizes( QDC_ONLY_ACTIVE_PATHS, &num_path, &num_mode );
} diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 854221bf948..0b4bede19e9 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -401,6 +401,7 @@ static const struct user_driver_funcs x11drv_funcs = .pClipCursor = X11DRV_ClipCursor, .pChangeDisplaySettingsEx = X11DRV_ChangeDisplaySettingsEx, .pEnumDisplaySettingsEx = X11DRV_EnumDisplaySettingsEx,
- .pUpdateDisplayDevices = X11DRV_UpdateDisplayDevices, .pCreateDesktopWindow = X11DRV_CreateDesktopWindow, .pCreateWindow = X11DRV_CreateWindow, .pDestroyWindow = X11DRV_DestroyWindow,
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 169334fd917..ae03f955e0d 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -209,6 +209,8 @@ extern LONG CDECL X11DRV_ChangeDisplaySettingsEx( LPCWSTR devname, LPDEVMODEW de HWND hwnd, DWORD flags, LPVOID lpvoid ) DECLSPEC_HIDDEN; extern BOOL CDECL X11DRV_EnumDisplaySettingsEx( LPCWSTR name, DWORD n, LPDEVMODEW devmode, DWORD flags ) DECLSPEC_HIDDEN; +extern void CDECL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manager,
BOOL force, void *param ) DECLSPEC_HIDDEN;
extern BOOL CDECL X11DRV_CreateDesktopWindow( HWND hwnd ) DECLSPEC_HIDDEN; extern BOOL CDECL X11DRV_CreateWindow( HWND hwnd ) DECLSPEC_HIDDEN; extern void CDECL X11DRV_DestroyWindow( HWND hwnd ) DECLSPEC_HIDDEN; diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 4a8605fc668..c29d081a0a5 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -631,8 +631,8 @@ static BOOL process_attach(void) X11DRV_InitKeyboard( gdi_display ); if (use_xim) use_xim = X11DRV_InitXIM( input_style );
- X11DRV_DisplayDevices_Init(FALSE); init_user_driver();
- X11DRV_DisplayDevices_Init(FALSE); return TRUE;
}
On 11/26/21 8:12 AM, Zhiyi Zhang wrote:
Hi Jacek,
There are many X11DRV_EnumDisplaySettingsEx() failures after this patch when running user32/tests/monitor.c tests that doesn't appear before. Also the monitor resolution doesn't get restored after finishing the tests.
... 0080:err:x11settings:X11DRV_EnumDisplaySettingsEx Failed to get L"\\.\DISPLAY1" registry display settings. 0080:err:x11settings:X11DRV_EnumDisplaySettingsEx Failed to get L"\\.\DISPLAY2" registry display settings. 0080:err:x11settings:X11DRV_EnumDisplaySettingsEx Failed to get L"\\.\DISPLAY1" registry display settings. 0080:err:x11settings:X11DRV_EnumDisplaySettingsEx Failed to get L"\\.\DISPLAY2" registry display settings. 0020:monitor: 942 tests executed (31 marked as todo, 0 failures), 1 skipped.
It seems to be caused by the old prepare_devices() not deleting Wine-specific adapter keys and driver settings code depends on it. I will send an updated series doing. Ultimately, we will want this to be more reliable (right now if adapter numbering changes, we may not do the right thing). Moving registry handling part of ChangeDisplaySettingsEx and EnumDisplaySettingsEx from drivers to win32u could help with that.
Thanks,
Jacek