[mutter] monitor-manager: Generate a monitor abstraction from outputs and crtcs
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] monitor-manager: Generate a monitor abstraction from outputs and crtcs
- Date: Wed, 25 Jan 2017 08:34:24 +0000 (UTC)
commit d9a0f2a88d2abc2d0862da1691161baddbab5ac4
Author: Jonas Ådahl <jadahl gmail com>
Date: Tue Dec 13 10:53:38 2016 +0800
monitor-manager: Generate a monitor abstraction from outputs and crtcs
Generate a set of "monitors" abstracting the physical concepts. Each
monitor is built up of one or more outputs; multiple outputs being
tiled monitors. Logical monitors will later be built from these.
https://bugzilla.gnome.org/show_bug.cgi?id=777732
src/Makefile.am | 3 +
src/backends/meta-monitor-manager-private.h | 7 +
src/backends/meta-monitor-manager.c | 46 +++++
src/backends/meta-monitor.c | 268 +++++++++++++++++++++++++++
src/backends/meta-monitor.h | 69 +++++++
5 files changed, 393 insertions(+), 0 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index b2509ad..d5af5b2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -105,6 +105,9 @@ libmutter_la_SOURCES = \
backends/meta-logical-monitor.h \
backends/meta-monitor-config.c \
backends/meta-monitor-config.h \
+ backends/meta-monitor.c \
+ backends/meta-monitor.h \
+ backends/meta-monitor-private.h \
backends/meta-monitor-manager.c \
meta/meta-monitor-manager.h \
backends/meta-monitor-manager-private.h \
diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h
index 53f1e4e..e27107b 100644
--- a/src/backends/meta-monitor-manager-private.h
+++ b/src/backends/meta-monitor-manager-private.h
@@ -50,6 +50,9 @@
typedef struct _MetaMonitorConfigClass MetaMonitorConfigClass;
typedef struct _MetaMonitorConfig MetaMonitorConfig;
+typedef struct _MetaMonitor MetaMonitor;
+typedef struct _MetaMonitorNormal MetaMonitorNormal;
+typedef struct _MetaMonitorTiled MetaMonitorTiled;
typedef struct _MetaLogicalMonitor MetaLogicalMonitor;
typedef struct _MetaCrtc MetaCrtc;
@@ -266,6 +269,8 @@ struct _MetaMonitorManager
MetaCrtc *crtcs;
unsigned int n_crtcs;
+ GList *monitors;
+
GList *logical_monitors;
MetaLogicalMonitor *primary_logical_monitor;
@@ -344,6 +349,8 @@ MetaLogicalMonitor *meta_monitor_manager_get_logical_monitor_neighbor (MetaMonit
MetaLogicalMonitor *logical_monitor,
MetaScreenDirection direction);
+GList * meta_monitor_manager_get_monitors (MetaMonitorManager *manager);
+
MetaOutput *meta_monitor_manager_get_outputs (MetaMonitorManager *manager,
unsigned int *n_outputs);
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 588c084..14dd503 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -38,6 +38,7 @@
#include "edid.h"
#include "meta-monitor-config.h"
#include "backends/meta-logical-monitor.h"
+#include "backends/meta-monitor.h"
#include "backends/x11/meta-monitor-manager-xrandr.h"
#include "meta-backend-private.h"
@@ -1446,6 +1447,12 @@ meta_monitor_manager_get_logical_monitor_neighbor (MetaMonitorManager *manager,
return NULL;
}
+GList *
+meta_monitor_manager_get_monitors (MetaMonitorManager *manager)
+{
+ return manager->monitors;
+}
+
MetaOutput *
meta_monitor_manager_get_outputs (MetaMonitorManager *manager,
unsigned int *n_outputs)
@@ -1498,6 +1505,43 @@ meta_monitor_manager_get_screen_limits (MetaMonitorManager *manager,
*height = manager->max_screen_height;
}
+static void
+rebuild_monitors (MetaMonitorManager *manager)
+{
+ unsigned int i;
+
+ if (manager->monitors)
+ {
+ g_list_free_full (manager->monitors, g_object_unref);
+ manager->monitors = NULL;
+ }
+
+ for (i = 0; i < manager->n_outputs; i++)
+ {
+ MetaOutput *output = &manager->outputs[i];
+
+ if (output->tile_info.group_id)
+ {
+ if (is_main_tiled_monitor_output (output))
+ {
+ MetaMonitorTiled *monitor_tiled;
+
+ monitor_tiled = meta_monitor_tiled_new (manager, output);
+ manager->monitors = g_list_append (manager->monitors,
+ monitor_tiled);
+ }
+ }
+ else
+ {
+ MetaMonitorNormal *monitor_normal;
+
+ monitor_normal = meta_monitor_normal_new (output);
+ manager->monitors = g_list_append (manager->monitors,
+ monitor_normal);
+ }
+ }
+}
+
void
meta_monitor_manager_read_current_config (MetaMonitorManager *manager)
{
@@ -1519,6 +1563,8 @@ meta_monitor_manager_read_current_config (MetaMonitorManager *manager)
manager->serial++;
META_MONITOR_MANAGER_GET_CLASS (manager)->read_current (manager);
+ rebuild_monitors (manager);
+
meta_monitor_manager_free_output_array (old_outputs, n_old_outputs);
meta_monitor_manager_free_mode_array (old_modes, n_old_modes);
meta_monitor_manager_free_crtc_array (old_crtcs, n_old_crtcs);
diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c
new file mode 100644
index 0000000..d528686
--- /dev/null
+++ b/src/backends/meta-monitor.c
@@ -0,0 +1,268 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2016 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-monitor.h"
+
+#include "backends/meta-monitor-manager-private.h"
+
+typedef struct _MetaMonitorPrivate
+{
+ GList *outputs;
+
+ /*
+ * The primary or first output for this monitor, 0 if we can't figure out.
+ * It can be matched to a winsys_id of a MetaOutput.
+ *
+ * This is used as an opaque token on reconfiguration when switching from
+ * clone to extened, to decide on what output the windows should go next
+ * (it's an attempt to keep windows on the same monitor, and preferably on
+ * the primary one).
+ */
+ long winsys_id;
+} MetaMonitorPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (MetaMonitor, meta_monitor, G_TYPE_OBJECT)
+
+struct _MetaMonitorNormal
+{
+ MetaMonitor parent;
+};
+
+G_DEFINE_TYPE (MetaMonitorNormal, meta_monitor_normal, META_TYPE_MONITOR)
+
+struct _MetaMonitorTiled
+{
+ MetaMonitor parent;
+
+ uint32_t tile_group_id;
+
+ MetaOutput *main_output;
+};
+
+G_DEFINE_TYPE (MetaMonitorTiled, meta_monitor_tiled, META_TYPE_MONITOR)
+
+GList *
+meta_monitor_get_outputs (MetaMonitor *monitor)
+{
+ MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
+
+ return priv->outputs;
+}
+
+static MetaOutput *
+meta_monitor_get_main_output (MetaMonitor *monitor)
+{
+ return META_MONITOR_GET_CLASS (monitor)->get_main_output (monitor);
+}
+
+gboolean
+meta_monitor_is_active (MetaMonitor *monitor)
+{
+ MetaOutput *output;
+
+ output = meta_monitor_get_main_output (monitor);
+
+ return output->crtc && output->crtc->current_mode;
+}
+
+void
+meta_monitor_get_dimensions (MetaMonitor *monitor,
+ int *width,
+ int *height)
+{
+ META_MONITOR_GET_CLASS (monitor)->get_dimensions (monitor, width, height);
+}
+
+void
+meta_monitor_get_physical_dimensions (MetaMonitor *monitor,
+ int *width_mm,
+ int *height_mm)
+{
+ MetaOutput *output;
+
+ output = meta_monitor_get_main_output (monitor);
+ *width_mm = output->width_mm;
+ *height_mm = output->height_mm;
+}
+
+static void
+meta_monitor_finalize (GObject *object)
+{
+ MetaMonitor *monitor = META_MONITOR (object);
+ MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
+
+ g_clear_pointer (&priv->outputs, g_list_free);
+}
+
+static void
+meta_monitor_init (MetaMonitor *monitor)
+{
+}
+
+static void
+meta_monitor_class_init (MetaMonitorClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = meta_monitor_finalize;
+}
+
+MetaMonitorNormal *
+meta_monitor_normal_new (MetaOutput *output)
+{
+ MetaMonitorNormal *monitor_normal;
+ MetaMonitorPrivate *monitor_priv;
+
+ monitor_normal = g_object_new (META_TYPE_MONITOR_NORMAL, NULL);
+ monitor_priv =
+ meta_monitor_get_instance_private (META_MONITOR (monitor_normal));
+
+ monitor_priv->outputs = g_list_append (NULL, output);
+ monitor_priv->winsys_id = output->winsys_id;
+
+ return monitor_normal;
+}
+
+static MetaOutput *
+meta_monitor_normal_get_main_output (MetaMonitor *monitor)
+{
+ MetaMonitorPrivate *monitor_priv =
+ meta_monitor_get_instance_private (monitor);
+
+ return monitor_priv->outputs->data;
+}
+
+static void
+meta_monitor_normal_get_dimensions (MetaMonitor *monitor,
+ int *width,
+ int *height)
+{
+ MetaOutput *output;
+
+ output = meta_monitor_get_main_output (monitor);
+ *width = output->crtc->rect.width;
+ *height = output->crtc->rect.height;
+}
+
+static void
+meta_monitor_normal_init (MetaMonitorNormal *monitor)
+{
+}
+
+static void
+meta_monitor_normal_class_init (MetaMonitorNormalClass *klass)
+{
+ MetaMonitorClass *monitor_class = META_MONITOR_CLASS (klass);
+
+ monitor_class->get_main_output = meta_monitor_normal_get_main_output;
+ monitor_class->get_dimensions = meta_monitor_normal_get_dimensions;
+}
+
+static void
+add_tiled_monitor_outputs (MetaMonitorManager *monitor_manager,
+ MetaMonitorTiled *monitor_tiled)
+{
+ MetaMonitorPrivate *monitor_priv =
+ meta_monitor_get_instance_private (META_MONITOR (monitor_tiled));
+ unsigned int i;
+
+ for (i = 0; i < monitor_manager->n_outputs; i++)
+ {
+ MetaOutput *output = &monitor_manager->outputs[i];
+
+ if (output->tile_info.group_id != monitor_tiled->tile_group_id)
+ continue;
+
+ monitor_priv->outputs = g_list_append (monitor_priv->outputs, output);
+ }
+}
+
+MetaMonitorTiled *
+meta_monitor_tiled_new (MetaMonitorManager *monitor_manager,
+ MetaOutput *output)
+{
+ MetaMonitorTiled *monitor_tiled;
+ MetaMonitorPrivate *monitor_priv;
+
+ monitor_tiled = g_object_new (META_TYPE_MONITOR_TILED, NULL);
+ monitor_priv =
+ meta_monitor_get_instance_private (META_MONITOR (monitor_tiled));
+
+ monitor_tiled->tile_group_id = output->tile_info.group_id;
+ monitor_priv->winsys_id = output->winsys_id;
+
+ add_tiled_monitor_outputs (monitor_manager, monitor_tiled);
+ monitor_tiled->main_output = output;
+
+ return monitor_tiled;
+}
+
+static MetaOutput *
+meta_monitor_tiled_get_main_output (MetaMonitor *monitor)
+{
+ MetaMonitorTiled *monitor_tiled = META_MONITOR_TILED (monitor);
+
+ return monitor_tiled->main_output;
+}
+
+static void
+meta_monitor_tiled_get_dimensions (MetaMonitor *monitor,
+ int *out_width,
+ int *out_height)
+{
+ MetaMonitorPrivate *monitor_priv =
+ meta_monitor_get_instance_private (monitor);
+ GList *l;
+ int width;
+ int height;
+
+ width = 0;
+ height = 0;
+ for (l = monitor_priv->outputs; l; l = l->next)
+ {
+ MetaOutput *output = l->data;
+
+ if (output->tile_info.loc_v_tile == 0)
+ width += output->tile_info.tile_w;
+
+ if (output->tile_info.loc_h_tile == 0)
+ height += output->tile_info.tile_h;
+ }
+
+ *out_width = width;
+ *out_height = height;
+}
+
+static void
+meta_monitor_tiled_init (MetaMonitorTiled *monitor)
+{
+}
+
+static void
+meta_monitor_tiled_class_init (MetaMonitorTiledClass *klass)
+{
+ MetaMonitorClass *monitor_class = META_MONITOR_CLASS (klass);
+
+ monitor_class->get_main_output = meta_monitor_tiled_get_main_output;
+ monitor_class->get_dimensions = meta_monitor_tiled_get_dimensions;
+}
diff --git a/src/backends/meta-monitor.h b/src/backends/meta-monitor.h
new file mode 100644
index 0000000..b469e18
--- /dev/null
+++ b/src/backends/meta-monitor.h
@@ -0,0 +1,69 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2016 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_MONITOR_H
+#define META_MONITOR_H
+
+#include <glib-object.h>
+
+#include "backends/meta-monitor-manager-private.h"
+
+#define META_TYPE_MONITOR (meta_monitor_get_type ())
+G_DECLARE_DERIVABLE_TYPE (MetaMonitor, meta_monitor, META, MONITOR, GObject)
+
+struct _MetaMonitorClass
+{
+ GObjectClass parent_class;
+
+ MetaOutput * (* get_main_output) (MetaMonitor *monitor);
+ void (* get_dimensions) (MetaMonitor *monitor,
+ int *width,
+ int *height);
+};
+
+#define META_TYPE_MONITOR_NORMAL (meta_monitor_normal_get_type ())
+G_DECLARE_FINAL_TYPE (MetaMonitorNormal, meta_monitor_normal,
+ META, MONITOR_NORMAL,
+ MetaMonitor)
+
+#define META_TYPE_MONITOR_TILED (meta_monitor_tiled_get_type ())
+G_DECLARE_FINAL_TYPE (MetaMonitorTiled, meta_monitor_tiled,
+ META, MONITOR_TILED,
+ MetaMonitor)
+
+MetaMonitorTiled * meta_monitor_tiled_new (MetaMonitorManager *monitor_manager,
+ MetaOutput *main_output);
+
+MetaMonitorNormal * meta_monitor_normal_new (MetaOutput *output);
+
+gboolean meta_monitor_is_active (MetaMonitor *monitor);
+
+GList * meta_monitor_get_outputs (MetaMonitor *monitor);
+
+void meta_monitor_get_dimensions (MetaMonitor *monitor,
+ int *width,
+ int *height);
+
+void meta_monitor_get_physical_dimensions (MetaMonitor *monitor,
+ int *width_mm,
+ int *height_mm);
+
+#endif /* META_MONITOR_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]