[mutter/wip/wayland-display: 25/55] Extend the DBus XRandR protocol to expose cloning restriction



commit c88e7b42a4683cb49c1da794759a4e0682e96764
Author: Giovanni Campagna <gcampagn redhat com>
Date:   Fri Jul 19 18:47:01 2013 +0200

    Extend the DBus XRandR protocol to expose cloning restriction
    
    Turns out that even if two outputs say that they can be controlled
    by a given CRTC, you can't configure them in the same CRTC unless
    they are marked as "possible clones" one of the other.
    This can further restrict the configuration options, so we need
    to expose this limitation in the DBus API.

 src/core/monitor-private.h |    3 ++
 src/core/monitor.c         |   50 +++++++++++++++++++++++++++++++++++++++++--
 src/xrandr.xml             |    7 +++++-
 3 files changed, 56 insertions(+), 4 deletions(-)
---
diff --git a/src/core/monitor-private.h b/src/core/monitor-private.h
index 30526f6..b28123d 100644
--- a/src/core/monitor-private.h
+++ b/src/core/monitor-private.h
@@ -70,6 +70,9 @@ struct _MetaOutput
   MetaCRTC **possible_crtcs;
   unsigned int n_possible_crtcs;
 
+  MetaOutput **possible_clones;
+  unsigned int n_possible_clones;
+
   /* The low-level bits used to build the high-level info
      in MetaMonitorInfo
 
diff --git a/src/core/monitor.c b/src/core/monitor.c
index 6eae86a..7046aea 100644
--- a/src/core/monitor.c
+++ b/src/core/monitor.c
@@ -145,6 +145,8 @@ make_dummy_monitor_config (MetaMonitorManager *manager)
   manager->outputs[0].n_possible_crtcs = 1;
   manager->outputs[0].possible_crtcs = g_new0 (MetaCRTC *, 1);
   manager->outputs[0].possible_crtcs[0] = &manager->crtcs[0];
+  manager->outputs[0].n_possible_clones = 0;
+  manager->outputs[0].possible_clones = g_new0 (MetaOutput *, 0);
 }
 
 #ifdef HAVE_RANDR
@@ -280,6 +282,17 @@ read_monitor_infos_from_xrandr (MetaMonitorManager *manager)
                   }
               }
 
+            meta_output->n_possible_clones = output->nclone;
+            meta_output->possible_clones = g_new0 (MetaOutput *, meta_output->n_possible_clones);
+            /* We can build the list of clones now, because we don't have the list of outputs
+               yet, so temporarily set the pointers to the bare XIDs, and then we'll fix them
+               in a second pass
+            */
+            for (j = 0; j < (unsigned)output->nclone; j++)
+              {
+                meta_output->possible_clones = GINT_TO_POINTER (output->clones[j]);
+              }
+
             meta_output->is_primary = ((XID)meta_output->output_id == primary_output);
             meta_output->is_presentation = FALSE;
 
@@ -291,6 +304,28 @@ read_monitor_infos_from_xrandr (MetaMonitorManager *manager)
 
     manager->n_outputs = n_actual_outputs;
 
+    /* Now fix the clones */
+    for (i = 0; i < manager->n_outputs; i++)
+      {
+        MetaOutput *meta_output;
+
+        meta_output = &manager->outputs[i];
+
+        for (j = 0; j < meta_output->n_possible_clones; j++)
+          {
+            RROutput clone = GPOINTER_TO_INT (meta_output->possible_clones[j]);
+
+            for (k = 0; k < manager->n_outputs; k++)
+              {
+                if (clone == (XID)manager->outputs[k].output_id)
+                  {
+                    meta_output->possible_clones[j] = &manager->outputs[k];
+                    break;
+                  }
+              }
+          }
+      }
+
     XRRFreeScreenResources (resources);
 }
 
@@ -411,6 +446,8 @@ read_monitor_infos_from_cogl (MetaMonitorManager *manager)
       meta_output.n_possible_crtcs = 1;
       meta_output.possible_crtcs = g_new (MetaCRTC *, 1);
       meta_output.possible_crtcs[0] = meta_output.crtc;
