--- a/patches/gnome-session-18-fastreboot.diff Tue Nov 10 10:11:24 2009 +0000
+++ b/patches/gnome-session-18-fastreboot.diff Tue Nov 10 10:14:51 2009 +0000
@@ -1,42 +1,169 @@
---- gnome-session-2.27.5/gnome-session/gsm-logout-dialog.c 2009-07-29 09:51:22.000000000 +0800
-+++ gnome-session-2.27.5-new/gnome-session/gsm-logout-dialog.c 2009-08-05 17:30:30.296881870 +0800
-@@ -349,6 +389,190 @@ gsm_logout_dialog_set_timeout (GsmLogout
+diff -uprN gnome-session-2.28.0/gnome-session/gsm-consolekit.c gnome-session-2.28.0-new/gnome-session/gsm-consolekit.c
+--- gnome-session-2.28.0/gnome-session/gsm-consolekit.c 2009-09-09 19:16:53.000000000 +0800
++++ gnome-session-2.28.0-new/gnome-session/gsm-consolekit.c 2009-11-10 16:58:17.029348387 +0800
+@@ -479,6 +479,70 @@ gsm_consolekit_attempt_stop (GsmConsolek
+ }
+ }
+
++void
++gsm_consolekit_get_available_systems (GsmConsolekit *manager, GPtrArray **array)
++{
++ gboolean res;
++ GError *error;
++
++ error = NULL;
++
++ if (!gsm_consolekit_ensure_ck_connection (manager, &error)) {
++ g_warning ("Could not connect to ConsoleKit: %s",
++ error->message);
++ emit_stop_complete (manager, error);
++ g_error_free (error);
++ return;
++ }
++
++ res = dbus_g_proxy_call_with_timeout (manager->priv->ck_proxy,
++ "GetAvailableOperatingSystems",
++ INT_MAX,
++ &error,
++ G_TYPE_INVALID,
++ dbus_g_type_get_collection ("GPtrArray", OS_STRUCT_TYPE),
++ array,
++ G_TYPE_INVALID);
++
++ if (!res) {
++ g_warning ("Unable to get available operating system: %s", error->message);
++ g_error_free (error);
++ }
++}
++
++void
++gsm_consolekit_restart_with_parameters (GsmConsolekit *manager,
++ const gchar *parameters)
++{
++ gboolean res;
++ GError *error;
++
++ error = NULL;
++
++ if (!gsm_consolekit_ensure_ck_connection (manager, &error)) {
++ g_warning ("Could not connect to ConsoleKit: %s",
++ error->message);
++ emit_stop_complete (manager, error);
++ g_error_free (error);
++ return;
++ }
++
++ res = dbus_g_proxy_call_with_timeout (manager->priv->ck_proxy,
++ "RestartWithParameters",
++ INT_MAX,
++ &error,
++ G_TYPE_STRING,
++ parameters,
++ G_TYPE_INVALID,
++ G_TYPE_INVALID);
++
++ if (!res) {
++ g_warning ("Unable to restart system: %s", error->message);
++ emit_restart_complete (manager, error);
++ g_error_free (error);
++ }
++}
++
+ static gboolean
+ get_current_session_id (DBusConnection *connection,
+ char **session_id)
+diff -uprN gnome-session-2.28.0/gnome-session/gsm-consolekit.h gnome-session-2.28.0-new/gnome-session/gsm-consolekit.h
+--- gnome-session-2.28.0/gnome-session/gsm-consolekit.h 2009-04-20 02:26:52.000000000 +0800
++++ gnome-session-2.28.0-new/gnome-session/gsm-consolekit.h 2009-11-10 16:58:17.029557135 +0800
+@@ -94,6 +94,18 @@ void gsm_consolekit_set_sess
+
+ gchar *gsm_consolekit_get_current_session_type (GsmConsolekit *manager);
+
++#define OS_STRUCT_TYPE (dbus_g_type_get_struct ("GValueArray", \
++ G_TYPE_INT, \
++ G_TYPE_STRING, \
++ G_TYPE_STRING, \
++ G_TYPE_STRING, \
++ G_TYPE_BOOLEAN, \
++ G_TYPE_INVALID))
++
++
++void gsm_consolekit_get_available_systems (GsmConsolekit *manager, GPtrArray **array);
++void gsm_consolekit_with_with_parameters (GsmConsolekit *manager, const gchar *parameters);
++
+ GsmConsolekit *gsm_get_consolekit (void);
+
+ G_END_DECLS
+diff -uprN gnome-session-2.28.0/gnome-session/gsm-logout-dialog.c gnome-session-2.28.0-new/gnome-session/gsm-logout-dialog.c
+--- gnome-session-2.28.0/gnome-session/gsm-logout-dialog.c 2009-11-10 17:44:49.039510013 +0800
++++ gnome-session-2.28.0-new/gnome-session/gsm-logout-dialog.c 2009-11-10 17:43:21.340885644 +0800
+@@ -59,6 +59,9 @@ struct _GsmLogoutDialogPrivate
+ unsigned int timeout_id;
+
+ unsigned int default_response;
++
++ unsigned int fast;
++ int id;
+ };
+
+ static GsmLogoutDialog *current_dialog = NULL;
+@@ -140,6 +143,9 @@ gsm_logout_dialog_init (GsmLogoutDialog
+ logout_dialog->priv->timeout = 0;
+ logout_dialog->priv->default_response = GTK_RESPONSE_CANCEL;
+
++ logout_dialog->priv->fast = 1;
++ logout_dialog->priv->id = -1;
++
+ gtk_window_set_skip_taskbar_hint (GTK_WINDOW (logout_dialog), TRUE);
+ gtk_window_set_keep_above (GTK_WINDOW (logout_dialog), TRUE);
+ gtk_window_stick (GTK_WINDOW (logout_dialog));
+@@ -352,6 +358,235 @@ gsm_logout_dialog_set_timeout (GsmLogout
logout_dialog);
}
-+#define ENABLE_FASTREBOOT "/usr/sbin/svccfg -s system/boot-config:default setprop config/fastreboot_default=true"
-+#define DISABLE_FASTREBOOT "/usr/sbin/svccfg -s system/boot-config:default setprop config/fastreboot_default=false"
-+#define REFRESH_FASTREBOOT "/usr/sbin/svcadm refresh system/boot-config:default"
-+#define GET_FASTREBOOT "/usr/bin/svcprop -p config/fastreboot_default system/boot-config:default"
++#if defined(__x86) || defined(__x86__)
++static void
++fast_reboot_cb (GtkWidget *button, gpointer data)
++{
++ GsmLogoutDialog *logout_dialog = (GsmLogoutDialog *)data;
++
++ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) {
++ logout_dialog->priv->fast = 1;
++ } else {
++ logout_dialog->priv->fast = 0;
++ }
++}
++
++/* Option to skip boot menu on restart. */
++static GtkWidget *
++get_fast_reboot_option (GsmLogoutDialog *logout_dialog)
++{
++ GtkWidget *check;
++ char *obuf = NULL;
++
++ check = gtk_check_button_new_with_mnemonic (_("S_kip boot menu on restart"));
++ gtk_widget_show (check);
++ g_signal_connect (GTK_WIDGET (check),
++ "toggled",
++ G_CALLBACK (fast_reboot_cb),
++ logout_dialog);
++ gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (check), TRUE);
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
++
++ return check;
++}
++#endif
+
+static void
-+skip_boot_menu_response (GsmLogoutDialog *logout_dialog,
-+ guint response_id,
-+ GtkWidget *widget)
++boot_environment_cb (GtkWidget *button, gpointer data)
+{
-+ char *obuf = NULL;
-+ gboolean refresh = FALSE;
++ GsmLogoutDialog *logout_dialog = (GsmLogoutDialog *)data;
+
-+ if (response_id == GSM_LOGOUT_RESPONSE_REBOOT) {
-+ g_spawn_command_line_sync (GET_FASTREBOOT, &obuf,
-+ NULL, NULL, NULL);
-+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
-+ if (strncmp (obuf, "false", strlen ("false")) == 0) {
-+ g_spawn_command_line_sync (ENABLE_FASTREBOOT, NULL,
-+ NULL, NULL, NULL);
-+ refresh = TRUE;
-+ }
-+ } else {
-+ if (obuf && (strncmp (obuf, "true", strlen ("true")) == 0)) {
-+ g_spawn_command_line_sync (DISABLE_FASTREBOOT, NULL,
-+ NULL, NULL, NULL);
-+ refresh = TRUE;
-+ }
-+ }
-+ if (refresh)
-+ g_spawn_command_line_sync (REFRESH_FASTREBOOT, NULL,
-+ NULL, NULL, NULL);
-+ g_free (obuf);
++ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) {
++ gint id;
++
++ id = (gint)g_object_get_data (G_OBJECT (button), "id");
++ logout_dialog->priv->id = id;
+ }
+}
+
@@ -62,46 +189,83 @@
+ return hbox;
+}
+
-+static void
-+show_warning (GtkWidget *button, gpointer data)
++/* Options to choose BE. */
++static GtkWidget *
++get_be_option (GsmLogoutDialog *logout_dialog)
+{
-+ gtk_widget_show (GTK_WIDGET(data));
-+}
++ GtkWidget *warning;
++ GtkWidget *label;
++ GtkWidget *radio;
++ GtkWidget *scroll;
++ GtkWidget *vbox;
++ GSList *group;
++ GPtrArray *array = NULL;
++
++ warning = get_warning ();
++ gtk_widget_show (warning);
+
-+/* Option to skip boot menu on restart. */
-+static GtkWidget *
-+get_skip_option (GtkWidget *warning)
-+{
-+ GtkWidget *check;
-+ char *obuf = NULL;
++ label = gtk_label_new_with_mnemonic (_("_Default boot environment at next restart:"));
++ gtk_widget_show (label);
++
++ vbox = gtk_vbox_new (FALSE, 2);
++ gtk_widget_show (vbox);
++
++ gsm_consolekit_get_available_systems (logout_dialog->priv->consolekit,
++ &array);
++ group = NULL;
++ for (int i = 0; i < array->len; i++) {
++ GValue elem = {0};
++ gint id;
++ gchar *name;
++ gboolean is_default = FALSE;
+
-+ check = gtk_check_button_new_with_mnemonic (_("S_kip boot menu on restart"));
-+ gtk_widget_show (check);
-+ g_spawn_command_line_sync (GET_FASTREBOOT, &obuf,
-+ NULL, NULL, NULL);
-+ gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (check),
-+ TRUE);
-+ if (obuf && (strncmp (obuf, "true", strlen ("true")) == 0))
-+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check),
-+ TRUE);
-+ else
-+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check),
-+ FALSE);
-+ g_free (obuf);
++ g_value_init (&elem, OS_STRUCT_TYPE);
++ g_value_set_static_boxed (&elem, g_ptr_array_index (array, i));
++ dbus_g_type_struct_get (&elem,
++ 0, &id,
++ 3, &name,
++ 4, &is_default,
++ G_MAXUINT);
+
-+ g_signal_connect (GTK_WIDGET (check),
-+ "toggled",
-+ G_CALLBACK (show_warning),
-+ warning);
++ radio = gtk_radio_button_new_with_label (group, name);
++ gtk_widget_show (radio);
++ g_object_set_data (G_OBJECT (radio), "id", (gpointer)id);
++ if (is_default) {
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio),
++ TRUE);
++ logout_dialog->priv->id = id;
++ }
++ gtk_box_pack_start (GTK_BOX (vbox), radio, FALSE, FALSE, 0);
++ group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio));
++ g_signal_connect (GTK_WIDGET (radio),
++ "toggled",
++ G_CALLBACK (boot_environment_cb),
++ logout_dialog);
++ }
++ scroll = gtk_scrolled_window_new (NULL, NULL);
++ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
++ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
++ gtk_widget_show (scroll);
++ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroll),
++ vbox);
+
-+ return check;
++ /* a new vbox to put label, scrolled window and warning in */
++ vbox = gtk_vbox_new (FALSE, 2);
++ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
++ gtk_box_pack_start (GTK_BOX (vbox), scroll, FALSE, FALSE, 0);
++ gtk_box_pack_start (GTK_BOX (vbox), warning, FALSE, FALSE, 0);
++
++ if (array->len > 1)
++ gtk_widget_show (vbox);
++ g_ptr_array_free (array, TRUE);
++
++ return vbox;
+}
+
+static void
+create_fastreboot_options (GsmLogoutDialog *logout_dialog)
+{
+ GtkWidget *expander;
-+ GtkWidget *warning;
+ GtkWidget *align;
+ GtkWidget *check;
+ GtkWidget *be;
@@ -119,21 +283,23 @@
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (vbox);
+
-+ warning = get_warning ();
-+ align = gtk_alignment_new (0.0, 0.0, 0.0, 0.0);
-+ gtk_widget_show (align);
-+ gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0,
-+ (size + 2 * spacing), 0);
-+ gtk_container_add (GTK_CONTAINER (align), warning);
-+ gtk_box_pack_end (GTK_BOX (vbox), align, FALSE, FALSE, 0);
-+
-+ check = get_skip_option (warning);
++#if defined(__x86) || defined(__x86__)
++ check = get_fast_reboot_option (logout_dialog);
+ align = gtk_alignment_new (0.0, 0.0, 0.0, 0.0);
+ gtk_widget_show (align);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0,
+ (size + 2 * spacing), 0);
+ gtk_container_add (GTK_CONTAINER (align), check);
+ gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 10);
++#endif
++
++ be = get_be_option (logout_dialog);
++ align = gtk_alignment_new (0.0, 0.0, 0.0, 0.0);
++ gtk_widget_show (align);
++ gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0,
++ (size + 2 * spacing), 0);
++ gtk_container_add (GTK_CONTAINER (align), be);
++ gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
+
+ gtk_container_add (GTK_CONTAINER (expander), vbox);
+
@@ -176,10 +342,6 @@
+ if (vbox) {
+ gtk_box_pack_start (GTK_BOX (vbox), expander, FALSE,
+ FALSE, 10);
-+ g_signal_connect (GTK_WIDGET (logout_dialog),
-+ "response",
-+ G_CALLBACK (skip_boot_menu_response),
-+ check);
+ } else {
+ gtk_widget_destroy (expander);
+ }
@@ -191,7 +353,7 @@
static GtkWidget *
gsm_get_dialog (GsmDialogLogoutType type,
GdkScreen *screen,
-@@ -414,6 +647,8 @@ gsm_get_dialog (GsmDialogLogoutType type
+@@ -418,6 +653,8 @@ gsm_get_dialog (GsmDialogLogoutType type
}
if (gsm_logout_supports_reboot (logout_dialog)) {
@@ -200,3 +362,123 @@
gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
_("_Restart"),
GSM_LOGOUT_RESPONSE_REBOOT);
+@@ -454,6 +691,21 @@ gsm_get_dialog (GsmDialogLogoutType type
+ return GTK_WIDGET (logout_dialog);
+ }
+
++gchar *
++gsm_logout_dialog_get_restart_parameters (GsmLogoutDialog *logout_dialog)
++{
++ gchar *param = NULL;
++
++ if (logout_dialog->priv->id < 0)
++ return NULL;
++
++ param = g_strdup_printf("id:%d fast:%d",
++ logout_dialog->priv->id,
++ logout_dialog->priv->fast);
++
++ return param;
++}
++
+ GtkWidget *
+ gsm_get_shutdown_dialog (GdkScreen *screen,
+ guint32 activate_time)
+diff -uprN gnome-session-2.28.0/gnome-session/gsm-logout-dialog.h gnome-session-2.28.0-new/gnome-session/gsm-logout-dialog.h
+--- gnome-session-2.28.0/gnome-session/gsm-logout-dialog.h 2009-04-20 02:26:52.000000000 +0800
++++ gnome-session-2.28.0-new/gnome-session/gsm-logout-dialog.h 2009-11-10 16:58:17.030235487 +0800
+@@ -68,6 +68,8 @@ GtkWidget *gsm_get_logout_dialog
+ GtkWidget *gsm_get_shutdown_dialog (GdkScreen *screen,
+ guint32 activate_time);
+
++gchar *gsm_logout_dialog_get_restart_parameters (GsmLogoutDialog *logout_dialog);
++
+ G_END_DECLS
+
+ #endif /* __GSM_LOGOUT_DIALOG_H__ */
+diff -uprN gnome-session-2.28.0/gnome-session/gsm-manager.c gnome-session-2.28.0-new/gnome-session/gsm-manager.c
+--- gnome-session-2.28.0/gnome-session/gsm-manager.c 2009-11-10 17:44:49.071472976 +0800
++++ gnome-session-2.28.0-new/gnome-session/gsm-manager.c 2009-11-10 16:58:17.035407219 +0800
+@@ -132,6 +132,8 @@ struct GsmManagerPrivate
+
+ DBusGProxy *bus_proxy;
+ DBusGConnection *connection;
++
++ gchar *parameters;
+ };
+
+ enum {
+@@ -416,7 +418,8 @@ gsm_manager_quit (GsmManager *manager)
+ "request-completed",
+ G_CALLBACK (quit_request_completed),
+ GINT_TO_POINTER (GDM_LOGOUT_ACTION_REBOOT));
+- gsm_consolekit_attempt_restart (consolekit);
++ gsm_consolekit_restart_with_parameters (consolekit,
++ manager->priv->parameters);
+ break;
+ case GSM_MANAGER_LOGOUT_REBOOT_GDM:
+ gdm_set_logout_action (GDM_LOGOUT_ACTION_REBOOT);
+@@ -2176,6 +2179,11 @@ gsm_manager_dispose (GObject *object)
+ manager->priv->gconf_client = NULL;
+ }
+
++ if (manager->priv->parameters) {
++ g_free (manager->priv->parameters);
++ manager->priv->parameters = NULL;
++ }
++
+ G_OBJECT_CLASS (gsm_manager_parent_class)->dispose (object);
+ }
+
+@@ -2800,6 +2808,8 @@ logout_dialog_response (GsmLogoutDialog
+ request_shutdown (manager);
+ break;
+ case GSM_LOGOUT_RESPONSE_REBOOT:
++ manager->priv->parameters =
++ gsm_logout_dialog_get_restart_parameters (logout_dialog);
+ request_reboot (manager);
+ break;
+ case GSM_LOGOUT_RESPONSE_LOGOUT:
+diff -uprN gnome-session-2.28.0/gnome-session/gsm-manager.c.orig gnome-session-2.28.0-new/gnome-session/gsm-manager.c.orig
+--- gnome-session-2.28.0/gnome-session/gsm-manager.c.orig 2009-11-10 17:44:49.055937229 +0800
++++ gnome-session-2.28.0-new/gnome-session/gsm-manager.c.orig 2009-11-10 16:58:17.031615520 +0800
+@@ -132,6 +132,8 @@ struct GsmManagerPrivate
+
+ DBusGProxy *bus_proxy;
+ DBusGConnection *connection;
++
++ gchar *parameters;
+ };
+
+ enum {
+@@ -416,7 +418,8 @@ gsm_manager_quit (GsmManager *manager)
+ "request-completed",
+ G_CALLBACK (quit_request_completed),
+ GINT_TO_POINTER (GDM_LOGOUT_ACTION_REBOOT));
+- gsm_consolekit_attempt_restart (consolekit);
++ gsm_consolekit_restart_with_parameters (consolekit,
++ manager->priv->parameters);
+ break;
+ case GSM_MANAGER_LOGOUT_REBOOT_GDM:
+ gdm_set_logout_action (GDM_LOGOUT_ACTION_REBOOT);
+@@ -2176,6 +2179,11 @@ gsm_manager_dispose (GObject *object)
+ manager->priv->gconf_client = NULL;
+ }
+
++ if (manager->priv->parameters) {
++ g_free (manager->priv->parameters);
++ manager->priv->parameters = NULL;
++ }
++
+ G_OBJECT_CLASS (gsm_manager_parent_class)->dispose (object);
+ }
+
+@@ -2800,6 +2808,8 @@ logout_dialog_response (GsmLogoutDialog
+ request_shutdown (manager);
+ break;
+ case GSM_LOGOUT_RESPONSE_REBOOT:
++ manager->priv->parameters =
++ gsm_logout_dialog_get_restart_parameters (logout_dialog);
+ request_reboot (manager);
+ break;
+ case GSM_LOGOUT_RESPONSE_LOGOUT: