[PATCH v3 5/6] winex11.drv: Initialize monitor registry data.

Zhiyi Zhang zzhang at codeweavers.com
Tue May 14 04:48:53 CDT 2019


Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/winex11.drv/display.c | 120 +++++++++++++++++++++++++++++++++++--
 1 file changed, 115 insertions(+), 5 deletions(-)

diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index 56ab29a140..f9708bfac6 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -39,11 +39,19 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
 
+/* Wine specific monitor properties */
+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_descW[] = {'D','r','i','v','e','r','D','e','s','c',0};
 static const WCHAR graphics_driverW[] = {'G','r','a','p','h','i','c','s','D','r','i','v','e','r',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 mointor_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','-',
@@ -90,6 +98,13 @@ static const WCHAR device_video_fmtW[] = {
 static const WCHAR machine_prefixW[] = {
     '\\','R','e','g','i','s','t','r','y','\\',
     'M','a','c','h','i','n','e','\\',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 struct x11drv_display_device_handler handler;
 
@@ -185,7 +200,7 @@ fail:
     return ret;
 }
 
-static BOOL X11DRV_InitAdapter(HKEY video_hkey, INT video_index, INT gpu_index, INT adapter_index,
+static BOOL X11DRV_InitAdapter(HKEY video_hkey, INT video_index, INT gpu_index, INT adapter_index, INT monitor_count,
                                const struct x11drv_gpu *gpu, const WCHAR *guid_string,
                                const WCHAR *gpu_driver, const struct x11drv_adapter *adapter)
 {
@@ -195,6 +210,7 @@ static BOOL X11DRV_InitAdapter(HKEY video_hkey, INT video_index, INT gpu_index,
     HKEY hkey = NULL;
     BOOL ret = FALSE;
     LSTATUS ls;
+    INT i;
 
     sprintfW(key_nameW, device_video_fmtW, video_index);
     strcpyW(bufferW, machine_prefixW);
@@ -229,6 +245,15 @@ static BOOL X11DRV_InitAdapter(HKEY video_hkey, INT video_index, INT gpu_index,
     if (RegSetValueExW(hkey, gpu_idW, 0, REG_SZ, (const BYTE *)bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR)))
         goto fail;
 
+    /* Write all monitor instances paths under this adapter */
+    for (i = 0; i < monitor_count; i++)
+    {
+        sprintfW(key_nameW, mointor_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 fail;
+    }
+
     /* Write StateFlags */
     if (RegSetValueExW(hkey, state_flagsW, 0, REG_DWORD, (const BYTE *)&adapter->state_flags,
                        sizeof(adapter->state_flags)))
@@ -242,6 +267,64 @@ fail:
     return ret;
 }
 
+static BOOL X11DRV_InitMonitor(HDEVINFO devinfo, const struct x11drv_monitor *monitor, int monitor_index,
+                               int video_index)
+{
+    WCHAR bufferW[MAX_PATH];
+    SP_DEVINFO_DATA device_data = {sizeof(SP_DEVINFO_DATA)};
+    HKEY hkey = NULL;
+    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 fail;
+
+    /* Write HaredwareID registry property */
+    if (!SetupDiSetDeviceRegistryPropertyW(devinfo, &device_data, SPDRP_HARDWAREID,
+                                           (const BYTE *)monitor_hardware_idW, sizeof(monitor_hardware_idW)))
+        goto fail;
+
+    /* Open driver key */
+    hkey = SetupDiOpenDevRegKey(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_ALL_ACCESS);
+    if (hkey == INVALID_HANDLE_VALUE)
+        hkey = SetupDiCreateDevRegKeyW(devinfo, &device_data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL);
+
+    /* Write DriverDesc value */
+    if (RegSetValueExW(hkey, driver_descW, 0, REG_SZ, (const BYTE *)monitor->name,
+                       (strlenW(monitor->name) + 1) * sizeof(WCHAR)))
+        goto fail;
+
+    /* 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 fail;
+    /* RcMonitor */
+    if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCMONITOR, DEVPROP_TYPE_BINARY,
+                                   (const BYTE *)&monitor->rc_monitor, sizeof(monitor->rc_monitor), 0))
+        goto fail;
+    /* RcWork */
+    if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCWORK, DEVPROP_TYPE_BINARY,
+                                   (const BYTE *)&monitor->rc_work, sizeof(monitor->rc_work), 0))
+        goto fail;
+
+    sprintfW(bufferW, adapter_name_fmtW, video_index + 1);
+    /* Adapter name */
+    if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, DEVPROP_TYPE_STRING,
+                                   (const BYTE *)bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR), 0))
+        goto fail;
+
+    ret = TRUE;
+fail:
+    RegCloseKey(hkey);
+    if (!ret)
+        ERR("Failed to initialize monitor\n");
+    return ret;
+}
+
 static void prepare_devices(void)
 {
     static const BOOL not_present = FALSE;
@@ -249,8 +332,18 @@ static void prepare_devices(void)
     HDEVINFO devinfo;
     DWORD i = 0;
 
+    /* Remove all monitors */
+    devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_MONITOR, NULL, NULL, 0);
+    while (SetupDiEnumDeviceInfo(devinfo, i++, &device_data))
+    {
+        if (!SetupDiRemoveDevice(devinfo, &device_data))
+            ERR("Failed to remove monitor\n");
+    }
+    SetupDiDestroyDeviceInfoList(devinfo);
+
     /* Set all GPUs as not present. We can't simply delete them because we need to keep the GUID consistent with
      * each initialization run. We clean up non present GPUs at the end of initialization */
