Blame SOURCES/support-suggested-output-position.patch

2c033f
From 9fa99a888d9d9b84cabf419d321f0223e0d5ab7e Mon Sep 17 00:00:00 2001
2c033f
From: Jonathon Jongsma <jjongsma@redhat.com>
2c033f
Date: Mon, 17 Nov 2014 15:13:15 -0600
2c033f
Subject: [PATCH 1/4] monitor-config: refactor make_default_config()
2c033f
2c033f
Move logic for creating different types of configurations into separate
2c033f
functions. This keeps things a bit cleaner and allows us to add alternate
2c033f
configuration types more easily.
2c033f
2c033f
Conflicts:
2c033f
	src/backends/meta-monitor-config.c
2c033f
2c033f
https://bugzilla.redhat.com/show_bug.cgi?id=1166319
2c033f
---
2c033f
 src/backends/meta-monitor-config.c | 172 +++++++++++++++++++++----------------
2c033f
 1 file changed, 100 insertions(+), 72 deletions(-)
2c033f
2c033f
diff --git a/src/backends/meta-monitor-config.c b/src/backends/meta-monitor-config.c
2c033f
index 399e9f0..99042d7 100644
2c033f
--- a/src/backends/meta-monitor-config.c
2c033f
+++ b/src/backends/meta-monitor-config.c
2c033f
@@ -1081,47 +1081,78 @@ find_primary_output (MetaOutput *outputs,
2c033f
   return best;
2c033f
 }
2c033f
 
2c033f
-static MetaConfiguration *
2c033f
-make_default_config (MetaMonitorConfig *self,
2c033f
-                     MetaOutput        *outputs,
2c033f
-                     unsigned           n_outputs,
2c033f
-                     int                max_width,
2c033f
-                     int                max_height)
2c033f
+static void
2c033f
+init_config_from_preferred_mode (MetaOutputConfig *config,
2c033f
+                                 MetaOutput *output)
2c033f
+{
2c033f
+  config->enabled = TRUE;
2c033f
+  config->rect.x = 0;
2c033f
+  config->rect.y = 0;
2c033f
+  config->rect.width = output->preferred_mode->width;
2c033f
+  config->rect.height = output->preferred_mode->height;
2c033f
+  config->refresh_rate = output->preferred_mode->refresh_rate;
2c033f
+  config->transform = META_MONITOR_TRANSFORM_NORMAL;
2c033f
+  config->is_primary = FALSE;
2c033f
+  config->is_presentation = FALSE;
2c033f
+}
2c033f
+
2c033f
+static void
2c033f
+make_linear_config (MetaMonitorConfig *self,
2c033f
+                    MetaOutput        *outputs,
2c033f
+                    unsigned           n_outputs,
2c033f
+                    int                max_width,
2c033f
+                    int                max_height,
2c033f
+                    MetaConfiguration *config)
2c033f
 {
2c033f
-  unsigned i, j;
2c033f
-  int x, y;
2c033f
-  MetaConfiguration *ret;
2c033f
   MetaOutput *primary;
2c033f
+  unsigned i;
2c033f
+  int x;
2c033f
 
2c033f
-  ret = g_slice_new (MetaConfiguration);
2c033f
-  make_config_key (ret, outputs, n_outputs, -1);
2c033f
-  ret->outputs = g_new0 (MetaOutputConfig, n_outputs);
2c033f
+  g_return_if_fail (config != NULL);
2c033f
 
2c033f
-  /* Special case the simple case: one output, primary at preferred mode,
2c033f
-     nothing else to do */
2c033f
-  if (n_outputs == 1)
2c033f
+  primary = find_primary_output (outputs, n_outputs);
2c033f
+
2c033f
+  x = primary->preferred_mode->width;
2c033f
+  for (i = 0; i < n_outputs; i++)
2c033f
     {
2c033f
-      ret->outputs[0].enabled = TRUE;
2c033f
-      ret->outputs[0].rect.x = 0;
2c033f
-      ret->outputs[0].rect.y = 0;
2c033f
-      ret->outputs[0].rect.width = outputs[0].preferred_mode->width;
2c033f
-      ret->outputs[0].rect.height = outputs[0].preferred_mode->height;
2c033f
-      ret->outputs[0].refresh_rate = outputs[0].preferred_mode->refresh_rate;
2c033f
-      ret->outputs[0].transform = META_MONITOR_TRANSFORM_NORMAL;
2c033f
-      ret->outputs[0].is_primary = TRUE;
2c033f
+      gboolean is_primary = (&outputs[i] == primary);
2c033f
 
2c033f
-      return ret;
2c033f
-    }
2c033f
+      init_config_from_preferred_mode (&config->outputs[i], &outputs[i]);
2c033f
+      config->outputs[i].is_primary = is_primary;
2c033f
 
2c033f
-  /* If we reach this point, this is either the first time mutter runs
2c033f
-     on this system ever, or we just hotplugged a new screen.
2c033f
-     In the latter case, search for a configuration that includes one
2c033f
-     less screen, then add the new one as a presentation screen
2c033f
-     in preferred mode.
2c033f
+      if (is_primary)
2c033f
+        {
2c033f
+          config->outputs[i].rect.x = 0;
2c033f
+        }
2c033f
+      else
2c033f
+        {
2c033f
+          config->outputs[i].rect.x = x;
2c033f
+          x += config->outputs[i].rect.width;
2c033f
+        }
2c033f
+
2c033f
+      /* Disable outputs that would go beyond framebuffer limits */
2c033f
+      if (config->outputs[i].rect.x + config->outputs[i].rect.width > max_width)
2c033f
+        config->outputs[i].enabled = FALSE;
2c033f
+    }
2c033f
+}
2c033f
 
