[glib/gdbus-merge] GDBus: Catch up with new PropertiesChanged signal



commit 82158afdadd10e6ffd1540f695931f64957b59f6
Author: David Zeuthen <davidz redhat com>
Date:   Thu May 13 11:56:15 2010 -0400

    GDBus: Catch up with new PropertiesChanged signal
    
    After a long discussion, this has finally been standardized in the
    D-Bus spec. See
    
     http://lists.freedesktop.org/archives/dbus/2010-May/012667.html
     http://lists.freedesktop.org/archives/dbus/2010-May/012712.html
    
    Signed-off-by: David Zeuthen <davidz redhat com>

 gio/gdbusconnection.c                    |    1 +
 gio/gdbusproxy.c                         |   74 ++++++++++++++++++++++++------
 gio/gdbusproxy.h                         |   13 +++--
 gio/gio-marshal.list                     |    1 +
 gio/tests/gdbus-example-export.c         |    7 ++-
 gio/tests/gdbus-example-proxy-subclass.c |   34 ++++++++------
 gio/tests/gdbus-example-server.c         |   12 +++--
 gio/tests/gdbus-example-watch-proxy.c    |   55 ++++++++++++++--------
 gio/tests/gdbus-testserver.py            |    1 +
 9 files changed, 136 insertions(+), 62 deletions(-)
---
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index 559df84..dd49189 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -3549,6 +3549,7 @@ static const gchar introspect_standard_interfaces[] =
   "    <signal name=\"PropertiesChanged\">\n"
   "      <arg type=\"s\" name=\"interface_name\"/>\n"
   "      <arg type=\"a{sv}\" name=\"changed_properties\"/>\n"
+  "      <arg type=\"as\" name=\"invalidated_properties\"/>\n"
   "    </signal>\n"
   "  </interface>\n"
   "  <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
diff --git a/gio/gdbusproxy.c b/gio/gdbusproxy.c
index c1c97d2..17619a1 100644
--- a/gio/gdbusproxy.c
+++ b/gio/gdbusproxy.c
@@ -387,10 +387,17 @@ g_dbus_proxy_class_init (GDBusProxyClass *klass)
   /**
    * GDBusProxy::g-properties-changed:
    * @proxy: The #GDBusProxy emitting the signal.
-   * @changed_properties: A #GVariant containing the properties that changed.
+   * @changed_properties: A #GVariant containing the properties that
+   * changed or %NULL if no properties changed.
+   * @invalidated_properties: A %NULL terminated list of properties that was
+   * invalidated or %NULL if no properties was invalidated.
    *
-   * Emitted when one or more D-Bus properties on @proxy changes. The cached properties
-   * are already replaced when this signal fires.
+   * Emitted when one or more D-Bus properties on @proxy changes. The
+   * local cache has already been updated when this signal fires.
+   *
+   * This signal corresponds to the
+   * <literal>PropertiesChanged</literal> D-Bus signal on the
+   * <literal>org.freedesktop.DBus.Properties</literal> interface.
    *
    * Since: 2.26
    */
@@ -400,10 +407,11 @@ g_dbus_proxy_class_init (GDBusProxyClass *klass)
                                                      G_STRUCT_OFFSET (GDBusProxyClass, g_properties_changed),
                                                      NULL,
                                                      NULL,
-                                                     g_cclosure_marshal_VOID__BOXED,
+                                                     _gio_marshal_VOID__BOXED_BOXED,
                                                      G_TYPE_NONE,
