aboutsummaryrefslogtreecommitdiff
path: root/src/dbus-listener.c
diff options
context:
space:
mode:
authorCharles Kerr <charles.kerr@canonical.com>2012-05-26 15:19:38 -0500
committerCharles Kerr <charles.kerr@canonical.com>2012-05-26 15:19:38 -0500
commit9ee74a367606a4dd6779b0448bef237dd9e2797e (patch)
tree5fab482debba267aac5e33d490c88c2788dbcfb2 /src/dbus-listener.c
parente0d1b3299edde62797fe6fa08be3740f24c7d38e (diff)
downloadayatana-indicator-power-9ee74a367606a4dd6779b0448bef237dd9e2797e.tar.gz
ayatana-indicator-power-9ee74a367606a4dd6779b0448bef237dd9e2797e.tar.bz2
ayatana-indicator-power-9ee74a367606a4dd6779b0448bef237dd9e2797e.zip
separate the dbus org.gnome.SettingsDaemon.Power logic into a separate class
Diffstat (limited to 'src/dbus-listener.c')
-rw-r--r--src/dbus-listener.c276
1 files changed, 276 insertions, 0 deletions
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);
+}