[PATCH] winex11.drv: Derive the monitor device name from the EDID where available.

Eduard Permyakov epermyakov at codeweavers.com
Fri Sep 3 09:32:39 CDT 2021


Signed-off-by: Eduard Permyakov <epermyakov at codeweavers.com>
---
 dlls/winex11.drv/xrandr.c | 43 +++++++++++++++++++++++++++++++++++----
 1 file changed, 39 insertions(+), 4 deletions(-)

diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c
index eb2f7021ba6..3ae1e845ed3 100644
--- a/dlls/winex11.drv/xrandr.c
+++ b/dlls/winex11.drv/xrandr.c
@@ -499,6 +499,43 @@ static void get_edid(RROutput output, unsigned char **prop, unsigned long *len)
     }
 }
 
+static BOOL edid_parse_name(const unsigned char *edid, unsigned long edid_len, WCHAR name[14])
+{
+    BOOL found = FALSE;
+    enum { DESC_OFFSET = 0x48, DESC_SIZE = 18, NDESCS = 3, MAXLEN = 13 };
+    static unsigned char disp_product_name_hdr[5] = {0x00, 0x00, 0x00, 0xFC, 0x00};
+    const unsigned char *cursor = edid + DESC_OFFSET;
+    int i, name_idx = 0;
+
+    if (edid_len < 128)
+        return FALSE;
+
+    for (i = 0; i < NDESCS; i++, cursor += DESC_SIZE)
+    {
+        if (memcmp( cursor, disp_product_name_hdr, sizeof(disp_product_name_hdr) ) != 0)
+            continue;
+
+        cursor += sizeof(disp_product_name_hdr);
+        while (*cursor != 0x0A && name_idx < MAXLEN)
+            name[name_idx++] = *cursor++;
+        name[name_idx++] = '\0';
+
+        found = TRUE;
+        break;
+    }
+    return found;
+}
+
+static void monitor_set_name(struct x11drv_monitor *monitor, int index, const WCHAR *default_name)
+{
+    WCHAR name[14];
+    if (monitor->edid && edid_parse_name(monitor->edid, monitor->edid_len, name))
+        lstrcpyW( monitor->name, name );
+    else
+        lstrcpyW( monitor->name, default_name );
+    TRACE("set name of monitor %d: %s\n", index, debugstr_w(monitor->name));
+}
+
 static void set_screen_size( int width, int height )
 {
     int screen = default_visual.screen;
@@ -1067,9 +1104,9 @@ static BOOL xrandr14_get_monitors( ULONG_PTR adapter_id, struct x11drv_monitor *
     /* Inactive but attached monitor, no need to check for mirrored/replica monitors */
     if (!output_info->crtc || !crtc_info->mode)
     {
-        lstrcpyW( monitors[monitor_count].name, generic_nonpnp_monitorW );
         monitors[monitor_count].state_flags = DISPLAY_DEVICE_ATTACHED;
         get_edid( adapter_id, &monitors[monitor_count].edid, &monitors[monitor_count].edid_len );
+        monitor_set_name( monitors + monitor_count, monitor_count, generic_nonpnp_monitorW );
         monitor_count = 1;
     }
     /* Active monitors, need to find other monitors with the same coordinates as mirrored */
@@ -1112,9 +1149,6 @@ static BOOL xrandr14_get_monitors( ULONG_PTR adapter_id, struct x11drv_monitor *
                     enum_crtc_info->width == crtc_info->width &&
                     enum_crtc_info->height == crtc_info->height)
                 {
-                    /* FIXME: Read output EDID property and parse the data to get the correct name */
-                    lstrcpyW( monitors[monitor_count].name, generic_nonpnp_monitorW );
-
                     SetRect( &monitors[monitor_count].rc_monitor, crtc_info->x, crtc_info->y,
                              crtc_info->x + crtc_info->width, crtc_info->y + crtc_info->height );
                     monitors[monitor_count].rc_work = get_work_area( &monitors[monitor_count].rc_monitor );
@@ -1128,6 +1162,7 @@ static BOOL xrandr14_get_monitors( ULONG_PTR adapter_id, struct x11drv_monitor *
 
                     get_edid( screen_resources->outputs[i], &monitors[monitor_count].edid,
                         &monitors[monitor_count].edid_len );
+                    monitor_set_name( monitors + monitor_count, monitor_count, generic_nonpnp_monitorW );
                     monitor_count++;
                 }
 
-- 
2.25.1




More information about the wine-devel mailing list