~xavi-garcia-mena/ubuntu/vivid/upower/percentages-power-off

« back to all changes in this revision

Viewing changes to libupower-glib/up-wakeups.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2010-02-16 10:16:24 UTC
  • Revision ID: james.westby@ubuntu.com-20100216101624-2cmwqsr1ndftdd87
Tags: upstream-0.9.0+git20100216.72bb2
ImportĀ upstreamĀ versionĀ 0.9.0+git20100216.72bb2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
 
2
 *
 
3
 * Copyright (C) 2009 Richard Hughes <richard@hughsie.com>
 
4
 *
 
5
 * Licensed under the GNU General Public License Version 2
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; either version 2 of the License, or
 
10
 * (at your option) any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
20
 */
 
21
 
 
22
#include "config.h"
 
23
 
 
24
#include <stdlib.h>
 
25
#include <stdio.h>
 
26
#include <glib.h>
 
27
#include <dbus/dbus-glib.h>
 
28
 
 
29
#include "up-wakeups.h"
 
30
 
 
31
static void     up_wakeups_class_init   (UpWakeupsClass *klass);
 
32
static void     up_wakeups_init         (UpWakeups      *wakeups);
 
33
static void     up_wakeups_finalize     (GObject        *object);
 
34
 
 
35
#define UP_WAKEUPS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), UP_TYPE_WAKEUPS, UpWakeupsPrivate))
 
36
 
 
37
struct UpWakeupsPrivate
 
38
{
 
39
        DBusGConnection         *bus;
 
40
        DBusGProxy              *proxy;
 
41
        DBusGProxy              *prop_proxy;
 
42
        gboolean                 has_capability;
 
43
        gboolean                 have_properties;
 
44
};
 
45
 
 
46
enum {
 
47
        UP_WAKEUPS_DATA_CHANGED,
 
48
        UP_WAKEUPS_TOTAL_CHANGED,
 
49
        UP_WAKEUPS_LAST_SIGNAL
 
50
};
 
51
 
 
52
static guint signals [UP_WAKEUPS_LAST_SIGNAL] = { 0 };
 
53
 
 
54
G_DEFINE_TYPE (UpWakeups, up_wakeups, G_TYPE_OBJECT)
 
55
 
 
56
/**
 
57
 * up_wakeups_get_total_sync:
 
58
 * @wakeups: a #UpWakeups instance.
 
59
 * @cancellable: a #GCancellable or %NULL
 
60
 * @error: a #GError, or %NULL.
 
61
 *
 
62
 * Gets the the total number of wakeups per second from the daemon.
 
63
 *
 
64
 * Return value: number of wakeups per second.
 
65
 *
 
66
 * Since: 0.9.1
 
67
 **/
 
68
guint
 
69
up_wakeups_get_total_sync (UpWakeups *wakeups, GCancellable *cancellable, GError **error)
 
70
{
 
71
        guint total = 0;
 
72
        gboolean ret;
 
73
        GError *error_local = NULL;
 
74
 
 
75
        g_return_val_if_fail (UP_IS_WAKEUPS (wakeups), FALSE);
 
76
        g_return_val_if_fail (wakeups->priv->proxy != NULL, FALSE);
 
77
 
 
78
        ret = dbus_g_proxy_call (wakeups->priv->proxy, "GetTotal", &error_local,
 
79
                                 G_TYPE_INVALID,
 
80
                                 G_TYPE_UINT, &total,
 
81
                                 G_TYPE_INVALID);
 
82
        if (!ret) {
 
83
                g_warning ("Couldn't get total: %s", error_local->message);
 
84
                g_set_error (error, 1, 0, "%s", error_local->message);
 
85
                g_error_free (error_local);
 
86
        }
 
87
        return total;
 
88
}
 
89
 
 
90
/**
 
91
 * up_wakeups_get_data_sync:
 
92
 * @wakeups: a #UpWakeups instance.
 
93
 * @cancellable: a #GCancellable or %NULL
 
94
 * @error: a #GError, or %NULL.
 
95
 *
 
96
 * Gets the wakeups data from the daemon.
 
97
 *
 
98
 * Return value: an array of %UpWakeupItem's
 
99
 *
 
100
 * Since: 0.9.1
 
101
 **/
 
102
GPtrArray *
 
