- AtkObject *current, *tmp;
- GQueue *stack;
- GList *uplist = NULL;
- guint i, ref;
- gboolean recurse;
-
-
- /* Export subtree including object itself */
- /*========================================*/
- ref = atk_dbus_object_to_ref (accessible);
- if (ref)
- return ref;
-
- stack = g_queue_new ();
-
- current = g_object_ref (accessible);
- ref = export (&uplist, current);
- g_queue_push_head (stack, GINT_TO_POINTER (0));
-
- /*
- * The index held on the stack is the next child node
- * that needs processing at the corresponding level in the tree.
- */
- while (!g_queue_is_empty (stack))
- {
- /* This while loop finds the next node that needs processing,
- * if one exists.
- */
- i = GPOINTER_TO_INT(g_queue_peek_head (stack));
- recurse = FALSE;
- while (i < atk_object_get_n_accessible_children (current) &&
- recurse == FALSE)
- {
- tmp = atk_object_ref_accessible_child (current, i);
- if (!atk_dbus_object_to_ref (tmp))
- {
- recurse = TRUE;
- }
- else
- {
- i++;
- g_object_unref (G_OBJECT (tmp));
- }
- }
- if (recurse)
- {
- /* Still children to process */
- current = tmp;
- export (&uplist, current);
- /* Update parent nodes next child index */
- g_queue_peek_head_link (stack)->data = GINT_TO_POINTER (i+1);
- /* Push a new child index for the current node */
- g_queue_push_head (stack, GINT_TO_POINTER (0));
- }
- else
- {
- /* No more children, move to parent */
- tmp = current;
- current = atk_object_get_parent (current);
- g_object_unref (G_OBJECT (tmp));
- g_queue_pop_head (stack);
- }
- }
-
- /* Export all neccessary ancestors of the object */
- /*===============================================*/
- current = atk_object_get_parent (accessible);
- while (current && !atk_dbus_object_to_ref (current))
- {
- export (&uplist, current);
- }
-
- spi_emit_cache_update (uplist, atk_adaptor_app_data->bus);
- g_list_free (uplist);
- return ref;