Blob Blame History Raw
diff -up gdm-2.28.1/gui/simple-greeter/gdm-greeter-login-window.c.move-shutdown-functions gdm-2.28.1/gui/simple-greeter/gdm-greeter-login-window.c
--- gdm-2.28.1/gui/simple-greeter/gdm-greeter-login-window.c.move-shutdown-functions	2009-10-20 18:10:14.222638248 -0400
+++ gdm-2.28.1/gui/simple-greeter/gdm-greeter-login-window.c	2009-10-20 18:16:01.124636507 -0400
@@ -37,11 +37,6 @@
 #include <errno.h>
 #include <pwd.h>
 
-#ifdef ENABLE_RBAC_SHUTDOWN
-#include <auth_attr.h>
-#include <secdb.h>
-#endif
-
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
@@ -59,10 +54,6 @@
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
 
-#ifdef HAVE_DEVICEKIT_POWER
-#include <devkit-power-gobject/devicekit-power.h>
-#endif
-
 #include "gdm-marshal.h"
 
 #include "gdm-settings-client.h"
@@ -97,7 +88,6 @@
 #define KEY_BANNER_MESSAGE_TEXT     KEY_GREETER_DIR "/banner_message_text"
 #define KEY_BANNER_MESSAGE_TEXT_NOCHOOSER     KEY_GREETER_DIR "/banner_message_text_nochooser"
 #define KEY_LOGO                    KEY_GREETER_DIR "/logo_icon_name"
-#define KEY_DISABLE_RESTART_BUTTONS KEY_GREETER_DIR "/disable_restart_buttons"
 #define GDM_GREETER_LOGIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER_LOGIN_WINDOW, GdmGreeterLoginWindowPrivate))
 
 enum {
@@ -134,8 +124,6 @@ struct GdmGreeterLoginWindowPrivate
         char            *timed_login_username;
         guint            timed_login_timeout_id;
 
-        guint            sensitize_power_buttons_timeout_id;
-
         guint            login_button_handler_id;
         guint            start_session_handler_id;
 };
@@ -378,37 +366,6 @@ sensitize_widget (GdmGreeterLoginWindow 
         }
 }
 
-static gboolean
-get_show_restart_buttons (GdmGreeterLoginWindow *login_window)
-{
-        gboolean     show;
-        GError      *error;
-
-        error = NULL;
-        show = ! gconf_client_get_bool (login_window->priv->client, KEY_DISABLE_RESTART_BUTTONS, &error);
-        if (error != NULL) {
-                g_debug ("GdmGreeterLoginWindow: unable to get disable-restart-buttons configuration: %s", error->message);
-                g_error_free (error);
-        }
-
-#ifdef ENABLE_RBAC_SHUTDOWN
-        {
-                char *username;
-
-                username = g_get_user_name ();
-                if (username == NULL || !chkauthattr (RBAC_SHUTDOWN_KEY, username)) {
-                        show = FALSE;
-                        g_debug ("GdmGreeterLoginWindow: Not showing stop/restart buttons for user %s due to RBAC key %s",
-                                 username, RBAC_SHUTDOWN_KEY);
-                } else {
-                        g_debug ("GdmGreeterLoginWindow: Showing stop/restart buttons for user %s due to RBAC key %s",
-                                 username, RBAC_SHUTDOWN_KEY);
-                }
-        }
-#endif
-        return show;
-}
-
 static void
 on_login_button_clicked_timed_login (GtkButton             *button,
                                      GdmGreeterLoginWindow *login_window)
@@ -562,61 +519,6 @@ adjust_other_login_visibility(GdmGreeter
         }
 }
 
-#ifdef HAVE_DEVICEKIT_POWER
-static gboolean
-can_suspend (GdmGreeterLoginWindow *login_window)
-{
-        gboolean ret;
-        DkpClient *dkp_client;
-
-        /* use DeviceKit-power to get data */
-        dkp_client = dkp_client_new ();
-        g_object_get (dkp_client,
-                      "can-suspend", &ret,
-                      NULL);
-        g_object_unref (dkp_client);
-        return ret;
-}
-#endif
-
-static void
-remove_sensitize_power_buttons_timeout (GdmGreeterLoginWindow *login_window)
-{
-        if (login_window->priv->sensitize_power_buttons_timeout_id > 0) {
-                g_source_remove (login_window->priv->sensitize_power_buttons_timeout_id);
-                login_window->priv->sensitize_power_buttons_timeout_id = 0;
-        }
-}
-
-static gboolean
-sensitize_power_buttons_timeout (GdmGreeterLoginWindow *login_window)
-{
-        switch (login_window->priv->dialog_mode) {
-        case MODE_SELECTION:
-                sensitize_widget (login_window, "shutdown-button", TRUE);
-                sensitize_widget (login_window, "restart-button", TRUE);
-                sensitize_widget (login_window, "suspend-button", TRUE);
-                sensitize_widget (login_window, "disconnect-button", TRUE);
-                break;
-        case MODE_AUTHENTICATION:
-                break;
-        default:
-                g_assert_not_reached ();
-        }
-
-        login_window->priv->sensitize_power_buttons_timeout_id = 0;
-        return FALSE;
-}
-
-static void
-add_sensitize_power_buttons_timeout (GdmGreeterLoginWindow *login_window)
-{
-        remove_sensitize_power_buttons_timeout (login_window);
-        login_window->priv->sensitize_power_buttons_timeout_id = g_timeout_add_seconds (1,
-                                                                                   (GSourceFunc)sensitize_power_buttons_timeout,
-                                                                                   login_window);
-}
-
 static void
 switch_mode (GdmGreeterLoginWindow *login_window,
              int                    number)
