Expect attributes in a collection match rule to be sent as a hash
[platform/core/uifw/at-spi2-atk.git] / droute / droute.c
index 0700283..a6fe157 100644 (file)
@@ -42,7 +42,7 @@ struct _DRouteContext
     DBusConnection       *bus;
     GPtrArray            *registered_paths;
 
-    gchar                *introspect_dir;
+    gchar                *introspect_string;
 };
 
 struct _DRoutePath
@@ -50,9 +50,12 @@ struct _DRoutePath
     DRouteContext        *cnx;
     GStringChunk         *chunks;
     GPtrArray            *interfaces;
+    GPtrArray            *introspection;
     GHashTable           *methods;
     GHashTable           *properties;
 
+    DRouteIntrospectChildrenFunction introspect_children_cb;
+    void *introspect_children_data;
     void                   *user_data;
     DRouteGetDatumFunction  get_datum;
 };
@@ -78,6 +81,8 @@ droute_object_does_not_exist_error (DBusMessage *message);
 static DRoutePath *
 path_new (DRouteContext *cnx,
           void    *user_data,
+          DRouteIntrospectChildrenFunction introspect_children_cb,
+          void *introspect_children_data,
           DRouteGetDatumFunction get_datum)
 {
     DRoutePath *new_path;
@@ -86,6 +91,7 @@ path_new (DRouteContext *cnx,
     new_path->cnx = cnx;
     new_path->chunks = g_string_chunk_new (CHUNKS_DEFAULT);
     new_path->interfaces = g_ptr_array_new ();
+    new_path->introspection = g_ptr_array_new ();
 
     new_path->methods = g_hash_table_new_full ((GHashFunc)str_pair_hash,
                                                str_pair_equal,
@@ -97,6 +103,8 @@ path_new (DRouteContext *cnx,
                                                   g_free,
                                                   NULL);
 
+    new_path->introspect_children_cb = introspect_children_cb;
+    new_path->introspect_children_data = introspect_children_data;
     new_path->user_data = user_data;
     new_path->get_datum = get_datum;
 
@@ -108,6 +116,7 @@ path_free (DRoutePath *path, gpointer user_data)
 {
     g_string_chunk_free  (path->chunks);
     g_ptr_array_free     (path->interfaces, TRUE);
+    g_ptr_array_free     (path->introspection, FALSE);
     g_hash_table_destroy (path->methods);
     g_hash_table_destroy (path->properties);
 }
@@ -124,14 +133,13 @@ path_get_datum (DRoutePath *path, const gchar *pathstr)
 /*---------------------------------------------------------------------------*/
 
 DRouteContext *
-droute_new (DBusConnection *bus, const char *introspect_dir)
+droute_new (DBusConnection *bus)
 {
     DRouteContext *cnx;
 
     cnx = g_new0 (DRouteContext, 1);
     cnx->bus = bus;
     cnx->registered_paths = g_ptr_array_new ();
-    cnx->introspect_dir = g_strdup(introspect_dir);
 
     return cnx;
 }
@@ -140,7 +148,6 @@ void
 droute_free (DRouteContext *cnx)
 {
     g_ptr_array_foreach (cnx->registered_paths, (GFunc) path_free, NULL);
-    g_free (cnx->introspect_dir);
     g_free (cnx);
 }
 
@@ -169,11 +176,14 @@ droute_add_one (DRouteContext *cnx,
     DRoutePath *new_path;
     gboolean registered;
 
-    new_path = path_new (cnx, (void *) data, NULL);
+    new_path = path_new (cnx, (void *)data, NULL, NULL, NULL);
 
     registered = dbus_connection_register_object_path (cnx->bus, path, &droute_vtable, new_path);
     if (!registered)
-        oom();
+      {
+        path_free (new_path, NULL);
+        return NULL;
+      }
 
     g_ptr_array_add (cnx->registered_paths, new_path);
     return new_path;
@@ -183,11 +193,13 @@ DRoutePath *
 droute_add_many (DRouteContext *cnx,
                  const char    *path,
                  const void    *data,
+                 DRouteIntrospectChildrenFunction introspect_children_cb,
+                 void *introspect_children_data,
                  const DRouteGetDatumFunction get_datum)
 {
     DRoutePath *new_path;
 
-    new_path = path_new (cnx, (void *) data, get_datum);
+    new_path = path_new (cnx, (void *) data, introspect_children_cb, introspect_children_data, get_datum);
 
     if (!dbus_connection_register_fallback (cnx->bus, path, &droute_vtable, new_path))
         oom();
@@ -201,6 +213,7 @@ droute_add_many (DRouteContext *cnx,
 void
 droute_path_add_interface(DRoutePath *path,
                           const char *name,
+                          const char *introspect,
                           const DRouteMethod   *methods,
                           const DRouteProperty *properties)
 {
@@ -210,6 +223,7 @@ droute_path_add_interface(DRoutePath *path,
 
     itf = g_string_chunk_insert (path->chunks, name);
     g_ptr_array_add (path->interfaces, itf);
+    g_ptr_array_add (path->introspection, introspect);
 
     for (; methods != NULL && methods->name != NULL; methods++)
       {
@@ -280,7 +294,7 @@ impl_prop_GetAll (DBusMessage *message,
                         (&iter_dict, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict_entry))
               oom ();
            dbus_message_iter_append_basic (&iter_dict_entry, DBUS_TYPE_STRING,
-                                           key->two);
+                                           &key->two);
            (value->get) (&iter_dict_entry, datum);
            if (!dbus_message_iter_close_container (&iter_dict, &iter_dict_entry))
                oom ();
@@ -403,35 +417,6 @@ static const char *introspection_node_element =
 static const char *introspection_footer =
 "</node>";
 
-static void
-append_interface (GString     *str,
-                  const gchar *interface,
-                  const gchar *directory)
-{
-    gchar *filename;
-    gchar *contents;
-    gsize len;
-
-    GError *err = NULL;
-
-    filename = g_build_filename (directory, interface, NULL);
-
-    if (g_file_get_contents (filename, &contents, &len, &err))
-      {
-        g_string_append_len (str, contents, len);
-      }
-    else
-      {
-        g_warning ("AT-SPI: Cannot find introspection XML file %s - %s",
-                   filename, err->message);
-        g_error_free (err);
-      }
-
-    g_string_append (str, "\n");
-    g_free (filename);
-    g_free (contents);
-}
-
 static DBusHandlerResult
 handle_introspection (DBusConnection *bus,
                       DBusMessage    *message,
@@ -455,11 +440,23 @@ handle_introspection (DBusConnection *bus,
 
     g_string_append_printf(output, introspection_node_element, pathstr);
 
-    for (i=0; i < path->interfaces->len; i++)
+    if (!path->get_datum || path_get_datum (path, pathstr))
       {
-        gchar *interface = (gchar *) g_ptr_array_index (path->interfaces, i);
-        _DROUTE_DEBUG ("DRoute (appending interface): %s\n", interface);
-        append_interface(output, interface, path->cnx->introspect_dir);
+        for (i=0; i < path->introspection->len; i++)
+          {
+            gchar *introspect = (gchar *) g_ptr_array_index (path->introspection, i);
+            g_string_append (output, introspect);
+          }
+      }
+
+    if (path->introspect_children_cb)
+      {
+        gchar *children = (*path->introspect_children_cb) (pathstr, path->introspect_children_data);
+        if (children)
+          {
+            g_string_append (output, children);
+            g_free (children);
+          }
       }
 
     g_string_append(output, introspection_footer);