[notification-daemon] Port to GDBus



commit 60ae378d785ccb3eed0027ae292bc85bf34d3743
Author: William Jon McCann <jmccann redhat com>
Date:   Thu Oct 28 18:59:30 2010 -0400

    Port to GDBus
    
    https://bugzilla.gnome.org/show_bug.cgi?id=622892

 configure.ac          |   21 +---
 src/daemon.c          |  419 ++++++++++++++++++++++++++-----------------------
 src/daemon.h          |   29 ----
 src/nd-notification.c |  205 +++++-------------------
 src/nd-notification.h |    2 +-
 5 files changed, 264 insertions(+), 412 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 85da557..72159b2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -81,13 +81,11 @@ dnl Requirements for the daemon
 dnl ---------------------------------------------------------------------------
 REQ_GTK_VERSION=2.91.0
 REQ_GLIB_VERSION=2.27.0
-REQ_DBUS_VERSION=0.78
 REQ_LIBCANBERRA_GTK_VERSION=0.4
 pkg_modules="
 	gtk+-3.0 >= $REQ_GTK_VERSION, \
 	glib-2.0 >= $REQ_GLIB_VERSION, \
-	dbus-1 >= $REQ_DBUS_VERSION, \
-	dbus-glib-1 >= $REQ_DBUS_VERSION, \
+        gio-2.0 >= $REQ_GLIB_VERSION, \
         libcanberra-gtk3 >= $REQ_LIBCANBERRA_GTK_VERSION, \
         x11 \
 "
@@ -95,23 +93,6 @@ PKG_CHECK_MODULES(NOTIFICATION_DAEMON, $pkg_modules)
 AC_SUBST(NOTIFICATION_DAEMON_CFLAGS)
 AC_SUBST(NOTIFICATION_DAEMON_LIBS)
 
-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.])
-
-AC_DEFINE_UNQUOTED(DBUS_API_SUBJECT_TO_CHANGE, ,DBUS API is subject to change)
-
 AS_AC_EXPAND(SYSCONFDIR, $sysconfdir)
 AS_AC_EXPAND(LIBDIR, $libdir)
 AS_AC_EXPAND(DATADIR, $datadir)
diff --git a/src/daemon.c b/src/daemon.c
index a26bb93..f93002c 100644
--- a/src/daemon.c
+++ b/src/daemon.c
@@ -27,10 +27,9 @@
 #include <string.h>
 #include <stdio.h>
 
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib.h>
 #include <glib/gi18n.h>
 #include <glib.h>
+#include <gio/gio.h>
 #include <glib-object.h>
 #include <gtk/gtk.h>
 
@@ -44,7 +43,6 @@
 #include "daemon.h"
 #include "nd-notification.h"
 #include "nd-queue.h"
-#include "notificationdaemon-dbus-glue.h"
 
 #define MAX_NOTIFICATIONS 20
 
@@ -57,12 +55,11 @@
 
 struct _NotifyDaemonPrivate
 {
-        guint           exit_timeout_source;
-        NdQueue        *queue;
+        GDBusConnection *connection;
+        guint            exit_timeout_source;
+        NdQueue         *queue;
 };
 
-static DBusConnection *dbus_conn = NULL;
-
 static void notify_daemon_finalize (GObject *object);
 
 G_DEFINE_TYPE (NotifyDaemon, notify_daemon, G_TYPE_OBJECT);
@@ -143,56 +140,18 @@ notify_daemon_finalize (GObject *object)
         G_OBJECT_CLASS (notify_daemon_parent_class)->finalize (object);
 }
 
-static DBusMessage *
-create_signal_for_notification (NdNotification *notification,
-                                const char     *signal_name)
-{
-        guint           id;
-        const char     *dest;
-        DBusMessage    *message;
-
-        id = nd_notification_get_id (notification);
-        dest = nd_notification_get_sender (notification);
-        g_assert (dest != NULL);
-
-        message = dbus_message_new_signal (NOTIFICATION_BUS_PATH,
-                                           NOTIFICATION_BUS_NAME,
-                                           signal_name);
-
-        dbus_message_set_destination (message, dest);
-        dbus_message_append_args (message,
-                                  DBUS_TYPE_UINT32,
-                                  &id,
-                                  DBUS_TYPE_INVALID);
-
-        return message;
-}
-
-GQuark
-notify_daemon_error_quark (void)
-{
-        static GQuark   q = 0;
-
-        if (q == 0)
-                q = g_quark_from_static_string ("notification-daemon-error-quark");
-
-        return q;
-}
-
 static void
 on_notification_close (NdNotification *notification,
                        int             reason,
                        NotifyDaemon   *daemon)
 {
-        DBusMessage *message;
-
-        message = create_signal_for_notification (notification, "NotificationClosed");
-        dbus_message_append_args (message,
-                                  DBUS_TYPE_UINT32,
-                                  &reason,
-                                  DBUS_TYPE_INVALID);
-        dbus_connection_send (dbus_conn, message, NULL);
-        dbus_message_unref (message);
+        g_dbus_connection_emit_signal (daemon->priv->connection,
+                                       nd_notification_get_sender (notification),
+                                       "/org/freedesktop/Notifications",
+                                       "org.freedesktop.Notifications",
+                                       "NotificationClosed",
+                                       g_variant_new ("(uu)", nd_notification_get_id (notification), reason),
+                                       NULL);
 }
 
 static void
@@ -200,51 +159,87 @@ on_notification_action_invoked (NdNotification *notification,
                                 const char     *action,
                                 NotifyDaemon   *daemon)
 {
-        guint           id;
-        DBusMessage    *message;
-
-        id = nd_notification_get_id (notification);
-        message = create_signal_for_notification (notification, "ActionInvoked");
-        dbus_message_append_args (message,
-                                  DBUS_TYPE_STRING,
-                                  &action,
-                                  DBUS_TYPE_INVALID);
-
-        dbus_connection_send (dbus_conn, message, NULL);
-        dbus_message_unref (message);
+        g_dbus_connection_emit_signal (daemon->priv->connection,
+                                       nd_notification_get_sender (notification),
+                                       "/org/freedesktop/Notifications",
+                                       "org.freedesktop.Notifications",
+                                       "ActionInvoked",
+                                       g_variant_new ("(us)", nd_notification_get_id (notification), action),
+                                       NULL);
 
         nd_notification_close (notification, ND_NOTIFICATION_CLOSED_USER);
 }
 