+      meta_output.n_possible_clones = 0;
+      meta_output.possible_clones = g_new (MetaOutput *, 0);
       meta_output.is_primary = (iter == output_list);
       meta_output.is_presentation = FALSE;
 
@@ -619,6 +656,7 @@ free_output_array (MetaOutput *old_outputs,
       g_free (old_outputs[i].serial);
       g_free (old_outputs[i].modes);
       g_free (old_outputs[i].possible_crtcs);
+      g_free (old_outputs[i].possible_clones);
     }
 
   g_free (old_outputs);
@@ -679,7 +717,7 @@ handle_get_resources (MetaDBusDisplayConfig *skeleton,
   unsigned int i, j;
 
   g_variant_builder_init (&crtc_builder, G_VARIANT_TYPE ("a(uxiiiiiuaua{sv})"));
-  g_variant_builder_init (&output_builder, G_VARIANT_TYPE ("a(uxiaussssaua{sv})"));
+  g_variant_builder_init (&output_builder, G_VARIANT_TYPE ("a(uxiaussssauaua{sv})"));
   g_variant_builder_init (&mode_builder, G_VARIANT_TYPE ("a(uxuud)"));
 
   for (i = 0; i < manager->n_crtcs; i++)
@@ -706,7 +744,7 @@ handle_get_resources (MetaDBusDisplayConfig *skeleton,
   for (i = 0; i < manager->n_outputs; i++)
     {
       MetaOutput *output = &manager->outputs[i];
-      GVariantBuilder crtcs, modes, properties;
+      GVariantBuilder crtcs, modes, clones, properties;
 
       g_variant_builder_init (&crtcs, G_VARIANT_TYPE ("au"));
       for (j = 0; j < output->n_possible_crtcs; j++)
@@ -718,13 +756,18 @@ handle_get_resources (MetaDBusDisplayConfig *skeleton,
         g_variant_builder_add (&modes, "u",
                                (unsigned)(output->modes[j] - manager->modes));
 
+      g_variant_builder_init (&clones, G_VARIANT_TYPE ("au"));
+      for (j = 0; j < output->n_possible_clones; j++)
+        g_variant_builder_add (&clones, "u",
+                               (unsigned)(output->possible_clones[j] - manager->outputs));
+
       g_variant_builder_init (&properties, G_VARIANT_TYPE ("a{sv}"));
       g_variant_builder_add (&properties, "{sv}", "primary",
                              g_variant_new_boolean (output->is_primary));
       g_variant_builder_add (&properties, "{sv}", "presentation",
                              g_variant_new_boolean (output->is_presentation));
 
-      g_variant_builder_add (&output_builder, "(uxiaussssaua{sv})",
+      g_variant_builder_add (&output_builder, "(uxiaussssauaua{sv})",
                              i, /* ID */
                              output->output_id,
                              (int)(output->crtc ? output->crtc - manager->crtcs : -1),
@@ -734,6 +777,7 @@ handle_get_resources (MetaDBusDisplayConfig *skeleton,
                              output->product,
                              output->serial,
                              &modes,
+                             &clones,
                              &properties);
     }
       
diff --git a/src/xrandr.xml b/src/xrandr.xml
index 9b49706..f519bb7 100644
--- a/src/xrandr.xml
+++ b/src/xrandr.xml
@@ -79,6 +79,11 @@
        * s product: the human readable name of the display model
        * s serial: the serial number of this particular hardward part
        * au modes: valid modes for this output
+       * au clones: valid clones for this output, ie other outputs that
+                    can be assigned the same CRTC as this one; if you
+                    want to mirror two outputs that don't have each other
+                    in the clone list, you must configure two different
+                    CRTCs for the same geometry
        * a{sv} properties: other high-level properties that affect this
                            output; they are not necessarily reflected in
                            the hardware.
@@ -118,7 +123,7 @@
     <method name="GetResources">
       <arg name="serial" direction="out" type="u" />
       <arg name="crtcs" direction="out" type="a(uxiiiiiuaua{sv})" />
-      <arg name="outputs" direction="out" type="a(uxiaussssaua{sv})" />
+      <arg name="outputs" direction="out" type="a(uxiaussssauaua{sv})" />
       <arg name="modes" direction="out" type="a(uxuud)" />
     </method>
 


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