diff --git a/src/Makefile.am b/src/Makefile.am index df5e040bd..9a0cbe809 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -131,6 +131,8 @@ libmutter_wayland_la_SOURCES = \ core/meta-cursor-tracker-private.h \ core/meta-idle-monitor.c \ core/meta-idle-monitor-private.h \ + core/meta-idle-monitor-dbus.c \ + core/meta-idle-monitor-dbus.h \ core/meta-xrandr-shared.h \ core/monitor.c \ core/monitor-config.c \ diff --git a/src/core/display.c b/src/core/display.c index 2b1a574be..b4c5b2bce 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -48,7 +48,7 @@ #include #include #include "mutter-enum-types.h" -#include "meta-idle-monitor-private.h" +#include "meta-idle-monitor-dbus.h" #include "meta-cursor-tracker-private.h" #ifdef HAVE_RANDR diff --git a/src/core/meta-idle-monitor-dbus.c b/src/core/meta-idle-monitor-dbus.c new file mode 100644 index 000000000..811b46ada --- /dev/null +++ b/src/core/meta-idle-monitor-dbus.c @@ -0,0 +1,286 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * 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 2 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 . + * + * 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-dbus.h" +#include +#include "meta-dbus-idle-monitor.h" + +#include +#include +#include /* for meta_get_replace_current_wm () */ + +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)); +} + +static void +on_device_added (ClutterDeviceManager *device_manager, + ClutterInputDevice *device, + GDBusObjectManagerServer *manager) +{ + + MetaIdleMonitor *monitor; + int device_id; + char *path; + + 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); + + create_monitor_skeleton (manager, monitor, path); + g_free (path); +} + +static void +on_device_removed (ClutterDeviceManager *device_manager, + ClutterInputDevice *device, + GDBusObjectManagerServer *manager) +{ + int device_id; + char *path; + + device_id = clutter_input_device_get_device_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_bus_acquired (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + GDBusObjectManagerServer *manager; + ClutterDeviceManager *device_manager; + MetaIdleMonitor *monitor; + GSList *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 = 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_slist_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_dbus_object_manager_server_set_connection (manager, connection); +} + +static void +on_name_acquired (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + meta_verbose ("Acquired name %s\n", name); +} + +static void +on_name_lost (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + meta_verbose ("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/meta-idle-monitor-dbus.h b/src/core/meta-idle-monitor-dbus.h new file mode 100644 index 000000000..a0d703f0e --- /dev/null +++ b/src/core/meta-idle-monitor-dbus.h @@ -0,0 +1,28 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * 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 2 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 . + * + * 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 + +void meta_idle_monitor_init_dbus (void); + +#endif diff --git a/src/core/meta-idle-monitor-private.h b/src/core/meta-idle-monitor-private.h index 05289782f..aabd1cc3b 100644 --- a/src/core/meta-idle-monitor-private.h +++ b/src/core/meta-idle-monitor-private.h @@ -25,5 +25,3 @@ 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 baadaf068..7af248584 100644 --- a/src/core/meta-idle-monitor.c +++ b/src/core/meta-idle-monitor.c @@ -36,9 +36,9 @@ #include #include #include -#include "display-private.h" #include "meta-idle-monitor-private.h" -#include "meta-dbus-idle-monitor.h" +#include "meta-idle-monitor-dbus.h" +#include "display-private.h" G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer)); @@ -443,6 +443,15 @@ ensure_device_monitor (int device_id) device_id_max = MAX (device_id_max, device_id); } +/* FIXME -- destroy device monitors at some point */ +G_GNUC_UNUSED static void +destroy_device_monitor (int device_id) +{ + g_clear_object (&device_monitors[device_id]); + if (device_id == device_id_max) + device_id_max--; +} + /** * meta_idle_monitor_get_core: * @@ -743,262 +752,3 @@ meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor) 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 -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)); -} - -static void -on_device_added (ClutterDeviceManager *device_manager, - ClutterInputDevice *device, - GDBusObjectManagerServer *manager) -{ - - MetaIdleMonitor *monitor; - int device_id; - char *path; - - 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); - - create_monitor_skeleton (manager, monitor, path); - g_free (path); -} - -static void -on_device_removed (ClutterDeviceManager *device_manager, - ClutterInputDevice *device, - GDBusObjectManagerServer *manager) -{ - int device_id; - char *path; - - device_id = clutter_input_device_get_device_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); - - g_clear_object (&device_monitors[device_id]); - if (device_id == device_id_max) - device_id_max--; -} - -static void -on_bus_acquired (GDBusConnection *connection, - const char *name, - gpointer user_data) -{ - GDBusObjectManagerServer *manager; - ClutterDeviceManager *device_manager; - MetaIdleMonitor *monitor; - GSList *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 = 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_slist_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_dbus_object_manager_server_set_connection (manager, connection); -} - -static void -on_name_acquired (GDBusConnection *connection, - const char *name, - gpointer user_data) -{ - meta_verbose ("Acquired name %s\n", name); -} - -static void -on_name_lost (GDBusConnection *connection, - const char *name, - gpointer user_data) -{ - meta_verbose ("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); -} -