[PATCH 6/6] winemac.drv: Support multiple adapter display settings in registry.

Zhiyi Zhang zzhang at codeweavers.com
Wed Jun 3 09:30:45 CDT 2020


Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/winemac.drv/display.c | 91 +++++++++++++++++++++++++-------------
 1 file changed, 60 insertions(+), 31 deletions(-)

diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c
index 461662b33b9..896948b2fea 100644
--- a/dlls/winemac.drv/display.c
+++ b/dlls/winemac.drv/display.c
@@ -151,44 +151,64 @@ static void release_display_device_init_mutex(HANDLE mutex)
     CloseHandle(mutex);
 }
 
-static BOOL get_display_device_reg_key(char *key, unsigned len)
+static BOOL get_display_device_reg_key(const WCHAR *device_name, WCHAR *key, unsigned len)
 {
-    static const char display_device_guid_prop[] = "__wine_display_device_guid";
-    static const char video_path[] = "System\\CurrentControlSet\\Control\\Video\\{";
-    static const char display0[] = "}\\0000";
-    ATOM guid_atom;
+    static const WCHAR display[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y'};
+    static const WCHAR video_value_fmt[] = {'\\','D','e','v','i','c','e','\\',
+                                            'V','i','d','e','o','%','d',0};
+    static const WCHAR video_key[] = {'H','A','R','D','W','A','R','E','\\',
+                                      'D','E','V','I','C','E','M','A','P','\\',
+                                      'V','I','D','E','O','\\',0};
+    WCHAR value_name[MAX_PATH], buffer[MAX_PATH], *end_ptr;
+    DWORD adapter_index, size;
 
-    assert(len >= sizeof(video_path) + sizeof(display0) + 40);
-
-    guid_atom = HandleToULong(GetPropA(GetDesktopWindow(), display_device_guid_prop));
-    if (!guid_atom) return FALSE;
-
-    memcpy(key, video_path, sizeof(video_path));
-
-    if (!GlobalGetAtomNameA(guid_atom, key + strlen(key), 40))
+    /* Device name has to be \\.\DISPLAY%d */
+    if (strncmpiW(device_name, display, ARRAY_SIZE(display)))
         return FALSE;
 
-    strcat(key, display0);
+    /* Parse \\.\DISPLAY* */
+    adapter_index = strtolW(device_name + ARRAY_SIZE(display), &end_ptr, 10) - 1;
+    if (*end_ptr)
+        return FALSE;
 
-    TRACE("display device key %s\n", wine_dbgstr_a(key));
+    /* Open \Device\Video* in HKLM\HARDWARE\DEVICEMAP\VIDEO\ */
+    sprintfW(value_name, video_value_fmt, adapter_index);
+    size = sizeof(buffer);
+    if (RegGetValueW(HKEY_LOCAL_MACHINE, video_key, value_name, RRF_RT_REG_SZ, NULL, buffer, &size))
+        return FALSE;
+
+    if (len < lstrlenW(buffer + 18) + 1)
+        return FALSE;
+
+    /* Skip \Registry\Machine\ prefix */
+    lstrcpyW(key, buffer + 18);
+    TRACE("display device %s registry settings key %s.\n", wine_dbgstr_w(device_name), wine_dbgstr_w(key));
     return TRUE;
 }
 
 
-static BOOL read_registry_settings(DEVMODEW *dm)
+static BOOL read_registry_settings(const WCHAR *device_name, DEVMODEW *dm)
 {
-    char wine_mac_reg_key[128];
+    WCHAR wine_mac_reg_key[MAX_PATH];
+    HANDLE mutex;
     HKEY hkey;
     DWORD type, size;
     BOOL ret = TRUE;
 
     dm->dmFields = 0;
 
-    if (!get_display_device_reg_key(wine_mac_reg_key, sizeof(wine_mac_reg_key)))
+    mutex = get_display_device_init_mutex();
+    if (!get_display_device_reg_key(device_name, wine_mac_reg_key, ARRAY_SIZE(wine_mac_reg_key)))
+    {
+        release_display_device_init_mutex(mutex);
         return FALSE;
+    }
 
-    if (RegOpenKeyExA(HKEY_CURRENT_CONFIG, wine_mac_reg_key, 0, KEY_READ, &hkey))
+    if (RegOpenKeyExW(HKEY_CURRENT_CONFIG, wine_mac_reg_key, 0, KEY_READ, &hkey))
+    {
+        release_display_device_init_mutex(mutex);
         return FALSE;
+    }
 
 #define query_value(name, data) \
     size = sizeof(DWORD); \
@@ -216,22 +236,31 @@ static BOOL read_registry_settings(DEVMODEW *dm)
 #undef query_value
 
     RegCloseKey(hkey);
+    release_display_device_init_mutex(mutex);
     return ret;
 }
 
 
-static BOOL write_registry_settings(const DEVMODEW *dm)
+static BOOL write_registry_settings(const WCHAR *device_name, const DEVMODEW *dm)
 {
-    char wine_mac_reg_key[128];
+    WCHAR wine_mac_reg_key[MAX_PATH];
+    HANDLE mutex;
     HKEY hkey;
     BOOL ret = TRUE;
 
-    if (!get_display_device_reg_key(wine_mac_reg_key, sizeof(wine_mac_reg_key)))
+    mutex = get_display_device_init_mutex();
+    if (!get_display_device_reg_key(device_name, wine_mac_reg_key, ARRAY_SIZE(wine_mac_reg_key)))
+    {
+        release_display_device_init_mutex(mutex);
         return FALSE;
+    }
 
-    if (RegCreateKeyExA(HKEY_CURRENT_CONFIG, wine_mac_reg_key, 0, NULL,
+    if (RegCreateKeyExW(HKEY_CURRENT_CONFIG, wine_mac_reg_key, 0, NULL,
                         REG_OPTION_VOLATILE, KEY_WRITE, NULL, &hkey, NULL))
+    {
+        release_display_device_init_mutex(mutex);
         return FALSE;
+    }
 
 #define set_value(name, data) \
     if (RegSetValueExA(hkey, name, 0, REG_DWORD, (const BYTE*)(data), sizeof(DWORD))) \
@@ -250,6 +279,7 @@ static BOOL write_registry_settings(const DEVMODEW *dm)
 #undef set_value
 
     RegCloseKey(hkey);
+    release_display_device_init_mutex(mutex);
     return ret;
 }
 
@@ -833,12 +863,6 @@ LONG CDECL macdrv_ChangeDisplaySettingsEx(LPCWSTR devname, LPDEVMODEW devmode,
         devmode = &default_mode;
     }
 
-    if (lstrcmpiW(primary_adapter, devname))
-    {
-        FIXME("Changing non-primary adapter settings is currently unsupported.\n");
-        return DISP_CHANGE_SUCCESSFUL;
-    }
-
     if (is_detached_mode(devmode))
     {
         FIXME("Detaching adapters is currently unsupported.\n");
@@ -956,13 +980,18 @@ better:
         /* we have a valid mode */
         TRACE("Requested display settings match mode %ld\n", best);
 
-        if ((flags & CDS_UPDATEREGISTRY) && !write_registry_settings(devmode))
+        if ((flags & CDS_UPDATEREGISTRY) && !write_registry_settings(devname, devmode))
         {
             WARN("Failed to update registry\n");
             ret = DISP_CHANGE_NOTUPDATED;
         }
         else if (flags & (CDS_TEST | CDS_NORESET))
             ret = DISP_CHANGE_SUCCESSFUL;
+        else if (lstrcmpiW(primary_adapter, devname))
+        {
+            FIXME("Changing non-primary adapter settings is currently unsupported.\n");
+            ret = DISP_CHANGE_SUCCESSFUL;
+        }
         else if (macdrv_set_display_mode(&displays[0], best_display_mode))
         {
             int mode_bpp = display_mode_bits_per_pixel(best_display_mode);
@@ -1032,7 +1061,7 @@ BOOL CDECL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode,
     if (mode == ENUM_REGISTRY_SETTINGS)
     {
         TRACE("mode %d (registry) -- getting default mode\n", mode);
-        return read_registry_settings(devmode);
+        return read_registry_settings(devname, devmode);
     }
 
     if (macdrv_get_displays(&displays, &num_displays))
-- 
2.25.1



More information about the wine-devel mailing list