Integrate leasing scheme in-to atk-bridge.
authorMark Doffman <mark.doffman@codethink.co.uk>
Tue, 5 Jan 2010 09:47:34 +0000 (01:47 -0800)
committerMark Doffman <mark.doffman@codethink.co.uk>
Tue, 5 Jan 2010 10:21:17 +0000 (02:21 -0800)
This involved:
Separating the 'cache' and registration
        of accessible objects. This is because
        the leased objects need to be available over
        D-Bus but are not cached.

        Separating the cache updating from the 'events'.
        This is because we should still recieve updates on
        leased accessibles, but they are not cached.

35 files changed:
Makefile.am
atk-adaptor/Makefile.am
atk-adaptor/accessible-cache.c [new file with mode: 0644]
atk-adaptor/accessible-cache.h [new file with mode: 0644]
atk-adaptor/accessible-leasing.c
atk-adaptor/accessible-leasing.h
atk-adaptor/accessible-register.c
atk-adaptor/accessible-register.h
atk-adaptor/adaptors/Makefile.am
atk-adaptor/adaptors/accessible-adaptor.c
atk-adaptor/adaptors/accessible-marshaller.c [deleted file]
atk-adaptor/adaptors/accessible-marshaller.h [deleted file]
atk-adaptor/adaptors/adaptors.h
atk-adaptor/adaptors/cache-adaptor.c [new file with mode: 0644]
atk-adaptor/adaptors/collection-adaptor.c
atk-adaptor/adaptors/component-adaptor.c
atk-adaptor/adaptors/document-adaptor.c
atk-adaptor/adaptors/hyperlink-adaptor.c
atk-adaptor/adaptors/hypertext-adaptor.c
atk-adaptor/adaptors/image-adaptor.c
atk-adaptor/adaptors/selection-adaptor.c
atk-adaptor/adaptors/table-adaptor.c
atk-adaptor/adaptors/text-adaptor.c
atk-adaptor/adaptors/tree-adaptor.c [deleted file]
atk-adaptor/bridge.c
atk-adaptor/bridge.h
atk-adaptor/event.c
atk-adaptor/object.c [new file with mode: 0644]
atk-adaptor/object.h [moved from atk-adaptor/adaptors/tree-adaptor.h with 54% similarity]
common/spi-dbus.c
common/spi-dbus.h
common/spi-stateset.c
common/spi-stateset.h
configure.ac
droute/droute.c

index 305d97d..31982fe 100644 (file)
@@ -1 +1 @@
-SUBDIRS=droute dbind common atk-adaptor tests
+SUBDIRS=droute common atk-adaptor
index fea7091..140ede4 100644 (file)
@@ -22,17 +22,20 @@ libatk_bridge_la_LIBADD = $(DBUS_GLIB_LIBS) \
                          $(ATK_LIBS)       \
                          $(X_LIBS)         \
                          $(top_builddir)/droute/libdroute.la \
-                         $(top_builddir)/dbind/libdbind.la \
                          $(top_builddir)/common/libspicommon.la \
                          $(top_builddir)/atk-adaptor/adaptors/libatk-bridge-adaptors.la
 
 libatk_bridge_la_SOURCES =     \
         accessible-leasing.c    \
         accessible-leasing.h    \
+        accessible-cache.c      \
+        accessible-cache.h      \
        accessible-register.c   \
        accessible-register.h   \
        bridge.c                \
        bridge.h                \
+       object.c                \
+       object.h                \
        event.c                 \
        event.h
 
diff --git a/atk-adaptor/accessible-cache.c b/atk-adaptor/accessible-cache.c
new file mode 100644 (file)
index 0000000..4f87b18
--- /dev/null
@@ -0,0 +1,389 @@
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
+ *
+ * Copyright 2009, 2010 Codethink Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <atk/atk.h>
+
+#include "accessible-cache.h"
+#include "accessible-register.h"
+#include "bridge.h"
+
+SpiCache *spi_global_cache = NULL;
+
+static gboolean
+child_added_listener (GSignalInvocationHint * signal_hint,
+                      guint n_param_values,
+                      const GValue * param_values, gpointer data);
+
+static void
+toplevel_added_listener (AtkObject * accessible,
+                         guint index, AtkObject * child);
+
+static void
+remove_object (gpointer data, GObject * gobj);
+
+static void
+add_object (SpiCache * cache, GObject * gobj);
+
+static void
+add_subtree (SpiCache *cache, AtkObject * accessible);
+
+/*---------------------------------------------------------------------------*/
+
+static void
+spi_cache_finalize (GObject * object);
+
+static void
+spi_cache_dispose (GObject * object);
+
+/*---------------------------------------------------------------------------*/
+
+enum
+{
+  OBJECT_ADDED,
+  OBJECT_REMOVED,
+  LAST_SIGNAL
+};
+static guint cache_signals[LAST_SIGNAL] = { 0 };
+
+/*---------------------------------------------------------------------------*/
+
+G_DEFINE_TYPE (SpiCache, spi_cache, G_TYPE_OBJECT)
+
+static void spi_cache_class_init (SpiCacheClass * klass)
+{
+  GObjectClass *object_class = (GObjectClass *) klass;
+
+  spi_cache_parent_class = g_type_class_ref (G_TYPE_OBJECT);
+
+  object_class->finalize = spi_cache_finalize;
+  object_class->dispose = spi_cache_dispose;
+
+  cache_signals [OBJECT_ADDED] = \
+      g_signal_new ("object-added",
+                    SPI_CACHE_TYPE,
+                    G_SIGNAL_ACTION,
+                    0,
+                    NULL,
+                    NULL,
+                    g_cclosure_marshal_VOID__OBJECT,
+                    G_TYPE_NONE,
+                    1,
+                    G_TYPE_OBJECT);
+
+  cache_signals [OBJECT_REMOVED] = \
+      g_signal_new ("object-removed",
+                    SPI_CACHE_TYPE,
+                    G_SIGNAL_ACTION,
+                    0,
+                    NULL,
+                    NULL,
+                    g_cclosure_marshal_VOID__OBJECT,
+                    G_TYPE_NONE,
+                    1,
+                    G_TYPE_OBJECT);
+}
+
+static void
+spi_cache_init (SpiCache * cache)
+{
+  cache->objects = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+#ifdef SPI_ATK_DEBUG
+  if (g_thread_supported ())
+    g_message ("AT-SPI: Threads enabled");
+
+  g_debug ("AT-SPI: Initial Atk tree regisration");
+#endif
+
+  g_signal_connect (spi_global_register,
+                    "object-deregistered",
+                    (GCallback) remove_object, cache);
+
+  add_subtree (cache, spi_global_app_data->root);
+
+  atk_add_global_event_listener (child_added_listener,
+                                 "Gtk:AtkObject:children-changed");
+
+  g_signal_connect (G_OBJECT (spi_global_app_data->root),
+                    "children-changed::add",
+                    (GCallback) toplevel_added_listener, NULL);
+}
+
+static void
+spi_cache_finalize (GObject * object)
+{
+  SpiCache *cache = SPI_CACHE (object);
+
+  g_free (cache->objects);
+
+  G_OBJECT_CLASS (spi_cache_parent_class)->finalize (object);
+}
+
+static void
+spi_cache_dispose (GObject * object)
+{
+  SpiCache *cache = SPI_CACHE (object);
+
+  G_OBJECT_CLASS (spi_cache_parent_class)->dispose (object);
+}
+
+/*---------------------------------------------------------------------------*/
+
+static void
+remove_object (gpointer data, GObject * gobj)
+{
+  SpiCache *cache = SPI_CACHE (data);
+  
+  if (spi_cache_in (cache, gobj))
+    {
+      g_signal_emit (cache, cache_signals [OBJECT_REMOVED], 0, gobj);
+      g_hash_table_remove (cache->objects, gobj);
+    }
+}
+
+static void
+add_object (SpiCache * cache, GObject * gobj)
+{
+  g_return_if_fail (G_IS_OBJECT (gobj));
+
+  g_hash_table_insert (cache->objects, gobj, NULL);
+
+  g_signal_emit (cache, cache_signals [OBJECT_ADDED], 0, gobj);
+}
+
+/*---------------------------------------------------------------------------*/
+
+static GStaticRecMutex cache_mutex        = G_STATIC_REC_MUTEX_INIT;
+static GStaticMutex recursion_check_guard = G_STATIC_MUTEX_INIT;
+
+static gboolean recursion_check = FALSE;
+
+static gboolean
+recursion_check_and_set ()
+{
+  gboolean ret;
+  g_static_mutex_lock (&recursion_check_guard);
+  ret = recursion_check;
+  recursion_check = TRUE;
+  g_static_mutex_unlock (&recursion_check_guard);
+  return ret;
+}
+
+static void
+recursion_check_unset ()
+{
+  g_static_mutex_lock (&recursion_check_guard);
+  recursion_check = FALSE;
+  g_static_mutex_unlock (&recursion_check_guard);
+}
+
+/*---------------------------------------------------------------------------*/
+
+static void
+append_children (AtkObject * accessible, GQueue * traversal)
+{
+  AtkObject *current;
+  guint i;
+  gint count = atk_object_get_n_accessible_children (accessible);
+
+  if (count < 0)
+    count = 0;
+  for (i = 0; i < count; i++)
+    {
+      current = atk_object_ref_accessible_child (accessible, i);
+      if (current)
+        {
+          g_queue_push_tail (traversal, current);
+        }
+    }
+}
+
+/*
+ * Adds a subtree of accessible objects
+ * to the cache at the accessible object provided.
+ *
+ * The leaf nodes do not have their children
+ * registered. A node is considered a leaf
+ * if it has the state "manages-descendants"
+ * or if it has already been registered.
+ */
+static void
+add_subtree (SpiCache *cache, AtkObject * accessible)
+{
+  AtkObject *current;
+  GQueue *traversal;
+  GQueue *to_add;
+
+  g_return_if_fail (ATK_IS_OBJECT (accessible));
+
+  traversal = g_queue_new ();
+  to_add = g_queue_new ();
+
+  g_object_ref (accessible);
+  g_queue_push_tail (traversal, accessible);
+
+  while (!g_queue_is_empty (traversal))
+    {
+      AtkStateSet *set;
+      
+      current = g_queue_pop_head (traversal);
+      set = atk_object_ref_state_set (current);
+
+      if (!atk_state_set_contains_state (set, ATK_STATE_TRANSIENT))
+        {
+         g_queue_push_tail (to_add, current);
+          if (!spi_cache_in (cache, G_OBJECT (current)) &&
+              !atk_state_set_contains_state  (set, ATK_STATE_MANAGES_DESCENDANTS))
+            {
+#ifdef SPI_ATK_DEBUG
+              g_debug ("REG  - %s - %d - %s", atk_object_get_name (current),
+                       atk_object_get_role (current),
+                       atk_dbus_object_to_path (current));
+#endif
+              append_children (current, traversal);
+            }
+        }
+
+      g_object_unref (set);
+    }
+
+  while (!g_queue_is_empty (to_add))
+    {
+      current = g_queue_pop_head (to_add);
+      add_object (cache, G_OBJECT(current));
+      g_object_unref (G_OBJECT (current));
+    }
+
+  g_queue_free (traversal);
+  g_queue_free (to_add);
+}
+
+/*---------------------------------------------------------------------------*/
+
+static gboolean
+child_added_listener (GSignalInvocationHint * signal_hint,
+                      guint n_param_values,
+                      const GValue * param_values, gpointer data)
+{
+  SpiCache *cache = spi_global_cache;
+
+  AtkObject *accessible;
+  AtkObject *child;
+
+  const gchar *detail = NULL;
+
+  g_static_rec_mutex_lock (&cache_mutex);
+
+  /* 
+   * Ensure that only accessibles already in the cache
+   * have their signals processed.
+   */
+  accessible = ATK_OBJECT (g_value_get_object (&param_values[0]));
+  g_return_val_if_fail (ATK_IS_OBJECT (accessible), TRUE);
+
+  if (spi_cache_in (cache, G_OBJECT(accessible)))
+    {
+#ifdef SPI_ATK_DEBUG
+      if (recursion_check_and_set ())
+        g_warning ("AT-SPI: Recursive use of cache module");
+
+      g_debug ("AT-SPI: Tree update listener");
+#endif
+      if (signal_hint->detail)
+        detail = g_quark_to_string (signal_hint->detail);
+
+      if (!strcmp (detail, "add"))
+        {
+          gpointer child;
+          int index = g_value_get_uint (param_values + 1);
+          child = g_value_get_pointer (param_values + 2);
+
+          if (!ATK_IS_OBJECT (child))
+           {
+             child = atk_object_ref_accessible_child (accessible, index);
+           }
+          add_subtree (cache, child);
+        }
+#ifdef SPI_ATK_DEBUG
+      recursion_check_unset ();
+#endif
+    }
+
+  g_static_rec_mutex_unlock (&cache_mutex);
+
+  return TRUE;
+}
+
+/*---------------------------------------------------------------------------*/
+
+static void
+toplevel_added_listener (AtkObject * accessible,
+                         guint index, AtkObject * child)
+{
+  SpiCache *cache = spi_global_cache;
+
+  g_static_rec_mutex_lock (&cache_mutex);
+
+  g_return_if_fail (ATK_IS_OBJECT (accessible));
+
+  if (spi_cache_in (cache, G_OBJECT(accessible)))
+    {
+#ifdef SPI_ATK_DEBUG
+      if (recursion_check_and_set ())
+        g_warning ("AT-SPI: Recursive use of registration module");
+
+      g_debug ("AT-SPI: Toplevel added listener");
+#endif
+      if (!ATK_IS_OBJECT (child))
+        {
+          child = atk_object_ref_accessible_child (accessible, index);
+        }
+      add_subtree (cache, child);
+#ifdef SPI_ATK_DEBUG
+      recursion_check_unset ();
+#endif
+    }
+
+  g_static_rec_mutex_unlock (&cache_mutex);
+}
+
+/*---------------------------------------------------------------------------*/
+
+void
+spi_cache_foreach (SpiCache * cache, GHFunc func, gpointer data)
+{
+  g_hash_table_foreach (cache->objects, func, data);
+}
+
+gboolean
+spi_cache_in (SpiCache * cache, GObject * object)
+{
+  if (g_hash_table_lookup_extended (cache->objects,
+                                    object,
+                                    NULL,
+                                    NULL))
+    return TRUE;
+  else
+    return FALSE;
+}
+
+/*END------------------------------------------------------------------------*/
diff --git a/atk-adaptor/accessible-cache.h b/atk-adaptor/accessible-cache.h
new file mode 100644 (file)
index 0000000..8d75b5d
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
+ *
+ * Copyright 2010 Codethink Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef ACCESSIBLE_CACHE_H
+#define ACCESSIBLE_CACHE_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+typedef struct _SpiCache SpiCache;
+typedef struct _SpiCacheClass SpiCacheClass;
+
+G_BEGIN_DECLS
+
+#define SPI_CACHE_TYPE        (spi_cache_get_type ())
+#define SPI_CACHE(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_CACHE_TYPE, SpiCache))
+#define SPI_CACHE_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_CACHE_TYPE, SpiCacheClass))
+#define SPI_IS_CACHE(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_CACHE_TYPE))
+#define SPI_IS_CACHE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_CACHE_TYPE))
+
+struct _SpiCache
+{
+  GObject parent;
+
+  GHashTable * objects;
+};
+
+struct _SpiCacheClass
+{
+  GObjectClass parent_class;
+};
+
+GType spi_cache_get_type (void);
+
+extern SpiCache *spi_global_cache;
+
+void
+spi_cache_foreach (SpiCache * cache, GHFunc func, gpointer data);
+
+gboolean
+spi_cache_in (SpiCache * cache, GObject * object);
+
+G_END_DECLS
+#endif /* ACCESSIBLE_CACHE_H */
index 0bfd496..28d4099 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
-#include <accessible-leasing.h>
+#include "accessible-leasing.h"
 
 /*---------------------------------------------------------------------------*/
 
