Submitted By:            Christopher Gregory <cjg at higgs dot linuxfromscratch dot org>
Date:                    2014-07-31
Initial Package Version: 0.4.9.2
Upstream Status:         Commited
Origin:                  Upstream
Description:             Backport hibernate, suspend, logind dbus fixes to current version.

--- a/lxsession-logout/dbus-interface.c	2013-04-12 23:02:19.000000000 +0200
+++ b/lxsession-logout/dbus-interface.c	2014-08-12 18:35:15.653647205 +0200
@@ -1,21 +1,17 @@
-/**
- * Copyright (c) 2010 LxDE Developers, see the file AUTHORS for details.
+/* Taken from LightDM and modified.
+ * Copyright (C) 2012 Fabrice THIROUX <fabrice.thiroux@free.fr>.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ **** License from former file (power.c) ****
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Copyright (C) 2010-2011 Robert Ancell.
+ * Author: Robert Ancell <robert.ancell@canonical.com>
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option) any
+ * later version. See http://www.gnu.org/copyleft/lgpl.html the full text of the
+ * license.
  */
-
 #include <config.h>
 #include <glib.h>
 #include <string.h>
@@ -24,192 +20,151 @@
 
 /*** Mechanism independent ***/
 
-/* D-Bus context. */
-static struct {
-    int connection_tried : 1;			/* True if connection has been tried */
-    DBusConnection * connection;		/* Handle for connection */
-} dbus_context;
-
-static GDBusProxy *logind_proxy = NULL;
-
-enum { DBUS_TIMEOUT = 60000 };			/* Reply timeout */
-
-/* FORWARDS */
-gboolean dbus_ConsoleKit_CanStop(void);
-gboolean dbus_ConsoleKit_CanRestart(void);
-char * dbus_ConsoleKit_Stop(void);
-char * dbus_ConsoleKit_Restart(void);
-gboolean dbus_UPower_CanSuspend(void);
-gboolean dbus_UPower_CanHibernate(void);
-char * dbus_UPower_Suspend(void);
-char * dbus_UPower_Hibernate(void);
-gboolean dbus_HAL_CanShutdown(void);
-gboolean dbus_HAL_CanReboot(void);
-gboolean dbus_HAL_CanSuspend(void);
-gboolean dbus_HAL_CanHibernate(void);
-char * dbus_HAL_Shutdown(void);
-char * dbus_HAL_Reboot(void);
-char * dbus_HAL_Suspend(void);
-char * dbus_HAL_Hibernate(void);
-char * dbus_LXDE_Logout(void);
-/* End FORWARDS */
-
-/* Connect to the system bus.  Once a connection is made, it is saved for reuse. */
-static DBusConnection * dbus_connect_system(void)
-{
-        DBusError error;
-        dbus_error_init(&error);
-        dbus_context.connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
-        if (dbus_context.connection == NULL)
-        {
-            g_warning(G_STRLOC ": Failed to connect to the system message bus: %s", error.message);
-            dbus_error_free(&error);
-        }
-        dbus_context.connection_tried = TRUE;
-
-    return dbus_context.connection;
-}
-
-static DBusConnection * dbus_connect_session(void)
-{
-        DBusError error;
-        dbus_error_init(&error);
-        dbus_context.connection = dbus_bus_get(DBUS_BUS_SESSION, &error);
-        if (dbus_context.connection == NULL)
-        {
-            g_warning(G_STRLOC ": Failed to connect to the session message bus: %s", error.message);
-            dbus_error_free(&error);
-        }
-        dbus_context.connection_tried = TRUE;
-
-    return dbus_context.connection;
-}
-
-
-/* Send a message. */
-static DBusMessage * dbus_send_message_system(DBusMessage * message, char * * error_text)
-{
-    /* Get a connection handle. */
-    DBusConnection * connection = dbus_connect_system();
-    if (connection == NULL)
-        return FALSE;
-
-    /* Send the message. */
-    DBusError error;
-    dbus_error_init(&error);
-    DBusMessage * reply = dbus_connection_send_with_reply_and_block(connection, message, DBUS_TIMEOUT, &error);
-    dbus_message_unref(message);
-    if (reply == NULL)
+static GDBusProxy *upower_proxy = NULL;
+static GDBusProxy *ck_proxy = NULL;
+static GDBusProxy *systemd_proxy = NULL;
+static GDBusProxy *lightdm_proxy = NULL;
+static GDBusProxy *lxde_proxy = NULL;
+
+
+/*** UPower mechanism ***/
+
+static gboolean
+upower_call_function (const gchar *function, gboolean default_result, GError **error)
+{
+    GVariant *result;
+    gboolean function_result = FALSE;
+
+    if (!upower_proxy)
     {
-        if ((error.name == NULL) || (strcmp(error.name, DBUS_ERROR_NO_REPLY) != 0))
-        {
-            if (error_text != NULL)
-                *error_text = g_strdup(error.message);
-            g_warning(G_STRLOC ": DBUS: %s", error.message);
-        }
-        dbus_error_free(&error);
+        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;
     }
-    return reply;
+
+    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);
+
+    g_variant_unref (result);
+    return function_result;
 }
 
-/* Send a message. */
-static DBusMessage * dbus_send_message_session(DBusMessage * message, char * * error_text)
+gboolean
+dbus_UPower_CanSuspend (void)
 {
-    /* Get a connection handle. */
-    DBusConnection * connection = dbus_connect_session();
-    if (connection == NULL)
-        return FALSE;
-
-    /* Send the message. */
-    DBusError error;
-    dbus_error_init(&error);
-    DBusMessage * reply = dbus_connection_send_with_reply_and_block(connection, message, DBUS_TIMEOUT, &error);
-    dbus_message_unref(message);
-    if (reply == NULL)
-    {
-        if ((error.name == NULL) || (strcmp(error.name, DBUS_ERROR_NO_REPLY) != 0))
-        {
-            if (error_text != NULL)
-                *error_text = g_strdup(error.message);
-            g_warning(G_STRLOC ": DBUS: %s", error.message);
-        }
-        dbus_error_free(&error);
-    }
-    return reply;
+    return upower_call_function ("SuspendAllowed", FALSE, NULL);
 }
 
-/* Read a result for a method that returns void. */
-static char * dbus_read_result_void(DBusMessage * reply)
+gboolean
+dbus_UPower_Suspend (GError **error)
 {
-    if (reply != NULL)
-        dbus_message_unref(reply);
+    return upower_call_function ("Suspend", TRUE, error);
+}
 
-    /* No result.  Assume success. */
-    return NULL;
+gboolean
+dbus_UPower_CanHibernate (void)
+{
+    return upower_call_function ("HibernateAllowed", FALSE, NULL);
+}
+
+gboolean
+dbus_UPower_Hibernate (GError **error)
+{
+    return upower_call_function ("Hibernate", TRUE, error);
 }
 
-/* Read a result for a method that returns boolean. */
-static gboolean dbus_read_result_boolean(DBusMessage * reply)
+/*** ConsoleKit mechanism ***/
+
+static gboolean
+ck_call_function (const gchar *function, gboolean default_result, GError **error)
 {
-    gboolean result = FALSE;
-    if (reply != NULL)
+    GVariant *result;
+    gboolean function_result = FALSE;
+
+    if (!ck_proxy)
     {
-        /* Get the boolean result. */
-        DBusError error;
-        dbus_error_init(&error);
-        dbus_bool_t status = dbus_message_get_args(
-            reply,
-            &error,
-            DBUS_TYPE_BOOLEAN, &result,
-            DBUS_TYPE_INVALID);
-        dbus_message_unref(reply);
-        if ( ! status)
-        {
-            g_warning(G_STRLOC ": DBUS: %s", error.message);
-            dbus_error_free(&error);
+        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;
-        }
     }
-    return result;
+
+    result = g_dbus_proxy_call_sync (ck_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);
+
+    g_variant_unref (result);
+    return function_result;
 }
 
-/* Read a result for a method that returns string. */
-static char * dbus_read_result_string(DBusMessage * reply)
+gboolean
+dbus_ConsoleKit_CanRestart (void)
 {
-    char * result = FALSE;
-    if (reply != NULL)
-    {
-        /* Get the boolean result. */
-        DBusError error;
-        dbus_error_init(&error);
-        dbus_bool_t status = dbus_message_get_args(
-            reply,
-            &error,
-            DBUS_TYPE_STRING, &result,
-            DBUS_TYPE_INVALID);
-        dbus_message_unref(reply);
-        if ( ! status)
-        {
-            g_warning(G_STRLOC ": DBUS: %s", error.message);
-            dbus_error_free(&error);
-            return NULL;
-        }
-    }
-    return result;
+    return ck_call_function ("CanRestart", FALSE, NULL);
 }
 
-/*** logind mechanism ***/
+gboolean
+dbus_ConsoleKit_Restart (GError **error)
+{
+    return ck_call_function ("Restart", TRUE, error);
+}
+
+gboolean
+dbus_ConsoleKit_CanStop (void)
+{
+    return ck_call_function ("CanStop", FALSE, NULL);
+}
+
+gboolean
+dbus_ConsoleKit_Stop (GError **error)
+{
+    return ck_call_function ("Stop", TRUE, error);
+}
+
+/*** Systemd mechanism ***/
 
 static gboolean
-logind_query (const gchar *function, gboolean default_result, GError **error)
+systemd_query (const gchar *function, gboolean default_result, GError **error)
 {
     GVariant *result;
     gboolean function_result = FALSE;
     const gchar *str;
 
-    if (!logind_proxy)
+    if (!systemd_proxy)
     {
-        logind_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+        systemd_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
                                                       G_DBUS_PROXY_FLAGS_NONE,
                                                       NULL,
                                                       "org.freedesktop.login1",
@@ -217,11 +172,11 @@
                                                       "org.freedesktop.login1.Manager",
                                                       NULL,
                                                       error);
-        if (!logind_proxy)
+        if (!systemd_proxy)
             return FALSE;
     }
 
