[mutter] monitor-manager: Make max screen size optional



commit f25f14351c10e999f22a7c7ad172d5f0b8f2101e
Author: Jonas Ådahl <jadahl gmail com>
Date:   Wed Feb 15 16:06:46 2017 +0800

    monitor-manager: Make max screen size optional
    
    Make the concept of maximum screen size optional, as it is not
    necessarily a thing on all systems (e.g. when using the native backend
    and stage views).
    
    The meta_monitor_monitor_get_limits() function is replaced by a
    meta_monitor_manager_get_max_screen_size() which fails when no screen
    limit is available. Callers and other users of the previous max screen
    size fields are updated to deal with the fact that the limit is
    optional.
    
    The new D-Bus API is changed to move it to the properties bag, where
    its absence means there is no applicable limit.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=777732

 src/backends/meta-monitor-config.c             |    7 ++-
 src/backends/meta-monitor-manager-dummy.c      |   19 +++++-
 src/backends/meta-monitor-manager-private.h    |   14 ++--
 src/backends/meta-monitor-manager.c            |   83 +++++++++++++++++-------
 src/backends/native/meta-monitor-manager-kms.c |   25 ++++++-
 src/backends/x11/meta-monitor-manager-xrandr.c |   22 ++++++-
 src/org.gnome.Mutter.DisplayConfig.xml         |    9 +--
 src/tests/meta-monitor-manager-test.c          |   19 +++++-
 8 files changed, 150 insertions(+), 48 deletions(-)
---
diff --git a/src/backends/meta-monitor-config.c b/src/backends/meta-monitor-config.c
index ced2336..063a3da 100644
--- a/src/backends/meta-monitor-config.c
+++ b/src/backends/meta-monitor-config.c
@@ -1460,7 +1460,12 @@ meta_monitor_config_make_default (MetaMonitorConfig  *self,
   gboolean use_stored_config;
 
   outputs = meta_monitor_manager_get_outputs (manager, &n_outputs);
-  meta_monitor_manager_get_screen_limits (manager, &max_width, &max_height);
+  if (!meta_monitor_manager_get_max_screen_size (manager, &max_width, &max_height))
+    {
+      /* No max screen size, just pretend it's something large. */
+      max_width = 65535;
+      max_height = 65535;
+    }
 
   if (n_outputs == 0)
     {
diff --git a/src/backends/meta-monitor-manager-dummy.c b/src/backends/meta-monitor-manager-dummy.c
index f5b993f..8c8134b 100644
--- a/src/backends/meta-monitor-manager-dummy.c
+++ b/src/backends/meta-monitor-manager-dummy.c
@@ -30,6 +30,7 @@
 #include <stdlib.h>
 
 #include <meta/util.h>
+#include "backends/meta-backend-private.h"
 #include "backends/meta-monitor-config-manager.h"
 
 #define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
@@ -324,9 +325,6 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
   tiled_monitors_str = g_getenv ("MUTTER_DEBUG_TILED_DUMMY_MONITORS");
   tiled_monitors = g_strcmp0 (tiled_monitors_str, "1") == 0;
 
-  manager->max_screen_width = 65535;
-  manager->max_screen_height = 65535;
-
   modes = g_array_sized_new (FALSE, TRUE, sizeof (MetaCrtcMode), MAX_MODES);
   crtcs = g_array_sized_new (FALSE, TRUE, sizeof (MetaCrtc), MAX_CRTCS);
   outputs = g_array_sized_new (FALSE, TRUE, sizeof (MetaOutput), MAX_OUTPUTS);
@@ -613,6 +611,20 @@ meta_monitor_manager_dummy_get_capabilities (MetaMonitorManager *manager)
   return META_MONITOR_MANAGER_CAPABILITY_MIRRORING;
 }
 
+static gboolean
+meta_monitor_manager_dummy_get_max_screen_size (MetaMonitorManager *manager,
+                                                int                *max_width,
+                                                int                *max_height)
+{
+  if (meta_is_stage_views_enabled ())
+    return FALSE;
+
+  *max_width = 65535;
+  *max_height = 65535;
+
+  return TRUE;
+}
+
 static void
 meta_monitor_manager_dummy_class_init (MetaMonitorManagerDummyClass *klass)
 {
@@ -626,6 +638,7 @@ meta_monitor_manager_dummy_class_init (MetaMonitorManagerDummyClass *klass)
   manager_class->calculate_monitor_mode_scale = meta_monitor_manager_dummy_calculate_monitor_mode_scale;
   manager_class->get_supported_scales = meta_monitor_manager_dummy_get_supported_scales;
   manager_class->get_capabilities = meta_monitor_manager_dummy_get_capabilities;
+  manager_class->get_max_screen_size = meta_monitor_manager_dummy_get_max_screen_size;
 }
 
 static void
diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h
index ade2c60..1e0e611 100644
--- a/src/backends/meta-monitor-manager-private.h
+++ b/src/backends/meta-monitor-manager-private.h
@@ -274,8 +274,6 @@ struct _MetaMonitorManager
 
   MetaPowerSave power_save_mode;
 
-  int max_screen_width;
-  int max_screen_height;
   int screen_width;
   int screen_height;
 
@@ -374,6 +372,10 @@ struct _MetaMonitorManagerClass
                                 int                *);
 
   MetaMonitorManagerCapability (*get_capabilities) (MetaMonitorManager *);
