diff options
-rw-r--r-- | debian/changelog | 7 | ||||
-rw-r--r-- | src/dbus-shared-names.h | 12 | ||||
-rw-r--r-- | src/session-service.c | 185 | ||||
-rw-r--r-- | src/status-service.c | 1 |
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); |