Introduce new monitor configuration system
The new monitor configuration system (MetaMonitorConfigManager) aims to replace the current MetaMonitorConfig. The main difference between the two is that MetaMonitorConfigManager works with higher level input (MetaMonitor, MetaMonitorMode) instead of directly looking at the CRTC and connector state. It still produces CRTC and connector configuration later applied by the respective backends. Other difference the new system aims to introduce is that the configuration system doesn't manipulate the monitor manager state; that responsibility is left for the monitor manager to handle (it only manages configuration and creates CRTC/connector assignments, it doesn't apply anything). The new configuration system allows backends to not rely on deriving the current configuration from the CRTC/connector state, as this may no longer be possible (i.e. when using KMS and multiple framebuffers). The MetaMonitorConfigManager system is so far disabled by default, as it does not yet have all the features of the old system, but eventually it will replace MetaMonitorConfig which will at that point be removed. This will make it possible to remove old hacks introduced due to limitations in the old system. https://bugzilla.gnome.org/show_bug.cgi?id=777732
This commit is contained in:
@ -39,6 +39,7 @@
|
||||
#include "meta-monitor-config.h"
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "backends/meta-monitor.h"
|
||||
#include "backends/meta-monitor-config-manager.h"
|
||||
#include "backends/x11/meta-monitor-manager-xrandr.h"
|
||||
#include "meta-backend-private.h"
|
||||
|
||||
@ -106,6 +107,85 @@ logical_monitor_from_layout (MetaMonitorManager *manager,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static MetaLogicalMonitor *
|
||||
create_logical_monitor_from_config (MetaMonitorManager *manager,
|
||||
MetaLogicalMonitorConfig *logical_monitor_config,
|
||||
int monitor_number)
|
||||
{
|
||||
MetaLogicalMonitor *logical_monitor;
|
||||
GList *monitor_configs;
|
||||
MetaMonitorConfig *first_monitor_config;
|
||||
MetaMonitorSpec *first_monitor_spec;
|
||||
MetaMonitor *first_monitor;
|
||||
GList *l;
|
||||
|
||||
monitor_configs = logical_monitor_config->monitor_configs;
|
||||
first_monitor_config = g_list_first (monitor_configs)->data;
|
||||
first_monitor_spec = first_monitor_config->monitor_spec;
|
||||
first_monitor =
|
||||
meta_monitor_manager_get_monitor_from_spec (manager, first_monitor_spec);
|
||||
|
||||
/* Create logical monitor from the first monitor. */
|
||||
logical_monitor = meta_logical_monitor_new (first_monitor,
|
||||
logical_monitor_config->layout.x,
|
||||
logical_monitor_config->layout.y,
|
||||
monitor_number);
|
||||
|
||||
/* Add the other monitors. */
|
||||
for (l = monitor_configs->next; l; l = l->next)
|
||||
{
|
||||
MetaMonitorConfig *monitor_config = l->data;
|
||||
MetaMonitorSpec *monitor_spec;
|
||||
MetaMonitor *monitor;
|
||||
|
||||
monitor_spec = monitor_config->monitor_spec;
|
||||
monitor = meta_monitor_manager_get_monitor_from_spec (manager,
|
||||
monitor_spec);
|
||||
|
||||
meta_logical_monitor_add_monitor (logical_monitor, monitor);
|
||||
}
|
||||
|
||||
return logical_monitor;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_rebuild_logical_monitors (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config)
|
||||
{
|
||||
GList *logical_monitors = NULL;
|
||||
GList *l;
|
||||
int monitor_number = 0;
|
||||
MetaLogicalMonitor *primary_logical_monitor = NULL;
|
||||
|
||||
for (l = config->logical_monitor_configs; l; l = l->next)
|
||||
{
|
||||
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
|
||||
MetaLogicalMonitor *logical_monitor;
|
||||
|
||||
logical_monitor =
|
||||
create_logical_monitor_from_config (manager,
|
||||
logical_monitor_config,
|
||||
monitor_number);
|
||||
monitor_number++;
|
||||
|
||||
if (logical_monitor_config->is_primary)
|
||||
primary_logical_monitor = logical_monitor;
|
||||
|
||||
logical_monitors = g_list_append (logical_monitors, logical_monitor);
|
||||
}
|
||||
|
||||
/*
|
||||
* If no monitor was marked as primary, fall back on marking the first
|
||||
* logical monitor the primary one.
|
||||
*/
|
||||
if (!primary_logical_monitor && logical_monitors)
|
||||
primary_logical_monitor = g_list_first (logical_monitors)->data;
|
||||
|
||||
manager->logical_monitors = logical_monitors;
|
||||
meta_monitor_manager_set_primary_logical_monitor (manager,
|
||||
primary_logical_monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
derive_monitor_position (MetaMonitor *monitor,
|
||||
int *x,
|
||||
@ -206,6 +286,17 @@ meta_monitor_manager_ensure_initial_config (MetaMonitorManager *manager)
|
||||
META_MONITOR_MANAGER_GET_CLASS (manager)->ensure_initial_config (manager);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_monitor_manager_apply_monitors_config (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config,
|
||||
GError **error)
|
||||
{
|
||||
MetaMonitorManagerClass *manager_class =
|
||||
META_MONITOR_MANAGER_GET_CLASS (manager);
|
||||
|
||||
return manager_class->apply_monitors_config (manager, config, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager)
|
||||
{
|
||||
@ -229,10 +320,52 @@ legacy_ensure_configured (MetaMonitorManager *manager)
|
||||
meta_monitor_config_make_default (manager->legacy_config, manager);
|
||||
}
|
||||
|
||||
void
|
||||
MetaMonitorsConfig *
|
||||
meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
|
||||
{
|
||||
legacy_ensure_configured (manager);
|
||||
MetaMonitorsConfig *config = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!manager->config_manager)
|
||||
{
|
||||
legacy_ensure_configured (manager);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
config = meta_monitor_config_manager_create_linear (manager->config_manager);
|
||||
if (!meta_monitor_manager_apply_monitors_config (manager, config, &error))
|
||||
{
|
||||
g_clear_object (&config);
|
||||
g_warning ("Failed to use linear monitor configuration: %s",
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
else
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
|
||||
config = meta_monitor_config_manager_create_fallback (manager->config_manager);
|
||||
if (!meta_monitor_manager_apply_monitors_config (manager, config, &error))
|
||||
{
|
||||
g_clear_object (&config);
|
||||
g_warning ("Failed to use fallback monitor configuration: %s",
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
else
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
if (!config)
|
||||
meta_fatal ("Failed to find any working monitor configuration, giving up");
|
||||
|
||||
meta_monitor_config_manager_set_current (manager->config_manager, config);
|
||||
g_object_unref (config);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -245,7 +378,10 @@ meta_monitor_manager_constructed (GObject *object)
|
||||
|
||||
manager->in_init = TRUE;
|
||||
|
||||
manager->legacy_config = meta_monitor_config_new ();
|
||||
if (g_strcmp0 (g_getenv ("MUTTER_USE_CONFIG_MANAGER"), "1") == 0)
|
||||
manager->config_manager = meta_monitor_config_manager_new (manager);
|
||||
else
|
||||
manager->legacy_config = meta_monitor_config_new ();
|
||||
|
||||
meta_monitor_manager_read_current_state (manager);
|
||||
|
||||
@ -353,6 +489,8 @@ meta_monitor_manager_dispose (GObject *object)
|
||||
manager->dbus_name_id = 0;
|
||||
}
|
||||
|
||||
g_clear_object (&manager->config_manager);
|
||||
|
||||
G_OBJECT_CLASS (meta_monitor_manager_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@ -704,7 +842,10 @@ save_config_timeout (gpointer user_data)
|
||||
{
|
||||
MetaMonitorManager *manager = user_data;
|
||||
|
||||
legacy_restore_previous_config (manager);
|
||||
if (manager->config_manager)
|
||||
g_assert (!"missing implementation");
|
||||
else
|
||||
legacy_restore_previous_config (manager);
|
||||
|
||||
manager->persistent_timeout_id = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
@ -728,6 +869,14 @@ meta_monitor_manager_legacy_handle_apply_configuration (MetaDBusDisplayConfig *
|
||||
guint output_index;
|
||||
GPtrArray *crtc_infos, *output_infos;
|
||||
|
||||
if (manager->config_manager)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Used old configuration API with new configuration system");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (serial != manager->serial)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
@ -968,7 +1117,10 @@ meta_monitor_manager_confirm_configuration (MetaMonitorManager *manager,
|
||||
g_source_remove (manager->persistent_timeout_id);
|
||||
manager->persistent_timeout_id = 0;
|
||||
|
||||
legacy_confirm_configuration (manager, ok);
|
||||
if (manager->config_manager)
|
||||
g_assert (!"not implemented");
|
||||
else
|
||||
legacy_confirm_configuration (manager, ok);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -1543,6 +1695,79 @@ meta_monitor_manager_notify_monitors_changed (MetaMonitorManager *manager)
|
||||
g_signal_emit_by_name (manager, "monitors-changed");
|
||||
}
|
||||
|
||||
static void
|
||||
set_logical_monitor_modes (MetaMonitorManager *manager,
|
||||
MetaLogicalMonitorConfig *logical_monitor_config)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = logical_monitor_config->monitor_configs; l; l = l->next)
|
||||
{
|
||||
MetaMonitorConfig *monitor_config = l->data;
|
||||
MetaMonitorSpec *monitor_spec;
|
||||
MetaMonitor *monitor;
|
||||
MetaMonitorModeSpec *monitor_mode_spec;
|
||||
MetaMonitorMode *monitor_mode;
|
||||
|
||||
monitor_spec = monitor_config->monitor_spec;
|
||||
monitor = meta_monitor_manager_get_monitor_from_spec (manager,
|
||||
monitor_spec);
|
||||
monitor_mode_spec = monitor_config->mode_spec;
|
||||
monitor_mode = meta_monitor_get_mode_from_spec (monitor,
|
||||
monitor_mode_spec);
|
||||
|
||||
meta_monitor_set_current_mode (monitor, monitor_mode);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_update_monitor_modes (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = config->logical_monitor_configs; l; l = l->next)
|
||||
{
|
||||
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
|
||||
|
||||
set_logical_monitor_modes (manager, logical_monitor_config);
|
||||
}
|
||||
|
||||
for (l = manager->monitors; l; l = l->next)
|
||||
{
|
||||
MetaMonitor *monitor = l->data;
|
||||
|
||||
if (!meta_monitor_get_logical_monitor (monitor))
|
||||
meta_monitor_set_current_mode (monitor, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_manager_update_logical_state (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config)
|
||||
{
|
||||
meta_monitor_manager_rebuild_logical_monitors (manager, config);
|
||||
meta_monitor_manager_update_monitor_modes (manager, config);
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_manager_rebuild (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config)
|
||||
{
|
||||
GList *old_logical_monitors;
|
||||
|
||||
if (manager->in_init)
|
||||
return;
|
||||
|
||||
old_logical_monitors = manager->logical_monitors;
|
||||
|
||||
meta_monitor_manager_update_logical_state (manager, config);
|
||||
|
||||
meta_monitor_manager_notify_monitors_changed (manager);
|
||||
|
||||
g_list_free_full (old_logical_monitors, g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_update_monitor_modes_derived (MetaMonitorManager *manager)
|
||||
{
|
||||
@ -1664,7 +1889,13 @@ legacy_on_hotplug (MetaMonitorManager *manager)
|
||||
void
|
||||
meta_monitor_manager_on_hotplug (MetaMonitorManager *manager)
|
||||
{
|
||||
legacy_on_hotplug (manager);
|
||||
if (manager->legacy_config)
|
||||
{
|
||||
legacy_on_hotplug (manager);
|
||||
return;
|
||||
}
|
||||
|
||||
meta_monitor_manager_ensure_configured (manager);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
Reference in New Issue
Block a user