[mutter] DisplayConfig: Add new API for getting current state



commit bc56971e188123f190fd9c001dc3a3c8727a3afb
Author: Jonas Ådahl <jadahl gmail com>
Date:   Fri Jan 20 16:55:43 2017 +0800

    DisplayConfig: Add new API for getting current state
    
    Add a D-Bus method for getting the current monitor and logical monitor
    state. Currently does not contain information about transforms or any
    limitations (such as limited CRTCs and cloning).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=777732

 src/backends/meta-monitor-manager.c    |  137 ++++++++++++++++++++++++++++++++
 src/org.gnome.Mutter.DisplayConfig.xml |   55 +++++++++++++
 2 files changed, 192 insertions(+), 0 deletions(-)
---
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index e3b68ad..b520e2e 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -1174,6 +1174,142 @@ meta_monitor_manager_legacy_handle_apply_configuration  (MetaDBusDisplayConfig *
   return TRUE;
 }
 
+#define META_DISPLAY_CONFIG_MODE_FLAGS_PREFERRED (1 << 0)
+#define META_DISPLAY_CONFIG_MODE_FLAGS_CURRENT (1 << 1)
+
+#define MODE_FORMAT "(iidiu)"
+#define MODES_FORMAT "a" MODE_FORMAT
+#define MONITOR_SPEC_FORMAT "(ssss)"
+#define MONITOR_FORMAT "(" MONITOR_SPEC_FORMAT MODES_FORMAT "a{sv})"
+#define MONITORS_FORMAT "a" MONITOR_FORMAT
+
+#define LOGICAL_MONITOR_MONITORS_FORMAT "a" MONITOR_SPEC_FORMAT
+#define LOGICAL_MONITOR_FORMAT "(iiii" LOGICAL_MONITOR_MONITORS_FORMAT "iba{sv})"
+#define LOGICAL_MONITORS_FORMAT "a" LOGICAL_MONITOR_FORMAT
+
+static gboolean
+meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton,
+                                               GDBusMethodInvocation *invocation)
+{
+  MetaMonitorManager *manager = META_MONITOR_MANAGER (skeleton);
+  GVariantBuilder monitors_builder;
+  GVariantBuilder logical_monitors_builder;
+  GVariantBuilder max_screen_size_builder;
+  GList *l;
+
+  g_variant_builder_init (&monitors_builder,
+                          G_VARIANT_TYPE (MONITORS_FORMAT));
+  g_variant_builder_init (&logical_monitors_builder,
+                          G_VARIANT_TYPE (LOGICAL_MONITORS_FORMAT));
+
+  for (l = manager->monitors; l; l = l->next)
+    {
+      MetaMonitor *monitor = l->data;
+      MetaMonitorSpec *monitor_spec = meta_monitor_get_spec (monitor);
+      MetaMonitorMode *current_mode;
+      MetaMonitorMode *preferred_mode;
+      GVariantBuilder modes_builder;
+      GList *k;
+
+      current_mode = meta_monitor_get_current_mode (monitor);
+      preferred_mode = meta_monitor_get_preferred_mode (monitor);
+
+      g_variant_builder_init (&modes_builder, G_VARIANT_TYPE (MODES_FORMAT));
+      for (k = meta_monitor_get_modes (monitor); k; k = k->next)
+        {
+          MetaMonitorMode *monitor_mode = k->data;
+          MetaMonitorModeSpec *monitor_mode_spec;
+          int preferred_scale;
+          uint32_t flags = 0;
+
+          monitor_mode_spec = meta_monitor_mode_get_spec (monitor_mode);
+          preferred_scale =
+            meta_monitor_manager_calculate_monitor_mode_scale (manager,
+                                                               monitor,
+                                                               monitor_mode);
+          if (monitor_mode == current_mode)
+            flags |= META_DISPLAY_CONFIG_MODE_FLAGS_CURRENT;
+          if (monitor_mode == preferred_mode)
+            flags |= META_DISPLAY_CONFIG_MODE_FLAGS_PREFERRED;
+
+          g_variant_builder_add (&modes_builder, MODE_FORMAT,
+                                 monitor_mode_spec->width,
+                                 monitor_mode_spec->height,
+                                 monitor_mode_spec->refresh_rate,
+                                 preferred_scale,
+                                 flags);
+        }
+
+      g_variant_builder_add (&monitors_builder, MONITOR_FORMAT,
+                             monitor_spec->connector,
+                             monitor_spec->vendor,
+                             monitor_spec->product,
+                             monitor_spec->serial,
+                             &modes_builder,
+                             NULL);
+    }
+
+  for (l = manager->logical_monitors; l; l = l->next)
+    {
+      MetaLogicalMonitor *logical_monitor = l->data;
+      GVariantBuilder logical_monitor_monitors_builder;
+      GList *k;
+
+      g_variant_builder_init (&logical_monitor_monitors_builder,
+                              G_VARIANT_TYPE (LOGICAL_MONITOR_MONITORS_FORMAT));
+
+      for (k = logical_monitor->monitors; k; k = k->next)
+        {
+          MetaMonitor *monitor = k->data;
+          MetaMonitorSpec *monitor_spec = meta_monitor_get_spec (monitor);
+
+          g_variant_builder_add (&logical_monitor_monitors_builder,
+                                 MONITOR_SPEC_FORMAT,
+                                 monitor_spec->connector,
+                                 monitor_spec->vendor,
+                                 monitor_spec->product,
+                                 monitor_spec->serial);
+        }
+
+      g_variant_builder_add (&logical_monitors_builder,
+                             LOGICAL_MONITOR_FORMAT,
+                             logical_monitor->rect.x,
+                             logical_monitor->rect.y,
+                             logical_monitor->rect.width,
+                             logical_monitor->rect.height,
+                             &logical_monitor_monitors_builder,
+                             logical_monitor->scale,
+                             logical_monitor->is_primary,
+                             NULL);
+    }
+
+  g_variant_builder_init (&max_screen_size_builder,
+                          G_VARIANT_TYPE ("(ii)"));
+  g_variant_builder_add (&max_screen_size_builder, "i",
+                         manager->max_screen_width);
+  g_variant_builder_add (&max_screen_size_builder, "i",
+                         manager->max_screen_height);
+
+  meta_dbus_display_config_complete_get_current_state (
+    skeleton,
+    invocation,
+    manager->serial,
+    g_variant_builder_end (&monitors_builder),
+    g_variant_builder_end (&logical_monitors_builder),
+    g_variant_builder_end (&max_screen_size_builder));
+
+  return TRUE;
+}
+
+#undef MODE_FORMAT
+#undef MODES_FORMAT
+#undef MONITOR_SPEC_FORMAT
+#undef MONITOR_FORMAT
+#undef MONITORS_FORMAT
+#undef LOGICAL_MONITOR_MONITORS_FORMAT
+#undef LOGICAL_MONITOR_FORMAT
+#undef LOGICAL_MONITORS_FORMAT
+
 static void
 legacy_confirm_configuration (MetaMonitorManager *manager,
                               gboolean            confirmed)
