Backport DRM lease configuration

Backport DRM lease configuration via monitors.xml and D-Bus:

 - https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4112
 - https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4121

Resolves: RHEL-62220
This commit is contained in:
José Expósito 2025-02-12 18:33:35 +01:00
parent 243d00d80d
commit cf077a55b7
9 changed files with 1600 additions and 0 deletions

View File

@ -0,0 +1,338 @@
From 406de0d6d72bcd68ccc71880e618d933537d755c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= <jexposit@redhat.com>
Date: Mon, 28 Oct 2024 08:37:12 +0100
Subject: [PATCH 1/5] monitor-manager: Add forlease config to monitors.xml
Allow to configure a list of monitors as available for lease in
monitors.xml.
The monitors available for lease, must be disabled as well.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4112>
---
src/backends/meta-monitor-config-manager.c | 23 +++++++
src/backends/meta-monitor-config-manager.h | 2 +
src/backends/meta-monitor-config-store.c | 79 +++++++++++++++++++++-
3 files changed, 103 insertions(+), 1 deletion(-)
diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
index 279169ace9..ecf4ee8202 100644
--- a/src/backends/meta-monitor-config-manager.c
+++ b/src/backends/meta-monitor-config-manager.c
@@ -1495,6 +1495,8 @@ meta_monitors_config_key_new (GList *logical_monitor_conf
}
}
+ /* Monitors for lease must be disabled (see meta_verify_monitors_config ()).
+ Therefore, there is no need to include them here. */
for (l = disabled_monitor_specs; l; l = l->next)
{
MetaMonitorSpec *monitor_spec = l->data;
@@ -1598,6 +1600,7 @@ meta_monitors_config_set_parent_config (MetaMonitorsConfig *config,
MetaMonitorsConfig *
meta_monitors_config_new_full (GList *logical_monitor_configs,
GList *disabled_monitor_specs,
+ GList *for_lease_monitor_specs,
MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitorsConfigFlag flags)
{
@@ -1606,6 +1609,7 @@ meta_monitors_config_new_full (GList *logical_monitor_con
config = g_object_new (META_TYPE_MONITORS_CONFIG, NULL);
config->logical_monitor_configs = logical_monitor_configs;
config->disabled_monitor_specs = disabled_monitor_specs;
+ config->for_lease_monitor_specs = for_lease_monitor_specs;
config->layout_mode = layout_mode;
config->key = meta_monitors_config_key_new (logical_monitor_configs,
disabled_monitor_specs,
@@ -1649,6 +1653,7 @@ meta_monitors_config_new (MetaMonitorManager *monitor_manager,
return meta_monitors_config_new_full (logical_monitor_configs,
disabled_monitor_specs,
+ NULL,
layout_mode,
flags);
}
@@ -1664,6 +1669,8 @@ meta_monitors_config_finalize (GObject *object)
(GDestroyNotify) meta_logical_monitor_config_free);
g_list_free_full (config->disabled_monitor_specs,
(GDestroyNotify) meta_monitor_spec_free);
+ g_list_free_full (config->for_lease_monitor_specs,
+ (GDestroyNotify) meta_monitor_spec_free);
G_OBJECT_CLASS (meta_monitors_config_parent_class)->finalize (object);
}
@@ -1907,5 +1914,21 @@ meta_verify_monitors_config (MetaMonitorsConfig *config,
}
}
+ for (l = config->for_lease_monitor_specs; l; l = l->next)
+ {
+ MetaMonitorSpec *monitor_spec = l->data;
+ gpointer disabled = NULL;
+
+ disabled = g_list_find_custom (config->disabled_monitor_specs,
+ monitor_spec,
+ (GCompareFunc) meta_monitor_spec_compare);
+ if (!disabled)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "For lease monitor must be explicitly disabled");
+ return FALSE;
+ }
+ }
+
return TRUE;
}
diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h
index 8d21c8694c..87a29bc2dd 100644
--- a/src/backends/meta-monitor-config-manager.h
+++ b/src/backends/meta-monitor-config-manager.h
@@ -67,6 +67,7 @@ struct _MetaMonitorsConfig
GList *logical_monitor_configs;
GList *disabled_monitor_specs;
+ GList *for_lease_monitor_specs;
MetaMonitorsConfigFlag flags;
@@ -142,6 +143,7 @@ void meta_monitor_config_manager_save_current (MetaMonitorConfigManager *config_
META_EXPORT_TEST
MetaMonitorsConfig * meta_monitors_config_new_full (GList *logical_monitor_configs,
GList *disabled_monitors,
+ GList *for_lease_monitors,
MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitorsConfigFlag flags);
diff --git a/src/backends/meta-monitor-config-store.c b/src/backends/meta-monitor-config-store.c
index 6e8aed1f9e..eb22dc3f36 100644
--- a/src/backends/meta-monitor-config-store.c
+++ b/src/backends/meta-monitor-config-store.c
@@ -89,6 +89,14 @@
* <serial>Serial C</serial>
* </monitorspec>
* </disabled>
+ * <forlease>
+ * <monitorspec>
+ * <connector>LVDS3</connector>
+ * <vendor>Vendor C</vendor>
+ * <product>Product C</product>
+ * <serial>Serial C</serial>
+ * </monitorspec>
+ * </forlease>
* </configuration>
* </monitors>
*
@@ -158,6 +166,7 @@ typedef enum
STATE_MONITOR_MAXBPC,
STATE_MONITOR_RGB_RANGE,
STATE_DISABLED,
+ STATE_FOR_LEASE,
STATE_POLICY,
STATE_STORES,
STATE_STORE,
@@ -184,6 +193,7 @@ typedef struct
MetaMonitorConfig *current_monitor_config;
MetaLogicalMonitorConfig *current_logical_monitor_config;
GList *current_disabled_monitor_specs;
+ GList *current_for_lease_monitor_specs;
gboolean seen_policy;
gboolean seen_stores;
gboolean seen_dbus;
@@ -333,6 +343,10 @@ handle_start_element (GMarkupParseContext *context,
{
parser->state = STATE_DISABLED;
}
+ else if (g_str_equal (element_name, "forlease"))
+ {
+ parser->state = STATE_FOR_LEASE;
+ }
else
{
enter_unknown_element (parser, element_name,
@@ -578,6 +592,22 @@ handle_start_element (GMarkupParseContext *context,
return;
}
+ case STATE_FOR_LEASE:
+ {
+ if (!g_str_equal (element_name, "monitorspec"))
+ {
+ g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+ "Invalid element '%s' under forlease", element_name);
+ return;
+ }
+
+ parser->current_monitor_spec = g_new0 (MetaMonitorSpec, 1);
+ parser->monitor_spec_parent_state = STATE_FOR_LEASE;
+ parser->state = STATE_MONITOR_SPEC;
+
+ return;
+ }
+
case STATE_POLICY:
{
if (!(parser->extra_config_flags &
@@ -673,6 +703,15 @@ finish_monitor_spec (ConfigParser *parser)
parser->current_monitor_spec);
parser->current_monitor_spec = NULL;
+ return;
+ }
+ case STATE_FOR_LEASE:
+ {
+ parser->current_for_lease_monitor_specs =
+ g_list_prepend (parser->current_for_lease_monitor_specs,
+ parser->current_monitor_spec);
+ parser->current_monitor_spec = NULL;
+
return;
}
@@ -729,12 +768,15 @@ static gboolean
detect_layout_mode_configs (MetaMonitorManager *monitor_manager,
GList *logical_monitor_configs,
GList *disabled_monitor_specs,
+ GList *for_lease_monitor_specs,
MetaMonitorsConfigFlag config_flags,
MetaMonitorsConfig **physical_layout_mode_config,
MetaMonitorsConfig **logical_layout_mode_config,
GError **error)
{
- GList *logical_monitor_configs_copy, *disabled_monitor_specs_copy;
+ GList *logical_monitor_configs_copy;
+ GList *disabled_monitor_specs_copy;
+ GList *for_lease_monitor_specs_copy;
MetaMonitorsConfig *physical_config, *logical_config;
g_autoptr (GError) local_error_physical = NULL;
g_autoptr (GError) local_error_logical = NULL;
@@ -743,12 +785,15 @@ detect_layout_mode_configs (MetaMonitorManager *monitor_manager,
meta_clone_logical_monitor_config_list (logical_monitor_configs);
disabled_monitor_specs_copy =
g_list_copy_deep (disabled_monitor_specs, (GCopyFunc) meta_monitor_spec_clone, NULL);
+ for_lease_monitor_specs_copy =
+ g_list_copy_deep (for_lease_monitor_specs, (GCopyFunc) meta_monitor_spec_clone, NULL);
derive_logical_monitor_layouts (logical_monitor_configs,
META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL);
physical_config =
meta_monitors_config_new_full (g_steal_pointer (&logical_monitor_configs),
g_steal_pointer (&disabled_monitor_specs),
+ g_steal_pointer (&for_lease_monitor_specs),
META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL,
config_flags);
@@ -761,6 +806,7 @@ detect_layout_mode_configs (MetaMonitorManager *monitor_manager,
logical_config =
meta_monitors_config_new_full (g_steal_pointer (&logical_monitor_configs_copy),
g_steal_pointer (&disabled_monitor_specs_copy),
+ g_steal_pointer (&for_lease_monitor_specs_copy),
META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL,
config_flags);
@@ -1207,6 +1253,7 @@ static MetaMonitorsConfig *
attempt_layout_mode_conversion (MetaMonitorManager *monitor_manager,
GList *logical_monitor_configs,
GList *disabled_monitor_specs,
+ GList *for_lease_monitor_specs,
MetaMonitorsConfigFlag config_flags)
{
GList *logical_monitor_configs_copy;
@@ -1251,6 +1298,9 @@ create_full_config:
g_list_copy_deep (disabled_monitor_specs,
(GCopyFunc) meta_monitor_spec_clone,
NULL),
+ g_list_copy_deep (for_lease_monitor_specs,
+ (GCopyFunc) meta_monitor_spec_clone,
+ NULL),
META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL,
config_flags);
@@ -1438,6 +1488,14 @@ handle_end_element (GMarkupParseContext *context,
return;
}
+ case STATE_FOR_LEASE:
+ {
+ g_assert (g_str_equal (element_name, "forlease"));
+
+ parser->state = STATE_CONFIGURATION;
+ return;
+ }
+
case STATE_CONFIGURATION:
{
MetaMonitorConfigStore *store = parser->config_store;
@@ -1458,6 +1516,7 @@ handle_end_element (GMarkupParseContext *context,
if (!detect_layout_mode_configs (store->monitor_manager,
parser->current_logical_monitor_configs,
parser->current_disabled_monitor_specs,
+ parser->current_for_lease_monitor_specs,
config_flags,
&physical_layout_mode_config,
&logical_layout_mode_config,
@@ -1465,11 +1524,13 @@ handle_end_element (GMarkupParseContext *context,
{
parser->current_logical_monitor_configs = NULL;
parser->current_disabled_monitor_specs = NULL;
+ parser->current_for_lease_monitor_specs = NULL;
return;
}
parser->current_logical_monitor_configs = NULL;
parser->current_disabled_monitor_specs = NULL;
+ parser->current_for_lease_monitor_specs = NULL;
if (physical_layout_mode_config)
{
@@ -1487,6 +1548,7 @@ handle_end_element (GMarkupParseContext *context,
attempt_layout_mode_conversion (store->monitor_manager,
physical_layout_mode_config->logical_monitor_configs,
physical_layout_mode_config->disabled_monitor_specs,
+ physical_layout_mode_config->for_lease_monitor_specs,
config_flags);
}
}
@@ -1508,11 +1570,13 @@ handle_end_element (GMarkupParseContext *context,
config =
meta_monitors_config_new_full (parser->current_logical_monitor_configs,
parser->current_disabled_monitor_specs,
+ parser->current_for_lease_monitor_specs,
layout_mode,
config_flags);
parser->current_logical_monitor_configs = NULL;
parser->current_disabled_monitor_specs = NULL;
+ parser->current_for_lease_monitor_specs = NULL;
if (!meta_verify_monitors_config (config, store->monitor_manager,
error))
@@ -1747,6 +1811,7 @@ handle_text (GMarkupParseContext *context,
case STATE_MONITOR_MODE:
case STATE_TRANSFORM:
case STATE_DISABLED:
+ case STATE_FOR_LEASE:
case STATE_POLICY:
case STATE_STORES:
{
@@ -2323,6 +2388,18 @@ generate_config_xml (MetaMonitorConfigStore *config_store)
g_string_append (buffer, " </disabled>\n");
}
+ if (config->for_lease_monitor_specs)
+ {
+ g_string_append (buffer, " <forlease>\n");
+ for (l = config->for_lease_monitor_specs; l; l = l->next)
+ {
+ MetaMonitorSpec *monitor_spec = l->data;
+
+ append_monitor_spec (buffer, monitor_spec, " ");
+ }
+ g_string_append (buffer, " </forlease>\n");
+ }
+
g_string_append (buffer, " </configuration>\n");
}
--
2.48.1

View File

@ -0,0 +1,201 @@
From c93e06696fea37303e4d9143ed62a31a97532c51 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= <jexposit@redhat.com>
Date: Mon, 4 Nov 2024 19:12:19 +0100
Subject: [PATCH 1/3] monitor-manager: Return for lease status in
GetCurrentState
Add a new property to the list of monitors returned by the
GetCurrentState D-Bus API indicating whether the monitor is available
for lease or not.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4121>
---
.../org.gnome.Mutter.DisplayConfig.xml | 1 +
src/backends/meta-monitor-manager.c | 6 +
src/tests/monitor-unit-tests.c | 127 ++++++++++++++++++
3 files changed, 134 insertions(+)
diff --git a/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml b/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml
index 3c28814b16..192c08a796 100644
--- a/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml
+++ b/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml
@@ -392,6 +392,7 @@
- "min-refresh-rate" (i): minimum refresh rate of monitor when
Variable Refresh Rate is active (absence
of this means unknown)
+ - "is-for-lease" (b): whether the monitor is for lease or not
Possible mode flags:
1 : preferred mode
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 55816ed7bb..127181df60 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -2032,6 +2032,7 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton,
GVariantBuilder monitor_properties_builder;
GList *k;
gboolean is_builtin;
+ gboolean is_for_lease;
const char *display_name;
current_mode = meta_monitor_get_current_mode (monitor);
@@ -2153,6 +2154,11 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton,
g_variant_new_int32 (min_refresh_rate));
}
+ is_for_lease = meta_monitor_is_for_lease (monitor);
+ g_variant_builder_add (&monitor_properties_builder, "{sv}",
+ "is-for-lease",
+ g_variant_new_boolean (is_for_lease));
+
g_variant_builder_add (&monitors_builder, MONITOR_FORMAT,
monitor_spec->connector,
monitor_spec->vendor,
diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c
index 0d5d1511ea..1f87c36528 100644
--- a/src/tests/monitor-unit-tests.c
+++ b/src/tests/monitor-unit-tests.c
@@ -9474,6 +9474,131 @@ meta_test_monitor_custom_for_lease_invalid_config (void)
g_test_assert_expected_messages ();
}
+static void
+on_proxy_call_cb (GObject *object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ g_autoptr (GError) error = NULL;
+ GVariant **ret = user_data;
+
+ *ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error);
+ g_assert_no_error (error);
+ g_assert_nonnull (ret);
+}
+
+static void
+assert_monitor_state (GVariant *state,
+ guint monitor_index,
+ const char *connector,
+ gboolean is_for_lease)
+{
+ g_autoptr (GVariant) monitors = NULL;
+ g_autoptr (GVariant) monitor = NULL;
+ g_autoptr (GVariant) monitor_spec = NULL;
+ g_autoptr (GVariant) spec_connector = NULL;
+ g_autoptr (GVariant) monitor_properties = NULL;
+ g_autoptr (GVariant) for_lease_property = NULL;
+
+ monitors = g_variant_get_child_value (state, 1);
+ monitor = g_variant_get_child_value (monitors, monitor_index);
+
+ monitor_spec = g_variant_get_child_value (monitor, 0);
+ spec_connector = g_variant_get_child_value (monitor_spec, 0);
+ g_assert_cmpstr (g_variant_get_string (spec_connector, NULL), ==, connector);
+
+ monitor_properties = g_variant_get_child_value (monitor, 2);
+ for_lease_property = g_variant_lookup_value (monitor_properties,
+ "is-for-lease",
+ G_VARIANT_TYPE_BOOLEAN);
+ g_assert (g_variant_get_boolean (for_lease_property) == is_for_lease);
+}
+
+static void
+meta_test_monitor_custom_for_lease_config_dbus (void)
+{
+ MonitorTestCaseSetup test_case_setup = {
+ .modes = {
+ {
+ .width = 800,
+ .height = 600,
+ .refresh_rate = 60.0
+ }
+ },
+ .n_modes = 1,
+ .outputs = {
+ {
+ .crtc = -1,
+ .modes = { 0 },
+ .n_modes = 1,
+ .preferred_mode = 0,
+ .possible_crtcs = { 0, 1 },
+ .n_possible_crtcs = 2,
+ .width_mm = 222,
+ .height_mm = 125,
+ .serial = "0x123456",
+ },
+ {
+ .crtc = -1,
+ .modes = { 0 },
+ .n_modes = 1,
+ .preferred_mode = 0,
+ .possible_crtcs = { 0, 1 },
+ .n_possible_crtcs = 2,
+ .width_mm = 222,
+ .height_mm = 125,
+ .serial = "0x654321"
+ }
+ },
+ .n_outputs = 2,
+ .crtcs = {
+ {
+ .current_mode = -1
+ },
+ {
+ .current_mode = -1
+ }
+ },
+ .n_crtcs = 2
+ };
+ MetaMonitorTestSetup *test_setup;
+ g_autoptr (GDBusProxy) display_config_proxy = NULL;
+ g_autoptr (GVariant) state = NULL;
+
+ test_setup = meta_create_monitor_test_setup (test_backend,
+ &test_case_setup,
+ MONITOR_TEST_FLAG_NONE);
+ meta_set_custom_monitor_config (test_context, "forlease.xml");
+ emulate_hotplug (test_setup);
+ check_monitor_test_clients_state ();
+
+ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+ NULL,
+ "org.gnome.Mutter.DisplayConfig",
+ "/org/gnome/Mutter/DisplayConfig",
+ "org.gnome.Mutter.DisplayConfig",
+ NULL,
+ proxy_ready_cb,
+ &display_config_proxy);
+ while (!display_config_proxy)
+ g_main_context_iteration (NULL, TRUE);
+
+ g_dbus_proxy_call (display_config_proxy,
+ "GetCurrentState",
+ NULL,
+ G_DBUS_CALL_FLAGS_NO_AUTO_START,
+ -1,
+ NULL,
+ on_proxy_call_cb,
+ &state);
+ while (!state)
+ g_main_context_iteration (NULL, TRUE);
+
+ assert_monitor_state (state, 0, "DP-1", FALSE);
+ assert_monitor_state (state, 1, "DP-2", TRUE);
+}
+
static gboolean
quit_main_loop (gpointer data)
{
@@ -10704,6 +10829,8 @@ init_monitor_tests (void)
meta_test_monitor_custom_for_lease_config);
add_monitor_test ("/backends/monitor/custom/for-lease-invalid-config",
meta_test_monitor_custom_for_lease_invalid_config);
+ add_monitor_test ("/backends/monitor/custom/for-lease-config-dbus",
+ meta_test_monitor_custom_for_lease_config_dbus);
add_monitor_test ("/backends/monitor/migrated/rotated",
meta_test_monitor_migrated_rotated);
--
2.48.1

View File

@ -0,0 +1,462 @@
From f93e85f69b9d63d4bedeaf778d5f620ad64ddab4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= <jexposit@redhat.com>
Date: Mon, 28 Oct 2024 08:44:35 +0100
Subject: [PATCH 2/5] monitor: Keep track of the for lease status
Add a flag to MetaMonitor indicating if the monitor is available for
lease and store/update it from the monitor configuration.
Also, add unit tests validating that the configuration is applied and
that invalid configurations fail.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4112>
---
src/backends/meta-monitor-config-manager.c | 10 +-
src/backends/meta-monitor-manager-private.h | 3 +
src/backends/meta-monitor-manager.c | 41 +++++
src/backends/meta-monitor.c | 19 ++
src/backends/meta-monitor.h | 6 +
.../native/meta-monitor-manager-native.c | 1 +
.../monitor-configs/forlease-invalid.xml | 32 ++++
src/tests/monitor-configs/forlease.xml | 40 +++++
src/tests/monitor-unit-tests.c | 165 ++++++++++++++++++
9 files changed, 316 insertions(+), 1 deletion(-)
create mode 100644 src/tests/monitor-configs/forlease-invalid.xml
create mode 100644 src/tests/monitor-configs/forlease.xml
diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
index ecf4ee8202..0df193f0a4 100644
--- a/src/backends/meta-monitor-config-manager.c
+++ b/src/backends/meta-monitor-config-manager.c
@@ -1628,6 +1628,7 @@ meta_monitors_config_new (MetaMonitorManager *monitor_manager,
MetaMonitorsConfigFlag flags)
{
GList *disabled_monitor_specs = NULL;
+ GList *for_lease_monitor_specs = NULL;
GList *monitors;
GList *l;
@@ -1649,11 +1650,18 @@ meta_monitors_config_new (MetaMonitorManager *monitor_manager,
disabled_monitor_specs =
g_list_prepend (disabled_monitor_specs,
meta_monitor_spec_clone (monitor_spec));
+
+ if (meta_monitor_is_for_lease (monitor))
+ {
+ for_lease_monitor_specs =
+ g_list_prepend (for_lease_monitor_specs,
+ meta_monitor_spec_clone (monitor_spec));
+ }
}
return meta_monitors_config_new_full (logical_monitor_configs,
disabled_monitor_specs,
- NULL,
+ for_lease_monitor_specs,
layout_mode,
flags);
}
diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h
index 977ce417cc..66492c2a5f 100644
--- a/src/backends/meta-monitor-manager-private.h
+++ b/src/backends/meta-monitor-manager-private.h
@@ -345,6 +345,9 @@ META_EXPORT_TEST
void meta_monitor_manager_update_logical_state (MetaMonitorManager *manager,
MetaMonitorsConfig *config);
+void meta_monitor_manager_update_for_lease_state (MetaMonitorManager *manager,
+ MetaMonitorsConfig *config);
+
META_EXPORT_TEST
void meta_monitor_manager_update_logical_state_derived (MetaMonitorManager *manager,
MetaMonitorsConfig *config);
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 4fcc8a696c..55816ed7bb 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -3824,6 +3824,46 @@ meta_monitor_manager_update_logical_state (MetaMonitorManager *manager,
meta_monitor_manager_rebuild_logical_monitors (manager, config);
}
+static gboolean
+is_monitor_configured_for_lease (MetaMonitor *monitor,
+ MetaMonitorsConfig *config)
+{
+ MetaMonitorSpec *monitor_spec;
+ GList *l;
+
+ monitor_spec = meta_monitor_get_spec (monitor);
+
+ for (l = config->for_lease_monitor_specs; l; l = l->next)
+ {
+ MetaMonitorSpec *spec = l->data;
+
+ if (meta_monitor_spec_equals (monitor_spec, spec))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void
+meta_monitor_manager_update_for_lease_state (MetaMonitorManager *manager,
+ MetaMonitorsConfig *config)
+{
+ GList *l;
+
+ for (l = manager->monitors; l; l = l->next)
+ {
+ MetaMonitor *monitor = l->data;
+ gboolean is_for_lease;
+
+ if (config)
+ is_for_lease = is_monitor_configured_for_lease (monitor, config);
+ else
+ is_for_lease = FALSE;
+
+ meta_monitor_set_for_lease (monitor, is_for_lease);
+ }
+}
+
void
meta_monitor_manager_rebuild (MetaMonitorManager *manager,
MetaMonitorsConfig *config)
@@ -3838,6 +3878,7 @@ meta_monitor_manager_rebuild (MetaMonitorManager *manager,
old_logical_monitors = manager->logical_monitors;
meta_monitor_manager_update_logical_state (manager, config);
+ meta_monitor_manager_update_for_lease_state (manager, config);
ensure_privacy_screen_settings (manager);
diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c
index b7efabda2c..badde7cea2 100644
--- a/src/backends/meta-monitor.c
+++ b/src/backends/meta-monitor.c
@@ -67,6 +67,8 @@ typedef struct _MetaMonitorPrivate
MetaLogicalMonitor *logical_monitor;
char *display_name;
+
+ gboolean is_for_lease;
} MetaMonitorPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaMonitor, meta_monitor, G_TYPE_OBJECT)
@@ -2459,3 +2461,20 @@ meta_monitor_get_backlight (MetaMonitor *monitor,
return FALSE;
}
}
+
+void
+meta_monitor_set_for_lease (MetaMonitor *monitor,
+ gboolean for_lease)
+{
+ MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
+
+ priv->is_for_lease = for_lease;
+}
+
+gboolean
+meta_monitor_is_for_lease (MetaMonitor *monitor)
+{
+ MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
+
+ return priv->is_for_lease;
+}
diff --git a/src/backends/meta-monitor.h b/src/backends/meta-monitor.h
index 01836dc0e7..cc11348b35 100644
--- a/src/backends/meta-monitor.h
+++ b/src/backends/meta-monitor.h
@@ -349,4 +349,10 @@ META_EXPORT_TEST
gboolean meta_monitor_get_backlight (MetaMonitor *monitor,
int *value);
+void meta_monitor_set_for_lease (MetaMonitor *monitor,
+ gboolean for_lease);
+
+META_EXPORT_TEST
+gboolean meta_monitor_is_for_lease (MetaMonitor *monitor);
+
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaMonitorSpec, meta_monitor_spec_free)
diff --git a/src/backends/native/meta-monitor-manager-native.c b/src/backends/native/meta-monitor-manager-native.c
index 668f4e0eb4..21cc1b95be 100644
--- a/src/backends/native/meta-monitor-manager-native.c
+++ b/src/backends/native/meta-monitor-manager-native.c
@@ -156,6 +156,7 @@ meta_monitor_manager_native_ensure_initial_config (MetaMonitorManager *manager)
config = meta_monitor_manager_ensure_configured (manager);
meta_monitor_manager_update_logical_state (manager, config);
+ meta_monitor_manager_update_for_lease_state (manager, config);
}
static void
diff --git a/src/tests/monitor-configs/forlease-invalid.xml b/src/tests/monitor-configs/forlease-invalid.xml
new file mode 100644
index 0000000000..4a7ff9d5da
--- /dev/null
+++ b/src/tests/monitor-configs/forlease-invalid.xml
@@ -0,0 +1,32 @@
+<monitors version="2">
+ <configuration>
+ <layoutmode>logical</layoutmode>
+ <logicalmonitor>
+ <x>0</x>
+ <y>0</y>
+ <scale>1</scale>
+ <primary>yes</primary>
+ <monitor>
+ <monitorspec>
+ <connector>DP-1</connector>
+ <vendor>MetaProduct&apos;s Inc.</vendor>
+ <product>MetaMonitor</product>
+ <serial>0x123456</serial>
+ </monitorspec>
+ <mode>
+ <width>800</width>
+ <height>600</height>
+ <rate>60</rate>
+ </mode>
+ </monitor>
+ </logicalmonitor>
+ <forlease>
+ <monitorspec>
+ <connector>DP-1</connector>
+ <vendor>MetaProduct&apos;s Inc.</vendor>
+ <product>MetaMonitor</product>
+ <serial>0x123456</serial>
+ </monitorspec>
+ </forlease>
+ </configuration>
+</monitors>
diff --git a/src/tests/monitor-configs/forlease.xml b/src/tests/monitor-configs/forlease.xml
new file mode 100644
index 0000000000..482f095a6d
--- /dev/null
+++ b/src/tests/monitor-configs/forlease.xml
@@ -0,0 +1,40 @@
+<monitors version="2">
+ <configuration>
+ <layoutmode>logical</layoutmode>
+ <logicalmonitor>
+ <x>0</x>
+ <y>0</y>
+ <scale>1</scale>
+ <primary>yes</primary>
+ <monitor>
+ <monitorspec>
+ <connector>DP-1</connector>
+ <vendor>MetaProduct&apos;s Inc.</vendor>
+ <product>MetaMonitor</product>
+ <serial>0x123456</serial>
+ </monitorspec>
+ <mode>
+ <width>800</width>
+ <height>600</height>
+ <rate>60</rate>
+ </mode>
+ </monitor>
+ </logicalmonitor>
+ <disabled>
+ <monitorspec>
+ <connector>DP-2</connector>
+ <vendor>MetaProduct&apos;s Inc.</vendor>
+ <product>MetaMonitor</product>
+ <serial>0x654321</serial>
+ </monitorspec>
+ </disabled>
+ <forlease>
+ <monitorspec>
+ <connector>DP-2</connector>
+ <vendor>MetaProduct&apos;s Inc.</vendor>
+ <product>MetaMonitor</product>
+ <serial>0x654321</serial>
+ </monitorspec>
+ </forlease>
+ </configuration>
+</monitors>
diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c
index 2414789bab..326dd83855 100644
--- a/src/tests/monitor-unit-tests.c
+++ b/src/tests/monitor-unit-tests.c
@@ -9176,6 +9176,167 @@ meta_test_monitor_custom_detached_groups (void)
g_assert_cmpstr (error->message, ==, "Logical monitors not adjacent");
}
+static void
+meta_test_monitor_custom_for_lease_config (void)
+{
+ MonitorTestCase test_case = {
+ .setup = {
+ .modes = {
+ {
+ .width = 800,
+ .height = 600,
+ .refresh_rate = 60.0
+ }
+ },
+ .n_modes = 1,
+ .outputs = {
+ {
+ .crtc = -1,
+ .modes = { 0 },
+ .n_modes = 1,
+ .preferred_mode = 0,
+ .possible_crtcs = { 0, 1 },
+ .n_possible_crtcs = 2,
+ .width_mm = 222,
+ .height_mm = 125,
+ .serial = "0x123456",
+ },
+ {
+ .crtc = -1,
+ .modes = { 0 },
+ .n_modes = 1,
+ .preferred_mode = 0,
+ .possible_crtcs = { 0, 1 },
+ .n_possible_crtcs = 2,
+ .width_mm = 222,
+ .height_mm = 125,
+ .serial = "0x654321"
+ }
+ },
+ .n_outputs = 2,
+ .crtcs = {
+ {
+ .current_mode = -1
+ },
+ {
+ .current_mode = -1
+ }
+ },
+ .n_crtcs = 2
+ },
+
+ .expect = {
+ .monitors = {
+ {
+ .outputs = { 0 },
+ .n_outputs = 1,
+ .modes = {
+ {
+ .width = 800,
+ .height = 600,
+ .refresh_rate = 60.0,
+ .crtc_modes = {
+ {
+ .output = 0,
+ .crtc_mode = 0
+ }
+ }
+ }
+ },
+ .n_modes = 1,
+ .current_mode = 0,
+ .width_mm = 222,
+ .height_mm = 125
+ },
+ {
+ .outputs = { 1 },
+ .n_outputs = 1,
+ .modes = {
+ {
+ .width = 800,
+ .height = 600,
+ .refresh_rate = 60.0,
+ .crtc_modes = {
+ {
+ .output = 1,
+ .crtc_mode = 0
+ }
+ }
+ }
+ },
+ .n_modes = 1,
+ .current_mode = -1,
+ .width_mm = 222,
+ .height_mm = 125
+ }
+ },
+ .n_monitors = 2,
+ .logical_monitors = {
+ {
+ .monitors = { 0 },
+ .n_monitors = 1,
+ .layout = { .x = 0, .y = 0, .width = 800, .height = 600 },
+ .scale = 1,
+ .transform = MTK_MONITOR_TRANSFORM_NORMAL
+ },
+ },
+ .n_logical_monitors = 1,
+ .primary_logical_monitor = 0,
+ .n_outputs = 2,
+ .crtcs = {
+ {
+ .current_mode = 0,
+ },
+ {
+ .current_mode = -1,
+ }
+ },
+ .n_crtcs = 2,
+ .screen_width = 800,
+ .screen_height = 600,
+ }
+ };
+ MetaMonitorTestSetup *test_setup;
+ MetaBackend *backend = meta_context_get_backend (test_context);
+ MetaMonitorManager *monitor_manager =
+ meta_backend_get_monitor_manager (backend);
+ GList *monitors;
+ MetaMonitor *first_monitor;
+ MetaMonitor *second_monitor;
+
+ test_setup = meta_create_monitor_test_setup (test_backend,
+ &test_case.setup,
+ MONITOR_TEST_FLAG_NONE);
+ meta_set_custom_monitor_config (test_context, "forlease.xml");
+ emulate_hotplug (test_setup);
+
+ META_TEST_LOG_CALL ("Checking monitor configuration",
+ meta_check_monitor_configuration (test_context,
+ &test_case.expect));
+ check_monitor_test_clients_state ();
+
+ monitors = meta_monitor_manager_get_monitors (monitor_manager);
+ g_assert_cmpuint (g_list_length (monitors), ==, 2);
+
+ first_monitor = g_list_nth_data (monitors, 0);
+ second_monitor = g_list_nth_data (monitors, 1);
+
+ g_assert_true (meta_monitor_is_active (first_monitor));
+ g_assert_false (meta_monitor_is_for_lease (first_monitor));
+
+ g_assert_false (meta_monitor_is_active (second_monitor));
+ g_assert_true (meta_monitor_is_for_lease (second_monitor));
+}
+
+static void
+meta_test_monitor_custom_for_lease_invalid_config (void)
+{
+ g_test_expect_message ("libmutter-test", G_LOG_LEVEL_WARNING,
+ "*For lease monitor must be explicitly disabled");
+ meta_set_custom_monitor_config (test_context, "forlease-invalid.xml");
+ g_test_assert_expected_messages ();
+}
+
static gboolean
quit_main_loop (gpointer data)
{
@@ -10400,6 +10561,10 @@ init_monitor_tests (void)
meta_test_monitor_custom_lid_switch_config);
add_monitor_test ("/backends/monitor/custom/detached-groups",
meta_test_monitor_custom_detached_groups);
+ add_monitor_test ("/backends/monitor/custom/for-lease-config",
+ meta_test_monitor_custom_for_lease_config);
+ add_monitor_test ("/backends/monitor/custom/for-lease-invalid-config",
+ meta_test_monitor_custom_for_lease_invalid_config);
add_monitor_test ("/backends/monitor/migrated/rotated",
meta_test_monitor_migrated_rotated);
--
2.48.1

View File

@ -0,0 +1,80 @@
From 80a19134ffb5ddd6577f00986aafcaf9db6505b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= <jexposit@redhat.com>
Date: Tue, 5 Nov 2024 12:03:49 +0100
Subject: [PATCH 2/3] monitor-manager: Allow to check if config has a visible
monitor
Add a new function, similar to meta_logical_monitor_configs_have_monitor()
that, in addition, checks if the monitor is visible.
Refactor, no functional change.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4121>
---
src/backends/meta-monitor-config-manager.c | 24 +++++++++++++++++-----
src/backends/meta-monitor-config-manager.h | 4 ++++
2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
index 0df193f0a4..74aa2df4b1 100644
--- a/src/backends/meta-monitor-config-manager.c
+++ b/src/backends/meta-monitor-config-manager.c
@@ -1638,14 +1638,12 @@ meta_monitors_config_new (MetaMonitorManager *monitor_manager,
MetaMonitor *monitor = l->data;
MetaMonitorSpec *monitor_spec;
- if (!monitor_matches_rule (monitor, monitor_manager,
- MONITOR_MATCH_VISIBLE))
+ if (meta_logical_monitor_configs_have_visible_monitor (monitor_manager,
+ logical_monitor_configs,
+ monitor))
continue;
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,
@@ -1889,6 +1887,22 @@ meta_logical_monitor_configs_have_monitor (GList *logical_monitor_conf
return FALSE;
}
+gboolean
+meta_logical_monitor_configs_have_visible_monitor (MetaMonitorManager *monitor_manager,
+ GList *logical_monitor_configs,
+ MetaMonitor *monitor)
+{
+ MetaMonitorSpec *monitor_spec;
+
+ if (!monitor_matches_rule (monitor, monitor_manager, MONITOR_MATCH_VISIBLE))
+ return TRUE;
+
+ monitor_spec = meta_monitor_get_spec (monitor);
+
+ return meta_logical_monitor_configs_have_monitor (logical_monitor_configs,
+ monitor_spec);
+}
+
static gboolean
meta_monitors_config_is_monitor_enabled (MetaMonitorsConfig *config,
MetaMonitorSpec *monitor_spec)
diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h
index 87a29bc2dd..f033ac6555 100644
--- a/src/backends/meta-monitor-config-manager.h
+++ b/src/backends/meta-monitor-config-manager.h
@@ -187,6 +187,10 @@ META_EXPORT_TEST
gboolean meta_logical_monitor_configs_have_monitor (GList *logical_monitor_configs,
MetaMonitorSpec *monitor_spec);
+gboolean meta_logical_monitor_configs_have_visible_monitor (MetaMonitorManager *monitor_manager,
+ GList *logical_monitor_configs,
+ MetaMonitor *monitor);
+
META_EXPORT_TEST
gboolean meta_verify_monitor_mode_spec (MetaMonitorModeSpec *monitor_mode_spec,
GError **error);
--
2.48.1

View File

@ -0,0 +1,224 @@
From 479bb6921da3d7004a74c4c7db999534b32ff214 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= <jexposit@redhat.com>
Date: Tue, 5 Nov 2024 12:26:42 +0100
Subject: [PATCH 3/3] monitor-manager: Configure for lease monitors in
ApplyMonitorsConfig
Add a new property to the ApplyMonitorsConfig D-Bus API allowing to set
a list of monitors for lease.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4121>
---
.../org.gnome.Mutter.DisplayConfig.xml | 6 ++
src/backends/meta-monitor-manager.c | 85 ++++++++++++++++++-
src/tests/monitor-unit-tests.c | 60 +++++++++++++
3 files changed, 147 insertions(+), 4 deletions(-)
diff --git a/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml b/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml
index 192c08a796..fec38a34a8 100644
--- a/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml
+++ b/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml
@@ -501,6 +501,12 @@
* "layout-mode" (u): layout mode the passed configuration is in; may
only be set when changing the layout mode is
supported (see GetCurrentState).
+ * "monitors-for-lease" (a(ssss)): a list of monitors to be made available for
+ lease. Monitors listed here must not be listed in @logical_monitors:
+ * s connector: connector name (e.g. HDMI-1, DP-1, etc)
+ * s vendor: vendor name
+ * s product: product name
+ * s serial: product serial
-->
<method name="ApplyMonitorsConfig">
<arg name="serial" direction="in" type="u" />
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 127181df60..abe1db6649 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -2713,6 +2713,74 @@ is_valid_layout_mode (MetaLogicalMonitorLayoutMode layout_mode)
return FALSE;
}
+static GList *
+create_disabled_monitor_specs_for_config (MetaMonitorManager *monitor_manager,
+ GList *logical_monitor_configs)
+{
+ 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;
+
+ if (!meta_logical_monitor_configs_have_visible_monitor (monitor_manager,
+ logical_monitor_configs,
+ monitor))
+ {
+ MetaMonitorSpec *monitor_spec = meta_monitor_get_spec (monitor);
+
+ disabled_monitor_specs =
+ g_list_prepend (disabled_monitor_specs,
+ meta_monitor_spec_clone (monitor_spec));
+ }
+ }
+
+ return disabled_monitor_specs;
+}
+
+static GList *
+create_for_lease_monitor_specs_from_variant (GVariant *properties_variant)
+{
+ GList *for_lease_monitor_specs = NULL;
+ g_autoptr (GVariant) for_lease_variant = NULL;
+ GVariantIter iter;
+ char *connector = NULL;
+ char *vendor = NULL;
+ char *product = NULL;
+ char *serial = NULL;
+
+ if (!properties_variant)
+ return NULL;
+
+ for_lease_variant = g_variant_lookup_value (properties_variant,
+ "monitors-for-lease",
+ G_VARIANT_TYPE ("a(ssss)"));
+ if (!for_lease_variant)
+ return NULL;
+
+ g_variant_iter_init (&iter, for_lease_variant);
+ while (g_variant_iter_next (&iter, "(ssss)", &connector, &vendor, &product, &serial))
+ {
+ MetaMonitorSpec *monitor_spec;
+
+ monitor_spec = g_new0 (MetaMonitorSpec, 1);
+ *monitor_spec = (MetaMonitorSpec) {
+ .connector = connector,
+ .vendor = vendor,
+ .product = product,
+ .serial = serial
+ };
+
+ for_lease_monitor_specs =
+ g_list_append (for_lease_monitor_specs, monitor_spec);
+ }
+
+ return for_lease_monitor_specs;
+}
+
static gboolean
meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skeleton,
GDBusMethodInvocation *invocation,
@@ -2730,6 +2798,8 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet
GVariantIter logical_monitor_configs_iter;
MetaMonitorsConfig *config;
GList *logical_monitor_configs = NULL;
+ GList *disabled_monitor_specs = NULL;
+ GList *for_lease_monitor_specs = NULL;
GError *error = NULL;
if (serial != manager->serial)
@@ -2818,10 +2888,17 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet
logical_monitor_config);
}
- config = meta_monitors_config_new (manager,
- logical_monitor_configs,
- layout_mode,
- META_MONITORS_CONFIG_FLAG_NONE);
+ disabled_monitor_specs =
+ create_disabled_monitor_specs_for_config (manager,
+ logical_monitor_configs);
+ for_lease_monitor_specs =
+ create_for_lease_monitor_specs_from_variant (properties_variant);
+
+ config = meta_monitors_config_new_full (logical_monitor_configs,
+ disabled_monitor_specs,
+ for_lease_monitor_specs,
+ layout_mode,
+ META_MONITORS_CONFIG_FLAG_NONE);
if (!meta_verify_monitors_config (config, manager, &error))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c
index 1f87c36528..380f55cc75 100644
--- a/src/tests/monitor-unit-tests.c
+++ b/src/tests/monitor-unit-tests.c
@@ -9564,6 +9564,10 @@ meta_test_monitor_custom_for_lease_config_dbus (void)
MetaMonitorTestSetup *test_setup;
g_autoptr (GDBusProxy) display_config_proxy = NULL;
g_autoptr (GVariant) state = NULL;
+ uint32_t serial;
+ GVariantBuilder b;
+ g_autoptr (GVariant) apply_config_ret = NULL;
+ g_autoptr (GVariant) new_state = NULL;
test_setup = meta_create_monitor_test_setup (test_backend,
&test_case_setup,
@@ -9597,6 +9601,62 @@ meta_test_monitor_custom_for_lease_config_dbus (void)
assert_monitor_state (state, 0, "DP-1", FALSE);
assert_monitor_state (state, 1, "DP-2", TRUE);
+
+ /* Swap monitor for lease */
+ serial = g_variant_get_uint32 (g_variant_get_child_value (state, 0));
+
+ g_variant_builder_init (&b, G_VARIANT_TYPE ("(uua(iiduba(ssa{sv}))a{sv})"));
+ g_variant_builder_add (&b, "u", serial); /* Serial from GetCurrentState */
+ g_variant_builder_add (&b, "u", 1); /* Method: Temporary */
+
+ /* Logical monitors */
+ g_variant_builder_open (&b, G_VARIANT_TYPE ("a(iiduba(ssa{sv}))"));
+ g_variant_builder_open (&b, G_VARIANT_TYPE ("(iiduba(ssa{sv}))"));
+ g_variant_builder_add (&b, "i", 0); /* x */
+ g_variant_builder_add (&b, "i", 0); /* y */
+ g_variant_builder_add (&b, "d", 1.0); /* Scale */
+ g_variant_builder_add (&b, "u", 0); /* Transform */
+ g_variant_builder_add (&b, "b", TRUE); /* Primary */
+ g_variant_builder_add_parsed (&b, "[(%s, %s, @a{sv} {})]", /* Monitors */
+ "DP-2",
+ "800x600@60.000");
+ g_variant_builder_close (&b);
+ g_variant_builder_close (&b);
+
+ /* Properties */
+ g_variant_builder_open (&b, G_VARIANT_TYPE ("a{sv}"));
+ g_variant_builder_add_parsed (&b, "{'monitors-for-lease', <[(%s, %s, %s, %s)]>}",
+ "DP-1",
+ "MetaProduct\'s Inc.",
+ "MetaMonitor",
+ "0x123456");
+ g_variant_builder_close (&b);
+
+ g_dbus_proxy_call (display_config_proxy,
+ "ApplyMonitorsConfig",
+ g_variant_builder_end (&b),
+ G_DBUS_CALL_FLAGS_NO_AUTO_START,
+ -1,
+ NULL,
+ on_proxy_call_cb,
+ &apply_config_ret);
+ while (!apply_config_ret)
+ g_main_context_iteration (NULL, TRUE);
+
+ /* Check that monitors changed */
+ g_dbus_proxy_call (display_config_proxy,
+ "GetCurrentState",
+ NULL,
+ G_DBUS_CALL_FLAGS_NO_AUTO_START,
+ -1,
+ NULL,
+ on_proxy_call_cb,
+ &new_state);
+ while (!new_state)
+ g_main_context_iteration (NULL, TRUE);
+
+ assert_monitor_state (new_state, 0, "DP-1", TRUE);
+ assert_monitor_state (new_state, 1, "DP-2", FALSE);
}
static gboolean
--
2.48.1

View File

@ -0,0 +1,74 @@
From 863b31cae9be5e8e0467f1a9f93e7348d41f7e88 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= <jexposit@redhat.com>
Date: Tue, 29 Oct 2024 11:35:17 +0100
Subject: [PATCH 3/5] output/kms: Add meta_output_kms_from_kms_connector()
Add a function that returns a MetaOutputKms (if any) from a
MetaKmsConnector.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4112>
---
src/backends/native/meta-output-kms.c | 19 +++++++++++++++++++
src/backends/native/meta-output-kms.h | 2 ++
2 files changed, 21 insertions(+)
diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c
index 684cf0e094..27b7533a5e 100644
--- a/src/backends/native/meta-output-kms.c
+++ b/src/backends/native/meta-output-kms.c
@@ -47,6 +47,8 @@ struct _MetaOutputKms
G_DEFINE_TYPE (MetaOutputKms, meta_output_kms, META_TYPE_OUTPUT_NATIVE)
+static GQuark kms_connector_output_kms_quark;
+
MetaKmsConnector *
meta_output_kms_get_kms_connector (MetaOutputKms *output_kms)
{
@@ -90,6 +92,13 @@ meta_output_kms_can_clone (MetaOutputKms *output_kms,
return TRUE;
}
+MetaOutputKms *
+meta_output_kms_from_kms_connector (MetaKmsConnector *connector)
+{
+ return g_object_get_qdata (G_OBJECT (connector),
+ kms_connector_output_kms_quark);
+}
+
static GBytes *
meta_output_kms_read_edid (MetaOutputNative *output_native)
{
@@ -534,6 +543,16 @@ meta_output_kms_new (MetaGpuKms *gpu_kms,
meta_output_unassign_crtc (output);
}
+ if (!kms_connector_output_kms_quark)
+ {
+ kms_connector_output_kms_quark =
+ g_quark_from_static_string ("kms-connector-output-kms-quark");
+ }
+
+ g_object_set_qdata (G_OBJECT (kms_connector),
+ kms_connector_output_kms_quark,
+ output_kms);
+
return output_kms;
}
diff --git a/src/backends/native/meta-output-kms.h b/src/backends/native/meta-output-kms.h
index e0eb60eb4d..4391dc1899 100644
--- a/src/backends/native/meta-output-kms.h
+++ b/src/backends/native/meta-output-kms.h
@@ -39,6 +39,8 @@ MetaKmsConnector * meta_output_kms_get_kms_connector (MetaOutputKms *output_kms)
uint32_t meta_output_kms_get_connector_id (MetaOutputKms *output_kms);
+MetaOutputKms * meta_output_kms_from_kms_connector (MetaKmsConnector *connector);
+
MetaOutputKms * meta_output_kms_new (MetaGpuKms *gpu_kms,
MetaKmsConnector *kms_connector,
MetaOutput *old_output,
--
2.48.1

View File

@ -0,0 +1,78 @@
From 63b7d958f226b05694eeeed7d1a7bc77d84464ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= <jexposit@redhat.com>
Date: Tue, 29 Oct 2024 12:09:21 +0100
Subject: [PATCH 4/5] kms/connector: Rename meta_kms_connector_is_for_lease()
Now that connectors can be configured as for lease, rename the function
to meta_kms_connector_is_non_desktop() to make clear that it returns
the hardware configuration rather than the user configuration.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4112>
---
src/backends/native/meta-drm-lease.c | 4 ++--
src/backends/native/meta-gpu-kms.c | 2 +-
src/backends/native/meta-kms-connector.c | 2 +-
src/backends/native/meta-kms-connector.h | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/backends/native/meta-drm-lease.c b/src/backends/native/meta-drm-lease.c
index 7cddb6c8ed..302147e9bb 100644
--- a/src/backends/native/meta-drm-lease.c
+++ b/src/backends/native/meta-drm-lease.c
@@ -227,7 +227,7 @@ find_resources_to_lease (MetaDrmLeaseManager *lease_manager,
MetaKmsDevice *connector_device;
if (!g_list_find (available_connectors, connector) ||
- !meta_kms_connector_is_for_lease (connector))
+ !meta_kms_connector_is_non_desktop (connector))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"Failed to find connector %u (%s)",
@@ -645,7 +645,7 @@ update_connectors (MetaDrmLeaseManager *lease_manager,
kms_connector = o->data;
lease = NULL;
- if (!meta_kms_connector_is_for_lease (kms_connector))
+ if (!meta_kms_connector_is_non_desktop (kms_connector))
continue;
if (g_list_find (lease_manager->connectors, kms_connector))
diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c
index 3b4356ca6b..c633d6d68e 100644
--- a/src/backends/native/meta-gpu-kms.c
+++ b/src/backends/native/meta-gpu-kms.c
@@ -355,7 +355,7 @@ init_outputs (MetaGpuKms *gpu_kms)
if (!meta_kms_connector_get_current_state (kms_connector))
continue;
- if (meta_kms_connector_is_for_lease (kms_connector))
+ if (meta_kms_connector_is_non_desktop (kms_connector))
continue;
old_output =
diff --git a/src/backends/native/meta-kms-connector.c b/src/backends/native/meta-kms-connector.c
index cc6cd89f56..7723416aa3 100644
--- a/src/backends/native/meta-kms-connector.c
+++ b/src/backends/native/meta-kms-connector.c
@@ -165,7 +165,7 @@ meta_kms_connector_get_current_state (MetaKmsConnector *connector)
}
gboolean
-meta_kms_connector_is_for_lease (MetaKmsConnector *connector)
+meta_kms_connector_is_non_desktop (MetaKmsConnector *connector)
{
const char *lease_connectors_str;
diff --git a/src/backends/native/meta-kms-connector.h b/src/backends/native/meta-kms-connector.h
index 84ee7f5c26..328465d0fa 100644
--- a/src/backends/native/meta-kms-connector.h
+++ b/src/backends/native/meta-kms-connector.h
@@ -102,4 +102,4 @@ MetaKmsMode * meta_kms_connector_get_preferred_mode (MetaKmsConnector *connector
META_EXPORT_TEST
const MetaKmsConnectorState * meta_kms_connector_get_current_state (MetaKmsConnector *connector);
-gboolean meta_kms_connector_is_for_lease (MetaKmsConnector *connector);
+gboolean meta_kms_connector_is_non_desktop (MetaKmsConnector *connector);
--
2.48.1

View File

@ -0,0 +1,130 @@
From 55910e467f42ce9d6e761afd8f50110cb1cc3164 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= <jexposit@redhat.com>
Date: Mon, 28 Oct 2024 08:54:45 +0100
Subject: [PATCH 5/5] native/drm-lease: Handle monitors configured for lease
Follow the configuration stored in MetaMonitor and make connectors
configured as for lease available to Wayland clients.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4112>
---
src/backends/native/meta-drm-lease.c | 45 ++++++++++++++++++++++++++--
1 file changed, 43 insertions(+), 2 deletions(-)
diff --git a/src/backends/native/meta-drm-lease.c b/src/backends/native/meta-drm-lease.c
index 302147e9bb..582f869b3b 100644
--- a/src/backends/native/meta-drm-lease.c
+++ b/src/backends/native/meta-drm-lease.c
@@ -21,12 +21,14 @@
#include <glib.h>
+#include "backends/meta-logical-monitor.h"
#include "backends/native/meta-crtc-kms.h"
#include "backends/native/meta-kms.h"
#include "backends/native/meta-kms-connector.h"
#include "backends/native/meta-kms-crtc-private.h"
#include "backends/native/meta-kms-device.h"
#include "backends/native/meta-kms-plane.h"
+#include "backends/native/meta-output-kms.h"
enum
{
@@ -68,6 +70,7 @@ struct _MetaDrmLeaseManager
gulong resources_changed_handler_id;
gulong lease_changed_handler_id;
+ gulong monitors_changed_handler_id;
/* MetaKmsDevice *kms_device */
GList *devices;
@@ -179,6 +182,32 @@ find_plane_to_lease (MetaKmsCrtc *kms_crtc,
return NULL;
}
+static gboolean
+is_connector_configured_for_lease (MetaKmsConnector *connector)
+{
+ const MetaKmsConnectorState *connector_state;
+ MetaOutputKms *output_kms;
+ MetaMonitor *monitor;
+
+ connector_state = meta_kms_connector_get_current_state (connector);
+ if (!connector_state)
+ return FALSE;
+
+ output_kms = meta_output_kms_from_kms_connector (connector);
+ if (!output_kms)
+ return FALSE;
+
+ monitor = meta_output_get_monitor (META_OUTPUT (output_kms));
+ return meta_monitor_is_for_lease (monitor);
+}
+
+static gboolean
+is_connector_for_lease (MetaKmsConnector *connector)
+{
+ return meta_kms_connector_is_non_desktop (connector) ||
+ is_connector_configured_for_lease (connector);
+}
+
static gboolean
find_resources_to_lease (MetaDrmLeaseManager *lease_manager,
MetaKmsDevice *kms_device,
@@ -227,7 +256,7 @@ find_resources_to_lease (MetaDrmLeaseManager *lease_manager,
MetaKmsDevice *connector_device;
if (!g_list_find (available_connectors, connector) ||
- !meta_kms_connector_is_non_desktop (connector))
+ !is_connector_for_lease (connector))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"Failed to find connector %u (%s)",
@@ -645,7 +674,7 @@ update_connectors (MetaDrmLeaseManager *lease_manager,
kms_connector = o->data;
lease = NULL;
- if (!meta_kms_connector_is_non_desktop (kms_connector))
+ if (!is_connector_for_lease (kms_connector))
continue;
if (g_list_find (lease_manager->connectors, kms_connector))
@@ -845,6 +874,9 @@ meta_drm_lease_manager_constructed (GObject *object)
{
MetaDrmLeaseManager *lease_manager = META_DRM_LEASE_MANAGER (object);
MetaKms *kms = lease_manager->kms;
+ MetaBackend *backend = meta_kms_get_backend (kms);
+ MetaMonitorManager *monitor_manager =
+ meta_backend_get_monitor_manager (backend);
lease_manager->resources_changed_handler_id =
g_signal_connect (kms, "resources-changed",
@@ -854,6 +886,10 @@ meta_drm_lease_manager_constructed (GObject *object)
g_signal_connect (kms, "lease-changed",
G_CALLBACK (on_lease_changed),
lease_manager);
+ lease_manager->monitors_changed_handler_id =
+ g_signal_connect_swapped (monitor_manager, "monitors-changed-internal",
+ G_CALLBACK (update_resources),
+ lease_manager);
lease_manager->leases =
g_hash_table_new_full (NULL, NULL,
@@ -905,9 +941,14 @@ meta_drm_lease_manager_dispose (GObject *object)
{
MetaDrmLeaseManager *lease_manager = META_DRM_LEASE_MANAGER (object);
MetaKms *kms = lease_manager->kms;
+ MetaBackend *backend = meta_kms_get_backend (kms);
+ MetaMonitorManager *monitor_manager =
+ meta_backend_get_monitor_manager (backend);
g_clear_signal_handler (&lease_manager->resources_changed_handler_id, kms);
g_clear_signal_handler (&lease_manager->lease_changed_handler_id, kms);
+ g_clear_signal_handler (&lease_manager->monitors_changed_handler_id,
+ monitor_manager);
g_list_free_full (g_steal_pointer (&lease_manager->devices), g_object_unref);
g_list_free_full (g_steal_pointer (&lease_manager->connectors),
--
2.48.1

View File

@ -46,6 +46,19 @@ Patch: 0002-cursor-renderer-native-Store-formats-in-MetaCursorRe.patch
Patch: 0003-cursor-renderer-native-Probe-formats-supported-by-cu.patch
Patch: 0001-cursor-renderer-native-Skip-init_hw_cursor_support_f.patch
# RHEL-62220
# DRM lease configuration via monitors.xml and D-Bus:
# https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4112
Patch: 0001-monitor-manager-Add-forlease-config-to-monitors.xml.patch
Patch: 0002-monitor-Keep-track-of-the-for-lease-status.patch
Patch: 0003-output-kms-Add-meta_output_kms_from_kms_connector.patch
Patch: 0004-kms-connector-Rename-meta_kms_connector_is_for_lease.patch
Patch: 0005-native-drm-lease-Handle-monitors-configured-for-leas.patch
# https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4121
Patch: 0001-monitor-manager-Return-for-lease-status-in-GetCurren.patch
Patch: 0002-monitor-manager-Allow-to-check-if-config-has-a-visib.patch
Patch: 0003-monitor-manager-Configure-for-lease-monitors-in-Appl.patch
# Backports from gnome-47 branch between 47.5 and 47.6
Patch: 0001-wayland-Fix-refresh-interval-reporting-in-presentati.patch
Patch: 0002-input-capture-session-Disconnect-on_keymap_changed-o.patch