3
Listens on DBus for Power changes and passes them to an IndicatorPower
5
Copyright 2012 Canonical Ltd.
8
Charles Kerr <charles.kerr@canonical.com>
10
This library is free software; you can redistribute it and/or
11
modify it under the terms of the GNU General Public License
12
version 3.0 as published by the Free Software Foundation.
14
This library is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
GNU General Public License version 3.0 for more details.
19
You should have received a copy of the GNU General Public
20
License along with this library. If not, see
21
<http://www.gnu.org/licenses/>.
24
#include "dbus-listener.h"
27
struct _IndicatorPowerDbusListenerPrivate
29
GCancellable * cancellable;
34
#define INDICATOR_POWER_DBUS_LISTENER_GET_PRIVATE(o) (INDICATOR_POWER_DBUS_LISTENER(o)->priv)
41
static guint signals[SIGNAL_LAST] = { 0 };
45
static void indicator_power_dbus_listener_class_init (IndicatorPowerDbusListenerClass *klass);
46
static void indicator_power_dbus_listener_init (IndicatorPowerDbusListener *self);
47
static void indicator_power_dbus_listener_dispose (GObject *object);
48
static void indicator_power_dbus_listener_finalize (GObject *object);
50
static void gsd_appeared_callback (GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data);
53
G_DEFINE_TYPE (IndicatorPowerDbusListener, indicator_power_dbus_listener, G_TYPE_OBJECT);
57
indicator_power_dbus_listener_class_init (IndicatorPowerDbusListenerClass *klass)
59
GObjectClass *object_class = G_OBJECT_CLASS (klass);
61
g_type_class_add_private (klass, sizeof (IndicatorPowerDbusListenerPrivate));
64
object_class->dispose = indicator_power_dbus_listener_dispose;
65
object_class->finalize = indicator_power_dbus_listener_finalize;
68
* IndicatorPowerDbusListener::devices-enumerated:
70
* @listener: the IndicatorPowerDbusListener
71
* @devices: a GSList of #IndicatorPowerDevice objects. (transfer none)
73
* This is emitted each time a new set of devices is enumerated over the bus.
75
signals[SIGNAL_DEVICES] = g_signal_new (INDICATOR_POWER_DBUS_LISTENER_DEVICES_ENUMERATED,
76
G_TYPE_FROM_CLASS(klass), 0,
77
G_STRUCT_OFFSET (IndicatorPowerDbusListenerClass, devices_enumerated),
79
g_cclosure_marshal_VOID__POINTER,
80
G_TYPE_NONE, 1, G_TYPE_POINTER);
83
/* Initialize an instance */
85
indicator_power_dbus_listener_init (IndicatorPowerDbusListener *self)
87
IndicatorPowerDbusListenerPrivate * priv;
89
priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
90
INDICATOR_POWER_DBUS_LISTENER_TYPE,
91
IndicatorPowerDbusListenerPrivate);
93
priv->cancellable = g_cancellable_new ();
95
priv->watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
97
G_BUS_NAME_WATCHER_FLAGS_NONE,
98
gsd_appeared_callback,
107
indicator_power_dbus_listener_dispose (GObject *object)
109
IndicatorPowerDbusListener * self = INDICATOR_POWER_DBUS_LISTENER(object);
110
IndicatorPowerDbusListenerPrivate * priv = self->priv;
112
g_clear_object (&priv->proxy);
114
if (priv->cancellable != NULL)
116
g_cancellable_cancel (priv->cancellable);
117
g_clear_object (&priv->cancellable);
120
if (priv->watcher_id)
122
g_bus_unwatch_name (priv->watcher_id);
123
priv->watcher_id = 0;
126
G_OBJECT_CLASS (indicator_power_dbus_listener_parent_class)->dispose (object);
130
indicator_power_dbus_listener_finalize (GObject *object)
132
G_OBJECT_CLASS (indicator_power_dbus_listener_parent_class)->finalize (object);
140
get_devices_cb (GObject * source_object,
145
GSList * devices = NULL;
146
GVariant * devices_container;
147
IndicatorPowerDbusListener * self = INDICATOR_POWER_DBUS_LISTENER (user_data);
149
/* build an array of IndicatorPowerDevices from the DBus response */
151
devices_container = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error);
152
if (devices_container == NULL)
154
g_message ("Couldn't get devices: %s\n", error->message);
155
g_error_free (error);
160
GVariant * devices_variant = g_variant_get_child_value (devices_container, 0);
161
const int device_count = devices_variant ? g_variant_n_children (devices_variant) : 0;
163
for (i=0; i<device_count; i++)
165
GVariant * v = g_variant_get_child_value (devices_variant, i);
166
devices = g_slist_prepend (devices, indicator_power_device_new_from_variant (v));
170
devices = g_slist_reverse (devices);
172
g_variant_unref (devices_variant);
173
g_variant_unref (devices_container);
176
g_signal_emit (self, signals[SIGNAL_DEVICES], (GQuark)0, devices);
177
g_slist_free_full (devices, g_object_unref);
181
request_device_list (IndicatorPowerDbusListener * self)
183
g_dbus_proxy_call (self->priv->proxy,
186
G_DBUS_CALL_FLAGS_NONE,
188
self->priv->cancellable,
194
receive_properties_changed (GDBusProxy *proxy G_GNUC_UNUSED,
195
GVariant *changed_properties G_GNUC_UNUSED,
196
GStrv invalidated_properties G_GNUC_UNUSED,
199
request_device_list (INDICATOR_POWER_DBUS_LISTENER(user_data));
204
service_proxy_cb (GObject *object,
208
GError * error = NULL;
209
IndicatorPowerDbusListener * self = INDICATOR_POWER_DBUS_LISTENER(user_data);
210
IndicatorPowerDbusListenerPrivate * priv = self->priv;
212
priv->proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
216
g_error ("Error creating proxy: %s", error->message);
217
g_error_free (error);
221
/* we want to change the primary device changes */
222
g_signal_connect (priv->proxy, "g-properties-changed",
223
G_CALLBACK (receive_properties_changed), user_data);
225
/* get the initial state */
226
request_device_list (self);
230
gsd_appeared_callback (GDBusConnection *connection,
232
const gchar *name_owner,
235
IndicatorPowerDbusListener * self = INDICATOR_POWER_DBUS_LISTENER(user_data);
236
IndicatorPowerDbusListenerPrivate * priv = self->priv;
238
g_dbus_proxy_new (connection,
239
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
243
GSD_POWER_DBUS_INTERFACE,