[Xfce4-commits] <xfce4-session:master> Directly use upower for suspend/hibernate.

Nick Schermer noreply at xfce.org
Sat Mar 24 22:50:22 CET 2012


Updating branch refs/heads/master
         to e752a3e68afe5b9129fe558aa7a5205fde7a0fac (commit)
       from 3419125796cd4ed3460b0e4c02c18b3fe19ef01f (commit)

commit e752a3e68afe5b9129fe558aa7a5205fde7a0fac
Author: Nick Schermer <nick at xfce.org>
Date:   Sat Mar 24 21:46:32 2012 +0100

    Directly use upower for suspend/hibernate.
    
    Working with Xfpm is too much work to get right for 4.10,
    so readd the upower dbus communication.

 xfce4-session-logout/main.c         |   78 +++-----
 xfce4-session/Makefile.am           |    4 +-
 xfce4-session/xfsm-consolekit.c     |    3 +
 xfce4-session/xfsm-consolekit.h     |    6 +-
 xfce4-session/xfsm-logout-dialog.c  |   62 ++++---
 xfce4-session/xfsm-manager-dbus.xml |   34 +++-
 xfce4-session/xfsm-manager.c        |   65 ++++++
 xfce4-session/xfsm-shutdown.c       |  101 +--------
 xfce4-session/xfsm-shutdown.h       |    2 +
 xfce4-session/xfsm-upower.c         |  381 +++++++++++++++++++++++++++++++++++
 xfce4-session/xfsm-upower.h         |   54 +++++
 11 files changed, 623 insertions(+), 167 deletions(-)

diff --git a/xfce4-session-logout/main.c b/xfce4-session-logout/main.c
index 9619be4..1bc73cd 100644
--- a/xfce4-session-logout/main.c
+++ b/xfce4-session-logout/main.c
@@ -139,56 +139,42 @@ main (int argc, char **argv)
     }
 
   /* create messsage */
-  if (opt_suspend || opt_hibernate)
+  proxy = dbus_g_proxy_new_for_name_owner (conn,
+                                           "org.xfce.SessionManager",
+                                           "/org/xfce/SessionManager",
+                                           "org.xfce.Session.Manager",
+                                           &err);
+  if (proxy != NULL)
     {
-      proxy = dbus_g_proxy_new_for_name_owner (conn,
-                                               "org.xfce.PowerManager",
-                                               "/org/xfce/PowerManager",
-                                               "org.xfce.PowerManager",
-                                               &err);
-      if (proxy != NULL)
+      if (opt_halt)
         {
-          if (opt_halt)
-            {
-              result = dbus_g_proxy_call (proxy, "Suspend", &err,
-                                          G_TYPE_INVALID, G_TYPE_INVALID);
-            }
-          else
-            {
-              result = dbus_g_proxy_call (proxy, "Hibernate", &err,
-                                          G_TYPE_INVALID, G_TYPE_INVALID);
-            }
+          result = dbus_g_proxy_call (proxy, "Shutdown", &err,
+                                      G_TYPE_BOOLEAN, allow_save,
+                                      G_TYPE_INVALID, G_TYPE_INVALID);
         }
-    }
-  else
-    {
-      proxy = dbus_g_proxy_new_for_name_owner (conn,
-                                               "org.xfce.SessionManager",
-                                               "/org/xfce/SessionManager",
-                                               "org.xfce.Session.Manager",
-                                               &err);
-      if (proxy != NULL)
+      else if (opt_reboot)
+        {
+          result = dbus_g_proxy_call (proxy, "Restart", &err,
+                                      G_TYPE_BOOLEAN, allow_save,
+                                      G_TYPE_INVALID, G_TYPE_INVALID);
+        }
+      else if (opt_suspend)
+        {
+          result = dbus_g_proxy_call (proxy, "Suspend", &err,
+                                      G_TYPE_INVALID, G_TYPE_INVALID);
+        }
+      else if (opt_hibernate)
+        {
+          result = dbus_g_proxy_call (proxy, "Hibernate", &err,
+                                      G_TYPE_INVALID, G_TYPE_INVALID);
+        }
+      else
         {
-          if (opt_halt)
-            {
-              result = dbus_g_proxy_call (proxy, "Shutdown", &err,
-                                          G_TYPE_BOOLEAN, allow_save,
-                                          G_TYPE_INVALID, G_TYPE_INVALID);
-            }
-          else if (opt_reboot)
-            {
-              result = dbus_g_proxy_call (proxy, "Restart", &err,
-                                          G_TYPE_BOOLEAN, allow_save,
-                                          G_TYPE_INVALID, G_TYPE_INVALID);
-            }
-          else
-            {
-              show_dialog = !opt_logout;
-              result = dbus_g_proxy_call (proxy, "Logout", &err,
-                                          G_TYPE_BOOLEAN, show_dialog,
-                                          G_TYPE_BOOLEAN, allow_save,
-                                          G_TYPE_INVALID, G_TYPE_INVALID);
-            }
+          show_dialog = !opt_logout;
+          result = dbus_g_proxy_call (proxy, "Logout", &err,
+                                      G_TYPE_BOOLEAN, show_dialog,
+                                      G_TYPE_BOOLEAN, allow_save,
+                                      G_TYPE_INVALID, G_TYPE_INVALID);
         }
     }
 
