You are not logged in.

#1 2007-09-26 03:24:07

.:B:.
Forum Fellow
Registered: 2006-11-26
Posts: 5,819
Website

Integrate suspend & hibernate buttons into XFCE logout dialog

The inevitable (X)ubuntu has suspend/hibernate buttons integrated into the XFCE logout dialog. I grabbed their patch and recompiled xfce4-session, and the buttons show up nicely (what's even better: they talk to pm-utils).

Since the 'switch user' functionality depends on GDM and I do not use either, I would like to remove it. This is the original patch from Xubuntu to add the extra buttons:

diff -Nur xfce4-session-4.4.1/settings/session/session.c xfce4-session-4.4.1.new/settings/session/session.c
--- xfce4-session-4.4.1/settings/session/session.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/settings/session/session.c    2007-09-10 15:00:27.000000000 +0200
@@ -51,6 +51,8 @@
 static GtkWidget    *general_chooser;
 static GtkWidget    *general_autosave;
 static GtkWidget    *general_prompt;
+static GtkWidget    *general_hibernate_button;
+static GtkWidget    *general_suspend_button;
 static GtkWidget    *advanced_kde;
 static GtkWidget    *advanced_gnome;
 static GtkWidget    *advanced_remote;
@@ -88,6 +90,8 @@
     {
       xfce_rc_write_bool_entry (rc, "AutoSave", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (general_autosave)));
       xfce_rc_write_bool_entry (rc, "PromptOnLogout", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (general_prompt)));
+      xfce_rc_write_bool_entry (rc, "HibernateButton", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (general_hibernate_button)));
+      xfce_rc_write_bool_entry (rc, "SuspendButton", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (general_suspend_button)));
     }
   if (G_LIKELY (kiosk_can_security))
     {
@@ -124,10 +128,14 @@
   gboolean   autosave;
   gboolean   prompt;
   gboolean   chooser;
+  gboolean   hibernate;
+  gboolean   suspend;
 
   xfce_rc_set_group (rc, "General");
   autosave = xfce_rc_read_bool_entry (rc, "AutoSave", FALSE);
   prompt = xfce_rc_read_bool_entry (rc, "PromptOnLogout", TRUE);
+  hibernate = xfce_rc_read_bool_entry (rc, "HibernateButton", TRUE);
+  suspend = xfce_rc_read_bool_entry (rc, "SuspendButton", TRUE);
   xfce_rc_set_group (rc, "Chooser");
   chooser = xfce_rc_read_bool_entry (rc, "AlwaysDisplay", FALSE);
 
@@ -181,6 +189,29 @@
                           "depends on whether you enabled the automatic "
                           "saving of sessions on logout or not."),
                         NULL);
+  
+  general_hibernate_button = gtk_check_button_new_with_label (_("Show hibernate button"));
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (general_hibernate_button), hibernate);
+  g_signal_connect (G_OBJECT (general_hibernate_button), "toggled",
+                    G_CALLBACK (config_store), NULL);
+  gtk_box_pack_start (GTK_BOX (vbox), general_hibernate_button, FALSE, TRUE, 0);
+  gtk_tooltips_set_tip (tooltips, general_hibernate_button,
+                        _("This option adds a hibernate button to the logout dialog. "
+                          "Only enable if you known your system suspends to"
+              "disk and resumes correctly."),
+                        NULL);
+
+  general_suspend_button = gtk_check_button_new_with_label (_("Show suspend button"));
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (general_suspend_button), suspend);
+  g_signal_connect (G_OBJECT (general_suspend_button), "toggled",
+                    G_CALLBACK (config_store), NULL);
+  gtk_box_pack_start (GTK_BOX (vbox), general_suspend_button, FALSE, TRUE, 0);
+  gtk_tooltips_set_tip (tooltips, general_suspend_button,
+                        _("This option adds a suspend button to the logout dialog. "
+                          "Only enable if you known your system suspends to"
+              "RAM and resumes correctly."),
+                        NULL);
+
 
   return page;
 }
diff -Nur xfce4-session-4.4.1/xfce4-session/main.c xfce4-session-4.4.1.new/xfce4-session/main.c
--- xfce4-session-4.4.1/xfce4-session/main.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/main.c    2007-09-10 15:00:27.000000000 +0200
@@ -61,6 +61,11 @@
 #include <xfce4-session/xfsm-manager.h>
 #include <xfce4-session/xfsm-startup.h>
 
+#include <xfce4-session/xfsm-shutdown-helper.h>
+
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
 
 void
 setup_environment (void)
@@ -225,8 +230,6 @@
 int
 main (int argc, char **argv)
 {
-  /* imported from xfsm-manager.c */
-  extern gint shutdown_type;
 
   xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
   
@@ -248,5 +251,5 @@
   
   ice_cleanup ();
 
-  return xfsm_shutdown (shutdown_type);
+  return xfsm_shutdown ();
 }
diff -Nur xfce4-session-4.4.1/xfce4-session/shutdown.c xfce4-session-4.4.1.new/xfce4-session/shutdown.c
--- xfce4-session-4.4.1/xfce4-session/shutdown.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/shutdown.c    2007-09-10 15:01:21.000000000 +0200
@@ -110,34 +110,36 @@
   gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
 }
 
-static void
-logout_button_clicked (GtkWidget *b, gint *shutdownType)
-{
-    *shutdownType = SHUTDOWN_LOGOUT;
-
-    gtk_dialog_response (GTK_DIALOG (shutdown_dialog), GTK_RESPONSE_OK);
-}
+static gint shutdownType = XFSM_LOGOUT;
 
 static void
-reboot_button_clicked (GtkWidget *b, gint *shutdownType)
+logout_dialog_button_clicked (GtkWidget *b, gint *cmd)
 {
-    *shutdownType = SHUTDOWN_REBOOT;
+    shutdownType = *cmd;
 
     gtk_dialog_response (GTK_DIALOG (shutdown_dialog), GTK_RESPONSE_OK);
 }
 
-static void
-halt_button_clicked (GtkWidget *b, gint *shutdownType)
+struct LogoutButton
 {
-    *shutdownType = SHUTDOWN_HALT;
-
-    gtk_dialog_response (GTK_DIALOG (shutdown_dialog), GTK_RESPONSE_OK);
-}
+    gchar * label;
+    gchar * icon;
+    gint    cmd;
+    gboolean present;
+    GtkWidget * button;
+};
+
+struct LogoutButton logout_buttons [] = {
+ { N_("Switch user"), "xfsm-switch", XFSM_SWITCH, TRUE },
+ { N_("Log out"), "xfsm-logout", XFSM_LOGOUT, TRUE },
+ { N_("Restart"), "xfsm-reboot", XFSM_REBOOT, TRUE },
+ { N_("Shut down"), "xfsm-shutdown", XFSM_SHUTDOWN, TRUE },
+ { N_("Suspend"), "xfsm-suspend", XFSM_SUSPEND, FALSE},
+ { N_("Hibernate"), "xfsm-hibernate", XFSM_HIBERNATE, FALSE},
+};
 
-/*
- */
 gboolean
