summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Doffman <mark.doffman@codethink.co.uk>2010-01-05 01:47:34 -0800
committerMark Doffman <mark.doffman@codethink.co.uk>2010-01-05 02:21:17 -0800
commit5713a8e46559b6de9fbf5fc3e073d0d482d8c7e1 (patch)
treebcd5bec668df796becdcafb64131c2c4c887b245
parent1dd7a3f08c3ac54abca261ae5aa539371f77ccc9 (diff)
downloadat-spi2-core-5713a8e46559b6de9fbf5fc3e073d0d482d8c7e1.tar.gz
Integrate leasing scheme in-to atk-bridge.
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.
-rw-r--r--Makefile.am2
-rw-r--r--atk-adaptor/Makefile.am5
-rw-r--r--atk-adaptor/accessible-cache.c389
-rw-r--r--atk-adaptor/accessible-cache.h63
-rw-r--r--atk-adaptor/accessible-leasing.c4
-rw-r--r--atk-adaptor/accessible-leasing.h8
-rw-r--r--atk-adaptor/accessible-register.c889
-rw-r--r--atk-adaptor/accessible-register.h58
-rw-r--r--atk-adaptor/adaptors/Makefile.am5
-rw-r--r--atk-adaptor/adaptors/accessible-adaptor.c173
-rw-r--r--atk-adaptor/adaptors/accessible-marshaller.c445
-rw-r--r--atk-adaptor/adaptors/accessible-marshaller.h64
-rw-r--r--atk-adaptor/adaptors/adaptors.h2
-rw-r--r--atk-adaptor/adaptors/cache-adaptor.c301
-rw-r--r--atk-adaptor/adaptors/collection-adaptor.c23
-rw-r--r--atk-adaptor/adaptors/component-adaptor.c4
-rw-r--r--atk-adaptor/adaptors/document-adaptor.c3
-rw-r--r--atk-adaptor/adaptors/hyperlink-adaptor.c5
-rw-r--r--atk-adaptor/adaptors/hypertext-adaptor.c5
-rw-r--r--atk-adaptor/adaptors/image-adaptor.c1
-rw-r--r--atk-adaptor/adaptors/selection-adaptor.c4
-rw-r--r--atk-adaptor/adaptors/table-adaptor.c16
-rw-r--r--atk-adaptor/adaptors/text-adaptor.c23
-rw-r--r--atk-adaptor/adaptors/tree-adaptor.c155
-rw-r--r--atk-adaptor/bridge.c71
-rw-r--r--atk-adaptor/bridge.h24
-rw-r--r--atk-adaptor/event.c328
-rw-r--r--atk-adaptor/object.c404
-rw-r--r--atk-adaptor/object.h (renamed from atk-adaptor/adaptors/tree-adaptor.h)35
-rw-r--r--common/spi-dbus.c38
-rw-r--r--common/spi-dbus.h2
-rw-r--r--common/spi-stateset.c2
-rw-r--r--common/spi-stateset.h2
-rw-r--r--configure.ac25
-rw-r--r--droute/droute.c2
35 files changed, 1706 insertions, 1874 deletions
diff --git a/Makefile.am b/Makefile.am
index 305d97d7..31982fe0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1 +1 @@
-SUBDIRS=droute dbind common atk-adaptor tests
+SUBDIRS=droute common atk-adaptor
diff --git a/atk-adaptor/Makefile.am b/atk-adaptor/Makefile.am
index fea70913..140ede44 100644
--- a/atk-adaptor/Makefile.am
+++ b/atk-adaptor/Makefile.am
@@ -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
index 00000000..4f87b180
--- /dev/null
+++ b/atk-adaptor/accessible-cache.c
@@ -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
index 00000000..8d75b5df
--- /dev/null
+++ b/atk-adaptor/accessible-cache.h
@@ -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 */
diff --git a/atk-adaptor/accessible-leasing.c b/atk-adaptor/accessible-leasing.c
index 0bfd496b..28d40998 100644
--- a/atk-adaptor/accessible-leasing.c
+++ b/atk-adaptor/accessible-leasing.c
@@ -24,10 +24,12 @@
#include <stdlib.h>
#include <string.h>
-#include <accessible-leasing.h>
+#include "accessible-leasing.h"
/*---------------------------------------------------------------------------*/
+SpiLeasing *spi_global_leasing;
+
typedef struct _ExpiryElement
{
guint expiry_s;
diff --git a/atk-adaptor/accessible-leasing.h b/atk-adaptor/accessible-leasing.h
index 50f1f3c0..af01a78f 100644
--- a/atk-adaptor/accessible-leasing.h
+++ b/atk-adaptor/accessible-leasing.h
@@ -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 */
diff --git a/atk-adaptor/accessible-register.c b/atk-adaptor/accessible-register.c
index f0963af0..ac93dee6 100644
--- a/atk-adaptor/accessible-register.c
+++ b/atk-adaptor/accessible-register.c
@@ -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"
/*
@@ -46,74 +45,95 @@
* 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------------------------------------------------------------------------*/
diff --git a/atk-adaptor/accessible-register.h b/atk-adaptor/accessible-register.h
index fe1912d3..dda103bd 100644
--- a/atk-adaptor/accessible-register.h
+++ b/atk-adaptor/accessible-register.h
@@ -21,31 +21,57 @@
* 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 */
diff --git a/atk-adaptor/adaptors/Makefile.am b/atk-adaptor/adaptors/Makefile.am
index d130c80f..e3f5cf94 100644
--- a/atk-adaptor/adaptors/Makefile.am
+++ b/atk-adaptor/adaptors/Makefile.am
@@ -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
diff --git a/atk-adaptor/adaptors/accessible-adaptor.c b/atk-adaptor/adaptors/accessible-adaptor.c
index 434223ee..6359fa77 100644
--- a/atk-adaptor/adaptors/accessible-adaptor.c
+++ b/atk-adaptor/adaptors/accessible-adaptor.c
@@ -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
index f087171c..00000000
--- a/atk-adaptor/adaptors/accessible-marshaller.c
+++ /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
index 4d0a1317..00000000
--- a/atk-adaptor/adaptors/accessible-marshaller.h
+++ /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 */
diff --git a/atk-adaptor/adaptors/adaptors.h b/atk-adaptor/adaptors/adaptors.h
index 7f8bdd97..ccc07abc 100644
--- a/atk-adaptor/adaptors/adaptors.h
+++ b/atk-adaptor/adaptors/adaptors.h
@@ -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
index 00000000..45eb41be
--- /dev/null
+++ b/atk-adaptor/adaptors/cache-adaptor.c
@@ -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------------------------------------------------------------------------*/
diff --git a/atk-adaptor/adaptors/collection-adaptor.c b/atk-adaptor/adaptors/collection-adaptor.c
index e920545b..1702ee75 100644
--- a/atk-adaptor/adaptors/collection-adaptor.c
+++ b/atk-adaptor/adaptors/collection-adaptor.c
@@ -27,13 +27,13 @@
#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;
diff --git a/atk-adaptor/adaptors/component-adaptor.c b/atk-adaptor/adaptors/component-adaptor.c
index 40f83603..a3810ded 100644
--- a/atk-adaptor/adaptors/component-adaptor.c
+++ b/atk-adaptor/adaptors/component-adaptor.c
@@ -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 *
diff --git a/atk-adaptor/adaptors/document-adaptor.c b/atk-adaptor/adaptors/document-adaptor.c
index de83a0d9..dc3f628e 100644
--- a/atk-adaptor/adaptors/document-adaptor.c
+++ b/atk-adaptor/adaptors/document-adaptor.c
@@ -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)
diff --git a/atk-adaptor/adaptors/hyperlink-adaptor.c b/atk-adaptor/adaptors/hyperlink-adaptor.c
index 75521ede..732ab2b4 100644
--- a/atk-adaptor/adaptors/hyperlink-adaptor.c
+++ b/atk-adaptor/adaptors/hyperlink-adaptor.c
@@ -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 *
diff --git a/atk-adaptor/adaptors/hypertext-adaptor.c b/atk-adaptor/adaptors/hypertext-adaptor.c
index 082dde38..0bb4060e 100644
--- a/atk-adaptor/adaptors/hypertext-adaptor.c
+++ b/atk-adaptor/adaptors/hypertext-adaptor.c
@@ -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 *
diff --git a/atk-adaptor/adaptors/image-adaptor.c b/atk-adaptor/adaptors/image-adaptor.c
index 1ed7b249..c2e00b00 100644
--- a/atk-adaptor/adaptors/image-adaptor.c
+++ b/atk-adaptor/adaptors/image-adaptor.c
@@ -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)
diff --git a/atk-adaptor/adaptors/selection-adaptor.c b/atk-adaptor/adaptors/selection-adaptor.c
index 4516b523..02e28f23 100644
--- a/atk-adaptor/adaptors/selection-adaptor.c
+++ b/atk-adaptor/adaptors/selection-adaptor.c
@@ -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 *
diff --git a/atk-adaptor/adaptors/table-adaptor.c b/atk-adaptor/adaptors/table-adaptor.c
index 212004ac..b61caa2e 100644
--- a/atk-adaptor/adaptors/table-adaptor.c
+++ b/atk-adaptor/adaptors/table-adaptor.c
@@ -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 *
diff --git a/atk-adaptor/adaptors/text-adaptor.c b/atk-adaptor/adaptors/text-adaptor.c
index a15f9c73..dc20a802 100644
--- a/atk-adaptor/adaptors/text-adaptor.c
+++ b/atk-adaptor/adaptors/text-adaptor.c
@@ -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
index 89a065f6..00000000
--- a/atk-adaptor/adaptors/tree-adaptor.c
+++ /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------------------------------------------------------------------------*/
diff --git a/atk-adaptor/bridge.c b/atk-adaptor/bridge.c
index 00ead5c4..b283506c 100644
--- a/atk-adaptor/bridge.c
+++ b/atk-adaptor/bridge.c
@@ -31,15 +31,19 @@
#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);
diff --git a/atk-adaptor/bridge.h b/atk-adaptor/bridge.h
index 44315f11..2a95fcd4 100644
--- a/atk-adaptor/bridge.h
+++ b/atk-adaptor/bridge.h
@@ -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
@@ -28,15 +28,29 @@
#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 */
diff --git a/atk-adaptor/event.c b/atk-adaptor/event.c
index 687fc79b..e97046b1 100644
--- a/atk-adaptor/event.c
+++ b/atk-adaptor/event.c
@@ -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
index 00000000..856e9910
--- /dev/null
+++ b/atk-adaptor/object.c
@@ -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------------------------------------------------------------------------*/
diff --git a/atk-adaptor/adaptors/tree-adaptor.h b/atk-adaptor/object.h
index 24064489..fb30b047 100644
--- a/atk-adaptor/adaptors/tree-adaptor.h
+++ b/atk-adaptor/object.h
@@ -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
@@ -22,14 +21,34 @@
* 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 */
diff --git a/common/spi-dbus.c b/common/spi-dbus.c
index f8591567..b24a8ee2 100644
--- a/common/spi-dbus.c
+++ b/common/spi-dbus.c
@@ -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)
{
diff --git a/common/spi-dbus.h b/common/spi-dbus.h
index b6e1283a..f82e24c8 100644
--- a/common/spi-dbus.h
+++ b/common/spi-dbus.h
@@ -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"
diff --git a/common/spi-stateset.c b/common/spi-stateset.c
index ff0a53de..2c148f0f 100644
--- a/common/spi-stateset.c
+++ b/common/spi-stateset.c
@@ -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;
diff --git a/common/spi-stateset.h b/common/spi-stateset.h
index b82466df..f097c926 100644
--- a/common/spi-stateset.h
+++ b/common/spi-stateset.h
@@ -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);
diff --git a/configure.ac b/configure.ac
index aadf7f5b..f16ff7f6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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
diff --git a/droute/droute.c b/droute/droute.c
index 55020a7e..5ab1478e 100644
--- a/droute/droute.c
+++ b/droute/droute.c
@@ -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 ||