gdk: x11: Fill GdkMonitor manufacturer with PNP id from EDID

Previously, the manufacturer property of the GdkMonitor was NULL,
and having at least PNP id at GdkMonitor.manufacturer makes it
possible to distinguish between different monitors programmatically.
This commit is contained in:
Priit Laes 2019-08-06 09:16:01 +03:00
parent a3609c3f6d
commit f43d344aa3
2 changed files with 53 additions and 1 deletions

View File

@ -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
*/

View File

@ -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)