+
+  gboolean (*get_max_screen_size) (MetaMonitorManager *,
+                                   int                *,
+                                   int                *);
 };
 
 void                meta_monitor_manager_rebuild (MetaMonitorManager *manager,
@@ -424,10 +426,6 @@ void                meta_monitor_manager_get_screen_size   (MetaMonitorManager *
                                                             int                *width,
                                                             int                *height);
 
-void                meta_monitor_manager_get_screen_limits (MetaMonitorManager *manager,
-                                                            int                *width,
-                                                            int                *height);
-
 void                meta_monitor_manager_apply_configuration (MetaMonitorManager  *manager,
                                                               MetaCrtcInfo       **crtcs,
                                                               unsigned int         n_crtcs,
@@ -477,6 +475,10 @@ int                meta_monitor_manager_calculate_monitor_mode_scale (MetaMonito
                                                                       MetaMonitor        *monitor,
                                                                       MetaMonitorMode    *monitor_mode);
 
+gboolean           meta_monitor_manager_get_max_screen_size (MetaMonitorManager *manager,
+                                                             int                *max_width,
+                                                             int                *max_height);
+
 void meta_monitor_manager_clear_output (MetaOutput *output);
 void meta_monitor_manager_clear_mode (MetaCrtcMode *mode);
 void meta_monitor_manager_clear_crtc (MetaCrtc *crtc);
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 64a45b6..4513bc0 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -308,6 +308,17 @@ meta_monitor_manager_get_capabilities (MetaMonitorManager *manager)
   return manager_class->get_capabilities (manager);
 }
 
+gboolean
+meta_monitor_manager_get_max_screen_size (MetaMonitorManager *manager,
+                                          int                *max_width,
+                                          int                *max_height)
+{
+  MetaMonitorManagerClass *manager_class =
+    META_MONITOR_MANAGER_GET_CLASS (manager);
+
+  return manager_class->get_max_screen_size (manager, max_width, max_height);
+}
+
 static void
 meta_monitor_manager_ensure_initial_config (MetaMonitorManager *manager)
 {
@@ -760,6 +771,8 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
   MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_GET_CLASS (skeleton);
   GVariantBuilder crtc_builder, output_builder, mode_builder;
   unsigned int i, j;
+  int max_screen_width;
+  int max_screen_height;
 
   g_variant_builder_init (&crtc_builder, G_VARIANT_TYPE ("a(uxiiiiiuaua{sv})"));
   g_variant_builder_init (&output_builder, G_VARIANT_TYPE ("a(uxiausauaua{sv})"));
@@ -896,14 +909,23 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
                              (guint32)mode->flags);
     }
 
+  if (!meta_monitor_manager_get_max_screen_size (manager,
+                                                 &max_screen_width,
+                                                 &max_screen_height))
+    {
+      /* No max screen size, just send something large */
+      max_screen_width = 65535;
+      max_screen_height = 65535;
+    }
+
   meta_dbus_display_config_complete_get_resources (skeleton,
                                                    invocation,
                                                    manager->serial,
                                                    g_variant_builder_end (&crtc_builder),
                                                    g_variant_builder_end (&output_builder),
                                                    g_variant_builder_end (&mode_builder),
-                                                   manager->max_screen_width,
-                                                   manager->max_screen_height);
+                                                   max_screen_width,
+                                                   max_screen_height);
   return TRUE;
 }
 
