[at-spi2-atk/mgorse: 3/8] 2009-08-28 Mike Gorse <mgorse novell com>



commit 441bd62892a379bfea73f21d7103a3d44a655a22
Author: Mike Gorse <mgorse novell com>
Date:   Fri Aug 28 13:47:28 2009 -0500

    2009-08-28  Mike Gorse  <mgorse novell com>
    
    Allow objects to record transient sub-objects which will be dereferenced
    when the containing object is removed.
    Initial pass at supporting hyperlinks and visible Transient objects.
    Transient objects should be removed from memory if they lose visibility.

 atk-adaptor/accessible-adaptor.c    |   13 ++-
 atk-adaptor/accessible-marshaller.c |   47 +++++++-
 atk-adaptor/accessible-marshaller.h |    8 +-
 atk-adaptor/accessible-register.c   |  224 +++++++++++++++++++++++++++++++----
 atk-adaptor/accessible-register.h   |   11 ++-
 atk-adaptor/component-adaptor.c     |    2 +-
 atk-adaptor/event.c                 |   10 +-
 atk-adaptor/hyperlink-adaptor.c     |   25 +++--
 atk-adaptor/hypertext-adaptor.c     |    4 +-
 atk-adaptor/selection-adaptor.c     |    2 +-
 atk-adaptor/table-adaptor.c         |   14 +-
 atk-adaptor/tree-adaptor.c          |    6 +-
 12 files changed, 305 insertions(+), 61 deletions(-)
---
diff --git a/atk-adaptor/accessible-adaptor.c b/atk-adaptor/accessible-adaptor.c
index c59f39e..6124080 100644
--- a/atk-adaptor/accessible-adaptor.c
+++ b/atk-adaptor/accessible-adaptor.c
@@ -114,7 +114,7 @@ impl_getChildAtIndex (DBusConnection *bus,
   if (!dbus_message_get_args (message, &error, DBUS_TYPE_INT32, &i, DBUS_TYPE_INVALID))
       return spi_dbus_general_error (message);
   child = atk_object_ref_accessible_child (object, i);
-  return spi_dbus_return_object (message, child, FALSE);
+  return spi_dbus_return_object (message, child, FALSE, FALSE);
 }
 
 static DBusMessage *
