summaryrefslogtreecommitdiff
path: root/mate-session/gsm-logout-dialog.c
diff options
context:
space:
mode:
Diffstat (limited to 'mate-session/gsm-logout-dialog.c')
-rw-r--r--mate-session/gsm-logout-dialog.c461
1 files changed, 461 insertions, 0 deletions
diff --git a/mate-session/gsm-logout-dialog.c b/mate-session/gsm-logout-dialog.c
new file mode 100644
index 0000000..de606a4
--- /dev/null
+++ b/mate-session/gsm-logout-dialog.c
@@ -0,0 +1,461 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006 Vincent Untz
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#include <config.h>
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include <upower.h>
+
+#include "gsm-logout-dialog.h"
+#include "gsm-consolekit.h"
+#include "mdm.h"
+
+#define GSM_LOGOUT_DIALOG_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_LOGOUT_DIALOG, GsmLogoutDialogPrivate))
+
+#define AUTOMATIC_ACTION_TIMEOUT 60
+
+#define GSM_ICON_LOGOUT "system-log-out"
+#define GSM_ICON_SHUTDOWN "system-shutdown"
+
+typedef enum {
+ GSM_DIALOG_LOGOUT_TYPE_LOGOUT,
+ GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN
+} GsmDialogLogoutType;
+
+struct _GsmLogoutDialogPrivate
+{
+ GsmDialogLogoutType type;
+
+ UpClient *up_client;
+ GsmConsolekit *consolekit;
+
+ int timeout;
+ unsigned int timeout_id;
+
+ unsigned int default_response;
+};
+
+static GsmLogoutDialog *current_dialog = NULL;
+
+static void gsm_logout_dialog_set_timeout (GsmLogoutDialog *logout_dialog);
+
+static void gsm_logout_dialog_destroy (GsmLogoutDialog *logout_dialog,
+ gpointer data);
+
+static void gsm_logout_dialog_show (GsmLogoutDialog *logout_dialog,
+ gpointer data);
+
+enum {
+ PROP_0,
+ PROP_MESSAGE_TYPE
+};
+
+G_DEFINE_TYPE (GsmLogoutDialog, gsm_logout_dialog, GTK_TYPE_MESSAGE_DIALOG);
+
+static void
+gsm_logout_dialog_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case PROP_MESSAGE_TYPE:
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gsm_logout_dialog_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case PROP_MESSAGE_TYPE:
+ g_value_set_enum (value, GTK_MESSAGE_WARNING);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gsm_logout_dialog_class_init (GsmLogoutDialogClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+
+ /* This is a workaround to avoid a stupid crash: libmateui
+ * listens for the "show" signal on all GtkMessageDialog and
+ * gets the "message-type" of the dialogs. We will crash when
+ * it accesses this property if we don't override it since we
+ * didn't define it. */
+ gobject_class->set_property = gsm_logout_dialog_set_property;
+ gobject_class->get_property = gsm_logout_dialog_get_property;
+
+ g_object_class_override_property (gobject_class,
+ PROP_MESSAGE_TYPE,
+ "message-type");
+
+ g_type_class_add_private (klass, sizeof (GsmLogoutDialogPrivate));
+}
+
+static void
+gsm_logout_dialog_init (GsmLogoutDialog *logout_dialog)
+{
+ logout_dialog->priv = GSM_LOGOUT_DIALOG_GET_PRIVATE (logout_dialog);
+
+ logout_dialog->priv->timeout_id = 0;
+ logout_dialog->priv->timeout = 0;
+ logout_dialog->priv->default_response = GTK_RESPONSE_CANCEL;
+
+ 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));
+
+ logout_dialog->priv->up_client = up_client_new ();
+
+ logout_dialog->priv->consolekit = gsm_get_consolekit ();
+
+ g_signal_connect (logout_dialog,
+ "destroy",
+ G_CALLBACK (gsm_logout_dialog_destroy),
+ NULL);
+
+ g_signal_connect (logout_dialog,
+ "show",
+ G_CALLBACK (gsm_logout_dialog_show),
+ NULL);
+}
+
+static void
+gsm_logout_dialog_destroy (GsmLogoutDialog *logout_dialog,
+ gpointer data)
+{
+ if (logout_dialog->priv->timeout_id != 0) {
+ g_source_remove (logout_dialog->priv->timeout_id);
+ logout_dialog->priv->timeout_id = 0;
+ }
+
+ if (logout_dialog->priv->up_client) {
+ g_object_unref (logout_dialog->priv->up_client);
+ logout_dialog->priv->up_client = NULL;
+ }
+
+ if (logout_dialog->priv->consolekit) {
+ g_object_unref (logout_dialog->priv->consolekit);
+ logout_dialog->priv->consolekit = NULL;
+ }
+
+ current_dialog = NULL;
+}
+
+static gboolean
+gsm_logout_supports_system_suspend (GsmLogoutDialog *logout_dialog)
+{
+ return up_client_get_can_suspend (logout_dialog->priv->up_client);
+}
+
+static gboolean
+gsm_logout_supports_system_hibernate (GsmLogoutDialog *logout_dialog)
+{
+ return up_client_get_can_hibernate (logout_dialog->priv->up_client);
+}
+
+static gboolean
+gsm_logout_supports_switch_user (GsmLogoutDialog *logout_dialog)
+{
+ gboolean ret;
+
+ ret = gsm_consolekit_can_switch_user (logout_dialog->priv->consolekit);
+
+ return ret;
+}
+
+static gboolean
+gsm_logout_supports_reboot (GsmLogoutDialog *logout_dialog)
+{
+ gboolean ret;
+
+ ret = gsm_consolekit_can_restart (logout_dialog->priv->consolekit);
+ if (!ret) {
+ ret = mdm_supports_logout_action (MDM_LOGOUT_ACTION_REBOOT);
+ }
+
+ return ret;
+}
+
+static gboolean
+gsm_logout_supports_shutdown (GsmLogoutDialog *logout_dialog)
+{
+ gboolean ret;
+
+ ret = gsm_consolekit_can_stop (logout_dialog->priv->consolekit);
+
+ if (!ret) {
+ ret = mdm_supports_logout_action (MDM_LOGOUT_ACTION_SHUTDOWN);
+ }
+
+ return ret;
+}
+
+static void
+gsm_logout_dialog_show (GsmLogoutDialog *logout_dialog, gpointer user_data)
+{
+ gsm_logout_dialog_set_timeout (logout_dialog);
+}
+
+static gboolean
+gsm_logout_dialog_timeout (gpointer data)
+{
+ GsmLogoutDialog *logout_dialog;
+ char *seconds_warning;
+ char *secondary_text;
+ int seconds_to_show;
+ static char *session_type = NULL;
+
+ logout_dialog = (GsmLogoutDialog *) data;
+
+ if (!logout_dialog->priv->timeout) {
+ gtk_dialog_response (GTK_DIALOG (logout_dialog),
+ logout_dialog->priv->default_response);
+
+ return FALSE;
+ }
+
+ if (logout_dialog->priv->timeout <= 30) {
+ seconds_to_show = logout_dialog->priv->timeout;
+ } else {
+ seconds_to_show = (logout_dialog->priv->timeout/10) * 10;
+
+ if (logout_dialog->priv->timeout % 10)
+ seconds_to_show += 10;
+ }
+
+ switch (logout_dialog->priv->type) {
+ case GSM_DIALOG_LOGOUT_TYPE_LOGOUT:
+ seconds_warning = ngettext ("You will be automatically logged "
+ "out in %d second.",
+ "You will be automatically logged "
+ "out in %d seconds.",
+ seconds_to_show);
+ break;
+
+ case GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN:
+ seconds_warning = ngettext ("This system will be automatically "
+ "shut down in %d second.",
+ "This system will be automatically "
+ "shut down in %d seconds.",
+ seconds_to_show);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (session_type == NULL) {
+ GsmConsolekit *consolekit;
+
+ consolekit = gsm_get_consolekit ();
+ session_type = gsm_consolekit_get_current_session_type (consolekit);
+ g_object_unref (consolekit);
+ }
+
+ if (g_strcmp0 (session_type, GSM_CONSOLEKIT_SESSION_TYPE_LOGIN_WINDOW) != 0) {
+ char *name, *tmp;
+
+ name = g_locale_to_utf8 (g_get_real_name (), -1, NULL, NULL, NULL);
+
+ if (!name || name[0] == '\0' || strcmp (name, "Unknown") == 0) {
+ name = g_locale_to_utf8 (g_get_user_name (), -1 , NULL, NULL, NULL);
+ }
+
+ if (!name) {
+ name = g_strdup (g_get_user_name ());
+ }
+
+ tmp = g_strdup_printf (_("You are currently logged in as \"%s\"."), name);
+ secondary_text = g_strconcat (tmp, "\n", seconds_warning, NULL);
+ g_free (tmp);
+
+ g_free (name);
+ } else {
+ secondary_text = g_strdup (seconds_warning);
+ }
+
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (logout_dialog),
+ secondary_text,
+ seconds_to_show,
+ NULL);
+
+ logout_dialog->priv->timeout--;
+
+ g_free (secondary_text);
+
+ return TRUE;
+}
+
+static void
+gsm_logout_dialog_set_timeout (GsmLogoutDialog *logout_dialog)
+{
+ logout_dialog->priv->timeout = AUTOMATIC_ACTION_TIMEOUT;
+
+ /* Sets the secondary text */
+ gsm_logout_dialog_timeout (logout_dialog);
+
+ if (logout_dialog->priv->timeout_id != 0) {
+ g_source_remove (logout_dialog->priv->timeout_id);
+ }
+
+ logout_dialog->priv->timeout_id = g_timeout_add (1000,
+ gsm_logout_dialog_timeout,
+ logout_dialog);
+}
+
+static GtkWidget *
+gsm_get_dialog (GsmDialogLogoutType type,
+ GdkScreen *screen,
+ guint32 activate_time)
+{
+ GsmLogoutDialog *logout_dialog;
+ GtkWidget *dialog_image;
+ const char *primary_text;
+ const char *icon_name;
+
+ if (current_dialog != NULL) {
+ gtk_widget_destroy (GTK_WIDGET (current_dialog));
+ }
+
+ logout_dialog = g_object_new (GSM_TYPE_LOGOUT_DIALOG, NULL);
+
+ current_dialog = logout_dialog;
+
+ gtk_window_set_title (GTK_WINDOW (logout_dialog), "");
+
+ logout_dialog->priv->type = type;
+
+ icon_name = NULL;
+ primary_text = NULL;
+
+ switch (type) {
+ case GSM_DIALOG_LOGOUT_TYPE_LOGOUT:
+ icon_name = GSM_ICON_LOGOUT;
+ primary_text = _("Log out of this system now?");
+
+ logout_dialog->priv->default_response = GSM_LOGOUT_RESPONSE_LOGOUT;
+
+ if (gsm_logout_supports_switch_user (logout_dialog)) {
+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
+ _("_Switch User"),
+ GSM_LOGOUT_RESPONSE_SWITCH_USER);
+ }
+
+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL);
+
+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
+ _("_Log Out"),
+ GSM_LOGOUT_RESPONSE_LOGOUT);
+
+ break;
+ case GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN:
+ icon_name = GSM_ICON_SHUTDOWN;
+ primary_text = _("Shut down this system now?");
+
+ logout_dialog->priv->default_response = GSM_LOGOUT_RESPONSE_SHUTDOWN;
+
+ if (gsm_logout_supports_system_suspend (logout_dialog)) {
+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
+ _("S_uspend"),
+ GSM_LOGOUT_RESPONSE_SLEEP);
+ }
+
+ if (gsm_logout_supports_system_hibernate (logout_dialog)) {
+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
+ _("_Hibernate"),
+ GSM_LOGOUT_RESPONSE_HIBERNATE);
+ }
+
+ if (gsm_logout_supports_reboot (logout_dialog)) {
+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
+ _("_Restart"),
+ GSM_LOGOUT_RESPONSE_REBOOT);
+ }
+
+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL);
+
+ if (gsm_logout_supports_shutdown (logout_dialog)) {
+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
+ _("_Shut Down"),
+ GSM_LOGOUT_RESPONSE_SHUTDOWN);
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ dialog_image = gtk_message_dialog_get_image (GTK_MESSAGE_DIALOG (logout_dialog));
+
+ gtk_image_set_from_icon_name (GTK_IMAGE (dialog_image),
+ icon_name, GTK_ICON_SIZE_DIALOG);
+ gtk_window_set_icon_name (GTK_WINDOW (logout_dialog), icon_name);
+ gtk_window_set_position (GTK_WINDOW (logout_dialog), GTK_WIN_POS_CENTER_ALWAYS);
+ gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (logout_dialog), primary_text);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (logout_dialog),
+ logout_dialog->priv->default_response);
+
+ gtk_window_set_screen (GTK_WINDOW (logout_dialog), screen);
+
+ return GTK_WIDGET (logout_dialog);
+}
+
+GtkWidget *
+gsm_get_shutdown_dialog (GdkScreen *screen,
+ guint32 activate_time)
+{
+ return gsm_get_dialog (GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN,
+ screen,
+ activate_time);
+}
+
+GtkWidget *
+gsm_get_logout_dialog (GdkScreen *screen,
+ guint32 activate_time)
+{
+ return gsm_get_dialog (GSM_DIALOG_LOGOUT_TYPE_LOGOUT,
+ screen,
+ activate_time);
+}