-shutdownDialog(gint *shutdownType, gboolean *saveSession)
+shutdownDialog(gboolean *saveSession)
 {
   gboolean accessibility;
   XfsmFadeout *fadeout = NULL;
@@ -145,7 +147,9 @@
   GtkWidget *dialog;
   GtkWidget *label;
   GtkWidget *dbox;
+  GtkWidget *rbox;
   GtkWidget *hbox;
+  GtkWidget *hbox2;
   GtkWidget *vbox;
   GtkWidget *vbox2;
   GtkWidget *image;
@@ -154,14 +158,14 @@
   GtkWidget *entry;
   GtkWidget *hidden;
   GtkWidget *logout_button;
-  GtkWidget *reboot_button;
-  GtkWidget *halt_button;
   GtkWidget *cancel_button;
   GtkWidget *ok_button;
   GdkPixbuf *icon;
   gboolean saveonexit;
   gboolean autosave;
   gboolean prompt;
+  gboolean have_suspend;
+  gboolean have_hibernate;
   gint monitor;
   gint result;
   XfceKiosk *kiosk;
@@ -173,9 +177,8 @@
   GdkPixmap *screenshot_pm = NULL;
   GdkGC *screenshot_gc;
 #endif
-
+  gint i;
   g_return_val_if_fail(saveSession != NULL, FALSE);
-  g_return_val_if_fail(shutdownType != NULL, FALSE);
 
   /* destroy any previously running shutdown helper first */
   if (shutdown_helper != NULL)
@@ -195,13 +198,15 @@
   saveonexit = xfce_rc_read_bool_entry (rc, "SaveOnExit", TRUE);
   autosave = xfce_rc_read_bool_entry (rc, "AutoSave", FALSE);
   prompt = xfce_rc_read_bool_entry (rc, "PromptOnLogout", TRUE);
+  have_suspend = xfce_rc_read_bool_entry (rc, "SuspendButton", TRUE);
+  have_hibernate = xfce_rc_read_bool_entry (rc, "HibernateButton", TRUE);
 
   /* if PromptOnLogout is off, saving depends on AutoSave */
   if (!prompt)
     {
       xfce_rc_close (rc);
 
-      *shutdownType = SHUTDOWN_LOGOUT;
+      shutdownType = XFSM_LOGOUT;
       *saveSession = autosave;
 
       return TRUE;
@@ -311,76 +316,43 @@
   hbox = gtk_hbox_new (TRUE, BORDER);
   gtk_widget_show (hbox);
   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+  hbox2 = gtk_hbox_new (TRUE, BORDER);
+  gtk_widget_show (hbox2);
+  gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
+  logout_buttons[4].present = have_suspend;
+  logout_buttons[5].present = have_hibernate;
   
-  /* logout */
-  logout_button = gtk_button_new ();
-  gtk_widget_show (logout_button);
-  gtk_box_pack_start (GTK_BOX (hbox), logout_button, TRUE, TRUE, 0);
-
-  g_signal_connect (logout_button, "clicked", 
-                    G_CALLBACK (logout_button_clicked), shutdownType);
-
-  vbox2 = gtk_vbox_new (FALSE, BORDER);
-  gtk_container_set_border_width (GTK_CONTAINER (vbox2), BORDER);
-  gtk_widget_show (vbox2);
-  gtk_container_add (GTK_CONTAINER (logout_button), vbox2);
-
-  icon = xfce_themed_icon_load ("xfsm-logout", 32);
-  image = gtk_image_new_from_pixbuf (icon);
-  gtk_widget_show (image);
-  gtk_box_pack_start (GTK_BOX (vbox2), image, FALSE, FALSE, 0);
-  g_object_unref (icon);
-
-  label = gtk_label_new (_("Log Out"));
-  gtk_widget_show (label);
-  gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
-  
-  /* reboot */
-  reboot_button = gtk_button_new ();
-  gtk_widget_show (reboot_button);
-  gtk_box_pack_start (GTK_BOX (hbox), reboot_button, TRUE, TRUE, 0);
-
-  g_signal_connect (reboot_button, "clicked", 
-                    G_CALLBACK (reboot_button_clicked), shutdownType);
-
-  vbox2 = gtk_vbox_new (FALSE, BORDER);
-  gtk_container_set_border_width (GTK_CONTAINER (vbox2), BORDER);
-  gtk_widget_show (vbox2);
-  gtk_container_add (GTK_CONTAINER (reboot_button), vbox2);
-
-  icon = xfce_themed_icon_load ("xfsm-reboot", 32);
-  image = gtk_image_new_from_pixbuf (icon);
-  gtk_widget_show (image);
-  gtk_box_pack_start (GTK_BOX (vbox2), image, FALSE, FALSE, 0);
-  g_object_unref (icon);
-
-  label = gtk_label_new (_("Restart"));
-  gtk_widget_show (label);
-  gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
-  
-  /* halt */
-  halt_button = gtk_button_new ();
-  gtk_widget_show (halt_button);
-  gtk_box_pack_start (GTK_BOX (hbox), halt_button, TRUE, TRUE, 0);
-
-  g_signal_connect (halt_button, "clicked", 
-                    G_CALLBACK (halt_button_clicked), shutdownType);
-
-  vbox2 = gtk_vbox_new (FALSE, BORDER);
-  gtk_container_set_border_width (GTK_CONTAINER (vbox2), BORDER);
-  gtk_widget_show (vbox2);
-  gtk_container_add (GTK_CONTAINER (halt_button), vbox2);
-
-  icon = xfce_themed_icon_load ("xfsm-shutdown", 32);
-  image = gtk_image_new_from_pixbuf (icon);
-  gtk_widget_show (image);
-  gtk_box_pack_start (GTK_BOX (vbox2), image, FALSE, FALSE, 0);
-  g_object_unref (icon);
-  
-  label = gtk_label_new (_("Shut Down"));
-  gtk_widget_show (label);
-  gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
-  
+  for (i = 0; i < G_N_ELEMENTS (logout_buttons); i++) { 
+      
+    if (logout_buttons[i].present == FALSE)
+       continue;        
+    
+    logout_button = gtk_button_new ();
+    gtk_widget_show (logout_button);
+    rbox = i > G_N_ELEMENTS (logout_buttons)/2 - 1 ? hbox2 : hbox;
+    gtk_box_pack_start (GTK_BOX (rbox), logout_button, TRUE, TRUE, 0);
+
+    g_signal_connect (logout_button, "clicked", 
+              G_CALLBACK (logout_dialog_button_clicked), &logout_buttons[i].cmd);
+
+    vbox2 = gtk_vbox_new (FALSE, BORDER);
+    gtk_container_set_border_width (GTK_CONTAINER (vbox2), BORDER);
+    gtk_widget_show (vbox2);
+    gtk_container_add (GTK_CONTAINER (logout_button), vbox2);
+
+    icon = xfce_themed_icon_load (logout_buttons[i].icon, 32);
+    image = gtk_image_new_from_pixbuf (icon);
+    gtk_widget_show (image);
+    gtk_box_pack_start (GTK_BOX (vbox2), image, FALSE, FALSE, 0);
+    g_object_unref (icon);
+
+    label = gtk_label_new (_(logout_buttons[i].label));
+    gtk_widget_show (label);
+    gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
+
+    logout_buttons[i].button = logout_button;
+  }
+ 
   /* save session */
   if (!autosave)
     {
@@ -406,8 +378,9 @@
   if (!kiosk_can_shutdown || 
       (shutdown_helper = xfsm_shutdown_helper_spawn ()) == NULL)
     {
-      gtk_widget_set_sensitive (reboot_button, FALSE);
-      gtk_widget_set_sensitive (halt_button, FALSE);
+      for (i = 2; i < G_N_ELEMENTS (logout_buttons); i++) { 
+          gtk_widget_set_sensitive (logout_buttons[i].button, FALSE);
+      }
     }
 
   /* save portion of the root window covered by the dialog */
@@ -437,7 +410,9 @@
   gtk_widget_hide (dialog);
 
   /* ask password */
-  if (result == GTK_RESPONSE_OK && *shutdownType != SHUTDOWN_LOGOUT
+  if (result == GTK_RESPONSE_OK
+      && shutdownType != XFSM_LOGOUT
+      && shutdownType != XFSM_SWITCH
       && xfsm_shutdown_helper_need_password (shutdown_helper))
     {
       gtk_widget_show (ok_button);
@@ -533,6 +508,21 @@
       gdk_flush ();
     }
 
+  /*
+   * For suspend/hibernate perform the action but do not
+   * close the session so it is still there on resume
+   */
+  if (result == GTK_RESPONSE_OK
+          && (shutdownType == XFSM_SUSPEND || shutdownType == XFSM_HIBERNATE)) {
+      xfsm_shutdown_helper_send_command (shutdown_helper, shutdownType);
+      return FALSE;
+  }
+ 
+  if (result == GTK_RESPONSE_OK && shutdownType == XFSM_SWITCH) {
+        g_spawn_command_line_sync ("gdmflexiserver --startnew", NULL, NULL, NULL, NULL);
+        return FALSE;
+  }
+
   /* process all pending events first */
   while (gtk_events_pending ())
     g_main_context_iteration (NULL, FALSE);
@@ -571,7 +561,7 @@
 /*
  */
 gint
-xfsm_shutdown(gint type)
+xfsm_shutdown(void)
 {
   gboolean result;
 
@@ -589,7 +579,7 @@
   sync ();
 #endif
 
-  if (type == SHUTDOWN_LOGOUT)
+  if (shutdownType == XFSM_LOGOUT)
     return EXIT_SUCCESS;
 
   if (shutdown_helper == NULL)
@@ -598,16 +588,7 @@
       return EXIT_FAILURE;
     }
 
-  if (type == SHUTDOWN_HALT)
-    {
-      result = xfsm_shutdown_helper_send_command (shutdown_helper,
-                                                  XFSM_SHUTDOWN_POWEROFF);
-    }
-  else
-    {
-      result = xfsm_shutdown_helper_send_command (shutdown_helper,
-                                                  XFSM_SHUTDOWN_REBOOT);
-    }
+  result = xfsm_shutdown_helper_send_command (shutdown_helper, shutdownType);
 
   xfsm_shutdown_helper_destroy (shutdown_helper);
   shutdown_helper = NULL;
diff -Nur xfce4-session-4.4.1/xfce4-session/shutdown.h xfce4-session-4.4.1.new/xfce4-session/shutdown.h
--- xfce4-session-4.4.1/xfce4-session/shutdown.h    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/shutdown.h    2007-09-10 15:00:27.000000000 +0200
@@ -24,13 +24,8 @@
 
 #include <glib.h>
 
-/* */
-#define    SHUTDOWN_LOGOUT    0
-#define SHUTDOWN_REBOOT    1
-#define SHUTDOWN_HALT    2
-
 /* prototypes */
-extern gboolean    shutdownDialog(gint *, gboolean *);
-extern gint    xfsm_shutdown(gint);
+extern gboolean    shutdownDialog(gboolean *);
+extern gint    xfsm_shutdown(void);
 
 #endif    /* !__XFSM_SHUTDOWN_H__ */
diff -Nur xfce4-session-4.4.1/xfce4-session/xfsm-global.c xfce4-session-4.4.1.new/xfce4-session/xfsm-global.c
--- xfce4-session-4.4.1/xfce4-session/xfsm-global.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/xfsm-global.c    2007-09-10 15:00:27.000000000 +0200
@@ -46,7 +46,6 @@
 gchar            *session_file = NULL;
 GList            *failsafe_clients = NULL;
 gboolean          failsafe_mode = TRUE;
-gint              shutdown_type = SHUTDOWN_LOGOUT;
 XfsmSplashScreen *splash_screen = NULL;
 
 void
diff -Nur xfce4-session-4.4.1/xfce4-session/xfsm-global.h xfce4-session-4.4.1.new/xfce4-session/xfsm-global.h
--- xfce4-session-4.4.1/xfce4-session/xfsm-global.h    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/xfsm-global.h    2007-09-10 15:00:27.000000000 +0200
@@ -47,7 +47,6 @@
 extern gchar            *session_file;
 extern GList            *failsafe_clients;
 extern gboolean          failsafe_mode;
-extern gint              shutdown_type;
 extern XfsmSplashScreen *splash_screen;
 
 
diff -Nur xfce4-session-4.4.1/xfce4-session/xfsm-manager.c xfce4-session-4.4.1.new/xfce4-session/xfsm-manager.c
--- xfce4-session-4.4.1/xfce4-session/xfsm-manager.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/xfsm-manager.c    2007-09-10 15:00:27.000000000 +0200
@@ -799,7 +799,7 @@
     }
   else
     {
-      if (!fast && shutdown && !shutdownDialog (&shutdown_type, &shutdown_save))
+      if (!fast && shutdown && !shutdownDialog (&shutdown_save))
         return;
   
       if (!shutdown || shutdown_save)
diff -Nur xfce4-session-4.4.1/xfce4-session/xfsm-shutdown-helper.c xfce4-session-4.4.1.new/xfce4-session/xfsm-shutdown-helper.c
--- xfce4-session-4.4.1/xfce4-session/xfsm-shutdown-helper.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/xfsm-shutdown-helper.c    2007-09-10 15:00:27.000000000 +0200
@@ -55,6 +55,12 @@
 
 #ifdef HAVE_DBUS
 #include <dbus/dbus.h>
+#define    HAL_DBUS_SERVICE        "org.freedesktop.Hal"
+#define HAL_ROOT_COMPUTER        "/org/freedesktop/Hal/devices/computer"
+#define    HAL_DBUS_INTERFACE_DEVICE    "org.freedesktop.Hal.Device"
+#define    HAL_DBUS_INTERFACE_POWER    "org.freedesktop.Hal.Device.SystemPowerManagement"
+#define    HAL_PM_CAN_SUSPEND        "power_management.can_suspend_to_ram"
+#define    HAL_PM_CAN_HIBERNATE        "power_management.can_suspend_to_disk"
 #endif
 
 #include <libxfce4util/libxfce4util.h>
@@ -74,6 +80,17 @@
 };
 
 
+static struct
+{ 
+  XfsmShutdownCommand command;
+  gchar * name;
+} xfsm2hal[] =
+{
+           { XFSM_REBOOT,    "Reboot"},
+           { XFSM_SHUTDOWN,  "Shutdown"},
+           { XFSM_SUSPEND,   "Suspend"},
+           { XFSM_HIBERNATE, "Hibernate"}
+};
 
 static gboolean
 xfsm_shutdown_helper_hal_check (XfsmShutdownHelper *helper)
@@ -100,9 +117,9 @@
    * use the org.freedesktop.Hal.Device.SystemPowerManagement
    * interface without shutting down/rebooting now.
    */
-  message = dbus_message_new_method_call ("org.freedesktop.Hal",
-                                          "/org/freedesktop/Hal/devices/computer",
-                                          "org.freedesktop.Hal.Device.SystemPowerManagement",
+  message = dbus_message_new_method_call (HAL_DBUS_SERVICE,
+                                          HAL_ROOT_COMPUTER,
+                                          HAL_DBUS_INTERFACE_POWER,
                                           "ThisMethodMustNotExistInHal");
   result = dbus_connection_send_with_reply_and_block (connection, message, 2000, &error);
   dbus_message_unref (message);
@@ -145,42 +162,45 @@
                                XfsmShutdownCommand command)
 {
 #ifdef HAVE_DBUS
-  DBusConnection *connection;
-  DBusMessage    *message;
-  DBusMessage    *result;
-  DBusError       error;
-
-  /* initialize the error */
-  dbus_error_init (&error);
-
-  /* connect to the system message bus */
-  connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
-  if (G_UNLIKELY (connection == NULL))
-    {
-      g_warning (G_STRLOC ": Failed to connect to the system message bus: %s", error.message);
-      dbus_error_free (&error);
-      return FALSE;
-    }
-
-  /* send the appropriate message to HAL, telling it to shutdown or reboot the system */
-  message = dbus_message_new_method_call ("org.freedesktop.Hal",
-                                          "/org/freedesktop/Hal/devices/computer",
-                                          "org.freedesktop.Hal.Device.SystemPowerManagement",
-                                          (command == XFSM_SHUTDOWN_REBOOT) ? "Reboot" : "Shutdown");
-  result = dbus_connection_send_with_reply_and_block (connection, message, 2000, &error);
-  dbus_message_unref (message);
-
-  /* check if we received a result */
-  if (G_UNLIKELY (result == NULL))
-    {
-      g_warning (G_STRLOC ": Failed to contact HAL: %s", error.message);
-      dbus_error_free (&error);
-      return FALSE;
-    }
-
-  /* pretend that we succeed */
-  dbus_message_unref (result);
-  return TRUE;
+    DBusConnection *connection;
+    DBusMessage *method;
+    DBusMessage *result;
+    DBusError derror;
+    gint i;
+    gchar *methodname;
+    dbus_int32_t wakeup = 0;
+    
+    for (i = 0; i < G_N_ELEMENTS (xfsm2hal); i++) {
+      if ( xfsm2hal[i].command == command ) {
+        methodname = xfsm2hal[i].name;
+      }
+     }
+   
+    dbus_error_init(&derror);
+    
+    connection = dbus_bus_get(DBUS_BUS_SYSTEM, &derror);
+
+    if (connection == NULL)
+        return FALSE;
+    
+    method = dbus_message_new_method_call(HAL_DBUS_SERVICE,
+                                  HAL_ROOT_COMPUTER,
+                      HAL_DBUS_INTERFACE_POWER,
+                      methodname);
+
+    if (command == XFSM_SUSPEND) {
+    dbus_message_append_args (method, DBUS_TYPE_INT32, &wakeup, DBUS_TYPE_INVALID);
+     }
+    
+    result = dbus_connection_send_with_reply_and_block(connection, method, 2000, &derror);
+    
+    dbus_message_unref(method);
+    
+    if (result == NULL)
+    return FALSE;
+    
+    dbus_message_unref(result);
+    return TRUE;
 #else
   return FALSE;
 #endif
diff -Nur xfce4-session-4.4.1/xfce4-session/xfsm-shutdown-helper.h xfce4-session-4.4.1.new/xfce4-session/xfsm-shutdown-helper.h
--- xfce4-session-4.4.1/xfce4-session/xfsm-shutdown-helper.h    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/xfsm-shutdown-helper.h    2007-09-10 15:00:27.000000000 +0200
@@ -27,8 +27,12 @@
 
 typedef enum
 {
-  XFSM_SHUTDOWN_POWEROFF   = 0,
-  XFSM_SHUTDOWN_REBOOT     = 1,
+  XFSM_SWITCH     =-2,
+  XFSM_LOGOUT     =-1,
+  XFSM_SHUTDOWN   = 0,
+  XFSM_REBOOT     = 1,
+  XFSM_SUSPEND    = 2,
+  XFSM_HIBERNATE  = 3,
 } XfsmShutdownCommand;

I have 'succeeded' in taking out the code relating to the switch user functionality, and the patch applies cleanly, the code seems to compile cleanly. However, only four buttons are shown (which means the logout dialog drops the 'suspend' button). I have been playing with the numbers in the typedef enum stuff above, to no avail though. This is what I made of it:

diff -Nur xfce4-session-4.4.1/settings/session/session.c xfce4-session-4.4.1.new/settings/session/session.c
--- xfce4-session-4.4.1/settings/session/session.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/settings/session/session.c    2007-09-10 15:00:27.000000000 +0200
@@ -51,6 +51,8 @@
 static GtkWidget    *general_chooser;
 static GtkWidget    *general_autosave;
 static GtkWidget    *general_prompt;
+static GtkWidget    *general_hibernate_button;
+static GtkWidget    *general_suspend_button;
 static GtkWidget    *advanced_kde;
 static GtkWidget    *advanced_gnome;
 static GtkWidget    *advanced_remote;
@@ -88,6 +90,8 @@
     {
       xfce_rc_write_bool_entry (rc, "AutoSave", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (general_autosave)));
       xfce_rc_write_bool_entry (rc, "PromptOnLogout", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (general_prompt)));
+      xfce_rc_write_bool_entry (rc, "HibernateButton", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (general_hibernate_button)));
+      xfce_rc_write_bool_entry (rc, "SuspendButton", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (general_suspend_button)));
     }
   if (G_LIKELY (kiosk_can_security))
     {
@@ -124,10 +128,14 @@
   gboolean   autosave;
   gboolean   prompt;
   gboolean   chooser;
+  gboolean   hibernate;
+  gboolean   suspend;
 
   xfce_rc_set_group (rc, "General");
   autosave = xfce_rc_read_bool_entry (rc, "AutoSave", FALSE);
   prompt = xfce_rc_read_bool_entry (rc, "PromptOnLogout", TRUE);
+  hibernate = xfce_rc_read_bool_entry (rc, "HibernateButton", TRUE);
+  suspend = xfce_rc_read_bool_entry (rc, "SuspendButton", TRUE);
   xfce_rc_set_group (rc, "Chooser");
   chooser = xfce_rc_read_bool_entry (rc, "AlwaysDisplay", FALSE);
 
@@ -181,6 +189,29 @@
                           "depends on whether you enabled the automatic "
                           "saving of sessions on logout or not."),
                         NULL);
