summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2019-08-25 11:58:02 +0000
committerMatthias Clasen <mclasen@redhat.com>2019-08-25 11:58:02 +0000
commit4fa1f459dda18dd6e1020089eeb9f58b0b9276c3 (patch)
tree2acc0fb52fb66a43d6acb41534d96f0914ab7fea
parent25644aa6b1b35ec7eef8603c170b835ce8707334 (diff)
parentf43d344aa39e0872449840690ea2981f46bc67cb (diff)
downloadgtk+-4fa1f459dda18dd6e1020089eeb9f58b0b9276c3.tar.gz
Merge branch 'gdkmonitor-x11-manufacturer' into 'master'
gdk: x11: Fill GdkMonitor manufacturer with PNP id from EDID Closes #1765 See merge request GNOME/gtk!859
-rw-r--r--gdk/gdkmonitor.c7
-rw-r--r--gdk/x11/gdkscreen-x11.c47
2 files changed, 53 insertions, 1 deletions
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)