@@ -624,17 +526,7 @@ switch_mode (GdmGreeterLoginWindow *logi
         const char *default_name;
         GtkWidget  *user_chooser;
         GtkWidget  *box;
-        gboolean    show_restart_buttons;
-        gboolean    show_suspend_button;
         int         number_of_tasks;
-
-        show_restart_buttons = get_show_restart_buttons (login_window);
-
-#ifdef HAVE_DEVICEKIT_POWER
-        show_suspend_button = can_suspend (login_window);
-#else
-        show_suspend_button = FALSE;
-#endif
 
         /* we want to run this even if we're supposed to
            be in the mode already so that we reset everything
@@ -643,30 +534,15 @@ switch_mode (GdmGreeterLoginWindow *logi
 
         default_name = NULL;
 
-        remove_sensitize_power_buttons_timeout (login_window);
-
         switch (number) {
         case MODE_SELECTION:
                 set_log_in_button_mode (login_window, LOGIN_BUTTON_HIDDEN);
 
                 show_widget (login_window, "cancel-button", FALSE);
 
-                show_widget (login_window, "shutdown-button",
-                             login_window->priv->display_is_local && show_restart_buttons);
-                show_widget (login_window, "restart-button",
-                             login_window->priv->display_is_local && show_restart_buttons);
-                show_widget (login_window, "suspend-button",
-                             login_window->priv->display_is_local && show_restart_buttons && show_suspend_button);
-                show_widget (login_window, "disconnect-button",
-                             ! login_window->priv->display_is_local);
-
                 show_widget (login_window, "auth-page-box", FALSE);
                 show_widget (login_window, "conversation-list", FALSE);
 
-                add_sensitize_power_buttons_timeout (login_window);
-                sensitize_widget (login_window, "shutdown-button", FALSE);
-                sensitize_widget (login_window, "restart-button", FALSE);
-                sensitize_widget (login_window, "suspend-button", FALSE);
                 sensitize_widget (login_window, "disconnect-button", FALSE);
 
                 default_name = NULL;
@@ -676,9 +552,6 @@ switch_mode (GdmGreeterLoginWindow *logi
                                              GTK_WIDGET (login_window)->allocation.width,
                                              -1);
                 show_widget (login_window, "cancel-button", TRUE);
-                show_widget (login_window, "shutdown-button", FALSE);
-                show_widget (login_window, "restart-button", FALSE);
-                show_widget (login_window, "suspend-button", FALSE);
                 show_widget (login_window, "disconnect-button", FALSE);
                 show_widget (login_window, "auth-page-box", TRUE);
 
@@ -723,32 +596,6 @@ switch_mode (GdmGreeterLoginWindow *logi
         }
 }
 
-static void
-do_disconnect (GdmGreeterLoginWindow *login_window)
-{
-        gtk_main_quit ();
-}
-
-#ifdef HAVE_DEVICEKIT_POWER
-static void
-do_suspend (GdmGreeterLoginWindow *login_window)
-{
-        gboolean ret;
-        DkpClient *dkp_client;
-        GError *error = NULL;
-
-        /* use DeviceKit-power to get data */
-        dkp_client = dkp_client_new ();
-        ret = dkp_client_suspend (dkp_client, &error);
-        if (!ret) {
-                g_warning ("Couldn't suspend: %s", error->message);
-                g_error_free (error);
-                return;
-        }
-        g_object_unref (dkp_client);
-}
-#endif
-
 static gboolean
 task_has_service_name (GdmTaskList *task_list,
                        GdmTask     *task,
@@ -1229,16 +1076,6 @@ gdm_greeter_login_window_get_property (G
 }
 
 static void
-suspend_button_clicked (GtkButton             *button,
-                        GdmGreeterLoginWindow *login_window)
-{
-#ifdef HAVE_DEVICEKIT_POWER
-        do_suspend (login_window);
-#endif
-}
-
-
-static void
 cancel_button_clicked (GtkButton             *button,
                        GdmGreeterLoginWindow *login_window)
 {
@@ -1246,125 +1083,6 @@ cancel_button_clicked (GtkButton        
 }
 
 static void
-disconnect_button_clicked (GtkButton             *button,
-                           GdmGreeterLoginWindow *login_window)
-{
-        do_disconnect (login_window);
-}
-
-static gboolean
-try_system_stop (DBusGConnection *connection,
-                 GError         **error)
-{
-        DBusGProxy      *proxy;
-        gboolean         res;
-
-        g_debug ("GdmGreeterLoginWindow: trying to stop system");
-
-        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;
-
-        g_debug ("GdmGreeterLoginWindow: trying to restart system");
-
-        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
-do_system_restart (GdmGreeterLoginWindow *login_window)
-{
-        gboolean         res;
-        GError          *error;
-        DBusGConnection *connection;
-
-        error = NULL;
-        connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
-        if (connection == NULL) {
-                g_warning ("Unable to get system bus connection: %s", error->message);
-                g_error_free (error);
-                return;
-        }
-
-        res = try_system_restart (connection, &error);
-        if (!res) {
-                g_debug ("GdmGreeterLoginWindow: unable to restart system: %s: %s",
-                         dbus_g_error_get_name (error),
-                         error->message);
-		g_error_free (error);
-        }
-}
-
-static void
-do_system_stop (GdmGreeterLoginWindow *login_window)
-{
-        gboolean         res;
-        GError          *error;
-        DBusGConnection *connection;
-
-        error = NULL;
-        connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
-        if (connection == NULL) {
-                g_warning ("Unable to get system bus connection: %s", error->message);
-                g_error_free (error);
-                return;
-        }
-
-        res = try_system_stop (connection, &error);
-        if (!res) {
-                g_debug ("GdmGreeterLoginWindow: unable to stop system: %s: %s",
-                         dbus_g_error_get_name (error),
-                         error->message);
-                g_error_free (error);
-        }
-}
-
-static void
-restart_button_clicked (GtkButton             *button,
-                        GdmGreeterLoginWindow *login_window)
-{
-        g_debug ("GdmGreeterLoginWindow: restart button clicked");
-        do_system_restart (login_window);
-}
-
-static void
-shutdown_button_clicked (GtkButton             *button,
-                         GdmGreeterLoginWindow *login_window)
-{
-        g_debug ("GdmGreeterLoginWindow: stop button clicked");
-        do_system_stop (login_window);
-}
-
-static void
 on_user_chooser_visibility_changed (GdmGreeterLoginWindow *login_window)
 {
         update_banner_message (login_window);
@@ -1877,20 +1595,9 @@ load_theme (GdmGreeterLoginWindow *login
         /*make_label_small_italic (login_window->priv->auth_banner_label);*/
         login_window->priv->auth_page_box = glade_xml_get_widget (login_window->priv->xml, "auth-page-box");
 
-        button = glade_xml_get_widget (login_window->priv->xml, "suspend-button");
-        g_signal_connect (button, "clicked", G_CALLBACK (suspend_button_clicked), login_window);
-
         button = glade_xml_get_widget (login_window->priv->xml, "cancel-button");
         g_signal_connect (button, "clicked", G_CALLBACK (cancel_button_clicked), login_window);
 
-        button = glade_xml_get_widget (login_window->priv->xml, "disconnect-button");
-        g_signal_connect (button, "clicked", G_CALLBACK (disconnect_button_clicked), login_window);
-
-        button = glade_xml_get_widget (login_window->priv->xml, "restart-button");
-        g_signal_connect (button, "clicked", G_CALLBACK (restart_button_clicked), login_window);
-        button = glade_xml_get_widget (login_window->priv->xml, "shutdown-button");
-        g_signal_connect (button, "clicked", G_CALLBACK (shutdown_button_clicked), login_window);
-
         create_computer_info (login_window);
 
         box = glade_xml_get_widget (login_window->priv->xml, "computer-info-event-box");
@@ -2484,8 +2191,6 @@ gdm_greeter_login_window_finalize (GObje
                 g_object_unref (login_window->priv->client);
         }
 
-        remove_sensitize_power_buttons_timeout (login_window);
-
         G_OBJECT_CLASS (gdm_greeter_login_window_parent_class)->finalize (object);
 }
 
diff -up gdm-2.28.1/gui/simple-greeter/gdm-greeter-login-window.glade.move-shutdown-functions gdm-2.28.1/gui/simple-greeter/gdm-greeter-login-window.glade
--- gdm-2.28.1/gui/simple-greeter/gdm-greeter-login-window.glade.move-shutdown-functions	2009-10-20 18:10:14.224636470 -0400
+++ gdm-2.28.1/gui/simple-greeter/gdm-greeter-login-window.glade	2009-10-20 18:10:14.326876724 -0400
@@ -337,200 +337,6 @@
 		  <property name="spacing">6</property>
 
 		  <child>
-		    <widget class="GtkButton" id="disconnect-button">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="label">gtk-disconnect</property>
-		      <property name="use_stock">True</property>
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
-		      <property name="focus_on_click">True</property>
-		    </widget>
-		  </child>
-
-		  <child>
-		    <widget class="GtkButton" id="suspend-button">
-		      <property name="visible">True</property>
-		      <property name="can_default">True</property>
-		      <property name="has_default">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
-		      <property name="focus_on_click">True</property>
-
-		      <child>
-			<widget class="GtkHBox" id="hbox3">
-			  <property name="visible">True</property>
-			  <property name="homogeneous">False</property>
-			  <property name="spacing">0</property>
-
-			  <child>
-			    <widget class="GtkImage" id="image9">
-			      <property name="visible">True</property>
-			      <property name="icon_name">media-playback-pause</property>
-			      <property name="pixel_size">16</property>
-			      <property name="xalign">0.5</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkLabel" id="label4">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">Suspend</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">False</property>
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
-			      <property name="wrap">False</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">0</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-			</widget>
-		      </child>
-		    </widget>
-		  </child>
-
-		  <child>
-		    <widget class="GtkButton" id="restart-button">
-		      <property name="visible">True</property>
-		      <property name="can_default">True</property>
-		      <property name="has_default">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
-		      <property name="focus_on_click">True</property>
-
-		      <child>
-			<widget class="GtkHBox" id="hbox1">
-			  <property name="visible">True</property>
-			  <property name="homogeneous">False</property>
-			  <property name="spacing">0</property>
-
-			  <child>
-			    <widget class="GtkImage" id="image7">
-			      <property name="visible">True</property>
-			      <property name="icon_name">view-refresh</property>
-			      <property name="pixel_size">16</property>
-			      <property name="xalign">0.5</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkLabel" id="label2">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">Restart</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">False</property>
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
-			      <property name="wrap">False</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">0</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-			</widget>
-		      </child>
-		    </widget>
-		  </child>
-
-		  <child>
-		    <widget class="GtkButton" id="shutdown-button">
-		      <property name="visible">True</property>
-		      <property name="can_default">True</property>
-		      <property name="has_default">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
-		      <property name="focus_on_click">True</property>
-
-		      <child>
-			<widget class="GtkHBox" id="hbox4">
-			  <property name="visible">True</property>
-			  <property name="homogeneous">False</property>
-			  <property name="spacing">0</property>
-
-			  <child>
-			    <widget class="GtkImage" id="image5">
-			      <property name="visible">True</property>
-			      <property name="icon_name">system-shutdown</property>
-			      <property name="pixel_size">16</property>
-			      <property name="xalign">0.5</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkLabel" id="label10">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">Shut Down</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">False</property>
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
-			      <property name="wrap">False</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">0.5</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-			</widget>
-		      </child>
-		    </widget>
-		  </child>
-
-		  <child>
 		    <widget class="GtkButton" id="cancel-button">
 		      <property name="visible">True</property>
 		      <property name="can_focus">True</property>
diff -up gdm-2.28.1/gui/simple-greeter/gdm-greeter-panel.c.move-shutdown-functions gdm-2.28.1/gui/simple-greeter/gdm-greeter-panel.c
--- gdm-2.28.1/gui/simple-greeter/gdm-greeter-panel.c.move-shutdown-functions	2009-10-19 18:12:45.000000000 -0400
+++ gdm-2.28.1/gui/simple-greeter/gdm-greeter-panel.c	2009-10-20 18:10:14.338886522 -0400
@@ -27,12 +27,22 @@
 #include <unistd.h>
 #include <string.h>
 
+#ifdef ENABLE_RBAC_SHUTDOWN
+#include <auth_attr.h>
+#include <secdb.h>
+#endif
+
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <glib-object.h>
 #include <gtk/gtk.h>
 
 #include <gconf/gconf-client.h>
+#include <dbus/dbus-glib.h>
+
+#ifdef HAVE_DEVICEKIT_POWER
+#include <devkit-power-gobject/devicekit-power.h>
+#endif
 
 #include "gdm-languages.h"
 #include "gdm-layouts.h"
@@ -46,6 +56,16 @@
 
 #include "na-tray.h"
 
+#define CK_NAME              "org.freedesktop.ConsoleKit"
+#define CK_MANAGER_PATH      "/org/freedesktop/ConsoleKit/Manager"
+#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
+
+#define GPM_DBUS_NAME      "org.freedesktop.PowerManagement"
+#define GPM_DBUS_PATH      "/org/freedesktop/PowerManagement"
+#define GPM_DBUS_INTERFACE "org.freedesktop.PowerManagement"
+
+#define KEY_DISABLE_RESTART_BUTTONS "/apps/gdm/simple-greeter/disable_restart_buttons"
+
 #define GDM_GREETER_PANEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER_PANEL, GdmGreeterPanelPrivate))
 
 struct GdmGreeterPanelPrivate
@@ -57,6 +77,8 @@ struct GdmGreeterPanelPrivate
         GtkWidget              *option_hbox;
         GtkWidget              *hostname_label;
         GtkWidget              *clock;
+        GtkWidget              *shutdown_button;
+        GtkWidget              *shutdown_menu;
         GtkWidget              *language_option_widget;
         GtkWidget              *layout_option_widget;
         GtkWidget              *session_option_widget;
@@ -66,11 +88,15 @@ struct GdmGreeterPanelPrivate
 
         char                   *default_session_name;
         char                   *default_language_name;
+
+        GConfClient            *client;
+        guint                   display_is_local : 1;
 };
 
 enum {
         PROP_0,
-        PROP_MONITOR
+        PROP_MONITOR,
+        PROP_DISPLAY_IS_LOCAL
 };
 
 enum {
@@ -107,6 +133,13 @@ gdm_greeter_panel_set_monitor (GdmGreete
 }
 
 static void
+_gdm_greeter_panel_set_display_is_local (GdmGreeterPanel       *panel,
+                                         gboolean               is)
+{
+        panel->priv->display_is_local = is;
+}
+
+static void
 gdm_greeter_panel_set_property (GObject        *object,
                                 guint           prop_id,
                                 const GValue   *value,
@@ -120,6 +153,9 @@ gdm_greeter_panel_set_property (GObject 
         case PROP_MONITOR:
                 gdm_greeter_panel_set_monitor (self, g_value_get_int (value));
                 break;
+        case PROP_DISPLAY_IS_LOCAL:
+                _gdm_greeter_panel_set_display_is_local (self, g_value_get_boolean (value));
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -140,6 +176,9 @@ gdm_greeter_panel_get_property (GObject 
         case PROP_MONITOR:
                 g_value_set_int (value, self->priv->monitor);
                 break;
+        case PROP_DISPLAY_IS_LOCAL:
+                g_value_set_boolean (value, self->priv->display_is_local);
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -477,6 +516,13 @@ gdm_greeter_panel_class_init (GdmGreeter
                                                            G_MAXINT,
                                                            0,
                                                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
+                                         PROP_DISPLAY_IS_LOCAL,
+                                         g_param_spec_boolean ("display-is-local",
+                                                               "display is local",
+                                                               "display is local",
+                                                               FALSE,
+                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
         g_type_class_add_private (klass, sizeof (GdmGreeterPanelPrivate));
 }
@@ -563,6 +609,216 @@ on_animation_tick (GdmGreeterPanel *pane
         gtk_widget_queue_resize (GTK_WIDGET (panel));
 }
 
+static gboolean
+try_system_stop (DBusGConnection *connection,
+                 GError         **error)
+{
+        DBusGProxy      *proxy;
+        gboolean         res;
+
+        g_debug ("GdmGreeterPanel: trying to stop system");
+
+        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;
+
+        g_debug ("GdmGreeterPanel: trying to restart system");
+
+        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 gboolean
+can_suspend (void)
+{
+        gboolean ret = FALSE;
+
+#ifdef HAVE_DEVICEKIT_POWER
+        DkpClient *dkp_client;
+
+        /* use DeviceKit-power to get data */
+        dkp_client = dkp_client_new ();
+        g_object_get (dkp_client,
+                      "can-suspend", &ret,
+                      NULL);
+        g_object_unref (dkp_client);
+#endif
+
+        return ret;
+}
+
+static void
+do_system_suspend (void)
+{
+#ifdef HAVE_DEVICEKIT_POWER
+        gboolean ret;
+        DkpClient *dkp_client;
+        GError *error = NULL;
+
+        /* use DeviceKit-power to get data */
+        dkp_client = dkp_client_new ();
+        ret = dkp_client_suspend (dkp_client, &error);
+        if (!ret) {
+                g_warning ("Couldn't suspend: %s", error->message);
+                g_error_free (error);
+                return;
+        }
+        g_object_unref (dkp_client);
+#endif
+}
+
+static void
+do_system_restart (void)
+{
+        gboolean         res;
+        GError          *error;
+        DBusGConnection *connection;
+
+        error = NULL;
+        connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+        if (connection == NULL) {
+                g_warning ("Unable to get system bus connection: %s", error->message);
+                g_error_free (error);
+                return;
+        }
+
+        res = try_system_restart (connection, &error);
+        if (!res) {
+                g_debug ("GdmGreeterPanel: unable to restart system: %s: %s",
+                         dbus_g_error_get_name (error),
+                         error->message);
+                g_error_free (error);
+        }
+}
+
+static void
+do_system_stop (void)
+{
+        gboolean         res;
+        GError          *error;
+        DBusGConnection *connection;
+
+        error = NULL;
+        connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+        if (connection == NULL) {
+                g_warning ("Unable to get system bus connection: %s", error->message);
+                g_error_free (error);
+                return;
+        }
+
+        res = try_system_stop (connection, &error);
+        if (!res) {
+                g_debug ("GdmGreeterPanel: unable to stop system: %s: %s",
+                         dbus_g_error_get_name (error),
+                         error->message);
+                g_error_free (error);
+        }
+}
+
+static void
+do_disconnect (void)
+{
+        gtk_main_quit ();
+}
+
+static gboolean
+get_show_restart_buttons (GdmGreeterPanel *panel)
+{
+        gboolean     show;
+        GError      *error;
+
+        error = NULL;
+        show = ! gconf_client_get_bool (panel->priv->client, KEY_DISABLE_RESTART_BUTTONS, &error);
+        if (error != NULL) {
+                g_debug ("GdmGreeterPanel: unable to get disable-restart-buttons configuration: %s", error->message);
+                g_error_free (error);
+        }
+
+#ifdef ENABLE_RBAC_SHUTDOWN
+        {
+                char *username;
+
+                username = g_get_user_name ();
+                if (username == NULL || !chkauthattr (RBAC_SHUTDOWN_KEY, username)) {
+                        show = FALSE;
+                        g_debug ("GdmGreeterPanel: Not showing stop/restart buttons for user %s due to RBAC key %s",
+                                 username, RBAC_SHUTDOWN_KEY);
+                } else {
+                        g_debug ("GdmGreeterPanel: Showing stop/restart buttons for user %s due to RBAC key %s",
+                                 username, RBAC_SHUTDOWN_KEY);
+                }
+        }
+#endif
+        return show;
+}
+
+static void
+position_shutdown_menu (GtkMenu         *menu,
+                        int             *x,
+                        int             *y,
+                        gboolean        *push_in,
+                        GdmGreeterPanel *panel)
+{
+        GtkRequisition menu_requisition;
+
+        *push_in = TRUE;
+
+        *x = panel->priv->shutdown_button->allocation.x;
+        gtk_window_get_position (GTK_WINDOW (panel), NULL, y);
+
+        gtk_widget_size_request (GTK_WIDGET (menu), &menu_requisition);
+
+        *y -= menu_requisition.height;
+}
+
+static void
+on_shutdown_button_toggled (GdmGreeterPanel *panel)
+{
+        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (panel->priv->shutdown_button))) {
+                gtk_menu_popup (GTK_MENU (panel->priv->shutdown_menu), NULL, NULL,
+                                (GtkMenuPositionFunc) position_shutdown_menu,
+                                panel, 0, 0);
+        } else {
+                gtk_menu_popdown (GTK_MENU (panel->priv->shutdown_menu));
+        }
+}
+
+static void
+on_shutdown_menu_deactivate (GdmGreeterPanel *panel)
+{
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (panel->priv->shutdown_button),
+                                      FALSE);
+}
+
 static void
 gdm_greeter_panel_init (GdmGreeterPanel *panel)
 {
@@ -603,6 +859,8 @@ gdm_greeter_panel_init (GdmGreeterPanel 
         spacer = gtk_label_new ("");
         gtk_box_pack_start (GTK_BOX (panel->priv->option_hbox), spacer, TRUE, TRUE, 6);
         gtk_widget_show (spacer);
+    
+        panel->priv->client = gconf_client_get_default ();
 
         gdm_profile_start ("creating option widget");
         panel->priv->language_option_widget = gdm_language_option_widget_new ();
@@ -642,6 +900,51 @@ gdm_greeter_panel_init (GdmGreeterPanel 
                 gtk_widget_show (panel->priv->hostname_label);
         }
 
+        if (panel->priv->display_is_local || get_show_restart_buttons (panel)) {
+                GtkWidget *menu_item;
+                GtkWidget *image;
+
+                panel->priv->shutdown_button = gtk_toggle_button_new ();
+                gtk_button_set_relief (GTK_BUTTON (panel->priv->shutdown_button),
+                                       GTK_RELIEF_NONE);
+
+                panel->priv->shutdown_menu = gtk_menu_new ();
+                gtk_menu_attach_to_widget (GTK_MENU (panel->priv->shutdown_menu),
+                                           panel->priv->shutdown_button, NULL);
+                g_signal_connect_swapped (panel->priv->shutdown_button, "toggled",
+                                          G_CALLBACK (on_shutdown_button_toggled), panel);
+                g_signal_connect_swapped (panel->priv->shutdown_menu, "deactivate",
+                                          G_CALLBACK (on_shutdown_menu_deactivate), panel);
+
+                image = gtk_image_new_from_icon_name ("system-shutdown", GTK_ICON_SIZE_BUTTON);
+                gtk_widget_show (image);
+                gtk_container_add (GTK_CONTAINER (panel->priv->shutdown_button), image);
+
+                if (panel->priv->display_is_local) {
+                        menu_item = gtk_menu_item_new_with_label ("Disconnect");
+                        g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_disconnect), NULL);
+                        gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
+                } else {
+                        if (can_suspend ()) {
+                                menu_item = gtk_menu_item_new_with_label (_("Suspend"));
+                                g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_suspend), NULL);
+                                gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
+                        }
+
+                        menu_item = gtk_menu_item_new_with_label (_("Restart"));
+                        g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_restart), NULL);
+                        gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
+
+                        menu_item = gtk_menu_item_new_with_label (_("Shut Down"));
+                        g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_stop), NULL);
+                        gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
+                }
+
+                gtk_box_pack_end (GTK_BOX (panel->priv->hbox), GTK_WIDGET (panel->priv->shutdown_button), FALSE, FALSE, 0);
+                gtk_widget_show_all (panel->priv->shutdown_menu);
+                gtk_widget_show_all (GTK_WIDGET (panel->priv->shutdown_button));
+        }
+
         panel->priv->clock = gdm_clock_widget_new ();
         gtk_box_pack_end (GTK_BOX (panel->priv->hbox),
                             GTK_WIDGET (panel->priv->clock), FALSE, FALSE, 6);