+  
+  general_hibernate_button = gtk_check_button_new_with_label (_("Show hibernate button"));
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (general_hibernate_button), hibernate);
+  g_signal_connect (G_OBJECT (general_hibernate_button), "toggled",
+                    G_CALLBACK (config_store), NULL);
+  gtk_box_pack_start (GTK_BOX (vbox), general_hibernate_button, FALSE, TRUE, 0);
+  gtk_tooltips_set_tip (tooltips, general_hibernate_button,
+                        _("This option adds a hibernate button to the logout dialog. "
+                          "Only enable if you known your system suspends to"
+              "disk and resumes correctly."),
+                        NULL);
+
+  general_suspend_button = gtk_check_button_new_with_label (_("Show suspend button"));
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (general_suspend_button), suspend);
+  g_signal_connect (G_OBJECT (general_suspend_button), "toggled",
+                    G_CALLBACK (config_store), NULL);
+  gtk_box_pack_start (GTK_BOX (vbox), general_suspend_button, FALSE, TRUE, 0);
+  gtk_tooltips_set_tip (tooltips, general_suspend_button,
+                        _("This option adds a suspend button to the logout dialog. "
+                          "Only enable if you known your system suspends to"
+              "RAM and resumes correctly."),
+                        NULL);
+
 
   return page;
 }
