← Back to team overview

ayatana-commits team mailing list archive

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

 

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

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

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

Ported to gdbus!
-- 
https://code.launchpad.net/~mterry/indicator-datetime/gdbus/+merge/45770
Your team ayatana-commits is subscribed to branch lp:indicator-datetime.
=== modified file '.bzrignore'
--- .bzrignore	2010-08-30 18:44:15 +0000
+++ .bzrignore	2011-01-10 22:24:08 +0000
@@ -7,5 +7,5 @@
 indicator-datetime-[0-9].[0-9].[0-9].tar.gz
 data/indicator-datetime.service
 data/org.ayatana.indicator.datetime.gschema.valid
-src/datetime-service-client.h
-src/datetime-service-server.h
+src/gen-datetime-service.xml.c
+src/gen-datetime-service.xml.h

=== modified file 'src/Makefile.am'
--- src/Makefile.am	2010-11-11 21:10:59 +0000
+++ src/Makefile.am	2011-01-10 22:24:08 +0000
@@ -4,7 +4,7 @@
 indicator_datetime_service_SOURCES = \
 	datetime-interface.c \
 	datetime-interface.h \
-	datetime-service-server.h \
+	gen-datetime-service.xml.c \
 	calendar-menu-item.c \
 	calendar-menu-item.h \
 	datetime-service.c \
@@ -20,7 +20,7 @@
 datetimelibdir = $(INDICATORDIR)
 datetimelib_LTLIBRARIES = libdatetime.la
 libdatetime_la_SOURCES = \
-	datetime-service-client.h \
+	gen-datetime-service.xml.h \
 	dbus-shared.h \
 	indicator-datetime.c
 libdatetime_la_CFLAGS = \
@@ -32,23 +32,20 @@
 	-module \
 	-avoid-version
 
-datetime-service-client.h: $(srcdir)/datetime-service.xml
-	dbus-binding-tool \
-		--prefix=_datetime_service_client \
-		--mode=glib-client \
-		--output=datetime-service-client.h \
-		$(srcdir)/datetime-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 ";" >> $@
 
-datetime-service-server.h: $(srcdir)/datetime-service.xml
-	dbus-binding-tool \
-		--prefix=_datetime_service_server \
-		--mode=glib-server \
-		--output=datetime-service-server.h \
-		$(srcdir)/datetime-service.xml
+gen-%.xml.h: %.xml
+	@echo "Building $@ from $<"
+	@echo "extern const char * _$(subst -,_,$(subst .,_,$(basename $<)));" > $@
 
 BUILT_SOURCES = \
-	datetime-service-client.h \
-	datetime-service-server.h
+	gen-datetime-service.xml.c \
+	gen-datetime-service.xml.h
+
 
 CLEANFILES = \
 	$(BUILT_SOURCES)

=== modified file 'src/datetime-interface.c'
--- src/datetime-interface.c	2010-08-31 03:11:36 +0000
+++ src/datetime-interface.c	2011-01-10 22:24:08 +0000
@@ -23,21 +23,37 @@
 #include "config.h"
 #endif
 
+#include <gio/gio.h>
+
 #include "datetime-interface.h"
-#include "datetime-service-server.h"
+#include "gen-datetime-service.xml.h"
 #include "dbus-shared.h"
 
-enum {
-	UPDATE_TIME,
-	LAST_SIGNAL
+/**
+	DatetimeInterfacePrivate:
+	@dbus_registration: The handle for this object being registered
+		on dbus.
+
+	Structure to define the memory for the private area
+	of the datetime interface instance.
+*/
+struct _DatetimeInterfacePrivate {
+	GDBusConnection * bus;
+	GCancellable * bus_cancel;
+	guint dbus_registration;
 };
 
-static guint signals[LAST_SIGNAL] = { 0 };
+#define DATETIME_INTERFACE_GET_PRIVATE(o) (DATETIME_INTERFACE(o)->priv)
+
+/* GDBus Stuff */
+static GDBusNodeInfo *      node_info = NULL;
+static GDBusInterfaceInfo * interface_info = NULL;
 
 static void datetime_interface_class_init (DatetimeInterfaceClass *klass);
 static void datetime_interface_init       (DatetimeInterface *self);
 static void datetime_interface_dispose    (GObject *object);
 static void datetime_interface_finalize   (GObject *object);
+static void bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data);
 
 G_DEFINE_TYPE (DatetimeInterface, datetime_interface, G_TYPE_OBJECT);
 
@@ -46,18 +62,29 @@
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+	g_type_class_add_private (klass, sizeof (DatetimeInterfacePrivate));
+
 	object_class->dispose = datetime_interface_dispose;
 	object_class->finalize = datetime_interface_finalize;
 
-	signals[UPDATE_TIME] =  g_signal_new("update-time",
-	                                      G_TYPE_FROM_CLASS(klass),
-	                                      G_SIGNAL_RUN_LAST,
-	                                      G_STRUCT_OFFSET (DatetimeInterfaceClass, update_time),
-	                                      NULL, NULL,
-	                                      g_cclosure_marshal_VOID__VOID,
-	                                      G_TYPE_NONE, 0, G_TYPE_NONE);
-
-	dbus_g_object_type_install_info(DATETIME_INTERFACE_TYPE, &dbus_glib__datetime_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(_datetime_service, &error);
+		if (error != NULL) {
+			g_error("Unable to parse Datetime Service Interface description: %s", error->message);
+			g_error_free(error);
+		}
+	}
+
+	if (interface_info == NULL) {
+		interface_info = g_dbus_node_info_lookup_interface(node_info, SERVICE_IFACE);
+
+		if (interface_info == NULL) {
+			g_error("Unable to find interface '" SERVICE_IFACE "'");
+		}
+	}
 
 	return;
 }
