[mutter] monitor-manager: Generate logical monitors from monitors



commit bf8b4e9927f7dd2902d4cc88d6f71c40d233a14b
Author: Jonas Ådahl <jadahl gmail com>
Date:   Tue Dec 13 11:03:22 2016 +0800

    monitor-manager: Generate logical monitors from monitors
    
    Instead of using crtcs and outputs to generate logical monitors, use
    the ready made monitor abstraction that hides irrelevant things such as
    monitor tiling etc.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=777732

 src/backends/meta-logical-monitor.c |   99 +++++++++++++++
 src/backends/meta-logical-monitor.h |   17 +++-
 src/backends/meta-monitor-manager.c |  234 ++++++++---------------------------
 src/backends/meta-monitor.c         |   12 ++-
 src/backends/meta-monitor.h         |    4 +
 5 files changed, 181 insertions(+), 185 deletions(-)
---
diff --git a/src/backends/meta-logical-monitor.c b/src/backends/meta-logical-monitor.c
index 19ca43d..a386537 100644
--- a/src/backends/meta-logical-monitor.c
+++ b/src/backends/meta-logical-monitor.c
@@ -25,6 +25,105 @@
 
 G_DEFINE_TYPE (MetaLogicalMonitor, meta_logical_monitor, G_TYPE_OBJECT)
 
+MetaLogicalMonitor *
+meta_logical_monitor_new (MetaMonitor *monitor,
+                          int          x,
+                          int          y,
+                          int          number)
+{
+  MetaLogicalMonitor *logical_monitor;
+  MetaOutput *main_output;
+  GList *outputs;
+  GList *l;
+  gboolean is_presentation;
+  int i;
+
+  g_assert (meta_monitor_is_active (monitor));
+
+  logical_monitor = g_object_new (META_TYPE_LOGICAL_MONITOR, NULL);
+
+  main_output = meta_monitor_get_main_output (monitor);
+  logical_monitor->number = number;
+  logical_monitor->refresh_rate = main_output->crtc->current_mode->refresh_rate;
+  logical_monitor->width_mm = main_output->width_mm;
+  logical_monitor->height_mm = main_output->height_mm;
+  logical_monitor->winsys_id = main_output->winsys_id;
+  logical_monitor->scale = main_output->scale;
+  logical_monitor->in_fullscreen = -1;
+
+  logical_monitor->rect.x = x;
+  logical_monitor->rect.y = y;
+  meta_monitor_get_dimensions (monitor,
+                               &logical_monitor->rect.width,
+                               &logical_monitor->rect.height);
+
+  is_presentation = TRUE;
+  outputs = meta_monitor_get_outputs (monitor);
+  for (l = outputs, i = 0; l; l = l->next, i++)
+    {
+      MetaOutput *output = l->data;
+
+      output->crtc->logical_monitor = logical_monitor;
+
+      if (i <= META_MAX_OUTPUTS_PER_MONITOR)
+        logical_monitor->outputs[i] = output;
+      else
+        g_warning ("Couldn't add all outputs to monitor");
+
+      is_presentation = is_presentation && output->is_presentation;
+    }
+  logical_monitor->n_outputs = MIN (i, META_MAX_OUTPUTS_PER_MONITOR);
+  logical_monitor->is_presentation = is_presentation;
+
+  logical_monitor->monitors = g_list_append (logical_monitor->monitors,
+                                             monitor);
+
+  return logical_monitor;
+}
+
+void
+meta_logical_monitor_add_monitor (MetaLogicalMonitor *logical_monitor,
+                                  MetaMonitor        *monitor)
+{
+  GList *outputs;
+  GList *l;
+  gboolean is_presentation;
+  int i;
+
+  is_presentation = logical_monitor->is_presentation;
+  logical_monitor->monitors = g_list_append (logical_monitor->monitors,
+                                             monitor);
+
+  outputs = meta_monitor_get_outputs (monitor);
+  for (l = outputs, i = logical_monitor->n_outputs; l; l = l->next, i++)
+    {
+      MetaOutput *output = l->data;
+
+      output->crtc->logical_monitor = logical_monitor;
+
+      if (i <= META_MAX_OUTPUTS_PER_MONITOR)
+        logical_monitor->outputs[i] = output;
+      else
+        g_warning ("Couldn't add all outputs to monitor");
+
+      is_presentation = is_presentation && output->is_presentation;
+    }
+  logical_monitor->n_outputs = MIN (i, META_MAX_OUTPUTS_PER_MONITOR);
+  logical_monitor->is_presentation = is_presentation;
+}
+
+gboolean
+meta_logical_monitor_is_primary (MetaLogicalMonitor *logical_monitor)
+{
+  return logical_monitor->is_primary;
+}
+
+void
+meta_logical_monitor_make_primary (MetaLogicalMonitor *logical_monitor)
+{
+  logical_monitor->is_primary = TRUE;
+}
+
 static void
 meta_logical_monitor_init (MetaLogicalMonitor *logical_monitor)
 {
diff --git a/src/backends/meta-logical-monitor.h b/src/backends/meta-logical-monitor.h
index 42002bc..543f35b 100644
--- a/src/backends/meta-logical-monitor.h
+++ b/src/backends/meta-logical-monitor.h
@@ -24,6 +24,7 @@
 
 #include <glib-object.h>
 
+#include "backends/meta-monitor.h"
 #include "backends/meta-monitor-manager-private.h"
 #include "meta/boxes.h"
 
@@ -54,11 +55,11 @@ struct _MetaLogicalMonitor
   */
   glong winsys_id;
 
-  guint32 tile_group_id;
-
   int monitor_winsys_xid;
   int n_outputs;
   MetaOutput *outputs[META_MAX_OUTPUTS_PER_MONITOR];
+
+  GList *monitors;
 };
 
 #define META_TYPE_LOGICAL_MONITOR (meta_logical_monitor_get_type ())