2c033f
-     XXX: but presentation mode is not implemented in the control-center
2c033f
-     or in mutter core, so let's do extended for now.
2c033f
+/* Search for a configuration that includes one less screen, then add the new
2c033f
+ * one as a presentation screen in preferred mode.
2c033f
+ *
2c033f
+ * XXX: but presentation mode is not implemented in the control-center or in
2c033f
+ * mutter core, so let's do extended for now.
2c033f
   */
2c033f
+static gboolean
2c033f
+extend_stored_config (MetaMonitorConfig *self,
2c033f
+                      MetaOutput        *outputs,
2c033f
+                      unsigned           n_outputs,
2c033f
+                      int                max_width,
2c033f
+                      int                max_height,
2c033f
+                      MetaConfiguration *config)
2c033f
+{
2c033f
+  int x, y;
2c033f
+  unsigned i, j;
2c033f
+
2c033f
   x = 0;
2c033f
   y = 0;
2c033f
   for (i = 0; i < n_outputs; i++)
2c033f
@@ -1139,71 +1170,68 @@ make_default_config (MetaMonitorConfig *self,
2c033f
             {
2c033f
               if (j < i)
2c033f
                 {
2c033f
-                  g_assert (output_key_equal (&ret->keys[j], &ref->keys[j]));
2c033f
-                  ret->outputs[j] = ref->outputs[j];
2c033f
+                  g_assert (output_key_equal (&config->keys[j], &ref->keys[j]));
2c033f
+                  config->outputs[j] = ref->outputs[j];
2c033f
                   x = MAX (x, ref->outputs[j].rect.x + ref->outputs[j].rect.width);
2c033f
                   y = MAX (y, ref->outputs[j].rect.y + ref->outputs[j].rect.height);
2c033f
                 }
2c033f
               else if (j > i)
2c033f
                 {
2c033f
-                  g_assert (output_key_equal (&ret->keys[j], &ref->keys[j - 1]));
2c033f
-                  ret->outputs[j] = ref->outputs[j - 1];
2c033f
+                  g_assert (output_key_equal (&config->keys[j], &ref->keys[j - 1]));
2c033f
+                  config->outputs[j] = ref->outputs[j - 1];
2c033f
                   x = MAX (x, ref->outputs[j - 1].rect.x + ref->outputs[j - 1].rect.width);
2c033f
                   y = MAX (y, ref->outputs[j - 1].rect.y + ref->outputs[j - 1].rect.height);
2c033f
                 }
2c033f
               else
2c033f
                 {
2c033f
-                  ret->outputs[j].enabled = TRUE;
2c033f
-                  ret->outputs[j].rect.x = 0;
2c033f
-                  ret->outputs[j].rect.y = 0;
2c033f
-                  ret->outputs[j].rect.width = outputs[0].preferred_mode->width;
2c033f
-                  ret->outputs[j].rect.height = outputs[0].preferred_mode->height;
2c033f
-                  ret->outputs[j].refresh_rate = outputs[0].preferred_mode->refresh_rate;
2c033f
-                  ret->outputs[j].transform = META_MONITOR_TRANSFORM_NORMAL;
2c033f
-                  ret->outputs[j].is_primary = FALSE;
2c033f
-                  ret->outputs[j].is_presentation = FALSE;
2c033f
+                  init_config_from_preferred_mode (&ref->outputs[j], &outputs[0]);
2c033f
                 }
2c033f
             }
2c033f
 
2c033f
           /* Place the new output at the right end of the screen, if it fits,
2c033f
              otherwise below it, otherwise disable it (or apply_configuration will fail) */
2c033f
-          if (x + ret->outputs[i].rect.width <= max_width)
2c033f
-            ret->outputs[i].rect.x = x;
2c033f
-          else if (y + ret->outputs[i].rect.height <= max_height)
2c033f
-            ret->outputs[i].rect.y = y;
2c033f
+          if (x + config->outputs[i].rect.width <= max_width)
2c033f
+            config->outputs[i].rect.x = x;
2c033f
+          else if (y + config->outputs[i].rect.height <= max_height)
2c033f
+            config->outputs[i].rect.y = y;
2c033f
           else
2c033f
-            ret->outputs[i].enabled = FALSE;
2c033f
+            config->outputs[i].enabled = FALSE;
2c033f
 
2c033f
-          return ret;
2c033f
+          return TRUE;
2c033f
         }
2c033f
     }
