diff --git a/plugins/media-keys/Makefile.am b/plugins/media-keys/Makefile.am
index 3607725..00babd0 100644
--- a/plugins/media-keys/Makefile.am
+++ b/plugins/media-keys/Makefile.am
@@ -81,6 +81,7 @@ libmedia_keys_la_SOURCES = 		\
 	$(NULL)
 
 libmedia_keys_la_CPPFLAGS = \
+	-I$(top_srcdir)/data/					\
 	-I$(top_srcdir)/gnome-settings-daemon			\
 	-I$(top_srcdir)/plugins/common				\
 	-I$(top_srcdir)/plugins/media-keys/cut-n-paste		\
@@ -92,6 +93,7 @@ libmedia_keys_la_CPPFLAGS = \
 libmedia_keys_la_CFLAGS = \
 	$(PLUGIN_CFLAGS)		\
 	$(SETTINGS_PLUGIN_CFLAGS)	\
+	$(UPOWER_CFLAGS)		\
 	$(AM_CFLAGS)
 
 libmedia_keys_la_LDFLAGS = 		\
@@ -100,6 +102,7 @@ libmedia_keys_la_LDFLAGS = 		\
 libmedia_keys_la_LIBADD  = 		\
 	$(top_builddir)/plugins/common/libcommon.la			\
 	$(top_builddir)/plugins/media-keys/cut-n-paste/libgvc.la	\
+	$(UPOWER_LIBS)							\
 	$(SETTINGS_PLUGIN_LIBS)						\
 	$(XF86MISC_LIBS)						\
 	-lm
@@ -125,6 +128,7 @@ test_media_window_SOURCES =			\
 	$(NULL)
 
 test_media_window_CPPFLAGS = \
+	-I$(top_srcdir)/data/					\
 	-I$(top_srcdir)/gnome-settings-daemon			\
 	-I$(top_srcdir)/plugins/common				\
 	-I$(top_srcdir)/plugins/media-keys/cut-n-paste		\
@@ -158,6 +162,7 @@ test_media_keys_SOURCES =			\
 	$(NULL)
 
 test_media_keys_CPPFLAGS = \
+	-I$(top_srcdir)/data/					\
 	-I$(top_srcdir)/gnome-settings-daemon			\
 	-I$(top_srcdir)/plugins/common				\
 	-I$(top_srcdir)/plugins/media-keys/cut-n-paste		\
@@ -175,6 +180,7 @@ test_media_keys_LDADD = \
 	$(top_builddir)/plugins/common/libcommon.la			\
 	$(SETTINGS_DAEMON_LIBS)			\
 	$(SETTINGS_PLUGIN_LIBS)			\
+	$(UPOWER_LIBS)				\
 	$(XF86MISC_LIBS)			\
 	$(GST_LIBS)				\
 	-lm
diff --git a/plugins/media-keys/acme.h b/plugins/media-keys/acme.h
index ac58d7b..7f94227 100644
--- a/plugins/media-keys/acme.h
+++ b/plugins/media-keys/acme.h
@@ -65,6 +65,17 @@ typedef enum {
         TOGGLE_CONTRAST_KEY,
         MAGNIFIER_ZOOM_IN_KEY,
         MAGNIFIER_ZOOM_OUT_KEY,
+        POWER_KEY,
+        SLEEP_KEY,
+        SUSPEND_KEY,
+        HIBERNATE_KEY,
+        SCREEN_BRIGHTNESS_UP_KEY,
+        SCREEN_BRIGHTNESS_DOWN_KEY,
+        KEYBOARD_BRIGHTNESS_UP_KEY,
+        KEYBOARD_BRIGHTNESS_DOWN_KEY,
+        KEYBOARD_BRIGHTNESS_TOGGLE_KEY,
+        LOCK_KEY,
+        BATTERY_KEY,
         HANDLED_KEYS
 } MediaKeyType;
 
@@ -116,6 +127,18 @@ static struct {
 	{ TOGGLE_CONTRAST_KEY, "toggle-contrast", NULL, NULL },
 	{ MAGNIFIER_ZOOM_IN_KEY, "magnifier-zoom-in", NULL, NULL },
 	{ MAGNIFIER_ZOOM_OUT_KEY, "magnifier-zoom-out", NULL, NULL },
+        { POWER_KEY, NULL, "XF86PowerOff", NULL },
+        /* the kernel / Xorg names really are like this... */
+        { SLEEP_KEY, NULL, "XF86Suspend", NULL },
+        { SUSPEND_KEY, NULL, "XF86Sleep", NULL },
+        { HIBERNATE_KEY, NULL, "XF86Hibernate", NULL },
+        { SCREEN_BRIGHTNESS_UP_KEY, NULL, "XF86MonBrightnessUp", NULL },
+        { SCREEN_BRIGHTNESS_DOWN_KEY, NULL, "XF86MonBrightnessDown", NULL },
+        { KEYBOARD_BRIGHTNESS_UP_KEY, NULL, "XF86KbdBrightnessUp", NULL },
+        { KEYBOARD_BRIGHTNESS_DOWN_KEY, NULL, "XF86KbdBrightnessDown", NULL },
+        { KEYBOARD_BRIGHTNESS_TOGGLE_KEY, NULL, "XF86KbdLightOnOff", NULL },
+        { LOCK_KEY, NULL, "XF86ScreenSaver", NULL },
+        { BATTERY_KEY, NULL, "XF86Battery", NULL },
 };
 
 #endif /* __ACME_H__ */
diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c
index b6e9cf9..d76b255 100644
--- a/plugins/media-keys/gsd-media-keys-manager.c
+++ b/plugins/media-keys/gsd-media-keys-manager.c
@@ -46,6 +46,7 @@
 #include "acme.h"
 #include "gsd-media-keys-window.h"
 #include "gsd-input-helper.h"
+#include "gsd-enums.h"
 
 #ifdef HAVE_PULSE
 #include <canberra-gtk.h>
@@ -53,6 +54,8 @@
 #include "gvc-mixer-control.h"
 #endif /* HAVE_PULSE */
 
+#include <libupower-glib/upower.h>
+
 #define GSD_DBUS_PATH "/org/gnome/SettingsDaemon"
 #define GSD_DBUS_NAME "org.gnome.SettingsDaemon"
 #define GSD_MEDIA_KEYS_DBUS_PATH GSD_DBUS_PATH "/MediaKeys"
@@ -74,6 +77,7 @@ static const gchar introspection_xml[] =
 "</node>";
 
 #define SETTINGS_INTERFACE_DIR "org.gnome.desktop.interface"
+#define SETTINGS_POWER_DIR "org.gnome.settings-daemon.plugins.power"
 #define SETTINGS_XSETTINGS_DIR "org.gnome.settings-daemon.plugins.xsettings"
 #define SETTINGS_TOUCHPAD_DIR "org.gnome.settings-daemon.peripherals.touchpad"
 #define TOUCHPAD_ENABLED_KEY "touchpad-enabled"
@@ -109,6 +113,12 @@ struct GsdMediaKeysManagerPrivate
         char            *icon_theme;
         char            *gtk_theme;
 
+        /* Power stuff */
+        GSettings       *power_settings;
+        UpClient        *up_client;
+        GDBusProxy      *power_screen_proxy;
+        GDBusProxy      *power_keyboard_proxy;
+
         /* Multihead stuff */
         GdkScreen       *current_screen;
         GSList          *screens;
@@ -1150,6 +1160,163 @@ do_toggle_contrast_action (GsdMediaKeysManager *manager)
 	}
 }
 
