[mutter] monitor-manager: Make MetaCrtc a GObject



commit f64fab1d2d199e6ea46314f543607b0ea7030e04
Author: Jonas Ådahl <jadahl gmail com>
Date:   Tue Mar 28 12:35:19 2017 +0800

    monitor-manager: Make MetaCrtc a GObject
    
    Turn MetaCrtc into a GObject and move it to a separate file. This
    changes the storage format, resulting in changing the API for accessing
    MetaCrtcs from using an array, to using a GList.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=785381

 src/Makefile.am                                |    2 +
 src/backends/meta-crtc.c                       |   48 +++++++++++++
 src/backends/meta-crtc.h                       |   89 ++++++++++++++++++++++++
 src/backends/meta-logical-monitor.c            |    1 +
 src/backends/meta-monitor-manager-dummy.c      |   56 ++++++++-------
 src/backends/meta-monitor-manager-private.h    |   66 +-----------------
 src/backends/meta-monitor-manager.c            |   65 ++++++++---------
 src/backends/meta-monitor.c                    |    1 +
 src/backends/meta-monitor.h                    |    1 +
 src/backends/native/meta-monitor-manager-kms.c |   40 +++++++----
 src/backends/native/meta-renderer-native.c     |   25 ++++---
 src/backends/x11/meta-monitor-manager-xrandr.c |   36 ++++++----
 src/backends/x11/meta-stage-x11-nested.c       |    1 +
 src/tests/headless-start-test.c                |   14 ++--
 src/tests/meta-monitor-manager-test.c          |    6 +-
 src/tests/meta-monitor-manager-test.h          |    3 +-
 src/tests/monitor-unit-tests.c                 |   36 ++++++----
 17 files changed, 299 insertions(+), 191 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 97b6da1..45d4e7d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -97,6 +97,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES =        \
        backends/meta-backend-private.h         \
        backends/meta-barrier.c                 \
        backends/meta-barrier-private.h         \
+       backends/meta-crtc.c                    \
+       backends/meta-crtc.h                    \
        backends/meta-cursor.c                  \
        backends/meta-cursor.h                  \
        backends/meta-cursor-tracker.c          \
diff --git a/src/backends/meta-crtc.c b/src/backends/meta-crtc.c
new file mode 100644
index 0000000..ee16be1
--- /dev/null
+++ b/src/backends/meta-crtc.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2017 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "backends/meta-crtc.h"
+
+G_DEFINE_TYPE (MetaCrtc, meta_crtc, G_TYPE_OBJECT)
+
+static void
+meta_crtc_finalize (GObject *object)
+{
+  MetaCrtc *crtc = META_CRTC (object);
+
+  if (crtc->driver_notify)
+    crtc->driver_notify (crtc);
+
+  G_OBJECT_CLASS (meta_crtc_parent_class)->finalize (object);
+}
+
+static void
+meta_crtc_init (MetaCrtc *crtc)
+{
+}
+
+static void
+meta_crtc_class_init (MetaCrtcClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = meta_crtc_finalize;
+}
diff --git a/src/backends/meta-crtc.h b/src/backends/meta-crtc.h
new file mode 100644
index 0000000..0baa7d6
--- /dev/null
+++ b/src/backends/meta-crtc.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2017 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef META_CRTC_H
+#define META_CRTC_H
+
+#include <glib-object.h>
+
+#include "backends/meta-monitor-manager-private.h"
+
+/* Same as KMS mode flags and X11 randr flags */
+typedef enum _MetaCrtcModeFlag
+{
+  META_CRTC_MODE_FLAG_NONE = 0,
+  META_CRTC_MODE_FLAG_PHSYNC = (1 << 0),
+  META_CRTC_MODE_FLAG_NHSYNC = (1 << 1),
+  META_CRTC_MODE_FLAG_PVSYNC = (1 << 2),
+  META_CRTC_MODE_FLAG_NVSYNC = (1 << 3),
+  META_CRTC_MODE_FLAG_INTERLACE = (1 << 4),
+  META_CRTC_MODE_FLAG_DBLSCAN = (1 << 5),
+  META_CRTC_MODE_FLAG_CSYNC = (1 << 6),
+  META_CRTC_MODE_FLAG_PCSYNC = (1 << 7),
+  META_CRTC_MODE_FLAG_NCSYNC = (1 << 8),
+  META_CRTC_MODE_FLAG_HSKEW = (1 << 9),
+  META_CRTC_MODE_FLAG_BCAST = (1 << 10),
+  META_CRTC_MODE_FLAG_PIXMUX = (1 << 11),
+  META_CRTC_MODE_FLAG_DBLCLK = (1 << 12),
+  META_CRTC_MODE_FLAG_CLKDIV2 = (1 << 13),
+
+  META_CRTC_MODE_FLAG_MASK = 0x3fff
+} MetaCrtcModeFlag;
+
+struct _MetaCrtc
+{
+  GObject parent;
+
+  glong crtc_id;
+  MetaRectangle rect;
+  MetaCrtcMode *current_mode;
+  MetaMonitorTransform transform;
+  unsigned int all_transforms;
+
+  MetaLogicalMonitor *logical_monitor;
+
+  /* Used when changing configuration */
+  gboolean is_dirty;
+
+  /* Used by cursor renderer backend */
+  void *cursor_renderer_private;
+
+  gpointer driver_private;
+  GDestroyNotify driver_notify;
+};
+
+struct _MetaCrtcMode
+{
+  /* The low-level ID of this mode, used to apply back configuration */
+  glong mode_id;
+  char *name;
+
+  int width;
+  int height;
+  float refresh_rate;
+  MetaCrtcModeFlag flags;
+
+  gpointer driver_private;
+  GDestroyNotify driver_notify;
+};
+
+#define META_TYPE_CRTC (meta_crtc_get_type ())
+G_DECLARE_FINAL_TYPE (MetaCrtc, meta_crtc, META, CRTC, GObject)
+
+#endif /* META_CRTC_H */
diff --git a/src/backends/meta-logical-monitor.c b/src/backends/meta-logical-monitor.c
index 0b68868..2fb8b76 100644
--- a/src/backends/meta-logical-monitor.c
+++ b/src/backends/meta-logical-monitor.c
@@ -24,6 +24,7 @@
 #include "backends/meta-logical-monitor.h"
 
 #include "backends/meta-backend-private.h"
