]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - liblightdm-gobject/power.c
Load all users only when really needed
[sojka/lightdm.git] / liblightdm-gobject / power.c
1 /*
2  * Copyright (C) 2010-2011 Robert Ancell.
3  * Author: Robert Ancell <robert.ancell@canonical.com>
4  *
5  * This library is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU Lesser General Public License as published by the Free
7  * Software Foundation; either version 2 or version 3 of the License.
8  * See http://www.gnu.org/copyleft/lgpl.html the full text of the license.
9  */
10
11 #include <config.h>
12
13 #include <string.h>
14 #include <gio/gio.h>
15
16 #include "lightdm/power.h"
17
18 static GDBusProxy *upower_proxy = NULL;
19 static GDBusProxy *ck_proxy = NULL;
20 static GDBusProxy *login1_proxy = NULL;
21
22 static GVariant *
23 upower_call_function (const gchar *function, GError **error)
24 {
25     if (!upower_proxy)
26     {
27         upower_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
28                                                       G_DBUS_PROXY_FLAGS_NONE,
29                                                       NULL,
30                                                       "org.freedesktop.UPower",
31                                                       "/org/freedesktop/UPower",
32                                                       "org.freedesktop.UPower",
33                                                       NULL,
34                                                       error);
35         if (!upower_proxy)
36             return NULL;
37     }
38
39     return g_dbus_proxy_call_sync (upower_proxy,
40                                    function,
41                                    NULL,
42                                    G_DBUS_CALL_FLAGS_NONE,
43                                    -1,
44                                    NULL,
45                                    error);
46 }
47
48 static GVariant *
49 login1_call_function (const gchar *function, GVariant *parameters, GError **error)
50 {
51     GVariant *r;
52
53     if (!login1_proxy)
54     {
55         login1_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
56                                                       G_DBUS_PROXY_FLAGS_NONE,
57                                                       NULL,
58                                                       "org.freedesktop.login1",
59                                                       "/org/freedesktop/login1",
60                                                       "org.freedesktop.login1.Manager",
61                                                       NULL,
62                                                       error);
63         if (!login1_proxy)
64             return NULL;
65     }
66
67     r = g_dbus_proxy_call_sync (login1_proxy,
68                                 function,
69                                 parameters,
70                                 G_DBUS_CALL_FLAGS_NONE,
71                                 -1,
72                                 NULL,
73                                 error);
74
75     return r;
76 }
77
78 /**
79  * lightdm_get_can_suspend:
80  *
81  * Checks if authorized to do a system suspend.
82  *
83  * Return value: #TRUE if can suspend the system
84  **/
85 gboolean
86 lightdm_get_can_suspend (void)
87 {
88     gboolean can_suspend = FALSE;
89     GVariant *r;
90
91     r = login1_call_function ("CanSuspend", NULL, NULL);
92     if (r)
93     {
94         gchar *result;
95         if (g_variant_is_of_type (r, G_VARIANT_TYPE ("(s)")))
96         {
97             g_variant_get (r, "(&s)", &result);
98             can_suspend = g_strcmp0 (result, "yes") == 0;
99         }
100     }
101     else
102     {
103         r = upower_call_function ("SuspendAllowed", NULL);
104         if (r && g_variant_is_of_type (r, G_VARIANT_TYPE ("(b)")))
105             g_variant_get (r, "(b)", &can_suspend);
106     }
107     if (r)
108         g_variant_unref (r);
109
110     return can_suspend;
111 }
112
113 /**
114  * lightdm_suspend:
115  * @error: return location for a #GError, or %NULL
116  *
117  * Triggers a system suspend.
118  *
119  * Return value: #TRUE if suspend initiated.
120  **/
121 gboolean
122 lightdm_suspend (GError **error)
123 {
124     GVariant *result;
125     gboolean suspended;
126
127     result = login1_call_function ("Suspend", g_variant_new("(b)", FALSE), error);
128     if (!result)
129     {
130         if (error)
131             g_debug ("Can't suspend using logind; falling back to UPower: %s", (*error)->message);
132         g_clear_error (error);
133         result = upower_call_function ("Suspend", error);
134     }
135
136     suspended = result != NULL;
137     if (result)
138         g_variant_unref (result);
139
140     return suspended;
141 }
142
143 /**
144  * lightdm_get_can_hibernate:
145  *
146  * Checks if is authorized to do a system hibernate.
147  *
148  * Return value: #TRUE if can hibernate the system
149  **/
150 gboolean
151 lightdm_get_can_hibernate (void)
152 {
153     gboolean can_hibernate = FALSE;
154     GVariant *r;
155
156     r = login1_call_function ("CanHibernate", NULL, NULL);
157     if (r)
158     {
159         gchar *result;
160         if (g_variant_is_of_type (r, G_VARIANT_TYPE ("(s)")))
161         {
162             g_variant_get (r, "(&s)", &result);
163             can_hibernate = g_strcmp0 (result, "yes") == 0;
164         }
165     }
166     else
167     {
168         r = upower_call_function ("HibernateAllowed", NULL);
169         if (r && g_variant_is_of_type (r, G_VARIANT_TYPE ("(b)")))
170             g_variant_get (r, "(b)", &can_hibernate);
171     }
172     if (r)
173         g_variant_unref (r);
174
175     return can_hibernate;
176 }
177
178 /**
179  * lightdm_hibernate:
180  * @error: return location for a #GError, or %NULL
181  *
182  * Triggers a system hibernate.
183  *
184  * Return value: #TRUE if hibernate initiated.
185  **/
186 gboolean
187 lightdm_hibernate (GError **error)
188 {
189     GVariant *result;
190     gboolean hibernated;
191
192     result = login1_call_function ("Hibernate", g_variant_new("(b)", FALSE), error);
193     if (!result)
194     {
195         if (error)
196             g_debug ("Can't hibernate using logind; falling back to UPower: %s", (*error)->message);
197         g_clear_error (error);
198         result = upower_call_function ("Hibernate", error);
199     }
200
201     hibernated = result != NULL;
202     if (result)
203         g_variant_unref (result);
204
205     return hibernated;
206 }
207
208 static GVariant *
209 ck_call_function (const gchar *function, GError **error)
210 {
211     GVariant *r;
212
213     if (!ck_proxy)
214     {
215         ck_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
216                                                   G_DBUS_PROXY_FLAGS_NONE,
217                                                   NULL,
218                                                   "org.freedesktop.ConsoleKit",
219                                                   "/org/freedesktop/ConsoleKit/Manager",
220                                                   "org.freedesktop.ConsoleKit.Manager",
221                                                   NULL,
222                                                   error);
223         if (!ck_proxy)
224             return FALSE;
225     }
226
227     r = g_dbus_proxy_call_sync (ck_proxy,
228                                 function,
229                                 NULL,
230                                 G_DBUS_CALL_FLAGS_NONE,
231                                 -1,
232                                 NULL,
233                                 error);
234
235     return r;
236 }
237
238 /**
239  * lightdm_get_can_restart:
240  *
241  * Checks if is authorized to do a system restart.
242  *
243  * Return value: #TRUE if can restart the system
244  **/
245 gboolean
246 lightdm_get_can_restart (void)
247 {
248     gboolean can_restart = FALSE;
249     GVariant *r;
250
251     r = login1_call_function ("CanReboot", NULL, NULL);
252     if (r)
253     {
254         gchar *result;
255         if (g_variant_is_of_type (r, G_VARIANT_TYPE ("(s)")))
256         {
257             g_variant_get (r, "(&s)", &result);
258             can_restart = g_strcmp0 (result, "yes") == 0;
259         }
260     }
261     else
262     {
263         r = ck_call_function ("CanRestart", NULL);
264         if (r && g_variant_is_of_type (r, G_VARIANT_TYPE ("(b)")))
265             g_variant_get (r, "(b)", &can_restart);
266     }
267     if (r)
268         g_variant_unref (r);
269
270     return can_restart;
271 }
272
273 /**
274  * lightdm_restart:
275  * @error: return location for a #GError, or %NULL
276  *
277  * Triggers a system restart.
278  *
279  * Return value: #TRUE if restart initiated.
280  **/
281 gboolean
282 lightdm_restart (GError **error)
283 {
284     GVariant *r;
285     gboolean restarted;
286
287     r = login1_call_function ("Reboot", g_variant_new("(b)", FALSE), error);
288     if (!r)
289     {
290         g_clear_error (error);
291         r = ck_call_function ("Restart", error);
292     }
293     restarted = r != NULL;
294     if (r)
295         g_variant_unref (r);
296
297     return restarted;
298 }
299
300 /**
301  * lightdm_get_can_shutdown:
302  *
303  * Checks if is authorized to do a system shutdown.
304  *
305  * Return value: #TRUE if can shutdown the system
306  **/
307 gboolean
308 lightdm_get_can_shutdown (void)
309 {
310     gboolean can_shutdown = FALSE;
311     GVariant *r;
312
313     r = login1_call_function ("CanPowerOff", NULL, NULL);
314     if (r)
315     {
316         gchar *result;
317         if (g_variant_is_of_type (r, G_VARIANT_TYPE ("(s)")))
318         {
319             g_variant_get (r, "(&s)", &result);
320             can_shutdown = g_strcmp0 (result, "yes") == 0;
321         }
322     }
323     else
324     {
325         r = ck_call_function ("CanStop", NULL);
326         if (r && g_variant_is_of_type (r, G_VARIANT_TYPE ("(b)")))
327             g_variant_get (r, "(b)", &can_shutdown);
328     }
329     if (r)
330         g_variant_unref (r);
331
332     return can_shutdown;
333 }
334
335 /**
336  * lightdm_shutdown:
337  * @error: return location for a #GError, or %NULL
338  *
339  * Triggers a system shutdown.
340  *
341  * Return value: #TRUE if shutdown initiated.
342  **/
343 gboolean
344 lightdm_shutdown (GError **error)
345 {
346     GVariant *r;
347     gboolean shutdown;
348
349     r = login1_call_function ("PowerOff", g_variant_new("(b)", FALSE), error);
350     if (!r)
351     {
352         g_clear_error (error);
353         r = ck_call_function ("Stop", error);
354     }
355     shutdown = r != NULL;
356     if (r)
357         g_variant_unref (r);
358
359     return shutdown;
360 }