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



Author: mccann
Date: Wed Jun 25 19:15:56 2008
New Revision: 4781
URL: http://svn.gnome.org/viewvc/gnome-session?rev=4781&view=rev

Log:
2008-06-25  William Jon McCann  <jmccann redhat com>

	* gnome-session/gsm-consolekit.c (get_current_session_id),
	(get_seat_id_for_session), (get_current_seat_id),
	(seat_can_activate_sessions), (gsm_consolekit_can_switch_user):
	* gnome-session/gsm-consolekit.h:
	* gnome-session/gsm-logout-dialog.c
	(gsm_logout_supports_system_suspend),
	(gsm_logout_supports_system_hibernate),
	(gsm_logout_supports_switch_user), (gsm_get_dialog):
	* gnome-session/gsm-logout-inhibit-dialog.c
	(gsm_logout_inhibit_dialog_class_init):
	* gnome-session/gsm-manager.c
	(gsm_manager_is_switch_user_inhibited), (manager_switch_user),
	(do_action), (request_switch_user), (logout_dialog_response):
	Make switch user work.



Modified:
   branches/dbus_based/ChangeLog
   branches/dbus_based/gnome-session/gsm-consolekit.c
   branches/dbus_based/gnome-session/gsm-consolekit.h
   branches/dbus_based/gnome-session/gsm-logout-dialog.c
   branches/dbus_based/gnome-session/gsm-logout-inhibit-dialog.c
   branches/dbus_based/gnome-session/gsm-manager.c

Modified: branches/dbus_based/gnome-session/gsm-consolekit.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-consolekit.c	(original)
+++ branches/dbus_based/gnome-session/gsm-consolekit.c	Wed Jun 25 19:15:56 2008
@@ -31,6 +31,7 @@
 #include <glib/gi18n.h>
 
 #include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
 
 #ifdef HAVE_POLKIT_GNOME
 #include <polkit-gnome/polkit-gnome.h>
@@ -630,6 +631,202 @@
         }
 }
 
+static gboolean
+get_current_session_id (DBusConnection *connection,
+                        char          **session_id)
+{
+        DBusError       local_error;
+        DBusMessage    *message;
+        DBusMessage    *reply;
+        gboolean        ret;
+        DBusMessageIter iter;
+        const char     *value;
+
+        ret = FALSE;
+        reply = NULL;
+
+        dbus_error_init (&local_error);
+        message = dbus_message_new_method_call (CK_NAME,
+                                                CK_MANAGER_PATH,
+                                                CK_MANAGER_INTERFACE,
+                                                "GetCurrentSession");
+        if (message == NULL) {
+                goto out;
+        }
+
+        dbus_error_init (&local_error);
+        reply = dbus_connection_send_with_reply_and_block (connection,
+                                                           message,
+                                                           -1,
+                                                           &local_error);
+        if (reply == NULL) {
+                if (dbus_error_is_set (&local_error)) {
+                        g_warning ("Unable to determine session: %s", local_error.message);
+                        dbus_error_free (&local_error);
+                        goto out;
+                }
+        }
+
+        dbus_message_iter_init (reply, &iter);
+        dbus_message_iter_get_basic (&iter, &value);
+        if (session_id != NULL) {
+                *session_id = g_strdup (value);
+        }
+
+        ret = TRUE;
+ out:
+        if (message != NULL) {
+                dbus_message_unref (message);
+        }
+        if (reply != NULL) {
+                dbus_message_unref (reply);
+        }
+
+        return ret;
+}
+
+static gboolean
+get_seat_id_for_session (DBusConnection *connection,
+                         const char     *session_id,
+                         char          **seat_id)
+{
+        DBusError       local_error;
+        DBusMessage    *message;
+        DBusMessage    *reply;
+        gboolean        ret;
+        DBusMessageIter iter;
+        const char     *value;
+
+        ret = FALSE;
+        reply = NULL;
+
+        dbus_error_init (&local_error);
+        message = dbus_message_new_method_call (CK_NAME,
+                                                session_id,
+                                                CK_SESSION_INTERFACE,
+                                                "GetSeatId");
+        if (message == NULL) {
+                goto out;
+        }
+
+        dbus_error_init (&local_error);
+        reply = dbus_connection_send_with_reply_and_block (connection,
+                                                           message,
+                                                           -1,
+                                                           &local_error);
+        if (reply == NULL) {
+                if (dbus_error_is_set (&local_error)) {
+                        g_warning ("Unable to determine seat: %s", local_error.message);
+                        dbus_error_free (&local_error);
+                        goto out;
+                }
+        }
+
+        dbus_message_iter_init (reply, &iter);
+        dbus_message_iter_get_basic (&iter, &value);
+        if (seat_id != NULL) {
+                *seat_id = g_strdup (value);
+        }
+
+        ret = TRUE;
+ out:
+        if (message != NULL) {
+                dbus_message_unref (message);
+        }
+        if (reply != NULL) {
+                dbus_message_unref (reply);
+        }
+
+        return ret;
+}
+
+static char *
+get_current_seat_id (DBusConnection *connection)
+{
+        gboolean res;
+        char    *session_id;
+        char    *seat_id;
+
+        session_id = NULL;
+        seat_id = NULL;
+
+        res = get_current_session_id (connection, &session_id);
+        if (res) {
+                res = get_seat_id_for_session (connection, session_id, &seat_id);
+        }
+        g_free (session_id);
+
+        return seat_id;
+}
+
+static gboolean
+seat_can_activate_sessions (DBusConnection *connection,
+                            const char     *seat_id)
+{
+        DBusError       local_error;
+        DBusMessage    *message;
+        DBusMessage    *reply;
+        DBusMessageIter iter;
+        gboolean        can_activate;
+
+        can_activate = FALSE;
+        reply = NULL;
+
+        dbus_error_init (&local_error);
+        message = dbus_message_new_method_call (CK_NAME,
+                                                seat_id,
+                                                CK_SEAT_INTERFACE,
+                                                "CanActivateSessions");
+        if (message == NULL) {
+                goto out;
+        }
+
+        dbus_error_init (&local_error);
+        reply = dbus_connection_send_with_reply_and_block (connection,
+                                                           message,
+                                                           -1,
+                                                           &local_error);
+        if (reply == NULL) {
+                if (dbus_error_is_set (&local_error)) {
+                        g_warning ("Unable to activate session: %s", local_error.message);
+                        dbus_error_free (&local_error);
+                        goto out;
+                }
+        }
+
+        dbus_message_iter_init (reply, &iter);
+        dbus_message_iter_get_basic (&iter, &can_activate);
+
+ out:
+        if (message != NULL) {
+                dbus_message_unref (message);
+        }
+        if (reply != NULL) {
+                dbus_message_unref (reply);
+        }
+
+        return can_activate;
+}
+
+gboolean
+gsm_consolekit_can_switch_user (GsmConsolekit *manager)
+{
+        char    *seat_id;
+        gboolean ret;
+
+        seat_id = get_current_seat_id (dbus_g_connection_get_connection (manager->priv->dbus_connection));
+        if (seat_id == NULL || seat_id[0] == '\0') {
+                g_debug ("seat id is not set; can't switch sessions");
+                return FALSE;
+        }
+
+        ret = seat_can_activate_sessions (dbus_g_connection_get_connection (manager->priv->dbus_connection),
+                                          seat_id);
+        g_free (seat_id);
+
+        return ret;
+}
+
 gboolean
 gsm_consolekit_can_restart (GsmConsolekit *manager)
 {

Modified: branches/dbus_based/gnome-session/gsm-consolekit.h
==============================================================================
--- branches/dbus_based/gnome-session/gsm-consolekit.h	(original)
+++ branches/dbus_based/gnome-session/gsm-consolekit.h	Wed Jun 25 19:15:56 2008
@@ -68,6 +68,8 @@
 
 GsmConsolekit   *gsm_consolekit_new             (void) G_GNUC_MALLOC;
 
+gboolean         gsm_consolekit_can_switch_user (GsmConsolekit *manager);
+
 gboolean         gsm_consolekit_can_stop        (GsmConsolekit *manager);
 
 gboolean         gsm_consolekit_can_restart     (GsmConsolekit *manager);

Modified: branches/dbus_based/gnome-session/gsm-logout-dialog.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-logout-dialog.c	(original)
+++ branches/dbus_based/gnome-session/gsm-logout-dialog.c	Wed Jun 25 19:15:56 2008
@@ -195,6 +195,31 @@
         current_dialog = NULL;
 }
 
+static gboolean
+gsm_logout_supports_system_suspend (GsmLogoutDialog *logout_dialog)
+{
+        gboolean ret;
+        ret = gsm_power_manager_can_suspend (logout_dialog->priv->power_manager);
+        return ret;
+}
+
+static gboolean
+gsm_logout_supports_system_hibernate (GsmLogoutDialog *logout_dialog)
+{
+        gboolean ret;
+        ret = gsm_power_manager_can_hibernate (logout_dialog->priv->power_manager);
+        return ret;
+}
+
+static gboolean
+gsm_logout_supports_switch_user (GsmLogoutDialog *logout_dialog)
+{
+        gboolean ret;
+
+        ret = gsm_consolekit_can_switch_user (logout_dialog->priv->consolekit);
+
+        return ret;
+}
 
 static gboolean
 gsm_logout_supports_reboot (GsmLogoutDialog *logout_dialog)
@@ -349,7 +374,7 @@
 
                 logout_dialog->priv->default_response = GSM_LOGOUT_RESPONSE_LOGOUT;
 
