2 * AT-SPI - Assistive Technology Service Provider Interface
3 * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
5 * Copyright 2001, 2002 Sun Microsystems Inc.,
6 * Copyright 2001, 2002 Ximian, Inc.
7 * Copyright 2010, 2011 Novell, Inc.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
25 #include "atspi-private.h"
26 #include "atspi-accessible-private.h"
30 static gboolean enable_caching = FALSE;
31 static guint quark_locale;
34 atspi_action_interface_init (AtspiAction *action)
39 atspi_collection_interface_init (AtspiCollection *component)
44 atspi_component_interface_init (AtspiComponent *component)
49 atspi_document_interface_init (AtspiDocument *document)
54 atspi_editable_text_interface_init (AtspiEditableText *editable_text)
59 atspi_hypertext_interface_init (AtspiHypertext *hypertext)
64 atspi_image_interface_init (AtspiImage *image)
69 atspi_selection_interface_init (AtspiSelection *selection)
74 atspi_table_interface_init (AtspiTable *table)
79 atspi_table_cell_interface_init (AtspiTableCell *cell)
84 atspi_text_interface_init (AtspiText *text)
89 atspi_value_interface_init (AtspiValue *value)
93 G_DEFINE_TYPE_WITH_CODE (AtspiAccessible, atspi_accessible, ATSPI_TYPE_OBJECT,
94 G_ADD_PRIVATE (AtspiAccessible)
95 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_ACTION, atspi_action_interface_init)
96 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_COLLECTION, atspi_collection_interface_init)
97 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_COMPONENT, atspi_component_interface_init)
98 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_DOCUMENT, atspi_document_interface_init)
99 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_EDITABLE_TEXT, atspi_editable_text_interface_init)
100 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_HYPERTEXT, atspi_hypertext_interface_init)
101 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_IMAGE, atspi_image_interface_init)
102 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_SELECTION, atspi_selection_interface_init)
103 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_TABLE, atspi_table_interface_init)
104 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_TABLE_CELL, atspi_table_cell_interface_init)
105 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_TEXT, atspi_text_interface_init)
106 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_VALUE, atspi_value_interface_init))
108 #ifdef DEBUG_REF_COUNTS
109 static gint accessible_count = 0;
113 atspi_accessible_init (AtspiAccessible *accessible)
115 #ifdef DEBUG_REF_COUNTS
117 g_hash_table_insert (_atspi_get_live_refs (), accessible, NULL);
118 g_print("at-spi: init: %d objects\n", accessible_count);
121 accessible->priv = atspi_accessible_get_instance_private (accessible);
125 atspi_accessible_dispose (GObject *object)
127 AtspiAccessible *accessible = ATSPI_ACCESSIBLE (object);
129 AtspiAccessible *parent;
133 /* TODO: Only fire if object not already marked defunct */
134 memset (&e, 0, sizeof (e));
135 e.type = "object:state-changed:defunct";
136 e.source = accessible;
139 _atspi_send_event (&e);
141 if (accessible->states)
143 g_object_unref (accessible->states);
144 accessible->states = NULL;
147 parent = accessible->accessible_parent;
148 if (parent && parent->children)
150 GList*ls = g_list_find (parent->children, accessible);
153 gboolean replace = (ls == parent->children);
154 ls = g_list_remove (ls, accessible);
156 parent->children = ls;
157 g_object_unref (object);
163 g_object_unref (parent);
164 accessible->accessible_parent = NULL;
167 children = accessible->children;
168 accessible->children = NULL;
169 for (l = children; l; l = l->next)
171 AtspiAccessible *child = l->data;
172 if (child && child->accessible_parent == accessible)
174 g_object_unref (accessible);
175 child->accessible_parent = NULL;
177 g_object_unref (child);
179 g_list_free (children);
181 G_OBJECT_CLASS (atspi_accessible_parent_class) ->dispose (object);
185 atspi_accessible_finalize (GObject *object)
187 AtspiAccessible *accessible = ATSPI_ACCESSIBLE (object);
189 g_free (accessible->description);
190 g_free (accessible->name);
191 if (accessible->attributes)
192 g_hash_table_unref (accessible->attributes);
194 if (accessible->priv->cache)
195 g_hash_table_destroy (accessible->priv->cache);
197 #ifdef DEBUG_REF_COUNTS
199 g_hash_table_remove (_atspi_get_live_refs (), accessible);
200 g_print ("at-spi: finalize: %d objects\n", accessible_count);
203 G_OBJECT_CLASS (atspi_accessible_parent_class)
208 atspi_accessible_class_init (AtspiAccessibleClass *klass)
210 GObjectClass *object_class = G_OBJECT_CLASS (klass);
212 object_class->dispose = atspi_accessible_dispose;
213 object_class->finalize = atspi_accessible_finalize;
215 quark_locale = g_quark_from_string ("accessible-locale");
219 * atspi_accessible_get_name:
220 * @obj: a pointer to the #AtspiAccessible object on which to operate.
222 * Gets the name of an #AtspiAccessible object.
224 * Returns: a UTF-8 string indicating the name of the #AtspiAccessible object
225 * or NULL on exception.
228 atspi_accessible_get_name (AtspiAccessible *obj, GError **error)
230 g_return_val_if_fail (obj != NULL, g_strdup (""));
231 if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_NAME))
233 if (!_atspi_dbus_get_property (obj, atspi_interface_accessible, "Name", error,
235 return g_strdup ("");
236 _atspi_accessible_add_cache (obj, ATSPI_CACHE_NAME);
238 return g_strdup (obj->name);
243 * atspi_accessible_get_unique_id:
244 * @obj: a pointer to the #AtspiAccessible object on which to operate.
246 * Gets the identificator, uniquely identifying object, or NULL if an error occured.
248 * Returns: a UTF-8 string describing the #AtspiAccessible object
249 * or NULL on exception or NULL object passed.
252 atspi_accessible_get_unique_id(AtspiAccessible *obj, GError **error)
255 g_set_error(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "argument is null");
260 gchar *bus_name = atspi_accessible_get_bus_name(obj, error);
261 if (bus_name && bus_name[0]) {
262 gchar *path = atspi_accessible_get_path(obj, error);
264 id = g_strdup_printf("%s:%s", bus_name, path);
266 g_set_error(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "failed to get path");
270 g_set_error(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "failed to get bus name");
276 * atspi_accessible_get_bus_name:
277 * @obj: a pointer to the #AtspiAccessible object on which to operate.
279 * Gets the bus name, where object belongs.
281 * Returns: a UTF-8 string describing the #AtspiAccessible object's
282 * bus name or empty string on exception or NULL object passed.
285 atspi_accessible_get_bus_name(AtspiAccessible *obj, GError **error)
287 if (!obj || !obj->parent.app)
289 return g_strdup (obj->parent.app->bus_name);
293 * atspi_accessible_get_path:
294 * @obj: a pointer to the #AtspiAccessible object on which to operate.
296 * Gets the path, uniquely identifying object over its bus name.
298 * Returns: a UTF-8 string describing the #AtspiAccessible object
299 * or empty string on exception or NULL object passed.
302 atspi_accessible_get_path(AtspiAccessible *obj, GError **error)
304 static const char *prefix = "/org/a11y/atspi/accessible/";
305 static int prefix_len = 27;
309 AtspiObject *o = ATSPI_OBJECT (obj);
312 if (strncmp(o->path, prefix, prefix_len) == 0)
313 return g_strdup(o->path + prefix_len);
314 return g_strdup (o->path);
318 * atspi_accessible_get_navigable_at_point:
319 * @root: a pointer to the #AtspiAccessible to start search from.
320 * @x: a #gint specifying the x coordinate of the point in question.
321 * @y: a #gint specifying the y coordinate of the point in question.
322 * @ctype: the coordinate system of the point (@x, @y)
323 * (e.g. ATSPI_COORD_TYPE_WINDOW, ATSPI_COORD_TYPE_SCREEN).
325 * Finds the accessible element closest to user (highest in z-order), at a given coordinate within an #AtspiAccessible.
326 * This should be the element, that should be picked, when doing mouse click or finger tap at given coordinates.
328 * Returns: (nullable) (transfer full): a pointer to an
329 * #AtspiAccessible descendant (of any depth) of the specified component which
330 * contains the point (@x, @y), or NULL if no descendant contains
334 atspi_accessible_get_navigable_at_point (AtspiAccessible *root,
337 AtspiCoordType ctype, GError **error)
339 dbus_int32_t d_x = x, d_y = y;
340 dbus_uint32_t d_ctype = ctype;
342 AtspiAccessible *return_value = NULL;
343 unsigned char recurse = 0;
344 DBusMessageIter iter;
345 AtspiAccessible *deputy = NULL;
347 g_return_val_if_fail (root != NULL, NULL);
349 reply = _atspi_dbus_call_partial (root, atspi_interface_accessible, "GetNavigableAtPoint", error, "iiu", d_x, d_y, d_ctype);
350 // call failed, error is set, so we bail out
352 if (deputy) g_object_unref(deputy);
353 if (return_value) g_object_unref(return_value);
356 _ATSPI_DBUS_CHECK_SIG (reply, "(so)y(so)", NULL, NULL);
358 dbus_message_iter_init (reply, &iter);
359 AtspiAccessible *tmp = _atspi_dbus_return_accessible_from_iter (&iter);
361 unsigned char value = 0;
362 dbus_message_iter_get_basic (&iter, &value);
363 dbus_message_iter_next (&iter);
364 recurse = (value != 0);
366 /* keep deputy if tmp has deputy */
368 deputy = _atspi_dbus_return_accessible_from_iter (&iter);
370 dbus_message_unref(reply);
374 /* TODO: need to check deputy works for return value */
376 g_object_unref(return_value);
383 g_object_unref(return_value);
384 return_value = root = tmp;
390 * atspi_accessible_get_reading_material:
391 * @obj: a pointer to the #AtspiAccessible object on which to operate.
393 * Gets reading material
395 * Returns: reading material to be used screen-reader side. This is not stable.
396 * You have to handle all alocated memory as below on screen-reader side.
398 * AtspiAccessibleReadingMaterial *rm
399 * g_object_unref(rm->parent);
400 * g_object_unref(rm->described_by_accessible);
401 * g_hash_table_unref(rm->attributes);
403 * free(rm->labeled_by_name);
404 * free(rm->text_interface_name);
405 * free(rm->localized_role_name);
406 * free(rm->description);
409 AtspiAccessibleReadingMaterial *
410 atspi_accessible_get_reading_material (AtspiAccessible *obj, GError **error)
412 AtspiAccessible *parent;
413 AtspiAccessibleReadingMaterial *reading_material = NULL;
415 double current_value;
419 DBusMessageIter iter;
420 DBusMessageIter iter_array;
422 dbus_uint32_t *states;
423 dbus_int32_t index_in_parent;
424 dbus_int32_t child_count;
425 dbus_bool_t is_selected;
427 g_return_val_if_fail (obj != NULL, NULL);
429 reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetReadingMaterial", error, "");
431 _ATSPI_DBUS_CHECK_SIG (reply, "a{ss}sssuausiddddsibbii(so)auiui(so)", NULL, NULL);
433 reading_material = calloc(1, sizeof(AtspiAccessibleReadingMaterial));
434 if (!reading_material)
436 return reading_material;
439 dbus_message_iter_init (reply, &iter);
442 reading_material->attributes = _atspi_dbus_hash_from_iter (&iter);
443 dbus_message_iter_next (&iter);
446 dbus_message_iter_get_basic (&iter, &name);
447 reading_material->name = g_strdup (name);
448 dbus_message_iter_next (&iter);
450 /* get name of relation LABELED_BY */
451 dbus_message_iter_get_basic (&iter, &name);
452 reading_material->labeled_by_name = g_strdup (name);
453 dbus_message_iter_next (&iter);
455 /* get name of text interface */
456 dbus_message_iter_get_basic (&iter, &name);
457 reading_material->text_interface_name = g_strdup (name);
458 dbus_message_iter_next (&iter);
461 dbus_message_iter_get_basic (&iter, &role);
462 reading_material->role = role;
463 dbus_message_iter_next (&iter);
466 dbus_message_iter_recurse (&iter, &iter_array);
467 dbus_message_iter_get_fixed_array (&iter_array, &states, &count);
468 val = ((guint64)states [1]) << 32;
470 reading_material->states = val;
471 dbus_message_iter_next (&iter);
473 /* get localized role name */
474 dbus_message_iter_get_basic (&iter, &name);
475 reading_material->localized_role_name = g_strdup (name);
476 dbus_message_iter_next (&iter);
478 /* get child count */
479 dbus_message_iter_get_basic (&iter, &child_count);
480 reading_material->child_count = child_count;
481 dbus_message_iter_next (&iter);
483 /* get current value */
484 dbus_message_iter_get_basic (&iter, ¤t_value);
485 reading_material->value = current_value;
486 dbus_message_iter_next (&iter);
488 /* get minimum increment */
489 dbus_message_iter_get_basic (&iter, ¤t_value);
490 reading_material->increment = current_value;
491 dbus_message_iter_next (&iter);
493 /* get maximum value */
494 dbus_message_iter_get_basic (&iter, ¤t_value);
495 reading_material->upper = current_value;
496 dbus_message_iter_next (&iter);
498 /* get minimum value */
499 dbus_message_iter_get_basic (&iter, ¤t_value);
500 reading_material->lower = current_value;
501 dbus_message_iter_next (&iter);
503 /* get description */
504 dbus_message_iter_get_basic (&iter, &name);
505 reading_material->description = g_strdup (name);
506 dbus_message_iter_next (&iter);
508 /* get index in parent */
509 dbus_message_iter_get_basic (&iter, &index_in_parent);
510 reading_material->index_in_parent = index_in_parent;
511 dbus_message_iter_next (&iter);
513 /* get selected in parent */
514 dbus_message_iter_get_basic (&iter, &is_selected);
515 reading_material->is_selected_in_parent = is_selected;
516 dbus_message_iter_next (&iter);
518 /* get has checkbox child */
519 dbus_message_iter_get_basic (&iter, &is_selected);
520 reading_material->has_checkbox_child = is_selected;
521 dbus_message_iter_next (&iter);
523 /* get list children count */
524 dbus_message_iter_get_basic (&iter, &child_count);
525 reading_material->list_children_count = child_count;
526 dbus_message_iter_next (&iter);
528 /* get first selected child index */
529 dbus_message_iter_get_basic (&iter, &index_in_parent);
530 reading_material->first_selected_child_index = index_in_parent;
531 dbus_message_iter_next (&iter);
535 parent = _atspi_dbus_return_accessible_from_iter (&iter);
536 reading_material->parent = parent;
539 dbus_message_iter_recurse (&iter, &iter_array);
540 dbus_message_iter_get_fixed_array (&iter_array, &states, &count);
541 val = ((guint64)states [1]) << 32;
543 reading_material->parent_states = val;
544 dbus_message_iter_next (&iter);
546 /* get parent child count */
547 dbus_message_iter_get_basic (&iter, &child_count);
548 reading_material->parent_child_count = child_count;
549 dbus_message_iter_next (&iter);
551 /* get parent role */
552 dbus_message_iter_get_basic (&iter, &role);
553 reading_material->parent_role = role;
554 dbus_message_iter_next (&iter);
556 /* get parent selected child count */
557 dbus_message_iter_get_basic (&iter, &child_count);
558 reading_material->parent_selected_child_count = child_count;
559 dbus_message_iter_next (&iter);
561 ////////////////////////////////////////
562 /* get relation object - DESCRIBED_BY */
563 parent = _atspi_dbus_return_accessible_from_iter (&iter);
564 reading_material->described_by_accessible = parent;
566 return reading_material;
570 * atspi_accessible_get_default_label_info:
571 * @obj: a pointer to the #AtspiAccessible object would be window.
573 * Gets default label information
575 * Returns: default label information to be used screen-reader side.
576 * This is not stable. And this depends on toolkit side UI definition.
577 * The candidate of default label object could be changed by UI definition.
578 * You have to handle all alocated memory as below on screen-reader side.
580 * AtspiAccessibleDefaultLabelInfo *dli
581 * g_object_unref(dli->obj);
584 AtspiAccessibleDefaultLabelInfo *
585 atspi_accessible_get_default_label_info (AtspiAccessible *obj, GError **error)
587 AtspiAccessibleDefaultLabelInfo *default_label_info = NULL;
588 AtspiAccessible *default_label_object;
591 DBusMessageIter iter;
593 g_return_val_if_fail (obj != NULL, NULL);
595 reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetDefaultLabelInfo", error, "");
597 _ATSPI_DBUS_CHECK_SIG (reply, "(so)u", NULL, NULL);
599 default_label_info = calloc(1, sizeof(AtspiAccessibleDefaultLabelInfo));
600 if (!default_label_info)
602 return default_label_info;
605 dbus_message_iter_init (reply, &iter);
607 default_label_object = _atspi_dbus_return_accessible_from_iter (&iter);
608 default_label_info->obj = default_label_object;
610 dbus_message_iter_get_basic (&iter, &role);
611 default_label_info->role = role;
612 dbus_message_iter_next (&iter);
614 return default_label_info;
617 static unsigned char are_objects_on_the_same_bus(AtspiAccessible *obj1, AtspiAccessible *obj2)
619 const char *bus_name_1 = obj1->parent.app->bus_name;
620 const char *bus_name_2 = obj2->parent.app->bus_name;
621 return strcmp(bus_name_1, bus_name_2) == 0;
624 static unsigned char object_is_valid(AtspiAccessible *obj)
628 AtspiStateSet *ss = atspi_accessible_get_state_set(obj);
631 unsigned char valid = atspi_state_set_contains(ss, ATSPI_STATE_DEFUNCT) == 0;
637 NEIGHBOR_SEARCH_MODE_NORMAL = 0,
638 NEIGHBOR_SEARCH_MODE_RECURSE_FROM_ROOT = 1,
639 NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING = 2,
640 NEIGHBOR_SEARCH_MODE_RECURSE_TO_OUTSIDE = 3,
641 } GetNeighborSearchMode;
643 * atspi_accessible_get_neighbor:
644 * @root: a pointer to a #AtspiAccessible, which represents current root of subtree to search
645 * @start: a pointer to the #AtspiAccessible to start search from (can be null, which means start from root)
646 * @direction: direction, in which search (forward or backward)
648 * Calculates next (or previous) accessible element in logical order or null if none found.
650 * Returns: (nullable) (transfer full): a pointer to an
651 * #AtspiAccessible element, which is next (previous) in logical order or null if none found.
654 atspi_accessible_get_neighbor (AtspiAccessible *root,
655 AtspiAccessible *start,
656 AtspiNeighborSearchDirection direction,
659 g_return_val_if_fail (object_is_valid(root), NULL);
660 if (!object_is_valid(start))
662 const char *root_path = ATSPI_OBJECT(root)->path;
663 AtspiAccessible *return_value = NULL;
665 unsigned char recurse;
666 GetNeighborSearchMode search_mode = NEIGHBOR_SEARCH_MODE_NORMAL;
667 GQueue *children_root_stack = g_queue_new();
668 DBusMessageIter iter;
671 const char *path = are_objects_on_the_same_bus(root, start) ? root_path : "";
672 DBusMessage *reply = _atspi_dbus_call_partial (start, atspi_interface_accessible, "GetNeighbor", error, "sii", path, (int)direction, (int)search_mode);
673 // call failed, error is set, so we bail out
676 _ATSPI_DBUS_CHECK_SIG (reply, "(so)y", error, NULL);
677 dbus_message_iter_init (reply, &iter);
678 AtspiAccessible *ret = _atspi_dbus_return_accessible_from_iter (&iter);
680 unsigned char value = 0;
681 dbus_message_iter_get_basic (&iter, &value);
682 dbus_message_iter_next (&iter);
683 recurse = (value != 0);
685 dbus_message_unref(reply);
687 // got return value and request for recursive search, it means ret is on another bridge, than start
688 // thus we're recursing. should the recurse failed to find anything it will end with
689 if (ret && recurse) {
690 g_object_unref(G_OBJECT(start));
693 if (are_objects_on_the_same_bus(root, ret))
695 search_mode = NEIGHBOR_SEARCH_MODE_RECURSE_TO_OUTSIDE;
699 g_queue_push_tail(children_root_stack, ret);
700 search_mode = NEIGHBOR_SEARCH_MODE_RECURSE_FROM_ROOT;
704 // found the one we've been looking for
706 g_object_unref(G_OBJECT(start));
711 // we've stepped into different bridges previously and now we're going back to the last one
712 // and continuing search where we left
713 if (!g_queue_is_empty(children_root_stack)) {
714 g_object_unref(G_OBJECT(start));
715 start = g_queue_pop_tail(children_root_stack);
717 search_mode = NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING;
720 // there's no more bridges to check, but we might have started from one
721 // in that case there might be bridges "below" start, which we yet have to visit
722 if (!are_objects_on_the_same_bus(root, start)) {
723 unsigned char continue_loop = 1;
724 while(continue_loop) {
725 AtspiAccessible *parent = atspi_accessible_get_parent(start, NULL);
726 continue_loop = parent ? are_objects_on_the_same_bus(start, parent) : 0;
727 g_object_unref(G_OBJECT(start));
731 // going up thru parents put us in weird place (we didnt meet root on the way)
736 // start object now points to different bridge and must be treated as "resume after recursing"
737 search_mode = NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING;
742 g_object_unref(start);
745 while(!g_queue_is_empty(children_root_stack))
746 g_object_unref(g_queue_pop_tail(children_root_stack));
747 g_queue_free(children_root_stack);
753 * atspi_accessible_get_description:
754 * @obj: a pointer to the #AtspiAccessible object on which to operate.
756 * Gets the description of an #AtspiAccessible object.
758 * Returns: a UTF-8 string describing the #AtspiAccessible object
759 * or NULL on exception.
762 atspi_accessible_get_description (AtspiAccessible *obj, GError **error)
764 g_return_val_if_fail (obj != NULL, g_strdup (""));
766 if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_DESCRIPTION))
768 if (!_atspi_dbus_get_property (obj, atspi_interface_accessible,
769 "Description", error, "s",
771 return g_strdup ("");
772 _atspi_accessible_add_cache (obj, ATSPI_CACHE_DESCRIPTION);
774 return g_strdup (obj->description);
777 const char *str_parent = "Parent";
780 * atspi_accessible_get_parent:
781 * @obj: a pointer to the #AtspiAccessible object to query.
783 * Gets an #AtspiAccessible object's parent container.
785 * Returns: (nullable) (transfer full): a pointer to the
786 * #AtspiAccessible object which contains the given
787 * #AtspiAccessible instance, or NULL if the @obj has no
792 atspi_accessible_get_parent (AtspiAccessible *obj, GError **error)
794 g_return_val_if_fail (obj != NULL, NULL);
796 if (obj->parent.app &&
797 !_atspi_accessible_test_cache (obj, ATSPI_CACHE_PARENT))
799 DBusMessage *message, *reply;
800 DBusMessageIter iter, iter_variant;
801 message = dbus_message_new_method_call (obj->parent.app->bus_name,
803 DBUS_INTERFACE_PROPERTIES, "Get");
806 dbus_message_append_args (message, DBUS_TYPE_STRING, &atspi_interface_accessible,
807 DBUS_TYPE_STRING, &str_parent,
809 reply = _atspi_dbus_send_with_reply_and_block (message, error);
812 if (strcmp (dbus_message_get_signature (reply), "v") != 0)
814 dbus_message_unref (reply);
817 dbus_message_iter_init (reply, &iter);
818 dbus_message_iter_recurse (&iter, &iter_variant);
819 obj->accessible_parent = _atspi_dbus_return_accessible_from_iter (&iter_variant);
820 dbus_message_unref (reply);
821 _atspi_accessible_add_cache (obj, ATSPI_CACHE_PARENT);
823 if (!obj->accessible_parent)
825 return g_object_ref (obj->accessible_parent);
829 * atspi_accessible_get_child_count:
830 * @obj: a pointer to the #AtspiAccessible object on which to operate.
832 * Gets the number of children contained by an #AtspiAccessible object.
834 * Returns: a #long indicating the number of #AtspiAccessible children
835 * contained by an #AtspiAccessible object or -1 on exception.
839 atspi_accessible_get_child_count (AtspiAccessible *obj, GError **error)
841 g_return_val_if_fail (obj != NULL, -1);
843 if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_CHILDREN))
846 if (!_atspi_dbus_get_property (obj, atspi_interface_accessible,
847 "ChildCount", error, "i", &ret))
852 return g_list_length (obj->children);
856 * atspi_accessible_get_child_at_index:
857 * @obj: a pointer to the #AtspiAccessible object on which to operate.
858 * @child_index: a #long indicating which child is specified.
860 * Gets the #AtspiAccessible child of an #AtspiAccessible object at a given index.
862 * Returns: (transfer full): a pointer to the #AtspiAccessible child object at
863 * index @child_index or NULL on exception.
866 atspi_accessible_get_child_at_index (AtspiAccessible *obj,
870 AtspiAccessible *child;
872 g_return_val_if_fail (obj != NULL, NULL);
874 if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_CHILDREN))
877 reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible,
878 "GetChildAtIndex", error, "i",
880 return _atspi_dbus_return_accessible_from_message (reply);
883 child = g_list_nth_data (obj->children, child_index);
886 return g_object_ref (child);
890 * atspi_accessible_get_index_in_parent:
891 * @obj: a pointer to the #AtspiAccessible object on which to operate.
893 * Gets the index of an #AtspiAccessible object within its parent's
894 * #AtspiAccessible children list.
896 * Returns: a #glong indicating the index of the #AtspiAccessible object
898 * or -1 if @obj has no containing parent or on exception.
901 atspi_accessible_get_index_in_parent (AtspiAccessible *obj, GError **error)
906 g_return_val_if_fail (obj != NULL, -1);
907 if (_atspi_accessible_test_cache (obj, ATSPI_CACHE_PARENT) &&
908 !obj->accessible_parent)
910 if (!obj->accessible_parent ||
911 !_atspi_accessible_test_cache (obj->accessible_parent,
912 ATSPI_CACHE_CHILDREN))
914 dbus_int32_t ret = -1;
915 _atspi_dbus_call (obj, atspi_interface_accessible,
916 "GetIndexInParent", NULL, "=>i", &ret);
920 l = obj->accessible_parent->children;
923 if (l->data == obj) return i;
934 } Accessibility_Relation;
937 * atspi_accessible_get_relation_set:
938 * @obj: a pointer to the #AtspiAccessible object on which to operate.
940 * Gets the set of #AtspiRelation objects which describes this #AtspiAccessible object's
941 * relationships with other #AtspiAccessible objects.
943 * Returns: (element-type AtspiRelation*) (transfer full): a #GArray of
944 * #AtspiRelation pointers or NULL on exception.
947 atspi_accessible_get_relation_set (AtspiAccessible *obj, GError **error)
950 DBusMessageIter iter, iter_array;
953 g_return_val_if_fail (obj != NULL, NULL);
955 reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetRelationSet", error, "");
958 _ATSPI_DBUS_CHECK_SIG (reply, "a(ua(so))", error, NULL);
960 ret = g_array_new (TRUE, TRUE, sizeof (AtspiRelation *));
961 dbus_message_iter_init (reply, &iter);
962 dbus_message_iter_recurse (&iter, &iter_array);
963 while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
965 AtspiRelation *relation;
966 relation = _atspi_relation_new_from_iter (&iter_array);
967 ret = g_array_append_val (ret, relation);
968 dbus_message_iter_next (&iter_array);
970 dbus_message_unref (reply);
975 * atspi_accessible_get_role:
976 * @obj: a pointer to the #AtspiAccessible object on which to operate.
978 * Gets the UI role played by an #AtspiAccessible object.
979 * This role's name can be obtained via atspi_accessible_get_role_name ().
981 * Returns: the #AtspiRole of an #AtspiAccessible object.
985 atspi_accessible_get_role (AtspiAccessible *obj, GError **error)
987 g_return_val_if_fail (obj != NULL, ATSPI_ROLE_INVALID);
989 if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_ROLE))
992 /* TODO: Make this a property */
993 if (_atspi_dbus_call (obj, atspi_interface_accessible, "GetRole", error, "=>u", &role))
996 _atspi_accessible_add_cache (obj, ATSPI_CACHE_ROLE);
1003 * atspi_accessible_get_role_name:
1004 * @obj: a pointer to the #AtspiAccessible object on which to operate.
1006 * Gets a UTF-8 string corresponding to the name of the role played by an object.
1007 * This method will return useful values for roles that fall outside the
1008 * enumeration used in atspi_accessible_get_role ().
1010 * Returns: a UTF-8 string specifying the type of UI role played by an
1011 * #AtspiAccessible object.
1015 atspi_accessible_get_role_name (AtspiAccessible *obj, GError **error)
1017 gchar *retval = NULL;
1020 g_return_val_if_fail (obj != NULL, NULL);
1022 role = atspi_accessible_get_role (obj, error);
1023 if (role >= 0 && role < ATSPI_ROLE_COUNT && role != ATSPI_ROLE_EXTENDED)
1024 return atspi_role_get_name (role);
1026 _atspi_dbus_call (obj, atspi_interface_accessible, "GetRoleName", error, "=>s", &retval);
1029 retval = g_strdup ("");
1035 * atspi_accessible_get_localized_role_name:
1036 * @obj: a pointer to the #AtspiAccessible object on which to operate.
1038 * Gets a UTF-8 string corresponding to the name of the role played by an
1039 * object, translated to the current locale.
1040 * This method will return useful values for roles that fall outside the
1041 * enumeration used in atspi_accessible_getRole ().
1043 * Returns: a localized, UTF-8 string specifying the type of UI role played
1044 * by an #AtspiAccessible object.
1048 atspi_accessible_get_localized_role_name (AtspiAccessible *obj, GError **error)
1050 char *retval = NULL;
1052 g_return_val_if_fail (obj != NULL, NULL);
1054 _atspi_dbus_call (obj, atspi_interface_accessible, "GetLocalizedRoleName", error, "=>s", &retval);
1057 return g_strdup ("");
1062 static AtspiStateSet *
1065 AtspiStateSet *set = atspi_state_set_new (NULL);
1066 atspi_state_set_add (set, ATSPI_STATE_DEFUNCT);
1071 * atspi_accessible_get_state_set:
1072 * @obj: a pointer to the #AtspiAccessible object on which to operate.
1074 * Gets the states currently held by an object.
1076 * Returns: (transfer full): a pointer to an #AtspiStateSet representing an
1077 * object's current state set.
1080 atspi_accessible_get_state_set (AtspiAccessible *obj)
1082 /* TODO: Should take a GError **, but would be an API break */
1083 if (!obj->parent.app || !obj->parent.app->bus)
1084 return defunct_set ();
1086 if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_STATES))
1089 DBusMessageIter iter;
1090 reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible,
1091 "GetState", NULL, "");
1092 _ATSPI_DBUS_CHECK_SIG (reply, "au", NULL, defunct_set ());
1093 dbus_message_iter_init (reply, &iter);
1094 _atspi_dbus_set_state (obj, &iter);
1095 dbus_message_unref (reply);
1096 _atspi_accessible_add_cache (obj, ATSPI_CACHE_STATES);
1098 return g_object_ref (obj->states);
1102 * atspi_accessible_get_attributes:
1103 * @obj: The #AtspiAccessible being queried.
1105 * Gets the #AttributeSet representing any assigned
1106 * name-value pair attributes or annotations for this object.
1107 * For typographic, textual, or textually-semantic attributes, see
1108 * atspi_text_get_attributes instead.
1110 * Returns: (element-type gchar* gchar*) (transfer full): The name-value-pair
1111 * attributes assigned to this object.
1114 atspi_accessible_get_attributes (AtspiAccessible *obj, GError **error)
1116 DBusMessage *message;
1118 g_return_val_if_fail (obj != NULL, NULL);
1120 if (obj->priv->cache)
1122 GValue *val = g_hash_table_lookup (obj->priv->cache, "Attributes");
1124 return g_value_dup_boxed (val);
1127 if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_ATTRIBUTES))
1129 message = _atspi_dbus_call_partial (obj, atspi_interface_accessible,
1130 "GetAttributes", error, "");
1131 obj->attributes = _atspi_dbus_return_hash_from_message (message);
1132 _atspi_accessible_add_cache (obj, ATSPI_CACHE_ATTRIBUTES);
1135 if (!obj->attributes)
1137 return g_hash_table_ref (obj->attributes);
1141 add_to_attribute_array (gpointer key, gpointer value, gpointer data)
1143 GArray **array = (GArray **)data;
1144 gchar *str = g_strconcat (key, ":", value, NULL);
1145 *array = g_array_append_val (*array, str);
1149 * atspi_accessible_get_attributes_as_array:
1150 * @obj: The #AtspiAccessible being queried.
1152 * Gets a #GArray representing any assigned
1153 * name-value pair attributes or annotations for this object.
1154 * For typographic, textual, or textually-semantic attributes, see
1155 * atspi_text_get_attributes_as_array instead.
1157 * Returns: (element-type gchar*) (transfer full): The name-value-pair
1158 * attributes assigned to this object.
1161 atspi_accessible_get_attributes_as_array (AtspiAccessible *obj, GError **error)
1163 DBusMessage *message;
1165 g_return_val_if_fail (obj != NULL, NULL);
1167 if (obj->priv->cache)
1169 GValue *val = g_hash_table_lookup (obj->priv->cache, "Attributes");
1172 GArray *array = g_array_new (TRUE, TRUE, sizeof (gchar *));
1173 GHashTable *attributes = g_value_get_boxed (val);
1174 g_hash_table_foreach (attributes, add_to_attribute_array, &array);
1179 message = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetAttributes", error, "");
1180 return _atspi_dbus_return_attribute_array_from_message (message);
1184 * atspi_accessible_get_application:
1185 * @obj: The #AtspiAccessible being queried.
1187 * Gets the containing #AtspiApplication for an object.
1189 * Returns: (transfer full): the containing #AtspiApplication instance for
1193 atspi_accessible_get_application (AtspiAccessible *obj, GError **error)
1195 AtspiAccessible *parent;
1200 parent = atspi_accessible_get_parent (obj, NULL);
1201 if (!parent && obj->parent.app &&
1202 atspi_accessible_get_role (obj, NULL) != ATSPI_ROLE_APPLICATION)
1204 AtspiAccessible *root = g_object_ref (obj->parent.app->root);
1207 g_object_unref (obj);
1208 if (atspi_accessible_get_role (root, NULL) == ATSPI_ROLE_DESKTOP_FRAME)
1210 g_object_unref (root);
1216 if (!parent || parent == obj ||
1217 atspi_accessible_get_role (parent, NULL) == ATSPI_ROLE_DESKTOP_FRAME)
1220 g_object_unref (parent);
1223 g_object_unref (obj);
1228 /* Application-specific methods */
1231 * atspi_accessible_get_toolkit_name:
1232 * @obj: a pointer to the #AtspiAccessible object on which to operate.
1234 * Gets the toolkit name for an #AtspiAccessible object.
1235 * Only works on application root objects.
1237 * Returns: a UTF-8 string indicating the toolkit name for the #AtspiAccessible object or NULL on exception.
1240 atspi_accessible_get_toolkit_name (AtspiAccessible *obj, GError **error)
1242 g_return_val_if_fail (obj != NULL, NULL);
1244 if (!obj->parent.app)
1247 if (!obj->parent.app->toolkit_name)
1248 _atspi_dbus_get_property (obj, atspi_interface_application, "ToolkitName",
1249 error, "s", &obj->parent.app->toolkit_name);
1251 return g_strdup (obj->parent.app->toolkit_name);
1255 * atspi_accessible_get_toolkit_version:
1256 * @obj: a pointer to the #AtspiAccessible object on which to operate.
1258 * Gets the toolkit version for an #AtspiAccessible object.
1259 * Only works on application root objects.
1261 * Returns: a UTF-8 string indicating the toolkit version for the #AtspiAccessible object or NULL on exception.
1264 atspi_accessible_get_toolkit_version (AtspiAccessible *obj, GError **error)
1266 g_return_val_if_fail (obj != NULL, NULL);
1268 if (!obj->parent.app)
1271 if (!obj->parent.app->toolkit_version)
1272 _atspi_dbus_get_property (obj, atspi_interface_application, "Version",
1273 error, "s", &obj->parent.app->toolkit_version);
1275 return g_strdup (obj->parent.app->toolkit_version);
1279 * atspi_accessible_get_atspi_version:
1280 * @obj: a pointer to the #AtspiAccessible object on which to operate.
1282 * Gets the AT-SPI IPC specification version supported by the application
1283 * pointed to by the #AtspiAccessible object.
1284 * Only works on application root objects.
1286 * Returns: a UTF-8 string indicating the AT-SPI version for the #AtspiAccessible object or NULL on exception.
1289 atspi_accessible_get_atspi_version (AtspiAccessible *obj, GError **error)
1291 g_return_val_if_fail (obj != NULL, NULL);
1293 if (!obj->parent.app)
1296 if (!obj->parent.app->atspi_version)
1297 _atspi_dbus_get_property (obj, atspi_interface_application, "AtspiVersion",
1298 error, "s", &obj->parent.app->atspi_version);
1300 return g_strdup (obj->parent.app->atspi_version);
1304 * atspi_accessible_get_id:
1305 * @obj: a pointer to the #AtspiAccessible object on which to operate.
1307 * Gets the application id for a #AtspiAccessible object.
1308 * Only works on application root objects.
1310 * Returns: a positive #gint indicating the id for the #AtspiAccessible object
1311 * or -1 on exception.
1314 atspi_accessible_get_id (AtspiAccessible *obj, GError **error)
1318 g_return_val_if_fail (obj != NULL, -1);
1320 if (!_atspi_dbus_get_property (obj, atspi_interface_application, "Id", error, "i", &ret))
1326 /* Interface query methods */
1329 _atspi_accessible_is_a (AtspiAccessible *accessible,
1330 const char *interface_name)
1334 if (accessible == NULL)
1339 if (!_atspi_accessible_test_cache (accessible, ATSPI_CACHE_INTERFACES))
1342 DBusMessageIter iter;
1343 reply = _atspi_dbus_call_partial (accessible, atspi_interface_accessible,
1344 "GetInterfaces", NULL, "");
1345 _ATSPI_DBUS_CHECK_SIG (reply, "as", NULL, FALSE);
1346 dbus_message_iter_init (reply, &iter);
1347 _atspi_dbus_set_interfaces (accessible, &iter);
1348 dbus_message_unref (reply);
1349 _atspi_accessible_add_cache (accessible, ATSPI_CACHE_INTERFACES);
1352 n = _atspi_get_iface_num (interface_name);
1353 if (n == -1) return FALSE;
1354 return (gboolean) ((accessible->interfaces & (1 << n))? TRUE: FALSE);
1358 * atspi_accessible_is_action:
1359 * @obj: a pointer to the #AtspiAccessible instance to query.
1361 * Query whether the specified #AtspiAccessible implements the
1362 * #AtspiAction interface.
1364 * Returns: #TRUE if @obj implements the #AtspiAction interface,
1368 atspi_accessible_is_action (AtspiAccessible *obj)
1370 return _atspi_accessible_is_a (obj,
1371 atspi_interface_action);
1375 * atspi_accessible_is_application:
1376 * @obj: a pointer to the #AtspiAccessible instance to query.
1378 * Query whether the specified #AtspiAccessible implements the
1379 * #AtspiApplication interface.
1381 * Returns: #TRUE if @obj implements the #AtspiApplication interface,
1385 atspi_accessible_is_application (AtspiAccessible *obj)
1387 return _atspi_accessible_is_a (obj,
1388 atspi_interface_application);
1392 * atspi_accessible_is_collection:
1393 * @obj: a pointer to the #AtspiAccessible instance to query.
1395 * Query whether the specified #AtspiAccessible implements the
1396 * #AtspiCollection interface.
1398 * Returns: #TRUE if @obj implements the #AtspiCollection interface,
1402 atspi_accessible_is_collection (AtspiAccessible *obj)
1404 return _atspi_accessible_is_a (obj,
1405 atspi_interface_collection);
1409 * atspi_accessible_is_component:
1410 * @obj: a pointer to the #AtspiAccessible instance to query.
1412 * Query whether the specified #AtspiAccessible implements #AtspiComponent.
1414 * Returns: #TRUE if @obj implements the #AtspiComponent interface,
1418 atspi_accessible_is_component (AtspiAccessible *obj)
1420 return _atspi_accessible_is_a (obj,
1421 atspi_interface_component);
1425 * atspi_accessible_is_document:
1426 * @obj: a pointer to the #AtspiAccessible instance to query.
1428 * Query whether the specified #AtspiAccessible implements the
1429 * #AtspiDocument interface.
1431 * Returns: #TRUE if @obj implements the #AtspiDocument interface,
1435 atspi_accessible_is_document (AtspiAccessible *obj)
1437 return _atspi_accessible_is_a (obj,
1438 atspi_interface_document);
1442 * atspi_accessible_is_editable_text:
1443 * @obj: a pointer to the #AtspiAccessible instance to query.
1445 * Query whether the specified #AtspiAccessible implements the
1446 * #AtspiEditableText interface.
1448 * Returns: #TRUE if @obj implements the #AtspiEditableText interface,
1452 atspi_accessible_is_editable_text (AtspiAccessible *obj)
1454 return _atspi_accessible_is_a (obj,
1455 atspi_interface_editable_text);
1459 * atspi_accessible_is_hypertext:
1460 * @obj: a pointer to the #AtspiAccessible instance to query.
1462 * Query whether the specified #AtspiAccessible implements the
1463 * #AtspiHypertext interface.
1465 * Returns: #TRUE if @obj implements the #AtspiHypertext interface,
1469 atspi_accessible_is_hypertext (AtspiAccessible *obj)
1471 return _atspi_accessible_is_a (obj,
1472 atspi_interface_hypertext);
1476 * atspi_accessible_is_hyperlink:
1477 * @obj: a pointer to the #AtspiAccessible instance to query.
1479 * Query whether the specified #AtspiAccessible implements the
1480 * #AtspiHyperlink interface.
1482 * Returns: #TRUE if @obj implements the #AtspiHypertext interface,
1486 atspi_accessible_is_hyperlink (AtspiAccessible *obj)
1488 return _atspi_accessible_is_a (obj,
1489 atspi_interface_hyperlink);
1493 * atspi_accessible_is_image:
1494 * @obj: a pointer to the #AtspiAccessible instance to query.
1496 * Query whether the specified #AtspiAccessible implements the
1497 * #AtspiImage interface.
1499 * Returns: #TRUE if @obj implements the #AtspiImage interface,
1503 atspi_accessible_is_image (AtspiAccessible *obj)
1505 return _atspi_accessible_is_a (obj,
1506 atspi_interface_image);
1510 * atspi_accessible_is_selection:
1511 * @obj: a pointer to the #AtspiAccessible instance to query.
1513 * Query whether the specified #AtspiAccessible implements the
1514 * #AtspiSelection interface.
1516 * Returns: #TRUE if @obj implements the #AtspiSelection interface,
1520 atspi_accessible_is_selection (AtspiAccessible *obj)
1522 return _atspi_accessible_is_a (obj,
1523 atspi_interface_selection);
1527 * atspi_accessible_is_table:
1528 * @obj: a pointer to the #AtspiAccessible instance to query.
1530 * Query whether the specified #AtspiAccessible implements the
1531 * #AtspiTable interface.
1533 * Returns: #TRUE if @obj implements the #AtspiTable interface,
1537 atspi_accessible_is_table (AtspiAccessible *obj)
1539 return _atspi_accessible_is_a (obj,
1540 atspi_interface_table);
1544 * atspi_accessible_is_table_cell:
1545 * @obj: a pointer to the #AtspiAccessible instance to query.
1547 * Query whether the specified #AtspiAccessible implements the
1548 * #AtspiTableCell interface.
1550 * Returns: #TRUE if @obj implements the #AtspiTable interface,
1554 atspi_accessible_is_table_cell (AtspiAccessible *obj)
1556 return _atspi_accessible_is_a (obj,
1557 atspi_interface_table_cell);
1561 * atspi_accessible_is_streamable_content:
1562 * @obj: a pointer to the #AtspiAccessible instance to query.
1564 * Query whether the specified #AtspiAccessible implements the
1565 * #AtspiStreamableContent interface.
1567 * Returns: #TRUE if @obj implements the #AtspiStreamableContent interface,
1571 atspi_accessible_is_streamable_content (AtspiAccessible *obj)
1574 return _atspi_accessible_is_a (obj,
1575 atspi_interface_streamable_content);
1577 g_warning ("Streamable content not implemented");
1583 * atspi_accessible_is_text:
1584 * @obj: a pointer to the #AtspiAccessible instance to query.
1586 * Query whether the specified #AtspiAccessible implements the
1587 * #AtspiText interface.
1589 * Returns: #TRUE if @obj implements the #AtspiText interface,
1593 atspi_accessible_is_text (AtspiAccessible *obj)
1595 return _atspi_accessible_is_a (obj,
1596 atspi_interface_text);
1600 * atspi_accessible_is_value:
1601 * @obj: a pointer to the #AtspiAccessible instance to query.
1603 * Query whether the specified #AtspiAccessible implements the
1604 * #AtspiValue interface.
1606 * Returns: #TRUE if @obj implements the #AtspiValue interface,
1610 atspi_accessible_is_value (AtspiAccessible *obj)
1612 return _atspi_accessible_is_a (obj,
1613 atspi_interface_value);
1617 * atspi_accessible_get_action: (rename-to atspi_accessible_get_action_iface)
1618 * @obj: a pointer to the #AtspiAccessible instance to query.
1620 * Gets the #AtspiAction interface for an #AtspiAccessible.
1622 * Returns: (transfer full): a pointer to an #AtspiAction interface
1623 * instance, or NULL if @obj does not implement #AtspiAction.
1625 * Deprecated: 2.10: Use atspi_accessible_get_action_iface instead.
1628 atspi_accessible_get_action (AtspiAccessible *accessible)
1630 return (_atspi_accessible_is_a (accessible, atspi_interface_action) ?
1631 g_object_ref (ATSPI_ACTION (accessible)) : NULL);
1635 * atspi_accessible_get_action_iface:
1636 * @obj: a pointer to the #AtspiAccessible instance to query.
1638 * Gets the #AtspiAction interface for an #AtspiAccessible.
1640 * Returns: (transfer full): a pointer to an #AtspiAction interface
1641 * instance, or NULL if @obj does not implement #AtspiAction.
1644 atspi_accessible_get_action_iface (AtspiAccessible *accessible)
1646 return (_atspi_accessible_is_a (accessible, atspi_interface_action) ?
1647 g_object_ref (ATSPI_ACTION (accessible)) : NULL);
1651 * atspi_accessible_get_collection: (rename-to atspi_accessible_get_collection_iface)
1652 * @obj: a pointer to the #AtspiAccessible instance to query.
1654 * Gets the #AtspiCollection interface for an #AtspiAccessible.
1656 * Returns: (transfer full): a pointer to an #AtspiCollection interface
1657 * instance, or NULL if @obj does not implement #AtspiCollection.
1659 * Deprecated: 2.10: Use atspi_accessible_get_collection_iface instead.
1662 atspi_accessible_get_collection (AtspiAccessible *accessible)
1664 return (_atspi_accessible_is_a (accessible, atspi_interface_collection) ?
1665 g_object_ref (ATSPI_COLLECTION (accessible)) : NULL);
1669 * atspi_accessible_get_collection_iface:
1670 * @obj: a pointer to the #AtspiAccessible instance to query.
1672 * Gets the #AtspiCollection interface for an #AtspiAccessible.
1674 * Returns: (transfer full): a pointer to an #AtspiCollection interface
1675 * instance, or NULL if @obj does not implement #AtspiCollection.
1678 atspi_accessible_get_collection_iface (AtspiAccessible *accessible)
1680 return (_atspi_accessible_is_a (accessible, atspi_interface_collection) ?
1681 g_object_ref (ATSPI_COLLECTION (accessible)) : NULL);
1685 * atspi_accessible_get_component: (rename-to atspi_accessible_get_component_iface)
1686 * @obj: a pointer to the #AtspiAccessible instance to query.
1688 * Gets the #AtspiComponent interface for an #AtspiAccessible.
1690 * Returns: (transfer full): a pointer to an #AtspiComponent interface
1691 * instance, or NULL if @obj does not implement #AtspiComponent.
1693 * Deprecated: 2.10: Use atspi_accessible_get_component_iface instead.
1696 atspi_accessible_get_component (AtspiAccessible *obj)
1698 return (_atspi_accessible_is_a (obj, atspi_interface_component) ?
1699 g_object_ref (ATSPI_COMPONENT (obj)) : NULL);
1703 * atspi_accessible_get_component_iface:
1704 * @obj: a pointer to the #AtspiAccessible instance to query.
1706 * Gets the #AtspiComponent interface for an #AtspiAccessible.
1708 * Returns: (transfer full): a pointer to an #AtspiComponent interface
1709 * instance, or NULL if @obj does not implement #AtspiComponent.
1712 atspi_accessible_get_component_iface (AtspiAccessible *obj)
1714 return (_atspi_accessible_is_a (obj, atspi_interface_component) ?
1715 g_object_ref (ATSPI_COMPONENT (obj)) : NULL);
1719 * atspi_accessible_get_document: (rename-to atspi_accessible_get_document_iface)
1720 * @obj: a pointer to the #AtspiAccessible instance to query.
1722 * Gets the #AtspiDocument interface for an #AtspiAccessible.
1724 * Returns: (transfer full): a pointer to an #AtspiDocument interface
1725 * instance, or NULL if @obj does not implement #AtspiDocument.
1727 * Deprecated: 2.10: Use atspi_accessible_get_document_iface instead.
1730 atspi_accessible_get_document (AtspiAccessible *accessible)
1732 return (_atspi_accessible_is_a (accessible, atspi_interface_document) ?
1733 g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL);
1737 * atspi_accessible_get_document_iface:
1738 * @obj: a pointer to the #AtspiAccessible instance to query.
1740 * Gets the #AtspiDocument interface for an #AtspiAccessible.
1742 * Returns: (transfer full): a pointer to an #AtspiDocument interface
1743 * instance, or NULL if @obj does not implement #AtspiDocument.
1746 atspi_accessible_get_document_iface (AtspiAccessible *accessible)
1748 return (_atspi_accessible_is_a (accessible, atspi_interface_document) ?
1749 g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL);
1753 * atspi_accessible_get_editable_text: (rename-to atspi_accessible_get_editable_text_iface)
1754 * @obj: a pointer to the #AtspiAccessible instance to query.
1756 * Gets the #AtspiEditableText interface for an #AtspiAccessible.
1758 * Returns: (transfer full): a pointer to an #AtspiEditableText interface
1759 * instance, or NULL if @obj does not implement #AtspiEditableText.
1761 * Deprecated: 2.10: Use atspi_accessible_get_editable_text_iface instead.
1764 atspi_accessible_get_editable_text (AtspiAccessible *accessible)
1766 return (_atspi_accessible_is_a (accessible, atspi_interface_editable_text) ?
1767 g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL);
1771 * atspi_accessible_get_editable_text_iface:
1772 * @obj: a pointer to the #AtspiAccessible instance to query.
1774 * Gets the #AtspiEditableText interface for an #AtspiAccessible.
1776 * Returns: (transfer full): a pointer to an #AtspiEditableText interface
1777 * instance, or NULL if @obj does not implement #AtspiEditableText.
1780 atspi_accessible_get_editable_text_iface (AtspiAccessible *accessible)
1782 return (_atspi_accessible_is_a (accessible, atspi_interface_editable_text) ?
1783 g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL);
1787 * atspi_accessible_get_hyperlink:
1788 * @obj: a pointer to the #AtspiAccessible object on which to operate.
1790 * Gets the #AtspiHyperlink interface for an #AtspiAccessible.
1792 * Returns: (transfer full): the #AtspiHyperlink object associated with
1793 * the given #AtspiAccessible, or NULL if not supported.
1796 atspi_accessible_get_hyperlink (AtspiAccessible *accessible)
1798 return (_atspi_accessible_is_a (accessible, atspi_interface_hyperlink) ?
1799 _atspi_hyperlink_new (accessible->parent.app, accessible->parent.path) : NULL);
1803 * atspi_accessible_get_hypertext: (rename-to atspi_accessible_get_hypertext_iface)
1804 * @obj: a pointer to the #AtspiAccessible instance to query.
1806 * Gets the #AtspiHypertext interface for an #AtspiAccessible.
1808 * Returns: (transfer full): a pointer to an #AtspiHypertext interface
1809 * instance, or NULL if @obj does not implement #AtspiHypertext.
1811 * Deprecated: 2.10: Use atspi_accessible_get_hypertext_iface instead.
1814 atspi_accessible_get_hypertext (AtspiAccessible *accessible)
1816 return (_atspi_accessible_is_a (accessible, atspi_interface_hypertext) ?
1817 g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL);
1821 * atspi_accessible_get_hypertext_iface:
1822 * @obj: a pointer to the #AtspiAccessible instance to query.
1824 * Gets the #AtspiHypertext interface for an #AtspiAccessible.
1826 * Returns: (transfer full): a pointer to an #AtspiHypertext interface
1827 * instance, or NULL if @obj does not implement #AtspiHypertext.
1830 atspi_accessible_get_hypertext_iface (AtspiAccessible *accessible)
1832 return (_atspi_accessible_is_a (accessible, atspi_interface_hypertext) ?
1833 g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL);
1837 * atspi_accessible_get_image: (rename-to atspi_accessible_get_image_iface)
1838 * @obj: a pointer to the #AtspiAccessible instance to query.
1840 * Gets the #AtspiImage interface for an #AtspiAccessible.
1842 * Returns: (transfer full): a pointer to an #AtspiImage interface instance, or
1843 * NULL if @obj does not implement #AtspiImage.
1845 * Deprecated: 2.10: Use atspi_accessible_get_image_iface instead.
1848 atspi_accessible_get_image (AtspiAccessible *accessible)
1850 return (_atspi_accessible_is_a (accessible, atspi_interface_image) ?
1851 g_object_ref (ATSPI_IMAGE (accessible)) : NULL);
1855 * atspi_accessible_get_image_iface:
1856 * @obj: a pointer to the #AtspiAccessible instance to query.
1858 * Gets the #AtspiImage interface for an #AtspiAccessible.
1860 * Returns: (transfer full): a pointer to an #AtspiImage interface instance, or
1861 * NULL if @obj does not implement #AtspiImage.
1864 atspi_accessible_get_image_iface (AtspiAccessible *accessible)
1866 return (_atspi_accessible_is_a (accessible, atspi_interface_image) ?
1867 g_object_ref (ATSPI_IMAGE (accessible)) : NULL);
1871 * atspi_accessible_get_selection: (rename-to atspi_accessible_get_selection_iface)
1872 * @obj: a pointer to the #AtspiAccessible instance to query.
1874 * Gets the #AtspiSelection interface for an #AtspiAccessible.
1876 * Returns: (transfer full): a pointer to an #AtspiSelection interface
1877 * instance, or NULL if @obj does not implement #AtspiSelection.
1879 * Deprecated: 2.10: Use atspi_accessible_get_selection_iface instead.
1882 atspi_accessible_get_selection (AtspiAccessible *accessible)
1884 return (_atspi_accessible_is_a (accessible, atspi_interface_selection) ?
1885 g_object_ref (ATSPI_SELECTION (accessible)) : NULL);
1889 * atspi_accessible_get_selection_iface:
1890 * @obj: a pointer to the #AtspiAccessible instance to query.
1892 * Gets the #AtspiSelection interface for an #AtspiAccessible.
1894 * Returns: (transfer full): a pointer to an #AtspiSelection interface
1895 * instance, or NULL if @obj does not implement #AtspiSelection.
1898 atspi_accessible_get_selection_iface (AtspiAccessible *accessible)
1900 return (_atspi_accessible_is_a (accessible, atspi_interface_selection) ?
1901 g_object_ref (ATSPI_SELECTION (accessible)) : NULL);
1906 * atspi_accessible_get_streamable_content:
1907 * @obj: a pointer to the #AtspiAccessible instance to query.
1909 * Gets the #AtspiStreamableContent interface for an #AtspiAccessible.
1911 * Returns: (transfer full): a pointer to an #AtspiStreamableContent interface
1912 * instance, or NULL if @obj does not implement #AtspiStreamableContent.
1914 AtspiStreamableContent *
1915 atspi_accessible_get_streamable_content (AtspiAccessible *accessible)
1917 return (_atspi_accessible_is_a (accessible, atspi_interface_streamable_content) ?
1923 * atspi_accessible_get_table: (rename-to atspi_accessible_get_table_iface)
1924 * @obj: a pointer to the #AtspiAccessible instance to query.
1926 * Gets the #AtspiTable interface for an #AtspiAccessible.
1928 * Returns: (transfer full): a pointer to an #AtspiTable interface instance, or
1929 * NULL if @obj does not implement #AtspiTable.
1931 * Deprecated: 2.10: Use atspi_accessible_get_table_iface instead.
1934 atspi_accessible_get_table (AtspiAccessible *obj)
1936 return (_atspi_accessible_is_a (obj, atspi_interface_table) ?
1937 g_object_ref (ATSPI_TABLE (obj)) : NULL);
1941 * atspi_accessible_get_table_iface:
1942 * @obj: a pointer to the #AtspiAccessible instance to query.
1944 * Gets the #AtspiTable interface for an #AtspiAccessible.
1946 * Returns: (transfer full): a pointer to an #AtspiTable interface instance, or
1947 * NULL if @obj does not implement #AtspiTable.
1950 atspi_accessible_get_table_iface (AtspiAccessible *obj)
1952 return (_atspi_accessible_is_a (obj, atspi_interface_table) ?
1953 g_object_ref (ATSPI_TABLE (obj)) : NULL);
1957 * atspi_accessible_get_table_cell:
1958 * @obj: a pointer to the #AtspiAccessible instance to query.
1960 * Gets the #AtspiTableCell interface for an #AtspiAccessible.
1962 * Returns: (transfer full): a pointer to an #AtspiTableCell interface instance,
1963 * or NULL if @obj does not implement #AtspiTable.
1966 atspi_accessible_get_table_cell (AtspiAccessible *obj)
1968 return (_atspi_accessible_is_a (obj, atspi_interface_table_cell) ?
1969 g_object_ref (ATSPI_TABLE_CELL (obj)) : NULL);
1973 * atspi_accessible_get_text: (rename-to atspi_accessible_get_text_iface)
1974 * @obj: a pointer to the #AtspiAccessible instance to query.
1976 * Gets the #AtspiTable interface for an #AtspiAccessible.
1978 * Returns: (transfer full): a pointer to an #AtspiText interface instance, or
1979 * NULL if @obj does not implement #AtspiText.
1981 * Deprecated: 2.10: Use atspi_accessible_get_text_iface instead.
1984 atspi_accessible_get_text (AtspiAccessible *obj)
1986 return (_atspi_accessible_is_a (obj, atspi_interface_text) ?
1987 g_object_ref (ATSPI_TEXT (obj)) : NULL);
1991 * atspi_accessible_get_text_iface:
1992 * @obj: a pointer to the #AtspiAccessible instance to query.
1994 * Gets the #AtspiTable interface for an #AtspiAccessible.
1996 * Returns: (transfer full): a pointer to an #AtspiText interface instance, or
1997 * NULL if @obj does not implement #AtspiText.
2000 atspi_accessible_get_text_iface (AtspiAccessible *obj)
2002 return (_atspi_accessible_is_a (obj, atspi_interface_text) ?
2003 g_object_ref (ATSPI_TEXT (obj)) : NULL);
2007 * atspi_accessible_get_value: (rename-to atspi_accessible_get_value_iface)
2008 * @obj: a pointer to the #AtspiAccessible instance to query.
2010 * Gets the #AtspiTable interface for an #AtspiAccessible.
2012 * Returns: (transfer full): a pointer to an #AtspiValue interface instance, or
2013 * NULL if @obj does not implement #AtspiValue.
2015 * Deprecated: 2.10: Use atspi_accessible_get_value_iface instead.
2018 atspi_accessible_get_value (AtspiAccessible *accessible)
2020 return (_atspi_accessible_is_a (accessible, atspi_interface_value) ?
2021 g_object_ref (ATSPI_VALUE (accessible)) : NULL);
2025 * atspi_accessible_get_value_iface:
2026 * @obj: a pointer to the #AtspiAccessible instance to query.
2028 * Gets the #AtspiTable interface for an #AtspiAccessible.
2030 * Returns: (transfer full): a pointer to an #AtspiValue interface instance, or
2031 * NULL if @obj does not implement #AtspiValue.
2034 atspi_accessible_get_value_iface (AtspiAccessible *accessible)
2036 return (_atspi_accessible_is_a (accessible, atspi_interface_value) ?
2037 g_object_ref (ATSPI_VALUE (accessible)) : NULL);
2041 append_const_val (GArray *array, const gchar *val)
2043 gchar *dup = g_strdup (val);
2046 g_array_append_val (array, dup);
2050 * atspi_accessible_get_interfaces:
2051 * @obj: The #AtspiAccessible to query.
2053 * A set of pointers to all interfaces supported by an #AtspiAccessible.
2055 * Returns: (element-type gchar*) (transfer full): A #GArray of strings
2056 * describing the interfaces supported by the object. Interfaces are
2057 * denoted in short-hand (i.e. "Component", "Text" etc.).
2060 atspi_accessible_get_interfaces (AtspiAccessible *obj)
2062 GArray *ret = g_array_new (TRUE, TRUE, sizeof (gchar *));
2064 g_return_val_if_fail (obj != NULL, NULL);
2066 append_const_val (ret, "Accessible");
2067 if (atspi_accessible_is_action (obj))
2068 append_const_val (ret, "Action");
2069 if (atspi_accessible_is_collection (obj))
2070 append_const_val (ret, "Collection");
2071 if (atspi_accessible_is_component (obj))
2072 append_const_val (ret, "Component");
2073 if (atspi_accessible_is_document (obj))
2074 append_const_val (ret, "Document");
2075 if (atspi_accessible_is_editable_text (obj))
2076 append_const_val (ret, "EditableText");
2077 if (atspi_accessible_is_hypertext (obj))
2078 append_const_val (ret, "Hypertext");
2079 if (atspi_accessible_is_hyperlink (obj))
2080 append_const_val (ret, "Hyperlink");
2081 if (atspi_accessible_is_image (obj))
2082 append_const_val (ret, "Image");
2083 if (atspi_accessible_is_selection (obj))
2084 append_const_val (ret, "Selection");
2085 if (atspi_accessible_is_table (obj))
2086 append_const_val (ret, "Table");
2087 if (atspi_accessible_is_table_cell (obj))
2088 append_const_val (ret, "TableCell");
2089 if (atspi_accessible_is_text (obj))
2090 append_const_val (ret, "Text");
2091 if (atspi_accessible_is_value (obj))
2092 append_const_val (ret, "Value");
2098 _atspi_accessible_new (AtspiApplication *app, const gchar *path)
2100 AtspiAccessible *accessible;
2102 accessible = g_object_new (ATSPI_TYPE_ACCESSIBLE, NULL);
2103 g_return_val_if_fail (accessible != NULL, NULL);
2105 accessible->parent.app = g_object_ref (app);
2106 accessible->parent.path = g_strdup (path);
2112 * atspi_accessible_set_cache_mask:
2113 * @accessible: The #AtspiAccessible to operate on. Must be the desktop or
2114 * the root of an application.
2115 * @mask: An #AtspiCache specifying a bit mask of the types of data to cache.
2117 * Sets the type of data to cache for accessibles.
2118 * If this is not set for an application or is reset to ATSPI_CACHE_UNDEFINED,
2119 * then the desktop's cache flag will be used.
2120 * If the desktop's cache flag is also undefined, then all possible data will
2122 * This function is intended to work around bugs in toolkits where the proper
2123 * events are not raised / to aid in testing for such bugs.
2126 atspi_accessible_set_cache_mask (AtspiAccessible *accessible, AtspiCache mask)
2128 g_return_if_fail (accessible != NULL);
2129 g_return_if_fail (accessible->parent.app != NULL);
2130 g_return_if_fail (accessible == accessible->parent.app->root);
2131 accessible->parent.app->cache = mask;
2132 enable_caching = TRUE;
2136 * atspi_accessible_clear_cache:
2137 * @accessible: The #AtspiAccessible whose cache to clear.
2139 * Clears the cached information for the given accessible and all of its
2143 atspi_accessible_clear_cache (AtspiAccessible *accessible)
2149 accessible->cached_properties = ATSPI_CACHE_NONE;
2150 for (l = accessible->children; l; l = l->next)
2151 atspi_accessible_clear_cache (l->data);
2156 * atspi_accessible_get_process_id:
2157 * @accessible: The #AtspiAccessible to query.
2158 * @error: a pointer to a %NULL #GError pointer
2160 * Returns the process id associated with the given accessible. Mainly
2161 * added for debugging; it is a shortcut to explicitly querying the
2162 * accessible's app->bus_name and then calling GetConnectionUnixProcessID.
2164 * Returns: The process ID or undetermined value if @error is set.
2167 atspi_accessible_get_process_id (AtspiAccessible *accessible, GError **error)
2169 DBusMessage *message, *reply;
2170 DBusConnection *bus = _atspi_bus ();
2171 dbus_uint32_t pid = -1;
2174 if (!accessible->parent.app || !accessible->parent.app->bus_name)
2176 g_set_error_literal(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "Process is defunct");
2180 message = dbus_message_new_method_call ("org.freedesktop.DBus",
2181 "/org/freedesktop/DBus",
2182 "org.freedesktop.DBus",
2183 "GetConnectionUnixProcessID");
2184 dbus_message_append_args (message, DBUS_TYPE_STRING,
2185 &accessible->parent.app->bus_name,
2187 dbus_error_init (&d_error);
2188 reply = dbus_connection_send_with_reply_and_block (bus, message, -1, &d_error);
2189 dbus_message_unref (message);
2192 if (!strcmp (dbus_message_get_signature (reply), "u"))
2193 dbus_message_get_args (reply, NULL, DBUS_TYPE_UINT32, &pid, DBUS_TYPE_INVALID);
2194 dbus_message_unref (reply);
2196 if (dbus_error_is_set (&d_error))
2198 g_set_error_literal(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "Process is defunct");
2199 dbus_error_free (&d_error);
2205 _atspi_accessible_get_cache_mask (AtspiAccessible *accessible)
2209 if (!accessible->parent.app)
2210 return ATSPI_CACHE_NONE;
2212 mask = accessible->parent.app->cache;
2213 if (mask == ATSPI_CACHE_UNDEFINED &&
2214 accessible->parent.app->root &&
2215 accessible->parent.app->root->accessible_parent)
2217 AtspiAccessible *desktop = atspi_get_desktop (0);
2218 mask = desktop->parent.app->cache;
2219 g_object_unref (desktop);
2222 if (mask == ATSPI_CACHE_UNDEFINED)
2223 mask = ATSPI_CACHE_DEFAULT;
2229 _atspi_accessible_test_cache (AtspiAccessible *accessible, AtspiCache flag)
2231 AtspiCache mask = _atspi_accessible_get_cache_mask (accessible);
2232 AtspiCache result = accessible->cached_properties & mask & flag;
2233 if (accessible->states && atspi_state_set_contains (accessible->states, ATSPI_STATE_TRANSIENT))
2235 return (result != 0 && (atspi_main_loop || enable_caching ||
2236 flag == ATSPI_CACHE_INTERFACES) &&
2241 _atspi_accessible_add_cache (AtspiAccessible *accessible, AtspiCache flag)
2243 AtspiCache mask = _atspi_accessible_get_cache_mask (accessible);
2245 accessible->cached_properties |= flag & mask;
2249 * atspi_accessible_get_locale:
2250 * @accessible: an #AtspiAccessible
2252 * Gets a UTF-8 string indicating the POSIX-style LC_MESSAGES locale
2257 * Returns: a UTF-8 string indicating the POSIX-style LC_MESSAGES
2258 * locale of @accessible.
2261 atspi_accessible_get_object_locale (AtspiAccessible *accessible, GError **error)
2265 g_return_val_if_fail (accessible != NULL, NULL);
2267 locale = g_object_get_qdata (G_OBJECT (accessible), quark_locale);
2270 if (!_atspi_dbus_get_property (accessible, atspi_interface_accessible,
2271 "Locale", error, "s", &locale))
2274 g_object_set_qdata_full (G_OBJECT (accessible), quark_locale, locale,
2281 free_value (gpointer data)
2283 GValue *value = data;
2285 g_value_unset (value);
2290 _atspi_accessible_ref_cache (AtspiAccessible *accessible)
2292 AtspiAccessiblePrivate *priv = accessible->priv;
2294 priv->cache_ref_count++;
2296 return g_hash_table_ref (priv->cache);
2297 priv->cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
2303 _atspi_accessible_unref_cache (AtspiAccessible *accessible)
2305 AtspiAccessiblePrivate *priv = accessible->priv;
2309 g_hash_table_unref (priv->cache);
2310 if (--priv->cache_ref_count == 0)