@@ -66,4 +67,16 @@ G_DECLARE_FINAL_TYPE (MetaLogicalMonitor, meta_logical_monitor,
                       META, LOGICAL_MONITOR,
                       GObject)
 
+MetaLogicalMonitor * meta_logical_monitor_new (MetaMonitor *monitor,
+                                               int          x,
+                                               int          y,
+                                               int          number);
+
+void meta_logical_monitor_add_monitor (MetaLogicalMonitor *logical_monitor,
+                                       MetaMonitor        *monitor);
+
+gboolean meta_logical_monitor_is_primary (MetaLogicalMonitor *logical_monitor);
+
+void meta_logical_monitor_make_primary (MetaLogicalMonitor *logical_monitor);
+
 #endif /* META_LOGICAL_MONITOR_H */
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 14dd503..98dd7de 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -73,227 +73,94 @@ meta_monitor_manager_init (MetaMonitorManager *manager)
 {
 }
 
+static void
+meta_monitor_manager_set_primary_logical_monitor (MetaMonitorManager *manager,
+                                                  MetaLogicalMonitor *logical_monitor)
+{
+  manager->primary_logical_monitor = logical_monitor;
+  if (logical_monitor)
+    meta_logical_monitor_make_primary (logical_monitor);
+}
+
 static gboolean
 is_main_tiled_monitor_output (MetaOutput *output)
 {
   return output->tile_info.loc_h_tile == 0 && output->tile_info.loc_v_tile == 0;
 }
 
-static void
-calculate_tiled_monitor_size (MetaMonitorManager *manager,
-                              uint32_t            tile_group_id,
-                              int                *out_width,
-                              int                *out_height)
+static MetaLogicalMonitor *
+logical_monitor_from_layout (MetaMonitorManager *manager,
+                             GList              *logical_monitors,
+                             MetaRectangle      *layout)
 {
-  int width, height;
-  unsigned int i;
+  GList *l;
 
-  width = 0;
-  height = 0;
-  for (i = 0; i < manager->n_outputs; i++)
+  for (l = logical_monitors; l; l = l->next)
     {
-      MetaOutput *output = &manager->outputs[i];
-
-      if (output->tile_info.group_id != tile_group_id)
-        continue;
-
-      if (output->tile_info.loc_v_tile == 0)
-        width += output->tile_info.tile_w;
+      MetaLogicalMonitor *logical_monitor = l->data;
 
-      if (output->tile_info.loc_h_tile == 0)
-        height += output->tile_info.tile_h;
+      if (meta_rectangle_equal (layout, &logical_monitor->rect))
+        return logical_monitor;
     }
 
-  *out_width = width;
-  *out_height = height;
+  return NULL;
 }
 
 static void
