diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c index d40c2e0c4..cdc9fb775 100644 --- a/src/backends/meta-monitor-config-manager.c +++ b/src/backends/meta-monitor-config-manager.c @@ -612,7 +612,9 @@ meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_mana x += logical_monitor_config->layout.width; } - return meta_monitors_config_new (logical_monitor_configs, layout_mode, + return meta_monitors_config_new (monitor_manager, + logical_monitor_configs, + layout_mode, META_MONITORS_CONFIG_FLAG_NONE); } @@ -641,7 +643,9 @@ meta_monitor_config_manager_create_fallback (MetaMonitorConfigManager *config_ma logical_monitor_configs = g_list_append (NULL, primary_logical_monitor_config); - return meta_monitors_config_new (logical_monitor_configs, layout_mode, + return meta_monitors_config_new (monitor_manager, + logical_monitor_configs, + layout_mode, META_MONITORS_CONFIG_FLAG_NONE); } @@ -717,7 +721,9 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m if (!logical_monitor_configs) return NULL; - return meta_monitors_config_new (logical_monitor_configs, layout_mode, + return meta_monitors_config_new (monitor_manager, + logical_monitor_configs, + layout_mode, META_MONITORS_CONFIG_FLAG_NONE); } @@ -726,8 +732,11 @@ create_for_builtin_display_rotation (MetaMonitorConfigManager *config_manager, gboolean rotate, MetaMonitorTransform transform) { + MetaMonitorManager *monitor_manager = config_manager->monitor_manager; MetaLogicalMonitorConfig *logical_monitor_config; MetaLogicalMonitorConfig *current_logical_monitor_config; + GList *logical_monitor_configs; + MetaLogicalMonitorLayoutMode layout_mode; MetaMonitorConfig *monitor_config; MetaMonitorConfig *current_monitor_config; @@ -772,8 +781,11 @@ create_for_builtin_display_rotation (MetaMonitorConfigManager *config_manager, logical_monitor_config->layout.height = temp; } - return meta_monitors_config_new (g_list_append (NULL, logical_monitor_config), - config_manager->current_config->layout_mode, + logical_monitor_configs = g_list_append (NULL, logical_monitor_config); + layout_mode = config_manager->current_config->layout_mode; + return meta_monitors_config_new (monitor_manager, + logical_monitor_configs, + layout_mode, META_MONITORS_CONFIG_FLAG_NONE); } @@ -796,6 +808,7 @@ create_for_switch_config_all_mirror (MetaMonitorConfigManager *config_manager) MetaMonitorManager *monitor_manager = config_manager->monitor_manager; MetaLogicalMonitorLayoutMode layout_mode; MetaLogicalMonitorConfig *logical_monitor_config = NULL; + GList *logical_monitor_configs; GList *monitor_configs = NULL; gint common_mode_w = 0, common_mode_h = 0; float best_scale = 1.0; @@ -893,8 +906,10 @@ create_for_switch_config_all_mirror (MetaMonitorConfigManager *config_manager) .monitor_configs = monitor_configs }; + logical_monitor_configs = g_list_append (NULL, logical_monitor_config); layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager); - return meta_monitors_config_new (g_list_append (NULL, logical_monitor_config), + return meta_monitors_config_new (monitor_manager, + logical_monitor_configs, layout_mode, META_MONITORS_CONFIG_FLAG_NONE); } @@ -935,7 +950,9 @@ create_for_switch_config_external (MetaMonitorConfigManager *config_manager) x += logical_monitor_config->layout.width; } - return meta_monitors_config_new (logical_monitor_configs, layout_mode, + return meta_monitors_config_new (monitor_manager, + logical_monitor_configs, + layout_mode, META_MONITORS_CONFIG_FLAG_NONE); } @@ -964,7 +981,9 @@ create_for_switch_config_builtin (MetaMonitorConfigManager *config_manager) logical_monitor_configs = g_list_append (NULL, primary_logical_monitor_config); - return meta_monitors_config_new (logical_monitor_configs, layout_mode, + return meta_monitors_config_new (monitor_manager, + logical_monitor_configs, + layout_mode, META_MONITORS_CONFIG_FLAG_NONE); } @@ -1087,7 +1106,8 @@ meta_logical_monitor_config_free (MetaLogicalMonitorConfig *logical_monitor_conf } static MetaMonitorsConfigKey * -meta_monitors_config_key_new (GList *logical_monitor_configs) +meta_monitors_config_key_new (GList *logical_monitor_configs, + GList *disabled_monitor_specs) { MetaMonitorsConfigKey *config_key; GList *monitor_specs; @@ -1109,6 +1129,14 @@ meta_monitors_config_key_new (GList *logical_monitor_configs) } } + for (l = disabled_monitor_specs; l; l = l->next) + { + MetaMonitorSpec *monitor_spec = l->data; + + monitor_spec = meta_monitor_spec_clone (monitor_spec); + monitor_specs = g_list_prepend (monitor_specs, monitor_spec); + } + monitor_specs = g_list_sort (monitor_specs, (GCompareFunc) meta_monitor_spec_compare); @@ -1175,21 +1203,56 @@ meta_monitors_config_key_equal (gconstpointer data_a, } MetaMonitorsConfig * -meta_monitors_config_new (GList *logical_monitor_configs, - MetaLogicalMonitorLayoutMode layout_mode, - MetaMonitorsConfigFlag flags) +meta_monitors_config_new_full (GList *logical_monitor_configs, + GList *disabled_monitor_specs, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitorsConfigFlag flags) { MetaMonitorsConfig *config; config = g_object_new (META_TYPE_MONITORS_CONFIG, NULL); config->logical_monitor_configs = logical_monitor_configs; - config->key = meta_monitors_config_key_new (logical_monitor_configs); + config->disabled_monitor_specs = disabled_monitor_specs; + config->key = meta_monitors_config_key_new (logical_monitor_configs, + disabled_monitor_specs); config->layout_mode = layout_mode; config->flags = flags; return config; } +MetaMonitorsConfig * +meta_monitors_config_new (MetaMonitorManager *monitor_manager, + GList *logical_monitor_configs, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitorsConfigFlag flags) +{ + GList *disabled_monitor_specs = NULL; + GList *monitors; + GList *l; + + monitors = meta_monitor_manager_get_monitors (monitor_manager); + for (l = monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + MetaMonitorSpec *monitor_spec; + + monitor_spec = meta_monitor_get_spec (monitor); + if (meta_logical_monitor_configs_have_monitor (logical_monitor_configs, + monitor_spec)) + continue; + + disabled_monitor_specs = + g_list_prepend (disabled_monitor_specs, + meta_monitor_spec_clone (monitor_spec)); + } + + return meta_monitors_config_new_full (logical_monitor_configs, + disabled_monitor_specs, + layout_mode, + flags); +} + static void meta_monitors_config_finalize (GObject *object) { @@ -1198,6 +1261,8 @@ meta_monitors_config_finalize (GObject *object) meta_monitors_config_key_free (config->key); g_list_free_full (config->logical_monitor_configs, (GDestroyNotify) meta_logical_monitor_config_free); + g_list_free_full (config->disabled_monitor_specs, + (GDestroyNotify) meta_monitor_spec_free); G_OBJECT_CLASS (meta_monitors_config_parent_class)->finalize (object); } @@ -1375,6 +1440,38 @@ has_adjecent_neighbour (MetaMonitorsConfig *config, return FALSE; } +gboolean +meta_logical_monitor_configs_have_monitor (GList *logical_monitor_configs, + MetaMonitorSpec *monitor_spec) +{ + GList *l; + + for (l = logical_monitor_configs; l; l = l->next) + { + MetaLogicalMonitorConfig *logical_monitor_config = l->data; + GList *k; + + for (k = logical_monitor_config->monitor_configs; k; k = k->next) + { + MetaMonitorConfig *monitor_config = k->data; + + if (meta_monitor_spec_equals (monitor_spec, + monitor_config->monitor_spec)) + return TRUE; + } + } + + return FALSE; +} + +static gboolean +meta_monitors_config_is_monitor_enabled (MetaMonitorsConfig *config, + MetaMonitorSpec *monitor_spec) +{ + return meta_logical_monitor_configs_have_monitor (config->logical_monitor_configs, + monitor_spec); +} + gboolean meta_verify_monitors_config (MetaMonitorsConfig *config, MetaMonitorManager *monitor_manager, @@ -1456,6 +1553,18 @@ meta_verify_monitors_config (MetaMonitorsConfig *config, g_list_free (region); + for (l = config->disabled_monitor_specs; l; l = l->next) + { + MetaMonitorSpec *monitor_spec = l->data; + + if (meta_monitors_config_is_monitor_enabled (config, monitor_spec)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Assigned monitor explicitly disabled"); + return FALSE; + } + } + if (min_x != 0 || min_y != 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h index 04501eebd..b99cdaba2 100644 --- a/src/backends/meta-monitor-config-manager.h +++ b/src/backends/meta-monitor-config-manager.h @@ -64,6 +64,8 @@ struct _MetaMonitorsConfig MetaMonitorsConfigKey *key; GList *logical_monitor_configs; + GList *disabled_monitor_specs; + MetaMonitorsConfigFlag flags; MetaLogicalMonitorLayoutMode layout_mode; @@ -112,9 +114,15 @@ void meta_monitor_config_manager_clear_history (MetaMonitorConfigManager *config void meta_monitor_config_manager_save_current (MetaMonitorConfigManager *config_manager); -MetaMonitorsConfig * meta_monitors_config_new (GList *logical_monitor_configs, - MetaLogicalMonitorLayoutMode layout_mode, - MetaMonitorsConfigFlag flags); +MetaMonitorsConfig * meta_monitors_config_new_full (GList *logical_monitor_configs, + GList *disabled_monitors, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitorsConfigFlag flags); + +MetaMonitorsConfig * meta_monitors_config_new (MetaMonitorManager *monitor_manager, + GList *logical_monitor_configs, + MetaLogicalMonitorLayoutMode layout_mode, + MetaMonitorsConfigFlag flags); unsigned int meta_monitors_config_key_hash (gconstpointer config_key); @@ -127,6 +135,9 @@ void meta_logical_monitor_config_free (MetaLogicalMonitorConfig *logical_monitor void meta_monitor_config_free (MetaMonitorConfig *monitor_config); +gboolean meta_logical_monitor_configs_have_monitor (GList *logical_monitor_configs, + MetaMonitorSpec *monitor_spec); + gboolean meta_verify_monitor_mode_spec (MetaMonitorModeSpec *monitor_mode_spec, GError **error); diff --git a/src/backends/meta-monitor-config-migration.c b/src/backends/meta-monitor-config-migration.c index 6164d9fc0..c862168a2 100644 --- a/src/backends/meta-monitor-config-migration.c +++ b/src/backends/meta-monitor-config-migration.c @@ -1056,6 +1056,35 @@ generate_config_name (MetaLegacyMonitorsConfig *config) return key_name; } +static GList * +find_disabled_monitor_specs (MetaLegacyMonitorsConfig *legacy_config) +{ + GList *disabled_monitors = NULL; + unsigned int i; + + for (i = 0; i < legacy_config->n_outputs; i++) + { + MetaOutputKey *output_key = &legacy_config->keys[i]; + MetaOutputConfig *output_config = &legacy_config->outputs[i]; + MetaMonitorSpec *monitor_spec; + + if (output_config->enabled) + continue; + + monitor_spec = g_new0 (MetaMonitorSpec, 1); + *monitor_spec = (MetaMonitorSpec) { + .connector = output_key->connector, + .vendor = output_key->vendor, + .product = output_key->product, + .serial = output_key->serial + }; + + disabled_monitors = g_list_prepend (disabled_monitors, monitor_spec); + } + + return disabled_monitors; +} + static void migrate_config (gpointer key, gpointer value, @@ -1068,6 +1097,7 @@ migrate_config (gpointer key, GList *logical_monitor_configs; MetaLogicalMonitorLayoutMode layout_mode; GError *error = NULL; + GList *disabled_monitor_specs; MetaMonitorsConfig *config; logical_monitor_configs = derive_logical_monitor_configs (legacy_config, @@ -1083,9 +1113,13 @@ migrate_config (gpointer key, return; } + disabled_monitor_specs = find_disabled_monitor_specs (legacy_config); + layout_mode = META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL; - config = meta_monitors_config_new (logical_monitor_configs, layout_mode, - META_MONITORS_CONFIG_FLAG_MIGRATED); + config = meta_monitors_config_new_full (logical_monitor_configs, + disabled_monitor_specs, + layout_mode, + META_MONITORS_CONFIG_FLAG_MIGRATED); if (!meta_verify_monitors_config (config, monitor_manager, &error)) { g_autofree char *config_name = NULL; diff --git a/src/backends/meta-monitor-config-store.c b/src/backends/meta-monitor-config-store.c index 351cb65a7..ed0ce34f0 100644 --- a/src/backends/meta-monitor-config-store.c +++ b/src/backends/meta-monitor-config-store.c @@ -83,6 +83,14 @@ * * yes * + * + * + * LVDS3 + * Vendor C + * Product C + * Serial C + * + * * * * @@ -151,7 +159,8 @@ typedef enum STATE_MONITOR_MODE_HEIGHT, STATE_MONITOR_MODE_RATE, STATE_MONITOR_MODE_FLAG, - STATE_MONITOR_UNDERSCANNING + STATE_MONITOR_UNDERSCANNING, + STATE_DISABLED, } ParserState; typedef struct @@ -169,6 +178,7 @@ typedef struct MetaMonitorModeSpec *current_monitor_mode_spec; MetaMonitorConfig *current_monitor_config; MetaLogicalMonitorConfig *current_logical_monitor_config; + GList *current_disabled_monitor_specs; } ConfigParser; G_DEFINE_TYPE (MetaMonitorConfigStore, meta_monitor_config_store, @@ -256,6 +266,10 @@ handle_start_element (GMarkupParseContext *context, parser->state = STATE_MIGRATED; } + else if (g_str_equal (element_name, "disabled")) + { + parser->state = STATE_DISABLED; + } else { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, @@ -458,6 +472,22 @@ handle_start_element (GMarkupParseContext *context, "Invalid element '%s' under underscanning", element_name); return; } + + case STATE_DISABLED: + { + if (!g_str_equal (element_name, "monitorspec")) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Invalid element '%s' under disabled", element_name); + return; + } + + parser->current_monitor_spec = g_new0 (MetaMonitorSpec, 1); + parser->monitor_spec_parent_state = STATE_DISABLED; + parser->state = STATE_MONITOR_SPEC; + + return; + } } } @@ -526,6 +556,15 @@ finish_monitor_spec (ConfigParser *parser) parser->current_monitor_spec; parser->current_monitor_spec = NULL; + return; + } + case STATE_DISABLED: + { + parser->current_disabled_monitor_specs = + g_list_prepend (parser->current_disabled_monitor_specs, + parser->current_monitor_spec); + parser->current_monitor_spec = NULL; + return; } @@ -684,6 +723,14 @@ handle_end_element (GMarkupParseContext *context, return; } + case STATE_DISABLED: + { + g_assert (g_str_equal (element_name, "disabled")); + + parser->state = STATE_CONFIGURATION; + return; + } + case STATE_CONFIGURATION: { MetaMonitorConfigStore *store = parser->config_store; @@ -720,11 +767,13 @@ handle_end_element (GMarkupParseContext *context, config_flags |= META_MONITORS_CONFIG_FLAG_MIGRATED; config = - meta_monitors_config_new (parser->current_logical_monitor_configs, - layout_mode, - config_flags); + meta_monitors_config_new_full (parser->current_logical_monitor_configs, + parser->current_disabled_monitor_specs, + layout_mode, + config_flags); parser->current_logical_monitor_configs = NULL; + parser->current_disabled_monitor_specs = NULL; if (!meta_verify_monitors_config (config, store->monitor_manager, error)) @@ -868,6 +917,7 @@ handle_text (GMarkupParseContext *context, case STATE_MONITOR_SPEC: case STATE_MONITOR_MODE: case STATE_TRANSFORM: + case STATE_DISABLED: { if (!is_all_whitespace (text, text_len)) g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, @@ -1236,6 +1286,18 @@ generate_config_xml (MetaMonitorConfigStore *config_store) append_logical_monitor_xml (buffer, config, logical_monitor_config); } + if (config->disabled_monitor_specs) + { + g_string_append (buffer, " \n"); + for (l = config->disabled_monitor_specs; l; l = l->next) + { + MetaMonitorSpec *monitor_spec = l->data; + + append_monitor_spec (buffer, monitor_spec, " "); + } + g_string_append (buffer, " \n"); + } + g_string_append (buffer, " \n"); } diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 3e0d980fb..2caec1b57 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -1934,7 +1934,9 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet logical_monitor_config); } - config = meta_monitors_config_new (logical_monitor_configs, layout_mode, + config = meta_monitors_config_new (manager, + logical_monitor_configs, + layout_mode, META_MONITORS_CONFIG_FLAG_NONE); if (!meta_verify_monitors_config (config, manager, &error)) {