+#include "backends/meta-crtc.h"
 #include "backends/meta-output.h"
 
 G_DEFINE_TYPE (MetaLogicalMonitor, meta_logical_monitor, G_TYPE_OBJECT)
diff --git a/src/backends/meta-monitor-manager-dummy.c b/src/backends/meta-monitor-manager-dummy.c
index a1fc040..7ef4599 100644
--- a/src/backends/meta-monitor-manager-dummy.c
+++ b/src/backends/meta-monitor-manager-dummy.c
@@ -31,6 +31,7 @@
 
 #include <meta/util.h>
 #include "backends/meta-backend-private.h"
+#include "backends/meta-crtc.h"
 #include "backends/meta-monitor.h"
 #include "backends/meta-monitor-config-manager.h"
 #include "backends/meta-output.h"
@@ -69,7 +70,7 @@ meta_output_dummy_notify_destroy (MetaOutput *output);
 
 static void
 append_monitor (GArray *modes,
-                GArray *crtcs,
+                GList **crtcs,
                 GList **outputs,
                 float   scale)
 {
@@ -85,7 +86,7 @@ append_monitor (GArray *modes,
       .refresh_rate = 60.0
     }
   };
-  MetaCrtc crtc;
+  MetaCrtc *crtc;
   MetaOutputDummy *output_dummy;
   MetaOutput *output;
   unsigned int i;