@@ -1053,6 +1075,7 @@ meta_monitor_manager_legacy_handle_apply_configuration  (MetaDBusDisplayConfig *
       if (mode)
         {
           int width, height;
+          int max_screen_width, max_screen_height;
 
           if (meta_monitor_transform_is_rotated (transform))
             {
@@ -1065,10 +1088,7 @@ meta_monitor_manager_legacy_handle_apply_configuration  (MetaDBusDisplayConfig *
               height = mode->height;
             }
 
-          if (x < 0 ||
-              x + width > manager->max_screen_width ||
-              y < 0 ||
-              y + height > manager->max_screen_height)
+          if (x < 0 || y < 0)
             {
               g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                                      G_DBUS_ERROR_INVALID_ARGS,
@@ -1076,6 +1096,20 @@ meta_monitor_manager_legacy_handle_apply_configuration  (MetaDBusDisplayConfig *
               return TRUE;
             }
 
+          if (meta_monitor_manager_get_max_screen_size (manager,
+                                                        &max_screen_width,
+                                                        &max_screen_height))
+            {
+              if (x + width > max_screen_width ||
+                  y + height > max_screen_height)
+                {
+                  g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+                                                         G_DBUS_ERROR_INVALID_ARGS,
+                                                         "Invalid CRTC geometry");
+                  return TRUE;
+                }
+            }
+
           new_screen_width = MAX (new_screen_width, x + width);
           new_screen_height = MAX (new_screen_height, y + height);
           crtc_info->x = x;
@@ -1240,13 +1274,13 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton,
   GVariantBuilder monitors_builder;
   GVariantBuilder logical_monitors_builder;
   GVariantBuilder supported_scales_builder;
-  GVariantBuilder max_screen_size_builder;
   GVariantBuilder properties_builder;
   GList *l;
   float *supported_scales;
   int n_supported_scales;
   int i;
   MetaMonitorManagerCapability capabilities;
+  int max_screen_width, max_screen_height;
 
   g_variant_builder_init (&monitors_builder,
                           G_VARIANT_TYPE (MONITORS_FORMAT));
@@ -1351,13 +1385,6 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton,
   for (i = 0; i < n_supported_scales; i++)
     g_variant_builder_add (&supported_scales_builder, "d", supported_scales[i]);
 
-  g_variant_builder_init (&max_screen_size_builder,
-                          G_VARIANT_TYPE ("(ii)"));
-  g_variant_builder_add (&max_screen_size_builder, "i",
-                         manager->max_screen_width);
-  g_variant_builder_add (&max_screen_size_builder, "i",
-                         manager->max_screen_height);
-
   g_variant_builder_init (&properties_builder, G_VARIANT_TYPE ("a{sv}"));
   capabilities = meta_monitor_manager_get_capabilities (manager);
   if ((capabilities & META_MONITOR_MANAGER_CAPABILITY_MIRRORING) == 0)
@@ -1367,6 +1394,24 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton,
                              g_variant_new_boolean (FALSE));
     }
 
+  if (meta_monitor_manager_get_max_screen_size (manager,
+                                                &max_screen_width,
+                                                &max_screen_height))
+    {
+      GVariantBuilder max_screen_size_builder;
+
+      g_variant_builder_init (&max_screen_size_builder,
+                              G_VARIANT_TYPE ("(ii)"));
+      g_variant_builder_add (&max_screen_size_builder, "i",
+                             max_screen_width);
+      g_variant_builder_add (&max_screen_size_builder, "i",
+                             max_screen_height);
+
+      g_variant_builder_add (&properties_builder, "{sv}",
+                             "max_screen_size",
+                             g_variant_builder_end (&max_screen_size_builder));
+    }
+
   meta_dbus_display_config_complete_get_current_state (
     skeleton,
     invocation,
@@ -1374,7 +1419,6 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton,
     g_variant_builder_end (&monitors_builder),
     g_variant_builder_end (&logical_monitors_builder),
     g_variant_builder_end (&supported_scales_builder),
-    g_variant_builder_end (&max_screen_size_builder),
     g_variant_builder_end (&properties_builder));
 
   return TRUE;
@@ -2213,15 +2257,6 @@ meta_monitor_manager_get_screen_size (MetaMonitorManager *manager,
   *height = manager->screen_height;
 }
 
-void
-meta_monitor_manager_get_screen_limits (MetaMonitorManager *manager,
-                                        int                *width,
-                                        int                *height)
-{
-  *width = manager->max_screen_width;
-  *height = manager->max_screen_height;
-}
-
 static void
 rebuild_monitors (MetaMonitorManager *manager)
 {
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index 92be434..a000a7e 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -118,6 +118,9 @@ struct _MetaMonitorManagerKms
   GSettings *desktop_settings;
 
   gboolean page_flips_not_supported;
+
+  int max_buffer_width;
+  int max_buffer_height;
 };
 
 struct _MetaMonitorManagerKmsClass
@@ -1119,9 +1122,8 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
 
   resources = drmModeGetResources (manager_kms->fd);
 
-  /* TODO: max screen width only matters for stage views is not enabled. */
-  manager->max_screen_width = resources->max_width;
-  manager->max_screen_height = resources->max_height;
+  manager_kms->max_buffer_width = resources->max_width;
+  manager_kms->max_buffer_height = resources->max_height;
 
   manager->power_save_mode = META_POWER_SAVE_ON;
 
@@ -1949,6 +1951,22 @@ meta_monitor_manager_kms_get_capabilities (MetaMonitorManager *manager)
   return capabilities;
 }
 