+static void
+do_power_action_type (GsdMediaKeysManager *manager,
+                      GsdPowerActionType action_type)
+{
+        gboolean ret;
+        GError *error = NULL;
+
+        switch (action_type) {
+        case GSD_POWER_ACTION_SUSPEND:
+                ret = up_client_suspend_sync (manager->priv->up_client,
+                                              NULL, &error);
+                if (!ret) {
+                        g_warning ("failed to suspend: %s",
+                                   error->message);
+                        g_error_free (error);
+                }
+                break;
+        case GSD_POWER_ACTION_SHUTDOWN:
+                /* TODO: shutdown the machine using ConsoleKit */;
+                break;
+        case GSD_POWER_ACTION_HIBERNATE:
+                ret = up_client_hibernate_sync (manager->priv->up_client,
+                                                NULL, &error);
+                if (!ret) {
+                        g_warning ("failed to suspend: %s",
+                                   error->message);
+                        g_error_free (error);
+                }
+                break;
+        case GSD_POWER_ACTION_BLANK:
+        case GSD_POWER_ACTION_NOTHING:
+        case GSD_POWER_ACTION_INTERACTIVE:
+                break;
+        }
+}
+
+static void
+do_power_action (GsdMediaKeysManager *manager)
+{
+        GsdPowerActionType action_type;
+        action_type = g_settings_get_enum (manager->priv->power_settings,
+                                           "button-power");
+        do_power_action_type (manager, action_type);
+}
+
+static void
+do_sleep_action (GsdMediaKeysManager *manager)
+{
+        GsdPowerActionType action_type;
+        action_type = g_settings_get_enum (manager->priv->power_settings,
+                                           "button-sleep");
+        do_power_action_type (manager, action_type);
+}
+
+static void
+do_suspend_action (GsdMediaKeysManager *manager)
+{
+        GsdPowerActionType action_type;
+        action_type = g_settings_get_enum (manager->priv->power_settings,
+                                           "button-suspend");
+        do_power_action_type (manager, action_type);
+}
+
+static void
+do_hibernate_action (GsdMediaKeysManager *manager)
+{
+        GsdPowerActionType action_type;
+        action_type = g_settings_get_enum (manager->priv->power_settings,
+                                           "button-hibernate");
+        do_power_action_type (manager, action_type);
+}
+
+typedef enum {
+        GSD_BRIGHTNESS_ACTION_INCREMENT,
+        GSD_BRIGHTNESS_ACTION_DECREMENT,
+        GSD_BRIGHTNESS_ACTION_TOGGLE
+} GsdBrightnessAction;
+
+static void
+update_brightness_cb (GObject             *source_object,
+                      GAsyncResult        *res,
+                      gpointer             user_data)
+{
+        GError *error = NULL;
+        guint percentage;
+        GVariant *new_percentage;
+        GsdMediaKeysManager *manager = GSD_MEDIA_KEYS_MANAGER (user_data);
+
+        new_percentage = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
+                                                   res, &error);
+        if (new_percentage == NULL) {
+                g_warning ("Failed to set new percentage: %s",
+                           error->message);
+                g_error_free (error);
+                return;
+        }
+
+        /* update the dialog with the new value */
+        percentage = g_variant_get_uint32 (new_percentage);
+        gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                                percentage);
+        g_variant_unref (new_percentage);
+}
+
+static void
+do_screen_brightness_action (GsdMediaKeysManager *manager,
+                             GsdBrightnessAction action)
+{
+        GVariant *old_percentage;
+        guint percentage;
+
+        if (manager->priv->connection == NULL ||
+            manager->priv->power_screen_proxy == NULL) {
+                g_warning ("No existing D-Bus connection trying to handle power keys");
+                return;
+        }
+
+        /* show the dialogue with the old value so we can get the
+         * transistion from old value to new value */
+        dialog_init (manager);
+        gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                                 "display-brightness-symbolic",
+                                                 TRUE);
+
+        /* display what we have now */
+        old_percentage = g_dbus_proxy_get_cached_property (manager->priv->power_screen_proxy,
+                                                           "Percentage");
+        percentage = g_variant_get_uint32 (old_percentage);
+        gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                                percentage);
+
+        /* call into the power plugin */
+        g_dbus_proxy_call (manager->priv->power_screen_proxy,
+                           action == GSD_BRIGHTNESS_ACTION_INCREMENT ? "StepUp" : "StepDown",
+                           NULL,
+                           G_DBUS_CALL_FLAGS_NONE,
+                           -1,
+                           NULL,
+                           update_brightness_cb,
+                           manager);
+        g_variant_unref (old_percentage);
+        dialog_show (manager);
+}
+
+static void
+do_keyboard_brightness_action (GsdMediaKeysManager *manager,
+                               GsdBrightnessAction action)
+{
+        /* TODO: same logic here, but no point until screen stuff
+         * above is reviewed */
+        dialog_init (manager);
+        gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                                 "keyboard-brightness-symbolic",
+                                                 FALSE);
+        dialog_show (manager);
+}
+
 static gboolean
 do_action (GsdMediaKeysManager *manager,
            MediaKeyType         type,
@@ -1219,6 +1386,7 @@ do_action (GsdMediaKeysManager *manager,
         case EMAIL_KEY:
                 do_url_action (manager, "mailto");
                 break;
+        case LOCK_KEY:
         case SCREENSAVER_KEY:
                 if ((cmd = g_find_program_in_path ("gnome-screensaver-command"))) {
                         execute (manager, "gnome-screensaver-command --lock", FALSE, FALSE);
@@ -1285,6 +1453,42 @@ do_action (GsdMediaKeysManager *manager,
 	case TOGGLE_CONTRAST_KEY:
 		do_toggle_contrast_action (manager);
 		break;
+        case POWER_KEY:
+                do_power_action (manager);
+                break;
+        case SLEEP_KEY:
+                do_sleep_action (manager);
+                break;
+        case SUSPEND_KEY:
+                do_suspend_action (manager);
+                break;
+        case HIBERNATE_KEY:
+                do_hibernate_action (manager);
+                break;
+        case SCREEN_BRIGHTNESS_UP_KEY:
+                do_screen_brightness_action (manager,
+                                             GSD_BRIGHTNESS_ACTION_INCREMENT);
+                break;
+        case SCREEN_BRIGHTNESS_DOWN_KEY:
+                do_screen_brightness_action (manager,
+                                             GSD_BRIGHTNESS_ACTION_DECREMENT);
+                break;
+        case KEYBOARD_BRIGHTNESS_UP_KEY:
+                do_keyboard_brightness_action (manager,
+                                               GSD_BRIGHTNESS_ACTION_INCREMENT);
+                break;
+        case KEYBOARD_BRIGHTNESS_DOWN_KEY:
+                do_keyboard_brightness_action (manager,
+                                               GSD_BRIGHTNESS_ACTION_DECREMENT);
+                break;
+        case KEYBOARD_BRIGHTNESS_TOGGLE_KEY:
+                do_keyboard_brightness_action (manager,
+                                               GSD_BRIGHTNESS_ACTION_TOGGLE);
+                break;
+        case BATTERY_KEY:
+                /* don't actually do anything here until we've agreed
+                 * something sane with the designers */
+                break;
         case HANDLED_KEYS:
                 g_assert_not_reached ();
         /* Note, no default so compiler catches missing keys */
@@ -1391,6 +1595,10 @@ start_media_keys_idle_cb (GsdMediaKeysManager *manager)
         g_signal_connect (G_OBJECT (manager->priv->settings), "changed",
                           G_CALLBACK (update_kbd_cb), manager);
 
+        /* for the power plugin interface code */
+        manager->priv->power_settings = g_settings_new (SETTINGS_POWER_DIR);
+        manager->priv->up_client = up_client_new ();
+
         /* Logic from http://git.gnome.org/browse/gnome-shell/tree/js/ui/status/accessibility.js#n163 */
         manager->priv->interface_settings = g_settings_new (SETTINGS_INTERFACE_DIR);
         g_signal_connect (G_OBJECT (manager->priv->interface_settings), "changed::gtk-theme",
@@ -1492,6 +1700,26 @@ gsd_media_keys_manager_stop (GsdMediaKeysManager *manager)
                 priv->settings = NULL;
         }
 
+        if (priv->power_settings) {
+                g_object_unref (priv->power_settings);
+                priv->power_settings = NULL;
+        }
+
+        if (priv->power_screen_proxy) {
+                g_object_unref (priv->power_screen_proxy);
+                priv->power_screen_proxy = NULL;
+        }
+
+        if (priv->power_keyboard_proxy) {
+                g_object_unref (priv->power_keyboard_proxy);
+                priv->power_keyboard_proxy = NULL;
+        }
+
+        if (priv->up_client) {
+                g_object_unref (priv->up_client);
+                priv->up_client = NULL;
+        }
+
         if (priv->cancellable != NULL) {
                 g_cancellable_cancel (priv->cancellable);
                 g_object_unref (priv->cancellable);
@@ -1651,6 +1879,36 @@ xrandr_ready_cb (GObject             *source_object,
 }
 
 static void
+power_screen_ready_cb (GObject             *source_object,
+                       GAsyncResult        *res,
+                       GsdMediaKeysManager *manager)
+{
+        GError *error = NULL;
+
+        manager->priv->power_screen_proxy = g_dbus_proxy_new_finish (res, &error);
+        if (manager->priv->power_screen_proxy == NULL) {
+                g_warning ("Failed to get proxy for power (screen): %s",
+                           error->message);
+                g_error_free (error);
+        }
+}
+
+static void
+power_keyboard_ready_cb (GObject             *source_object,
+                         GAsyncResult        *res,
+                         GsdMediaKeysManager *manager)
+{
+        GError *error = NULL;
+
+        manager->priv->power_keyboard_proxy = g_dbus_proxy_new_finish (res, &error);
+        if (manager->priv->power_keyboard_proxy == NULL) {
+                g_warning ("Failed to get proxy for power (keyboard): %s",
+                           error->message);
+                g_error_free (error);
+        }
+}
+
+static void
 on_bus_gotten (GObject             *source_object,
                GAsyncResult        *res,
                GsdMediaKeysManager *manager)
@@ -1683,6 +1941,26 @@ on_bus_gotten (GObject             *source_object,
                           NULL,
                           (GAsyncReadyCallback) xrandr_ready_cb,
                           manager);
+
+        g_dbus_proxy_new (manager->priv->connection,
+                          G_DBUS_PROXY_FLAGS_NONE,
+                          NULL,
+                          "org.gnome.SettingsDaemon",
+                          "/org/gnome/SettingsDaemon/Power",
+                          "org.gnome.SettingsDaemon.Power.Screen",
+                          NULL,
+                          (GAsyncReadyCallback) power_screen_ready_cb,
+                          manager);
+
+        g_dbus_proxy_new (manager->priv->connection,
+                          G_DBUS_PROXY_FLAGS_NONE,
+                          NULL,
+                          "org.gnome.SettingsDaemon",
+                          "/org/gnome/SettingsDaemon/Power",
+                          "org.gnome.SettingsDaemon.Power.Keyboard",
+                          NULL,
+                          (GAsyncReadyCallback) power_keyboard_ready_cb,
+                          manager);
 }
 
 static void
