1
0
Fork 0

monitor-config-manager: Move verification of logical monitor configs into utils

We'll need these verification utilities in the next commits where we introduce
detection for physical vs logical layout modes.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3596>
This commit is contained in:
Jonas Dreßler 2024-02-19 01:00:10 +01:00 committed by Marge Bot
parent bbb34c2a80
commit 0d23eb1da8
3 changed files with 189 additions and 164 deletions

View file

@ -1850,76 +1850,6 @@ meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor
return TRUE;
}
static GList *
find_adjacent_neighbours (GList *logical_monitor_configs,
MetaLogicalMonitorConfig *logical_monitor_config)
{
GList *adjacent_neighbors = NULL;
GList *l;
if (!logical_monitor_configs->next)
{
g_assert (logical_monitor_configs->data == logical_monitor_config);
return NULL;
}
for (l = logical_monitor_configs; l; l = l->next)
{
MetaLogicalMonitorConfig *other_logical_monitor_config = l->data;
if (logical_monitor_config == other_logical_monitor_config)
continue;
if (mtk_rectangle_is_adjacent_to (&logical_monitor_config->layout,
&other_logical_monitor_config->layout))
{
adjacent_neighbors = g_list_prepend (adjacent_neighbors,
other_logical_monitor_config);
}
}
return adjacent_neighbors;
}
static void
traverse_new_neighbours (GList *logical_monitor_configs,
MetaLogicalMonitorConfig *logical_monitor_config,
GHashTable *neighbourhood)
{
g_autoptr (GList) adjacent_neighbours = NULL;
GList *l;
g_hash_table_add (neighbourhood, logical_monitor_config);
adjacent_neighbours = find_adjacent_neighbours (logical_monitor_configs,
logical_monitor_config);
for (l = adjacent_neighbours; l; l = l->next)
{
MetaLogicalMonitorConfig *neighbour = l->data;
if (g_hash_table_contains (neighbourhood, neighbour))
continue;
traverse_new_neighbours (logical_monitor_configs, neighbour, neighbourhood);
}
}
static gboolean
is_connected_to_all (MetaLogicalMonitorConfig *logical_monitor_config,
GList *logical_monitor_configs)
{
g_autoptr (GHashTable) neighbourhood = NULL;
neighbourhood = g_hash_table_new (NULL, NULL);
traverse_new_neighbours (logical_monitor_configs,
logical_monitor_config,
neighbourhood);
return g_hash_table_size (neighbourhood) == g_list_length (logical_monitor_configs);
}
gboolean
meta_logical_monitor_configs_have_monitor (GList *logical_monitor_configs,
MetaMonitorSpec *monitor_spec)
@ -1957,89 +1887,14 @@ meta_verify_monitors_config (MetaMonitorsConfig *config,
MetaMonitorManager *monitor_manager,
GError **error)
{
int min_x, min_y;
gboolean has_primary;
GList *region;
GList *l;
gboolean global_scale_required;
if (!config->logical_monitor_configs)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Monitors config incomplete");
return FALSE;
}
global_scale_required =
!!(meta_monitor_manager_get_capabilities (monitor_manager) &
META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED);
min_x = INT_MAX;
min_y = INT_MAX;
region = NULL;
has_primary = FALSE;
for (l = config->logical_monitor_configs; l; l = l->next)
{
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
if (!meta_verify_logical_monitor_config (logical_monitor_config,
if (!meta_verify_logical_monitor_config_list (config->logical_monitor_configs,
config->layout_mode,
monitor_manager,
error))
return FALSE;
if (global_scale_required)
{
MetaLogicalMonitorConfig *prev_logical_monitor_config =
l->prev ? l->prev->data : NULL;
if (prev_logical_monitor_config &&
(prev_logical_monitor_config->scale !=
logical_monitor_config->scale))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Logical monitor scales must be identical");
return FALSE;
}
}
if (meta_rectangle_overlaps_with_region (region,
&logical_monitor_config->layout))
{
g_list_free (region);
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Logical monitors overlap");
return FALSE;
}
if (has_primary && logical_monitor_config->is_primary)
{
g_list_free (region);
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Config contains multiple primary logical monitors");
return FALSE;
}
else if (logical_monitor_config->is_primary)
{
has_primary = TRUE;
}
if (!is_connected_to_all (logical_monitor_config, config->logical_monitor_configs))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Logical monitors not adjacent");
return FALSE;
}
min_x = MIN (logical_monitor_config->layout.x, min_x);
min_y = MIN (logical_monitor_config->layout.y, min_y);
region = g_list_prepend (region, &logical_monitor_config->layout);
}
g_list_free (region);
for (l = config->disabled_monitor_specs; l; l = l->next)
{
MetaMonitorSpec *monitor_spec = l->data;
@ -2052,19 +1907,5 @@ meta_verify_monitors_config (MetaMonitorsConfig *config,
}
}
if (min_x != 0 || min_y != 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Logical monitors positions are offset");
return FALSE;
}
if (!has_primary)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Config is missing primary logical");
return FALSE;
}
return TRUE;
}