@@ -140,7 +140,7 @@ impl_getChildren (DBusConnection *bus,
   for (i = 0; i < count; i++)
     {
       AtkObject *child = atk_object_ref_accessible_child (object, i);
-      char *path = atk_dbus_object_to_path (child);
+      char *path = atk_dbus_object_to_path (child, FALSE);
       if (path)
 	{
 	  dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_OBJECT_PATH,
@@ -270,7 +270,12 @@ impl_getRelationSet (DBusConnection *bus,
       AtkObject *obj = target->pdata[j];
       char *path;
       if (!obj) continue;
-      path = atk_dbus_object_to_path (obj);
+      path = atk_dbus_object_to_path (obj, FALSE);
+      if (!path)
+      {
+	g_warning ("Unknown object in relation type %d\n", type);
+	continue;
+      }
       dbus_message_iter_append_basic (&iter_targets, DBUS_TYPE_OBJECT_PATH, &path);
     }
     dbus_message_iter_close_container (&iter_struct, &iter_targets);
@@ -543,7 +548,7 @@ impl_getApplication (DBusConnection *bus,
                      void *user_data)
 {
   AtkObject *root = atk_get_root ();
-  return spi_dbus_return_object (message, root, FALSE);
+  return spi_dbus_return_object (message, root, FALSE, FALSE);
 }
 
 static DBusMessage *
diff --git a/atk-adaptor/accessible-marshaller.c b/atk-adaptor/accessible-marshaller.c
index b6b052b..4bfb362 100644
--- a/atk-adaptor/accessible-marshaller.c
+++ b/atk-adaptor/accessible-marshaller.c
@@ -38,12 +38,12 @@
  * Unrefs the AtkObject if unref is true.
  */
 DBusMessage *
-spi_dbus_return_object (DBusMessage *message, AtkObject *obj, gboolean unref)
+spi_dbus_return_object (DBusMessage *message, AtkObject *obj, gboolean do_register, gboolean unref)
 {
   DBusMessage *reply;
   gchar *path;
 
-  path = atk_dbus_object_to_path (obj);
+  path = atk_dbus_object_to_path (obj, do_register);
 
   if (obj && unref)
     g_object_unref (obj);
@@ -63,6 +63,38 @@ spi_dbus_return_object (DBusMessage *message, AtkObject *obj, gboolean 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;
+}
+
 /*---------------------------------------------------------------------------*/
 
 /*
@@ -76,7 +108,10 @@ spi_dbus_return_v_object (DBusMessageIter *iter, AtkObject *obj, int unref)
 {
   char *path;
 
-  path = atk_dbus_object_to_path (obj);
+  path = atk_dbus_object_to_path (obj, FALSE);
+
+  if (!path)
+    path = g_strdup (SPI_DBUS_PATH_NULL);
 
   if (unref)
     g_object_unref (obj);
@@ -201,7 +236,7 @@ spi_atk_append_accessible(AtkObject *obj, gpointer iter)
       gchar *path, *path_parent;
 
       /* Marshall object path */
-      path = atk_dbus_object_to_path (obj);
+      path = atk_dbus_object_to_path (obj, FALSE);
       dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
 
       /* Marshall parent */
@@ -212,7 +247,7 @@ spi_atk_append_accessible(AtkObject *obj, gpointer iter)
         }
       else
         {
-          path_parent = atk_dbus_object_to_path (parent);
+          path_parent = atk_dbus_object_to_path (parent, FALSE);
           if (!path_parent)
             {
               /* This should only happen if a widget is re-parented to
@@ -243,7 +278,7 @@ spi_atk_append_accessible(AtkObject *obj, gpointer iter)
               gchar *child_path;
 
               child = atk_object_ref_accessible_child (obj, i);
-              child_path = atk_dbus_object_to_path (child);
+              child_path = atk_dbus_object_to_path (child, FALSE);
               if (child_path)
                 {
                   dbus_message_iter_append_basic (&iter_sub_array, DBUS_TYPE_OBJECT_PATH, &child_path);
diff --git a/atk-adaptor/accessible-marshaller.h b/atk-adaptor/accessible-marshaller.h
index d372537..ed72967 100644
--- a/atk-adaptor/accessible-marshaller.h
+++ b/atk-adaptor/accessible-marshaller.h
@@ -28,7 +28,13 @@
 #include <atk/atk.h>
 
 DBusMessage *
-spi_dbus_return_object (DBusMessage *message, AtkObject *obj, gboolean unref);
+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);
diff --git a/atk-adaptor/accessible-register.c b/atk-adaptor/accessible-register.c
index 793e0ea..883a9d9 100644
--- a/atk-adaptor/accessible-register.c
+++ b/atk-adaptor/accessible-register.c
@@ -128,8 +128,20 @@ assign_reference(void)
  * 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)
 {
+  return gobject_to_ref (G_OBJECT (accessible));
+}
+
+static guint
+hyperlink_to_ref (AtkHyperlink *accessible)
+{
   return GPOINTER_TO_INT(g_object_get_data (G_OBJECT (accessible), "dbus-id"));
 }
 
@@ -144,6 +156,12 @@ atk_dbus_ref_to_path (guint ref)
 
 /*---------------------------------------------------------------------------*/
 
+static void
+deregister_sub_accessible (gpointer key, gpointer obj_data, gpointer iter);
+
+static void
+deregister_sub_hyperlink (gpointer key, gpointer obj_data, gpointer iter);
+
 /*
  * Callback for when a registered AtkObject is destroyed.
  *
@@ -151,33 +169,125 @@ atk_dbus_ref_to_path (guint ref)
  * it is no longer exposed over D-Bus.
  */
 static void
-deregister_accessible (gpointer data, GObject *accessible)
+deregister_object (gpointer data, GObject *gobj)
 {
   guint ref;
-  g_return_if_fail (ATK_IS_OBJECT (accessible));
+  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");
+  if (subrefs_atk)
+    g_hash_table_foreach (subrefs_atk, deregister_sub_accessible, data);
+  
+  subrefs_hyperlink = (GHashTable *) g_object_get_data (gobj, "dbus-subrefs-hyperlink");
+  if (subrefs_hyperlink)
+    g_hash_table_foreach (subrefs_hyperlink, deregister_sub_hyperlink, data);
+  
+  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_object_unref (obj);
+}
 
-  ref = object_to_ref (ATK_OBJECT(accessible));
+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);
   if (ref != 0)
     {
-      spi_emit_cache_removal (ref, atk_adaptor_app_data->bus);
       g_hash_table_remove(ref2ptr, GINT_TO_POINTER(ref));
     }
+  g_object_unref (ghyperlink);
+}
+
+static void
+register_gobject (GObject *gobj, GObject *container)
+{
+  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);
+  }
+
+  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) &&
+        atk_state_set_contains_state (state, ATK_STATE_SHOWING))
+    {
+      g_object_ref (gobj);
+    }
+    g_object_unref (state);
+  }
 }
 
 /*
  * Called to register an AtkObject with AT-SPI and expose it over D-Bus.
  */
 static void
