aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/changelog7
-rw-r--r--src/dbus-shared-names.h12
-rw-r--r--src/session-service.c185
-rw-r--r--src/status-service.c1
4 files changed, 191 insertions, 14 deletions
diff --git a/debian/changelog b/debian/changelog
index c7efc21..416eb0e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+indicator-sus (0.1~ppa2~indicator9ubuntu6) UNRELEASED; urgency=low
+
+ * Adding in devkit power support for suspend/hibernate
+ * Changing namespace from com.ubuntu to org.ayatana
+
+ -- Ted Gould <ted@ubuntu.com> Fri, 24 Jul 2009 16:46:10 -0500
+
indicator-sus (0.1~ppa2~indicator9ubuntu5) karmic; urgency=low
* debian/control: Adding a dep on polkit-gnome-dev
diff --git a/src/dbus-shared-names.h b/src/dbus-shared-names.h
index f56e9cb..bd2f8ab 100644
--- a/src/dbus-shared-names.h
+++ b/src/dbus-shared-names.h
@@ -2,13 +2,13 @@
#ifndef __DBUS_SHARED_NAMES_H__
#define __DBUS_SHARED_NAMES_H__ 1
-#define INDICATOR_STATUS_DBUS_NAME "com.ubuntu.indicator.status"
-#define INDICATOR_STATUS_DBUS_OBJECT "/com/ubuntu/indicator/status"
+#define INDICATOR_STATUS_DBUS_NAME "org.ayatana.indicator.status"
+#define INDICATOR_STATUS_DBUS_OBJECT "/org/ayatana/indicator/status"
-#define INDICATOR_USERS_DBUS_NAME "com.ubuntu.indicator.users"
-#define INDICATOR_USERS_DBUS_OBJECT "/com/ubuntu/indicator/users"
+#define INDICATOR_USERS_DBUS_NAME "org.ayatana.indicator.users"
+#define INDICATOR_USERS_DBUS_OBJECT "/org/ayatana/indicator/users"
-#define INDICATOR_SESSION_DBUS_NAME "com.ubuntu.indicator.session"
-#define INDICATOR_SESSION_DBUS_OBJECT "/com/ubuntu/indicator/session"
+#define INDICATOR_SESSION_DBUS_NAME "org.ayatana.indicator.session"
+#define INDICATOR_SESSION_DBUS_OBJECT "/org/ayatana/indicator/session"
#endif /* __DBUS_SHARED_NAMES_H__ */
diff --git a/src/session-service.c b/src/session-service.c
index c8b3170..235d0bc 100644
--- a/src/session-service.c
+++ b/src/session-service.c
@@ -9,9 +9,171 @@
#include "dbus-shared-names.h"
+#define DKP_ADDRESS "org.freedesktop.DeviceKit.Power"
+#define DKP_OBJECT "/org/freedesktop/DeviceKit/Power"
+#define DKP_INTERFACE "org.freedesktop.DeviceKit.Power"
+
static DbusmenuMenuitem * root_menuitem = NULL;
static GMainLoop * mainloop = NULL;
+static DBusGProxy * dkp_main_proxy = NULL;
+static DBusGProxy * dkp_prop_proxy = NULL;
+
+static DBusGProxyCall * suspend_call = NULL;
+static DBusGProxyCall * hibernate_call = NULL;
+
+static DbusmenuMenuitem * hibernate_mi = NULL;
+static DbusmenuMenuitem * suspend_mi = NULL;
+
+/* Let's put this machine to sleep, with some info on how
+ it should sleep. */
+static void
+sleep (DbusmenuMenuitem * mi, gpointer userdata)
+{
+ gchar * type = (gchar *)userdata;
+
+ if (dkp_main_proxy == NULL) {
+ g_warning("Can not %s as no DeviceKit Power Proxy", type);
+ }
+ dbus_g_proxy_call_no_reply(dkp_main_proxy,
+ type,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+
+ return;
+}
+
+/* A response to getting the suspend property */
+static void
+suspend_prop_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata)
+{
+ suspend_call = NULL;
+
+ GValue candoit = {0};
+ GError * error = NULL;
+ dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_VALUE, &candoit, G_TYPE_INVALID);
+ if (error != NULL) {
+ g_warning("Unable to check suspend: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+ g_debug("Got Suspend: %s", g_value_get_boolean(&candoit) ? "true" : "false");
+
+ if (suspend_mi != NULL) {
+ dbusmenu_menuitem_property_set(suspend_mi, "visible", g_value_get_boolean(&candoit) ? "true" : "false");
+ }
+
+ return;
+}
+
+/* Response to getting the hibernate property */
+static void
+hibernate_prop_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata)
+{
+ hibernate_call = NULL;
+
+ GValue candoit = {0};
+ GError * error = NULL;
+ dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_VALUE, &candoit, G_TYPE_INVALID);
+ if (error != NULL) {
+ g_warning("Unable to check hibernate: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+ g_debug("Got Hibernate: %s", g_value_get_boolean(&candoit) ? "true" : "false");
+
+ if (suspend_mi != NULL) {
+ dbusmenu_menuitem_property_set(hibernate_mi, "visible", g_value_get_boolean(&candoit) ? "true" : "false");
+ }
+
+ return;
+}
+
+/* A signal that we need to recheck to ensure we can still
+ hibernate and/or suspend */
+static void
+dpk_changed_cb (DBusGProxy * proxy, gpointer user_data)
+{
+ /* Start Async call to see if we can hibernate */
+ if (suspend_call == NULL) {
+ suspend_call = dbus_g_proxy_begin_call(dkp_prop_proxy,
+ "Get",
+ suspend_prop_cb,
+ NULL,
+ NULL,
+ G_TYPE_STRING,
+ DKP_INTERFACE,
+ G_TYPE_STRING,
+ "can-suspend",
+ G_TYPE_INVALID,
+ G_TYPE_VALUE,
+ G_TYPE_INVALID);
+ }
+
+ /* Start Async call to see if we can suspend */
+ if (hibernate_call == NULL) {
+ hibernate_call = dbus_g_proxy_begin_call(dkp_prop_proxy,
+ "Get",
+ hibernate_prop_cb,
+ NULL,
+ NULL,
+ G_TYPE_STRING,
+ DKP_INTERFACE,
+ G_TYPE_STRING,
+ "can-hibernate",
+ G_TYPE_INVALID,
+ G_TYPE_VALUE,
+ G_TYPE_INVALID);
+ }
+
+ return;
+}
+
+/* This function goes through and sets up what we need for
+ DKp checking. We're even setting up the calls for the props
+ we need */
+static void
+setup_dkp (void) {
+ DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
+ g_return_if_fail(bus != NULL);
+
+ if (dkp_main_proxy == NULL) {
+ dkp_main_proxy = dbus_g_proxy_new_for_name(bus,
+ DKP_ADDRESS,
+ DKP_OBJECT,
+ DKP_INTERFACE);
+ }
+ g_return_if_fail(dkp_main_proxy != NULL);
+
+ if (dkp_prop_proxy == NULL) {
+ dkp_prop_proxy = dbus_g_proxy_new_for_name(bus,
+ DKP_ADDRESS,
+ DKP_OBJECT,
+ DBUS_INTERFACE_PROPERTIES);
+ }
+ g_return_if_fail(dkp_prop_proxy != NULL);
+
+ /* Connect to changed signal */
+ dbus_g_proxy_add_signal(dkp_main_proxy,
+ "Changed",
+ G_TYPE_INVALID);
+
+ dbus_g_proxy_connect_signal(dkp_main_proxy,
+ "Changed",
+ G_CALLBACK(dpk_changed_cb),
+ NULL,
+ NULL);
+
+ /* Force an original "changed" event */
+ dpk_changed_cb(dkp_main_proxy, NULL);
+
+ return;
+}
+
+/* This is the function to show a dialog on actions that
+ can destroy data. Currently it just calls the GTK version
+ but it seems that in the future it should figure out
+ what's going on and something better. */
static void
show_dialog (DbusmenuMenuitem * mi, gchar * type)
{
@@ -32,6 +194,8 @@ show_dialog (DbusmenuMenuitem * mi, gchar * type)
return;
}
+/* This function creates all of the menuitems that the service
+ provides in the UI. It also connects them to the callbacks. */
static void
create_items (DbusmenuMenuitem * root) {
DbusmenuMenuitem * mi = NULL;
@@ -41,15 +205,17 @@ create_items (DbusmenuMenuitem * root) {
dbusmenu_menuitem_child_append(root, mi);
g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_dialog), "logout");
- mi = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(mi, "label", _("Suspend"));
- dbusmenu_menuitem_child_append(root, mi);
- g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_dialog), "suspend");
+ suspend_mi = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set(suspend_mi, "visible", "false");
+ dbusmenu_menuitem_property_set(suspend_mi, "label", _("Suspend"));
+ dbusmenu_menuitem_child_append(root, suspend_mi);
+ g_signal_connect(G_OBJECT(suspend_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(sleep), "Suspend");
- mi = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(mi, "label", _("Hibernate"));
- dbusmenu_menuitem_child_append(root, mi);
- g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_dialog), "hibernate");
+ hibernate_mi = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set(hibernate_mi, "visible", "false");
+ dbusmenu_menuitem_property_set(hibernate_mi, "label", _("Hibernate"));
+ dbusmenu_menuitem_child_append(root, hibernate_mi);
+ g_signal_connect(G_OBJECT(hibernate_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(sleep), "Hibernate");
mi = dbusmenu_menuitem_new();
dbusmenu_menuitem_property_set(mi, "label", _("Restart"));
@@ -64,6 +230,8 @@ create_items (DbusmenuMenuitem * root) {
return;
}
+/* Main, is well, main. It brings everything up and throws
+ us into the mainloop of no return. */
int
main (int argc, char ** argv)
{
@@ -88,6 +256,7 @@ main (int argc, char ** argv)
g_debug("Root ID: %d", dbusmenu_menuitem_get_id(root_menuitem));
create_items(root_menuitem);
+ setup_dkp();
DbusmenuServer * server = dbusmenu_server_new(INDICATOR_SESSION_DBUS_OBJECT);
dbusmenu_server_set_root(server, root_menuitem);
diff --git a/src/status-service.c b/src/status-service.c
index 314929e..e02e70f 100644
--- a/src/status-service.c
+++ b/src/status-service.c
@@ -52,6 +52,7 @@ static void
status_menu_click (DbusmenuMenuitem * mi, gpointer data)
{
StatusProviderStatus status = (StatusProviderStatus)GPOINTER_TO_INT(data);
+ g_debug("Setting status: %d", status);
int i;
for (i = 0; i < STATUS_PROVIDER_CNT; i++) {
status_provider_set_status(status_providers[i], status);