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:
parent
bbb34c2a80
commit
0d23eb1da8
3 changed files with 189 additions and 164 deletions
|
@ -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,88 +1887,13 @@ 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,
|
||||
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);
|
||||
if (!meta_verify_logical_monitor_config_list (config->logical_monitor_configs,
|
||||
config->layout_mode,
|
||||
monitor_manager,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
for (l = config->disabled_monitor_specs; l; l = l->next)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue