diff -up gnome-session-2.24.0/gnome-session/gsm-consolekit.c.add-can-shutdown-api gnome-session-2.24.0/gnome-session/gsm-consolekit.c --- gnome-session-2.24.0/gnome-session/gsm-consolekit.c.add-can-shutdown-api 2008-09-22 17:21:08.000000000 -0400 +++ gnome-session-2.24.0/gnome-session/gsm-consolekit.c 2008-10-10 16:39:55.000000000 -0400 @@ -54,6 +54,9 @@ struct _GsmConsolekitPrivate DBusGConnection *dbus_connection; DBusGProxy *bus_proxy; DBusGProxy *ck_proxy; +#ifdef HAVE_POLKIT_GNOME + PolKitSession *pk_session; +#endif guint32 is_connected : 1; }; @@ -140,11 +143,14 @@ static gboolean gsm_consolekit_ensure_ck_connection (GsmConsolekit *manager, GError **error) { + DBusConnection *connection; GError *connection_error; gboolean is_connected; + const char *cookie; connection_error = NULL; + connection = NULL; if (manager->priv->dbus_connection == NULL) { manager->priv->dbus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &connection_error); @@ -154,6 +160,8 @@ gsm_consolekit_ensure_ck_connection (Gsm is_connected = FALSE; goto out; } + + connection = dbus_g_connection_get_connection (manager->priv->dbus_connection); } if (manager->priv->bus_proxy == NULL) { @@ -198,6 +206,17 @@ gsm_consolekit_ensure_ck_connection (Gsm } } +#ifdef HAVE_POLKIT_GNOME + cookie = g_getenv ("XDG_SESSION_COOKIE"); + if (manager->priv->pk_session == NULL && connection != NULL && cookie != NULL) { + DBusError error; + + dbus_error_init (&error); + manager->priv->pk_session = polkit_session_new_from_cookie (connection, cookie, &error); + dbus_error_free (&error); + } +#endif + is_connected = TRUE; out: @@ -825,20 +844,62 @@ gsm_consolekit_can_switch_user (GsmConso return ret; } +#ifdef HAVE_POLKIT_GNOME +static gboolean +gsm_consolekit_can_do_action (GsmConsolekit *manager, + const char *action_id) +{ + PolKitGnomeContext *gnome_context; + PolKitPolicyCache *policy_cache; + PolKitPolicyFileEntry *file_entry; + PolKitPolicyDefault *policy; + PolKitAction *action; + PolKitResult result; + + gnome_context = polkit_gnome_context_get (NULL); + + if (gnome_context == NULL) { + return FALSE; + } + + policy_cache = polkit_context_get_policy_cache (gnome_context->pk_context); + file_entry = polkit_policy_cache_get_entry_by_id (policy_cache, action_id); + policy = polkit_policy_file_entry_get_default (file_entry); + action = polkit_action_new (); + if (!polkit_action_set_action_id (action, action_id)) { + polkit_action_unref (action); + return FALSE; + } + + result = POLKIT_RESULT_UNKNOWN; + if (manager->priv->pk_session != NULL) { + result = polkit_policy_default_can_session_do_action (policy, + action, + manager->priv->pk_session); + } + + return result != POLKIT_RESULT_NO && result != POLKIT_RESULT_UNKNOWN; +} +#endif + gboolean gsm_consolekit_can_restart (GsmConsolekit *manager) { #ifdef HAVE_POLKIT_GNOME gboolean res; GError *error; + error = NULL; res = gsm_consolekit_ensure_ck_connection (manager, &error); if (!res) { g_warning ("Could not connect to ConsoleKit: %s", error->message); g_error_free (error); + return FALSE; } - return res; + + return gsm_consolekit_can_do_action (manager, "org.freedesktop.consolekit.system.restart") || + gsm_consolekit_can_do_action (manager, "org.freedesktop.consolekit.system.restart-multiple-users"); #else g_debug ("GsmConsolekit: built without PolicyKit-gnome support - cannot restart system"); return FALSE; @@ -857,8 +918,11 @@ gsm_consolekit_can_stop (GsmConsolekit * g_warning ("Could not connect to ConsoleKit: %s", error->message); g_error_free (error); + return FALSE; } - return res; + + return gsm_consolekit_can_do_action (manager, "org.freedesktop.consolekit.system.stop") || + gsm_consolekit_can_do_action (manager, "org.freedesktop.consolekit.system.stop-multiple-users"); #else g_debug ("GsmConsolekit: built without PolicyKit-gnome support - cannot stop system"); return FALSE; diff -up gnome-session-2.24.0/gnome-session/gsm-manager.c.add-can-shutdown-api gnome-session-2.24.0/gnome-session/gsm-manager.c --- gnome-session-2.24.0/gnome-session/gsm-manager.c.add-can-shutdown-api 2008-09-22 17:21:08.000000000 -0400 +++ gnome-session-2.24.0/gnome-session/gsm-manager.c 2008-10-10 16:16:17.000000000 -0400 @@ -2313,6 +2313,35 @@ gsm_manager_shutdown (GsmManager *manage } gboolean +gsm_manager_can_shutdown (GsmManager *manager, + gboolean *shutdown_available, + GError **error) +{ + GsmConsolekit *consolekit; + GsmPowerManager *power_manager; + + g_debug ("GsmManager: CanShutdown called"); + + g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE); + + if (manager->priv->phase != GSM_MANAGER_PHASE_RUNNING) { + *shutdown_available = FALSE; + return TRUE; + } + + consolekit = gsm_get_consolekit (); + power_manager = gsm_get_power_manager (); + *shutdown_available = gsm_consolekit_can_stop (consolekit) + || gsm_consolekit_can_restart (consolekit) + || gsm_power_manager_can_suspend (power_manager) + || gsm_power_manager_can_hibernate (power_manager); + g_object_unref (consolekit); + g_object_unref (power_manager); + + return TRUE; +} + +gboolean gsm_manager_logout (GsmManager *manager, guint logout_mode, GError **error) diff -up gnome-session-2.24.0/gnome-session/gsm-manager.h.add-can-shutdown-api gnome-session-2.24.0/gnome-session/gsm-manager.h --- gnome-session-2.24.0/gnome-session/gsm-manager.h.add-can-shutdown-api 2008-09-22 17:21:08.000000000 -0400 +++ gnome-session-2.24.0/gnome-session/gsm-manager.h 2008-10-10 16:16:17.000000000 -0400 @@ -151,6 +151,10 @@ gboolean gsm_manager_is_inhib gboolean gsm_manager_shutdown (GsmManager *manager, GError **error); + +gboolean gsm_manager_can_shutdown (GsmManager *manager, + gboolean *shutdown_available, + GError **error); gboolean gsm_manager_logout (GsmManager *manager, guint logout_mode, GError **error); diff -up gnome-session-2.24.0/gnome-session/org.gnome.SessionManager.xml.add-can-shutdown-api gnome-session-2.24.0/gnome-session/org.gnome.SessionManager.xml --- gnome-session-2.24.0/gnome-session/org.gnome.SessionManager.xml.add-can-shutdown-api 2008-09-22 17:21:08.000000000 -0400 +++ gnome-session-2.24.0/gnome-session/org.gnome.SessionManager.xml 2008-10-10 16:16:17.000000000 -0400 @@ -252,6 +252,20 @@ + + + + True if shutdown is available to the user, false otherwise + + + + + Allows the caller to determine whether or not it's okay to show + a shutdown option in the UI + + + +