summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Schermer <nick@xfce.org>2011-11-06 21:59:43 +0100
committerNick Schermer <nick@xfce.org>2012-03-24 22:24:35 +0100
commit4002e8d4ef3905e878e44633c076f8e7d42fd91b (patch)
tree55f0bb8949e63a00f15db6c8bf15053ed4c19a70
parente90852df0f772184546320871c69d3358699d182 (diff)
downloadxfce4-session-4002e8d4ef3905e878e44633c076f8e7d42fd91b.tar.gz
Remove suspend/hibernate, split consolekit and rebuild dialog.
Way too many changes in 1 commit, but it's all related.
-rw-r--r--configure.in.in14
-rw-r--r--libxfsm/xfsm-util.c19
-rw-r--r--libxfsm/xfsm-util.h2
-rwxr-xr-xscripts/xinitrc.in.in2
-rw-r--r--xfce4-session/Makefile.am7
-rw-r--r--xfce4-session/main.c28
-rw-r--r--xfce4-session/xfsm-consolekit.c337
-rw-r--r--xfce4-session/xfsm-consolekit.h54
-rw-r--r--xfce4-session/xfsm-error.h2
-rw-r--r--xfce4-session/xfsm-fadeout.c9
-rw-r--r--xfce4-session/xfsm-fadeout.h1
-rw-r--r--xfce4-session/xfsm-global.c19
-rw-r--r--xfce4-session/xfsm-global.h10
-rw-r--r--xfce4-session/xfsm-logout-dialog.c1321
-rw-r--r--xfce4-session/xfsm-logout-dialog.h20
-rw-r--r--xfce4-session/xfsm-manager.c20
-rw-r--r--xfce4-session/xfsm-manager.h1
-rw-r--r--xfce4-session/xfsm-shutdown-helper.c1862
-rw-r--r--xfce4-session/xfsm-shutdown-helper.h64
-rw-r--r--xfce4-session/xfsm-shutdown.c716
-rw-r--r--xfce4-session/xfsm-shutdown.h73
21 files changed, 1927 insertions, 2654 deletions
diff --git a/configure.in.in b/configure.in.in
index 980bc35c..c80e5e53 100644
--- a/configure.in.in
+++ b/configure.in.in
@@ -62,7 +62,7 @@ AC_HEADER_STDC
AC_CHECK_HEADERS([asm/unistd.h errno.h fcntl.h limits.h \
netdb.h pwd.h signal.h stdarg.h sys/param.h sys/resource.h \
sys/socket.h sys/time.h sys/wait.h sys/utsname.h time.h \
- unistd.h sys/param.h sys/user.h sys/sysctl.h])
+ unistd.h sys/param.h sys/user.h sys/sysctl.h math.h])
AC_CHECK_FUNCS([getaddrinfo gethostbyname gethostname getpwuid setsid \
sigaction strdup sync vfork])
@@ -142,18 +142,6 @@ else
AC_MSG_RESULT([yes])
fi
-dnl Check whether to create session screenshots
-AC_ARG_ENABLE([session-screenshots],
-AC_HELP_STRING([--enable-session-screenshots], [Create screenshots of sessions on logout]),
- [], [enable_session_screenshots=no])
-AC_MSG_CHECKING([whether to create screenshots of sessions on logout])
-if test x"$enable_session_screenshots" != x"yes"; then
- AC_MSG_RESULT([no])
-else
- AC_DEFINE([SESSION_SCREENSHOTS], [1], [Define for session screenshots])
- AC_MSG_RESULT([yes])
-fi
-
dnl
dnl D-Bus RUNTIME Dependencies
dnl
diff --git a/libxfsm/xfsm-util.c b/libxfsm/xfsm-util.c
index e766c25c..ddd9d2a6 100644
--- a/libxfsm/xfsm-util.c
+++ b/libxfsm/xfsm-util.c
@@ -175,23 +175,14 @@ xfsm_window_add_border (GtkWindow *window)
gtk_container_add (GTK_CONTAINER (window), box1);
}
-
-void
-xfsm_window_grab_input (GtkWindow *window)
-{
- GdkWindow *xwindow = GTK_WIDGET (window)->window;
-
- gdk_pointer_grab (xwindow, TRUE, 0, NULL, NULL, GDK_CURRENT_TIME);
- gdk_keyboard_grab (xwindow, FALSE, GDK_CURRENT_TIME);
- XSetInputFocus (GDK_DISPLAY (), GDK_WINDOW_XWINDOW (xwindow),
- RevertToParent, CurrentTime);
-}
-
-
XfconfChannel*
xfsm_open_config (void)
{
- return xfconf_channel_get ("xfce4-session");
+ static XfconfChannel *channel = NULL;
+
+ if (G_UNLIKELY (channel == NULL))
+ channel = xfconf_channel_get ("xfce4-session");
+ return channel;
}
gchar*
diff --git a/libxfsm/xfsm-util.h b/libxfsm/xfsm-util.h
index b215b54b..8ca9fc25 100644
--- a/libxfsm/xfsm-util.h
+++ b/libxfsm/xfsm-util.h
@@ -47,8 +47,6 @@ gboolean xfsm_strv_equal (gchar **a, gchar **b);
void xfsm_window_add_border (GtkWindow *window);
-void xfsm_window_grab_input (GtkWindow *window);
-
XfconfChannel *xfsm_open_config (void);
gchar *xfsm_gdk_display_get_fullname (GdkDisplay *display);
diff --git a/scripts/xinitrc.in.in b/scripts/xinitrc.in.in
index e63eac1b..1395fb5e 100755
--- a/scripts/xinitrc.in.in
+++ b/scripts/xinitrc.in.in
@@ -212,7 +212,7 @@ fi
# Run xfce4-session if installed
if which xfce4-session >/dev/null 2>&1; then
- xfce4-session
+ ck-launch-session xfce4-session
if test "$ssh_agent_kill_cmd"; then
echo "running '$ssh_agent_kill_cmd'"
diff --git a/xfce4-session/Makefile.am b/xfce4-session/Makefile.am
index 9c845b92..089d3c56 100644
--- a/xfce4-session/Makefile.am
+++ b/xfce4-session/Makefile.am
@@ -37,6 +37,8 @@ xfce4_session_SOURCES = \
xfsm-compat-gnome.h \
xfsm-compat-kde.c \
xfsm-compat-kde.h \
+ xfsm-consolekit.c \
+ xfsm-consolekit.h \
xfsm-dns.c \
xfsm-dns.h \
xfsm-error.c \
@@ -55,8 +57,6 @@ xfce4_session_SOURCES = \
xfsm-properties.h \
xfsm-shutdown.c \
xfsm-shutdown.h \
- xfsm-shutdown-helper.c \
- xfsm-shutdown-helper.h \
xfsm-splash-screen.c \
xfsm-splash-screen.h \
xfsm-startup.c \
@@ -95,7 +95,8 @@ xfce4_session_LDADD = \
$(DBUS_GLIB_LIBS) \
$(LIBWNCK_LIBS) \
$(XFCONF_LIBS) \
- $(GNOME_KEYRING_LIBS)
+ $(GNOME_KEYRING_LIBS) \
+ -lm
xfce4_session_DEPENDENCIES = \
$(top_builddir)/libxfsm/libxfsm-4.6.la
diff --git a/xfce4-session/main.c b/xfce4-session/main.c
index e88b8952..ddac4077 100644
--- a/xfce4-session/main.c
+++ b/xfce4-session/main.c
@@ -195,11 +195,13 @@ xfsm_dbus_cleanup (void)
int
main (int argc, char **argv)
{
- XfsmManager *manager;
- XfsmShutdownType shutdown_type;
- GError *error = NULL;
- GdkDisplay *dpy;
- XfconfChannel *channel;
+ XfsmManager *manager;
+ GError *error = NULL;
+ GdkDisplay *dpy;
+ XfconfChannel *channel;
+ XfsmShutdownType shutdown_type;
+ XfsmShutdown *shutdown;
+ gboolean succeed;
xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
@@ -261,13 +263,25 @@ main (int argc, char **argv)
xfsm_manager_restart (manager);
gtk_main ();
-
+
shutdown_type = xfsm_manager_get_shutdown_type (manager);
+
g_object_unref (manager);
g_object_unref (channel);
xfsm_dbus_cleanup ();
ice_cleanup ();
- return xfsm_shutdown (shutdown_type);
+ if (shutdown_type == XFSM_SHUTDOWN_SHUTDOWN
+ || shutdown_type == XFSM_SHUTDOWN_RESTART)
+ {
+ shutdown = xfsm_shutdown_get ();
+ succeed = xfsm_shutdown_try_type (shutdown, shutdown_type, &error);
+ if (!succeed)
+ g_warning ("Failed to shutdown/restart: %s", ERROR_MSG (error));
+ g_object_unref (shutdown);
+ return succeed ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
}
diff --git a/xfce4-session/xfsm-consolekit.c b/xfce4-session/xfsm-consolekit.c
new file mode 100644
index 00000000..d11c8105
--- /dev/null
+++ b/xfce4-session/xfsm-consolekit.c
@@ -0,0 +1,337 @@
+/*-
+ * Copyright (c) 2010 Ali Abdallah <aliov@xfce.org>
+ * Copyright (c) 2011 Nick Schermer <nick@xfce.org>
+ * All rights reserved.
+ *
+ * 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, 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <xfce4-session/xfsm-consolekit.h>
+
+
+
+#define CK_NAME "org.freedesktop.ConsoleKit"
+#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
+#define CK_MANAGER_NAME CK_NAME ".Manager"
+
+
+
+static void xfsm_consolekit_finalize (GObject *object);
+static gboolean xfsm_consolekit_proxy_ensure (XfsmConsolekit *consolekit,
+ GError **error);
+static void xfsm_consolekit_proxy_free (XfsmConsolekit *consolekit);
+
+
+
+struct _XfsmConsolekitClass
+{
+ GObjectClass __parent__;
+};
+
+struct _XfsmConsolekit
+{
+ GObject __parent__;
+
+ DBusGConnection *dbus_conn;
+ DBusGProxy *ck_proxy;
+ DBusGProxy *dbus_proxy;
+};
+
+
+
+G_DEFINE_TYPE (XfsmConsolekit, xfsm_consolekit, G_TYPE_OBJECT)
+
+
+
+static void
+xfsm_consolekit_class_init (XfsmConsolekitClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = xfsm_consolekit_finalize;
+}
+
+
+
+static void
+xfsm_consolekit_init (XfsmConsolekit *consolekit)
+{
+}
+
+
+
+static void
+xfsm_consolekit_finalize (GObject *object)
+{
+ xfsm_consolekit_proxy_free (XFSM_CONSOLEKIT (object));
+
+ (*G_OBJECT_CLASS (xfsm_consolekit_parent_class)->finalize) (object);
+}
+
+
+
+static DBusHandlerResult
+xfsm_consolekit_dbus_filter (DBusConnection *connection,
+ DBusMessage *message,
+ gpointer data)
+{
+ g_return_val_if_fail (XFSM_IS_CONSOLEKIT (data), DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+
+ if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")
+ && g_strcmp0 (dbus_message_get_path (message), DBUS_PATH_LOCAL) == 0)
+ {
+ xfsm_consolekit_proxy_free (XFSM_CONSOLEKIT (data));
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+
+
+static void
+xfsm_consolekit_name_owner_changed (DBusGProxy *dbus_proxy,
+ const gchar *name,
+ const gchar *prev_owner,
+ const gchar *new_owner,
+ XfsmConsolekit *consolekit)
+{
+ GError *err = NULL;
+
+ g_return_if_fail (XFSM_IS_CONSOLEKIT (consolekit));
+ g_return_if_fail (consolekit->dbus_proxy == dbus_proxy);
+
+ if (g_strcmp0 (name, CK_NAME) == 0)
+ {
+ /* only reconnect the consolekit proxy */
+ if (consolekit->ck_proxy != NULL)
+ {
+ g_object_unref (G_OBJECT (consolekit->ck_proxy));
+ consolekit->ck_proxy = NULL;
+ }
+
+ if (!xfsm_consolekit_proxy_ensure (consolekit, &err))
+ {
+ g_warning ("Failed to reconnect to consolekit: %s", err->message);
+ g_error_free (err);
+ }
+ }
+}
+
+
+
+static gboolean
+xfsm_consolekit_proxy_ensure (XfsmConsolekit *consolekit,
+ GError **error)
+{
+ GError *err = NULL;
+ DBusConnection *connection;
+
+ if (consolekit->dbus_conn == NULL)
+ {
+ consolekit->dbus_conn = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
+ if (consolekit->dbus_conn == NULL)
+ goto error1;
+
+ connection = dbus_g_connection_get_connection (consolekit->dbus_conn);
+ dbus_connection_set_exit_on_disconnect (connection, FALSE);
+ dbus_connection_add_filter (connection, xfsm_consolekit_dbus_filter, consolekit, NULL);
+ }
+
+ if (consolekit->dbus_proxy == NULL)
+ {
+ consolekit->dbus_proxy = dbus_g_proxy_new_for_name_owner (consolekit->dbus_conn,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ &err);
+ if (consolekit->dbus_proxy == NULL)
+ goto error1;
+
+ /* (dis)connect to consolekit if stopped/started */
+ dbus_g_proxy_add_signal (consolekit->dbus_proxy,
+ "NameOwnerChanged",
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_INVALID);
+
+ dbus_g_proxy_connect_signal (consolekit->dbus_proxy,
+ "NameOwnerChanged",
+ G_CALLBACK (xfsm_consolekit_name_owner_changed),
+ consolekit, NULL);
+ }
+
+ if (consolekit->ck_proxy == NULL)
+ {
+ consolekit->ck_proxy = dbus_g_proxy_new_for_name_owner (consolekit->dbus_conn,
+ CK_NAME,
+ CK_MANAGER_PATH,
+ CK_MANAGER_NAME,
+ &err);
+ if (consolekit->ck_proxy == NULL)
+ goto error1;
+ }
+
+ return TRUE;
+
+ error1:
+
+ g_propagate_error (error, err);
+ xfsm_consolekit_proxy_free (consolekit);
+
+ return FALSE;
+}
+
+
+
+static void
+xfsm_consolekit_proxy_free (XfsmConsolekit *consolekit)
+{
+ DBusConnection *connection;
+
+ if (consolekit->ck_proxy != NULL)
+ {
+ g_object_unref (G_OBJECT (consolekit->ck_proxy));
+ consolekit->ck_proxy = NULL;
+ }
+
+ if (consolekit->dbus_proxy != NULL)
+ {
+ g_object_unref (G_OBJECT (consolekit->dbus_proxy));
+ consolekit->dbus_proxy = NULL;
+ }
+
+ if (consolekit->dbus_conn != NULL)
+ {
+ connection = dbus_g_connection_get_connection (consolekit->dbus_conn);
+ dbus_connection_remove_filter (connection,
+ xfsm_consolekit_dbus_filter,
+ consolekit);
+
+ dbus_g_connection_unref (consolekit->dbus_conn);
+ consolekit->dbus_conn = NULL;
+ }
+}
+
+
+
+static gboolean
+xfsm_consolekit_can_method (XfsmConsolekit *consolekit,
+ const gchar *method,
+ gboolean *can_method,
+ GError **error)
+{
+ g_return_val_if_fail (can_method != NULL, FALSE);
+
+ /* never return true if something fails */
+ *can_method = FALSE;
+
+ if (!xfsm_consolekit_proxy_ensure (consolekit, error))
+ return FALSE;
+
+ return dbus_g_proxy_call (consolekit->ck_proxy, method,
+ error, G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, can_method,
+ G_TYPE_INVALID);
+}
+
+
+
+static gboolean
+xfsm_consolekit_try_method (XfsmConsolekit *consolekit,
+ const gchar *method,
+ GError **error)
+{
+ if (!xfsm_consolekit_proxy_ensure (consolekit, error))
+ return FALSE;
+
+ return dbus_g_proxy_call (consolekit->ck_proxy, method, error,
+ G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+
+
+XfsmConsolekit *
+xfsm_consolekit_get (void)
+{
+ static XfsmConsolekit *object = NULL;
+
+ if (G_LIKELY (object != NULL))
+ {
+ g_object_ref (G_OBJECT (object));
+ }
+ else
+ {
+ object = g_object_new (XFSM_TYPE_CONSOLEKIT, NULL);
+ g_object_add_weak_pointer (G_OBJECT (object), (gpointer) &object);
+ }
+
+ return object;
+}
+
+
+
+gboolean
+xfsm_consolekit_try_restart (XfsmConsolekit *consolekit,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_CONSOLEKIT (consolekit), FALSE);
+
+ return xfsm_consolekit_try_method (consolekit, "Restart", error);
+}
+
+
+
+gboolean
+xfsm_consolekit_try_shutdown (XfsmConsolekit *consolekit,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_CONSOLEKIT (consolekit), FALSE);
+
+ return xfsm_consolekit_try_method (consolekit, "Stop", error);
+}
+
+
+
+gboolean
+xfsm_consolekit_can_restart (XfsmConsolekit *consolekit,
+ gboolean *can_restart,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_CONSOLEKIT (consolekit), FALSE);
+
+
+ return xfsm_consolekit_can_method (consolekit, "CanRestart",
+ can_restart, error);
+}
+
+
+
+gboolean
+xfsm_consolekit_can_shutdown (XfsmConsolekit *consolekit,
+ gboolean *can_shutdown,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_CONSOLEKIT (consolekit), FALSE);
+
+ return xfsm_consolekit_can_method (consolekit, "CanStop",
+ can_shutdown, error);
+}
diff --git a/xfce4-session/xfsm-consolekit.h b/xfce4-session/xfsm-consolekit.h
new file mode 100644
index 00000000..17dbe428
--- /dev/null
+++ b/xfce4-session/xfsm-consolekit.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2003-2006 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2010 Ali Abdallah <aliov@xfce.org>
+ * Copyright (c) 2011 Nick Schermer <nick@xfce.org>
+ * All rights reserved.
+ *
+ * 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, 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_SHUTDOWN_HELPER_H__
+#define __XFSM_SHUTDOWN_HELPER_H__
+
+typedef struct _XfsmConsolekitClass XfsmConsolekitClass;
+typedef struct _XfsmConsolekit XfsmConsolekit;
+
+#define XFSM_TYPE_CONSOLEKIT (xfsm_consolekit_get_type ())
+#define XFSM_CONSOLEKIT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFSM_TYPE_CONSOLEKIT, XfsmConsolekit))
+#define XFSM_CONSOLEKIT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFSM_TYPE_CONSOLEKIT, XfsmConsolekitClass))
+#define XFSM_IS_CONSOLEKIT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFSM_TYPE_CONSOLEKIT))
+#define XFSM_IS_CONSOLEKIT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFSM_TYPE_CONSOLEKIT))
+#define XFSM_CONSOLEKIT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFSM_TYPE_CONSOLEKIT, XfsmConsolekitClass))
+
+GType xfsm_consolekit_get_type (void) G_GNUC_CONST;
+
+XfsmConsolekit *xfsm_consolekit_get (void);
+
+gboolean xfsm_consolekit_try_restart (XfsmConsolekit *consolekit,
+ GError **error);
+
+gboolean xfsm_consolekit_try_shutdown (XfsmConsolekit *consolekit,
+ GError **error);
+
+gboolean xfsm_consolekit_can_restart (XfsmConsolekit *consolekit,
+ gboolean *can_restart,
+ GError **error);
+
+gboolean xfsm_consolekit_can_shutdown (XfsmConsolekit *consolekit,
+ gboolean *can_shutdown,
+ GError **error);
+
+#endif /* !__XFSM_SHUTDOWN_HELPER_H__ */
diff --git a/xfce4-session/xfsm-error.h b/xfce4-session/xfsm-error.h
index f2bedf94..22ff710c 100644
--- a/xfce4-session/xfsm-error.h
+++ b/xfce4-session/xfsm-error.h
@@ -23,6 +23,8 @@
#define XFSM_TYPE_ERROR (xfsm_error_get_type ())
#define XFSM_ERROR (xfsm_error_get_quark ())
+#define ERROR_MSG(err) ((err) != NULL ? (err)->message : "Error not set")
+
G_BEGIN_DECLS
typedef enum
diff --git a/xfce4-session/xfsm-fadeout.c b/xfce4-session/xfsm-fadeout.c
index 9ee46915..91af5b68 100644
--- a/xfce4-session/xfsm-fadeout.c
+++ b/xfce4-session/xfsm-fadeout.c
@@ -120,6 +120,15 @@ xfsm_fadeout_new (GdkDisplay *display)
void
+xfsm_fadeout_clear (XfsmFadeout *fadeout)
+{
+ if (fadeout != NULL)
+ g_slist_foreach (fadeout->windows, (GFunc) gdk_window_clear, NULL);
+}
+
+
+
+void
xfsm_fadeout_destroy (XfsmFadeout *fadeout)
{
g_slist_foreach (fadeout->windows, (GFunc) gdk_window_hide, NULL);
diff --git a/xfce4-session/xfsm-fadeout.h b/xfce4-session/xfsm-fadeout.h
index 9b31af24..6cc80fe9 100644
--- a/xfce4-session/xfsm-fadeout.h
+++ b/xfce4-session/xfsm-fadeout.h
@@ -30,6 +30,7 @@ G_BEGIN_DECLS;
typedef struct _XfsmFadeout XfsmFadeout;
XfsmFadeout *xfsm_fadeout_new (GdkDisplay *display);
+void xfsm_fadeout_clear (XfsmFadeout *fadeout);
void xfsm_fadeout_destroy (XfsmFadeout *fadeout);
G_END_DECLS;
diff --git a/xfce4-session/xfsm-global.c b/xfce4-session/xfsm-global.c
index 1d5ed372..05f8d80a 100644
--- a/xfce4-session/xfsm-global.c
+++ b/xfce4-session/xfsm-global.c
@@ -142,30 +142,25 @@ xfsm_generate_client_id (SmsConn sms_conn)
GdkPixbuf *
xfsm_load_session_preview (const gchar *name)
{
-#ifdef SESSION_SCREENSHOTS
GdkDisplay *display;
- GdkPixbuf *pb;
+ GdkPixbuf *pb = NULL;
gchar *display_name;
- gchar *resource;
gchar *filename;
+ gchar *path;
/* determine thumb file */
display = gdk_display_get_default ();
display_name = xfsm_gdk_display_get_fullname (display);
- resource = g_strconcat ("sessions/thumbs-", display_name,
- "/", name, ".png", NULL);
- filename = xfce_resource_save_location (XFCE_RESOURCE_CACHE, resource, TRUE);
+ path = g_strconcat ("sessions/thumbs-", display_name, "/", name, ".png", NULL);
+ filename = xfce_resource_lookup (XFCE_RESOURCE_CACHE, path);
g_free (display_name);
- g_free (resource);
-
- pb = gdk_pixbuf_new_from_file (filename, NULL);
+ g_free (path);
+ if (filename != NULL)
+ pb = gdk_pixbuf_new_from_file (filename, NULL);
g_free (filename);
return pb;
-#else
- return NULL;
-#endif
}
diff --git a/xfce4-session/xfsm-global.h b/xfce4-session/xfsm-global.h
index 1fdfe8cc..273361fe 100644
--- a/xfce4-session/xfsm-global.h
+++ b/xfce4-session/xfsm-global.h
@@ -29,16 +29,6 @@
#include <xfce4-session/xfsm-splash-screen.h>
#include <dbus/dbus.h>
-typedef enum
-{
- XFSM_SHUTDOWN_ASK = 0,
- XFSM_SHUTDOWN_LOGOUT,
- XFSM_SHUTDOWN_HALT,
- XFSM_SHUTDOWN_REBOOT,
- XFSM_SHUTDOWN_SUSPEND,
- XFSM_SHUTDOWN_HIBERNATE,
-} XfsmShutdownType;
-
typedef struct _FailsafeClient FailsafeClient;
struct _FailsafeClient
{
diff --git a/xfce4-session/xfsm-logout-dialog.c b/xfce4-session/xfsm-logout-dialog.c
index 8b2fc15a..32c92c27 100644
--- a/xfce4-session/xfsm-logout-dialog.c
+++ b/xfce4-session/xfsm-logout-dialog.c
@@ -1,29 +1,6 @@
/*-
* Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
- * All rights reserved.
- *
- * 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, 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., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA.
- *
- * Parts of this file where taken from gnome-session/logout.c, which
- * was written by Owen Taylor <otaylor@redhat.com>.
- */
-
-/* $Id$ */
-/*-
- * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2011 Nick Schermer <nick@xfce.org>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -62,18 +39,8 @@
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-
-#ifdef HAVE_GETPWUID
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
-#endif
-
-#ifdef HAVE_ASM_UNISTD_H
-#include <asm/unistd.h> /* for __NR_ioprio_set */
+#ifdef HAVE_MATH_H
+#include <math.h>
#endif
#include <libxfce4util/libxfce4util.h>
@@ -82,177 +49,122 @@
#include <libxfsm/xfsm-util.h>
#include <xfce4-session/xfsm-logout-dialog.h>
-#include <xfce4-session/xfsm-compat-gnome.h>
-#include <xfce4-session/xfsm-compat-kde.h>
#include <xfce4-session/xfsm-fadeout.h>
#include <xfce4-session/xfsm-global.h>
#include <xfce4-session/xfsm-legacy.h>
-#include <xfce4-session/xfsm-shutdown-helper.h>
+#include <xfce4-session/xfsm-error.h>
-#define BORDER 6
+#ifdef GDK_WINDOWING_X11
+#include <X11/Xlib.h>
+#include <gdk/gdkx.h>
+#endif
-static XfsmShutdownHelper *shutdown_helper = NULL;
-static GtkWidget *shutdown_dialog = NULL;
+#define BORDER 6
+#define SHOTSIZE 64
-#ifdef SESSION_SCREENSHOTS
-static void
-screenshot_save (const gchar *session_name, GdkPixmap *pm, GdkRectangle *area)
-{
- gchar *display_name;
- gchar *resource;
- gchar *filename;
- GdkDisplay *dpy;
- GdkPixbuf *spb;
- GdkPixbuf *pb;
- pb = gdk_pixbuf_get_from_drawable (NULL, GDK_DRAWABLE (pm), NULL,
- 0, 0, 0, 0, area->width, area->height);
- if (pb != NULL)
- {
- /* scale down the pixbuf */
- spb = gdk_pixbuf_scale_simple (pb, 52, 43, GDK_INTERP_HYPER);
+static void xfsm_logout_dialog_finalize (GObject *object);
+static GtkWidget *xfsm_logout_dialog_button (const gchar *title,
+ const gchar *icon_name,
+ const gchar *icon_name_fallback,
+ XfsmShutdownType type,
+ XfsmLogoutDialog *dialog);
+static void xfsm_logout_dialog_activate (XfsmLogoutDialog *dialog);
- if (spb != NULL)
- {
- /* determine thumb file */
- dpy = gdk_drawable_get_display (GDK_DRAWABLE (pm));
- display_name = xfsm_gdk_display_get_fullname (dpy);
- resource = g_strconcat ("sessions/thumbs-", display_name,
- "/", session_name, ".png", NULL);
- filename = xfce_resource_save_location (XFCE_RESOURCE_CACHE,
- resource, TRUE);
- g_free (display_name);
- g_free (resource);
-
- gdk_pixbuf_save (spb, filename, "png", NULL, NULL);
-
- g_object_unref (G_OBJECT (spb));
- g_free (filename);
- }
- g_object_unref (G_OBJECT (pb));
- }
-}
-#endif
+enum
+{
+ MODE_LOGOUT_BUTTONS,
+ MODE_ASK_PASSWORD,
+ MODE_SHOW_ERROR,
+ N_MODES
+};
-static void
-entry_activate_cb (GtkWidget *entry, GtkDialog *dialog)
+struct _XfsmLogoutDialogClass
{
- gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
-}
+ GtkDialogClass __parent__;
+};
-static void
-logout_button_clicked (GtkWidget *b, gint *shutdown_type)
+struct _XfsmLogoutDialog
{
- *shutdown_type = XFSM_SHUTDOWN_LOGOUT;
+ GtkDialog __parent__;
- gtk_dialog_response (GTK_DIALOG (shutdown_dialog), GTK_RESPONSE_OK);
-}
+ /* set when a button is clicked */
+ XfsmShutdownType type_clicked;
-static void
-reboot_button_clicked (GtkWidget *b, gint *shutdown_type)
-{
- *shutdown_type = XFSM_SHUTDOWN_REBOOT;
+ /* save session checkbox */
+ GtkWidget *save_session;
- gtk_dialog_response (GTK_DIALOG (shutdown_dialog), GTK_RESPONSE_OK);
-}
+ /* mode widgets */
+ GtkWidget *box[N_MODES];
-static void
-halt_button_clicked (GtkWidget *b, gint *shutdown_type)
-{
- *shutdown_type = XFSM_SHUTDOWN_HALT;
+ /* dialog buttons */
+ GtkWidget *button_cancel;
+ GtkWidget *button_ok;
+ GtkWidget *button_close;
- gtk_dialog_response (GTK_DIALOG (shutdown_dialog), GTK_RESPONSE_OK);
-}
+ /* password entry */
+ GtkWidget *password_entry;
+
+ /* error label */
+ GtkWidget *error_label;
+
+ /* pm instance */
+ XfsmShutdown *shutdown;
+};
+
+
+
+G_DEFINE_TYPE (XfsmLogoutDialog, xfsm_logout_dialog, GTK_TYPE_DIALOG)
-static void
-suspend_button_clicked (GtkWidget *b, gint *shutdown_type)
-{
- *shutdown_type = XFSM_SHUTDOWN_SUSPEND;
- gtk_dialog_response (GTK_DIALOG (shutdown_dialog), GTK_RESPONSE_OK);
-}
static void
-hibernate_button_clicked (GtkWidget *b, gint *shutdown_type)
+xfsm_logout_dialog_class_init (XfsmLogoutDialogClass *klass)
{
- *shutdown_type = XFSM_SHUTDOWN_HIBERNATE;
+ GObjectClass *gobject_class;
- gtk_dialog_response (GTK_DIALOG (shutdown_dialog), GTK_RESPONSE_OK);
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = xfsm_logout_dialog_finalize;
}
-/*
- */
-gboolean
-xfsm_logout_dialog (const gchar *session_name,
- XfsmShutdownType *shutdown_type,
- gboolean *save_session)
+
+
+static void
+xfsm_logout_dialog_init (XfsmLogoutDialog *dialog)
{
- gboolean accessibility;
- GtkIconTheme *icon_theme;
- XfsmFadeout *fadeout = NULL;
- GdkScreen *screen;
- GtkWidget *dialog;
- GtkWidget *label;
- GtkWidget *dbox;
- GtkWidget *hbox;
- GtkWidget *vbox;
- GtkWidget *vbox2;
- GtkWidget *image;
- GtkWidget *checkbox;
- GtkWidget *entry_vbox;
- GtkWidget *entry;
- GtkWidget *hidden;
- GtkWidget *logout_button;
- GtkWidget *reboot_button;
- GtkWidget *halt_button;
- GtkWidget *suspend_button = NULL;
- GtkWidget *hibernate_button = NULL;
- GtkWidget *cancel_button;
- GtkWidget *ok_button;
- GdkPixbuf *icon;
- gboolean saveonexit;
- gboolean autosave;
- gboolean prompt;
- gboolean show_suspend;
- gboolean show_hibernate;
-
- gboolean show_restart;
- gboolean show_shutdown;
-
- gboolean require_password;
-
- gint monitor;
- gint result;
- XfceKiosk *kiosk;
- gboolean kiosk_can_shutdown;
- gboolean kiosk_can_save_session;
+ const gchar *username;
+ GtkWidget *label;
+ gchar *label_str;
+ PangoAttrList *attrs;
+ GtkWidget *vbox;
+ GtkWidget *main_vbox;
+ GtkWidget *hbox;
+ GtkWidget *button;
+ XfceKiosk *kiosk;
+ gboolean can_shutdown;
+ gboolean kiosk_can_shutdown;
+ gboolean kiosk_can_save_session;
+ gboolean save_session = FALSE;
+ gboolean can_restart;
+ gboolean can_suspend = FALSE;
+ gboolean can_hibernate = FALSE;
+ GError *error = NULL;
XfconfChannel *channel;
-#ifdef SESSION_SCREENSHOTS
- GdkRectangle screenshot_area;
- GdkWindow *root;
- GdkPixmap *screenshot_pm = NULL;
- GdkGC *screenshot_gc;
-#endif
-#ifdef HAVE_GETPWUID
- struct passwd *pw;
-#endif
+ GtkWidget *entry;
+ GtkWidget *image;
+ GtkWidget *separator;
- g_return_val_if_fail(save_session != NULL, FALSE);
- g_return_val_if_fail(shutdown_type != NULL, FALSE);
+ dialog->type_clicked = XFSM_SHUTDOWN_LOGOUT;
- icon_theme = gtk_icon_theme_get_default ();
-
- /* destroy any previously running shutdown helper first */
- if (shutdown_helper != NULL)
- {
- g_object_unref (shutdown_helper);
- shutdown_helper = NULL;
- }
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
+ gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+ gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
/* load kiosk settings */
kiosk = xfce_kiosk_new ("xfce4-session");
@@ -260,549 +172,744 @@ xfsm_logout_dialog (const gchar *session_name,
kiosk_can_save_session = xfce_kiosk_query (kiosk, "SaveSession");
xfce_kiosk_free (kiosk);
- /* load configuration */
+ /* load xfconf settings */
channel = xfsm_open_config ();
- channel = xfconf_channel_get ("xfce4-session");
- saveonexit = xfconf_channel_get_bool (channel, "/general/SaveOnExit", TRUE);
- autosave = xfconf_channel_get_bool (channel, "/general/AutoSave", FALSE);
- prompt = xfconf_channel_get_bool (channel, "/general/PromptOnLogout", TRUE);
- show_suspend = xfconf_channel_get_bool (channel, "/shutdown/ShowSuspend", TRUE);
- show_hibernate = xfconf_channel_get_bool (channel, "/shutdown/ShowHibernate", TRUE);
-
- /* make the session-save settings obey the kiosk settings */
- if (!kiosk_can_save_session)
- {
- saveonexit = FALSE;
- autosave = FALSE;
- }
+ if (kiosk_can_save_session)
+ save_session = xfconf_channel_get_bool (channel, "/general/SaveOnExit", TRUE);
+
+ main_vbox = gtk_vbox_new (FALSE, BORDER);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), main_vbox, TRUE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (main_vbox), BORDER);
+ gtk_widget_show (main_vbox);
+
+ /* label showing the users' name */
+ username = g_get_real_name ();
+ if (username == NULL || *username == '\0')
+ username = g_get_user_name ();
+
+ label_str = g_strdup_printf (_("Log out %s"), username);
+ label = gtk_label_new (label_str);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
+ gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, TRUE, 0);
+ gtk_widget_show (label);
+ g_free (label_str);
+
+ attrs = pango_attr_list_new ();
+ pango_attr_list_insert (attrs, pango_attr_scale_new (PANGO_SCALE_LARGE));
+ pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
+ gtk_label_set_attributes (GTK_LABEL (label), attrs);
+ pango_attr_list_unref (attrs);
+
+ separator = gtk_hseparator_new ();
+ gtk_box_pack_start (GTK_BOX (main_vbox), separator, FALSE, TRUE, 0);
+ gtk_widget_show (separator);
+
+ /**
+ * Start mode MODE_LOGOUT_BUTTONS
+ **/
+ dialog->box[MODE_LOGOUT_BUTTONS] = vbox = gtk_vbox_new (FALSE, BORDER);
+ gtk_box_pack_start (GTK_BOX (main_vbox), vbox, TRUE, TRUE, 0);
- /* if PromptOnLogout is off, saving depends on AutoSave */
- if (!prompt)
+ hbox = gtk_hbox_new (TRUE, BORDER);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+ gtk_widget_show (hbox);
+
+ dialog->shutdown = xfsm_shutdown_get ();
+
+ /**
+ * Cancel
+ **/
+ dialog->button_cancel = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL);
+
+ /**
+ * Ok, for password mode
+ **/
+ dialog->button_ok = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK);
+ gtk_widget_hide (dialog->button_ok);
+
+ /**
+ * Close, for password error
+ **/
+ dialog->button_close = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ GTK_STOCK_CLOSE,
+ GTK_RESPONSE_CANCEL);
+ gtk_widget_hide (dialog->button_close);
+
+ /**
+ * Logout
+ **/
+ button = xfsm_logout_dialog_button (_("_Log Out"), "system-log-out",
+ "xfsm-logout", XFSM_SHUTDOWN_LOGOUT,
+ dialog);
+
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show (button);
+ gtk_widget_grab_focus (button);
+
+ /**
+ * Reboot
+ **/
+ can_restart = kiosk_can_shutdown;
+ if (can_restart)
{
- *shutdown_type = XFSM_SHUTDOWN_LOGOUT;
- *save_session = autosave;
+ if (!xfsm_shutdown_can_restart (dialog->shutdown, &can_restart, &error))
+ {
+ g_printerr ("%s: Querying CanRestart failed, %s\n\n",
+ PACKAGE_NAME, ERROR_MSG (error));
+ g_clear_error (&error);
- return TRUE;
+ can_restart = FALSE;
+ }
}
- /* spawn the helper early so we know what it supports when
- * constructing the dialog */
- shutdown_helper = xfsm_shutdown_helper_new ();
+ button = xfsm_logout_dialog_button (_("_Restart"), "system-reboot",
+ "xfsm-reboot", XFSM_SHUTDOWN_RESTART,
+ dialog);
- /* It's really bad here if someone else has the pointer
- * grabbed, so we first grab the pointer and keyboard
- * to an offscreen window, and then once we have the
- * server grabbed, move that to our dialog.
- */
- gtk_rc_reparse_all ();
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_set_sensitive (button, can_restart);
+ gtk_widget_show (button);
- /* get screen with pointer */
- screen = xfce_gdk_screen_get_active (&monitor);
- if (screen == NULL)
+ /**
+ * Shutdown
+ **/
+ can_shutdown = kiosk_can_shutdown;
+ if (can_shutdown)
{
- screen = gdk_screen_get_default ();
- monitor = 0;
+ if (!xfsm_shutdown_can_shutdown (dialog->shutdown, &can_shutdown, &error))
+ {
+ g_printerr ("%s: Querying CanShutdown failed. %s\n\n",
+ PACKAGE_NAME, ERROR_MSG (error));
+ g_clear_error (&error);
+
+ can_shutdown = FALSE;
+ }
}
- /* Try to grab Input on a hidden window first */
- hidden = gtk_invisible_new_for_screen (screen);
- gtk_widget_show_now (hidden);
+ button = xfsm_logout_dialog_button (_("Shut _Down"), "system-shutdown",
+ "xfsm-shutdown", XFSM_SHUTDOWN_SHUTDOWN,
+ dialog);
- accessibility = GTK_IS_ACCESSIBLE (gtk_widget_get_accessible (hidden));
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_set_sensitive (button, can_shutdown);
+ gtk_widget_show (button);
- if (!accessibility)
+ /**
+ * Suspend and Hibernate
+ **/
+ if (kiosk_can_shutdown)
{
- for (;;)
+ /**
+ * Suspend
+ *
+ * Hide the button if Xfpm is not installed
+ **/
+ if (xfconf_channel_get_bool (channel, "/shutdown/ShowSuspend", TRUE))
{
- if (gdk_pointer_grab (hidden->window, TRUE, 0, NULL, NULL,
- GDK_CURRENT_TIME) == GDK_GRAB_SUCCESS)
+ if (xfsm_shutdown_can_suspend (dialog->shutdown, &can_suspend, &error))
{
- if (gdk_keyboard_grab (hidden->window, FALSE, GDK_CURRENT_TIME)
- == GDK_GRAB_SUCCESS)
- {
- break;
- }
+ button = xfsm_logout_dialog_button (_("Sus_pend"), "system-suspend",
+ "xfsm-suspend", XFSM_SHUTDOWN_SUSPEND,
+ dialog);
- gdk_pointer_ungrab (GDK_CURRENT_TIME);
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_set_sensitive (button, can_suspend);
+ gtk_widget_show (button);
+ }
+ else
+ {
+ g_printerr ("%s: Querying CanSuspend failed. %s\n\n",
+ PACKAGE_NAME, ERROR_MSG (error));
+ g_clear_error (&error);
}
-
- g_usleep (50 * 1000);
}
-#ifdef SESSION_SCREENSHOTS
- /* grab a screenshot */
- root = gdk_screen_get_root_window (screen);
- gdk_screen_get_monitor_geometry (screen, monitor, &screenshot_area);
- screenshot_pm = gdk_pixmap_new (GDK_DRAWABLE (root),
- screenshot_area.width,
- screenshot_area.height,
- -1);
- screenshot_gc = gdk_gc_new (GDK_DRAWABLE (screenshot_pm));
- gdk_gc_set_function (screenshot_gc, GDK_COPY);
- gdk_gc_set_subwindow (screenshot_gc, TRUE);
- gdk_draw_drawable (GDK_DRAWABLE (screenshot_pm),
- screenshot_gc,
- GDK_DRAWABLE (root),
- screenshot_area.x,
- screenshot_area.y,
- 0,
- 0,
- screenshot_area.width,
- screenshot_area.height);
- g_object_unref (G_OBJECT (screenshot_gc));
-#endif
-
- /* display fadeout */
- fadeout = xfsm_fadeout_new (gtk_widget_get_display (hidden));
- gdk_flush ();
+ /**
+ * Hibernate
+ *
+ * Hide the button if Xfpm is not installed
+ **/
+ if (xfconf_channel_get_bool (channel, "/shutdown/ShowHibernate", TRUE))
+ {
+ if (xfsm_shutdown_can_hibernate (dialog->shutdown, &can_hibernate, &error))
+ {
+ button = xfsm_logout_dialog_button (_("_Hibernate"), "system-hibernate",
+ "xfsm-hibernate", XFSM_SHUTDOWN_HIBERNATE,
+ dialog);
- /* create confirm dialog */
- dialog = g_object_new (GTK_TYPE_DIALOG,
- "type", GTK_WINDOW_POPUP,
- NULL);
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_set_sensitive (button, can_hibernate);
+ gtk_widget_show (button);
+ }
+ else
+ {
+ g_printerr ("%s: Querying CanHibernate failed. %s\n\n",
+ PACKAGE_NAME, ERROR_MSG (error));
+ g_clear_error (&error);
+ }
+ }
}
- else
+
+ /**
+ * Save session
+ **/
+ if (kiosk_can_save_session
+ && !xfconf_channel_get_bool (channel, "/general/AutoSave", FALSE))
{
- dialog = gtk_dialog_new ();
- atk_object_set_role (gtk_widget_get_accessible (dialog), ATK_ROLE_ALERT);
- gtk_window_set_decorated (GTK_WINDOW (dialog), FALSE);
+ dialog->save_session = gtk_check_button_new_with_mnemonic (_("_Save session for future logins"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->save_session), save_session);
+ gtk_box_pack_start (GTK_BOX (vbox), dialog->save_session, FALSE, TRUE, BORDER);
+ gtk_widget_show (dialog->save_session);
}
- shutdown_dialog = dialog;
-
- cancel_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL);
+ attrs = pango_attr_list_new ();
+ pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
- ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK,
- GTK_RESPONSE_OK);
+ /**
+ * Start mode MODE_ASK_PASSWORD
+ **/
+ dialog->box[MODE_ASK_PASSWORD] = vbox = gtk_vbox_new (FALSE, BORDER);
+ gtk_box_pack_start (GTK_BOX (main_vbox), vbox, TRUE, TRUE, 0);
- gtk_widget_hide (ok_button);
-
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
- gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
- gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
- gtk_window_set_screen (GTK_WINDOW (dialog), screen);
+ hbox = gtk_hbox_new (FALSE, BORDER * 2);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+ gtk_widget_show (hbox);
- dbox = GTK_DIALOG(dialog)->vbox;
+ image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_DIALOG);
+ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
+ gtk_widget_show (image);
- vbox = gtk_vbox_new(FALSE, BORDER);
- gtk_box_pack_start(GTK_BOX(dbox), vbox, TRUE, TRUE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), BORDER);
- gtk_widget_show(vbox);
+ vbox = gtk_vbox_new (FALSE, BORDER);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+ gtk_widget_show (vbox);
-#ifdef HAVE_GETPWUID
- pw = getpwuid (getuid ());
- if (G_LIKELY(pw && pw->pw_name && *pw->pw_name))
- {
- gchar *text = g_strdup_printf (_("<span size='large'><b>Log out %s</b></span>"), pw->pw_name);
- GtkWidget *logout_label = g_object_new (GTK_TYPE_LABEL,
- "label", text,
- "use-markup", TRUE,
- "justify", GTK_JUSTIFY_CENTER,
- "xalign", 0.5,
- "yalign", 0.5,
- NULL);
-
- gtk_widget_show (logout_label);
- gtk_box_pack_start (GTK_BOX (vbox), logout_label, FALSE, FALSE, 0);
-
- g_free (text);
- }
-#endif
+ label = gtk_label_new (_("Please enter your password"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.00, 0.50);
+ gtk_label_set_attributes (GTK_LABEL (label), attrs);
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
- hbox = gtk_hbox_new (TRUE, BORDER);
+ dialog->password_entry = entry = gtk_entry_new ();
+ gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
+ gtk_entry_set_width_chars (GTK_ENTRY (entry), 30);
+ gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, TRUE, 0);
+ g_signal_connect_swapped (G_OBJECT (entry), "activate",
+ G_CALLBACK (xfsm_logout_dialog_activate), dialog);
+ gtk_widget_show (entry);
+
+ /**
+ * Start mode MODE_SHOW_ERROR
+ **/
+ dialog->box[MODE_SHOW_ERROR] = vbox = gtk_vbox_new (FALSE, BORDER);
+ gtk_box_pack_start (GTK_BOX (main_vbox), vbox, TRUE, TRUE, 0);
+
+ hbox = gtk_hbox_new (FALSE, BORDER * 2);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
gtk_widget_show (hbox);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
- /* 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), shutdown_type);
-
- 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 = gtk_icon_theme_load_icon (icon_theme,
- "system-log-out",
- 32,
- 0,
- NULL);
- if (!icon)
- icon = gtk_icon_theme_load_icon (icon_theme,
- "xfsm-logout",
- 32,
- GTK_ICON_LOOKUP_GENERIC_FALLBACK,
- NULL);
-
- 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_with_mnemonic (_("_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), shutdown_type);
-
- 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 = gtk_icon_theme_load_icon (icon_theme,
- "system-reboot",
- 32,
- 0,
- NULL);
-
- if (!icon)
- icon = gtk_icon_theme_load_icon (icon_theme,
- "xfsm-reboot",
- 32,
- GTK_ICON_LOOKUP_GENERIC_FALLBACK,
- NULL);
-
- image = gtk_image_new_from_pixbuf (icon);
+ image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG);
+ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
gtk_widget_show (image);
- gtk_box_pack_start (GTK_BOX (vbox2), image, FALSE, FALSE, 0);
- g_object_unref (icon);
- label = gtk_label_new_with_mnemonic (_("_Restart"));
+ vbox = gtk_vbox_new (FALSE, BORDER);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+ gtk_widget_show (vbox);
+
+ label = gtk_label_new (_("An error occurred"));
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.00, 0.50);
+ gtk_label_set_attributes (GTK_LABEL (label), attrs);
gtk_widget_show (label);
- gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
-
- g_object_get (shutdown_helper,
- "user-can-restart", &show_restart,
- NULL);
-
- if (!kiosk_can_shutdown || !show_restart )
- gtk_widget_set_sensitive (reboot_button, FALSE);
-
- /* 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), shutdown_type);
-
- 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 = gtk_icon_theme_load_icon (icon_theme,
- "system-shutdown",
- 32,
- 0,
- NULL);
-
- if (!icon)
- icon = gtk_icon_theme_load_icon (icon_theme,
- "xfsm-shutdown",
- 32,
- GTK_ICON_LOOKUP_GENERIC_FALLBACK,
- NULL);
-
- 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_with_mnemonic (_("Shut _Down"));
+ label = gtk_label_new (_("Either the password you entered is "
+ "invalid, or the system administrator "
+ "disallows shutting down this computer "
+ "with your user account."));
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
gtk_widget_show (label);
- gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
- g_object_get (shutdown_helper,
- "user-can-shutdown", &show_shutdown,
- NULL);
+ pango_attr_list_unref (attrs);
+}
- if (!kiosk_can_shutdown || !show_shutdown)
- gtk_widget_set_sensitive (halt_button, FALSE);
- if (show_suspend)
- g_object_get (shutdown_helper,
- "user-can-suspend", &show_suspend,
- NULL);
- if (show_hibernate)
- g_object_get (shutdown_helper,
- "user-can-hibernate", &show_hibernate,
- NULL);
+static void
+xfsm_logout_dialog_finalize (GObject *object)
+{
+ XfsmLogoutDialog *dialog = XFSM_LOGOUT_DIALOG (object);
+ g_object_unref (G_OBJECT (dialog->shutdown));
- if (kiosk_can_shutdown && (show_suspend || show_hibernate))
+ (*G_OBJECT_CLASS (xfsm_logout_dialog_parent_class)->finalize) (object);
+}
+
+
+
+static void
+xfsm_logout_dialog_set_mode (XfsmLogoutDialog *dialog,
+ gint mode)
+{
+ gint i;
+
+ for (i = 0; i < N_MODES; i++)
+ gtk_widget_set_visible (dialog->box[i], i == mode);
+
+ gtk_widget_set_visible (dialog->button_cancel, mode != MODE_SHOW_ERROR);
+ gtk_widget_set_visible (dialog->button_ok, mode == MODE_ASK_PASSWORD);
+ gtk_widget_set_visible (dialog->button_close, mode == MODE_SHOW_ERROR);
+}
+
+
+
+static void
+xfsm_logout_dialog_button_clicked (GtkWidget *button,
+ XfsmLogoutDialog *dialog)
+{
+ gint *val;
+
+ val = g_object_get_data (G_OBJECT (button), "shutdown-type");
+ g_assert (val != NULL);
+ dialog->type_clicked = *val;
+
+ gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+}
+
+
+
+static GtkWidget *
+xfsm_logout_dialog_button (const gchar *title,
+ const gchar *icon_name,
+ const gchar *icon_name_fallback,
+ XfsmShutdownType type,
+ XfsmLogoutDialog *dialog)
+{
+ GtkWidget *button;
+ GtkWidget *vbox;
+ GdkPixbuf *pixbuf;
+ GtkWidget *image;
+ GtkWidget *label;
+ static gint icon_size = 0;
+ gint w, h;
+ gint *val;
+ GtkIconTheme *icon_theme;
+
+ g_return_val_if_fail (XFSM_IS_LOGOUT_DIALOG (dialog), NULL);
+
+ val = g_new0 (gint, 1);
+ *val = type;
+
+ button = gtk_button_new ();
+ g_object_set_data_full (G_OBJECT (button), "shutdown-type", val, g_free);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (xfsm_logout_dialog_button_clicked), dialog);
+
+ vbox = gtk_vbox_new (FALSE, BORDER);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), BORDER);
+ gtk_container_add (GTK_CONTAINER (button), vbox);
+ gtk_widget_show (vbox);
+
+ if (G_UNLIKELY (icon_size == 0))
{
- hbox = gtk_hbox_new (FALSE, BORDER);
- gtk_widget_show (hbox);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+ if (gtk_icon_size_lookup (GTK_ICON_SIZE_DND, &w, &h))
+ icon_size = MAX (w, h);
+ else
+ icon_size = 32;
}
- /* suspend */
- if (kiosk_can_shutdown && show_suspend)
+ icon_theme = gtk_icon_theme_get_for_screen (gtk_window_get_screen (GTK_WINDOW (dialog)));
+ pixbuf = gtk_icon_theme_load_icon (icon_theme, icon_name, icon_size, 0, NULL);
+ if (G_UNLIKELY (pixbuf == NULL))
{
- suspend_button = gtk_button_new ();
- gtk_widget_show (suspend_button);
- gtk_box_pack_start (GTK_BOX (hbox), suspend_button, TRUE, TRUE, 0);
-
- g_signal_connect (suspend_button, "clicked",
- G_CALLBACK (suspend_button_clicked), shutdown_type);
-
- vbox2 = gtk_vbox_new (FALSE, BORDER);
- gtk_container_set_border_width (GTK_CONTAINER (vbox2), BORDER);
- gtk_widget_show (vbox2);
- gtk_container_add (GTK_CONTAINER (suspend_button), vbox2);
-
- icon = gtk_icon_theme_load_icon (icon_theme,
- "system-suspend",
- 32,
- 0,
- NULL);
-
- if (!icon)
- icon = gtk_icon_theme_load_icon (icon_theme,
- "xfsm-suspend",
- 32,
- GTK_ICON_LOOKUP_GENERIC_FALLBACK,
+ pixbuf = gtk_icon_theme_load_icon (icon_theme, icon_name_fallback,
+ icon_size, GTK_ICON_LOOKUP_GENERIC_FALLBACK,
NULL);
+ }
- 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);
+ image = gtk_image_new_from_pixbuf (pixbuf);
+ gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0);
+ gtk_widget_show (image);
- label = gtk_label_new_with_mnemonic (_("Sus_pend"));
- gtk_widget_show (label);
- gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
- }
+ label = gtk_label_new_with_mnemonic (title);
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
- /* hibernate */
- if (kiosk_can_shutdown && show_hibernate)
- {
- hibernate_button = gtk_button_new ();
- gtk_widget_show (hibernate_button);
- gtk_box_pack_start (GTK_BOX (hbox), hibernate_button, TRUE, TRUE, 0);
-
- g_signal_connect (hibernate_button, "clicked",
- G_CALLBACK (hibernate_button_clicked), shutdown_type);
-
- vbox2 = gtk_vbox_new (FALSE, BORDER);
- gtk_container_set_border_width (GTK_CONTAINER (vbox2), BORDER);
- gtk_widget_show (vbox2);
- gtk_container_add (GTK_CONTAINER (hibernate_button), vbox2);
-
- icon = gtk_icon_theme_load_icon (icon_theme,
- "system-hibernate",
- 32,
- 0,
- NULL);
-
- if (!icon)
- icon = gtk_icon_theme_load_icon (icon_theme,
- "xfsm-hibernate",
- 32,
- GTK_ICON_LOOKUP_GENERIC_FALLBACK,
- NULL);
+ return button;
+}
- 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_with_mnemonic (_("_Hibernate"));
- gtk_widget_show (label);
- gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
- }
- /* save session */
- if (!autosave && kiosk_can_save_session)
+static void
+xfsm_logout_dialog_activate (XfsmLogoutDialog *dialog)
+{
+ g_return_if_fail (XFSM_IS_LOGOUT_DIALOG (dialog));
+ gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+}
+
+
+
+static GdkPixbuf *
+xfsm_logout_dialog_screenshot_new (GdkScreen *screen)
+{
+ GdkRectangle rect, screen_rect;
+ GdkWindow *window;
+ GdkPixbuf *screenshot;
+ gint x, y;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ screen_rect.x = 0;
+ screen_rect.y = 0;
+ screen_rect.width = gdk_screen_get_width (screen);
+ screen_rect.height = gdk_screen_get_height (screen);
+
+ window = gdk_screen_get_root_window (screen);
+ gdk_drawable_get_size (GDK_DRAWABLE (window), &rect.width, &rect.height);
+ gdk_window_get_origin (window, &x, &y);
+
+ rect.x = x;
+ rect.y = y;
+
+ if (!gdk_rectangle_intersect (&rect, &screen_rect, &rect))
+ return NULL;
+
+ screenshot = gdk_pixbuf_get_from_drawable (NULL,
+ GDK_DRAWABLE (window),
+ NULL,
+ 0, 0,
+ 0, 0,
+ rect.width,
+ rect.height);
+
+ gdk_display_beep (gdk_screen_get_display (screen));
+
+ return screenshot;
+}
+
+
+
+static GdkPixbuf *
+exo_gdk_pixbuf_scale_ratio (GdkPixbuf *source,
+ gint dest_size)
+{
+ gdouble wratio;
+ gdouble hratio;
+ gint source_width;
+ gint source_height;
+ gint dest_width;
+ gint dest_height;
+
+ g_return_val_if_fail (GDK_IS_PIXBUF (source), NULL);
+ g_return_val_if_fail (dest_size > 0, NULL);
+
+ source_width = gdk_pixbuf_get_width (source);
+ source_height = gdk_pixbuf_get_height (source);
+
+ wratio = (gdouble) source_width / (gdouble) dest_size;
+ hratio = (gdouble) source_height / (gdouble) dest_size;
+
+ if (hratio > wratio)
{
- checkbox = gtk_check_button_new_with_mnemonic(
- _("_Save session for future logins"));
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbox), saveonexit);
- gtk_box_pack_start(GTK_BOX(vbox), checkbox, FALSE, TRUE, BORDER);
- gtk_widget_show(checkbox);
+ dest_width = rint (source_width / hratio);
+ dest_height = dest_size;
}
else
{
- checkbox = NULL;
+ dest_width = dest_size;
+ dest_height = rint (source_height / wratio);
}
- /* create small border */
- if (!accessibility)
- xfsm_window_add_border (GTK_WINDOW (dialog));
+ return gdk_pixbuf_scale_simple (source, MAX (dest_width, 1),
+ MAX (dest_height, 1), GDK_INTERP_BILINEAR);
+}
- /* center dialog on target monitor */
- gtk_window_set_screen (GTK_WINDOW (dialog), screen);
- gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
- /* save portion of the root window covered by the dialog */
- if (!accessibility && shutdown_helper != NULL)
+
+static void
+xfsm_logout_dialog_screenshot_save (GdkPixbuf *screenshot,
+ GdkScreen *screen,
+ const gchar *session_name)
+{
+ GdkPixbuf *scaled;
+ gchar *path;
+ gchar *display_name;
+ GdkDisplay *dpy;
+ GError *error = NULL;
+ gchar *filename;
+
+ g_return_if_fail (GDK_IS_PIXBUF (screenshot));
+ g_return_if_fail (GDK_IS_SCREEN (screen));
+
+ scaled = exo_gdk_pixbuf_scale_ratio (screenshot, SHOTSIZE);
+ if (G_LIKELY (scaled != NULL))
{
- gtk_widget_realize (dialog);
- gdk_window_set_override_redirect (dialog->window, TRUE);
- gdk_window_raise (dialog->window);
+ dpy = gdk_screen_get_display (screen);
+ display_name = xfsm_gdk_display_get_fullname (dpy);
+ path = g_strconcat ("sessions/thumbs-", display_name, "/", session_name, ".png", NULL);
+ filename = xfce_resource_save_location (XFCE_RESOURCE_CACHE, path, TRUE);
+ g_free (display_name);
+ g_free (path);
+
+ if (!gdk_pixbuf_save (scaled, filename, "png", &error, NULL))
+ {
+ g_warning ("Failed to save session screenshot: %s", error->message);
+ g_error_free (error);
+ }
+
+ g_free (filename);
+ g_object_unref (G_OBJECT (scaled));
}
+}
- /* need to realize the dialog first! */
- gtk_widget_show_now (dialog);
- gtk_widget_grab_focus (logout_button);
- /* Grab Keyboard and Mouse pointer */
- if (!accessibility)
- xfsm_window_grab_input (GTK_WINDOW (dialog));
- /* run the logout dialog */
- result = gtk_dialog_run (GTK_DIALOG(dialog));
+static gint
+xfsm_logout_dialog_run (GtkDialog *dialog,
+ gboolean grab_input)
+{
+ GdkWindow *window;
+ gint ret;
- if (result == GTK_RESPONSE_OK) {
- *save_session = autosave ? autosave :
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbox));
- }
+ if (grab_input)
+ {
+ gtk_widget_show_now (GTK_WIDGET (dialog));
+
+ window = gtk_widget_get_window (GTK_WIDGET (dialog));
+ if (gdk_keyboard_grab (window, FALSE, GDK_CURRENT_TIME) != GDK_GRAB_SUCCESS)
+ g_critical ("Failed to grab the keyboard for logout window");
+
+#ifdef GDK_WINDOWING_X11
+ /* force input to the dialog */
+ gdk_error_trap_push ();
+ XSetInputFocus (GDK_DISPLAY (),
+ GDK_WINDOW_XWINDOW (window),
+ RevertToParent, CurrentTime);
+ gdk_error_trap_pop ();
+#endif
+ }
- gtk_widget_hide (dialog);
+ ret = gtk_dialog_run (dialog);
+
+ if (grab_input)
+ gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+
+ return ret;
+}
+
+
+
+gboolean
+xfsm_logout_dialog (const gchar *session_name,
+ XfsmShutdownType *return_type,
+ gboolean *return_save_session)
+{
+ gint result;
+ GtkWidget *hidden;
+ gboolean a11y;
+ GtkWidget *dialog;
+ GdkScreen *screen;
+ gint monitor;
+ GdkPixbuf *screenshot = NULL;
+ XfsmFadeout *fadeout = NULL;
+ XfsmLogoutDialog *xfsm_dialog;
+ XfconfChannel *channel = xfsm_open_config ();
+ XfceKiosk *kiosk;
+ gboolean autosave;
+ gboolean kiosk_can_save_session;
+ const gchar *text;
+ XfsmPassState state;
+
+ g_return_val_if_fail (return_type != NULL, FALSE);
+ g_return_val_if_fail (return_save_session != NULL, FALSE);
+
+ /* get autosave state */
+ kiosk = xfce_kiosk_new ("xfce4-session");
+ kiosk_can_save_session = xfce_kiosk_query (kiosk, "SaveSession");
+ xfce_kiosk_free (kiosk);
- g_object_get (shutdown_helper,
- "require-password", &require_password,
- NULL);
+ if (kiosk_can_save_session)
+ autosave = xfconf_channel_get_bool (channel, "/general/AutoSave", FALSE);
+ else
+ autosave = FALSE;
- /* ask password */
- if (result == GTK_RESPONSE_OK && *shutdown_type != XFSM_SHUTDOWN_LOGOUT
- && require_password )
+ /* check if we need to bother the user */
+ if (!xfconf_channel_get_bool (channel, "/general/PromptOnLogout", TRUE))
{
- gtk_widget_show (ok_button);
+ *return_type = XFSM_SHUTDOWN_LOGOUT;
+ *return_save_session = autosave;
- gtk_widget_destroy (vbox);
+ return TRUE;
+ }
- entry_vbox = gtk_vbox_new (FALSE, BORDER);
- gtk_box_pack_start (GTK_BOX (dbox), entry_vbox, TRUE, TRUE, BORDER);
- gtk_widget_show (entry_vbox);
+ /* decide on which screen we should show the dialog */
+ screen = xfce_gdk_screen_get_active (&monitor);
+ if (G_UNLIKELY (screen == NULL))
+ {
+ screen = gdk_screen_get_default ();
+ monitor = 0;
+ }
- label = gtk_label_new (_("Please enter your password:"));
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
- gtk_widget_show (label);
- gtk_box_pack_start (GTK_BOX (entry_vbox), label, FALSE, FALSE, 0);
+ /* check if accessibility is enabled */
+ hidden = gtk_invisible_new_for_screen (screen);
+ gtk_widget_show (hidden);
+ a11y = GTK_IS_ACCESSIBLE (gtk_widget_get_accessible (hidden));
- entry = gtk_entry_new ();
- gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
- gtk_box_pack_start (GTK_BOX (entry_vbox), entry, TRUE, TRUE, 0);
- g_signal_connect (G_OBJECT (entry), "activate",
- G_CALLBACK (entry_activate_cb), dialog);
- gtk_widget_show (entry);
+ if (G_LIKELY (!a11y))
+ {
+ /* wait until we can grab the keyboard, we need this for
+ * the dialog when running it */
+ for (;;)
+ {
+ if (gdk_keyboard_grab (gtk_widget_get_window (hidden), FALSE,
+ GDK_CURRENT_TIME) == GDK_GRAB_SUCCESS)
+ {
+ gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+ break;
+ }
- /* center dialog on target monitor */
- gtk_window_set_screen (GTK_WINDOW (dialog), screen);
- gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+ g_usleep (G_USEC_PER_SEC / 20);
+ }
+
+ /* make a screenshot */
+ if (xfconf_channel_get_bool (channel, "/general/ShowScreenshots", TRUE))
+ screenshot = xfsm_logout_dialog_screenshot_new (screen);
- gtk_widget_show_now (dialog);
- gtk_widget_grab_focus (entry);
+ /* display fadeout */
+ fadeout = xfsm_fadeout_new (gdk_screen_get_display (screen));
+ gdk_flush ();
- /* Grab Keyboard and Mouse pointer */
- if (!accessibility)
- xfsm_window_grab_input (GTK_WINDOW (dialog));
+ dialog = g_object_new (XFSM_TYPE_LOGOUT_DIALOG,
+ "type", GTK_WINDOW_POPUP,
+ "screen", screen, NULL);
- result = gtk_dialog_run (GTK_DIALOG (dialog));
+ xfsm_window_add_border (GTK_WINDOW (dialog));
- if (result == GTK_RESPONSE_OK)
+ gtk_widget_realize (dialog);
+ gdk_window_set_override_redirect (dialog->window, TRUE);
+ gdk_window_raise (dialog->window);
+ }
+ else
+ {
+ dialog = g_object_new (XFSM_TYPE_LOGOUT_DIALOG,
+ "decorated", !a11y,
+ "screen", screen, NULL);
+
+ gtk_window_set_keep_above (GTK_WINDOW (dialog), TRUE);
+ atk_object_set_role (gtk_widget_get_accessible (dialog), ATK_ROLE_ALERT);
+ }
+
+ gtk_widget_destroy (hidden);
+
+ xfsm_dialog = XFSM_LOGOUT_DIALOG (dialog);
+
+ /* set mode */
+ xfsm_logout_dialog_set_mode (xfsm_dialog, MODE_LOGOUT_BUTTONS);
+
+ result = xfsm_logout_dialog_run (GTK_DIALOG (dialog), !a11y);
+
+ gtk_widget_hide (dialog);
+
+ if (result == GTK_RESPONSE_OK)
+ {
+ /* check if the sudo helper needs a password */
+ if (xfsm_shutdown_password_require (xfsm_dialog->shutdown, xfsm_dialog->type_clicked))
{
- const gchar *password = gtk_entry_get_text (GTK_ENTRY (entry));
+ /* switch mode */
+ xfsm_logout_dialog_set_mode (xfsm_dialog, MODE_ASK_PASSWORD);
- if (!xfsm_shutdown_helper_send_password (shutdown_helper, password))
+ /* don't leave artifacts on the background window */
+ xfsm_fadeout_clear (fadeout);
+
+ /* loop for sudo password tries */
+ for (;;)
{
- gtk_label_set_text (GTK_LABEL (label),
- _("<b>An error occurred</b>"));
- gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+ gtk_widget_grab_focus (xfsm_dialog->password_entry);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ result = xfsm_logout_dialog_run (GTK_DIALOG (dialog), !a11y);
- gtk_container_remove (GTK_CONTAINER (
- GTK_DIALOG (dialog)->action_area), cancel_button);
- gtk_container_remove (GTK_CONTAINER (
- GTK_DIALOG (dialog)->action_area), ok_button);
+ if (result == GTK_RESPONSE_OK)
+ {
+ /* bit of visual feedback we're processing the password */
+ gtk_widget_set_sensitive (xfsm_dialog->button_cancel, FALSE);
+ gtk_widget_set_sensitive (xfsm_dialog->button_ok, FALSE);
- gtk_container_remove (GTK_CONTAINER (entry_vbox), entry);
+ /* update the widgets before we lock the loop */
+ while (gtk_events_pending ())
+ g_main_context_iteration (NULL, FALSE);
- gtk_dialog_add_button (GTK_DIALOG (dialog),
- GTK_STOCK_CLOSE,
- GTK_RESPONSE_CANCEL);
+ /* send the password to the helper */
+ text = gtk_entry_get_text (GTK_ENTRY (xfsm_dialog->password_entry));
+ state = xfsm_shutdown_password_send (xfsm_dialog->shutdown, xfsm_dialog->type_clicked, text);
+ gtk_entry_set_text (GTK_ENTRY (xfsm_dialog->password_entry), "");
- label = gtk_label_new (_("Either the password you entered is "
- "invalid, or the system administrator "
- "disallows shutting down this computer "
- "with your user account."));
- gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
- gtk_box_pack_start (GTK_BOX (entry_vbox), label, TRUE, TRUE, 0);
- gtk_widget_show (label);
+ gtk_widget_set_sensitive (xfsm_dialog->button_cancel, TRUE);
+ gtk_widget_set_sensitive (xfsm_dialog->button_ok, TRUE);
- /* center dialog on target monitor */
- gtk_window_set_screen (GTK_WINDOW (dialog), screen);
- gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+ if (state == PASSWORD_RETRY)
+ continue;
- gtk_widget_show_now (dialog);
+ if (state == PASSWORD_FAILED)
+ {
+ gtk_widget_hide (dialog);
- /* Grab Keyboard and Mouse pointer */
- if (!accessibility)
- xfsm_window_grab_input (GTK_WINDOW (dialog));
+ xfsm_logout_dialog_set_mode (xfsm_dialog, MODE_SHOW_ERROR);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
- gtk_dialog_run (GTK_DIALOG (dialog));
+ /* don't leave artifacts on the background window */
+ xfsm_fadeout_clear (fadeout);
- result = GTK_RESPONSE_CANCEL;
- }
- }
- }
+ /* show error */
+ xfsm_logout_dialog_run (GTK_DIALOG (dialog), !a11y);
- gtk_widget_destroy(dialog);
- gtk_widget_destroy(hidden);
+ result = GTK_RESPONSE_CANCEL;
+ }
+ }
- shutdown_dialog = NULL;
+ /* cancel clicked, succeeded or helper killed */
+ break;
+ }
- /* Release Keyboard/Mouse pointer grab */
- if (!accessibility)
- {
- xfsm_fadeout_destroy (fadeout);
+ gtk_widget_hide (dialog);
+ }
- gdk_pointer_ungrab (GDK_CURRENT_TIME);
- gdk_keyboard_ungrab (GDK_CURRENT_TIME);
- gdk_flush ();
+ if (result == GTK_RESPONSE_OK)
+ {
+ /* store autosave state */
+ if (autosave)
+ *return_save_session = TRUE;
+ else if (xfsm_dialog->save_session != NULL)
+ *return_save_session = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (xfsm_dialog->save_session));
+ else
+ *return_save_session = FALSE;
+
+ /* return the clicked action */
+ *return_type = xfsm_dialog->type_clicked;
+ }
}
- /* process all pending events first */
- while (gtk_events_pending ())
- g_main_context_iteration (NULL, FALSE);
+ if (fadeout != NULL)
+ xfsm_fadeout_destroy (fadeout);
- /*
- * remember the current settings.
- */
+ gtk_widget_destroy (dialog);
+
+ /* store channel settings if everything worked fine */
if (result == GTK_RESPONSE_OK)
{
xfconf_channel_set_string (channel, "/general/SessionName", session_name);
- xfconf_channel_set_bool (channel, "/general/SaveOnExit", *save_session);
- }
- else
- {
- g_object_unref (shutdown_helper);
- shutdown_helper = NULL;
+ xfconf_channel_set_bool (channel, "/general/SaveOnExit", *return_save_session);
}
-#ifdef SESSION_SCREENSHOTS
- if (screenshot_pm != NULL)
+ /* save the screenshot */
+ if (screenshot != NULL)
{
if (result == GTK_RESPONSE_OK)
- screenshot_save (session_name, screenshot_pm, &screenshot_area);
-
- g_object_unref (G_OBJECT (screenshot_pm));
+ xfsm_logout_dialog_screenshot_save (screenshot, screen, session_name);
+ g_object_unref (G_OBJECT (screenshot));
}
-#endif
return (result == GTK_RESPONSE_OK);
}
diff --git a/xfce4-session/xfsm-logout-dialog.h b/xfce4-session/xfsm-logout-dialog.h
index ed348b7a..2cb08828 100644
--- a/xfce4-session/xfsm-logout-dialog.h
+++ b/xfce4-session/xfsm-logout-dialog.h
@@ -22,10 +22,22 @@
#ifndef __XFSM_LOGOUT_DIALOG_H__
#define __XFSM_LOGOUT_DIALOG_H__
-#include <xfce4-session/xfsm-global.h>
+#include <xfce4-session/xfsm-shutdown.h>
-gboolean xfsm_logout_dialog (const gchar *session_name,
- XfsmShutdownType *shutdown_type,
- gboolean *save_session);
+typedef struct _XfsmLogoutDialogClass XfsmLogoutDialogClass;
+typedef struct _XfsmLogoutDialog XfsmLogoutDialog;
+
+#define XFSM_TYPE_LOGOUT_DIALOG (xfsm_logout_dialog_get_type ())
+#define XFSM_LOGOUT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFSM_TYPE_LOGOUT_DIALOG, XfsmLogoutDialog))
+#define XFSM_LOGOUT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFSM_TYPE_LOGOUT_DIALOG, XfsmLogoutDialogClass))
+#define XFSM_IS_LOGOUT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFSM_TYPE_LOGOUT_DIALOG))
+#define XFSM_IS_LOGOUT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFSM_TYPE_LOGOUT_DIALOG))
+#define XFSM_LOGOUT_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFSM_TYPE_LOGOUT_DIALOG, XfsmLogoutDialogClass))
+
+GType xfsm_logout_dialog_get_type (void) G_GNUC_CONST;
+
+gboolean xfsm_logout_dialog (const gchar *session_name,
+ XfsmShutdownType *return_type,
+ gboolean *return_save_session);
#endif
diff --git a/xfce4-session/xfsm-manager.c b/xfce4-session/xfsm-manager.c
index 9f87c482..367c11c9 100644
--- a/xfce4-session/xfsm-manager.c
+++ b/xfce4-session/xfsm-manager.c
@@ -71,7 +71,6 @@
#include <libwnck/libwnck.h>
-#include <xfce4-session/xfsm-shutdown-helper.h>
#include <libxfce4ui/libxfce4ui.h>
#include <libxfsm/xfsm-splash-engine.h>
@@ -1085,8 +1084,10 @@ xfsm_manager_save_yourself_global (XfsmManager *manager,
XfsmShutdownType shutdown_type,
gboolean allow_shutdown_save)
{
- gboolean shutdown_save = allow_shutdown_save;
- GList *lp;
+ gboolean shutdown_save = allow_shutdown_save;
+ GList *lp;
+ XfsmShutdown *shutdown_helper;
+ GError *error = NULL;
if (shutdown)
{
@@ -1111,14 +1112,11 @@ xfsm_manager_save_yourself_global (XfsmManager *manager,
if (manager->shutdown_type == XFSM_SHUTDOWN_SUSPEND
|| manager->shutdown_type == XFSM_SHUTDOWN_HIBERNATE)
{
- XfsmShutdownHelper *shutdown_helper;
- GError *error = NULL;
-
- shutdown_helper = xfsm_shutdown_helper_new ();
+ shutdown_helper = xfsm_shutdown_get ();
- if (!xfsm_shutdown_helper_send_command (shutdown_helper,
- manager->shutdown_type,
- &error))
+ if (!xfsm_shutdown_try_type (shutdown_helper,
+ manager->shutdown_type,
+ &error))
{
xfce_message_dialog (NULL, _("Shutdown Failed"),
GTK_STOCK_DIALOG_ERROR,
@@ -1131,10 +1129,8 @@ xfsm_manager_save_yourself_global (XfsmManager *manager,
g_error_free (error);
}
- /* clean up and return */
g_object_unref (shutdown_helper);
-
/* at this point, either we failed to suspend/hibernate, or we
* successfully suspended/hibernated, and we've been woken back
* up, so return control to the user */
diff --git a/xfce4-session/xfsm-manager.h b/xfce4-session/xfsm-manager.h
index b12b143a..521bacc0 100644
--- a/xfce4-session/xfsm-manager.h
+++ b/xfce4-session/xfsm-manager.h
@@ -30,6 +30,7 @@
#include <xfce4-session/xfsm-client.h>
#include <xfce4-session/xfsm-global.h>
+#include <xfce4-session/xfsm-shutdown.h>
G_BEGIN_DECLS
diff --git a/xfce4-session/xfsm-shutdown-helper.c b/xfce4-session/xfsm-shutdown-helper.c
deleted file mode 100644
index ef29f4f5..00000000
--- a/xfce4-session/xfsm-shutdown-helper.c
+++ /dev/null
@@ -1,1862 +0,0 @@
-/* $Id$ */
-/*-
- * Copyright (c) 2003-2006 Benedikt Meurer <benny@xfce.org>
- * Copyright (c) 2010 Ali Abdallah <aliov@xfce.org>
- * All rights reserved.
- *
- * 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, 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., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#ifdef HAVE_SYS_USER_H
-#include <sys/user.h>
-#endif
-#ifdef HAVE_SYS_SYSCTL_H
-#include <sys/sysctl.h>
-#endif
-
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib-lowlevel.h>
-
-#include <libxfce4util/libxfce4util.h>
-
-#include <xfce4-session/xfsm-shutdown-helper.h>
-#include <xfce4-session/xfsm-global.h>
-
-static void xfsm_shutdown_helper_finalize (GObject *object);
-
-static void xfsm_shutdown_helper_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-
-static void xfsm_shutdown_helper_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-
-/**
- * Suspend/Hibernate backend to use.
- *
- * upower, HAL, pmutils via sudo.
- *
- **/
-typedef enum
-{
- XFSM_SLEEP_BACKEND_NOT_SUPPORTED,
- XFSM_SLEEP_BACKEND_UPOWER,
- XFSM_SLEEP_BACKEND_HAL,
- XFSM_SLEEP_BACKEND_SUDO /*sudo pm-suspend ?*/
-
-} XfsmSleepBackend;
-
-/**
- * Shutdown/Reboot backend to use
- *
- * ConsoleKit, HAL, sudo
- **/
-typedef enum
-{
- XFSM_SHUTDOWN_BACKEND_NOT_SUPPORTED,
- XFSM_SHUTDOWN_BACKEND_CONSOLE_KIT,
- XFSM_SHUTDOWN_BACKEND_HAL,
- XFSM_SHUTDOWN_BACKEND_SUDO
-
-} XfsmShutdownBackend;
-
-#ifdef ENABLE_POLKIT
-/*DBus GTypes for polkit calls*/
-static GType polkit_subject_gtype = G_TYPE_INVALID;
-static GType polkit_details_gtype = G_TYPE_INVALID;
-static GType polkit_result_gtype = G_TYPE_INVALID;
-#endif /*ENABLE_POLKIT*/
-
-struct _XfsmShutdownHelper
-{
- GObject parent;
-
- DBusGConnection *system_bus;
-
-#ifdef ENABLE_POLKIT
- DBusGProxy *polkit_proxy;
- GValueArray *polkit_subject;
- GHashTable *polkit_details;
- GHashTable *polkit_subject_hash;
-#endif
-
- XfsmShutdownBackend shutdown_backend;
- XfsmSleepBackend sleep_backend;
-
- gboolean auth_shutdown;
- gboolean auth_restart;
- gboolean auth_suspend;
- gboolean auth_hibernate;
- gboolean can_shutdown;
- gboolean can_restart;
- gboolean can_suspend;
- gboolean can_hibernate;
-
- gboolean devkit_is_upower;
-
- /* Sudo data */
- gchar *sudo;
- FILE *infile;
- FILE *outfile;
- pid_t pid;
- gboolean require_password;
-
-};
-
-struct _XfsmShutdownHelperClass
-{
- GObjectClass parent_class;
-};
-
-enum
-{
- PROP_0,
- PROP_AUTHORIZED_TO_SHUTDOWN,
- PROP_AUTHORIZED_TO_RESTART,
- PROP_AUTHORIZED_TO_SUSPEND,
- PROP_AUTHORIZED_TO_HIBERNATE,
- PROP_CAN_SHUTDOWN,
- PROP_CAN_RESTART,
- PROP_CAN_SUSPEND,
- PROP_CAN_HIBERNATE,
- PROP_USER_CAN_SHUTDOWN,
- PROP_USER_CAN_RESTART,
- PROP_USER_CAN_SUSPEND,
- PROP_USER_CAN_HIBERNATE,
- PROP_REQUIRE_PASSWORD
-};
-
-G_DEFINE_TYPE (XfsmShutdownHelper, xfsm_shutdown_helper, G_TYPE_OBJECT)
-
-#ifdef ENABLE_POLKIT
-
-#if defined(__FreeBSD__)
-/**
- * Taken from polkitunixprocess.c code to get process start
- * time from pid.
- *
- * Copyright (C) 2008 Red Hat, Inc.
- *
- **/
-static gboolean
-get_kinfo_proc (pid_t pid, struct kinfo_proc *p)
-{
- int mib[4];
- size_t len;
-
- len = 4;
- sysctlnametomib ("kern.proc.pid", mib, &len);
-
- len = sizeof (struct kinfo_proc);
- mib[3] = pid;
-
- if (sysctl (mib, 4, p, &len, NULL, 0) == -1)
- return FALSE;
-
- return TRUE;
-}
-#endif /*if defined(__FreeBSD__)*/
-
-static guint64
-get_start_time_for_pid (pid_t pid)
-{
- guint64 start_time;
-#if !defined(__FreeBSD__)
- gchar *filename;
- gchar *contents;
- size_t length;
- gchar **tokens;
- guint num_tokens;
- gchar *p;
- gchar *endp;
-
- start_time = 0;
- contents = NULL;
-
- filename = g_strdup_printf ("/proc/%d/stat", pid);
-
- if (!g_file_get_contents (filename, &contents, &length, NULL))
- goto out;
-
- /* start time is the token at index 19 after the '(process name)' entry - since only this
- * field can contain the ')' character, search backwards for this to avoid malicious
- * processes trying to fool us
- */
- p = strrchr (contents, ')');
- if (p == NULL)
- {
- goto out;
- }
- p += 2; /* skip ') ' */
-
- if (p - contents >= (int) length)
- {
- g_warning ("Error parsing file %s", filename);
- goto out;
- }
-
- tokens = g_strsplit (p, " ", 0);
-
- num_tokens = g_strv_length (tokens);
-
- if (num_tokens < 20)
- {
- g_warning ("Error parsing file %s", filename);
- goto out;
- }
-
- start_time = strtoull (tokens[19], &endp, 10);
- if (endp == tokens[19])
- {
- g_warning ("Error parsing file %s", filename);
- goto out;
- }
-
- g_strfreev (tokens);
-
- out:
- g_free (filename);
- g_free (contents);
-
-#else /*if !defined(__FreeBSD__)*/
-
- struct kinfo_proc p;
-
- start_time = 0;
-
- if (! get_kinfo_proc (pid, &p))
- {
- g_warning ("Error obtaining start time for %d (%s)",
- (gint) pid,
- g_strerror (errno));
- goto out;
- }
-
- start_time = (guint64) p.ki_start.tv_sec;
-
-out:
-#endif
-
- return start_time;
-}
-
-static void
-init_dbus_gtypes (void)
-{
- if (G_UNLIKELY (polkit_subject_gtype == G_TYPE_INVALID ) )
- {
- polkit_subject_gtype =
- dbus_g_type_get_struct ("GValueArray",
- G_TYPE_STRING,
- dbus_g_type_get_map ("GHashTable",
- G_TYPE_STRING,
- G_TYPE_VALUE),
- G_TYPE_INVALID);
- }
-
- if (G_UNLIKELY (polkit_details_gtype == G_TYPE_INVALID ))
- {
- polkit_details_gtype = dbus_g_type_get_map ("GHashTable",
- G_TYPE_STRING,
- G_TYPE_STRING);
- }
-
- if (G_UNLIKELY (polkit_result_gtype == G_TYPE_INVALID ) )
- {
- polkit_result_gtype =
- dbus_g_type_get_struct ("GValueArray",
- G_TYPE_BOOLEAN,
- G_TYPE_BOOLEAN,
- dbus_g_type_get_map ("GHashTable",
- G_TYPE_STRING,
- G_TYPE_STRING),
- G_TYPE_INVALID);
- }
-}
-
-/**
- * xfsm_shutdown_helper_init_polkit_data:
- *
- * Check for Pokit and
- * Init the neccarry Polkit data an GTypes.
- *
- **/
-static gboolean
-xfsm_shutdown_helper_init_polkit_data (XfsmShutdownHelper *helper)
-{
- GValue hash_elem = { 0 };
- guint64 start_time;
- gint pid;
-
- helper->polkit_proxy =
- dbus_g_proxy_new_for_name (helper->system_bus,
- "org.freedesktop.PolicyKit1",
- "/org/freedesktop/PolicyKit1/Authority",
- "org.freedesktop.PolicyKit1.Authority");
-
- if (!helper->polkit_proxy)
- return FALSE;
-
- pid = getpid ();
-
- start_time = get_start_time_for_pid (pid);
-
- if (G_LIKELY (start_time != 0))
- {
- GValue val = { 0 }, pid_val = { 0 }, start_time_val = { 0 };
-
- helper->polkit_subject = g_value_array_new (2);
- helper->polkit_subject_hash = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free, NULL);
- g_value_init (&val, G_TYPE_STRING);
- g_value_set_string (&val, "unix-process");
- g_value_array_append (helper->polkit_subject, &val);
-
- g_value_unset (&val);
-
- g_value_init (&pid_val, G_TYPE_UINT);
- g_value_set_uint (&pid_val, pid);
- g_hash_table_insert (helper->polkit_subject_hash, g_strdup ("pid"), &pid_val);
-
- g_value_init (&start_time_val, G_TYPE_UINT64);
- g_value_set_uint64 (&start_time_val, start_time);
- g_hash_table_insert (helper->polkit_subject_hash, g_strdup ("start-time"), &start_time_val);
- }
- else
- {
- g_warning ("Unable to create Polkit subject");
- return FALSE;
- }
-
-
- g_value_init (&hash_elem,
- dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE));
-
- g_value_set_static_boxed (&hash_elem, helper->polkit_subject_hash);
- g_value_array_append (helper->polkit_subject, &hash_elem);
-
- /**
- * Polkit details, will leave it empty.
- **/
- helper->polkit_details = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-
- return TRUE;
-}
-#endif /*ENABLE_POLKIT*/
-
-/**
- * xfsm_shutdown_helper_check_sudo:
- *
- * Check if we can use sudo backend.
- * Method is called if HAL, upower, consolekit are missing
- * or the session was compiled without those services.
- *
- **/
-static gboolean
-xfsm_shutdown_helper_check_sudo (XfsmShutdownHelper *helper)
-{
- struct rlimit rlp;
- gchar buf[15];
- gint parent_pipe[2];
- gint child_pipe[2];
- gint result;
- gint n;
-
- helper->sudo = g_find_program_in_path ("sudo");
-
- if ( G_UNLIKELY (helper->sudo == NULL ) )
- {
- g_warning ("Program 'sudo' was not found.");
- return FALSE;
- }
-
- result = pipe (parent_pipe);
-
- if (result < 0)
- {
- g_warning ("Unable to create parent pipe: %s", strerror (errno));
- return FALSE;
- }
-
- result = pipe (child_pipe);
- if (result < 0)
- {
- g_warning ("Unable to create child pipe: %s", strerror (errno));
- goto error0;
- }
-
- helper->pid = fork ();
-
- if (helper->pid < 0)
- {
- g_warning ("Unable to fork sudo helper: %s", strerror (errno));
- goto error1;
- }
- else if (helper->pid == 0)
- {
- /* setup signals */
- signal (SIGPIPE, SIG_IGN);
-
- /* setup environment */
- xfce_setenv ("LC_ALL", "C", TRUE);
- xfce_setenv ("LANG", "C", TRUE);
- xfce_setenv ("LANGUAGE", "C", TRUE);
-
- /* setup the 3 standard file handles */
- dup2 (child_pipe[0], STDIN_FILENO);
- dup2 (parent_pipe[1], STDOUT_FILENO);
- dup2 (parent_pipe[1], STDERR_FILENO);
-
- /* Close all other file handles */
- getrlimit (RLIMIT_NOFILE, &rlp);
- for (n = 0; n < (gint) rlp.rlim_cur; ++n)
- {
- if (n != STDIN_FILENO && n != STDOUT_FILENO && n != STDERR_FILENO)
- close (n);
- }
-
- /* execute sudo with the helper */
- execl (helper->sudo, "sudo", "-H", "-S", "-p",
- "XFSM_SUDO_PASS ", "--", XFSM_SHUTDOWN_HELPER_CMD, NULL);
- _exit (127);
- }
-
- close (parent_pipe[1]);
-
- /* read sudo/helper answer */
- n = read (parent_pipe[0], buf, 15);
- if (n < 15)
- {
- g_warning ("Unable to read response from sudo helper: %s",
- n < 0 ? strerror (errno) : "Unknown error");
- goto error1;
- }
-
- helper->infile = fdopen (parent_pipe[0], "r");
-
- if (helper->infile == NULL)
- {
- g_warning ("Unable to open parent pipe: %s", strerror (errno));
- goto error1;
- }
-
- helper->outfile = fdopen (child_pipe[1], "w");
-
- if (helper->outfile == NULL)
- {
- g_warning ("Unable to open child pipe: %s", strerror (errno));
- goto error2;
- }
-
- if (memcmp (buf, "XFSM_SUDO_PASS ", 15) == 0)
- {
- helper->require_password = TRUE;
- }
- else if (memcmp (buf, "XFSM_SUDO_DONE ", 15) == 0)
- {
- helper->require_password = FALSE;
- }
- else
- {
- g_warning ("Got unexpected reply from sudo shutdown helper");
- goto error2;
- }
-
- close (parent_pipe[1]);
- close (child_pipe[0]);
-
- return TRUE;
-
-error2:
- if (helper->infile != NULL)
- {
- fclose (helper->infile);
- helper->infile = NULL;
- }
-
- if (helper->outfile != NULL)
- {
- fclose (helper->outfile);
- helper->outfile = NULL;
- }
-
-error1:
- close (child_pipe[0]);
- close (child_pipe[1]);
-
-error0:
- close (parent_pipe[0]);
- close (parent_pipe[1]);
-
- return FALSE;
-}
-
-#ifdef ENABLE_UPOWER
-/**
- * xfsm_shutdown_helper_get_power_props:
- *
- **/
-static GHashTable *
-xfsm_shutdown_helper_get_power_props (XfsmShutdownHelper *helper,
- const gchar *name,
- const gchar *path,
- const gchar *iface)
-{
- DBusGProxy *proxy_prop;
- GHashTable *props;
- GType g_type_hash_map;
- GError *error = NULL;
-
- proxy_prop = dbus_g_proxy_new_for_name (helper->system_bus,
- name,
- path,
- DBUS_INTERFACE_PROPERTIES);
-
- if (!proxy_prop)
- {
- g_warning ("Unable to create proxy for %s", name);
- return NULL;
- }
-
- /* The Hash table is a pair of (strings, GValues) */
- g_type_hash_map = dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE);
-
- dbus_g_proxy_call (proxy_prop, "GetAll", &error,
- G_TYPE_STRING, iface,
- G_TYPE_INVALID,
- g_type_hash_map, &props,
- G_TYPE_INVALID);
-
- g_object_unref (proxy_prop);
-
- if (error)
- {
- g_warning ("Method 'GetAll' failed : %s", error->message);
- g_error_free (error);
- return NULL;
- }
-
- return props;
-}
-
-
-/**
- * xfsm_shutdown_helper_check_devkit_upower:
- *
- * Check upower (formely devicekit-power)
- * for hibernate and suspend availability.
- *
- * Returns: FALSE if failed to contact upower, TRUE otherwise.
- **/
-static gboolean
-xfsm_shutdown_helper_check_devkit_upower (XfsmShutdownHelper *helper)
-{
- /**
- * Get the properties on 'org.freedesktop.UPower'
- * or 'org.freedesktop.DeviceKit.Power'
- *
- * DaemonVersion 's'
- * CanSuspend' 'b'
- * CanHibernate' 'b'
- * OnBattery' 'b'
- * OnLowBattery' 'b'
- * LidIsClosed' 'b'
- * LidIsPresent' 'b'
- **/
-
- GHashTable *props;
- GValue *value;
- const gchar *name, *path, *iface;
-
- /* Check for upower first */
- name = "org.freedesktop.UPower";
- path = "/org/freedesktop/UPower";
- iface = "org.freedesktop.UPower";
-
- helper->devkit_is_upower = TRUE;
-
- props = xfsm_shutdown_helper_get_power_props (helper,
- name,
- path,
- iface);
- if (!props)
- {
- g_message ("UPower not found, trying DevKitPower");
-
- name = "org.freedesktop.DeviceKit.Power";
- path = "/org/freedesktop/DeviceKit/Power";
- iface = "org.freedesktop.DeviceKit.Power";
-
- helper->devkit_is_upower = FALSE;
-
- props = xfsm_shutdown_helper_get_power_props (helper,
- name,
- path,
- iface);
- if (!props)
- {
- g_message ("Devkit Power is not running or not installed");
- return FALSE;
- }
- }
-
- /*Get The CanSuspend bit*/
- value = g_hash_table_lookup (props, "CanSuspend");
-
- if (G_LIKELY (value))
- {
- helper->can_suspend = g_value_get_boolean (value);
- }
- else
- {
- g_warning ("No 'CanSuspend' property");
- }
-
- /*Get the CanHibernate bit*/
- value = g_hash_table_lookup (props, "CanHibernate");
-
- if (G_LIKELY (value))
- {
- helper->can_hibernate = g_value_get_boolean (value);
- }
- else
- {
- g_warning ("No 'CanHibernate' property");
- }
-
- g_hash_table_destroy (props);
-
- return TRUE;
-}
-#endif /*ENABLE_UPOWER*/
-
-
-/**
- * xfsm_shutdown_helper_check_console_kit:
- *
- * Check Consolekit for methods:
- * Stop (Shutdown), Restart.
- **/
-#ifdef ENABLE_CONSOLE_KIT
-static gboolean
-xfsm_shutdown_helper_check_console_kit (XfsmShutdownHelper *helper)
-{
- DBusGProxy *proxy;
- GError *error = NULL;
- gboolean ret;
-
- proxy = dbus_g_proxy_new_for_name (helper->system_bus,
- "org.freedesktop.ConsoleKit",
- "/org/freedesktop/ConsoleKit/Manager",
- "org.freedesktop.ConsoleKit.Manager");
-
- if (!proxy)
- {
- g_warning ("Failed to create proxy for 'org.freedesktop.ConsoleKit'");
- return FALSE;
- }
-
- ret = dbus_g_proxy_call (proxy, "CanStop", &error,
- G_TYPE_INVALID,
- G_TYPE_BOOLEAN, &helper->can_shutdown,
- G_TYPE_INVALID);
-
- if (error)
- {
- g_warning ("'CanStop' method failed : %s", error->message);
- g_error_free (error);
- goto out;
- }
-
- dbus_g_proxy_call (proxy, "CanRestart", &error,
- G_TYPE_INVALID,
- G_TYPE_BOOLEAN, &helper->can_restart,
- G_TYPE_INVALID);
-
- if (error)
- {
- g_warning ("'CanRestart' method failed : %s", error->message);
- g_error_free (error);
- goto out;
- }
-
- ret = TRUE;
-
- out:
-
- g_object_unref (proxy);
-
- return ret;
-}
-#endif /*ENABLE_CONSOLE_KIT*/
-
-
-/**
- * xfsm_shutdown_helper_check_hal:
- *
- * Check if HAL is running and for its PowerManagement bits
- *
- **/
-#ifdef ENABLE_HAL
-static gboolean
-xfsm_shutdown_helper_check_hal (XfsmShutdownHelper *helper)
-{
- DBusGProxy *proxy_power;
- DBusGProxy *proxy_device;
- GError *error = NULL;
- gboolean ret = FALSE;
-
- proxy_power =
- dbus_g_proxy_new_for_name (helper->system_bus,
- "org.freedesktop.Hal",
- "/org/freedesktop/Hal/devices/computer",
- "org.freedesktop.Hal.Device.SystemPowerManagement");
-
- if (!proxy_power)
- {
- g_warning ("Failed to create proxy for 'org.freedesktop.Hal' ");
- return FALSE;
- }
-
- dbus_g_proxy_call (proxy_power, "JustToCheckUserPermission", &error,
- G_TYPE_INVALID,
- G_TYPE_INVALID);
-
- g_object_unref (proxy_power);
-
- if (G_LIKELY (error))
- {
- /* The message passed dbus permission check? */
- if ( !g_error_matches (error, DBUS_GERROR, DBUS_GERROR_UNKNOWN_METHOD) )
- {
- g_error_free (error);
- return FALSE;
- }
-
- g_error_free (error);
- error = NULL;
- }
- else
- {
- /*Something went wrong with HAL*/
- return FALSE;
- }
-
- /*
- * Message raised DBUS_GERROR_UNKNOWN_METHOD, so it reached HAL,
- * we can consider thatn HAL allows us to use its power management interface
- */
- helper->auth_shutdown = TRUE;
- helper->auth_restart = TRUE;
- helper->auth_suspend = TRUE;
- helper->auth_hibernate = TRUE;
- /* HAL doesn't have can_shutdown and can_reboot bits since it can always
- shutdown and reboot the system */
- helper->can_shutdown = TRUE;
- helper->can_restart = TRUE;
-
- /*Check to see is the system can_hibernate and can_suspend*/
- proxy_device = dbus_g_proxy_new_for_name (helper->system_bus,
- "org.freedesktop.Hal",
- "/org/freedesktop/Hal/devices/computer",
- "org.freedesktop.Hal.Device");
-
- if (!proxy_device)
- return FALSE;
-
- dbus_g_proxy_call (proxy_device, "GetPropertyBoolean", &error,
- G_TYPE_STRING, "power_management.can_hibernate",
- G_TYPE_INVALID,
- G_TYPE_BOOLEAN, &helper->can_hibernate,
- G_TYPE_INVALID);
-
- if (error)
- {
- g_warning ("Method 'GetPropertyBoolean' failed : %s", error->message);
- g_error_free (error);
- goto out;
- }
-
- dbus_g_proxy_call (proxy_device, "GetPropertyBoolean", &error,
- G_TYPE_STRING, "power_management.can_suspend",
- G_TYPE_INVALID,
- G_TYPE_BOOLEAN, &helper->can_suspend,
- G_TYPE_INVALID);
-
- if (error)
- {
- g_warning ("Method 'GetPropertyBoolean' failed : %s", error->message);
- g_error_free (error);
- goto out;
- }
-
- ret = TRUE;
-
- out:
-
- g_object_unref (proxy_device);
-
- return ret;
-}
-#endif /*ENABLE_HAL*/
-
-/**
- * xfsm_shutdown_helper_check_polkit_authorization:
- *
- **/
-#ifdef ENABLE_POLKIT
-static gboolean
-xfsm_shutdown_helper_check_authorization (XfsmShutdownHelper *helper,
- const gchar *action_id)
-{
- GValueArray *result;
- GValue result_val = { 0 };
- GError *error = NULL;
- gboolean is_authorized = FALSE;
- gboolean ret;
-
- /**
- * <method name="CheckAuthorization">
- * <arg type="(sa{sv})" name="subject" direction="in"/>
- * <arg type="s" name="action_id" direction="in"/>
- * <arg type="a{ss}" name="details" direction="in"/>
- * <arg type="u" name="flags" direction="in"/>
- * <arg type="s" name="cancellation_id" direction="in"/>
- * <arg type="(bba{ss})" name="result" direction="out"/>
- * </method>
- *
- **/
-
- g_return_val_if_fail (helper->polkit_proxy != NULL, FALSE);
- g_return_val_if_fail (helper->polkit_subject, FALSE);
- g_return_val_if_fail (helper->polkit_details, FALSE);
-
- /* Initialized DBus GTypes */
- init_dbus_gtypes ();
-
- result = g_value_array_new (0);
-
- ret = dbus_g_proxy_call (helper->polkit_proxy, "CheckAuthorization", &error,
- polkit_subject_gtype, helper->polkit_subject,
- G_TYPE_STRING, action_id,
- polkit_details_gtype, helper->polkit_details,
- G_TYPE_UINT, 0,
- G_TYPE_STRING, NULL,
- G_TYPE_INVALID,
- polkit_result_gtype, &result,
- G_TYPE_INVALID);
-
- if (G_LIKELY (ret))
- {
- g_value_init (&result_val, polkit_result_gtype);
- g_value_set_static_boxed (&result_val, result);
-
- dbus_g_type_struct_get (&result_val,
- 0, &is_authorized,
- G_MAXUINT);
- g_value_unset (&result_val);
- }
- else if (error)
- {
- g_warning ("'CheckAuthorization' failed : %s", error->message);
- g_error_free (error);
- }
-
- g_value_array_free (result);
- return is_authorized;
-}
-#endif /*ENABLE_POLKIT*/
-
-/**
- *xfsm_shutdown_helper_check_backends:
- *
- * Try to check what is the best available backend to use
- * Supported: ConsoleKit, HAL, upower and sudo.
- *
- **/
-static void
-xfsm_shutdown_helper_check_backends (XfsmShutdownHelper *helper)
-{
-#ifdef ENABLE_POLKIT
- /*if polkit data was successfully initialized*/
- gboolean polkit_ok = FALSE;
-#endif
-
-#ifdef ENABLE_UPOWER
- /*Check upower (formely devicekit-power)*/
- if ( xfsm_shutdown_helper_check_devkit_upower (helper) )
- helper->sleep_backend = XFSM_SLEEP_BACKEND_UPOWER;
-#endif /* ENABLE_UPOWER */
-
-#ifdef ENABLE_CONSOLE_KIT
- if ( xfsm_shutdown_helper_check_console_kit (helper) )
- {
- helper->shutdown_backend = XFSM_SHUTDOWN_BACKEND_CONSOLE_KIT;
- /*ConsoleKit doesn't use Polkit*/
- helper->auth_shutdown = helper->can_shutdown;
- helper->auth_restart = helper->can_restart;
- }
-#endif
-
- if ( helper->sleep_backend == XFSM_SLEEP_BACKEND_UPOWER )
- {
-#ifdef ENABLE_POLKIT
-
- polkit_ok = xfsm_shutdown_helper_init_polkit_data (helper);
-
- if (polkit_ok)
- {
- const gchar *action_hibernate, *action_suspend;
-
- if (helper->devkit_is_upower)
- {
- action_hibernate = "org.freedesktop.upower.hibernate";
- action_suspend = "org.freedesktop.upower.suspend";
- }
- else
- {
- action_hibernate = "org.freedesktop.devicekit.power.hibernate";
- action_suspend = "org.freedesktop.devicekit.power.suspend";
- }
-
- helper->auth_hibernate =
- xfsm_shutdown_helper_check_authorization (helper, action_hibernate);
-
- helper->auth_suspend =
- xfsm_shutdown_helper_check_authorization (helper, action_suspend);
- }
- else
- {
- helper->auth_hibernate = TRUE;
- helper->auth_suspend = TRUE;
- }
-#else
- helper->auth_hibernate = TRUE;
- helper->auth_suspend = TRUE;
-#endif /* ENABLE_POLKIT */
- }
-
- /*
- * Use HAL just as a fallback.
- */
-#ifdef ENABLE_HAL
- if (helper->sleep_backend == XFSM_SLEEP_BACKEND_NOT_SUPPORTED ||
- helper->shutdown_backend == XFSM_SHUTDOWN_BACKEND_NOT_SUPPORTED)
- {
- if (xfsm_shutdown_helper_check_hal (helper))
- {
- if (helper->shutdown_backend == XFSM_SHUTDOWN_BACKEND_NOT_SUPPORTED)
- helper->shutdown_backend = XFSM_SHUTDOWN_BACKEND_HAL;
-
- if (helper->sleep_backend == XFSM_SLEEP_BACKEND_NOT_SUPPORTED)
- helper->sleep_backend = XFSM_SLEEP_BACKEND_HAL;
- }
- }
-#endif
-
- /* Fallback for sudo */
- if (helper->shutdown_backend == XFSM_SHUTDOWN_BACKEND_NOT_SUPPORTED)
- {
- if (xfsm_shutdown_helper_check_sudo (helper) )
- {
- helper->shutdown_backend = XFSM_SHUTDOWN_BACKEND_SUDO;
- helper->can_shutdown = TRUE;
- helper->can_restart = TRUE;
- helper->auth_shutdown = TRUE;
- helper->auth_restart = TRUE;
- }
- }
-
-#ifdef DEBUG
- {
- const gchar *shutdown_str[] = {"Shutdown not supported",
- "Using ConsoleKit for shutdown",
- "Using HAL for shutdown",
- "Using Sudo for shutdown",
- NULL};
-
- const gchar *sleep_str[] = {"Sleep not supported",
- "Using UPower for sleep",
- "Using HAL for sleep",
- "Using Sudo for sleep",
- NULL};
-
- g_debug ("%s", shutdown_str[helper->shutdown_backend]);
- g_debug ("%s", sleep_str[helper->sleep_backend]);
-
- g_debug ("can_shutdown=%d can_restart=%d can_hibernate=%d can_suspend=%d",
- helper->can_shutdown, helper->can_restart,
- helper->can_hibernate, helper->can_suspend);
-
- g_debug ("auth_shutdown=%d auth_restart=%d auth_hibernate=%d auth_suspend=%d",
- helper->auth_shutdown, helper->auth_restart,
- helper->auth_hibernate, helper->auth_suspend);
- }
-#endif
-
-#ifdef ENABLE_POLKIT
-
- if (polkit_ok)
- {
- g_hash_table_destroy (helper->polkit_details);
- g_hash_table_destroy (helper->polkit_subject_hash);
- g_value_array_free (helper->polkit_subject);
- }
-
-#endif
-
-}
-
-static void
-xfsm_shutdown_helper_class_init (XfsmShutdownHelperClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = xfsm_shutdown_helper_finalize;
-
- object_class->get_property = xfsm_shutdown_helper_get_property;
- object_class->set_property = xfsm_shutdown_helper_set_property;
-
- /**
- * XfsmShutdownHelper::authorized-to-shutdown
- *
- * Whether the user is allowed to preform shutdown.
- **/
- g_object_class_install_property (object_class,
- PROP_AUTHORIZED_TO_SHUTDOWN,
- g_param_spec_boolean ("authorized-to-shutdown",
- NULL, NULL,
- FALSE,
- G_PARAM_READABLE));
-
- /**
- * XfsmShutdownHelper::authorized-to-reboot
- *
- * Whether the user is allowed to preform reboot.
- **/
- g_object_class_install_property (object_class,
- PROP_AUTHORIZED_TO_RESTART,
- g_param_spec_boolean ("authorized-to-restart",
- NULL, NULL,
- FALSE,
- G_PARAM_READABLE));
-
- /**
- * XfsmShutdownHelper::authorized-to-suspend
- *
- * Whether the user is allowed to preform suspend.
- **/
- g_object_class_install_property (object_class,
- PROP_AUTHORIZED_TO_SUSPEND,
- g_param_spec_boolean ("authorized-to-suspend",
- NULL, NULL,
- FALSE,
- G_PARAM_READABLE));
-
- /**
- * XfsmShutdownHelper::authorized-to-hibernate
- *
- * Whether the user is allowed to preform hibernate.
- **/
- g_object_class_install_property (object_class,
- PROP_AUTHORIZED_TO_HIBERNATE,
- g_param_spec_boolean ("authorized-to-hibernate",
- NULL, NULL, FALSE,
- G_PARAM_READABLE));
-
- /**
- * XfsmShutdownHelper::can-shutdown
- *
- * Whether the system can do shutdown.
- **/
- g_object_class_install_property (object_class,
- PROP_CAN_SHUTDOWN,
- g_param_spec_boolean ("can-shutdown",
- NULL, NULL,
- FALSE,
- G_PARAM_READABLE));
-
- /**
- * XfsmShutdownHelper::can-restart
- *
- * Whether the system can do restart.
- **/
- g_object_class_install_property (object_class,
- PROP_CAN_RESTART,
- g_param_spec_boolean ("can-restart",
- NULL, NULL,
- FALSE,
- G_PARAM_READABLE));
-
- /**
- * XfsmShutdownHelper::can-suspend
- *
- * Whether the system can do suspend.
- **/
- g_object_class_install_property (object_class,
- PROP_CAN_SUSPEND,
- g_param_spec_boolean ("can-suspend",
- NULL, NULL,
- FALSE,
- G_PARAM_READABLE));
- /**
- * XfsmShutdownHelper::can-hibernate
- *
- * Whether the system can do hibernate.
- **/
- g_object_class_install_property (object_class,
- PROP_CAN_HIBERNATE,
- g_param_spec_boolean ("can-hibernate",
- NULL, NULL,
- FALSE,
- G_PARAM_READABLE));
-
- /**
- * XfsmShutdownHelper::user-can-shutdown
- *
- * Whether the user is allowed and the system can shutdown.
- **/
- g_object_class_install_property (object_class,
- PROP_USER_CAN_SHUTDOWN,
- g_param_spec_boolean ("user-can-shutdown",
- NULL, NULL,
- FALSE,
- G_PARAM_READABLE));
-
- /**
- * XfsmShutdownHelper::user-can-restart
- *
- * Whether the user is allowed and the system can restart.
- **/
- g_object_class_install_property (object_class,
- PROP_USER_CAN_RESTART,
- g_param_spec_boolean ("user-can-restart",
- NULL, NULL,
- FALSE,
- G_PARAM_READABLE));
-
- /**
- * XfsmShutdownHelper::user-can-suspend
- *
- * Whether the user is allowed and the system can suspend.
- **/
- g_object_class_install_property (object_class,
- PROP_USER_CAN_SUSPEND,
- g_param_spec_boolean ("user-can-suspend",
- NULL, NULL,
- FALSE,
- G_PARAM_READABLE));
- /**
- * XfsmShutdownHelper::user-can-hibernate
- *
- * Whether the user is allowed and the system can hibernate.
- **/
- g_object_class_install_property (object_class,
- PROP_USER_CAN_HIBERNATE,
- g_param_spec_boolean ("user-can-hibernate",
- NULL, NULL,
- FALSE,
- G_PARAM_READABLE));
-
- /**
- * XfsmShutdownHelper::require-password
- *
- * Whether the shutdown operation requires a password to
- * pass to sudo.
- **/
- g_object_class_install_property (object_class,
- PROP_REQUIRE_PASSWORD,
- g_param_spec_boolean ("require-password",
- NULL, NULL,
- FALSE,
- G_PARAM_READABLE));
-
-}
-
-static void
-xfsm_shutdown_helper_init (XfsmShutdownHelper *helper)
-{
- GError *error = NULL;
-
-#ifdef ENABLE_POLKIT
- helper->polkit_proxy = NULL;
- helper->polkit_subject = NULL;
- helper->polkit_details = NULL;
- helper->polkit_subject_hash = NULL;
-#endif
-
- helper->sudo = NULL;
- helper->infile = NULL;
- helper->outfile = NULL;
- helper->pid = 0;
- helper->require_password = FALSE;
-
- helper->sleep_backend = XFSM_SLEEP_BACKEND_NOT_SUPPORTED;
- helper->shutdown_backend = XFSM_SHUTDOWN_BACKEND_NOT_SUPPORTED;
-
- helper->auth_shutdown = FALSE;
- helper->auth_restart = FALSE;
- helper->auth_suspend = FALSE;
- helper->auth_hibernate = FALSE;
- helper->can_shutdown = FALSE;
- helper->can_restart = FALSE;
- helper->can_suspend = FALSE;
- helper->can_hibernate = FALSE;
-
- helper->system_bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
-
- if (G_LIKELY (helper->system_bus))
- {
- xfsm_shutdown_helper_check_backends (helper);
- }
- else
- {
- g_warning ("Failed to connect to the system bus : %s", error->message);
- g_error_free (error);
-
- /* Unable to connect to the system bus, just try sudo */
- if (xfsm_shutdown_helper_check_sudo (helper))
- {
- helper->shutdown_backend = XFSM_SHUTDOWN_BACKEND_SUDO;
-
- helper->can_shutdown = TRUE;
- helper->can_restart = TRUE;
- helper->auth_shutdown = TRUE;
- helper->auth_restart = TRUE;
- }
- }
-}
-
-static void xfsm_shutdown_helper_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-}
-
-static void xfsm_shutdown_helper_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- XfsmShutdownHelper *helper;
-
- helper = XFSM_SHUTDOWN_HELPER (object);
-
- switch (prop_id)
- {
- case PROP_AUTHORIZED_TO_SHUTDOWN:
- g_value_set_boolean (value, helper->auth_shutdown);
- break;
- case PROP_AUTHORIZED_TO_RESTART:
- g_value_set_boolean (value, helper->auth_restart);
- break;
- case PROP_AUTHORIZED_TO_SUSPEND:
- g_value_set_boolean (value, helper->auth_suspend);
- break;
- case PROP_AUTHORIZED_TO_HIBERNATE:
- g_value_set_boolean (value, helper->auth_hibernate);
- break;
- case PROP_CAN_SUSPEND:
- g_value_set_boolean (value, helper->can_suspend);
- break;
- case PROP_CAN_HIBERNATE:
- g_value_set_boolean (value, helper->can_hibernate);
- break;
- case PROP_CAN_RESTART:
- g_value_set_boolean (value, helper->can_restart);
- break;
- case PROP_CAN_SHUTDOWN:
- g_value_set_boolean (value, helper->can_shutdown);
- break;
- case PROP_USER_CAN_SUSPEND:
- g_value_set_boolean (value, helper->can_suspend && helper->auth_suspend);
- break;
- case PROP_USER_CAN_HIBERNATE:
- g_value_set_boolean (value, helper->can_hibernate && helper->auth_hibernate);
- break;
- case PROP_USER_CAN_RESTART:
- g_value_set_boolean (value, helper->can_restart && helper->auth_restart);
- break;
- case PROP_USER_CAN_SHUTDOWN:
- g_value_set_boolean (value, helper->can_shutdown && helper->auth_shutdown);
- break;
- case PROP_REQUIRE_PASSWORD:
- g_value_set_boolean (value, helper->require_password);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-xfsm_shutdown_helper_finalize (GObject *object)
-{
- XfsmShutdownHelper *helper;
- gint status;
-
- helper = XFSM_SHUTDOWN_HELPER (object);
-
-#ifdef ENABLE_POLKIT
- if (helper->polkit_proxy)
- g_object_unref (helper->polkit_proxy);
-#endif
-
- if (helper->system_bus)
- dbus_g_connection_unref (helper->system_bus);
-
- if (helper->infile != NULL)
- fclose (helper->infile);
-
- if (helper->outfile != NULL)
- fclose (helper->outfile);
-
- if (helper->pid > 0)
- waitpid (helper->pid, &status, 0);
-
- g_free (helper->sudo);
-
- G_OBJECT_CLASS (xfsm_shutdown_helper_parent_class)->finalize (object);
-}
-
-/**
- * xfsm_shutdown_helper_upower_sleep:
- * @helper: a #XfsmShutdownHelper,
- * @action: 'Hibernate' or 'Suspend'
- * @error: a #GError
- *
- **/
-#ifdef ENABLE_UPOWER
-static gboolean
-xfsm_shutdown_helper_upower_sleep (XfsmShutdownHelper *helper,
- const gchar *action,
- GError **error)
-{
- DBusGProxy *proxy;
- GError *error_local = NULL;
- const gchar *name, *path, *iface;
- gboolean ret;
-
- if (helper->devkit_is_upower)
- {
- name = "org.freedesktop.UPower";
- path = "/org/freedesktop/UPower";
- iface = "org.freedesktop.UPower";
- }
- else
- {
- name = "org.freedesktop.DeviceKit.Power";
- path = "/org/freedesktop/DeviceKit/Power";
- iface = "org.freedesktop.DeviceKit.Power";
- }
-
- g_message (G_STRLOC ": Using %s to %s", name, action);
-
- proxy = dbus_g_proxy_new_for_name_owner (helper->system_bus,
- name,
- path,
- iface,
- &error_local);
-
- if (!proxy)
- {
- g_warning ("Failed to create proxy for %s : %s", name, error_local->message);
- g_set_error (error, 1, 0, "%s", error_local->message);
- g_error_free (error_local);
- return FALSE;
- }
-
- ret = dbus_g_proxy_call (proxy, action, &error_local,
- G_TYPE_INVALID,
- G_TYPE_INVALID);
-
- g_object_unref (proxy);
-
- if (!ret)
- {
- /* DBus timeout?*/
- if (g_error_matches (error_local, DBUS_GERROR, DBUS_GERROR_NO_REPLY))
- {
- g_error_free (error_local);
- return TRUE;
- }
- else
- {
- g_set_error (error, 1, 0, "%s", error_local->message);
- g_error_free (error_local);
- return FALSE;
- }
- }
-
- return TRUE;
-}
-#endif /*ENABLE_UPOWER*/
-
-/**
- * xfsm_shutdown_helper_console_kit_shutdown:
- * @helper: a #XfsmShutdownHelper,
- * @action: 'Stop' for shutdown and 'Restart' for reboot.
- * @error: a #GError
- *
- **/
-#ifdef ENABLE_CONSOLE_KIT
-static gboolean
-xfsm_shutdown_helper_console_kit_shutdown (XfsmShutdownHelper *helper,
- const gchar *action,
- GError **error)
-{
- DBusGProxy *proxy;
- GError *error_local = NULL;
- gboolean ret;
-
- g_message (G_STRLOC ": Using ConsoleKit to %s", action);
-
- proxy = dbus_g_proxy_new_for_name_owner (helper->system_bus,
- "org.freedesktop.ConsoleKit",
- "/org/freedesktop/ConsoleKit/Manager",
- "org.freedesktop.ConsoleKit.Manager",
- &error_local);
-
- if (!proxy)
- {
- g_warning ("Failed to create proxy for 'org.freedesktop.ConsoleKit' : %s", error_local->message);
- g_set_error (error, 1, 0, "%s", error_local->message);
- g_error_free (error_local);
- return FALSE;
- }
-
- ret = dbus_g_proxy_call (proxy, action, &error_local,
- G_TYPE_INVALID,
- G_TYPE_INVALID);
-
- g_object_unref (proxy);
-
- if (!ret)
- {
- g_set_error (error, 1, 0, "%s", error_local->message);
- g_error_free (error_local);
- return FALSE;
- }
-
- return TRUE;
-}
-#endif /*ENABLE_CONSOLE_KIT*/
-
-/**
- * xfsm_shutdown_helper_hal_send:
- * @helper: a #XfsmShutdownHelper,
- * @action: 'Reboot' 'Shutdown' 'Hibernate' 'Suspend'
- * @error: a #GError
- *
- **/
-#ifdef ENABLE_HAL
-static gboolean
-xfsm_shutdown_helper_hal_send (XfsmShutdownHelper *helper,
- const gchar *action,
- GError **error)
-{
- DBusGProxy *proxy;
- GError *error_local = NULL;
- gboolean ret;
- gint return_code;
-
- g_message (G_STRLOC ": Using ConsoleKit to %s", action);
-
- proxy = dbus_g_proxy_new_for_name_owner (helper->system_bus,
- "org.freedesktop.Hal",
- "/org/freedesktop/Hal/devices/computer",
- "org.freedesktop.Hal.Device.SystemPowerManagement",
- &error_local);
- if (!proxy)
- {
- g_warning ("Failed to create proxy for 'org.freedesktop.Hal' : %s", error_local->message);
- g_set_error (error, 1, 0, "%s", error_local->message);
- g_error_free (error_local);
- return FALSE;
- }
-
- if (!g_strcmp0 (action, "Suspend"))
- {
- gint seconds = 0;
- ret = dbus_g_proxy_call (proxy, action, &error_local,
- G_TYPE_INT, seconds,
- G_TYPE_INVALID,
- G_TYPE_INT, &return_code,
- G_TYPE_INVALID);
- }
- else
- {
- ret = dbus_g_proxy_call (proxy, action, &error_local,
- G_TYPE_INVALID,
- G_TYPE_INT, &return_code,
- G_TYPE_INVALID);
- }
-
- g_object_unref (proxy);
-
- if (!ret)
- {
- /* A D-Bus timeout? */
- if (g_error_matches (error_local, DBUS_GERROR, DBUS_GERROR_NO_REPLY))
- {
- g_error_free (error_local);
- return TRUE;
- }
- else
- {
- g_set_error (error, 1, 0, "%s", error_local->message);
- g_error_free (error_local);
- return FALSE;
- }
- }
-
- return TRUE;
-}
-#endif /*ENABLE_HAL*/
-
-/**
- * xfsm_shutdown_helper_sudo_send:
- *
- *
- **/
-static gboolean
-xfsm_shutdown_helper_sudo_send (XfsmShutdownHelper *helper,
- const gchar *action,
- GError **error)
-{
- gchar response[256];
-
- fprintf (helper->outfile, "%s\n", action);
- fflush (helper->outfile);
-
- g_message (G_STRLOC ": Using sudo to %s", action);
-
- if (ferror (helper->outfile))
- {
- if (errno == EINTR)
- {
- /* probably succeeded but the helper got killed */
- return TRUE;
- }
-
- g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
- _("Error sending command to shutdown helper: %s"),
- strerror (errno));
- return FALSE;
- }
-
- if (fgets (response, 256, helper->infile) == NULL)
- {
- if (errno == EINTR)
- {
- /* probably succeeded but the helper got killed */
- return TRUE;
- }
-
- g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
- _("Error receiving response from shutdown helper: %s"),
- strerror (errno));
-
- return FALSE;
- }
-
- if (strncmp (response, "SUCCEED", 7) != 0)
- {
- g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
- _("Shutdown command failed"));
-
- return FALSE;
- }
- return TRUE;
-}
-
-/**
- * xfsm_shutdown_helper_new:
- *
- **/
-XfsmShutdownHelper *
-xfsm_shutdown_helper_new (void)
-{
- XfsmShutdownHelper *xfsm_shutdown_helper = NULL;
-
- xfsm_shutdown_helper = g_object_new (XFSM_TYPE_SHUTDOWN_HELPER, NULL);
-
- return xfsm_shutdown_helper;
-}
-
-/**
- * xfsm_shutdown_helper_send_password:
- *
- * Send password to sudo
- *
- **/
-gboolean xfsm_shutdown_helper_send_password (XfsmShutdownHelper *helper, const gchar *password)
-{
- gssize result;
- gchar buffer[1024];
- gsize failed;
- gsize length;
- gsize bytes;
- gint fd;
-
- g_return_val_if_fail (password != NULL, FALSE);
- g_return_val_if_fail (helper->shutdown_backend == XFSM_SHUTDOWN_BACKEND_SUDO, FALSE);
- g_return_val_if_fail (helper->require_password, FALSE);
-
- g_snprintf (buffer, 1024, "%s\n", password);
- length = strlen (buffer);
- bytes = fwrite (buffer, 1, length, helper->outfile);
- fflush (helper->outfile);
- bzero (buffer, length);
-
- if (bytes != length)
- {
- fprintf (stderr, "Failed to write password (bytes=%lu, length=%lu)\n", (long)bytes, (long)length);
- return FALSE;
- }
-
- if (ferror (helper->outfile))
- {
- fprintf (stderr, "Pipe error\n");
- return FALSE;
- }
-
- fd = fileno (helper->infile);
-
- for (failed = length = 0;;)
- {
- result = read (fd, buffer + length, 256 - length);
-
- if (result < 0)
- {
- perror ("read");
- return FALSE;
- }
- else if (result == 0)
- {
- if (++failed > 20)
- return FALSE;
- continue;
- }
- else if (result + length >= 1024)
- {
- fprintf (stderr, "Too much output from sudo!\n");
- return FALSE;
- }
-
- length += result;
- buffer[length] = 0;
-
- if (length >= 15)
- {
- if (strncmp (buffer + (length - 15), "XFSM_SUDO_PASS ", 15) == 0)
- {
- return FALSE;
- }
- else if (strncmp (buffer + (length - 15), "XFSM_SUDO_DONE ", 15) == 0)
- {
- helper->require_password = FALSE;
- break;
- }
- }
- }
-
- return TRUE;
-}
-
-/**
- * xfsm_shutdown_helper_shutdown:
- *
- *
- **/
-gboolean xfsm_shutdown_helper_shutdown (XfsmShutdownHelper *helper, GError **error)
-{
- g_return_val_if_fail (!error || !*error, FALSE);
-
-#ifdef ENABLE_CONSOLE_KIT
- if ( helper->shutdown_backend == XFSM_SHUTDOWN_BACKEND_CONSOLE_KIT )
- {
- return xfsm_shutdown_helper_console_kit_shutdown (helper, "Stop", error);
- }
-#endif
-
-#ifdef ENABLE_HAL
- if ( helper->shutdown_backend == XFSM_SHUTDOWN_BACKEND_HAL )
- {
- return xfsm_shutdown_helper_hal_send (helper, "Shutdown", error);
- }
-#endif
-
- /*Use Sudo mode*/
- return xfsm_shutdown_helper_sudo_send (helper, "POWEROFF", error);
-
-}
-
-/**
- * xfsm_shutdown_helper_restart:
- *
- *
- **/
-gboolean xfsm_shutdown_helper_restart (XfsmShutdownHelper *helper, GError **error)
-{
- g_return_val_if_fail (!error || !*error, FALSE);
-
-#ifdef ENABLE_CONSOLE_KIT
- if ( helper->shutdown_backend == XFSM_SHUTDOWN_BACKEND_CONSOLE_KIT )
- {
- return xfsm_shutdown_helper_console_kit_shutdown (helper, "Restart", error);
- }
-#endif
-
-#ifdef ENABLE_HAL
- if ( helper->shutdown_backend == XFSM_SHUTDOWN_BACKEND_HAL )
- {
- return xfsm_shutdown_helper_hal_send (helper, "Reboot", error);
- }
-#endif
-
- return xfsm_shutdown_helper_sudo_send (helper, "REBOOT", error);
-
-}
-
-/**
- * xfsm_shutdown_helper_suspend:
- *
- **/
-gboolean xfsm_shutdown_helper_suspend (XfsmShutdownHelper *helper, GError **error)
-{
- g_return_val_if_fail (!error || !*error, FALSE);
-
-#ifdef ENABLE_UPOWER
- if ( helper->sleep_backend == XFSM_SLEEP_BACKEND_UPOWER )
- {
- return xfsm_shutdown_helper_upower_sleep (helper, "Suspend", error);
- }
-#endif
-
-#ifdef ENABLE_HAL
- if ( helper->sleep_backend == XFSM_SLEEP_BACKEND_HAL )
- {
- return xfsm_shutdown_helper_hal_send (helper, "Suspend", error);
- }
-#endif
-
- g_set_error (error, 1, 0, "%s", _("Suspend failed, no backend supported"));
-
- return FALSE;
-}
-
-/**
- * xfsm_shutdown_helper_hibernate:
- *
- **/
-gboolean xfsm_shutdown_helper_hibernate (XfsmShutdownHelper *helper, GError **error)
-{
- g_return_val_if_fail (!error || !*error, FALSE);
-
-#ifdef ENABLE_UPOWER
- if ( helper->sleep_backend == XFSM_SLEEP_BACKEND_UPOWER )
- {
- return xfsm_shutdown_helper_upower_sleep (helper, "Hibernate", error);
- }
-#endif
-
-#ifdef ENABLE_HAL
- if ( helper->sleep_backend == XFSM_SLEEP_BACKEND_HAL )
- {
- return xfsm_shutdown_helper_hal_send (helper, "Hibernate", error);
- }
-#endif
-
- g_set_error (error, 1, 0, "%s", _("Hibernate failed, no backend supported"));
-
- return FALSE;
-}
-
-/**
- * xfsm_shutdown_helper_send_command:
- *
- **/
-gboolean xfsm_shutdown_helper_send_command (XfsmShutdownHelper *helper,
- XfsmShutdownType shutdown_type,
- GError **error)
-{
- g_return_val_if_fail (!error || !*error, FALSE);
-
- switch (shutdown_type)
- {
- case XFSM_SHUTDOWN_HALT:
- return xfsm_shutdown_helper_shutdown (helper, error);
- case XFSM_SHUTDOWN_REBOOT:
- return xfsm_shutdown_helper_restart (helper, error);
- case XFSM_SHUTDOWN_HIBERNATE:
- return xfsm_shutdown_helper_hibernate (helper, error);
- case XFSM_SHUTDOWN_SUSPEND:
- return xfsm_shutdown_helper_suspend (helper, error);
- default:
- g_warn_if_reached ();
- break;
- }
-
- g_set_error (error, 1, 0, "%s", _("Shutdown Command not found"));
-
- return FALSE;
-}
diff --git a/xfce4-session/xfsm-shutdown-helper.h b/xfce4-session/xfsm-shutdown-helper.h
deleted file mode 100644
index 4bacbe82..00000000
--- a/xfce4-session/xfsm-shutdown-helper.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* $Id$ */
-/*-
- * Copyright (c) 2003-2006 Benedikt Meurer <benny@xfce.org>
- * Copyright (c) 2010 Ali Abdallah <aliov@xfce.org>
- * All rights reserved.
- *
- * 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, 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., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA.
- */
-
-#ifndef __XFSM_SHUTDOWN_HELPER_H
-#define __XFSM_SHUTDOWN_HELPER_H
-
-#include <glib-object.h>
-#include <xfce4-session/xfsm-global.h>
-
-G_BEGIN_DECLS
-
-#define XFSM_TYPE_SHUTDOWN_HELPER (xfsm_shutdown_helper_get_type () )
-#define XFSM_SHUTDOWN_HELPER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XFSM_TYPE_SHUTDOWN_HELPER, XfsmShutdownHelper))
-#define XFSM_IS_SHUTDOWN_HELPER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XFSM_TYPE_SHUTDOWN_HELPER))
-
-typedef struct _XfsmShutdownHelperClass XfsmShutdownHelperClass;
-typedef struct _XfsmShutdownHelper XfsmShutdownHelper;
-
-GType xfsm_shutdown_helper_get_type (void) G_GNUC_CONST;
-
-XfsmShutdownHelper *xfsm_shutdown_helper_new (void);
-
-gboolean xfsm_shutdown_helper_send_password (XfsmShutdownHelper *helper,
- const gchar *password);
-
-gboolean xfsm_shutdown_helper_shutdown (XfsmShutdownHelper *helper,
- GError **error);
-
-gboolean xfsm_shutdown_helper_restart (XfsmShutdownHelper *helper,
- GError **error);
-
-gboolean xfsm_shutdown_helper_suspend (XfsmShutdownHelper *helper,
- GError **error);
-
-gboolean xfsm_shutdown_helper_hibernate (XfsmShutdownHelper *helper,
- GError **error);
-
-gboolean xfsm_shutdown_helper_send_command (XfsmShutdownHelper *helper,
- XfsmShutdownType shutdown_type,
- GError **error);
-
-
-G_END_DECLS
-
-#endif /* __XFSM_SHUTDOWN_HELPER_H */
diff --git a/xfce4-session/xfsm-shutdown.c b/xfce4-session/xfsm-shutdown.c
index 9246c010..2436dcd1 100644
--- a/xfce4-session/xfsm-shutdown.c
+++ b/xfce4-session/xfsm-shutdown.c
@@ -1,6 +1,6 @@
-/* $Id$ */
/*-
* Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2011 Nick Schermer <nick@xfce.org>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -36,7 +36,19 @@
#ifdef HAVE_STRING_H
#include <string.h>
#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
#include <libxfce4util/libxfce4util.h>
#include <gtk/gtk.h>
@@ -48,60 +60,682 @@
#include <xfce4-session/xfsm-fadeout.h>
#include <xfce4-session/xfsm-global.h>
#include <xfce4-session/xfsm-legacy.h>
-#include <xfce4-session/xfsm-shutdown-helper.h>
+#include <xfce4-session/xfsm-consolekit.h>
+
+
+
+static void xfsm_shutdown_finalize (GObject *object);
+static void xfsm_shutdown_sudo_free (XfsmShutdown *shutdown);
+
+
+
+struct _XfsmShutdownClass
+{
+ GObjectClass __parent__;
+};
+
+typedef enum
+{
+ SUDO_NOT_INITIAZED,
+ SUDO_AVAILABLE,
+ SUDO_FAILED
+}
+HelperState;
+
+struct _XfsmShutdown
+{
+ GObject __parent__;
+
+ XfsmConsolekit *consolekit;
+
+ /* sudo helper */
+ HelperState helper_state;
+ pid_t helper_pid;
+ FILE *helper_infile;
+ FILE *helper_outfile;
+ guint helper_watchid;
+ gboolean helper_require_password;
+};
+
+
+
+G_DEFINE_TYPE (XfsmShutdown, xfsm_shutdown, G_TYPE_OBJECT)
+
+
+
+static void
+xfsm_shutdown_class_init (XfsmShutdownClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = xfsm_shutdown_finalize;
+}
+
+
+
+static void
+xfsm_shutdown_init (XfsmShutdown *shutdown)
+{
+ shutdown->consolekit = xfsm_consolekit_get ();
+ shutdown->helper_state = SUDO_NOT_INITIAZED;
+ shutdown->helper_require_password = FALSE;
+}
+
+
+
+static void
+xfsm_shutdown_finalize (GObject *object)
+{
+ XfsmShutdown *shutdown = XFSM_SHUTDOWN (object);
+
+ g_object_unref (G_OBJECT (shutdown->consolekit));
+
+ /* close down helper */
+ xfsm_shutdown_sudo_free (shutdown);
+
+ (*G_OBJECT_CLASS (xfsm_shutdown_parent_class)->finalize) (object);
+}
+
+
+
+static void
+xfsm_shutdown_sudo_free (XfsmShutdown *shutdown)
+{
+ gint status;
+
+ /* close down helper */
+ if (shutdown->helper_infile != NULL)
+ {
+ fclose (shutdown->helper_infile);
+ shutdown->helper_infile = NULL;
+ }
+
+ if (shutdown->helper_outfile != NULL)
+ {
+ fclose (shutdown->helper_outfile);
+ shutdown->helper_outfile = NULL;
+ }
+
+ if (shutdown->helper_watchid > 0)
+ {
+ g_source_remove (shutdown->helper_watchid);
+ shutdown->helper_watchid = 0;
+ }
+
+ if (shutdown->helper_pid > 0)
+ {
+ waitpid (shutdown->helper_pid, &status, 0);
+ shutdown->helper_pid = 0;
+ }
+
+ /* reset state */
+ shutdown->helper_state = SUDO_NOT_INITIAZED;
+}
+
+
+
+static void
+xfsm_shutdown_sudo_childwatch (GPid pid,
+ gint status,
+ gpointer data)
+{
+ /* close down sudo stuff */
+ xfsm_shutdown_sudo_free (XFSM_SHUTDOWN (data));
+}
+
+
+
+static gboolean
+xfsm_shutdown_sudo_init (XfsmShutdown *shutdown,
+ GError **error)
+{
+ gchar *cmd;
+ struct rlimit rlp;
+ gchar buf[15];
+ gint parent_pipe[2];
+ gint child_pipe[2];
+ gint n;
+
+ /* return state if we succeeded */
+ if (shutdown->helper_state != SUDO_NOT_INITIAZED)
+ return shutdown->helper_state == SUDO_AVAILABLE;
+
+ g_return_val_if_fail (shutdown->helper_infile == NULL, FALSE);
+ g_return_val_if_fail (shutdown->helper_outfile == NULL, FALSE);
+ g_return_val_if_fail (shutdown->helper_watchid == 0, FALSE);
+ g_return_val_if_fail (shutdown->helper_pid == 0, FALSE);
+
+ /* assume it won't work for now */
+ shutdown->helper_state = SUDO_FAILED;
+
+ cmd = g_find_program_in_path ("sudo");
+ if (G_UNLIKELY (cmd == NULL))
+ {
+ g_set_error_literal (error, 1, 0,
+ "The program \"sudo\" was not found");
+ return FALSE;
+ }
+
+ if (pipe (parent_pipe) == -1)
+ {
+ g_set_error (error, 1, 0,
+ "Unable to create parent pipe: %s",
+ strerror (errno));
+ goto err0;
+ }
+
+ if (pipe (child_pipe) == -1)
+ {
+ g_set_error (error, 1, 0,
+ "Unable to create child pipe: %s",
+ strerror (errno));
+ goto err1;
+ }
+
+ shutdown->helper_pid = fork ();
+ if (shutdown->helper_pid < 0)
+ {
+ g_set_error (error, 1, 0,
+ "Unable to fork sudo helper: %s",
+ strerror (errno));
+ goto err2;
+ }
+ else if (shutdown->helper_pid == 0)
+ {
+ /* setup signals */
+ signal (SIGPIPE, SIG_IGN);
+
+ /* setup environment */
+ xfce_setenv ("LC_ALL", "C", TRUE);
+ xfce_setenv ("LANG", "C", TRUE);
+ xfce_setenv ("LANGUAGE", "C", TRUE);
+
+ /* setup the 3 standard file handles */
+ dup2 (child_pipe[0], STDIN_FILENO);
+ dup2 (parent_pipe[1], STDOUT_FILENO);
+ dup2 (parent_pipe[1], STDERR_FILENO);
+
+ /* close all other file handles */
+ getrlimit (RLIMIT_NOFILE, &rlp);
+ for (n = 0; n < (gint) rlp.rlim_cur; ++n)
+ {
+ if (n != STDIN_FILENO && n != STDOUT_FILENO && n != STDERR_FILENO)
+ close (n);
+ }
+
+ /* execute sudo with the helper */
+ execl (cmd, "sudo", "-H", "-S", "-p",
+ "XFSM_SUDO_PASS ", "--",
+ XFSM_SHUTDOWN_HELPER_CMD, NULL);
+
+ g_free (cmd);
+ cmd = NULL;
+
+ _exit (127);
+ }
+ else
+ {
+ /* watch the sudo helper */
+ shutdown->helper_watchid = g_child_watch_add (shutdown->helper_pid,
+ xfsm_shutdown_sudo_childwatch,
+ shutdown);
+ }
+
+ /* read sudo/helper answer */
+ n = read (parent_pipe[0], buf, sizeof (buf));
+ if (n < 15)
+ {
+ g_set_error (error, 1, 0,
+ "Unable to read response from sudo helper: %s",
+ n < 0 ? strerror (errno) : "Unknown error");
+ goto err2;
+ }
+
+ /* open pipe to receive replies from sudo */
+ shutdown->helper_infile = fdopen (parent_pipe[0], "r");
+ if (shutdown->helper_infile == NULL)
+ {
+ g_set_error (error, 1, 0,
+ "Unable to open parent pipe: %s",
+ strerror (errno));
+ goto err2;
+ }
+ close (parent_pipe[1]);
+
+ /* open pipe to send passwords to sudo */
+ shutdown->helper_outfile = fdopen (child_pipe[1], "w");
+ if (shutdown->helper_outfile == NULL)
+ {
+ g_set_error (error, 1, 0,
+ "Unable to open parent pipe: %s",
+ strerror (errno));
+ goto err2;
+ }
+ close (child_pipe[0]);
+
+ /* check if NOPASSWD is set in /etc/sudoers */
+ if (memcmp (buf, "XFSM_SUDO_PASS ", 15) == 0)
+ {
+ shutdown->helper_require_password = TRUE;
+ }
+ else if (memcmp (buf, "XFSM_SUDO_DONE ", 15) == 0)
+ {
+ shutdown->helper_require_password = FALSE;
+ }
+ else
+ {
+ g_set_error (error, 1, 0,
+ "Got unexpected reply from sudo shutdown helper");
+ goto err2;
+ }
+
+ /* if we try again */
+ shutdown->helper_state = SUDO_AVAILABLE;
+
+ return TRUE;
+
+err2:
+ xfsm_shutdown_sudo_free (shutdown);
+
+ close (child_pipe[0]);
+ close (child_pipe[1]);
+
+err1:
+ close (parent_pipe[0]);
+ close (parent_pipe[1]);
+
+err0:
+ g_free (cmd);
+
+ shutdown->helper_pid = 0;
+
+ return FALSE;
+}
+
+
+
+static gboolean
+xfsm_shutdown_sudo_try_action (XfsmShutdown *shutdown,
+ XfsmShutdownType type,
+ GError **error)
+{
+ const gchar *action;
+ gchar reply[256];
+
+ g_return_val_if_fail (shutdown->helper_state == SUDO_AVAILABLE, FALSE);
+ g_return_val_if_fail (shutdown->helper_outfile != NULL, FALSE);
+ g_return_val_if_fail (shutdown->helper_infile != NULL, FALSE);
+ g_return_val_if_fail (type == XFSM_SHUTDOWN_SHUTDOWN
+ || type == XFSM_SHUTDOWN_RESTART, FALSE);
-gint
-xfsm_shutdown(XfsmShutdownType type)
+ /* the command we send to sudo */
+ if (type == XFSM_SHUTDOWN_SHUTDOWN)
+ action = "POWEROFF";
+ else if (type == XFSM_SHUTDOWN_RESTART)
+ action = "REBOOT";
+ else
+ return FALSE;
+
+ /* write action to sudo helper */
+ if (fprintf (shutdown->helper_outfile, "%s\n", action) > 0)
+ fflush (shutdown->helper_outfile);
+
+ /* check if the write succeeded */
+ if (ferror (shutdown->helper_outfile) != 0)
+ {
+ /* probably succeeded but the helper got killed */
+ if (errno == EINTR)
+ return TRUE;
+
+ g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+ _("Error sending command to shutdown helper: %s"),
+ strerror (errno));
+ return FALSE;
+ }
+
+ /* get responce from sudo helper */
+ if (fgets (reply, sizeof (reply), shutdown->helper_infile) == NULL)
+ {
+ /* probably succeeded but the helper got killed */
+ if (errno == EINTR)
+ return TRUE;
+
+ g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+ _("Error receiving response from shutdown helper: %s"),
+ strerror (errno));
+ return FALSE;
+ }
+
+ if (strncmp (reply, "SUCCEED", 7) != 0)
+ {
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ _("Shutdown command failed"));
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+
+static XfsmPassState
+xfsm_shutdown_sudo_send_password (XfsmShutdown *shutdown,
+ const gchar *password)
{
- gboolean result;
- GError *error = NULL;
- XfsmShutdownHelper *shutdown_helper;
+ gchar buf[1024];
+ gsize len_buf, len_send;
+ gint fd;
+ gsize len;
+ gssize result;
+ gint attempts;
+ const gchar *errmsg = NULL;
+
+ g_return_val_if_fail (shutdown->helper_state == SUDO_AVAILABLE, PASSWORD_FAILED);
+ g_return_val_if_fail (shutdown->helper_outfile != NULL, PASSWORD_FAILED);
+ g_return_val_if_fail (shutdown->helper_infile != NULL, PASSWORD_FAILED);
+ g_return_val_if_fail (shutdown->helper_require_password, PASSWORD_FAILED);
+ g_return_val_if_fail (password != NULL, PASSWORD_FAILED);
+
+ /* write password to sudo helper */
+ g_snprintf (buf, sizeof (buf), "%s\n", password);
+ len_buf = strlen (buf);
+ len_send = fwrite (buf, 1, len_buf, shutdown->helper_outfile);
+ fflush (shutdown->helper_outfile);
+ bzero (buf, len_buf);
- /* kludge */
- if (type == XFSM_SHUTDOWN_ASK)
+ if (len_send != len_buf
+ || ferror (shutdown->helper_outfile) != 0)
{
- g_warning ("xfsm_shutdown () passed XFSM_SHUTDOWN_ASK. This is a bug.");
- type = XFSM_SHUTDOWN_LOGOUT;
+ errmsg = "Failed to send password to sudo";
+ goto err1;
}
- /* these two remember if they were started or not */
- xfsm_compat_gnome_shutdown ();
- xfsm_compat_kde_shutdown ();
+ fd = fileno (shutdown->helper_infile);
+
+ for (len = 0, attempts = 0;;)
+ {
+ result = read (fd, buf + len, 256 - len);
+
+ if (result < 0)
+ {
+ errmsg = "Failed to read data from sudo";
+ goto err1;
+ }
+ else if (result == 0)
+ {
+ /* don't try too often */
+ if (++attempts > 20)
+ {
+ errmsg = "Too many password attempts";
+ goto err1;
+ }
+
+ continue;
+ }
+ else if (result + len >= sizeof (buf))
+ {
+ errmsg = "Received too much data from sudo";
+ goto err1;
+ }
- /* kill legacy clients */
- xfsm_legacy_shutdown ();
+ len += result;
+ buf[len] = '\0';
+
+ if (len >= 15)
+ {
+ if (g_str_has_suffix (buf, "XFSM_SUDO_PASS "))
+ {
+ return PASSWORD_RETRY;
+ }
+ else if (g_str_has_suffix (buf, "XFSM_SUDO_DONE "))
+ {
+ /* sudo is unlocked, no further passwords required */
+ shutdown->helper_require_password = FALSE;
+
+ return PASSWORD_SUCCEED;
+ }
+ }
+ }
+
+ return PASSWORD_FAILED;
+
+ err1:
+
+ g_printerr (PACKAGE_NAME ": %s.\n\n", errmsg);
+ return PASSWORD_FAILED;
+}
-#if !defined(__NR_ioprio_set) && defined(HAVE_SYNC)
- /* sync disk block in-core status with that on disk. if
- * we have ioprio_set (), then we've already synced. */
- if (fork () == 0)
+
+
+static gboolean
+xfsm_shutdown_query_xfpm (XfsmShutdown *shutdown,
+ const gchar *method,
+ gboolean *can_method,
+ GError **error)
+{
+ DBusGConnection *conn;
+ DBusGProxy *proxy;
+ gboolean result = FALSE;
+
+ g_return_val_if_fail (can_method != NULL, FALSE);
+
+ /* never return true if something fails */
+ *can_method = FALSE;
+
+ conn = dbus_g_bus_get (DBUS_BUS_SESSION, error);
+ if (conn == NULL)
+ return FALSE;
+
+ proxy = dbus_g_proxy_new_for_name_owner (conn, "org.xfce.Power.Manager",
+ "/org/xfce/PowerManager",
+ "org.xfce.Power.Manager", error);
+ if (proxy != NULL)
+ {
+ result = dbus_g_proxy_call (proxy, method, error,
+ G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, can_method,
+ G_TYPE_INVALID);
+ g_object_unref (proxy);
+ }
+
+ dbus_g_connection_unref (conn);
+
+ return result;
+}
+
+
+
+XfsmShutdown *
+xfsm_shutdown_get (void)
+{
+ static XfsmShutdown *object = NULL;
+
+ if (G_LIKELY (object != NULL))
+ {
+ g_object_ref (G_OBJECT (object));
+ }
+ else
{
-# ifdef HAVE_SETSID
- setsid ();
-# endif
- sync ();
- _exit (EXIT_SUCCESS);
+ object = g_object_new (XFSM_TYPE_SHUTDOWN, NULL);
+ g_object_add_weak_pointer (G_OBJECT (object), (gpointer) &object);
}
-#endif /* HAVE_SYNC */
- if (type == XFSM_SHUTDOWN_LOGOUT)
- return EXIT_SUCCESS;
+ return object;
+}
+
+
+
+gboolean
+xfsm_shutdown_password_require (XfsmShutdown *shutdown,
+ XfsmShutdownType type)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ /* the helper only handled shutdown and restart */
+ if (type == XFSM_SHUTDOWN_SHUTDOWN || type == XFSM_SHUTDOWN_RESTART)
+ return shutdown->helper_require_password;
+
+ return FALSE;
+}
+
+
+
+XfsmPassState
+xfsm_shutdown_password_send (XfsmShutdown *shutdown,
+ XfsmShutdownType type,
+ const gchar *password)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), PASSWORD_FAILED);
+ g_return_val_if_fail (password != NULL, PASSWORD_FAILED);
+
+ if ((type == XFSM_SHUTDOWN_SHUTDOWN || type == XFSM_SHUTDOWN_RESTART)
+ && shutdown->helper_state == SUDO_AVAILABLE)
+ return xfsm_shutdown_sudo_send_password (shutdown, password);
+
+ return PASSWORD_FAILED;
+}
- shutdown_helper = xfsm_shutdown_helper_new ();
- result = xfsm_shutdown_helper_send_command (shutdown_helper, type, &error);
- g_object_unref (shutdown_helper);
- if (!result)
+
+gboolean
+xfsm_shutdown_try_type (XfsmShutdown *shutdown,
+ XfsmShutdownType type,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ switch (type)
{
- xfce_message_dialog (NULL, _("Shutdown Failed"),
- GTK_STOCK_DIALOG_ERROR,
- _("Unable to perform shutdown"),
- error->message,
- GTK_STOCK_QUIT, GTK_RESPONSE_ACCEPT,
- NULL);
- g_error_free (error);
- return EXIT_FAILURE;
+ case XFSM_SHUTDOWN_SHUTDOWN:
+ return xfsm_shutdown_try_shutdown (shutdown, error);
+
+ case XFSM_SHUTDOWN_RESTART:
+ return xfsm_shutdown_try_restart (shutdown, error);
+
+ case XFSM_SHUTDOWN_SUSPEND:
+ return xfsm_shutdown_try_suspend (shutdown, error);
+
+ case XFSM_SHUTDOWN_HIBERNATE:
+ return xfsm_shutdown_try_hibernate (shutdown, error);
+
+ default:
+ g_set_error (error, 1, 0, _("Unknown shutdown method %d"), type);
+ break;
}
- return EXIT_SUCCESS;
+ return FALSE;
+}
+
+
+
+gboolean
+xfsm_shutdown_try_restart (XfsmShutdown *shutdown,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ if (shutdown->helper_state == SUDO_AVAILABLE)
+ return xfsm_shutdown_sudo_try_action (shutdown, XFSM_SHUTDOWN_RESTART, error);
+ else
+ return xfsm_consolekit_try_restart (shutdown->consolekit, error);
+}
+
+
+
+gboolean
+xfsm_shutdown_try_shutdown (XfsmShutdown *shutdown,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ if (shutdown->helper_state == SUDO_AVAILABLE)
+ return xfsm_shutdown_sudo_try_action (shutdown, XFSM_SHUTDOWN_SHUTDOWN, error);
+ else
+ return xfsm_consolekit_try_shutdown (shutdown->consolekit, error);
+}
+
+
+
+gboolean
+xfsm_shutdown_try_suspend (XfsmShutdown *shutdown,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ return TRUE;
+}
+
+
+
+gboolean
+xfsm_shutdown_try_hibernate (XfsmShutdown *shutdown,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ return TRUE;
+}
+
+
+
+gboolean
+xfsm_shutdown_can_restart (XfsmShutdown *shutdown,
+ gboolean *can_restart,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ if (xfsm_consolekit_can_restart (shutdown->consolekit, can_restart, error))
+ return TRUE;
+
+ return xfsm_shutdown_sudo_init (shutdown, error);
+}
+
+
+
+gboolean
+xfsm_shutdown_can_shutdown (XfsmShutdown *shutdown,
+ gboolean *can_shutdown,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ if (xfsm_consolekit_can_shutdown (shutdown->consolekit, can_shutdown, error))
+ return TRUE;
+
+ return xfsm_shutdown_sudo_init (shutdown, error);
+}
+
+
+
+/* This function only queries the CanSuspend state of
+ * xfce4-power-manager. If this package is not installed,
+ * suspend is not supported. */
+gboolean
+xfsm_shutdown_can_suspend (XfsmShutdown *shutdown,
+ gboolean *can_suspend,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ return xfsm_shutdown_query_xfpm (shutdown, "CanSuspend",
+ can_suspend, error);
+}
+
+
+
+/* This function only queries the CanHibernate state of
+ * xfce4-power-manager. If this package is not installed,
+ * hibernation is not supported. */
+gboolean
+xfsm_shutdown_can_hibernate (XfsmShutdown *shutdown,
+ gboolean *can_hibernate,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ return xfsm_shutdown_query_xfpm (shutdown, "CanHibernate",
+ can_hibernate, error);
}
diff --git a/xfce4-session/xfsm-shutdown.h b/xfce4-session/xfsm-shutdown.h
index 76d71458..2ec61f0a 100644
--- a/xfce4-session/xfsm-shutdown.h
+++ b/xfce4-session/xfsm-shutdown.h
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2011 Nick Schermer <nick@xfce.org>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -21,8 +22,76 @@
#ifndef __XFSM_SHUTDOWN_H__
#define __XFSM_SHUTDOWN_H__
-#include <xfce4-session/xfsm-global.h>
+typedef struct _XfsmShutdownClass XfsmShutdownClass;
+typedef struct _XfsmShutdown XfsmShutdown;
-gint xfsm_shutdown (XfsmShutdownType type);
+#define XFSM_TYPE_SHUTDOWN (xfsm_shutdown_get_type ())
+#define XFSM_SHUTDOWN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFSM_TYPE_SHUTDOWN, XfsmShutdown))
+#define XFSM_SHUTDOWN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFSM_TYPE_SHUTDOWN, XfsmShutdownClass))
+#define XFSM_IS_SHUTDOWN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFSM_TYPE_SHUTDOWN))
+#define XFSM_IS_SHUTDOWN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFSM_TYPE_SHUTDOWN))
+#define XFSM_SHUTDOWN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFSM_TYPE_SHUTDOWN, XfsmShutdownClass))
+
+typedef enum
+{
+ XFSM_SHUTDOWN_ASK = 0,
+ XFSM_SHUTDOWN_LOGOUT,
+ XFSM_SHUTDOWN_SHUTDOWN,
+ XFSM_SHUTDOWN_RESTART,
+ XFSM_SHUTDOWN_SUSPEND,
+ XFSM_SHUTDOWN_HIBERNATE,
+}
+XfsmShutdownType;
+
+typedef enum
+{
+ PASSWORD_RETRY,
+ PASSWORD_SUCCEED,
+ PASSWORD_FAILED
+}
+XfsmPassState;
+
+GType xfsm_shutdown_get_type (void) G_GNUC_CONST;
+
+XfsmShutdown *xfsm_shutdown_get (void);
+
+gboolean xfsm_shutdown_password_require (XfsmShutdown *shutdown,
+ XfsmShutdownType type);
+
+XfsmPassState xfsm_shutdown_password_send (XfsmShutdown *shutdown,
+ XfsmShutdownType type,
+ const gchar *password);
+
+gboolean xfsm_shutdown_try_type (XfsmShutdown *shutdown,
+ XfsmShutdownType type,
+ GError **error);
+
+gboolean xfsm_shutdown_try_restart (XfsmShutdown *shutdown,
+ GError **error);
+
+gboolean xfsm_shutdown_try_shutdown (XfsmShutdown *shutdown,
+ GError **error);
+
+gboolean xfsm_shutdown_try_suspend (XfsmShutdown *shutdown,
+ GError **error);
+
+gboolean xfsm_shutdown_try_hibernate (XfsmShutdown *shutdown,
+ GError **error);
+
+gboolean xfsm_shutdown_can_restart (XfsmShutdown *shutdown,
+ gboolean *can_restart,
+ GError **error);
+
+gboolean xfsm_shutdown_can_shutdown (XfsmShutdown *shutdown,
+ gboolean *can_shutdown,
+ GError **error);
+
+gboolean xfsm_shutdown_can_suspend (XfsmShutdown *shutdown,
+ gboolean *can_suspend,
+ GError **error);
+
+gboolean xfsm_shutdown_can_hibernate (XfsmShutdown *shutdown,
+ gboolean *can_hibernate,
+ GError **error);
#endif /* !__XFSM_SHUTDOWN_H__ */