1 /* Taken from LightDM and modified.
2 * Copyright (C) 2012 Fabrice THIROUX <fabrice.thiroux@free.fr>.
3 *
4 **** License from former file (power.c) ****
5 *
6 * Copyright (C) 2010-2011 Robert Ancell.
7 * Author: Robert Ancell <robert.ancell@canonical.com>
8 *
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at your option) any
12 * later version. See http://www.gnu.org/copyleft/lgpl.html the full text of the
13 * license.
14 */
15 #include <config.h>
16 #include <glib.h>
17 #include <string.h>
18 #include <gio/gio.h>
19
20 /*** Mechanism independent ***/
21
22 static GDBusProxy *upower_proxy = NULL;
23 static GDBusProxy *ck_proxy = NULL;
24 static GDBusProxy *systemd_proxy = NULL;
25 static GDBusProxy *lightdm_proxy = NULL;
26 static GDBusProxy *lxde_proxy = NULL;
27
28
29 /*** UPower mechanism ***/
30
31 static gboolean
upower_call_function(const gchar * function,gboolean default_result,GError ** error)32 upower_call_function (const gchar *function, gboolean default_result, GError **error)
33 {
34 GVariant *result;
35 gboolean function_result = FALSE;
36
37 if (!upower_proxy)
38 {
39 upower_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
40 G_DBUS_PROXY_FLAGS_NONE,
41 NULL,
42 "org.freedesktop.UPower",
43 "/org/freedesktop/UPower",
44 "org.freedesktop.UPower",
45 NULL,
46 error);
47 if (!upower_proxy)
48 return FALSE;
49 }
50
51 result = g_dbus_proxy_call_sync (upower_proxy,
52 function,
53 NULL,
54 G_DBUS_CALL_FLAGS_NONE,
55 -1,
56 NULL,
57 error);
58 if (!result)
59 return default_result;
60
61 if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(b)")))
62 g_variant_get (result, "(b)", &function_result);
63
64 g_variant_unref (result);
65 return function_result;
66 }
67
68 gboolean
dbus_UPower_CanSuspend(void)69 dbus_UPower_CanSuspend (void)
70 {
71 return upower_call_function ("SuspendAllowed", FALSE, NULL);
72 }
73
74 gboolean
dbus_UPower_Suspend(GError ** error)75 dbus_UPower_Suspend (GError **error)
76 {
77 return upower_call_function ("Suspend", TRUE, error);
78 }
79
80 gboolean
dbus_UPower_CanHibernate(void)81 dbus_UPower_CanHibernate (void)
82 {
83 return upower_call_function ("HibernateAllowed", FALSE, NULL);
84 }
85
86 gboolean
dbus_UPower_Hibernate(GError ** error)87 dbus_UPower_Hibernate (GError **error)
88 {
89 return upower_call_function ("Hibernate", TRUE, error);
90 }
91
92 /*** ConsoleKit mechanism ***/
93
94 static gboolean
ck_query(const gchar * function,gboolean default_result,GError ** error)95 ck_query (const gchar *function, gboolean default_result, GError **error)
96 {
97 GVariant *result;
98 gboolean function_result = FALSE;
99 const gchar *str;
100
101 if (!ck_proxy)
102 {
103 ck_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
104 G_DBUS_PROXY_FLAGS_NONE,
105 NULL,
106 "org.freedesktop.ConsoleKit",
107 "/org/freedesktop/ConsoleKit/Manager",
108 "org.freedesktop.ConsoleKit.Manager",
109 NULL,
110 error);
111 if (!ck_proxy)
112 return FALSE;
113 }
114
115 result = g_dbus_proxy_call_sync (ck_proxy,
116 function,
117 NULL,
118 G_DBUS_CALL_FLAGS_NONE,
119 -1,
120 NULL,
121 error);
122 if (!result)
123 return default_result;
124
125 if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(s)")))
126 {
127 g_variant_get (result, "(s)", &str);
128 if ( g_strcmp0 (str, "yes") == 0 || g_strcmp0 (str, "challenge") == 0 )
129 function_result = TRUE;
130 else
131 function_result = default_result;
132 }
133
134 g_variant_unref (result);
135 return function_result;
136 }
137
138 static void
ck_call_function(const gchar * function,gboolean value,GError ** error)139 ck_call_function (const gchar *function, gboolean value, GError **error)
140 {
141 GVariant *result;
142
143 if (!ck_proxy)
144 {
145 ck_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
146 G_DBUS_PROXY_FLAGS_NONE,
147 NULL,
148 "org.freedesktop.ConsoleKit",
149 "/org/freedesktop/ConsoleKit",
150 "org.freedesktop.ConsoleKit.Manager",
151 NULL,
152 error);
153 if (!ck_proxy)
154 return;
155 }
156
157 result = g_dbus_proxy_call_sync (ck_proxy,
158 function,
159 g_variant_new ("(b)", value),
160 G_DBUS_CALL_FLAGS_NONE,
161 -1,
162 NULL,
163 error);
164 g_variant_unref (result);
165 return;
166 }
167
168 gboolean
dbus_ConsoleKit_CanPowerOff(void)169 dbus_ConsoleKit_CanPowerOff (void)
170 {
171 return ck_query ("CanPowerOff", FALSE, NULL);
172 }
173
174 void
dbus_ConsoleKit_PowerOff(GError ** error)175 dbus_ConsoleKit_PowerOff (GError **error)
176 {
177 ck_call_function ("PowerOff", TRUE, error);
178 }
179
180 gboolean
dbus_ConsoleKit_CanReboot(void)181 dbus_ConsoleKit_CanReboot (void)
182 {
183 return ck_query ("CanReboot", FALSE, NULL);
184 }
185
186 void
dbus_ConsoleKit_Reboot(GError ** error)187 dbus_ConsoleKit_Reboot (GError **error)
188 {
189 ck_call_function ("Reboot", TRUE, error);
190 }
191
192 gboolean
dbus_ConsoleKit_CanSuspend(void)193 dbus_ConsoleKit_CanSuspend (void)
194 {
195 return ck_query ("CanSuspend", FALSE, NULL);
196 }
197
198 void
dbus_ConsoleKit_Suspend(GError ** error)199 dbus_ConsoleKit_Suspend (GError **error)
200 {
201 ck_call_function ("Suspend", TRUE, error);
202 }
203
204 gboolean
dbus_ConsoleKit_CanHibernate(void)205 dbus_ConsoleKit_CanHibernate (void)
206 {
207 return ck_query ("CanHibernate", FALSE, NULL);
208 }
209
210 void
dbus_ConsoleKit_Hibernate(GError ** error)211 dbus_ConsoleKit_Hibernate (GError **error)
212 {
213 ck_call_function ("Hibernate", TRUE, error);
214 }
215
216 /*** Systemd mechanism ***/
217
218 static gboolean
systemd_query(const gchar * function,gboolean default_result,GError ** error)219 systemd_query (const gchar *function, gboolean default_result, GError **error)
220 {
221 GVariant *result;
222 gboolean function_result = FALSE;
223 const gchar *str;
224
225 if (!systemd_proxy)
226 {
227 systemd_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
228 G_DBUS_PROXY_FLAGS_NONE,
229 NULL,
230 "org.freedesktop.login1",
231 "/org/freedesktop/login1",
232 "org.freedesktop.login1.Manager",
233 NULL,
234 error);
235 if (!systemd_proxy)
236 return FALSE;
237 }
238
239 result = g_dbus_proxy_call_sync (systemd_proxy,
240 function,
241 NULL,
242 G_DBUS_CALL_FLAGS_NONE,
243 -1,
244 NULL,
245 error);
246 if (!result)
247 return default_result;
248
249 if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(s)")))
250 {
251 g_variant_get (result, "(s)", &str);
252 if ( g_strcmp0 (str, "yes") == 0 || g_strcmp0 (str, "challenge") == 0 )
253 function_result = TRUE;
254 else
255 function_result = default_result;
256 }
257
258 g_variant_unref (result);
259 return function_result;
260 }
261
262 static void
systemd_call_function(const gchar * function,gboolean value,GError ** error)263 systemd_call_function (const gchar *function, gboolean value, GError **error)
264 {
265 GVariant *result;
266
267 if (!systemd_proxy)
268 {
269 systemd_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
270 G_DBUS_PROXY_FLAGS_NONE,
271 NULL,
272 "org.freedesktop.login1",
273 "/org/freedesktop/login1",
274 "org.freedesktop.login1.Manager",
275 NULL,
276 error);
277 if (!systemd_proxy)
278 return;
279 }
280
281 result = g_dbus_proxy_call_sync (systemd_proxy,
282 function,
283 g_variant_new ("(b)", value),
284 G_DBUS_CALL_FLAGS_NONE,
285 -1,
286 NULL,
287 error);
288 g_variant_unref (result);
289 return;
290 }
291
292 gboolean
dbus_systemd_CanPowerOff(void)293 dbus_systemd_CanPowerOff (void)
294 {
295 return systemd_query ("CanPowerOff", FALSE, NULL);
296 }
297
298 void
dbus_systemd_PowerOff(GError ** error)299 dbus_systemd_PowerOff (GError **error)
300 {
301 systemd_call_function ("PowerOff", TRUE, error);
302 }
303
304 gboolean
dbus_systemd_CanReboot(void)305 dbus_systemd_CanReboot (void)
306 {
307 return systemd_query ("CanReboot", FALSE, NULL);
308 }
309
310 void
dbus_systemd_Reboot(GError ** error)311 dbus_systemd_Reboot (GError **error)
312 {
313 systemd_call_function ("Reboot", TRUE, error);
314 }
315
316 gboolean
dbus_systemd_CanSuspend(void)317 dbus_systemd_CanSuspend (void)
318 {
319 return systemd_query ("CanSuspend", FALSE, NULL);
320 }
321
322 void
dbus_systemd_Suspend(GError ** error)323 dbus_systemd_Suspend (GError **error)
324 {
325 systemd_call_function ("Suspend", TRUE, error);
326 }
327
328 gboolean
dbus_systemd_CanHibernate(void)329 dbus_systemd_CanHibernate (void)
330 {
331 return systemd_query ("CanHibernate", FALSE, NULL);
332 }
333
334 void
dbus_systemd_Hibernate(GError ** error)335 dbus_systemd_Hibernate (GError **error)
336 {
337 systemd_call_function ("Hibernate", TRUE, error);
338 }
339
340 /*** Lightdm mechanism ***/
341
342 static gboolean
lightdm_call_function(const gchar * function,gboolean default_result,GError ** error)343 lightdm_call_function (const gchar *function, gboolean default_result, GError **error)
344 {
345 GVariant *result;
346 gboolean function_result = FALSE;
347
348 if (!lightdm_proxy)
349 {
350 lightdm_proxy = g_dbus_proxy_new_for_bus_sync ( G_BUS_TYPE_SYSTEM,
351 G_DBUS_PROXY_FLAGS_NONE,
352 NULL,
353 "org.freedesktop.DisplayManager",
354 g_getenv ("XDG_SEAT_PATH"),
355 "org.freedesktop.DisplayManager.Seat",
356 NULL,
357 error);
358 if (!lightdm_proxy)
359 return FALSE;
360 }
361
362 result = g_dbus_proxy_call_sync (lightdm_proxy,
363 function,
364 NULL,
365 G_DBUS_CALL_FLAGS_NONE,
366 -1,
367 NULL,
368 error);
369 if (!result)
370 return default_result;
371
372 if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(b)")))
373 g_variant_get (result, "(b)", &function_result);
374
375 g_variant_unref (result);
376 return function_result;
377 }
378
379 gboolean
dbus_Lightdm_SwitchToGreeter(GError ** error)380 dbus_Lightdm_SwitchToGreeter (GError **error)
381 {
382 return lightdm_call_function ("SwitchToGreeter", TRUE, error);
383 }
384
385 /*** LXDE mechanism ***/
386
387 static gboolean
lxde_call_function(const gchar * function,gboolean default_result,GError ** error)388 lxde_call_function (const gchar *function, gboolean default_result, GError **error)
389 {
390 GVariant *result;
391 gboolean function_result = FALSE;
392
393 if (!lxde_proxy)
394 {
395 lxde_proxy = g_dbus_proxy_new_for_bus_sync ( G_BUS_TYPE_SYSTEM,
396 G_DBUS_PROXY_FLAGS_NONE,
397 NULL,
398 "org.lxde.SessionManager",
399 "/org/lxde/SessionManager",
400 "org.lxde.SessionManager",
401 NULL,
402 error);
403 if (!lxde_proxy)
404 return FALSE;
405 }
406
407 result = g_dbus_proxy_call_sync (lxde_proxy,
408 function,
409 NULL,
410 G_DBUS_CALL_FLAGS_NONE,
411 -1,
412 NULL,
413 error);
414 if (!result)
415 return default_result;
416
417 if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(b)")))
418 g_variant_get (result, "(b)", &function_result);
419
420 g_variant_unref (result);
421 return function_result;
422 }
423
424 gboolean
dbus_LXDE_Logout(GError ** error)425 dbus_LXDE_Logout (GError **error)
426 {
427 return lxde_call_function ("Restart", TRUE, error);
428 }
429