-gboolean
-notify_daemon_notify_handler (NotifyDaemon *daemon,
-                              const char   *app_name,
-                              guint         id,
-                              const char   *icon,
-                              const char   *summary,
-                              const char   *body,
-                              char        **actions,
-                              GHashTable   *hints,
-                              int           timeout,
-                              DBusGMethodInvocation *context)
-{
-        NotifyDaemonPrivate *priv = daemon->priv;
-        NdNotification      *notification;
+/* ---------------------------------------------------------------------------------------------- */
+
+static GDBusNodeInfo *introspection_data = NULL;
+
+/* Introspection data for the service we are exporting */
+static const char introspection_xml[] =
+        "<node>"
+        "  <interface name='org.freedesktop.Notifications'>"
+        "    <method name='Notify'>"
+        "      <arg type='s' name='app_name' direction='in' />"
+        "      <arg type='u' name='id' direction='in' />"
+        "      <arg type='s' name='icon' direction='in' />"
+        "      <arg type='s' name='summary' direction='in' />"
+        "      <arg type='s' name='body' direction='in' />"
+        "      <arg type='as' name='actions' direction='in' />"
+        "      <arg type='a{sv}' name='hints' direction='in' />"
+        "      <arg type='i' name='timeout' direction='in' />"
+        "      <arg type='u' name='return_id' direction='out' />"
+        "    </method>"
+        "    <method name='CloseNotification'>"
+        "      <arg type='u' name='id' direction='in' />"
+        "    </method>"
+        "    <method name='GetCapabilities'>"
+        "      <arg type='as' name='return_caps' direction='out'/>"
+        "    </method>"
+        "    <method name='GetServerInformation'>"
+        "      <arg type='s' name='return_name' direction='out'/>"
+        "      <arg type='s' name='return_vendor' direction='out'/>"
+        "      <arg type='s' name='return_version' direction='out'/>"
+        "      <arg type='s' name='return_spec_version' direction='out'/>"
+        "    </method>"
+        "  </interface>"
+        "</node>";
 
-        if (nd_queue_length (priv->queue) > MAX_NOTIFICATIONS) {
-                GError *error;
-
-                error = g_error_new (notify_daemon_error_quark (),
-                                     1,
-                                     _("Exceeded maximum number of notifications"));
-                dbus_g_method_return_error (context, error);
-                g_error_free (error);
-
-                return TRUE;
+static void
+handle_notify (NotifyDaemon          *daemon,
+               const char            *sender,
+               GVariant              *parameters,
+               GDBusMethodInvocation *invocation)
+{
+        NdNotification *notification;
+        const char     *app_name;
+        guint           id;
+        const char     *icon_name;
+        const char     *summary;
+        const char     *body;
+        const char    **actions;
+        GVariantIter   *hints_iter;
+        int             timeout;
+
+        if (nd_queue_length (daemon->priv->queue) > MAX_NOTIFICATIONS) {
+                g_dbus_method_invocation_return_dbus_error (invocation,
+                                                            "org.freedesktop.Notifications.MaxNotificationsExceeded",
+                                                            _("Exceeded maximum number of notifications"));
+                return;
         }
 
+        g_variant_get (parameters,
+                       "(&su&s&s&s^a&sa{sv}i)",
+                       &app_name,
+                       &id,
+                       &icon_name,
+                       &summary,
+                       &body,
+                       &actions,
+                       &hints_iter,
+                       &timeout);
+
         if (id > 0) {
-                notification = nd_queue_lookup (priv->queue, id);
+                notification = nd_queue_lookup (daemon->priv->queue, id);
                 if (notification == NULL) {
                         id = 0;
                 } else {
@@ -253,163 +248,189 @@ notify_daemon_notify_handler (NotifyDaemon *daemon,
         }
 
         if (id == 0) {
-                char *sender;
-
-                sender = dbus_g_method_get_sender (context);
-
                 notification = nd_notification_new (sender);
-
-                g_free (sender);
         }
 
         nd_notification_update (notification,
                                 app_name,
-                                icon,
+                                icon_name,
                                 summary,
                                 body,
-                                (const char **)actions,
-                                hints,
+                                actions,
+                                hints_iter,
                                 timeout);
         g_signal_connect (notification, "closed", G_CALLBACK (on_notification_close), daemon);
         g_signal_connect (notification, "action-invoked", G_CALLBACK (on_notification_action_invoked), daemon);
 
         if (id == 0) {
-                nd_queue_add (priv->queue, notification);
+                nd_queue_add (daemon->priv->queue, notification);
         }
 
-        dbus_g_method_return (context, nd_notification_get_id (notification));
+        g_dbus_method_invocation_return_value (invocation,
+                                               g_variant_new ("(u)", nd_notification_get_id (notification)));
 
         g_object_unref (notification);
-
-        return TRUE;
 }
 
-gboolean
-notify_daemon_close_notification_handler (NotifyDaemon *daemon,
-                                          guint         id,
-                                          GError      **error)
+static void
+handle_close_notification (NotifyDaemon          *daemon,
+                           const char            *sender,
+                           GVariant              *parameters,
+                           GDBusMethodInvocation *invocation)
 {
+        NdNotification *notification;
+        guint           id;
+
+        g_variant_get (parameters, "(u)", &id);
+
         if (id == 0) {
-                g_set_error (error,
-                             notify_daemon_error_quark (),
-                             100,
-                             _("%u is not a valid notification ID"),
-                             id);
-                return FALSE;
-        } else {
-                NdNotification *notification;
+                g_dbus_method_invocation_return_dbus_error (invocation,
+                                                            "org.freedesktop.Notifications.InvalidId",
+                                                            _("Invalid notification identifier"));
+                return;
+        }
 
-                notification = nd_queue_lookup (daemon->priv->queue, id);
-                if (notification != NULL) {
-                        nd_notification_close (notification, ND_NOTIFICATION_CLOSED_API);
-                }
+        notification = nd_queue_lookup (daemon->priv->queue, id);
+        if (notification != NULL) {
+                nd_notification_close (notification, ND_NOTIFICATION_CLOSED_API);
+        }
 
-                return TRUE;
+        g_dbus_method_invocation_return_value (invocation, NULL);
+}
+
+static void
+handle_get_capabilities (NotifyDaemon          *daemon,
+                         const char            *sender,
+                         GVariant              *parameters,
+                         GDBusMethodInvocation *invocation)
+{
+        GVariantBuilder *builder;
+
+        builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
+        g_variant_builder_add (builder, "s", "actions");
+        g_variant_builder_add (builder, "s", "body");
+        g_variant_builder_add (builder, "s", "body-hyperlinks");
+        g_variant_builder_add (builder, "s", "body-markup");
+        g_variant_builder_add (builder, "s", "icon-static");
+        g_variant_builder_add (builder, "s", "sound");
+        g_variant_builder_add (builder, "s", "persistence");
+
+        g_dbus_method_invocation_return_value (invocation,
+                                               g_variant_new ("(as)", builder));
+        g_variant_builder_unref (builder);
+}
+
+static void
+handle_get_server_information (NotifyDaemon          *daemon,
+                               const char            *sender,
+                               GVariant              *parameters,
+                               GDBusMethodInvocation *invocation)
+{
+        g_dbus_method_invocation_return_value (invocation,
+                                               g_variant_new ("(ssss)",
+                                                              "Notification Daemon",
+                                                              "GNOME",
+                                                              PACKAGE_VERSION,
+                                                              "1.1"));
+}
+
+static void
+handle_method_call (GDBusConnection       *connection,
+                    const char            *sender,
+                    const char            *object_path,
+                    const char            *interface_name,
+                    const char            *method_name,
+                    GVariant              *parameters,
+                    GDBusMethodInvocation *invocation,
+                    gpointer               user_data)
+{
+        NotifyDaemon *daemon = user_data;
+
+        if (g_strcmp0 (method_name, "Notify") == 0) {
+                handle_notify (daemon, sender, parameters, invocation);
+        } else if (g_strcmp0 (method_name, "CloseNotification") == 0) {
+                handle_close_notification (daemon, sender, parameters, invocation);
+        } else if (g_strcmp0 (method_name, "GetCapabilities") == 0) {
+                handle_get_capabilities (daemon, sender, parameters, invocation);
+        } else if (g_strcmp0 (method_name, "GetServerInformation") == 0) {
+                handle_get_server_information (daemon, sender, parameters, invocation);
         }
 }
 
-gboolean
-notify_daemon_get_capabilities (NotifyDaemon *daemon,
-                                char       ***caps)
+/* for now */
+static const GDBusInterfaceVTable interface_vtable =
 {
-        GPtrArray *a;
-        char     **_caps;
-
-        a = g_ptr_array_new ();
-        g_ptr_array_add (a, g_strdup ("actions"));
-        g_ptr_array_add (a, g_strdup ("body"));
-        g_ptr_array_add (a, g_strdup ("body-hyperlinks"));
-        g_ptr_array_add (a, g_strdup ("body-markup"));
-        g_ptr_array_add (a, g_strdup ("icon-static"));
-        g_ptr_array_add (a, g_strdup ("sound"));
-        g_ptr_array_add (a, g_strdup ("persistence"));
-        g_ptr_array_add (a, NULL);
-        _caps = (char **) g_ptr_array_free (a, FALSE);
-
-        *caps = _caps;
-
-        return TRUE;
+        handle_method_call,
+        NULL, /* get property */
+        NULL  /* set property */
+};
+
+static void
+on_bus_acquired (GDBusConnection *connection,
+                 const char      *name,
+                 gpointer         user_data)
+{
+        NotifyDaemon *daemon = user_data;
+        guint         registration_id;
+
+        registration_id = g_dbus_connection_register_object (connection,
+                                                             "/org/freedesktop/Notifications",
+                                                             introspection_data->interfaces[0],
+                                                             &interface_vtable,
+                                                             daemon,
+                                                             NULL,  /* user_data_free_func */
+                                                             NULL); /* GError** */
+        g_assert (registration_id > 0);
 }
 
-gboolean
-notify_daemon_get_server_information (NotifyDaemon *daemon,
-                                      char        **out_name,
-                                      char        **out_vendor,
-                                      char        **out_version,
-                                      char        **out_spec_ver)
+static void
+on_name_acquired (GDBusConnection *connection,
+                  const char      *name,
+                  gpointer         user_data)
 {
-        *out_name = g_strdup ("Notification Daemon");
-        *out_vendor = g_strdup ("GNOME");
-        *out_version = g_strdup (PACKAGE_VERSION);
-        *out_spec_ver = g_strdup ("1.1");
+        NotifyDaemon *daemon = user_data;
+        daemon->priv->connection = connection;
+}
 
-        return TRUE;
+static void
+on_name_lost (GDBusConnection *connection,
+              const char      *name,
+              gpointer         user_data)
+{
+        exit (1);
 }
 
+
 int
 main (int argc, char **argv)
 {
-        NotifyDaemon    *daemon;
-        DBusGConnection *connection;
-        DBusGProxy      *bus_proxy;
-        GError          *error;
-        gboolean         res;
-        guint            request_name_result;
+        NotifyDaemon *daemon;
+        guint         owner_id;
 
         g_log_set_always_fatal (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
 
         gtk_init (&argc, &argv);
 
-        error = NULL;
-        connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-        if (connection == NULL) {
-                g_printerr ("Failed to open connection to bus: %s\n",
-                            error->message);
-                g_error_free (error);
-                exit (1);
-        }
-
-        dbus_conn = dbus_g_connection_get_connection (connection);
-
-        dbus_g_object_type_install_info (NOTIFY_TYPE_DAEMON,
-                                         &dbus_glib_notification_daemon_object_info);
-
-        bus_proxy = dbus_g_proxy_new_for_name (connection,
-                                               "org.freedesktop.DBus",
-                                               "/org/freedesktop/DBus",
-                                               "org.freedesktop.DBus");
-
-        res = dbus_g_proxy_call (bus_proxy,
-                                 "RequestName",
-                                 &error,
-                                 G_TYPE_STRING, NOTIFICATION_BUS_NAME,
-                                 G_TYPE_UINT, 0,
-                                 G_TYPE_INVALID,
-                                 G_TYPE_UINT, &request_name_result,
-                                 G_TYPE_INVALID);
-        if (! res
-            || request_name_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
-                if (error != NULL) {
-                        g_warning ("Failed to acquire name %s: %s",
-                                   NOTIFICATION_BUS_NAME,
-                                   error->message);
-                        g_error_free (error);
-                } else {
-                        g_warning ("Failed to acquire name %s", NOTIFICATION_BUS_NAME);
-                }
-                goto out;
-        }
+        introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+        g_assert (introspection_data != NULL);
 
         daemon = g_object_new (NOTIFY_TYPE_DAEMON, NULL);
 
-        dbus_g_connection_register_g_object (connection,
-                                             "/org/freedesktop/Notifications",
-                                             G_OBJECT (daemon));
+        owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
+                                   "org.freedesktop.Notifications",
+                                   G_BUS_NAME_OWNER_FLAGS_NONE,
+                                   on_bus_acquired,
+                                   on_name_acquired,
+                                   on_name_lost,
+                                   daemon,
+                                   NULL);
 
         gtk_main ();
 
+        g_bus_unown_name (owner_id);
+        g_dbus_node_info_unref (introspection_data);
+
         g_object_unref (daemon);
- out:
 
         return 0;
 }
diff --git a/src/daemon.h b/src/daemon.h
index 7a55dd1..e9e7412 100644
--- a/src/daemon.h
+++ b/src/daemon.h
@@ -25,9 +25,6 @@
 #include <glib.h>
 #include <glib-object.h>
 
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-
 #define NOTIFY_TYPE_DAEMON (notify_daemon_get_type())
 #define NOTIFY_DAEMON(obj) \
         (G_TYPE_CHECK_INSTANCE_CAST ((obj), NOTIFY_TYPE_DAEMON, NotifyDaemon))
@@ -68,31 +65,5 @@ struct _NotifyDaemonClass
 
 G_BEGIN_DECLS GType notify_daemon_get_type (void);
 
-GQuark          notify_daemon_error_quark (void);
-
-gboolean        notify_daemon_notify_handler             (NotifyDaemon *daemon,
-                                                          const gchar  *app_name,
-                                                          guint         id,
-                                                          const gchar  *icon,
-                                                          const gchar  *summary,
-                                                          const gchar  *body,
-                                                          gchar       **actions,
-                                                          GHashTable   *hints,
-                                                          int           timeout,
-                                                          DBusGMethodInvocation *context);
-
-gboolean        notify_daemon_close_notification_handler (NotifyDaemon *daemon,
-                                                          guint         id,
-                                                          GError      **error);
-
-gboolean        notify_daemon_get_capabilities           (NotifyDaemon *daemon,
-                                                          char       ***out_caps);
-
-gboolean        notify_daemon_get_server_information     (NotifyDaemon *daemon,
-                                                          char        **out_name,
-                                                          char        **out_vendor,
-                                                          char        **out_version,
-                                                          char        **out_spec_ver);
-
 G_END_DECLS
 #endif /* NOTIFY_DAEMON_H */
diff --git a/src/nd-notification.c b/src/nd-notification.c
index 0910c55..dffb099 100644
--- a/src/nd-notification.c
+++ b/src/nd-notification.c
@@ -22,7 +22,6 @@
 #include <string.h>
 #include <strings.h>
 #include <gtk/gtk.h>
-#include <dbus/dbus-glib.h>
 
 #include "nd-notification.h"
 
@@ -112,13 +111,6 @@ nd_notification_class_init (NdNotificationClass *class)
                               G_TYPE_NONE, 1, G_TYPE_STRING);
 }
 
- static void
-_g_value_free (GValue *value)
-{
-        g_value_unset (value);
-        g_free (value);
-}
-
 static void
 nd_notification_init (NdNotification *notification)
 {
@@ -132,7 +124,7 @@ nd_notification_init (NdNotification *notification)
         notification->hints = g_hash_table_new_full (g_str_hash,
                                                      g_str_equal,
                                                      g_free,
-                                                     (GDestroyNotify) _g_value_free);
+                                                     (GDestroyNotify) g_variant_unref);
 }
 
 static void
@@ -164,11 +156,10 @@ nd_notification_update (NdNotification *notification,
                         const char     *summary,
                         const char     *body,
                         const char    **actions,
-                        GHashTable     *hints,
+                        GVariantIter   *hints_iter,
                         int             timeout)
 {
-        GHashTableIter iter;
-        gpointer       key, value;
+        GVariant *item;
 
         g_return_val_if_fail (ND_IS_NOTIFICATION (notification), FALSE);
 
@@ -189,15 +180,18 @@ nd_notification_update (NdNotification *notification,
 
         g_hash_table_remove_all (notification->hints);
 
-        g_hash_table_iter_init (&iter, hints);
-        while (g_hash_table_iter_next (&iter, &key, &value)) {
-                GValue *value_copy;
+        while ((item = g_variant_iter_next_value (hints_iter))) {
+                const char *key;
+                GVariant   *value;
 
-                value_copy = g_new0 (GValue, 1);
-                g_value_init (value_copy, G_VALUE_TYPE (value));
-                g_value_copy (value, value_copy);
+                g_variant_get (item,
+                               "{sv}",
+                               &key,
+                               &value);
 
-                g_hash_table_insert (notification->hints, g_strdup (key), value_copy);
+                g_hash_table_insert (notification->hints,
+                                     g_strdup (key),
+                                     value); /* steals value */
         }
 
         g_signal_emit (notification, signals[CHANGED], 0);
@@ -328,159 +322,44 @@ scale_pixbuf (GdkPixbuf *pixbuf,
 }
 
 static GdkPixbuf *
-_notify_daemon_pixbuf_from_data_hint (GValue *icon_data,
-                                      int     size)
+_notify_daemon_pixbuf_from_data_hint (GVariant *icon_data,
+                                      int       size)
 {
-        const guchar   *data = NULL;
         gboolean        has_alpha;
         int             bits_per_sample;
         int             width;
         int             height;
         int             rowstride;
         int             n_channels;
+        GVariant       *data_variant;
         gsize           expected_len;
+        guchar         *data;
         GdkPixbuf      *pixbuf;
-        GValueArray    *image_struct;
-        GValue         *value;
-        GArray         *tmp_array;
-        GType           struct_type;
-
-        struct_type = dbus_g_type_get_struct ("GValueArray",
-                                              G_TYPE_INT,
-                                              G_TYPE_INT,
-                                              G_TYPE_INT,
-                                              G_TYPE_BOOLEAN,
-                                              G_TYPE_INT,
-                                              G_TYPE_INT,
-                                              dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR),
-                                              G_TYPE_INVALID);
-
-        if (!G_VALUE_HOLDS (icon_data, struct_type)) {
-                g_warning ("_notify_daemon_pixbuf_from_data_hint expected a "
-                           "GValue of type GValueArray");
-                return NULL;
-        }
-
-        image_struct = (GValueArray *) g_value_get_boxed (icon_data);
-        value = g_value_array_get_nth (image_struct, 0);
-
-        if (value == NULL) {
-                g_warning ("_notify_daemon_pixbuf_from_data_hint expected position "
-                           "0 of the GValueArray to exist");
-                return NULL;
-        }
-
-        if (!G_VALUE_HOLDS (value, G_TYPE_INT)) {
-                g_warning ("_notify_daemon_pixbuf_from_data_hint expected "
-                           "position 0 of the GValueArray to be of type int");
-                return NULL;
-        }
-
-        width = g_value_get_int (value);
-        value = g_value_array_get_nth (image_struct, 1);
-
-        if (value == NULL) {
-                g_warning ("_notify_daemon_pixbuf_from_data_hint expected "
-                           "position 1 of the GValueArray to exist");
-                return NULL;
-        }
-
-        if (!G_VALUE_HOLDS (value, G_TYPE_INT)) {
-                g_warning ("_notify_daemon_pixbuf_from_data_hint expected "
-                           "position 1 of the GValueArray to be of type int");
-                return NULL;
-        }
-
-        height = g_value_get_int (value);
-        value = g_value_array_get_nth (image_struct, 2);
-
-        if (value == NULL) {
-                g_warning ("_notify_daemon_pixbuf_from_data_hint expected "
-                           "position 2 of the GValueArray to exist");
-                return NULL;
-        }
-
-        if (!G_VALUE_HOLDS (value, G_TYPE_INT)) {
-                g_warning ("_notify_daemon_pixbuf_from_data_hint expected "
-                           "position 2 of the GValueArray to be of type int");
-                return NULL;
-        }
-
-        rowstride = g_value_get_int (value);
-        value = g_value_array_get_nth (image_struct, 3);
 
-        if (value == NULL) {
-                g_warning ("_notify_daemon_pixbuf_from_data_hint expected "
-                           "position 3 of the GValueArray to exist");
-                return NULL;
-        }
-
-        if (!G_VALUE_HOLDS (value, G_TYPE_BOOLEAN)) {
-                g_warning ("_notify_daemon_pixbuf_from_data_hint expected "
-                           "position 3 of the GValueArray to be of type gboolean");
-                return NULL;
-        }
-
-        has_alpha = g_value_get_boolean (value);
-        value = g_value_array_get_nth (image_struct, 4);
-
-        if (value == NULL) {
-                g_warning ("_notify_daemon_pixbuf_from_data_hint expected "
-                           "position 4 of the GValueArray to exist");
-                return NULL;
-        }
+        g_variant_get (icon_data,
+                       "(iiibii ay)",
+                       &width,
+                       &height,
+                       &rowstride,
+                       &has_alpha,
+                       &bits_per_sample,
+                       &n_channels,
+                       &data_variant);
 
-        if (!G_VALUE_HOLDS (value, G_TYPE_INT)) {
-                g_warning ("_notify_daemon_pixbuf_from_data_hint expected "
-                           "position 4 of the GValueArray to be of type int");
-                return NULL;
-        }
-
-        bits_per_sample = g_value_get_int (value);
-        value = g_value_array_get_nth (image_struct, 5);
-
-        if (value == NULL) {
-                g_warning ("_notify_daemon_pixbuf_from_data_hint expected "
-                           "position 5 of the GValueArray to exist");
-                return NULL;
-        }
-
-        if (!G_VALUE_HOLDS (value, G_TYPE_INT)) {
-                g_warning ("_notify_daemon_pixbuf_from_data_hint expected "
-                           "position 5 of the GValueArray to be of type int");
-                return NULL;
-        }
-
-        n_channels = g_value_get_int (value);
-        value = g_value_array_get_nth (image_struct, 6);
-
-        if (value == NULL) {
-                g_warning ("_notify_daemon_pixbuf_from_data_hint expected "
-                           "position 6 of the GValueArray to exist");
-                return NULL;
-        }
-
-        if (!G_VALUE_HOLDS (value,
-                            dbus_g_type_get_collection ("GArray",
-                                                        G_TYPE_UCHAR))) {
-                g_warning ("_notify_daemon_pixbuf_from_data_hint expected "
-                           "position 6 of the GValueArray to be of type GArray");
-                return NULL;
-        }
-
-        tmp_array = (GArray *) g_value_get_boxed (value);
         expected_len = (height - 1) * rowstride + width
                 * ((n_channels * bits_per_sample + 7) / 8);
 
-        if (expected_len != tmp_array->len) {
-                g_warning ("_notify_daemon_pixbuf_from_data_hint expected image "
-                           "data to be of length %" G_GSIZE_FORMAT
-                           " but got a " "length of %u", expected_len,
-                           tmp_array->len);
+        if (expected_len != g_variant_get_size (data_variant)) {
+                g_warning ("Expected image data to be of length %" G_GSIZE_FORMAT
+                           " but got a " "length of %u",
+                           expected_len,
+                           g_variant_get_size (data_variant));
                 return NULL;
         }
 
-        data = (guchar *) g_memdup (tmp_array->data, tmp_array->len);
+        data = (guchar *) g_memdup (g_variant_get_data (data_variant),
+                                    g_variant_get_size (data_variant));
+
         pixbuf = gdk_pixbuf_new_from_data (data,
                                            GDK_COLORSPACE_RGB,
                                            has_alpha,
@@ -554,24 +433,24 @@ GdkPixbuf *
 nd_notification_load_image (NdNotification *notification,
                             int             size)
 {
-        GValue    *data;
+        GVariant  *data;
         GdkPixbuf *pixbuf;
 
         pixbuf = NULL;
 
-        if ((data = (GValue *) g_hash_table_lookup (notification->hints, "image_data"))) {
+        if ((data = (GVariant *) g_hash_table_lookup (notification->hints, "image_data"))) {
                 pixbuf = _notify_daemon_pixbuf_from_data_hint (data, size);
-        } else if ((data = (GValue *) g_hash_table_lookup (notification->hints, "image_path"))) {
-                if (G_VALUE_HOLDS_STRING (data)) {
-                        const char *path = g_value_get_string (data);
+        } else if ((data = (GVariant *) g_hash_table_lookup (notification->hints, "image_path"))) {
+                if (g_variant_is_of_type (data, G_VARIANT_TYPE ("(s)"))) {
+                        const char *path;
+                        path = g_variant_get_string (data, NULL);
                         pixbuf = _notify_daemon_pixbuf_from_path (path, size);
                 } else {
-                        g_warning ("notify_daemon_notify_handler expected "
-                                   "image_path hint to be of type string");
+                        g_warning ("Expected image_path hint to be of type string");
                 }
         } else if (*notification->icon != '\0') {
                 pixbuf = _notify_daemon_pixbuf_from_path (notification->icon, size);
-        } else if ((data = (GValue *) g_hash_table_lookup (notification->hints, "icon_data"))) {
+        } else if ((data = (GVariant *) g_hash_table_lookup (notification->hints, "icon_data"))) {
                 g_warning("\"icon_data\" hint is deprecated, please use \"image_data\" instead");
                 pixbuf = _notify_daemon_pixbuf_from_data_hint (data, size);
         }
diff --git a/src/nd-notification.h b/src/nd-notification.h
index b2c4438..b6dc19b 100644
--- a/src/nd-notification.h
+++ b/src/nd-notification.h
@@ -53,7 +53,7 @@ gboolean              nd_notification_update              (NdNotification *notif
                                                            const char     *summary,
                                                            const char     *body,
                                                            const char    **actions,
-                                                           GHashTable     *hints,
+                                                           GVariantIter   *hints_iter,
                                                            int             timeout);
 
 gboolean              nd_notification_get_is_closed       (NdNotification *notification);



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