View file

@ -23,6 +23,7 @@
#include "backends/meta-backend-private.h"
#include "backends/meta-monitor-config-store.h"
#include "backends/meta-monitor-manager-private.h"
#include "core/boxes-private.h"
#include "meta/meta-monitor-manager.h"
static GList *
@ -76,3 +77,179 @@ meta_clone_logical_monitor_config_list (GList *logical_monitor_configs_in)
return logical_monitor_configs_out;
}
static GList *
find_adjacent_neighbours (GList *logical_monitor_configs,
MetaLogicalMonitorConfig *logical_monitor_config)
{
GList *adjacent_neighbors = NULL;
GList *l;
if (!logical_monitor_configs->next)
{
g_assert (logical_monitor_configs->data == logical_monitor_config);
return NULL;
}
for (l = logical_monitor_configs; l; l = l->next)
{
MetaLogicalMonitorConfig *other_logical_monitor_config = l->data;
if (logical_monitor_config == other_logical_monitor_config)
continue;
if (mtk_rectangle_is_adjacent_to (&logical_monitor_config->layout,
&other_logical_monitor_config->layout))
{
adjacent_neighbors = g_list_prepend (adjacent_neighbors,
other_logical_monitor_config);
}
}
return adjacent_neighbors;
}
static void
traverse_new_neighbours (GList *logical_monitor_configs,
MetaLogicalMonitorConfig *logical_monitor_config,
GHashTable *neighbourhood)
{
g_autoptr (GList) adjacent_neighbours = NULL;
GList *l;
g_hash_table_add (neighbourhood, logical_monitor_config);
adjacent_neighbours = find_adjacent_neighbours (logical_monitor_configs,
logical_monitor_config);
for (l = adjacent_neighbours; l; l = l->next)
{
MetaLogicalMonitorConfig *neighbour = l->data;
if (g_hash_table_contains (neighbourhood, neighbour))
continue;
traverse_new_neighbours (logical_monitor_configs, neighbour, neighbourhood);
}
}
static gboolean
is_connected_to_all (MetaLogicalMonitorConfig *logical_monitor_config,
GList *logical_monitor_configs)
{
g_autoptr (GHashTable) neighbourhood = NULL;
neighbourhood = g_hash_table_new (NULL, NULL);
traverse_new_neighbours (logical_monitor_configs,
logical_monitor_config,
neighbourhood);
return g_hash_table_size (neighbourhood) == g_list_length (logical_monitor_configs);
}
gboolean
meta_verify_logical_monitor_config_list (GList *logical_monitor_configs,
MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitorManager *monitor_manager,
GError **error)
{
int min_x, min_y;
gboolean has_primary;
GList *region;
GList *l;
gboolean global_scale_required;
if (!logical_monitor_configs)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Monitors config incomplete");
return FALSE;
}
global_scale_required =
!!(meta_monitor_manager_get_capabilities (monitor_manager) &
META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED);
min_x = INT_MAX;
min_y = INT_MAX;
region = NULL;
has_primary = FALSE;
for (l = logical_monitor_configs; l; l = l->next)
{
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
if (!meta_verify_logical_monitor_config (logical_monitor_config,
layout_mode,
monitor_manager,
error))
return FALSE;
if (global_scale_required)
{
MetaLogicalMonitorConfig *prev_logical_monitor_config =
l->prev ? l->prev->data : NULL;
if (prev_logical_monitor_config &&
(prev_logical_monitor_config->scale !=
logical_monitor_config->scale))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Logical monitor scales must be identical");
return FALSE;
}
}
if (meta_rectangle_overlaps_with_region (region,
&logical_monitor_config->layout))
{
g_list_free (region);
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Logical monitors overlap");
return FALSE;
}
if (has_primary && logical_monitor_config->is_primary)
{
g_list_free (region);
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Config contains multiple primary logical monitors");
return FALSE;
}
else if (logical_monitor_config->is_primary)
{
has_primary = TRUE;
}
if (!is_connected_to_all (logical_monitor_config, logical_monitor_configs))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Logical monitors not adjacent");
return FALSE;
}
min_x = MIN (logical_monitor_config->layout.x, min_x);
min_y = MIN (logical_monitor_config->layout.y, min_y);
region = g_list_prepend (region, &logical_monitor_config->layout);
}
g_list_free (region);
if (min_x != 0 || min_y != 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Logical monitors positions are offset");
return FALSE;
}
if (!has_primary)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Config is missing primary logical");
return FALSE;
}
return TRUE;
}

View file

@ -19,4 +19,11 @@
#include <glib.h>
#include "backends/meta-monitor-manager-private.h"
GList * meta_clone_logical_monitor_config_list (GList *logical_monitor_configs_in);
gboolean meta_verify_logical_monitor_config_list (GList *logical_monitor_configs,
MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitorManager *monitor_manager,
GError **error);