← Back to team overview

ayatana-commits team mailing list archive

[Merge] lp:~mterry/indicator-session/gdbus into lp:indicator-session

 

Michael Terry has proposed merging lp:~mterry/indicator-session/gdbus into lp:indicator-session.

Requested reviews:
  Indicator Applet Developers (indicator-applet-developers)
Related bugs:
  #701149 Port the session indicator to the new dbusmenu
  https://bugs.launchpad.net/bugs/701149

For more details, see:
https://code.launchpad.net/~mterry/indicator-session/gdbus/+merge/45885

Ported to gdbus!  (only the actual indicator part, not the bits that talk to other services over dbus)
-- 
https://code.launchpad.net/~mterry/indicator-session/gdbus/+merge/45885
Your team ayatana-commits is subscribed to branch lp:indicator-session.
=== modified file '.bzrignore'
--- .bzrignore	2010-03-17 13:09:07 +0000
+++ .bzrignore	2011-01-11 16:56:36 +0000
@@ -55,8 +55,8 @@
 indicator-session-[0-9].[0-9].[0-9].tar.gz.asc
 indicator-session-[0-9].[0-9].tar.gz.asc
 src/consolekit-manager-client.h
-src/session-dbus-client.h
-src/session-dbus-server.h
+src/gen-session-dbus.xml.c
+src/gen-session-dbus.xml.h
 src/upower-client.h
 src/gdm-local-display-factory-client.h
 src/consolekit-session-client.h

=== modified file 'configure.ac'
--- configure.ac	2010-08-12 16:32:35 +0000
+++ configure.ac	2011-01-11 16:56:36 +0000
@@ -32,14 +32,15 @@
 
 PKG_CHECK_MODULES(APPLET, gtk+-2.0 >= $GTK_REQUIRED_VERSION
                           indicator >= $INDICATOR_REQUIRED_VERSION
-						  dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION)
+                          dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION)
 AC_SUBST(APPLET_CFLAGS)
 AC_SUBST(APPLET_LIBS)
 
 DBUSMENUGLIB_REQUIRED_VERSION=0.1.1
 
-PKG_CHECK_MODULES(SESSIONSERVICE, dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION
-						          dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION
+PKG_CHECK_MODULES(SESSIONSERVICE, dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
+                                  dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
+                                  dbus-glib-1
                                   gio-unix-2.0
                                   indicator >= $INDICATOR_REQUIRED_VERSION)
 

=== modified file 'src/Makefile.am'
--- src/Makefile.am	2010-03-17 13:09:07 +0000
+++ src/Makefile.am	2011-01-11 16:56:36 +0000
@@ -11,7 +11,7 @@
 sessionlib_LTLIBRARIES = libsession.la
 libsession_la_SOURCES = \
 	indicator-session.c \
-	session-dbus-client.h \
+	gen-session-dbus.xml.h \
 	dbus-shared-names.h \
 	dbusmenu-shared.h \
 	users-service-client.h
@@ -54,20 +54,6 @@
 		--output=upower-client.h \
 		$(srcdir)/upower.xml
 
-session-dbus-client.h: $(srcdir)/session-dbus.xml
-	dbus-binding-tool \
-		--prefix=_session_dbus_client \
-		--mode=glib-client \
-		--output=session-dbus-client.h \
-		$(srcdir)/session-dbus.xml
-
-session-dbus-server.h: $(srcdir)/session-dbus.xml
-	dbus-binding-tool \
-		--prefix=_session_dbus_server \
-		--mode=glib-server \
-		--output=session-dbus-server.h \
-		$(srcdir)/session-dbus.xml
-
 users-service-marshal.h: $(srcdir)/users-service.list
 	glib-genmarshal --header \
 		--prefix=_users_service_marshal $(srcdir)/users-service.list \
@@ -78,6 +64,16 @@
 		--prefix=_users_service_marshal $(srcdir)/users-service.list \
 		> users-service-marshal.c
 
+gen-%.xml.c: %.xml
+	@echo "Building $@ from $<"
+	@echo "const char * _$(subst -,_,$(subst .,_,$(basename $<))) = " > $@
+	@sed -e "s:\":\\\\\":g" -e s:^:\": -e s:\$$:\\\\n\": $< >> $@
+	@echo ";" >> $@
+
+gen-%.xml.h: %.xml
+	@echo "Building $@ from $<"
+	@echo "extern const char * _$(subst -,_,$(subst .,_,$(basename $<)));" > $@
+
 #################
 # Session Stuff
 #################
@@ -88,7 +84,7 @@
 	session-service.c \
 	session-dbus.c \
 	session-dbus.h \
-	session-dbus-server.h \
+	gen-session-dbus.xml.c \
 	dbusmenu-shared.h \
 	gconf-helper.c \
 	users-service-dbus.h \
@@ -129,8 +125,8 @@
 	consolekit-manager-client.h \
 	consolekit-session-client.h \
 	gdm-local-display-factory-client.h \
-	session-dbus-client.h \
-	session-dbus-server.h \
+	gen-session-dbus.xml.c \
+	gen-session-dbus.xml.h \
 	upower-client.h \
 	users-service-client.h \
 	users-service-marshal.h \

=== modified file 'src/indicator-session.c'
--- src/indicator-session.c	2010-08-06 18:45:10 +0000
+++ src/indicator-session.c	2011-01-11 16:56:36 +0000
@@ -31,9 +31,6 @@
 #include <gio/gio.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>
@@ -41,7 +38,6 @@
 
 #include "dbus-shared-names.h"
 #include "dbusmenu-shared.h"
-#include "session-dbus-client.h"
 
 #define INDICATOR_SESSION_TYPE            (indicator_session_get_type ())
 #define INDICATOR_SESSION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_SESSION_TYPE, IndicatorSession))
@@ -62,7 +58,8 @@
 	IndicatorServiceManager * service;
 	GtkImage * status_image;
 	DbusmenuGtkMenu * menu;
-	DBusGProxy * service_proxy;
+	GCancellable * service_proxy_cancel;
+	GDBusProxy * service_proxy;
 };
 
 GType indicator_session_get_type (void);