@@ -95,11 +96,10 @@ append_monitor (GArray *modes,
     modes_decl[i].mode_id = modes->len + i;
   g_array_append_vals (modes, modes_decl, G_N_ELEMENTS (modes_decl));
 
-  crtc = (MetaCrtc) {
-    .crtc_id = crtcs->len + 1,
-    .all_transforms = ALL_TRANSFORMS,
-  };
-  g_array_append_val (crtcs, crtc);
+  crtc = g_object_new (META_TYPE_CRTC, NULL);
+  crtc->crtc_id = g_list_length (*crtcs) + 1;
+  crtc->all_transforms = ALL_TRANSFORMS;
+  *crtcs = g_list_append (*crtcs, crtc);
 
   output = g_object_new (META_TYPE_OUTPUT, NULL);
 
@@ -134,7 +134,7 @@ append_monitor (GArray *modes,
                                        modes->len - (i + 1));
   output->n_modes = G_N_ELEMENTS (modes_decl);
   output->possible_crtcs = g_new0 (MetaCrtc *, 1);
-  output->possible_crtcs[0] = &array_last (crtcs, MetaCrtc);
+  output->possible_crtcs[0] = g_list_last (*crtcs)->data;
   output->n_possible_crtcs = 1;
 
   *outputs = g_list_append (*outputs, output);
@@ -142,7 +142,7 @@ append_monitor (GArray *modes,
 
 static void
 append_tiled_monitor (GArray *modes,
-                      GArray *crtcs,
+                      GList **crtcs,
                       GList **outputs,
                       int     scale)
 {
@@ -159,6 +159,7 @@ append_tiled_monitor (GArray *modes,
     }
   };
   unsigned int n_tiles = 2;
+  GList *new_crtcs = NULL;
   MetaOutput *output;
   unsigned int i;
   uint32_t tile_group_id;
@@ -169,13 +170,14 @@ append_tiled_monitor (GArray *modes,
 
   for (i = 0; i < n_tiles; i++)
     {
-      MetaCrtc crtc = {
-        .crtc_id = crtcs->len + i + 1,
-        .all_transforms = ALL_TRANSFORMS
-      };
+      MetaCrtc *crtc;
 
-      g_array_append_val (crtcs, crtc);
+      crtc = g_object_new (META_TYPE_CRTC, NULL);
+      crtc->crtc_id = g_list_length (*crtcs) + i + 1;
+      crtc->all_transforms = ALL_TRANSFORMS;
+      new_crtcs = g_list_append (new_crtcs, crtc);
     }
+  *crtcs = g_list_concat (*crtcs, new_crtcs);
 
   tile_group_id = g_list_length (*outputs) + 1;
   for (i = 0; i < n_tiles; i++)
@@ -184,6 +186,7 @@ append_tiled_monitor (GArray *modes,
       MetaCrtcMode *preferred_mode;
       unsigned int j;
       unsigned int number;
+      GList *l;
 
       output_dummy = g_new0 (MetaOutputDummy, 1);
       *output_dummy = (MetaOutputDummy) {
@@ -231,9 +234,12 @@ append_tiled_monitor (GArray *modes,
       output->n_modes = G_N_ELEMENTS (modes_decl);
 
       output->possible_crtcs = g_new0 (MetaCrtc *, n_tiles);
-      for (j = 0; j < n_tiles; j++)
-        output->possible_crtcs[j] = &g_array_index (crtcs, MetaCrtc,
-                                                    crtcs->len - (j + 1));
+      for (l = new_crtcs, j = 0; l; l = l->next, j++)
+        {
+          MetaCrtc *crtc = l->data;
+
+          output->possible_crtcs[j] = crtc;
+        }
       output->n_possible_crtcs = n_tiles;
 
       *outputs = g_list_append (*outputs, output);
@@ -257,7 +263,7 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
   gboolean tiled_monitors;
   unsigned int i;
   GList *outputs;
-  GArray *crtcs;
+  GList *crtcs;
   GArray *modes;
 
   /* To control what monitor configuration is generated, there are two available
@@ -328,25 +334,23 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
   tiled_monitors = g_strcmp0 (tiled_monitors_str, "1") == 0;
 
   modes = g_array_sized_new (FALSE, TRUE, sizeof (MetaCrtcMode), MAX_MODES);
-  crtcs = g_array_sized_new (FALSE, TRUE, sizeof (MetaCrtc), MAX_CRTCS);
+  crtcs = NULL;
   outputs = NULL;
 
   for (i = 0; i < num_monitors; i++)
     {
       if (tiled_monitors)
-        append_tiled_monitor (modes, crtcs, &outputs, monitor_scales[i]);
+        append_tiled_monitor (modes, &crtcs, &outputs, monitor_scales[i]);
       else
-        append_monitor (modes, crtcs, &outputs, monitor_scales[i]);
+        append_monitor (modes, &crtcs, &outputs, monitor_scales[i]);
     }
 
   manager->modes = (MetaCrtcMode *) modes->data;
   manager->n_modes = modes->len;
-  manager->crtcs = (MetaCrtc *) crtcs->data;
-  manager->n_crtcs = crtcs->len;
+  manager->crtcs = crtcs;
   manager->outputs = outputs;
 
   g_array_free (modes, FALSE);
-  g_array_free (crtcs, FALSE);
 }
 
 static void
@@ -433,9 +437,9 @@ apply_crtc_assignments (MetaMonitorManager *manager,
     }
 
   /* Disable CRTCs not mentioned in the list */
-  for (i = 0; i < manager->n_crtcs; i++)
+  for (l = manager->crtcs; l; l = l->next)
     {
-      MetaCrtc *crtc = &manager->crtcs[i];
+      MetaCrtc *crtc = l->data;
 
       crtc->logical_monitor = NULL;
 
diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h
index 5ac683d..676c480 100644
--- a/src/backends/meta-monitor-manager-private.h
+++ b/src/backends/meta-monitor-manager-private.h
@@ -105,66 +105,6 @@ typedef enum
   META_MONITOR_TRANSFORM_FLIPPED_270,
 } MetaMonitorTransform;
 
-/* Same as KMS mode flags and X11 randr flags */
-typedef enum
-{
-  META_CRTC_MODE_FLAG_NONE = 0,
-  META_CRTC_MODE_FLAG_PHSYNC = (1 << 0),
-  META_CRTC_MODE_FLAG_NHSYNC = (1 << 1),
-  META_CRTC_MODE_FLAG_PVSYNC = (1 << 2),
-  META_CRTC_MODE_FLAG_NVSYNC = (1 << 3),
-  META_CRTC_MODE_FLAG_INTERLACE = (1 << 4),
-  META_CRTC_MODE_FLAG_DBLSCAN = (1 << 5),
-  META_CRTC_MODE_FLAG_CSYNC = (1 << 6),
-  META_CRTC_MODE_FLAG_PCSYNC = (1 << 7),
-  META_CRTC_MODE_FLAG_NCSYNC = (1 << 8),
-  META_CRTC_MODE_FLAG_HSKEW = (1 << 9),
-  META_CRTC_MODE_FLAG_BCAST = (1 << 10),
-  META_CRTC_MODE_FLAG_PIXMUX = (1 << 11),
-  META_CRTC_MODE_FLAG_DBLCLK = (1 << 12),
-  META_CRTC_MODE_FLAG_CLKDIV2 = (1 << 13),
-
-  META_CRTC_MODE_FLAG_MASK = 0x3fff
-} MetaCrtcModeFlag;
-
-struct _MetaCrtc
-{
-  glong crtc_id;
-  MetaRectangle rect;
-  MetaCrtcMode *current_mode;
-  MetaMonitorTransform transform;
-  unsigned int all_transforms;
-
-  /* Only used to build the logical configuration
-     from the HW one
-  */
-  MetaLogicalMonitor *logical_monitor;
-
-  /* Used when changing configuration */
-  gboolean is_dirty;
-
-  /* Used by cursor renderer backend */
-  void *cursor_renderer_private;
-
-  gpointer driver_private;
-  GDestroyNotify driver_notify;
-};
-
-struct _MetaCrtcMode
-{
-  /* The low-level ID of this mode, used to apply back configuration */
-  glong mode_id;
-  char *name;
-
-  int width;
-  int height;
-  float refresh_rate;
-  MetaCrtcModeFlag flags;
-
-  gpointer driver_private;
-  GDestroyNotify driver_notify;
-};
-
 /*
  * MetaCrtcInfo:
  *
@@ -228,13 +168,11 @@ struct _MetaMonitorManager
      while logical_monitors refer to logical ones.
   */
   GList *outputs;
+  GList *crtcs;
 
   MetaCrtcMode *modes;
   unsigned int n_modes;
 
-  MetaCrtc *crtcs;
-  unsigned int n_crtcs;
-
   GList *monitors;
 
   GList *logical_monitors;
@@ -362,6 +300,8 @@ GList *             meta_monitor_manager_get_monitors      (MetaMonitorManager *
 
 GList *             meta_monitor_manager_get_outputs       (MetaMonitorManager *manager);
 
+GList *             meta_monitor_manager_get_crtcs         (MetaMonitorManager *manager);
+
 void                meta_monitor_manager_get_screen_size   (MetaMonitorManager *manager,
                                                             int                *width,
                                                             int                *height);
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index c944733..b5c83fc 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -36,6 +36,7 @@
 #include "util-private.h"
 #include <meta/errors.h>
 #include "edid.h"
+#include "backends/meta-crtc.h"
 #include "backends/meta-logical-monitor.h"
 #include "backends/meta-monitor.h"
 #include "backends/meta-monitor-config-manager.h"
@@ -742,27 +743,6 @@ meta_monitor_manager_free_mode_array (MetaCrtcMode *old_modes,
   g_free (old_modes);
 }
 
-void
-meta_monitor_manager_clear_crtc (MetaCrtc *crtc)
-{
-  if (crtc->driver_notify)
-    crtc->driver_notify (crtc);
-
-  memset (crtc, 0, sizeof (*crtc));
-}
-
-static void
-meta_monitor_manager_free_crtc_array (MetaCrtc *old_crtcs,
-                                      int       n_old_crtcs)
-{
-  int i;
-
-  for (i = 0; i < n_old_crtcs; i++)
-    meta_monitor_manager_clear_crtc (&old_crtcs[i]);
-
-  g_free (old_crtcs);
-}
-
 static void
 meta_monitor_manager_finalize (GObject *object)
 {
@@ -770,7 +750,7 @@ meta_monitor_manager_finalize (GObject *object)
 
   g_list_free_full (manager->outputs, g_object_unref);
   meta_monitor_manager_free_mode_array (manager->modes, manager->n_modes);
-  meta_monitor_manager_free_crtc_array (manager->crtcs, manager->n_crtcs);
+  g_list_free_full (manager->crtcs, g_object_unref);
   g_list_free_full (manager->logical_monitors, g_object_unref);
 
   g_signal_handler_disconnect (meta_get_backend (),
@@ -946,9 +926,9 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
   g_variant_builder_init (&output_builder, G_VARIANT_TYPE ("a(uxiausauaua{sv})"));
   g_variant_builder_init (&mode_builder, G_VARIANT_TYPE ("a(uxuudu)"));
 
-  for (i = 0; i < manager->n_crtcs; i++)
+  for (l = manager->crtcs, i = 0; l; l = l->next, i++)
     {
-      MetaCrtc *crtc = &manager->crtcs[i];
+      MetaCrtc *crtc = l->data;
       GVariantBuilder transforms;
 
       g_variant_builder_init (&transforms, G_VARIANT_TYPE ("au"));
@@ -975,11 +955,17 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
       GVariantBuilder crtcs, modes, clones, properties;
       GBytes *edid;
       char *edid_file;
+      int crtc_index;
 
       g_variant_builder_init (&crtcs, G_VARIANT_TYPE ("au"));
       for (j = 0; j < output->n_possible_crtcs; j++)
-        g_variant_builder_add (&crtcs, "u",
-                               (unsigned)(output->possible_crtcs[j] - manager->crtcs));
+        {
+          MetaCrtc *possible_crtc = output->possible_crtcs[j];
+          unsigned possible_crtc_index;
+
+          possible_crtc_index = g_list_index (manager->crtcs, possible_crtc);
+          g_variant_builder_add (&crtcs, "u", possible_crtc_index);
+        }
 
       g_variant_builder_init (&modes, G_VARIANT_TYPE ("au"));
       for (j = 0; j < output->n_modes; j++)
@@ -1058,10 +1044,12 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
                                                 output->tile_info.tile_h));
         }
 
+      crtc_index = output->crtc ? g_list_index (manager->crtcs, output->crtc)
+                                : -1;
       g_variant_builder_add (&output_builder, "(uxiausauaua{sv})",
                              i, /* ID */
                              (gint64)output->winsys_id,
-                             (int)(output->crtc ? output->crtc - manager->crtcs : -1),
+                             crtc_index,
                              &crtcs,
                              output->name,
                              &modes,
@@ -2064,14 +2052,15 @@ meta_monitor_manager_handle_get_crtc_gamma  (MetaDBusDisplayConfig *skeleton,
       return TRUE;
     }
 
-  if (crtc_id >= manager->n_crtcs)
+  if (crtc_id >= g_list_length (manager->crtcs))
     {
       g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                              G_DBUS_ERROR_INVALID_ARGS,
                                              "Invalid crtc id");
       return TRUE;
     }
-  crtc = &manager->crtcs[crtc_id];
+
+  crtc = g_list_nth_data (manager->crtcs, crtc_id);
 
   klass = META_MONITOR_MANAGER_GET_CLASS (manager);
   if (klass->get_crtc_gamma)
@@ -2126,14 +2115,15 @@ meta_monitor_manager_handle_set_crtc_gamma  (MetaDBusDisplayConfig *skeleton,
       return TRUE;
     }
 
-  if (crtc_id >= manager->n_crtcs)
+  if (crtc_id >= g_list_length (manager->crtcs))
     {
       g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
                                              G_DBUS_ERROR_INVALID_ARGS,
                                              "Invalid crtc id");
       return TRUE;
     }
-  crtc = &manager->crtcs[crtc_id];
+
+  crtc = g_list_nth_data (manager->crtcs, crtc_id);
 
   red_bytes = g_variant_get_data_as_bytes (red_v);
   green_bytes = g_variant_get_data_as_bytes (green_v);
@@ -2409,6 +2399,12 @@ meta_monitor_manager_get_outputs (MetaMonitorManager *manager)
   return manager->outputs;
 }
 
+GList *
+meta_monitor_manager_get_crtcs (MetaMonitorManager *manager)
+{
+  return manager->crtcs;
+}
+
 void
 meta_monitor_manager_get_screen_size (MetaMonitorManager *manager,
                                       int                *width,
@@ -2492,16 +2488,15 @@ void
 meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
 {
   GList *old_outputs;
-  MetaCrtc *old_crtcs;
+  GList *old_crtcs;
   MetaCrtcMode *old_modes;
-  unsigned int n_old_crtcs, n_old_modes;
+  unsigned int n_old_modes;
 
   /* Some implementations of read_current use the existing information
    * we have available, so don't free the old configuration until after
    * read_current finishes. */
   old_outputs = manager->outputs;
   old_crtcs = manager->crtcs;
-  n_old_crtcs = manager->n_crtcs;
   old_modes = manager->modes;
   n_old_modes = manager->n_modes;
 
@@ -2512,7 +2507,7 @@ meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
 
   g_list_free_full (old_outputs, g_object_unref);
   meta_monitor_manager_free_mode_array (old_modes, n_old_modes);
-  meta_monitor_manager_free_crtc_array (old_crtcs, n_old_crtcs);
+  g_list_free_full (old_crtcs, g_object_unref);
 }
 
 static void
diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c
index 477bbed..340544f 100644
--- a/src/backends/meta-monitor.c
+++ b/src/backends/meta-monitor.c
@@ -24,6 +24,7 @@
 #include "backends/meta-monitor.h"
 
 #include "backends/meta-backend-private.h"
+#include "backends/meta-crtc.h"
 #include "backends/meta-monitor-manager-private.h"
 #include "backends/meta-settings-private.h"
 #include "backends/meta-output.h"
diff --git a/src/backends/meta-monitor.h b/src/backends/meta-monitor.h
index 9a9e6d8..5b6f747 100644
--- a/src/backends/meta-monitor.h
+++ b/src/backends/meta-monitor.h
@@ -24,6 +24,7 @@
 
 #include <glib-object.h>
 
+#include "backends/meta-crtc.h"
 #include "backends/meta-monitor-manager-private.h"
 #include "backends/meta-output.h"
 
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index 48e4d14..aba8985 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -25,6 +25,7 @@
 
 #include "meta-monitor-manager-kms.h"
 #include "meta-monitor-config-manager.h"
+#include "meta-crtc.h"
 #include "meta-output.h"
 #include "meta-backend-private.h"
 #include "meta-renderer-native.h"
@@ -663,13 +664,15 @@ add_common_modes (MetaMonitorManager *manager,
   g_ptr_array_free (array, TRUE);
 }
 
-static void
-init_crtc (MetaCrtc           *crtc,
-           MetaMonitorManager *manager,
-           drmModeCrtc        *drm_crtc)
+static MetaCrtc *
+create_crtc (MetaMonitorManager *manager,
+             drmModeCrtc        *drm_crtc)
 {
+  MetaCrtc *crtc;
   unsigned int i;
 
+  crtc = g_object_new (META_TYPE_CRTC, NULL);
+
   crtc->crtc_id = drm_crtc->crtc_id;
   crtc->rect.x = drm_crtc->x;
   crtc->rect.y = drm_crtc->y;
@@ -694,6 +697,8 @@ init_crtc (MetaCrtc           *crtc,
 
   crtc->driver_private = g_new0 (MetaCrtcKms, 1);
   crtc->driver_notify = (GDestroyNotify) meta_crtc_destroy_notify;
+
+  return crtc;
 }
 
 static MetaOutput *
@@ -706,6 +711,7 @@ create_output (MetaMonitorManager *manager,
   MetaOutputKms *output_kms;
   GArray *crtcs;
   GBytes *edid;
+  GList *l;
   unsigned int i;
   unsigned int crtc_mask;
 
@@ -791,11 +797,12 @@ create_output (MetaMonitorManager *manager,
 
   crtcs = g_array_new (FALSE, FALSE, sizeof (MetaCrtc*));
 
-  for (i = 0; i < manager->n_crtcs; i++)
+  for (l = manager->crtcs, i = 0; l; l = l->next, i++)
     {
       if (crtc_mask & (1 << i))
         {
-          MetaCrtc *crtc = &manager->crtcs[i];
+          MetaCrtc *crtc = l->data;
+
           g_array_append_val (crtcs, crtc);
         }
     }
@@ -805,11 +812,13 @@ create_output (MetaMonitorManager *manager,
 
   if (output_kms->current_encoder && output_kms->current_encoder->crtc_id != 0)
     {
-      for (i = 0; i < manager->n_crtcs; i++)
+      for (l = manager->crtcs; l; l = l->next)
         {
-          if (manager->crtcs[i].crtc_id == output_kms->current_encoder->crtc_id)
+          MetaCrtc *crtc = l->data;
+
+          if (crtc->crtc_id == output_kms->current_encoder->crtc_id)
             {
-              output->crtc = &manager->crtcs[i];
+              output->crtc = crtc;
               break;
             }
         }
@@ -1041,8 +1050,7 @@ init_crtcs (MetaMonitorManager *manager,
   MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
   unsigned int i;
 
-  manager->n_crtcs = resources->count_crtcs;
-  manager->crtcs = g_new0 (MetaCrtc, manager->n_crtcs);
+  manager->crtcs = NULL;
 
   for (i = 0; i < (unsigned)resources->count_crtcs; i++)
     {
@@ -1051,13 +1059,13 @@ init_crtcs (MetaMonitorManager *manager,
 
       drm_crtc = drmModeGetCrtc (manager_kms->fd, resources->crtcs[i]);
 
-      crtc = &manager->crtcs[i];
-
-      init_crtc (crtc, manager, drm_crtc);
+      crtc = create_crtc (manager, drm_crtc);
       find_crtc_properties (manager_kms, crtc);
       init_crtc_rotations (manager, crtc, i);
 
       drmModeFreeCrtc (drm_crtc);
+
+      manager->crtcs = g_list_append (manager->crtcs, crtc);
     }
 }
 
@@ -1327,9 +1335,9 @@ apply_crtc_assignments (MetaMonitorManager *manager,
     }
   /* Disable CRTCs not mentioned in the list (they have is_dirty == FALSE,
      because they weren't seen in the first loop) */
-  for (i = 0; i < manager->n_crtcs; i++)
+  for (l = manager->crtcs; l; l = l->next)
     {
-      MetaCrtc *crtc = &manager->crtcs[i];
+      MetaCrtc *crtc = l->data;
 
       crtc->logical_monitor = NULL;
 
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 79767f7..d2a6c03 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -48,6 +48,7 @@
 #include <xf86drm.h>
 
 #include "backends/meta-backend-private.h"
+#include "backends/meta-crtc.h"
 #include "backends/meta-egl.h"
 #include "backends/meta-egl-ext.h"
 #include "backends/meta-logical-monitor.h"
@@ -683,11 +684,13 @@ meta_onscreen_native_set_crtc_modes (MetaOnscreenNative *onscreen_native)
     }
   else
     {
-      unsigned int i;
+      GList *crtcs;
+      GList *l;
 
-      for (i = 0; i < monitor_manager->n_crtcs; i++)
+      crtcs = meta_monitor_manager_get_crtcs (monitor_manager);
+      for (l = crtcs; l; l = l->next)
         {
-          MetaCrtc *crtc = &monitor_manager->crtcs[i];
+          MetaCrtc *crtc = l->data;
 
           meta_monitor_manager_kms_apply_crtc_mode (monitor_manager_kms,
                                                     crtc,
@@ -768,11 +771,13 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen)
     }
   else
     {
-      unsigned int i;
+      GList *crtcs;
+      GList *l;
 
-      for (i = 0; i < monitor_manager->n_crtcs; i++)
+      crtcs = meta_monitor_manager_get_crtcs (monitor_manager);
+      for (l = crtcs; l; l = l->next)
         {
-          MetaCrtc *crtc = &monitor_manager->crtcs[i];
+          MetaCrtc *crtc = l->data;
 
           meta_onscreen_native_flip_crtc (onscreen_native, flip_closure,
                                           crtc, crtc->rect.x, crtc->rect.y,
@@ -1827,11 +1832,13 @@ meta_renderer_native_finish_frame (MetaRendererNative *renderer_native)
         meta_backend_get_monitor_manager (backend);
       MetaMonitorManagerKms *monitor_manager_kms =
         META_MONITOR_MANAGER_KMS (monitor_manager);
-      unsigned int i;
+      GList *crtcs;
+      GList *l;
 
-      for (i = 0; i < monitor_manager->n_crtcs; i++)
+      crtcs = meta_monitor_manager_get_crtcs (monitor_manager);
+      for (l = crtcs; l; l = l->next)
         {
-          MetaCrtc *crtc = &monitor_manager->crtcs[i];
+          MetaCrtc *crtc = l->data;
 
           if (crtc->current_mode)
             continue;
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index 1300d5b..6087010 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -43,6 +43,7 @@
 #include "meta-backend-x11.h"
 #include <meta/main.h>
 #include <meta/errors.h>
+#include "backends/meta-crtc.h"
 #include "backends/meta-monitor-config-manager.h"
 #include "backends/meta-logical-monitor.h"
 #include "backends/meta-output.h"
@@ -686,19 +687,22 @@ output_get_crtcs (MetaMonitorManager *manager,
                   MetaOutput         *output,
                   XRROutputInfo      *xrandr_output)
 {
-  guint j, k;
+  guint j;
   guint n_actual_crtcs;
+  GList *l;
 
   output->possible_crtcs = g_new0 (MetaCrtc *, xrandr_output->ncrtc);
 
   n_actual_crtcs = 0;
   for (j = 0; j < (unsigned) xrandr_output->ncrtc; j++)
     {
-      for (k = 0; k < manager->n_crtcs; k++)
+      for (l = manager->crtcs; l; l = l->next)
         {
-          if ((XID) manager->crtcs[k].crtc_id == xrandr_output->crtcs[j])
+          MetaCrtc *crtc = l->data;
+
+          if ((XID) crtc->crtc_id == xrandr_output->crtcs[j])
             {
-              output->possible_crtcs[n_actual_crtcs] = &manager->crtcs[k];
+              output->possible_crtcs[n_actual_crtcs] = crtc;
               n_actual_crtcs += 1;
               break;
             }
@@ -707,11 +711,13 @@ output_get_crtcs (MetaMonitorManager *manager,
   output->n_possible_crtcs = n_actual_crtcs;
 
   output->crtc = NULL;
-  for (j = 0; j < manager->n_crtcs; j++)
+  for (l = manager->crtcs; l; l = l->next)
     {
-      if ((XID) manager->crtcs[j].crtc_id == xrandr_output->crtc)
+      MetaCrtc *crtc = l->data;
+
+      if ((XID) crtc->crtc_id == xrandr_output->crtc)
         {
-          output->crtc = &manager->crtcs[j];
+          output->crtc = crtc;
           break;
         }
     }
@@ -791,11 +797,10 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
     return;
 
   manager_xrandr->resources = resources;
-  manager->n_crtcs = resources->ncrtc;
   manager->n_modes = resources->nmode;
   manager->outputs = NULL;
   manager->modes = g_new0 (MetaCrtcMode, manager->n_modes);
-  manager->crtcs = g_new0 (MetaCrtc, manager->n_crtcs);
+  manager->crtcs = NULL;
 
   for (i = 0; i < (unsigned)resources->nmode; i++)
     {
@@ -821,7 +826,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
       xrandr_crtc = XRRGetCrtcInfo (manager_xrandr->xdisplay, resources,
                                     resources->crtcs[i]);
 
-      crtc = &manager->crtcs[i];
+      crtc = g_object_new (META_TYPE_CRTC, NULL);
 
       crtc->crtc_id = resources->crtcs[i];
       crtc->rect.x = xrandr_crtc->x;
@@ -844,6 +849,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
        }
 
       XRRFreeCrtcInfo (xrandr_crtc);
+
+      manager->crtcs = g_list_append (manager->crtcs, crtc);
     }
 
   primary_output = XRRGetOutputPrimary (manager_xrandr->xdisplay,
@@ -1219,12 +1226,11 @@ is_assignments_changed (MetaMonitorManager *manager,
                         MetaOutputInfo    **output_infos,
                         unsigned int        n_output_infos)
 {
-  unsigned int i;
   GList *l;
 
-  for (i = 0; i < manager->n_crtcs; i++)
+  for (l = manager->crtcs; l; l = l->next)
     {
-      MetaCrtc *crtc = &manager->crtcs[i];
+      MetaCrtc *crtc = l->data;
 
       if (is_crtc_assignment_changed (crtc, crtc_infos, n_crtc_infos))
         return TRUE;
@@ -1314,9 +1320,9 @@ apply_crtc_assignments (MetaMonitorManager *manager,
     }
 
   /* Disable CRTCs not mentioned in the list */
-  for (i = 0; i < manager->n_crtcs; i++)
+  for (l = manager->crtcs; l; l = l->next)
     {
-      MetaCrtc *crtc = &manager->crtcs[i];
+      MetaCrtc *crtc = l->data;
 
       if (crtc->is_dirty)
         {
diff --git a/src/backends/x11/meta-stage-x11-nested.c b/src/backends/x11/meta-stage-x11-nested.c
index ba70b4b..57fdabb 100644
--- a/src/backends/x11/meta-stage-x11-nested.c
+++ b/src/backends/x11/meta-stage-x11-nested.c
@@ -27,6 +27,7 @@
 #include "backends/x11/meta-stage-x11-nested.h"
 
 #include "backends/meta-backend-private.h"
+#include "backends/meta-crtc.h"
 #include "backends/meta-logical-monitor.h"
 #include "backends/meta-monitor.h"
 #include "backends/meta-output.h"
diff --git a/src/tests/headless-start-test.c b/src/tests/headless-start-test.c
index e53d599..22116f3 100644
--- a/src/tests/headless-start-test.c
+++ b/src/tests/headless-start-test.c
@@ -20,6 +20,7 @@
 #include "config.h"
 
 #include "backends/meta-monitor-manager-private.h"
+#include "backends/meta-crtc.h"
 #include "backends/meta-output.h"
 #include "compositor/meta-plugin-manager.h"
 #include "core/main-private.h"
@@ -98,6 +99,7 @@ meta_test_headless_monitor_connect (void)
     META_MONITOR_MANAGER_TEST (monitor_manager);
   MetaMonitorTestSetup *test_setup;
   MetaCrtcMode **modes;
+  MetaCrtc *crtc;
   MetaCrtc **possible_crtcs;
   MetaOutput *output;
   GList *logical_monitors;
@@ -113,18 +115,16 @@ meta_test_headless_monitor_connect (void)
     .refresh_rate = 60.0
   };
 
-  test_setup->n_crtcs = 1;
-  test_setup->crtcs = g_new0 (MetaCrtc, test_setup->n_crtcs);
-  test_setup->crtcs[0] = (MetaCrtc) {
-    .crtc_id = 1,
-    .all_transforms = ALL_TRANSFORMS
-  };
+  crtc = g_object_new (META_TYPE_CRTC, NULL);
+  crtc->crtc_id = 1;
+  crtc->all_transforms = ALL_TRANSFORMS;
+  test_setup->crtcs = g_list_append (NULL, crtc);
 
   modes = g_new0 (MetaCrtcMode *, 1);
   modes[0] = &test_setup->modes[0];
 
   possible_crtcs = g_new0 (MetaCrtc *, 1);
-  possible_crtcs[0] = &test_setup->crtcs[0];
+  possible_crtcs[0] = g_list_first (test_setup->crtcs)->data;
 
   output = g_object_new (META_TYPE_OUTPUT, NULL);
   output->winsys_id = 1;
diff --git a/src/tests/meta-monitor-manager-test.c b/src/tests/meta-monitor-manager-test.c
index 79e5272..0fa586f 100644
--- a/src/tests/meta-monitor-manager-test.c
+++ b/src/tests/meta-monitor-manager-test.c
@@ -22,6 +22,7 @@
 #include "tests/meta-monitor-manager-test.h"
 
 #include "backends/meta-backend-private.h"
+#include "backends/meta-crtc.h"
 #include "backends/meta-monitor-config-manager.h"
 #include "backends/meta-output.h"
 
@@ -97,7 +98,6 @@ meta_monitor_manager_test_read_current (MetaMonitorManager *manager)
   manager->n_modes = manager_test->test_setup->n_modes;
 
   manager->crtcs = manager_test->test_setup->crtcs;
-  manager->n_crtcs = manager_test->test_setup->n_crtcs;
 
   manager->outputs = manager_test->test_setup->outputs;
 }
@@ -199,9 +199,9 @@ apply_crtc_assignments (MetaMonitorManager *manager,
     }
 
   /* Disable CRTCs not mentioned in the list */
-  for (i = 0; i < manager->n_crtcs; i++)
+  for (l = manager->crtcs; l; l = l->next)
     {
-      MetaCrtc *crtc = &manager->crtcs[i];
+      MetaCrtc *crtc = l->data;
 
       crtc->logical_monitor = NULL;
 
diff --git a/src/tests/meta-monitor-manager-test.h b/src/tests/meta-monitor-manager-test.h
index 4f35b22..4dcb90a 100644
--- a/src/tests/meta-monitor-manager-test.h
+++ b/src/tests/meta-monitor-manager-test.h
@@ -27,8 +27,7 @@ typedef struct _MetaMonitorTestSetup
   MetaCrtcMode *modes;
   int n_modes;
   GList *outputs;
-  MetaCrtc *crtcs;
-  int n_crtcs;
+  GList *crtcs;
 } MetaMonitorTestSetup;
 
 typedef struct _MetaOutputTest
diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c
index e42534f..e6af4b9 100644
--- a/src/tests/monitor-unit-tests.c
+++ b/src/tests/monitor-unit-tests.c
@@ -22,6 +22,7 @@
 #include "tests/monitor-unit-tests.h"
 
 #include "backends/meta-backend-private.h"
+#include "backends/meta-crtc.h"
 #include "backends/meta-logical-monitor.h"
 #include "backends/meta-monitor.h"
 #include "backends/meta-monitor-config-migration.h"
@@ -607,6 +608,7 @@ check_monitor_configuration (MonitorTestCase *test_case)
     META_MONITOR_MANAGER_TEST (monitor_manager);
   int tiled_monitor_count;
   GList *monitors;
+  GList *crtcs;
   int n_logical_monitors;
   GList *l;
   int i;
@@ -620,7 +622,7 @@ check_monitor_configuration (MonitorTestCase *test_case)
   g_assert_cmpint ((int) g_list_length (monitor_manager->outputs),
                    ==,
                    test_case->expect.n_outputs);
-  g_assert_cmpint ((int) monitor_manager->n_crtcs,
+  g_assert_cmpint ((int) g_list_length (monitor_manager->crtcs),
                    ==,
                    test_case->expect.n_crtcs);
 
@@ -786,15 +788,17 @@ check_monitor_configuration (MonitorTestCase *test_case)
     }
   g_assert_cmpint (n_logical_monitors, ==, i);
 
-  for (i = 0; i < test_case->expect.n_crtcs; i++)
+  crtcs = meta_monitor_manager_get_crtcs (monitor_manager);
+  for (l = crtcs, i = 0; l; l = l->next, i++)
     {
+      MetaCrtc *crtc = l->data;
+
       if (test_case->expect.crtcs[i].current_mode == -1)
         {
-          g_assert_null (monitor_manager->crtcs[i].current_mode);
+          g_assert_null (crtc->current_mode);
         }
       else
         {
-          MetaCrtc *crtc = &monitor_manager->crtcs[i];
           MetaLogicalMonitor *logical_monitor = crtc->logical_monitor;
           MetaCrtcMode *expected_current_mode =
             &monitor_manager->modes[test_case->expect.crtcs[i].current_mode];
@@ -872,10 +876,10 @@ create_monitor_test_setup (MonitorTestCase *test_case,
       };
     }
 
-  test_setup->n_crtcs = test_case->setup.n_crtcs;
-  test_setup->crtcs = g_new0 (MetaCrtc, test_setup->n_crtcs);
-  for (i = 0; i < test_setup->n_crtcs; i++)
+  test_setup->crtcs = NULL;
+  for (i = 0; i < test_case->setup.n_crtcs; i++)
     {
+      MetaCrtc *crtc;
       int current_mode_index;
       MetaCrtcMode *current_mode;
 
@@ -885,12 +889,13 @@ create_monitor_test_setup (MonitorTestCase *test_case,
       else
         current_mode = &test_setup->modes[current_mode_index];
 
-      test_setup->crtcs[i] = (MetaCrtc) {
-        .crtc_id = i + 1,
-        .current_mode = current_mode,
-        .transform = META_MONITOR_TRANSFORM_NORMAL,
-        .all_transforms = ALL_TRANSFORMS
-      };
+      crtc = g_object_new (META_TYPE_CRTC, NULL);
+      crtc->crtc_id = i + 1;
+      crtc->current_mode = current_mode;
+      crtc->transform = META_MONITOR_TRANSFORM_NORMAL;
+      crtc->all_transforms = ALL_TRANSFORMS;
+
+      test_setup->crtcs = g_list_append (test_setup->crtcs, crtc);
     }
 
   test_setup->outputs = NULL;
@@ -915,7 +920,7 @@ create_monitor_test_setup (MonitorTestCase *test_case,
       if (crtc_index == -1)
         crtc = NULL;
       else
-        crtc = &test_setup->crtcs[crtc_index];
+        crtc = g_list_nth_data (test_setup->crtcs, crtc_index);
 
       preferred_mode_index = test_case->setup.outputs[i].preferred_mode;
       if (preferred_mode_index == -1)
@@ -940,7 +945,8 @@ create_monitor_test_setup (MonitorTestCase *test_case,
           int possible_crtc_index;
 
           possible_crtc_index = test_case->setup.outputs[i].possible_crtcs[j];
-          possible_crtcs[j] = &test_setup->crtcs[possible_crtc_index];
+          possible_crtcs[j] = g_list_nth_data (test_setup->crtcs,
+                                               possible_crtc_index);
         }
 
       output_test = g_new0 (MetaOutputTest, 1);



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