aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore4
-rw-r--r--configure.ac10
-rw-r--r--src/Makefile.am29
-rw-r--r--src/datetime-interface.c145
-rw-r--r--src/datetime-interface.h6
-rw-r--r--src/indicator-datetime.c88
6 files changed, 217 insertions, 65 deletions
diff --git a/.bzrignore b/.bzrignore
index 82ba294..c27777b 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -7,5 +7,5 @@ po/indicator-datetime.pot
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
diff --git a/configure.ac b/configure.ac
index dc0448c..a57d91e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -62,21 +62,21 @@ OOBS_REQUIRED_VERSION=2.31.0
AS_IF([test "x$with_gtk" = x3],
[PKG_CHECK_MODULES(INDICATOR, indicator3 >= $INDICATOR_REQUIRED_VERSION
- dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION
- dbusmenu-gtk3 >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
+ dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
libido3-0.1 >= $INDICATOR_DISPLAY_OBJECTS)
],
[test "x$with_gtk" = x2],
[PKG_CHECK_MODULES(INDICATOR, indicator >= $INDICATOR_REQUIRED_VERSION
- dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION
- dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
+ dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS)
],
[AC_MSG_FAILURE([Value for --with-gtk was neither 2 nor 3])]
)
PKG_CHECK_MODULES(SERVICE, indicator >= $INDICATOR_REQUIRED_VERSION
- dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION
+ dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
libido-0.1 >= $INDICATOR_DISPLAY_OBJECTS
gio-2.0 >= $GIO_REQUIRED_VERSION
geoclue >= $GEOCLUE_REQUIRED_VERSION
diff --git a/src/Makefile.am b/src/Makefile.am
index ebe466d..5e3625d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -4,7 +4,7 @@ libexec_PROGRAMS = indicator-datetime-service
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 @@ indicator_datetime_service_LDADD = \
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 @@ libdatetime_la_LDFLAGS = \
-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)
diff --git a/src/datetime-interface.c b/src/datetime-interface.c
index c58c5af..5939061 100644
--- a/src/datetime-interface.c
+++ b/src/datetime-interface.c
@@ -23,21 +23,37 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#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 @@ datetime_interface_class_init (DatetimeInterfaceClass *klass)
{
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);
+ /* Setting up the DBus interfaces */
+ if (node_info == NULL) {
+ GError * error = NULL;
- dbus_g_object_type_install_info(DATETIME_INTERFACE_TYPE, &dbus_glib__datetime_service_server_object_info);
+ 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 @@ datetime_interface_class_init (DatetimeInterfaceClass *klass)
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 @@ void
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;
}
diff --git a/src/datetime-interface.h b/src/datetime-interface.h
index 60ead1b..ae85605 100644
--- a/src/datetime-interface.h
+++ b/src/datetime-interface.h
@@ -34,8 +34,9 @@ G_BEGIN_DECLS
#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 _DatetimeInterfaceClass {
struct _DatetimeInterface {
GObject parent;
+ DatetimeInterfacePrivate * priv;
};
GType datetime_interface_get_type (void);
diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c
index 276a840..c3b7e4a 100644
--- a/src/indicator-datetime.c
+++ b/src/indicator-datetime.c
@@ -33,9 +33,6 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#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>
@@ -87,7 +84,8 @@ struct _IndicatorDatetimePrivate {
IndicatorServiceManager * sm;
DbusmenuGtkMenu * menu;
- DBusGProxy * service_proxy;
+ GCancellable * service_proxy_cancel;
+ GDBusProxy * service_proxy;
IdoCalendarMenuItem *ido_calendar;
GSettings * settings;
@@ -165,7 +163,9 @@ static gchar * generate_format_string (IndicatorDatetime * self);
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);
static gint generate_strftime_bitmask (const char *time_str);
/* Indicator Module Config */
@@ -294,21 +294,53 @@ indicator_datetime_init (IndicatorDatetime *self)
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;
}
@@ -601,17 +633,29 @@ update_label (IndicatorDatetime * io)
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)