[mutter/wip/wayland-display: 64/65] MetaIdleMonitor: add a DBus interface for the idle monitor



commit a67c12e873bb008c35970ed7ed063e7517db708e
Author: Giovanni Campagna <gcampagn redhat com>
Date:   Wed Aug 14 13:51:05 2013 +0200

    MetaIdleMonitor: add a DBus interface for the idle monitor
    
    To allow other clients (gnome-session, gnome-settings-daemon)
    to monitor user activity, introduce a DBus interface for the
    idle monitor inside mutter.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=706005

 src/Makefile.am                      |   13 ++-
 src/core/meta-idle-monitor-private.h |    1 +
 src/core/meta-idle-monitor.c         |  230 ++++++++++++++++++++++++++++++++++
 src/core/screen.c                    |    2 +
 src/wayland/meta-wayland.c           |    2 +
 5 files changed, 247 insertions(+), 1 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 024de06..48fe6fe 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -37,6 +37,7 @@ endif
 
 mutter_built_sources = \
        $(dbus_xrandr_built_sources)    \
+       $(dbus_idle_built_sources) \
        mutter-enum-types.h \
        mutter-enum-types.c
 
@@ -388,12 +389,22 @@ mutter-enum-types.c: stamp-mutter-enum-types.h mutter-enum-types.c.in
 dbus_xrandr_built_sources = meta-dbus-xrandr.c meta-dbus-xrandr.h
 
 $(dbus_xrandr_built_sources) : Makefile.am xrandr.xml
-       $(AM_V_GEN)gdbus-codegen                                                                \
+       $(AM_V_GEN)gdbus-codegen                                                        \
                --interface-prefix org.gnome.Mutter                                     \
                --c-namespace MetaDBus                                                  \
                --generate-c-code meta-dbus-xrandr                                      \
                xrandr.xml
 
+dbus_idle_built_sources = meta-dbus-idle-monitor.c meta-dbus-idle-monitor.h
+
+$(dbus_idle_built_sources) : Makefile.am idle-monitor.xml
+       $(AM_V_GEN)gdbus-codegen                                                        \
+               --interface-prefix org.gnome.Mutter                                     \
+               --c-namespace MetaDBus                                                  \
+               --generate-c-code meta-dbus-idle-monitor                                \
+               --c-generate-object-manager                                             \
+               idle-monitor.xml
+
 if HAVE_WAYLAND
 wayland/%-protocol.c : $(top_builddir)/protocol/%.xml
        $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
diff --git a/src/core/meta-idle-monitor-private.h b/src/core/meta-idle-monitor-private.h
index f0f5935..40608ff 100644
--- a/src/core/meta-idle-monitor-private.h
+++ b/src/core/meta-idle-monitor-private.h
@@ -28,3 +28,4 @@ void meta_idle_monitor_handle_xevent_all (XEvent *xevent);
 
 void meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor);
 
+void meta_idle_monitor_init_dbus (void);
diff --git a/src/core/meta-idle-monitor.c b/src/core/meta-idle-monitor.c
index a2fba4c..1da0c4b 100644
--- a/src/core/meta-idle-monitor.c
+++ b/src/core/meta-idle-monitor.c
@@ -40,6 +40,7 @@
 #include <meta/meta-idle-monitor.h>
 #include "display-private.h"
 #include "meta-idle-monitor-private.h"
+#include "meta-dbus-idle-monitor.h"
 
 G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer));
 
@@ -700,3 +701,232 @@ meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor)
   g_list_foreach (closure.fired_watches, fire_wayland_watch, NULL);
   g_list_free (closure.fired_watches);
 }
