[PATCH v2 9/9] winex11: Use UpdateDisplayDevices driver entry point for registering devices.

Zhiyi Zhang zzhang at codeweavers.com
Fri Nov 26 01:12:25 CST 2021


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 at 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 *)&not_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;
>  }
>  
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20211126/2c6422fc/attachment.htm>


More information about the wine-devel mailing list