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;
|
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
|
gboolean
|
||||||
meta_logical_monitor_configs_have_monitor (GList *logical_monitor_configs,
|
meta_logical_monitor_configs_have_monitor (GList *logical_monitor_configs,
|
||||||
MetaMonitorSpec *monitor_spec)
|
MetaMonitorSpec *monitor_spec)
|
||||||
|
@ -1957,89 +1887,14 @@ meta_verify_monitors_config (MetaMonitorsConfig *config,
|
||||||
MetaMonitorManager *monitor_manager,
|
MetaMonitorManager *monitor_manager,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
int min_x, min_y;
|
|
||||||
gboolean has_primary;
|
|
||||||
GList *region;
|
|
||||||
GList *l;
|
GList *l;
|
||||||
gboolean global_scale_required;
|
|
||||||
|
|
||||||
if (!config->logical_monitor_configs)
|
if (!meta_verify_logical_monitor_config_list (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,
|
config->layout_mode,
|
||||||
monitor_manager,
|
monitor_manager,
|
||||||
error))
|
error))
|
||||||
return FALSE;
|
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)
|
for (l = config->disabled_monitor_specs; l; l = l->next)
|
||||||
{
|
{
|
||||||
MetaMonitorSpec *monitor_spec = l->data;
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "backends/meta-backend-private.h"
|
#include "backends/meta-backend-private.h"
|
||||||
#include "backends/meta-monitor-config-store.h"
|
#include "backends/meta-monitor-config-store.h"
|
||||||
#include "backends/meta-monitor-manager-private.h"
|
#include "backends/meta-monitor-manager-private.h"
|
||||||
|
#include "core/boxes-private.h"
|
||||||
#include "meta/meta-monitor-manager.h"
|
#include "meta/meta-monitor-manager.h"
|
||||||
|
|
||||||
static GList *
|
static GList *
|
||||||
|
@ -76,3 +77,179 @@ meta_clone_logical_monitor_config_list (GList *logical_monitor_configs_in)
|
||||||
|
|
||||||
return logical_monitor_configs_out;
|
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 <glib.h>
|
||||||
|
|
||||||
|
#include "backends/meta-monitor-manager-private.h"
|
||||||
|
|
||||||
GList * meta_clone_logical_monitor_config_list (GList *logical_monitor_configs_in);
|
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