From 9ceeddd952904f8b51943f4e034cf5c75a7d6b8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 22 Dec 2016 15:22:13 +0800 Subject: [PATCH] monitor: Track current monitor mode Track what monitor mode is the current. This is derived from the mode of the corresponding CRTC's. https://bugzilla.gnome.org/show_bug.cgi?id=777732 --- src/backends/meta-monitor-manager.c | 14 +++++++ src/backends/meta-monitor.c | 62 +++++++++++++++++++++++++++++ src/backends/meta-monitor.h | 4 ++ 3 files changed, 80 insertions(+) diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index d1f35e373..195990bc4 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -1533,6 +1533,19 @@ meta_monitor_manager_read_current_state (MetaMonitorManager *manager) meta_monitor_manager_free_crtc_array (old_crtcs, n_old_crtcs); } +static void +meta_monitor_manager_update_monitor_modes_derived (MetaMonitorManager *manager) +{ + GList *l; + + for (l = manager->monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + + meta_monitor_derive_current_mode (monitor); + } +} + void meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager) { @@ -1545,6 +1558,7 @@ meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager) old_logical_monitors = manager->logical_monitors; make_logical_config (manager); + meta_monitor_manager_update_monitor_modes_derived (manager); /* Tell the backend about that the monitors changed before emitting the * signal, so that the backend can prepare itself before all the signal diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c index e7b280512..be8f309c0 100644 --- a/src/backends/meta-monitor.c +++ b/src/backends/meta-monitor.c @@ -38,6 +38,7 @@ typedef struct _MetaMonitorPrivate GList *modes; MetaMonitorMode *preferred_mode; + MetaMonitorMode *current_mode; MetaMonitorSpec *spec; @@ -293,6 +294,8 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal) if (crtc_mode == output->preferred_mode) monitor_priv->preferred_mode = mode; + if (output->crtc && crtc_mode == output->crtc->current_mode) + monitor_priv->current_mode = mode; monitor_priv->modes = g_list_append (monitor_priv->modes, mode); } @@ -444,6 +447,7 @@ meta_monitor_tiled_generate_modes (MetaMonitorTiled *monitor_tiled) MetaMonitorPrivate *monitor_priv = meta_monitor_get_instance_private (monitor); MetaMonitorMode *mode; + gboolean preferred_mode_is_current; GList *l; int i; @@ -453,6 +457,7 @@ meta_monitor_tiled_generate_modes (MetaMonitorTiled *monitor_tiled) &mode->spec.height); mode->crtc_modes = g_new (MetaMonitorCrtcMode, g_list_length (monitor_priv->outputs)); + preferred_mode_is_current = TRUE; for (l = monitor_priv->outputs, i = 0; l; l = l->next, i++) { MetaOutput *output = l->data; @@ -474,11 +479,18 @@ meta_monitor_tiled_generate_modes (MetaMonitorTiled *monitor_tiled) preferred_crtc_mode->refresh_rate)); mode->spec.refresh_rate = preferred_crtc_mode->refresh_rate; + + if (!output->crtc || + mode->crtc_modes[i].crtc_mode != output->crtc->current_mode) + preferred_mode_is_current = FALSE; } monitor_priv->modes = g_list_append (monitor_priv->modes, mode); monitor_priv->preferred_mode = mode; + if (preferred_mode_is_current) + monitor_priv->current_mode = mode; + /* TODO: Add single tile modes */ } @@ -606,6 +618,56 @@ meta_monitor_get_preferred_mode (MetaMonitor *monitor) return priv->preferred_mode; } +MetaMonitorMode * +meta_monitor_get_current_mode (MetaMonitor *monitor) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + + return priv->current_mode; +} + +static gboolean +is_monitor_mode_assigned (MetaMonitor *monitor, + MetaMonitorMode *mode) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + GList *l; + int i; + + for (l = priv->outputs, i = 0; l; l = l->next, i++) + { + MetaOutput *output = l->data; + MetaMonitorCrtcMode *monitor_crtc_mode = &mode->crtc_modes[i]; + + if (!output->crtc || + output->crtc->current_mode != monitor_crtc_mode->crtc_mode) + return FALSE; + } + + return TRUE; +} + +void +meta_monitor_derive_current_mode (MetaMonitor *monitor) +{ + MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor); + MetaMonitorMode *current_mode = NULL; + GList *l; + + for (l = priv->modes; l; l = l->next) + { + MetaMonitorMode *mode = l->data; + + if (is_monitor_mode_assigned (monitor, mode)) + { + current_mode = mode; + break; + } + } + + priv->current_mode = current_mode; +} + GList * meta_monitor_get_modes (MetaMonitor *monitor) { diff --git a/src/backends/meta-monitor.h b/src/backends/meta-monitor.h index fceae1b7c..c784d0f12 100644 --- a/src/backends/meta-monitor.h +++ b/src/backends/meta-monitor.h @@ -120,6 +120,10 @@ MetaMonitorMode * meta_monitor_get_mode_from_spec (MetaMonitor *monitor, MetaMonitorMode * meta_monitor_get_preferred_mode (MetaMonitor *monitor); +MetaMonitorMode * meta_monitor_get_current_mode (MetaMonitor *monitor); + +void meta_monitor_derive_current_mode (MetaMonitor *monitor); + GList * meta_monitor_get_modes (MetaMonitor *monitor); MetaMonitorModeSpec * meta_monitor_mode_get_spec (MetaMonitorMode *monitor_mode);