diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h index 1b7efd261..3ba8bcfc9 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" @@ -405,4 +406,6 @@ meta_find_output_assignment (MetaOutputAssignment **outputs, return NULL; } +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 a519442f3..b9879abdf 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -3175,3 +3175,37 @@ meta_monitor_manager_get_vendor_name (MetaMonitorManager *manager, return gnome_pnp_ids_get_pnp_id (manager->pnp_ids, vendor); } + +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 000000000..0e50dcbfe --- /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 + */ + +#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 000000000..c9a881869 --- /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 + */ + +#ifndef META_VIEWPORT_INFO_H +#define META_VIEWPORT_INFO_H + +#include +#include + +#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 9e7f48e17..b24f12d9c 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',