[libnotify] Port to gdbus



commit f63e8ab8b192b291b81148fac53947cdea5841f1
Author: Christian Persch <chpe gnome org>
Date:   Tue Oct 12 01:13:31 2010 +0200

    Port to gdbus
    
    Bug #622891.

 configure.ac                          |   19 +-
 docs/reference/libnotify-sections.txt |    1 +
 docs/reference/tmpl/notification.sgml |   10 +
 libnotify/internal.h                  |    8 +-
 libnotify/notification.c              |  508 +++++++++++++--------------------
 libnotify/notification.h              |    4 +
 libnotify/notify.c                    |  256 +++++++----------
 libnotify/notify.h                    |   17 --
 tests/test-default-action.c           |   11 -
 tests/test-image.c                    |    7 -
 tests/test-multi-actions.c            |   11 -
 tests/test-xy-actions.c               |    9 -
 12 files changed, 322 insertions(+), 539 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 690e1f3..1c9d8d2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -88,17 +88,16 @@ AC_EXEEXT
 
 AM_PROG_LIBTOOL
 
-REQ_DBUS_VERSION=0.76
 REQ_GTK_VERSION=2.90
-REQ_GLIB_VERSION=2.6
+REQ_GLIB_VERSION=2.26.0
 
-pkg_modules="gdk-pixbuf-2.0 glib-2.0 >= $REQ_GLIB_VERSION, dbus-1 >= $REQ_DBUS_VERSION, dbus-glib-1 >= $REQ_DBUS_VERSION"
+pkg_modules="gdk-pixbuf-2.0 glib-2.0 >= $REQ_GLIB_VERSION gio-2.0 >= $REQ_GLIB_VERSION"
 PKG_CHECK_MODULES(PACKAGE, [$pkg_modules])
 AC_SUBST(PACKAGE_LIBS)
 AC_SUBST(PACKAGE_CFLAGS)
 AC_SUBST(pkg_modules)
 
-tests_modules="gtk+-3.0 >= $REQ_GTK_VERSION dbus-glib-1 >= $REQ_DBUS_VERSION"
+tests_modules="gtk+-3.0 >= $REQ_GTK_VERSION"
 PKG_CHECK_MODULES(TESTS, [$tests_modules])
 AC_SUBST(TESTS_LIBS)
 AC_SUBST(TESTS_CFLAGS)
@@ -110,18 +109,6 @@ dnl
 dnl Check the D-BUS version.
 dnl
 
-AC_MSG_CHECKING([dbus version])
-DBUS_VERSION=`$PKG_CONFIG --modversion dbus-1`
-DBUS_MAJOR_VER=`echo $DBUS_VERSION | cut -d. -f 1`
-DBUS_MINOR_VER=`echo $DBUS_VERSION | cut -d. -f 2`
-DBUS_MICRO_VER=`echo $DBUS_VERSION | cut -d. -f 3`
-
-AC_MSG_RESULT($DBUS_VERSION)
-AC_DEFINE_UNQUOTED(DBUS_MAJOR_VER, $DBUS_MAJOR_VER, [D-BUS major version.])
-AC_DEFINE_UNQUOTED(DBUS_MINOR_VER, $DBUS_MINOR_VER, [D-BUS minor version.])
-AC_DEFINE_UNQUOTED(DBUS_MICRO_VER, $DBUS_MICRO_VER, [D-BUS micro version.])
-
-
 dnl ################################################################
 dnl # Set up gtk-doc
 dnl ################################################################
diff --git a/docs/reference/libnotify-sections.txt b/docs/reference/libnotify-sections.txt
index 485d96f..ca2534f 100644
--- a/docs/reference/libnotify-sections.txt
+++ b/docs/reference/libnotify-sections.txt
@@ -18,6 +18,7 @@ notify_notification_set_timeout
 notify_notification_set_category
 notify_notification_set_urgency
 notify_notification_set_icon_from_pixbuf
+notify_notification_set_hint
 notify_notification_set_hint_int32
 notify_notification_set_hint_double
 notify_notification_set_hint_string
diff --git a/docs/reference/tmpl/notification.sgml b/docs/reference/tmpl/notification.sgml
index e5937f3..c2093fd 100644
--- a/docs/reference/tmpl/notification.sgml
+++ b/docs/reference/tmpl/notification.sgml
@@ -183,6 +183,16 @@ is much like G_CALLBACK().
 @icon: 
 
 
+<!-- ##### FUNCTION notify_notification_set_hint ##### -->
+<para>
+
+</para>
+
+ notification: 
+ key: 
+ value: 
+
+
 <!-- ##### FUNCTION notify_notification_set_hint_int32 ##### -->
 <para>
 
diff --git a/libnotify/internal.h b/libnotify/internal.h
index 9b46406..741d002 100644
--- a/libnotify/internal.h
+++ b/libnotify/internal.h
@@ -22,19 +22,13 @@
 #ifndef _LIBNOTIFY_INTERNAL_H_
 #define _LIBNOTIFY_INTERNAL_H_
 
-#include "config.h"
-
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
-
 #define NOTIFY_DBUS_NAME           "org.freedesktop.Notifications"
 #define NOTIFY_DBUS_CORE_INTERFACE "org.freedesktop.Notifications"
 #define NOTIFY_DBUS_CORE_OBJECT    "/org/freedesktop/Notifications"
 
 G_BEGIN_DECLS
 
-DBusGConnection * _notify_get_dbus_g_conn (void);
-DBusGProxy      * _notify_get_g_proxy     (void);
+GDBusProxy      * _notify_get_proxy                         (GError **error);
 
 void            _notify_cache_add_notification              (NotifyNotification       *n);
 void            _notify_cache_remove_notification           (NotifyNotification       *n);
diff --git a/libnotify/notification.c b/libnotify/notification.c
index 2a42236..c947882 100644
--- a/libnotify/notification.c
+++ b/libnotify/notification.c
@@ -3,6 +3,7 @@
  * Copyright (C) 2006 Christian Hammond
  * Copyright (C) 2006 John Palmieri
  * Copyright (C) 2010 Red Hat, Inc.
