[gnome-flashback] backends: add GfLogicalMonitor



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]