103
up_wakeups_get_data_sync (UpWakeups *wakeups, GCancellable *cancellable, GError **error)
 
104
{
 
105
        GError *error_local = NULL;
 
106
        GType g_type_gvalue_array;
 
107
        GPtrArray *gvalue_ptr_array = NULL;
 
108
        GValueArray *gva;
 
109
        GValue *gv;
 
110
        guint i;
 
111
        UpWakeupItem *item;
 
112
        GPtrArray *array = NULL;
 
113
        gboolean ret;
 
114
 
 
115
        g_return_val_if_fail (UP_IS_WAKEUPS (wakeups), NULL);
 
116
        g_return_val_if_fail (wakeups->priv->proxy != NULL, NULL);
 
117
 
 
118
        g_type_gvalue_array = dbus_g_type_get_collection ("GPtrArray",
 
119
                                        dbus_g_type_get_struct("GValueArray",
 
120
                                                G_TYPE_BOOLEAN,
 
121
                                                G_TYPE_UINT,
 
122
                                                G_TYPE_DOUBLE,
 
123
                                                G_TYPE_STRING,
 
124
                                                G_TYPE_STRING,
 
125
                                                G_TYPE_INVALID));
 
126
 
 
127
        /* get compound data */
 
128
        ret = dbus_g_proxy_call (wakeups->priv->proxy, "GetData", &error_local,
 
129
                                 G_TYPE_INVALID,
 
130
                                 g_type_gvalue_array, &gvalue_ptr_array,
 
131
                                 G_TYPE_INVALID);
 
132
        if (!ret) {
 
133
                g_warning ("GetData on failed: %s", error_local->message);
 
134
                g_set_error (error, 1, 0, "%s", error_local->message);
 
135
                g_error_free (error_local);
 
136
                goto out;
 
137
        }
 
138
 
 
139
        /* no data */
 
140
        if (gvalue_ptr_array->len == 0)
 
141
                goto out;
 
142
 
 
143
        /* convert */
 
144
        array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
 
145
        for (i=0; i<gvalue_ptr_array->len; i++) {
 
146
                gva = (GValueArray *) g_ptr_array_index (gvalue_ptr_array, i);
 
147
                item = up_wakeup_item_new ();
 
148
 
 
149
                /* 0 */
 
150
                gv = g_value_array_get_nth (gva, 0);
 
151
                up_wakeup_item_set_is_userspace (item, g_value_get_boolean (gv));
 
152
                g_value_unset (gv);
 
153
 
 
154
                /* 1 */
 
155
                gv = g_value_array_get_nth (gva, 1);
 
156
                up_wakeup_item_set_id (item, g_value_get_uint (gv));
 
157
                g_value_unset (gv);
 
158
 
 
159
                /* 2 */
 
160
                gv = g_value_array_get_nth (gva, 2);
 
161
                up_wakeup_item_set_value (item, g_value_get_double (gv));
 
162
                g_value_unset (gv);
 
163
 
 
164
                /* 3 */
 
165
                gv = g_value_array_get_nth (gva, 3);
 
166
                up_wakeup_item_set_cmdline (item, g_value_get_string (gv));
 
167
                g_value_unset (gv);
 
168
 
 
169
                /* 4 */
 
170
                gv = g_value_array_get_nth (gva, 4);
 
171
                up_wakeup_item_set_details (item, g_value_get_string (gv));
 
172
                g_value_unset (gv);
 
173
 
 
174
                /* add */
 
175
                g_ptr_array_add (array, item);
 
176
                g_value_array_free (gva);
 
177
        }
 
178
out:
 
179
        if (gvalue_ptr_array != NULL)
 
180
                g_ptr_array_unref (gvalue_ptr_array);
 
181
        return array;
 
182
}
 
183
 
 
184
/**
 
185
 * up_wakeups_ensure_properties:
 
186
 **/
 
187
static void
 
188
up_wakeups_ensure_properties (UpWakeups *wakeups)
 
