diff -Nur xfce4-session-4.4.0/settings/session/session.c xfce4-session-4.4.0.new/settings/session/session.c --- xfce4-session-4.4.0/settings/session/session.c 2007-03-24 23:27:52.000000000 +0200 +++ xfce4-session-4.4.0.new/settings/session/session.c 2007-03-25 00:42:54.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.0/xfce4-session/main.c xfce4-session-4.4.0.new/xfce4-session/main.c --- xfce4-session-4.4.0/xfce4-session/main.c 2007-03-24 23:27:52.000000000 +0200 +++ xfce4-session-4.4.0.new/xfce4-session/main.c 2007-03-25 00:42:54.000000000 +0200 @@ -61,6 +61,11 @@ #include #include +#include + + +#include +#include 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.0/xfce4-session/shutdown.c xfce4-session-4.4.0.new/xfce4-session/shutdown.c --- xfce4-session-4.4.0/xfce4-session/shutdown.c 2007-03-24 23:27:52.000000000 +0200 +++ xfce4-session-4.4.0.new/xfce4-session/shutdown.c 2007-03-25 01:25:43.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; @@ -154,14 +156,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 +175,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 +196,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 +314,39 @@ hbox = gtk_hbox_new (TRUE, BORDER); gtk_widget_show (hbox); gtk_box_pack_start (GTK_BOX (vbox), hbox, 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); + gtk_box_pack_start (GTK_BOX (hbox), 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 +372,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 +404,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 +502,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 +555,7 @@ /* */ gint -xfsm_shutdown(gint type) +xfsm_shutdown(void) { gboolean result; @@ -589,7 +573,7 @@ sync (); #endif - if (type == SHUTDOWN_LOGOUT) + if (shutdownType == XFSM_LOGOUT) return EXIT_SUCCESS; if (shutdown_helper == NULL) @@ -598,16 +582,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.0/xfce4-session/shutdown.h xfce4-session-4.4.0.new/xfce4-session/shutdown.h --- xfce4-session-4.4.0/xfce4-session/shutdown.h 2007-03-24 23:27:52.000000000 +0200 +++ xfce4-session-4.4.0.new/xfce4-session/shutdown.h 2007-03-25 00:42:54.000000000 +0200 @@ -24,13 +24,8 @@ #include -/* */ -#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.0/xfce4-session/xfsm-global.c xfce4-session-4.4.0.new/xfce4-session/xfsm-global.c --- xfce4-session-4.4.0/xfce4-session/xfsm-global.c 2007-03-24 23:27:52.000000000 +0200 +++ xfce4-session-4.4.0.new/xfce4-session/xfsm-global.c 2007-03-25 00:42:54.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.0/xfce4-session/xfsm-global.h xfce4-session-4.4.0.new/xfce4-session/xfsm-global.h --- xfce4-session-4.4.0/xfce4-session/xfsm-global.h 2007-03-24 23:27:52.000000000 +0200 +++ xfce4-session-4.4.0.new/xfce4-session/xfsm-global.h 2007-03-25 00:42:54.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.0/xfce4-session/xfsm-manager.c xfce4-session-4.4.0.new/xfce4-session/xfsm-manager.c --- xfce4-session-4.4.0/xfce4-session/xfsm-manager.c 2007-03-24 23:27:52.000000000 +0200 +++ xfce4-session-4.4.0.new/xfce4-session/xfsm-manager.c 2007-03-25 00:42:54.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.0/xfce4-session/xfsm-shutdown-helper.c xfce4-session-4.4.0.new/xfce4-session/xfsm-shutdown-helper.c --- xfce4-session-4.4.0/xfce4-session/xfsm-shutdown-helper.c 2007-03-24 23:27:52.000000000 +0200 +++ xfce4-session-4.4.0.new/xfce4-session/xfsm-shutdown-helper.c 2007-03-25 00:42:54.000000000 +0200 @@ -55,6 +55,12 @@ #ifdef HAVE_DBUS #include +#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 @@ -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.0/xfce4-session/xfsm-shutdown-helper.h xfce4-session-4.4.0.new/xfce4-session/xfsm-shutdown-helper.h --- xfce4-session-4.4.0/xfce4-session/xfsm-shutdown-helper.h 2007-03-24 23:27:52.000000000 +0200 +++ xfce4-session-4.4.0.new/xfce4-session/xfsm-shutdown-helper.h 2007-03-25 00:42:54.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;