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,237 @@ gsm_logout_dialog_set_timeout (GsmLogout
logout_dialog);
}
+#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;
+
+ /* SUN_BRANDING */
+ 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;
+}
+
+static void
+boot_environment_cb (GtkWidget *button, gpointer data)
+{
+ GsmLogoutDialog *logout_dialog = (GsmLogoutDialog *)data;
+
+ 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;
+ }
+}
+
+static GtkWidget *
+get_warning ()
+{
+ GtkBox *hbox;
+ GtkImage *image;
+ GtkWidget *label;
+
+ hbox = gtk_hbox_new (FALSE, 0);
+
+ image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING,
+ GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_widget_show (image);
+ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
+ label = gtk_label_new (NULL);
+ gtk_widget_show (label);
+ gtk_label_set_markup (GTK_LABEL (label),
+ /* SUN_BRANDING */
+ _("<span style=\"italic\" size=\"smaller\">Options apply only after Restart, not after Shut Down</span>"));
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+ return hbox;
+}
+
+/* Options to choose BE. */
+static GtkWidget *
+get_be_option (GsmLogoutDialog *logout_dialog)
+{
+ GtkWidget *warning;
+ GtkWidget *label;
+ GtkWidget *radio;
+ GtkWidget *scroll;
+ GtkWidget *vbox;
+ GSList *group;
+ GPtrArray *array = NULL;
+
+ warning = get_warning ();
+ gtk_widget_show (warning);
+
+ /* SUN_BRANDING */
+ 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;
+
+ 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);
+
+ 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);
+
+ /* 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 *align;
+ GtkWidget *check;
+ GtkWidget *be;
+ GtkWidget *hbox;
+ GtkWidget *vbox;
+ GList *list;
+ gint spacing;
+ gint size;
+
+ /* SUN_BRANDING */
+ expander = gtk_expander_new_with_mnemonic (_("_More Options"));
+ gtk_widget_show (expander);
+ gtk_widget_style_get (expander, "expander-size", &size,
+ "expander-spacing", &spacing, NULL);
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (vbox);
+
+ 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);
+
+ 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);
+
+ /*
+ * Find the right container to put the expander in.
+ * This is gtk dialog imeplementation specific.
+ * So if there is something wrong with the layout
+ * the code need to be udpated
+ */
+ hbox = NULL;
+ vbox = gtk_dialog_get_content_area (GTK_DIALOG
+ (logout_dialog));
+ list = gtk_container_get_children (GTK_CONTAINER (vbox));
+ for (GList *l = list; l != NULL; l = g_list_next (l)) {
+ GtkWidget *widget;
+
+ widget = l->data;
+ if (GTK_IS_HBOX(widget)) {
+ hbox = widget;
+ break;
+ }
+ }
+ g_list_free (list);
+ g_assert (hbox != NULL);
+
+ vbox = NULL;
+ list = gtk_container_get_children (GTK_CONTAINER (hbox));
+ for (GList *l = list; l != NULL; l = g_list_next (l)) {
+ GtkWidget *widget;
+
+ widget = l->data;
+ if (GTK_IS_VBOX(widget)) {
+ vbox = widget;
+ break;
+ }
+ }
+ g_list_free (list);
+ g_assert (vbox != NULL);
+
+ if (vbox) {
+ gtk_box_pack_start (GTK_BOX (vbox), expander, FALSE,
+ FALSE, 10);
+ } else {
+ gtk_widget_destroy (expander);
+ }
+
+ return;
+}
+#endif
+
+
static GtkWidget *
gsm_get_dialog (GsmDialogLogoutType type,
GdkScreen *screen,
@@ -418,6 +653,10 @@ gsm_get_dialog (GsmDialogLogoutType type
}
if (gsm_logout_supports_reboot (logout_dialog)) {
+#if defined(__x86) || defined(__x86__)
+ /* fast reboot support */
+ create_fastreboot_options(logout_dialog);
+#endif
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: