[mutter/wip/carlosg/input-thread: 58/95] backends: Add simple object to delegate logical monitor layout queries




commit dc7c1311fecbb0fa31b035bde8fc27fd31f6bcbc
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Jul 16 13:52:39 2020 +0200

    backends: Add simple object to delegate logical monitor layout queries
    
    This object can be passed to random places, and be trusted to remain unchanged
    till replaced. Makes it an ideal replacement for MetaMonitorManager across
    threads.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403

 src/backends/meta-monitor-manager-private.h |   3 +
 src/backends/meta-monitor-manager.c         |  34 +++++
 src/backends/meta-viewport-info.c           | 189 ++++++++++++++++++++++++++++
 src/backends/meta-viewport-info.h           |  53 ++++++++
 src/meson.build                             |   2 +
 5 files changed, 281 insertions(+)
---
diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h
index ac3bc94d68..874c6e58b9 100644
--- a/src/backends/meta-monitor-manager-private.h
+++ b/src/backends/meta-monitor-manager-private.h
@@ -31,6 +31,7 @@
 #include "backends/meta-cursor.h"
 #include "backends/meta-display-config-shared.h"
 #include "backends/meta-monitor-transform.h"
+#include "backends/meta-viewport-info.h"
 #include "core/util-private.h"
 #include "meta/display.h"
 #include "meta/meta-monitor-manager.h"
@@ -409,4 +410,6 @@ meta_find_output_assignment (MetaOutputAssignment **outputs,
 
 void meta_monitor_manager_post_init (MetaMonitorManager *manager);
 
+MetaViewportInfo * meta_monitor_manager_get_viewports (MetaMonitorManager *manager);
+
 #endif /* META_MONITOR_MANAGER_PRIVATE_H */
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 1beb658bdf..0157f6ef4c 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -3247,3 +3247,37 @@ meta_monitor_manager_post_init (MetaMonitorManager *manager)
                            G_CALLBACK (update_panel_orientation_managed), manager,
                            G_CONNECT_SWAPPED);
 }