+ * Copyright © 2010 Christian Persch
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -22,8 +23,7 @@
 
 #include "config.h"
 
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
+#include <gio/gio.h>
 
 #include "notify.h"
 #include "internal.h"
@@ -38,15 +38,6 @@
 static void     notify_notification_class_init (NotifyNotificationClass *klass);
 static void     notify_notification_init       (NotifyNotification *sp);
 static void     notify_notification_finalize   (GObject            *object);
-static void     _close_signal_handler          (DBusGProxy         *proxy,
-                                                guint32             id,
-                                                guint32             reason,
-                                                NotifyNotification *notification);
-
-static void     _action_signal_handler         (DBusGProxy         *proxy,
-                                                guint32             id,
-                                                char               *action,
-                                                NotifyNotification *notification);
 
 typedef struct
 {
@@ -78,7 +69,8 @@ struct _NotifyNotificationPrivate
 
         gboolean        has_nondefault_actions;
         gboolean        updates_pending;
-        gboolean        signals_registered;
+
+        gulong          proxy_signal_handler;
 
         gint            closed_reason;
 };
@@ -299,13 +291,6 @@ notify_notification_get_property (GObject    *object,
 }
 
 static void
-_g_value_free (GValue *value)
-{
-        g_value_unset (value);
-        g_free (value);
-}
-
-static void
 destroy_pair (CallbackPair *pair)
 {
         if (pair->user_data != NULL && pair->free_func != NULL) {
@@ -324,29 +309,12 @@ notify_notification_init (NotifyNotification *obj)
         obj->priv->hints = g_hash_table_new_full (g_str_hash,
                                                   g_str_equal,
                                                   g_free,
-                                                  (GFreeFunc) _g_value_free);
+                                                  (GDestroyNotify) g_variant_unref);
 
         obj->priv->action_map = g_hash_table_new_full (g_str_hash,
                                                        g_str_equal,
                                                        g_free,
-                                                       (GFreeFunc) destroy_pair);
-}
-
-static void
-on_proxy_destroy (DBusGProxy         *proxy,
-                  NotifyNotification *notification)
-{
-        if (notification->priv->signals_registered) {
-                dbus_g_proxy_disconnect_signal (proxy,
-                                                "NotificationClosed",
-                                                G_CALLBACK (_close_signal_handler),
-                                                notification);
-                dbus_g_proxy_disconnect_signal (proxy,
-                                                "ActionInvoked",
-                                                G_CALLBACK (_action_signal_handler),
-                                                notification);
-                notification->priv->signals_registered = FALSE;
-        }
+                                                       (GDestroyNotify) destroy_pair);
 }
 
 static void