@@ -651,7 +954,6 @@ gdm_greeter_panel_init (GdmGreeterPanel 
                                        GTK_ORIENTATION_HORIZONTAL);
         gtk_box_pack_end (GTK_BOX (panel->priv->hbox), GTK_WIDGET (tray), FALSE, FALSE, 6);
         gtk_widget_show (GTK_WIDGET (tray));
-
         gdm_greeter_panel_hide_user_options (panel);
 
         panel->priv->progress = 0.0;
@@ -684,13 +986,15 @@ gdm_greeter_panel_finalize (GObject *obj
 
 GtkWidget *
 gdm_greeter_panel_new (GdkScreen *screen,
-                       int        monitor)
+                       int        monitor,
+                       gboolean   is_local)
 {
         GObject *object;
 
         object = g_object_new (GDM_TYPE_GREETER_PANEL,
                                "screen", screen,
                                "monitor", monitor,
+                               "display-is-local", is_local,                               
                                NULL);
 
         return GTK_WIDGET (object);
diff -up gdm-2.28.1/gui/simple-greeter/gdm-greeter-panel.h.move-shutdown-functions gdm-2.28.1/gui/simple-greeter/gdm-greeter-panel.h
--- gdm-2.28.1/gui/simple-greeter/gdm-greeter-panel.h.move-shutdown-functions	2009-10-19 18:12:45.000000000 -0400
+++ gdm-2.28.1/gui/simple-greeter/gdm-greeter-panel.h	2009-10-20 18:10:14.330886648 -0400
@@ -60,7 +60,8 @@ typedef struct
 GType                  gdm_greeter_panel_get_type                       (void);
 
 GtkWidget            * gdm_greeter_panel_new                            (GdkScreen *screen,
-                                                                         int        monitor);
+                                                                         int        monitor,
+                                                                         gboolean   is_local);
 
 void                   gdm_greeter_panel_show_user_options              (GdmGreeterPanel *panel);
 void                   gdm_greeter_panel_hide_user_options              (GdmGreeterPanel *panel);