diff -Nur xfce4-session-4.4.1/xfce4-session/main.c xfce4-session-4.4.1.new/xfce4-session/main.c
--- xfce4-session-4.4.1/xfce4-session/main.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/main.c    2007-09-10 15:00:27.000000000 +0200
@@ -61,6 +61,11 @@
 #include <xfce4-session/xfsm-manager.h>
 #include <xfce4-session/xfsm-startup.h>
 
+#include <xfce4-session/xfsm-shutdown-helper.h>
+
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
 
 void
 setup_environment (void)
@@ -225,8 +230,6 @@
 int
 main (int argc, char **argv)
 {
-  /* imported from xfsm-manager.c */
-  extern gint shutdown_type;
 
   xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
   
@@ -248,5 +251,5 @@
   
   ice_cleanup ();
 
-  return xfsm_shutdown (shutdown_type);
+  return xfsm_shutdown ();
 }
diff -Nur xfce4-session-4.4.1/xfce4-session/shutdown.c xfce4-session-4.4.1.new/xfce4-session/shutdown.c
--- xfce4-session-4.4.1/xfce4-session/shutdown.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/shutdown.c    2007-09-10 15:01:21.000000000 +0200
@@ -110,34 +110,35 @@
   gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
 }
 
-static void
-logout_button_clicked (GtkWidget *b, gint *shutdownType)
-{
-    *shutdownType = SHUTDOWN_LOGOUT;
-
-    gtk_dialog_response (GTK_DIALOG (shutdown_dialog), GTK_RESPONSE_OK);
-}
+static gint shutdownType = XFSM_LOGOUT;
 
 static void
-reboot_button_clicked (GtkWidget *b, gint *shutdownType)
+logout_dialog_button_clicked (GtkWidget *b, gint *cmd)
 {
-    *shutdownType = SHUTDOWN_REBOOT;
+    shutdownType = *cmd;
 
     gtk_dialog_response (GTK_DIALOG (shutdown_dialog), GTK_RESPONSE_OK);
 }
 
-static void
-halt_button_clicked (GtkWidget *b, gint *shutdownType)
+struct LogoutButton
 {
-    *shutdownType = SHUTDOWN_HALT;
-
-    gtk_dialog_response (GTK_DIALOG (shutdown_dialog), GTK_RESPONSE_OK);
-}
+    gchar * label;
+    gchar * icon;
+    gint    cmd;
+    gboolean present;
+    GtkWidget * button;
+};
+
+struct LogoutButton logout_buttons [] = {
+ { N_("Log out"), "xfsm-logout", XFSM_LOGOUT, TRUE },
+ { N_("Restart"), "xfsm-reboot", XFSM_REBOOT, TRUE },
+ { N_("Shut down"), "xfsm-shutdown", XFSM_SHUTDOWN, TRUE },
+ { N_("Suspend"), "xfsm-suspend", XFSM_SUSPEND, FALSE},
+ { N_("Hibernate"), "xfsm-hibernate", XFSM_HIBERNATE, FALSE},
+};
 
-/*
- */
 gboolean