+
+MetaViewportInfo *
+meta_monitor_manager_get_viewports (MetaMonitorManager *manager)
+{
+  MetaViewportInfo *info;
+  GArray *views, *scales;
+  GList *logical_monitors, *l;
+
+  views = g_array_new (FALSE, FALSE, sizeof (cairo_rectangle_int_t));
+  scales = g_array_new (FALSE, FALSE, sizeof (float));
+
+  logical_monitors = meta_monitor_manager_get_logical_monitors (manager);
+
+  for (l = logical_monitors; l; l = l->next)
+    {
+      MetaLogicalMonitor *logical_monitor = l->data;
+      cairo_rectangle_int_t rect;
+      float scale;
+
+      rect = logical_monitor->rect;
+      g_array_append_val (views, rect);
+
+      scale = logical_monitor->scale;
+      g_array_append_val (scales, scale);
+    }
+
+  info = meta_viewport_info_new ((cairo_rectangle_int_t *) views->data,
+                                 (float *) scales->data,
+                                 views->len);
+  g_array_unref (views);
+  g_array_unref (scales);
+
+  return info;
+}
diff --git a/src/backends/meta-viewport-info.c b/src/backends/meta-viewport-info.c
new file mode 100644
index 0000000000..0e50dcbfea
--- /dev/null
+++ b/src/backends/meta-viewport-info.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ * Written by:
+ *     Carlos Garnacho <carlosg gnome org>
+ */
+
+#include "config.h"
+
+#include "meta-viewport-info.h"
+#include "core/main-private.h"
+#include "core/boxes-private.h"
+
+typedef struct _ViewInfo ViewInfo;
+
+struct _ViewInfo
+{
+  cairo_rectangle_int_t rect;
+  float scale;
+};
+
+struct _MetaViewportInfo
+{
+  GObject parent_class;
+  GArray *views;
+};
+
+G_DEFINE_TYPE (MetaViewportInfo, meta_viewport_info, G_TYPE_OBJECT)
+
+static void
+meta_viewport_info_finalize (GObject *object)
+{
+  MetaViewportInfo *info = META_VIEWPORT_INFO (object);
+
+  g_array_unref (info->views);
+
+  G_OBJECT_CLASS (meta_viewport_info_parent_class)->finalize (object);
+}
+
+static void
+meta_viewport_info_class_init (MetaViewportInfoClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = meta_viewport_info_finalize;
+}
+
+static void
+meta_viewport_info_init (MetaViewportInfo *info)
+{
+  info->views = g_array_new (FALSE, FALSE, sizeof (ViewInfo));
+}
+
+MetaViewportInfo *
+meta_viewport_info_new (cairo_rectangle_int_t *views,
+                        float                 *scales,
+                        guint                  n_views)
+{
+  MetaViewportInfo *viewport_info;
+  int i;
+
+  viewport_info = g_object_new (META_TYPE_VIEWPORT_INFO, NULL);
+
+  for (i = 0; i < n_views; i++)
+    {
+      ViewInfo info;
+
+      info.rect = views[i];
+      info.scale = scales[i];
+      g_array_append_val (viewport_info->views, info);
+    }
+
+  return viewport_info;
+}
+
+int
+meta_viewport_info_get_view_at (MetaViewportInfo *viewport_info,
+                                float             x,
+                                float             y)
+{
+  int i;
+
+  for (i = 0; i < viewport_info->views->len; i++)
+    {
+      ViewInfo *info = &g_array_index (viewport_info->views, ViewInfo, i);
+
+      if (META_POINT_IN_RECT (x, y, info->rect))
+        return i;
+    }
+
+  return -1;
+}
+
+gboolean
+meta_viewport_info_get_view (MetaViewportInfo      *viewport_info,
+                             int                    idx,
+                             cairo_rectangle_int_t *rect,
+                             float                 *scale)
+{
+  ViewInfo *info;
+
+  if (idx < 0 || idx >= viewport_info->views->len)
+    return FALSE;
+
+  info = &g_array_index (viewport_info->views, ViewInfo, idx);
+  if (rect)
+    *rect = info->rect;
+  if (scale)
+    *scale = info->scale;
+
+  return TRUE;
+}
+
+static gboolean
+view_has_neighbor (cairo_rectangle_int_t *view,
+                   cairo_rectangle_int_t *neighbor,
+                   MetaDisplayDirection   neighbor_direction)
+{
+  switch (neighbor_direction)
+    {
+    case META_DISPLAY_RIGHT:
+      if (neighbor->x == (view->x + view->width) &&
+          meta_rectangle_vert_overlap (neighbor, view))
+        return TRUE;
+      break;
+    case META_DISPLAY_LEFT:
+      if (view->x == (neighbor->x + neighbor->width) &&
+          meta_rectangle_vert_overlap (neighbor, view))
+        return TRUE;
+      break;
+    case META_DISPLAY_UP:
+      if (view->y == (neighbor->y + neighbor->height) &&
+          meta_rectangle_horiz_overlap (neighbor, view))
+        return TRUE;
+      break;
+    case META_DISPLAY_DOWN:
+      if (neighbor->y == (view->y + view->height) &&
+          meta_rectangle_horiz_overlap (neighbor, view))
+        return TRUE;
+      break;
+    }
+
+  return FALSE;
+}
+
+int
+meta_viewport_info_get_neighbor (MetaViewportInfo     *viewport_info,
+                                 int                   idx,
+                                 MetaDisplayDirection  direction)
+{
+  cairo_rectangle_int_t rect;
+  int i;
+
+  if (!meta_viewport_info_get_view (viewport_info, idx, &rect, NULL))
+    return -1;
+
+  for (i = 0; i < viewport_info->views->len; i++)
+    {
+      ViewInfo *info = &g_array_index (viewport_info->views, ViewInfo, i);
+
+      if (idx == i)
+        continue;
+      if (view_has_neighbor (&rect, &info->rect, direction))
+        return i;
+    }
+
+  return -1;
+}
+
+int
+meta_viewport_info_get_num_views (MetaViewportInfo *info)
+{
+  return info->views->len;
+}
diff --git a/src/backends/meta-viewport-info.h b/src/backends/meta-viewport-info.h
new file mode 100644
index 0000000000..c9a8818695
--- /dev/null
+++ b/src/backends/meta-viewport-info.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2020 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.
+ *
+ * Written by:
+ *     Carlos Garnacho <carlosg gnome org>
+ */
+
+#ifndef META_VIEWPORT_INFO_H
+#define META_VIEWPORT_INFO_H
+
+#include <cairo.h>
+#include <glib-object.h>
+
+#include "meta/display.h"
+
+#define META_TYPE_VIEWPORT_INFO (meta_viewport_info_get_type ())
+G_DECLARE_FINAL_TYPE (MetaViewportInfo, meta_viewport_info,
+                      META, VIEWPORT_INFO, GObject)
+
+MetaViewportInfo * meta_viewport_info_new (cairo_rectangle_int_t *views,
+                                           float                 *scales,
+                                           guint                  n_views);
+
+int meta_viewport_info_get_view_at (MetaViewportInfo *info,
+                                    float             x,
+                                    float             y);
+
+gboolean meta_viewport_info_get_view (MetaViewportInfo      *viewport_info,
+                                      int                    idx,
+                                      cairo_rectangle_int_t *rect,
+                                      float                 *scale);
+
+int meta_viewport_info_get_neighbor (MetaViewportInfo     *info,
+                                     int                   idx,
+                                     MetaDisplayDirection  direction);
+int meta_viewport_info_get_num_views (MetaViewportInfo *info);
+
+#endif /* META_VIEWPORT_INFO_H */
diff --git a/src/meson.build b/src/meson.build
index 8bdfd9f6d8..c55e7fe0df 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -233,6 +233,8 @@ mutter_sources = [
   'backends/meta-settings-private.h',
   'backends/meta-stage.c',
   'backends/meta-stage-private.h',
+  'backends/meta-viewport-info.c',
+  'backends/meta-viewport-info.h',
   'backends/x11/cm/meta-backend-x11-cm.c',
   'backends/x11/cm/meta-backend-x11-cm.h',
   'backends/x11/cm/meta-cursor-sprite-xfixes.c',


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