[mutter] monitor: Track current monitor mode



commit 9ceeddd952904f8b51943f4e034cf5c75a7d6b8b
Author: Jonas Ådahl <jadahl gmail com>
Date:   Thu Dec 22 15:22:13 2016 +0800

    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(+), 0 deletions(-)
---
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index d1f35e3..195990b 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 e7b2805..be8f309 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 fceae1b..c784d0f 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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]