[mutter] monitor-manager: Find the supported scales from one passed



commit 67eb289a6a6602c088168228a01b9d0794d4847f
Author: Jonas Ådahl <jadahl gmail com>
Date:   Wed Jun 7 17:39:58 2017 +0800

    monitor-manager: Find the supported scales from one passed
    
    When passing scales over D-Bus, we'll loose some precision. To set the
    correct scale, use the configured scale and look up the one actually
    supported by the monitor mode, and use that. To match the supported one
    with the configured one, the difference must be within rounding error
    range.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=765011

 src/backends/meta-monitor-manager.c |  107 +++++++++++++++++++++++++++--------
 1 files changed, 84 insertions(+), 23 deletions(-)
---
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 64c600a..aed4604 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -1884,25 +1884,75 @@ create_monitor_config_from_variant (MetaMonitorManager *manager,
 }
 
 static gboolean
-derive_logical_monitor_size (GList                       *monitor_configs,
-                             int                         *out_width,
-                             int                         *out_height,
-                             double                       scale,
-                             MetaMonitorTransform         transform,
-                             MetaLogicalMonitorLayoutMode layout_mode,
-                             GError                     **error)
+find_monitor_mode_scale (MetaMonitorManager          *manager,
+                         MetaLogicalMonitorLayoutMode layout_mode,
+                         MetaMonitorConfig           *monitor_config,
+                         float                        scale,
+                         float                       *out_scale,
+                         GError                     **error)
 {
-  MetaMonitorConfig *monitor_config;
-  int width, height;
+  MetaMonitorSpec *monitor_spec;
+  MetaMonitor *monitor;
+  MetaMonitorModeSpec *monitor_mode_spec;
+  MetaMonitorMode *monitor_mode;
+  g_autofree float *supported_scales = NULL;
+  int n_supported_scales;
+  int i;
 
-  if (!monitor_configs)
+  monitor_spec = monitor_config->monitor_spec;
+  monitor = meta_monitor_manager_get_monitor_from_spec (manager,
+                                                        monitor_spec);
+  if (!monitor)
     {
       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "Empty logical monitor");
+                   "Monitor not found");
       return FALSE;
     }
 
-  monitor_config = monitor_configs->data;
+  monitor_mode_spec = monitor_config->mode_spec;
+  monitor_mode = meta_monitor_get_mode_from_spec (monitor,
+                                                  monitor_mode_spec);
+  if (!monitor_mode)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Monitor mode not found");
+      return FALSE;
+    }
+
+  supported_scales =
+    meta_monitor_manager_calculate_supported_scales (manager, layout_mode,
+                                                     monitor, monitor_mode,
+                                                     &n_supported_scales);
+
+  for (i = 0; i < n_supported_scales; i++)
+    {
+      float supported_scale = supported_scales[i];
+
+      if (fabsf (supported_scale - scale) < FLT_EPSILON)
+        {
+          *out_scale = supported_scale;
+          return TRUE;
+        }
+    }
+
+  g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+               "Scale %g not valid for resolution %dx%d",
+               scale,
+               monitor_mode_spec->width,
+               monitor_mode_spec->height);
+  return FALSE;
+}
+
+static gboolean
+derive_logical_monitor_size (MetaMonitorConfig           *monitor_config,
+                             int                         *out_width,
+                             int                         *out_height,
+                             float                        scale,
+                             MetaMonitorTransform         transform,
+                             MetaLogicalMonitorLayoutMode layout_mode,
+                             GError                     **error)
+{
+  int width, height;
 
   if (meta_monitor_transform_is_rotated (transform))
     {
@@ -1918,14 +1968,6 @@ derive_logical_monitor_size (GList                       *monitor_configs,
   switch (layout_mode)
     {
     case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL:
-      if (fmodf (width, scale) != 0.0 || fmodf (height, scale) != 0.0)
-        {
-          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                       "Scale %g not valid for resolution %dx%d",
-                       scale, width, height);
-          return FALSE;
-        }
-
       width /= scale;
       height /= scale;
       break;
@@ -1947,19 +1989,22 @@ create_logical_monitor_config_from_variant (MetaMonitorManager          *manager
 {
   MetaLogicalMonitorConfig *logical_monitor_config;
   int x, y, width, height;
-  double scale;
+  double scale_d;
+  float scale;
   MetaMonitorTransform transform;
   gboolean is_primary;
   GVariantIter *monitor_configs_iter;
   GList *monitor_configs = NULL;
+  MetaMonitorConfig *monitor_config;
 
   g_variant_get (logical_monitor_config_variant, LOGICAL_MONITOR_CONFIG_FORMAT,
                  &x,
                  &y,
-                 &scale,
+                 &scale_d,
                  &transform,
                  &is_primary,
                  &monitor_configs_iter);
+  scale = (float) scale_d;
 
   while (TRUE)
     {
@@ -1986,7 +2031,23 @@ create_logical_monitor_config_from_variant (MetaMonitorManager          *manager
     }
   g_variant_iter_free (monitor_configs_iter);
 
-  if (!derive_logical_monitor_size (monitor_configs, &width, &height,
+  if (!monitor_configs)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Empty logical monitor");
+      goto err;
+    }
+
+  monitor_config = monitor_configs->data;
+  if (!find_monitor_mode_scale (manager,
+                                layout_mode,
+                                monitor_config,
+                                scale,
+                                &scale,
+                                error))
+    goto err;
+
+  if (!derive_logical_monitor_size (monitor_config, &width, &height,
                                     scale, transform, layout_mode, error))
     goto err;
 


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