@@ -65,17 +92,82 @@
 static void
 datetime_interface_init (DatetimeInterface *self)
 {
-	DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
-	dbus_g_connection_register_g_object(connection,
-	                                    SERVICE_OBJ,
-	                                    G_OBJECT(self));
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, DATETIME_INTERFACE_TYPE, DatetimeInterfacePrivate);
+
+	self->priv->bus = NULL;
+	self->priv->bus_cancel = NULL;
+	self->priv->dbus_registration = 0;
+
+	self->priv->bus_cancel = g_cancellable_new();
+	g_bus_get(G_BUS_TYPE_SESSION,
+	          self->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;
+	}
+
+	DatetimeInterfacePrivate * priv = DATETIME_INTERFACE_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,
+	                                                            SERVICE_OBJ,
+	                                                            interface_info,
+	                                                            NULL,
+	                                                            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;	
+}
+
+static void
 datetime_interface_dispose (GObject *object)
 {
+	DatetimeInterfacePrivate * priv = DATETIME_INTERFACE_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 (datetime_interface_parent_class)->dispose (object);
 	return;
@@ -93,6 +185,23 @@
 datetime_interface_update (DatetimeInterface *self)
 {
 	g_return_if_fail(IS_DATETIME_INTERFACE(self));
-	g_signal_emit(G_OBJECT(self), signals[UPDATE_TIME], 0, TRUE);
+
+	DatetimeInterfacePrivate * priv = DATETIME_INTERFACE_GET_PRIVATE(self);
+	GError * error = NULL;
+
+	g_dbus_connection_emit_signal (priv->bus,
+	                               NULL,
+	                               SERVICE_OBJ,
+	                               SERVICE_IFACE,
+	                               "UpdateTime",
+	                               NULL,
+	                               &error);
+
+	if (error != NULL) {
+		g_error("Unable to send UpdateTime signal: %s", error->message);
+		g_error_free(error);
+		return;
+	}
+
 	return;
 }

=== modified file 'src/datetime-interface.h'
--- src/datetime-interface.h	2010-08-31 03:11:36 +0000
+++ src/datetime-interface.h	2011-01-10 22:24:08 +0000
@@ -34,8 +34,9 @@
 #define IS_DATETIME_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DATETIME_INTERFACE_TYPE))
 #define DATETIME_INTERFACE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), DATETIME_INTERFACE_TYPE, DatetimeInterfaceClass))
 
-typedef struct _DatetimeInterface      DatetimeInterface;
-typedef struct _DatetimeInterfaceClass DatetimeInterfaceClass;
+typedef struct _DatetimeInterface        DatetimeInterface;
+typedef struct _DatetimeInterfacePrivate DatetimeInterfacePrivate;
+typedef struct _DatetimeInterfaceClass   DatetimeInterfaceClass;
 
 struct _DatetimeInterfaceClass {
 	GObjectClass parent_class;
@@ -45,6 +46,7 @@
 
 struct _DatetimeInterface {
 	GObject parent;
+	DatetimeInterfacePrivate * priv;
 };
 
 GType              datetime_interface_get_type       (void);

=== modified file 'src/indicator-datetime.c'
--- src/indicator-datetime.c	2011-01-07 05:03:06 +0000
+++ src/indicator-datetime.c	2011-01-10 22:24:08 +0000
@@ -33,9 +33,6 @@
 #include <glib/gi18n-lib.h>
 #include <gio/gio.h>
 
-/* DBus Stuff */
-#include <dbus/dbus-glib.h>
-
 /* Indicator Stuff */
 #include <libindicator/indicator.h>
 #include <libindicator/indicator-object.h>
@@ -86,7 +83,8 @@
 	IndicatorServiceManager * sm;
 	DbusmenuGtkMenu * menu;
 
-	DBusGProxy * service_proxy;
+	GCancellable * service_proxy_cancel;
+	GDBusProxy * service_proxy;
 	IdoCalendarMenuItem *ido_calendar;
 
 	GSettings * settings;
@@ -152,7 +150,9 @@
 static struct tm * update_label           (IndicatorDatetime * io);
 static void guess_label_size              (IndicatorDatetime * self);
 static void setup_timer                   (IndicatorDatetime * self, struct tm * ltime);
-static void update_time                   (DBusGProxy * proxy, gpointer user_data);
+static void update_time                   (IndicatorDatetime * self);
+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);
 
 /* Indicator Module Config */
 INDICATOR_SET_VERSION
@@ -279,20 +279,52 @@
 
 	self->priv->sm = indicator_service_manager_new_version(SERVICE_NAME, SERVICE_VERSION);
 
-	DBusGConnection * session = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
-	if (session != NULL) {
-		self->priv->service_proxy = dbus_g_proxy_new_for_name(session,
-		                                                      SERVICE_NAME,
-		                                                      SERVICE_OBJ,
-		                                                      SERVICE_IFACE);
-
-		dbus_g_proxy_add_signal(self->priv->service_proxy, "UpdateTime", G_TYPE_INVALID);
-		dbus_g_proxy_connect_signal(self->priv->service_proxy,
-		                            "UpdateTime",
-		                            G_CALLBACK(update_time),
-		                            self,
-		                            NULL);
-	}
+	self->priv->service_proxy_cancel = g_cancellable_new();
+
+	g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+		                  G_DBUS_PROXY_FLAGS_NONE,
+		                  NULL,
+		                  SERVICE_NAME,
+		                  SERVICE_OBJ,
+		                  SERVICE_IFACE,
+		                  self->priv->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;
+
+	IndicatorDatetime * self = INDICATOR_DATETIME(user_data);
+	g_return_if_fail(self != NULL);
+
+	GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
+
+	IndicatorDatetimePrivate * priv = INDICATOR_DATETIME_GET_PRIVATE(self);
+
+	if (priv->service_proxy_cancel != NULL) {
+		g_object_unref(priv->service_proxy_cancel);
+		priv->service_proxy_cancel = NULL;
+	}
+
+	if (error != NULL) {
+		g_error("Could not grab DBus proxy for %s: %s", SERVICE_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. */
+	priv->service_proxy = proxy;
+
+	g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self);
 
 	return;
 }
@@ -574,17 +606,29 @@
 	return ltime;
 }
 
-/* Recieves the signal from the service that we should update
-   the time right now.  Usually from a timezone switch. */
+/* Update the time right now.  Usually the result of a timezone switch. */
 static void
-update_time (DBusGProxy * proxy, gpointer user_data)
+update_time (IndicatorDatetime * self)
 {
-	IndicatorDatetime * self = INDICATOR_DATETIME(user_data);
 	struct tm * ltime = update_label(self);
 	setup_timer(self, ltime);
 	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)
+{
+	IndicatorDatetime * self = INDICATOR_DATETIME(user_data);
+
+	if (g_strcmp0(signal_name, "UpdateTime") == 0) {
+		update_time(self);
+	}
+
+	return;
+}
+
 /* Runs every minute and updates the time */
 gboolean
 timer_func (gpointer user_data)


Follow ups