-shutdownDialog(gint *shutdownType, gboolean *saveSession)
+shutdownDialog(gboolean *saveSession)
 {
   gboolean accessibility;
   XfsmFadeout *fadeout = NULL;
@@ -145,7 +147,9 @@
   GtkWidget *dialog;
   GtkWidget *label;
   GtkWidget *dbox;
+  GtkWidget *rbox;
   GtkWidget *hbox;
+  GtkWidget *hbox2;
   GtkWidget *vbox;
   GtkWidget *vbox2;
   GtkWidget *image;
@@ -154,14 +158,14 @@
   GtkWidget *entry;
   GtkWidget *hidden;
   GtkWidget *logout_button;
-  GtkWidget *reboot_button;
-  GtkWidget *halt_button;
   GtkWidget *cancel_button;
   GtkWidget *ok_button;
   GdkPixbuf *icon;
   gboolean saveonexit;
   gboolean autosave;
   gboolean prompt;
+  gboolean have_suspend;
+  gboolean have_hibernate;
   gint monitor;
   gint result;
   XfceKiosk *kiosk;
@@ -173,9 +177,8 @@
   GdkPixmap *screenshot_pm = NULL;
   GdkGC *screenshot_gc;
 #endif
-
+  gint i;
   g_return_val_if_fail(saveSession != NULL, FALSE);
-  g_return_val_if_fail(shutdownType != NULL, FALSE);
 
   /* destroy any previously running shutdown helper first */
   if (shutdown_helper != NULL)
@@ -195,13 +198,15 @@
   saveonexit = xfce_rc_read_bool_entry (rc, "SaveOnExit", TRUE);
   autosave = xfce_rc_read_bool_entry (rc, "AutoSave", FALSE);
   prompt = xfce_rc_read_bool_entry (rc, "PromptOnLogout", TRUE);
+  have_suspend = xfce_rc_read_bool_entry (rc, "SuspendButton", TRUE);
+  have_hibernate = xfce_rc_read_bool_entry (rc, "HibernateButton", TRUE);
 
   /* if PromptOnLogout is off, saving depends on AutoSave */
   if (!prompt)
     {
       xfce_rc_close (rc);
 
-      *shutdownType = SHUTDOWN_LOGOUT;
+      shutdownType = XFSM_LOGOUT;
       *saveSession = autosave;
 
       return TRUE;
@@ -311,76 +316,43 @@
   hbox = gtk_hbox_new (TRUE, BORDER);
   gtk_widget_show (hbox);
   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+  hbox2 = gtk_hbox_new (TRUE, BORDER);
+  gtk_widget_show (hbox2);
+  gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
+  logout_buttons[4].present = have_suspend;
+  logout_buttons[5].present = have_hibernate;
   
-  /* logout */
-  logout_button = gtk_button_new ();
-  gtk_widget_show (logout_button);
-  gtk_box_pack_start (GTK_BOX (hbox), logout_button, TRUE, TRUE, 0);
-
-  g_signal_connect (logout_button, "clicked", 
-                    G_CALLBACK (logout_button_clicked), shutdownType);
-
-  vbox2 = gtk_vbox_new (FALSE, BORDER);
-  gtk_container_set_border_width (GTK_CONTAINER (vbox2), BORDER);
-  gtk_widget_show (vbox2);
-  gtk_container_add (GTK_CONTAINER (logout_button), vbox2);
-
-  icon = xfce_themed_icon_load ("xfsm-logout", 32);
-  image = gtk_image_new_from_pixbuf (icon);
-  gtk_widget_show (image);
-  gtk_box_pack_start (GTK_BOX (vbox2), image, FALSE, FALSE, 0);
-  g_object_unref (icon);
-
-  label = gtk_label_new (_("Log Out"));
-  gtk_widget_show (label);
-  gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
-  
-  /* reboot */
-  reboot_button = gtk_button_new ();
-  gtk_widget_show (reboot_button);
-  gtk_box_pack_start (GTK_BOX (hbox), reboot_button, TRUE, TRUE, 0);
-
-  g_signal_connect (reboot_button, "clicked", 
-                    G_CALLBACK (reboot_button_clicked), shutdownType);
-
-  vbox2 = gtk_vbox_new (FALSE, BORDER);
-  gtk_container_set_border_width (GTK_CONTAINER (vbox2), BORDER);
-  gtk_widget_show (vbox2);
-  gtk_container_add (GTK_CONTAINER (reboot_button), vbox2);
-
-  icon = xfce_themed_icon_load ("xfsm-reboot", 32);
-  image = gtk_image_new_from_pixbuf (icon);
-  gtk_widget_show (image);
-  gtk_box_pack_start (GTK_BOX (vbox2), image, FALSE, FALSE, 0);
-  g_object_unref (icon);
-
-  label = gtk_label_new (_("Restart"));
-  gtk_widget_show (label);
-  gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
-  
-  /* halt */
-  halt_button = gtk_button_new ();
-  gtk_widget_show (halt_button);
-  gtk_box_pack_start (GTK_BOX (hbox), halt_button, TRUE, TRUE, 0);
-
-  g_signal_connect (halt_button, "clicked", 
-                    G_CALLBACK (halt_button_clicked), shutdownType);
-
-  vbox2 = gtk_vbox_new (FALSE, BORDER);
-  gtk_container_set_border_width (GTK_CONTAINER (vbox2), BORDER);
-  gtk_widget_show (vbox2);
-  gtk_container_add (GTK_CONTAINER (halt_button), vbox2);
-
-  icon = xfce_themed_icon_load ("xfsm-shutdown", 32);
-  image = gtk_image_new_from_pixbuf (icon);
-  gtk_widget_show (image);
-  gtk_box_pack_start (GTK_BOX (vbox2), image, FALSE, FALSE, 0);
-  g_object_unref (icon);
-  
-  label = gtk_label_new (_("Shut Down"));
-  gtk_widget_show (label);
-  gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
-  
+  for (i = 0; i < G_N_ELEMENTS (logout_buttons); i++) { 
+      
+    if (logout_buttons[i].present == FALSE)
+       continue;        
+    
+    logout_button = gtk_button_new ();
+    gtk_widget_show (logout_button);
+    rbox = i > G_N_ELEMENTS (logout_buttons)/2 - 1 ? hbox2 : hbox;
+    gtk_box_pack_start (GTK_BOX (rbox), logout_button, TRUE, TRUE, 0);
+
+    g_signal_connect (logout_button, "clicked", 
+              G_CALLBACK (logout_dialog_button_clicked), &logout_buttons[i].cmd);
+
+    vbox2 = gtk_vbox_new (FALSE, BORDER);
+    gtk_container_set_border_width (GTK_CONTAINER (vbox2), BORDER);
+    gtk_widget_show (vbox2);
+    gtk_container_add (GTK_CONTAINER (logout_button), vbox2);
+
+    icon = xfce_themed_icon_load (logout_buttons[i].icon, 32);
+    image = gtk_image_new_from_pixbuf (icon);
+    gtk_widget_show (image);
+    gtk_box_pack_start (GTK_BOX (vbox2), image, FALSE, FALSE, 0);
+    g_object_unref (icon);
+
+    label = gtk_label_new (_(logout_buttons[i].label));
+    gtk_widget_show (label);
+    gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
+
+    logout_buttons[i].button = logout_button;
+  }
+ 
   /* save session */
   if (!autosave)
     {
@@ -406,8 +378,9 @@
   if (!kiosk_can_shutdown || 
       (shutdown_helper = xfsm_shutdown_helper_spawn ()) == NULL)
     {
-      gtk_widget_set_sensitive (reboot_button, FALSE);
-      gtk_widget_set_sensitive (halt_button, FALSE);
+      for (i = 2; i < G_N_ELEMENTS (logout_buttons); i++) { 
+          gtk_widget_set_sensitive (logout_buttons[i].button, FALSE);
+      }
     }
 
   /* save portion of the root window covered by the dialog */
@@ -437,7 +410,8 @@
   gtk_widget_hide (dialog);
 
   /* ask password */
-  if (result == GTK_RESPONSE_OK && *shutdownType != SHUTDOWN_LOGOUT
+  if (result == GTK_RESPONSE_OK
+      && shutdownType != XFSM_LOGOUT
       && xfsm_shutdown_helper_need_password (shutdown_helper))
     {
       gtk_widget_show (ok_button);
@@ -533,6 +508,16 @@
       gdk_flush ();
     }
 
+  /*
+   * For suspend/hibernate perform the action but do not
+   * close the session so it is still there on resume
+   */
+  if (result == GTK_RESPONSE_OK
+          && (shutdownType == XFSM_SUSPEND || shutdownType == XFSM_HIBERNATE)) {
+      xfsm_shutdown_helper_send_command (shutdown_helper, shutdownType);
+      return FALSE;
+  }
+ 
   /* process all pending events first */
   while (gtk_events_pending ())
     g_main_context_iteration (NULL, FALSE);
@@ -571,7 +561,7 @@
 /*
  */
 gint
-xfsm_shutdown(gint type)
+xfsm_shutdown(void)
 {
   gboolean result;
 
@@ -589,7 +579,7 @@
   sync ();
 #endif
 
-  if (type == SHUTDOWN_LOGOUT)
+  if (shutdownType == XFSM_LOGOUT)
     return EXIT_SUCCESS;
 
   if (shutdown_helper == NULL)
@@ -598,16 +588,7 @@
       return EXIT_FAILURE;
     }
 
-  if (type == SHUTDOWN_HALT)
-    {
-      result = xfsm_shutdown_helper_send_command (shutdown_helper,
-                                                  XFSM_SHUTDOWN_POWEROFF);
-    }
-  else
-    {
-      result = xfsm_shutdown_helper_send_command (shutdown_helper,
-                                                  XFSM_SHUTDOWN_REBOOT);
-    }
+  result = xfsm_shutdown_helper_send_command (shutdown_helper, shutdownType);
 
   xfsm_shutdown_helper_destroy (shutdown_helper);
   shutdown_helper = NULL;
diff -Nur xfce4-session-4.4.1/xfce4-session/shutdown.h xfce4-session-4.4.1.new/xfce4-session/shutdown.h
--- xfce4-session-4.4.1/xfce4-session/shutdown.h    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/shutdown.h    2007-09-10 15:00:27.000000000 +0200
@@ -24,13 +24,8 @@
 
 #include <glib.h>
 
-/* */
-#define    SHUTDOWN_LOGOUT    0
-#define SHUTDOWN_REBOOT    1
-#define SHUTDOWN_HALT    2
-
 /* prototypes */
-extern gboolean    shutdownDialog(gint *, gboolean *);
-extern gint    xfsm_shutdown(gint);
+extern gboolean    shutdownDialog(gboolean *);
+extern gint    xfsm_shutdown(void);
 
 #endif    /* !__XFSM_SHUTDOWN_H__ */
diff -Nur xfce4-session-4.4.1/xfce4-session/xfsm-global.c xfce4-session-4.4.1.new/xfce4-session/xfsm-global.c
--- xfce4-session-4.4.1/xfce4-session/xfsm-global.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/xfsm-global.c    2007-09-10 15:00:27.000000000 +0200
@@ -46,7 +46,6 @@
 gchar            *session_file = NULL;
 GList            *failsafe_clients = NULL;
 gboolean          failsafe_mode = TRUE;
-gint              shutdown_type = SHUTDOWN_LOGOUT;
 XfsmSplashScreen *splash_screen = NULL;
 
 void
diff -Nur xfce4-session-4.4.1/xfce4-session/xfsm-global.h xfce4-session-4.4.1.new/xfce4-session/xfsm-global.h
--- xfce4-session-4.4.1/xfce4-session/xfsm-global.h    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/xfsm-global.h    2007-09-10 15:00:27.000000000 +0200
@@ -47,7 +47,6 @@
 extern gchar            *session_file;
 extern GList            *failsafe_clients;
 extern gboolean          failsafe_mode;
-extern gint              shutdown_type;
 extern XfsmSplashScreen *splash_screen;
 
 
diff -Nur xfce4-session-4.4.1/xfce4-session/xfsm-manager.c xfce4-session-4.4.1.new/xfce4-session/xfsm-manager.c
--- xfce4-session-4.4.1/xfce4-session/xfsm-manager.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/xfsm-manager.c    2007-09-10 15:00:27.000000000 +0200
@@ -799,7 +799,7 @@
     }
   else
     {
-      if (!fast && shutdown && !shutdownDialog (&shutdown_type, &shutdown_save))
+      if (!fast && shutdown && !shutdownDialog (&shutdown_save))
         return;
   
       if (!shutdown || shutdown_save)
diff -Nur xfce4-session-4.4.1/xfce4-session/xfsm-shutdown-helper.c xfce4-session-4.4.1.new/xfce4-session/xfsm-shutdown-helper.c
--- xfce4-session-4.4.1/xfce4-session/xfsm-shutdown-helper.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/xfsm-shutdown-helper.c    2007-09-10 15:00:27.000000000 +0200
@@ -55,6 +55,12 @@
 
 #ifdef HAVE_DBUS
 #include <dbus/dbus.h>
+#define    HAL_DBUS_SERVICE        "org.freedesktop.Hal"
+#define HAL_ROOT_COMPUTER        "/org/freedesktop/Hal/devices/computer"
+#define    HAL_DBUS_INTERFACE_DEVICE    "org.freedesktop.Hal.Device"
+#define    HAL_DBUS_INTERFACE_POWER    "org.freedesktop.Hal.Device.SystemPowerManagement"
+#define    HAL_PM_CAN_SUSPEND        "power_management.can_suspend_to_ram"
+#define    HAL_PM_CAN_HIBERNATE        "power_management.can_suspend_to_disk"
 #endif
 
 #include <libxfce4util/libxfce4util.h>
@@ -74,6 +80,17 @@
 };
 
 
+static struct
+{ 
+  XfsmShutdownCommand command;
+  gchar * name;
+} xfsm2hal[] =
+{
+           { XFSM_REBOOT,    "Reboot"},
+           { XFSM_SHUTDOWN,  "Shutdown"},
+           { XFSM_SUSPEND,   "Suspend"},
+           { XFSM_HIBERNATE, "Hibernate"}
+};
 
 static gboolean
 xfsm_shutdown_helper_hal_check (XfsmShutdownHelper *helper)
@@ -100,9 +117,9 @@
    * use the org.freedesktop.Hal.Device.SystemPowerManagement
    * interface without shutting down/rebooting now.
    */
-  message = dbus_message_new_method_call ("org.freedesktop.Hal",
-                                          "/org/freedesktop/Hal/devices/computer",
-                                          "org.freedesktop.Hal.Device.SystemPowerManagement",
+  message = dbus_message_new_method_call (HAL_DBUS_SERVICE,
+                                          HAL_ROOT_COMPUTER,
+                                          HAL_DBUS_INTERFACE_POWER,
                                           "ThisMethodMustNotExistInHal");
   result = dbus_connection_send_with_reply_and_block (connection, message, 2000, &error);
   dbus_message_unref (message);
@@ -145,42 +162,45 @@
                                XfsmShutdownCommand command)
 {
 #ifdef HAVE_DBUS
-  DBusConnection *connection;
-  DBusMessage    *message;
-  DBusMessage    *result;
-  DBusError       error;
-
-  /* initialize the error */
-  dbus_error_init (&error);
-
-  /* connect to the system message bus */
-  connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
-  if (G_UNLIKELY (connection == NULL))
-    {
-      g_warning (G_STRLOC ": Failed to connect to the system message bus: %s", error.message);
-      dbus_error_free (&error);
-      return FALSE;
-    }
-
-  /* send the appropriate message to HAL, telling it to shutdown or reboot the system */
-  message = dbus_message_new_method_call ("org.freedesktop.Hal",
-                                          "/org/freedesktop/Hal/devices/computer",
-                                          "org.freedesktop.Hal.Device.SystemPowerManagement",
-                                          (command == XFSM_SHUTDOWN_REBOOT) ? "Reboot" : "Shutdown");
-  result = dbus_connection_send_with_reply_and_block (connection, message, 2000, &error);
-  dbus_message_unref (message);
-
-  /* check if we received a result */
-  if (G_UNLIKELY (result == NULL))
-    {
-      g_warning (G_STRLOC ": Failed to contact HAL: %s", error.message);
-      dbus_error_free (&error);
-      return FALSE;
-    }
-
-  /* pretend that we succeed */
-  dbus_message_unref (result);
-  return TRUE;
+    DBusConnection *connection;
+    DBusMessage *method;
+    DBusMessage *result;
+    DBusError derror;
+    gint i;
+    gchar *methodname;
+    dbus_int32_t wakeup = 0;
+    
+    for (i = 0; i < G_N_ELEMENTS (xfsm2hal); i++) {
+      if ( xfsm2hal[i].command == command ) {
+        methodname = xfsm2hal[i].name;
+      }
+     }
+   
+    dbus_error_init(&derror);
+    
+    connection = dbus_bus_get(DBUS_BUS_SYSTEM, &derror);
+
+    if (connection == NULL)
+        return FALSE;
+    
+    method = dbus_message_new_method_call(HAL_DBUS_SERVICE,
+                                  HAL_ROOT_COMPUTER,
+                      HAL_DBUS_INTERFACE_POWER,
+                      methodname);
+
+    if (command == XFSM_SUSPEND) {
+    dbus_message_append_args (method, DBUS_TYPE_INT32, &wakeup, DBUS_TYPE_INVALID);
+     }
+    
+    result = dbus_connection_send_with_reply_and_block(connection, method, 2000, &derror);
+    
+    dbus_message_unref(method);
+    
+    if (result == NULL)
+    return FALSE;
+    
+    dbus_message_unref(result);
+    return TRUE;
 #else
   return FALSE;
 #endif
diff -Nur xfce4-session-4.4.1/xfce4-session/xfsm-shutdown-helper.h xfce4-session-4.4.1.new/xfce4-session/xfsm-shutdown-helper.h
--- xfce4-session-4.4.1/xfce4-session/xfsm-shutdown-helper.h    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/xfsm-shutdown-helper.h    2007-09-10 15:00:27.000000000 +0200
@@ -27,8 +27,11 @@
 
 typedef enum
 {
-  XFSM_SHUTDOWN_POWEROFF   = 0,
-  XFSM_SHUTDOWN_REBOOT     = 1,
+  XFSM_LOGOUT     =-2,
+  XFSM_SHUTDOWN   =-1,
+  XFSM_REBOOT     = 0,
+  XFSM_SUSPEND    = 1,
+  XFSM_HIBERNATE  = 2,
 } XfsmShutdownCommand;

Is there some C master who can point me in the right direction?

Last edited by B (2007-09-26 03:24:53)


Got Leenucks? :: Arch: Power in simplicity :: Get Counted! Registered Linux User #392717 :: Blog thingy

Offline

#2 2007-09-27 01:49:38

.:B:.
Forum Fellow
Registered: 2006-11-26
Posts: 5,819
Website

Re: Integrate suspend & hibernate buttons into XFCE logout dialog

Well, I bugged some C coders, and it just seems the logout_buttons [] thingy was hardcoded, while it should not. For those interested in five fancy buttons in their logout screen, here's the patch:

diff -Nur xfce4-session-4.4.1/settings/session/session.c xfce4-session-4.4.1.new/settings/session/session.c
--- xfce4-session-4.4.1/settings/session/session.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/settings/session/session.c    2007-09-10 15:00:27.000000000 +0200
@@ -51,6 +51,8 @@
 static GtkWidget    *general_chooser;
 static GtkWidget    *general_autosave;
 static GtkWidget    *general_prompt;
+static GtkWidget    *general_hibernate_button;
+static GtkWidget    *general_suspend_button;
 static GtkWidget    *advanced_kde;
 static GtkWidget    *advanced_gnome;
 static GtkWidget    *advanced_remote;
@@ -88,6 +90,8 @@
     {
       xfce_rc_write_bool_entry (rc, "AutoSave", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (general_autosave)));
       xfce_rc_write_bool_entry (rc, "PromptOnLogout", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (general_prompt)));
+      xfce_rc_write_bool_entry (rc, "HibernateButton", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (general_hibernate_button)));
+      xfce_rc_write_bool_entry (rc, "SuspendButton", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (general_suspend_button)));
     }
   if (G_LIKELY (kiosk_can_security))
     {
@@ -124,10 +128,14 @@
   gboolean   autosave;
   gboolean   prompt;
   gboolean   chooser;
+  gboolean   hibernate;
+  gboolean   suspend;
 
   xfce_rc_set_group (rc, "General");
   autosave = xfce_rc_read_bool_entry (rc, "AutoSave", FALSE);
   prompt = xfce_rc_read_bool_entry (rc, "PromptOnLogout", TRUE);
+  hibernate = xfce_rc_read_bool_entry (rc, "HibernateButton", TRUE);
+  suspend = xfce_rc_read_bool_entry (rc, "SuspendButton", TRUE);
   xfce_rc_set_group (rc, "Chooser");
   chooser = xfce_rc_read_bool_entry (rc, "AlwaysDisplay", FALSE);
 
@@ -181,6 +189,29 @@
                           "depends on whether you enabled the automatic "
                           "saving of sessions on logout or not."),
                         NULL);