@@ -1378,6 +1514,7 @@ meta_monitor_manager_display_config_init (MetaDBusDisplayConfigIface *iface)
   iface->handle_change_backlight = meta_monitor_manager_handle_change_backlight;
   iface->handle_get_crtc_gamma = meta_monitor_manager_handle_get_crtc_gamma;
   iface->handle_set_crtc_gamma = meta_monitor_manager_handle_set_crtc_gamma;
+  iface->handle_get_current_state = meta_monitor_manager_handle_get_current_state;
 }
 
 static void
diff --git a/src/org.gnome.Mutter.DisplayConfig.xml b/src/org.gnome.Mutter.DisplayConfig.xml
index 16ef01e..a71e145 100644
--- a/src/org.gnome.Mutter.DisplayConfig.xml
+++ b/src/org.gnome.Mutter.DisplayConfig.xml
@@ -290,5 +290,60 @@
        The client should then call GetResources() to read the new layout.
     -->
     <signal name="MonitorsChanged" />
+
+    <!--
+       GetCurrentState:
+       @serial: configuration serial
+       @monitors: available monitors
+       @logical_monitors: current logical monitor configuration
+       @max_screen_size: the maximum screen size
+
+       @monitors represent connected physical monitors
+
+       * s connector: connector name (e.g. HDMI-1, DP-1, etc)
+       * s vendor: vendor name
+       * s product: product name
+       * s serial: product serial
+       * a(iidu) modes: available modes
+           * i width: width in physical pixels
+           * i height: height in physical pixels
+           * d refresh rate: refresh rate
+           * i preferred scale: scale preferred as per calculations
+           * u flags: mode flags (see below)
+       * a{sv} properties: optional properties, including:
+           - "width_mm" (i): physical width of monitor in millimeters
+           - "height_mm" (i): physical height of monitor in millimeters
+
+        Possible mode flags:
+         1 : preferred mode
+         2 : current mode
+
+
+       @logical_monitors represent current logical monitor configuration
+
+       * i x: x position
+       * i y: y position
+       * i width: width
+       * i height: height
+       * a(sss) monitors: monitors displaying this logical monitor
+           * connector: name of the connector (e.g. DP-1, eDP-1 etc)
+           * vendor: vendor name
+           * product: product name
+           * serial: product serial
+       * i scale: scale
+       * b primary: true if this is the primary logical monitor
+       * a{sv} properties: possibly other properties
+
+
+       @max_screen_size represents the maximum size the screen may have, or 0x0 if no
+       such limit is known.
+
+    -->
+    <method name="GetCurrentState">
+      <arg name="serial" direction="out" type="u" />
+      <arg name="monitors" direction="out" type="a((ssss)a(iidiu)a{sv})" />
+      <arg name="logical_monitors" direction="out" type="a(iiiia(ssss)iba{sv})" />
+      <arg name="max_screen_size" direction="out" type="(ii)" />
+    </method>
   </interface>
 </node>


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