+SpiLeasing *spi_global_leasing;
+
 typedef struct _ExpiryElement
 {
   guint expiry_s;
index 50f1f3c..af01a78 100644 (file)
@@ -21,8 +21,8 @@
  * Boston, MA 02111-1307, USA.
  */
 
-#ifndef ACCESSIBLE_LEASING
-#define ACCESSIBLE_LEASING
+#ifndef ACCESSIBLE_LEASING_H
+#define ACCESSIBLE_LEASING_H
 
 #include <glib.h>
 #include <glib-object.h>
@@ -53,7 +53,9 @@ struct _SpiLeasingClass
 
 GType spi_leasing_get_type (void);
 
+extern SpiLeasing *spi_global_leasing;
+
 GObject *spi_leasing_take (SpiLeasing * leasing, GObject * object);
 
 G_END_DECLS
-#endif /* ACCESSIBLE_LEASING */
+#endif /* ACCESSIBLE_LEASING_H */
index f0963af..ac93dee 100644 (file)
@@ -3,7 +3,7 @@
  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
  *
  * Copyright 2008 Novell, Inc.
- * Copyright 2008, 2009 Codethink Ltd.
+ * Copyright 2008, 2009, 2010 Codethink Ltd.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -26,7 +26,6 @@
 #include <string.h>
 
 #include "bridge.h"
-#include "tree-adaptor.h"
 #include "accessible-register.h"
 
 /*
  * object destruction. When an object is destroyed it must be 'deregistered'
  * To do this lookup we keep a dbus-id attribute on each AtkObject.
  *
- * In addition to accessing the objects remotely we must be able to update
- * the client side cache. This is done using the 'update' signal of the 
- * org.freedesktop.atspi.Tree interface. The update signal should send out
- * all of the cacheable data for an Accessible object.
- *
  */
 
-/*
- * FIXME
- *
- * This code seems very brittle.
- * I would prefer changes to be made to
- * gail and the ATK interface so that all Accessible
- * objects are registered with an exporting module.
- *
- * This is the same system as Qt has with the QAccessibleBridge
- * and QAccessibleBridgePlugin. It entails some rather
- * large structural changes to ATK though:
- *
- * Removing infinite spaces (Child access no longer references child).
- * Removing lazy creation of accessible objects.
- */
-
-#define SPI_ATK_OBJECT_PATH_PREFIX  "/org/freedesktop/atspi/accessible"
-#define SPI_ATK_OBJECT_PATH_DESKTOP "/desktop"
+#define SPI_ATK_PATH_PREFIX_LENGTH 22
+#define SPI_ATK_OBJECT_PATH_PREFIX  "/org/at_spi/accessible"
+#define SPI_ATK_OBJECT_PATH_DESKTOP SPI_ATK_OBJECT_PATH_PREFIX "/desktop"
 
-#define SPI_ATK_PATH_PREFIX_LENGTH 33
 #define SPI_ATK_OBJECT_REFERENCE_TEMPLATE SPI_ATK_OBJECT_PATH_PREFIX "/%d"
 
+#define SPI_DBUS_ID "spi-dbus-id"
+
+SpiRegister *spi_global_register = NULL;
+
+enum
+{
+  OBJECT_REGISTERED,
+  OBJECT_DEREGISTERED,
+  LAST_SIGNAL
+};
+static guint register_signals[LAST_SIGNAL] = { 0 };
 
-static GHashTable *ref2ptr = NULL;      /* Used for converting a D-Bus path (Reference) to the object pointer */
-static GHashTable *objects_with_subrefs = NULL;
-static GHashTable *leased_refs = NULL;
-static int leased_refs_count;
+/*---------------------------------------------------------------------------*/
 
-static guint reference_counter = 0;
+static void
+spi_register_finalize (GObject * object);
 
-static GStaticRecMutex registration_mutex = G_STATIC_REC_MUTEX_INIT;
+static void
+spi_register_dispose (GObject * object);
 
 /*---------------------------------------------------------------------------*/
 
-static GStaticMutex recursion_check_guard = G_STATIC_MUTEX_INIT;
-static gboolean recursion_check = FALSE;
-static int last_gc_time;
+G_DEFINE_TYPE (SpiRegister, spi_register, G_TYPE_OBJECT)
 
-static void deregister_sub_accessible (gpointer key, gpointer obj_data,
-                                       gpointer iter);
+static void spi_register_class_init (SpiRegisterClass * klass)
+{
+  GObjectClass *object_class = (GObjectClass *) klass;
 
-static void deregister_sub_hyperlink (gpointer key, gpointer obj_data,
-                                      gpointer iter);
+  spi_register_parent_class = g_type_class_ref (G_TYPE_OBJECT);
+
+  object_class->finalize = spi_register_finalize;
+  object_class->dispose = spi_register_dispose;
+
+  register_signals [OBJECT_REGISTERED] =
+      g_signal_new ("object-registered",
+                    SPI_REGISTER_TYPE,
+                    G_SIGNAL_ACTION,
+                    0,
+                    NULL,
+                    NULL,
+                    g_cclosure_marshal_VOID__OBJECT,
+                    G_TYPE_NONE,
+                    1,
+                    G_TYPE_OBJECT);
+
+  register_signals [OBJECT_DEREGISTERED] =
+      g_signal_new ("object-deregistered",
+                    SPI_REGISTER_TYPE,
+                    G_SIGNAL_ACTION,
+                    0,
+                    NULL,
+                    NULL,
+                    g_cclosure_marshal_VOID__OBJECT,
+                    G_TYPE_NONE,
+                    1,
+                    G_TYPE_OBJECT);
+}
 
-static gboolean
-recursion_check_and_set ()
+static void
+spi_register_init (SpiRegister * reg)
 {
-  gboolean ret;
-  g_static_mutex_lock (&recursion_check_guard);
-  ret = recursion_check;
-  recursion_check = TRUE;
-  g_static_mutex_unlock (&recursion_check_guard);
-  return ret;
+  reg->ref2ptr = g_hash_table_new (g_direct_hash, g_direct_equal);
+  reg->reference_counter = 0;
 }
 
 static void
-recursion_check_unset ()
+spi_register_finalize (GObject * object)
 {
-  g_static_mutex_lock (&recursion_check_guard);
-  recursion_check = FALSE;
-  g_static_mutex_unlock (&recursion_check_guard);
+  SpiRegister *reg = SPI_REGISTER (object);
+
+  g_free (reg->ref2ptr);
+
+  G_OBJECT_CLASS (spi_register_parent_class)->finalize (object);
+}
+
+static void
+spi_register_dispose (GObject * object)
+{
+  SpiRegister *reg = SPI_REGISTER (object);
+
+  G_OBJECT_CLASS (spi_register_parent_class)->dispose (object);
 }
 
 /*---------------------------------------------------------------------------*/
@@ -123,44 +143,35 @@ recursion_check_unset ()
  *
  * This function provides an integer reference for a new
  * AtkObject.
+ *
+ * TODO: Make this reference a little more unique, this is shoddy.
  */
 static guint
-assign_reference (void)
+assign_reference (SpiRegister * reg)
 {
-  reference_counter++;
+  reg->reference_counter++;
   /* Reference of 0 not allowed as used as direct key in hash table */
-  if (reference_counter == 0)
-    reference_counter++;
-  /* TODO: If we've wrapped, ensure that two objects don't have the same ref */
-  return reference_counter;
+  if (reg->reference_counter == 0)
+    reg->reference_counter++;
+  return reg->reference_counter;
 }
 
+/*---------------------------------------------------------------------------*/
+
 /*
  * Returns the reference of the object, or 0 if it is not registered.
  */
 static guint
-gobject_to_ref (GObject * gobj)
-{
-  return GPOINTER_TO_INT (g_object_get_data (gobj, "dbus-id"));
-}
-
-static guint
-object_to_ref (AtkObject * accessible)
+object_to_ref (GObject * gobj)
 {
-  return gobject_to_ref (G_OBJECT (accessible));
-}
-
-static guint
-hyperlink_to_ref (AtkHyperlink * link)
-{
-  return gobject_to_ref (G_OBJECT (link));
+  return GPOINTER_TO_INT (g_object_get_data (gobj, SPI_DBUS_ID));
 }
 
 /*
  * Converts the Accessible object reference to its D-Bus object path
  */
-gchar *
-atk_dbus_ref_to_path (guint ref)
+static gchar *
+ref_to_path (guint ref)
 {
   return g_strdup_printf (SPI_ATK_OBJECT_REFERENCE_TEMPLATE, ref);
 }
@@ -176,305 +187,44 @@ atk_dbus_ref_to_path (guint ref)
 static void
 deregister_object (gpointer data, GObject * gobj)
 {
+  SpiRegister *reg = SPI_REGISTER (data);
   guint ref;
-  GHashTable *subrefs_atk;
-  GHashTable *subrefs_hyperlink;
-  g_return_if_fail (ATK_IS_OBJECT (gobj) || ATK_IS_HYPERLINK (gobj));
-
-  subrefs_atk = (GHashTable *) g_object_get_data (gobj, "dbus-subrefs-atk");
-  subrefs_hyperlink =
-    (GHashTable *) g_object_get_data (gobj, "dbus-subrefs-hyperlink");
-
-  if (subrefs_atk)
-    {
-      g_hash_table_foreach (subrefs_atk, deregister_sub_accessible, data);
-      g_hash_table_unref (subrefs_atk);
-    }
-
-  if (subrefs_hyperlink)
-    {
-      g_hash_table_foreach (subrefs_hyperlink, deregister_sub_hyperlink,
-                            data);
-      g_hash_table_unref (subrefs_hyperlink);
-    }
-
-  if (subrefs_atk || subrefs_hyperlink)
-    g_hash_table_remove (objects_with_subrefs, gobj);
-
-  if (ATK_IS_OBJECT (gobj))
-    {
-      ref = object_to_ref (ATK_OBJECT (gobj));
-      if (ref != 0)
-        {
-          spi_emit_cache_removal (ref, atk_adaptor_app_data->bus);
-          g_hash_table_remove (ref2ptr, GINT_TO_POINTER (ref));
-        }
-    }
-}
-
-static void
-deregister_sub_accessible (gpointer key, gpointer obj_data, gpointer iter)
-{
-  GObject *obj = G_OBJECT (obj_data);
-  deregister_object (NULL, obj);
-  g_hash_table_remove (leased_refs, obj);
-  g_object_unref (obj);
-}
-
-static void
-deregister_sub_hyperlink (gpointer key, gpointer obj_data, gpointer iter)
-{
-  guint ref;
-  GObject *ghyperlink = G_OBJECT (obj_data);
 
-  g_return_if_fail (ATK_IS_HYPERLINK (ghyperlink));
-
-  ref = gobject_to_ref (ghyperlink);
+  ref = object_to_ref (gobj);
   if (ref != 0)
     {
-      g_hash_table_remove (ref2ptr, GINT_TO_POINTER (ref));
+      g_signal_emit (reg,
+                     register_signals [OBJECT_DEREGISTERED],
+                     0,
+                     gobj);
+      g_hash_table_remove (reg->ref2ptr, GINT_TO_POINTER (ref));
     }
-  g_object_unref (ghyperlink);
 }
 
 static void
-register_gobject (GObject * gobj, GObject * container)
+register_object (SpiRegister * reg, GObject * gobj)
 {
   guint ref;
   g_return_if_fail (G_IS_OBJECT (gobj));
 
-  ref = assign_reference ();
-
-  g_hash_table_insert (ref2ptr, GINT_TO_POINTER (ref), gobj);
-  g_object_set_data (G_OBJECT (gobj), "dbus-id", GINT_TO_POINTER (ref));
-  g_object_weak_ref (G_OBJECT (gobj), deregister_object, NULL);
-
-  if (container)
-    {
-      GHashTable *subrefs =
-        (GHashTable *) g_object_get_data (G_OBJECT (container),
-                                          "dbus-subrefs-atk");
-      if (!subrefs)
-        {
-          subrefs = g_hash_table_new (g_direct_hash, g_direct_equal);
-          g_object_set_data (G_OBJECT (container), "dbus-subrefs-atk",
-                             subrefs);
-        }
-      g_hash_table_insert (subrefs, GINT_TO_POINTER (ref), gobj);
-      g_hash_table_insert (objects_with_subrefs, gobj, subrefs);
-    }
-
-  if (ATK_IS_HYPERLINK (gobj))
-    g_object_ref (gobj);
-  else if (ATK_IS_OBJECT (gobj))
-    {
-      AtkObject *accessible = ATK_OBJECT (gobj);
-      AtkStateSet *state = atk_object_ref_state_set (accessible);
-      if (atk_state_set_contains_state (state, ATK_STATE_TRANSIENT))
-        {
-          g_object_ref (gobj);
-          /* We should only get here as the result of a query other than GetTree */
-          spi_emit_cache_update (accessible, atk_adaptor_app_data->bus);
-        }
-      g_object_unref (state);
-    }
-}
-
-/*
- * Called to register an AtkObject with AT-SPI and expose it over D-Bus.
- */
-static void
-register_accessible (AtkObject * accessible, AtkObject * container)
-{
-  g_return_if_fail (ATK_IS_OBJECT (accessible));
-
-  register_gobject (G_OBJECT (accessible), G_OBJECT (container));
-}
-
-static void
-register_hyperlink (AtkHyperlink * hyperlink, AtkObject * container)
-{
-  guint ref;
-  g_return_if_fail (ATK_IS_HYPERLINK (hyperlink));
-  g_return_if_fail (container);
-
-  ref = assign_reference ();
+  ref = assign_reference (reg);
 
-  g_hash_table_insert (ref2ptr, GINT_TO_POINTER (ref), hyperlink);
-  g_object_set_data (G_OBJECT (hyperlink), "dbus-id", GINT_TO_POINTER (ref));
-  g_object_ref (G_OBJECT (hyperlink));
+  g_hash_table_insert (reg->ref2ptr, GINT_TO_POINTER (ref), gobj);
+  g_object_set_data (G_OBJECT (gobj), SPI_DBUS_ID, GINT_TO_POINTER (ref));
+  g_object_weak_ref (G_OBJECT (gobj), deregister_object, reg);
 
-  GHashTable *subrefs =
-    (GHashTable *) g_object_get_data (G_OBJECT (container),
-                                      "dbus-subrefs-hyperlink");
-  if (!subrefs)
-    {
-      subrefs = g_hash_table_new (g_direct_hash, g_direct_equal);
-      g_object_set_data (G_OBJECT (container), "dbus-subrefs-hyperlink",
-                         GINT_TO_POINTER (ref));
-    }
-  g_hash_table_insert (subrefs, GINT_TO_POINTER (ref), hyperlink);
-}
-
-/*---------------------------------------------------------------------------*/
-
-#ifdef SPI_ATK_DEBUG
-/*
- * This function checks that the ref-count of an accessible
- * is greater than 1.
- *
- * There is not currently any remote reference counting
- * in AT-SPI D-Bus so objects that are remotely owned are not
- * allowed.
- *
- * TODO Add debug wrapper
- */
-static gboolean
-non_owned_accessible (AtkObject * accessible)
-{
-  if ((G_OBJECT (accessible))->ref_count <= 1)
-    {
-      g_warning ("AT-SPI: Child referenced that is not owned by its parent");
-      return TRUE;
-    }
-  else
-    {
-      return FALSE;
-    }
-}
-#endif /* SPI_ATK_DEBUG */
-
-/*---------------------------------------------------------------------------*/
-
-/* TRUE if we should not keep this object / tell the AT about it
- * Currently true if TRANSIENT and not SHOWING
- */
-static gboolean
-object_is_moot (AtkObject * accessible)
-{
-  AtkStateSet *state;
-  gboolean result = FALSE;
-
-  /* This is dangerous, refing the state set
-   * seems to do wierd things to the tree & cause recursion
-   * by modifying the tree alot.
-   */
-  state = atk_object_ref_state_set (accessible);
-  if (atk_state_set_contains_state (state, ATK_STATE_TRANSIENT) &&
-      !atk_state_set_contains_state (state, ATK_STATE_SHOWING))
-    {
-      result = TRUE;
-    }
-  g_object_unref (state);
-
-  return result;
-}
-
-static void
-append_children (AtkObject * accessible, GQueue * traversal)
-{
-  AtkObject *current;
-  guint i;
-  gint count = atk_object_get_n_accessible_children (accessible);
-
-  if (count < 0)
-    count = 0;
-  for (i = 0; i < count; i++)
-    {
-      current = atk_object_ref_accessible_child (accessible, i);
-      if (current)
-        {
-#ifdef SPI_ATK_DEBUG
-          non_owned_accessible (current);
-#endif
-          g_queue_push_tail (traversal, current);
-        }
-    }
-}
-
-/*
- * Registers a subtree of accessible objects
- * rooted at the accessible object provided.
- *
- * The leaf nodes do not have their children
- * registered. A node is considered a leaf
- * if it has the state "manages-descendants"
- * or if it has already been registered.
- */
-void
-register_subtree (AtkObject * accessible)
-{
-  AtkObject *current;
-  GQueue *traversal;
-  GQueue *emit_update;
-
-  g_return_if_fail (ATK_IS_OBJECT (accessible));
-
-  traversal = g_queue_new ();
-  emit_update = g_queue_new ();
-
-  g_object_ref (accessible);
-  g_queue_push_tail (traversal, accessible);
-
-  while (!g_queue_is_empty (traversal))
-    {
-      current = g_queue_pop_head (traversal);
-      g_queue_push_tail (emit_update, current);
-      if (!object_to_ref (current))
-        {
-          register_accessible (current, NULL);
-#ifdef SPI_ATK_DEBUG
-          g_debug ("REG  - %s - %d - %s", atk_object_get_name (current),
-                   atk_object_get_role (current),
-                   atk_dbus_object_to_path (current));
-#endif
-          append_children (current, traversal);
-        }
-    }
-
-  while (!g_queue_is_empty (emit_update))
-    {
-      current = g_queue_pop_head (emit_update);
-      spi_emit_cache_update (current, atk_adaptor_app_data->bus);
-      g_object_unref (G_OBJECT (current));
-    }
-
-  g_queue_free (traversal);
-  g_queue_free (emit_update);
-}
-
-/*---------------------------------------------------------------------------*/
-
-/*
- * Called when an already registered object is updated in such a
- * way that client side cache needs to be updated.
- */
-static void
-update_accessible (AtkObject * accessible)
-{
-  guint ref = 0;
-  g_return_if_fail (ATK_IS_OBJECT (accessible));
-
-  ref = object_to_ref (accessible);
-  if (ref)
-    {
-      spi_emit_cache_update (accessible, atk_adaptor_app_data->bus);
-    }
+  g_signal_emit (reg, register_signals [OBJECT_REGISTERED], 0, gobj);
 }
 
 /*---------------------------------------------------------------------------*/
 
-void
-atk_dbus_foreach_registered (GHFunc func, gpointer data)
-{
-  g_hash_table_foreach (ref2ptr, func, data);
-}
-
 /*
- * Used to lookup an AtkObject from its D-Bus path.
+ * Used to lookup an GObject from its D-Bus path.
+ * 
+ * If the D-Bus path is not found this function returns NULL.
  */
 GObject *
-atk_dbus_path_to_gobject (const char *path)
+spi_register_path_to_object (SpiRegister * reg, const char *path)
 {
   guint index;
   void *data;
@@ -494,447 +244,58 @@ atk_dbus_path_to_gobject (const char *path)
 
   path++;
   index = atoi (path);
-  data = g_hash_table_lookup (ref2ptr, GINT_TO_POINTER (index));
+  data = g_hash_table_lookup (reg->ref2ptr, GINT_TO_POINTER (index));
   if (data)
-    {
-      GObject *gobj = G_OBJECT (data);
-      g_object_set_data (gobj, "last-ref-time", (gpointer) time (NULL));
-      return gobj;
-    }
+    return G_OBJECT(data);
   else
     return NULL;
 }
 
-AtkObject *
-atk_dbus_path_to_object (const char *path)
+GObject *
+spi_global_register_path_to_object (const char * path)
 {
-  return ATK_OBJECT (atk_dbus_path_to_gobject (path));
+  return spi_register_path_to_object (spi_global_register, path);
 }
 
 /*
- * TODO WARNING HACK This function is dangerous.
- * It should only be called before sending an event on an
- * object that has not already been registered.
+ * Used to lookup a D-Bus path from the GObject.
+ * 
+ * If the objects is not already registered, 
+ * this function will register it.
  */
 gchar *
-atk_dbus_object_attempt_registration (AtkObject * accessible)
+spi_register_object_to_path (SpiRegister * reg, GObject * gobj)
 {
   guint ref;
 
-  ref = object_to_ref (accessible);
+  ref = object_to_ref (gobj);
   if (!ref)
     {
-      /* See if the object is attached to the main tree */
-      AtkObject *current, *prev = NULL;
-      guint cref = 0;
-
-      /* This should iterate until it hits a NULL or registered parent */
-      prev = accessible;
-      current = atk_object_get_parent (accessible);
-      if (current)
-        cref = object_to_ref (current);
-      while (current && !cref)
-        {
-          prev = current;
-          current = atk_object_get_parent (current);
-          if (current)
-            cref = object_to_ref (current);
-        }
-
-      /* A registered parent, with non-registered child, has been found */
-      if (current)
-        {
-          register_subtree (prev);
-        }
-
-      /* The object SHOULD be registered now. If it isn't - I give up */
-      ref = object_to_ref (accessible);
-      if (ref)
-        {
-          return atk_dbus_ref_to_path (ref);
-        }
-      else
-        {
-#ifdef SPI_ATK_DEBUG
-          g_debug
-            ("AT-SPI: Could not register a non-attached accessible object");
-#endif
-          return NULL;
-        }
-    }
-  else
-    {
-      return atk_dbus_ref_to_path (ref);
-    }
-}
-
-
-/*
- * Used to lookup a D-Bus path from the AtkObject.
- */
-static gchar *
-atk_dbus_gobject_to_path_internal (GObject * gobj, gboolean do_register,
-                                   GObject * container)
-{
-  guint ref;
-
-  ref = gobject_to_ref (gobj);
-  if (!ref && do_register)
-    {
-      register_gobject (gobj, container);
-      ref = gobject_to_ref (gobj);
+      register_object (reg, gobj);
+      ref = object_to_ref (gobj);
     }
 
   if (!ref)
     return NULL;
   else
-    return atk_dbus_ref_to_path (ref);
-}
-
-gchar *
-atk_dbus_object_to_path (AtkObject * accessible, gboolean do_register)
-{
-  AtkObject *container = (accessible
-                          && do_register ? atk_object_get_parent (accessible)
-                          : NULL);
-  return atk_dbus_gobject_to_path_internal (G_OBJECT (accessible),
-                                            do_register,
-                                            G_OBJECT (container));
-}
-
-gchar *
-atk_dbus_sub_object_to_path (GObject * gobj, GObject * container)
-{
-  return atk_dbus_gobject_to_path_internal (gobj, TRUE, container);
-}
-
-gchar *
-atk_dbus_hyperlink_to_path (AtkHyperlink * hyperlink, AtkObject * container)
-{
-  guint ref;
-
-  ref = gobject_to_ref (G_OBJECT (hyperlink));
-  if (!ref && container)
-    {
-      register_hyperlink (hyperlink, container);
-      ref = hyperlink_to_ref (hyperlink);
-    }
-
-  if (!ref)
-    return NULL;
-  else
-    return atk_dbus_ref_to_path (ref);
-}
-
-gchar *
-atk_dbus_desktop_object_path ()
-{
-  return g_strdup (SPI_ATK_OBJECT_PATH_PREFIX SPI_ATK_OBJECT_PATH_DESKTOP);
-}
-
-/*---------------------------------------------------------------------------*/
-
-typedef gboolean (*TreeUpdateAction) (GSignalInvocationHint * signal_hint,
-                                      guint n_param_values,
-                                      const GValue * param_values,
-                                      gpointer data, AtkObject * accessible);
-
-/*
- * Events are not evaluated for non-registered accessibles.
- *
- * When a property change is made on a registered accessible
- * the client side cache should be updated.
- *
- * When a parent is changed the subtree is de-registered
- * if the parent is not attached to the root accessible.
- */
-/* TODO Turn this function into a macro? */
-static gboolean
-tree_update_wrapper (GSignalInvocationHint * signal_hint,
-                     guint n_param_values,
-                     const GValue * param_values,
-                     gpointer data, TreeUpdateAction action)
-{
-  AtkObject *accessible;
-
-  g_static_rec_mutex_lock (&registration_mutex);
-
-  /* Ensure that only registered accessibles
-   * have their signals processed.
-   */
-  accessible = ATK_OBJECT (g_value_get_object (&param_values[0]));
-  g_return_val_if_fail (ATK_IS_OBJECT (accessible), TRUE);
-
-  if (object_to_ref (accessible))
-    {
-#ifdef SPI_ATK_DEBUG
-      if (recursion_check_and_set ())
-        g_warning ("AT-SPI: Recursive use of registration module");
-
-      g_debug ("AT-SPI: Tree update listener");
-#endif
-      action (signal_hint, n_param_values, param_values, data, accessible);
-
-      recursion_check_unset ();
-    }
-
-  g_static_rec_mutex_unlock (&registration_mutex);
-
-  return TRUE;
-}
-
-static gboolean
-maybe_expire_lease (gpointer key, gpointer obj_data, gpointer iter)
-{
-  time_t secs = time (NULL) - (time_t) obj_data;
-
-  if (secs < 30)
-    return FALSE;
-  deregister_sub_accessible (key, obj_data, iter);
-  return TRUE;
+    return ref_to_path (ref);
 }
 
-static void
-expire_old_leases_in (gpointer key, gpointer obj_data, gpointer iter)
-{
-  g_hash_table_foreach_remove ((GHashTable *) obj_data, maybe_expire_lease,
-                               NULL);
-}
-
-static void
-expire_old_leases ()
-{
-  g_hash_table_foreach (objects_with_subrefs, expire_old_leases_in, NULL);
-}
-
-static gboolean
-tree_update_state_action (GSignalInvocationHint * signal_hint,
-                          guint n_param_values,
-                          const GValue * param_values,
-                          gpointer data, AtkObject * accessible)
-{
-  const gchar *name;
-  gboolean state;
-
-  if (n_param_values < 3)
-    {
-      g_warning ("at-spi: Not enough params in state-changed signal");
-      return TRUE;
-    }
-
-  name = g_value_get_string (param_values + 1);
-  state = g_value_get_boolean (param_values + 2);
-  if (!strcmp (name, "visible"))
-    {
-      AtkStateSet *set = atk_object_ref_state_set (accessible);
-      if (atk_state_set_contains_state (set, ATK_STATE_TRANSIENT))
-        {
-          if (state == 0)
-            {
-              g_hash_table_insert (leased_refs, accessible,
-                                   (gpointer) time (NULL));
-              leased_refs_count++;
-              /* todo: Set to a high number: 5 for dbg. */
-              if (leased_refs_count > 5)
-                expire_old_leases ();
-            }
-          else
-            {
-              g_hash_table_remove (leased_refs, accessible);
-              leased_refs_count--;
-            }
-        }
-      g_object_unref (set);
-    }
-
-  update_accessible (accessible);
-  return TRUE;
-}
-
-static gboolean
-tree_update_state_listener (GSignalInvocationHint * signal_hint,
-                            guint n_param_values,
-                            const GValue * param_values, gpointer data)
+guint
+spi_register_object_to_ref (GObject * gobj)
 {
-  tree_update_wrapper (signal_hint, n_param_values, param_values, data,
-                       tree_update_state_action);
-  return TRUE;
-}
-
-static gboolean
-tree_update_property_action (GSignalInvocationHint * signal_hint,
-                             guint n_param_values,
-                             const GValue * param_values,
-                             gpointer data, AtkObject * accessible)
-{
-  AtkPropertyValues *values;
-  const gchar *pname = NULL;
-
-  values = (AtkPropertyValues *) g_value_get_pointer (&param_values[1]);
-  pname = values[0].property_name;
-  if (strcmp (pname, "accessible-name") == 0 ||
-      strcmp (pname, "accessible-description") == 0 ||
-      strcmp (pname, "accessible-parent") == 0 ||
-      strcmp (pname, "accessible-role") == 0)
-    {
-      update_accessible (accessible);
-    }
-  /* Parent value us updated by child-add signal of parent object */
-  return TRUE;
-}
-
-static gboolean
-tree_update_property_listener (GSignalInvocationHint * signal_hint,
-                               guint n_param_values,
-                               const GValue * param_values, gpointer data)
-{
-  tree_update_wrapper (signal_hint, n_param_values, param_values, data,
-                       tree_update_property_action);
-  return TRUE;
-}
-
-static gboolean
-tree_update_children_action (GSignalInvocationHint * signal_hint,
-                             guint n_param_values,
-                             const GValue * param_values,
-                             gpointer data, AtkObject * accessible)
-{
-  const gchar *detail = NULL;
-  AtkObject *child;
-
-  if (signal_hint->detail)
-    detail = g_quark_to_string (signal_hint->detail);
-
-  if (!strcmp (detail, "add"))
-    {
-      gpointer child;
-      int index = g_value_get_uint (param_values + 1);
-      child = g_value_get_pointer (param_values + 2);
-
-      if (!ATK_IS_OBJECT (child))
-        {
-          child = atk_object_ref_accessible_child (accessible, index);
-#ifdef SPI_ATK_DEBUG
-          non_owned_accessible (child);
-#endif
-        }
-      register_subtree (child);
-      update_accessible (accessible);
-    }
-  else if (!strcmp (detail, "remove"))
-    {
-      update_accessible (accessible);
-    }
-  return TRUE;
+  return object_to_ref (gobj);
 }
-
-static gboolean
-tree_update_children_listener (GSignalInvocationHint * signal_hint,
-                               guint n_param_values,
-                               const GValue * param_values, gpointer data)
-{
-  tree_update_wrapper (signal_hint, n_param_values, param_values, data,
-                       tree_update_children_action);
-  return TRUE;
-}
-
-/*---------------------------------------------------------------------------*/
-
-static void
-spi_atk_register_toplevel_added (AtkObject * accessible,
-                                 guint index, AtkObject * child)
-{
-  g_static_rec_mutex_lock (&registration_mutex);
-
-  g_return_if_fail (ATK_IS_OBJECT (accessible));
-
-  if (object_to_ref (accessible))
-    {
-#ifdef SPI_ATK_DEBUG
-      if (recursion_check_and_set ())
-        g_warning ("AT-SPI: Recursive use of registration module");
-
-      g_debug ("AT-SPI: Toplevel added listener");
-#endif
-      if (!ATK_IS_OBJECT (child))
-        {
-          child = atk_object_ref_accessible_child (accessible, index);
-#ifdef SPI_ATK_DEBUG
-          non_owned_accessible (child);
-#endif
-        }
-      register_subtree (child);
-      update_accessible (accessible);
-
-      recursion_check_unset ();
-    }
-
-  g_static_rec_mutex_unlock (&registration_mutex);
-}
-
-static void
-spi_atk_register_toplevel_removed (AtkObject * accessible,
-                                   guint index, AtkObject * child)
-{
-  g_static_rec_mutex_lock (&registration_mutex);
-
-  g_return_if_fail (ATK_IS_OBJECT (accessible));
-
-  if (object_to_ref (accessible))
-    {
-#ifdef SPI_ATK_DEBUG
-      if (recursion_check_and_set ())
-        g_warning ("AT-SPI: Recursive use of registration module");
-
-      g_debug ("AT-SPI: Toplevel removed listener");
-#endif
-      update_accessible (accessible);
-      recursion_check_unset ();
-    }
-
-  g_static_rec_mutex_unlock (&registration_mutex);
-}
-
+  
 /*
- * Initializes required global data. The update and removal lists
- * and the reference lookup tables.
- *
- * Initializes all of the required D-Bus interfaces.
+ * Gets the path that indicates the accessible desktop object.
+ * This object is logically located on the registry daemon and not
+ * within any particular application.
  */
-void
-atk_dbus_initialize (AtkObject * root)
+gchar *
+spi_register_desktop_object_path ()
 {
-  if (!ref2ptr)
-    ref2ptr = g_hash_table_new (g_direct_hash, g_direct_equal);
-
-  if (!objects_with_subrefs)
-    objects_with_subrefs = g_hash_table_new (g_direct_hash, g_direct_equal);
-
-  if (!leased_refs)
-    leased_refs = g_hash_table_new (g_direct_hash, g_direct_equal);
-
-#ifdef SPI_ATK_DEBUG
-  if (g_thread_supported ())
-    g_message ("AT-SPI: Threads enabled");
-
-  g_debug ("AT-SPI: Initial Atk tree regisration");
-#endif
-
-  register_subtree (root);
-
-  atk_add_global_event_listener (tree_update_property_listener,
-                                 "Gtk:AtkObject:property-change");
-  atk_add_global_event_listener (tree_update_children_listener,
-                                 "Gtk:AtkObject:children-changed");
-  atk_add_global_event_listener (tree_update_state_listener,
-                                 "Gtk:AtkObject:state-change");
-
-  g_signal_connect (root,
-                    "children-changed::add",
-                    (GCallback) spi_atk_register_toplevel_added, NULL);
-  g_signal_connect (root,
-                    "children-changed::remove",
-                    (GCallback) spi_atk_register_toplevel_removed, NULL);
+  return g_strdup (SPI_ATK_OBJECT_PATH_PREFIX SPI_ATK_OBJECT_PATH_DESKTOP);
 }
 
 /*END------------------------------------------------------------------------*/
index fe1912d..dda103b 100644 (file)
  * Boston, MA 02111-1307, USA.
  */
 
-#ifndef ACCESSIBLE_REGISTER
-#define ACCESSIBLE_REGISTER
+#ifndef ACCESSIBLE_REGISTER_H
+#define ACCESSIBLE_REGISTER_H
 
-#include <atk/atk.h>
 #include <glib.h>
+#include <glib-object.h>
 
-void atk_dbus_foreach_registered (GHFunc func, gpointer data);
+typedef struct _SpiRegister SpiRegister;
+typedef struct _SpiRegisterClass SpiRegisterClass;
 
-/*---------------------------------------------------------------------------*/
+G_BEGIN_DECLS
+
+#define SPI_REGISTER_TYPE        (spi_register_get_type ())
+#define SPI_REGISTER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_REGISTER_TYPE, SpiRegister))
+#define SPI_REGISTER_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_REGISTER_TYPE, SpiRegisterClass))
+#define SPI_IS_REGISTER(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_REGISTER_TYPE))
+#define SPI_IS_REGISTER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_REGISTER_TYPE))
+
+struct _SpiRegister
+{
+  GObject parent;
+
+  GHashTable * ref2ptr;
+  guint reference_counter;
+};
 
-GObject *atk_dbus_path_to_gobject (const char *path);
+struct _SpiRegisterClass
+{
+  GObjectClass parent_class;
+};
 
-AtkObject *atk_dbus_path_to_object (const char *path);
+GType spi_register_get_type (void);
 
-gchar *atk_dbus_object_attempt_registration (AtkObject * accessible);
+extern SpiRegister *spi_global_register;
 
-gchar *atk_dbus_object_to_path (AtkObject * accessible, gboolean do_register);
+/*---------------------------------------------------------------------------*/
+
+GObject *
+spi_register_path_to_object (SpiRegister * reg, const char *path);
 
-gchar *atk_dbus_sub_object_to_path (GObject * accessible,
-                                    GObject * container);
+GObject *
+spi_global_register_path_to_object (const char * path);
 
-gchar *atk_dbus_hyperlink_to_path (AtkHyperlink * hyperlink,
-                                   AtkObject * container);
+gchar *
+spi_register_object_to_path (SpiRegister * reg, GObject * gobj);
 
-gchar *atk_dbus_desktop_object_path ();
+guint
+spi_register_object_to_ref (GObject * gobj);
+  
+gchar *
+spi_register_desktop_object_path ();
+
+/*---------------------------------------------------------------------------*/
 
-gchar *atk_dbus_ref_to_path (guint ref);
-#endif /* ACCESSIBLE_REGISTER */
+#endif /* ACCESSIBLE_REGISTER_H */
index d130c80..e3f5cf9 100644 (file)
@@ -14,11 +14,10 @@ libatk_bridge_adaptors_la_LIBADD =\
 
 libatk_bridge_adaptors_la_SOURCES =\
        accessible-adaptor.c    \
-       accessible-marshaller.c \
-       accessible-marshaller.h \
        action-adaptor.c        \
        adaptors.h              \
        application-adaptor.c   \
+       cache-adaptor.c         \
        collection-adaptor.c    \
        component-adaptor.c     \
        document-adaptor.c      \
@@ -29,6 +28,4 @@ libatk_bridge_adaptors_la_SOURCES =\
        selection-adaptor.c     \
        table-adaptor.c         \
        text-adaptor.c          \
-       tree-adaptor.c          \
-       tree-adaptor.h          \
        value-adaptor.c
index 434223e..6359fa7 100644 (file)
@@ -27,8 +27,7 @@
 
 #include "common/spi-dbus.h"
 #include "common/spi-stateset.h"
-#include "accessible-marshaller.h"
-#include "accessible-register.h"
+#include "object.h"
 
 static dbus_bool_t
 impl_get_Name (DBusMessageIter * iter, void *user_data)
@@ -81,8 +80,8 @@ impl_get_Parent (DBusMessageIter * iter, void *user_data)
 
   g_return_val_if_fail (ATK_IS_OBJECT (user_data), FALSE);
 
-  return spi_dbus_return_v_object (iter,
-                                   atk_object_get_parent (object), FALSE);
+  spi_object_append_v_reference (iter, atk_object_get_parent (object));
+  return TRUE;
 }
 
 static dbus_bool_t
@@ -115,7 +114,7 @@ impl_GetChildAtIndex (DBusConnection * bus,
       return droute_invalid_arguments_error (message);
     }
   child = atk_object_ref_accessible_child (object, i);
-  return spi_dbus_return_object (message, child, TRUE, TRUE);
+  return spi_object_return_reference (message, child);
 }
 
 static DBusMessage *
@@ -136,18 +135,12 @@ impl_GetChildren (DBusConnection * bus,
     goto oom;
   dbus_message_iter_init_append (reply, &iter);
   if (!dbus_message_iter_open_container
-      (&iter, DBUS_TYPE_ARRAY, "o", &iter_array))
+      (&iter, DBUS_TYPE_ARRAY, "(so)", &iter_array))
     goto oom;
   for (i = 0; i < count; i++)
     {
       AtkObject *child = atk_object_ref_accessible_child (object, i);
-      char *path = atk_dbus_object_to_path (child, FALSE);
-      if (path)
-        {
-          dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_OBJECT_PATH,
-                                          &path);
-          g_free (path);
-        }
+      spi_object_append_reference (&iter_array, child); 
       if (child)
         g_object_unref (child);
     }
@@ -169,13 +162,10 @@ impl_GetIndexInParent (DBusConnection * bus,
 
   g_return_val_if_fail (ATK_IS_OBJECT (user_data),
                         droute_not_yet_handled_error (message));
+
   rv = atk_object_get_index_in_parent (object);
   reply = dbus_message_new_method_return (message);
-  if (reply)
-    {
-      dbus_message_append_args (reply, DBUS_TYPE_UINT32, &rv,
-                                DBUS_TYPE_INVALID);
-    }
+  dbus_message_append_args (reply, DBUS_TYPE_UINT32, &rv, DBUS_TYPE_INVALID);
   return reply;
 }
 
@@ -278,13 +268,7 @@ impl_GetRelationSet (DBusConnection * bus,
           char *path;
           if (!obj)
             continue;
-          path = atk_dbus_object_to_path (obj, FALSE);
-          if (!path)
-            {
-              g_warning ("Unknown object in relation type %d\n", type);
-              continue;
-            }
-          spi_dbus_append_name_and_path_inner (&iter_targets, NULL, path);
+          spi_object_append_reference (&iter_targets, obj);
         }
       dbus_message_iter_close_container (&iter_struct, &iter_targets);
       dbus_message_iter_close_container (&iter_array, &iter_struct);
@@ -295,133 +279,6 @@ oom:
   return reply;
 }
 
-static gboolean
-spi_init_role_lookup_table (Accessibility_Role * role_table)
-{
-  int i;
-  /* if it's not in the list below, dunno what it is */
-  for (i = 0; i < ATK_ROLE_LAST_DEFINED; ++i)
-    {
-      role_table[i] = Accessibility_ROLE_UNKNOWN;
-    }
-
-  role_table[ATK_ROLE_INVALID] = Accessibility_ROLE_INVALID;
-  role_table[ATK_ROLE_ACCEL_LABEL] = Accessibility_ROLE_ACCELERATOR_LABEL;
-  role_table[ATK_ROLE_ALERT] = Accessibility_ROLE_ALERT;
-  role_table[ATK_ROLE_ANIMATION] = Accessibility_ROLE_ANIMATION;
-  role_table[ATK_ROLE_ARROW] = Accessibility_ROLE_ARROW;
-  role_table[ATK_ROLE_CALENDAR] = Accessibility_ROLE_CALENDAR;
-  role_table[ATK_ROLE_CANVAS] = Accessibility_ROLE_CANVAS;
-  role_table[ATK_ROLE_CHECK_BOX] = Accessibility_ROLE_CHECK_BOX;
-  role_table[ATK_ROLE_CHECK_MENU_ITEM] = Accessibility_ROLE_CHECK_MENU_ITEM;
-  role_table[ATK_ROLE_COLOR_CHOOSER] = Accessibility_ROLE_COLOR_CHOOSER;
-  role_table[ATK_ROLE_COLUMN_HEADER] = Accessibility_ROLE_COLUMN_HEADER;
-  role_table[ATK_ROLE_COMBO_BOX] = Accessibility_ROLE_COMBO_BOX;
-  role_table[ATK_ROLE_DATE_EDITOR] = Accessibility_ROLE_DATE_EDITOR;
-  role_table[ATK_ROLE_DESKTOP_ICON] = Accessibility_ROLE_DESKTOP_ICON;
-  role_table[ATK_ROLE_DESKTOP_FRAME] = Accessibility_ROLE_DESKTOP_FRAME;
-  role_table[ATK_ROLE_DIAL] = Accessibility_ROLE_DIAL;
-  role_table[ATK_ROLE_DIALOG] = Accessibility_ROLE_DIALOG;
-  role_table[ATK_ROLE_DIRECTORY_PANE] = Accessibility_ROLE_DIRECTORY_PANE;
-  role_table[ATK_ROLE_DRAWING_AREA] = Accessibility_ROLE_DRAWING_AREA;
-  role_table[ATK_ROLE_FILE_CHOOSER] = Accessibility_ROLE_FILE_CHOOSER;
-  role_table[ATK_ROLE_FILLER] = Accessibility_ROLE_FILLER;
-  role_table[ATK_ROLE_FONT_CHOOSER] = Accessibility_ROLE_FONT_CHOOSER;
-  role_table[ATK_ROLE_FRAME] = Accessibility_ROLE_FRAME;
-  role_table[ATK_ROLE_GLASS_PANE] = Accessibility_ROLE_GLASS_PANE;
-  role_table[ATK_ROLE_HTML_CONTAINER] = Accessibility_ROLE_HTML_CONTAINER;
-  role_table[ATK_ROLE_ICON] = Accessibility_ROLE_ICON;
-  role_table[ATK_ROLE_IMAGE] = Accessibility_ROLE_IMAGE;
-  role_table[ATK_ROLE_INTERNAL_FRAME] = Accessibility_ROLE_INTERNAL_FRAME;
-  role_table[ATK_ROLE_LABEL] = Accessibility_ROLE_LABEL;
-  role_table[ATK_ROLE_LAYERED_PANE] = Accessibility_ROLE_LAYERED_PANE;
-  role_table[ATK_ROLE_LIST] = Accessibility_ROLE_LIST;
-  role_table[ATK_ROLE_LIST_ITEM] = Accessibility_ROLE_LIST_ITEM;
-  role_table[ATK_ROLE_MENU] = Accessibility_ROLE_MENU;
-  role_table[ATK_ROLE_MENU_BAR] = Accessibility_ROLE_MENU_BAR;
-  role_table[ATK_ROLE_MENU_ITEM] = Accessibility_ROLE_MENU_ITEM;
-  role_table[ATK_ROLE_OPTION_PANE] = Accessibility_ROLE_OPTION_PANE;
-  role_table[ATK_ROLE_PAGE_TAB] = Accessibility_ROLE_PAGE_TAB;
-  role_table[ATK_ROLE_PAGE_TAB_LIST] = Accessibility_ROLE_PAGE_TAB_LIST;
-  role_table[ATK_ROLE_PANEL] = Accessibility_ROLE_PANEL;
-  role_table[ATK_ROLE_PASSWORD_TEXT] = Accessibility_ROLE_PASSWORD_TEXT;
-  role_table[ATK_ROLE_POPUP_MENU] = Accessibility_ROLE_POPUP_MENU;
-  role_table[ATK_ROLE_PROGRESS_BAR] = Accessibility_ROLE_PROGRESS_BAR;
-  role_table[ATK_ROLE_PUSH_BUTTON] = Accessibility_ROLE_PUSH_BUTTON;
-  role_table[ATK_ROLE_RADIO_BUTTON] = Accessibility_ROLE_RADIO_BUTTON;
-  role_table[ATK_ROLE_RADIO_MENU_ITEM] = Accessibility_ROLE_RADIO_MENU_ITEM;
-  role_table[ATK_ROLE_ROOT_PANE] = Accessibility_ROLE_ROOT_PANE;
-  role_table[ATK_ROLE_ROW_HEADER] = Accessibility_ROLE_ROW_HEADER;
-  role_table[ATK_ROLE_SCROLL_BAR] = Accessibility_ROLE_SCROLL_BAR;
-  role_table[ATK_ROLE_SCROLL_PANE] = Accessibility_ROLE_SCROLL_PANE;
-  role_table[ATK_ROLE_SEPARATOR] = Accessibility_ROLE_SEPARATOR;
-  role_table[ATK_ROLE_SLIDER] = Accessibility_ROLE_SLIDER;
-  role_table[ATK_ROLE_SPIN_BUTTON] = Accessibility_ROLE_SPIN_BUTTON;
-  role_table[ATK_ROLE_SPLIT_PANE] = Accessibility_ROLE_SPLIT_PANE;
-  role_table[ATK_ROLE_STATUSBAR] = Accessibility_ROLE_STATUS_BAR;
-  role_table[ATK_ROLE_TABLE] = Accessibility_ROLE_TABLE;
-  role_table[ATK_ROLE_TABLE_CELL] = Accessibility_ROLE_TABLE_CELL;
-  role_table[ATK_ROLE_TABLE_COLUMN_HEADER] =
-    Accessibility_ROLE_TABLE_COLUMN_HEADER;
-  role_table[ATK_ROLE_TABLE_ROW_HEADER] = Accessibility_ROLE_TABLE_ROW_HEADER;
-  role_table[ATK_ROLE_TEAR_OFF_MENU_ITEM] =
-    Accessibility_ROLE_TEAROFF_MENU_ITEM;
-  role_table[ATK_ROLE_TERMINAL] = Accessibility_ROLE_TERMINAL;
-  role_table[ATK_ROLE_TEXT] = Accessibility_ROLE_TEXT;
-  role_table[ATK_ROLE_TOGGLE_BUTTON] = Accessibility_ROLE_TOGGLE_BUTTON;
-  role_table[ATK_ROLE_TOOL_BAR] = Accessibility_ROLE_TOOL_BAR;
-  role_table[ATK_ROLE_TOOL_TIP] = Accessibility_ROLE_TOOL_TIP;
-  role_table[ATK_ROLE_TREE] = Accessibility_ROLE_TREE;
-  role_table[ATK_ROLE_TREE_TABLE] = Accessibility_ROLE_TREE_TABLE;
-  role_table[ATK_ROLE_UNKNOWN] = Accessibility_ROLE_UNKNOWN;
-  role_table[ATK_ROLE_VIEWPORT] = Accessibility_ROLE_VIEWPORT;
-  role_table[ATK_ROLE_WINDOW] = Accessibility_ROLE_WINDOW;
-  role_table[ATK_ROLE_HEADER] = Accessibility_ROLE_HEADER;
-  role_table[ATK_ROLE_FOOTER] = Accessibility_ROLE_FOOTER;
-  role_table[ATK_ROLE_PARAGRAPH] = Accessibility_ROLE_PARAGRAPH;
-  role_table[ATK_ROLE_RULER] = Accessibility_ROLE_RULER;
-  role_table[ATK_ROLE_APPLICATION] = Accessibility_ROLE_APPLICATION;
-  role_table[ATK_ROLE_AUTOCOMPLETE] = Accessibility_ROLE_AUTOCOMPLETE;
-  role_table[ATK_ROLE_EDITBAR] = Accessibility_ROLE_EDITBAR;
-  role_table[ATK_ROLE_EMBEDDED] = Accessibility_ROLE_EMBEDDED;
-  role_table[ATK_ROLE_ENTRY] = Accessibility_ROLE_ENTRY;
-  role_table[ATK_ROLE_CHART] = Accessibility_ROLE_CHART;
-  role_table[ATK_ROLE_CAPTION] = Accessibility_ROLE_CAPTION;
-  role_table[ATK_ROLE_DOCUMENT_FRAME] = Accessibility_ROLE_DOCUMENT_FRAME;
-  role_table[ATK_ROLE_HEADING] = Accessibility_ROLE_HEADING;
-  role_table[ATK_ROLE_PAGE] = Accessibility_ROLE_PAGE;
-  role_table[ATK_ROLE_SECTION] = Accessibility_ROLE_SECTION;
-  role_table[ATK_ROLE_FORM] = Accessibility_ROLE_FORM;
-  role_table[ATK_ROLE_REDUNDANT_OBJECT] = Accessibility_ROLE_REDUNDANT_OBJECT;
-  role_table[ATK_ROLE_LINK] = Accessibility_ROLE_LINK;
-  role_table[ATK_ROLE_INPUT_METHOD_WINDOW] =
-    Accessibility_ROLE_INPUT_METHOD_WINDOW;
-  return TRUE;
-}
-
-Accessibility_Role
-spi_accessible_role_from_atk_role (AtkRole role)
-{
-  static gboolean is_initialized = FALSE;
-  static Accessibility_Role spi_role_table[ATK_ROLE_LAST_DEFINED];
-  Accessibility_Role spi_role;
-
-  if (!is_initialized)
-    {
-      is_initialized = spi_init_role_lookup_table (spi_role_table);
-    }
-
-  if (role >= 0 && role < ATK_ROLE_LAST_DEFINED)
-    {
-      spi_role = spi_role_table[role];
-    }
-  else
-    {
-      spi_role = Accessibility_ROLE_EXTENDED;
-    }
-  return spi_role;
-}
-
 static DBusMessage *
 impl_GetRole (DBusConnection * bus, DBusMessage * message, void *user_data)
 {
@@ -534,9 +391,8 @@ impl_GetAttributes (DBusConnection * bus,
                     DBusMessage * message, void *user_data)
 {
   AtkObject *object = (AtkObject *) user_data;
-  DBusMessage *reply = NULL;
-
   AtkAttributeSet *attributes;
+  DBusMessage *reply = NULL;
   DBusMessageIter iter;
 
   g_return_val_if_fail (ATK_IS_OBJECT (user_data),
@@ -546,10 +402,9 @@ impl_GetAttributes (DBusConnection * bus,
 
   reply = dbus_message_new_method_return (message);
   dbus_message_iter_init_append (reply, &iter);
-  spi_atk_append_attribute_set (&iter, attributes);
+  spi_object_append_attribute_set (&iter, attributes);
 
-  if (attributes)
-    atk_attribute_set_free (attributes);
+  atk_attribute_set_free (attributes);
 
   return reply;
 }
@@ -559,7 +414,7 @@ impl_GetApplication (DBusConnection * bus,
                      DBusMessage * message, void *user_data)
 {
   AtkObject *root = atk_get_root ();
-  return spi_dbus_return_object (message, root, FALSE, FALSE);
+  return spi_object_return_reference (message, root);
 }
 
 static DBusMessage *
@@ -580,7 +435,7 @@ impl_GetInterfaces (DBusConnection * bus,
       dbus_message_iter_init_append (reply, &iter);
       dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "s",
                                         &iter_array);
-      append_atk_object_interfaces (object, &iter_array);
+      spi_object_append_interfaces (&iter_array, object);
       dbus_message_iter_close_container (&iter, &iter_array);
     }
   return reply;
diff --git a/atk-adaptor/adaptors/accessible-marshaller.c b/atk-adaptor/adaptors/accessible-marshaller.c
deleted file mode 100644 (file)
index f087171..0000000
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * AT-SPI - Assistive Technology Service Provider Interface
- * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
- *
- * Copyright 2008 Novell, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <droute/droute.h>
-
-#include "common/spi-dbus.h"
-#include "common/spi-stateset.h"
-
-#include "accessible-register.h"
-#include "accessible-marshaller.h"
-#include "bridge.h"
-
-#include "adaptors.h"
-
-/*---------------------------------------------------------------------------*/
-
-void
-spi_dbus_append_name_and_path_inner (DBusMessageIter * iter,
-                                     const char *bus_name, const char *path)
-{
-  DBusMessageIter iter_struct;
-
-  if (!bus_name)
-    bus_name = "";
-  if (!path)
-    path = SPI_DBUS_PATH_NULL;
-
-  dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
-                                    &iter_struct);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &bus_name);
-  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
-  dbus_message_iter_close_container (iter, &iter_struct);
-}
-
-extern gchar *atspi_dbus_name;
-
-void
-spi_dbus_append_name_and_path (DBusMessage * message, DBusMessageIter * iter,
-                               AtkObject * obj, gboolean do_register,
-                               gboolean unref)
-{
-  gchar *path;
-  DBusMessageIter iter_struct;
-
-  path = atk_dbus_object_to_path (obj, do_register);
-
-  spi_dbus_append_name_and_path_inner (iter, atspi_dbus_name, path);
-
-  g_free (path);
-  if (obj && unref)
-    g_object_unref (obj);
-}
-
-/*
- * Marshals the D-Bus path of an AtkObject into a D-Bus message.
- *
- * Unrefs the AtkObject if unref is true.
- */
-DBusMessage *
-spi_dbus_return_object (DBusMessage * message, AtkObject * obj,
-                        gboolean do_register, gboolean unref)
-{
-  DBusMessage *reply;
-  reply = dbus_message_new_method_return (message);
-  if (reply)
-    {
-      DBusMessageIter iter;
-      dbus_message_iter_init_append (reply, &iter);
-      spi_dbus_append_name_and_path (message, &iter, obj, do_register, unref);
-    }
-
-  return reply;
-}
-
-DBusMessage *
-spi_dbus_return_hyperlink (DBusMessage * message, AtkHyperlink * link,
-                           AtkObject * container, gboolean unref)
-{
-  return spi_dbus_return_sub_object (message, G_OBJECT (link),
-                                     G_OBJECT (container), unref);
-}
-
-DBusMessage *
-spi_dbus_return_sub_object (DBusMessage * message, GObject * sub,
-                            GObject * container, gboolean unref)
-{
-  DBusMessage *reply;
-  gchar *path;
-
-  path = atk_dbus_sub_object_to_path (sub, container);
-
-  if (sub && unref)
-    g_object_unref (sub);
-
-  if (!path)
-    path = g_strdup (SPI_DBUS_PATH_NULL);
-
-  reply = dbus_message_new_method_return (message);
-  if (reply)
-    {
-      dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path,
-                                DBUS_TYPE_INVALID);
-    }
-
-  g_free (path);
-
-  return reply;
-}
-
-/*---------------------------------------------------------------------------*/
-
-/*
- * Marshals a variant containing the D-Bus path of an AtkObject into a D-Bus
- * message.
- *
- * Unrefs the object if unref is true.
- */
-dbus_bool_t
-spi_dbus_return_v_object (DBusMessageIter * iter, AtkObject * obj, int unref)
-{
-  DBusMessageIter iter_variant;
-  char *path;
-
-  path = atk_dbus_object_to_path (obj, FALSE);
-
-  if (!path)
-    path = g_strdup (SPI_DBUS_PATH_NULL);
-
-  if (unref)
-    g_object_unref (obj);
-
-  dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "(so)",
-                                    &iter_variant);
-  spi_dbus_append_name_and_path_inner (&iter_variant, NULL, path);
-  dbus_message_iter_close_container (iter, &iter_variant);
-  return TRUE;
-}
-
-/*---------------------------------------------------------------------------*/
-
-void
-append_atk_object_interfaces (AtkObject * object, DBusMessageIter * iter)
-{
-  const gchar *itf;
-
-  itf = SPI_DBUS_INTERFACE_ACCESSIBLE;
-  dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
-
-  if (ATK_IS_ACTION (object))
-    {
-      itf = SPI_DBUS_INTERFACE_ACTION;
-      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
-    }
-
-  if (ATK_IS_COMPONENT (object))
-    {
-      itf = SPI_DBUS_INTERFACE_COMPONENT;
-      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
-    }
-
-  if (ATK_IS_EDITABLE_TEXT (object))
-    {
-      itf = SPI_DBUS_INTERFACE_EDITABLE_TEXT;
-      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
-    }
-
-  if (ATK_IS_TEXT (object))
-    {
-      itf = SPI_DBUS_INTERFACE_TEXT;
-      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
-    }
-
-  if (ATK_IS_HYPERTEXT (object))
-    {
-      itf = SPI_DBUS_INTERFACE_HYPERTEXT;
-      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
-    }
-
-  if (ATK_IS_IMAGE (object))
-    {
-      itf = SPI_DBUS_INTERFACE_IMAGE;
-      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
-    }
-
-  if (ATK_IS_SELECTION (object))
-    {
-      itf = SPI_DBUS_INTERFACE_SELECTION;
-      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
-    }
-
-  if (ATK_IS_TABLE (object))
-    {
-      itf = SPI_DBUS_INTERFACE_TABLE;
-      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
-    }
-
-  if (ATK_IS_VALUE (object))
-    {
-      itf = SPI_DBUS_INTERFACE_VALUE;
-      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
-    }
-
-  if (ATK_IS_STREAMABLE_CONTENT (object))
-    {
-      itf = "org.freedesktop.atspi.StreamableContent";
-      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
-    }
-
-  if (ATK_IS_DOCUMENT (object))
-    {
-      itf = "org.freedesktop.atspi.Collection";
-      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
-      itf = SPI_DBUS_INTERFACE_DOCUMENT;
-      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
-    }
-
-  if (ATK_IS_HYPERLINK_IMPL (object))
-    {
-      itf = SPI_DBUS_INTERFACE_HYPERLINK;
-      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
-    }
-}
-
-/*---------------------------------------------------------------------------*/
-
-/*
- * Marshals the given AtkObject into the provided D-Bus iterator.
- *
- * The object is marshalled including all its client side cache data.
- * The format of the structure is (o(so)a(so)assusau).
- * This is used in the updateTree signal and the GetTree method
- * of the org.freedesktop.atspi.Tree interface.
- *
- * To marshal an object its parent, and all its children must already
- * be registered with D-Bus and have been given a D-Bus object path.
- */
-void
-spi_atk_append_accessible (AtkObject * obj, gpointer data)
-{
-  DBusMessageIter iter_struct, iter_sub_array;
-  dbus_uint32_t states[2];
-  int count;
-  AtkStateSet *set;
-  DBusMessageIter *iter_array = (DBusMessageIter *) data;
-
-  const char *name, *desc;
-  dbus_uint32_t role;
-
-  set = atk_object_ref_state_set (obj);
-  {
-    AtkObject *parent;
-    gchar *path;
-    gchar *bus_parent = NULL, *path_parent;
-
-    /* Marshall object path */
-    path = atk_dbus_object_to_path (obj, FALSE);
-
-    role = spi_accessible_role_from_atk_role (atk_object_get_role (obj));
-
-    /* Marshall parent */
-    parent = atk_object_get_parent (obj);
-    if (parent == NULL)
-      {
-        /* TODO: Support getting parent of an AtkPlug */
-#ifdef __ATK_PLUG_H__
-          if (ATK_IS_PLUG (obj))
-            {
-              char *id = g_object_get_data (G_OBJECT (obj), "dbus-plug-parent");
-              if (id)
-                bus_parent = g_strdup (id);
-              if (bus_parent && (path_parent = g_utf8_strchr (bus_parent + 1, -1, ':')))
-                {
-                  *(path_parent++) = '\0';
-                  /* path_parent is going to be freed, so dup it */
-                  path_parent = g_strdup (path_parent);
-                }
-            }
-          else if (role != Accessibility_ROLE_APPLICATION)
-#else
-        if (role != Accessibility_ROLE_APPLICATION)
-#endif
-          path_parent = g_strdup (SPI_DBUS_PATH_NULL);
-        else
-          path_parent = atk_dbus_desktop_object_path ();
-      }
-    else
-      {
-        path_parent = atk_dbus_object_to_path (parent, FALSE);
-        if (!path_parent)
-          {
-            /* This should only happen if a widget is re-parented to
-             * an AtkObject that has not been registered and is then
-             * updated. Ideally objects would be de-registered when
-             * they are removed from a registered tree object, but
-             * this would invalidate a huge amount of cache when
-             * re-parenting.
-             */
-#if SPI_ATK_DEBUG
-            g_warning
-              ("AT-SPI: Registered accessible marshalled when parent not registered");
-#endif
-            path_parent = atk_dbus_desktop_object_path ();
-          }
-      }
-
-    dbus_message_iter_open_container (iter_array, DBUS_TYPE_STRUCT, NULL,
-                                      &iter_struct);
-    dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH,
-                                    &path);
-    spi_dbus_append_name_and_path_inner (&iter_struct, bus_parent,
-                                         path_parent);
-    g_free (path_parent);
-    g_free (bus_parent);
-
-    /* Marshall children */
-    dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "(so)",
-                                      &iter_sub_array);
-    if (!atk_state_set_contains_state (set, ATK_STATE_MANAGES_DESCENDANTS))
-      {
-        gint childcount, i;
-
-        childcount = atk_object_get_n_accessible_children (obj);
-        for (i = 0; i < childcount; i++)
-          {
-            AtkObject *child;
-            gchar *child_path;
-
-            child = atk_object_ref_accessible_child (obj, i);
-            child_path = atk_dbus_object_to_path (child, FALSE);
-            if (child_path)
-              {
-                spi_dbus_append_name_and_path_inner (&iter_sub_array, NULL,
-                                                     child_path);
-                g_free (child_path);
-              }
-            g_object_unref (G_OBJECT (child));
-          }
-      }
-#ifdef __ATK_PLUG_H__
-    if (ATK_IS_SOCKET (obj) && atk_socket_is_occupied (ATK_SOCKET (obj)))
-      {
-        AtkSocket *socket = ATK_SOCKET (obj);
-        gchar *child_name, *child_path;
-        child_name = g_strdup (socket->embedded_plug_id);
-        child_path = g_utf8_strchr (child_name + 1, -1, ':');
-        if (child_path)
-          {
-            *(child_path++) = '\0';
-            spi_dbus_append_name_and_path_inner (&iter_sub_array, child_name,
-                                                 child_path);
-          }
-        g_free (child_name);
-      }
-#endif
-
-    dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
-
-    /* Marshall interfaces */
-    dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "s",
-                                      &iter_sub_array);
-    append_atk_object_interfaces (obj, &iter_sub_array);
-    dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
-
-    /* Marshall name */
-    name = atk_object_get_name (obj);
-    if (!name)
-      name = "";
-    dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
-
-    /* Marshall role */
-    dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT32, &role);
-
-    /* Marshall description */
-    desc = atk_object_get_description (obj);
-    if (!desc)
-      desc = "";
-    dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &desc);
-
-    g_free (path);
-
-    /* Marshall state set */
-    spi_atk_state_set_to_dbus_array (set, states);
-    dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "u",
-                                      &iter_sub_array);
-    for (count = 0; count < 2; count++)
-      {
-        dbus_message_iter_append_basic (&iter_sub_array, DBUS_TYPE_UINT32,
-                                        &states[count]);
-      }
-    dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
-  }
-  dbus_message_iter_close_container (iter_array, &iter_struct);
-  g_object_unref (set);
-}
-
-void
-spi_atk_append_attribute_set (DBusMessageIter * iter, AtkAttributeSet * attr)
-{
-  DBusMessageIter dictIter;
-
-  dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{ss}", &dictIter);
-  spi_atk_append_attribute_set_inner (&dictIter, attr);
-  dbus_message_iter_close_container (iter, &dictIter);
-}
-
-void
-spi_atk_append_attribute_set_inner (DBusMessageIter * iter,
-                                    AtkAttributeSet * attr)
-{
-  DBusMessageIter dictEntryIter;
-
-  while (attr)
-    {
-      AtkAttribute *attribute = (AtkAttribute *) attr->data;
-      dbus_message_iter_open_container (iter, DBUS_TYPE_DICT_ENTRY, NULL,
-                                        &dictEntryIter);
-      dbus_message_iter_append_basic (&dictEntryIter, DBUS_TYPE_STRING,
-                                      &attribute->name);
-      dbus_message_iter_append_basic (&dictEntryIter, DBUS_TYPE_STRING,
-                                      &attribute->value);
-      dbus_message_iter_close_container (iter, &dictEntryIter);
-      attr = g_slist_next (attr);
-    }
-}
-
-/*END------------------------------------------------------------------------*/
diff --git a/atk-adaptor/adaptors/accessible-marshaller.h b/atk-adaptor/adaptors/accessible-marshaller.h
deleted file mode 100644 (file)
index 4d0a131..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * AT-SPI - Assistive Technology Service Provider Interface
- * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
- *
- * Copyright 2008 Novell, Inc.
- * Copyright 2008, 2009 Codethink Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef ACCESSIBLE_MARSHALLER
-#define ACCESSIBLE_MARSHALLER
-
-#include <dbus/dbus.h>
-#include <atk/atk.h>
-
-void
-spi_dbus_append_name_and_path_inner (DBusMessageIter * iter,
-                                     const char *bus_name, const char *path);
-
-void
-spi_dbus_append_name_and_path (DBusMessage * message, DBusMessageIter * iter,
-                               AtkObject * obj, gboolean do_register,
-                               gboolean unref);
-
-DBusMessage *spi_dbus_return_object (DBusMessage * message, AtkObject * obj,
-                                     gboolean do_register, gboolean unref);
-
-DBusMessage *spi_dbus_return_hyperlink (DBusMessage * message,
-                                        AtkHyperlink * link,
-                                        AtkObject * container,
-                                        gboolean unref);
-
-DBusMessage *spi_dbus_return_sub_object (DBusMessage * message, GObject * sub,
-                                         GObject * container, gboolean unref);
-
-dbus_bool_t
-spi_dbus_return_v_object (DBusMessageIter * iter, AtkObject * obj, int unref);
-
-void spi_atk_append_accessible (AtkObject * obj, gpointer iter);
-
-void
-spi_atk_append_attribute_set (DBusMessageIter * iter, AtkAttributeSet * attr);
-
-void
-spi_atk_append_attribute_set_inner (DBusMessageIter * iter,
-                                    AtkAttributeSet * attr);
-
-void
-append_atk_object_interfaces (AtkObject * object, DBusMessageIter * iter);
-#endif /* ACCESSIBLE_MARSHALLER */
index 7f8bdd9..ccc07ab 100644 (file)
@@ -43,6 +43,6 @@ void spi_initialize_selection (DRoutePath * path);
 void spi_initialize_table (DRoutePath * path);
 void spi_initialize_text (DRoutePath * path);
 void spi_initialize_value (DRoutePath * path);