-    result = g_dbus_proxy_call_sync (logind_proxy,
+    result = g_dbus_proxy_call_sync (systemd_proxy,
                                      function,
                                      NULL,
                                      G_DBUS_CALL_FLAGS_NONE,
@@ -245,13 +200,13 @@
 }
 
 static void
-logind_call_function (const gchar *function, gboolean value, GError **error)
+systemd_call_function (const gchar *function, gboolean value, GError **error)
 {
     GVariant *result;
 
-    if (!logind_proxy)
+    if (!systemd_proxy)
     {
-        logind_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+        systemd_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
                                                       G_DBUS_PROXY_FLAGS_NONE,
                                                       NULL,
                                                       "org.freedesktop.login1",
@@ -259,11 +214,11 @@
                                                       "org.freedesktop.login1.Manager",
                                                       NULL,
                                                       error);
-        if (!logind_proxy)
+        if (!systemd_proxy)
             return;
     }
 
-    result = g_dbus_proxy_call_sync (logind_proxy,
+    result = g_dbus_proxy_call_sync (systemd_proxy,
                                      function,
                                      g_variant_new ("(b)", value),
                                      G_DBUS_CALL_FLAGS_NONE,
@@ -275,367 +230,139 @@
 }
 
 gboolean
-dbus_logind_CanPowerOff (void)
+dbus_systemd_CanPowerOff (void)
 {
-    return logind_query ("CanPowerOff", FALSE, NULL);
+    return systemd_query ("CanPowerOff", FALSE, NULL);
 }
 
 void
-dbus_logind_PowerOff (GError **error)
+dbus_systemd_PowerOff (GError **error)
 {
-    logind_call_function ("PowerOff", TRUE, error);
+    systemd_call_function ("PowerOff", TRUE, error);
 }
 
 gboolean
-dbus_logind_CanReboot (void)
+dbus_systemd_CanReboot (void)
 {
-    return logind_query ("CanReboot", FALSE, NULL);
+    return systemd_query ("CanReboot", FALSE, NULL);
 }
 
 void
-dbus_logind_Reboot (GError **error)
+dbus_systemd_Reboot (GError **error)
 {
-    logind_call_function ("Reboot", TRUE, error);
+    systemd_call_function ("Reboot", TRUE, error);
 }
 
 gboolean
-dbus_logind_CanSuspend (void)
+dbus_systemd_CanSuspend (void)
 {
-    return logind_query ("CanSuspend", FALSE, NULL);
+    return systemd_query ("CanSuspend", FALSE, NULL);
 }
 
 void
-dbus_logind_Suspend (GError **error)
+dbus_systemd_Suspend (GError **error)
 {
-    logind_call_function ("Suspend", TRUE, error);
+    systemd_call_function ("Suspend", TRUE, error);
 }
 
 gboolean
-dbus_logind_CanHibernate (void)
+dbus_systemd_CanHibernate (void)
 {
-    return logind_query ("CanHibernate", FALSE, NULL);
+    return systemd_query ("CanHibernate", FALSE, NULL);
 }
 
 void
-dbus_logind_Hibernate (GError **error)
+dbus_systemd_Hibernate (GError **error)
 {
-    logind_call_function ("Hibernate", TRUE, error);
+    systemd_call_function ("Hibernate", TRUE, error);
 }
 
-/*** ConsoleKit mechanism ***/
-
-/* Formulate a message to the ConsoleKit Manager interface. */
-static DBusMessage * dbus_ConsoleKit_formulate_message(const char * const query)
-{
-    return dbus_message_new_method_call(
-        "org.freedesktop.ConsoleKit",
-        "/org/freedesktop/ConsoleKit/Manager",
-        "org.freedesktop.ConsoleKit.Manager",
-        query);
-}
-
-/* Send a specified message to the ConsoleKit interface and process a boolean result. */
-static gboolean dbus_ConsoleKit_query(const char * const query)
-{
-    return dbus_read_result_boolean(dbus_send_message_system(dbus_ConsoleKit_formulate_message(query), NULL));
-}
-
-/* Send a specified message to the ConsoleKit interface and process a void result. */
-static char * dbus_ConsoleKit_command(const char * const command)
-{
-    char * error = NULL;
-    dbus_read_result_void(dbus_send_message_system(dbus_ConsoleKit_formulate_message(command), &error));
-    return error;
-}
-
-/* Invoke the CanStop method on ConsoleKit. */
-gboolean dbus_ConsoleKit_CanStop(void)
-{
-    return dbus_ConsoleKit_query("CanStop");
-}
-
-/* Invoke the CanRestart method on ConsoleKit. */
-gboolean dbus_ConsoleKit_CanRestart(void)
-{
-    return dbus_ConsoleKit_query("CanRestart");
-}
-
-/* Invoke the Stop method on ConsoleKit. */
-char * dbus_ConsoleKit_Stop(void)
-{
-    return dbus_ConsoleKit_command("Stop");
-}
+/*** Lightdm mechanism ***/
 
-/* Invoke the Restart method on ConsoleKit. */
-char * dbus_ConsoleKit_Restart(void)
+static gboolean
+lightdm_call_function (const gchar *function, gboolean default_result, GError **error)
 {
-    return dbus_ConsoleKit_command("Restart");
-}
-
-/*** UPower mechanism ***/
+    GVariant *result;
+    gboolean function_result = FALSE;
 
-/* Formulate a message to the UPower interface. */
-static DBusMessage * dbus_UPower_formulate_command(const char * const command)
-{
-    return dbus_message_new_method_call(
-        "org.freedesktop.UPower",
-	"/org/freedesktop/UPower",
-	"org.freedesktop.UPower",
-        command);
-}
-
-/* Send a specified message to the UPower interface and process a boolean result. */
-static gboolean dbus_UPower_query(const char * const query)
-{
-    /* Formulate a message to the Properties interface. */
-    DBusMessage * message = dbus_message_new_method_call(
-        "org.freedesktop.UPower",
-	"/org/freedesktop/UPower",
-	"org.freedesktop.DBus.Properties",
-        "Get");
-    const char * const interface_name = "org.freedesktop.UPower";
-    dbus_message_append_args(message,
-        DBUS_TYPE_STRING, &interface_name,
-        DBUS_TYPE_STRING, &query,
-        DBUS_TYPE_INVALID);
-
-    /* Send the message. */
-    DBusMessage * reply = dbus_send_message_system(message, NULL);
-    if (reply == NULL)
-	return FALSE;
-
-    /* The return type is VARIANT expected to contain BOOLEAN. */
-    gboolean result = FALSE;
-    DBusMessageIter iter;
-    DBusMessageIter inner;
-    dbus_message_iter_init(reply, &iter);
-    if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_VARIANT)
+    if (!lightdm_proxy)
     {
-        dbus_message_iter_recurse(&iter, &inner);
-        if (dbus_message_iter_get_arg_type(&inner) == DBUS_TYPE_BOOLEAN)
-            dbus_message_iter_get_basic(&inner, &result);
+        lightdm_proxy = g_dbus_proxy_new_for_bus_sync ( G_BUS_TYPE_SYSTEM,
+                                                        G_DBUS_PROXY_FLAGS_NONE,
+                                                        NULL,
+                                                        "org.freedesktop.DisplayManager",
+                                                        g_getenv ("XDG_SEAT_PATH"),
+                                                        "org.freedesktop.DisplayManager.Seat",
+                                                        NULL,
+                                                        error);
+        if (!lightdm_proxy)
+            return FALSE;
     }
-    dbus_message_unref(reply);
-    return result;
-}
-
-/* Send a specified message to the UPower interface and process a void result. */
-static char * dbus_UPower_command(const char * const command)
-{
-    char * error = NULL;
-    dbus_read_result_void(dbus_send_message_system(dbus_UPower_formulate_command(command), &error));
-    return error;
-}
-
-/* Read the can-suspend property of UPower. */
-gboolean dbus_UPower_CanSuspend(void)
-{
-    return dbus_UPower_query("CanSuspend");
-}
-
-/* Read the can-hibernate property of UPower. */
-gboolean dbus_UPower_CanHibernate(void)
-{
-    return dbus_UPower_query("CanHibernate");
-}
-
-/* Invoke the Suspend method on UPower. */
-char * dbus_UPower_Suspend(void)
-{
-    return dbus_UPower_command("Suspend");
-}
 
-/* Invoke the Hibernate method on UPower. */
-char * dbus_UPower_Hibernate(void)
-{
-    return dbus_UPower_command("Hibernate");
-}
-
-/*** HAL mechanism ***/
-
-/* Formulate a message to the HAL SystemPowerManagement interface. */
-static DBusMessage * dbus_HAL_formulate_message(const char * const query)
-{
-    return dbus_message_new_method_call(
-        "org.freedesktop.Hal",
-	"/org/freedesktop/Hal/devices/computer",
-	"org.freedesktop.Hal.Device.SystemPowerManagement",
-        query);
-}
-
-/* Formulate a message to the HAL SystemPowerManagement interface to query a property. */
-static DBusMessage * dbus_HAL_formulate_property_query(const char * const method, const char * const property)
-{
-    DBusMessage * message = dbus_message_new_method_call(
-        "org.freedesktop.Hal",
-	"/org/freedesktop/Hal/devices/computer",
-	"org.freedesktop.Hal.Device",
-        method);
-    if (message != NULL)
-        dbus_message_append_args(message, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID);
-    return message;
-}
+    result = g_dbus_proxy_call_sync (lightdm_proxy,
+                                     function,
+                                     NULL,
+                                     G_DBUS_CALL_FLAGS_NONE,
+                                     -1,
+                                     NULL,
+                                     error);
+    if (!result)
+        return default_result;
 
-/* Formulate a message to the HAL SystemPowerManagement interface to query a boolean property. */
-static DBusMessage * dbus_HAL_formulate_boolean_property_query(const char * const property)
-{
-    return dbus_HAL_formulate_property_query("GetPropertyBoolean", property);
-}
+    if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(b)")))
+        g_variant_get (result, "(b)", &function_result);
 
-/* Formulate a message to the HAL SystemPowerManagement interface to query a string property. */
-static DBusMessage * dbus_HAL_formulate_string_property_query(const char * const property)
-{
-    return dbus_HAL_formulate_property_query("GetPropertyString", property);
+    g_variant_unref (result);
+    return function_result;
 }
 
-/* Send a specified property query to the HAL interface and process whether the result exists. */
-static gboolean dbus_HAL_string_exists_query(const char * const property)
+gboolean
+dbus_Lightdm_SwitchToGreeter (GError **error)
 {
-    DBusMessage * message = dbus_HAL_formulate_string_property_query(property);
-    if (message == NULL)
-        return FALSE;
-    DBusMessage * reply = dbus_send_message_system(message, NULL);
-    if (reply == NULL)
-	return FALSE;
-    dbus_message_unref(reply);
-    return TRUE;
+    return lightdm_call_function ("SwitchToGreeter", TRUE, error);
 }
 
-/* Send a specified property query to the HAL interface and process a boolean result. */
-static gboolean dbus_HAL_boolean_query(const char * const property)
-{
-    return dbus_read_result_boolean(dbus_send_message_system(dbus_HAL_formulate_boolean_property_query(property), NULL));
-}
+/*** LXDE mechanism ***/
 
-/* Send a specified message to the HAL interface and process a void result. */
-static char * dbus_HAL_command(const char * const command)
+static gboolean
+lxde_call_function (const gchar *function, gboolean default_result, GError **error)
 {
-    /* Formulate the message. */
-    DBusMessage * message = dbus_HAL_formulate_message(command);
-    if (message == NULL)
-        return NULL;
+    GVariant *result;
+    gboolean function_result = FALSE;
 
-    /* Suspend has an argument. */
-    if (strcmp(command, "Suspend") == 0)
+    if (!lxde_proxy)
     {
-        dbus_int32_t suspend_arg = 0;
-        dbus_message_append_args(message, DBUS_TYPE_INT32, &suspend_arg, DBUS_TYPE_INVALID);
+        lxde_proxy = g_dbus_proxy_new_for_bus_sync (    G_BUS_TYPE_SYSTEM,
+                                                        G_DBUS_PROXY_FLAGS_NONE,
+                                                        NULL,
+                                                        "org.lxde.SessionManager",
+                                                        "/org/lxde/SessionManager",
+                                                        "org.lxde.SessionManager",
+                                                        NULL,
+                                                        error);
+        if (!lxde_proxy)
+            return FALSE;
     }
 
-    /* Send the message and wait for a reply. */
-    char * error = NULL;
-    dbus_read_result_void(dbus_send_message_system(message, &error));
-    return error;
-}
-
-/* Read the can-shutdown property of HAL. */
-gboolean dbus_HAL_CanShutdown(void)
-{
-    return dbus_HAL_string_exists_query("power_management.type");
-}
-
-/* Read the can-reboot property of HAL. */
-gboolean dbus_HAL_CanReboot(void)
-{
-    return dbus_HAL_string_exists_query("power_management.type");
-}
-
-/* Read the can-suspend property of HAL. */
-gboolean dbus_HAL_CanSuspend(void)
-{
-    return dbus_HAL_boolean_query("power_management.can_suspend");
-}
-
-/* Read the can-hibernate property of HAL. */
-gboolean dbus_HAL_CanHibernate(void)
-{
-    return dbus_HAL_boolean_query("power_management.can_hibernate");
-}
-
-/* Invoke the Shutdown method on HAL. */
-char * dbus_HAL_Shutdown(void)
-{
-    return dbus_HAL_command("Shutdown");
-}
-
-/* Invoke the Reboot method on HAL. */
-char * dbus_HAL_Reboot(void)
-{
-    return dbus_HAL_command("Reboot");
-}
-
-/* Invoke the Suspend method on HAL. */
-char * dbus_HAL_Suspend(void)
-{
-    return dbus_HAL_command("Suspend");
-}
-
-/* Invoke the Hibernate method on HAL. */
-char * dbus_HAL_Hibernate(void)
-{
-    return dbus_HAL_command("Hibernate");
-}
-
-/*** LXDE mechanism ***/
-
-/* Formulate a message to the LXDE Session Manager interface. */
-static DBusMessage * dbus_LXDE_formulate_message(const char * const query)
-{
-    return dbus_message_new_method_call(
-        "org.lxde.SessionManager",
-        "/org/lxde/SessionManager",
-        "org.lxde.SessionManager",
-        query);
-}
-
-/* Send a specified message to the LXDE interface and process a boolean result. */
-static gboolean dbus_LXDE_query(const char * const query)
-{
-    return dbus_read_result_boolean(dbus_send_message_session(dbus_LXDE_formulate_message(query), NULL));
-}
-
-/* Send a specified message to the LXDE interface and process a void result. */
-static char * dbus_LXDE_command(const char * const command)
-{
-    char * error = NULL;
-    dbus_read_result_void(dbus_send_message_session(dbus_LXDE_formulate_message(command), &error));
-    return error;
-}
-
-/* Invoke the Logout method on LXDE. */
-char * dbus_LXDE_Logout(void)
-{
-    return dbus_LXDE_command("Logout");
-}
-
-/*** Lightdm mechanism ***/
-
-/* Formulate a message to the Lightdm interface. */
-static DBusMessage * dbus_Lightdm_formulate_message(const char * const query)
-{
-    return dbus_message_new_method_call(
-                "org.freedesktop.DisplayManager",
-                g_getenv ("XDG_SEAT_PATH"),
-                "org.freedesktop.DisplayManager.Seat",
-                query);
-}
+    result = g_dbus_proxy_call_sync (lxde_proxy,
+                                     function,
+                                     NULL,
+                                     G_DBUS_CALL_FLAGS_NONE,
+                                     -1,
+                                     NULL,
+                                     error);
+    if (!result)
+        return default_result;
 
-/* Send a specified message to the Lightdm interface and process a boolean result. */
-static gboolean dbus_Lightdm_query(const char * const query)
-{
-    return dbus_read_result_boolean(dbus_send_message_session(dbus_Lightdm_formulate_message(query), NULL));
-}
+    if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(b)")))
+        g_variant_get (result, "(b)", &function_result);
 
-/* Send a specified message to the Lightdm interface and process a void result. */
-static char * dbus_Lightdm_command(const char * const command)
-{
-    char * error = NULL;
-    dbus_read_result_void(dbus_send_message_session(dbus_Lightdm_formulate_message(command), &error));
-    return error;
+    g_variant_unref (result);
+    return function_result;
 }
 
-/* Invoke the Logout method on LXDE. */
-char * dbus_Lightdm_SwitchToGreeter(void)
+gboolean
+dbus_LXDE_Logout (GError **error)
 {
-    return dbus_Lightdm_command("SwitchToGreeter");
+    return lxde_call_function ("Restart", TRUE, error);
 }
--- a/lxsession-logout/dbus-interface.h	2013-03-10 12:48:25.000000000 +0100
+++ b/lxsession-logout/dbus-interface.h	2014-08-12 18:35:15.654647223 +0200
@@ -21,41 +21,32 @@
 
 #include <glib.h>
 
-/* Interface to logind for shutdown, reboot, suspend and hibernate. */
-extern gboolean dbus_logind_CanPowerOff(void);
-extern gboolean dbus_logind_CanReboot(void);
-extern gboolean dbus_logind_CanSuspend(void);
-extern gboolean dbus_logind_CanHibernate(void);
-extern char * dbus_logind_PowerOff(void);
-extern char * dbus_logind_Reboot(void);
-extern char * dbus_logind_Suspend(void);
-extern char * dbus_logind_Hibernate(void);
-
 /* Interface to ConsoleKit for shutdown and reboot. */
 extern gboolean dbus_ConsoleKit_CanStop(void);
 extern gboolean dbus_ConsoleKit_CanRestart(void);
-extern char * dbus_ConsoleKit_Stop(void);
-extern char * dbus_ConsoleKit_Restart(void);
+extern gboolean dbus_ConsoleKit_Stop(GError **);
+extern gboolean dbus_ConsoleKit_Restart(GError **);
 
 /* Interface to UPower for suspend and hibernate. */
 extern gboolean dbus_UPower_CanSuspend(void);
 extern gboolean dbus_UPower_CanHibernate(void);
-extern char * dbus_UPower_Suspend(void);
-extern char * dbus_UPower_Hibernate(void);
+extern gboolean dbus_UPower_Suspend(GError **);
+extern gboolean dbus_UPower_Hibernate(GError **);
 
-/* Interface to HAL for shutdown, reboot, suspend, and hibernate.
- * HAL is being replaced by the above two mechanisms; this support is legacy. */
-extern gboolean dbus_HAL_CanShutdown(void);
-extern gboolean dbus_HAL_CanReboot(void);
-extern gboolean dbus_HAL_CanSuspend(void);
-extern gboolean dbus_HAL_CanHibernate(void);
-extern char * dbus_HAL_Shutdown(void);
-extern char * dbus_HAL_Reboot(void);
-extern char * dbus_HAL_Suspend(void);
-extern char * dbus_HAL_Hibernate(void);
+/* Interface to systemd for suspend, hibernate, shutdown and reboot. */
+extern gboolean dbus_systemd_CanPowerOff(void);
+extern gboolean dbus_systemd_CanReboot(void);
+extern gboolean dbus_systemd_CanSuspend(void);
+extern gboolean dbus_systemd_CanHibernate(void);
+extern void dbus_systemd_PowerOff(GError **);
+extern void dbus_systemd_Reboot(GError **);
+extern void dbus_systemd_Suspend(GError **);
+extern void dbus_systemd_Hibernate(GError **);
 
-extern char * dbus_LXDE_Logout(void);
+/* Interface to lightdm for switch user. */
+extern gboolean dbus_Lightdm_SwitchToGreeter (GError **error);
 
-extern char * dbus_Lightdm_SwitchToGreeter();
+/* Interface to lxde for logout. */
+extern gboolean dbus_LXDE_Logout (GError **error);
 
 #endif
--- a/lxsession-logout/lxsession-logout.c	2013-05-31 21:38:58.000000000 +0200
+++ b/lxsession-logout/lxsession-logout.c	2014-08-12 18:35:15.654647223 +0200
@@ -61,18 +61,14 @@
     int hibernate_available : 1;	/* Hibernate is available */
     int switch_user_available : 1;	/* Switch User is available */
 
-    int shutdown_logind : 1;		/* Shutdown is available via logind */
-    int reboot_logind : 1;		/* Reboot is available via logind */
-    int suspend_logind : 1;		/* Suspend is available via logind */
-    int hibernate_logind : 1;		/* Hibernate is available via logind */
+    int shutdown_systemd : 1;		/* Shutdown is available via systemd */
+    int reboot_systemd : 1;		/* Reboot is available via systemd */
+    int suspend_systemd : 1;		/* Suspend is available via systemd */
+    int hibernate_systemd : 1;		/* Hibernate is available via systemd */
     int shutdown_ConsoleKit : 1;	/* Shutdown is available via ConsoleKit */
     int reboot_ConsoleKit : 1;		/* Reboot is available via ConsoleKit */
     int suspend_UPower : 1;		/* Suspend is available via UPower */
     int hibernate_UPower : 1;		/* Hibernate is available via UPower */
-    int shutdown_HAL : 1;		/* Shutdown is available via HAL */
-    int reboot_HAL : 1;			/* Reboot is available via HAL */
-    int suspend_HAL : 1;		/* Suspend is available via HAL */
-    int hibernate_HAL : 1;		/* Hibernate is available via HAL */
     int switch_user_GDM : 1;		/* Switch User is available via GDM */
     int switch_user_LIGHTDM : 1;	/* Switch User is available via GDM */
     int switch_user_KDM : 1;		/* Switch User is available via LIGHTDM */
@@ -212,7 +208,7 @@
 /* Handler for "clicked" signal on Shutdown button. */
 static void shutdown_clicked(GtkButton * button, HandlerContext * handler_context)
 {
-    char * error_result = NULL;
+    GError *err = NULL;
     gtk_label_set_text(GTK_LABEL(handler_context->error_label), NULL);
 
     if (handler_context->ltsp)
@@ -224,21 +220,25 @@
         }
     }
     else if (handler_context->shutdown_ConsoleKit)