+  
+  general_hibernate_button = gtk_check_button_new_with_label (_("Show hibernate button"));
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (general_hibernate_button), hibernate);
+  g_signal_connect (G_OBJECT (general_hibernate_button), "toggled",
+                    G_CALLBACK (config_store), NULL);
+  gtk_box_pack_start (GTK_BOX (vbox), general_hibernate_button, FALSE, TRUE, 0);
+  gtk_tooltips_set_tip (tooltips, general_hibernate_button,
+                        _("This option adds a hibernate button to the logout dialog. "
+                          "Only enable if you known your system suspends to"
+              "disk and resumes correctly."),
+                        NULL);
+
+  general_suspend_button = gtk_check_button_new_with_label (_("Show suspend button"));
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (general_suspend_button), suspend);
+  g_signal_connect (G_OBJECT (general_suspend_button), "toggled",
+                    G_CALLBACK (config_store), NULL);
+  gtk_box_pack_start (GTK_BOX (vbox), general_suspend_button, FALSE, TRUE, 0);
+  gtk_tooltips_set_tip (tooltips, general_suspend_button,
+                        _("This option adds a suspend button to the logout dialog. "
+                          "Only enable if you known your system suspends to"
+              "RAM and resumes correctly."),
+                        NULL);
+
 
   return page;
 }
diff -Nur xfce4-session-4.4.1/xfce4-session/main.c xfce4-session-4.4.1.new/xfce4-session/main.c
--- xfce4-session-4.4.1/xfce4-session/main.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/main.c    2007-09-10 15:00:27.000000000 +0200
@@ -61,6 +61,11 @@
 #include <xfce4-session/xfsm-manager.h>
 #include <xfce4-session/xfsm-startup.h>
 
+#include <xfce4-session/xfsm-shutdown-helper.h>
+
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
 
 void
 setup_environment (void)
@@ -225,8 +230,6 @@
 int
 main (int argc, char **argv)
 {
-  /* imported from xfsm-manager.c */
-  extern gint shutdown_type;
 
   xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
   
@@ -248,5 +251,5 @@
   
   ice_cleanup ();
 
-  return xfsm_shutdown (shutdown_type);
+  return xfsm_shutdown ();
 }
diff -Nur xfce4-session-4.4.1/xfce4-session/shutdown.c xfce4-session-4.4.1.new/xfce4-session/shutdown.c
--- xfce4-session-4.4.1/xfce4-session/shutdown.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/shutdown.c    2007-09-10 15:01:21.000000000 +0200
@@ -110,34 +110,35 @@
   gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
 }
 
-static void
-logout_button_clicked (GtkWidget *b, gint *shutdownType)
-{
-    *shutdownType = SHUTDOWN_LOGOUT;
-
-    gtk_dialog_response (GTK_DIALOG (shutdown_dialog), GTK_RESPONSE_OK);
-}
+static gint shutdownType = XFSM_LOGOUT;
 
 static void
-reboot_button_clicked (GtkWidget *b, gint *shutdownType)
+logout_dialog_button_clicked (GtkWidget *b, gint *cmd)
 {
-    *shutdownType = SHUTDOWN_REBOOT;
+    shutdownType = *cmd;
 
     gtk_dialog_response (GTK_DIALOG (shutdown_dialog), GTK_RESPONSE_OK);
 }
 
-static void
-halt_button_clicked (GtkWidget *b, gint *shutdownType)
+struct LogoutButton
 {
-    *shutdownType = SHUTDOWN_HALT;
-
-    gtk_dialog_response (GTK_DIALOG (shutdown_dialog), GTK_RESPONSE_OK);
-}
+    gchar * label;
+    gchar * icon;
+    gint    cmd;
+    gboolean present;
+    GtkWidget * button;
+};
+
+struct LogoutButton logout_buttons [] = {
+ { N_("Log out"), "xfsm-logout", XFSM_LOGOUT, TRUE },
+ { N_("Restart"), "xfsm-reboot", XFSM_REBOOT, TRUE },
+ { N_("Shut down"), "xfsm-shutdown", XFSM_SHUTDOWN, TRUE },
+ { N_("Suspend"), "xfsm-suspend", XFSM_SUSPEND, FALSE},
+ { N_("Hibernate"), "xfsm-hibernate", XFSM_HIBERNATE, FALSE},
+};
 
-/*
- */
 gboolean