-void spi_initialize_tree (DRoutePath * path);
+void spi_initialize_cache (DRoutePath * path);
 
 #endif /* ADAPTORS_H */
diff --git a/atk-adaptor/adaptors/cache-adaptor.c b/atk-adaptor/adaptors/cache-adaptor.c
new file mode 100644 (file)
index 0000000..45eb41b
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
+ *
+ * Copyright 2008 Novell, Inc.
+ * Copyright 2001, 2002 Sun Microsystems Inc.,
+ * Copyright 2001, 2002 Ximian, Inc.
+ * Copyright 2008, 2009 Codethink Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include <atk/atk.h>
+#include <droute/droute.h>
+
+#include "common/spi-dbus.h"
+#include "accessible-cache.h"
+#include "bridge.h"
+#include "object.h"
+
+/* TODO - This should possibly be a common define */
+#define SPI_OBJECT_PREFIX "/org/at_spi"
+#define SPI_CACHE_OBJECT_SUFFIX "/cache"
+#define SPI_CACHE_OBJECT_PATH SPI_OBJECT_PREFIX SPI_CACHE_OBJECT_SUFFIX
+
+#define SPI_OBJECT_REFERENCE_SIGNATURE "(" \
+                                          DBUS_TYPE_STRING_AS_STRING \
+                                          DBUS_TYPE_OBJECT_PATH_AS_STRING \
+                                       ")"
+                                          
+#define SPI_CACHE_ITEM_SIGNATURE "(" \
+                                   DBUS_TYPE_OBJECT_PATH_AS_STRING \
+                                   SPI_OBJECT_REFERENCE_SIGNATURE \
+                                   SPI_OBJECT_REFERENCE_SIGNATURE \
+                                   DBUS_TYPE_ARRAY_AS_STRING \
+                                     SPI_OBJECT_REFERENCE_SIGNATURE \
+                                   DBUS_TYPE_ARRAY_AS_STRING \
+                                     DBUS_TYPE_STRING_AS_STRING \
+                                   DBUS_TYPE_STRING_AS_STRING \
+                                   DBUS_TYPE_UINT32_AS_STRING \
+                                   DBUS_TYPE_STRING_AS_STRING \
+                                   DBUS_TYPE_ARRAY_AS_STRING \
+                                     DBUS_TYPE_UINT32_AS_STRING \
+                                 ")"
+
+/*---------------------------------------------------------------------------*/
+
+/*
+ * Marshals the given AtkObject into the provided D-Bus iterator.
+ *
+ * The object is marshalled including all its client side cache data.
+ * The format of the structure is (o(so)a(so)assusau).
+ */
+static void
+append_cache_item (AtkObject * obj, gpointer data)
+{
+  DBusMessageIter iter_struct, iter_sub_array;
+  dbus_uint32_t states[2];
+  int count;
+  AtkStateSet *set;
+  DBusMessageIter *iter_array = (DBusMessageIter *) data;
+
+  const char *name, *desc;
+  dbus_uint32_t role;
+
+  set = atk_object_ref_state_set (obj);
+  {
+    AtkObject *application, *parent;
+
+    dbus_message_iter_open_container (iter_array, DBUS_TYPE_STRUCT, NULL,
+                                      &iter_struct);
+
+    /* Marshall object path */
+    spi_object_append_reference (&iter_struct, obj);
+
+    role = spi_accessible_role_from_atk_role (atk_object_get_role (obj));
+
+    /* Marshall application */
+    application = spi_global_app_data->root; 
+    spi_object_append_reference (&iter_struct, application);
+
+    /* Marshall parent */
+    parent = atk_object_get_parent (obj);
+    if (parent == NULL)
+      {
+        /* TODO: Support getting parent of an AtkPlug */
+#ifdef __ATK_PLUG_H__
+        if (role != Accessibility_ROLE_APPLICATION && !ATK_IS_PLUG (obj))
+#else
+        if (role != Accessibility_ROLE_APPLICATION)
+#endif
+          spi_object_append_null_reference (&iter_struct);
+        else
+          spi_object_append_desktop_reference (&iter_struct);
+      }
+    else
+      {
+        spi_object_append_reference (&iter_struct, parent);
+      }
+
+    /* Marshall children */
+    dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "(so)",
+                                      &iter_sub_array);
+    if (!atk_state_set_contains_state (set, ATK_STATE_MANAGES_DESCENDANTS))
+      {
+        gint childcount, i;
+
+        childcount = atk_object_get_n_accessible_children (obj);
+        for (i = 0; i < childcount; i++)
+          {
+            AtkObject *child;
+            gchar *child_path;
+
+            child = atk_object_ref_accessible_child (obj, i);
+            spi_object_append_reference (&iter_sub_array, child);
+            g_object_unref (G_OBJECT (child));
+          }
+      }
+#ifdef __ATK_PLUG_H__
+    if (ATK_IS_SOCKET (obj) && atk_socket_is_occupied (ATK_SOCKET (obj)))
+      {
+        AtkSocket *socket = ATK_SOCKET (obj);
+        gchar *child_name, *child_path;
+        child_name = g_strdup (socket->embedded_plug_id);
+        child_path = g_utf8_strchr (child_name + 1, -1, ':');
+        if (child_path)
+          {
+            DBusMessageIter iter_socket;
+            *(child_path++) = '\0';
+            dbus_message_iter_open_container (&iter_sub_array, DBUS_TYPE_STRUCT, NULL,
+                                              &iter_socket);
+            dbus_message_iter_append_basic (&iter_socket, DBUS_TYPE_STRING, &name);
+            dbus_message_iter_append_basic (&iter_socket, DBUS_TYPE_OBJECT_PATH, &path);
+            dbus_message_iter_close_container (&iter_sub_array, &iter_socket);
+          }
+        g_free (child_name);
+      }
+#endif
+
+    dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
+
+    /* Marshall interfaces */
+    dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "s",
+                                      &iter_sub_array);
+    spi_object_append_interfaces (&iter_sub_array, obj);
+    dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
+
+    /* Marshall name */
+    name = atk_object_get_name (obj);
+    if (!name)
+      name = "";
+    dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
+
+    /* Marshall role */
+    dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT32, &role);
+
+    /* Marshall description */
+    desc = atk_object_get_description (obj);
+    if (!desc)
+      desc = "";
+    dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &desc);
+
+    /* Marshall state set */
+    spi_atk_state_set_to_dbus_array (set, states);
+    dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "u",
+                                      &iter_sub_array);
+    for (count = 0; count < 2; count++)
+      {
+        dbus_message_iter_append_basic (&iter_sub_array, DBUS_TYPE_UINT32,
+                                        &states[count]);
+      }
+    dbus_message_iter_close_container (&iter_struct, &iter_sub_array);
+  }
+  dbus_message_iter_close_container (iter_array, &iter_struct);
+  g_object_unref (set);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/* For use as a GHFunc */
+static void
+append_accessible_hf (gpointer key, gpointer obj_data, gpointer data)
+{
+  /* Make sure it isn't a hyperlink */
+  if (ATK_IS_OBJECT (obj_data))
+    append_cache_item (ATK_OBJECT (obj_data), data);
+}
+
+/*---------------------------------------------------------------------------*/
+
+static void
+emit_cache_remove (SpiCache *cache, GObject * obj)
+{
+  DBusMessage *message;
+
+  if ((message = dbus_message_new_signal (SPI_CACHE_OBJECT_PATH,
+                                          SPI_DBUS_INTERFACE_CACHE,
+                                          "RemoveAccessible")))
+    {
+      DBusMessageIter iter;
+      gchar *path;
+
+      dbus_message_iter_init_append (message, &iter);
+
+      spi_object_append_reference (&iter, ATK_OBJECT (obj));
+
+      dbus_connection_send (spi_global_app_data->bus, message, NULL);
+
+      dbus_message_unref (message);
+    }
+}
+
+static void
+emit_cache_add (SpiCache *cache, GObject * obj)
+{
+  AtkObject *accessible = ATK_OBJECT (obj);
+  DBusMessage *message;
+
+  if ((message = dbus_message_new_signal (SPI_CACHE_OBJECT_PATH,
+                                          SPI_DBUS_INTERFACE_CACHE,
+                                          "AddAccessible")))
+    {
+      DBusMessageIter iter;
+
+      dbus_message_iter_init_append (message, &iter);
+      append_cache_item (accessible, &iter);
+
+      dbus_connection_send (spi_global_app_data->bus, message, NULL);
+
+      dbus_message_unref (message);
+    }
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+static DBusMessage *
+impl_GetRoot (DBusConnection * bus, DBusMessage * message, void *user_data)
+{
+  return spi_object_return_reference (message,
+                                      g_object_ref (G_OBJECT (spi_global_app_data->root)));
+}
+
+/*---------------------------------------------------------------------------*/
+
+static DBusMessage *
+impl_GetItems (DBusConnection * bus, DBusMessage * message, void *user_data)
+{
+  DBusMessage *reply;
+  DBusMessageIter iter, iter_array;
+
+  reply = dbus_message_new_method_return (message);
+
+  dbus_message_iter_init_append (reply, &iter);
+  dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
+                                    SPI_CACHE_ITEM_SIGNATURE, &iter_array);
+  spi_cache_foreach (spi_global_cache, append_accessible_hf, &iter_array);
+  dbus_message_iter_close_container (&iter, &iter_array);
+  return reply;
+}
+
+/*---------------------------------------------------------------------------*/
+
+static DRouteMethod methods[] = {
+  {impl_GetRoot, "GetRoot"},
+  {impl_GetItems, "GetItems"},
+  {NULL, NULL}
+};
+
+void
+spi_initialize_cache (DRoutePath * path)
+{
+  droute_path_add_interface (path, SPI_DBUS_INTERFACE_CACHE, methods, NULL);
+
+  g_signal_connect (spi_global_cache,
+                    "object-added",
+                    (GCallback) emit_cache_add,
+                    NULL);
+
+  g_signal_connect (spi_global_cache,
+                    "object-removed",
+                    (GCallback) emit_cache_remove,
+                    NULL);
+};
+
+/*END------------------------------------------------------------------------*/
index e920545..1702ee7 100644 (file)
 #include <atk/atk.h>
 #include <droute/droute.h>
 
-#include "accessible-register.h"
-#include "accessible-marshaller.h"
-
 #include "common/bitarray.h"
 #include "common/spi-dbus.h"
 #include "common/spi-stateset.h"
 
+#include "accessible-register.h"
+#include "object.h"
+
 typedef struct _MatchRulePrivate MatchRulePrivate;
 struct _MatchRulePrivate
 {
@@ -762,8 +762,7 @@ return_and_free_list (DBusMessage * message, GList * ls)
     goto oom;
   for (item = ls; item; item = g_list_next (item))
     {
-      spi_dbus_append_name_and_path (message, &iter_array,
-                                     ATK_OBJECT (item->data), TRUE, FALSE);
+      spi_object_append_reference (&iter_array, ATK_OBJECT (item->data));
     }
   if (!dbus_message_iter_close_container (&iter, &iter_array))
     goto oom;
@@ -871,7 +870,7 @@ GetMatchesInOrder (DBusMessage * message,
 
   ls = g_list_append (ls, current_object);
 
-  obj = atk_dbus_path_to_object (dbus_message_get_path (message));
+  obj = ATK_OBJECT(spi_register_path_to_object (spi_global_register, dbus_message_get_path (message)));
 
   kount = inorder (obj, mrp, ls, 0, count,
                    current_object, TRUE, NULL, traverse);
@@ -903,7 +902,7 @@ GetMatchesInBackOrder (DBusMessage * message,
 
   ls = g_list_append (ls, current_object);
 
-  collection = atk_dbus_path_to_object (dbus_message_get_path (message));
+  collection = ATK_OBJECT(spi_register_path_to_object (spi_global_register, dbus_message_get_path (message)));
 
   kount = sort_order_rev_canonical (mrp, ls, 0, count, current_object,
                                     FALSE, collection);
@@ -933,13 +932,13 @@ GetMatchesTo (DBusMessage * message,
 
   if (recurse)
     {
-      obj = atk_object_get_parent (current_object);
+      obj = ATK_OBJECT (atk_object_get_parent (current_object));
       kount = query_exec (mrp, sortby, ls, 0, count,
                           obj, 0, TRUE, current_object, TRUE, traverse);
     }
   else
     {
-      obj = atk_dbus_path_to_object (dbus_message_get_path (message));
+      obj = ATK_OBJECT (spi_register_path_to_object (spi_global_register, dbus_message_get_path (message)));
       kount = query_exec (mrp, sortby, ls, 0, count,
                           obj, 0, TRUE, current_object, TRUE, traverse);
 
@@ -978,7 +977,7 @@ impl_GetMatchesFrom (DBusConnection * bus, DBusMessage * message,
 
   dbus_message_iter_init (message, &iter);
   dbus_message_iter_get_basic (&iter, &current_object_path);
-  current_object = atk_dbus_path_to_object (current_object_path);
+  current_object = ATK_OBJECT (spi_register_path_to_object (spi_global_register, current_object_path));
   if (!current_object)
     {
       // TODO: object-not-found error
@@ -1042,7 +1041,7 @@ impl_GetMatchesTo (DBusConnection * bus, DBusMessage * message,
 
   dbus_message_iter_init (message, &iter);
   dbus_message_iter_get_basic (&iter, &current_object_path);
-  current_object = atk_dbus_path_to_object (current_object_path);
+  current_object = ATK_OBJECT (spi_register_path_to_object (spi_global_register, current_object_path));
   if (!current_object)
     {
       // TODO: object-not-found error
@@ -1086,7 +1085,7 @@ impl_GetMatchesTo (DBusConnection * bus, DBusMessage * message,
 static DBusMessage *
 impl_GetMatches (DBusConnection * bus, DBusMessage * message, void *user_data)
 {
-  AtkObject *obj = atk_dbus_path_to_object (dbus_message_get_path (message));
+  AtkObject *obj = ATK_OBJECT (spi_register_path_to_object (spi_global_register, dbus_message_get_path (message)));
   DBusMessageIter iter;
   MatchRulePrivate rule;
   dbus_uint32_t sortby;
index 40f8360..a3810de 100644 (file)
@@ -25,8 +25,8 @@
 #include <atk/atk.h>
 #include <droute/droute.h>
 
-#include "accessible-marshaller.h"
 #include "common/spi-dbus.h"
+#include "object.h"
 
 static DBusMessage *
 impl_contains (DBusConnection * bus, DBusMessage * message, void *user_data)
@@ -82,7 +82,7 @@ impl_GetAccessibleAtPoint (DBusConnection * bus, DBusMessage * message,
   child =
     atk_component_ref_accessible_at_point (component, x, y,
                                            (AtkCoordType) coord_type);
-  return spi_dbus_return_object (message, child, TRUE, TRUE);
+  return spi_object_return_reference (message, child);
 }
 
 static DBusMessage *
index de83a0d..dc3f628 100644 (file)
@@ -26,8 +26,7 @@
 #include <droute/droute.h>
 
 #include "common/spi-dbus.h"
-
-#include "accessible-marshaller.h"
+#include "object.h"
 
 static DBusMessage *
 impl_GetLocale (DBusConnection * bus, DBusMessage * message, void *user_data)
index 75521ed..732ab2b 100644 (file)
@@ -25,8 +25,8 @@
 #include <atk/atk.h>
 #include <droute/droute.h>
 
-#include "accessible-marshaller.h"
 #include "common/spi-dbus.h"
+#include "object.h"
 
 static AtkHyperlink *
 get_hyperlink (void *user_data)
@@ -80,8 +80,7 @@ impl_GetObject (DBusConnection * bus, DBusMessage * message, void *user_data)
       return droute_invalid_arguments_error (message);
     }
   atk_object = atk_hyperlink_get_object (link, i);
-  return spi_dbus_return_sub_object (message, G_OBJECT (atk_object),
-                                     G_OBJECT (link), FALSE);
+  return spi_object_return_reference (message, atk_object);
 }
 
 static DBusMessage *
index 082dde3..0bb4060 100644 (file)
@@ -26,7 +26,7 @@
 #include <droute/droute.h>
 
 #include "common/spi-dbus.h"
-#include "accessible-marshaller.h"
+#include "object.h"
 
 static DBusMessage *
 impl_GetNLinks (DBusConnection * bus, DBusMessage * message, void *user_data)
@@ -64,8 +64,7 @@ impl_GetLink (DBusConnection * bus, DBusMessage * message, void *user_data)
       return droute_invalid_arguments_error (message);
     }
   link = atk_hypertext_get_link (hypertext, linkIndex);
-  return spi_dbus_return_hyperlink (message, link, ATK_OBJECT (hypertext),
-                                    TRUE);
+  return spi_object_return_reference (message, ATK_OBJECT (hypertext));
 }
 
 static DBusMessage *
index 1ed7b24..c2e00b0 100644 (file)
@@ -26,6 +26,7 @@
 #include <droute/droute.h>
 
 #include "common/spi-dbus.h"
+#include "object.h"
 
 static dbus_bool_t
 impl_get_ImageDescription (DBusMessageIter * iter, void *user_data)
index 4516b52..02e28f2 100644 (file)
@@ -26,7 +26,7 @@
 #include <droute/droute.h>
 
 #include "common/spi-dbus.h"
-#include "accessible-marshaller.h"
+#include "object.h"
 
 static dbus_bool_t
 impl_get_NSelectedChildren (DBusMessageIter * iter, void *user_data)
@@ -66,7 +66,7 @@ impl_GetSelectedChild (DBusConnection * bus, DBusMessage * message,
       return droute_invalid_arguments_error (message);
     }
   atk_object = atk_selection_ref_selection (selection, selectedChildIndex);
-  return spi_dbus_return_object (message, atk_object, TRUE, TRUE);
+  return spi_object_return_reference (message, atk_object);
 }
 
 static DBusMessage *
index 212004a..b61caa2 100644 (file)
@@ -25,8 +25,8 @@
 #include <atk/atk.h>
 #include <droute/droute.h>
 
-#include "accessible-marshaller.h"
 #include "common/spi-dbus.h"
+#include "object.h"
 
 static dbus_bool_t
 impl_get_NRows (DBusMessageIter * iter, void *user_data)
@@ -49,8 +49,8 @@ impl_get_Caption (DBusMessageIter * iter, void *user_data)
 {
   AtkTable *table = (AtkTable *) user_data;
   g_return_val_if_fail (ATK_IS_TABLE (user_data), FALSE);
-  return spi_dbus_return_v_object (iter, atk_table_get_caption (table),
-                                   FALSE);
+  spi_object_append_v_reference (iter, atk_table_get_caption (table));
+  return TRUE;
 }
 
 static dbus_bool_t
@@ -58,8 +58,8 @@ impl_get_Summary (DBusMessageIter * iter, void *user_data)
 {
   AtkTable *table = (AtkTable *) user_data;
   g_return_val_if_fail (ATK_IS_TABLE (user_data), FALSE);
-  return spi_dbus_return_v_object (iter, atk_table_get_summary (table),
-                                   FALSE);
+  spi_object_append_v_reference (iter, atk_table_get_summary (table));
+  return TRUE;
 }
 
 static dbus_bool_t
@@ -107,7 +107,7 @@ impl_GetAccessibleAt (DBusConnection * bus, DBusMessage * message,
       return droute_invalid_arguments_error (message);
     }
   obj = atk_table_ref_at (table, row, column);
-  return spi_dbus_return_object (message, obj, TRUE, TRUE);
+  return spi_object_return_reference (message, obj);
 }
 
 static DBusMessage *
@@ -331,7 +331,7 @@ impl_GetRowHeader (DBusConnection * bus, DBusMessage * message,
     }
   obj = atk_table_get_row_header (table, row);
   obj = atk_table_get_row_header (table, row);
-  return spi_dbus_return_object (message, obj, TRUE, FALSE);
+  return spi_object_return_reference (message, obj);
 }
 
 static DBusMessage *
@@ -353,7 +353,7 @@ impl_GetColumnHeader (DBusConnection * bus, DBusMessage * message,
     }
   obj = atk_table_get_column_header (table, column);
   obj = atk_table_get_column_header (table, column);
-  return spi_dbus_return_object (message, obj, TRUE, FALSE);
+  return spi_object_return_reference (message, obj);
 }
 
 static DBusMessage *
index a15f9c7..dc20a80 100644 (file)
@@ -28,8 +28,7 @@
 #include <droute/droute.h>
 
 #include "common/spi-dbus.h"
-
-#include "accessible-marshaller.h"
+#include "object.h"
 
 static dbus_bool_t
 impl_get_CharacterCount (DBusMessageIter * iter, void *user_data)
@@ -735,7 +734,7 @@ impl_GetAttributeRun (DBusConnection * bus, DBusMessage * message,
   dbus_int32_t startOffset, endOffset;
   gint intstart_offset = 0, intend_offset = 0;
   DBusMessage *reply;
-  AtkAttributeSet *attributes, *default_attributes = NULL;
+  AtkAttributeSet *attributes = NULL;
   AtkAttribute *attr = NULL;
   DBusMessageIter iter, iterArray;
 
@@ -753,20 +752,18 @@ impl_GetAttributeRun (DBusConnection * bus, DBusMessage * message,
     atk_text_get_run_attributes (text, offset, &intstart_offset,
                                  &intend_offset);
 
+  if (includeDefaults)
+    {
+      attributes = g_slist_concat (attributes,
+                                   atk_text_get_default_attributes (text));
+    }
+
   reply = dbus_message_new_method_return (message);
   if (!reply)
     return NULL;
 
   dbus_message_iter_init_append (reply, &iter);
-  dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{ss}",
-                                    &iterArray);
-  spi_atk_append_attribute_set_inner (&iterArray, attributes);
-  if (includeDefaults)
-    {
-      default_attributes = atk_text_get_default_attributes (text);
-      spi_atk_append_attribute_set_inner (&iterArray, default_attributes);
-    }
-  dbus_message_iter_close_container (&iter, &iterArray);
+  spi_object_append_attribute_set (&iter, attributes);
 
   startOffset = intstart_offset;
   endOffset = intend_offset;
@@ -774,8 +771,6 @@ impl_GetAttributeRun (DBusConnection * bus, DBusMessage * message,
   dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &endOffset);
 
   atk_attribute_set_free (attributes);
-  if (default_attributes)
-    atk_attribute_set_free (default_attributes);
 
   return reply;
 }
diff --git a/atk-adaptor/adaptors/tree-adaptor.c b/atk-adaptor/adaptors/tree-adaptor.c
deleted file mode 100644 (file)
index 89a065f..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * AT-SPI - Assistive Technology Service Provider Interface
- * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
- *
- * Copyright 2008 Novell, Inc.
- * Copyright 2001, 2002 Sun Microsystems Inc.,
- * Copyright 2001, 2002 Ximian, Inc.
- * Copyright 2008, 2009 Codethink Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <string.h>
-
-#include <atk/atk.h>
-#include <droute/droute.h>
-
-#include "bridge.h"
-#include "accessible-register.h"
-#include "accessible-marshaller.h"
-#include "common/spi-dbus.h"
-
-/*---------------------------------------------------------------------------*/
-
-/* For use as a GHFunc */
-static void
-append_accessible_hf (gpointer key, gpointer obj_data, gpointer data)
-{
-  /* Make sure it isn't a hyperlink */
-  if (ATK_IS_OBJECT (obj_data))
-    spi_atk_append_accessible (ATK_OBJECT (obj_data), data);
-}
-
-/*---------------------------------------------------------------------------*/
-
-void
-spi_emit_cache_removal (guint ref, DBusConnection * bus)
-{
-  DBusMessage *message;
-
-  if ((message = dbus_message_new_signal ("/org/freedesktop/atspi/tree",
-                                          SPI_DBUS_INTERFACE_TREE,
-                                          "RemoveAccessible")))
-    {
-      DBusMessageIter iter;
-      gchar *path;
-
-      dbus_message_iter_init_append (message, &iter);
-
-      path = atk_dbus_ref_to_path (ref);
-      dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &path);
-
-      dbus_connection_send (bus, message, NULL);
-
-      dbus_message_unref (message);
-    }
-}
-
-void
-spi_emit_cache_update (AtkObject * accessible, DBusConnection * bus)
-{
-  DBusMessage *message;
-
-  if ((message = dbus_message_new_signal ("/org/freedesktop/atspi/tree",
-                                          SPI_DBUS_INTERFACE_TREE,
-                                          "UpdateAccessible")))
-    {
-      DBusMessageIter iter;
-
-      dbus_message_iter_init_append (message, &iter);
-      spi_atk_append_accessible (accessible, &iter);
-
-      dbus_connection_send (bus, message, NULL);
-
-      dbus_message_unref (message);
-    }
-}
-
-
-/*---------------------------------------------------------------------------*/
-
-static DBusMessage *
-impl_GetRoot (DBusConnection * bus, DBusMessage * message, void *user_data)
-{
-  AtkObject *root = atk_get_root ();
-  char *path;
-  DBusMessage *reply;
-  gchar *errmsg;
-
-  if (!root)
-    {
-      reply = dbus_message_new_error (message,
-                                      DBUS_ERROR_FAILED,
-                                      "No root accessible available");
-    }
-  path = atk_dbus_object_to_path (root, FALSE);
-  if (!path)
-    {
-      reply = dbus_message_new_error (message,
-                                      DBUS_ERROR_FAILED,
-                                      "No root accessible available");
-    }
-  reply = dbus_message_new_method_return (message);
-  dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path,
-                            DBUS_TYPE_INVALID);
-  g_free (path);
-  return reply;
-}
-
-/*---------------------------------------------------------------------------*/
-
-static DBusMessage *
-impl_GetTree (DBusConnection * bus, DBusMessage * message, void *user_data)
-{
-  DBusMessage *reply;
-  DBusMessageIter iter, iter_array;
-
-  reply = dbus_message_new_method_return (message);
-
-  dbus_message_iter_init_append (reply, &iter);
-  dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
-                                    "(o(so)a(so)assusau)", &iter_array);
-  atk_dbus_foreach_registered (append_accessible_hf, &iter_array);
-  dbus_message_iter_close_container (&iter, &iter_array);
-  return reply;
-}
-
-/*---------------------------------------------------------------------------*/
-
-static DRouteMethod methods[] = {
-  {impl_GetRoot, "GetRoot"},
-  {impl_GetTree, "GetTree"},
-  {NULL, NULL}
-};
-
-void
-spi_initialize_tree (DRoutePath * path)
-{
-  droute_path_add_interface (path, SPI_DBUS_INTERFACE_TREE, methods, NULL);
-};
-
-/*END------------------------------------------------------------------------*/
index 00ead5c..b283506 100644 (file)
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <string.h>
 #include <atk/atk.h>
 
 #include <droute/droute.h>
 
 #include "bridge.h"
 #include "event.h"
