diff -Naurp lightdm-1.6.0.orig/liblightdm-gobject/power.c lightdm-1.6.0/liblightdm-gobject/power.c --- lightdm-1.6.0.orig/liblightdm-gobject/power.c 2013-03-06 03:40:10.000000000 +0100 +++ lightdm-1.6.0/liblightdm-gobject/power.c 2013-06-08 00:45:07.411183727 +0200 @@ -15,44 +15,67 @@ #include "lightdm/power.h" -static GDBusProxy *upower_proxy = NULL; -static GDBusProxy *ck_proxy = NULL; +/* static GDBusProxy *upower_proxy = NULL; + static GDBusProxy *ck_proxy = NULL; + static GDBusProxy *login1_proxy = NULL; + */ + +struct proxy_info { + /* proxy reference */ + GDBusProxy *proxy; + + /* arguments to g_dbus_proxy_new_for_bus_sync() */ + const char *name; + const char *object_path; + const char *interface_name; + +}; + +static struct proxy_info upower_proxy = { + .proxy = NULL, + .name = "org.freedesktop.UPower", + .object_path = "/org/freedesktop/UPower", + .interface_name = "org.freedesktop.UPower", +}; + +static struct proxy_info ck_proxy = { + .proxy = NULL, + .name = "org.freedesktop.ConsoleKit", + .object_path = "/org/freedesktop/ConsoleKit/Manager", + .interface_name = "org.freedesktop.ConsoleKit.Manager", +}; + +static struct proxy_info login1_proxy = { + .proxy = NULL, + .name = "org.freedesktop.login1", + .object_path = "/org/freedesktop/login1", + .interface_name = "org.freedesktop.login1.Manager", +}; -static gboolean -upower_call_function (const gchar *function, gboolean default_result, GError **error) +static GVariant * +do_call_function (const gchar *function, GVariant *parameters, GError **error, struct proxy_info *proxy) { - GVariant *result; - gboolean function_result = FALSE; - - if (!upower_proxy) + if (!proxy->proxy) { - upower_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.UPower", - "/org/freedesktop/UPower", - "org.freedesktop.UPower", - NULL, - error); - if (!upower_proxy) - return FALSE; - } - - result = g_dbus_proxy_call_sync (upower_proxy, - function, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - error); - if (!result) - return default_result; - - if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(b)"))) - g_variant_get (result, "(b)", &function_result); + proxy->proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + proxy->name, + proxy->object_path, + proxy->interface_name, + NULL, + error); + if (!proxy->proxy) + return NULL; + } - g_variant_unref (result); - return function_result; + return g_dbus_proxy_call_sync(proxy->proxy, + function, + parameters, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + error); } /** @@ -65,7 +88,29 @@ upower_call_function (const gchar *funct gboolean lightdm_get_can_suspend (void) { - return upower_call_function ("SuspendAllowed", FALSE, NULL); + gboolean can_suspend = FALSE; + GVariant *r; + + r = do_call_function ("CanSuspend", NULL, NULL, &login1_proxy); + if (r) + { + gchar *result; + if (g_variant_is_of_type (r, G_VARIANT_TYPE ("(s)"))) + { + g_variant_get (r, "(&s)", &result); + can_suspend = g_strcmp0 (result, "yes") == 0; + } + } + else + { + r = do_call_function ("SuspendAllowed", NULL, NULL, &upower_proxy); + if (r && g_variant_is_of_type (r, G_VARIANT_TYPE ("(b)"))) + g_variant_get (r, "(b)", &can_suspend); + } + if (r) + g_variant_unref (r); + + return can_suspend; } /** @@ -73,13 +118,29 @@ lightdm_get_can_suspend (void) * @error: return location for a #GError, or %NULL * * Triggers a system suspend. - * + * * Return value: #TRUE if suspend initiated. **/ gboolean lightdm_suspend (GError **error) { - return upower_call_function ("Suspend", TRUE, error); + GVariant *result; + gboolean suspended; + + result = do_call_function ("Suspend", g_variant_new("(b)", FALSE), error, &login1_proxy); + if (!result) + { + if (error) + g_debug ("Can't suspend using logind; falling back to UPower: %s", (*error)->message); + g_clear_error (error); + result = do_call_function ("Suspend", NULL, error, &upower_proxy); + } + + suspended = result != NULL; + if (result) + g_variant_unref (result); + + return suspended; } /** @@ -92,7 +153,29 @@ lightdm_suspend (GError **error) gboolean lightdm_get_can_hibernate (void) { - return upower_call_function ("HibernateAllowed", FALSE, NULL); + gboolean can_hibernate = FALSE; + GVariant *r; + + r = do_call_function ("CanHibernate", NULL, NULL, &login1_proxy); + if (r) + { + gchar *result; + if (g_variant_is_of_type (r, G_VARIANT_TYPE ("(s)"))) + { + g_variant_get (r, "(&s)", &result); + can_hibernate = g_strcmp0 (result, "yes") == 0; + } + } + else + { + r = do_call_function ("HibernateAllowed", NULL, NULL, &upower_proxy); + if (r && g_variant_is_of_type (r, G_VARIANT_TYPE ("(b)"))) + g_variant_get (r, "(b)", &can_hibernate); + } + if (r) + g_variant_unref (r); + + return can_hibernate; } /** @@ -100,53 +183,32 @@ lightdm_get_can_hibernate (void) * @error: return location for a #GError, or %NULL * * Triggers a system hibernate. - * + * * Return value: #TRUE if hibernate initiated. **/ gboolean lightdm_hibernate (GError **error) { - return upower_call_function ("Hibernate", TRUE, error); -} - -static gboolean -ck_call_function (const gchar *function, gboolean default_result, GError **error) -{ GVariant *result; - gboolean function_result = FALSE; - - if (!ck_proxy) - { - ck_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - "org.freedesktop.ConsoleKit.Manager", - NULL, - error); - if (!ck_proxy) - return FALSE; - } - - result = g_dbus_proxy_call_sync (ck_proxy, - function, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - error); + gboolean hibernated; + result = do_call_function ("Hibernate", g_variant_new("(b)", FALSE), error, &login1_proxy); if (!result) - return default_result; + { + if (error) + g_debug ("Can't hibernate using logind; falling back to UPower: %s", (*error)->message); + g_clear_error (error); + result = do_call_function ("Hibernate", NULL, error, &upower_proxy); + } - if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(b)"))) - g_variant_get (result, "(b)", &function_result); + hibernated = result != NULL; + if (result) + g_variant_unref (result); - g_variant_unref (result); - return function_result; + return hibernated; } + /** * lightdm_get_can_restart: * @@ -157,7 +219,29 @@ ck_call_function (const gchar *function, gboolean lightdm_get_can_restart (void) { - return ck_call_function ("CanRestart", FALSE, NULL); + gboolean can_restart = FALSE; + GVariant *r; + + r = do_call_function ("CanReboot", NULL, NULL, &login1_proxy); + if (r) + { + gchar *result; + if (g_variant_is_of_type (r, G_VARIANT_TYPE ("(s)"))) + { + g_variant_get (r, "(&s)", &result); + can_restart = g_strcmp0 (result, "yes") == 0; + } + } + else + { + r = do_call_function ("CanRestart", NULL, NULL, &ck_proxy); + if (r && g_variant_is_of_type (r, G_VARIANT_TYPE ("(b)"))) + g_variant_get (r, "(b)", &can_restart); + } + if (r) + g_variant_unref (r); + + return can_restart; } /** @@ -171,7 +255,20 @@ lightdm_get_can_restart (void) gboolean lightdm_restart (GError **error) { - return ck_call_function ("Restart", TRUE, error); + GVariant *r; + gboolean restarted; + + r = do_call_function ("Reboot", g_variant_new("(b)", FALSE), error, &login1_proxy); + if (!r) + { + g_clear_error (error); + r = do_call_function ("Restart", NULL, error, &ck_proxy); + } + restarted = r != NULL; + if (r) + g_variant_unref (r); + + return restarted; } /** @@ -184,7 +281,29 @@ lightdm_restart (GError **error) gboolean lightdm_get_can_shutdown (void) { - return ck_call_function ("CanStop", FALSE, NULL); + gboolean can_shutdown = FALSE; + GVariant *r; + + r = do_call_function ("CanPowerOff", NULL, NULL, &login1_proxy); + if (r) + { + gchar *result; + if (g_variant_is_of_type (r, G_VARIANT_TYPE ("(s)"))) + { + g_variant_get (r, "(&s)", &result); + can_shutdown = g_strcmp0 (result, "yes") == 0; + } + } + else + { + r = do_call_function ("CanStop", NULL, NULL, &ck_proxy); + if (r && g_variant_is_of_type (r, G_VARIANT_TYPE ("(b)"))) + g_variant_get (r, "(b)", &can_shutdown); + } + if (r) + g_variant_unref (r); + + return can_shutdown; } /** @@ -198,5 +317,18 @@ lightdm_get_can_shutdown (void) gboolean lightdm_shutdown (GError **error) { - return ck_call_function ("Stop", TRUE, error); + GVariant *r; + gboolean shutdown; + + r = do_call_function ("PowerOff", g_variant_new("(b)", FALSE), error, &login1_proxy); + if (!r) + { + g_clear_error (error); + r = do_call_function ("Stop", NULL, error, &ck_proxy); + } + shutdown = r != NULL; + if (r) + g_variant_unref (r); + + return shutdown; }