@@ -77,9 +74,11 @@
 static GtkMenu * get_menu (IndicatorObject * io);
 static gboolean build_menu_switch (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
 static gboolean new_user_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
-static void icon_changed (DBusGProxy * proxy, gchar * icon_name, gpointer user_data);
+static void icon_changed (IndicatorSession * session, const gchar * icon_name);
 static void service_connection_cb (IndicatorServiceManager * sm, gboolean connected, gpointer user_data);
 static gboolean build_restart_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
+static void receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, GVariant * parameters, gpointer user_data);
+static void service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data);
 
 static void indicator_session_class_init (IndicatorSessionClass *klass);
 static void indicator_session_init       (IndicatorSession *self);
@@ -109,6 +108,8 @@
 {
 	/* Set good defaults */
 	self->service = NULL;
+	self->service_proxy_cancel = NULL;
+	self->service_proxy = NULL;
 
 	/* Now let's fire these guys up. */
 	self->service = indicator_service_manager_new_version(INDICATOR_SESSION_DBUS_NAME, INDICATOR_SESSION_DBUS_VERSION);
@@ -125,19 +126,50 @@
 	GtkAccelGroup * agroup = gtk_accel_group_new();
 	dbusmenu_gtkclient_set_accel_group(DBUSMENU_GTKCLIENT(client), agroup);
 
-	DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
-	self->service_proxy = dbus_g_proxy_new_for_name(session_bus,
-	                                                INDICATOR_SESSION_DBUS_NAME,
-	                                                INDICATOR_SESSION_SERVICE_DBUS_OBJECT,
-	                                                INDICATOR_SESSION_SERVICE_DBUS_IFACE);
-
-	dbus_g_proxy_add_signal(self->service_proxy, "IconUpdated",
-	                        G_TYPE_STRING, G_TYPE_INVALID);
-	dbus_g_proxy_connect_signal(self->service_proxy,
-	                            "IconUpdated",
-	                            G_CALLBACK(icon_changed),
-	                            self,
-	                            NULL);
+	self->service_proxy_cancel = g_cancellable_new();
+
+	g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+		                  G_DBUS_PROXY_FLAGS_NONE,
+		                  NULL,
+		                  INDICATOR_SESSION_DBUS_NAME,
+		                  INDICATOR_SESSION_SERVICE_DBUS_OBJECT,
+		                  INDICATOR_SESSION_SERVICE_DBUS_IFACE,
+		                  self->service_proxy_cancel,
+		                  service_proxy_cb,
+	                          self);
+
+	return;
+}
+
+/* Callback from trying to create the proxy for the serivce, this
+   could include starting the service.  Sometime it'll fail and
+   we'll try to start that dang service again! */
+static void
+service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data)
+{
+	GError * error = NULL;
+
+	IndicatorSession * self = INDICATOR_SESSION(user_data);
+	g_return_if_fail(self != NULL);
+
+	GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
+
+	if (self->service_proxy_cancel != NULL) {
+		g_object_unref(self->service_proxy_cancel);
+		self->service_proxy_cancel = NULL;
+	}
+
+	if (error != NULL) {
+		g_error("Could not grab DBus proxy for %s: %s", INDICATOR_SESSION_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. */
+	self->service_proxy = proxy;
+
+	g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self);
 
 	return;
 }
@@ -170,18 +202,26 @@
 }
 
 static void
-icon_name_get_cb (DBusGProxy *proxy, char * OUT_name, GError *error, gpointer userdata)
+icon_name_get_cb (GObject * obj, GAsyncResult * res, gpointer user_data)
 {
+	IndicatorSession * self = INDICATOR_SESSION(user_data);
+	GError * error = NULL;
+	gchar * name;
+	GVariant * result;
+
+	result = g_dbus_proxy_call_finish(self->service_proxy, res, &error);
+
 	if (error != NULL) {
 		return;
 	}
 
-	if (OUT_name == NULL || OUT_name[0] == '\0') {
+	g_variant_get(result, "(&s)", &name);
+
+	if (name == NULL || name[0] == '\0') {
 		return;
 	}
 
-	IndicatorSession * self = INDICATOR_SESSION(userdata);
-	indicator_image_helper_update(self->status_image, OUT_name);
+	indicator_image_helper_update(self->status_image, name);
 	return;
 }
 
@@ -191,7 +231,9 @@
 	IndicatorSession * self = INDICATOR_SESSION(user_data);
 
 	if (connected) {
-		org_ayatana_indicator_session_service_get_icon_async(self->service_proxy, icon_name_get_cb, user_data);
+		g_dbus_proxy_call(self->service_proxy, "GetIcon", NULL,
+		                  G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+		                  icon_name_get_cb, user_data);
 	} else {
 		indicator_image_helper_update(self->status_image, ICON_DEFAULT);
 	}
@@ -206,13 +248,28 @@
 }
 
 static void
-icon_changed (DBusGProxy * proxy, gchar * icon_name, gpointer user_data)
+icon_changed (IndicatorSession * session, const gchar * icon_name)
 {
-	IndicatorSession * session = INDICATOR_SESSION(user_data);
 	indicator_image_helper_update(session->status_image, icon_name);
 	return;
 }
 
+/* Receives all signals from the service, routed to the appropriate functions */
+static void
+receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name,
+                GVariant * parameters, gpointer user_data)
+{
+	IndicatorSession * self = INDICATOR_SESSION(user_data);
+
+	if (g_strcmp0(signal_name, "IconUpdated") == 0) {
+		const gchar *name;
+		g_variant_get (parameters, "(&s)", &name);
+		icon_changed(self, name);
+	}
+
+	return;
+}
+
 static GtkImage *
 get_icon (IndicatorObject * io)
 {
@@ -221,10 +278,10 @@
 }
 
 static void
-user_property_change (DbusmenuMenuitem * item, const gchar * property, const GValue * value, gpointer user_data)
+user_property_change (DbusmenuMenuitem * item, const gchar * property, GVariant * variant, gpointer user_data)
 {
 	if (g_strcmp0(property, USER_ITEM_PROP_LOGGED_IN) == 0) {
-		if (g_value_get_boolean(value)) {
+		if (g_variant_get_boolean(variant)) {
 			gtk_widget_show(GTK_WIDGET(user_data));
 		} else {
 			gtk_widget_hide(GTK_WIDGET(user_data));
@@ -308,7 +365,7 @@
 }
 
 static void
-switch_property_change (DbusmenuMenuitem * item, const gchar * property, const GValue * value, gpointer user_data)
+switch_property_change (DbusmenuMenuitem * item, const gchar * property, GVariant * variant, gpointer user_data)
 {
 	if (g_strcmp0(property, MENU_SWITCH_USER) != 0) {
 		return;
@@ -330,13 +387,13 @@
 	/* If there's a NULL string of some type, then we want to
 	   go back to our old 'Switch User' which isn't great but
 	   eh, this error condition should never happen. */
-	if (value == NULL || g_value_get_string(value) == NULL || g_value_get_string(value)[0] == '\0' || no_name_in_lang) {
+	if (variant == NULL || g_variant_get_string(variant, NULL) == NULL || g_variant_get_string(variant, NULL)[0] == '\0' || no_name_in_lang) {
 		finalstring = _("Switch User...");
 		set_ellipsize = FALSE;
 	}
 
 	if (finalstring == NULL) {
-		const gchar * username = g_value_get_string(value);
+		const gchar * username = g_variant_get_string(variant, NULL);
 		GtkStyle * style = gtk_widget_get_style(GTK_WIDGET(gmi));
 
 		PangoLayout * layout = pango_layout_new(gtk_widget_get_pango_context(GTK_WIDGET(gmi)));
@@ -387,17 +444,17 @@
 /* IF the label or icon changes we need to grab that and update
    the menu item */
 static void
-restart_property_change (DbusmenuMenuitem * item, const gchar * property, const GValue * value, gpointer user_data)
+restart_property_change (DbusmenuMenuitem * item, const gchar * property, GVariant * variant, gpointer user_data)
 {
 	DbusmenuGtkClient * client = DBUSMENU_GTKCLIENT(user_data);
 	GtkMenuItem * gmi = dbusmenu_gtkclient_menuitem_get(client, item);
 
 	if (g_strcmp0(property, RESTART_ITEM_LABEL) == 0) {
-		gtk_menu_item_set_label(gmi, g_value_get_string(value));
+		gtk_menu_item_set_label(gmi, g_variant_get_string(variant, NULL));
 	} else if (g_strcmp0(property, RESTART_ITEM_ICON) == 0) {
 		GtkWidget * image = gtk_image_menu_item_get_image(GTK_IMAGE_MENU_ITEM(gmi));
 
-		GIcon * gicon = g_themed_icon_new_with_default_fallbacks(g_value_get_string(value));
+		GIcon * gicon = g_themed_icon_new_with_default_fallbacks(g_variant_get_string(variant, NULL));
 		if (image == NULL) {
 			image = gtk_image_new_from_gicon(gicon, GTK_ICON_SIZE_MENU);
 			gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(gmi), image);
@@ -424,16 +481,16 @@
 
 	g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(restart_property_change), client);
 
-	/* Grab the inital values and put them into the item */
-	const GValue * value;
-	value = dbusmenu_menuitem_property_get_value(newitem, RESTART_ITEM_LABEL);
-	if (value != NULL) {
-		restart_property_change(newitem, RESTART_ITEM_LABEL, value, client);
+	/* Grab the inital variants and put them into the item */
+	GVariant * variant;
+	variant = dbusmenu_menuitem_property_get_variant(newitem, RESTART_ITEM_LABEL);
+	if (variant != NULL) {
+		restart_property_change(newitem, RESTART_ITEM_LABEL, variant, client);
 	}
 
-	value = dbusmenu_menuitem_property_get_value(newitem, RESTART_ITEM_ICON);
-	if (value != NULL) {
-		restart_property_change(newitem, RESTART_ITEM_ICON, value, client);
+	variant = dbusmenu_menuitem_property_get_variant(newitem, RESTART_ITEM_ICON);
+	if (variant != NULL) {
+		restart_property_change(newitem, RESTART_ITEM_ICON, variant, client);
 	}
 
 	return TRUE;
@@ -448,7 +505,7 @@
 	DbusmenuGtkClient * client = DBUSMENU_GTKCLIENT(user_data);
 	DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(g_object_get_data(G_OBJECT(widget), dbusmenu_item_data));
 
-	switch_property_change(mi, MENU_SWITCH_USER, dbusmenu_menuitem_property_get_value(mi, MENU_SWITCH_USER), client);
+	switch_property_change(mi, MENU_SWITCH_USER, dbusmenu_menuitem_property_get_variant(mi, MENU_SWITCH_USER), client);
 	return;
 }
 
@@ -468,7 +525,7 @@
 
 	g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(switch_property_change), client);
 	g_signal_connect(G_OBJECT(gmi), "style-set", G_CALLBACK(switch_style_set), client);
-	switch_property_change(newitem, MENU_SWITCH_USER, dbusmenu_menuitem_property_get_value(newitem, MENU_SWITCH_USER), client);
+	switch_property_change(newitem, MENU_SWITCH_USER, dbusmenu_menuitem_property_get_variant(newitem, MENU_SWITCH_USER), client);
 
 	return TRUE;
 }

=== modified file 'src/session-dbus.c'
--- src/session-dbus.c	2010-03-12 22:10:57 +0000
+++ src/session-dbus.c	2011-01-11 16:56:36 +0000
@@ -23,25 +23,33 @@
 #include "config.h"
 #endif
 
+#include <gio/gio.h>
+
 #include "session-dbus.h"
 #include "dbus-shared-names.h"
 
-static gboolean _session_dbus_server_get_icon (SessionDbus * service, gchar ** icon, GError ** error);
+static GVariant * get_icon (SessionDbus * 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);
 
-#include "session-dbus-server.h"
+#include "gen-session-dbus.xml.h"
 
 typedef struct _SessionDbusPrivate SessionDbusPrivate;
 struct _SessionDbusPrivate {
 	gchar * name;
-};
-
-/* Signals */
-enum {
-	ICON_UPDATED,
-	LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
+	GDBusConnection * bus;
+	GCancellable * bus_cancel;
+	guint dbus_registration;
+};
+
+/* 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 */
+};
 
 #define SESSION_DBUS_GET_PRIVATE(o) \
 (G_TYPE_INSTANCE_GET_PRIVATE ((o), SESSION_DBUS_TYPE, SessionDbusPrivate))
@@ -63,15 +71,24 @@
 	object_class->dispose = session_dbus_dispose;
 	object_class->finalize = session_dbus_finalize;
 
-	signals[ICON_UPDATED] = g_signal_new ("icon-updated",
-	                                      G_TYPE_FROM_CLASS (klass),
-	                                      G_SIGNAL_RUN_LAST,
-	                                      G_STRUCT_OFFSET (SessionDbusClass, icon_updated),
-	                                      NULL, NULL,
-	                                      g_cclosure_marshal_VOID__STRING,
-	                                      G_TYPE_NONE, 1, G_TYPE_STRING);
-
-	dbus_g_object_type_install_info(SESSION_DBUS_TYPE, &dbus_glib__session_dbus_server_object_info);
+	/* Setting up the DBus interfaces */
+	if (node_info == NULL) {
+		GError * error = NULL;
+
+		node_info = g_dbus_node_info_new_for_xml(_session_dbus, &error);
+		if (error != NULL) {
+			g_error("Unable to parse Session 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_SESSION_SERVICE_DBUS_IFACE);
+
+		if (interface_info == NULL) {
+			g_error("Unable to find interface '" INDICATOR_SESSION_SERVICE_DBUS_IFACE "'");
+		}
+	}
 
 	return;
 }
@@ -79,19 +96,104 @@
 static void
 session_dbus_init (SessionDbus *self)
 {
-	DBusGConnection * session = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
-	dbus_g_connection_register_g_object(session, INDICATOR_SESSION_SERVICE_DBUS_OBJECT, G_OBJECT(self));
-
 	SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(self);
 
 	priv->name = g_strdup(ICON_DEFAULT);
-
+	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;
+	}
+
+	SessionDbusPrivate * priv = SESSION_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(priv->bus,
+	                                                            INDICATOR_SESSION_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)
+{
+	SessionDbus * service = SESSION_DBUS(user_data);
+	GVariant * retval = NULL;
+
+	if (g_strcmp0(method, "GetIcon") == 0) {
+		retval = get_icon(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
 session_dbus_dispose (GObject *object)
 {
+	SessionDbusPrivate * priv = SESSION_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 (session_dbus_parent_class)->dispose (object);
 	return;
@@ -111,12 +213,11 @@
 	return;
 }
 
-static gboolean
-_session_dbus_server_get_icon (SessionDbus * service, gchar ** icon, GError ** error)
+static GVariant *
+get_icon (SessionDbus * service)
 {
 	SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(service);
-	*icon = g_strdup(priv->name);
-	return TRUE;
+	return g_variant_new("(s)", priv->name);
 }
 
 SessionDbus *
@@ -129,11 +230,28 @@
 session_dbus_set_name (SessionDbus * session, const gchar * name)
 {
 	SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(session);
+	GError * error = NULL;
 	if (priv->name != NULL) {
 		g_free(priv->name);
 		priv->name = NULL;
 	}
 	priv->name = g_strdup(name);
-	g_signal_emit(G_OBJECT(session), signals[ICON_UPDATED], 0, priv->name, TRUE);
+
+	if (priv->bus != NULL) {
+		g_dbus_connection_emit_signal (priv->bus,
+			                       NULL,
+			                       INDICATOR_SESSION_SERVICE_DBUS_OBJECT,
+			                       INDICATOR_SESSION_SERVICE_DBUS_IFACE,
+			                       "IconUpdated",
+			                       g_variant_new ("(s)", priv->name, NULL),
+			                       &error);
+
+		if (error != NULL) {
+			g_error("Unable to send IconUpdated signal: %s", error->message);
+			g_error_free(error);
+			return;
+		}
+	}
+
 	return;
 }


Follow ups