gnome-session r4744 - in branches/dbus_based: . gnome-session
- From: mccann svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-session r4744 - in branches/dbus_based: . gnome-session
- Date: Mon, 16 Jun 2008 02:08:57 +0000 (UTC)
Author: mccann
Date: Mon Jun 16 02:08:56 2008
New Revision: 4744
URL: http://svn.gnome.org/viewvc/gnome-session?rev=4744&view=rev
Log:
2008-06-15 William Jon McCann <jmccann redhat com>
* configure.in:
* gnome-session/Makefile.am:
* gnome-session/gdm.c (gdm_init_protocol_connection),
(gdm_is_available):
* gnome-session/gdm.h:
* gnome-session/gsm-consolekit.c (gsm_consolekit_get_property),
(gsm_consolekit_class_init), (gsm_consolekit_ensure_ck_connection),
(gsm_consolekit_on_name_owner_changed), (gsm_consolekit_init),
(gsm_consolekit_finalize), (gsm_consolekit_error_quark),
(gsm_consolekit_new), (try_system_stop), (try_system_restart),
(emit_restart_complete), (emit_stop_complete),
(system_restart_auth_cb), (system_stop_auth_cb),
(get_action_from_error), (request_restart_priv),
(request_stop_priv), (gsm_consolekit_attempt_restart),
(gsm_consolekit_attempt_stop), (gsm_consolekit_can_restart),
(gsm_consolekit_can_stop), (gsm_get_consolekit):
* gnome-session/gsm-consolekit.h:
* gnome-session/gsm-manager.c (do_request_reboot),
(do_request_shutdown), (manager_shutdown):
* gnome-session/logout-dialog.c (on_ck_request_completed),
(gsm_logout_dialog_init), (gsm_logout_dialog_destroy),
(gsm_logout_supports_reboot), (gsm_logout_supports_shutdown),
(gsm_get_logout_dialog):
Add CK shutdown support. Merged from trunk.
Added:
branches/dbus_based/gnome-session/gsm-consolekit.c
branches/dbus_based/gnome-session/gsm-consolekit.h
Modified:
branches/dbus_based/ChangeLog
branches/dbus_based/configure.in
branches/dbus_based/gnome-session/Makefile.am
branches/dbus_based/gnome-session/gdm.c
branches/dbus_based/gnome-session/gdm.h
branches/dbus_based/gnome-session/gsm-manager.c
branches/dbus_based/gnome-session/logout-dialog.c
Modified: branches/dbus_based/configure.in
==============================================================================
--- branches/dbus_based/configure.in (original)
+++ branches/dbus_based/configure.in Mon Jun 16 02:08:56 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: branches/dbus_based/gnome-session/Makefile.am
==============================================================================
--- branches/dbus_based/gnome-session/Makefile.am (original)
+++ branches/dbus_based/gnome-session/Makefile.am Mon Jun 16 02:08:56 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 = \
gsm-autostart-app.h \
@@ -36,6 +38,8 @@
gsm-client.h \
gsm-marshal.h \
gsm-marshal.c \
+ gsm-consolekit.c \
+ gsm-consolekit.h \
gconf.c \
gconf.h \
gdm.h \
Modified: branches/dbus_based/gnome-session/gdm.c
==============================================================================
--- branches/dbus_based/gnome-session/gdm.c (original)
+++ branches/dbus_based/gnome-session/gdm.c Mon Jun 16 02:08:56 2008
@@ -250,6 +250,13 @@
g_assert (data->fd <= 0);
+ if (g_file_test (GDM_PROTOCOL_SOCKET_PATH, G_FILE_TEST_EXISTS))
+ strcpy (addr.sun_path, GDM_PROTOCOL_SOCKET_PATH);
+ else if (g_file_test ("/tmp/.gdm_socket", G_FILE_TEST_EXISTS))
+ strcpy (addr.sun_path, "/tmp/.gdm_socket");
+ else
+ return FALSE;
+
data->fd = socket (AF_UNIX, SOCK_STREAM, 0);
if (data->fd < 0)
@@ -262,11 +269,6 @@
return FALSE;
}
- if (g_file_test (GDM_PROTOCOL_SOCKET_PATH, G_FILE_TEST_EXISTS))
- strcpy (addr.sun_path, GDM_PROTOCOL_SOCKET_PATH);
- else
- strcpy (addr.sun_path, "/tmp/.gdm_socket");
-
addr.sun_family = AF_UNIX;
if (connect (data->fd, (struct sockaddr *) &addr, sizeof (addr)) < 0)
@@ -380,6 +382,17 @@
}
gboolean
+gdm_is_available (void)
+{
+ if (!gdm_init_protocol_connection (&gdm_protocol_data))
+ return FALSE;
+
+ gdm_shutdown_protocol_connection (&gdm_protocol_data);
+
+ return TRUE;
+}
+
+gboolean
gdm_supports_logout_action (GdmLogoutAction action)
{
gdm_update_logout_actions (&gdm_protocol_data);
Modified: branches/dbus_based/gnome-session/gdm.h
==============================================================================
--- branches/dbus_based/gnome-session/gdm.h (original)
+++ branches/dbus_based/gnome-session/gdm.h Mon Jun 16 02:08:56 2008
@@ -39,6 +39,8 @@
GDM_LOGOUT_ACTION_SUSPEND = 1 << 2
} GdmLogoutAction;
+gboolean gdm_is_available (void);
+
void gdm_new_login (void);
void gdm_set_logout_action (GdmLogoutAction action);
Added: branches/dbus_based/gnome-session/gsm-consolekit.c
==============================================================================
--- (empty file)
+++ branches/dbus_based/gnome-session/gsm-consolekit.c Mon Jun 16 02:08:56 2008
@@ -0,0 +1,653 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * 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 "gsm-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: branches/dbus_based/gnome-session/gsm-consolekit.h
==============================================================================
--- (empty file)
+++ branches/dbus_based/gnome-session/gsm-consolekit.h Mon Jun 16 02:08:56 2008
@@ -0,0 +1,83 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * 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: branches/dbus_based/gnome-session/gsm-manager.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-manager.c (original)
+++ branches/dbus_based/gnome-session/gsm-manager.c Mon Jun 16 02:08:56 2008
@@ -49,6 +49,7 @@
#include "util.h"
#include "gdm.h"
#include "logout-dialog.h"
+#include "gsm-consolekit.h"
#include "power-manager.h"
#define GSM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_MANAGER, GsmManagerPrivate))
@@ -1184,6 +1185,28 @@
return TRUE;
}
+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 gboolean
_stop_client (const char *id,
GsmClient *client,
@@ -1197,6 +1220,8 @@
static void
manager_shutdown (GsmManager *manager)
{
+ GsmConsolekit *consolekit;
+
/* Emit session over signal */
g_signal_emit (manager, signals[SESSION_OVER], 0);
@@ -1207,10 +1232,14 @@
switch (manager->priv->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:
gtk_main_quit ();
Modified: branches/dbus_based/gnome-session/logout-dialog.c
==============================================================================
--- branches/dbus_based/gnome-session/logout-dialog.c (original)
+++ branches/dbus_based/gnome-session/logout-dialog.c Mon Jun 16 02:08:56 2008
@@ -31,6 +31,7 @@
#include "logout-dialog.h"
#include "power-manager.h"
+#include "gsm-consolekit.h"
#include "gdm.h"
#define GSM_LOGOUT_DIALOG_GET_PRIVATE(o) \
@@ -46,6 +47,7 @@
GsmDialogLogoutType type;
GsmPowerManager *power_manager;
+ GsmConsolekit *consolekit;
int timeout;
unsigned int timeout_id;
@@ -126,6 +128,17 @@
}
static void
+on_ck_request_completed (GsmConsolekit *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);
@@ -139,7 +152,14 @@
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),
@@ -167,9 +187,45 @@
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)
{
@@ -274,8 +330,8 @@
guint32 activate_time)
{
GsmLogoutDialog *logout_dialog;
- char *icon_name;
- char *primary_text;
+ const char *primary_text;
+ const char *icon_name;
if (current_dialog != NULL)
{
@@ -297,15 +353,15 @@
{
case GSM_DIALOG_LOGOUT_TYPE_LOGOUT:
icon_name = GSM_ICON_LOGOUT;
- primary_text = N_("Log out of this system now?");
+ primary_text = _("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);
+
+ if (gdm_is_available ()) {
+ gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
+ _("_Switch User"),
+ GSM_LOGOUT_RESPONSE_SWITCH_USER);
+ }
gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
GTK_STOCK_CANCEL,
@@ -318,7 +374,7 @@
break;
case GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN:
icon_name = GSM_ICON_SHUTDOWN;
- primary_text = N_("Shut down this system now?");
+ primary_text = _("Shut down this system now?");
logout_dialog->priv->default_response = GSM_LOGOUT_RESPONSE_SHUTDOWN;
@@ -332,7 +388,7 @@
_("_Hibernate"),
GSM_LOGOUT_RESPONSE_STD);
- if (gdm_supports_logout_action (GDM_LOGOUT_ACTION_REBOOT))
+ if (gsm_logout_supports_reboot (logout_dialog))
gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
_("_Restart"),
GSM_LOGOUT_RESPONSE_REBOOT);
@@ -341,7 +397,7 @@
GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL);
- if (gdm_supports_logout_action (GDM_LOGOUT_ACTION_SHUTDOWN))
+ if (gsm_logout_supports_shutdown (logout_dialog))
gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
_("_Shut Down"),
GSM_LOGOUT_RESPONSE_SHUTDOWN);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]