-        error_result = dbus_ConsoleKit_Stop();
-    else if (handler_context->shutdown_logind)
-        error_result = dbus_logind_PowerOff();
-    else if (handler_context->shutdown_HAL)
-        error_result = dbus_HAL_Shutdown();
-
-    if (error_result != NULL)
-        gtk_label_set_text(GTK_LABEL(handler_context->error_label), error_result);
-        else gtk_main_quit();
+        dbus_ConsoleKit_Stop(&err);
+    else if (handler_context->shutdown_systemd)
+        dbus_systemd_PowerOff(&err);
+
+	if (err)
+	{
+		gtk_label_set_text(GTK_LABEL(handler_context->error_label), err->message);
+		g_error_free (err);
+	}
+	else
+    {
+        gtk_main_quit();
+    }
 }
 
 /* Handler for "clicked" signal on Reboot button. */
 static void reboot_clicked(GtkButton * button, HandlerContext * handler_context)
 {
-    char * error_result = NULL;
+    GError *err = NULL;
     gtk_label_set_text(GTK_LABEL(handler_context->error_label), NULL);
 
     if (handler_context->ltsp)
@@ -250,58 +250,71 @@
         }
     }
     else if (handler_context->reboot_ConsoleKit)
-        error_result = dbus_ConsoleKit_Restart();
-    else if (handler_context->reboot_logind)
-        error_result = dbus_logind_Reboot();
-    else if (handler_context->reboot_HAL)
-        error_result = dbus_HAL_Reboot();
-
-    if (error_result != NULL)
-        gtk_label_set_text(GTK_LABEL(handler_context->error_label), error_result);
-        else gtk_main_quit();
+        dbus_ConsoleKit_Restart(&err);
+    else if (handler_context->reboot_systemd)
+        dbus_systemd_Reboot(&err);
+
+	if (err)
+	{
+		gtk_label_set_text(GTK_LABEL(handler_context->error_label), err->message);
+		g_error_free (err);
+	}
+	else
+    {
+        gtk_main_quit();
+    }
 }
 
 /* Handler for "clicked" signal on Suspend button. */
 static void suspend_clicked(GtkButton * button, HandlerContext * handler_context)
 {
-    char * error_result = NULL;
+    GError *err = NULL;
     gtk_label_set_text(GTK_LABEL(handler_context->error_label), NULL);
 
     lock_screen();
     if (handler_context->suspend_UPower)
-        error_result = dbus_UPower_Suspend();
-    else if (handler_context->suspend_logind)
-        error_result = dbus_logind_Suspend();
-    else if (handler_context->suspend_HAL)
-        error_result = dbus_HAL_Suspend();
-
-    if (error_result != NULL)
-        gtk_label_set_text(GTK_LABEL(handler_context->error_label), error_result);
-        else gtk_main_quit();
+        dbus_UPower_Suspend(&err);
+    else if (handler_context->suspend_systemd)
+        dbus_systemd_Suspend(&err);
+
+	if (err)
+	{
+		gtk_label_set_text(GTK_LABEL(handler_context->error_label), err->message);
+		g_error_free (err);
+	}
+	else
+    {
+        gtk_main_quit();
+    }
 }
 
 /* Handler for "clicked" signal on Hibernate button. */
 static void hibernate_clicked(GtkButton * button, HandlerContext * handler_context)
 {
-    char * error_result = NULL;
+    GError *err = NULL;
     gtk_label_set_text(GTK_LABEL(handler_context->error_label), NULL);
 
     lock_screen();
     if (handler_context->hibernate_UPower)
-        error_result = dbus_UPower_Hibernate();
-    else if (handler_context->hibernate_logind)
-        error_result = dbus_logind_Hibernate();
-    else if (handler_context->hibernate_HAL)
-        error_result = dbus_HAL_Hibernate();
-
-    if (error_result != NULL)
-        gtk_label_set_text(GTK_LABEL(handler_context->error_label), error_result);
-        else gtk_main_quit();
+        dbus_UPower_Hibernate(&err);
+    else if (handler_context->hibernate_systemd)
+        dbus_systemd_Hibernate(&err);
+
+	if (err)
+	{
+		gtk_label_set_text(GTK_LABEL(handler_context->error_label), err->message);
+		g_error_free (err);
+	}
+	else
+    {
+        gtk_main_quit();
+    }
 }
 
 /* Handler for "clicked" signal on Switch User button. */
 static void switch_user_clicked(GtkButton * button, HandlerContext * handler_context)
 {
+    GError *err = NULL;
     gtk_label_set_text(GTK_LABEL(handler_context->error_label), NULL);
 
     lock_screen();
@@ -310,11 +323,19 @@
     else if (handler_context->switch_user_KDM)
         g_spawn_command_line_sync("kdmctl reserve", NULL, NULL, NULL, NULL);
     else if (handler_context->switch_user_LIGHTDM)
-        dbus_Lightdm_SwitchToGreeter();
+        dbus_Lightdm_SwitchToGreeter(&err);
     else if(handler_context->switch_user_LXDM)
         g_spawn_command_line_sync("lxdm-binary -c USER_SWITCH", NULL, NULL, NULL, NULL);
 
-    gtk_main_quit();
+	if (err)
+	{
+		gtk_label_set_text(GTK_LABEL(handler_context->error_label), err->message);
+		g_error_free (err);
+	}
+	else
+    {
+        gtk_main_quit();
+    }
 }
 
 /* Handler for "clicked" signal on Lock button. */
