[mutter/wip/display-no-wayland: 29/33] MonitorManager: add EDID properties to the output DBus description



commit d7b2ea37b15639c7c71b8c7f70f8647530264a71
Author: Giovanni Campagna <gcampagn redhat com>
Date:   Thu Aug 8 13:32:05 2013 +0200

    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

 src/core/monitor-private.h |    6 ++++
 src/core/monitor-xrandr.c  |   70 ++++++++++++++++++++++++++++++++++++++++++++
 src/core/monitor.c         |   38 ++++++++++++++++++++++++
 3 files changed, 114 insertions(+), 0 deletions(-)
---
diff --git a/src/core/monitor-private.h b/src/core/monitor-private.h
index c3ac0eb..970bd32 100644
--- a/src/core/monitor-private.h
+++ b/src/core/monitor-private.h
@@ -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         ,
diff --git a/src/core/monitor-xrandr.c b/src/core/monitor-xrandr.c
index 0f251ff..3e245c9 100644
--- a/src/core/monitor-xrandr.c
+++ b/src/core/monitor-xrandr.c
@@ -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;
diff --git a/src/core/monitor.c b/src/core/monitor.c
index eee0360..1fbcd9c 100644
--- a/src/core/monitor.c
+++ b/src/core/monitor.c
@@ -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,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]