-                if (gdm_is_available ()) {
+                if (gsm_logout_supports_switch_user (logout_dialog)) {
                         gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
                                                _("_Switch User"),
                                                GSM_LOGOUT_RESPONSE_SWITCH_USER);
@@ -370,13 +395,13 @@
 
                 logout_dialog->priv->default_response = GSM_LOGOUT_RESPONSE_SHUTDOWN;
 
-                if (gsm_power_manager_can_suspend (logout_dialog->priv->power_manager)) {
+                if (gsm_logout_supports_system_suspend (logout_dialog)) {
                         gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
                                                _("S_uspend"),
                                                GSM_LOGOUT_RESPONSE_SLEEP);
                 }
 
-                if (gsm_power_manager_can_hibernate (logout_dialog->priv->power_manager)) {
+                if (gsm_logout_supports_system_hibernate (logout_dialog)) {
                         gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
                                                _("_Hibernate"),
                                                GSM_LOGOUT_RESPONSE_HIBERNATE);

Modified: branches/dbus_based/gnome-session/gsm-logout-inhibit-dialog.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-logout-inhibit-dialog.c	(original)
+++ branches/dbus_based/gnome-session/gsm-logout-inhibit-dialog.c	Wed Jun 25 19:15:56 2008
@@ -577,7 +577,7 @@
                                                            -1,
                                                            G_MAXINT,
                                                            -1,
-                                                           G_PARAM_READWRITE));
+                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
         g_object_class_install_property (object_class,
                                          PROP_INHIBITOR_STORE,
                                          g_param_spec_object ("inhibitor-store",

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	Wed Jun 25 19:15:56 2008
@@ -72,6 +72,9 @@
 #define GSM_GCONF_DEFAULT_SESSION_KEY           "/desktop/gnome/session/default-session"
 #define GSM_GCONF_REQUIRED_COMPONENTS_DIRECTORY "/desktop/gnome/session/required-components"
 
+#define GDM_FLEXISERVER_COMMAND "gdmflexiserver"
+#define GDM_FLEXISERVER_ARGS    "--startnew Standard"
+
 struct GsmManagerPrivate
 {
         gboolean                failsafe;
@@ -1447,6 +1450,21 @@
 }
 
 static gboolean
+gsm_manager_is_switch_user_inhibited (GsmManager *manager)
+{
+        if (manager->priv->inhibitors == NULL) {
+                return FALSE;
+        }
+
+        /* FIXME: need to check ALLOW_SWITCH flags */
+        if (gsm_inhibitor_store_size (manager->priv->inhibitors) == 0) {
+                return FALSE;
+        }
+        return TRUE;
+}
+
+
+static gboolean
 gsm_manager_is_logout_inhibited (GsmManager *manager)
 {
         if (manager->priv->inhibitors == NULL) {
@@ -1459,12 +1477,36 @@
 }
 
 static void
+manager_switch_user (GsmManager *manager)
+{
+        GError  *error;
+        gboolean res;
+        char    *command;
+
+        command = g_strdup_printf ("%s %s",
+                                   GDM_FLEXISERVER_COMMAND,
+                                   GDM_FLEXISERVER_ARGS);
+
+        error = NULL;
+        res = gdk_spawn_command_line_on_screen (gdk_screen_get_default (),
+                                                command,
+                                                &error);
+
+        g_free (command);
+
+        if (! res) {
+                g_debug ("GsmManager: Unable to start GDM greeter: %s", error->message);
+                g_error_free (error);
+        }
+}
+
+static void
 do_action (GsmManager *manager,
            int         action)
 {
         switch (action) {
         case GSM_LOGOUT_ACTION_SWITCH_USER:
-                gdm_new_login ();
+                manager_switch_user (manager);
                 break;
         case GSM_LOGOUT_ACTION_HIBERNATE:
                 manager_request_hibernate (manager);
@@ -1545,6 +1587,32 @@
 }
 
 static void
+request_switch_user (GsmManager *manager)
+{
+        g_debug ("GsmManager: requesting user switch");
+
+        if (! gsm_manager_is_switch_user_inhibited (manager)) {
+                manager_switch_user (manager);
+                return;
+        }
+
+        if (manager->priv->inhibit_dialog != NULL) {
+                g_debug ("GsmManager: inhibit dialog already up");
+                gtk_window_present (GTK_WINDOW (manager->priv->inhibit_dialog));
+                return;
+        }
+
+        manager->priv->inhibit_dialog = gsm_logout_inhibit_dialog_new (manager->priv->inhibitors,
+                                                                       GSM_LOGOUT_ACTION_SWITCH_USER);
+
+        g_signal_connect (manager->priv->inhibit_dialog,
+                          "response",
+                          G_CALLBACK (logout_inhibit_dialog_response),
+                          manager);
+        gtk_widget_show (manager->priv->inhibit_dialog);
+}
+
+static void
 logout_dialog_response (GsmLogoutDialog *logout_dialog,
                         guint            response_id,
                         GsmManager      *manager)
@@ -1562,7 +1630,7 @@
         case GTK_RESPONSE_DELETE_EVENT:
                 break;
         case GSM_LOGOUT_RESPONSE_SWITCH_USER:
-                gdm_new_login ();
+                request_switch_user (manager);
                 break;
         case GSM_LOGOUT_RESPONSE_HIBERNATE:
                 manager_request_hibernate (manager);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]