Commit 57077435 authored by Giovanni Campagna's avatar Giovanni Campagna Committed by Giovanni Campagna
Browse files

MonitorManager: add EDID properties to the output DBus description

Add "edid-file", if we have one (in the KMS case, where we can point
people to the right sysfs file), or "edid" with inline data.
These are needed by colord to build the default ICC profile for
uncalibrated displays.

https://bugzilla.gnome.org/show_bug.cgi?id=705670
parent 46de0ed4
......@@ -257,6 +257,12 @@ struct _MetaMonitorManagerClass
MetaDBusDisplayConfigSkeletonClass parent_class;
void (*read_current) (MetaMonitorManager *);
char* (*get_edid_file) (MetaMonitorManager *,
MetaOutput *);
GBytes* (*read_edid) (MetaMonitorManager *,
MetaOutput *);
void (*apply_configuration) (MetaMonitorManager *,
MetaCRTCInfo **,
unsigned int ,
......
......@@ -467,6 +467,75 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
}
}
static guint8 *
get_edid_property (Display *dpy,
RROutput output,
Atom atom,
gsize *len)
{
unsigned char *prop;
int actual_format;
unsigned long nitems, bytes_after;
Atom actual_type;
guint8 *result;
XRRGetOutputProperty (dpy, output, atom,
0, 100, False, False,
AnyPropertyType,
&actual_type, &actual_format,
&nitems, &bytes_after, &prop);
if (actual_type == XA_INTEGER && actual_format == 8)
{
result = g_memdup (prop, nitems);
if (len)
*len = nitems;
}
else
{
result = NULL;
}
XFree (prop);
return result;
}
static GBytes *
meta_monitor_manager_xrandr_read_edid (MetaMonitorManager *manager,
MetaOutput *output)
{
MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
Atom edid_atom;
guint8 *result;
gsize len;
edid_atom = XInternAtom (manager_xrandr->xdisplay, "EDID", FALSE);
result = get_edid_property (manager_xrandr->xdisplay, output->output_id, edid_atom, &len);
if (!result)
{
edid_atom = XInternAtom (manager_xrandr->xdisplay, "EDID_DATA", FALSE);
result = get_edid_property (manager_xrandr->xdisplay, output->output_id, edid_atom, &len);
}
if (!result)
{
edid_atom = XInternAtom (manager_xrandr->xdisplay, "XFree86_DDC_EDID1_RAWDATA", FALSE);
result = get_edid_property (manager_xrandr->xdisplay, output->output_id, edid_atom, &len);
}
if (result)
{
if (len > 0 && len % 128 == 0)
return g_bytes_new_take (result, len);
else
g_free (result);
}
return NULL;
}
static void
meta_monitor_manager_xrandr_set_power_save_mode (MetaMonitorManager *manager,
MetaPowerSave mode)
......@@ -767,6 +836,7 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
object_class->finalize = meta_monitor_manager_xrandr_finalize;
manager_class->read_current = meta_monitor_manager_xrandr_read_current;
manager_class->read_edid = meta_monitor_manager_xrandr_read_edid;
manager_class->apply_configuration = meta_monitor_manager_xrandr_apply_configuration;
manager_class->set_power_save_mode = meta_monitor_manager_xrandr_set_power_save_mode;
manager_class->change_backlight = meta_monitor_manager_xrandr_change_backlight;
......
......@@ -353,6 +353,20 @@ apply_config_dummy (MetaMonitorManager *manager,
invalidate_logical_config (manager);
}
static GBytes *
read_edid_dummy (MetaMonitorManager *manager,
MetaOutput *output)
{
return NULL;
}
static char *
get_edid_file_dummy (MetaMonitorManager *manager,
MetaOutput *output)
{
return NULL;
}
static void
meta_monitor_manager_init (MetaMonitorManager *manager)
{
......@@ -643,6 +657,8 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
klass->read_current = read_current_dummy;
klass->apply_configuration = apply_config_dummy;
klass->get_edid_file = get_edid_file_dummy;
klass->read_edid = read_edid_dummy;
signals[MONITORS_CHANGED] =
g_signal_new ("monitors-changed",
......@@ -712,6 +728,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
GDBusMethodInvocation *invocation)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (skeleton);
MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_GET_CLASS (skeleton);
GVariantBuilder crtc_builder, output_builder, mode_builder;
unsigned int i, j;
......@@ -746,6 +763,8 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
{
MetaOutput *output = &manager->outputs[i];
GVariantBuilder crtcs, modes, clones, properties;
GBytes *edid;
char *edid_file;
g_variant_builder_init (&crtcs, G_VARIANT_TYPE ("au"));
for (j = 0; j < output->n_possible_crtcs; j++)
......@@ -778,6 +797,25 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
g_variant_builder_add (&properties, "{sv}", "presentation",
g_variant_new_boolean (output->is_presentation));
edid_file = manager_class->get_edid_file (manager, output);
if (edid_file)
{
g_variant_builder_add (&properties, "{sv}", "edid-file",
g_variant_new_take_string (edid_file));
}
else
{
edid = manager_class->read_edid (manager, output);
if (edid)
{
g_variant_builder_add (&properties, "{sv}", "edid",
g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"),
edid, TRUE));
g_bytes_unref (edid);
}
}
g_variant_builder_add (&output_builder, "(uxiausauaua{sv})",
i, /* ID */
output->output_id,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment