← Back to team overview

ayatana-commits team mailing list archive

[Merge] lp:~ken-vandine/indicator-me/gdbus into lp:indicator-me

 

Ken VanDine has proposed merging lp:~ken-vandine/indicator-me/gdbus into lp:indicator-me.

Requested reviews:
  Indicator Applet Developers (indicator-applet-developers)

For more details, see:
https://code.launchpad.net/~ken-vandine/indicator-me/gdbus/+merge/46178
-- 
https://code.launchpad.net/~ken-vandine/indicator-me/gdbus/+merge/46178
Your team ayatana-commits is subscribed to branch lp:indicator-me.
=== modified file '.bzrignore'
--- .bzrignore	2010-01-11 14:41:00 +0000
+++ .bzrignore	2011-01-13 20:41:26 +0000
@@ -59,5 +59,5 @@
 src/libme.la
 src/libme_la-indicator-me.lo
 po/indicator-me.pot
-src/me-service-client.h
-src/me-service-server.h
+src/gen-me-service.xml.c
+src/gen-me-service.xml.h

=== modified file 'configure.ac'
--- configure.ac	2011-01-10 21:16:11 +0000
+++ configure.ac	2011-01-13 20:41:26 +0000
@@ -31,19 +31,23 @@
 INDICATOR_REQUIRED_VERSION=0.3.0
 GWIBBER_REQUIRED_VERSION=0.0.4
 DBUSMENUGLIB_REQUIRED_VERSION=0.3.90
+DBUSMENUGTK_REQUIRED_VERSION=0.3.90
 TELEPATHYGLIB_REQUIRED_VERSION=0.9.0
 GCONF_REQUIRED_VERSION=2.0.0
 INDICATOR_DISPLAY_OBJECTS=0.1
+GIO_UNIX_REQUIRED_VERSION=2.22
 
 PKG_CHECK_MODULES(APPLET,        gtk+-2.0 >= $GTK_REQUIRED_VERSION
                                  indicator >= $INDICATOR_REQUIRED_VERSION
 				 libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS
                                  dbus-glib-1
-                                 dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION)
+                                 dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
+                                 dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION)
 PKG_CHECK_MODULES(MESERVICE,     dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
 				 gconf-2.0 >= $GCONF_REQUIRED_VERSION
                                  indicator >= $INDICATOR_REQUIRED_VERSION
                                  gwibber >= $GWIBBER_REQUIRED_VERSION
+                                 gio-unix-2.0 >= $GIO_UNIX_REQUIRED_VERSION
                                  telepathy-glib >= $TELEPATHYGLIB_REQUIRED_VERSION)
 
 ###########################

=== modified file 'src/Makefile.am'
--- src/Makefile.am	2010-02-17 22:52:43 +0000
+++ src/Makefile.am	2011-01-13 20:41:26 +0000
@@ -12,7 +12,8 @@
 	about-me-menu-item.h \
 	indicator-me.c \
 	dbus-shared-names.h \
-	me-service-client.h
+	gen-me-service.xml.h \
+	gen-me-service.xml.c
 libme_la_CFLAGS = $(APPLET_CFLAGS) -Wall -Werror
 libme_la_LIBADD = $(APPLET_LIBS)
 libme_la_LDFLAGS = -module -avoid-version
@@ -27,7 +28,8 @@
 	me-service.c \
 	me-service-dbus.h \
 	me-service-dbus.c \
-	me-service-server.h \
+	gen-me-service.xml.h \
+	gen-me-service.xml.c \
 	me-service-gwibber.c \
 	me-service-gwibber.h \
 	status-provider.h \
@@ -47,19 +49,15 @@
 indicator_me_service_CFLAGS = $(MESERVICE_CFLAGS) -Wall -Werror
 indicator_me_service_LDADD = $(MESERVICE_LIBS)
 
-me-service-client.h: $(srcdir)/me-service.xml
-	dbus-binding-tool \
-		--prefix=_me_service_client \
-		--mode=glib-client \
-		--output=me-service-client.h \
-		$(srcdir)/me-service.xml
+gen-%.xml.h: %.xml
+	@echo "Building $@ from $<"
+	@echo "extern const char * _$(subst -,_,$(subst .,_,$(basename $<)));" > $@
 
-me-service-server.h: $(srcdir)/me-service.xml
-	dbus-binding-tool \
-		--prefix=_me_service_server \
-		--mode=glib-server \
-		--output=me-service-server.h \
-		$(srcdir)/me-service.xml
+gen-%.xml.c: %.xml
+	@echo "Building $@ from $<"
+	@echo "const char * _$(subst -,_,$(subst .,_,$(basename $<))) = " > $@
+	@sed -e "s:\":\\\\\":g" -e s:^:\": -e s:\$$:\\\\n\": $< >> $@
+	@echo ";" >> $@
 
 status-provider-pidgin-marshal.h: $(srcdir)/status-provider-pidgin.list
 	glib-genmarshal --header \
@@ -96,8 +94,8 @@
 ###############
 
 BUILT_SOURCES = \
-	me-service-client.h \
-	me-service-server.h \
+	gen-me-service.xml.h \
+	gen-me-service.xml.c \
 	status-provider-mc5-marshal.h \
 	status-provider-mc5-marshal.c \
 	status-provider-pidgin-marshal.h \
@@ -113,4 +111,3 @@
 
 CLEANFILES = \
 	$(BUILT_SOURCES)
-

=== modified file 'src/indicator-me.c'
--- src/indicator-me.c	2011-01-10 21:16:11 +0000
+++ src/indicator-me.c	2011-01-13 20:41:26 +0000
@@ -25,12 +25,10 @@
 #include <glib.h>
 #include <glib-object.h>
 #include <gtk/gtk.h>
+#include <gio/gio.h>
 #include <libdbusmenu-glib/menuitem.h>
 #include <libdbusmenu-gtk/menu.h>
 
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-bindings.h>
-
 #include <libindicator/indicator.h>
 #include <libindicator/indicator-object.h>
 #include <libindicator/indicator-service-manager.h>
@@ -40,7 +38,7 @@
 #include "about-me-menu-item.h"
 
 #include "dbus-shared-names.h"
-#include "me-service-client.h"
+#include "gen-me-service.xml.h"
 
 #define INDICATOR_ME_TYPE            (indicator_me_get_type ())
 #define INDICATOR_ME(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_ME_TYPE, IndicatorMe))
@@ -72,7 +70,9 @@
 /* Globals */
 static GtkImage * status_image = NULL;
 static GtkLabel *label = NULL;
-static DBusGProxy * status_proxy = NULL;
+static GDBusProxy * status_proxy = NULL;
+
+static GCancellable * status_proxy_cancel = NULL;
 
 static IdoEntryMenuItem *ido_entry = NULL;
 
@@ -86,13 +86,19 @@
 static void indicator_me_dispose    (GObject *object);
 static void indicator_me_finalize   (GObject *object);
 static void connection_changed      (IndicatorServiceManager * sm, gboolean connected, gpointer userdata);
-static void status_icon_cb (DBusGProxy * proxy, char * icons, GError *error, gpointer userdata);
+static void receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, GVariant * parameters, gpointer user_data);
+
 static gboolean new_entry_item (DbusmenuMenuitem * newitem,
                                 DbusmenuMenuitem * parent,
                                 DbusmenuClient   * client);
 static void     entry_activate_cb (GtkEntry *entry, DbusmenuMenuitem *mi);
 static void     entry_prop_change_cb (DbusmenuMenuitem *mi, gchar *prop, GVariant *value, GtkEntry *entry);
 static gboolean entry_hint_is_shown (GtkWidget *widget);
+static void status_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data);
+static void status_icon_changed (IndicatorMe * self, gchar * icon);
+static void status_icon_cb (GObject * object, GAsyncResult * res, gpointer user_data);
+static void username_changed (IndicatorMe * self, gchar * username);
+static void username_cb (GObject * object, GAsyncResult * res, gpointer user_data);
 
 G_DEFINE_TYPE (IndicatorMe, indicator_me, INDICATOR_OBJECT_TYPE);
 
@@ -129,21 +135,65 @@
 static void
 indicator_me_dispose (GObject *object)
 {
+        IndicatorMe * self = INDICATOR_ME(object);
+
+	if (self->service != NULL) {
+		g_object_unref(G_OBJECT(self->service));
+		self->service = NULL;
+	}
+
+	if (status_proxy != NULL) {
+		g_object_unref(status_proxy);
+		status_proxy = NULL;
+	}
+
+	if (status_proxy_cancel != NULL) {
+		g_cancellable_cancel(status_proxy_cancel);
+		g_object_unref(status_proxy_cancel);
+		status_proxy_cancel = NULL;
+	}
 
 	G_OBJECT_CLASS (indicator_me_parent_class)->dispose (object);
+
 	return;
 }
 
 static void
 indicator_me_finalize (GObject *object)
 {
-
 	G_OBJECT_CLASS (indicator_me_parent_class)->finalize (object);
 	return;
 }
 
 static void
