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"
29 static gboolean enable_caching = FALSE;
30 static guint quark_locale;
33 atspi_action_interface_init (AtspiAction *action)
38 atspi_collection_interface_init (AtspiCollection *component)
43 atspi_component_interface_init (AtspiComponent *component)
48 atspi_document_interface_init (AtspiDocument *document)
53 atspi_editable_text_interface_init (AtspiEditableText *editable_text)
58 atspi_hypertext_interface_init (AtspiHypertext *hypertext)
63 atspi_image_interface_init (AtspiImage *image)
68 atspi_selection_interface_init (AtspiSelection *selection)
73 atspi_table_interface_init (AtspiTable *table)
78 atspi_table_cell_interface_init (AtspiTableCell *cell)
83 atspi_text_interface_init (AtspiText *text)
88 atspi_value_interface_init (AtspiValue *value)
92 G_DEFINE_TYPE_WITH_CODE (AtspiAccessible, atspi_accessible, ATSPI_TYPE_OBJECT,
93 G_ADD_PRIVATE (AtspiAccessible)
94 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_ACTION, atspi_action_interface_init)
95 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_COLLECTION, atspi_collection_interface_init)
96 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_COMPONENT, atspi_component_interface_init)
97 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_DOCUMENT, atspi_document_interface_init)
98 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_EDITABLE_TEXT, atspi_editable_text_interface_init)
99 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_HYPERTEXT, atspi_hypertext_interface_init)
100 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_IMAGE, atspi_image_interface_init)
101 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_SELECTION, atspi_selection_interface_init)
102 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_TABLE, atspi_table_interface_init)
103 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_TABLE_CELL, atspi_table_cell_interface_init)
104 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_TEXT, atspi_text_interface_init)
105 G_IMPLEMENT_INTERFACE (ATSPI_TYPE_VALUE, atspi_value_interface_init))
107 #ifdef DEBUG_REF_COUNTS
108 static gint accessible_count = 0;
112 atspi_accessible_init (AtspiAccessible *accessible)
114 #ifdef DEBUG_REF_COUNTS
116 g_hash_table_insert (_atspi_get_live_refs (), accessible, NULL);
117 g_print("at-spi: init: %d objects\n", accessible_count);
120 accessible->priv = atspi_accessible_get_instance_private (accessible);
124 atspi_accessible_dispose (GObject *object)
126 AtspiAccessible *accessible = ATSPI_ACCESSIBLE (object);
128 AtspiAccessible *parent;
132 /* TODO: Only fire if object not already marked defunct */
133 memset (&e, 0, sizeof (e));
134 e.type = "object:state-changed:defunct";
135 e.source = accessible;
138 _atspi_send_event (&e);
140 if (accessible->states)
142 g_object_unref (accessible->states);
143 accessible->states = NULL;
146 parent = accessible->accessible_parent;
147 if (parent && parent->children)
149 GList*ls = g_list_find (parent->children, accessible);
152 gboolean replace = (ls == parent->children);
153 ls = g_list_remove (ls, accessible);
155 parent->children = ls;
156 g_object_unref (object);
162 g_object_unref (parent);
163 accessible->accessible_parent = NULL;
166 children = accessible->children;
167 accessible->children = NULL;
168 for (l = children; l; l = l->next)
170 AtspiAccessible *child = l->data;
171 if (child && child->accessible_parent == accessible)
173 g_object_unref (accessible);
174 child->accessible_parent = NULL;
176 g_object_unref (child);
178 g_list_free (children);
180 G_OBJECT_CLASS (atspi_accessible_parent_class) ->dispose (object);
184 atspi_accessible_finalize (GObject *object)
186 AtspiAccessible *accessible = ATSPI_ACCESSIBLE (object);
188 g_free (accessible->description);
189 g_free (accessible->name);
190 if (accessible->attributes)
191 g_hash_table_unref (accessible->attributes);
193 if (accessible->priv->cache)
194 g_hash_table_destroy (accessible->priv->cache);
196 #ifdef DEBUG_REF_COUNTS
198 g_hash_table_remove (_atspi_get_live_refs (), accessible);
199 g_print ("at-spi: finalize: %d objects\n", accessible_count);
202 G_OBJECT_CLASS (atspi_accessible_parent_class)
207 atspi_accessible_class_init (AtspiAccessibleClass *klass)
209 GObjectClass *object_class = G_OBJECT_CLASS (klass);
211 object_class->dispose = atspi_accessible_dispose;
212 object_class->finalize = atspi_accessible_finalize;
214 quark_locale = g_quark_from_string ("accessible-locale");
218 * atspi_accessible_get_name:
219 * @obj: a pointer to the #AtspiAccessible object on which to operate.
221 * Gets the name of an #AtspiAccessible object.
223 * Returns: a UTF-8 string indicating the name of the #AtspiAccessible object
224 * or NULL on exception.
227 atspi_accessible_get_name (AtspiAccessible *obj, GError **error)
229 g_return_val_if_fail (obj != NULL, g_strdup (""));
230 if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_NAME))
232 if (!_atspi_dbus_get_property (obj, atspi_interface_accessible, "Name", error,
234 return g_strdup ("");
235 _atspi_accessible_add_cache (obj, ATSPI_CACHE_NAME);
237 return g_strdup (obj->name);
242 * atspi_accessible_get_unique_id:
243 * @obj: a pointer to the #AtspiAccessible object on which to operate.
245 * Gets the identificator, uniquely identifying object, or NULL if an error occured.
247 * Returns: a UTF-8 string describing the #AtspiAccessible object
248 * or NULL on exception or NULL object passed.
251 atspi_accessible_get_unique_id(AtspiAccessible *obj, GError **error)
254 g_set_error(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "argument is null");
259 gchar *bus_name = atspi_accessible_get_bus_name(obj, error);
260 if (bus_name && bus_name[0]) {
261 gchar *path = atspi_accessible_get_path(obj, error);
263 id = g_strdup_printf("%s:%s", bus_name, path);
265 g_set_error(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "failed to get path");
269 g_set_error(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "failed to get bus name");
275 * atspi_accessible_get_bus_name:
276 * @obj: a pointer to the #AtspiAccessible object on which to operate.
278 * Gets the bus name, where object belongs.
280 * Returns: a UTF-8 string describing the #AtspiAccessible object's
281 * bus name or empty string on exception or NULL object passed.
284 atspi_accessible_get_bus_name(AtspiAccessible *obj, GError **error)
286 if (!obj || !obj->parent.app)
288 return g_strdup (obj->parent.app->bus_name);
292 * atspi_accessible_get_path:
293 * @obj: a pointer to the #AtspiAccessible object on which to operate.
295 * Gets the path, uniquely identifying object over its bus name.
297 * Returns: a UTF-8 string describing the #AtspiAccessible object
298 * or empty string on exception or NULL object passed.
301 atspi_accessible_get_path(AtspiAccessible *obj, GError **error)
303 static const char *prefix = "/org/a11y/atspi/accessible/";
304 static int prefix_len = 27;
308 AtspiObject *o = ATSPI_OBJECT (obj);
311 if (strncmp(o->path, prefix, prefix_len) == 0)
312 return g_strdup(o->path + prefix_len);
313 return g_strdup (o->path);
317 * atspi_accessible_get_navigable_at_point:
318 * @root: a pointer to the #AtspiAccessible to start search from.
319 * @x: a #gint specifying the x coordinate of the point in question.
320 * @y: a #gint specifying the y coordinate of the point in question.
321 * @ctype: the coordinate system of the point (@x, @y)
322 * (e.g. ATSPI_COORD_TYPE_WINDOW, ATSPI_COORD_TYPE_SCREEN).
324 * Finds the accessible element closest to user (highest in z-order), at a given coordinate within an #AtspiAccessible.
325 * This should be the element, that should be picked, when doing mouse click or finger tap at given coordinates.
327 * Returns: (nullable) (transfer full): a pointer to an
328 * #AtspiAccessible descendant (of any depth) of the specified component which
329 * contains the point (@x, @y), or NULL if no descendant contains
333 atspi_accessible_get_navigable_at_point (AtspiAccessible *root,
336 AtspiCoordType ctype, GError **error)
338 dbus_int32_t d_x = x, d_y = y;
339 dbus_uint32_t d_ctype = ctype;
341 AtspiAccessible *return_value = NULL;
342 unsigned char recurse = 0;
343 DBusMessageIter iter;
344 AtspiAccessible *deputy = NULL;
346 g_return_val_if_fail (root != NULL, NULL);
348 reply = _atspi_dbus_call_partial (root, atspi_interface_accessible, "GetNavigableAtPoint", error, "iiu", d_x, d_y, d_ctype);
349 // call failed, error is set, so we bail out
351 if (deputy) g_object_unref(deputy);
352 if (return_value) g_object_unref(return_value);
355 _ATSPI_DBUS_CHECK_SIG (reply, "(so)y(so)", NULL, NULL);
357 dbus_message_iter_init (reply, &iter);
358 AtspiAccessible *tmp = _atspi_dbus_return_accessible_from_iter (&iter);
360 unsigned char value = 0;
361 dbus_message_iter_get_basic (&iter, &value);
362 dbus_message_iter_next (&iter);
363 recurse = (value != 0);
365 /* keep deputy if tmp has deputy */
367 deputy = _atspi_dbus_return_accessible_from_iter (&iter);
369 dbus_message_unref(reply);
373 /* TODO: need to check deputy works for return value */
375 g_object_unref(return_value);
382 g_object_unref(return_value);
383 return_value = root = tmp;
389 * atspi_accessible_get_reading_material:
390 * @obj: a pointer to the #AtspiAccessible object on which to operate.
392 * Gets reading material
394 * Returns: reading material to be used screen-reader side. This is not stable.
395 * You have to handle all alocated memory as below on screen-reader side.
397 * AtspiAccessibleReadingMaterial *rm
398 * g_object_unref(rm->parent);
399 * g_object_unref(rm->described_by_accessible);
400 * g_hash_table_unref(rm->attributes);
402 * free(rm->labeled_by_name);
403 * free(rm->text_interface_name);
404 * free(rm->localized_role_name);
405 * free(rm->description);
408 AtspiAccessibleReadingMaterial *
409 atspi_accessible_get_reading_material (AtspiAccessible *obj, GError **error)
411 AtspiAccessible *parent;
412 AtspiAccessibleReadingMaterial *reading_material = NULL;
414 double current_value;
418 DBusMessageIter iter;
419 DBusMessageIter iter_array;
421 dbus_uint32_t *states;
422 dbus_int32_t index_in_parent;
423 dbus_int32_t child_count;
424 dbus_bool_t is_selected;
426 g_return_val_if_fail (obj != NULL, NULL);
428 reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetReadingMaterial", error, "");
430 _ATSPI_DBUS_CHECK_SIG (reply, "a{ss}sssuausiddddsibbii(so)auiui(so)", NULL, NULL);
432 reading_material = calloc(1, sizeof(AtspiAccessibleReadingMaterial));
433 if (!reading_material)
435 return reading_material;
438 dbus_message_iter_init (reply, &iter);
441 reading_material->attributes = _atspi_dbus_hash_from_iter (&iter);
442 dbus_message_iter_next (&iter);
445 dbus_message_iter_get_basic (&iter, &name);
446 reading_material->name = g_strdup (name);
447 dbus_message_iter_next (&iter);
449 /* get name of relation LABELED_BY */
450 dbus_message_iter_get_basic (&iter, &name);
451 reading_material->labeled_by_name = g_strdup (name);
452 dbus_message_iter_next (&iter);
454 /* get name of text interface */
455 dbus_message_iter_get_basic (&iter, &name);
456 reading_material->text_interface_name = g_strdup (name);
457 dbus_message_iter_next (&iter);
460 dbus_message_iter_get_basic (&iter, &role);
461 reading_material->role = role;
462 dbus_message_iter_next (&iter);
465 dbus_message_iter_recurse (&iter, &iter_array);
466 dbus_message_iter_get_fixed_array (&iter_array, &states, &count);
467 val = ((guint64)states [1]) << 32;
469 reading_material->states = val;
470 dbus_message_iter_next (&iter);
472 /* get localized role name */
473 dbus_message_iter_get_basic (&iter, &name);
474 reading_material->localized_role_name = g_strdup (name);
475 dbus_message_iter_next (&iter);
477 /* get child count */
478 dbus_message_iter_get_basic (&iter, &child_count);
479 reading_material->child_count = child_count;
480 dbus_message_iter_next (&iter);
482 /* get current value */
483 dbus_message_iter_get_basic (&iter, ¤t_value);
484 reading_material->value = current_value;
485 dbus_message_iter_next (&iter);
487 /* get minimum increment */
488 dbus_message_iter_get_basic (&iter, ¤t_value);
489 reading_material->increment = current_value;
490 dbus_message_iter_next (&iter);
492 /* get maximum value */
493 dbus_message_iter_get_basic (&iter, ¤t_value);
494 reading_material->upper = current_value;
495 dbus_message_iter_next (&iter);
497 /* get minimum value */
498 dbus_message_iter_get_basic (&iter, ¤t_value);
499 reading_material->lower = current_value;
500 dbus_message_iter_next (&iter);
502 /* get description */
503 dbus_message_iter_get_basic (&iter, &name);
504 reading_material->description = g_strdup (name);
505 dbus_message_iter_next (&iter);
507 /* get index in parent */
508 dbus_message_iter_get_basic (&iter, &index_in_parent);
509 reading_material->index_in_parent = index_in_parent;
510 dbus_message_iter_next (&iter);
512 /* get selected in parent */
513 dbus_message_iter_get_basic (&iter, &is_selected);
514 reading_material->is_selected_in_parent = is_selected;
515 dbus_message_iter_next (&iter);
517 /* get has checkbox child */
518 dbus_message_iter_get_basic (&iter, &is_selected);
519 reading_material->has_checkbox_child = is_selected;
520 dbus_message_iter_next (&iter);
522 /* get list children count */
523 dbus_message_iter_get_basic (&iter, &child_count);
524 reading_material->list_children_count = child_count;
525 dbus_message_iter_next (&iter);
527 /* get first selected child index */
528 dbus_message_iter_get_basic (&iter, &index_in_parent);
529 reading_material->first_selected_child_index = index_in_parent;
530 dbus_message_iter_next (&iter);
534 parent = _atspi_dbus_return_accessible_from_iter (&iter);
535 reading_material->parent = parent;
538 dbus_message_iter_recurse (&iter, &iter_array);
539 dbus_message_iter_get_fixed_array (&iter_array, &states, &count);
540 val = ((guint64)states [1]) << 32;
542 reading_material->parent_states = val;
543 dbus_message_iter_next (&iter);
545 /* get parent child count */
546 dbus_message_iter_get_basic (&iter, &child_count);
547 reading_material->parent_child_count = child_count;
548 dbus_message_iter_next (&iter);
550 /* get parent role */
551 dbus_message_iter_get_basic (&iter, &role);
552 reading_material->parent_role = role;
553 dbus_message_iter_next (&iter);
555 /* get parent selected child count */
556 dbus_message_iter_get_basic (&iter, &child_count);
557 reading_material->parent_selected_child_count = child_count;
558 dbus_message_iter_next (&iter);
560 ////////////////////////////////////////
561 /* get relation object - DESCRIBED_BY */
562 parent = _atspi_dbus_return_accessible_from_iter (&iter);
563 reading_material->described_by_accessible = parent;
565 return reading_material;
568 static unsigned char are_objects_on_the_same_bus(AtspiAccessible *obj1, AtspiAccessible *obj2)
570 const char *bus_name_1 = obj1->parent.app->bus_name;
571 const char *bus_name_2 = obj2->parent.app->bus_name;
572 return strcmp(bus_name_1, bus_name_2) == 0;
575 static unsigned char object_is_valid(AtspiAccessible *obj)
579 AtspiStateSet *ss = atspi_accessible_get_state_set(obj);
582 unsigned char valid = atspi_state_set_contains(ss, ATSPI_STATE_DEFUNCT) == 0;
588 NEIGHBOR_SEARCH_MODE_NORMAL = 0,
589 NEIGHBOR_SEARCH_MODE_RECURSE_FROM_ROOT = 1,
590 NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING = 2,
591 NEIGHBOR_SEARCH_MODE_RECURSE_TO_OUTSIDE = 3,
592 } GetNeighborSearchMode;
594 * atspi_accessible_get_neighbor:
595 * @root: a pointer to a #AtspiAccessible, which represents current root of subtree to search
596 * @start: a pointer to the #AtspiAccessible to start search from (can be null, which means start from root)
597 * @direction: direction, in which search (forward or backward)
599 * Calculates next (or previous) accessible element in logical order or null if none found.
601 * Returns: (nullable) (transfer full): a pointer to an
602 * #AtspiAccessible element, which is next (previous) in logical order or null if none found.
605 atspi_accessible_get_neighbor (AtspiAccessible *root,
606 AtspiAccessible *start,
607 AtspiNeighborSearchDirection direction,
610 g_return_val_if_fail (object_is_valid(root), NULL);
611 if (!object_is_valid(start))
613 const char *root_path = ATSPI_OBJECT(root)->path;
614 AtspiAccessible *return_value = NULL;
616 unsigned char recurse;
617 GetNeighborSearchMode search_mode = NEIGHBOR_SEARCH_MODE_NORMAL;
618 GQueue *children_root_stack = g_queue_new();
619 DBusMessageIter iter;
622 const char *path = are_objects_on_the_same_bus(root, start) ? root_path : "";
623 DBusMessage *reply = _atspi_dbus_call_partial (start, atspi_interface_accessible, "GetNeighbor", error, "sii", path, (int)direction, (int)search_mode);
624 // call failed, error is set, so we bail out
627 _ATSPI_DBUS_CHECK_SIG (reply, "(so)y", error, NULL);
628 dbus_message_iter_init (reply, &iter);
629 AtspiAccessible *ret = _atspi_dbus_return_accessible_from_iter (&iter);
631 unsigned char value = 0;
632 dbus_message_iter_get_basic (&iter, &value);
633 dbus_message_iter_next (&iter);
634 recurse = (value != 0);
636 dbus_message_unref(reply);
638 // got return value and request for recursive search, it means ret is on another bridge, than start
639 // thus we're recursing. should the recurse failed to find anything it will end with
640 if (ret && recurse) {
641 g_object_unref(G_OBJECT(start));
644 if (are_objects_on_the_same_bus(root, ret))
646 search_mode = NEIGHBOR_SEARCH_MODE_RECURSE_TO_OUTSIDE;
650 g_queue_push_tail(children_root_stack, ret);
651 search_mode = NEIGHBOR_SEARCH_MODE_RECURSE_FROM_ROOT;
655 // found the one we've been looking for
657 g_object_unref(G_OBJECT(start));
662 // we've stepped into different bridges previously and now we're going back to the last one
663 // and continuing search where we left
664 if (!g_queue_is_empty(children_root_stack)) {
665 g_object_unref(G_OBJECT(start));
666 start = g_queue_pop_tail(children_root_stack);
668 search_mode = NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING;
671 // there's no more bridges to check, but we might have started from one
672 // in that case there might be bridges "below" start, which we yet have to visit
673 if (!are_objects_on_the_same_bus(root, start)) {
674 unsigned char continue_loop = 1;
675 while(continue_loop) {
676 AtspiAccessible *parent = atspi_accessible_get_parent(start, NULL);
677 continue_loop = parent ? are_objects_on_the_same_bus(start, parent) : 0;
678 g_object_unref(G_OBJECT(start));
682 // going up thru parents put us in weird place (we didnt meet root on the way)
687 // start object now points to different bridge and must be treated as "resume after recursing"
688 search_mode = NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING;
693 g_object_unref(start);
696 while(!g_queue_is_empty(children_root_stack))
697 g_object_unref(g_queue_pop_tail(children_root_stack));
698 g_queue_free(children_root_stack);
704 * atspi_accessible_get_description:
705 * @obj: a pointer to the #AtspiAccessible object on which to operate.
707 * Gets the description of an #AtspiAccessible object.
709 * Returns: a UTF-8 string describing the #AtspiAccessible object
710 * or NULL on exception.
713 atspi_accessible_get_description (AtspiAccessible *obj, GError **error)
715 g_return_val_if_fail (obj != NULL, g_strdup (""));
717 if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_DESCRIPTION))
719 if (!_atspi_dbus_get_property (obj, atspi_interface_accessible,
720 "Description", error, "s",
722 return g_strdup ("");
723 _atspi_accessible_add_cache (obj, ATSPI_CACHE_DESCRIPTION);
725 return g_strdup (obj->description);
728 const char *str_parent = "Parent";
731 * atspi_accessible_get_parent:
732 * @obj: a pointer to the #AtspiAccessible object to query.
734 * Gets an #AtspiAccessible object's parent container.
736 * Returns: (nullable) (transfer full): a pointer to the
737 * #AtspiAccessible object which contains the given
738 * #AtspiAccessible instance, or NULL if the @obj has no
743 atspi_accessible_get_parent (AtspiAccessible *obj, GError **error)
745 g_return_val_if_fail (obj != NULL, NULL);
747 if (obj->parent.app &&
748 !_atspi_accessible_test_cache (obj, ATSPI_CACHE_PARENT))
750 DBusMessage *message, *reply;
751 DBusMessageIter iter, iter_variant;
752 message = dbus_message_new_method_call (obj->parent.app->bus_name,
754 DBUS_INTERFACE_PROPERTIES, "Get");
757 dbus_message_append_args (message, DBUS_TYPE_STRING, &atspi_interface_accessible,
758 DBUS_TYPE_STRING, &str_parent,
760 reply = _atspi_dbus_send_with_reply_and_block (message, error);
763 if (strcmp (dbus_message_get_signature (reply), "v") != 0)
765 dbus_message_unref (reply);
768 dbus_message_iter_init (reply, &iter);
769 dbus_message_iter_recurse (&iter, &iter_variant);
770 obj->accessible_parent = _atspi_dbus_return_accessible_from_iter (&iter_variant);
771 dbus_message_unref (reply);
772 _atspi_accessible_add_cache (obj, ATSPI_CACHE_PARENT);
774 if (!obj->accessible_parent)
776 return g_object_ref (obj->accessible_parent);
780 * atspi_accessible_get_child_count:
781 * @obj: a pointer to the #AtspiAccessible object on which to operate.
783 * Gets the number of children contained by an #AtspiAccessible object.
785 * Returns: a #long indicating the number of #AtspiAccessible children
786 * contained by an #AtspiAccessible object or -1 on exception.
790 atspi_accessible_get_child_count (AtspiAccessible *obj, GError **error)
792 g_return_val_if_fail (obj != NULL, -1);
794 if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_CHILDREN))
797 if (!_atspi_dbus_get_property (obj, atspi_interface_accessible,
798 "ChildCount", error, "i", &ret))
803 return g_list_length (obj->children);
807 * atspi_accessible_get_child_at_index:
808 * @obj: a pointer to the #AtspiAccessible object on which to operate.
809 * @child_index: a #long indicating which child is specified.
811 * Gets the #AtspiAccessible child of an #AtspiAccessible object at a given index.
813 * Returns: (transfer full): a pointer to the #AtspiAccessible child object at
814 * index @child_index or NULL on exception.
817 atspi_accessible_get_child_at_index (AtspiAccessible *obj,
821 AtspiAccessible *child;
823 g_return_val_if_fail (obj != NULL, NULL);
825 if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_CHILDREN))
828 reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible,
829 "GetChildAtIndex", error, "i",
831 return _atspi_dbus_return_accessible_from_message (reply);
834 child = g_list_nth_data (obj->children, child_index);
837 return g_object_ref (child);
841 * atspi_accessible_get_index_in_parent:
842 * @obj: a pointer to the #AtspiAccessible object on which to operate.
844 * Gets the index of an #AtspiAccessible object within its parent's
845 * #AtspiAccessible children list.
847 * Returns: a #glong indicating the index of the #AtspiAccessible object
849 * or -1 if @obj has no containing parent or on exception.
852 atspi_accessible_get_index_in_parent (AtspiAccessible *obj, GError **error)
857 g_return_val_if_fail (obj != NULL, -1);
858 if (_atspi_accessible_test_cache (obj, ATSPI_CACHE_PARENT) &&
859 !obj->accessible_parent)
861 if (!obj->accessible_parent ||
862 !_atspi_accessible_test_cache (obj->accessible_parent,
863 ATSPI_CACHE_CHILDREN))
865 dbus_int32_t ret = -1;
866 _atspi_dbus_call (obj, atspi_interface_accessible,
867 "GetIndexInParent", NULL, "=>i", &ret);
871 l = obj->accessible_parent->children;
874 if (l->data == obj) return i;
885 } Accessibility_Relation;
888 * atspi_accessible_get_relation_set:
889 * @obj: a pointer to the #AtspiAccessible object on which to operate.
891 * Gets the set of #AtspiRelation objects which describes this #AtspiAccessible object's
892 * relationships with other #AtspiAccessible objects.
894 * Returns: (element-type AtspiRelation*) (transfer full): a #GArray of
895 * #AtspiRelation pointers or NULL on exception.
898 atspi_accessible_get_relation_set (AtspiAccessible *obj, GError **error)
901 DBusMessageIter iter, iter_array;
904 g_return_val_if_fail (obj != NULL, NULL);
906 reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetRelationSet", error, "");
909 _ATSPI_DBUS_CHECK_SIG (reply, "a(ua(so))", error, NULL);
911 ret = g_array_new (TRUE, TRUE, sizeof (AtspiRelation *));
912 dbus_message_iter_init (reply, &iter);
913 dbus_message_iter_recurse (&iter, &iter_array);
914 while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
916 AtspiRelation *relation;
917 relation = _atspi_relation_new_from_iter (&iter_array);
918 ret = g_array_append_val (ret, relation);
919 dbus_message_iter_next (&iter_array);
921 dbus_message_unref (reply);
926 * atspi_accessible_get_role:
927 * @obj: a pointer to the #AtspiAccessible object on which to operate.
929 * Gets the UI role played by an #AtspiAccessible object.
930 * This role's name can be obtained via atspi_accessible_get_role_name ().
932 * Returns: the #AtspiRole of an #AtspiAccessible object.
936 atspi_accessible_get_role (AtspiAccessible *obj, GError **error)
938 g_return_val_if_fail (obj != NULL, ATSPI_ROLE_INVALID);
940 if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_ROLE))
943 /* TODO: Make this a property */
944 if (_atspi_dbus_call (obj, atspi_interface_accessible, "GetRole", error, "=>u", &role))
947 _atspi_accessible_add_cache (obj, ATSPI_CACHE_ROLE);
954 * atspi_accessible_get_role_name:
955 * @obj: a pointer to the #AtspiAccessible object on which to operate.
957 * Gets a UTF-8 string corresponding to the name of the role played by an object.
958 * This method will return useful values for roles that fall outside the
959 * enumeration used in atspi_accessible_get_role ().
961 * Returns: a UTF-8 string specifying the type of UI role played by an
962 * #AtspiAccessible object.
966 atspi_accessible_get_role_name (AtspiAccessible *obj, GError **error)
968 gchar *retval = NULL;
971 g_return_val_if_fail (obj != NULL, NULL);
973 role = atspi_accessible_get_role (obj, error);
974 if (role >= 0 && role < ATSPI_ROLE_COUNT && role != ATSPI_ROLE_EXTENDED)
975 return atspi_role_get_name (role);
977 _atspi_dbus_call (obj, atspi_interface_accessible, "GetRoleName", error, "=>s", &retval);
980 retval = g_strdup ("");
986 * atspi_accessible_get_localized_role_name:
987 * @obj: a pointer to the #AtspiAccessible object on which to operate.
989 * Gets a UTF-8 string corresponding to the name of the role played by an
990 * object, translated to the current locale.
991 * This method will return useful values for roles that fall outside the
992 * enumeration used in atspi_accessible_getRole ().
994 * Returns: a localized, UTF-8 string specifying the type of UI role played
995 * by an #AtspiAccessible object.
999 atspi_accessible_get_localized_role_name (AtspiAccessible *obj, GError **error)
1001 char *retval = NULL;
1003 g_return_val_if_fail (obj != NULL, NULL);
1005 _atspi_dbus_call (obj, atspi_interface_accessible, "GetLocalizedRoleName", error, "=>s", &retval);
1008 return g_strdup ("");
1013 static AtspiStateSet *
1016 AtspiStateSet *set = atspi_state_set_new (NULL);
1017 atspi_state_set_add (set, ATSPI_STATE_DEFUNCT);
1022 * atspi_accessible_get_state_set:
1023 * @obj: a pointer to the #AtspiAccessible object on which to operate.
1025 * Gets the states currently held by an object.
1027 * Returns: (transfer full): a pointer to an #AtspiStateSet representing an
1028 * object's current state set.
1031 atspi_accessible_get_state_set (AtspiAccessible *obj)
1033 /* TODO: Should take a GError **, but would be an API break */
1034 if (!obj->parent.app || !obj->parent.app->bus)
1035 return defunct_set ();
1037 if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_STATES))
1040 DBusMessageIter iter;
1041 reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible,
1042 "GetState", NULL, "");
1043 _ATSPI_DBUS_CHECK_SIG (reply, "au", NULL, defunct_set ());
1044 dbus_message_iter_init (reply, &iter);
1045 _atspi_dbus_set_state (obj, &iter);
1046 dbus_message_unref (reply);
1047 _atspi_accessible_add_cache (obj, ATSPI_CACHE_STATES);
1049 return g_object_ref (obj->states);
1053 * atspi_accessible_get_attributes:
1054 * @obj: The #AtspiAccessible being queried.
1056 * Gets the #AttributeSet representing any assigned
1057 * name-value pair attributes or annotations for this object.
1058 * For typographic, textual, or textually-semantic attributes, see
1059 * atspi_text_get_attributes instead.
1061 * Returns: (element-type gchar* gchar*) (transfer full): The name-value-pair
1062 * attributes assigned to this object.
1065 atspi_accessible_get_attributes (AtspiAccessible *obj, GError **error)
1067 DBusMessage *message;
1069 g_return_val_if_fail (obj != NULL, NULL);
1071 if (obj->priv->cache)
1073 GValue *val = g_hash_table_lookup (obj->priv->cache, "Attributes");
1075 return g_value_dup_boxed (val);
1078 if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_ATTRIBUTES))
1080 message = _atspi_dbus_call_partial (obj, atspi_interface_accessible,
1081 "GetAttributes", error, "");
1082 obj->attributes = _atspi_dbus_return_hash_from_message (message);
1083 _atspi_accessible_add_cache (obj, ATSPI_CACHE_ATTRIBUTES);
1086 if (!obj->attributes)
1088 return g_hash_table_ref (obj->attributes);
1092 add_to_attribute_array (gpointer key, gpointer value, gpointer data)
1094 GArray **array = (GArray **)data;
1095 gchar *str = g_strconcat (key, ":", value, NULL);
1096 *array = g_array_append_val (*array, str);
1100 * atspi_accessible_get_attributes_as_array:
1101 * @obj: The #AtspiAccessible being queried.
1103 * Gets a #GArray representing any assigned
1104 * name-value pair attributes or annotations for this object.
1105 * For typographic, textual, or textually-semantic attributes, see
1106 * atspi_text_get_attributes_as_array instead.
1108 * Returns: (element-type gchar*) (transfer full): The name-value-pair
1109 * attributes assigned to this object.
1112 atspi_accessible_get_attributes_as_array (AtspiAccessible *obj, GError **error)
1114 DBusMessage *message;
1116 g_return_val_if_fail (obj != NULL, NULL);
1118 if (obj->priv->cache)
1120 GValue *val = g_hash_table_lookup (obj->priv->cache, "Attributes");
1123 GArray *array = g_array_new (TRUE, TRUE, sizeof (gchar *));
1124 GHashTable *attributes = g_value_get_boxed (val);
1125 g_hash_table_foreach (attributes, add_to_attribute_array, &array);
1130 message = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetAttributes", error, "");
1131 return _atspi_dbus_return_attribute_array_from_message (message);
1135 * atspi_accessible_get_application:
1136 * @obj: The #AtspiAccessible being queried.
1138 * Gets the containing #AtspiApplication for an object.
1140 * Returns: (transfer full): the containing #AtspiApplication instance for
1144 atspi_accessible_get_application (AtspiAccessible *obj, GError **error)
1146 AtspiAccessible *parent;
1151 parent = atspi_accessible_get_parent (obj, NULL);
1152 if (!parent && obj->parent.app &&
1153 atspi_accessible_get_role (obj, NULL) != ATSPI_ROLE_APPLICATION)
1155 AtspiAccessible *root = g_object_ref (obj->parent.app->root);
1158 g_object_unref (obj);
1159 if (atspi_accessible_get_role (root, NULL) == ATSPI_ROLE_DESKTOP_FRAME)
1161 g_object_unref (root);
1167 if (!parent || parent == obj ||
1168 atspi_accessible_get_role (parent, NULL) == ATSPI_ROLE_DESKTOP_FRAME)
1171 g_object_unref (parent);
1174 g_object_unref (obj);
1179 /* Application-specific methods */
1182 * atspi_accessible_get_toolkit_name:
1183 * @obj: a pointer to the #AtspiAccessible object on which to operate.
1185 * Gets the toolkit name for an #AtspiAccessible object.
1186 * Only works on application root objects.
1188 * Returns: a UTF-8 string indicating the toolkit name for the #AtspiAccessible object or NULL on exception.
1191 atspi_accessible_get_toolkit_name (AtspiAccessible *obj, GError **error)
1193 g_return_val_if_fail (obj != NULL, NULL);
1195 if (!obj->parent.app)
1198 if (!obj->parent.app->toolkit_name)
1199 _atspi_dbus_get_property (obj, atspi_interface_application, "ToolkitName",
1200 error, "s", &obj->parent.app->toolkit_name);
1202 return g_strdup (obj->parent.app->toolkit_name);
1206 * atspi_accessible_get_toolkit_version:
1207 * @obj: a pointer to the #AtspiAccessible object on which to operate.
1209 * Gets the toolkit version for an #AtspiAccessible object.
1210 * Only works on application root objects.
1212 * Returns: a UTF-8 string indicating the toolkit version for the #AtspiAccessible object or NULL on exception.
1215 atspi_accessible_get_toolkit_version (AtspiAccessible *obj, GError **error)
1217 g_return_val_if_fail (obj != NULL, NULL);
1219 if (!obj->parent.app)
1222 if (!obj->parent.app->toolkit_version)
1223 _atspi_dbus_get_property (obj, atspi_interface_application, "Version",
1224 error, "s", &obj->parent.app->toolkit_version);
1226 return g_strdup (obj->parent.app->toolkit_version);
1230 * atspi_accessible_get_atspi_version:
1231 * @obj: a pointer to the #AtspiAccessible object on which to operate.
1233 * Gets the AT-SPI IPC specification version supported by the application
1234 * pointed to by the #AtspiAccessible object.
1235 * Only works on application root objects.
1237 * Returns: a UTF-8 string indicating the AT-SPI version for the #AtspiAccessible object or NULL on exception.
1240 atspi_accessible_get_atspi_version (AtspiAccessible *obj, GError **error)
1242 g_return_val_if_fail (obj != NULL, NULL);
1244 if (!obj->parent.app)
1247 if (!obj->parent.app->atspi_version)
1248 _atspi_dbus_get_property (obj, atspi_interface_application, "AtspiVersion",
1249 error, "s", &obj->parent.app->atspi_version);
1251 return g_strdup (obj->parent.app->atspi_version);
1255 * atspi_accessible_get_id:
1256 * @obj: a pointer to the #AtspiAccessible object on which to operate.
1258 * Gets the application id for a #AtspiAccessible object.
1259 * Only works on application root objects.
1261 * Returns: a positive #gint indicating the id for the #AtspiAccessible object
1262 * or -1 on exception.
1265 atspi_accessible_get_id (AtspiAccessible *obj, GError **error)
1269 g_return_val_if_fail (obj != NULL, -1);
1271 if (!_atspi_dbus_get_property (obj, atspi_interface_application, "Id", error, "i", &ret))
1277 /* Interface query methods */
1280 _atspi_accessible_is_a (AtspiAccessible *accessible,
1281 const char *interface_name)
1285 if (accessible == NULL)
1290 if (!_atspi_accessible_test_cache (accessible, ATSPI_CACHE_INTERFACES))
1293 DBusMessageIter iter;
1294 reply = _atspi_dbus_call_partial (accessible, atspi_interface_accessible,
1295 "GetInterfaces", NULL, "");
1296 _ATSPI_DBUS_CHECK_SIG (reply, "as", NULL, FALSE);
1297 dbus_message_iter_init (reply, &iter);
1298 _atspi_dbus_set_interfaces (accessible, &iter);
1299 dbus_message_unref (reply);
1300 _atspi_accessible_add_cache (accessible, ATSPI_CACHE_INTERFACES);
1303 n = _atspi_get_iface_num (interface_name);
1304 if (n == -1) return FALSE;
1305 return (gboolean) ((accessible->interfaces & (1 << n))? TRUE: FALSE);
1309 * atspi_accessible_is_action:
1310 * @obj: a pointer to the #AtspiAccessible instance to query.
1312 * Query whether the specified #AtspiAccessible implements the
1313 * #AtspiAction interface.
1315 * Returns: #TRUE if @obj implements the #AtspiAction interface,
1319 atspi_accessible_is_action (AtspiAccessible *obj)
1321 return _atspi_accessible_is_a (obj,
1322 atspi_interface_action);
1326 * atspi_accessible_is_application:
1327 * @obj: a pointer to the #AtspiAccessible instance to query.
1329 * Query whether the specified #AtspiAccessible implements the
1330 * #AtspiApplication interface.
1332 * Returns: #TRUE if @obj implements the #AtspiApplication interface,
1336 atspi_accessible_is_application (AtspiAccessible *obj)
1338 return _atspi_accessible_is_a (obj,
1339 atspi_interface_application);
1343 * atspi_accessible_is_collection:
1344 * @obj: a pointer to the #AtspiAccessible instance to query.
1346 * Query whether the specified #AtspiAccessible implements the
1347 * #AtspiCollection interface.
1349 * Returns: #TRUE if @obj implements the #AtspiCollection interface,
1353 atspi_accessible_is_collection (AtspiAccessible *obj)
1355 return _atspi_accessible_is_a (obj,
1356 atspi_interface_collection);
1360 * atspi_accessible_is_component:
1361 * @obj: a pointer to the #AtspiAccessible instance to query.
1363 * Query whether the specified #AtspiAccessible implements #AtspiComponent.
1365 * Returns: #TRUE if @obj implements the #AtspiComponent interface,
1369 atspi_accessible_is_component (AtspiAccessible *obj)
1371 return _atspi_accessible_is_a (obj,
1372 atspi_interface_component);
1376 * atspi_accessible_is_document:
1377 * @obj: a pointer to the #AtspiAccessible instance to query.
1379 * Query whether the specified #AtspiAccessible implements the
1380 * #AtspiDocument interface.
1382 * Returns: #TRUE if @obj implements the #AtspiDocument interface,
1386 atspi_accessible_is_document (AtspiAccessible *obj)
1388 return _atspi_accessible_is_a (obj,
1389 atspi_interface_document);
1393 * atspi_accessible_is_editable_text:
1394 * @obj: a pointer to the #AtspiAccessible instance to query.
1396 * Query whether the specified #AtspiAccessible implements the
1397 * #AtspiEditableText interface.
1399 * Returns: #TRUE if @obj implements the #AtspiEditableText interface,
1403 atspi_accessible_is_editable_text (AtspiAccessible *obj)
1405 return _atspi_accessible_is_a (obj,
1406 atspi_interface_editable_text);
1410 * atspi_accessible_is_hypertext:
1411 * @obj: a pointer to the #AtspiAccessible instance to query.
1413 * Query whether the specified #AtspiAccessible implements the
1414 * #AtspiHypertext interface.
1416 * Returns: #TRUE if @obj implements the #AtspiHypertext interface,
1420 atspi_accessible_is_hypertext (AtspiAccessible *obj)
1422 return _atspi_accessible_is_a (obj,
1423 atspi_interface_hypertext);
1427 * atspi_accessible_is_hyperlink:
1428 * @obj: a pointer to the #AtspiAccessible instance to query.
1430 * Query whether the specified #AtspiAccessible implements the
1431 * #AtspiHyperlink interface.
1433 * Returns: #TRUE if @obj implements the #AtspiHypertext interface,
1437 atspi_accessible_is_hyperlink (AtspiAccessible *obj)
1439 return _atspi_accessible_is_a (obj,
1440 atspi_interface_hyperlink);
1444 * atspi_accessible_is_image:
1445 * @obj: a pointer to the #AtspiAccessible instance to query.
1447 * Query whether the specified #AtspiAccessible implements the
1448 * #AtspiImage interface.
1450 * Returns: #TRUE if @obj implements the #AtspiImage interface,
1454 atspi_accessible_is_image (AtspiAccessible *obj)
1456 return _atspi_accessible_is_a (obj,
1457 atspi_interface_image);
1461 * atspi_accessible_is_selection:
1462 * @obj: a pointer to the #AtspiAccessible instance to query.
1464 * Query whether the specified #AtspiAccessible implements the
1465 * #AtspiSelection interface.
1467 * Returns: #TRUE if @obj implements the #AtspiSelection interface,
1471 atspi_accessible_is_selection (AtspiAccessible *obj)
1473 return _atspi_accessible_is_a (obj,
1474 atspi_interface_selection);
1478 * atspi_accessible_is_table:
1479 * @obj: a pointer to the #AtspiAccessible instance to query.
1481 * Query whether the specified #AtspiAccessible implements the
1482 * #AtspiTable interface.
1484 * Returns: #TRUE if @obj implements the #AtspiTable interface,
1488 atspi_accessible_is_table (AtspiAccessible *obj)
1490 return _atspi_accessible_is_a (obj,
1491 atspi_interface_table);
1495 * atspi_accessible_is_table_cell:
1496 * @obj: a pointer to the #AtspiAccessible instance to query.
1498 * Query whether the specified #AtspiAccessible implements the
1499 * #AtspiTableCell interface.
1501 * Returns: #TRUE if @obj implements the #AtspiTable interface,
1505 atspi_accessible_is_table_cell (AtspiAccessible *obj)
1507 return _atspi_accessible_is_a (obj,
1508 atspi_interface_table_cell);
1512 * atspi_accessible_is_streamable_content:
1513 * @obj: a pointer to the #AtspiAccessible instance to query.
1515 * Query whether the specified #AtspiAccessible implements the
1516 * #AtspiStreamableContent interface.
1518 * Returns: #TRUE if @obj implements the #AtspiStreamableContent interface,
1522 atspi_accessible_is_streamable_content (AtspiAccessible *obj)
1525 return _atspi_accessible_is_a (obj,
1526 atspi_interface_streamable_content);
1528 g_warning ("Streamable content not implemented");
1534 * atspi_accessible_is_text:
1535 * @obj: a pointer to the #AtspiAccessible instance to query.
1537 * Query whether the specified #AtspiAccessible implements the
1538 * #AtspiText interface.
1540 * Returns: #TRUE if @obj implements the #AtspiText interface,
1544 atspi_accessible_is_text (AtspiAccessible *obj)
1546 return _atspi_accessible_is_a (obj,
1547 atspi_interface_text);
1551 * atspi_accessible_is_value:
1552 * @obj: a pointer to the #AtspiAccessible instance to query.
1554 * Query whether the specified #AtspiAccessible implements the
1555 * #AtspiValue interface.
1557 * Returns: #TRUE if @obj implements the #AtspiValue interface,
1561 atspi_accessible_is_value (AtspiAccessible *obj)
1563 return _atspi_accessible_is_a (obj,
1564 atspi_interface_value);
1568 * atspi_accessible_get_action: (rename-to atspi_accessible_get_action_iface)
1569 * @obj: a pointer to the #AtspiAccessible instance to query.
1571 * Gets the #AtspiAction interface for an #AtspiAccessible.
1573 * Returns: (transfer full): a pointer to an #AtspiAction interface
1574 * instance, or NULL if @obj does not implement #AtspiAction.
1576 * Deprecated: 2.10: Use atspi_accessible_get_action_iface instead.
1579 atspi_accessible_get_action (AtspiAccessible *accessible)
1581 return (_atspi_accessible_is_a (accessible, atspi_interface_action) ?
1582 g_object_ref (ATSPI_ACTION (accessible)) : NULL);
1586 * atspi_accessible_get_action_iface:
1587 * @obj: a pointer to the #AtspiAccessible instance to query.
1589 * Gets the #AtspiAction interface for an #AtspiAccessible.
1591 * Returns: (transfer full): a pointer to an #AtspiAction interface
1592 * instance, or NULL if @obj does not implement #AtspiAction.
1595 atspi_accessible_get_action_iface (AtspiAccessible *accessible)
1597 return (_atspi_accessible_is_a (accessible, atspi_interface_action) ?
1598 g_object_ref (ATSPI_ACTION (accessible)) : NULL);
1602 * atspi_accessible_get_collection: (rename-to atspi_accessible_get_collection_iface)
1603 * @obj: a pointer to the #AtspiAccessible instance to query.
1605 * Gets the #AtspiCollection interface for an #AtspiAccessible.
1607 * Returns: (transfer full): a pointer to an #AtspiCollection interface
1608 * instance, or NULL if @obj does not implement #AtspiCollection.
1610 * Deprecated: 2.10: Use atspi_accessible_get_collection_iface instead.
1613 atspi_accessible_get_collection (AtspiAccessible *accessible)
1615 return (_atspi_accessible_is_a (accessible, atspi_interface_collection) ?
1616 g_object_ref (ATSPI_COLLECTION (accessible)) : NULL);
1620 * atspi_accessible_get_collection_iface:
1621 * @obj: a pointer to the #AtspiAccessible instance to query.
1623 * Gets the #AtspiCollection interface for an #AtspiAccessible.
1625 * Returns: (transfer full): a pointer to an #AtspiCollection interface
1626 * instance, or NULL if @obj does not implement #AtspiCollection.
1629 atspi_accessible_get_collection_iface (AtspiAccessible *accessible)
1631 return (_atspi_accessible_is_a (accessible, atspi_interface_collection) ?
1632 g_object_ref (ATSPI_COLLECTION (accessible)) : NULL);
1636 * atspi_accessible_get_component: (rename-to atspi_accessible_get_component_iface)
1637 * @obj: a pointer to the #AtspiAccessible instance to query.
1639 * Gets the #AtspiComponent interface for an #AtspiAccessible.
1641 * Returns: (transfer full): a pointer to an #AtspiComponent interface
1642 * instance, or NULL if @obj does not implement #AtspiComponent.
1644 * Deprecated: 2.10: Use atspi_accessible_get_component_iface instead.
1647 atspi_accessible_get_component (AtspiAccessible *obj)
1649 return (_atspi_accessible_is_a (obj, atspi_interface_component) ?
1650 g_object_ref (ATSPI_COMPONENT (obj)) : NULL);
1654 * atspi_accessible_get_component_iface:
1655 * @obj: a pointer to the #AtspiAccessible instance to query.
1657 * Gets the #AtspiComponent interface for an #AtspiAccessible.
1659 * Returns: (transfer full): a pointer to an #AtspiComponent interface
1660 * instance, or NULL if @obj does not implement #AtspiComponent.
1663 atspi_accessible_get_component_iface (AtspiAccessible *obj)
1665 return (_atspi_accessible_is_a (obj, atspi_interface_component) ?
1666 g_object_ref (ATSPI_COMPONENT (obj)) : NULL);
1670 * atspi_accessible_get_document: (rename-to atspi_accessible_get_document_iface)
1671 * @obj: a pointer to the #AtspiAccessible instance to query.
1673 * Gets the #AtspiDocument interface for an #AtspiAccessible.
1675 * Returns: (transfer full): a pointer to an #AtspiDocument interface
1676 * instance, or NULL if @obj does not implement #AtspiDocument.
1678 * Deprecated: 2.10: Use atspi_accessible_get_document_iface instead.
1681 atspi_accessible_get_document (AtspiAccessible *accessible)
1683 return (_atspi_accessible_is_a (accessible, atspi_interface_document) ?
1684 g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL);
1688 * atspi_accessible_get_document_iface:
1689 * @obj: a pointer to the #AtspiAccessible instance to query.
1691 * Gets the #AtspiDocument interface for an #AtspiAccessible.
1693 * Returns: (transfer full): a pointer to an #AtspiDocument interface
1694 * instance, or NULL if @obj does not implement #AtspiDocument.
1697 atspi_accessible_get_document_iface (AtspiAccessible *accessible)
1699 return (_atspi_accessible_is_a (accessible, atspi_interface_document) ?
1700 g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL);
1704 * atspi_accessible_get_editable_text: (rename-to atspi_accessible_get_editable_text_iface)
1705 * @obj: a pointer to the #AtspiAccessible instance to query.
1707 * Gets the #AtspiEditableText interface for an #AtspiAccessible.
1709 * Returns: (transfer full): a pointer to an #AtspiEditableText interface
1710 * instance, or NULL if @obj does not implement #AtspiEditableText.
1712 * Deprecated: 2.10: Use atspi_accessible_get_editable_text_iface instead.
1715 atspi_accessible_get_editable_text (AtspiAccessible *accessible)
1717 return (_atspi_accessible_is_a (accessible, atspi_interface_editable_text) ?
1718 g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL);
1722 * atspi_accessible_get_editable_text_iface:
1723 * @obj: a pointer to the #AtspiAccessible instance to query.
1725 * Gets the #AtspiEditableText interface for an #AtspiAccessible.
1727 * Returns: (transfer full): a pointer to an #AtspiEditableText interface
1728 * instance, or NULL if @obj does not implement #AtspiEditableText.
1731 atspi_accessible_get_editable_text_iface (AtspiAccessible *accessible)
1733 return (_atspi_accessible_is_a (accessible, atspi_interface_editable_text) ?
1734 g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL);
1738 * atspi_accessible_get_hyperlink:
1739 * @obj: a pointer to the #AtspiAccessible object on which to operate.
1741 * Gets the #AtspiHyperlink interface for an #AtspiAccessible.
1743 * Returns: (transfer full): the #AtspiHyperlink object associated with
1744 * the given #AtspiAccessible, or NULL if not supported.
1747 atspi_accessible_get_hyperlink (AtspiAccessible *accessible)
1749 return (_atspi_accessible_is_a (accessible, atspi_interface_hyperlink) ?
1750 _atspi_hyperlink_new (accessible->parent.app, accessible->parent.path) : NULL);
1754 * atspi_accessible_get_hypertext: (rename-to atspi_accessible_get_hypertext_iface)
1755 * @obj: a pointer to the #AtspiAccessible instance to query.
1757 * Gets the #AtspiHypertext interface for an #AtspiAccessible.
1759 * Returns: (transfer full): a pointer to an #AtspiHypertext interface
1760 * instance, or NULL if @obj does not implement #AtspiHypertext.
1762 * Deprecated: 2.10: Use atspi_accessible_get_hypertext_iface instead.
1765 atspi_accessible_get_hypertext (AtspiAccessible *accessible)
1767 return (_atspi_accessible_is_a (accessible, atspi_interface_hypertext) ?
1768 g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL);
1772 * atspi_accessible_get_hypertext_iface:
1773 * @obj: a pointer to the #AtspiAccessible instance to query.
1775 * Gets the #AtspiHypertext interface for an #AtspiAccessible.
1777 * Returns: (transfer full): a pointer to an #AtspiHypertext interface
1778 * instance, or NULL if @obj does not implement #AtspiHypertext.
1781 atspi_accessible_get_hypertext_iface (AtspiAccessible *accessible)
1783 return (_atspi_accessible_is_a (accessible, atspi_interface_hypertext) ?
1784 g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL);
1788 * atspi_accessible_get_image: (rename-to atspi_accessible_get_image_iface)
1789 * @obj: a pointer to the #AtspiAccessible instance to query.
1791 * Gets the #AtspiImage interface for an #AtspiAccessible.
1793 * Returns: (transfer full): a pointer to an #AtspiImage interface instance, or
1794 * NULL if @obj does not implement #AtspiImage.
1796 * Deprecated: 2.10: Use atspi_accessible_get_image_iface instead.
1799 atspi_accessible_get_image (AtspiAccessible *accessible)
1801 return (_atspi_accessible_is_a (accessible, atspi_interface_image) ?
1802 g_object_ref (ATSPI_IMAGE (accessible)) : NULL);
1806 * atspi_accessible_get_image_iface:
1807 * @obj: a pointer to the #AtspiAccessible instance to query.
1809 * Gets the #AtspiImage interface for an #AtspiAccessible.
1811 * Returns: (transfer full): a pointer to an #AtspiImage interface instance, or
1812 * NULL if @obj does not implement #AtspiImage.
1815 atspi_accessible_get_image_iface (AtspiAccessible *accessible)
1817 return (_atspi_accessible_is_a (accessible, atspi_interface_image) ?
1818 g_object_ref (ATSPI_IMAGE (accessible)) : NULL);
1822 * atspi_accessible_get_selection: (rename-to atspi_accessible_get_selection_iface)
1823 * @obj: a pointer to the #AtspiAccessible instance to query.
1825 * Gets the #AtspiSelection interface for an #AtspiAccessible.
1827 * Returns: (transfer full): a pointer to an #AtspiSelection interface
1828 * instance, or NULL if @obj does not implement #AtspiSelection.
1830 * Deprecated: 2.10: Use atspi_accessible_get_selection_iface instead.
1833 atspi_accessible_get_selection (AtspiAccessible *accessible)
1835 return (_atspi_accessible_is_a (accessible, atspi_interface_selection) ?
1836 g_object_ref (ATSPI_SELECTION (accessible)) : NULL);
1840 * atspi_accessible_get_selection_iface:
1841 * @obj: a pointer to the #AtspiAccessible instance to query.
1843 * Gets the #AtspiSelection interface for an #AtspiAccessible.
1845 * Returns: (transfer full): a pointer to an #AtspiSelection interface
1846 * instance, or NULL if @obj does not implement #AtspiSelection.
1849 atspi_accessible_get_selection_iface (AtspiAccessible *accessible)
1851 return (_atspi_accessible_is_a (accessible, atspi_interface_selection) ?
1852 g_object_ref (ATSPI_SELECTION (accessible)) : NULL);
1857 * atspi_accessible_get_streamable_content:
1858 * @obj: a pointer to the #AtspiAccessible instance to query.
1860 * Gets the #AtspiStreamableContent interface for an #AtspiAccessible.
1862 * Returns: (transfer full): a pointer to an #AtspiStreamableContent interface
1863 * instance, or NULL if @obj does not implement #AtspiStreamableContent.
1865 AtspiStreamableContent *
1866 atspi_accessible_get_streamable_content (AtspiAccessible *accessible)
1868 return (_atspi_accessible_is_a (accessible, atspi_interface_streamable_content) ?
1874 * atspi_accessible_get_table: (rename-to atspi_accessible_get_table_iface)
1875 * @obj: a pointer to the #AtspiAccessible instance to query.
1877 * Gets the #AtspiTable interface for an #AtspiAccessible.
1879 * Returns: (transfer full): a pointer to an #AtspiTable interface instance, or
1880 * NULL if @obj does not implement #AtspiTable.
1882 * Deprecated: 2.10: Use atspi_accessible_get_table_iface instead.
1885 atspi_accessible_get_table (AtspiAccessible *obj)
1887 return (_atspi_accessible_is_a (obj, atspi_interface_table) ?
1888 g_object_ref (ATSPI_TABLE (obj)) : NULL);
1892 * atspi_accessible_get_table_iface:
1893 * @obj: a pointer to the #AtspiAccessible instance to query.
1895 * Gets the #AtspiTable interface for an #AtspiAccessible.
1897 * Returns: (transfer full): a pointer to an #AtspiTable interface instance, or
1898 * NULL if @obj does not implement #AtspiTable.
1901 atspi_accessible_get_table_iface (AtspiAccessible *obj)
1903 return (_atspi_accessible_is_a (obj, atspi_interface_table) ?
1904 g_object_ref (ATSPI_TABLE (obj)) : NULL);
1908 * atspi_accessible_get_table_cell:
1909 * @obj: a pointer to the #AtspiAccessible instance to query.
1911 * Gets the #AtspiTableCell interface for an #AtspiAccessible.
1913 * Returns: (transfer full): a pointer to an #AtspiTableCell interface instance,
1914 * or NULL if @obj does not implement #AtspiTable.
1917 atspi_accessible_get_table_cell (AtspiAccessible *obj)
1919 return (_atspi_accessible_is_a (obj, atspi_interface_table_cell) ?
1920 g_object_ref (ATSPI_TABLE_CELL (obj)) : NULL);
1924 * atspi_accessible_get_text: (rename-to atspi_accessible_get_text_iface)
1925 * @obj: a pointer to the #AtspiAccessible instance to query.
1927 * Gets the #AtspiTable interface for an #AtspiAccessible.
1929 * Returns: (transfer full): a pointer to an #AtspiText interface instance, or
1930 * NULL if @obj does not implement #AtspiText.
1932 * Deprecated: 2.10: Use atspi_accessible_get_text_iface instead.
1935 atspi_accessible_get_text (AtspiAccessible *obj)
1937 return (_atspi_accessible_is_a (obj, atspi_interface_text) ?
1938 g_object_ref (ATSPI_TEXT (obj)) : NULL);
1942 * atspi_accessible_get_text_iface:
1943 * @obj: a pointer to the #AtspiAccessible instance to query.
1945 * Gets the #AtspiTable interface for an #AtspiAccessible.
1947 * Returns: (transfer full): a pointer to an #AtspiText interface instance, or
1948 * NULL if @obj does not implement #AtspiText.
1951 atspi_accessible_get_text_iface (AtspiAccessible *obj)
1953 return (_atspi_accessible_is_a (obj, atspi_interface_text) ?
1954 g_object_ref (ATSPI_TEXT (obj)) : NULL);
1958 * atspi_accessible_get_value: (rename-to atspi_accessible_get_value_iface)
1959 * @obj: a pointer to the #AtspiAccessible instance to query.
1961 * Gets the #AtspiTable interface for an #AtspiAccessible.
1963 * Returns: (transfer full): a pointer to an #AtspiValue interface instance, or
1964 * NULL if @obj does not implement #AtspiValue.
1966 * Deprecated: 2.10: Use atspi_accessible_get_value_iface instead.
1969 atspi_accessible_get_value (AtspiAccessible *accessible)
1971 return (_atspi_accessible_is_a (accessible, atspi_interface_value) ?
1972 g_object_ref (ATSPI_VALUE (accessible)) : NULL);
1976 * atspi_accessible_get_value_iface:
1977 * @obj: a pointer to the #AtspiAccessible instance to query.
1979 * Gets the #AtspiTable interface for an #AtspiAccessible.
1981 * Returns: (transfer full): a pointer to an #AtspiValue interface instance, or
1982 * NULL if @obj does not implement #AtspiValue.
1985 atspi_accessible_get_value_iface (AtspiAccessible *accessible)
1987 return (_atspi_accessible_is_a (accessible, atspi_interface_value) ?
1988 g_object_ref (ATSPI_VALUE (accessible)) : NULL);
1992 append_const_val (GArray *array, const gchar *val)
1994 gchar *dup = g_strdup (val);
1997 g_array_append_val (array, dup);
2001 * atspi_accessible_get_interfaces:
2002 * @obj: The #AtspiAccessible to query.
2004 * A set of pointers to all interfaces supported by an #AtspiAccessible.
2006 * Returns: (element-type gchar*) (transfer full): A #GArray of strings
2007 * describing the interfaces supported by the object. Interfaces are
2008 * denoted in short-hand (i.e. "Component", "Text" etc.).
2011 atspi_accessible_get_interfaces (AtspiAccessible *obj)
2013 GArray *ret = g_array_new (TRUE, TRUE, sizeof (gchar *));
2015 g_return_val_if_fail (obj != NULL, NULL);
2017 append_const_val (ret, "Accessible");
2018 if (atspi_accessible_is_action (obj))
2019 append_const_val (ret, "Action");
2020 if (atspi_accessible_is_collection (obj))
2021 append_const_val (ret, "Collection");
2022 if (atspi_accessible_is_component (obj))
2023 append_const_val (ret, "Component");
2024 if (atspi_accessible_is_document (obj))
2025 append_const_val (ret, "Document");
2026 if (atspi_accessible_is_editable_text (obj))
2027 append_const_val (ret, "EditableText");
2028 if (atspi_accessible_is_hypertext (obj))
2029 append_const_val (ret, "Hypertext");
2030 if (atspi_accessible_is_hyperlink (obj))
2031 append_const_val (ret, "Hyperlink");
2032 if (atspi_accessible_is_image (obj))
2033 append_const_val (ret, "Image");
2034 if (atspi_accessible_is_selection (obj))
2035 append_const_val (ret, "Selection");
2036 if (atspi_accessible_is_table (obj))
2037 append_const_val (ret, "Table");
2038 if (atspi_accessible_is_table_cell (obj))
2039 append_const_val (ret, "TableCell");
2040 if (atspi_accessible_is_text (obj))
2041 append_const_val (ret, "Text");
2042 if (atspi_accessible_is_value (obj))
2043 append_const_val (ret, "Value");
2049 _atspi_accessible_new (AtspiApplication *app, const gchar *path)
2051 AtspiAccessible *accessible;
2053 accessible = g_object_new (ATSPI_TYPE_ACCESSIBLE, NULL);
2054 g_return_val_if_fail (accessible != NULL, NULL);
2056 accessible->parent.app = g_object_ref (app);
2057 accessible->parent.path = g_strdup (path);
2063 * atspi_accessible_set_cache_mask:
2064 * @accessible: The #AtspiAccessible to operate on. Must be the desktop or
2065 * the root of an application.
2066 * @mask: An #AtspiCache specifying a bit mask of the types of data to cache.
2068 * Sets the type of data to cache for accessibles.
2069 * If this is not set for an application or is reset to ATSPI_CACHE_UNDEFINED,
2070 * then the desktop's cache flag will be used.
2071 * If the desktop's cache flag is also undefined, then all possible data will
2073 * This function is intended to work around bugs in toolkits where the proper
2074 * events are not raised / to aid in testing for such bugs.
2077 atspi_accessible_set_cache_mask (AtspiAccessible *accessible, AtspiCache mask)
2079 g_return_if_fail (accessible != NULL);
2080 g_return_if_fail (accessible->parent.app != NULL);
2081 g_return_if_fail (accessible == accessible->parent.app->root);
2082 accessible->parent.app->cache = mask;
2083 enable_caching = TRUE;
2087 * atspi_accessible_clear_cache:
2088 * @accessible: The #AtspiAccessible whose cache to clear.
2090 * Clears the cached information for the given accessible and all of its
2094 atspi_accessible_clear_cache (AtspiAccessible *accessible)
2100 accessible->cached_properties = ATSPI_CACHE_NONE;
2101 for (l = accessible->children; l; l = l->next)
2102 atspi_accessible_clear_cache (l->data);
2107 * atspi_accessible_get_process_id:
2108 * @accessible: The #AtspiAccessible to query.
2109 * @error: a pointer to a %NULL #GError pointer
2111 * Returns the process id associated with the given accessible. Mainly
2112 * added for debugging; it is a shortcut to explicitly querying the
2113 * accessible's app->bus_name and then calling GetConnectionUnixProcessID.
2115 * Returns: The process ID or undetermined value if @error is set.
2118 atspi_accessible_get_process_id (AtspiAccessible *accessible, GError **error)
2120 DBusMessage *message, *reply;
2121 DBusConnection *bus = _atspi_bus ();
2122 dbus_uint32_t pid = -1;
2125 if (!accessible->parent.app || !accessible->parent.app->bus_name)
2127 g_set_error_literal(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "Process is defunct");
2131 message = dbus_message_new_method_call ("org.freedesktop.DBus",
2132 "/org/freedesktop/DBus",
2133 "org.freedesktop.DBus",
2134 "GetConnectionUnixProcessID");
2135 dbus_message_append_args (message, DBUS_TYPE_STRING,
2136 &accessible->parent.app->bus_name,
2138 dbus_error_init (&d_error);
2139 reply = dbus_connection_send_with_reply_and_block (bus, message, -1, &d_error);
2140 dbus_message_unref (message);
2143 if (!strcmp (dbus_message_get_signature (reply), "u"))
2144 dbus_message_get_args (reply, NULL, DBUS_TYPE_UINT32, &pid, DBUS_TYPE_INVALID);
2145 dbus_message_unref (reply);
2147 if (dbus_error_is_set (&d_error))
2149 g_set_error_literal(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "Process is defunct");
2150 dbus_error_free (&d_error);
2156 _atspi_accessible_get_cache_mask (AtspiAccessible *accessible)
2160 if (!accessible->parent.app)
2161 return ATSPI_CACHE_NONE;
2163 mask = accessible->parent.app->cache;
2164 if (mask == ATSPI_CACHE_UNDEFINED &&
2165 accessible->parent.app->root &&
2166 accessible->parent.app->root->accessible_parent)
2168 AtspiAccessible *desktop = atspi_get_desktop (0);
2169 mask = desktop->parent.app->cache;
2170 g_object_unref (desktop);
2173 if (mask == ATSPI_CACHE_UNDEFINED)
2174 mask = ATSPI_CACHE_DEFAULT;
2180 _atspi_accessible_test_cache (AtspiAccessible *accessible, AtspiCache flag)
2182 AtspiCache mask = _atspi_accessible_get_cache_mask (accessible);
2183 AtspiCache result = accessible->cached_properties & mask & flag;
2184 if (accessible->states && atspi_state_set_contains (accessible->states, ATSPI_STATE_TRANSIENT))
2186 return (result != 0 && (atspi_main_loop || enable_caching ||
2187 flag == ATSPI_CACHE_INTERFACES) &&
2192 _atspi_accessible_add_cache (AtspiAccessible *accessible, AtspiCache flag)
2194 AtspiCache mask = _atspi_accessible_get_cache_mask (accessible);
2196 accessible->cached_properties |= flag & mask;
2200 * atspi_accessible_get_locale:
2201 * @accessible: an #AtspiAccessible
2203 * Gets a UTF-8 string indicating the POSIX-style LC_MESSAGES locale
2208 * Returns: a UTF-8 string indicating the POSIX-style LC_MESSAGES
2209 * locale of @accessible.
2212 atspi_accessible_get_object_locale (AtspiAccessible *accessible, GError **error)
2216 g_return_val_if_fail (accessible != NULL, NULL);
2218 locale = g_object_get_qdata (G_OBJECT (accessible), quark_locale);
2221 if (!_atspi_dbus_get_property (accessible, atspi_interface_accessible,
2222 "Locale", error, "s", &locale))
2225 g_object_set_qdata_full (G_OBJECT (accessible), quark_locale, locale,
2232 free_value (gpointer data)
2234 GValue *value = data;
2236 g_value_unset (value);
2241 _atspi_accessible_ref_cache (AtspiAccessible *accessible)
2243 AtspiAccessiblePrivate *priv = accessible->priv;
2245 priv->cache_ref_count++;
2247 return g_hash_table_ref (priv->cache);
2248 priv->cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
2254 _atspi_accessible_unref_cache (AtspiAccessible *accessible)
2256 AtspiAccessiblePrivate *priv = accessible->priv;
2260 g_hash_table_unref (priv->cache);
2261 if (--priv->cache_ref_count == 0)