@@ -449,26 +470,26 @@
     const char * p = g_getenv("_LXSESSION_PID");
     if (p != NULL) handler_context.lxsession_pid = atoi(p);
 
-    /* Initialize capabilities of the logind mechanism. */
-    if (dbus_logind_CanPowerOff())
+    /* Initialize capabilities of the systemd mechanism. */
+    if (dbus_systemd_CanPowerOff())
     {
         handler_context.shutdown_available = TRUE;
-        handler_context.shutdown_logind = TRUE;
+        handler_context.shutdown_systemd = TRUE;
     }
-    if (dbus_logind_CanReboot())
+    if (dbus_systemd_CanReboot())
     {
         handler_context.reboot_available = TRUE;
-        handler_context.reboot_logind = TRUE;
+        handler_context.reboot_systemd = TRUE;
     }
-    if (dbus_logind_CanSuspend())
+    if (dbus_systemd_CanSuspend())
     {
         handler_context.suspend_available = TRUE;
-        handler_context.suspend_logind = TRUE;
+        handler_context.suspend_systemd = TRUE;
     }
-    if (dbus_logind_CanHibernate())
+    if (dbus_systemd_CanHibernate())
     {
         handler_context.hibernate_available = TRUE;
-        handler_context.hibernate_logind = TRUE;
+        handler_context.hibernate_systemd = TRUE;
     }
 
     /* Initialize capabilities of the ConsoleKit mechanism. */