-username_cb (DBusGProxy * proxy, char * username, GError *error, gpointer userdata)
+username_cb (GObject * object, GAsyncResult * res, gpointer user_data)
+{
+	GError * error = NULL;
+	gchar * username;
+	GVariant * result;
+
+	IndicatorMe * self = INDICATOR_ME (user_data);
+	g_return_if_fail(self != NULL);
+
+	result = g_dbus_proxy_call_finish(status_proxy, res, &error);
+	g_return_if_fail(status_proxy != NULL);
+
+	if (error != NULL) {
+		g_error("Could not get the username %s", error->message);
+		g_error_free(error);
+		return;
+	}
+
+	g_variant_get(result, "(&s)", &username);
+
+	if (username != NULL) {
+		username_changed (self, username);
+	}
+
+}
+
+static void
+username_changed (IndicatorMe * self, gchar * username)
 {
   if (label == NULL) {
     label = GTK_LABEL(gtk_label_new(NULL));
@@ -163,11 +213,10 @@
 static GtkLabel *
 get_label (IndicatorObject * io)
 {
-  if (label == NULL) {
+	if (label == NULL) {
 		/* Create the label if it doesn't exist already */
-    username_cb (NULL, NULL, NULL, NULL);
-  }
-
+		username_changed (NULL, NULL);
+	}
 	return label;
 }
 
@@ -176,35 +225,74 @@
 {
 	if (status_image == NULL) {
 		/* Will create the status icon if it doesn't exist already */
-		status_icon_cb(NULL, DEFAULT_ICON, NULL, NULL);
+		status_icon_changed(NULL, DEFAULT_ICON);
 	}
 	return status_image;
 }
 
 static void
-status_icon_cb (DBusGProxy * proxy, char * icons, GError *error, gpointer userdata)
-{
-	g_return_if_fail(icons != NULL);
-	g_return_if_fail(icons[0] != '\0');
+status_icon_cb (GObject * object, GAsyncResult * res, gpointer user_data)
+{
+	GError * error = NULL;
+	gchar * icon = NULL;
+	GVariant * result;
+
+	IndicatorMe * self = INDICATOR_ME (user_data);
+	g_return_if_fail(self != NULL);
+
+	result = g_dbus_proxy_call_finish(status_proxy, res, &error);
+	g_return_if_fail(status_proxy != NULL);
+
+	if (error != NULL) {
+		g_error("Could not get the username %s", error->message);
+		g_error_free(error);
+		return;
+	}
+
+	g_variant_get(result, "(&s)", &icon);
+
+	if (icon != NULL) {
+		status_icon_changed (self, icon);
+	}
+
+}
+
+static void
+status_icon_changed (IndicatorMe * self, gchar * icon)
+{
+	g_return_if_fail(icon != NULL);
+	g_return_if_fail(icon[0] != '\0');
 
 	if (status_image == NULL) {
-    status_image = indicator_image_helper (DEFAULT_ICON "-panel");
+		status_image = indicator_image_helper (DEFAULT_ICON "-panel");
 		gtk_widget_show(GTK_WIDGET(status_image));
 	}
 
-  gchar *panel_icon = g_strconcat (icons, "-panel", NULL);
-  indicator_image_helper_update (status_image, panel_icon);
-  g_free (panel_icon);
+	gchar *panel_icon = g_strconcat (icon, "-panel", NULL);
+	indicator_image_helper_update (status_image, panel_icon);
+	g_free (panel_icon);
 
 	return;
 }
 
+/* Receives all signals from the service, routed to the appropriate functions */
 static void
-status_icon_changed (DBusGProxy * proxy, gchar * icon, gpointer userdata)
+receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name,
+                GVariant * parameters, gpointer user_data)
 {
-	g_debug("Changing status icon: '%s'", icon);
+        IndicatorMe * self = INDICATOR_ME(user_data);
 
-	return status_icon_cb(proxy, icon, NULL, NULL);
+        if (g_strcmp0(signal_name, "StatusIconsChanged") == 0) {
+                gchar * icon;
+                g_variant_get (parameters, "(&s)", &icon);
+                status_icon_changed (self, icon);
+        }
+        else if (g_strcmp0(signal_name, "UserChanged") == 0) {
+                gchar * username;
+                g_variant_get (parameters, "(&s)", &username);
+                username_changed(self, username);
+        }
+	return;
 }
 
 static void
@@ -221,61 +309,92 @@
 }
 
 static void
-connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer userdata)
+connection_changed (IndicatorServiceManager * self, gboolean connected, gpointer userdata)
 {
 	if (connected) {
 		if (status_proxy == NULL) {
-			GError * error = NULL;
-
-			DBusGConnection * sbus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
-
-			status_proxy = dbus_g_proxy_new_for_name_owner(sbus,
-                                                     INDICATOR_ME_DBUS_NAME,
-                                                     INDICATOR_ME_SERVICE_DBUS_OBJECT,
-                                                     INDICATOR_ME_SERVICE_DBUS_INTERFACE,
-                                                     &error);
-
-			if (error != NULL) {
-				g_warning("Unable to get status proxy: %s", error->message);
-				g_error_free(error);
-			}
-
-      if (status_proxy == NULL) return;
-
-			dbus_g_proxy_add_signal(status_proxy, "StatusIconsChanged", G_TYPE_STRING, G_TYPE_INVALID);
-			dbus_g_proxy_connect_signal(status_proxy, "StatusIconsChanged", G_CALLBACK(status_icon_changed), NULL, NULL);
-
-			dbus_g_proxy_add_signal(status_proxy, "UserChanged", G_TYPE_STRING, G_TYPE_INVALID);
-			dbus_g_proxy_connect_signal(status_proxy, "UserChanged", G_CALLBACK(username_cb), NULL, NULL);
+			status_proxy_cancel = g_cancellable_new();
+
+			g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+						G_DBUS_PROXY_FLAGS_NONE,
+						NULL,
+						INDICATOR_ME_DBUS_NAME,
+						INDICATOR_ME_SERVICE_DBUS_OBJECT,
+						INDICATOR_ME_SERVICE_DBUS_INTERFACE,
+						status_proxy_cancel,
+						status_proxy_cb,
+						userdata);
+
 		}
-
-		org_ayatana_indicator_me_service_status_icons_async(status_proxy, status_icon_cb, NULL);
-
-    /* query the service for the username to display */
-		org_ayatana_indicator_me_service_pretty_user_name_async(status_proxy, username_cb, NULL);
 	} else {
-    DbusmenuMenuitem *mi = g_object_get_data (G_OBJECT (ido_entry),
+		DbusmenuMenuitem *mi = g_object_get_data (G_OBJECT (ido_entry),
                                               "dbusmenuitem");
 
-    g_signal_handlers_disconnect_by_func (ido_entry,
+		g_signal_handlers_disconnect_by_func (ido_entry,
                                           G_CALLBACK (entry_activate_cb),
                                           mi);
 
-    g_signal_handlers_disconnect_by_func (ido_entry,
+		g_signal_handlers_disconnect_by_func (ido_entry,
                                           G_CALLBACK (entry_prop_change_cb),
                                           mi);
 
 		/* If we're disconnecting, go back to offline */
-		status_icon_cb(NULL, DEFAULT_ICON, NULL, NULL);
-
-    g_object_unref (status_proxy);
-    status_proxy = NULL;
-
-    if (ido_entry != NULL) {
-      gtk_widget_destroy (GTK_WIDGET (ido_entry));
-      ido_entry = NULL;
-    }
-	}
+		status_icon_changed(NULL, DEFAULT_ICON);
+
+		g_object_unref (status_proxy);
+		status_proxy = NULL;
+
+		if (ido_entry != NULL) {
+			gtk_widget_destroy (GTK_WIDGET (ido_entry));
+			ido_entry = NULL;
+		}
+	}
+
+	return;
+}
+
+/* Callback from trying to create the proxy for the service, this
+   could include starting the service.  Sometimes it'll fail and
+   we'll try to start that dang service again! */
+static void
+status_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data)
+{
+	GError * error = NULL;
+
+	g_return_if_fail(object != NULL);
+
+	IndicatorMe * self = INDICATOR_ME (user_data);
+
+	GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
+
+	if (status_proxy_cancel != NULL) {
+		g_object_unref(status_proxy_cancel);
+		status_proxy_cancel = NULL;
+	}
+
+	if (error != NULL) {
+		g_error("Could not grab DBus proxy for %s: %s", INDICATOR_ME_DBUS_NAME, error->message);
+		g_error_free(error);
+		return;
+	}
+
+	/* Okay, we're good to grab the proxy at this point, we're
+	sure that it's ours. */
+	status_proxy = proxy;
+
+	g_signal_connect(status_proxy, "g-signal", G_CALLBACK(receive_signal), self);
+
+	/* Query to get the username */
+	g_debug("Get the username");
+	g_dbus_proxy_call(status_proxy, "PrettyUserName", NULL,
+		G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+		(GAsyncReadyCallback) username_cb, self);
+
+	/* Query to get the status icon */
+	g_debug("Get the status icon");
+	g_dbus_proxy_call(status_proxy, "StatusIcons", NULL,
+		G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+		(GAsyncReadyCallback) status_icon_cb, self);
 
 	return;
 }