-add_tiled_monitor_outputs (MetaMonitorManager *manager,
-                           MetaLogicalMonitor *logical_monitor,
-                           uint32_t            tile_group_id)
+derive_monitor_position (MetaMonitor *monitor,
+                         int         *x,
+                         int         *y)
 {
-  unsigned int i;
+  MetaOutput *main_output;
 
-  for (i = 0; i < manager->n_outputs; i++)
-    {
-      MetaOutput *output = &manager->outputs[i];
+  main_output = meta_monitor_get_main_output (monitor);
 
-      if (output->tile_info.group_id != tile_group_id)
-        continue;
-
-      if (logical_monitor->n_outputs > META_MAX_OUTPUTS_PER_MONITOR)
-        {
-          g_warning ("Couldn't add all outputs to monitor");
-          return;
-        }
-
-      logical_monitor->outputs[logical_monitor->n_outputs] = output;
-      logical_monitor->n_outputs++;
-    }
-}
-
-static MetaLogicalMonitor *
-construct_tile_monitor (MetaMonitorManager *manager,
-                        MetaOutput         *output,
-                        int                 monitor_number)
-{
-  MetaLogicalMonitor *logical_monitor = NULL;
-
-  logical_monitor = g_object_new (META_TYPE_LOGICAL_MONITOR, NULL);
-
-  logical_monitor->tile_group_id = output->tile_info.group_id;
-  logical_monitor->refresh_rate = output->crtc->current_mode->refresh_rate;
-  logical_monitor->width_mm = output->width_mm;
-  logical_monitor->height_mm = output->height_mm;
-  logical_monitor->winsys_id = output->winsys_id;
-
-  logical_monitor->scale = output->scale;
-  logical_monitor->rect.x = output->crtc->rect.x;
-  logical_monitor->rect.y = output->crtc->rect.y;
-  calculate_tiled_monitor_size (manager, output->tile_info.group_id,
-                                &logical_monitor->rect.width,
-                                &logical_monitor->rect.height);
-
-  add_tiled_monitor_outputs (manager, logical_monitor,
-                             output->tile_info.group_id);
-
-  return logical_monitor;
+  *x = main_output->crtc->rect.x;
+  *y = main_output->crtc->rect.y;
 }
 