diff --git a/xfce4-session/Makefile.am b/xfce4-session/Makefile.am
index 089d3c5..ff42d1c 100644
--- a/xfce4-session/Makefile.am
+++ b/xfce4-session/Makefile.am
@@ -60,7 +60,9 @@ xfce4_session_SOURCES =							\
 	xfsm-splash-screen.c						\
 	xfsm-splash-screen.h						\
 	xfsm-startup.c							\
-	xfsm-startup.h
+	xfsm-startup.h							\
+	xfsm-upower.c							\
+	xfsm-upower.h
 
 xfce4_session_CFLAGS =							\
 	$(GNOME_KEYRING_CFLAGS)						\
diff --git a/xfce4-session/xfsm-consolekit.c b/xfce4-session/xfsm-consolekit.c
index d11c810..f6cd641 100644
--- a/xfce4-session/xfsm-consolekit.c
+++ b/xfce4-session/xfsm-consolekit.c
@@ -98,6 +98,7 @@ xfsm_consolekit_dbus_filter (DBusConnection *connection,
   if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")
       && g_strcmp0 (dbus_message_get_path (message), DBUS_PATH_LOCAL) == 0)
     {
+      g_debug ("Consolekit disconnected");
       xfsm_consolekit_proxy_free (XFSM_CONSOLEKIT (data));
     }
 
