[gnome-flashback] display-config: handle x events



commit 5fcff6d9ca74409e8259f38e70a2bdcc6af6d16f
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Mon Mar 30 18:50:08 2015 +0300

    display-config: handle x events

 .../libdisplay-config/flashback-display-config.c   |   33 +++--
 .../libdisplay-config/flashback-monitor-manager.c  |  153 +++++++++++++++++++-
 .../libdisplay-config/flashback-monitor-manager.h  |    8 +-
 3 files changed, 171 insertions(+), 23 deletions(-)
---
diff --git a/gnome-flashback/libdisplay-config/flashback-display-config.c 
b/gnome-flashback/libdisplay-config/flashback-display-config.c
index a71e92b..dc25a2b 100644
--- a/gnome-flashback/libdisplay-config/flashback-display-config.c
+++ b/gnome-flashback/libdisplay-config/flashback-display-config.c
@@ -29,7 +29,6 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <math.h>
-#include "meta-dbus-display-config.h"
 #include "flashback-display-config.h"
 #include "flashback-monitor-config.h"
 #include "flashback-monitor-manager.h"
@@ -38,7 +37,7 @@ struct _FlashbackDisplayConfig
 {
   GObject                  parent;
   gint                     bus_name;
-  GDBusInterfaceSkeleton  *iface;
+  MetaDBusDisplayConfig   *skeleton;
   FlashbackMonitorManager *manager;
 };
 