-                                                     1,
-                                                     G_TYPE_VARIANT);
+                                                     2,
+                                                     G_TYPE_VARIANT,
+                                                     G_TYPE_STRV);
 
   /**
    * GDBusProxy::g-signal:
@@ -669,12 +677,17 @@ on_properties_changed (GDBusConnection *connection,
   GError *error;
   const gchar *interface_name_for_signal;
   GVariantIter *iter;
+  GVariantIter *invalidated_iter;
   GVariant *item;
   GVariant *changed_properties;
   GVariantBuilder *builder;
+  GPtrArray *p;
+  const gchar *str;
+  gchar **invalidated_properties;
 
   error = NULL;
   iter = NULL;
+  invalidated_iter = NULL;
 
 #if 0 // TODO!
   /* Ignore this signal if properties are not yet available
@@ -686,27 +699,31 @@ on_properties_changed (GDBusConnection *connection,
     goto out;
 #endif
 
-  if (strcmp (g_variant_get_type_string (parameters), "(sa{sv})") != 0)
+  if (strcmp (g_variant_get_type_string (parameters), "(sa{sv}as)") != 0)
     {
-      g_warning ("Value for PropertiesChanged signal with type `%s' does not match `(sa{sv})'",
+      g_warning ("Value for PropertiesChanged signal with type `%s' does not match `(sa{sv}as)'",
                  g_variant_get_type_string (parameters));
       goto out;
     }
 
   g_variant_get (parameters,
-                 "(sa{sv})",
+                 "(sa{sv}as)",
                  &interface_name_for_signal,
-                 &iter);
+                 &iter,
+                 &invalidated_iter);
 
   if (g_strcmp0 (interface_name_for_signal, proxy->priv->interface_name) != 0)
     goto out;
 
-  builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
+  builder = NULL;
   while ((item = g_variant_iter_next_value (iter)))
     {
       const gchar *key;
       GVariant *value;
 
+      if (builder == NULL)
+        builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
+
       g_variant_get (item,
                      "{sv}",
                      &key,
@@ -721,16 +738,45 @@ on_properties_changed (GDBusConnection *connection,
                              g_strdup (key),
                              g_variant_ref (value));
     }
-  changed_properties = g_variant_builder_end (builder);
+  if (builder != NULL)
+    changed_properties = g_variant_builder_end (builder);
+  else
+    changed_properties = NULL;
+
+  p = NULL;
+  while (g_variant_iter_loop (invalidated_iter, "s", &str))
+    {
+      if (p == NULL)
+        p = g_ptr_array_new ();
+      g_ptr_array_add (p, (gpointer) str);
+    }
+  if (p != NULL)
+    {
+      g_ptr_array_add (p, NULL);
+      invalidated_properties = (gchar **) g_ptr_array_free (p, FALSE);
+    }
+  else
+    {
+      invalidated_properties = NULL;
+    }
+
 
   /* emit signal */
-  g_signal_emit (proxy, signals[PROPERTIES_CHANGED_SIGNAL], 0, changed_properties);
+  g_signal_emit (proxy, signals[PROPERTIES_CHANGED_SIGNAL],
+                 0,
+                 changed_properties,
+                 invalidated_properties);
 
-  g_variant_unref (changed_properties);
+  if (changed_properties != NULL)
+    g_variant_unref (changed_properties);
+  if (invalidated_properties != NULL)
+    g_free (invalidated_properties);
 
  out:
   if (iter != NULL)
     g_variant_iter_free (iter);
+  if (invalidated_iter != NULL)
+    g_variant_iter_free (invalidated_iter);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
diff --git a/gio/gdbusproxy.h b/gio/gdbusproxy.h
index fcf3f96..f860555 100644
--- a/gio/gdbusproxy.h
+++ b/gio/gdbusproxy.h
@@ -69,12 +69,13 @@ struct _GDBusProxyClass
 
   /*< public >*/
   /* Signals */
-  void (*g_properties_changed) (GDBusProxy   *proxy,
-                                GVariant     *changed_properties);
-  void (*g_signal)             (GDBusProxy   *proxy,
-                                const gchar  *sender_name,
-                                const gchar  *signal_name,
-                                GVariant     *parameters);
+  void (*g_properties_changed) (GDBusProxy          *proxy,
+                                GVariant            *changed_properties,
+                                const gchar* const  *invalidated_properties);
+  void (*g_signal)             (GDBusProxy          *proxy,
+                                const gchar         *sender_name,
+                                const gchar         *signal_name,
+                                GVariant            *parameters);
 
   /*< private >*/
   /* Padding for future expansion */