=== modified file 'src/me-service-dbus.c'
--- src/me-service-dbus.c	2010-02-24 19:54:33 +0000
+++ src/me-service-dbus.c	2011-01-13 20:41:26 +0000
@@ -24,8 +24,9 @@
 #include "config.h"
 #endif
 
-#include <dbus/dbus-glib.h>
+#include <gio/gio.h>
 
+#include "gen-me-service.xml.h"
 #include "dbus-shared-names.h"
 #include "me-service-dbus.h"
 
@@ -33,16 +34,28 @@
 static void status_service_dbus_init       (StatusServiceDbus *self);
 static void status_service_dbus_dispose    (GObject *object);
 static void status_service_dbus_finalize   (GObject *object);
-static gboolean _me_service_server_watch (StatusServiceDbus * service, GError ** error);
-static gboolean _me_service_server_status_icons (StatusServiceDbus * service, gchar ** icon, GError ** error);
-static gboolean _me_service_server_pretty_user_name (StatusServiceDbus * service, gchar ** username, GError ** error);
-
-#include "me-service-server.h"
-
-/* Private */
+static GVariant * get_icon (StatusServiceDbus * service);
+static GVariant * get_username (StatusServiceDbus * service);
+static GVariant * status_service_dbus_watch (StatusServiceDbus * service);
+static void bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data);
+static void bus_method_call (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * method, GVariant * params, GDBusMethodInvocation * invocation, gpointer user_data);
+
+
+	
+/**
+	StatusServiceDbusPrivate:
+	@dbus_registration: The handle for this object being registered
+		on dbus.
+
+	Structure to define the memory for the private area
+	of the status service dbus instance.
+*/
 typedef struct _StatusServiceDbusPrivate StatusServiceDbusPrivate;
 struct _StatusServiceDbusPrivate
 {
+	GDBusConnection * bus;
+	GCancellable * bus_cancel;
+	guint dbus_registration;
 	gchar * name;
 	gchar * icon;
 };