+static gboolean
+meta_monitor_manager_kms_get_max_screen_size (MetaMonitorManager *manager,
+                                              int                *max_width,
+                                              int                *max_height)
+{
+  MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
+
+  if (meta_is_stage_views_enabled ())
+    return FALSE;
+
+  *max_width = manager_kms->max_buffer_width;
+  *max_height = manager_kms->max_buffer_height;
+
+  return TRUE;
+}
+
 static void
 meta_monitor_manager_kms_dispose (GObject *object)
 {
@@ -1992,4 +2010,5 @@ meta_monitor_manager_kms_class_init (MetaMonitorManagerKmsClass *klass)
   manager_class->calculate_monitor_mode_scale = meta_monitor_manager_kms_calculate_monitor_mode_scale;
   manager_class->get_supported_scales = meta_monitor_manager_kms_get_supported_scales;
   manager_class->get_capabilities = meta_monitor_manager_kms_get_capabilities;
+  manager_class->get_max_screen_size = meta_monitor_manager_kms_get_max_screen_size;
 }
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index d0e5209..4083e08 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -69,6 +69,9 @@ struct _MetaMonitorManagerXrandr
 #ifdef HAVE_XRANDR15
   GHashTable *tiled_monitor_atoms;
 #endif /* HAVE_XRANDR15 */
+
+  int max_screen_width;
+  int max_screen_height;
 };
 
 struct _MetaMonitorManagerXrandrClass
@@ -773,8 +776,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
   XRRGetScreenSizeRange (manager_xrandr->xdisplay, DefaultRootWindow (manager_xrandr->xdisplay),
                         &min_width,
                         &min_height,
-                        &manager->max_screen_width,
-                        &manager->max_screen_height);
+                        &manager_xrandr->max_screen_width,
+                        &manager_xrandr->max_screen_height);
 
   screen = ScreenOfDisplay (manager_xrandr->xdisplay,
                            DefaultScreen (manager_xrandr->xdisplay));
@@ -1606,6 +1609,20 @@ meta_monitor_manager_xrandr_get_capabilities (MetaMonitorManager *manager)
   return META_MONITOR_MANAGER_CAPABILITY_MIRRORING;
 }
 