+    i = 0;
     devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_DISPLAY, NULL, NULL, 0);
     while (SetupDiEnumDeviceInfo(devinfo, i++, &device_data))
     {
@@ -285,9 +378,10 @@ BOOL X11DRV_DisplayDevices_Init(void)
 {
     struct x11drv_gpu *gpus = NULL;
     struct x11drv_adapter *adapters = NULL;
-    INT gpu_count, adapter_count;
-    INT gpu, adapter;
-    HDEVINFO gpu_devinfo = NULL;
+    struct x11drv_monitor *monitors = NULL;
+    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;
@@ -316,6 +410,7 @@ BOOL X11DRV_DisplayDevices_Init(void)
     prepare_devices();
 
     gpu_devinfo = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_DISPLAY, NULL);
+    monitor_devinfo = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_MONITOR, NULL);
 
     /* Initialize GPUs */
     if (!handler.pGetGpus(&gpus, &gpu_count))
@@ -332,10 +427,22 @@ BOOL X11DRV_DisplayDevices_Init(void)
 
         for (adapter = 0; adapter < adapter_count; adapter++)
         {
-            if (!X11DRV_InitAdapter(video_hkey, video_index, gpu, adapter,
+            if (!handler.pGetMonitors(adapters[adapter].id, &monitors, &monitor_count))
+                goto fail;
+
+            if (!X11DRV_InitAdapter(video_hkey, video_index, gpu, adapter, monitor_count,
                                     &gpus[gpu], guidW, driverW, &adapters[adapter]))
                 goto fail;
 
+            /* Initialize monitors */
+            for (monitor = 0; monitor < monitor_count; monitor++)
+            {
+                if (!X11DRV_InitMonitor(monitor_devinfo, &monitors[monitor], monitor, video_index))
+                    goto fail;
+            }
+
+            handler.pFreeMonitors(monitors);
+            monitors = NULL;
             video_index++;
         }
 
@@ -346,12 +453,15 @@ BOOL X11DRV_DisplayDevices_Init(void)
     ret = TRUE;
 fail:
     cleanup_devices();
+    SetupDiDestroyDeviceInfoList(monitor_devinfo);
     SetupDiDestroyDeviceInfoList(gpu_devinfo);
     RegCloseKey(video_hkey);
     if (gpus)
         handler.pFreeGpus(gpus);
     if (adapters)
         handler.pFreeAdapters(adapters);
+    if (monitors)
+        handler.pFreeMonitors(monitors);
     if (!ret)
         ERR("Failed to initialize display devices\n");
     return ret;
-- 
2.20.1





More information about the wine-devel mailing list