-shutdownDialog(gint *shutdownType, gboolean *saveSession)
+shutdownDialog(gboolean *saveSession)
 {
   gboolean accessibility;
   XfsmFadeout *fadeout = NULL;
@@ -145,7 +147,9 @@
   GtkWidget *dialog;
   GtkWidget *label;
   GtkWidget *dbox;
+  GtkWidget *rbox;
   GtkWidget *hbox;
+  GtkWidget *hbox2;
   GtkWidget *vbox;
   GtkWidget *vbox2;
   GtkWidget *image;
@@ -154,14 +158,14 @@
   GtkWidget *entry;
   GtkWidget *hidden;
   GtkWidget *logout_button;
-  GtkWidget *reboot_button;
-  GtkWidget *halt_button;
   GtkWidget *cancel_button;
   GtkWidget *ok_button;
   GdkPixbuf *icon;
   gboolean saveonexit;
   gboolean autosave;
   gboolean prompt;
+  gboolean have_suspend;
+  gboolean have_hibernate;
   gint monitor;
   gint result;
   XfceKiosk *kiosk;
@@ -173,9 +177,8 @@
   GdkPixmap *screenshot_pm = NULL;
   GdkGC *screenshot_gc;
 #endif
-
+  gint i;
   g_return_val_if_fail(saveSession != NULL, FALSE);
-  g_return_val_if_fail(shutdownType != NULL, FALSE);
 
   /* destroy any previously running shutdown helper first */
   if (shutdown_helper != NULL)
@@ -195,13 +198,15 @@
   saveonexit = xfce_rc_read_bool_entry (rc, "SaveOnExit", TRUE);
   autosave = xfce_rc_read_bool_entry (rc, "AutoSave", FALSE);
   prompt = xfce_rc_read_bool_entry (rc, "PromptOnLogout", TRUE);
+  have_suspend = xfce_rc_read_bool_entry (rc, "SuspendButton", TRUE);
+  have_hibernate = xfce_rc_read_bool_entry (rc, "HibernateButton", TRUE);
 
   /* if PromptOnLogout is off, saving depends on AutoSave */
   if (!prompt)
     {
       xfce_rc_close (rc);
 
-      *shutdownType = SHUTDOWN_LOGOUT;
+      shutdownType = XFSM_LOGOUT;
       *saveSession = autosave;
 
       return TRUE;
@@ -311,76 +316,44 @@
   hbox = gtk_hbox_new (TRUE, BORDER);
   gtk_widget_show (hbox);
   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+  hbox2 = gtk_hbox_new (TRUE, BORDER);
+  gtk_widget_show (hbox2);
+  gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
+  /* shouldn't be hardcoded, but since I don't know C, I'll leave it like that */
+  logout_buttons[3].present = have_suspend;
+  logout_buttons[4].present = have_hibernate;
   
-  /* logout */
-  logout_button = gtk_button_new ();
-  gtk_widget_show (logout_button);
-  gtk_box_pack_start (GTK_BOX (hbox), logout_button, TRUE, TRUE, 0);
-
-  g_signal_connect (logout_button, "clicked", 
-                    G_CALLBACK (logout_button_clicked), shutdownType);
-
-  vbox2 = gtk_vbox_new (FALSE, BORDER);
-  gtk_container_set_border_width (GTK_CONTAINER (vbox2), BORDER);
-  gtk_widget_show (vbox2);
-  gtk_container_add (GTK_CONTAINER (logout_button), vbox2);
-
-  icon = xfce_themed_icon_load ("xfsm-logout", 32);
-  image = gtk_image_new_from_pixbuf (icon);
-  gtk_widget_show (image);
-  gtk_box_pack_start (GTK_BOX (vbox2), image, FALSE, FALSE, 0);
-  g_object_unref (icon);
-
-  label = gtk_label_new (_("Log Out"));
-  gtk_widget_show (label);
-  gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
-  
-  /* reboot */
-  reboot_button = gtk_button_new ();
-  gtk_widget_show (reboot_button);
-  gtk_box_pack_start (GTK_BOX (hbox), reboot_button, TRUE, TRUE, 0);
-
-  g_signal_connect (reboot_button, "clicked", 
-                    G_CALLBACK (reboot_button_clicked), shutdownType);
-
-  vbox2 = gtk_vbox_new (FALSE, BORDER);
-  gtk_container_set_border_width (GTK_CONTAINER (vbox2), BORDER);
-  gtk_widget_show (vbox2);
-  gtk_container_add (GTK_CONTAINER (reboot_button), vbox2);
-
-  icon = xfce_themed_icon_load ("xfsm-reboot", 32);
-  image = gtk_image_new_from_pixbuf (icon);
-  gtk_widget_show (image);
-  gtk_box_pack_start (GTK_BOX (vbox2), image, FALSE, FALSE, 0);
-  g_object_unref (icon);
-
-  label = gtk_label_new (_("Restart"));
-  gtk_widget_show (label);
-  gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
-  
-  /* halt */
-  halt_button = gtk_button_new ();
-  gtk_widget_show (halt_button);
-  gtk_box_pack_start (GTK_BOX (hbox), halt_button, TRUE, TRUE, 0);
-
-  g_signal_connect (halt_button, "clicked", 
-                    G_CALLBACK (halt_button_clicked), shutdownType);
-
-  vbox2 = gtk_vbox_new (FALSE, BORDER);
-  gtk_container_set_border_width (GTK_CONTAINER (vbox2), BORDER);
-  gtk_widget_show (vbox2);
-  gtk_container_add (GTK_CONTAINER (halt_button), vbox2);
-
-  icon = xfce_themed_icon_load ("xfsm-shutdown", 32);
-  image = gtk_image_new_from_pixbuf (icon);
-  gtk_widget_show (image);
-  gtk_box_pack_start (GTK_BOX (vbox2), image, FALSE, FALSE, 0);
-  g_object_unref (icon);
-  
-  label = gtk_label_new (_("Shut Down"));
-  gtk_widget_show (label);
-  gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
-  
+  for (i = 0; i < G_N_ELEMENTS (logout_buttons); i++) { 
+      
+    if (logout_buttons[i].present == FALSE)
+       continue;        
+    
+    logout_button = gtk_button_new ();
+    gtk_widget_show (logout_button);
+    rbox = i > G_N_ELEMENTS (logout_buttons)/2 - 1 ? hbox2 : hbox;
+    gtk_box_pack_start (GTK_BOX (rbox), logout_button, TRUE, TRUE, 0);
+
+    g_signal_connect (logout_button, "clicked", 
+              G_CALLBACK (logout_dialog_button_clicked), &logout_buttons[i].cmd);
+
+    vbox2 = gtk_vbox_new (FALSE, BORDER);
+    gtk_container_set_border_width (GTK_CONTAINER (vbox2), BORDER);
+    gtk_widget_show (vbox2);
+    gtk_container_add (GTK_CONTAINER (logout_button), vbox2);
+
+    icon = xfce_themed_icon_load (logout_buttons[i].icon, 32);
+    image = gtk_image_new_from_pixbuf (icon);
+    gtk_widget_show (image);
+    gtk_box_pack_start (GTK_BOX (vbox2), image, FALSE, FALSE, 0);
+    g_object_unref (icon);
+
+    label = gtk_label_new (_(logout_buttons[i].label));
+    gtk_widget_show (label);
+    gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
+
+    logout_buttons[i].button = logout_button;
+  }
+ 
   /* save session */
   if (!autosave)
     {
@@ -406,8 +378,9 @@
   if (!kiosk_can_shutdown || 
       (shutdown_helper = xfsm_shutdown_helper_spawn ()) == NULL)
     {
-      gtk_widget_set_sensitive (reboot_button, FALSE);
-      gtk_widget_set_sensitive (halt_button, FALSE);
+      for (i = 2; i < G_N_ELEMENTS (logout_buttons); i++) { 
+          gtk_widget_set_sensitive (logout_buttons[i].button, FALSE);
+      }
     }
 
   /* save portion of the root window covered by the dialog */
@@ -437,7 +410,8 @@
   gtk_widget_hide (dialog);
 
   /* ask password */
-  if (result == GTK_RESPONSE_OK && *shutdownType != SHUTDOWN_LOGOUT
+  if (result == GTK_RESPONSE_OK
+      && shutdownType != XFSM_LOGOUT
       && xfsm_shutdown_helper_need_password (shutdown_helper))
     {
       gtk_widget_show (ok_button);
@@ -533,6 +508,16 @@
       gdk_flush ();
     }
 
+  /*
+   * For suspend/hibernate perform the action but do not
+   * close the session so it is still there on resume
+   */
+  if (result == GTK_RESPONSE_OK
+          && (shutdownType == XFSM_SUSPEND || shutdownType == XFSM_HIBERNATE)) {
+      xfsm_shutdown_helper_send_command (shutdown_helper, shutdownType);
+      return FALSE;
+  }
+ 
   /* process all pending events first */
   while (gtk_events_pending ())
     g_main_context_iteration (NULL, FALSE);
@@ -571,7 +561,7 @@
 /*
  */
 gint
-xfsm_shutdown(gint type)
+xfsm_shutdown(void)
 {
   gboolean result;
 
@@ -589,7 +579,7 @@
   sync ();
 #endif
 
-  if (type == SHUTDOWN_LOGOUT)
+  if (shutdownType == XFSM_LOGOUT)
     return EXIT_SUCCESS;
 
   if (shutdown_helper == NULL)
@@ -598,16 +588,7 @@
       return EXIT_FAILURE;
     }
 
-  if (type == SHUTDOWN_HALT)
-    {
-      result = xfsm_shutdown_helper_send_command (shutdown_helper,
-                                                  XFSM_SHUTDOWN_POWEROFF);
-    }
-  else
-    {
-      result = xfsm_shutdown_helper_send_command (shutdown_helper,
-                                                  XFSM_SHUTDOWN_REBOOT);
-    }
+  result = xfsm_shutdown_helper_send_command (shutdown_helper, shutdownType);
 
   xfsm_shutdown_helper_destroy (shutdown_helper);
   shutdown_helper = NULL;
diff -Nur xfce4-session-4.4.1/xfce4-session/shutdown.h xfce4-session-4.4.1.new/xfce4-session/shutdown.h
--- xfce4-session-4.4.1/xfce4-session/shutdown.h    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/shutdown.h    2007-09-10 15:00:27.000000000 +0200
@@ -24,13 +24,8 @@
 
 #include <glib.h>
 
-/* */
-#define    SHUTDOWN_LOGOUT    0
-#define SHUTDOWN_REBOOT    1
-#define SHUTDOWN_HALT    2
-
 /* prototypes */
-extern gboolean    shutdownDialog(gint *, gboolean *);
-extern gint    xfsm_shutdown(gint);
+extern gboolean    shutdownDialog(gboolean *);
+extern gint    xfsm_shutdown(void);
 
 #endif    /* !__XFSM_SHUTDOWN_H__ */
diff -Nur xfce4-session-4.4.1/xfce4-session/xfsm-global.c xfce4-session-4.4.1.new/xfce4-session/xfsm-global.c
--- xfce4-session-4.4.1/xfce4-session/xfsm-global.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/xfsm-global.c    2007-09-10 15:00:27.000000000 +0200
@@ -46,7 +46,6 @@
 gchar            *session_file = NULL;
 GList            *failsafe_clients = NULL;
 gboolean          failsafe_mode = TRUE;
-gint              shutdown_type = SHUTDOWN_LOGOUT;
 XfsmSplashScreen *splash_screen = NULL;
 
 void
diff -Nur xfce4-session-4.4.1/xfce4-session/xfsm-global.h xfce4-session-4.4.1.new/xfce4-session/xfsm-global.h
--- xfce4-session-4.4.1/xfce4-session/xfsm-global.h    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/xfsm-global.h    2007-09-10 15:00:27.000000000 +0200
@@ -47,7 +47,6 @@
 extern gchar            *session_file;
 extern GList            *failsafe_clients;
 extern gboolean          failsafe_mode;
-extern gint              shutdown_type;
 extern XfsmSplashScreen *splash_screen;
 
 
diff -Nur xfce4-session-4.4.1/xfce4-session/xfsm-manager.c xfce4-session-4.4.1.new/xfce4-session/xfsm-manager.c
--- xfce4-session-4.4.1/xfce4-session/xfsm-manager.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/xfsm-manager.c    2007-09-10 15:00:27.000000000 +0200
@@ -799,7 +799,7 @@
     }
   else
     {
-      if (!fast && shutdown && !shutdownDialog (&shutdown_type, &shutdown_save))
+      if (!fast && shutdown && !shutdownDialog (&shutdown_save))
         return;
   
       if (!shutdown || shutdown_save)
diff -Nur xfce4-session-4.4.1/xfce4-session/xfsm-shutdown-helper.c xfce4-session-4.4.1.new/xfce4-session/xfsm-shutdown-helper.c
--- xfce4-session-4.4.1/xfce4-session/xfsm-shutdown-helper.c    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/xfsm-shutdown-helper.c    2007-09-10 15:00:27.000000000 +0200
@@ -55,6 +55,12 @@
 
 #ifdef HAVE_DBUS
 #include <dbus/dbus.h>
+#define    HAL_DBUS_SERVICE        "org.freedesktop.Hal"
+#define HAL_ROOT_COMPUTER        "/org/freedesktop/Hal/devices/computer"
+#define    HAL_DBUS_INTERFACE_DEVICE    "org.freedesktop.Hal.Device"
+#define    HAL_DBUS_INTERFACE_POWER    "org.freedesktop.Hal.Device.SystemPowerManagement"
+#define    HAL_PM_CAN_SUSPEND        "power_management.can_suspend_to_ram"
+#define    HAL_PM_CAN_HIBERNATE        "power_management.can_suspend_to_disk"
 #endif
 
 #include <libxfce4util/libxfce4util.h>
@@ -74,6 +80,17 @@
 };
 
 
+static struct
+{ 
+  XfsmShutdownCommand command;
+  gchar * name;
+} xfsm2hal[] =
+{
+           { XFSM_REBOOT,    "Reboot"},
+           { XFSM_SHUTDOWN,  "Shutdown"},
+           { XFSM_SUSPEND,   "Suspend"},
+           { XFSM_HIBERNATE, "Hibernate"}
+};
 
 static gboolean
 xfsm_shutdown_helper_hal_check (XfsmShutdownHelper *helper)
@@ -100,9 +117,9 @@
    * use the org.freedesktop.Hal.Device.SystemPowerManagement
    * interface without shutting down/rebooting now.
    */
-  message = dbus_message_new_method_call ("org.freedesktop.Hal",
-                                          "/org/freedesktop/Hal/devices/computer",
-                                          "org.freedesktop.Hal.Device.SystemPowerManagement",
+  message = dbus_message_new_method_call (HAL_DBUS_SERVICE,
+                                          HAL_ROOT_COMPUTER,
+                                          HAL_DBUS_INTERFACE_POWER,
                                           "ThisMethodMustNotExistInHal");
   result = dbus_connection_send_with_reply_and_block (connection, message, 2000, &error);
   dbus_message_unref (message);
@@ -145,42 +162,45 @@
                                XfsmShutdownCommand command)
 {
 #ifdef HAVE_DBUS
-  DBusConnection *connection;
-  DBusMessage    *message;
-  DBusMessage    *result;
-  DBusError       error;
-
-  /* initialize the error */
-  dbus_error_init (&error);
-
-  /* connect to the system message bus */
-  connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
-  if (G_UNLIKELY (connection == NULL))
-    {
-      g_warning (G_STRLOC ": Failed to connect to the system message bus: %s", error.message);
-      dbus_error_free (&error);
-      return FALSE;
-    }
-
-  /* send the appropriate message to HAL, telling it to shutdown or reboot the system */
-  message = dbus_message_new_method_call ("org.freedesktop.Hal",
-                                          "/org/freedesktop/Hal/devices/computer",
-                                          "org.freedesktop.Hal.Device.SystemPowerManagement",
-                                          (command == XFSM_SHUTDOWN_REBOOT) ? "Reboot" : "Shutdown");
-  result = dbus_connection_send_with_reply_and_block (connection, message, 2000, &error);
-  dbus_message_unref (message);
-
-  /* check if we received a result */
-  if (G_UNLIKELY (result == NULL))
-    {
-      g_warning (G_STRLOC ": Failed to contact HAL: %s", error.message);
-      dbus_error_free (&error);
-      return FALSE;
-    }
-
-  /* pretend that we succeed */
-  dbus_message_unref (result);
-  return TRUE;
+    DBusConnection *connection;
+    DBusMessage *method;
+    DBusMessage *result;
+    DBusError derror;
+    gint i;
+    gchar *methodname;
+    dbus_int32_t wakeup = 0;
+    
+    for (i = 0; i < G_N_ELEMENTS (xfsm2hal); i++) {
+      if ( xfsm2hal[i].command == command ) {
+        methodname = xfsm2hal[i].name;
+      }
+     }
+   
+    dbus_error_init(&derror);
+    
+    connection = dbus_bus_get(DBUS_BUS_SYSTEM, &derror);
+
+    if (connection == NULL)
+        return FALSE;
+    
+    method = dbus_message_new_method_call(HAL_DBUS_SERVICE,
+                                  HAL_ROOT_COMPUTER,
+                      HAL_DBUS_INTERFACE_POWER,
+                      methodname);
+
+    if (command == XFSM_SUSPEND) {
+    dbus_message_append_args (method, DBUS_TYPE_INT32, &wakeup, DBUS_TYPE_INVALID);
+     }
+    
+    result = dbus_connection_send_with_reply_and_block(connection, method, 2000, &derror);
+    
+    dbus_message_unref(method);
+    
+    if (result == NULL)
+    return FALSE;
+    
+    dbus_message_unref(result);
+    return TRUE;
 #else
   return FALSE;
 #endif
diff -Nur xfce4-session-4.4.1/xfce4-session/xfsm-shutdown-helper.h xfce4-session-4.4.1.new/xfce4-session/xfsm-shutdown-helper.h
--- xfce4-session-4.4.1/xfce4-session/xfsm-shutdown-helper.h    2007-04-09 19:06:35.000000000 +0200
+++ xfce4-session-4.4.1.new/xfce4-session/xfsm-shutdown-helper.h    2007-09-10 15:00:27.000000000 +0200
@@ -27,8 +27,11 @@
 
 typedef enum
 {
-  XFSM_SHUTDOWN_POWEROFF   = 0,
-  XFSM_SHUTDOWN_REBOOT     = 1,
+  XFSM_LOGOUT     =-2,
+  XFSM_SHUTDOWN   =-1,
+  XFSM_REBOOT     = 0,
+  XFSM_SUSPEND    = 1,
+  XFSM_HIBERNATE  = 2,
 } XfsmShutdownCommand;

Enjoy smile. And thanks to Larhzu!


Got Leenucks? :: Arch: Power in simplicity :: Get Counted! Registered Linux User #392717 :: Blog thingy

Offline

#3 2009-02-18 03:30:45

MarcoRosso
Member
Registered: 2009-02-08
Posts: 49

Re: Integrate suspend & hibernate buttons into XFCE logout dialog

Could this possibly be made into a package for the AUR repository?

Offline

#4 2009-02-18 03:33:36

SamC
Member
From: Calgary
Registered: 2008-05-13
Posts: 611
Website

Re: Integrate suspend & hibernate buttons into XFCE logout dialog

Dead thread is dead. Please read the date of the previous post before replying. XFCE is 2 versions past this, and the code has likely changed.

Offline

#5 2009-02-18 04:03:11

xaiviax
Member
From: Michigan
Registered: 2008-11-04
Posts: 282

Re: Integrate suspend & hibernate buttons into XFCE logout dialog

MarcoRosso wrote:

Could this possibly be made into a package for the AUR repository?

See SamC's reply, but just so you know, this is now in current xfce (in testing repo)

Offline

#6 2009-02-18 20:31:03

MarcoRosso
Member
Registered: 2009-02-08
Posts: 49

Re: Integrate suspend & hibernate buttons into XFCE logout dialog

The testing repo, is that different from the official one?

Offline

Board footer

Powered by FluxBB