+static gboolean
+meta_monitor_manager_xrandr_get_max_screen_size (MetaMonitorManager *manager,
+                                                 int                *max_width,
+                                                 int                *max_height)
+{
+  MetaMonitorManagerXrandr *manager_xrandr =
+    META_MONITOR_MANAGER_XRANDR (manager);
+
+  *max_width = manager_xrandr->max_screen_width;
+  *max_height = manager_xrandr->max_screen_height;
+
+  return TRUE;
+}
+
 static void
 meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
 {
@@ -1685,6 +1702,7 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
   manager_class->calculate_monitor_mode_scale = meta_monitor_manager_xrandr_calculate_monitor_mode_scale;
   manager_class->get_supported_scales = meta_monitor_manager_xrandr_get_supported_scales;
   manager_class->get_capabilities = meta_monitor_manager_xrandr_get_capabilities;
+  manager_class->get_max_screen_size = meta_monitor_manager_xrandr_get_max_screen_size;
 
   quark_meta_monitor_xrandr_data =
     g_quark_from_static_string ("-meta-monitor-xrandr-data");
diff --git a/src/org.gnome.Mutter.DisplayConfig.xml b/src/org.gnome.Mutter.DisplayConfig.xml
index 43ffb28..2c623c6 100644
--- a/src/org.gnome.Mutter.DisplayConfig.xml
+++ b/src/org.gnome.Mutter.DisplayConfig.xml
@@ -297,7 +297,6 @@
        @monitors: available monitors
        @logical_monitors: current logical monitor configuration
        @supported_scales: scaling factors supported by the display server
-       @max_screen_size: the maximum screen size
        @properties: display configuration properties
 
        @monitors represent connected physical monitors
@@ -318,6 +317,9 @@
            - "is_underscanning" (b): whether underscanning is enabled
                                      (absence of this means underscanning
                                      not being supported)
+           - "max_screen_size" (ii): the maximum size a screen may have
+                                     (absence of this means unlimited screen
+                                     size)
 
         Possible mode flags:
          1 : preferred mode
@@ -338,10 +340,6 @@
        * a{sv} properties: possibly other properties
 
 
-       @max_screen_size represents the maximum size the screen may have, or 0x0 if no
-       such limit is known.
-
-
        @supported_scales is an ordered list of floating point numbers representing
        scale factors of logical monitors supported by the display server.
 
@@ -356,7 +354,6 @@
       <arg name="monitors" direction="out" type="a((ssss)a(iiddu)a{sv})" />
       <arg name="logical_monitors" direction="out" type="a(iidba(ssss)a{sv})" />
       <arg name="supported_scales" direction="out" type="ad" />
-      <arg name="max_screen_size" direction="out" type="(ii)" />
       <arg name="properties" direction="out" type="a{sv}" />
     </method>
 
diff --git a/src/tests/meta-monitor-manager-test.c b/src/tests/meta-monitor-manager-test.c
index 292abe7..6925365 100644
--- a/src/tests/meta-monitor-manager-test.c
+++ b/src/tests/meta-monitor-manager-test.c
@@ -21,6 +21,7 @@
 
 #include "tests/meta-monitor-manager-test.h"
 
+#include "backends/meta-backend-private.h"
 #include "backends/meta-monitor-config-manager.h"
 
 static float supported_scales_test[] = {
@@ -84,9 +85,6 @@ meta_monitor_manager_test_read_current (MetaMonitorManager *manager)
 {
   MetaMonitorManagerTest *manager_test = META_MONITOR_MANAGER_TEST (manager);
 
-  manager->max_screen_width = 65535;
-  manager->max_screen_height = 65535;
-
   g_assert (manager_test->test_setup);
 
   manager->modes = manager_test->test_setup->modes;
@@ -388,6 +386,20 @@ meta_monitor_manager_test_get_capabilities (MetaMonitorManager *manager)
   return META_MONITOR_MANAGER_CAPABILITY_MIRRORING;
 }
 
+static gboolean
+meta_monitor_manager_test_get_max_screen_size (MetaMonitorManager *manager,
+                                               int                *max_width,
+                                               int                *max_height)
+{
+  if (meta_is_stage_views_enabled ())
+    return FALSE;
+
+  *max_width = 65535;
+  *max_height = 65535;
+
+  return TRUE;
+}
+
 static void
 meta_monitor_manager_test_dispose (GObject *object)
 {
@@ -423,4 +435,5 @@ meta_monitor_manager_test_class_init (MetaMonitorManagerTestClass *klass)
   manager_class->calculate_monitor_mode_scale = meta_monitor_manager_test_calculate_monitor_mode_scale;
   manager_class->get_supported_scales = meta_monitor_manager_test_get_supported_scales;
   manager_class->get_capabilities = meta_monitor_manager_test_get_capabilities;
+  manager_class->get_max_screen_size = meta_monitor_manager_test_get_max_screen_size;
 }


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