summaryrefslogtreecommitdiff
path: root/atspi/atspi-accessible.c
diff options
context:
space:
mode:
Diffstat (limited to 'atspi/atspi-accessible.c')
-rw-r--r--atspi/atspi-accessible.c103
1 files changed, 60 insertions, 43 deletions
diff --git a/atspi/atspi-accessible.c b/atspi/atspi-accessible.c
index 9c21f446..a5d2928d 100644
--- a/atspi/atspi-accessible.c
+++ b/atspi/atspi-accessible.c
@@ -104,6 +104,8 @@ atspi_accessible_init (AtspiAccessible *accessible)
accessible_count++;
printf("at-spi: init: %d objects\n", accessible_count);
#endif
+
+ accessible->children = g_ptr_array_new_with_free_func (g_object_unref);
}
static void
@@ -112,6 +114,7 @@ atspi_accessible_dispose (GObject *object)
AtspiAccessible *accessible = ATSPI_ACCESSIBLE (object);
AtspiEvent e;
AtspiAccessible *parent;
+ gint i;
/* TODO: Only fire if object not already marked defunct */
memset (&e, 0, sizeof (e));
@@ -128,23 +131,30 @@ atspi_accessible_dispose (GObject *object)
}
parent = accessible->accessible_parent;
- if (parent && parent->children)
+ if (parent)
+ {
+ accessible->accessible_parent = NULL;
+ if (parent->children)
+ g_ptr_array_remove (parent->children, accessible);
+ g_object_unref (parent);
+ }
+
+ while (accessible->children && accessible->children->len > 0)
{
- GList*ls = g_list_find (parent->children, accessible);
- if(ls)
+ int index = accessible->children->len - 1;
+ AtspiAccessible *child = g_ptr_array_index (accessible->children, index);
+ if (child && child->accessible_parent == accessible)
{
- gboolean replace = (ls == parent->children);
- ls = g_list_remove (ls, accessible);
- if (replace)
- parent->children = ls;
- g_object_unref (object);
+ child->accessible_parent = NULL;
+ g_object_unref (accessible);
}
+ g_ptr_array_remove_index (accessible->children, index);
}
- if (parent)
+ if (accessible->children)
{
- g_object_unref (parent);
- accessible->accessible_parent = NULL;
+ g_ptr_array_free (accessible->children, TRUE);
+ accessible->children = NULL;
}
G_OBJECT_CLASS (atspi_accessible_parent_class) ->dispose (object);
@@ -165,8 +175,7 @@ atspi_accessible_finalize (GObject *object)
g_print ("at-spi: finalize: %d objects\n", accessible_count);
#endif
- G_OBJECT_CLASS (atspi_accessible_parent_class)
- ->finalize (object);
+ G_OBJECT_CLASS (atspi_accessible_parent_class)->finalize (object);
}
static void
@@ -419,7 +428,10 @@ atspi_accessible_get_child_count (AtspiAccessible *obj, GError **error)
return ret;
}
- return g_list_length (obj->children);
+ if (!obj->children)
+ return 0; /* assume it's disposed */
+
+ return obj->children->len;
}
/**
@@ -438,22 +450,33 @@ atspi_accessible_get_child_at_index (AtspiAccessible *obj,
GError **error)
{
AtspiAccessible *child;
+ DBusMessage *reply;
g_return_val_if_fail (obj != NULL, NULL);
- if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_CHILDREN))
+ if (_atspi_accessible_test_cache (obj, ATSPI_CACHE_CHILDREN))
{
- DBusMessage *reply;
- reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible,
- "GetChildAtIndex", error, "i",
- child_index);
- return _atspi_dbus_return_accessible_from_message (reply);
+ if (!obj->children)
+ return NULL; /* assume disposed */
+
+ child = g_ptr_array_index (obj->children, child_index);
+ if (child)
+ return g_object_ref (child);
}
- child = g_list_nth_data (obj->children, child_index);
+ reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible,
+ "GetChildAtIndex", error, "i", child_index);
+ child = _atspi_dbus_return_accessible_from_message (reply);
+
if (!child)
return NULL;
- return g_object_ref (child);
+ if (_atspi_accessible_test_cache (obj, ATSPI_CACHE_CHILDREN))
+ {
+ if (child_index >= obj->children->len)
+ g_ptr_array_set_size (obj->children, child_index + 1);
+ g_ptr_array_index (obj->children, child_index) = g_object_ref (child);
+ }
+ return child;
}
/**
@@ -469,28 +492,22 @@ atspi_accessible_get_child_at_index (AtspiAccessible *obj,
gint
atspi_accessible_get_index_in_parent (AtspiAccessible *obj, GError **error)
{
- GList *l;
gint i = 0;
+ dbus_uint32_t ret = -1;
g_return_val_if_fail (obj != NULL, -1);
if (!obj->accessible_parent) return -1;
- if (!_atspi_accessible_test_cache (obj->accessible_parent,
+ if (_atspi_accessible_test_cache (obj->accessible_parent,
ATSPI_CACHE_CHILDREN))
{
- dbus_uint32_t ret = -1;
- _atspi_dbus_call (obj, atspi_interface_accessible,
- "GetIndexInParent", NULL, "=>u", &ret);
- return ret;
+ for (i = 0; i < obj->accessible_parent->children->len; i++)
+ if (g_ptr_array_index (obj->accessible_parent->children, i) == obj)
+ return i;
}
- l = obj->accessible_parent->children;
- while (l)
- {
- if (l->data == obj) return i;
- l = g_list_next (l);
- i++;
- }
- return -1;
+ _atspi_dbus_call (obj, atspi_interface_accessible,
+ "GetIndexInParent", NULL, "=>u", &ret);
+ return ret;
}
typedef struct
@@ -1442,21 +1459,21 @@ atspi_accessible_set_cache_mask (AtspiAccessible *accessible, AtspiCache mask)
/**
* atspi_accessible_clear_cache:
- * @accessible: The #AtspiAccessible whose cache to clear.
+ * @obj: The #AtspiAccessible whose cache to clear.
*
* Clears the cached information for the given accessible and all of its
* descendants.
*/
void
-atspi_accessible_clear_cache (AtspiAccessible *accessible)
+atspi_accessible_clear_cache (AtspiAccessible *obj)
{
- GList *l;
+ int i;
- if (accessible)
+ if (obj)
{
- accessible->cached_properties = ATSPI_CACHE_NONE;
- for (l = accessible->children; l; l = l->next)
- atspi_accessible_clear_cache (l->data);
+ obj->cached_properties = ATSPI_CACHE_NONE;
+ for (i = 0; i < obj->children->len; i++)
+ atspi_accessible_clear_cache (g_ptr_array_index (obj->children, i));
}
}