gnome-session r4744 - in branches/dbus_based: . gnome-session



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]