diff options
-rw-r--r-- | src/Makefile.am | 5 | ||||
-rw-r--r-- | src/dbus-listener.c | 276 | ||||
-rw-r--r-- | src/dbus-listener.h | 77 | ||||
-rw-r--r-- | src/indicator-power.c | 155 |
4 files changed, 366 insertions, 147 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index d14c270..c3200a7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,11 +8,14 @@ powerlibdir = $(INDICATORDIR) powerlib_LTLIBRARIES = libpower.la libpower_la_SOURCES = \ + dbus-listener.c \ device.c \ indicator-power.c noinst_HEADERS = \ - device.h + dbus-listener.h \ + device.h \ + indicator-power.h libpower_la_CFLAGS = \ $(UPOWER_CFLAGS) \ diff --git a/src/dbus-listener.c b/src/dbus-listener.c new file mode 100644 index 0000000..fe8af09 --- /dev/null +++ b/src/dbus-listener.c @@ -0,0 +1,276 @@ +/* + +Listens on DBus for Power changes and passes them to an IndicatorPower + +Copyright 2012 Canonical Ltd. + +Authors: + Charles Kerr <charles.kerr@canonical.com> + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +version 3.0 as published by the Free Software Foundation. + +This library 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 version 3.0 for more details. + +You should have received a copy of the GNU General Public +License along with this library. If not, see +<http://www.gnu.org/licenses/>. +*/ + +#include "dbus-listener.h" +#include "indicator-power.h" + +#define DBUS_SERVICE "org.gnome.SettingsDaemon" +#define DBUS_PATH "/org/gnome/SettingsDaemon" +#define POWER_DBUS_PATH DBUS_PATH "/Power" +#define POWER_DBUS_INTERFACE "org.gnome.SettingsDaemon.Power" + +struct _IndicatorPowerDbusListenerPrivate +{ + IndicatorPower * ipower; + + GCancellable * proxy_cancel; + GDBusProxy * proxy; + guint watcher_id; +}; + +#define INDICATOR_POWER_DBUS_LISTENER_GET_PRIVATE(o) (INDICATOR_POWER_DBUS_LISTENER(o)->priv) + +/* Properties */ +/* Enum for the properties so that they can be quickly found and looked up. */ +enum { + PROP_0, + PROP_INDICATOR +}; + +/* GObject stuff */ +static void indicator_power_dbus_listener_class_init (IndicatorPowerDbusListenerClass *klass); +static void indicator_power_dbus_listener_init (IndicatorPowerDbusListener *self); +static void indicator_power_dbus_listener_dispose (GObject *object); +static void indicator_power_dbus_listener_finalize (GObject *object); +static void set_property (GObject*, guint prop_id, const GValue*, GParamSpec* ); +static void get_property (GObject*, guint prop_id, GValue*, GParamSpec* ); + +static void gsd_appeared_callback (GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data); + +G_DEFINE_TYPE (IndicatorPowerDbusListener, indicator_power_dbus_listener, G_TYPE_OBJECT); + +static void +indicator_power_dbus_listener_class_init (IndicatorPowerDbusListenerClass *klass) +{ + GParamSpec * pspec; + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (IndicatorPowerDbusListenerPrivate)); + + object_class->dispose = indicator_power_dbus_listener_dispose; + object_class->finalize = indicator_power_dbus_listener_finalize; + object_class->set_property = set_property; + object_class->get_property = get_property; + + pspec = g_param_spec_object (INDICATOR_POWER_DBUS_LISTENER_INDICATOR, + "indicator", + "The IndicatorPower to notify when power changes are received", + INDICATOR_POWER_TYPE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_INDICATOR, pspec); +} + +/* Initialize an instance */ +static void +indicator_power_dbus_listener_init (IndicatorPowerDbusListener *self) +{ + IndicatorPowerDbusListenerPrivate * priv; + + priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_POWER_DBUS_LISTENER_TYPE, + IndicatorPowerDbusListenerPrivate); + priv->ipower = NULL; + + priv->watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION, + DBUS_SERVICE, + G_BUS_NAME_WATCHER_FLAGS_NONE, + gsd_appeared_callback, + NULL, + self, + NULL); + + self->priv = priv; +} + +static void +indicator_power_dbus_listener_dispose (GObject *object) +{ + IndicatorPowerDbusListener * self = INDICATOR_POWER_DBUS_LISTENER(object); + IndicatorPowerDbusListenerPrivate * priv = self->priv; + + g_clear_object (&priv->proxy); + g_clear_object (&priv->proxy_cancel); + g_clear_object (&priv->ipower); + + G_OBJECT_CLASS (indicator_power_dbus_listener_parent_class)->dispose (object); +} + +static void +indicator_power_dbus_listener_finalize (GObject *object) +{ + G_OBJECT_CLASS (indicator_power_dbus_listener_parent_class)->finalize (object); +} + +/*** +**** +***/ + +static void +get_property (GObject * o, guint prop_id, GValue * value, GParamSpec * pspec) +{ + IndicatorPowerDbusListener * self = INDICATOR_POWER_DBUS_LISTENER(o); + IndicatorPowerDbusListenerPrivate * priv = self->priv; + + switch (prop_id) + { + case PROP_INDICATOR: + g_value_set_object (value, priv->ipower); + break; + } +} + +static void +set_property (GObject * o, guint prop_id, const GValue * value, GParamSpec * pspec) +{ + IndicatorPowerDbusListener * self = INDICATOR_POWER_DBUS_LISTENER(o); + IndicatorPowerDbusListenerPrivate * priv = self->priv; + + switch (prop_id) + { + case PROP_INDICATOR: + priv->ipower = g_value_dup_object (value); + break; + } +} + +/*** +**** +***/ + +static void +get_devices_cb (GObject * source_object, + GAsyncResult * res, + gpointer user_data) +{ + GError *error; + int device_count = 0; + GVariant * devices_container; + IndicatorPowerDevice ** devices = NULL; + IndicatorPowerDbusListener * self = INDICATOR_POWER_DBUS_LISTENER (user_data); + IndicatorPowerDbusListenerPrivate * priv = self->priv; + + /* build an array of IndicatorPowerDevices from the DBus response */ + error = NULL; + devices_container = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); + if (devices_container == NULL) + { + g_message ("Couldn't get devices: %s\n", error->message); + g_error_free (error); + } + else + { + gsize i; + GVariant * devices_variant = g_variant_get_child_value (devices_container, 0); + device_count = devices_variant ? g_variant_n_children (devices_variant) : 0; + devices = g_new0 (IndicatorPowerDevice*, device_count); + + for (i=0; i<device_count; i++) + { + GVariant * v = g_variant_get_child_value (devices_variant, i); + devices[i] = indicator_power_device_new_from_variant (v); + g_variant_unref (v); + } + + g_variant_unref (devices_variant); + g_variant_unref (devices_container); + } + + if (priv->ipower != NULL) + { + indicator_power_set_devices (priv->ipower, devices, device_count); + } + + g_free (devices); +} + +static void +request_device_list (IndicatorPowerDbusListener * self) +{ + g_dbus_proxy_call (self->priv->proxy, + "GetDevices", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + self->priv->proxy_cancel, + get_devices_cb, + self); +} + +static void +receive_properties_changed (GDBusProxy *proxy G_GNUC_UNUSED, + GVariant *changed_properties G_GNUC_UNUSED, + GStrv invalidated_properties G_GNUC_UNUSED, + gpointer user_data) +{ + request_device_list (INDICATOR_POWER_DBUS_LISTENER(user_data)); +} + + +static void +service_proxy_cb (GObject *object, + GAsyncResult *res, + gpointer user_data) +{ + GError * error = NULL; + IndicatorPowerDbusListener * self = INDICATOR_POWER_DBUS_LISTENER(user_data); + IndicatorPowerDbusListenerPrivate * priv = self->priv; + + priv->proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + g_clear_object (&priv->proxy_cancel); + + if (error != NULL) { + g_error ("Error creating proxy: %s", error->message); + g_error_free (error); + return; + } + + /* we want to change the primary device changes */ + g_signal_connect (priv->proxy, + "g-properties-changed", + G_CALLBACK (receive_properties_changed), + user_data); + + /* get the initial state */ + request_device_list (self); +} + +static void +gsd_appeared_callback (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + IndicatorPowerDbusListener * self = INDICATOR_POWER_DBUS_LISTENER(user_data); + IndicatorPowerDbusListenerPrivate * priv = self->priv; + + priv->proxy_cancel = g_cancellable_new (); + + g_dbus_proxy_new (connection, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + name, + POWER_DBUS_PATH, + POWER_DBUS_INTERFACE, + priv->proxy_cancel, + service_proxy_cb, + self); +} diff --git a/src/dbus-listener.h b/src/dbus-listener.h new file mode 100644 index 0000000..816ecc5 --- /dev/null +++ b/src/dbus-listener.h @@ -0,0 +1,77 @@ +/* + +Listens for Power changes from org.gnome.SettingsDaemon.Power on Dbus + +Copyright 2012 Canonical Ltd. + +Authors: + Javier Jardon <javier.jardon@codethink.co.uk> + Charles Kerr <charles.kerr@canonical.com> + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +version 3.0 as published by the Free Software Foundation. + +This library 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 version 3.0 for more details. + +You should have received a copy of the GNU General Public +License along with this library. If not, see +<http://www.gnu.org/licenses/>. +*/ + +#ifndef __INDICATOR_POWER_DBUS_LISTENER_H__ +#define __INDICATOR_POWER_DBUS_LISTENER_H__ + +#include <glib-object.h> +#include <libupower-glib/upower.h> + +G_BEGIN_DECLS + +#define INDICATOR_POWER_DBUS_LISTENER_TYPE (indicator_power_dbus_listener_get_type ()) +#define INDICATOR_POWER_DBUS_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_POWER_DBUS_LISTENER_TYPE, IndicatorPowerDbusListener)) +#define INDICATOR_POWER_DBUS_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_POWER_DBUS_LISTENER_TYPE, IndicatorPowerDbusListenerClass)) +#define INDICATOR_IS_POWER_DBUS_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_POWER_DBUS_LISTENER_TYPE)) +#define INDICATOR_IS_POWER_DBUS_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_POWER_DBUS_LISTENER_TYPE)) +#define INDICATOR_POWER_DBUS_LISTENER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_POWER_DBUS_LISTENER_TYPE, IndicatorPowerDbusListenerClass)) + +typedef struct _IndicatorPowerDbusListener IndicatorPowerDbusListener; +typedef struct _IndicatorPowerDbusListenerClass IndicatorPowerDbusListenerClass; +typedef struct _IndicatorPowerDbusListenerPrivate IndicatorPowerDbusListenerPrivate; + +#define INDICATOR_POWER_DBUS_LISTENER_INDICATOR "indicator-power-dbus-listener-indicator" + +/** + * IndicatorPowerDbusListenerClass: + * @parent_class: #GObjectClass + */ +struct _IndicatorPowerDbusListenerClass +{ + GObjectClass parent_class; +}; + +/** + * IndicatorPowerDbusListener: + * @parent: #GObject + * @priv: A cached reference to the private data for the instance. +*/ +struct _IndicatorPowerDbusListener +{ + GObject parent; + IndicatorPowerDbusListenerPrivate * priv; +}; + +/*** +**** +***/ + +GType indicator_power_dbus_listener_get_type (void); + +IndicatorPowerDbusListener* indicator_power_dbus_listener_new (void); + + +G_END_DECLS + +#endif diff --git a/src/indicator-power.c b/src/indicator-power.c index 6eb6904..dc95aae 100644 --- a/src/indicator-power.c +++ b/src/indicator-power.c @@ -20,7 +20,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif /* GStuff */ @@ -28,9 +28,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <glib/gi18n-lib.h> #include <gio/gio.h> -/* upower */ -#include <libupower-glib/upower.h> - +#include "dbus-listener.h" #include "device.h" #include "indicator-power.h" @@ -38,11 +36,6 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #define DEFAULT_ICON "gpm-battery-missing" -#define DBUS_SERVICE "org.gnome.SettingsDaemon" -#define DBUS_PATH "/org/gnome/SettingsDaemon" -#define POWER_DBUS_PATH DBUS_PATH "/Power" -#define POWER_DBUS_INTERFACE "org.gnome.SettingsDaemon.Power" - enum { POWER_INDICATOR_ICON_POLICY_PRESENT, POWER_INDICATOR_ICON_POLICY_CHARGE, @@ -57,9 +50,7 @@ struct _IndicatorPowerPrivate GtkImage *status_image; gchar *accessible_desc; - GCancellable *proxy_cancel; - GDBusProxy *proxy; - guint watcher_id; + IndicatorPowerDbusListener * dbus_listener; GSList * devices; IndicatorPowerDevice * device; @@ -86,7 +77,9 @@ static gboolean should_be_visible (IndicatorPower * self); static void on_entry_added (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer user_data); +/* static void gsd_appeared_callback (GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data); +*/ G_DEFINE_TYPE (IndicatorPower, indicator_power, INDICATOR_OBJECT_TYPE); @@ -119,14 +112,9 @@ indicator_power_init (IndicatorPower *self) priv->accessible_desc = NULL; - priv->watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION, - DBUS_SERVICE, - G_BUS_NAME_WATCHER_FLAGS_NONE, - gsd_appeared_callback, - NULL, - self, - NULL); - + priv->dbus_listener = g_object_new (INDICATOR_POWER_DBUS_LISTENER_TYPE, + INDICATOR_POWER_DBUS_LISTENER_INDICATOR, self, + NULL); priv->settings = g_settings_new ("com.canonical.indicator.power"); g_signal_connect_swapped (priv->settings, "changed::" ICON_POLICY_KEY, G_CALLBACK(update_visibility), self); @@ -157,9 +145,7 @@ indicator_power_dispose (GObject *object) dispose_devices (self); - g_clear_object (&priv->proxy); - g_clear_object (&priv->proxy_cancel); - + g_clear_object (&priv->dbus_listener); g_clear_object (&priv->settings); G_OBJECT_CLASS (indicator_power_parent_class)->dispose (object); @@ -807,135 +793,12 @@ indicator_power_set_devices (IndicatorPower * self, } static void -get_devices_cb (GObject * source_object, - GAsyncResult * res, - gpointer user_data) -{ - GError *error; - int device_count = 0; - GVariant * devices_container; - IndicatorPowerDevice ** devices = NULL; - IndicatorPower *self = INDICATOR_POWER (user_data); - - /* build an array of IndicatorPowerDevices from the DBus response */ - error = NULL; - devices_container = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); - if (devices_container == NULL) - { - g_message ("Couldn't get devices: %s\n", error->message); - g_error_free (error); - } - else - { - gsize i; - GVariant * devices_variant = g_variant_get_child_value (devices_container, 0); - device_count = devices_variant ? g_variant_n_children (devices_variant) : 0; - devices = g_new0 (IndicatorPowerDevice*, device_count); - - for (i=0; i<device_count; i++) - { - GVariant * v = g_variant_get_child_value (devices_variant, i); - devices[i] = indicator_power_device_new_from_variant (v); - g_variant_unref (v); - } - - g_variant_unref (devices_variant); - g_variant_unref (devices_container); - } - - indicator_power_set_devices (self, devices, device_count); - g_free (devices); -} - -static void update_visibility (IndicatorPower * self) { indicator_object_set_visible (INDICATOR_OBJECT (self), should_be_visible (self)); } -static void -receive_properties_changed (GDBusProxy *proxy G_GNUC_UNUSED, - GVariant *changed_properties G_GNUC_UNUSED, - GStrv invalidated_properties G_GNUC_UNUSED, - gpointer user_data) -{ - IndicatorPower *self = INDICATOR_POWER (user_data); - IndicatorPowerPrivate * priv = self->priv; - - /* it's time to refresh our device list */ - g_dbus_proxy_call (priv->proxy, - "GetDevices", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - priv->proxy_cancel, - get_devices_cb, - user_data); -} - -static void -service_proxy_cb (GObject *object, - GAsyncResult *res, - gpointer user_data) -{ - IndicatorPower *self = INDICATOR_POWER (user_data); - IndicatorPowerPrivate * priv = self->priv; - GError *error = NULL; - - priv->proxy = g_dbus_proxy_new_for_bus_finish (res, &error); - - g_clear_object (&priv->proxy_cancel); - - if (error != NULL) - { - g_error ("Error creating proxy: %s", error->message); - g_error_free (error); - - return; - } - - /* we want to change the primary device changes */ - g_signal_connect (priv->proxy, - "g-properties-changed", - G_CALLBACK (receive_properties_changed), - user_data); - - /* get the initial state */ - g_dbus_proxy_call (priv->proxy, - "GetDevices", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - priv->proxy_cancel, - get_devices_cb, - user_data); -} - -static void -gsd_appeared_callback (GDBusConnection *connection, - const gchar *name, - const gchar *name_owner, - gpointer user_data) -{ - IndicatorPower *self = INDICATOR_POWER (user_data); - IndicatorPowerPrivate * priv = self->priv; - - priv->proxy_cancel = g_cancellable_new (); - - g_dbus_proxy_new (connection, - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NULL, - name, - POWER_DBUS_PATH, - POWER_DBUS_INTERFACE, - priv->proxy_cancel, - service_proxy_cb, - self); -} - - - /* Grabs the label. Creates it if it doesn't exist already */ |