gnome-session r4732 - in trunk: . gnome-session
- From: lucasr svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-session r4732 - in trunk: . gnome-session
- Date: Thu, 12 Jun 2008 23:13:33 +0000 (UTC)
Author: lucasr
Date: Thu Jun 12 23:13:33 2008
New Revision: 4732
URL: http://svn.gnome.org/viewvc/gnome-session?rev=4732&view=rev
Log:
2008-06-13 Lucas Rocha <lucasr gnome org>
Add support for ConsoleKit reboot and shutdown. #511881, William Jon
McCann. Patch by William Jon McCann and Matthias Clasen.
* configure.in: check for optional dependency on polkit-gnome.
* gnome-session/Makefile.am: use polkit-gnome flags and libs
on session manager build.
* gnome-session/consolekit.[ch]: interface to abstract the
communication with ConsoleKit and PolicyKit.
* gnome-session/logout-dialog.c (gsm_logout_supports_reboot,
gsm_logout_supports_shutdown): first check if ConsoleKit can
shutdown/restart system. If not, try GDM directly.
* gnome-session/session.c (do_request_reboot, do_request_shutdown,
session_shutdown): use ConsoleKit to shutdown/restart system after
logout. If not possible, use GDM directly.
Added:
trunk/gnome-session/consolekit.c
trunk/gnome-session/consolekit.h
Modified:
trunk/ChangeLog
trunk/configure.in
trunk/gnome-session/Makefile.am
trunk/gnome-session/app-autostart.c
trunk/gnome-session/logout-dialog.c
trunk/gnome-session/session.c
Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in (original)
+++ trunk/configure.in Thu Jun 12 23:13:33 2008
@@ -57,6 +57,7 @@
GLADE_REQUIRED=2.3.6
DBUS_GLIB_REQUIRED=0.35
GNOME_KEYRING_REQUIRED=2.21.92
+POLKIT_GNOME_REQUIRED=0.7
dnl ====================================================================
dnl Dependency Checks
@@ -76,6 +77,12 @@
PKG_CHECK_MODULES(EGG_SMCLIENT, gtk+-2.0)
PKG_CHECK_MODULES(EGG_LIBGNOMEUI, libgnomeui-2.0)
+PKG_CHECK_MODULES(POLKIT_GNOME, polkit-gnome >= $POLKIT_GNOME_REQUIRED, have_polkit=yes, have_polkit=no)
+
+if test "$have_polkit" = "yes"; then
+ AC_DEFINE(HAVE_POLKIT_GNOME, [1], [whether PolKit GNOME was found])
+fi
+
AC_CHECK_LIB(gdk-x11-2.0, gdk_x11_display_broadcast_startup_message, have_startup_message=yes, have_startup_message=no, "$GTK_LIBS")
if test "x$have_startup_message" = "xyes"; then
AC_DEFINE([HAVE_GDK_X11_DISPLAY_BROADCAST_STARTUP_MESSAGE],[1],[Define to compile with broadcast startup message support])
Modified: trunk/gnome-session/Makefile.am
==============================================================================
--- trunk/gnome-session/Makefile.am (original)
+++ trunk/gnome-session/Makefile.am Thu Jun 12 23:13:33 2008
@@ -8,6 +8,7 @@
$(DBUS_GLIB_CFLAGS) \
$(GCONF_CFLAGS) \
$(GTK_CFLAGS) \
+ $(POLKIT_GNOME_CFLAGS) \
-I$(top_srcdir)/egg \
-DLOCALE_DIR=\""$(datadir)/locale"\" \
-DDATA_DIR=\""$(datadir)/gnome-session"\" \
@@ -21,7 +22,8 @@
$(top_builddir)/egg/libeggdesktopfile.la \
$(GNOME_SESSION_LIBS) \
$(DBUS_GLIB_LIBS) \
- $(GCONF_LIBS)
+ $(GCONF_LIBS) \
+ $(POLKIT_GNOME_LIBS)
gnome_session_SOURCES = \
app-autostart.c \
@@ -34,6 +36,8 @@
client-xsmp.h \
client.c \
client.h \
+ consolekit.c \
+ consolekit.h \
dbus.c \
dbus.h \
gconf.c \
Modified: trunk/gnome-session/app-autostart.c
==============================================================================
--- trunk/gnome-session/app-autostart.c (original)
+++ trunk/gnome-session/app-autostart.c Thu Jun 12 23:13:33 2008
@@ -33,7 +33,8 @@
LAST_SIGNAL
};
-struct _GsmAppAutostartPrivate {
+struct _GsmAppAutostartPrivate
+{
GFileMonitor *monitor;
gboolean condition;
};
Added: trunk/gnome-session/consolekit.c
==============================================================================
--- (empty file)
+++ trunk/gnome-session/consolekit.c Thu Jun 12 23:13:33 2008
@@ -0,0 +1,683 @@
+/* console-kit.c
+ * Copyright (C) 2008 Jon McCann <jmccann redhat com>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gi18n.h>
+
+#include <dbus/dbus-glib.h>
+
+#ifdef HAVE_POLKIT_GNOME
+#include <polkit-gnome/polkit-gnome.h>
+#endif
+
+#include "consolekit.h"
+
+#define CK_NAME "org.freedesktop.ConsoleKit"
+#define CK_PATH "/org/freedesktop/ConsoleKit"
+#define CK_INTERFACE "org.freedesktop.ConsoleKit"
+
+#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
+#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
+#define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat"
+#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
+
+#define GSM_CONSOLEKIT_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_CONSOLEKIT, GsmConsolekitPrivate))
+
+struct _GsmConsolekitPrivate
+{
+ DBusGConnection *dbus_connection;
+ DBusGProxy *bus_proxy;
+ DBusGProxy *ck_proxy;
+ guint32 is_connected : 1;
+};
+
+enum
+{
+ PROP_0,
+ PROP_IS_CONNECTED
+};
+
+enum
+{
+ REQUEST_COMPLETED = 0,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void gsm_consolekit_class_init (GsmConsolekitClass *klass);
+static void gsm_consolekit_init (GsmConsolekit *ck);
+static void gsm_consolekit_finalize (GObject *object);
+
+static void gsm_consolekit_on_name_owner_changed (DBusGProxy *bus_proxy,
+ const char *name,
+ const char *prev_owner,
+ const char *new_owner,
+ GsmConsolekit *manager);
+
+G_DEFINE_TYPE (GsmConsolekit, gsm_consolekit, G_TYPE_OBJECT);
+
+static void
+gsm_consolekit_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GsmConsolekit *manager = GSM_CONSOLEKIT (object);
+
+ switch (prop_id) {
+ case PROP_IS_CONNECTED:
+ g_value_set_boolean (value,
+ manager->priv->is_connected);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+ prop_id,
+ pspec);
+ }
+}
+
+static void
+gsm_consolekit_class_init (GsmConsolekitClass *manager_class)
+{
+ GObjectClass *object_class;
+ GParamSpec *param_spec;
+
+ object_class = G_OBJECT_CLASS (manager_class);
+
+ object_class->finalize = gsm_consolekit_finalize;
+ object_class->get_property = gsm_consolekit_get_property;
+
+ param_spec = g_param_spec_boolean ("is-connected",
+ "Is connected",
+ "Whether the session is connected to ConsoleKit",
+ FALSE,
+ G_PARAM_READABLE);
+
+ g_object_class_install_property (object_class, PROP_IS_CONNECTED,
+ param_spec);
+
+ signals [REQUEST_COMPLETED] =
+ g_signal_new ("request-completed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmConsolekitClass, request_completed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE,
+ 1, G_TYPE_POINTER);
+
+ g_type_class_add_private (manager_class, sizeof (GsmConsolekitPrivate));
+}
+
+static gboolean
+gsm_consolekit_ensure_ck_connection (GsmConsolekit *manager,
+ GError **error)
+{
+ GError *connection_error;
+ gboolean is_connected;
+
+ connection_error = NULL;
+
+ if (manager->priv->dbus_connection == NULL)
+ {
+ manager->priv->dbus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM,
+ &connection_error);
+
+ if (manager->priv->dbus_connection == NULL)
+ {
+ g_propagate_error (error, connection_error);
+ is_connected = FALSE;
+ goto out;
+ }
+ }
+
+ if (manager->priv->bus_proxy == NULL)
+ {
+ manager->priv->bus_proxy =
+ dbus_g_proxy_new_for_name_owner (manager->priv->dbus_connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ &connection_error);
+
+ if (manager->priv->bus_proxy == NULL)
+ {
+ g_propagate_error (error, connection_error);
+ is_connected = FALSE;
+ goto out;
+ }
+
+ dbus_g_proxy_add_signal (manager->priv->bus_proxy,
+ "NameOwnerChanged",
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_INVALID);
+
+ dbus_g_proxy_connect_signal (manager->priv->bus_proxy,
+ "NameOwnerChanged",
+ G_CALLBACK (gsm_consolekit_on_name_owner_changed),
+ manager, NULL);
+ }
+
+ if (manager->priv->ck_proxy == NULL)
+ {
+ manager->priv->ck_proxy =
+ dbus_g_proxy_new_for_name_owner (manager->priv->dbus_connection,
+ "org.freedesktop.ConsoleKit",
+ "/org/freedesktop/ConsoleKit/Manager",
+ "org.freedesktop.ConsoleKit.Manager",
+ &connection_error);
+
+ if (manager->priv->ck_proxy == NULL)
+ {
+ g_propagate_error (error, connection_error);
+ is_connected = FALSE;
+ goto out;
+ }
+ }
+
+ is_connected = TRUE;
+
+out:
+ if (manager->priv->is_connected != is_connected)
+ {
+ manager->priv->is_connected = is_connected;
+ g_object_notify (G_OBJECT (manager), "is-connected");
+ }
+
+ if (!is_connected)
+ {
+ if (manager->priv->dbus_connection == NULL)
+ {
+ if (manager->priv->bus_proxy != NULL)
+ {
+ g_object_unref (manager->priv->bus_proxy);
+ manager->priv->bus_proxy = NULL;
+ }
+
+ if (manager->priv->ck_proxy != NULL)
+ {
+ g_object_unref (manager->priv->ck_proxy);
+ manager->priv->ck_proxy = NULL;
+ }
+ }
+ else if (manager->priv->bus_proxy == NULL)
+ {
+ if (manager->priv->ck_proxy != NULL)
+ {
+ g_object_unref (manager->priv->ck_proxy);
+ manager->priv->ck_proxy = NULL;
+ }
+ }
+ }
+
+ return is_connected;
+}
+
+static void
+gsm_consolekit_on_name_owner_changed (DBusGProxy *bus_proxy,
+ const char *name,
+ const char *prev_owner,
+ const char *new_owner,
+ GsmConsolekit *manager)
+{
+ if (name != NULL && strcmp (name, "org.freedesktop.ConsoleKit") != 0)
+ return;
+
+ if (manager->priv->ck_proxy != NULL)
+ {
+ g_object_unref (manager->priv->ck_proxy);
+ manager->priv->ck_proxy = NULL;
+ }
+
+ gsm_consolekit_ensure_ck_connection (manager, NULL);
+}
+
+static void
+gsm_consolekit_init (GsmConsolekit *manager)
+{
+ GError *error;
+
+ manager->priv = GSM_CONSOLEKIT_GET_PRIVATE (manager);
+
+ error = NULL;
+
+ if (!gsm_consolekit_ensure_ck_connection (manager, &error))
+ {
+ g_message ("Could not connect to ConsoleKit: %s",
+ error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+gsm_consolekit_finalize (GObject *object)
+{
+ GsmConsolekit *manager;
+ GObjectClass *parent_class;
+
+ manager = GSM_CONSOLEKIT (object);
+
+ parent_class = G_OBJECT_CLASS (gsm_consolekit_parent_class);
+
+ if (manager->priv->bus_proxy != NULL)
+ g_object_unref (manager->priv->bus_proxy);
+
+ if (manager->priv->ck_proxy != NULL)
+ g_object_unref (manager->priv->ck_proxy);
+
+ if (parent_class->finalize != NULL)
+ parent_class->finalize (object);
+}
+
+GQuark
+gsm_consolekit_error_quark (void)
+{
+ static GQuark error_quark = 0;
+
+ if (error_quark == 0)
+ error_quark = g_quark_from_static_string ("gsm-consolekit-error");
+
+ return error_quark;
+}
+
+GsmConsolekit *
+gsm_consolekit_new (void)
+{
+ GsmConsolekit *manager;
+
+ manager = g_object_new (GSM_TYPE_CONSOLEKIT, NULL);
+
+ return manager;
+}
+
+static gboolean
+try_system_stop (DBusGConnection *connection,
+ GError **error)
+{
+ DBusGProxy *proxy;
+ gboolean res;
+
+ proxy = dbus_g_proxy_new_for_name (connection,
+ CK_NAME,
+ CK_MANAGER_PATH,
+ CK_MANAGER_INTERFACE);
+
+ res = dbus_g_proxy_call_with_timeout (proxy,
+ "Stop",
+ INT_MAX,
+ error,
+ /* parameters: */
+ G_TYPE_INVALID,
+ /* return values: */
+ G_TYPE_INVALID);
+ return res;
+}
+
+static gboolean
+try_system_restart (DBusGConnection *connection,
+ GError **error)
+{
+ DBusGProxy *proxy;
+ gboolean res;
+
+ proxy = dbus_g_proxy_new_for_name (connection,
+ CK_NAME,
+ CK_MANAGER_PATH,
+ CK_MANAGER_INTERFACE);
+
+ res = dbus_g_proxy_call_with_timeout (proxy,
+ "Restart",
+ INT_MAX,
+ error,
+ /* parameters: */
+ G_TYPE_INVALID,
+ /* return values: */
+ G_TYPE_INVALID);
+ return res;
+}
+
+static void
+emit_restart_complete (GsmConsolekit *manager,
+ const char *error_message)
+{
+ GError *call_error;
+
+ call_error = NULL;
+
+ if (error_message != NULL)
+ {
+ call_error = g_error_new_literal (GSM_CONSOLEKIT_ERROR,
+ GSM_CONSOLEKIT_ERROR_RESTARTING,
+ error_message);
+ }
+
+ g_signal_emit (G_OBJECT (manager),
+ signals [REQUEST_COMPLETED],
+ 0, call_error);
+
+ if (call_error != NULL)
+ g_error_free (call_error);
+}
+
+static void
+emit_stop_complete (GsmConsolekit *manager,
+ GError *error)
+{
+ GError *call_error;
+
+ call_error = NULL;
+
+ if (error != NULL)
+ {
+ call_error = g_error_new_literal (GSM_CONSOLEKIT_ERROR,
+ GSM_CONSOLEKIT_ERROR_STOPPING,
+ error->message);
+ }
+
+ g_signal_emit (G_OBJECT (manager),
+ signals [REQUEST_COMPLETED],
+ 0, call_error);
+
+ if (call_error != NULL)
+ g_error_free (call_error);
+}
+
+#ifdef HAVE_POLKIT_GNOME
+static void
+system_restart_auth_cb (PolKitAction *action,
+ gboolean gained_privilege,
+ GError *error,
+ GsmConsolekit *manager)
+{
+ GError *local_error;
+ gboolean res;
+
+ if (!gained_privilege)
+ {
+ if (error != NULL)
+ emit_restart_complete (manager, error->message);
+
+ return;
+ }
+
+ local_error = NULL;
+
+ res = try_system_restart (manager->priv->dbus_connection, &local_error);
+
+ if (!res)
+ {
+ g_warning ("Unable to restart system: %s", local_error->message);
+ emit_restart_complete (manager, local_error->message);
+ g_error_free (local_error);
+
+ return;
+ }
+}
+
+static void
+system_stop_auth_cb (PolKitAction *action,
+ gboolean gained_privilege,
+ GError *error,
+ GsmConsolekit *manager)
+{
+ GError *local_error;
+ gboolean res;
+
+ if (!gained_privilege)
+ {
+ if (error != NULL)
+ emit_stop_complete (manager, error);
+
+ return;
+ }
+
+ local_error = NULL;
+
+ res = try_system_stop (manager->priv->dbus_connection, &local_error);
+
+ if (!res)
+ {
+ g_warning ("Unable to stop system: %s", local_error->message);
+ emit_stop_complete (manager, local_error);
+ g_error_free (local_error);
+
+ return;
+ }
+}
+
+static PolKitAction *
+get_action_from_error (GError *error)
+{
+ PolKitAction *action;
+ const char *paction;
+
+ action = polkit_action_new ();
+
+ paction = NULL;
+
+ if (g_str_has_prefix (error->message, "Not privileged for action: "))
+ {
+ paction = error->message + strlen ("Not privileged for action: ");
+ }
+
+ polkit_action_set_action_id (action, paction);
+
+ return action;
+}
+#endif /* HAVE_POLKIT_GNOME */
+
+static void
+request_restart_priv (GsmConsolekit *manager,
+ GError *error)
+{
+#ifdef HAVE_POLKIT_GNOME
+ PolKitAction *action;
+ pid_t pid;
+ char *error_message = NULL;
+ gboolean res = FALSE;
+ guint xid;
+ GError *local_error;
+
+ action = get_action_from_error (error);
+
+ xid = 0;
+ pid = getpid ();
+
+ local_error = NULL;
+ res = polkit_gnome_auth_obtain (action,
+ xid,
+ pid,
+ (PolKitGnomeAuthCB) system_restart_auth_cb,
+ manager,
+ &local_error);
+
+ polkit_action_unref (action);
+
+ if (local_error != NULL)
+ {
+ error_message = g_strdup (local_error->message);
+ g_error_free (local_error);
+ }
+
+ if (!res)
+ {
+ emit_restart_complete (manager, error_message);
+ g_free (error_message);
+ }
+#else
+ g_assert_not_reached ();
+#endif /* HAVE POLKIT */
+}
+
+static void
+request_stop_priv (GsmConsolekit *manager,
+ GError *error)
+{
+#ifdef HAVE_POLKIT_GNOME
+ PolKitAction *action;
+ pid_t pid;
+ gboolean res = FALSE;
+ guint xid;
+ GError *local_error;
+
+ action = get_action_from_error (error);
+
+ xid = 0;
+ pid = getpid ();
+
+ local_error = NULL;
+ res = polkit_gnome_auth_obtain (action,
+ xid,
+ pid,
+ (PolKitGnomeAuthCB) system_stop_auth_cb,
+ manager,
+ &local_error);
+
+ polkit_action_unref (action);
+
+ if (!res)
+ {
+ if (local_error != NULL)
+ {
+ g_warning ("Unable to obtain auth to stop system: %s",
+ local_error->message);
+
+ emit_stop_complete (manager, local_error);
+ g_error_free (local_error);
+ }
+ }
+#else
+ g_assert_not_reached ();
+#endif /* HAVE POLKIT */
+}
+
+void
+gsm_consolekit_attempt_restart (GsmConsolekit *manager)
+{
+ gboolean res;
+ GError *error;
+
+ error = NULL;
+
+ if (!gsm_consolekit_ensure_ck_connection (manager, &error))
+ {
+ g_warning ("Could not connect to ConsoleKit: %s",
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ res = try_system_restart (manager->priv->dbus_connection, &error);
+
+ if (!res)
+ {
+ if (dbus_g_error_has_name (error, "org.freedesktop.ConsoleKit.Manager.NotPrivileged"))
+ {
+ request_restart_priv (manager, error);
+ }
+ else
+ {
+ emit_restart_complete (manager, error->message);
+ }
+
+ g_error_free (error);
+ }
+}
+
+void
+gsm_consolekit_attempt_stop (GsmConsolekit *manager)
+{
+ gboolean res;
+ GError *error;
+
+ error = NULL;
+
+ if (!gsm_consolekit_ensure_ck_connection (manager, &error))
+ {
+ g_warning ("Could not connect to ConsoleKit: %s",
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ res = try_system_stop (manager->priv->dbus_connection, &error);
+
+ if (!res)
+ {
+ g_warning ("Unable to stop system: %s", error->message);
+ if (dbus_g_error_has_name (error, "org.freedesktop.ConsoleKit.Manager.NotPrivileged"))
+ {
+ request_stop_priv (manager, error);
+ }
+ else
+ {
+ emit_stop_complete (manager, error);
+ }
+
+ g_error_free (error);
+ }
+}
+
+gboolean
+gsm_consolekit_can_restart (GsmConsolekit *manager)
+{
+#ifdef HAVE_POLKIT_GNOME
+ return gsm_consolekit_ensure_ck_connection (manager, NULL);
+#else
+ return FALSE;
+#endif
+}
+
+gboolean
+gsm_consolekit_can_stop (GsmConsolekit *manager)
+{
+#ifdef HAVE_POLKIT_GNOME
+ return gsm_consolekit_ensure_ck_connection (manager, NULL);
+#else
+ return FALSE;
+#endif
+}
+
+GsmConsolekit *
+gsm_get_consolekit (void)
+{
+ static GsmConsolekit *manager = NULL;
+
+ if (manager == NULL)
+ {
+ manager = gsm_consolekit_new ();
+ }
+
+ return g_object_ref (manager);
+}
Added: trunk/gnome-session/consolekit.h
==============================================================================
--- (empty file)
+++ trunk/gnome-session/consolekit.h Thu Jun 12 23:13:33 2008
@@ -0,0 +1,83 @@
+/* console-kit.h
+ * Copyright (C) 2008 Jon McCann <jmccann redhat com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Jon McCann <jmccann redhat com>
+ */
+
+#ifndef __GSM_CONSOLEKIT_H__
+#define __GSM_CONSOLEKIT_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GSM_TYPE_CONSOLEKIT (gsm_consolekit_get_type ())
+#define GSM_CONSOLEKIT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSM_TYPE_CONSOLEKIT, GsmConsolekit))
+#define GSM_CONSOLEKIT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSM_TYPE_CONSOLEKIT, GsmConsolekitClass))
+#define GSM_IS_CONSOLEKIT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSM_TYPE_CONSOLEKIT))
+#define GSM_IS_CONSOLEKIT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSM_TYPE_CONSOLEKIT))
+#define GSM_CONSOLEKIT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GSM_TYPE_CONSOLEKIT, GsmConsolekitClass))
+#define GSM_CONSOLEKIT_ERROR (gsm_consolekit_error_quark ())
+
+typedef struct _GsmConsolekit GsmConsolekit;
+typedef struct _GsmConsolekitClass GsmConsolekitClass;
+typedef struct _GsmConsolekitPrivate GsmConsolekitPrivate;
+typedef enum _GsmConsolekitError GsmConsolekitError;
+
+struct _GsmConsolekit
+{
+ GObject parent;
+
+ GsmConsolekitPrivate *priv;
+};
+
+struct _GsmConsolekitClass
+{
+ GObjectClass parent_class;
+
+ void (* request_completed) (GsmConsolekit *manager,
+ GError *error);
+};
+
+enum _GsmConsolekitError
+{
+ GSM_CONSOLEKIT_ERROR_RESTARTING = 0,
+ GSM_CONSOLEKIT_ERROR_STOPPING
+};
+
+GType gsm_consolekit_get_type (void);
+
+GQuark gsm_consolekit_error_quark (void);
+
+GsmConsolekit *gsm_consolekit_new (void) G_GNUC_MALLOC;
+
+gboolean gsm_consolekit_can_stop (GsmConsolekit *manager);
+
+gboolean gsm_consolekit_can_restart (GsmConsolekit *manager);
+
+void gsm_consolekit_attempt_stop (GsmConsolekit *manager);
+
+void gsm_consolekit_attempt_restart (GsmConsolekit *manager);
+
+GsmConsolekit *gsm_get_consolekit (void);
+
+G_END_DECLS
+
+#endif /* __GSM_CONSOLEKIT_H__ */
Modified: trunk/gnome-session/logout-dialog.c
==============================================================================
--- trunk/gnome-session/logout-dialog.c (original)
+++ trunk/gnome-session/logout-dialog.c Thu Jun 12 23:13:33 2008
@@ -17,7 +17,7 @@
* 02111-1307, USA.
*
* Authors:
- * Vincent Untz <vuntz gnome org>
+ * Vincent Untz <vuntz gnome org>
*/
#ifdef HAVE_CONFIG_H
@@ -33,6 +33,7 @@
#include "session.h"
#include "logout-dialog.h"
#include "power-manager.h"
+#include "consolekit.h"
#include "gdm.h"
#define GSM_LOGOUT_DIALOG_GET_PRIVATE(o) \
@@ -48,6 +49,7 @@
GsmSessionLogoutType type;
GsmPowerManager *power_manager;
+ GsmConsolekit *consolekit;
int timeout;
unsigned int timeout_id;
@@ -60,10 +62,10 @@
static void gsm_logout_dialog_set_timeout (GsmLogoutDialog *logout_dialog);
static void gsm_logout_dialog_destroy (GsmLogoutDialog *logout_dialog,
- gpointer data);
+ gpointer data);
static void gsm_logout_dialog_show (GsmLogoutDialog *logout_dialog,
- gpointer data);
+ gpointer data);
enum {
PROP_0,
@@ -74,9 +76,9 @@
static void
gsm_logout_dialog_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
switch (prop_id)
{
@@ -90,9 +92,9 @@
static void
gsm_logout_dialog_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
switch (prop_id)
{
@@ -121,13 +123,24 @@
gobject_class->get_property = gsm_logout_dialog_get_property;
g_object_class_override_property (gobject_class,
- PROP_MESSAGE_TYPE,
- "message-type");
+ PROP_MESSAGE_TYPE,
+ "message-type");
g_type_class_add_private (klass, sizeof (GsmLogoutDialogPrivate));
}
static void
+on_ck_request_completed (GsmConsolekit *gsm_consolekit,
+ GError *error)
+{
+ if (error == NULL)
+ {
+ /* request was successful */
+ return;
+ }
+}
+
+static void
gsm_logout_dialog_init (GsmLogoutDialog *logout_dialog)
{
logout_dialog->priv = GSM_LOGOUT_DIALOG_GET_PRIVATE (logout_dialog);
@@ -141,21 +154,28 @@
gtk_window_stick (GTK_WINDOW (logout_dialog));
logout_dialog->priv->power_manager = gsm_get_power_manager ();
+
+ logout_dialog->priv->consolekit = gsm_get_consolekit ();
+
+ g_signal_connect (logout_dialog->priv->consolekit,
+ "request-completed",
+ G_CALLBACK (on_ck_request_completed),
+ NULL);
g_signal_connect (logout_dialog,
"destroy",
- G_CALLBACK (gsm_logout_dialog_destroy),
+ G_CALLBACK (gsm_logout_dialog_destroy),
NULL);
g_signal_connect (logout_dialog,
"show",
- G_CALLBACK (gsm_logout_dialog_show),
+ G_CALLBACK (gsm_logout_dialog_show),
NULL);
}
static void
gsm_logout_dialog_destroy (GsmLogoutDialog *logout_dialog,
- gpointer data)
+ gpointer data)
{
if (logout_dialog->priv->timeout_id != 0)
{
@@ -169,9 +189,44 @@
logout_dialog->priv->power_manager = NULL;
}
+ if (logout_dialog->priv->consolekit)
+ {
+ g_object_unref (logout_dialog->priv->consolekit);
+ logout_dialog->priv->consolekit = NULL;
+ }
+
current_dialog = NULL;
}
+static gboolean
+gsm_logout_supports_reboot (GsmLogoutDialog *logout_dialog)
+{
+ gboolean ret;
+
+ ret = gsm_consolekit_can_restart (logout_dialog->priv->consolekit);
+ if (!ret)
+ {
+ ret = gdm_supports_logout_action (GDM_LOGOUT_ACTION_REBOOT);
+ }
+
+ return ret;
+}
+
+static gboolean
+gsm_logout_supports_shutdown (GsmLogoutDialog *logout_dialog)
+{
+ gboolean ret;
+
+ ret = gsm_consolekit_can_stop (logout_dialog->priv->consolekit);
+
+ if (!ret)
+ {
+ ret = gdm_supports_logout_action (GDM_LOGOUT_ACTION_SHUTDOWN);
+ }
+
+ return ret;
+}
+
static void
gsm_logout_dialog_show (GsmLogoutDialog *logout_dialog, gpointer user_data)
{
@@ -191,7 +246,7 @@
if (!logout_dialog->priv->timeout)
{
gtk_dialog_response (GTK_DIALOG (logout_dialog),
- logout_dialog->priv->default_response);
+ logout_dialog->priv->default_response);
return FALSE;
}
@@ -212,26 +267,26 @@
{
case GSM_SESSION_LOGOUT_TYPE_LOGOUT:
secondary_text = ngettext ("You are currently logged in as "
- "\"%s\".\n"
- "You will be automatically logged "
- "out in %d second.",
- "You are currently logged in as "
- "\"%s\".\n"
- "You will be automatically logged "
- "out in %d seconds.",
- seconds_to_show);
+ "\"%s\".\n"
+ "You will be automatically logged "
+ "out in %d second.",
+ "You are currently logged in as "
+ "\"%s\".\n"
+ "You will be automatically logged "
+ "out in %d seconds.",
+ seconds_to_show);
break;
case GSM_SESSION_LOGOUT_TYPE_SHUTDOWN:
secondary_text = ngettext ("You are currently logged in as "
- "\"%s\".\n"
- "This system will be automatically "
- "shut down in %d second.",
- "You are currently logged in as "
- "\"%s\".\n"
- "This system will be automatically "
- "shut down in %d seconds.",
- seconds_to_show);
+ "\"%s\".\n"
+ "This system will be automatically "
+ "shut down in %d second.",
+ "You are currently logged in as "
+ "\"%s\".\n"
+ "This system will be automatically "
+ "shut down in %d seconds.",
+ seconds_to_show);
break;
default:
@@ -244,10 +299,10 @@
name = g_get_user_name ();
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (logout_dialog),
- secondary_text,
- name,
- seconds_to_show,
- NULL);
+ secondary_text,
+ name,
+ seconds_to_show,
+ NULL);
logout_dialog->priv->timeout--;
@@ -266,14 +321,14 @@
g_source_remove (logout_dialog->priv->timeout_id);
logout_dialog->priv->timeout_id = g_timeout_add (1000,
- gsm_logout_dialog_timeout,
- logout_dialog);
+ gsm_logout_dialog_timeout,
+ logout_dialog);
}
GtkWidget *
gsm_get_logout_dialog (GsmSessionLogoutType type,
- GdkScreen *screen,
- guint32 activate_time)
+ GdkScreen *screen,
+ guint32 activate_time)
{
GsmLogoutDialog *logout_dialog;
char *icon_name;
@@ -301,21 +356,20 @@
icon_name = GSM_ICON_LOGOUT;
primary_text = N_("Log out of this system now?");
- //FIXME need to verify that this response can be used
logout_dialog->priv->default_response = GSM_LOGOUT_RESPONSE_LOGOUT;
//FIXME is gdm running?
gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
- _("_Switch User"),
- GSM_LOGOUT_RESPONSE_SWITCH_USER);
+ _("_Switch User"),
+ GSM_LOGOUT_RESPONSE_SWITCH_USER);
gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL);
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL);
gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
- _("_Log Out"),
- GSM_LOGOUT_RESPONSE_LOGOUT);
+ _("_Log Out"),
+ GSM_LOGOUT_RESPONSE_LOGOUT);
break;
case GSM_SESSION_LOGOUT_TYPE_SHUTDOWN:
@@ -325,41 +379,41 @@
logout_dialog->priv->default_response = GSM_LOGOUT_RESPONSE_SHUTDOWN;
if (gsm_power_manager_can_suspend (logout_dialog->priv->power_manager))
- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
- _("S_uspend"),
- GSM_LOGOUT_RESPONSE_STR);
+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
+ _("S_uspend"),
+ GSM_LOGOUT_RESPONSE_STR);
if (gsm_power_manager_can_hibernate (logout_dialog->priv->power_manager))
- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
- _("_Hibernate"),
- GSM_LOGOUT_RESPONSE_STD);
+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
+ _("_Hibernate"),
+ GSM_LOGOUT_RESPONSE_STD);
- if (gdm_supports_logout_action (GDM_LOGOUT_ACTION_REBOOT))
- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
- _("_Restart"),
- GSM_LOGOUT_RESPONSE_REBOOT);
+ if (gsm_logout_supports_reboot (logout_dialog))
+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
+ _("_Restart"),
+ GSM_LOGOUT_RESPONSE_REBOOT);
gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL);
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL);
- if (gdm_supports_logout_action (GDM_LOGOUT_ACTION_SHUTDOWN))
- gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
- _("_Shut Down"),
- GSM_LOGOUT_RESPONSE_SHUTDOWN);
+ if (gsm_logout_supports_shutdown (logout_dialog))
+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
+ _("_Shut Down"),
+ GSM_LOGOUT_RESPONSE_SHUTDOWN);
break;
default:
g_assert_not_reached ();
}
gtk_image_set_from_icon_name (GTK_IMAGE (GTK_MESSAGE_DIALOG (logout_dialog)->image),
- icon_name, GTK_ICON_SIZE_DIALOG);
+ icon_name, GTK_ICON_SIZE_DIALOG);
gtk_label_set_text (GTK_LABEL (GTK_MESSAGE_DIALOG (logout_dialog)->label),
- primary_text);
+ primary_text);
gtk_dialog_set_default_response (GTK_DIALOG (logout_dialog),
- logout_dialog->priv->default_response);
+ logout_dialog->priv->default_response);
gtk_window_set_screen (GTK_WINDOW (logout_dialog), screen);
Modified: trunk/gnome-session/session.c
==============================================================================
--- trunk/gnome-session/session.c (original)
+++ trunk/gnome-session/session.c Thu Jun 12 23:13:33 2008
@@ -25,6 +25,7 @@
#include "app-autostart.h"
#include "app-resumed.h"
#include "logout-dialog.h"
+#include "consolekit.h"
#include "power-manager.h"
#include "gdm.h"
#include "gconf.h"
@@ -880,8 +881,37 @@
}
static void
+do_request_reboot (GsmConsolekit *consolekit)
+{
+ if (gsm_consolekit_can_restart (consolekit))
+ {
+ gdm_set_logout_action (GDM_LOGOUT_ACTION_NONE);
+ gsm_consolekit_attempt_restart (consolekit);
+ }
+ else
+ {
+ gdm_set_logout_action (GDM_LOGOUT_ACTION_REBOOT);
+ }
+}
+
+static void
+do_request_shutdown (GsmConsolekit *consolekit)
+{
+ if (gsm_consolekit_can_stop (consolekit))
+ {
+ gdm_set_logout_action (GDM_LOGOUT_ACTION_NONE);
+ gsm_consolekit_attempt_stop (consolekit);
+ }
+ else
+ {
+ gdm_set_logout_action (GDM_LOGOUT_ACTION_SHUTDOWN);
+ }
+}
+
+static void
session_shutdown (GsmSession *session)
{
+ GsmConsolekit *consolekit;
GSList *cl;
/* Emit session over signal */
@@ -894,11 +924,19 @@
switch (session->logout_response_id)
{
case GSM_LOGOUT_RESPONSE_SHUTDOWN:
- gdm_set_logout_action (GDM_LOGOUT_ACTION_SHUTDOWN);
+ consolekit = gsm_get_consolekit ();
+
+ do_request_shutdown (consolekit);
+
+ g_object_unref (consolekit);
break;
case GSM_LOGOUT_RESPONSE_REBOOT:
- gdm_set_logout_action (GDM_LOGOUT_ACTION_REBOOT);
+ consolekit = gsm_get_consolekit ();
+
+ do_request_reboot (consolekit);
+
+ g_object_unref (consolekit);
break;
default:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]