@@ -354,7 +322,7 @@ notify_notification_finalize (GObject *object)
 {
         NotifyNotification        *obj = NOTIFY_NOTIFICATION (object);
         NotifyNotificationPrivate *priv = obj->priv;
-        DBusGProxy                *proxy;
+        GDBusProxy                *proxy;
 
         _notify_cache_remove_notification (obj);
 
@@ -373,20 +341,9 @@ notify_notification_finalize (GObject *object)
         if (priv->hints != NULL)
                 g_hash_table_destroy (priv->hints);
 
-        proxy = _notify_get_g_proxy ();
-        if (proxy != NULL && priv->signals_registered) {
-                g_signal_handlers_disconnect_by_func (proxy,
-                                                      G_CALLBACK (on_proxy_destroy),
-                                                      object);
-
-                dbus_g_proxy_disconnect_signal (proxy,
-                                                "NotificationClosed",
-                                                G_CALLBACK (_close_signal_handler),
-                                                object);
-                dbus_g_proxy_disconnect_signal (proxy,
-                                                "ActionInvoked",
-                                                G_CALLBACK (_action_signal_handler),
-                                                object);
+        proxy = _notify_get_proxy (NULL);
+        if (proxy != NULL && priv->proxy_signal_handler != 0) {
+                g_signal_handler_disconnect (proxy, priv->proxy_signal_handler);
         }
 
         g_free (obj->priv);
@@ -466,62 +423,49 @@ notify_notification_update (NotifyNotification *notification,
 }
 
 static void
-_close_signal_handler (DBusGProxy         *proxy,
-                       guint32             id,
-                       guint32             reason,
-                       NotifyNotification *notification)
+proxy_g_signal_cb (GDBusProxy *proxy,
+                   const char *sender_name,
+                   const char *signal_name,
+                   GVariant   *parameters,
+                   NotifyNotification *notification)
 {
-        if (id == notification->priv->id) {
+        g_return_if_fail (NOTIFY_IS_NOTIFICATION (notification));
+
+        if (g_strcmp0 (signal_name, "NotificationClosed") == 0 &&
+            g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(uu)"))) {
+                guint32 id, reason;
+
+                g_variant_get (parameters, "(uu)", &id, &reason);
+                if (id != notification->priv->id)
+                        return;
+
                 g_object_ref (G_OBJECT (notification));
                 notification->priv->closed_reason = reason;
                 g_signal_emit (notification, signals[SIGNAL_CLOSED], 0);
                 notification->priv->id = 0;
                 g_object_unref (G_OBJECT (notification));
-        }
-}
-
-static void
-_action_signal_handler (DBusGProxy         *proxy,
-                        guint32             id,
-                        char               *action,
-                        NotifyNotification *notification)
-{
-        CallbackPair *pair;
-
-        g_return_if_fail (notification != NULL);
-        g_return_if_fail (NOTIFY_IS_NOTIFICATION (notification));
-
-        if (id != notification->priv->id)
-                return;
-
-        pair = (CallbackPair *) g_hash_table_lookup (notification->priv->action_map,
-                                                     action);
-
-        if (pair == NULL) {
-                if (g_ascii_strcasecmp (action, "default")) {
-                        g_warning ("Received unknown action %s", action);
+        } else if (g_strcmp0 (signal_name, "ActionInvoked") == 0 &&
+                   g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(us)"))) {
+                guint32 id;
+                const char *action;
+                CallbackPair *pair;
+
+                g_variant_get (parameters, "(u&s)", &id, &action);
+
+                if (id != notification->priv->id)
+                        return;
+
+                pair = (CallbackPair *) g_hash_table_lookup (notification->priv->action_map,
+                                                            action);
+
+                if (pair == NULL) {
+                        if (g_ascii_strcasecmp (action, "default")) {
+                                g_warning ("Received unknown action %s", action);
+                        }
+                } else {
+                        pair->cb (notification, (char *) action, pair->user_data);
                 }
-        } else {
-                pair->cb (notification, action, pair->user_data);
-        }
-}
-
-static char  **
-_gslist_to_string_array (GSList *list)
-{
-        GSList *l;
-        GArray *a;
-
-        a = g_array_sized_new (TRUE,
-                               FALSE,
-                               sizeof (char *),
-                               g_slist_length (list));
-
-        for (l = list; l != NULL; l = l->next) {
-                g_array_append_val (a, l->data);
         }
-
-        return (char **) g_array_free (a, FALSE);
 }
 
 /**
@@ -539,71 +483,70 @@ notify_notification_show (NotifyNotification *notification,
                           GError            **error)
 {
         NotifyNotificationPrivate *priv;
-        GError                    *tmp_error = NULL;
-        char                     **action_array;
-        DBusGProxy                *proxy;
+        GDBusProxy                *proxy;
+        GVariantBuilder            actions_builder, hints_builder;
+        GSList                    *l;
+        GHashTableIter             iter;
+        gpointer                   key, data;
+        GVariant                  *result;
 
         g_return_val_if_fail (notification != NULL, FALSE);
         g_return_val_if_fail (NOTIFY_IS_NOTIFICATION (notification), FALSE);
         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
         priv = notification->priv;
-        proxy = _notify_get_g_proxy ();
+        proxy = _notify_get_proxy (error);
         if (proxy == NULL) {
-                g_set_error (error, 0, 0, "Unable to connect to server");
                 return FALSE;
         }
 
-        if (!priv->signals_registered) {
-                g_signal_connect (proxy,
-                                  "destroy",
-                                  G_CALLBACK (on_proxy_destroy),
-                                  notification);
-
-                dbus_g_proxy_connect_signal (proxy,
-                                             "NotificationClosed",
-                                             G_CALLBACK (_close_signal_handler),
-                                             notification,
-                                             NULL);
-
-                dbus_g_proxy_connect_signal (proxy,
-                                             "ActionInvoked",
-                                             G_CALLBACK (_action_signal_handler),
-                                             notification,
-                                             NULL);
-
-                priv->signals_registered = TRUE;
+        if (priv->proxy_signal_handler == 0) {
+                priv->proxy_signal_handler = g_signal_connect (proxy,
+                                                               "g-signal",
+                                                               G_CALLBACK (proxy_g_signal_cb),
+                                                               notification);
+        }
+
+        g_variant_builder_init (&actions_builder, G_VARIANT_TYPE ("as"));
+        for (l = priv->actions; l != NULL; l = l->next) {
+                g_variant_builder_add (&actions_builder, "s", l->data);
         }
 
-        action_array = _gslist_to_string_array (priv->actions);
+        g_variant_builder_init (&hints_builder, G_VARIANT_TYPE ("a{sv}"));
+        g_hash_table_iter_init (&iter, priv->hints);
+        while (g_hash_table_iter_next (&iter, &key, &data)) {
+                g_variant_builder_add (&hints_builder, "{sv}", key, data);
+        }
 
         /* TODO: make this nonblocking */
-        dbus_g_proxy_call (proxy,
-                           "Notify",
-                           &tmp_error,
-                           G_TYPE_STRING, notify_get_app_name (),
-                           G_TYPE_UINT, priv->id,
-                           G_TYPE_STRING, priv->icon_name,
-                           G_TYPE_STRING, priv->summary,
-                           G_TYPE_STRING, priv->body,
-                           G_TYPE_STRV, action_array,
-                           dbus_g_type_get_map ("GHashTable",
-                                                G_TYPE_STRING,
-                                                G_TYPE_VALUE),
-                           priv->hints,
-                           G_TYPE_INT, priv->timeout,
-                           G_TYPE_INVALID,
-                           G_TYPE_UINT, &priv->id,
-                           G_TYPE_INVALID);
-
-        /* Don't free the elements because they are owned by priv->actions */
-        g_free (action_array);
-
-        if (tmp_error != NULL) {
-                g_propagate_error (error, tmp_error);
+        result = g_dbus_proxy_call_sync (proxy,
+                                         "Notify",
+                                         g_variant_new ("(susssasa{sv}i)",
+                                                        notify_get_app_name (),
+                                                        priv->id,
+                                                        priv->icon_name ? priv->icon_name : "",
+                                                        priv->summary ? priv->summary : "",
+                                                        priv->body ? priv->body : "",
+                                                        &actions_builder,
+                                                        &hints_builder,
+                                                        priv->timeout),
+                                         G_DBUS_CALL_FLAGS_NONE,
+                                         -1 /* FIXME ? */,
+                                         NULL,
+                                         error);
+        if (result == NULL) {
+                return FALSE;
+        }
+        if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(u)"))) {
+                g_variant_unref (result);
+                g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
+                             "Unexpected reply type");
                 return FALSE;
         }
 
+        g_variant_get (result, "(u)", &priv->id);
+        g_variant_unref (result);
+
         return TRUE;
 }
 
@@ -676,47 +619,6 @@ notify_notification_set_urgency (NotifyNotification *notification,
                                            (guchar) urgency);
 }
 
-static void
-_gvalue_array_append_int (GValueArray *array,
-                          gint         i)
-{
-        GValue value = { 0 };
-
-        g_value_init (&value, G_TYPE_INT);
-        g_value_set_int (&value, i);
-        g_value_array_append (array, &value);
-        g_value_unset (&value);
-}
-
-static void
-_gvalue_array_append_bool (GValueArray *array, gboolean b)
-{
-        GValue value = { 0 };
-
-        g_value_init (&value, G_TYPE_BOOLEAN);
-        g_value_set_boolean (&value, b);
-        g_value_array_append (array, &value);
-        g_value_unset (&value);
-}
-
-static void
-_gvalue_array_append_byte_array (GValueArray *array,
-                                 guchar      *bytes,
-                                 gsize        len)
-{
-        GArray *byte_array;
-        GValue  value = { 0 };
-
-        byte_array = g_array_sized_new (FALSE, FALSE, sizeof (guchar), len);
-        g_assert (byte_array != NULL);
-        byte_array = g_array_append_vals (byte_array, bytes, len);
-
-        g_value_init (&value, DBUS_TYPE_G_UCHAR_ARRAY);
-        g_value_take_boxed (&value, byte_array);
-        g_value_array_append (array, &value);
-        g_value_unset (&value);
-}
-
 /**
  * notify_notification_set_icon_from_pixbuf:
  * @notification: The notification.
@@ -757,12 +659,21 @@ notify_notification_set_image_from_pixbuf (NotifyNotification *notification,
         guchar         *image;
         gboolean        has_alpha;
         gsize           image_len;
-        GValueArray    *image_struct;
-        GValue         *value;
+        GVariant       *value;
         const char     *hint_name;
 
-        g_return_if_fail (notification != NULL);
-        g_return_if_fail (NOTIFY_IS_NOTIFICATION (notification));
+        g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
+
+        if (_notify_check_spec_version(1, 1)) {
+                hint_name = "image_data";
+        } else {
+                hint_name = "icon_data";
+        }
+
+        if (pixbuf == NULL) {
+                notify_notification_set_hint (notification, hint_name, NULL);
+                return;
+        }
 
         g_object_get (pixbuf,
                       "width", &width,
@@ -776,29 +687,50 @@ notify_notification_set_image_from_pixbuf (NotifyNotification *notification,
         image_len = (height - 1) * rowstride + width *
                 ((n_channels * bits_per_sample + 7) / 8);
 
-        image_struct = g_value_array_new (1);
-
-        _gvalue_array_append_int (image_struct, width);
-        _gvalue_array_append_int (image_struct, height);
-        _gvalue_array_append_int (image_struct, rowstride);
-        _gvalue_array_append_bool (image_struct, has_alpha);
-        _gvalue_array_append_int (image_struct, bits_per_sample);
-        _gvalue_array_append_int (image_struct, n_channels);
-        _gvalue_array_append_byte_array (image_struct, image, image_len);
+        value = g_variant_new ("(iiibii ay)",
+                               width,
+                               height,
+                               rowstride,
+                               has_alpha,
+                               bits_per_sample,
+                               n_channels,
+                               g_variant_new_from_data (G_VARIANT_TYPE ("ay"),
+                                                        image,
+                                                        image_len,
+                                                        TRUE,
+                                                        (GDestroyNotify) g_object_unref,
+                                                        pixbuf));
+        notify_notification_set_hint (notification, hint_name, value);
+}
 
-        value = g_new0 (GValue, 1);
-        g_value_init (value, G_TYPE_VALUE_ARRAY);
-        g_value_take_boxed (value, image_struct);
+/**
+ * notify_notification_set_hint:
+ * @notification: a #NotifyNotification
+ * @key: the hint key
+ * @variant: (allow-none): the hint value, or %NULL to unset the hint
+ *
+ * Sets a hint for @key with value @variant. If @value is %NULL,
+ * a previously set hint for @key is unset.
+ *
+ * If @variant is floating, it is consumed.
+ *
+ * Since: 0.6
+ */
+void
+notify_notification_set_hint (NotifyNotification *notification,
+                              const char         *key,
+                              GVariant           *value)
+{
+        g_return_if_fail (NOTIFY_IS_NOTIFICATION (notification));
+        g_return_if_fail (key != NULL && *key != '\0');
 
-        if (_notify_check_spec_version(1, 1)) {
-                hint_name = "image_data";
+        if (value != NULL) {
+                g_hash_table_insert (notification->priv->hints,
+                                    g_strdup (key),
+                                    g_variant_ref_sink (value));
         } else {
-                hint_name = "icon_data";
+                g_hash_table_remove (notification->priv->hints, key);
         }
-
-        g_hash_table_insert (notification->priv->hints,
-                             g_strdup (hint_name),
-                             value);
 }
 
 /**
@@ -808,24 +740,16 @@ notify_notification_set_image_from_pixbuf (NotifyNotification *notification,
  * @value: The hint's value.
  *
  * Sets a hint with a 32-bit integer value.
+ *
+ * Deprecated: 0.6. Use notify_notification_set_hint() instead
  */
 void
 notify_notification_set_hint_int32 (NotifyNotification *notification,
                                     const char         *key,
                                     gint                value)
 {
-        GValue *hint_value;
-
-        g_return_if_fail (notification != NULL);
-        g_return_if_fail (NOTIFY_IS_NOTIFICATION (notification));
-        g_return_if_fail (key != NULL && *key != '\0');
-
-        hint_value = g_new0 (GValue, 1);
-        g_value_init (hint_value, G_TYPE_INT);
-        g_value_set_int (hint_value, value);
-        g_hash_table_insert (notification->priv->hints,
-                             g_strdup (key),
-                             hint_value);
+        notify_notification_set_hint (notification, key,
+                                      g_variant_new_int32 (value));
 }
 
 
@@ -836,24 +760,16 @@ notify_notification_set_hint_int32 (NotifyNotification *notification,
  * @value: The hint's value.
  *
  * Sets a hint with an unsigned 32-bit integer value.
+ *
+ * Deprecated: 0.6. Use notify_notification_set_hint() instead
  */
 void
 notify_notification_set_hint_uint32 (NotifyNotification *notification,
                                      const char         *key,
                                      guint               value)
 {
-        GValue *hint_value;
-
-        g_return_if_fail (notification != NULL);
-        g_return_if_fail (NOTIFY_IS_NOTIFICATION (notification));
-        g_return_if_fail (key != NULL && *key != '\0');
-
-        hint_value = g_new0 (GValue, 1);
-        g_value_init (hint_value, G_TYPE_UINT);
-        g_value_set_uint (hint_value, value);
-        g_hash_table_insert (notification->priv->hints,
-                             g_strdup (key),
-                             hint_value);
+        notify_notification_set_hint (notification, key,
+                                      g_variant_new_uint32 (value));
 }
 
 /**
@@ -863,24 +779,16 @@ notify_notification_set_hint_uint32 (NotifyNotification *notification,
  * @value: The hint's value.
  *
  * Sets a hint with a double value.
+ *
+ * Deprecated: 0.6. Use notify_notification_set_hint() instead
  */
 void
 notify_notification_set_hint_double (NotifyNotification *notification,
                                      const char         *key,
                                      gdouble             value)
 {
-        GValue *hint_value;
-
-        g_return_if_fail (notification != NULL);
-        g_return_if_fail (NOTIFY_IS_NOTIFICATION (notification));
-        g_return_if_fail (key != NULL && *key != '\0');
-
-        hint_value = g_new0 (GValue, 1);
-        g_value_init (hint_value, G_TYPE_FLOAT);
-        g_value_set_float (hint_value, value);
-        g_hash_table_insert (notification->priv->hints,
-                             g_strdup (key),
-                             hint_value);
+        notify_notification_set_hint (notification, key,
+                                      g_variant_new_double (value));
 }
 
 /**
@@ -890,25 +798,16 @@ notify_notification_set_hint_double (NotifyNotification *notification,
  * @value: The hint's value.
  *
  * Sets a hint with a byte value.
+ *
+ * Deprecated: 0.6. Use notify_notification_set_hint() instead
  */
 void
 notify_notification_set_hint_byte (NotifyNotification *notification,
                                    const char         *key,
                                    guchar              value)
 {
-        GValue *hint_value;
-
-        g_return_if_fail (notification != NULL);
-        g_return_if_fail (NOTIFY_IS_NOTIFICATION (notification));
-        g_return_if_fail (key != NULL && *key != '\0');
-
-        hint_value = g_new0 (GValue, 1);
-        g_value_init (hint_value, G_TYPE_UCHAR);
-        g_value_set_uchar (hint_value, value);
-
-        g_hash_table_insert (notification->priv->hints,
-                             g_strdup (key),
-                             hint_value);
+        notify_notification_set_hint (notification, key,
+                                      g_variant_new_byte (value));
 }
 
 /**
@@ -920,6 +819,8 @@ notify_notification_set_hint_byte (NotifyNotification *notification,
  *
  * Sets a hint with a byte array value. The length of @value must be passed
  * as @len.
+ *
+ * Deprecated: 0.6. Use notify_notification_set_hint() instead
  */
 void
 notify_notification_set_hint_byte_array (NotifyNotification *notification,
@@ -927,26 +828,18 @@ notify_notification_set_hint_byte_array (NotifyNotification *notification,
                                          const guchar       *value,
                                          gsize               len)
 {
-        GValue *hint_value;
-        GArray *byte_array;
-
-        g_return_if_fail (notification != NULL);
-        g_return_if_fail (NOTIFY_IS_NOTIFICATION (notification));
-        g_return_if_fail (key != NULL && *key != '\0');
-        g_return_if_fail (value != NULL);
-        g_return_if_fail (len > 0);
-
-        byte_array = g_array_sized_new (FALSE, FALSE, sizeof (guchar), len);
-        byte_array = g_array_append_vals (byte_array, value, len);
-
-        hint_value = g_new0 (GValue, 1);
-        g_value_init (hint_value, dbus_g_type_get_collection ("GArray",
-                                                              G_TYPE_UCHAR));
-        g_value_take_boxed (hint_value, byte_array);
-
-        g_hash_table_insert (notification->priv->hints,
-                             g_strdup (key),
-                             hint_value);
+        gpointer value_dup;
+
+        g_return_if_fail (value != NULL || len == 0);
+
+        value_dup = g_memdup (value, len);
+        notify_notification_set_hint (notification, key,
+                                      g_variant_new_from_data (G_VARIANT_TYPE ("ay"),
+                                                               value_dup,
+                                                               len,
+                                                               TRUE,
+                                                               g_free,
+                                                               value_dup));
 }
 
 /**
@@ -956,24 +849,16 @@ notify_notification_set_hint_byte_array (NotifyNotification *notification,
  * @value: The hint's value.
  *
  * Sets a hint with a string value.
+ *
+ * Deprecated: 0.6. Use notify_notification_set_hint() instead
  */
 void
 notify_notification_set_hint_string (NotifyNotification *notification,
                                      const char         *key,
                                      const char         *value)
 {
-        GValue *hint_value;
-
-        g_return_if_fail (notification != NULL);
-        g_return_if_fail (NOTIFY_IS_NOTIFICATION (notification));
-        g_return_if_fail (key != NULL && *key != '\0');
-
-        hint_value = g_new0 (GValue, 1);
-        g_value_init (hint_value, G_TYPE_STRING);
-        g_value_set_string (hint_value, value);
-        g_hash_table_insert (notification->priv->hints,
-                             g_strdup (key),
-                             hint_value);
+        notify_notification_set_hint (notification, key,
+                                      g_variant_new_string (value));
 }
 
 static gboolean
@@ -1051,7 +936,6 @@ notify_notification_add_action (NotifyNotification  *notification,
         NotifyNotificationPrivate *priv;
         CallbackPair              *pair;
 
-        g_return_if_fail (notification != NULL);
         g_return_if_fail (NOTIFY_IS_NOTIFICATION (notification));
         g_return_if_fail (action != NULL && *action != '\0');
         g_return_if_fail (label != NULL && *label != '\0');
@@ -1088,44 +972,42 @@ _notify_notification_has_nondefault_actions (const NotifyNotification *n)
  * @notification: The notification.
  * @error: The returned error information.
  *
- * Tells the notification server to hide the notification on the screen.
+ * Synchronously tells the notification server to hide the notification on the screen.
  *
- * Returns: %TRUE if successful. On error, this will return %FALSE and set
- *          @error.
+ * Returns: %TRUE on success, or %FALSE on error with @error filled in
  */
 gboolean
 notify_notification_close (NotifyNotification *notification,
                            GError            **error)
 {
         NotifyNotificationPrivate *priv;
-        GError         *tmp_error = NULL;
-        DBusGProxy     *proxy;
+        GDBusProxy  *proxy;
+        GVariant   *result;
 
-        g_return_val_if_fail (notification != NULL, FALSE);
         g_return_val_if_fail (NOTIFY_IS_NOTIFICATION (notification), FALSE);
         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
         priv = notification->priv;
 
-        proxy = _notify_get_g_proxy ();
+        proxy = _notify_get_proxy (error);
         if (proxy == NULL) {
-                g_set_error (error, 0, 0, "Unable to connect to server");
                 return FALSE;
         }
 
-        dbus_g_proxy_call (proxy,
-                           "CloseNotification",
-                           &tmp_error,
-                           G_TYPE_UINT,
-                           priv->id,
-                           G_TYPE_INVALID,
-                           G_TYPE_INVALID);
-
-        if (tmp_error != NULL) {
-                g_propagate_error (error, tmp_error);
+        /* FIXME: make this nonblocking! */
+        result = g_dbus_proxy_call_sync (proxy,
+                                         "CloseNotification",
+                                         g_variant_new ("(u)", priv->id),
+                                         G_DBUS_CALL_FLAGS_NONE,
+                                         -1 /* FIXME! */,
+                                         NULL,
+                                         error);
+        if (result == NULL) {
                 return FALSE;
         }
 
+        g_variant_unref (result);
+
         return TRUE;
 }
 
diff --git a/libnotify/notification.h b/libnotify/notification.h
index c117210..b949365 100644
--- a/libnotify/notification.h
+++ b/libnotify/notification.h
@@ -126,6 +126,10 @@ void                notify_notification_set_hint_byte_array   (NotifyNotificatio
                                                                const guchar       *value,
                                                                gsize               len);
 
+void                notify_notification_set_hint              (NotifyNotification *notification,
+                                                               const char         *key,
+                                                               GVariant           *value);
+
 void                notify_notification_clear_hints           (NotifyNotification *notification);
 
 void                notify_notification_add_action            (NotifyNotification *notification,
diff --git a/libnotify/notify.c b/libnotify/notify.c
index d8593cc..1ecc67b 100644
--- a/libnotify/notify.c
+++ b/libnotify/notify.c
@@ -3,6 +3,7 @@
  * Copyright (C) 2004-2006 Christian Hammond <chipx86 chipx86 com>
  * Copyright (C) 2004-2006 Mike Hearn <mike navi cx>
  * Copyright (C) 2010 Red Hat, Inc.
+ * Copyright © 2010 Christian Persch
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -28,8 +29,7 @@
 #include <unistd.h>
 
 #include <glib.h>
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
+#include <gio/gio.h>
 
 #include "notify.h"
 #include "internal.h"
@@ -37,8 +37,7 @@
 
 static gboolean         _initted = FALSE;
 static char            *_app_name = NULL;
-static DBusGProxy      *_proxy = NULL;
-static DBusGConnection *_dbus_gconn = NULL;
+static GDBusProxy      *_proxy = NULL;
 static GList           *_active_notifications = NULL;
 static int              _spec_version_major = 0;
 static int              _spec_version_minor = 0;
@@ -55,11 +54,52 @@ _notify_check_spec_version (int major,
 }
 
 static gboolean
-_notify_update_spec_version (void)
+_notify_get_server_info (char **ret_name,
+                         char **ret_vendor,
+                         char **ret_version,
+                         char **ret_spec_version,
+                         GError **error)
+{
+        GDBusProxy *proxy;
+        GVariant   *result;
+
+        proxy = _notify_get_proxy (error);
+        if (proxy == NULL) {
+                return FALSE;
+        }
+
+        result = g_dbus_proxy_call_sync (proxy,
+                                         "GetServerInformation",
+                                         g_variant_new ("()"),
+                                         G_DBUS_CALL_FLAGS_NONE,
+                                         -1 /* FIXME shorter timeout? */,
+                                         NULL,
+                                         error);
+        if (result == NULL) {
+                return FALSE;
+        }
+        if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(ssss)"))) {
+                g_variant_unref (result);
+                g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
+                             "Unexpected reply type");
+                return FALSE;
+        }
+
+        g_variant_get (result, "(ssss)",
+                       ret_name,
+                       ret_vendor,
+                       ret_version,
+                       ret_spec_version);
+        g_variant_unref (result);
+        return TRUE;
+}
+
+static gboolean
+_notify_update_spec_version (GError **error)
 {
        char *spec_version;
 
-       if (!notify_get_server_info (NULL, NULL, NULL, &spec_version)) {
+       if (!_notify_get_server_info (NULL, NULL, NULL, &spec_version, error)) {
                return FALSE;
        }
 
@@ -146,6 +186,7 @@ notify_uninit (void)
 
         if (_proxy != NULL) {
             g_object_unref (_proxy);
+            _proxy = NULL;
         }
 
         _initted = FALSE;
@@ -164,136 +205,105 @@ notify_is_initted (void)
         return _initted;
 }
 
-DBusGConnection *
-_notify_get_dbus_g_conn (void)
-{
-        return _dbus_gconn;
-}
-
-static void
-on_proxy_destroy (DBusGProxy *proxy,
-                  gpointer    data)
-{
-        _proxy = NULL;
-}
-
-DBusGProxy *
-_notify_get_g_proxy (void)
+/*
+ * _notify_get_proxy:
+ * @error: (allow-none): a location to store a #GError, or %NULL
+ *
+ * Synchronously creates the #GDBusProxy for the notification service,
+ * and caches the result.
+ *
+ * Returns: the #GDBusProxy for the notification service, or %NULL on error
+ */
+GDBusProxy *
+_notify_get_proxy (GError **error)
 {
-        GError          *error;
-        DBusGConnection *bus;
-
         if (_proxy != NULL)
                 return _proxy;
 
-        /* lazily initialize D-Bus connection */
-        error = NULL;
-        bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-        if (error != NULL) {
-                g_error_free (error);
+        _proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+                                                G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
+                                                NULL,
+                                                NOTIFY_DBUS_NAME,
+                                                NOTIFY_DBUS_CORE_OBJECT,
+                                                NOTIFY_DBUS_CORE_INTERFACE,
+                                                NULL,
+                                                error);
+        if (_proxy == NULL) {
                 return NULL;
         }
 
-        _proxy = dbus_g_proxy_new_for_name (bus,
-                                            NOTIFY_DBUS_NAME,
-                                            NOTIFY_DBUS_CORE_OBJECT,
-                                            NOTIFY_DBUS_CORE_INTERFACE);
-        dbus_g_connection_unref (bus);
-
-        g_signal_connect (_proxy,
-                          "destroy",
-                          G_CALLBACK (on_proxy_destroy),
-                          NULL);
-
-        dbus_g_object_register_marshaller (notify_marshal_VOID__UINT_UINT,
-                                           G_TYPE_NONE,
-                                           G_TYPE_UINT,
-                                           G_TYPE_UINT,
-                                           G_TYPE_INVALID);
-
-        dbus_g_object_register_marshaller (notify_marshal_VOID__UINT_STRING,
-                                           G_TYPE_NONE,
-                                           G_TYPE_UINT,
-                                           G_TYPE_STRING,
-                                           G_TYPE_INVALID);
-
-        dbus_g_proxy_add_signal (_proxy,
-                                 "NotificationClosed",
-                                 G_TYPE_UINT,
-                                 G_TYPE_UINT,
-                                 G_TYPE_INVALID);
-        dbus_g_proxy_add_signal (_proxy,
-                                 "ActionInvoked",
-                                 G_TYPE_UINT,
-                                 G_TYPE_STRING,
-                                 G_TYPE_INVALID);
-
-        if (!_notify_update_spec_version ()) {
+        if (!_notify_update_spec_version (error)) {
+               g_object_unref (_proxy);
+               _proxy = NULL;
                return NULL;
         }
 
+        g_object_add_weak_pointer (G_OBJECT (_proxy), (gpointer *) &_proxy);
+
         return _proxy;
 }
 
 /**
  * notify_get_server_caps:
  *
- * Queries the server for its capabilities and returns them in a #GList.
+ * Synchronously queries the server for its capabilities and returns them in a #GList.
  *
- * Returns: A #GList of server capability strings.
+ * Returns: (transfer full) (element-type utf-8): a #GList of server capability strings. Free
+ *   the list elements with g_free() and the list itself with g_list_free().
  */
 GList *
 notify_get_server_caps (void)
 {
-        GError         *error;
-        char          **caps;
-        char          **cap;
-        GList          *result;
-        DBusGProxy     *proxy;
-
-        caps = NULL;
-        result = NULL;
+        GDBusProxy *proxy;
+        GVariant   *result;
+        char      **cap, **caps;
+        GList      *list = NULL;
 
-        proxy = _notify_get_g_proxy ();
+        proxy = _notify_get_proxy (NULL);
         if (proxy == NULL) {
-                return NULL;
+                return FALSE;
         }
 
-        error = NULL;
-        if (!dbus_g_proxy_call (proxy,
-                                "GetCapabilities",
-                                &error,
-                                G_TYPE_INVALID,
-                                G_TYPE_STRV,
-                                &caps,
-                                G_TYPE_INVALID)) {
-                g_error_free (error);
-                return NULL;
+        result = g_dbus_proxy_call_sync (proxy,
+                                         "GetCapabilities",
+                                         g_variant_new ("()"),
+                                         G_DBUS_CALL_FLAGS_NONE,
+                                         -1 /* FIXME shorter timeout? */,
+                                         NULL,
+                                         NULL);
+        if (result == NULL) {
+                return FALSE;
         }
+        if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(as)"))) {
+                g_variant_unref (result);
+                return FALSE;
+        }
+
+        g_variant_get (result, "(^as)", &caps);
 
         for (cap = caps; *cap != NULL; cap++) {
-                result = g_list_append (result, g_strdup (*cap));
+                list = g_list_prepend (list, *cap);
         }
 
-        g_strfreev (caps);
+        g_free (caps);
+        g_variant_unref (result);
 
-        return result;
+        return g_list_reverse (list);
 }
 
 /**
  * notify_get_server_info:
- * @ret_name: The resulting server name.
- * @ret_vendor: The resulting server vendor.
- * @ret_version: The resulting server version.
- * @ret_spec_version: The resulting version of the specification the server is
- *                    compliant with.
+ * @ret_name: (out) (allow-none): a location to store the server name, or %NULL
+ * @ret_vendor: (out) (allow-none): a location to store the server vendor, or %NULL
+ * @ret_version: (out) (allow-none): a location to store the server version, or %NULL
+ * @ret_spec_version: (out) (allow-none): a location to store the version the service is compliant with, or %NULL
  *
- * Queries the server for its information, specifically, the name, vendor,
+ * Synchronously queries the server for its information, specifically, the name, vendor,
  * server version, and the version of the notifications specification that it
  * is compliant with.
  *
- * Returns: %TRUE if successful, and the variables passed will be set. %FALSE
- *          on failure.
+ * Returns: %TRUE if successful, and the variables passed will be set, %FALSE
+ *          on error. The returned strings must be freed with g_free
  */
 gboolean
 notify_get_server_info (char **ret_name,
@@ -301,57 +311,7 @@ notify_get_server_info (char **ret_name,
                         char **ret_version,
                         char **ret_spec_version)
 {
-        GError         *error;
-        DBusGProxy     *proxy;
-        char           *name;
-        char           *vendor;
-        char           *version;
-        char           *spec_version;
-
-        proxy = _notify_get_g_proxy ();
-        if (proxy == NULL) {
-                return FALSE;
-        }
-
-        error = NULL;
-        if (!dbus_g_proxy_call (proxy,
-                                "GetServerInformation",
-                                &error,
-                                G_TYPE_INVALID,
-                                G_TYPE_STRING, &name,
-                                G_TYPE_STRING, &vendor,
-                                G_TYPE_STRING, &version,
-                                G_TYPE_STRING, &spec_version,
-                                G_TYPE_INVALID)) {
-                g_error_free (error);
-                return FALSE;
-        }
-
-        if (ret_name != NULL) {
-                *ret_name = name;
-        } else {
-                g_free (name);
-        }
-
-        if (ret_vendor != NULL) {
-                *ret_vendor = vendor;
-        } else {
-                g_free (vendor);
-        }
-
-        if (ret_version != NULL) {
-                *ret_version = version;
-        } else {
-                g_free (version);
-        }
-
-        if (ret_spec_version != NULL) {
-                *ret_spec_version = spec_version;
-        } else {
-                g_free (spec_version);
-        }
-
-        return TRUE;
+        return _notify_get_server_info (ret_name, ret_vendor, ret_version, ret_spec_version, NULL);
 }
 
 void
diff --git a/libnotify/notify.h b/libnotify/notify.h
index cceb21e..0235419 100644
--- a/libnotify/notify.h
+++ b/libnotify/notify.h
@@ -60,25 +60,8 @@ gboolean        notify_is_initted (void);
  */
 const char     *notify_get_app_name (void);
 
-/**
- * Returns the capabilities of the notification server.
- *
- * @return A list of capability strings. These strings must be freed.
- */
 GList          *notify_get_server_caps (void);
 
-/**
- * Returns the server notification information.
- *
- * The strings returned must be freed.
- *
- * @param ret_name         The returned product name of the server.
- * @param ret_vendor       The returned vendor.
- * @param ret_version      The returned server version.
- * @param ret_spec_version The returned specification version supported.
- *
- * @return TRUE if the call succeeded, or FALSE if there were errors.
- */
 gboolean        notify_get_server_info (char **ret_name,
                                         char **ret_vendor,
                                         char **ret_version,
diff --git a/tests/test-default-action.c b/tests/test-default-action.c
index 4b70623..e103262 100644
--- a/tests/test-default-action.c
+++ b/tests/test-default-action.c
@@ -27,13 +27,6 @@
 #include <assert.h>
 #include <string.h>
 
-#define DBUS_API_SUBJECT_TO_CHANGE
-
-#include <glib.h>
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-
 static GMainLoop *loop;
 
 static void
@@ -54,16 +47,12 @@ int
 main ()
 {
         NotifyNotification *n;
-        DBusConnection     *conn;
 
         if (!notify_init ("Default Action Test"))
                 exit (1);
 
-        conn = dbus_bus_get (DBUS_BUS_SESSION, NULL);
         loop = g_main_loop_new (NULL, FALSE);
 
-        dbus_connection_setup_with_g_main (conn, NULL);
-
         n = notify_notification_new ("Matt is online", "", NULL);
         notify_notification_set_timeout (n, NOTIFY_EXPIRES_DEFAULT);
         notify_notification_add_action (n,
diff --git a/tests/test-image.c b/tests/test-image.c
index 51b29c4..cb25f88 100644
--- a/tests/test-image.c
+++ b/tests/test-image.c
@@ -31,14 +31,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <fcntl.h>
-
-#define DBUS_API_SUBJECT_TO_CHANGE
-
-#include <glib.h>
 #include <gtk/gtk.h>
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
 
 GMainLoop          *loop;
 NotifyNotification *n;
diff --git a/tests/test-multi-actions.c b/tests/test-multi-actions.c
index 55d78a8..f361f79 100644
--- a/tests/test-multi-actions.c
+++ b/tests/test-multi-actions.c
@@ -26,13 +26,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-#define DBUS_API_SUBJECT_TO_CHANGE
-
-#include <glib.h>
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-
 static GMainLoop *loop;
 
 static void
@@ -82,16 +75,12 @@ int
 main (int argc, char **argv)
 {
         NotifyNotification *n;
-        DBusConnection     *conn;
 
         if (!notify_init ("Multi Action Test"))
                 exit (1);
 
-        conn = dbus_bus_get (DBUS_BUS_SESSION, NULL);
         loop = g_main_loop_new (NULL, FALSE);
 
-        dbus_connection_setup_with_g_main (conn, NULL);
-
         n = notify_notification_new ("Low disk space",
                                      "You can free up some disk space by "
                                      "emptying the trash can.",
diff --git a/tests/test-xy-actions.c b/tests/test-xy-actions.c
index b6e3548..060ffea 100644
--- a/tests/test-xy-actions.c
+++ b/tests/test-xy-actions.c
@@ -24,11 +24,6 @@
 #include <stdio.h>
 #include <unistd.h>
 
-#define DBUS_API_SUBJECT_TO_CHANGE
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-
 static GMainLoop *loop;
 
 static void
@@ -44,15 +39,11 @@ int
 main (int argc, char **argv)
 {
         NotifyNotification *n;
-        DBusConnection     *conn;
 
         notify_init ("XY");
 
-        conn = dbus_bus_get (DBUS_BUS_SESSION, NULL);
         loop = g_main_loop_new (NULL, FALSE);
 
-        dbus_connection_setup_with_g_main (conn, NULL);
-
         n = notify_notification_new ("System update available",
                                      "New system updates are available. It is "
                                      "recommended that you install the updates.",



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]