diff -up gdm-2.28.1/gui/simple-greeter/gdm-greeter-session.c.move-shutdown-functions gdm-2.28.1/gui/simple-greeter/gdm-greeter-session.c
--- gdm-2.28.1/gui/simple-greeter/gdm-greeter-session.c.move-shutdown-functions	2009-10-20 18:10:14.231637268 -0400
+++ gdm-2.28.1/gui/simple-greeter/gdm-greeter-session.c	2009-10-20 18:10:14.332887524 -0400
@@ -369,13 +369,15 @@ toggle_panel (GdmGreeterSession *session
                 GdkScreen  *screen;
                 int         monitor;
                 int         x, y;
+                gboolean    is_local;
 
                 display = gdk_display_get_default ();
                 gdk_display_get_pointer (display, &screen, &x, &y, NULL);
 
                 monitor = get_tallest_monitor_at_point (screen, x, y);
 
-                session->priv->panel = gdm_greeter_panel_new (screen, monitor);
+                is_local = gdm_greeter_client_get_display_is_local (session->priv->client);
+                session->priv->panel = gdm_greeter_panel_new (screen, monitor, is_local);
 
                 g_signal_connect_swapped (session->priv->panel,
                                           "language-selected",
diff -up gdm-2.28.1/gui/simple-greeter/Makefile.am.move-shutdown-functions gdm-2.28.1/gui/simple-greeter/Makefile.am
--- gdm-2.28.1/gui/simple-greeter/Makefile.am.move-shutdown-functions	2009-10-20 18:10:14.254638094 -0400
+++ gdm-2.28.1/gui/simple-greeter/Makefile.am	2009-10-20 18:10:14.319892618 -0400
@@ -103,7 +103,6 @@ test_greeter_login_window_LDADD =	\
 	libgdmuser.la			\
 	$(COMMON_LIBS)			\
 	$(SIMPLE_GREETER_LIBS)		\
-	$(DEVKIT_POWER_LIBS)		\
 	$(RBAC_LIBS)			\
 	$(NULL)
 
@@ -156,6 +155,7 @@ test_greeter_panel_LDADD =	\
 	$(GTK_LIBS)			\
 	$(GCONF_LIBS)			\
 	$(LIBXKLAVIER_LIBS)		\
+	$(DEVKIT_POWER_LIBS)		\
 	$(NULL)
 
 test_remote_login_window_SOURCES = 	\
diff -up gdm-2.28.1/gui/simple-greeter/test-greeter-panel.c.move-shutdown-functions gdm-2.28.1/gui/simple-greeter/test-greeter-panel.c
--- gdm-2.28.1/gui/simple-greeter/test-greeter-panel.c.move-shutdown-functions	2009-10-19 18:12:45.000000000 -0400
+++ gdm-2.28.1/gui/simple-greeter/test-greeter-panel.c	2009-10-20 18:10:14.334888750 -0400
@@ -53,7 +53,7 @@ main (int argc, char *argv[])
         gdk_display_get_pointer (display, &screen, &x, &y, NULL);
         monitor = gdk_screen_get_monitor_at_point (screen, x, y);
 
-        panel = gdm_greeter_panel_new (screen, monitor);
+        panel = gdm_greeter_panel_new (screen, monitor, TRUE);
         gdm_greeter_panel_show_user_options (GDM_GREETER_PANEL (panel));
 
         gtk_widget_show (panel);