@@ -838,30 +837,29 @@ on_bus_acquired (GDBusConnection *connection,
                  gpointer         user_data)
 {
   FlashbackDisplayConfig *config;
-  MetaDBusDisplayConfig *skeleton;
+  GDBusInterfaceSkeleton *iface;
   GError *error;
 
   config = FLASHBACK_DISPLAY_CONFIG (user_data);
-  skeleton = meta_dbus_display_config_skeleton_new ();
 
-  g_signal_connect (skeleton, "handle-get-resources",
+  g_signal_connect (config->skeleton, "handle-get-resources",
                     G_CALLBACK (handle_get_resources), config);
-  g_signal_connect (skeleton, "handle-apply-configuration",
+  g_signal_connect (config->skeleton, "handle-apply-configuration",
                     G_CALLBACK (handle_apply_configuration), config);
-  g_signal_connect (skeleton, "handle-change-backlight",
+  g_signal_connect (config->skeleton, "handle-change-backlight",
                     G_CALLBACK (handle_change_backlight), config);
-  g_signal_connect (skeleton, "handle-get-crtc-gamma",
+  g_signal_connect (config->skeleton, "handle-get-crtc-gamma",
                     G_CALLBACK (handle_get_crtc_gamma), config);
-  g_signal_connect (skeleton, "handle-set-crtc-gamma",
+  g_signal_connect (config->skeleton, "handle-set-crtc-gamma",
                     G_CALLBACK (handle_set_crtc_gamma), config);
 
-  g_signal_connect (skeleton, "notify::power-save-mode",
+  g_signal_connect (config->skeleton, "notify::power-save-mode",
                     G_CALLBACK (power_save_mode_changed), config);
 
-  config->iface = G_DBUS_INTERFACE_SKELETON (skeleton);
+  iface = G_DBUS_INTERFACE_SKELETON (config->skeleton);
   error = NULL;
 
-  if (!g_dbus_interface_skeleton_export (config->iface, connection,
+  if (!g_dbus_interface_skeleton_export (iface, connection,
                                          "/org/gnome/Mutter/DisplayConfig",
                                          &error))
     {
@@ -892,10 +890,10 @@ flashback_display_config_finalize (GObject *object)
 
   config = FLASHBACK_DISPLAY_CONFIG (object);
 
-  if (config->iface)
+  if (config->skeleton)
     {
-      g_dbus_interface_skeleton_unexport (config->iface);
-      g_clear_object (&config->iface);
+      g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (config->skeleton));
+      g_clear_object (&config->skeleton);
     }
 
   if (config->bus_name)
@@ -922,7 +920,10 @@ flashback_display_config_class_init (FlashbackDisplayConfigClass *config_class)
 static void
 flashback_display_config_init (FlashbackDisplayConfig *config)
 {
-  config->manager = flashback_monitor_manager_new ();
+  MetaDBusDisplayConfig *display_config;
+
+  config->skeleton = meta_dbus_display_config_skeleton_new ();
+  config->manager = flashback_monitor_manager_new (config->skeleton);
   config->bus_name = g_bus_own_name (G_BUS_TYPE_SESSION,
                                      "org.gnome.Mutter.DisplayConfig",
                                      G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
diff --git a/gnome-flashback/libdisplay-config/flashback-monitor-manager.c 
b/gnome-flashback/libdisplay-config/flashback-monitor-manager.c
index 2803c95..b039bc1 100644
--- a/gnome-flashback/libdisplay-config/flashback-monitor-manager.c
+++ b/gnome-flashback/libdisplay-config/flashback-monitor-manager.c
@@ -49,14 +49,59 @@
 
 struct _FlashbackMonitorManagerPrivate
 {
-  Display            *xdisplay;
-  XRRScreenResources *resources;
-  int                 rr_event_base;
-  int                 rr_error_base;
+  Display               *xdisplay;
+
+  XRRScreenResources    *resources;
+
+  int                    rr_event_base;
+  int                    rr_error_base;
+
+  MetaDBusDisplayConfig *display_config;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (FlashbackMonitorManager, flashback_monitor_manager, G_TYPE_OBJECT)
 
+enum
+{
+  PROP_0,
+  PROP_DISPLAY_CONFIG,
+  N_PROPERTIES
+};
+
+static GParamSpec *object_properties[N_PROPERTIES] = { NULL, };
+
+static GdkFilterReturn
+filter_func (GdkXEvent *xevent,
+             GdkEvent  *event,
+             gpointer   user_data)
+{
+  FlashbackMonitorManager *manager;
+  XEvent *xev;
+
+  manager = FLASHBACK_MONITOR_MANAGER (user_data);
+  xev = (XEvent *) xevent;
+
+  if ((xev->type - manager->priv->rr_event_base) == RRScreenChangeNotify)
+    {
+      XRRUpdateConfiguration (xev);
+
+      flashback_monitor_manager_read_current_config (manager);
+
+      if (manager->priv->resources->timestamp < manager->priv->resources->configTimestamp)
+        {
+          /* This is a hotplug event, so go ahead and build a new configuration. */
+          flashback_monitor_manager_on_hotplug (manager);
+        }
+      else
+        {
+          /* Something else changed -- tell the world about it. */
+          flashback_monitor_manager_rebuild_derived (manager);
+        }
+    }
+
+  return GDK_FILTER_CONTINUE;
+}
+
 static gboolean
 rectangle_contains_rect (const GdkRectangle *outer_rect,
                          const GdkRectangle *inner_rect)
@@ -1030,12 +1075,58 @@ flashback_monitor_manager_constructed (GObject *object)
 }
 
 static void
+flashback_monitor_manager_set_property (GObject      *object,
+                                        guint         property_id,
+                                        const GValue *value,
+                                        GParamSpec   *pspec)
+{
+  FlashbackMonitorManager *manager;
+
+  manager = FLASHBACK_MONITOR_MANAGER (object);
+
+  switch (property_id)
+    {
+      case PROP_DISPLAY_CONFIG:
+        if (manager->priv->display_config)
+          g_object_unref (manager->priv->display_config);
+        manager->priv->display_config = g_value_get_object (value);
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+        break;
+    }
+}
+
+static void
+flashback_monitor_manager_get_property (GObject    *object,
+                                        guint       property_id,
+                                        GValue     *value,
+                                        GParamSpec *pspec)
+{
+  FlashbackMonitorManager *manager;
+
+  manager = FLASHBACK_MONITOR_MANAGER (object);
+
+  switch (property_id)
+    {
+      case PROP_DISPLAY_CONFIG:
+        g_value_set_object (value, manager->priv->display_config);
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+        break;
+    }
+}
+
+static void
 flashback_monitor_manager_finalize (GObject *object)
 {
   FlashbackMonitorManager *manager;
 
   manager = FLASHBACK_MONITOR_MANAGER (object);
 
+  gdk_window_remove_filter (NULL, filter_func, manager);
+
   if (manager->priv->resources)
     XRRFreeScreenResources (manager->priv->resources);
   manager->priv->resources = NULL;
@@ -1056,7 +1147,19 @@ flashback_monitor_manager_class_init (FlashbackMonitorManagerClass *manager_clas
   object_class = G_OBJECT_CLASS (manager_class);
 
   object_class->constructed = flashback_monitor_manager_constructed;
+  object_class->set_property = flashback_monitor_manager_set_property;
+  object_class->get_property = flashback_monitor_manager_get_property;
   object_class->finalize = flashback_monitor_manager_finalize;
+
+  object_properties[PROP_DISPLAY_CONFIG] =
+    g_param_spec_object ("display-config",
+                         "display-config",
+                         "display-config",
+                         META_DBUS_TYPE_DISPLAY_CONFIG,
+                         G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+
+  g_object_class_install_properties (object_class, N_PROPERTIES,
+                                     object_properties);
 }
 
 static void
@@ -1072,6 +1175,8 @@ flashback_monitor_manager_init (FlashbackMonitorManager *manager)
   if (!XRRQueryExtension (priv->xdisplay, &priv->rr_event_base, &priv->rr_error_base))
     return;
 
+  gdk_window_add_filter (NULL, filter_func, manager);
+
   /* We only use ScreenChangeNotify, but GDK uses the others,
      and we don't want to step on its toes */
   XRRSelectInput (priv->xdisplay, DefaultRootWindow (priv->xdisplay),
@@ -1080,9 +1185,10 @@ flashback_monitor_manager_init (FlashbackMonitorManager *manager)
 }
 
 FlashbackMonitorManager *
-flashback_monitor_manager_new (void)
+flashback_monitor_manager_new (MetaDBusDisplayConfig *display_config)
 {
   return g_object_new (FLASHBACK_TYPE_MONITOR_MANAGER,
+                       "display-config", display_config,
                        NULL);
 }
 
@@ -1470,6 +1576,26 @@ meta_output_parse_edid (MetaOutput *meta_output,
     }
 }
 
+void
+flashback_monitor_manager_on_hotplug (FlashbackMonitorManager *manager)
+{
+  gboolean applied_config = FALSE;
+
+  /* If the monitor has hotplug_mode_update (which is used by VMs), don't bother
+   * applying our stored configuration, because it's likely the user just resizing
+   * the window.
+   */
+  if (!flashback_monitor_manager_has_hotplug_mode_update (manager))
+    {
+      if (flashback_monitor_config_apply_stored (manager->config))
+        applied_config = TRUE;
+    }
+
+  /* If we haven't applied any configuration, apply the default configuration. */
+  if (!applied_config)
+    flashback_monitor_config_make_default (manager->config);
+}
+
 MetaOutput *
 flashback_monitor_manager_get_outputs (FlashbackMonitorManager *manager,
                                        unsigned int            *n_outputs)
@@ -1533,3 +1659,20 @@ flashback_monitor_manager_get_monitor_for_output (FlashbackMonitorManager *manag
 
   return -1;
 }
+
+void
+flashback_monitor_manager_rebuild_derived (FlashbackMonitorManager *manager)
+{
+  MetaMonitorInfo *old_monitor_infos;
+
+  old_monitor_infos = manager->monitor_infos;
+
+  if (manager->in_init)
+    return;
+
+  make_logical_config (manager);
+
+  g_signal_emit_by_name (manager->priv->display_config, "monitors-changed");
+
+  g_free (old_monitor_infos);
+}
diff --git a/gnome-flashback/libdisplay-config/flashback-monitor-manager.h 
b/gnome-flashback/libdisplay-config/flashback-monitor-manager.h
index b2ec9ab..bc64172 100644
--- a/gnome-flashback/libdisplay-config/flashback-monitor-manager.h
+++ b/gnome-flashback/libdisplay-config/flashback-monitor-manager.h
@@ -29,6 +29,7 @@
 #include <gdk/gdk.h>
 #include <libgnome-desktop/gnome-pnp-ids.h>
 #include "meta-display-config-shared.h"
+#include "meta-dbus-display-config.h"
 
 G_BEGIN_DECLS
 
@@ -258,7 +259,7 @@ struct _FlashbackMonitorManager
   FlashbackMonitorManagerPrivate *priv;
 };
 
-FlashbackMonitorManager *flashback_monitor_manager_new                     (void);
+FlashbackMonitorManager *flashback_monitor_manager_new                     (MetaDBusDisplayConfig    
*display_config);
 
 void                     flashback_monitor_manager_apply_configuration     (FlashbackMonitorManager  
*manager,
                                                                             MetaCRTCInfo            **crtcs,
@@ -295,8 +296,9 @@ void                     meta_output_parse_edid                            (Meta
 void                     meta_crtc_info_free                               (MetaCRTCInfo             *info);
 void                     meta_output_info_free                             (MetaOutputInfo           *info);
 
-gboolean                 flashback_monitor_manager_has_hotplug_mode_update (FlashbackMonitorManager 
*manager);
+gboolean                 flashback_monitor_manager_has_hotplug_mode_update (FlashbackMonitorManager  
*manager);
 void                     flashback_monitor_manager_read_current_config     (FlashbackMonitorManager  
*manager);
+void                     flashback_monitor_manager_on_hotplug              (FlashbackMonitorManager  
*manager);
 
 MetaOutput              *flashback_monitor_manager_get_outputs             (FlashbackMonitorManager  
*manager,
                                                                             unsigned int             
*n_outputs);
@@ -316,6 +318,8 @@ void                     flashback_monitor_manager_get_screen_limits       (Flas
 gint                     flashback_monitor_manager_get_monitor_for_output  (FlashbackMonitorManager  
*manager,
                                                                             guint                     id);
 
+void                     flashback_monitor_manager_rebuild_derived         (FlashbackMonitorManager  
*manager);
+
 G_END_DECLS
 
 #endif


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