189
{
 
190
        gboolean ret;
 
191
        GError *error;
 
192
        GHashTable *props;
 
193
        GValue *value;
 
194
 
 
195
        props = NULL;
 
196
 
 
197
        if (wakeups->priv->have_properties)
 
198
                goto out;
 
199
 
 
200
        error = NULL;
 
201
        ret = dbus_g_proxy_call (wakeups->priv->prop_proxy, "GetAll", &error,
 
202
                                 G_TYPE_STRING, "org.freedesktop.UPower.Wakeups",
 
203
                                 G_TYPE_INVALID,
 
204
                                 dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &props,
 
205
                                 G_TYPE_INVALID);
 
206
        if (!ret) {
 
207
                g_warning ("Error invoking GetAll() to get properties: %s", error->message);
 
208
                g_error_free (error);
 
209
                goto out;
 
210
        }
 
211
 
 
212
        value = g_hash_table_lookup (props, "HasCapability");
 
213
        if (value == NULL) {
 
214
                g_warning ("No 'HasCapability' property");
 
215
                goto out;
 
216
        }
 
217
        wakeups->priv->has_capability = g_value_get_boolean (value);
 
218
 
 
219
        /* cached */
 
220
        wakeups->priv->have_properties = TRUE;
 
221
 
 
222
out:
 
223
        if (props != NULL)
 
224
                g_hash_table_unref (props);
 
225
}
 
226
 
 
227
/**
 
228
 * up_wakeups_get_properties_sync:
 
229
 * @wakeups: a #UpWakeups instance.
 
230
 * @cancellable: a #GCancellable or %NULL
 
231
 * @error: a #GError, or %NULL.
 
232
 *
 
233
 * Gets properties from the daemon about wakeup data.
 
234
 *
 
235
 * Return value: %TRUE if supported
 
236
 *
 
237
 * Since: 0.9.1
 
238
 **/
 
239
gboolean
 
240
up_wakeups_get_properties_sync (UpWakeups *wakeups, GCancellable *cancellable, GError **error)
 
241
{
 
242
        g_return_val_if_fail (UP_IS_WAKEUPS (wakeups), FALSE);
 
243
        up_wakeups_ensure_properties (wakeups);
 
244
        return TRUE;
 
245
}
 
246
 
 
247
/**
 
248
 * up_wakeups_get_has_capability:
 
249
 * @wakeups: a #UpWakeups instance.
 
250
 *
 
251
 * Returns if the daemon supports getting the wakeup data.
 
252
 *
 
253
 * Return value: %TRUE if supported
 
254
 *
 
255
 * Since: 0.9.1
 
256
 **/
 
257
gboolean
 
258
up_wakeups_get_has_capability (UpWakeups *wakeups)
 
259
{
 
260
        g_return_val_if_fail (UP_IS_WAKEUPS (wakeups), FALSE);
 
261
        up_wakeups_ensure_properties (wakeups);
 
262
        return wakeups->priv->has_capability;
 
263
}
 
264
 
 
265
/**
 
266
 * up_wakeups_total_changed_cb:
 
267
 **/
 
268
static void
 
269
up_wakeups_total_changed_cb (DBusGProxy *proxy, guint value, UpWakeups *wakeups)
 
270
{
 
271
        g_signal_emit (wakeups, signals [UP_WAKEUPS_TOTAL_CHANGED], 0, value);
 
272
}
 
273
 
 
274
/**
 
275
 * up_wakeups_data_changed_cb:
 
276
 **/
 
277
static void
 
278
up_wakeups_data_changed_cb (DBusGProxy *proxy, UpWakeups *wakeups)
 
279
{
 
280
        g_signal_emit (wakeups, signals [UP_WAKEUPS_DATA_CHANGED], 0);
 
281
}
 
282
 
 
283
/**
 
284
 * up_wakeups_class_init:
 
285
 **/
 
286
static void
 
287
up_wakeups_class_init (UpWakeupsClass *klass)
 
288
{
 
289
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
290
        object_class->finalize = up_wakeups_finalize;
 
291
 
 
292
        signals [UP_WAKEUPS_DATA_CHANGED] =
 
293
                g_signal_new ("data-changed",
 
294
                              G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
 
295
                              G_STRUCT_OFFSET (UpWakeupsClass, data_changed),
 
296
                              NULL, NULL, g_cclosure_marshal_VOID__VOID,
 
297
                              G_TYPE_NONE, 0);
 
298
        signals [UP_WAKEUPS_TOTAL_CHANGED] =
 
299
                g_signal_new ("total-changed",
 
300
                              G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
 
301
                              G_STRUCT_OFFSET (UpWakeupsClass, data_changed),
 
302
                              NULL, NULL, g_cclosure_marshal_VOID__UINT,
 
303
                              G_TYPE_NONE, 1, G_TYPE_UINT);
 
304
 
 
305
        g_type_class_add_private (klass, sizeof (UpWakeupsPrivate));
 
306
}
 