@@ -50,15 +63,15 @@
 #define STATUS_SERVICE_DBUS_GET_PRIVATE(o) \
     (G_TYPE_INSTANCE_GET_PRIVATE ((o), STATUS_SERVICE_DBUS_TYPE, StatusServiceDbusPrivate))
 
-/* Signals */
-enum {
-	USER_CHANGED,
-	STATUS_ICONS_CHANGED,
-	LAST_SIGNAL
+/* GDBus Stuff */
+static GDBusNodeInfo *      node_info = NULL;
+static GDBusInterfaceInfo * interface_info = NULL;
+static GDBusInterfaceVTable interface_table = {
+       method_call:    bus_method_call,
+       get_property:   NULL, /* No properties */
+       set_property:   NULL  /* No properties */
 };
 
-static guint signals[LAST_SIGNAL] = { 0 };
-
 /* GObject Boilerplate */
 G_DEFINE_TYPE (StatusServiceDbus, status_service_dbus, G_TYPE_OBJECT);
 
@@ -72,64 +85,135 @@
 	object_class->dispose = status_service_dbus_dispose;
 	object_class->finalize = status_service_dbus_finalize;
 
-	/**
-		StatusServiceDbus::user-changed:
-		@arg0: The #StatusServiceDbus object.
-		@arg1: The place to put the new user name
-
-		Signals that the user name has changed and gives the
-		new user name.
-	*/
-	signals[USER_CHANGED]      = g_signal_new("user-changed",
-	                                          G_TYPE_FROM_CLASS(klass),
-	                                          G_SIGNAL_RUN_LAST,
-	                                          G_STRUCT_OFFSET(StatusServiceDbusClass, user_changed),
-	                                          NULL, NULL,
-	                                          g_cclosure_marshal_VOID__STRING,
-	                                          G_TYPE_NONE, 1, G_TYPE_STRING);
-
-	/**
-		StatusServiceDbus::status-icons-changed:
-		@arg0: The #StatusServiceDbus object.
-		@arg1: The list of icon names representing the statuses in
-		       the order they should be displayed.  Left to right.
-
-		Signals that the user status set has changed and that
-		new icons may need to be loaded.  The list of icons will
-		always be complete.
-	*/
-	signals[STATUS_ICONS_CHANGED] = g_signal_new("status-icons-changed",
-	                                             G_TYPE_FROM_CLASS(klass),
-	                                             G_SIGNAL_RUN_LAST,
-	                                             G_STRUCT_OFFSET(StatusServiceDbusClass, status_icons_changed),
-	                                             NULL, NULL,
-	                                             g_cclosure_marshal_VOID__STRING,
-	                                             G_TYPE_NONE, 1, G_TYPE_STRING);
-
-	dbus_g_object_type_install_info(STATUS_SERVICE_DBUS_TYPE, &dbus_glib__me_service_server_object_info);
-	
+	/* Setting up the DBus interfaces */
+	if (node_info == NULL) {
+		GError * error = NULL;
+
+		node_info = g_dbus_node_info_new_for_xml(_me_service, &error);
+		if (error != NULL) {
+			g_error("Unable to parse Me Service Interface description: %s", error->message);
+			g_error_free(error);
+		}
+	}
+
+	if (interface_info == NULL) {
+		interface_info = g_dbus_node_info_lookup_interface(node_info, INDICATOR_ME_SERVICE_DBUS_INTERFACE);
+
+		if (interface_info == NULL) {
+			g_error("Unable to find interface '" INDICATOR_ME_SERVICE_DBUS_INTERFACE "'");
+		}
+	}
+
 	return;
 }
 
 static void
 status_service_dbus_init (StatusServiceDbus *self)
 {
-
-	DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
-	dbus_g_connection_register_g_object(connection,
-										INDICATOR_ME_SERVICE_DBUS_OBJECT,
-										G_OBJECT(self));
-
 	StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(self);
 	priv->name = NULL;
 	priv->icon = NULL;
 
-	return;
-}
+	priv->bus = NULL;
+	priv->bus_cancel = NULL;
+	priv->dbus_registration = 0;
+
+	priv->bus_cancel = g_cancellable_new();
+	g_bus_get(G_BUS_TYPE_SESSION,
+		priv->bus_cancel,
+		bus_get_cb,
+		self);
+
+	return;
+}
+
+static void
+bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data)
+{
+	GError * error = NULL;
+	GDBusConnection * connection = g_bus_get_finish(res, &error);
+
+	if (error != NULL) {
+		g_error("OMG! Unable to get a connection to DBus: %s", error->message);
+		g_error_free(error);
+		return;
+	}
+
+	StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(user_data);
+
+	g_warn_if_fail(priv->bus == NULL);
+	priv->bus = connection;
+
+	if (priv->bus_cancel != NULL) {
+		g_object_unref(priv->bus_cancel);
+		priv->bus_cancel = NULL;
+	}
+
+	/* Now register our object on our new connection */
+	priv->dbus_registration = g_dbus_connection_register_object(connection,
+                                                                   INDICATOR_ME_SERVICE_DBUS_OBJECT,
+                                                                   interface_info,
+                                                                   &interface_table,
+                                                                   user_data,
+                                                                   NULL,
+                                                                   &error);
+
+	if (error != NULL) {
+		g_error("Unable to register the object to DBus: %s", error->message);
+		g_error_free(error);
+		return;
+	}
+
+	return; 
+}
+
+/* A method has been called from our dbus inteface.  Figure out what it
+   is and dispatch it. */
+static void
+bus_method_call (GDBusConnection * connection, const gchar * sender,
+                 const gchar * path, const gchar * interface,
+                 const gchar * method, GVariant * params,
+                 GDBusMethodInvocation * invocation, gpointer user_data)
+{
+	StatusServiceDbus * service = STATUS_SERVICE_DBUS(user_data);
+	GVariant * retval = NULL;
+
+	if (g_strcmp0(method, "PrettyUserName") == 0) {
+		retval = get_username(service);
+	} else if (g_strcmp0(method, "StatusIcons") == 0) {
+		retval = get_icon(service);
+	} else if (g_strcmp0(method, "Watch") == 0) {
+		retval = status_service_dbus_watch(service);
+	} else {
+		g_warning("Calling method '%s' on the indicator service and it's unknown", method);
+	}
+
+	g_dbus_method_invocation_return_value(invocation, retval);
+	return;
+}
+
 
 static void
 status_service_dbus_dispose (GObject *object)
 {
+	StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(object);
+
+	if (priv->dbus_registration != 0) {
+		g_dbus_connection_unregister_object(priv->bus, priv->dbus_registration);
+		/* Don't care if it fails, there's nothing we can do */
+		priv->dbus_registration = 0;
+	}
+
+	if (priv->bus != NULL) {
+		g_object_unref(priv->bus);
+		priv->bus = NULL;
+	}
+
+	if (priv->bus_cancel != NULL) {
+		g_cancellable_cancel(priv->bus_cancel);
+		g_object_unref(priv->bus_cancel);
+		priv->bus_cancel = NULL;
+	}
 
 	G_OBJECT_CLASS (status_service_dbus_parent_class)->dispose (object);
 	return;
@@ -143,47 +227,25 @@
 	return;
 }
 
