diff options
-rw-r--r-- | debian/changelog | 6 | ||||
-rw-r--r-- | src/status-provider-telepathy.c | 201 | ||||
-rw-r--r-- | src/status-service.c | 6 |
3 files changed, 207 insertions, 6 deletions
diff --git a/debian/changelog b/debian/changelog index 706ba6d..a9ce76c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +indicator-session (0.1~bzr17-0ubuntu1~ppa2~morestatus2) UNRELEASED; urgency=low + + * More status... + + -- Ted Gould <ted@ubuntu.com> Mon, 24 Aug 2009 23:38:48 -0500 + indicator-session (0.1~bzr17-0ubuntu1~ppa2~morestatus1) karmic; urgency=low * Merging in the status work branch diff --git a/src/status-provider-telepathy.c b/src/status-provider-telepathy.c index 339ede3..bed962f 100644 --- a/src/status-provider-telepathy.c +++ b/src/status-provider-telepathy.c @@ -30,10 +30,38 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <dbus/dbus-glib.h> +typedef enum { + MC_STATUS_UNSET, + MC_STATUS_OFFLINE, + MC_STATUS_AVAILABLE, + MC_STATUS_AWAY, + MC_STATUS_EXTENDED_AWAY, + MC_STATUS_HIDDEN, + MC_STATUS_DND +} mc_status_t; + +static StatusProviderStatus mc_to_sp_map[] = { + /* MC_STATUS_UNSET, */ STATUS_PROVIDER_STATUS_OFFLINE, + /* MC_STATUS_OFFLINE, */ STATUS_PROVIDER_STATUS_OFFLINE, + /* MC_STATUS_AVAILABLE, */ STATUS_PROVIDER_STATUS_ONLINE, + /* MC_STATUS_AWAY, */ STATUS_PROVIDER_STATUS_AWAY, + /* MC_STATUS_EXTENDED_AWAY, */ STATUS_PROVIDER_STATUS_AWAY, + /* MC_STATUS_HIDDEN, */ STATUS_PROVIDER_STATUS_INVISIBLE, + /* MC_STATUS_DND */ STATUS_PROVIDER_STATUS_DND +}; + +static mc_status_t sp_to_mc_map[] = { + /* STATUS_PROVIDER_STATUS_ONLINE, */ MC_STATUS_AVAILABLE, + /* STATUS_PROVIDER_STATUS_AWAY, */ MC_STATUS_AWAY, + /* STATUS_PROVIDER_STATUS_DND */ MC_STATUS_DND, + /* STATUS_PROVIDER_STATUS_INVISIBLE*/ MC_STATUS_HIDDEN, + /* STATUS_PROVIDER_STATUS_OFFLINE */ MC_STATUS_OFFLINE +}; typedef struct _StatusProviderTelepathyPrivate StatusProviderTelepathyPrivate; struct _StatusProviderTelepathyPrivate { DBusGProxy * proxy; + mc_status_t mc_status; }; #define STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(o) \ @@ -45,6 +73,12 @@ static void status_provider_telepathy_class_init (StatusProviderTelepathyClass * static void status_provider_telepathy_init (StatusProviderTelepathy *self); static void status_provider_telepathy_dispose (GObject *object); static void status_provider_telepathy_finalize (GObject *object); +/* Internal Funcs */ +static void set_status (StatusProvider * sp, StatusProviderStatus status); +static StatusProviderStatus get_status (StatusProvider * sp); +static void changed_status (DBusGProxy * proxy, guint status, gchar * message, StatusProvider * sp); +static void proxy_destroy (DBusGProxy * proxy, StatusProvider * sp); +static void get_status_async (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata); G_DEFINE_TYPE (StatusProviderTelepathy, status_provider_telepathy, STATUS_PROVIDER_TYPE); @@ -58,10 +92,10 @@ status_provider_telepathy_class_init (StatusProviderTelepathyClass *klass) object_class->dispose = status_provider_telepathy_dispose; object_class->finalize = status_provider_telepathy_finalize; - //StatusProviderClass * spclass = STATUS_PROVIDER_CLASS(klass); + StatusProviderClass * spclass = STATUS_PROVIDER_CLASS(klass); - //spclass->set_status = set_status; - //spclass->get_status = get_status; + spclass->set_status = set_status; + spclass->get_status = get_status; return; } @@ -70,7 +104,56 @@ status_provider_telepathy_class_init (StatusProviderTelepathyClass *klass) static void status_provider_telepathy_init (StatusProviderTelepathy *self) { - //StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(self); + StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(self); + + priv->proxy = NULL; + priv->mc_status = MC_STATUS_OFFLINE; + + GError * error = NULL; + + DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); + + priv->proxy = NULL; + priv->proxy = dbus_g_proxy_new_for_name_owner(session_bus, + "org.freedesktop.Telepathy.MissionControl", + "/org/freedesktop/Telepathy/MissionControl", + "org.freedesktop.Telepathy.MissionControl", + &error); + + if (priv->proxy != NULL) { + g_object_add_weak_pointer (G_OBJECT(priv->proxy), (gpointer *)&priv->proxy); + g_signal_connect(G_OBJECT(priv->proxy), "destroy", + G_CALLBACK(proxy_destroy), self); + + dbus_g_object_register_marshaller(_status_provider_telepathy_marshal_VOID__UINT_STRING, + G_TYPE_NONE, + G_TYPE_UINT, + G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_add_signal (priv->proxy, + "PresenceChanged", + G_TYPE_UINT, + G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal(priv->proxy, + "PresenceChanged", + G_CALLBACK(changed_status), + (void *)self, + NULL); + + /* Do a get here, to init the status */ + dbus_g_proxy_begin_call(priv->proxy, + "GetStatus", + get_status_async, + self, + NULL, + G_TYPE_INVALID); + } else { + g_warning("Unable to connect to Mission Control"); + if (error != NULL) { + g_error_free(error); + } + } return; } @@ -111,3 +194,113 @@ status_provider_telepathy_new (void) return STATUS_PROVIDER(g_object_new(STATUS_PROVIDER_TELEPATHY_TYPE, NULL)); } +static void +set_status (StatusProvider * sp, StatusProviderStatus status) +{ + StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(sp); + if (priv->proxy == NULL) { + priv->mc_status = MC_STATUS_OFFLINE; + return; + } + + priv->mc_status = sp_to_mc_map[status]; + + guint mcstatus = MC_STATUS_UNSET; + gboolean ret = FALSE; + GError * error = NULL; + + ret = dbus_g_proxy_call(priv->proxy, + "GetPresence", &error, + G_TYPE_INVALID, + G_TYPE_UINT, &priv->mc_status, + G_TYPE_INVALID); + + /* If we can't get the get call to work, let's not set */ + if (!ret) { + if (error != NULL) { + g_error_free(error); + } + return; + } + + /* If the get call doesn't return a status, that means that there + are no clients connected. We don't want to connect them by telling + MC that we're going online -- we'd like to be more passive than that. */ + if (mcstatus == MC_STATUS_UNSET) { + return; + } + + ret = dbus_g_proxy_call(priv->proxy, + "SetPresence", &error, + G_TYPE_UINT, priv->mc_status, + G_TYPE_STRING, "", + G_TYPE_INVALID, + G_TYPE_INVALID); + + if (!ret) { + if (error != NULL) { + g_warning("Unable to set Mission Control Presence: %s", error->message); + g_error_free(error); + } else { + g_warning("Unable to set Mission Control Presence"); + } + return; + } + + return; +} + +static StatusProviderStatus +get_status (StatusProvider * sp) +{ + StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(sp); + + if (priv->proxy == NULL) { + return mc_to_sp_map[MC_STATUS_OFFLINE]; + } + + return mc_to_sp_map[priv->mc_status]; +} + +static void +changed_status (DBusGProxy * proxy, guint status, gchar * message, StatusProvider * sp) +{ + StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(sp); + priv->mc_status = status; + g_signal_emit(G_OBJECT(sp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, mc_to_sp_map[priv->mc_status], TRUE); +} + +static void +proxy_destroy (DBusGProxy * proxy, StatusProvider * sp) +{ + g_debug("Signal: Mission Control proxy destroyed"); + g_signal_emit(G_OBJECT(sp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, STATUS_PROVIDER_STATUS_OFFLINE, TRUE); + return; +} + +static void +get_status_async (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata) +{ + GError * error = NULL; + guint status = 0; + if (!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_UINT, &status, G_TYPE_INVALID)) { + g_warning("Unable to get type from Mission Control: %s", error->message); + g_error_free(error); + return; + } + + StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(userdata); + + gboolean changed = FALSE; + if (status != priv->mc_status) { + changed = TRUE; + } + + priv->mc_status = status; + + if (changed) { + g_signal_emit(G_OBJECT(userdata), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, mc_to_sp_map[priv->mc_status], TRUE); + } + + return; +} diff --git a/src/status-service.c b/src/status-service.c index 5a9d9b5..5a60fa6 100644 --- a/src/status-service.c +++ b/src/status-service.c @@ -39,11 +39,13 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include "status-provider.h" #include "status-provider-pidgin.h" +#include "status-provider-telepathy.h" typedef StatusProvider * (*newfunc) (void); -#define STATUS_PROVIDER_CNT 1 +#define STATUS_PROVIDER_CNT 2 static newfunc status_provider_newfuncs[STATUS_PROVIDER_CNT] = { - status_provider_pidgin_new + status_provider_pidgin_new, + status_provider_telepathy_new }; static StatusProvider * status_providers[STATUS_PROVIDER_CNT] = { 0 }; |