diff --git a/gdk/gdkmonitor.c b/gdk/gdkmonitor.c index 2d27c29972..37e2c872eb 100644 --- a/gdk/gdkmonitor.c +++ b/gdk/gdkmonitor.c @@ -401,7 +401,12 @@ gdk_monitor_get_connector (GdkMonitor *monitor) * gdk_monitor_get_manufacturer: * @monitor: a #GdkMonitor * - * Gets the name of the monitor's manufacturer, if available. + * Gets the name or PNP ID of the monitor's manufacturer, if available. + * + * Note that this value might also vary depending on actual + * display backend. + * + * PNP ID registry is located at https://uefi.org/pnp_id_list * * Returns: (transfer none) (nullable): the name of the manufacturer, or %NULL */ diff --git a/gdk/x11/gdkscreen-x11.c b/gdk/x11/gdkscreen-x11.c index cda654f04e..ffba0708f7 100644 --- a/gdk/x11/gdkscreen-x11.c +++ b/gdk/x11/gdkscreen-x11.c @@ -354,6 +354,7 @@ init_randr15 (GdkX11Screen *x11_screen, gboolean *changed) GdkRectangle geometry; GdkRectangle newgeo; char *name; + char *manufacturer = NULL; int refresh_rate = 0; gdk_x11_display_error_trap_push (display); @@ -405,6 +406,50 @@ init_randr15 (GdkX11Screen *x11_screen, gboolean *changed) g_ptr_array_add (x11_display->monitors, monitor); } + /* Fetch minimal manufacturer information (PNP ID) from EDID */ + { + #define EDID_LENGTH 128 + Atom actual_type, edid_atom; + char tmp[3]; + int actual_format; + unsigned char *prop; + unsigned long nbytes, bytes_left; + Display *disp = GDK_DISPLAY_XDISPLAY (x11_display); + + edid_atom = XInternAtom (disp, RR_PROPERTY_RANDR_EDID, FALSE); + + XRRGetOutputProperty (disp, output, + edid_atom, + 0, + EDID_LENGTH, + FALSE, + FALSE, + AnyPropertyType, + &actual_type, + &actual_format, + &nbytes, + &bytes_left, + &prop); + + // Check partial EDID header (whole header: 00 ff ff ff ff ff ff 00) + if (nbytes >= EDID_LENGTH && prop[0] == 0x00 && prop[1] == 0xff) + { + /* decode the Vendor ID from three 5 bit words packed into 2 bytes + * /--08--\/--09--\ + * 7654321076543210 + * |\---/\---/\---/ + * R C1 C2 C3 */ + tmp[0] = 'A' + ((prop[8] & 0x7c) / 4) - 1; + tmp[1] = 'A' + ((prop[8] & 0x3) * 8) + ((prop[9] & 0xe0) / 32) - 1; + tmp[2] = 'A' + (prop[9] & 0x1f) - 1; + + manufacturer = g_strndup (tmp, sizeof (tmp)); + } + + XFree(prop); + #undef EDID_LENGTH + } + gdk_monitor_get_geometry (GDK_MONITOR (monitor), &geometry); name = g_strndup (output_info->name, output_info->nameLen); @@ -433,6 +478,8 @@ init_randr15 (GdkX11Screen *x11_screen, gboolean *changed) gdk_monitor_set_scale_factor (GDK_MONITOR (monitor), x11_screen->surface_scale); gdk_monitor_set_model (GDK_MONITOR (monitor), name); gdk_monitor_set_connector (GDK_MONITOR (monitor), name); + gdk_monitor_set_manufacturer (GDK_MONITOR (monitor), manufacturer); + g_free (manufacturer); g_free (name); if (rr_monitors[i].primary)