307
 
 
308
/**
 
309
 * up_wakeups_init:
 
310
 **/
 
311
static void
 
312
up_wakeups_init (UpWakeups *wakeups)
 
313
{
 
314
        GError *error = NULL;
 
315
 
 
316
        wakeups->priv = UP_WAKEUPS_GET_PRIVATE (wakeups);
 
317
        wakeups->priv->has_capability = FALSE;
 
318
        wakeups->priv->have_properties = FALSE;
 
319
 
 
320
        /* get on the bus */
 
321
        wakeups->priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
 
322
        if (wakeups->priv->bus == NULL) {
 
323
                g_warning ("Couldn't connect to system bus: %s", error->message);
 
324
                g_error_free (error);
 
325
                goto out;
 
326
        }
 
327
 
 
328
        /* connect to properties interface */
 
329
        wakeups->priv->prop_proxy = dbus_g_proxy_new_for_name (wakeups->priv->bus,
 
330
                                                              "org.freedesktop.UPower",
 
331
                                                              "/org/freedesktop/UPower/Wakeups",
 
332
                                                              "org.freedesktop.DBus.Properties");
 
333
        if (wakeups->priv->prop_proxy == NULL) {
 
334
                g_warning ("Couldn't connect to proxy");
 
335
                goto out;
 
336
        }
 
337
 
 
338
        /* connect to main interface */
 
339
        wakeups->priv->proxy = dbus_g_proxy_new_for_name (wakeups->priv->bus,
 
340
                                                         "org.freedesktop.UPower",
 
341
                                                         "/org/freedesktop/UPower/Wakeups",
 
342
                                                         "org.freedesktop.UPower.Wakeups");
 
343
        if (wakeups->priv->proxy == NULL) {
 
344
                g_warning ("Couldn't connect to proxy");
 
345
                goto out;
 
346
        }
 
347
        dbus_g_proxy_add_signal (wakeups->priv->proxy, "TotalChanged", G_TYPE_UINT, G_TYPE_INVALID);
 
348
        dbus_g_proxy_add_signal (wakeups->priv->proxy, "DataChanged", G_TYPE_INVALID);
 
349
 
 
350
        /* all callbacks */
 
351
        dbus_g_proxy_connect_signal (wakeups->priv->proxy, "TotalChanged",
 
352
                                     G_CALLBACK (up_wakeups_total_changed_cb), wakeups, NULL);
 
353
        dbus_g_proxy_connect_signal (wakeups->priv->proxy, "DataChanged",
 
354
                                     G_CALLBACK (up_wakeups_data_changed_cb), wakeups, NULL);
 
355
out:
 
356
        return;
 
357
}
 
358
 
 
359
/**
 
360
 * up_wakeups_finalize:
 
361
 **/
 
362
static void
 
363
up_wakeups_finalize (GObject *object)
 
364
{
 
365
        UpWakeups *wakeups;
 
366
 
 
367
        g_return_if_fail (UP_IS_WAKEUPS (object));
 
368
 
 
369
        wakeups = UP_WAKEUPS (object);
 
370
        if (wakeups->priv->proxy != NULL)
 
371
                g_object_unref (wakeups->priv->proxy);
 
372
        if (wakeups->priv->prop_proxy != NULL)
 
373
                g_object_unref (wakeups->priv->prop_proxy);
 
374
 
 
375
        G_OBJECT_CLASS (up_wakeups_parent_class)->finalize (object);
 
376
}
 
377
 
 
378
/**
 
379
 * up_wakeups_new:
 
380
 *
 
381
 * Gets a new object to allow querying the wakeups data from the server.
 
382
 *
 
383
 * Return value: the a new @UpWakeups object.
 
384
 *
 
385
 * Since: 0.9.1
 
386
 **/
 
387
UpWakeups *
 
388
up_wakeups_new (void)
 
389
{
 
390
        UpWakeups *wakeups;
 
391
        wakeups = g_object_new (UP_TYPE_WAKEUPS, NULL);
 
392
        return UP_WAKEUPS (wakeups);
 
393
}
 
394