-#include "accessible-register.h"
 #include "adaptors.h"
 
+#include "accessible-register.h"
+#include "accessible-leasing.h"
+#include "accessible-cache.h"
+
 #include "common/spi-dbus.h"
 
 /*
@@ -51,7 +55,7 @@
 
 /*---------------------------------------------------------------------------*/
 
-SpiAppData *atk_adaptor_app_data = NULL;
+SpiBridge *spi_global_app_data = NULL;
 
 static const AtkMisc *atk_misc = NULL;
 
@@ -151,7 +155,7 @@ spi_atk_bridge_get_bus (void)
       else
         {
           if (!dbus_bus_register (bus, &error))
-            g_error ("AT-SPI: Couldn't register with bus: %s\n");
+            g_error ("AT-SPI: Couldn't register with bus: %s\n", error.message);
         }
     }
 
@@ -161,7 +165,7 @@ spi_atk_bridge_get_bus (void)
 /*---------------------------------------------------------------------------*/
 
 static void
-register_application (SpiAppData * app)
+register_application (SpiBridge * app)
 {
   DBusMessage *message;
   DBusMessageIter iter;
@@ -192,7 +196,7 @@ register_application (SpiAppData * app)
 /*---------------------------------------------------------------------------*/
 
 static void
-deregister_application (SpiAppData * app)
+deregister_application (SpiBridge * app)
 {
   DBusMessage *message;
   DBusMessageIter iter;
@@ -221,17 +225,17 @@ deregister_application (SpiAppData * app)
 static void
 exit_func (void)
 {
-  if (!atk_adaptor_app_data)
+  if (!spi_global_app_data)
     {
       return;
     }
 
   spi_atk_tidy_windows ();
   spi_atk_deregister_event_listeners ();
-  deregister_application (atk_adaptor_app_data);
+  deregister_application (spi_global_app_data);
 
-  g_free (atk_adaptor_app_data);
-  atk_adaptor_app_data = NULL;
+  g_free (spi_global_app_data);
+  spi_global_app_data = NULL;
 
   /* Not currently creating an XDisplay */
 #if 0
@@ -249,7 +253,7 @@ static AtkSocketClass *socket_class;
 static gchar *
 get_plug_id (AtkPlug * plug)
 {
-  const char *uname = dbus_bus_get_unique_name (atk_adaptor_app_data->bus);
+  const char *uname = dbus_bus_get_unique_name (spi_global_app_data->bus);
   gchar *path;
   GString *str = g_string_new (NULL);
 
@@ -352,24 +356,24 @@ adaptor_init (gint * argc, gchar ** argv[])
     g_warning ("AT-SPI Option parsing failed: %s\n", err->message);
 
   /* Allocate global data and do ATK initializations */
-  atk_adaptor_app_data = g_new0 (SpiAppData, 1);
+  spi_global_app_data = g_new0 (SpiBridge, 1);
   atk_misc = atk_misc_get_instance ();
-  atk_adaptor_app_data->root = root;
+  spi_global_app_data->root = root;
 
   /* Set up D-Bus connection and register bus name */
   dbus_error_init (&error);
-  atk_adaptor_app_data->bus = spi_atk_bridge_get_bus ();
-  if (!atk_adaptor_app_data->bus)
+  spi_global_app_data->bus = spi_atk_bridge_get_bus ();
+  if (!spi_global_app_data->bus)
     {
-      g_free (atk_adaptor_app_data);
-      atk_adaptor_app_data = NULL;
+      g_free (spi_global_app_data);
+      spi_global_app_data = NULL;
       return 0;
     }
 
   if (atspi_dbus_name != NULL)
     {
       if (dbus_bus_request_name
-          (atk_adaptor_app_data->bus, atspi_dbus_name, 0, &error))
+          (spi_global_app_data->bus, atspi_dbus_name, 0, &error))
         {
           g_print ("AT-SPI Recieved D-Bus name - %s\n", atspi_dbus_name);
         }
@@ -381,7 +385,7 @@ adaptor_init (gint * argc, gchar ** argv[])
         }
     }
 
-  dbus_connection_setup_with_g_main (atk_adaptor_app_data->bus,
+  dbus_connection_setup_with_g_main (spi_global_app_data->bus,
                                      g_main_context_default ());
 
   /* Get D-Bus introspection directory */
@@ -390,21 +394,29 @@ adaptor_init (gint * argc, gchar ** argv[])
     introspection_directory = ATSPI_INTROSPECTION_PATH;
 
   /* Register droute for routing AT-SPI messages */
-  atk_adaptor_app_data->droute =
-    droute_new (atk_adaptor_app_data->bus, introspection_directory);
+  spi_global_app_data->droute =
+    droute_new (spi_global_app_data->bus, introspection_directory);
 
-  treepath = droute_add_one (atk_adaptor_app_data->droute,
-                             "/org/freedesktop/atspi/tree", NULL);
+  treepath = droute_add_one (spi_global_app_data->droute,
+                             "/org/at_spi/cache", NULL);
 
-  accpath = droute_add_many (atk_adaptor_app_data->droute,
-                             "/org/freedesktop/atspi/accessible",
+  accpath = droute_add_many (spi_global_app_data->droute,
+                             "/org/at_spi/accessible",
                              NULL,
                              (DRouteGetDatumFunction)
-                             atk_dbus_path_to_gobject);
+                             spi_global_register_path_to_object);
 
-  /* Register all interfaces with droute and set up application accessible db */
-  spi_initialize_tree (treepath);
+  /* 
+   * Create the leasing, register and cache objects.
+   * The order is important here, the cache depends on the
+   * register object.
+   */
+  spi_global_register = g_object_new (SPI_REGISTER_TYPE, NULL);
+  spi_global_leasing  = g_object_new (SPI_LEASING_TYPE, NULL);
+  spi_global_cache    = g_object_new (SPI_CACHE_TYPE, NULL);
 
+  /* Register all interfaces with droute and set up application accessible db */
+  spi_initialize_cache (treepath);
   spi_initialize_accessible (accpath);
   spi_initialize_application (accpath);
   spi_initialize_action (accpath);
@@ -420,9 +432,6 @@ adaptor_init (gint * argc, gchar ** argv[])
   spi_initialize_text (accpath);
   spi_initialize_value (accpath);
 
-  /* Initialize the AtkObject registration */
-  atk_dbus_initialize (atk_adaptor_app_data->root);
-
   /* Register methods to send D-Bus signals on certain ATK events */
   spi_atk_register_event_listeners ();
 
@@ -433,7 +442,7 @@ adaptor_init (gint * argc, gchar ** argv[])
 
   /* Register this app by sending a signal out to AT-SPI registry daemon */
   if (!atspi_no_register)
-    register_application (atk_adaptor_app_data);
+    register_application (spi_global_app_data);
 
   g_atexit (exit_func);
 
index 44315f1..2a95fcd 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Copyright 2001, 2002, 2003 Sun Microsystems Inc.,
  * Copyright 2001, 2002, 2003 Ximian, Inc.
- * Copyright 2008, 2009 Codethink Ltd.
+ * Copyright 2008, 2009, 2010 Codethink Ltd.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 #include <atk/atk.h>
 #include <droute/droute.h>
 
-typedef struct _SpiAppData SpiAppData;
-struct _SpiAppData
+typedef struct _SpiBridge SpiBridge;
+typedef struct _SpiBridgeClass SpiBridgeClass;
+
+G_BEGIN_DECLS
+
+struct _SpiBridge
 {
+  GObject parent;
+
   AtkObject *root;
 
   DBusConnection *bus;
-  DRouteContext *droute;
+  DRouteContext  *droute;
+
+/*
+  SpiRegister *reg;
+  SpiCache    *cache;
+  SpiLeasing  *leasing;
+*/
 };
 
-extern SpiAppData *atk_adaptor_app_data;
+extern SpiBridge *spi_global_app_data;
+
+G_END_DECLS
 
 #endif /* BRIDGE_H */
index 687fc79..e97046b 100644 (file)
@@ -73,6 +73,14 @@ send_and_allow_reentry (DBusConnection * bus, DBusMessage * message)
   return reply;
 }
 
+/*---------------------------------------------------------------------------*/
+
+/*
+ * Functionality related to sending device events from the application.
+ *
+ * This is used for forwarding key events on to the registry daemon.
+ */
+
 static gboolean
 Accessibility_DeviceEventController_NotifyListenersSync (const
                                                          Accessibility_DeviceEvent
@@ -92,7 +100,7 @@ Accessibility_DeviceEventController_NotifyListenersSync (const
   if (spi_dbus_marshal_deviceEvent (message, key_event))
     {
       DBusMessage *reply =
-        send_and_allow_reentry (atk_adaptor_app_data->bus, message);
+        send_and_allow_reentry (spi_global_app_data->bus, message);
       if (reply)
         {
           DBusError error;
@@ -169,22 +177,10 @@ spi_atk_bridge_key_listener (AtkKeyEventStruct * event, gpointer data)
   return result;
 }
 
-
 /*---------------------------------------------------------------------------*/
 
-/*
- * Emits an AT-SPI event.
- * AT-SPI events names are split into three parts:
- * class:major:minor
- * This is mapped onto D-Bus events as:
- * D-Bus Interface:Signal Name:Detail argument
- *
- * Marshals a basic type into the 'any_data' attribute of
- * the AT-SPI event.
- */
-
 static gchar *
-DBusSignalName (const gchar * s)
+convert_signal_name (const gchar * s)
 {
   gchar *ret = g_strdup (s);
   gchar *t;
@@ -200,103 +196,122 @@ DBusSignalName (const gchar * s)
   return ret;
 }
 
+static const void *
+replace_null (const gint type,
+              const void *val)
+{
+  switch (type)
+    {
+      case DBUS_TYPE_STRING:
+      case DBUS_TYPE_OBJECT_PATH:
+          if (!val)
+             return "";
+          else
+             return val;
+      default:
+          return val;
+    }
+}
+
 static void
-emit (AtkObject * accessible,
-      const char *klass,
-      const char *major,
-      const char *minor,
-      dbus_int32_t detail1,
-      dbus_int32_t detail2, const char *type, const void *val)
+append_basic (DBusMessageIter *iter,
+              const char *type,
+              const void *val)
 {
-  gchar *path;
-  gchar *cname;
+  DBusMessageIter sub;
 
-  /* TODO this is a hack, used becuase child-added events are not guaranteed.
-   * On recieving an event from a non-registered object we check if it can be safely 
-   * registered before sending the event.
-   */
-  path = atk_dbus_object_attempt_registration (accessible);
+  dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, type, &sub);
 
-  /* Tough decision here
-   * We won't send events from accessible
-   * objects that have not yet been added to the accessible tree.
-   */
-  if (path == NULL)
-    {
-#ifdef SPI_ATK_DEBUG
-      g_debug ("AT-SPI: Event recieved from non-registered object");
-#endif
-      return;
-    }
+    val = replace_null ((int) *type, val);
+    dbus_message_iter_append_basic(&sub, (int) *type, &val);
 
-  cname = DBusSignalName (major);
-  spi_dbus_emit_signal (atk_adaptor_app_data->bus, path, klass, cname, minor,
-                        detail1, detail2, type, val);
-  g_free (cname);
-  g_free (path);
+  dbus_message_iter_close_container(iter, &sub);
 }
 
-/*---------------------------------------------------------------------------*/
-
-/*
- * Emits an AT-SPI event, marshalling a BoundingBox structure into the 
- * 'any_data' variant of the event.
- */
 static void
-emit_rect (AtkObject * accessible,
-           const char *klass,
-           const char *major, const char *minor, AtkRectangle * rect)
+append_rect (DBusMessageIter *iter,
+             const char *type,
+             const void *val)
 {
-  DBusMessage *sig;
-  DBusMessageIter iter, variant, sub;
-  gchar *path, *cname;
-  dbus_int32_t dummy = 0;
+  DBusMessageIter variant, sub;
+  const AtkRectangle *rect = (const AtkRectangle *) val;
 
-  path = atk_dbus_object_to_path (accessible, FALSE);
+  dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, type, &variant);
 
-  /* Tough decision here
-   * We won't send events from accessible
-   * objects that have not yet been added to the accessible tree.
-   */
-  if (path == NULL)
-    return;
+    dbus_message_iter_open_container (&variant, DBUS_TYPE_STRUCT, NULL, &sub);
+
+      dbus_message_iter_append_basic (&sub, DBUS_TYPE_INT32, &(rect->x));
+      dbus_message_iter_append_basic (&sub, DBUS_TYPE_INT32, &(rect->y));
+      dbus_message_iter_append_basic (&sub, DBUS_TYPE_INT32, &(rect->width));
+      dbus_message_iter_append_basic (&sub, DBUS_TYPE_INT32, &(rect->height));
 
-  if (!klass)
-    klass = "";
-  if (!major)
-    major = "";
-  if (!minor)
-    minor = "";
+    dbus_message_iter_close_container (&variant, &sub);
+
+  dbus_message_iter_close_container(iter, &variant);
+}
+
+static void
+append_object (DBusMessageIter *iter,
+               const char *type,
+               const void *val)
+{
+  spi_object_append_v_reference (iter, ATK_OBJECT (val));
+}
+
+/*
+ * Emits an AT-SPI event.
+ * AT-SPI events names are split into three parts:
+ * class:major:minor
+ * This is mapped onto D-Bus events as:
+ * D-Bus Interface:Signal Name:Detail argument
+ *
+ * Marshals a basic type into the 'any_data' attribute of
+ * the AT-SPI event.
+ */
+static void 
+emit_event (AtkObject  *obj,
+            const char *klass,
+            const char *major,
+            const char *minor,
+            dbus_int32_t detail1,
+            dbus_int32_t detail2,
+            const char *type,
+            const void *val,
+            void (*append_variant) (DBusMessageIter *, const char *, const void *))
+{
+  DBusConnection *bus = spi_global_app_data->bus;
+  const char *path =  spi_register_object_to_path (spi_global_register,
+                                                   G_OBJECT (obj));
+
+  gchar *cname, *t;
+  DBusMessage *sig;
+  DBusMessageIter iter;
+  
+  if (!klass) klass = "";
+  if (!major) major = "";
+  if (!minor) minor = "";
+  if (!type) type = "u";
 
   /*
    * This is very annoying, but as '-' isn't a legal signal
    * name in D-Bus (Why not??!?) The names need converting
    * on this side, and again on the client side.
    */
-  cname = DBusSignalName (major);
-
-  sig = dbus_message_new_signal (path, klass, cname);
-  g_free (path);
-  g_free (cname);
-
-  dbus_message_iter_init_append (sig, &iter);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &minor);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &dummy);
-  dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &dummy);
-
-  dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT, "(iiii)",
-                                    &variant);
-  dbus_message_iter_open_container (&variant, DBUS_TYPE_STRUCT, NULL, &sub);
-  dbus_message_iter_append_basic (&sub, DBUS_TYPE_INT32, &(rect->x));
-  dbus_message_iter_append_basic (&sub, DBUS_TYPE_INT32, &(rect->y));
-  dbus_message_iter_append_basic (&sub, DBUS_TYPE_INT32, &(rect->width));
-  dbus_message_iter_append_basic (&sub, DBUS_TYPE_INT32, &(rect->height));
-  dbus_message_iter_close_container (&variant, &sub);
-  dbus_message_iter_close_container (&iter, &variant);
-
-  dbus_connection_send (atk_adaptor_app_data->bus, sig, NULL);
-
-  dbus_message_unref (sig);
+  cname = g_strdup(major);
+  while ((t = strchr(cname, '-')) != NULL) *t = '_';
+  sig = dbus_message_new_signal(path, klass, cname);
+  g_free(cname);
+
+  dbus_message_iter_init_append(sig, &iter);
+
+  dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &minor);
+  dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &detail1);
+  dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &detail2);
+
+  append_variant (&iter, type, val);
+
+  dbus_connection_send(bus, sig, NULL);
+  dbus_message_unref(sig);
 }
 
 /*---------------------------------------------------------------------------*/
@@ -308,8 +323,8 @@ emit_rect (AtkObject * accessible,
 static void
 focus_tracker (AtkObject * accessible)
 {
-  emit (accessible, ITF_EVENT_FOCUS, "focus", "", 0, 0,
-        DBUS_TYPE_INT32_AS_STRING, 0);
+  emit_event (accessible, ITF_EVENT_FOCUS, "focus", "", 0, 0,
+              DBUS_TYPE_INT32_AS_STRING, 0, append_basic);
 }
 
 /*---------------------------------------------------------------------------*/
@@ -335,75 +350,85 @@ property_event_listener (GSignalInvocationHint * signal_hint,
   const gchar *pname = NULL;
 
   AtkObject *otemp;
-  const gchar *stemp;
+  const gchar *s1, s2;
   gint i;
 
   accessible = g_value_get_object (&param_values[0]);
   values = (AtkPropertyValues *) g_value_get_pointer (&param_values[1]);
 
   pname = values[0].property_name;
-  if (strcmp (pname, "accessible-name") == 0 ||
-      strcmp (pname, "accessible-description") == 0 ||
-      strcmp (pname, "accessible-role") == 0 ||
-      strcmp (pname, "accessible-parent") == 0)
-    {
-      return TRUE;
-    }
 
   /* TODO Could improve this control statement by matching
    * on only the end of the signal names,
    */
+  if (strcmp (pname, "accessible-name") == 0)
+    {
+      s1 = atk_object_get_name (accessible);
+      if (s1 != NULL)
+        emit_event (accessible, ITF_EVENT_OBJECT, PCHANGE, pname, 0, 0,
+                    DBUS_TYPE_STRING_AS_STRING, s1, append_basic);
+    }
+  if (strcmp (pname, "accessible-description") == 0)
+    {
+      s1 = atk_object_get_description (accessible);
+      if (s1 != NULL)
+        emit_event (accessible, ITF_EVENT_OBJECT, PCHANGE, pname, 0, 0,
+                    DBUS_TYPE_STRING_AS_STRING, s1, append_basic);
+    }
+  if (strcmp (pname, "accessible-parent") == 0)
+    {
+      otemp = atk_object_get_parent (accessible);
+      if (otemp != NULL)
+        emit_event (accessible, ITF_EVENT_OBJECT, PCHANGE, pname, 0, 0,
+                    "(so)", otemp, append_object);
+    }
   if (strcmp (pname, "accessible-table-summary") == 0)
     {
       otemp = atk_table_get_summary (ATK_TABLE (accessible));
-      stemp = atk_dbus_object_to_path (otemp, FALSE);
-      if (stemp != NULL)
-        emit (accessible, ITF_EVENT_OBJECT, PCHANGE, pname, 0, 0,
-              DBUS_TYPE_OBJECT_PATH_AS_STRING, stemp);
+      if (otemp != NULL)
+        emit_event (accessible, ITF_EVENT_OBJECT, PCHANGE, pname, 0, 0,
+                    "(so)", otemp, append_object);
     }
   else if (strcmp (pname, "accessible-table-column-header") == 0)
     {
       i = g_value_get_int (&(values->new_value));
       otemp = atk_table_get_column_header (ATK_TABLE (accessible), i);
-      stemp = atk_dbus_object_to_path (otemp, FALSE);
-      if (stemp != NULL)
-        emit (accessible, ITF_EVENT_OBJECT, PCHANGE, pname, 0, 0,
-              DBUS_TYPE_OBJECT_PATH_AS_STRING, stemp);
+      if (otemp != NULL)
+        emit_event (accessible, ITF_EVENT_OBJECT, PCHANGE, pname, 0, 0,
+                    "(so)", otemp, append_object);
     }
   else if (strcmp (pname, "accessible-table-row-header") == 0)
     {
       i = g_value_get_int (&(values->new_value));
       otemp = atk_table_get_row_header (ATK_TABLE (accessible), i);
-      stemp = atk_dbus_object_to_path (otemp, FALSE);
-      if (stemp != NULL)
-        emit (accessible, ITF_EVENT_OBJECT, PCHANGE, pname, 0, 0,
-              DBUS_TYPE_OBJECT_PATH_AS_STRING, stemp);
+      if (otemp != NULL)
+        emit_event (accessible, ITF_EVENT_OBJECT, PCHANGE, pname, 0, 0,
+                    "(so)", otemp, append_object);
     }
   else if (strcmp (pname, "accessible-table-row-description") == 0)
     {
       i = g_value_get_int (&(values->new_value));
-      stemp = atk_table_get_row_description (ATK_TABLE (accessible), i);
-      emit (accessible, ITF_EVENT_OBJECT, PCHANGE, pname, 0, 0,
-            DBUS_TYPE_STRING_AS_STRING, stemp);
+      s1 = atk_table_get_row_description (ATK_TABLE (accessible), i);
+      emit_event (accessible, ITF_EVENT_OBJECT, PCHANGE, pname, 0, 0,
+                  DBUS_TYPE_STRING_AS_STRING, s1, append_basic);
     }
   else if (strcmp (pname, "accessible-table-column-description") == 0)
     {
       i = g_value_get_int (&(values->new_value));
-      stemp = atk_table_get_column_description (ATK_TABLE (accessible), i);
-      emit (accessible, ITF_EVENT_OBJECT, PCHANGE, pname, 0, 0,
-            DBUS_TYPE_STRING_AS_STRING, stemp);
+      s1 = atk_table_get_column_description (ATK_TABLE (accessible), i);
+      emit_event (accessible, ITF_EVENT_OBJECT, PCHANGE, pname, 0, 0,
+                  DBUS_TYPE_STRING_AS_STRING, s1, append_basic);
     }
   else if (strcmp (pname, "accessible-table-caption-object") == 0)
     {
       otemp = atk_table_get_caption (ATK_TABLE (accessible));
-      stemp = atk_object_get_name (otemp);
-      emit (accessible, ITF_EVENT_OBJECT, PCHANGE, pname, 0, 0,
-            DBUS_TYPE_STRING_AS_STRING, stemp);
+      emit_event (accessible, ITF_EVENT_OBJECT, PCHANGE, pname, 0, 0,
+                  "(so)", otemp, append_object);
     }
   else
     {
-      emit (accessible, ITF_EVENT_OBJECT, PCHANGE, pname, 0, 0,
-            DBUS_TYPE_INT32_AS_STRING, 0);
+      emit_event (accessible, ITF_EVENT_OBJECT, PCHANGE, pname, 0, 0,
+            DBUS_TYPE_INT32_AS_STRING, 0, append_basic);
     }
   return TRUE;
 }
@@ -433,8 +458,8 @@ state_event_listener (GSignalInvocationHint * signal_hint,
    * This is because without reference counting defunct objects should be removed.
    */
   detail1 = (g_value_get_boolean (&param_values[2])) ? 1 : 0;
-  emit (accessible, ITF_EVENT_OBJECT, STATE_CHANGED, pname, detail1, 0,
-        DBUS_TYPE_INT32_AS_STRING, 0);
+  emit_event (accessible, ITF_EVENT_OBJECT, STATE_CHANGED, pname, detail1, 0,
+              DBUS_TYPE_INT32_AS_STRING, 0, append_basic);
   g_free (pname);
   return TRUE;
 }
@@ -466,8 +491,8 @@ window_event_listener (GSignalInvocationHint * signal_hint,
 
   accessible = ATK_OBJECT (g_value_get_object (&param_values[0]));
   s = atk_object_get_name (accessible);
-  emit (accessible, ITF_EVENT_WINDOW, name, "", 0, 0,
-        DBUS_TYPE_STRING_AS_STRING, s);
+  emit_event (accessible, ITF_EVENT_WINDOW, name, "", 0, 0,
+              DBUS_TYPE_STRING_AS_STRING, s, append_basic);
 
   return TRUE;
 }
@@ -496,8 +521,8 @@ document_event_listener (GSignalInvocationHint * signal_hint,
 
   accessible = ATK_OBJECT (g_value_get_object (&param_values[0]));
   s = atk_object_get_name (accessible);
-  emit (accessible, ITF_EVENT_DOCUMENT, name, "", 0, 0,
-        DBUS_TYPE_STRING_AS_STRING, s);
+  emit_event (accessible, ITF_EVENT_DOCUMENT, name, "", 0, 0,
+              DBUS_TYPE_STRING_AS_STRING, s, append_basic);
 
   return TRUE;
 }
@@ -524,9 +549,12 @@ bounds_event_listener (GSignalInvocationHint * signal_hint,
   accessible = ATK_OBJECT (g_value_get_object (&param_values[0]));
 
   if (G_VALUE_HOLDS_BOXED (param_values + 1))
+  {
     atk_rect = g_value_get_boxed (param_values + 1);
 
-  emit_rect (accessible, ITF_EVENT_OBJECT, name, "", atk_rect);
+    emit_event (accessible, ITF_EVENT_OBJECT, name, "", 0, 0,
+                "(iiii)", atk_rect, append_rect);
+  }
   return TRUE;
 }
 
@@ -558,15 +586,9 @@ active_descendant_event_listener (GSignalInvocationHint * signal_hint,
   minor = g_quark_to_string (signal_hint->detail);
 
   detail1 = atk_object_get_index_in_parent (child);
-  s = atk_dbus_object_to_path (child, FALSE);
-  if (s == NULL)
-    {
-      g_free (s);
-      return TRUE;
-    }
 
-  emit (accessible, ITF_EVENT_OBJECT, name, "", detail1, 0,
-        DBUS_TYPE_OBJECT_PATH_AS_STRING, s);
+  emit_event (accessible, ITF_EVENT_OBJECT, name, "", detail1, 0,
+              "(so)", child, append_object);
   g_free (s);
   return TRUE;
 }
@@ -597,8 +619,8 @@ link_selected_event_listener (GSignalInvocationHint * signal_hint,
   if (G_VALUE_TYPE (&param_values[1]) == G_TYPE_INT)
     detail1 = g_value_get_int (&param_values[1]);
 
-  emit (accessible, ITF_EVENT_OBJECT, name, minor, detail1, 0,
-        DBUS_TYPE_INT32_AS_STRING, 0);
+  emit_event (accessible, ITF_EVENT_OBJECT, name, minor, detail1, 0,
+              DBUS_TYPE_INT32_AS_STRING, 0, append_basic);
   return TRUE;
 }
 
@@ -635,8 +657,8 @@ text_changed_event_listener (GSignalInvocationHint * signal_hint,
   selected =
     atk_text_get_text (ATK_TEXT (accessible), detail1, detail1 + detail2);
 
-  emit (accessible, ITF_EVENT_OBJECT, name, minor, detail1, detail2,
-        DBUS_TYPE_STRING_AS_STRING, selected);
+  emit_event (accessible, ITF_EVENT_OBJECT, name, minor, detail1, detail2,
+              DBUS_TYPE_STRING_AS_STRING, selected, append_basic);
   return TRUE;
 }
 
@@ -670,8 +692,8 @@ text_selection_changed_event_listener (GSignalInvocationHint * signal_hint,
   if (G_VALUE_TYPE (&param_values[2]) == G_TYPE_INT)
     detail2 = g_value_get_int (&param_values[2]);
 
-  emit (accessible, ITF_EVENT_OBJECT, name, minor, detail1, detail2,
-        DBUS_TYPE_STRING_AS_STRING, "");
+  emit_event (accessible, ITF_EVENT_OBJECT, name, minor, detail1, detail2,
+              DBUS_TYPE_STRING_AS_STRING, "", append_basic);
   return TRUE;
 }
 
@@ -708,8 +730,8 @@ generic_event_listener (GSignalInvocationHint * signal_hint,
   if (n_param_values > 2 && G_VALUE_TYPE (&param_values[2]) == G_TYPE_INT)
     detail2 = g_value_get_int (&param_values[2]);
 
-  emit (accessible, ITF_EVENT_OBJECT, name, "", detail1, detail2,
-        DBUS_TYPE_INT32_AS_STRING, 0);
+  emit_event (accessible, ITF_EVENT_OBJECT, name, "", detail1, detail2,
+              DBUS_TYPE_INT32_AS_STRING, 0, append_basic);
   return TRUE;
 }
 
@@ -861,13 +883,13 @@ spi_atk_tidy_windows (void)
       name = atk_object_get_name (child);
       if (atk_state_set_contains_state (stateset, ATK_STATE_ACTIVE))
         {
-          emit (child, ITF_EVENT_WINDOW, "deactivate", NULL, 0, 0,
-                DBUS_TYPE_STRING_AS_STRING, name);
+          emit_event (child, ITF_EVENT_WINDOW, "deactivate", NULL, 0, 0,
+                      DBUS_TYPE_STRING_AS_STRING, name, append_basic);
         }
       g_object_unref (stateset);
 
-      emit (child, ITF_EVENT_WINDOW, "destroy", NULL, 0, 0,
-            DBUS_TYPE_STRING_AS_STRING, name);
+      emit_event (child, ITF_EVENT_WINDOW, "destroy", NULL, 0, 0,
+                  DBUS_TYPE_STRING_AS_STRING, name, append_basic);
       g_object_unref (child);
     }
 }