@@ -495,28 +516,6 @@
         handler_context.hibernate_UPower = TRUE;
     }
 
-    /* Initialize capabilities of the HAL mechanism. */
-    if (!handler_context.shutdown_available && dbus_HAL_CanShutdown())
-    {
-        handler_context.shutdown_available = TRUE;
-        handler_context.shutdown_HAL = TRUE;
-    }
-    if (!handler_context.reboot_available && dbus_HAL_CanReboot())
-    {
-        handler_context.reboot_available = TRUE;
-        handler_context.reboot_HAL = TRUE;
-    }
-    if (!handler_context.suspend_available && dbus_HAL_CanSuspend())
-    {
-        handler_context.suspend_available = TRUE;
-        handler_context.suspend_HAL = TRUE;
-    }
-    if (!handler_context.hibernate_available && dbus_HAL_CanHibernate())
-    {
-        handler_context.hibernate_available = TRUE;
-        handler_context.hibernate_HAL = TRUE;
-    }
-
     /* If we are under GDM, its "Switch User" is available. */
     if (verify_running("gdm", "gdmflexiserver"))
     {
@@ -664,20 +663,23 @@
         if (session_name == NULL)
             session_name = "LXDE";
 
-        const gchar *command_line = "lsb_release -r -s";
         gchar *output = NULL;
-        GError *error;
 
-        if (!g_spawn_command_line_sync( command_line,
-                                        &output,
-                                        NULL,
-                                        NULL,
-                                        &error))
+        if (g_find_program_in_path("lsb_release"))
         {
+            const gchar *command_line = "lsb_release -r -s";
+            GError *error;
+            if (!g_spawn_command_line_sync( command_line,
+                                            &output,
+                                            NULL,
+                                            NULL,
+                                            &error))
+            {
 
-            fprintf (stderr, "Error: %s\n", error->message);
-            g_error_free (error);
+                fprintf (stderr, "Error: %s\n", error->message);
+                g_error_free (error);
 
+            }
         }
 
         if (output == NULL)