@@ -120,6 +121,8 @@ xfsm_consolekit_name_owner_changed (DBusGProxy     *dbus_proxy,
 
   if (g_strcmp0 (name, CK_NAME) == 0)
     {
+      g_debug ("Consolekit owner changed");
+
       /* only reconnect the consolekit proxy */
       if (consolekit->ck_proxy != NULL)
         {
diff --git a/xfce4-session/xfsm-consolekit.h b/xfce4-session/xfsm-consolekit.h
index 17dbe42..051acaf 100644
--- a/xfce4-session/xfsm-consolekit.h
+++ b/xfce4-session/xfsm-consolekit.h
@@ -20,8 +20,8 @@
  * MA 02110-1301 USA.
  */
 
-#ifndef __XFSM_SHUTDOWN_HELPER_H__
-#define __XFSM_SHUTDOWN_HELPER_H__
+#ifndef __XFSM_CONSOLEKIT_HELPER_H__
+#define __XFSM_CONSOLEKIT_HELPER_H__
 
 typedef struct _XfsmConsolekitClass XfsmConsolekitClass;
 typedef struct _XfsmConsolekit      XfsmConsolekit;
@@ -51,4 +51,4 @@ gboolean        xfsm_consolekit_can_shutdown (XfsmConsolekit  *consolekit,
                                               gboolean        *can_shutdown,
                                               GError         **error);
 
-#endif /* !__XFSM_SHUTDOWN_HELPER_H__ */
+#endif /* !__XFSM_CONSOLEKIT_HELPER_H__ */
diff --git a/xfce4-session/xfsm-logout-dialog.c b/xfce4-session/xfsm-logout-dialog.c
index e342294..549eca6 100644
--- a/xfce4-session/xfsm-logout-dialog.c
+++ b/xfce4-session/xfsm-logout-dialog.c
@@ -151,12 +151,14 @@ xfsm_logout_dialog_init (XfsmLogoutDialog *dialog)
   gboolean       can_restart;
   gboolean       can_suspend = FALSE;
   gboolean       can_hibernate = FALSE;
+  gboolean       auth_suspend = FALSE;
+  gboolean       auth_hibernate = FALSE;
   GError        *error = NULL;
   XfconfChannel *channel;
   GtkWidget     *entry;
   GtkWidget     *image;
   GtkWidget     *separator;
-  gboolean       xfpm_not_found = FALSE;
+  gboolean       upower_not_found = FALSE;
 
   dialog->type_clicked = XFSM_SHUTDOWN_LOGOUT;
   dialog->shutdown = xfsm_shutdown_get ();
@@ -296,56 +298,62 @@ xfsm_logout_dialog_init (XfsmLogoutDialog *dialog)
   /**
    * Suspend
    *
-   * Hide the button if Xfpm is not installed
+   * Hide the button if UPower is not installed or system cannot suspend
    **/
   if (xfconf_channel_get_bool (channel, "/shutdown/ShowSuspend", TRUE))
     {
-      if (xfsm_shutdown_can_suspend (dialog->shutdown, &can_suspend, &error))
+      if (xfsm_shutdown_can_suspend (dialog->shutdown, &can_suspend, &auth_suspend, &error))
         {
-          button = xfsm_logout_dialog_button (_("Sus_pend"), "system-suspend",
-                                              "xfsm-suspend", XFSM_SHUTDOWN_SUSPEND,
-                                              dialog);
+          if (can_suspend)
+            {
+              button = xfsm_logout_dialog_button (_("Sus_pend"), "system-suspend",
+                                                  "xfsm-suspend", XFSM_SHUTDOWN_SUSPEND,
+                                                  dialog);
 
-          gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
-          gtk_widget_set_sensitive (button, can_suspend);
-          gtk_widget_show (button);
+              gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+              gtk_widget_set_sensitive (button, auth_suspend);
+              gtk_widget_show (button);
 
-          gtk_widget_show (hbox);
+              gtk_widget_show (hbox);
+            }
         }
       else
         {
-          g_printerr ("%s: Querying CanSuspend failed. %s\n\n",
+          g_printerr ("%s: Querying suspend failed: %s\n\n",
                       PACKAGE_NAME, ERROR_MSG (error));
           g_clear_error (&error);
 
           /* don't try hibernate again */
-          xfpm_not_found = TRUE;
+          upower_not_found = TRUE;
         }
     }
 
   /**
    * Hibernate
    *
-   * Hide the button if Xfpm is not installed
+   * Hide the button if UPower is not installed or system cannot suspend
    **/
-  if (!xfpm_not_found
+  if (!upower_not_found
       && xfconf_channel_get_bool (channel, "/shutdown/ShowHibernate", TRUE))
     {
-      if (xfsm_shutdown_can_hibernate (dialog->shutdown, &can_hibernate, &error))
+      if (xfsm_shutdown_can_hibernate (dialog->shutdown, &can_hibernate, &auth_hibernate, &error))
         {
-          button = xfsm_logout_dialog_button (_("_Hibernate"), "system-hibernate",
-                                              "xfsm-hibernate", XFSM_SHUTDOWN_HIBERNATE,
-                                              dialog);
+          if (can_hibernate)
+            {
+              button = xfsm_logout_dialog_button (_("_Hibernate"), "system-hibernate",
+                                                  "xfsm-hibernate", XFSM_SHUTDOWN_HIBERNATE,
+                                                  dialog);
 
-          gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
-          gtk_widget_set_sensitive (button, can_hibernate);
-          gtk_widget_show (button);
+              gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+              gtk_widget_set_sensitive (button, auth_hibernate);
+              gtk_widget_show (button);
 
-          gtk_widget_show (hbox);
+              gtk_widget_show (hbox);
+            }
         }
       else
         {
-          g_printerr ("%s: Querying CanHibernate failed. %s\n\n",
+          g_printerr ("%s: Querying hibernate failed: %s\n\n",
                       PACKAGE_NAME, ERROR_MSG (error));
           g_clear_error (&error);
         }
diff --git a/xfce4-session/xfsm-manager-dbus.xml b/xfce4-session/xfsm-manager-dbus.xml
index 08ebd11..9b0c7c0 100644
--- a/xfce4-session/xfsm-manager-dbus.xml
+++ b/xfce4-session/xfsm-manager-dbus.xml
@@ -79,7 +79,7 @@
         <method name="Checkpoint">
             <arg direction="in" name="session_name" type="s"/>
         </method>
-        
+
         <!--
              void org.Xfce.Session.Manager.Logout
         -->
@@ -117,6 +117,38 @@
         </method>
 
         <!--
+             void org.Xfce.Session.Manager.Suspend
+
+             This will possibly be removed in the future
+        -->
+        <method name="Suspend" />
+
+        <!--
+             void org.Xfce.Session.Manager.CanSuspend
+
+             This will possibly be removed in the future
+        -->
+        <method name="CanSuspend">
+            <arg direction="out" name="can_suspend" type="b"/>
+        </method>
+
+        <!--
+             void org.Xfce.Session.Manager.Hibernate
+
+             This will possibly be removed in the future
+        -->
+        <method name="Hibernate" />
+
+        <!--
+             void org.Xfce.Session.Manager.CanHibernate
+
+             This will possibly be removed in the future
+        -->
+        <method name="CanHibernate">
+            <arg direction="out" name="can_hibernate" type="b"/>
+        </method>
+
+        <!--
              void org.xfce.Session.Manager.StateChanged(Unsigned Int old_state,
                                                         Unsigned Int new_state)
 
diff --git a/xfce4-session/xfsm-manager.c b/xfce4-session/xfsm-manager.c
index 4aab1d8..2e244d9 100644
--- a/xfce4-session/xfsm-manager.c
+++ b/xfce4-session/xfsm-manager.c
@@ -1821,6 +1821,16 @@ static gboolean xfsm_manager_dbus_restart (XfsmManager *manager,
 static gboolean xfsm_manager_dbus_can_restart (XfsmManager *manager,
                                                gboolean    *can_restart,
                                                GError     **error);
+static gboolean xfsm_manager_dbus_suspend (XfsmManager *manager,
+                                           GError     **error);
+static gboolean xfsm_manager_dbus_can_suspend (XfsmManager *manager,
+                                               gboolean    *can_suspend,
+                                               GError     **error);
+static gboolean xfsm_manager_dbus_hibernate (XfsmManager *manager,
+                                             GError     **error);
+static gboolean xfsm_manager_dbus_can_hibernate (XfsmManager *manager,
+                                                 gboolean    *can_hibernate,
+                                                 GError     **error);
 
 
 /* eader needs the above fwd decls */
@@ -2077,3 +2087,58 @@ xfsm_manager_dbus_can_restart (XfsmManager *manager,
   return xfsm_shutdown_can_restart (manager->shutdown_helper,
                                     can_restart, error);
 }
+
+
+static gboolean
+xfsm_manager_dbus_suspend (XfsmManager *manager,
+                           GError     **error)
+{
+  g_return_val_if_fail (XFSM_IS_MANAGER (manager), FALSE);
+  return xfsm_shutdown_try_suspend (manager->shutdown_helper, error);
+}
+
+
+static gboolean
+xfsm_manager_dbus_can_suspend (XfsmManager *manager,
+                               gboolean    *can_suspend,
+                               GError     **error)
+{
+  gboolean retval;
+  gboolean auth_suspend;
+
+  g_return_val_if_fail (XFSM_IS_MANAGER (manager), FALSE);
+  retval = xfsm_shutdown_can_suspend (manager->shutdown_helper,
+                                      can_suspend, &auth_suspend, error);
+
+  if (!auth_suspend)
+    can_suspend = FALSE;
+
+  return retval;
+}
+
+static gboolean
+xfsm_manager_dbus_hibernate (XfsmManager *manager,
+                             GError     **error)
+{
+  g_return_val_if_fail (XFSM_IS_MANAGER (manager), FALSE);
+  return xfsm_shutdown_try_hibernate (manager->shutdown_helper, error);
+}
+
+
+static gboolean
+xfsm_manager_dbus_can_hibernate (XfsmManager *manager,
+                                 gboolean    *can_hibernate,
+                                 GError     **error)
+{
+  gboolean retval;
+  gboolean auth_hibernate;
+
+  g_return_val_if_fail (XFSM_IS_MANAGER (manager), FALSE);
+  retval = xfsm_shutdown_can_hibernate (manager->shutdown_helper,
+                                        can_hibernate, &auth_hibernate, error);
+
+  if (!auth_hibernate)
+    can_hibernate = FALSE;
+
+  return retval;
+}
diff --git a/xfce4-session/xfsm-shutdown.c b/xfce4-session/xfsm-shutdown.c
index 52a9841..a39f46c 100644
--- a/xfce4-session/xfsm-shutdown.c
+++ b/xfce4-session/xfsm-shutdown.c
@@ -61,6 +61,7 @@
 #include <xfce4-session/xfsm-global.h>
 #include <xfce4-session/xfsm-legacy.h>
 #include <xfce4-session/xfsm-consolekit.h>
+#include <xfce4-session/xfsm-upower.h>
 
 
 
@@ -87,6 +88,7 @@ struct _XfsmShutdown
   GObject __parent__;
 
   XfsmConsolekit *consolekit;
+  XfsmUPower     *upower;
 
   /* kiosk settings */
   gboolean        kiosk_can_shutdown;
@@ -124,6 +126,7 @@ xfsm_shutdown_init (XfsmShutdown *shutdown)
   XfceKiosk *kiosk;
 
   shutdown->consolekit = xfsm_consolekit_get ();
+  shutdown->upower = xfsm_upower_get ();
   shutdown->helper_state = SUDO_NOT_INITIAZED;
   shutdown->helper_require_password = FALSE;
 
@@ -142,6 +145,7 @@ xfsm_shutdown_finalize (GObject *object)
   XfsmShutdown *shutdown = XFSM_SHUTDOWN (object);
 
   g_object_unref (G_OBJECT (shutdown->consolekit));
+  g_object_unref (G_OBJECT (shutdown->upower));
 
   /* close down helper */
   xfsm_shutdown_sudo_free (shutdown);
@@ -522,46 +526,6 @@ xfsm_shutdown_sudo_send_password (XfsmShutdown  *shutdown,
 
 
 static gboolean
-xfsm_shutdown_query_xfpm (XfsmShutdown  *shutdown,
-                          const gchar   *method,
-                          gboolean      *can_method,
-                          GError       **error)
-{
-  DBusGConnection *conn;
-  DBusGProxy      *proxy;
-  gboolean         result = FALSE;
-
-  g_return_val_if_fail (can_method != NULL, FALSE);
-
-  /* never return true if something fails */
-  *can_method = FALSE;
-
-  conn = dbus_g_bus_get (DBUS_BUS_SESSION, error);
-  if (conn == NULL)
-    return FALSE;
-
-  proxy = dbus_g_proxy_new_for_name_owner (conn,
-                                           "org.xfce.PowerManagement",
-                                           "/org/xfce/PowerManagement",
-                                           "org.xfce.PowerManagement",
-                                           error);
-  if (proxy != NULL)
-    {
-      result = dbus_g_proxy_call (proxy, method, error,
-                                  G_TYPE_INVALID,
-                                  G_TYPE_BOOLEAN, can_method,
-                                  G_TYPE_INVALID);
-      g_object_unref (proxy);
-    }
-
-  dbus_g_connection_unref (conn);
-
-  return result;
-}
-
-
-
-static gboolean
 xfsm_shutdown_kiosk_can_shutdown (XfsmShutdown  *shutdown,
                                   GError       **error)
 {
@@ -576,43 +540,6 @@ xfsm_shutdown_kiosk_can_shutdown (XfsmShutdown  *shutdown,
 
 
 
-static gboolean
-xfsm_shutdown_run_xfpm (XfsmShutdown  *shutdown,
-                        const gchar   *method,
-                        GError       **error)
-{
-  DBusGConnection *conn;
-  DBusGProxy      *proxy;
-  gboolean         result = FALSE;
-
-  if (!xfsm_shutdown_kiosk_can_shutdown (shutdown, error))
-    return FALSE;
-
-  conn = dbus_g_bus_get (DBUS_BUS_SESSION, error);
-  if (conn == NULL)
-    return FALSE;
-
-  proxy = dbus_g_proxy_new_for_name_owner (conn,
-                                           "org.xfce.PowerManagement",
-                                           "/org/xfce/PowerManagement",
-                                           "org.xfce.PowerManagement",
-                                           error);
-
-  if (proxy != NULL)
-    {
-      result = dbus_g_proxy_call (proxy, method, error,
-                                  G_TYPE_INVALID,
-                                  G_TYPE_INVALID);
-      g_object_unref (proxy);
-    }
-
-  dbus_g_connection_unref (conn);
-
-  return result;
-}
-
-
-
 XfsmShutdown *
 xfsm_shutdown_get (void)
 {
@@ -736,7 +663,7 @@ xfsm_shutdown_try_suspend (XfsmShutdown  *shutdown,
 {
   g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
 
-  return xfsm_shutdown_run_xfpm (shutdown, "Suspend", error);
+  return xfsm_upower_try_suspend (shutdown->upower, error);
 }
 
 
@@ -747,7 +674,7 @@ xfsm_shutdown_try_hibernate (XfsmShutdown  *shutdown,
 {
   g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
 
-  return xfsm_shutdown_run_xfpm (shutdown, "Hibernate", error);
+  return xfsm_upower_try_hibernate (shutdown->upower, error);
 }
 
 
@@ -794,12 +721,10 @@ xfsm_shutdown_can_shutdown (XfsmShutdown  *shutdown,
 
 
 
-/* This function only queries the CanSuspend state of
- * xfce4-power-manager. If this package is not installed,
- * suspend is not supported. */
 gboolean
 xfsm_shutdown_can_suspend (XfsmShutdown  *shutdown,
                            gboolean      *can_suspend,
+                           gboolean      *auth_suspend,
                            GError       **error)
 {
   g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
@@ -810,18 +735,16 @@ xfsm_shutdown_can_suspend (XfsmShutdown  *shutdown,
       return TRUE;
     }
 
-  return xfsm_shutdown_query_xfpm (shutdown, "CanSuspend",
-                                   can_suspend, error);
+  return xfsm_upower_can_suspend (shutdown->upower, can_suspend, 
+                                  auth_suspend, error);
 }
 
 
 
-/* This function only queries the CanHibernate state of
- * xfce4-power-manager. If this package is not installed,
- * hibernation is not supported. */
 gboolean
 xfsm_shutdown_can_hibernate (XfsmShutdown  *shutdown,
                              gboolean      *can_hibernate,
+                             gboolean      *auth_hibernate,
                              GError       **error)
 {
   g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
@@ -832,8 +755,8 @@ xfsm_shutdown_can_hibernate (XfsmShutdown  *shutdown,
       return TRUE;
     }
 
-  return xfsm_shutdown_query_xfpm (shutdown, "CanHibernate",
-                                   can_hibernate, error);
+  return xfsm_upower_can_hibernate (shutdown->upower, can_hibernate,
+                                    auth_hibernate, error);
 }
 
 
diff --git a/xfce4-session/xfsm-shutdown.h b/xfce4-session/xfsm-shutdown.h
index 2be627f..eac26bf 100644
--- a/xfce4-session/xfsm-shutdown.h
+++ b/xfce4-session/xfsm-shutdown.h
@@ -88,10 +88,12 @@ gboolean      xfsm_shutdown_can_shutdown     (XfsmShutdown      *shutdown,
 
 gboolean      xfsm_shutdown_can_suspend      (XfsmShutdown      *shutdown,
                                               gboolean          *can_suspend,
+                                              gboolean          *auth_suspend,
                                               GError           **error);
 
 gboolean      xfsm_shutdown_can_hibernate    (XfsmShutdown      *shutdown,
                                               gboolean          *can_hibernate,
+                                              gboolean          *auth_hibernate,
                                               GError           **error);
 
 gboolean      xfsm_shutdown_can_save_session (XfsmShutdown      *shutdown);
diff --git a/xfce4-session/xfsm-upower.c b/xfce4-session/xfsm-upower.c
new file mode 100644
index 0000000..4707acc
--- /dev/null
+++ b/xfce4-session/xfsm-upower.c
@@ -0,0 +1,381 @@
+/*-
+ * Copyright (c) 2011 Nick Schermer <nick at xfce.org>
+ * All rights reserved.
+ *
+ * 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, or (at your option)
+ * any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <xfce4-session/xfsm-upower.h>
+
+
+
+#define UPOWER_NAME      "org.freedesktop.UPower"
+#define UPOWER_PATH      "/org/freedesktop/UPower"
+#define UPOWER_INTERFACE UPOWER_NAME
+
+
+
+static void     xfsm_upower_finalize     (GObject     *object);
+static gboolean xfsm_upower_proxy_ensure (XfsmUPower  *upower,
+                                          GError     **error);
+static void     xfsm_upower_proxy_free   (XfsmUPower  *upower);
+
+
+
+struct _XfsmUPowerClass
+{
+  GObjectClass __parent__;
+};
+
+struct _XfsmUPower
+{
+  GObject __parent__;
+
+  DBusGConnection *dbus_conn;
+  DBusGProxy      *upower_proxy;
+  DBusGProxy      *props_proxy;
+};
+
+
+
+G_DEFINE_TYPE (XfsmUPower, xfsm_upower, G_TYPE_OBJECT)
+
+
+
+static void
+xfsm_upower_class_init (XfsmUPowerClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = xfsm_upower_finalize;
+}
+
+
+
+static void
+xfsm_upower_init (XfsmUPower *upower)
+{
+}
+
+
+
+static void
+xfsm_upower_finalize (GObject *object)
+{
+  xfsm_upower_proxy_free (XFSM_UPOWER (object));
+
+  (*G_OBJECT_CLASS (xfsm_upower_parent_class)->finalize) (object);
+}
+
+
+
+static gboolean
+xfsm_upower_proxy_ensure (XfsmUPower  *upower,
+                          GError     **error)
+{
+  GError         *err = NULL;
+  DBusConnection *connection;
+
+  if (upower->dbus_conn == NULL)
+    {
+      upower->dbus_conn = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
+      if (upower->dbus_conn == NULL)
+        goto error1;
+
+      connection = dbus_g_connection_get_connection (upower->dbus_conn);
+      dbus_connection_set_exit_on_disconnect (connection, FALSE);
+    }
+
+  if (upower->upower_proxy == NULL)
+    {
+      upower->upower_proxy = dbus_g_proxy_new_for_name (upower->dbus_conn,
+                                                        UPOWER_NAME,
+                                                        UPOWER_PATH,
+                                                        UPOWER_INTERFACE);
+      if (upower->upower_proxy == NULL)
+        {
+          g_set_error (&err, DBUS_GERROR, DBUS_GERROR_FAILED,
+                       "Failed to get proxy for %s",
+                       UPOWER_NAME);
+          goto error1;
+        }
+    }
+
+  if (upower->props_proxy == NULL)
+    {
+      upower->props_proxy = dbus_g_proxy_new_for_name (upower->dbus_conn,
+                                                       UPOWER_NAME,
+                                                       UPOWER_PATH,
+                                                       DBUS_INTERFACE_PROPERTIES);
+      if (upower->props_proxy == NULL)
+        {
+          g_set_error (&err, DBUS_GERROR, DBUS_GERROR_FAILED,
+                       "Failed to get proxy for %s properties",
+                       UPOWER_NAME);
+          goto error1;
+        }
+    }
+
+  return TRUE;
+
+  error1:
+
+  g_propagate_error (error, err);
+  xfsm_upower_proxy_free (upower);
+
+  return FALSE;
+}
+
+
+
+static void
+xfsm_upower_proxy_free (XfsmUPower *upower)
+{
+  if (upower->upower_proxy != NULL)
+    {
+      g_object_unref (G_OBJECT (upower->upower_proxy));
+      upower->upower_proxy = NULL;
+    }
+
+  if (upower->props_proxy != NULL)
+    {
+      g_object_unref (G_OBJECT (upower->props_proxy));
+      upower->props_proxy = NULL;
+    }
+
+  if (upower->dbus_conn != NULL)
+    {
+      dbus_g_connection_unref (upower->dbus_conn);
+      upower->dbus_conn = NULL;
+    }
+}
+
+
+
+static gboolean
+xfsm_upower_get_property (XfsmUPower   *upower,
+                          const gchar  *prop_name,
+                          gboolean     *bool_return,
+                          GError      **error)
+{
+  GValue   val = { 0, };
+  gboolean succeed;
+
+  succeed = dbus_g_proxy_call (upower->props_proxy, "Get",
+                               error,
+                               G_TYPE_STRING, UPOWER_INTERFACE,
+                               G_TYPE_STRING, prop_name,
+                               G_TYPE_INVALID,
+                               G_TYPE_VALUE, &val,
+                               G_TYPE_INVALID);
+
+  if (succeed)
+    {
+      g_assert (G_VALUE_HOLDS_BOOLEAN (&val));
+      *bool_return = g_value_get_boolean (&val);
+    }
+  else
+    {
+      *bool_return = FALSE;
+    }
+
+  return succeed;
+}
+
+
+
+static gboolean
+xfsm_upower_can_method (XfsmUPower   *upower,
+                        const gchar  *can_property, /* if the system is capable */
+                        gboolean     *can_return,
+                        const gchar  *auth_method, /* if the user is allowed */
+                        gboolean     *auth_return,
+                        GError      **error)
+{
+  g_return_val_if_fail (can_return != NULL, FALSE);
+  g_return_val_if_fail (auth_return != NULL, FALSE);
+
+  /* never return true if something fails */
+  *can_return = FALSE;
+  *auth_return = FALSE;
+
+  if (!xfsm_upower_proxy_ensure (upower, error))
+    return FALSE;
+
+  if (xfsm_upower_get_property (upower, can_property, can_return, error))
+    {
+      if (*can_return)
+        {
+          /* check authentication if system is capable of this action */
+          return dbus_g_proxy_call (upower->upower_proxy, auth_method,
+                                    error, G_TYPE_INVALID,
+                                    G_TYPE_BOOLEAN, auth_return,
+                                    G_TYPE_INVALID);
+        }
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+
+
+static void
+xfsm_upower_try_method_cb (DBusGProxy     *proxy,
+                           DBusGProxyCall *call,
+                           gpointer        user_data)
+{
+  GError *error = NULL;
+
+  if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID, G_TYPE_INVALID))
+    {
+        g_warning ("Failed to suspend the system: %s %d %s",
+                   g_quark_to_string (error->domain),
+                   error->code, error->message);
+        g_error_free (error);
+    }
+}
+
+
+
+static gboolean
+xfsm_upower_try_method (XfsmUPower   *upower,
+                        const gchar  *method,
+                        GError      **error)
+{
+  DBusGProxyCall *call;
+
+  if (!xfsm_upower_proxy_ensure (upower, error))
+    return FALSE;
+
+  call = dbus_g_proxy_begin_call (upower->upower_proxy,
+                                  method,
+                                  xfsm_upower_try_method_cb,
+                                  upower,
+                                  NULL,
+                                  G_TYPE_INVALID,
+                                  G_TYPE_INVALID);
+
+  return call != NULL;
+}
+
+
+
+static void
+xfsm_upower_lock_screen (void)
+{
+  XfconfChannel *channel;
+  GError *err = NULL;
+
+  channel = xfsm_open_config ();
+  if (xfconf_channel_get_bool (channel, "/shutdown/LockScreen", FALSE))
+    {
+      if (!g_spawn_command_line_async ("xflock4", &err))
+        {
+          xfce_dialog_show_error (NULL, err, _("Failed to lock the screen"));
+        }
+
+      g_usleep (G_USEC_PER_SEC);
+    }
+}
+
+
+
+XfsmUPower *
+xfsm_upower_get (void)
+{
+  static XfsmUPower *object = NULL;
+
+  if (G_LIKELY (object != NULL))
+    {
+      g_object_ref (G_OBJECT (object));
+    }
+  else
+    {
+      object = g_object_new (XFSM_TYPE_UPOWER, NULL);
+      g_object_add_weak_pointer (G_OBJECT (object), (gpointer) &object);
+    }
+
+  return object;
+}
+
+
+
+gboolean
+xfsm_upower_try_suspend (XfsmUPower  *upower,
+                         GError     **error)
+{
+  g_return_val_if_fail (XFSM_IS_UPOWER (upower), FALSE);
+
+  xfsm_upower_lock_screen ();
+
+  return xfsm_upower_try_method (upower, "Suspend", error);
+}
+
+
+
+gboolean
+xfsm_upower_try_hibernate (XfsmUPower  *upower,
+                           GError     **error)
+{
+  g_return_val_if_fail (XFSM_IS_UPOWER (upower), FALSE);
+
+  xfsm_upower_lock_screen ();
+
+  return xfsm_upower_try_method (upower, "Hibernate", error);
+}
+
+
+
+gboolean
+xfsm_upower_can_suspend (XfsmUPower  *upower,
+                         gboolean    *can_suspend,
+                         gboolean    *auth_suspend,
+                         GError     **error)
+{
+  g_return_val_if_fail (XFSM_IS_UPOWER (upower), FALSE);
+
+  return xfsm_upower_can_method (upower,
+                                 "CanSuspend",
+                                 can_suspend,
+                                 "SuspendAllowed",
+                                 auth_suspend,
+                                 error);
+}
+
+
+
+gboolean
+xfsm_upower_can_hibernate (XfsmUPower  *upower,
+                           gboolean    *can_hibernate,
+                           gboolean    *auth_hibernate,
+                           GError     **error)
+{
+  g_return_val_if_fail (XFSM_IS_UPOWER (upower), FALSE);
+
+  return xfsm_upower_can_method (upower,
+                                 "CanHibernate",
+                                 can_hibernate,
+                                 "HibernateAllowed",
+                                 auth_hibernate,
+                                 error);
+}
diff --git a/xfce4-session/xfsm-upower.h b/xfce4-session/xfsm-upower.h
new file mode 100644
index 0000000..a492f7d
--- /dev/null
+++ b/xfce4-session/xfsm-upower.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2011      Nick Schermer <nick at xfce.org>
+ * All rights reserved.
+ *
+ * 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, or (at your option)
+ * any later version.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#ifndef __XFSM_UPOWER_HELPER_H__
+#define __XFSM_UPOWER_HELPER_H__
+
+typedef struct _XfsmUPowerClass XfsmUPowerClass;
+typedef struct _XfsmUPower      XfsmUPower;
+
+#define XFSM_TYPE_UPOWER            (xfsm_upower_get_type ())
+#define XFSM_UPOWER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFSM_TYPE_UPOWER, XfsmUPower))
+#define XFSM_UPOWER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), XFSM_TYPE_UPOWER, XfsmUPowerClass))
+#define XFSM_IS_UPOWER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFSM_TYPE_UPOWER))
+#define XFSM_IS_UPOWER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFSM_TYPE_UPOWER))
+#define XFSM_UPOWER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), XFSM_TYPE_UPOWER, XfsmUPowerClass))
+
+GType           xfsm_upower_get_type         (void) G_GNUC_CONST;
+
+XfsmUPower     *xfsm_upower_get              (void);
+
+gboolean        xfsm_upower_try_suspend      (XfsmUPower      *upower,
+                                              GError         **error);
+
+gboolean        xfsm_upower_try_hibernate    (XfsmUPower      *upower,
+                                              GError         **error);
+
+gboolean        xfsm_upower_can_suspend      (XfsmUPower      *upower,
+                                              gboolean        *can_suspend,
+                                              gboolean        *auth_suspend,
+                                              GError         **error);
+
+gboolean        xfsm_upower_can_hibernate    (XfsmUPower      *upower,
+                                              gboolean        *can_hibernate,
+                                              gboolean        *auth_hibernate,
+                                              GError         **error);
+
+#endif /* !__XFSM_UPOWER_HELPER_H__ */


More information about the Xfce4-commits mailing list