-/*
- * make_logical_config:
- *
- * Turn outputs and CRTCs into logical MetaLogicalMonitor,
- * that will be used by the core and API layer (MetaScreen
- * and friends)
- */
 static void
 make_logical_config (MetaMonitorManager *manager)
 {
   MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_GET_CLASS (manager);
   GList *logical_monitors = NULL;
+  GList *l;
   int monitor_number;
-  unsigned int i;
+  MetaLogicalMonitor *primary_logical_monitor = NULL;
 
   monitor_number = 0;
 
-  /* Walk the list of MetaCrtcs, and build a MetaLogicalMonitor
-     for each of them, unless they reference a rectangle that
-     is already there.
-  */
-  /* for tiling we need to work out how many tiled outputs there are */
-  for (i = 0; i < manager->n_outputs; i++)
+  for (l = manager->monitors; l; l = l->next)
     {
-      MetaOutput *output = &manager->outputs[i];
-
-      if (!output->crtc)
-        continue;
-
-      if (!output->tile_info.group_id)
-        continue;
-
-      if (is_main_tiled_monitor_output (output))
-        {
-          MetaLogicalMonitor *logical_monitor;
-
-          logical_monitor = construct_tile_monitor (manager,
-                                                    output,
-                                                    monitor_number);
-
-          logical_monitors = g_list_append (logical_monitors, logical_monitor);
-          monitor_number++;
-        }
-    }
-
-  for (i = 0; i < manager->n_crtcs; i++)
-    {
-      MetaCrtc *crtc = &manager->crtcs[i];
-      GList *l;
+      MetaMonitor *monitor = l->data;
+      MetaLogicalMonitor *logical_monitor;
+      MetaRectangle layout;
 
-      /* Ignore CRTCs not in use */
-      if (crtc->current_mode == NULL)
+      if (!meta_monitor_is_active (monitor))
         continue;
 
-      for (l = logical_monitors; l; l = l->next)
+      derive_monitor_position (monitor, &layout.x, &layout.y);
+      meta_monitor_get_dimensions (monitor, &layout.width, &layout.height);
+      logical_monitor = logical_monitor_from_layout (manager, logical_monitors,
+                                                     &layout);
+      if (logical_monitor)
         {
-          MetaLogicalMonitor *logical_monitor = l->data;
-
-          if (meta_rectangle_contains_rect (&logical_monitor->rect,
-                                            &crtc->rect))
-            {
-              crtc->logical_monitor = logical_monitor;
-              break;
-            }
+          meta_logical_monitor_add_monitor (logical_monitor, monitor);
         }
-
-      if (crtc->logical_monitor == NULL)
+      else
         {
-          MetaLogicalMonitor *logical_monitor;
-
-          logical_monitor = g_object_new (META_TYPE_LOGICAL_MONITOR, NULL);
-
-          logical_monitor->number = monitor_number;
-          logical_monitor->rect = crtc->rect;
-          logical_monitor->refresh_rate = crtc->current_mode->refresh_rate;
-          logical_monitor->scale = 1;
-          logical_monitor->is_primary = FALSE;
-          /* This starts true because we want
-             is_presentation only if all outputs are
-             marked as such (while for primary it's enough
-             that any is marked)
-          */
-          logical_monitor->is_presentation = TRUE;
-          logical_monitor->in_fullscreen = -1;
+          int x, y;
 
+          derive_monitor_position (monitor, &x, &y);
+          logical_monitor = meta_logical_monitor_new (monitor,
+                                                      x, y,
+                                                      monitor_number);
           logical_monitors = g_list_append (logical_monitors, logical_monitor);
           monitor_number++;
-
-          crtc->logical_monitor = logical_monitor;
         }
-    }
-
-  /* Now walk the list of outputs applying extended properties (primary
-     and presentation)
-  */
-  manager->primary_logical_monitor = NULL;
-  for (i = 0; i < manager->n_outputs; i++)
-    {
-      MetaOutput *output;
-      MetaLogicalMonitor *logical_monitor;
-
-      output = &manager->outputs[i];
-
-      /* Ignore outputs that are not active */
-      if (output->crtc == NULL)
-        continue;
 
-      if (output->tile_info.group_id)
-        continue;
-
-      /* We must have a logical monitor on every CRTC at this point */
-      g_assert (output->crtc->logical_monitor != NULL);
-
-      logical_monitor = output->crtc->logical_monitor;
-
-      logical_monitor->is_primary =
-        logical_monitor->is_primary || output->is_primary;
-      logical_monitor->is_presentation =
-        logical_monitor->is_presentation && output->is_presentation;
-
-      logical_monitor->width_mm = output->width_mm;
-      logical_monitor->height_mm = output->height_mm;
-
-      logical_monitor->outputs[0] = output;
-      logical_monitor->n_outputs = 1;
-
-      logical_monitor->scale = output->scale;
-
-      if (output->is_primary || logical_monitor->winsys_id == 0)
-        logical_monitor->winsys_id = output->winsys_id;
-
-      if (logical_monitor->is_primary)
-        manager->primary_logical_monitor = logical_monitor;
+      if (meta_monitor_is_primary (monitor))
+        primary_logical_monitor = logical_monitor;
     }
 
   manager->logical_monitors = logical_monitors;
@@ -302,8 +169,11 @@ make_logical_config (MetaMonitorManager *manager)
    * If no monitor was marked as primary, fall back on marking the first
    * logical monitor the primary one.
    */
-  if (!manager->primary_logical_monitor && manager->logical_monitors)
-    manager->primary_logical_monitor = g_list_first (manager->logical_monitors)->data;
+  if (!primary_logical_monitor && manager->logical_monitors)
+    primary_logical_monitor = g_list_first (manager->logical_monitors)->data;
+
+  meta_monitor_manager_set_primary_logical_monitor (manager,
+                                                    primary_logical_monitor);
 
   if (manager_class->add_monitor)
     {
diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c
index d528686..177dc7c 100644
--- a/src/backends/meta-monitor.c
+++ b/src/backends/meta-monitor.c
@@ -69,7 +69,7 @@ meta_monitor_get_outputs (MetaMonitor *monitor)
   return priv->outputs;
 }
 
-static MetaOutput *
+MetaOutput *
 meta_monitor_get_main_output (MetaMonitor *monitor)
 {
   return META_MONITOR_GET_CLASS (monitor)->get_main_output (monitor);
@@ -85,6 +85,16 @@ meta_monitor_is_active (MetaMonitor *monitor)
   return output->crtc && output->crtc->current_mode;
 }
 
+gboolean
+meta_monitor_is_primary (MetaMonitor *monitor)
+{
+  MetaOutput *output;
+
+  output = meta_monitor_get_main_output (monitor);
+
+  return output->is_primary;
+}
+
 void
 meta_monitor_get_dimensions (MetaMonitor   *monitor,
                              int           *width,
diff --git a/src/backends/meta-monitor.h b/src/backends/meta-monitor.h
index b469e18..d19c75e 100644
--- a/src/backends/meta-monitor.h
+++ b/src/backends/meta-monitor.h
@@ -56,6 +56,10 @@ MetaMonitorNormal * meta_monitor_normal_new (MetaOutput *output);
 
 gboolean meta_monitor_is_active (MetaMonitor *monitor);
 
+MetaOutput * meta_monitor_get_main_output (MetaMonitor *monitor);
+
+gboolean meta_monitor_is_primary (MetaMonitor *monitor);
+
 GList * meta_monitor_get_outputs (MetaMonitor *monitor);
 
 void meta_monitor_get_dimensions (MetaMonitor   *monitor,


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