diff --git a/gio/gio-marshal.list b/gio/gio-marshal.list
index 8473ea7..7899b9d 100644
--- a/gio/gio-marshal.list
+++ b/gio/gio-marshal.list
@@ -8,3 +8,4 @@ BOOL:POINTER,INT
 BOOL:UINT
 VOID:STRING,STRING,BOXED
 VOID:BOOL,BOXED
+VOID:BOXED,BOXED
diff --git a/gio/tests/gdbus-example-export.c b/gio/tests/gdbus-example-export.c
index 0f222ce..9dee12f 100644
--- a/gio/tests/gdbus-example-export.c
+++ b/gio/tests/gdbus-example-export.c
@@ -233,9 +233,11 @@ send_property_change (GObject         *obj,
                       GDBusConnection *connection)
 {
   GVariantBuilder *builder;
+  GVariantBuilder *invalidated_builder;
   MyObject *myobj = (MyObject *)obj;
 
   builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
+  invalidated_builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
 
   if (g_strcmp0 (pspec->name, "count") == 0)
     g_variant_builder_add (builder,
@@ -251,9 +253,10 @@ send_property_change (GObject         *obj,
                                  "/org/myorg/MyObject",
                                  "org.freedesktop.DBus.Properties",
                                  "PropertiesChanged",
-                                 g_variant_new ("(sa{sv})",
+                                 g_variant_new ("(sa{sv}as)",
                                                 "org.myorg.MyObject",
-                                                builder),
+                                                builder,
+                                                invalidated_builder),
                                  NULL);
 }
 
diff --git a/gio/tests/gdbus-example-proxy-subclass.c b/gio/tests/gdbus-example-proxy-subclass.c
index 110cbdb..19e313c 100644
--- a/gio/tests/gdbus-example-proxy-subclass.c
+++ b/gio/tests/gdbus-example-proxy-subclass.c
@@ -202,27 +202,31 @@ accounts_user_g_signal (GDBusProxy   *proxy,
 }
 
 static void
-accounts_user_g_properties_changed (GDBusProxy *proxy,
-                                    GVariant   *changed_properties)
+accounts_user_g_properties_changed (GDBusProxy          *proxy,
+                                    GVariant            *changed_properties,
+                                    const gchar* const  *invalidated_properties)
 {
   AccountsUser *user = ACCOUNTS_USER (proxy);
   GVariantIter *iter;
   GVariant *item;
 
-  g_variant_get (changed_properties, "a{sv}", &iter);
-  while ((item = g_variant_iter_next_value (iter)) != NULL)
+  if (changed_properties != NULL)
     {
-      const gchar *key;
-      g_variant_get (item,
-                     "{sv}",
-                     &key,
-                     NULL);
-      if (g_strcmp0 (key, "AutomaticLogin") == 0)
-        g_object_notify (G_OBJECT (user), "automatic-login");
-      else if (g_strcmp0 (key, "RealName") == 0)
-        g_object_notify (G_OBJECT (user), "real-name");
-      else if (g_strcmp0 (key, "UserName") == 0)
-        g_object_notify (G_OBJECT (user), "user-name");
+      g_variant_get (changed_properties, "a{sv}", &iter);
+      while ((item = g_variant_iter_next_value (iter)) != NULL)
+        {
+          const gchar *key;
+          g_variant_get (item,
+                         "{sv}",
+                         &key,
+                         NULL);
+          if (g_strcmp0 (key, "AutomaticLogin") == 0)
+            g_object_notify (G_OBJECT (user), "automatic-login");
+          else if (g_strcmp0 (key, "RealName") == 0)
+            g_object_notify (G_OBJECT (user), "real-name");
+          else if (g_strcmp0 (key, "UserName") == 0)
+            g_object_notify (G_OBJECT (user), "user-name");
+        }
     }
 }
 
diff --git a/gio/tests/gdbus-example-server.c b/gio/tests/gdbus-example-server.c
index a943f65..c4574cd 100644
--- a/gio/tests/gdbus-example-server.c
+++ b/gio/tests/gdbus-example-server.c
@@ -243,9 +243,10 @@ handle_set_property (GDBusConnection  *connection,
                                          object_path,
                                          "org.freedesktop.DBus.Properties",
                                          "PropertiesChanged",
-                                         g_variant_new ("(sa{sv})",
+                                         g_variant_new ("(sa{sv}as)",
                                                         interface_name,
-                                                        builder),
+                                                        builder,
+                                                        NULL),
                                          &local_error);
           g_assert_no_error (local_error);
         }
