[gnome-flashback] backends: add GfLogicalMonitor
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback] backends: add GfLogicalMonitor
- Date: Mon, 11 Sep 2017 20:49:28 +0000 (UTC)
commit 61cc497fb2dc24a4afd82f047bce6cc50495549d
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Mon Sep 11 22:11:37 2017 +0300
backends: add GfLogicalMonitor
backends/Makefile.am | 3 +
backends/gf-logical-monitor-private.h | 87 +++++++++++
backends/gf-logical-monitor.c | 213 ++++++++++++++++++++++++++
backends/gf-monitor-config-manager-private.h | 49 ++++++
backends/gf-monitor-manager-private.h | 3 +
backends/gf-monitor-manager.c | 19 +++
6 files changed, 374 insertions(+), 0 deletions(-)
---
diff --git a/backends/Makefile.am b/backends/Makefile.am
index e768918..7f10f63 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -33,6 +33,9 @@ libbackends_la_SOURCES = \
gf-display-config-shared.h \
gf-edid-parse.c \
gf-edid-private.h \
+ gf-logical-monitor-private.h \
+ gf-logical-monitor.c \
+ gf-monitor-config-manager-private.h \
gf-monitor-manager-dummy-private.h \
gf-monitor-manager-dummy.c \
gf-monitor-manager-enums-private.h \
diff --git a/backends/gf-logical-monitor-private.h b/backends/gf-logical-monitor-private.h
new file mode 100644
index 0000000..00b6f8d
--- /dev/null
+++ b/backends/gf-logical-monitor-private.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2016 Red Hat
+ * Copyright (C) 2017 Alberts Muktupāvels
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Adapted from mutter:
+ * - src/backends/meta-logical-monitor.h
+ */
+
+#ifndef GF_LOGICAL_MONITOR_PRIVATE_H
+#define GF_LOGICAL_MONITOR_PRIVATE_H
+
+#include "gf-monitor-config-manager-private.h"
+#include "gf-monitor-manager-private.h"
+#include "gf-monitor-private.h"
+
+G_BEGIN_DECLS
+
+#define GF_TYPE_LOGICAL_MONITOR (gf_logical_monitor_get_type ())
+G_DECLARE_FINAL_TYPE (GfLogicalMonitor, gf_logical_monitor,
+ GF, LOGICAL_MONITOR, GObject)
+
+struct _GfLogicalMonitor
+{
+ GObject parent;
+
+ gint number;
+ GfRectangle rect;
+ gboolean is_primary;
+ gboolean is_presentation;
+ gboolean in_fullscreen;
+ gfloat scale;
+ GfMonitorTransform transform;
+
+ /* 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 GfOutput.
+ *
+ * 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).
+ */
+ glong winsys_id;
+
+ GList *monitors;
+};
+
+GfLogicalMonitor *gf_logical_monitor_new (GfMonitorManager *monitor_manager,
+ GfLogicalMonitorConfig *logical_monitor_config,
+ gint monitor_number);
+
+GfLogicalMonitor *gf_logical_monitor_new_derived (GfMonitorManager *monitor_manager,
+ GfMonitor *monitor,
+ GfRectangle *layout,
+ gfloat scale,
+ gint monitor_number);
+
+void gf_logical_monitor_add_monitor (GfLogicalMonitor *logical_monitor,
+ GfMonitor *monitor);
+
+gboolean gf_logical_monitor_is_primary (GfLogicalMonitor *logical_monitor);
+
+void gf_logical_monitor_make_primary (GfLogicalMonitor *logical_monitor);
+
+gfloat gf_logical_monitor_get_scale (GfLogicalMonitor *logical_monitor);
+
+GfMonitorTransform gf_logical_monitor_get_transform (GfLogicalMonitor *logical_monitor);
+
+GfRectangle gf_logical_monitor_get_layout (GfLogicalMonitor *logical_monitor);
+
+GList *gf_logical_monitor_get_monitors (GfLogicalMonitor *logical_monitor);
+
+G_END_DECLS
+
+#endif
diff --git a/backends/gf-logical-monitor.c b/backends/gf-logical-monitor.c
new file mode 100644
index 0000000..479d9b9
--- /dev/null
+++ b/backends/gf-logical-monitor.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2016 Red Hat
+ * Copyright (C) 2017 Alberts Muktupāvels
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Adapted from mutter:
+ * - src/backends/meta-logical-monitor.h
+ */
+
+#include "config.h"
+#include "gf-crtc-private.h"
+#include "gf-logical-monitor-private.h"
+#include "gf-output-private.h"
+
+typedef struct
+{
+ GfMonitorManager *monitor_manager;
+ GfLogicalMonitor *logical_monitor;
+} AddMonitorFromConfigData;
+
+G_DEFINE_TYPE (GfLogicalMonitor, gf_logical_monitor, G_TYPE_OBJECT)
+
+static void
+add_monitor_from_config (GfMonitorConfig *monitor_config,
+ AddMonitorFromConfigData *data)
+{
+ GfMonitorSpec *monitor_spec;
+ GfMonitor *monitor;
+
+ monitor_spec = monitor_config->monitor_spec;
+ monitor = gf_monitor_manager_get_monitor_from_spec (data->monitor_manager, monitor_spec);
+
+ gf_logical_monitor_add_monitor (data->logical_monitor, monitor);
+}
+
+static GfMonitor *
+get_first_monitor (GfMonitorManager *monitor_manager,
+ GList *monitor_configs)
+{
+ GfMonitorConfig *first_monitor_config;
+ GfMonitorSpec *first_monitor_spec;
+
+ first_monitor_config = g_list_first (monitor_configs)->data;
+ first_monitor_spec = first_monitor_config->monitor_spec;
+
+ return gf_monitor_manager_get_monitor_from_spec (monitor_manager, first_monitor_spec);
+}
+
+static GfMonitorTransform
+derive_monitor_transform (GfMonitor *monitor)
+{
+ GfOutput *main_output;
+
+ main_output = gf_monitor_get_main_output (monitor);
+
+ return main_output->crtc->transform;
+}
+
+static void
+gf_logical_monitor_class_init (GfLogicalMonitorClass *logical_monitor_class)
+{
+}
+
+static void
+gf_logical_monitor_init (GfLogicalMonitor *logical_monitor)
+{
+}
+
+GfLogicalMonitor *
+gf_logical_monitor_new (GfMonitorManager *monitor_manager,
+ GfLogicalMonitorConfig *logical_monitor_config,
+ gint monitor_number)
+{
+ GfLogicalMonitor *logical_monitor;
+ GList *monitor_configs;
+ GfMonitor *first_monitor;
+ GfOutput *main_output;
+ AddMonitorFromConfigData data;
+
+ logical_monitor = g_object_new (GF_TYPE_LOGICAL_MONITOR, NULL);
+
+ monitor_configs = logical_monitor_config->monitor_configs;
+ first_monitor = get_first_monitor (monitor_manager, monitor_configs);
+ main_output = gf_monitor_get_main_output (first_monitor);
+
+ logical_monitor->number = monitor_number;
+ logical_monitor->winsys_id = main_output->winsys_id;
+ logical_monitor->scale = logical_monitor_config->scale;
+ logical_monitor->transform = logical_monitor_config->transform;
+ logical_monitor->in_fullscreen = -1;
+ logical_monitor->rect = logical_monitor_config->layout;
+
+ logical_monitor->is_presentation = TRUE;
+
+ data.monitor_manager = monitor_manager;
+ data.logical_monitor = logical_monitor;
+
+ g_list_foreach (monitor_configs, (GFunc) add_monitor_from_config, &data);
+
+ return logical_monitor;
+}
+
+GfLogicalMonitor *
+gf_logical_monitor_new_derived (GfMonitorManager *monitor_manager,
+ GfMonitor *monitor,
+ GfRectangle *layout,
+ gfloat scale,
+ gint monitor_number)
+{
+ GfLogicalMonitor *logical_monitor;
+ GfMonitorTransform transform;
+ GfOutput *main_output;
+
+ logical_monitor = g_object_new (GF_TYPE_LOGICAL_MONITOR, NULL);
+
+ transform = derive_monitor_transform (monitor);
+ main_output = gf_monitor_get_main_output (monitor);
+
+ logical_monitor->number = monitor_number;
+ logical_monitor->winsys_id = main_output->winsys_id;
+ logical_monitor->scale = scale;
+ logical_monitor->transform = transform;
+ logical_monitor->in_fullscreen = -1;
+ logical_monitor->rect = *layout;
+
+ logical_monitor->is_presentation = TRUE;
+
+ gf_logical_monitor_add_monitor (logical_monitor, monitor);
+
+ return logical_monitor;
+}
+
+void
+gf_logical_monitor_add_monitor (GfLogicalMonitor *logical_monitor,
+ GfMonitor *monitor)
+{
+ gboolean is_presentation;
+ GList *l;
+
+ is_presentation = logical_monitor->is_presentation;
+ logical_monitor->monitors = g_list_append (logical_monitor->monitors, monitor);
+
+ for (l = logical_monitor->monitors; l; l = l->next)
+ {
+ GfMonitor *l_monitor;
+ GList *outputs;
+ GList *l_output;
+
+ l_monitor = l->data;
+ outputs = gf_monitor_get_outputs (l_monitor);
+
+ for (l_output = outputs; l_output; l_output = l_output->next)
+ {
+ GfOutput *output;
+
+ output = l_output->data;
+ is_presentation = is_presentation && output->is_presentation;
+
+ if (output->crtc)
+ output->crtc->logical_monitor = logical_monitor;
+ }
+ }
+
+ logical_monitor->is_presentation = is_presentation;
+}
+
+gboolean
+gf_logical_monitor_is_primary (GfLogicalMonitor *logical_monitor)
+{
+ return logical_monitor->is_primary;
+}
+
+void
+gf_logical_monitor_make_primary (GfLogicalMonitor *logical_monitor)
+{
+ logical_monitor->is_primary = TRUE;
+}
+
+gfloat
+gf_logical_monitor_get_scale (GfLogicalMonitor *logical_monitor)
+{
+ return logical_monitor->scale;
+}
+
+GfMonitorTransform
+gf_logical_monitor_get_transform (GfLogicalMonitor *logical_monitor)
+{
+ return logical_monitor->transform;
+}
+
+GfRectangle
+gf_logical_monitor_get_layout (GfLogicalMonitor *logical_monitor)
+{
+ return logical_monitor->rect;
+}
+
+GList *
+gf_logical_monitor_get_monitors (GfLogicalMonitor *logical_monitor)
+{
+ return logical_monitor->monitors;
+}
diff --git a/backends/gf-monitor-config-manager-private.h b/backends/gf-monitor-config-manager-private.h
new file mode 100644
index 0000000..1cf5b1d
--- /dev/null
+++ b/backends/gf-monitor-config-manager-private.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 Red Hat
+ * Copyright (C) 2017 Alberts Muktupāvels
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Adapted from mutter:
+ * - src/backends/meta-monitor-config-manager.h
+ */
+
+#ifndef GF_MONITOR_CONFIG_MANAGER_PRIVATE_H
+#define GF_MONITOR_CONFIG_MANAGER_PRIVATE_H
+
+#include "gf-monitor-manager-private.h"
+#include "gf-monitor-private.h"
+
+G_BEGIN_DECLS
+
+typedef struct
+{
+ GfMonitorSpec *monitor_spec;
+ GfMonitorModeSpec *mode_spec;
+ gboolean enable_underscanning;
+} GfMonitorConfig;
+
+typedef struct
+{
+ GfRectangle layout;
+ GList *monitor_configs;
+ GfMonitorTransform transform;
+ gfloat scale;
+ gboolean is_primary;
+ gboolean is_presentation;
+} GfLogicalMonitorConfig;
+
+G_END_DECLS
+
+#endif
diff --git a/backends/gf-monitor-manager-private.h b/backends/gf-monitor-manager-private.h
index 5b16dbd..06dbf0b 100644
--- a/backends/gf-monitor-manager-private.h
+++ b/backends/gf-monitor-manager-private.h
@@ -159,6 +159,9 @@ GType gf_monitor_manager_get_type (void);
GfBackend *gf_monitor_manager_get_backend (GfMonitorManager *manager);
+GfMonitor *gf_monitor_manager_get_monitor_from_spec (GfMonitorManager *manager,
+ GfMonitorSpec *monitor_spec);
+
void gf_monitor_manager_tiled_monitor_added (GfMonitorManager *manager,
GfMonitor *monitor);
diff --git a/backends/gf-monitor-manager.c b/backends/gf-monitor-manager.c
index d0b6165..902a982 100644
--- a/backends/gf-monitor-manager.c
+++ b/backends/gf-monitor-manager.c
@@ -27,6 +27,8 @@
#include "config.h"
#include "gf-monitor-manager-private.h"
+#include "gf-monitor-spec-private.h"
+#include "gf-monitor-private.h"
typedef struct
{
@@ -328,6 +330,23 @@ gf_monitor_manager_get_backend (GfMonitorManager *manager)
return priv->backend;
}
+GfMonitor *
+gf_monitor_manager_get_monitor_from_spec (GfMonitorManager *manager,
+ GfMonitorSpec *monitor_spec)
+{
+ GList *l;
+
+ for (l = manager->monitors; l; l = l->next)
+ {
+ GfMonitor *monitor = l->data;
+
+ if (gf_monitor_spec_equals (gf_monitor_get_spec (monitor), monitor_spec))
+ return monitor;
+ }
+
+ return NULL;
+}
+
void
gf_monitor_manager_tiled_monitor_added (GfMonitorManager *manager,
GfMonitor *monitor)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]