+
+static gboolean
+handle_get_idletime (MetaDBusIdleMonitor   *skeleton,
+                     GDBusMethodInvocation *invocation,
+                     MetaIdleMonitor       *monitor)
+{
+  guint64 idletime;
+
+  idletime = meta_idle_monitor_get_idletime (monitor);
+  meta_dbus_idle_monitor_complete_get_idletime (skeleton, invocation, idletime);
+
+  return TRUE;
+}
+
+typedef struct {
+  MetaDBusIdleMonitor *dbus_monitor;
+  MetaIdleMonitor *monitor;
+  char *dbus_name;
+  guint watch_id;
+  guint name_watcher_id;
+} DBusWatch;
+
+static void
+destroy_dbus_watch (gpointer data)
+{
+  DBusWatch *watch = data;
+
+  g_object_unref (watch->dbus_monitor);
+  g_object_unref (watch->monitor);
+  g_free (watch->dbus_name);
+  g_bus_unwatch_name (watch->name_watcher_id);
+
+  g_slice_free (DBusWatch, watch);
+}
+
+static void
+dbus_idle_callback (MetaIdleMonitor *monitor,
+                    guint            watch_id,
+                    gpointer         user_data)
+{
+  DBusWatch *watch = user_data;
+  GDBusInterfaceSkeleton *skeleton = G_DBUS_INTERFACE_SKELETON (watch->dbus_monitor);
+
+  g_dbus_connection_emit_signal (g_dbus_interface_skeleton_get_connection (skeleton),
+                                 watch->dbus_name,
+                                 g_dbus_interface_skeleton_get_object_path (skeleton),
+                                 "org.gnome.Mutter.IdleMonitor",
+                                 "WatchFired",
+                                 g_variant_new ("(u)", watch_id),
+                                 NULL);
+}
+
+static void
+name_vanished_callback (GDBusConnection *connection,
+                        const char      *name,
+                        gpointer         user_data)
+{
+  DBusWatch *watch = user_data;
+
+  meta_idle_monitor_remove_watch (watch->monitor, watch->watch_id);
+}
+
+static DBusWatch *
+make_dbus_watch (MetaDBusIdleMonitor   *skeleton,
+                 GDBusMethodInvocation *invocation,
+                 MetaIdleMonitor       *monitor)
+{
+  DBusWatch *watch;
+
+  watch = g_slice_new (DBusWatch);
+  watch->dbus_monitor = g_object_ref (skeleton);
+  watch->monitor = g_object_ref (monitor);
+  watch->dbus_name = g_strdup (g_dbus_method_invocation_get_sender (invocation));
+  watch->name_watcher_id = g_bus_watch_name_on_connection (g_dbus_method_invocation_get_connection 
(invocation),
+                                                           watch->dbus_name,
+                                                           G_BUS_NAME_WATCHER_FLAGS_NONE,
+                                                           NULL, /* appeared */
+                                                           name_vanished_callback,
+                                                           watch, NULL);
+
+  return watch;
+}
+
+static gboolean
+handle_add_idle_watch (MetaDBusIdleMonitor   *skeleton,
+                       GDBusMethodInvocation *invocation,
+                       guint64                interval,                  
+                       MetaIdleMonitor       *monitor)
+{
+  DBusWatch *watch;
+
+  watch = make_dbus_watch (skeleton, invocation, monitor);
+  watch->watch_id = meta_idle_monitor_add_idle_watch (monitor, interval,
+                                                      dbus_idle_callback, watch, destroy_dbus_watch);
+
+  meta_dbus_idle_monitor_complete_add_idle_watch (skeleton, invocation, watch->watch_id);
+
+  return TRUE;
+}
+
+static gboolean
+handle_add_user_active_watch (MetaDBusIdleMonitor   *skeleton,
+                              GDBusMethodInvocation *invocation,
+                              MetaIdleMonitor       *monitor)
+{
+  DBusWatch *watch;
+
+  watch = make_dbus_watch (skeleton, invocation, monitor);
+  watch->watch_id = meta_idle_monitor_add_user_active_watch (monitor,
+                                                             dbus_idle_callback, watch,
+                                                             destroy_dbus_watch);
+
+  meta_dbus_idle_monitor_complete_add_user_active_watch (skeleton, invocation, watch->watch_id);
+
+  return TRUE;
+}
+
+static gboolean
+handle_remove_watch (MetaDBusIdleMonitor   *skeleton,
+                     GDBusMethodInvocation *invocation,
+                     guint                  id,
+                     MetaIdleMonitor       *monitor)
+{
+  meta_idle_monitor_remove_watch (monitor, id);
+  meta_dbus_idle_monitor_complete_remove_watch (skeleton, invocation);
+
+  return TRUE;
+}
+
+static void
+on_device_added (ClutterDeviceManager     *device_manager,
+                 ClutterInputDevice       *device,
+                 GDBusObjectManagerServer *manager)
+{
+  MetaDBusIdleMonitor *skeleton;
+  MetaIdleMonitor *monitor;
+  MetaDBusObjectSkeleton *object;
+  int device_id;
+  gboolean is_core;
+  char *path;
+
+  is_core = clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER;
+
+  if (is_core)
+    {
+      monitor = meta_idle_monitor_get_core ();
+      path = g_strdup ("/org/gnome/Mutter/IdleMonitor/Core");
+    }
+  else
+    {
+      device_id = clutter_input_device_get_device_id (device);
+      monitor = meta_idle_monitor_get_for_device (device_id);
+      path = g_strdup_printf ("/org/gnome/Mutter/IdleMonitor/Device%d", device_id);
+    }
+
+  skeleton = meta_dbus_idle_monitor_skeleton_new ();
+  g_signal_connect_object (skeleton, "handle-add-idle-watch",
+                           G_CALLBACK (handle_add_idle_watch), monitor, 0);
+  g_signal_connect_object (skeleton, "handle-add-user-active-watch",
+                           G_CALLBACK (handle_add_user_active_watch), monitor, 0);
+  g_signal_connect_object (skeleton, "handle-remove-watch",
+                           G_CALLBACK (handle_remove_watch), monitor, 0);
+  g_signal_connect_object (skeleton, "handle-get-idletime",
+                           G_CALLBACK (handle_get_idletime), monitor, 0);
+
+  object = meta_dbus_object_skeleton_new (path);
+  meta_dbus_object_skeleton_set_idle_monitor (object, skeleton);
+
+  g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
+}
+
+static void
+on_bus_acquired (GDBusConnection *connection,
+                 const char      *name,
+                 gpointer         user_data)
+{
+  GDBusObjectManagerServer *manager;
+  ClutterDeviceManager *device_manager;
+  GSList *devices, *iter;
+
+  manager = g_dbus_object_manager_server_new ("/org/gnome/Mutter/IdleMonitor");
+
+  device_manager = clutter_device_manager_get_default ();
+  devices = clutter_device_manager_list_devices (device_manager);
+
+  for (iter = devices; iter; iter = iter->next)
+    on_device_added (device_manager, iter->data, manager);
+
+  g_signal_connect_object (device_manager, "device-added",
+                           G_CALLBACK (on_device_added), manager, 0);
+
+  g_dbus_object_manager_server_set_connection (manager, g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL));
+}
+
+static void
+on_name_acquired (GDBusConnection *connection,
+                  const char      *name,
+                  gpointer         user_data)
+{
+  meta_topic (META_DEBUG_DBUS, "Acquired name %s\n", name);
+}
+
+static void
+on_name_lost (GDBusConnection *connection,
+              const char      *name,
+              gpointer         user_data)
+{
+  meta_topic (META_DEBUG_DBUS, "Lost or failed to acquire name %s\n", name);
+}
+
+void
+meta_idle_monitor_init_dbus (void)
+{
+  static int dbus_name_id;
+
+  if (dbus_name_id > 0)
+    return;
+
+  dbus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION,
+                                 "org.gnome.Mutter.IdleMonitor",
+                                 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
+                                 (meta_get_replace_current_wm () ?
+                                  G_BUS_NAME_OWNER_FLAGS_REPLACE : 0),
+                                 on_bus_acquired,
+                                 on_name_acquired,
+                                 on_name_lost,
+                                 NULL, NULL);
+}
+
diff --git a/src/core/screen.c b/src/core/screen.c
index ddf7569..4691daa 100644
--- a/src/core/screen.c
+++ b/src/core/screen.c
@@ -49,6 +49,7 @@
 #include "meta-wayland-private.h"
 #endif
 #include "meta-cursor-tracker-private.h"
+#include "meta-idle-monitor-private.h"
 
 #include <X11/extensions/Xinerama.h>
 
@@ -694,6 +695,7 @@ meta_screen_new (MetaDisplay *display,
   if (!meta_is_wayland_compositor ())
 #endif
     meta_monitor_manager_init_dbus (manager, NULL, NULL);
+  meta_idle_monitor_init_dbus ();
 
   screen->current_cursor = -1; /* invalid/unset */
   screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen);
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index a59e44f..1a4d3a8 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -1660,6 +1660,8 @@ on_display_config_ready (GObject      *object,
   ok = meta_monitor_manager_init_dbus_finish (META_MONITOR_MANAGER (object), result, NULL);
   g_assert (ok);
 
+  meta_idle_monitor_init_dbus ();
+
   /* Now we have X and DBus, and our stuff is on the bus.
      The only thing missing is gnome-session! */
   start_gnome_session (user_data);


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