-register_accessible (AtkObject *accessible)
+register_accessible (AtkObject *accessible, AtkObject *container)
 {
-  guint ref;
   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();
 
-  g_hash_table_insert (ref2ptr, GINT_TO_POINTER(ref), accessible);
-  g_object_set_data (G_OBJECT(accessible), "dbus-id", GINT_TO_POINTER(ref));
-  g_object_weak_ref(G_OBJECT(accessible), deregister_accessible, NULL);
+  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));
+
+  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);
 }
 
 /*---------------------------------------------------------------------------*/
@@ -210,8 +320,11 @@ non_owned_accessible (AtkObject *accessible)
 
 /*---------------------------------------------------------------------------*/
 
+/* TRUE if we should not keep this object / tell the AT about it
+ * Currently true if TRANSIENT and not SHOWING
+ */
 static gboolean
-has_manages_descendants (AtkObject *accessible)
+object_is_moot (AtkObject *accessible)
 {
    AtkStateSet *state;
    gboolean result = FALSE;
@@ -221,11 +334,9 @@ has_manages_descendants (AtkObject *accessible)
     * by modifying the tree alot.
     */
    state = atk_object_ref_state_set (accessible);
-   if (atk_state_set_contains_state (state, ATK_STATE_MANAGES_DESCENDANTS))
+   if ( atk_state_set_contains_state (state, ATK_STATE_TRANSIENT) &&
+       !atk_state_set_contains_state (state, ATK_STATE_SHOWING))
      {
-#ifdef SPI_ATK_DEBUG
-       g_warning ("AT-SPI: Object with 'Manages descendants' states not currently handled by AT-SPI");
-#endif
        result = TRUE;
      }
    g_object_unref (state);
@@ -249,7 +360,7 @@ append_children (AtkObject *accessible, GQueue *traversal)
 #ifdef SPI_ATK_DEBUG
           non_owned_accessible (current);
 #endif
-          if (!has_manages_descendants (current))
+          if (!object_is_moot (current))
               g_queue_push_tail (traversal, current);
           else
               g_object_unref (G_OBJECT (current));
@@ -287,7 +398,7 @@ register_subtree (AtkObject *accessible)
       g_queue_push_tail (emit_update, current);
       if (!object_to_ref (current))
         {
-          register_accessible (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),
@@ -338,8 +449,8 @@ atk_dbus_foreach_registered(GHFunc func, gpointer data)
 /*
  * Used to lookup an AtkObject from its D-Bus path.
  */
-AtkObject *
-atk_dbus_path_to_object (const char *path)
+GObject *
+atk_dbus_path_to_gobject (const char *path)
 {
   guint index;
   void *data;
@@ -352,7 +463,7 @@ atk_dbus_path_to_object (const char *path)
   path += SPI_ATK_PATH_PREFIX_LENGTH; /* Skip over the prefix */
 
   if (!g_strcmp0 (SPI_ATK_OBJECT_PATH_DESKTOP, path))
-     return atk_get_root();
+     return G_OBJECT (atk_get_root());
   if (path[0] != '/')
      return NULL;
 
@@ -360,11 +471,17 @@ atk_dbus_path_to_object (const char *path)
   index = atoi (path);
   data = g_hash_table_lookup (ref2ptr, GINT_TO_POINTER(index));
   if (data)
-    return ATK_OBJECT (data);
+    return G_OBJECT (data);
   else
     return NULL;
 }
 
+AtkObject *
+atk_dbus_path_to_object (const char *path)
+{
+  return ATK_OBJECT (atk_dbus_path_to_gobject (path));
+}
+
 /*
  * TODO WARNING HACK This function is dangerous.
  * It should only be called before sending an event on an
@@ -426,11 +543,48 @@ atk_dbus_object_attempt_registration (AtkObject *accessible)
  * Used to lookup a D-Bus path from the AtkObject.
  */
 gchar *
-atk_dbus_object_to_path (AtkObject *accessible)
+atk_dbus_gobject_to_path_internal (GObject *gobj, gboolean do_register, GObject *container)
 {
   guint ref;
 
-  ref = object_to_ref (accessible);
+  ref = gobject_to_ref (gobj);
+  if (!ref && do_register)
+  {
+    register_gobject (gobj, container);
+    ref = gobject_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
@@ -503,6 +657,31 @@ tree_update_state_action (GSignalInvocationHint *signal_hint,
                           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") && state == 0)
+  {
+    if (object_is_moot (accessible))
+    {
+      int ref_count = G_OBJECT(accessible)->ref_count;
+      g_object_unref (accessible);
+      /* If the ref count was >1, then someone else is still holding a ref,
+         but our ref is gone, so remove from the cache */
+      if (ref_count > 1)
+	deregister_object (NULL, G_OBJECT (accessible));
+      return TRUE;
+    }
+  }
+
       update_accessible (accessible);
   return TRUE;
 }
@@ -559,7 +738,6 @@ tree_update_children_action (GSignalInvocationHint *signal_hint,
       const gchar *detail = NULL;
       AtkObject *child;
 
-      if (has_manages_descendants (accessible)) return TRUE;
       if (signal_hint->detail)
           detail = g_quark_to_string (signal_hint->detail);
 
diff --git a/atk-adaptor/accessible-register.h b/atk-adaptor/accessible-register.h
index b238af7..f9f6a90 100644
--- a/atk-adaptor/accessible-register.h
+++ b/atk-adaptor/accessible-register.h
@@ -32,6 +32,9 @@ atk_dbus_foreach_registered(GHFunc func, gpointer data);
 
 /*---------------------------------------------------------------------------*/
 
+GObject *
+atk_dbus_path_to_gobject (const char *path);
+
 AtkObject *
 atk_dbus_path_to_object (const char *path);
 
@@ -39,7 +42,13 @@ gchar *
 atk_dbus_object_attempt_registration (AtkObject *accessible);
 
 gchar *
-atk_dbus_object_to_path (AtkObject *accessible);
+atk_dbus_object_to_path (AtkObject *accessible, gboolean do_register);
+
+gchar *
+atk_dbus_sub_object_to_path (GObject *accessible, GObject *container);
+
+gchar *
+atk_dbus_hyperlink_to_path (AtkHyperlink *hyperlink, AtkObject *container);
 
 gchar *
 atk_dbus_desktop_object_path ();
diff --git a/atk-adaptor/component-adaptor.c b/atk-adaptor/component-adaptor.c
index 5f0e104..34a21de 100644
--- a/atk-adaptor/component-adaptor.c
+++ b/atk-adaptor/component-adaptor.c
@@ -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);
+  return spi_dbus_return_object (message, child, TRUE, TRUE);
 }
 
 static DBusMessage *
diff --git a/atk-adaptor/event.c b/atk-adaptor/event.c
index 58c7e1c..a986f4c 100644
--- a/atk-adaptor/event.c
+++ b/atk-adaptor/event.c
@@ -227,7 +227,7 @@ emit_rect(AtkObject  *accessible,
   gchar *path, *cname, *t;
   dbus_int32_t dummy = 0;
 
-  path = atk_dbus_object_to_path (accessible);
+  path = atk_dbus_object_to_path (accessible, FALSE);
 
   /* Tough decision here
    * We won't send events from accessible
@@ -327,7 +327,7 @@ property_event_listener (GSignalInvocationHint *signal_hint,
   if (strcmp (pname, "accessible-table-summary") == 0)
     {
       otemp = atk_table_get_summary(ATK_TABLE (accessible));
-      stemp = atk_dbus_object_to_path (otemp);
+      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);
     }
@@ -335,7 +335,7 @@ property_event_listener (GSignalInvocationHint *signal_hint,
     {
       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);
+      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);
     }
@@ -343,7 +343,7 @@ property_event_listener (GSignalInvocationHint *signal_hint,
     {
       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);
+      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);
     }
@@ -524,7 +524,7 @@ 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);
+  s = atk_dbus_object_to_path (child, FALSE);
   if (s == NULL)
     {
       g_free (s);
diff --git a/atk-adaptor/hyperlink-adaptor.c b/atk-adaptor/hyperlink-adaptor.c
index 34d51a7..b839a0a 100644
--- a/atk-adaptor/hyperlink-adaptor.c
+++ b/atk-adaptor/hyperlink-adaptor.c
@@ -28,6 +28,16 @@
 #include "accessible-marshaller.h"
 #include "common/spi-dbus.h"
 
+static AtkHyperlink *
+get_hyperlink (void *user_data)
+{
+  if (ATK_IS_HYPERLINK (user_data))
+    return ATK_HYPERLINK (user_data);
+  if (ATK_IS_HYPERLINK_IMPL (user_data))
+    return atk_hyperlink_impl_get_hyperlink (ATK_HYPERLINK_IMPL (user_data));
+  return NULL;
+}
+
 static dbus_bool_t
 impl_get_nAnchors (DBusMessageIter * iter, void *user_data)
 {
@@ -41,7 +51,7 @@ static dbus_bool_t
 impl_get_startIndex (DBusMessageIter * iter,
                      void *user_data)
 {
-  AtkHyperlink *link = (AtkHyperlink *) user_data;
+  AtkHyperlink *link = get_hyperlink (user_data);
   g_return_val_if_fail (ATK_IS_HYPERLINK (user_data), FALSE);
   return droute_return_v_int32 (iter, atk_hyperlink_get_start_index (link));
 }
@@ -49,7 +59,7 @@ impl_get_startIndex (DBusMessageIter * iter,
 static dbus_bool_t
 impl_get_endIndex (DBusMessageIter * iter, void *user_data)
 {
-  AtkHyperlink *link = (AtkHyperlink *) user_data;
+  AtkHyperlink *link = get_hyperlink (user_data);
   g_return_val_if_fail (ATK_IS_HYPERLINK (user_data), FALSE);
   return droute_return_v_int32 (iter, atk_hyperlink_get_end_index (link));
 }
@@ -57,7 +67,7 @@ impl_get_endIndex (DBusMessageIter * iter, void *user_data)
 static DBusMessage *
 impl_getObject (DBusConnection * bus, DBusMessage * message, void *user_data)
 {
-  AtkHyperlink *link = (AtkHyperlink *) user_data;
+  AtkHyperlink *link = get_hyperlink (user_data);
   DBusError error;
   dbus_int32_t i;
   AtkObject *atk_object;
@@ -71,13 +81,13 @@ 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_object (message, atk_object, FALSE);
+  return spi_dbus_return_sub_object (message, G_OBJECT (atk_object), G_OBJECT (link), FALSE);
 }
 
 static DBusMessage *
 impl_getURI (DBusConnection * bus, DBusMessage * message, void *user_data)
 {
-  AtkHyperlink *link = (AtkHyperlink *) user_data;
+  AtkHyperlink *link = get_hyperlink (user_data);
   dbus_int32_t i;
   DBusError error;
   gchar *rv;
@@ -87,8 +97,7 @@ impl_getURI (DBusConnection * bus, DBusMessage * message, void *user_data)
                         droute_not_yet_handled_error (message));
   dbus_error_init (&error);
   if (!dbus_message_get_args
-      (message, &error, DBUS_TYPE_INT32, &i, DBUS_TYPE_INT32, &i,
-       DBUS_TYPE_INVALID))
+      (message, &error, DBUS_TYPE_INT32, &i, DBUS_TYPE_INVALID))
     {
       return droute_invalid_arguments_error (message);
     }
@@ -109,7 +118,7 @@ impl_getURI (DBusConnection * bus, DBusMessage * message, void *user_data)
 static DBusMessage *
 impl_isValid (DBusConnection * bus, DBusMessage * message, void *user_data)
 {
-  AtkHyperlink *link = (AtkHyperlink *) user_data;
+  AtkHyperlink *link = get_hyperlink (user_data);
   dbus_bool_t rv;
   DBusMessage *reply;
 
diff --git a/atk-adaptor/hypertext-adaptor.c b/atk-adaptor/hypertext-adaptor.c
index af3334e..452cc76 100644
--- a/atk-adaptor/hypertext-adaptor.c
+++ b/atk-adaptor/hypertext-adaptor.c
@@ -26,6 +26,7 @@
 #include <droute/droute.h>
 
 #include "common/spi-dbus.h"
+#include "accessible-marshaller.h"
 
 static DBusMessage *
 impl_getNLinks (DBusConnection * bus, DBusMessage * message, void *user_data)
@@ -63,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 NULL;	// TODO
-  //return spi_dbus_return_object (message, ATK_OBJECT (link), FALSE);
+  return spi_dbus_return_hyperlink (message, link, ATK_OBJECT(hypertext), TRUE);
 }
 
 static DBusMessage *
diff --git a/atk-adaptor/selection-adaptor.c b/atk-adaptor/selection-adaptor.c
index 31b4c84..1fee235 100644
--- a/atk-adaptor/selection-adaptor.c
+++ b/atk-adaptor/selection-adaptor.c
@@ -67,7 +67,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);
+  return spi_dbus_return_object (message, atk_object, TRUE, TRUE);
 }
 
 static DBusMessage *
diff --git a/atk-adaptor/table-adaptor.c b/atk-adaptor/table-adaptor.c
index 4356e71..845c1a1 100644
--- a/atk-adaptor/table-adaptor.c
+++ b/atk-adaptor/table-adaptor.c
@@ -109,7 +109,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);
+  return spi_dbus_return_object (message, obj, TRUE, TRUE);
 }
 
 static DBusMessage *
@@ -332,7 +332,7 @@ impl_getRowHeader (DBusConnection * bus, DBusMessage * message,
       return droute_invalid_arguments_error (message);
     }
   obj = atk_table_get_row_header (table, row);
-  return spi_dbus_return_object (message, obj, FALSE);
+  return spi_dbus_return_object (message, obj, TRUE, TRUE);
 }
 
 static DBusMessage *
@@ -353,7 +353,7 @@ impl_getColumnHeader (DBusConnection * bus, DBusMessage * message,
       return droute_invalid_arguments_error (message);
     }
   obj = atk_table_get_column_header (table, column);
-  return spi_dbus_return_object (message, obj, FALSE);
+  return spi_dbus_return_object (message, obj, TRUE, TRUE);
 }
 
 static DBusMessage *
@@ -639,10 +639,10 @@ impl_getRowColumnExtentsAtIndex (DBusConnection * bus, DBusMessage * message,
   reply = dbus_message_new_method_return (message);
   if (reply)
     {
-      dbus_message_append_args (reply, DBUS_TYPE_INT32, row, DBUS_TYPE_INT32,
-                                column, DBUS_TYPE_INT32, row_extents,
-                                DBUS_TYPE_INT32, col_extents,
-                                DBUS_TYPE_BOOLEAN, is_selected,
+      dbus_message_append_args (reply, DBUS_TYPE_INT32, &row, DBUS_TYPE_INT32,
+                                &column, DBUS_TYPE_INT32, &row_extents,
+                                DBUS_TYPE_INT32, &col_extents,
+                                DBUS_TYPE_BOOLEAN, &is_selected,
                                 DBUS_TYPE_BOOLEAN, &ret, DBUS_TYPE_INVALID);
     }
   return reply;
diff --git a/atk-adaptor/tree-adaptor.c b/atk-adaptor/tree-adaptor.c
index c292bbd..f4cc660 100644
--- a/atk-adaptor/tree-adaptor.c
+++ b/atk-adaptor/tree-adaptor.c
@@ -39,7 +39,9 @@
 static void
 append_accessible_hf (gpointer key, gpointer obj_data, gpointer iter)
 {
-  spi_atk_append_accessible (ATK_OBJECT(obj_data), iter);
+  /* Make sure it isn't a hyperlink */
+  if (ATK_IS_OBJECT (obj_data))
+    spi_atk_append_accessible (ATK_OBJECT(obj_data), iter);
 }
 
 /*---------------------------------------------------------------------------*/
@@ -102,7 +104,7 @@ impl_getRoot (DBusConnection *bus, DBusMessage *message, void *user_data)
                                       DBUS_ERROR_FAILED,
                                       "No root accessible available");
     }
-  path = atk_dbus_object_to_path (root);
+  path = atk_dbus_object_to_path (root, FALSE);
   if (!path)
     {
       reply = dbus_message_new_error (message,



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