-static gboolean
-_me_service_server_watch (StatusServiceDbus * service, GError ** error)
-{
-
-	return TRUE;
-}
-
-static gboolean
-_me_service_server_status_icons (StatusServiceDbus * service, gchar ** icon, GError ** error)
-{
-	if (!IS_STATUS_SERVICE_DBUS(service)) {
-		g_warning("NO BAD EVIL!");
-		return FALSE;
-	}
-
-	StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(service);
-	if (priv->icon == NULL) {
-		*icon = g_strdup("");
-	} else {
-		*icon = g_strdup(priv->icon);
-	}
-
-	return TRUE;
-}
-
-static gboolean
-_me_service_server_pretty_user_name (StatusServiceDbus * service, gchar ** username, GError ** error)
-{
-	if (!IS_STATUS_SERVICE_DBUS(service)) {
-		g_warning("NO BAD EVIL!");
-		return FALSE;
-	}
-
-	StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(service);
-	if (priv->name == NULL) {
-		*username = g_strdup("");
-	} else {
-		*username = g_strdup(priv->name);
-	}
-
-	return TRUE;
+static GVariant *
+status_service_dbus_watch (StatusServiceDbus * service)
+{
+	return g_variant_new("(b)", TRUE);
+}
+
+
+static GVariant *
+get_username (StatusServiceDbus * service)
+{
+	StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(service);
+        return g_variant_new("(s)", priv->name);
+}
+
+static GVariant *
+get_icon (StatusServiceDbus * service)
+{
+	StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(service);
+        return g_variant_new("(s)", priv->icon);
 }
 
 void
@@ -195,12 +257,31 @@
 
 	StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(self);
 
+	GError * error = NULL;
+
 	if (priv->icon != NULL) {
 		g_free(priv->icon);
 	}
 	priv->icon = g_strdup(icon);
 
-	g_signal_emit(G_OBJECT(self), signals[STATUS_ICONS_CHANGED], 0, priv->icon, TRUE);
+	if (priv->bus == NULL) {
+		return;
+	}
+
+	g_dbus_connection_emit_signal (priv->bus,
+                                       NULL,
+                                       INDICATOR_ME_SERVICE_DBUS_OBJECT,
+                                       INDICATOR_ME_SERVICE_DBUS_INTERFACE,
+                                       "StatusIconsChanged",
+                                       g_variant_new("(s)", icon),
+                                       &error);
+
+	if (error != NULL) {
+		g_error("Unable to send StatusIconsChanged signal: %s", error->message);
+		g_error_free(error);
+		return;
+	}
+
 	return;
 }
 
@@ -213,11 +294,30 @@
 
 	StatusServiceDbusPrivate * priv = STATUS_SERVICE_DBUS_GET_PRIVATE(self);
 
+	GError * error = NULL;
+
 	if (priv->name != NULL) {
 		g_free(priv->name);
 	}
 	priv->name = g_strdup(username);
 
-	g_signal_emit(G_OBJECT(self), signals[USER_CHANGED], 0, priv->name, TRUE);
+	if (priv->bus == NULL) {
+		return;
+	}
+
+	g_dbus_connection_emit_signal (priv->bus,
+                                       NULL,
+                                       INDICATOR_ME_SERVICE_DBUS_OBJECT,
+                                       INDICATOR_ME_SERVICE_DBUS_INTERFACE,
+                                       "UserChanged",
+                                       NULL,
+                                       &error);
+
+	if (error != NULL) {
+		g_error("Unable to send UserChanged signal: %s", error->message);
+		g_error_free(error);
+		return;
+	}
+
 	return;
 }


Follow ups