2c033f
 
2c033f
-  /* No previous configuration found, try with a really default one, which
2c033f
-     is one primary that goes first and the rest to the right of it, extended.
2c033f
-  */
2c033f
-  primary = find_primary_output (outputs, n_outputs);
2c033f
+  return FALSE;
2c033f
+}
2c033f
 
2c033f
-  x = primary->preferred_mode->width;
2c033f
-  for (i = 0; i < n_outputs; i++)
2c033f
-    {
2c033f
-      MetaOutput *output = &outputs[i];
2c033f
+static MetaConfiguration *
2c033f
+make_default_config (MetaMonitorConfig *self,
2c033f
+                     MetaOutput        *outputs,
2c033f
+                     unsigned           n_outputs,
2c033f
+                     int                max_width,
2c033f
+                     int                max_height)
2c033f
+{
2c033f
+  MetaConfiguration *ret = NULL;
2c033f
 
2c033f
-      ret->outputs[i].enabled = TRUE;
2c033f
-      ret->outputs[i].rect.x = (output == primary) ? 0 : x;
2c033f
-      ret->outputs[i].rect.y = 0;
2c033f
-      ret->outputs[i].rect.width = output->preferred_mode->width;
2c033f
-      ret->outputs[i].rect.height = output->preferred_mode->height;
2c033f
-      ret->outputs[i].refresh_rate = output->preferred_mode->refresh_rate;
2c033f
-      ret->outputs[i].transform = META_MONITOR_TRANSFORM_NORMAL;
2c033f
-      ret->outputs[i].is_primary = (output == primary);
2c033f
+  ret = g_slice_new (MetaConfiguration);
2c033f
+  make_config_key (ret, outputs, n_outputs, -1);
2c033f
+  ret->outputs = g_new0 (MetaOutputConfig, n_outputs);
2c033f
 
2c033f
-      /* Disable outputs that would go beyond framebuffer limits */
2c033f
-      if (ret->outputs[i].rect.x + ret->outputs[i].rect.width > max_width)
2c033f
-        ret->outputs[i].enabled = FALSE;
2c033f
-      else if (output != primary)
2c033f
-        x += output->preferred_mode->width;
2c033f
+  /* Special case the simple case: one output, primary at preferred mode,
2c033f
+     nothing else to do */
2c033f
+  if (n_outputs == 1)
2c033f
+    {
2c033f
+
2c033f
+      init_config_from_preferred_mode (&ret->outputs[0], &outputs[0]);
2c033f
+      ret->outputs[0].is_primary = TRUE;
2c033f
+      return ret;
2c033f
     }
2c033f
 
2c033f
+  if (extend_stored_config (self, outputs, n_outputs, max_width, max_height, ret))
2c033f
+      return ret;
2c033f
+
2c033f
+  make_linear_config (self, outputs, n_outputs, max_width, max_height, ret);
2c033f
+
2c033f
   return ret;
2c033f
 }
2c033f
 
2c033f
-- 
2c033f
2.3.6
2c033f
2c033f
2c033f
From 76566a956eaf7b905dbfd851ee63ebe6236ab872 Mon Sep 17 00:00:00 2001
2c033f
From: Jonathon Jongsma <jjongsma@redhat.com>
2c033f
Date: Wed, 12 Nov 2014 10:25:55 -0600
2c033f
Subject: [PATCH 2/4] monitor-config: ignore stored config when
2c033f
 hotplug_mode_update is set
2c033f
2c033f
When the output device has hotplug_mode_update (e.g. the qxl driver used in
2c033f
vms), the displays can be dynamically resized, so the current display
2c033f
configuration does not often match a stored configuration. When a new
2c033f
monitor is added, make_default_config() tries to create a new display
2c033f
configuration by choosing a stored configuration with N-1 monitors, and then
2c033f
adding a new monitor to the end of the layout. Because the stored config
2c033f
doesn't match the current outputs, apply_configuration() will routinely
2c033f
fail, leaving the additional display unconfigured. In this case, it's more
2c033f
useful to just fall back to creating a new default configuration from
2c033f
scratch so that all outputs get configured to their preferred mode.
2c033f
2c033f
Conflicts:
2c033f
	src/backends/meta-monitor-config.c
2c033f
2c033f
https://bugzilla.redhat.com/show_bug.cgi?id=1166319
2c033f
---
2c033f
 src/backends/meta-monitor-config.c | 17 ++++++++++++++---
2c033f
 1 file changed, 14 insertions(+), 3 deletions(-)
2c033f
2c033f
diff --git a/src/backends/meta-monitor-config.c b/src/backends/meta-monitor-config.c
2c033f
index 99042d7..3e57215 100644
2c033f
--- a/src/backends/meta-monitor-config.c
2c033f
+++ b/src/backends/meta-monitor-config.c
2c033f
@@ -1209,7 +1209,8 @@ make_default_config (MetaMonitorConfig *self,
2c033f
                      MetaOutput        *outputs,
2c033f
                      unsigned           n_outputs,
2c033f
                      int                max_width,
2c033f
-                     int                max_height)
2c033f
+                     int                max_height,
2c033f
+                     gboolean           use_stored_config)
2c033f
 {
2c033f
   MetaConfiguration *ret = NULL;
2c033f
 
2c033f
@@ -1227,7 +1228,8 @@ make_default_config (MetaMonitorConfig *self,
2c033f
       return ret;
2c033f
     }
2c033f
 
2c033f
-  if (extend_stored_config (self, outputs, n_outputs, max_width, max_height, ret))
2c033f
+  if (use_stored_config &&
2c033f
+      extend_stored_config (self, outputs, n_outputs, max_width, max_height, ret))
2c033f
       return ret;
2c033f
 
2c033f
   make_linear_config (self, outputs, n_outputs, max_width, max_height, ret);
2c033f
@@ -1292,6 +1294,7 @@ meta_monitor_config_make_default (MetaMonitorConfig  *self,
2c033f
   unsigned n_outputs;
2c033f
   gboolean ok;
2c033f
   int max_width, max_height;
2c033f
+  gboolean use_stored_config;
2c033f
 
2c033f
   outputs = meta_monitor_manager_get_outputs (manager, &n_outputs);
2c033f
   meta_monitor_manager_get_screen_limits (manager, &max_width, &max_height);
2c033f
@@ -1302,7 +1305,15 @@ meta_monitor_config_make_default (MetaMonitorConfig  *self,
2c033f
       return;
2c033f
     }
2c033f
 
2c033f
-  default_config = make_default_config (self, outputs, n_outputs, max_width, max_height);
2c033f
+  /* if the device has hotplug_mode_update, it's possible that the
2c033f
+   * current display configuration does not match a stored configuration.
2c033f
+   * Since extend_existing_config() tries to build a configuration that is
2c033f
+   * based on a previously-stored configuration, it's quite likely that the
2c033f
+   * resulting config will fail. Even if it doesn't fail, it may result in
2c033f
+   * an unexpected configuration, so don't attempt to use a stored config
2c033f
+   * in this situation. */
2c033f
+  use_stored_config = !meta_monitor_manager_has_hotplug_mode_update (manager);
2c033f
+  default_config = make_default_config (self, outputs, n_outputs, max_width, max_height, use_stored_config);
2c033f
 
2c033f
   if (default_config != NULL)
2c033f
     {
2c033f
-- 
2c033f
2.3.6
2c033f
2c033f
2c033f
From f357ed24e24efa26b2d65ca307db8c20e20238b9 Mon Sep 17 00:00:00 2001
2c033f
From: Jonathon Jongsma <jjongsma@redhat.com>
2c033f
Date: Mon, 10 Nov 2014 15:36:47 -0600
2c033f
Subject: [PATCH 3/4] monitor-manager: Add support for suggested position for
2c033f
 outputs
2c033f
2c033f
In recent versions of the QXL driver, it may set "suggested X|Y" connector
2c033f
properties. These properties are used to indicate the position at which
2c033f
multiple displays should be aligned.  If all outputs have a suggested position,
2c033f
the displays are arranged according to these positions, otherwise we fall back
2c033f
to the default configuration.
2c033f
2c033f
At the moment, we trust that the driver has chosen sane values for the
2c033f
suggested position.
2c033f
2c033f
https://bugzilla.redhat.com/show_bug.cgi?id=1166319
2c033f
---
2c033f
 src/backends/meta-monitor-config.c             | 53 ++++++++++++++++++++++++++
2c033f
 src/backends/meta-monitor-manager.h            |  2 +
2c033f
 src/backends/native/meta-monitor-manager-kms.c |  2 +
2c033f
 src/backends/x11/meta-monitor-manager-xrandr.c | 52 +++++++++++++++++++++++++
2c033f
 4 files changed, 109 insertions(+)
2c033f
2c033f
diff --git a/src/backends/meta-monitor-config.c b/src/backends/meta-monitor-config.c
2c033f
index 3e57215..a65c241 100644
2c033f
--- a/src/backends/meta-monitor-config.c
2c033f
+++ b/src/backends/meta-monitor-config.c
2c033f
@@ -34,6 +34,7 @@
2c033f
 
2c033f
 #include "config.h"
2c033f
 
2c033f
+#include "boxes-private.h"
2c033f
 #include "meta-monitor-config.h"
2c033f
 
2c033f
 #include <string.h>
2c033f
@@ -1096,6 +1097,55 @@ init_config_from_preferred_mode (MetaOutputConfig *config,
2c033f
   config->is_presentation = FALSE;
2c033f
 }
2c033f
 
2c033f
+/* This function handles configuring the outputs when the driver provides a
2c033f
+ * suggested layout position for each output. This is done in recent versions
2c033f
+ * of qxl and allows displays to be aligned on the guest in the same order as
2c033f
+ * they are aligned on the client.
2c033f
+ */
2c033f
+static gboolean
2c033f
+make_suggested_config (MetaMonitorConfig *self,
2c033f
+                       MetaOutput        *outputs,
2c033f
+                       unsigned           n_outputs,
2c033f
+                       int                max_width,
2c033f
+                       int                max_height,
2c033f
+                       MetaConfiguration *config)
2c033f
+{
2c033f
+  unsigned int i;
2c033f
+  MetaOutput *primary;
2c033f
+  GList *region = NULL;
2c033f
+
2c033f
+  g_return_val_if_fail (config != NULL, FALSE);
2c033f
+  primary = find_primary_output (outputs, n_outputs);
2c033f
+
2c033f
+  for (i = 0; i < n_outputs; i++)
2c033f
+    {
2c033f
+      gboolean is_primary = (&outputs[i] == primary);
2c033f
+
2c033f
+      if (outputs[i].suggested_x < 0 || outputs[i].suggested_y < 0)
2c033f
+          return FALSE;
2c033f
+
2c033f
+      init_config_from_preferred_mode (&config->outputs[i], &outputs[i]);
2c033f
+      config->outputs[i].is_primary = is_primary;
2c033f
+
2c033f
+      config->outputs[i].rect.x = outputs[i].suggested_x;
2c033f
+      config->outputs[i].rect.y = outputs[i].suggested_y;
2c033f
+
2c033f
+      /* Reject the configuration if the suggested positions result in
2c033f
+       * overlapping displays */
2c033f
+      if (meta_rectangle_overlaps_with_region (region, &config->outputs[i].rect))
2c033f
+        {
2c033f
+          g_warning ("Overlapping outputs, rejecting suggested configuration");
2c033f
+          g_list_free (region);
2c033f
+          return FALSE;
2c033f
+        }
2c033f
+
2c033f
+      region = g_list_prepend (region, &config->outputs[i].rect);
2c033f
+    }
2c033f
+
2c033f
+  g_list_free (region);
2c033f
+  return TRUE;
2c033f
+}
2c033f
+
2c033f
 static void
2c033f
 make_linear_config (MetaMonitorConfig *self,
2c033f
                     MetaOutput        *outputs,
2c033f
@@ -1228,6 +1278,9 @@ make_default_config (MetaMonitorConfig *self,
2c033f
       return ret;
2c033f
     }
2c033f
 
2c033f
+  if (make_suggested_config (self, outputs, n_outputs, max_width, max_height, ret))
2c033f
+      return ret;
2c033f
+
2c033f
   if (use_stored_config &&
2c033f
       extend_stored_config (self, outputs, n_outputs, max_width, max_height, ret))
2c033f
       return ret;
2c033f
diff --git a/src/backends/meta-monitor-manager.h b/src/backends/meta-monitor-manager.h
2c033f
index 77ab938..0b81a4e 100644
2c033f
--- a/src/backends/meta-monitor-manager.h
2c033f
+++ b/src/backends/meta-monitor-manager.h
2c033f
@@ -116,6 +116,8 @@ struct _MetaOutput
2c033f
 
2c033f
   /* get a new preferred mode on hotplug events, to handle dynamic guest resizing */
2c033f
   gboolean hotplug_mode_update;
2c033f
+  gint suggested_x;
2c033f
+  gint suggested_y;
2c033f
 };
2c033f
 
2c033f
 struct _MetaCRTC
2c033f
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
2c033f
index ad37df6..2e46276 100644
2c033f
--- a/src/backends/native/meta-monitor-manager-kms.c
2c033f
+++ b/src/backends/native/meta-monitor-manager-kms.c
2c033f
@@ -410,6 +410,8 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
2c033f
 	  meta_output->name = make_output_name (connector);
2c033f
 	  meta_output->width_mm = connector->mmWidth;
2c033f
 	  meta_output->height_mm = connector->mmHeight;
2c033f
+	  meta_output->suggested_x = -1;
2c033f
+	  meta_output->suggested_y = -1;
2c033f
 
2c033f
           switch (connector->subpixel)
2c033f
             {
2c033f
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
2c033f
index 4c1b16c..2c6d65e 100644
2c033f
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
2c033f
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
2c033f
@@ -141,6 +141,34 @@ meta_monitor_transform_from_xrandr_all (Rotation rotation)
2c033f
 }
2c033f
 
2c033f
 static gboolean
2c033f
+output_get_integer_property (MetaMonitorManagerXrandr *manager_xrandr,
2c033f
+                             MetaOutput *output, const char *propname,
2c033f
+                             gint *value)
2c033f
+{
2c033f
+  gboolean exists = FALSE;
2c033f
+  Atom atom, actual_type;
2c033f
+  int actual_format;
2c033f
+  unsigned long nitems, bytes_after;
2c033f
+  unsigned char *buffer;
2c033f
+
2c033f
+  atom = XInternAtom (manager_xrandr->xdisplay, propname, False);
2c033f
+  XRRGetOutputProperty (manager_xrandr->xdisplay,
2c033f
+                        (XID)output->winsys_id,
2c033f
+                        atom,
2c033f
+                        0, G_MAXLONG, False, False, XA_INTEGER,
2c033f
+                        &actual_type, &actual_format,
2c033f
+                        &nitems, &bytes_after, &buffer);
2c033f
+
2c033f
+  exists = (actual_type == XA_INTEGER && actual_format == 32 && nitems == 1);
2c033f
+
2c033f
+  if (exists && value != NULL)
2c033f
+    *value = ((int*)buffer)[0];
2c033f
+
2c033f
+  XFree (buffer);
2c033f
+  return exists;
2c033f
+}
2c033f
+
2c033f
+static gboolean
2c033f
 output_get_property_exists (MetaMonitorManagerXrandr *manager_xrandr,
2c033f
                             MetaOutput *output, const char *propname)
2c033f
 {
2c033f
@@ -357,6 +385,28 @@ output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr,
2c033f
   return output_get_property_exists (manager_xrandr, output, "hotplug_mode_update");
2c033f
 }
2c033f
 
2c033f
+static gint
2c033f
+output_get_suggested_x (MetaMonitorManagerXrandr *manager_xrandr,
2c033f
+                        MetaOutput               *output)
2c033f
+{
2c033f
+  gint val;
2c033f
+  if (output_get_integer_property (manager_xrandr, output, "suggested X", &val))
2c033f
+    return val;
2c033f
+
2c033f
+  return -1;
2c033f
+}
2c033f
+
2c033f
+static gint
2c033f
+output_get_suggested_y (MetaMonitorManagerXrandr *manager_xrandr,
2c033f
+                        MetaOutput               *output)
2c033f
+{
2c033f
+  gint val;
2c033f
+  if (output_get_integer_property (manager_xrandr, output, "suggested Y", &val))
2c033f
+    return val;
2c033f
+
2c033f
+  return -1;
2c033f
+}
2c033f
+
2c033f
 static char *
2c033f
 get_xmode_name (XRRModeInfo *xmode)
2c033f
 {
2c033f
@@ -545,6 +595,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
2c033f
 	  meta_output->height_mm = output->mm_height;
2c033f
 	  meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
2c033f
           meta_output->hotplug_mode_update = output_get_hotplug_mode_update (manager_xrandr, meta_output);
2c033f
+	  meta_output->suggested_x = output_get_suggested_x (manager_xrandr, meta_output);
2c033f
+	  meta_output->suggested_y = output_get_suggested_y (manager_xrandr, meta_output);
2c033f
 
2c033f
 	  meta_output->n_modes = output->nmode;
2c033f
 	  meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
2c033f
-- 
2c033f
2.3.6
2c033f
2c033f
2c033f
From d0607177b47d2e499ec822fb7aa4c55224f4c85a Mon Sep 17 00:00:00 2001
2c033f
From: Jonathon Jongsma <jjongsma@redhat.com>
2c033f
Date: Wed, 19 Nov 2014 10:56:27 -0600
2c033f
Subject: [PATCH 4/4] monitor-manager: check framebuffer limits for all configs
2c033f
2c033f
Refactor make_default_config() to always sanity-check the configuration to
2c033f
ensure that it fits within the framebuffer. Previously, this was only done
2c033f
for the default linear configuration.
2c033f
2c033f
https://bugzilla.redhat.com/show_bug.cgi?id=1166319
2c033f
---
2c033f
 src/backends/meta-monitor-config.c | 21 +++++++++++++--------
2c033f
 1 file changed, 13 insertions(+), 8 deletions(-)
2c033f
2c033f
diff --git a/src/backends/meta-monitor-config.c b/src/backends/meta-monitor-config.c
2c033f
index a65c241..9e15989 100644
2c033f
--- a/src/backends/meta-monitor-config.c
2c033f
+++ b/src/backends/meta-monitor-config.c
2c033f
@@ -1179,10 +1179,6 @@ make_linear_config (MetaMonitorConfig *self,
2c033f
           config->outputs[i].rect.x = x;
2c033f
           x += config->outputs[i].rect.width;
2c033f
         }
2c033f
-
2c033f
-      /* Disable outputs that would go beyond framebuffer limits */
2c033f
-      if (config->outputs[i].rect.x + config->outputs[i].rect.width > max_width)
2c033f
-        config->outputs[i].enabled = FALSE;
2c033f
     }
2c033f
 }
2c033f
 
2c033f
@@ -1263,6 +1259,7 @@ make_default_config (MetaMonitorConfig *self,
2c033f
                      gboolean           use_stored_config)
2c033f
 {
2c033f
   MetaConfiguration *ret = NULL;
2c033f
+  unsigned i;
2c033f
 
2c033f
   ret = g_slice_new (MetaConfiguration);
2c033f
   make_config_key (ret, outputs, n_outputs, -1);
2c033f
@@ -1272,21 +1269,29 @@ make_default_config (MetaMonitorConfig *self,
2c033f
      nothing else to do */
2c033f
   if (n_outputs == 1)
2c033f
     {
2c033f
-
2c033f
       init_config_from_preferred_mode (&ret->outputs[0], &outputs[0]);
2c033f
       ret->outputs[0].is_primary = TRUE;
2c033f
-      return ret;
2c033f
+      goto check_limits;
2c033f
     }
2c033f
 
2c033f
   if (make_suggested_config (self, outputs, n_outputs, max_width, max_height, ret))
2c033f
-      return ret;
2c033f
+      goto check_limits;
2c033f
 
2c033f
   if (use_stored_config &&
2c033f
       extend_stored_config (self, outputs, n_outputs, max_width, max_height, ret))
2c033f
-      return ret;
2c033f
+      goto check_limits;
2c033f
 
2c033f
   make_linear_config (self, outputs, n_outputs, max_width, max_height, ret);
2c033f
 
2c033f
+check_limits:
2c033f
+  /* Disable outputs that would go beyond framebuffer limits */
2c033f
+  for (i = 0; i < n_outputs; i++)
2c033f
+    {
2c033f
+        if ((ret->outputs[i].rect.x + ret->outputs[i].rect.width > max_width)
2c033f
+            || (ret->outputs[i].rect.y + ret->outputs[i].rect.height > max_height))
2c033f
+          ret->outputs[i].enabled = FALSE;
2c033f
+    }
2c033f
+
2c033f
   return ret;
2c033f
 }
2c033f
 
2c033f
-- 
2c033f
2.3.6
2c033f