[gnome-flashback] Revert "completely remove idle-monitor"



commit 78629934c02d09e8ca6a32b6d85546a5692ae928
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Tue Mar 31 14:19:09 2015 +0300

    Revert "completely remove idle-monitor"
    
    This reverts commit ecacae4932a9d3efb05c95ce89d6c1185f98d62f.

 gnome-flashback/libidle-monitor/Makefile.am        |   42 +++
 gnome-flashback/libidle-monitor/meta-backend.c     |  159 ++++++++
 gnome-flashback/libidle-monitor/meta-backend.h     |   53 +++
 .../libidle-monitor/meta-idle-monitor-dbus.c       |  379 ++++++++++++++++++++
 .../libidle-monitor/meta-idle-monitor-dbus.h       |   53 +++
 .../libidle-monitor/meta-idle-monitor-xsync.c      |  363 +++++++++++++++++++
 .../libidle-monitor/meta-idle-monitor-xsync.h      |   45 +++
 .../libidle-monitor/meta-idle-monitor.c            |  313 ++++++++++++++++
 .../libidle-monitor/meta-idle-monitor.h            |   90 +++++
 .../org.gnome.Mutter.IdleMonitor.xml               |   35 ++
 10 files changed, 1532 insertions(+), 0 deletions(-)
---
diff --git a/gnome-flashback/libidle-monitor/Makefile.am b/gnome-flashback/libidle-monitor/Makefile.am
new file mode 100644
index 0000000..22d083d
--- /dev/null
+++ b/gnome-flashback/libidle-monitor/Makefile.am
@@ -0,0 +1,42 @@
+noinst_LTLIBRARIES = \
+       libidle-monitor.la
+
+AM_CPPFLAGS = \
+       $(IDLE_MONITOR_CFLAGS) \
+       -I$(top_builddir)/gnome-flashback/libidle-monitor
+
+libidle_monitor_la_SOURCES = \
+       meta-dbus-idle-monitor.c \
+       meta-dbus-idle-monitor.h \
+       meta-backend.c \
+       meta-backend.h \
+       meta-idle-monitor.c \
+       meta-idle-monitor.h \
+       meta-idle-monitor-dbus.c \
+       meta-idle-monitor-dbus.h \
+       meta-idle-monitor-xsync.c \
+       meta-idle-monitor-xsync.h
+
+libidle_monitor_la_LIBADD = \
+       $(IDLE_MONITOR_LIBS)
+
+meta-dbus-idle-monitor.h:
+meta-dbus-idle-monitor.c: org.gnome.Mutter.IdleMonitor.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 \
+               $(srcdir)/org.gnome.Mutter.IdleMonitor.xml
+
+BUILT_SOURCES = \
+       meta-dbus-idle-monitor.h \
+       meta-dbus-idle-monitor.c
+
+EXTRA_DIST = \
+       org.gnome.Mutter.IdleMonitor.xml
+
+CLEANFILES = \
+       $(BUILT_SOURCES)
+
+-include $(top_srcdir)/git.mk
diff --git a/gnome-flashback/libidle-monitor/meta-backend.c b/gnome-flashback/libidle-monitor/meta-backend.c
new file mode 100644
index 0000000..d7ed2fd
--- /dev/null
+++ b/gnome-flashback/libidle-monitor/meta-backend.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2014 Red Hat
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Written by:
+ *     Jasper St. Pierre <jstpierre mecheye net>
+ */
+
+#include <gdk/gdkx.h>
+
+#include "config.h"
+#include "meta-backend.h"
+#include "meta-idle-monitor-xsync.h"
+
+static MetaBackend *backend = NULL;
+
+G_DEFINE_TYPE (MetaBackend, meta_backend, G_TYPE_OBJECT);
+
+static void
+meta_backend_finalize (GObject *object)
+{
+  MetaBackend *backend = META_BACKEND (object);
+  int i;
+
+  for (i = 0; i <= backend->device_id_max; i++)
+    {
+      if (backend->device_monitors[i])
+        g_object_unref (backend->device_monitors[i]);
+    }
+
+  G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
+}
+
+static void
+create_device_monitor (MetaBackend *backend,
+                       int          device_id)
+{
+  g_assert (backend->device_monitors[device_id] == NULL);
+
+  backend->device_monitors[device_id] = g_object_new (META_TYPE_IDLE_MONITOR_XSYNC,
+                                                      "device-id", device_id,
+                                                      NULL);
+  backend->device_id_max = MAX (backend->device_id_max, device_id);
+}
+
+static void
+destroy_device_monitor (MetaBackend *backend,
+                        int          device_id)
+{
+  g_clear_object (&backend->device_monitors[device_id]);
+
+  if (device_id == backend->device_id_max)
+    {
+      /* Reset the max device ID */
+      int i, new_max = 0;
+      for (i = 0; i < backend->device_id_max; i++)
+        if (backend->device_monitors[i] != NULL)
+          new_max = i;
+      backend->device_id_max = new_max;
+    }
+}
+
+static void
+on_device_added (GdkDeviceManager *device_manager,
+                 GdkDevice        *device,
+                 gpointer          user_data)
+{
+  MetaBackend *backend = META_BACKEND (user_data);
+  int device_id = gdk_x11_device_get_id (device);
+
+  create_device_monitor (backend, device_id);
+}
+
+static void
+on_device_removed (GdkDeviceManager *device_manager,
+                   GdkDevice        *device,
+                   gpointer          user_data)
+{
+  MetaBackend *backend = META_BACKEND (user_data);
+  int device_id = gdk_x11_device_get_id (device);
+
+  destroy_device_monitor (backend, device_id);
+}
+
+static void
+on_device_changed (GdkDeviceManager *device_manager,
+                   GdkDevice        *device,
+                   gpointer          user_data)
+{
+    MetaBackend *backend = META_BACKEND (user_data);
+
+       if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_FLOATING)
+               on_device_removed (device_manager, device, backend);
+       else
+               on_device_added (device_manager, device, backend);
+}
+
+static void
+meta_backend_class_init (MetaBackendClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = meta_backend_finalize;
+}
+
+static void
+meta_backend_init (MetaBackend *backend)
+{
+       GdkDeviceManager *manager;
+       GList *devices, *l;
+
+       /* Create the core device monitor. */
+       create_device_monitor (backend, 0);
+
+       manager = gdk_display_get_device_manager (gdk_display_get_default ());
+       g_signal_connect_object (manager, "device-added", G_CALLBACK (on_device_added), backend, 0);
+       g_signal_connect_object (manager, "device-removed", G_CALLBACK (on_device_removed), backend, 0);
+       g_signal_connect_object (manager, "device-changed", G_CALLBACK (on_device_changed), backend, 0);
+
+       devices = gdk_device_manager_list_devices (manager, GDK_DEVICE_TYPE_MASTER);
+       devices = g_list_concat (devices, gdk_device_manager_list_devices (manager, GDK_DEVICE_TYPE_SLAVE));
+
+       for (l = devices; l != NULL; l = l->next) {
+               GdkDevice *device = l->data;
+               on_device_added (manager, device, backend);
+       }
+
+       g_list_free (devices);
+}
+
+MetaBackend *
+meta_get_backend (void)
+{
+  if (!backend)
+       backend = g_object_new (META_TYPE_BACKEND, NULL);
+
+  return backend;
+}
+
+MetaIdleMonitor *
+meta_backend_get_idle_monitor (MetaBackend *backend,
+                               int          device_id)
+{
+  g_return_val_if_fail (device_id >= 0 && device_id < 256, NULL);
+
+  return backend->device_monitors[device_id];
+}
diff --git a/gnome-flashback/libidle-monitor/meta-backend.h b/gnome-flashback/libidle-monitor/meta-backend.h
new file mode 100644
index 0000000..5f57c34
--- /dev/null
+++ b/gnome-flashback/libidle-monitor/meta-backend.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 Red Hat
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Written by:
+ *     Jasper St. Pierre <jstpierre mecheye net>
+ */
+
+#ifndef META_BACKEND_H
+#define META_BACKEND_H
+
+#include <glib-object.h>
+#include "meta-idle-monitor.h"
+
+#define META_TYPE_BACKEND         (meta_backend_get_type ())
+#define META_BACKEND(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), META_TYPE_BACKEND, MetaBackend))
+#define META_BACKEND_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k),    META_TYPE_BACKEND, MetaBackendClass))
+#define META_IS_BACKEND(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), META_TYPE_BACKEND))
+#define META_IS_BACKEND_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k),    META_TYPE_BACKEND))
+#define META_BACKEND_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o),  META_TYPE_BACKEND, MetaBackendClass))
+
+typedef struct _MetaBackend      MetaBackend;
+typedef struct _MetaBackendClass MetaBackendClass;
+
+struct _MetaBackend {
+       GObject          parent;
+
+       MetaIdleMonitor *device_monitors[256];
+       int              device_id_max;
+};
+
+struct _MetaBackendClass {
+       GObjectClass parent_class;
+};
+
+GType            meta_backend_get_type         (void);
+MetaBackend     *meta_get_backend              (void);
+MetaIdleMonitor *meta_backend_get_idle_monitor (MetaBackend *backend,
+                                                int          device_id);
+
+#endif /* META_BACKEND_H */
diff --git a/gnome-flashback/libidle-monitor/meta-idle-monitor-dbus.c 
b/gnome-flashback/libidle-monitor/meta-idle-monitor-dbus.c
new file mode 100644
index 0000000..8a0cf9b
--- /dev/null
+++ b/gnome-flashback/libidle-monitor/meta-idle-monitor-dbus.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright 2013 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and
+ *         from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c
+ */
+
+#include "config.h"
+
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <X11/extensions/sync.h>
+
+#include "meta-backend.h"
+#include "meta-idle-monitor.h"
+#include "meta-idle-monitor-dbus.h"
+#include "meta-dbus-idle-monitor.h"
+
+struct _MetaIdleMonitorDBusPrivate {
+       gint dbus_name_id;
+
+       int  xsync_event_base;
+       int  xsync_error_base;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (MetaIdleMonitorDBus, meta_idle_monitor_dbus, G_TYPE_OBJECT);
+
+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
+create_monitor_skeleton (GDBusObjectManagerServer *manager,
+                         MetaIdleMonitor          *monitor,
+                         const char               *path)
+{
+  MetaDBusIdleMonitor *skeleton;
+  MetaDBusObjectSkeleton *object;
+
+  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));
+
+  g_object_unref (skeleton);
+  g_object_unref (object);
+}
+
+static void
+on_device_added (GdkDeviceManager         *device_manager,
+                 GdkDevice                *device,
+                 GDBusObjectManagerServer *manager)
+{
+
+  MetaIdleMonitor *monitor;
+  gint device_id;
+  gchar *path;
+
+  device_id = gdk_x11_device_get_id (device);
+  monitor = meta_idle_monitor_get_for_device (device_id);
+  path = g_strdup_printf ("/org/gnome/Mutter/IdleMonitor/Device%d", device_id);
+
+  create_monitor_skeleton (manager, monitor, path);
+  g_free (path);
+}
+
+static void
+on_device_removed (GdkDeviceManager         *device_manager,
+                   GdkDevice                *device,
+                   GDBusObjectManagerServer *manager)
+{
+  gint device_id;
+  gchar *path;
+
+  device_id = gdk_x11_device_get_id (device);
+  path = g_strdup_printf ("/org/gnome/Mutter/IdleMonitor/Device%d", device_id);
+  g_dbus_object_manager_server_unexport (manager, path);
+  g_free (path);
+}
+
+static void
+on_device_changed (GdkDeviceManager         *device_manager,
+                   GdkDevice                *device,
+                   GDBusObjectManagerServer *manager)
+{
+       if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_FLOATING)
+               on_device_removed (device_manager, device, manager);
+       else
+               on_device_added (device_manager, device, manager);
+}
+
+static void
+on_bus_acquired (GDBusConnection *connection,
+                 const char      *name,
+                 gpointer         user_data)
+{
+  GDBusObjectManagerServer *manager;
+  GdkDeviceManager *device_manager;
+  MetaIdleMonitor *monitor;
+  GList *devices, *iter;
+  char *path;
+
+  manager = g_dbus_object_manager_server_new ("/org/gnome/Mutter/IdleMonitor");
+
+  /* We never clear the core monitor, as that's supposed to cumulate idle times from
+     all devices */
+  monitor = meta_idle_monitor_get_core ();
+  path = g_strdup ("/org/gnome/Mutter/IdleMonitor/Core");
+  create_monitor_skeleton (manager, monitor, path);
+  g_free (path);
+
+  device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
+  devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
+  devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
+
+  for (iter = devices; iter; iter = iter->next)
+    on_device_added (device_manager, iter->data, manager);
+
+  g_list_free (devices);
+
+  g_signal_connect_object (device_manager, "device-added",
+                           G_CALLBACK (on_device_added), manager, 0);
+  g_signal_connect_object (device_manager, "device-removed",
+                           G_CALLBACK (on_device_removed), manager, 0);
+  g_signal_connect_object (device_manager, "device-changed",
+                           G_CALLBACK (on_device_changed), manager, 0);
+
+  g_dbus_object_manager_server_set_connection (manager, connection);
+}
+
+static void
+on_name_acquired (GDBusConnection *connection,
+                  const char      *name,
+                  gpointer         user_data)
+{
+}
+
+static void
+on_name_lost (GDBusConnection *connection,
+              const char      *name,
+              gpointer         user_data)
+{
+}
+
+static GdkFilterReturn
+filter_func (GdkXEvent *xevent,
+             GdkEvent  *event,
+             gpointer   user_data)
+{
+       MetaIdleMonitorDBus *monitor = META_IDLE_MONITOR_DBUS (user_data);
+       MetaBackend *backend = meta_get_backend ();
+       XEvent *xev = (XEvent *) xevent;
+       int i;
+
+       if (xev->type == (monitor->priv->xsync_event_base + XSyncAlarmNotify)) {
+               for (i = 0; i <= backend->device_id_max; i++) {
+                       if (backend->device_monitors[i]) {
+                               meta_idle_monitor_xsync_handle_xevent (backend->device_monitors[i], 
(XSyncAlarmNotifyEvent*) xev);
+                       }
+               }
+       }
+
+       return GDK_FILTER_CONTINUE;
+}
+
+static void
+meta_idle_monitor_dbus_dispose (GObject *object)
+{
+       MetaIdleMonitorDBus *monitor = META_IDLE_MONITOR_DBUS (object);
+
+       if (monitor->priv->dbus_name_id) {
+               g_bus_unown_name (monitor->priv->dbus_name_id);
+               monitor->priv->dbus_name_id = 0;
+       }
+
+       G_OBJECT_CLASS (meta_idle_monitor_dbus_parent_class)->dispose (object);
+}
+
+static void
+meta_idle_monitor_dbus_finalize (GObject *object)
+{
+       MetaIdleMonitorDBus *monitor = META_IDLE_MONITOR_DBUS (object);
+
+       gdk_window_remove_filter (NULL, filter_func, monitor);
+
+       G_OBJECT_CLASS (meta_idle_monitor_dbus_parent_class)->finalize (object);
+}
+
+static void
+meta_idle_monitor_dbus_init (MetaIdleMonitorDBus *monitor)
+{
+       GdkDisplay *display;
+       Display *xdisplay;
+       int major, minor;
+
+    monitor->priv = meta_idle_monitor_dbus_get_instance_private (monitor);
+       monitor->priv->dbus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION,
+                                                     "org.gnome.Mutter.IdleMonitor",
+                                                     G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
+                                                     G_BUS_NAME_OWNER_FLAGS_REPLACE,
+                                                     on_bus_acquired,
+                                                     on_name_acquired,
+                                                     on_name_lost,
+                                                     NULL, NULL);
+
+       display = gdk_display_get_default ();
+       xdisplay = gdk_x11_display_get_xdisplay (display);
+
+       if (!XSyncQueryExtension (xdisplay, &monitor->priv->xsync_event_base, 
&monitor->priv->xsync_error_base))
+       g_critical ("Could not query XSync extension");
+
+       if (!XSyncInitialize (xdisplay, &major, &minor))
+       g_critical ("Could not initialize XSync");
+
+       gdk_window_add_filter (NULL, filter_func, monitor);
+}
+
+static void
+meta_idle_monitor_dbus_class_init (MetaIdleMonitorDBusClass *class)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+       object_class->dispose = meta_idle_monitor_dbus_dispose;
+       object_class->finalize = meta_idle_monitor_dbus_finalize;
+}
+
+MetaIdleMonitorDBus *
+meta_idle_monitor_dbus_new (void)
+{
+       return g_object_new (META_TYPE_IDLE_MONITOR_DBUS, NULL);
+}
diff --git a/gnome-flashback/libidle-monitor/meta-idle-monitor-dbus.h 
b/gnome-flashback/libidle-monitor/meta-idle-monitor-dbus.h
new file mode 100644
index 0000000..1957dcd
--- /dev/null
+++ b/gnome-flashback/libidle-monitor/meta-idle-monitor-dbus.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2013 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and
+ *         from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c
+ */
+
+#ifndef META_IDLE_MONITOR_DBUS_H
+#define META_IDLE_MONITOR_DBUS_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define META_TYPE_IDLE_MONITOR_DBUS         (meta_idle_monitor_dbus_get_type ())
+#define META_IDLE_MONITOR_DBUS(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), META_TYPE_IDLE_MONITOR_DBUS, 
MetaIdleMonitorDBus))
+#define META_IDLE_MONITOR_DBUS_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k),    META_TYPE_IDLE_MONITOR_DBUS, 
MetaIdleMonitorDBusClass))
+#define META_IS_IDLE_MONITOR_DBUS(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), META_TYPE_IDLE_MONITOR_DBUS))
+#define META_IS_IDLE_MONITOR_DBUS_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k),    META_TYPE_IDLE_MONITOR_DBUS))
+#define META_IDLE_MONITOR_DBUS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o),  META_TYPE_IDLE_MONITOR_DBUS, 
MetaIdleMonitorDBusClass))
+
+typedef struct _MetaIdleMonitorDBus        MetaIdleMonitorDBus;
+typedef struct _MetaIdleMonitorDBusClass   MetaIdleMonitorDBusClass;
+typedef struct _MetaIdleMonitorDBusPrivate MetaIdleMonitorDBusPrivate;
+
+struct _MetaIdleMonitorDBus {
+       GObject                     parent;
+       MetaIdleMonitorDBusPrivate *priv;
+};
+
+struct _MetaIdleMonitorDBusClass {
+    GObjectClass parent_class;
+};
+
+GType                meta_idle_monitor_dbus_get_type (void);
+MetaIdleMonitorDBus *meta_idle_monitor_dbus_new      (void);
+
+G_END_DECLS
+
+#endif
diff --git a/gnome-flashback/libidle-monitor/meta-idle-monitor-xsync.c 
b/gnome-flashback/libidle-monitor/meta-idle-monitor-xsync.c
new file mode 100644
index 0000000..0ca81e0
--- /dev/null
+++ b/gnome-flashback/libidle-monitor/meta-idle-monitor-xsync.c
@@ -0,0 +1,363 @@
+/*
+ * Copyright 2013 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and
+ *         from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c
+ */
+
+#include "config.h"
+
+#include "meta-idle-monitor-xsync.h"
+
+#include <string.h>
+#include <gdk/gdkx.h>
+
+struct _MetaIdleMonitorXSync
+{
+  MetaIdleMonitor parent;
+
+  GHashTable  *alarms;
+  Display     *display;
+  XSyncCounter counter;
+  XSyncAlarm   user_active_alarm;
+};
+
+struct _MetaIdleMonitorXSyncClass
+{
+  MetaIdleMonitorClass parent_class;
+};
+
+typedef struct {
+  MetaIdleMonitorWatch base;
+
+  XSyncAlarm xalarm;
+} MetaIdleMonitorWatchXSync;
+
+G_DEFINE_TYPE (MetaIdleMonitorXSync, meta_idle_monitor_xsync, META_TYPE_IDLE_MONITOR)
+
+static gint64
+_xsyncvalue_to_int64 (XSyncValue value)
+{
+  return ((guint64) XSyncValueHigh32 (value)) << 32
+    | (guint64) XSyncValueLow32 (value);
+}
+
+#define GUINT64_TO_XSYNCVALUE(value, ret) XSyncIntsToValue (ret, (value) & 0xFFFFFFFF, ((guint64)(value)) >> 
32)
+
+static XSyncAlarm
+_xsync_alarm_set (MetaIdleMonitorXSync *monitor_xsync,
+                 XSyncTestType          test_type,
+                 guint64                interval,
+                 gboolean               want_events)
+{
+  XSyncAlarmAttributes attr;
+  XSyncValue        delta;
+  guint                     flags;
+
+  flags = XSyncCACounter | XSyncCAValueType | XSyncCATestType |
+    XSyncCAValue | XSyncCADelta | XSyncCAEvents;
+
+  XSyncIntToValue (&delta, 0);
+  attr.trigger.counter = monitor_xsync->counter;
+  attr.trigger.value_type = XSyncAbsolute;
+  attr.delta = delta;
+  attr.events = want_events;
+
+  GUINT64_TO_XSYNCVALUE (interval, &attr.trigger.wait_value);
+  attr.trigger.test_type = test_type;
+  return XSyncCreateAlarm (monitor_xsync->display, flags, &attr);
+}
+
+static void
+ensure_alarm_rescheduled (Display    *dpy,
+                         XSyncAlarm  alarm)
+{
+  XSyncAlarmAttributes attr;
+
+  /* Some versions of Xorg have an issue where alarms aren't
+   * always rescheduled. Calling XSyncChangeAlarm, even
+   * without any attributes, will reschedule the alarm. */
+  XSyncChangeAlarm (dpy, alarm, 0, &attr);
+}
+
+static void
+set_alarm_enabled (Display    *dpy,
+                  XSyncAlarm  alarm,
+                  gboolean    enabled)
+{
+  XSyncAlarmAttributes attr;
+  attr.events = enabled;
+  XSyncChangeAlarm (dpy, alarm, XSyncCAEvents, &attr);
+}
+
+static void
+check_x11_watch (gpointer data,
+                 gpointer user_data)
+{
+  MetaIdleMonitorWatchXSync *watch_xsync = data;
+  MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_xsync;
+  XSyncAlarm alarm = (XSyncAlarm) user_data;
+
+  if (watch_xsync->xalarm != alarm)
+    return;
+
+  _meta_idle_monitor_watch_fire (watch);
+}
+
+static char *
+counter_name_for_device (int device_id)
+{
+  if (device_id > 0)
+    return g_strdup_printf ("DEVICEIDLETIME %d", device_id);
+
+  return g_strdup ("IDLETIME");
+}
+
+static XSyncCounter
+find_idletime_counter (MetaIdleMonitorXSync *monitor_xsync)
+{
+  MetaIdleMonitor *monitor = META_IDLE_MONITOR (monitor_xsync);
+  int                i;
+  int                ncounters;
+  XSyncSystemCounter *counters;
+  XSyncCounter        counter = None;
+  char               *counter_name;
+
+  counter_name = counter_name_for_device (monitor->device_id);
+  counters = XSyncListSystemCounters (monitor_xsync->display, &ncounters);
+  for (i = 0; i < ncounters; i++)
+    {
+      if (counters[i].name != NULL && strcmp (counters[i].name, counter_name) == 0)
+        {
+          counter = counters[i].counter;
+          break;
+        }
+    }
+  XSyncFreeSystemCounterList (counters);
+  g_free (counter_name);
+
+  return counter;
+}
+
+static void
+init_xsync (MetaIdleMonitorXSync *monitor_xsync)
+{
+  monitor_xsync->counter = find_idletime_counter (monitor_xsync);
+  /* IDLETIME counter not found? */
+  if (monitor_xsync->counter == None)
+    {
+      g_warning ("IDLETIME counter not found\n");
+      return;
+    }
+
+  monitor_xsync->user_active_alarm = _xsync_alarm_set (monitor_xsync, XSyncNegativeTransition, 1, FALSE);
+}
+
+static void
+meta_idle_monitor_xsync_dispose (GObject *object)
+{
+  MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (object);
+
+  if (monitor_xsync->user_active_alarm != None)
+    {
+      XSyncDestroyAlarm (monitor_xsync->display, monitor_xsync->user_active_alarm);
+      monitor_xsync->user_active_alarm = None;
+    }
+
+  g_clear_pointer (&monitor_xsync->alarms, g_hash_table_destroy);
+
+  G_OBJECT_CLASS (meta_idle_monitor_xsync_parent_class)->dispose (object);
+}
+
+static void
+meta_idle_monitor_xsync_constructed (GObject *object)
+{
+  MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (object);
+  GdkDisplay *display = gdk_display_get_default ();
+
+  monitor_xsync->display = gdk_x11_display_get_xdisplay (display);
+  init_xsync (monitor_xsync);
+
+  G_OBJECT_CLASS (meta_idle_monitor_xsync_parent_class)->constructed (object);
+}
+
+static gint64
+meta_idle_monitor_xsync_get_idletime (MetaIdleMonitor *monitor)
+{
+  MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor);
+  XSyncValue value;
+
+  if (!XSyncQueryCounter (monitor_xsync->display, monitor_xsync->counter, &value))
+    return -1;
+
+  return _xsyncvalue_to_int64 (value);
+}
+
+static gboolean
+fire_watch_idle (gpointer data)
+{
+  MetaIdleMonitorWatch *watch = data;
+
+  watch->idle_source_id = 0;
+  _meta_idle_monitor_watch_fire (watch);
+
+  return FALSE;
+}
+
+static guint32
+get_next_watch_serial (void)
+{
+  static guint32 serial = 0;
+  g_atomic_int_inc (&serial);
+  return serial;
+}
+
+static void
+free_watch (gpointer data)
+{
+  MetaIdleMonitorWatchXSync *watch_xsync = data;
+  MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_xsync;
+  MetaIdleMonitor *monitor = watch->monitor;
+  MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor);
+
+  g_object_ref (monitor);
+
+  if (watch->idle_source_id)
+    {
+      g_source_remove (watch->idle_source_id);
+      watch->idle_source_id = 0;
+    }
+
+  if (watch->notify != NULL)
+    watch->notify (watch->user_data);
+
+  if (watch_xsync->xalarm != monitor_xsync->user_active_alarm &&
+      watch_xsync->xalarm != None)
+    {
+      XSyncDestroyAlarm (monitor_xsync->display, watch_xsync->xalarm);
+      g_hash_table_remove (monitor_xsync->alarms, (gpointer) watch_xsync->xalarm);
+    }
+
+  g_object_unref (monitor);
+  g_slice_free (MetaIdleMonitorWatchXSync, watch_xsync);
+}
+
+static MetaIdleMonitorWatch *
+meta_idle_monitor_xsync_make_watch (MetaIdleMonitor           *monitor,
+                                    guint64                    timeout_msec,
+                                    MetaIdleMonitorWatchFunc   callback,
+                                    gpointer                   user_data,
+                                    GDestroyNotify             notify)
+{
+  MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor);
+  MetaIdleMonitorWatchXSync *watch_xsync;
+  MetaIdleMonitorWatch *watch;
+
+  watch_xsync = g_slice_new0 (MetaIdleMonitorWatchXSync);
+  watch = (MetaIdleMonitorWatch *) watch_xsync;
+
+  watch->monitor = monitor;
+  watch->id = get_next_watch_serial ();
+  watch->callback = callback;
+  watch->user_data = user_data;
+  watch->notify = notify;
+  watch->timeout_msec = timeout_msec;
+
+  if (monitor_xsync->user_active_alarm != None)
+    {
+      if (timeout_msec != 0)
+        {
+          watch_xsync->xalarm = _xsync_alarm_set (monitor_xsync, XSyncPositiveTransition, timeout_msec, 
TRUE);
+
+          g_hash_table_add (monitor_xsync->alarms, (gpointer) watch_xsync->xalarm);
+
+          if (meta_idle_monitor_get_idletime (monitor) > (gint64)timeout_msec)
+            {
+              watch->idle_source_id = g_idle_add (fire_watch_idle, watch);
+              g_source_set_name_by_id (watch->idle_source_id, "[mutter] fire_watch_idle");
+            }
+        }
+      else
+        {
+          watch_xsync->xalarm = monitor_xsync->user_active_alarm;
+
+          set_alarm_enabled (monitor_xsync->display, monitor_xsync->user_active_alarm, TRUE);
+        }
+    }
+
+  return watch;
+}
+
+static void
+meta_idle_monitor_xsync_class_init (MetaIdleMonitorXSyncClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  MetaIdleMonitorClass *idle_monitor_class = META_IDLE_MONITOR_CLASS (klass);
+
+  object_class->dispose = meta_idle_monitor_xsync_dispose;
+  object_class->constructed = meta_idle_monitor_xsync_constructed;
+
+  idle_monitor_class->get_idletime = meta_idle_monitor_xsync_get_idletime;
+  idle_monitor_class->make_watch = meta_idle_monitor_xsync_make_watch;
+}
+
+static void
+meta_idle_monitor_xsync_init (MetaIdleMonitorXSync *monitor_xsync)
+{
+  MetaIdleMonitor *monitor = META_IDLE_MONITOR (monitor_xsync);
+
+  monitor->watches = g_hash_table_new_full (NULL, NULL, NULL, free_watch);
+  monitor_xsync->alarms = g_hash_table_new (NULL, NULL);
+}
+
+void
+meta_idle_monitor_xsync_handle_xevent (MetaIdleMonitor       *monitor,
+                                       XSyncAlarmNotifyEvent *alarm_event)
+{
+  MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor);
+  XSyncAlarm alarm;
+  GList *watches;
+  gboolean has_alarm;
+
+  if (alarm_event->state != XSyncAlarmActive)
+    return;
+
+  alarm = alarm_event->alarm;
+
+  has_alarm = FALSE;
+
+  if (alarm == monitor_xsync->user_active_alarm)
+    {
+      set_alarm_enabled (monitor_xsync->display,
+                         alarm,
+                         FALSE);
+      has_alarm = TRUE;
+    }
+  else if (g_hash_table_contains (monitor_xsync->alarms, (gpointer) alarm))
+    {
+      ensure_alarm_rescheduled (monitor_xsync->display,
+                                alarm);
+      has_alarm = TRUE;
+    }
+
+  if (has_alarm)
+    {
+      watches = g_hash_table_get_values (monitor->watches);
+
+      g_list_foreach (watches, check_x11_watch, (gpointer) alarm);
+      g_list_free (watches);
+    }
+}
diff --git a/gnome-flashback/libidle-monitor/meta-idle-monitor-xsync.h 
b/gnome-flashback/libidle-monitor/meta-idle-monitor-xsync.h
new file mode 100644
index 0000000..f7a1bd9
--- /dev/null
+++ b/gnome-flashback/libidle-monitor/meta-idle-monitor-xsync.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2013 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and
+ *         from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c
+ */
+
+#ifndef META_IDLE_MONITOR_XSYNC_H
+#define META_IDLE_MONITOR_XSYNC_H
+
+#include <glib-object.h>
+#include "meta-idle-monitor.h"
+
+#include <X11/Xlib.h>
+#include <X11/extensions/sync.h>
+
+#define META_TYPE_IDLE_MONITOR_XSYNC            (meta_idle_monitor_xsync_get_type ())
+#define META_IDLE_MONITOR_XSYNC(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
META_TYPE_IDLE_MONITOR_XSYNC, MetaIdleMonitorXSync))
+#define META_IDLE_MONITOR_XSYNC_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  
META_TYPE_IDLE_MONITOR_XSYNC, MetaIdleMonitorXSyncClass))
+#define META_IS_IDLE_MONITOR_XSYNC(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
META_TYPE_IDLE_MONITOR_XSYNC))
+#define META_IS_IDLE_MONITOR_XSYNC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  
META_TYPE_IDLE_MONITOR_XSYNC))
+#define META_IDLE_MONITOR_XSYNC_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  
META_TYPE_IDLE_MONITOR_XSYNC, MetaIdleMonitorXSyncClass))
+
+typedef struct _MetaIdleMonitorXSync        MetaIdleMonitorXSync;
+typedef struct _MetaIdleMonitorXSyncClass   MetaIdleMonitorXSyncClass;
+
+GType meta_idle_monitor_xsync_get_type (void);
+
+void meta_idle_monitor_xsync_handle_xevent (MetaIdleMonitor       *monitor,
+                                            XSyncAlarmNotifyEvent *xevent);
+
+#endif /* META_IDLE_MONITOR_XSYNC_H */
diff --git a/gnome-flashback/libidle-monitor/meta-idle-monitor.c 
b/gnome-flashback/libidle-monitor/meta-idle-monitor.c
new file mode 100644
index 0000000..c323bdc
--- /dev/null
+++ b/gnome-flashback/libidle-monitor/meta-idle-monitor.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright 2013 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Adapted from gnome-session/gnome-session/gs-idle-monitor.c and
+ *         from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c
+ */
+
+/**
+ * SECTION:idle-monitor
+ * @title: MetaIdleMonitor
+ * @short_description: Mutter idle counter (similar to X's IDLETIME)
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "meta-idle-monitor.h"
+#include "meta-idle-monitor-xsync.h"
+#include "meta-idle-monitor-dbus.h"
+#include "meta-backend.h"
+
+G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer));
+
+enum
+{
+  PROP_0,
+  PROP_DEVICE_ID,
+  PROP_LAST,
+};
+
+static GParamSpec *obj_props[PROP_LAST];
+
+G_DEFINE_TYPE (MetaIdleMonitor, meta_idle_monitor, G_TYPE_OBJECT)
+
+void
+_meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch)
+{
+  MetaIdleMonitor *monitor;
+  guint id;
+  gboolean is_user_active_watch;
+
+  monitor = watch->monitor;
+  g_object_ref (monitor);
+
+  if (watch->idle_source_id)
+    {
+      g_source_remove (watch->idle_source_id);
+      watch->idle_source_id = 0;
+    }
+
+  id = watch->id;
+  is_user_active_watch = (watch->timeout_msec == 0);
+
+  if (watch->callback)
+    watch->callback (monitor, id, watch->user_data);
+
+  if (is_user_active_watch)
+    meta_idle_monitor_remove_watch (monitor, id);
+
+  g_object_unref (monitor);
+}
+
+static void
+meta_idle_monitor_dispose (GObject *object)
+{
+  MetaIdleMonitor *monitor = META_IDLE_MONITOR (object);
+
+  g_clear_pointer (&monitor->watches, g_hash_table_destroy);
+
+  G_OBJECT_CLASS (meta_idle_monitor_parent_class)->dispose (object);
+}
+
+static void
+meta_idle_monitor_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+  MetaIdleMonitor *monitor = META_IDLE_MONITOR (object);
+
+  switch (prop_id)
+    {
+    case PROP_DEVICE_ID:
+      g_value_set_int (value, monitor->device_id);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+meta_idle_monitor_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+  MetaIdleMonitor *monitor = META_IDLE_MONITOR (object);
+  switch (prop_id)
+    {
+    case PROP_DEVICE_ID:
+      monitor->device_id = g_value_get_int (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+meta_idle_monitor_class_init (MetaIdleMonitorClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = meta_idle_monitor_dispose;
+  object_class->get_property = meta_idle_monitor_get_property;
+  object_class->set_property = meta_idle_monitor_set_property;
+
+  /**
+   * MetaIdleMonitor:device_id:
+   *
+   * The device to listen to idletime on.
+   */
+  obj_props[PROP_DEVICE_ID] =
+    g_param_spec_int ("device-id",
+                      "Device ID",
+                      "The device to listen to idletime on",
+                      0, 255, 0,
+                      G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+  g_object_class_install_property (object_class, PROP_DEVICE_ID, obj_props[PROP_DEVICE_ID]);
+}
+
+static void
+meta_idle_monitor_init (MetaIdleMonitor *monitor)
+{
+}
+
+static MetaIdleMonitor *device_monitors[256];
+
+/**
+ * meta_idle_monitor_get_core:
+ *
+ * Returns: (transfer none): the #MetaIdleMonitor that tracks the server-global
+ * idletime for all devices. To track device-specific idletime,
+ * use meta_idle_monitor_get_for_device().
+ */
+MetaIdleMonitor *
+meta_idle_monitor_get_core (void)
+{
+  MetaBackend *backend = meta_get_backend ();
+  return meta_backend_get_idle_monitor (backend, 0);
+}
+
+/**
+ * meta_idle_monitor_get_for_device:
+ * @device_id: the device to get the idle time for.
+ *
+ * Returns: (transfer none): a new #MetaIdleMonitor that tracks the
+ * device-specific idletime for @device. To track server-global idletime
+ * for all devices, use meta_idle_monitor_get_core().
+ */
+MetaIdleMonitor *
+meta_idle_monitor_get_for_device (gint device_id)
+{
+  MetaBackend *backend = meta_get_backend ();
+  return meta_backend_get_idle_monitor (backend, device_id);
+}
+
+static MetaIdleMonitorWatch *
+make_watch (MetaIdleMonitor           *monitor,
+            guint64                    timeout_msec,
+            MetaIdleMonitorWatchFunc   callback,
+            gpointer                   user_data,
+            GDestroyNotify             notify)
+{
+  MetaIdleMonitorWatch *watch;
+
+  watch = META_IDLE_MONITOR_GET_CLASS (monitor)->make_watch (monitor,
+                                                             timeout_msec,
+                                                             callback,
+                                                             user_data,
+                                                             notify);
+
+  g_hash_table_insert (monitor->watches,
+                       GUINT_TO_POINTER (watch->id),
+                       watch);
+  return watch;
+}
+
+/**
+ * meta_idle_monitor_add_idle_watch:
+ * @monitor: A #MetaIdleMonitor
+ * @interval_msec: The idletime interval, in milliseconds
+ * @callback: (nullable): The callback to call when the user has
+ *     accumulated @interval_msec milliseconds of idle time.
+ * @user_data: (nullable): The user data to pass to the callback
+ * @notify: A #GDestroyNotify
+ *
+ * Returns: a watch id
+ *
+ * Adds a watch for a specific idle time. The callback will be called
+ * when the user has accumulated @interval_msec milliseconds of idle time.
+ * This function will return an ID that can either be passed to
+ * meta_idle_monitor_remove_watch(), or can be used to tell idle time
+ * watches apart if you have more than one.
+ *
+ * Also note that this function will only care about positive transitions
+ * (user's idle time exceeding a certain time). If you want to know about
+ * when the user has become active, use
+ * meta_idle_monitor_add_user_active_watch().
+ */
+guint
+meta_idle_monitor_add_idle_watch (MetaIdleMonitor             *monitor,
+                                  guint64                      interval_msec,
+                                  MetaIdleMonitorWatchFunc      callback,
+                                  gpointer                     user_data,
+                                  GDestroyNotify               notify)
+{
+  MetaIdleMonitorWatch *watch;
+
+  g_return_val_if_fail (META_IS_IDLE_MONITOR (monitor), 0);
+  g_return_val_if_fail (interval_msec > 0, 0);
+
+  watch = make_watch (monitor,
+                      interval_msec,
+                      callback,
+                      user_data,
+                      notify);
+
+  return watch->id;
+}
+
+/**
+ * meta_idle_monitor_add_user_active_watch:
+ * @monitor: A #MetaIdleMonitor
+ * @callback: (nullable): The callback to call when the user is
+ *     active again.
+ * @user_data: (nullable): The user data to pass to the callback
+ * @notify: A #GDestroyNotify
+ *
+ * Returns: a watch id
+ *
+ * Add a one-time watch to know when the user is active again.
+ * Note that this watch is one-time and will de-activate after the
+ * function is called, for efficiency purposes. It's most convenient
+ * to call this when an idle watch, as added by
+ * meta_idle_monitor_add_idle_watch(), has triggered.
+ */
+guint
+meta_idle_monitor_add_user_active_watch (MetaIdleMonitor          *monitor,
+                                         MetaIdleMonitorWatchFunc  callback,
+                                         gpointer                 user_data,
+                                         GDestroyNotify                   notify)
+{
+  MetaIdleMonitorWatch *watch;
+
+  g_return_val_if_fail (META_IS_IDLE_MONITOR (monitor), 0);
+
+  watch = make_watch (monitor,
+                      0,
+                      callback,
+                      user_data,
+                      notify);
+
+  return watch->id;
+}
+
+/**
+ * meta_idle_monitor_remove_watch:
+ * @monitor: A #MetaIdleMonitor
+ * @id: A watch ID
+ *
+ * Removes an idle time watcher, previously added by
+ * meta_idle_monitor_add_idle_watch() or
+ * meta_idle_monitor_add_user_active_watch().
+ */
+void
+meta_idle_monitor_remove_watch (MetaIdleMonitor *monitor,
+                                guint           id)
+{
+  g_return_if_fail (META_IS_IDLE_MONITOR (monitor));
+
+  g_object_ref (monitor);
+  g_hash_table_remove (monitor->watches,
+                       GUINT_TO_POINTER (id));
+  g_object_unref (monitor);
+}
+
+/**
+ * meta_idle_monitor_get_idletime:
+ * @monitor: A #MetaIdleMonitor
+ *
+ * Returns: The current idle time, in milliseconds, or -1 for not supported
+ */
+gint64
+meta_idle_monitor_get_idletime (MetaIdleMonitor *monitor)
+{
+  return META_IDLE_MONITOR_GET_CLASS (monitor)->get_idletime (monitor);
+}
diff --git a/gnome-flashback/libidle-monitor/meta-idle-monitor.h 
b/gnome-flashback/libidle-monitor/meta-idle-monitor.h
new file mode 100644
index 0000000..327851a
--- /dev/null
+++ b/gnome-flashback/libidle-monitor/meta-idle-monitor.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2013 Red Hat, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef META_IDLE_MONITOR_H
+#define META_IDLE_MONITOR_H
+
+#include <glib-object.h>
+
+#define META_TYPE_IDLE_MONITOR            (meta_idle_monitor_get_type ())
+#define META_IDLE_MONITOR(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_IDLE_MONITOR, 
MetaIdleMonitor))
+#define META_IDLE_MONITOR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_IDLE_MONITOR, 
MetaIdleMonitorClass))
+#define META_IS_IDLE_MONITOR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_IDLE_MONITOR))
+#define META_IS_IDLE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_IDLE_MONITOR))
+#define META_IDLE_MONITOR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_IDLE_MONITOR, 
MetaIdleMonitorClass))
+
+typedef struct _MetaIdleMonitor        MetaIdleMonitor;
+typedef struct _MetaIdleMonitorClass   MetaIdleMonitorClass;
+
+typedef void (*MetaIdleMonitorWatchFunc) (MetaIdleMonitor *monitor,
+                                          guint            watch_id,
+                                          gpointer         user_data);
+
+typedef struct
+{
+  MetaIdleMonitor          *monitor;
+  guint                            id;
+  MetaIdleMonitorWatchFunc  callback;
+  gpointer                 user_data;
+  GDestroyNotify            notify;
+  guint64                   timeout_msec;
+  int                       idle_source_id;
+} MetaIdleMonitorWatch;
+
+void _meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch);
+
+struct _MetaIdleMonitor
+{
+  GObject parent_instance;
+
+  GHashTable *watches;
+  int device_id;
+};
+
+struct _MetaIdleMonitorClass
+{
+  GObjectClass parent_class;
+
+  gint64 (*get_idletime) (MetaIdleMonitor *monitor);
+  MetaIdleMonitorWatch * (*make_watch) (MetaIdleMonitor           *monitor,
+                                        guint64                    timeout_msec,
+                                        MetaIdleMonitorWatchFunc   callback,
+                                        gpointer                   user_data,
+                                        GDestroyNotify             notify);
+};
+
+GType meta_idle_monitor_get_type (void);
+
+MetaIdleMonitor *meta_idle_monitor_get_core (void);
+MetaIdleMonitor *meta_idle_monitor_get_for_device (int device_id);
+
+guint         meta_idle_monitor_add_idle_watch        (MetaIdleMonitor          *monitor,
+                                                      guint64                   interval_msec,
+                                                      MetaIdleMonitorWatchFunc  callback,
+                                                      gpointer                  user_data,
+                                                      GDestroyNotify            notify);
+
+guint         meta_idle_monitor_add_user_active_watch (MetaIdleMonitor          *monitor,
+                                                      MetaIdleMonitorWatchFunc  callback,
+                                                      gpointer                  user_data,
+                                                      GDestroyNotify            notify);
+
+void          meta_idle_monitor_remove_watch          (MetaIdleMonitor          *monitor,
+                                                      guint                     id);
+gint64        meta_idle_monitor_get_idletime          (MetaIdleMonitor          *monitor);
+
+#endif
diff --git a/gnome-flashback/libidle-monitor/org.gnome.Mutter.IdleMonitor.xml 
b/gnome-flashback/libidle-monitor/org.gnome.Mutter.IdleMonitor.xml
new file mode 100644
index 0000000..34a26dd
--- /dev/null
+++ b/gnome-flashback/libidle-monitor/org.gnome.Mutter.IdleMonitor.xml
@@ -0,0 +1,35 @@
+<!DOCTYPE node PUBLIC
+'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
+'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
+<node>
+  <!--
+      org.gnome.Mutter.IdleMonitor:
+      @short_description: idle monitor interface
+
+      This interface is used by gnome-desktop to implement
+      user activity monitoring.
+  -->
+
+  <interface name="org.gnome.Mutter.IdleMonitor">
+    <method name="GetIdletime">
+      <arg name="idletime" direction="out" type="t"/>
+    </method>
+
+    <method name="AddIdleWatch">
+      <arg name="interval" direction="in" type="t" />
+      <arg name="id" direction="out" type="u" />
+    </method>
+
+    <method name="AddUserActiveWatch">
+      <arg name="id" direction="out" type="u" />
+    </method>
+
+    <method name="RemoveWatch">
+      <arg name="id" direction="in" type="u" />
+    </method>
+
+    <signal name="WatchFired">
+      <arg name="id" direction="out" type="u" />
+    </signal>
+  </interface>
+</node>


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