diff --git a/atk-adaptor/object.c b/atk-adaptor/object.c
new file mode 100644 (file)
index 0000000..856e991
--- /dev/null
@@ -0,0 +1,404 @@
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
+ *
+ * Copyright 2008 Novell, Inc.
+ * Copyright 2008, 2009, 2010 Codethink Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * This module contains utility functions for exporting AT-SPI
+ * objects based upon an ATK object.
+ *
+ * It incudes functions for marshalling object references
+ * and supported interfaces to a D-Bus message.
+ */
+
+#include <atk/atk.h>
+#include <common/spi-types.h>
+#include <common/spi-dbus.h>
+
+#include "accessible-register.h"
+#include "accessible-cache.h"
+#include "accessible-leasing.h"
+
+#include "bridge.h"
+
+/*---------------------------------------------------------------------------*/
+
+/*
+ * This is the all important function that decides whether an object should
+ * be leased or not.
+ *
+ * The choice of algorithm for this is somewhat vuage. We want ideally to lease
+ * all atk objects that are not owned by their parent.
+ *
+ * The 'cache' object attempts to cache all objects that are owned by their
+ * parent by traversing the tree of accessibles, ignoring the children of
+ * manages-descendants and transient objects.
+ *
+ * This function will simply look for all the accessibles that the cache object
+ * has not found and assume that they need to be leased.
+ */
+static void
+maybe_lease (AtkObject *obj)
+{
+  if (!spi_cache_in (spi_global_cache, G_OBJECT (obj)))
+    {
+      spi_leasing_take (spi_global_leasing, G_OBJECT (obj));
+    }
+}
+
+/*---------------------------------------------------------------------------*/
+
+/*
+ * It is assumed that all of these functions are returning an accessible
+ * object to the client side.
+ *
+ * All of them will lease the AtkObject if it is deemed neccessary.
+ */
+
+void
+spi_object_append_reference (DBusMessageIter * iter, AtkObject * obj)
+{
+  DBusMessageIter iter_struct;
+  const gchar *name;
+  gchar *path;
+
+  maybe_lease (obj);
+
+  name = dbus_bus_get_unique_name (spi_global_app_data->bus);
+  path = spi_register_object_to_path (spi_global_register, G_OBJECT (obj));
+
+  if (!path)
+    path = g_strdup (SPI_DBUS_PATH_NULL);
+
+  dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
+                                    &iter_struct);
+  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
+  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
+  dbus_message_iter_close_container (iter, &iter_struct);
+  
+  g_free (path);
+}
+
+void
+spi_object_append_v_reference (DBusMessageIter * iter, AtkObject * obj)
+{
+  DBusMessageIter iter_variant;
+
+  dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "(so)",
+                                    &iter_variant);
+     spi_object_append_reference (&iter_variant, obj);
+  dbus_message_iter_close_container (iter, &iter_variant);
+}
+
+void
+spi_object_append_desktop_reference (DBusMessageIter * iter)
+{
+  DBusMessageIter iter_struct;
+  const char *name = SPI_DBUS_NAME_REGISTRY;
+  const char *path = SPI_DBUS_PATH_DESKTOP;
+
+  dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
+                                    &iter_struct);
+  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
+  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
+  dbus_message_iter_close_container (iter, &iter_struct);
+}
+
+void
+spi_object_append_null_reference (DBusMessageIter * iter)
+{
+  DBusMessageIter iter_struct;
+  const char *name;
+  const char *path = "/org/at_spi/null";
+
+  name = dbus_bus_get_unique_name (spi_global_app_data->bus);
+
+  dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
+                                    &iter_struct);
+  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
+  dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
+  dbus_message_iter_close_container (iter, &iter_struct);
+}
+
+DBusMessage *
+spi_object_return_reference (DBusMessage * msg, AtkObject * obj)
+{
+  DBusMessage *reply;
+
+  reply = dbus_message_new_method_return (msg);
+  if (reply)
+    {
+      DBusMessageIter iter;
+      dbus_message_iter_init_append (reply, &iter);
+      spi_object_append_reference (&iter, obj);
+    }
+  g_object_unref (G_OBJECT (obj));
+
+  return reply;
+}
+
+/*---------------------------------------------------------------------------*/
+
+void
+spi_object_append_interfaces (DBusMessageIter * iter, AtkObject * obj)
+{
+  const gchar *itf;
+
+  itf = SPI_DBUS_INTERFACE_ACCESSIBLE;
+  dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
+
+  if (ATK_IS_ACTION (obj))
+    {
+      itf = SPI_DBUS_INTERFACE_ACTION;
+      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
+    }
+
+  if (ATK_IS_COMPONENT (obj))
+    {
+      itf = SPI_DBUS_INTERFACE_COMPONENT;
+      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
+    }
+
+  if (ATK_IS_EDITABLE_TEXT (obj))
+    {
+      itf = SPI_DBUS_INTERFACE_EDITABLE_TEXT;
+      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
+    }
+
+  if (ATK_IS_TEXT (obj))
+    {
+      itf = SPI_DBUS_INTERFACE_TEXT;
+      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
+    }
+
+  if (ATK_IS_HYPERTEXT (obj))
+    {
+      itf = SPI_DBUS_INTERFACE_HYPERTEXT;
+      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
+    }
+
+  if (ATK_IS_IMAGE (obj))
+    {
+      itf = SPI_DBUS_INTERFACE_IMAGE;
+      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
+    }
+
+  if (ATK_IS_SELECTION (obj))
+    {
+      itf = SPI_DBUS_INTERFACE_SELECTION;
+      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
+    }
+
+  if (ATK_IS_TABLE (obj))
+    {
+      itf = SPI_DBUS_INTERFACE_TABLE;
+      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
+    }
+
+  if (ATK_IS_VALUE (obj))
+    {
+      itf = SPI_DBUS_INTERFACE_VALUE;
+      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
+    }
+
+  if (ATK_IS_STREAMABLE_CONTENT (obj))
+    {
+      itf = "org.freedesktop.atspi.StreamableContent";
+      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
+    }
+
+  if (ATK_IS_DOCUMENT (obj))
+    {
+      itf = "org.freedesktop.atspi.Collection";
+      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
+      itf = SPI_DBUS_INTERFACE_DOCUMENT;
+      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
+    }
+
+  if (ATK_IS_HYPERLINK_IMPL (obj))
+    {
+      itf = SPI_DBUS_INTERFACE_HYPERLINK;
+      dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &itf);
+    }
+}
+
+/*---------------------------------------------------------------------------*/
+
+void
+spi_object_append_attribute_set (DBusMessageIter * iter, AtkAttributeSet * attr)
+{
+  DBusMessageIter dictIter;
+
+  dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{ss}", &dictIter);
+  while (attr)
+    {
+      DBusMessageIter dictEntryIter;
+      AtkAttribute *attribute = (AtkAttribute *) attr->data;
+      const char *key = attribute->name;
+      const char *value = attribute->value;
+
+      if (key == NULL)
+       key = "";
+      if (value == NULL)
+        value = "";
+
+      dbus_message_iter_open_container (&dictIter, DBUS_TYPE_DICT_ENTRY, NULL,
+                                        &dictEntryIter);
+      dbus_message_iter_append_basic (&dictEntryIter, DBUS_TYPE_STRING,
+                                      &key);
+      dbus_message_iter_append_basic (&dictEntryIter, DBUS_TYPE_STRING,
+                                      &value);
+      dbus_message_iter_close_container (&dictIter, &dictEntryIter);
+      attr = g_slist_next (attr);
+    }
+  dbus_message_iter_close_container (iter, &dictIter);
+}
+
+/*---------------------------------------------------------------------------*/
+
+static gboolean
+init_role_lookup_table (Accessibility_Role * role_table)
+{
+  int i;
+  /* if it's not in the list below, dunno what it is */
+  for (i = 0; i < ATK_ROLE_LAST_DEFINED; ++i)
+    {
+      role_table[i] = Accessibility_ROLE_UNKNOWN;
+    }
+
+  role_table[ATK_ROLE_INVALID] = Accessibility_ROLE_INVALID;
+  role_table[ATK_ROLE_ACCEL_LABEL] = Accessibility_ROLE_ACCELERATOR_LABEL;
+  role_table[ATK_ROLE_ALERT] = Accessibility_ROLE_ALERT;
+  role_table[ATK_ROLE_ANIMATION] = Accessibility_ROLE_ANIMATION;
+  role_table[ATK_ROLE_ARROW] = Accessibility_ROLE_ARROW;
+  role_table[ATK_ROLE_CALENDAR] = Accessibility_ROLE_CALENDAR;
+  role_table[ATK_ROLE_CANVAS] = Accessibility_ROLE_CANVAS;
+  role_table[ATK_ROLE_CHECK_BOX] = Accessibility_ROLE_CHECK_BOX;
+  role_table[ATK_ROLE_CHECK_MENU_ITEM] = Accessibility_ROLE_CHECK_MENU_ITEM;
+  role_table[ATK_ROLE_COLOR_CHOOSER] = Accessibility_ROLE_COLOR_CHOOSER;
+  role_table[ATK_ROLE_COLUMN_HEADER] = Accessibility_ROLE_COLUMN_HEADER;
+  role_table[ATK_ROLE_COMBO_BOX] = Accessibility_ROLE_COMBO_BOX;
+  role_table[ATK_ROLE_DATE_EDITOR] = Accessibility_ROLE_DATE_EDITOR;
+  role_table[ATK_ROLE_DESKTOP_ICON] = Accessibility_ROLE_DESKTOP_ICON;
+  role_table[ATK_ROLE_DESKTOP_FRAME] = Accessibility_ROLE_DESKTOP_FRAME;
+  role_table[ATK_ROLE_DIAL] = Accessibility_ROLE_DIAL;
+  role_table[ATK_ROLE_DIALOG] = Accessibility_ROLE_DIALOG;
+  role_table[ATK_ROLE_DIRECTORY_PANE] = Accessibility_ROLE_DIRECTORY_PANE;
+  role_table[ATK_ROLE_DRAWING_AREA] = Accessibility_ROLE_DRAWING_AREA;
+  role_table[ATK_ROLE_FILE_CHOOSER] = Accessibility_ROLE_FILE_CHOOSER;
+  role_table[ATK_ROLE_FILLER] = Accessibility_ROLE_FILLER;
+  role_table[ATK_ROLE_FONT_CHOOSER] = Accessibility_ROLE_FONT_CHOOSER;
+  role_table[ATK_ROLE_FRAME] = Accessibility_ROLE_FRAME;
+  role_table[ATK_ROLE_GLASS_PANE] = Accessibility_ROLE_GLASS_PANE;
+  role_table[ATK_ROLE_HTML_CONTAINER] = Accessibility_ROLE_HTML_CONTAINER;
+  role_table[ATK_ROLE_ICON] = Accessibility_ROLE_ICON;
+  role_table[ATK_ROLE_IMAGE] = Accessibility_ROLE_IMAGE;
+  role_table[ATK_ROLE_INTERNAL_FRAME] = Accessibility_ROLE_INTERNAL_FRAME;
+  role_table[ATK_ROLE_LABEL] = Accessibility_ROLE_LABEL;
+  role_table[ATK_ROLE_LAYERED_PANE] = Accessibility_ROLE_LAYERED_PANE;
+  role_table[ATK_ROLE_LIST] = Accessibility_ROLE_LIST;
+  role_table[ATK_ROLE_LIST_ITEM] = Accessibility_ROLE_LIST_ITEM;
+  role_table[ATK_ROLE_MENU] = Accessibility_ROLE_MENU;
+  role_table[ATK_ROLE_MENU_BAR] = Accessibility_ROLE_MENU_BAR;
+  role_table[ATK_ROLE_MENU_ITEM] = Accessibility_ROLE_MENU_ITEM;
+  role_table[ATK_ROLE_OPTION_PANE] = Accessibility_ROLE_OPTION_PANE;
+  role_table[ATK_ROLE_PAGE_TAB] = Accessibility_ROLE_PAGE_TAB;
+  role_table[ATK_ROLE_PAGE_TAB_LIST] = Accessibility_ROLE_PAGE_TAB_LIST;
+  role_table[ATK_ROLE_PANEL] = Accessibility_ROLE_PANEL;
+  role_table[ATK_ROLE_PASSWORD_TEXT] = Accessibility_ROLE_PASSWORD_TEXT;
+  role_table[ATK_ROLE_POPUP_MENU] = Accessibility_ROLE_POPUP_MENU;
+  role_table[ATK_ROLE_PROGRESS_BAR] = Accessibility_ROLE_PROGRESS_BAR;
+  role_table[ATK_ROLE_PUSH_BUTTON] = Accessibility_ROLE_PUSH_BUTTON;
+  role_table[ATK_ROLE_RADIO_BUTTON] = Accessibility_ROLE_RADIO_BUTTON;
+  role_table[ATK_ROLE_RADIO_MENU_ITEM] = Accessibility_ROLE_RADIO_MENU_ITEM;
+  role_table[ATK_ROLE_ROOT_PANE] = Accessibility_ROLE_ROOT_PANE;
+  role_table[ATK_ROLE_ROW_HEADER] = Accessibility_ROLE_ROW_HEADER;
+  role_table[ATK_ROLE_SCROLL_BAR] = Accessibility_ROLE_SCROLL_BAR;
+  role_table[ATK_ROLE_SCROLL_PANE] = Accessibility_ROLE_SCROLL_PANE;
+  role_table[ATK_ROLE_SEPARATOR] = Accessibility_ROLE_SEPARATOR;
+  role_table[ATK_ROLE_SLIDER] = Accessibility_ROLE_SLIDER;
+  role_table[ATK_ROLE_SPIN_BUTTON] = Accessibility_ROLE_SPIN_BUTTON;
+  role_table[ATK_ROLE_SPLIT_PANE] = Accessibility_ROLE_SPLIT_PANE;
+  role_table[ATK_ROLE_STATUSBAR] = Accessibility_ROLE_STATUS_BAR;
+  role_table[ATK_ROLE_TABLE] = Accessibility_ROLE_TABLE;
+  role_table[ATK_ROLE_TABLE_CELL] = Accessibility_ROLE_TABLE_CELL;
+  role_table[ATK_ROLE_TABLE_COLUMN_HEADER] =
+    Accessibility_ROLE_TABLE_COLUMN_HEADER;
+  role_table[ATK_ROLE_TABLE_ROW_HEADER] = Accessibility_ROLE_TABLE_ROW_HEADER;
+  role_table[ATK_ROLE_TEAR_OFF_MENU_ITEM] =
+    Accessibility_ROLE_TEAROFF_MENU_ITEM;
+  role_table[ATK_ROLE_TERMINAL] = Accessibility_ROLE_TERMINAL;
+  role_table[ATK_ROLE_TEXT] = Accessibility_ROLE_TEXT;
+  role_table[ATK_ROLE_TOGGLE_BUTTON] = Accessibility_ROLE_TOGGLE_BUTTON;
+  role_table[ATK_ROLE_TOOL_BAR] = Accessibility_ROLE_TOOL_BAR;
+  role_table[ATK_ROLE_TOOL_TIP] = Accessibility_ROLE_TOOL_TIP;
+  role_table[ATK_ROLE_TREE] = Accessibility_ROLE_TREE;
+  role_table[ATK_ROLE_TREE_TABLE] = Accessibility_ROLE_TREE_TABLE;
+  role_table[ATK_ROLE_UNKNOWN] = Accessibility_ROLE_UNKNOWN;
+  role_table[ATK_ROLE_VIEWPORT] = Accessibility_ROLE_VIEWPORT;
+  role_table[ATK_ROLE_WINDOW] = Accessibility_ROLE_WINDOW;
+  role_table[ATK_ROLE_HEADER] = Accessibility_ROLE_HEADER;
+  role_table[ATK_ROLE_FOOTER] = Accessibility_ROLE_FOOTER;
+  role_table[ATK_ROLE_PARAGRAPH] = Accessibility_ROLE_PARAGRAPH;
+  role_table[ATK_ROLE_RULER] = Accessibility_ROLE_RULER;
+  role_table[ATK_ROLE_APPLICATION] = Accessibility_ROLE_APPLICATION;
+  role_table[ATK_ROLE_AUTOCOMPLETE] = Accessibility_ROLE_AUTOCOMPLETE;
+  role_table[ATK_ROLE_EDITBAR] = Accessibility_ROLE_EDITBAR;
+  role_table[ATK_ROLE_EMBEDDED] = Accessibility_ROLE_EMBEDDED;
+  role_table[ATK_ROLE_ENTRY] = Accessibility_ROLE_ENTRY;
+  role_table[ATK_ROLE_CHART] = Accessibility_ROLE_CHART;
+  role_table[ATK_ROLE_CAPTION] = Accessibility_ROLE_CAPTION;
+  role_table[ATK_ROLE_DOCUMENT_FRAME] = Accessibility_ROLE_DOCUMENT_FRAME;
+  role_table[ATK_ROLE_HEADING] = Accessibility_ROLE_HEADING;
+  role_table[ATK_ROLE_PAGE] = Accessibility_ROLE_PAGE;
+  role_table[ATK_ROLE_SECTION] = Accessibility_ROLE_SECTION;
+  role_table[ATK_ROLE_FORM] = Accessibility_ROLE_FORM;
+  role_table[ATK_ROLE_REDUNDANT_OBJECT] = Accessibility_ROLE_REDUNDANT_OBJECT;
+  role_table[ATK_ROLE_LINK] = Accessibility_ROLE_LINK;
+  role_table[ATK_ROLE_INPUT_METHOD_WINDOW] =
+    Accessibility_ROLE_INPUT_METHOD_WINDOW;
+  return TRUE;
+}
+
+Accessibility_Role
+spi_accessible_role_from_atk_role (AtkRole role)
+{
+  static gboolean is_initialized = FALSE;
+  static Accessibility_Role spi_role_table[ATK_ROLE_LAST_DEFINED];
+  Accessibility_Role spi_role;
+
+  if (!is_initialized)
+    {
+      is_initialized = init_role_lookup_table (spi_role_table);
+    }
+
+  if (role >= 0 && role < ATK_ROLE_LAST_DEFINED)
+    {
+      spi_role = spi_role_table[role];
+    }
+  else
+    {
+      spi_role = Accessibility_ROLE_EXTENDED;
+    }
+  return spi_role;
+}
+
+/*END------------------------------------------------------------------------*/
similarity index 54%
rename from atk-adaptor/adaptors/tree-adaptor.h
rename to atk-adaptor/object.h
index 2406448..fb30b04 100644 (file)
@@ -2,9 +2,8 @@
  * AT-SPI - Assistive Technology Service Provider Interface
  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
  *
- * Copyright 2001, 2002 Sun Microsystems Inc.,
- * Copyright 2001, 2002 Ximian, Inc.
- * Copyright 2008, 2009 Codethink Ltd.
+ * Copyright 2008 Novell, Inc.
+ * Copyright 2008, 2009, 2010 Codethink Ltd.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  * Boston, MA 02111-1307, USA.
  */
 
-#ifndef TREE_ADAPTOR_H
-#define TREE_ADAPTOR_H
+#ifndef ACCESSIBLE_OBJECT_H
+#define ACCESSIBLE_OBJECT_H
 
 #include <atk/atk.h>
 #include <dbus/dbus.h>
 
-void spi_emit_cache_update (AtkObject * accessible, DBusConnection * bus);
+void
+spi_object_append_reference (DBusMessageIter * iter, AtkObject * obj);
 
-void spi_emit_cache_removal (guint ref, DBusConnection * bus);
+void
+spi_object_append_v_reference (DBusMessageIter * iter, AtkObject * obj);
 
-#endif /* TREE_ADAPTOR_H */
+void
+spi_object_append_desktop_reference (DBusMessageIter * iter);
+
+void
+spi_object_append_null_reference (DBusMessageIter * iter);
+
+DBusMessage *
+spi_object_return_reference (DBusMessage * msg, AtkObject * obj);
+
+void
+spi_object_append_interfaces (DBusMessageIter * iter, AtkObject * obj);
+
+void
+spi_object_append_attribute_set (DBusMessageIter * iter, AtkAttributeSet * attr);
+
+Accessibility_Role
+spi_accessible_role_from_atk_role (AtkRole role);
+
+#endif /* ACCESSIBLE_OBJECT_H */
index f859156..b24a8ee 100644 (file)
@@ -172,6 +172,43 @@ provide_defaults(const gint type,
     }
 }
 
+/*
+ * Appends all the standard parameters to an AT-SPI event.
+ */
+void
+spi_dbus_signal_new (const char *path,
+                     const char *klass,
+                     const char *major,
+                     const char *minor,
+                     dbus_int32_t detail1,
+                     dbus_int32_t detail2)
+{
+  DBusMessage *sig;
+  DBusMessageIter iter, sub;
+  gchar *cname, *t;
+
+  if (!klass) klass = "";
+  if (!major) major = "";
+  if (!minor) minor = "";
+
+  /*
+   * This is very annoying, but as '-' isn't a legal signal
+   * name in D-Bus (Why not??!?) The names need converting
+   * on this side, and again on the client side.
+   */
+  cname = g_strdup(major);
+  while ((t = strchr(cname, '-')) != NULL) *t = '_';
+
+  sig = dbus_message_new_signal(path, klass, cname);
+  g_free(cname);
+
+  dbus_message_iter_init_append(sig, &iter);
+
+  dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &minor);
+  dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &detail1);
+  dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &detail2);
+}
+
 void 
 spi_dbus_emit_signal(DBusConnection *bus, const char *path,
      const char *klass,
@@ -222,6 +259,7 @@ spi_dbus_emit_signal(DBusConnection *bus, const char *path,
   dbus_message_unref(sig);
 }
 
+
 /*
 dbus_bool_t spi_dbus_get_simple_property (DBusConnection *bus, const char *dest, const char *path, const char *interface, const char *prop, int *type, void *ptr, DBusError *error)
 {
index b6e1283..f82e24c 100644 (file)
@@ -44,7 +44,7 @@ extern int _dbg;
 #define SPI_DBUS_INTERFACE_DEC "org.freedesktop.atspi.DeviceEventController"
 #define SPI_DBUS_INTERFACE_DEVICE_EVENT_LISTENER "org.freedesktop.atspi.DeviceEventListener"
 
-#define SPI_DBUS_INTERFACE_TREE "org.freedesktop.atspi.Tree"
+#define SPI_DBUS_INTERFACE_CACHE "org.freedesktop.atspi.Cache"
 #define SPI_DBUS_INTERFACE_ACCESSIBLE "org.freedesktop.atspi.Accessible"
 #define SPI_DBUS_INTERFACE_ACTION "org.freedesktop.atspi.Action"
 #define SPI_DBUS_INTERFACE_APPLICATION "org.freedesktop.atspi.Application"
index ff0a53d..2c148f0 100644 (file)
@@ -154,7 +154,7 @@ spi_atk_state_from_spi_state (Accessibility_StateType state)
 }
 
 AtkStateSet *
-spi_state_set_cache_from_sequence (const GArray *seq)
+spi_state_set_cache_from_sequence (GArray *seq)
 {
   int i;
   AtkStateSet *set;
index b82466d..f097c92 100644 (file)
@@ -30,7 +30,7 @@
 G_BEGIN_DECLS
 
 /* private - internal API to abstract away atk API */
-AtkStateSet *spi_state_set_cache_from_sequence(const GArray *seq);
+AtkStateSet *spi_state_set_cache_from_sequence(GArray *seq);
 AtkState     spi_atk_state_from_spi_state     (Accessibility_StateType state);
 void spi_atk_state_to_dbus_array (AtkObject * object, dbus_uint32_t * array);
 void spi_atk_state_set_to_dbus_array (AtkStateSet *set, dbus_uint32_t * array);
index aadf7f5..f16ff7f 100644 (file)
@@ -98,26 +98,23 @@ fi
 AC_SUBST(EXTRA_SOCKET_LIBS)
 
 dnl find sizes & alignments
-orig_CPPFLAGS=$CPPFLAGS
-CPPFLAGS="$CPPFLAGS $DBUS_CFLAGS"
-DBIND_CHECK_ALIGNOF(char)
-DBIND_CHECK_ALIGNOF(dbus_bool_t)
-DBIND_CHECK_ALIGNOF(dbus_int16_t)
-DBIND_CHECK_ALIGNOF(dbus_int32_t)
-DBIND_CHECK_ALIGNOF(dbus_int64_t)
-DBIND_CHECK_ALIGNOF(double)
-DBIND_CHECK_ALIGNOF(dbind_pointer)
-DBIND_CHECK_ALIGNOF(dbind_struct)
-CPPFLAGS=$orig_CPPFLAGS 
+#orig_CPPFLAGS=$CPPFLAGS
+#CPPFLAGS="$CPPFLAGS $DBUS_CFLAGS"
+#DBIND_CHECK_ALIGNOF(char)
+#DBIND_CHECK_ALIGNOF(dbus_bool_t)
+#DBIND_CHECK_ALIGNOF(dbus_int16_t)
+#DBIND_CHECK_ALIGNOF(dbus_int32_t)
+#DBIND_CHECK_ALIGNOF(dbus_int64_t)
+#DBIND_CHECK_ALIGNOF(double)
+#DBIND_CHECK_ALIGNOF(dbind_pointer)
+#DBIND_CHECK_ALIGNOF(dbind_struct)
+#CPPFLAGS=$orig_CPPFLAGS 
 
 AC_CONFIG_FILES([Makefile
                 droute/Makefile
-                dbind/Makefile
-                dbind/dbind-config.h
                 common/Makefile
                 atk-adaptor/Makefile
                 atk-adaptor/adaptors/Makefile
-                tests/Makefile
                ])
 
 AC_OUTPUT
index 55020a7..5ab1478 100644 (file)
@@ -525,6 +525,8 @@ handle_message (DBusConnection *bus, DBusMessage *message, void *user_data)
     const gint   type    = dbus_message_get_type (message);
     const gchar *pathstr = dbus_message_get_path (message);
 
+    _DROUTE_DEBUG ("DRoute (handle message): %s|%s of type %d on %s\n", member, iface, type, pathstr);
+
     /* Check for basic reasons not to handle */
     if (type   != DBUS_MESSAGE_TYPE_METHOD_CALL ||
         member == NULL ||