@@ -283,12 +284,14 @@ on_timeout_cb (gpointer user_data)
 {
   GDBusConnection *connection = G_DBUS_CONNECTION (user_data);
   GVariantBuilder *builder;
+  GVariantBuilder *invalidated_builder;
   GError *error;
 
   swap_a_and_b = !swap_a_and_b;
 
   error = NULL;
   builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
+  invalidated_builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
   g_variant_builder_add (builder,
                          "{sv}",
                          "Foo",
@@ -302,9 +305,10 @@ on_timeout_cb (gpointer user_data)
                                  "/org/gtk/GDBus/TestObject",
                                  "org.freedesktop.DBus.Properties",
                                  "PropertiesChanged",
-                                 g_variant_new ("(sa{sv})",
+                                 g_variant_new ("(sa{sv}as)",
                                                 "org.gtk.GDBus.TestInterface",
-                                                builder),
+                                                builder,
+                                                invalidated_builder),
                                  &error);
   g_assert_no_error (error);
 
diff --git a/gio/tests/gdbus-example-watch-proxy.c b/gio/tests/gdbus-example-watch-proxy.c
index 00768bc..f4796ee 100644
--- a/gio/tests/gdbus-example-watch-proxy.c
+++ b/gio/tests/gdbus-example-watch-proxy.c
@@ -42,32 +42,45 @@ print_properties (GDBusProxy *proxy)
 }
 
 static void
-on_properties_changed (GDBusProxy *proxy,
-                       GVariant   *changed_properties,
-                       gpointer    user_data)
+on_properties_changed (GDBusProxy          *proxy,
+                       GVariant            *changed_properties,
+                       const gchar* const  *invalidated_properties,
+                       gpointer             user_data)
 {
-  GVariantIter *iter;
-  GVariant *item;
 
-  g_print (" *** Properties Changed:\n");
-
-  g_variant_get (changed_properties,
-                 "a{sv}",
-                 &iter);
-  while ((item = g_variant_iter_next_value (iter)))
+  if (changed_properties != NULL)
     {
-      const gchar *key;
-      GVariant *value;
-      gchar *value_str;
-
-      g_variant_get (item,
-                     "{sv}",
-                     &key,
-                     &value);
+      GVariantIter *iter;
+      GVariant *item;
+
+      g_print (" *** Properties Changed:\n");
+      g_variant_get (changed_properties,
+                     "a{sv}",
+                     &iter);
+      while ((item = g_variant_iter_next_value (iter)))
+        {
+          const gchar *key;
+          GVariant *value;
+          gchar *value_str;
+          g_variant_get (item,
+                         "{sv}",
+                         &key,
+                         &value);
+          value_str = g_variant_print (value, TRUE);
+          g_print ("      %s -> %s\n", key, value_str);
+          g_free (value_str);
+        }
+    }
 
-      value_str = g_variant_print (value, TRUE);
-      g_print ("      %s -> %s\n", key, value_str);
-      g_free (value_str);
+  if (invalidated_properties != NULL)
+    {
+      guint n;
+      g_print (" *** Properties Invalidated:\n");
+      for (n = 0; invalidated_properties[n] != NULL; n++)
+        {
+          const gchar *key = invalidated_properties[n];
+          g_print ("      %s\n", key);
+        }
     }
 }
 
diff --git a/gio/tests/gdbus-testserver.py b/gio/tests/gdbus-testserver.py
index 04d654e..d31a493 100755
--- a/gio/tests/gdbus-testserver.py
+++ b/gio/tests/gdbus-testserver.py
@@ -187,6 +187,7 @@ class TestService(dbus.service.Object):
                                               "PropertiesChanged")
         message.append("com.example.Frob")
         message.append({prop_name : prop_value})
+        message.append([], signature="as")
         session_bus.send_message(message)
     # ----------------------------------------------------------------------------------------------------
 



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