[mutter] virtual-monitor: Add way to change virtual monitor mode
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] virtual-monitor: Add way to change virtual monitor mode
- Date: Fri, 4 Mar 2022 19:04:52 +0000 (UTC)
commit 34d0e68aef8623d2e21cf7f29d70729cee8d7d1f
Author: Jonas Ã…dahl <jadahl gmail com>
Date: Thu Dec 16 11:25:37 2021 +0100
virtual-monitor: Add way to change virtual monitor mode
This can be used to change the size of the virtual monitor without
recreating it.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2270>
src/backends/meta-output.c | 18 ++++++++++++
src/backends/meta-output.h | 5 ++++
src/backends/meta-virtual-monitor.c | 16 ++++++++--
src/backends/meta-virtual-monitor.h | 11 +++++++
src/backends/native/meta-monitor-manager-native.c | 36 +++++++++++++++++++++++
src/backends/native/meta-virtual-monitor-native.c | 30 +++++++++++++++++++
6 files changed, 114 insertions(+), 2 deletions(-)
---
diff --git a/src/backends/meta-output.c b/src/backends/meta-output.c
index f198752f7a..ed48075072 100644
--- a/src/backends/meta-output.c
+++ b/src/backends/meta-output.c
@@ -541,3 +541,21 @@ meta_tile_info_equal (MetaTileInfo *a,
return TRUE;
}
+
+void
+meta_output_update_modes (MetaOutput *output,
+ MetaCrtcMode *preferred_mode,
+ MetaCrtcMode **modes,
+ int n_modes)
+{
+ MetaOutputPrivate *priv = meta_output_get_instance_private (output);
+ int i;
+
+ for (i = 0; i < priv->info->n_modes; i++)
+ g_object_unref (priv->info->modes[i]);
+ g_free (priv->info->modes);
+
+ priv->info->preferred_mode = preferred_mode;
+ priv->info->modes = modes;
+ priv->info->n_modes = n_modes;
+}
diff --git a/src/backends/meta-output.h b/src/backends/meta-output.h
index 10ed947b9c..6c90d7e69e 100644
--- a/src/backends/meta-output.h
+++ b/src/backends/meta-output.h
@@ -212,4 +212,9 @@ MetaMonitorTransform meta_output_logical_to_crtc_transform (MetaOutput
MetaMonitorTransform meta_output_crtc_to_logical_transform (MetaOutput *output,
MetaMonitorTransform transform);
+void meta_output_update_modes (MetaOutput *output,
+ MetaCrtcMode *preferred_mode,
+ MetaCrtcMode **modes,
+ int n_modes);
+
#endif /* META_OUTPUT_H */
diff --git a/src/backends/meta-virtual-monitor.c b/src/backends/meta-virtual-monitor.c
index f4a207a6d8..9774a9e650 100644
--- a/src/backends/meta-virtual-monitor.c
+++ b/src/backends/meta-virtual-monitor.c
@@ -135,7 +135,8 @@ meta_virtual_monitor_set_property (GObject *object,
priv->crtc = g_value_get_object (value);
break;
case PROP_CRTC_MODE:
- priv->crtc_mode = g_value_get_object (value);
+ g_set_object (&priv->crtc_mode,
+ g_value_get_object (value));
break;
case PROP_OUTPUT:
priv->output = g_value_get_object (value);
@@ -219,7 +220,6 @@ meta_virtual_monitor_class_init (MetaVirtualMonitorClass *klass)
"The virtual CRTC mode",
META_TYPE_CRTC_MODE,
G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
obj_props[PROP_OUTPUT] =
g_param_spec_object ("output",
@@ -238,3 +238,15 @@ meta_virtual_monitor_class_init (MetaVirtualMonitorClass *klass)
NULL, NULL, NULL,
G_TYPE_NONE, 0);
}
+
+void
+meta_virtual_monitor_set_mode (MetaVirtualMonitor *virtual_monitor,
+ int width,
+ int height,
+ float refresh_rate)
+{
+ MetaVirtualMonitorClass *klass =
+ META_VIRTUAL_MONITOR_GET_CLASS (virtual_monitor);
+
+ klass->set_mode (virtual_monitor, width, height, refresh_rate);
+}
diff --git a/src/backends/meta-virtual-monitor.h b/src/backends/meta-virtual-monitor.h
index 1daa1d8bee..c127c46cad 100644
--- a/src/backends/meta-virtual-monitor.h
+++ b/src/backends/meta-virtual-monitor.h
@@ -50,6 +50,11 @@ G_DECLARE_DERIVABLE_TYPE (MetaVirtualMonitor, meta_virtual_monitor,
struct _MetaVirtualMonitorClass
{
GObjectClass parent_class;
+
+ void (* set_mode) (MetaVirtualMonitor *virtual_monitor,
+ int width,
+ int height,
+ float refresh_rate);
};
META_EXPORT_TEST
@@ -70,6 +75,12 @@ MetaCrtcMode * meta_virtual_monitor_get_crtc_mode (MetaVirtualMonitor *virtual_m
META_EXPORT_TEST
MetaOutput * meta_virtual_monitor_get_output (MetaVirtualMonitor *virtual_monitor);
+META_EXPORT_TEST
+void meta_virtual_monitor_set_mode (MetaVirtualMonitor *virtual_monitor,
+ int width,
+ int height,
+ float refresh_rate);
+
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaVirtualMonitorInfo,
meta_virtual_monitor_info_free)
diff --git a/src/backends/native/meta-monitor-manager-native.c
b/src/backends/native/meta-monitor-manager-native.c
index a0e36a4b93..ac53e6d157 100644
--- a/src/backends/native/meta-monitor-manager-native.c
+++ b/src/backends/native/meta-monitor-manager-native.c
@@ -83,6 +83,8 @@ struct _MetaMonitorManagerNative
GHashTable *crtc_gamma_cache;
gboolean needs_outputs;
+
+ guint rebuild_virtual_idle_id;
};
struct _MetaMonitorManagerNativeClass
@@ -778,6 +780,35 @@ meta_monitor_manager_native_set_privacy_screen_enabled (MetaMonitorManager *mana
return TRUE;
}
+static gboolean
+rebuild_virtual_idle_cb (gpointer user_data)
+{
+ MetaMonitorManager *manager = user_data;
+ MetaMonitorManagerNative *manager_native =
+ META_MONITOR_MANAGER_NATIVE (manager);
+
+ manager_native->rebuild_virtual_idle_id = 0;
+
+ meta_monitor_manager_reconfigure (manager);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+on_virtual_monitor_mode_changed (MetaVirtualMonitor *virtual_monitor,
+ GParamSpec *pspec,
+ MetaMonitorManager *manager)
+{
+ MetaMonitorManagerNative *manager_native =
+ META_MONITOR_MANAGER_NATIVE (manager);
+
+ if (manager_native->rebuild_virtual_idle_id)
+ return;
+
+ manager_native->rebuild_virtual_idle_id =
+ g_idle_add (rebuild_virtual_idle_cb, manager);
+}
+
static MetaVirtualMonitor *
meta_monitor_manager_native_create_virtual_monitor (MetaMonitorManager *manager,
const MetaVirtualMonitorInfo *info,
@@ -790,6 +821,10 @@ meta_monitor_manager_native_create_virtual_monitor (MetaMonitorManager
id = allocate_virtual_monitor_id (manager_native);
virtual_monitor_native = meta_virtual_monitor_native_new (id, info);
+ g_signal_connect (virtual_monitor_native, "notify::crtc-mode",
+ G_CALLBACK (on_virtual_monitor_mode_changed),
+ manager);
+
return META_VIRTUAL_MONITOR (virtual_monitor_native);
}
@@ -819,6 +854,7 @@ meta_monitor_manager_native_dispose (GObject *object)
MetaMonitorManagerNative *manager_native =
META_MONITOR_MANAGER_NATIVE (object);
+ g_clear_handle_id (&manager_native->rebuild_virtual_idle_id, g_source_remove);
g_clear_pointer (&manager_native->crtc_gamma_cache,
g_hash_table_unref);
diff --git a/src/backends/native/meta-virtual-monitor-native.c
b/src/backends/native/meta-virtual-monitor-native.c
index 93d351237f..97eff0ee6c 100644
--- a/src/backends/native/meta-virtual-monitor-native.c
+++ b/src/backends/native/meta-virtual-monitor-native.c
@@ -38,6 +38,33 @@ static uint64_t mode_id = 1;
G_DEFINE_TYPE (MetaVirtualMonitorNative, meta_virtual_monitor_native,
META_TYPE_VIRTUAL_MONITOR)
+static void
+meta_virtual_monitor_native_set_mode (MetaVirtualMonitor *virtual_monitor,
+ int width,
+ int height,
+ float refresh_rate)
+{
+ MetaOutput *output = meta_virtual_monitor_get_output (virtual_monitor);
+ MetaVirtualModeInfo info;
+ MetaCrtcModeVirtual *crtc_mode_virtual;
+ MetaCrtcMode **modes;
+
+ info = (MetaVirtualModeInfo) {
+ .width = width,
+ .height = height,
+ .refresh_rate = refresh_rate,
+ };
+ crtc_mode_virtual = meta_crtc_mode_virtual_new (mode_id++, &info);
+
+ modes = g_new0 (MetaCrtcMode *, 1);
+ modes[0] = META_CRTC_MODE (crtc_mode_virtual);
+ meta_output_update_modes (output, modes[0], modes, 1);
+
+ g_object_set (virtual_monitor,
+ "crtc-mode", crtc_mode_virtual,
+ NULL);
+}
+
uint64_t
meta_virtual_monitor_native_get_id (MetaVirtualMonitorNative *virtual_monitor_native)
{
@@ -77,4 +104,7 @@ meta_virtual_monitor_native_init (MetaVirtualMonitorNative *virtual_monitor_nati
static void
meta_virtual_monitor_native_class_init (MetaVirtualMonitorNativeClass *klass)
{
+ MetaVirtualMonitorClass *virtual_monitor_class = META_VIRTUAL_MONITOR_CLASS (klass);
+
+ virtual_monitor_class->set_mode = meta_virtual_monitor_native_set_mode;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]