X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=atspi%2Fatspi-accessible.c;h=b5d7616e962426b2090101d5b0f522d2a1f0b47e;hb=5016c77a44ff9bb5ce595a32429319d189839063;hp=9c21f446220911f182ce48979d1445283da0cbf6;hpb=5faed12b8466b621d08a24539c1fbc6e83963254;p=platform%2Fupstream%2Fat-spi2-core.git diff --git a/atspi/atspi-accessible.c b/atspi/atspi-accessible.c index 9c21f44..b5d7616 100644 --- a/atspi/atspi-accessible.c +++ b/atspi/atspi-accessible.c @@ -7,24 +7,82 @@ * Copyright 2010, 2011 Novell, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public + * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. */ #include "atspi-private.h" +#include "atspi-accessible-private.h" #include +enum { + REGION_CHANGED, + LAST_SIGNAL +}; + +static gboolean enable_caching = FALSE; +static guint quark_locale; + +static guint atspi_accessible_signals[LAST_SIGNAL] = { 0, }; + +static gboolean +screen_reader_signal_watcher (GSignalInvocationHint *signal_hint, + guint n_param_values, + const GValue *param_values, + gpointer data) +{ + GObject *object; + AtspiAccessible *accessible; + GSignalQuery signal_query; + const char *name; + DBusMessage *signal; + DBusMessageIter iter, iter_struct, iter_variant, iter_array; + dbus_int32_t detail1, detail2; + const char *detail = ""; + + object = g_value_get_object (param_values + 0); + g_return_val_if_fail (ATSPI_IS_ACCESSIBLE(object), FALSE); + + g_signal_query (signal_hint->signal_id, &signal_query); + name = signal_query.signal_name; + detail1 = g_value_get_int (param_values + 1); + detail2 = g_value_get_int (param_values + 2); + accessible = ATSPI_ACCESSIBLE (object); + + signal = dbus_message_new_signal (ATSPI_DBUS_PATH_SCREEN_READER, + ATSPI_DBUS_INTERFACE_EVENT_SCREEN_READER, + "RegionChanged"); + dbus_message_iter_init_append (signal, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &detail); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &detail1); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &detail2); + dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT, "(so)", + &iter_variant); + dbus_message_iter_open_container (&iter_variant, DBUS_TYPE_STRUCT, NULL, + &iter_struct); + dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &accessible->parent.app->bus_name); + dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &accessible->parent.path); + dbus_message_iter_close_container (&iter_variant, &iter_struct); + dbus_message_iter_close_container (&iter, &iter_variant); + dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{sv}", + &iter_array); + dbus_message_iter_close_container (&iter, &iter_array); + dbus_connection_send (_atspi_bus (), signal, NULL); + dbus_message_unref (signal); + return TRUE; +} + static void atspi_action_interface_init (AtspiAction *action) { @@ -71,6 +129,11 @@ atspi_table_interface_init (AtspiTable *table) } static void +atspi_table_cell_interface_init (AtspiTableCell *cell) +{ +} + +static void atspi_text_interface_init (AtspiText *text) { } @@ -81,6 +144,7 @@ atspi_value_interface_init (AtspiValue *value) } G_DEFINE_TYPE_WITH_CODE (AtspiAccessible, atspi_accessible, ATSPI_TYPE_OBJECT, + G_ADD_PRIVATE (AtspiAccessible) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_ACTION, atspi_action_interface_init) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_COLLECTION, atspi_collection_interface_init) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_COMPONENT, atspi_component_interface_init) @@ -90,6 +154,7 @@ G_DEFINE_TYPE_WITH_CODE (AtspiAccessible, atspi_accessible, ATSPI_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (ATSPI_TYPE_IMAGE, atspi_image_interface_init) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_SELECTION, atspi_selection_interface_init) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_TABLE, atspi_table_interface_init) + G_IMPLEMENT_INTERFACE (ATSPI_TYPE_TABLE_CELL, atspi_table_cell_interface_init) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_TEXT, atspi_text_interface_init) G_IMPLEMENT_INTERFACE (ATSPI_TYPE_VALUE, atspi_value_interface_init)) @@ -98,12 +163,24 @@ static gint accessible_count = 0; #endif static void +atspi_accessible_unref (GObject *accessible) +{ + if (accessible != NULL) + g_object_unref(accessible); +} + +static void atspi_accessible_init (AtspiAccessible *accessible) { #ifdef DEBUG_REF_COUNTS accessible_count++; - printf("at-spi: init: %d objects\n", accessible_count); + g_hash_table_insert (_atspi_get_live_refs (), accessible, NULL); + g_print("at-spi: init: %d objects\n", accessible_count); #endif + + accessible->priv = atspi_accessible_get_instance_private (accessible); + + accessible->children = g_ptr_array_new_with_free_func (atspi_accessible_unref); } static void @@ -112,39 +189,41 @@ atspi_accessible_dispose (GObject *object) AtspiAccessible *accessible = ATSPI_ACCESSIBLE (object); AtspiEvent e; AtspiAccessible *parent; + gint i; /* TODO: Only fire if object not already marked defunct */ memset (&e, 0, sizeof (e)); - e.type = "object:state-change:defunct"; + e.type = "object:state-changed:defunct"; e.source = accessible; e.detail1 = 1; e.detail2 = 0; _atspi_send_event (&e); - if (accessible->states) + g_clear_object (&accessible->states); + + parent = accessible->accessible_parent; + if (parent) { - g_object_unref (accessible->states); - accessible->states = NULL; + accessible->accessible_parent = NULL; + if (parent->children) + g_ptr_array_remove (parent->children, accessible); + g_object_unref (parent); } - parent = accessible->accessible_parent; - if (parent && parent->children) + if (accessible->children) for (i = accessible->children->len - 1; i >= 0; i--) { - GList*ls = g_list_find (parent->children, accessible); - if(ls) + AtspiAccessible *child = g_ptr_array_index (accessible->children, i); + if (child && child->accessible_parent == accessible) { - gboolean replace = (ls == parent->children); - ls = g_list_remove (ls, accessible); - if (replace) - parent->children = ls; - g_object_unref (object); + child->accessible_parent = NULL; + g_object_unref (accessible); } } - if (parent) + if (accessible->children) { - g_object_unref (parent); - accessible->accessible_parent = NULL; + g_ptr_array_free (accessible->children, TRUE); + accessible->children = NULL; } G_OBJECT_CLASS (atspi_accessible_parent_class) ->dispose (object); @@ -155,18 +234,24 @@ atspi_accessible_finalize (GObject *object) { AtspiAccessible *accessible = ATSPI_ACCESSIBLE (object); - g_free (accessible->description); - g_free (accessible->name); + g_free (accessible->description); + g_free (accessible->name); + if (accessible->attributes) g_hash_table_unref (accessible->attributes); + if (accessible->priv->cache) + g_hash_table_destroy (accessible->priv->cache); + #ifdef DEBUG_REF_COUNTS accessible_count--; + g_hash_table_remove (_atspi_get_live_refs (), accessible); g_print ("at-spi: finalize: %d objects\n", accessible_count); #endif - G_OBJECT_CLASS (atspi_accessible_parent_class) - ->finalize (object); + G_OBJECT_CLASS (atspi_accessible_parent_class)->finalize (object); + + /* TODO: remove emission hook */ } static void @@ -176,158 +261,584 @@ atspi_accessible_class_init (AtspiAccessibleClass *klass) object_class->dispose = atspi_accessible_dispose; object_class->finalize = atspi_accessible_finalize; + + quark_locale = g_quark_from_string ("accessible-locale"); + + /** + * AtspiAccessible::region-changed: + * @atspiaccessible: the object which received the signal + * @arg1: an integer specifying the current offset of the text being read, + * if the object is textual. + * @arg2: an integer specifying the ending offset of the text being read, + * if the object is textual. + * + * The signal "region-changed" is emitted by a screen reader to indicate + * that it is now reading or tracking a new object, or, a new piece of + * text within an object. This allows a magnifier to gain the information + * needed to highlight the object that the screen reader is reading. + */ + atspi_accessible_signals[REGION_CHANGED] = + g_signal_new ("region_changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (AtspiAccessibleClass, region_changed), + NULL, NULL, + atspi_marshal_VOID__INT_INT, + G_TYPE_NONE, + 2, G_TYPE_INT, G_TYPE_INT); + + g_signal_add_emission_hook (atspi_accessible_signals[REGION_CHANGED], 0, + screen_reader_signal_watcher, NULL, + (GDestroyNotify) NULL); } -/* TODO: Generate following from spec? */ -static const char *role_names [] = -{ - "invalid", - "accel-label", - "alert", - "animation", - "arrow", - "calendar", - "canvas", - "check-box", - "check-menu-item", - "color-chooser", - "column-header", - "combo-box", - "date-editor", - "desktop-icon", - "desktop-frame", - "dial", - "dialog", - "directory-pane", - "drawing-area", - "file-chooser", - "filler", - "focus traversable", - "font-chooser", - "frame", - "glass-pane", - "html-container", - "icon", - "image", - "internalframe", - "label", - "layered-pane", - "list", - "list-item", - "menu", - "menu-bar", - "menu-item", - "option-pane", - "page-tab", - "page-tab-list", - "panel", - "password-text", - "popup-menu", - "progress-bar", - "push-button", - "radio-button", - "radio-menu-item", - "root-pane", - "row-header", - "scroll-bar", - "scroll-pane", - "separator", - "slider", - "spin-button", - "split-pane", - "statusbar", - "table", - "table-cell", - "table-column-header", - "table-row-header", - "tear-off-menu-item", - "terminal", - "text", - "toggle-button", - "tool-bar", - "tool-tip", - "tree", - "tree-table", - "unknown", - "viewport", - "window", - NULL, - "header", - "footer", - "paragraph", - "ruler", - "application", - "autocomplete", - "editbar", - "embedded", - "entry", - "chart", - "caption", - "document_frame", - "heading", - "page", - "section", - "redundant object", - "form", - "link", - "input method window" -}; +/** + * atspi_accessible_get_name: + * @obj: a pointer to the #AtspiAccessible object on which to operate. + * + * Gets the name of an #AtspiAccessible object. + * + * Returns: a UTF-8 string indicating the name of the #AtspiAccessible object + * or NULL on exception. + **/ +gchar * +atspi_accessible_get_name (AtspiAccessible *obj, GError **error) +{ + g_return_val_if_fail (obj != NULL, g_strdup ("")); + if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_NAME)) + { + if (!_atspi_dbus_get_property (obj, atspi_interface_accessible, "Name", error, + "s", &obj->name)) + return g_strdup (""); + _atspi_accessible_add_cache (obj, ATSPI_CACHE_NAME); + } + return g_strdup (obj->name); +} -#define MAX_ROLES (sizeof (role_names) / sizeof (char *)) /** - * atspi_role_get_name - * @role: an #AtspiAccessibleRole object to query. + * atspi_accessible_get_unique_id: + * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Get a localizeable string that indicates the name of an #AtspiAccessibleRole. - * DEPRECATED. + * Gets the identificator, uniquely identifying object, or NULL if an error occured. * - * Returns: a localizable string name for an #AtspiAccessibleRole enumerated type. + * Returns: a UTF-8 string describing the #AtspiAccessible object + * or NULL on exception or NULL object passed. **/ gchar * -atspi_role_get_name (AtspiRole role) +atspi_accessible_get_unique_id(AtspiAccessible *obj, GError **error) { - if (role < MAX_ROLES && role_names [(int) role]) - { - return g_strdup (role_names [(int) role]); - } + if (!obj) { + g_set_error(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "argument is null"); + return NULL; + } + + gchar *id = NULL; + gchar *bus_name = atspi_accessible_get_bus_name(obj, error); + if (bus_name && bus_name[0]) { + gchar *path = atspi_accessible_get_path(obj, error); + if (path && path[0]) + id = g_strdup_printf("%s:%s", bus_name, path); + else + g_set_error(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "failed to get path"); + g_free(path); + } else - { - return g_strdup (""); - } + g_set_error(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "failed to get bus name"); + g_free(bus_name); + return id; } /** - * atspi_accessible_get_name: + * atspi_accessible_get_bus_name: * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Get the name of an #AtspiAccessible object. + * Gets the bus name, where object belongs. * - * Returns: a UTF-8 string indicating the name of the #AtspiAccessible object. - * or NULL on exception + * Returns: a UTF-8 string describing the #AtspiAccessible object's + * bus name or empty string on exception or NULL object passed. **/ gchar * -atspi_accessible_get_name (AtspiAccessible *obj, GError **error) +atspi_accessible_get_bus_name(AtspiAccessible *obj, GError **error) { - g_return_val_if_fail (obj != NULL, g_strdup ("")); - if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_NAME)) + if (!obj || !obj->parent.app) + return g_strdup(""); + return g_strdup (obj->parent.app->bus_name); +} + +/** + * atspi_accessible_get_path: + * @obj: a pointer to the #AtspiAccessible object on which to operate. + * + * Gets the path, uniquely identifying object over its bus name. + * + * Returns: a UTF-8 string describing the #AtspiAccessible object + * or empty string on exception or NULL object passed. + **/ +gchar * +atspi_accessible_get_path(AtspiAccessible *obj, GError **error) +{ + static const char *prefix = "/org/a11y/atspi/accessible/"; + static int prefix_len = 27; + + if (!obj) + return g_strdup(""); + AtspiObject *o = ATSPI_OBJECT (obj); + if (!o) + return g_strdup(""); + if (strncmp(o->path, prefix, prefix_len) == 0) + return g_strdup(o->path + prefix_len); + return g_strdup (o->path); +} + +/** + * atspi_accessible_get_navigable_at_point: + * @root: a pointer to the #AtspiAccessible to start search from. + * @x: a #gint specifying the x coordinate of the point in question. + * @y: a #gint specifying the y coordinate of the point in question. + * @ctype: the coordinate system of the point (@x, @y) + * (e.g. ATSPI_COORD_TYPE_WINDOW, ATSPI_COORD_TYPE_SCREEN). + * + * Finds the accessible element closest to user (highest in z-order), at a given coordinate within an #AtspiAccessible. + * This should be the element, that should be picked, when doing mouse click or finger tap at given coordinates. + * + * Returns: (nullable) (transfer full): a pointer to an + * #AtspiAccessible descendant (of any depth) of the specified component which + * contains the point (@x, @y), or NULL if no descendant contains + * the point. + **/ +AtspiAccessible * +atspi_accessible_get_navigable_at_point (AtspiAccessible *root, + gint x, + gint y, + AtspiCoordType ctype, GError **error) +{ + dbus_int32_t d_x = x, d_y = y; + dbus_uint32_t d_ctype = ctype; + DBusMessage *reply; + AtspiAccessible *return_value = NULL; + unsigned char recurse = 0; + DBusMessageIter iter; + AtspiAccessible *deputy = NULL; + + g_return_val_if_fail (root != NULL, NULL); + do { + reply = _atspi_dbus_call_partial (root, atspi_interface_accessible, "GetNavigableAtPoint", error, "iiu", d_x, d_y, d_ctype); + // call failed, error is set, so we bail out + if (!reply) { + if (deputy) g_object_unref(deputy); + if (return_value) g_object_unref(return_value); + return NULL; + } + _ATSPI_DBUS_CHECK_SIG (reply, "(so)y(so)", NULL, NULL); + + dbus_message_iter_init (reply, &iter); + AtspiAccessible *tmp = _atspi_dbus_return_accessible_from_iter (&iter); + + unsigned char value = 0; + dbus_message_iter_get_basic (&iter, &value); + dbus_message_iter_next (&iter); + recurse = (value != 0); + + /* keep deputy if tmp has deputy */ + if (!deputy) + deputy = _atspi_dbus_return_accessible_from_iter (&iter); + + dbus_message_unref(reply); + + if (!tmp) { + if (deputy) { + /* TODO: need to check deputy works for return value */ + if (return_value) + g_object_unref(return_value); + return deputy; + } + break; + } + + if (return_value) + g_object_unref(return_value); + return_value = root = tmp; + } while(recurse); + return return_value; +} + +/** + * atspi_accessible_get_reading_material: + * @obj: a pointer to the #AtspiAccessible object on which to operate. + * + * Gets reading material + * + * Returns: reading material to be used screen-reader side. This is not stable. + * You have to handle all alocated memory as below on screen-reader side. + * + * AtspiAccessibleReadingMaterial *rm + * g_object_unref(rm->parent); + * g_object_unref(rm->described_by_accessible); + * g_hash_table_unref(rm->attributes); + * free(rm->name); + * free(rm->labeled_by_name); + * free(rm->text_interface_name); + * free(rm->localized_role_name); + * free(rm->description); + * free(rm); + **/ +AtspiAccessibleReadingMaterial * +atspi_accessible_get_reading_material (AtspiAccessible *obj, GError **error) +{ + AtspiAccessible *parent; + AtspiAccessibleReadingMaterial *reading_material = NULL; + const char *name; + double current_value; + gint count; + guint64 val; + DBusMessage *reply; + DBusMessageIter iter; + DBusMessageIter iter_array; + dbus_uint32_t role; + dbus_uint32_t *states; + dbus_int32_t index_in_parent; + dbus_int32_t child_count; + dbus_bool_t is_selected; + + g_return_val_if_fail (obj != NULL, NULL); + + reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetReadingMaterial", error, ""); + + _ATSPI_DBUS_CHECK_SIG (reply, "a{ss}sssuausiddddsibbii(so)auiui(so)", NULL, NULL); + + reading_material = calloc(1, sizeof(AtspiAccessibleReadingMaterial)); + if (!reading_material) { - if (!_atspi_dbus_get_property (obj, atspi_interface_accessible, "Name", error, - "s", &obj->name)) - return g_strdup (""); - _atspi_accessible_add_cache (obj, ATSPI_CACHE_NAME); + return reading_material; } - return g_strdup (obj->name); + + dbus_message_iter_init (reply, &iter); + + /* get attributes */ + reading_material->attributes = _atspi_dbus_hash_from_iter (&iter); + dbus_message_iter_next (&iter); + + /* get name */ + dbus_message_iter_get_basic (&iter, &name); + reading_material->name = g_strdup (name); + dbus_message_iter_next (&iter); + + /* get name of relation LABELED_BY */ + dbus_message_iter_get_basic (&iter, &name); + reading_material->labeled_by_name = g_strdup (name); + dbus_message_iter_next (&iter); + + /* get name of text interface */ + dbus_message_iter_get_basic (&iter, &name); + reading_material->text_interface_name = g_strdup (name); + dbus_message_iter_next (&iter); + + /* get role */ + dbus_message_iter_get_basic (&iter, &role); + reading_material->role = role; + dbus_message_iter_next (&iter); + + /* get state set */ + dbus_message_iter_recurse (&iter, &iter_array); + dbus_message_iter_get_fixed_array (&iter_array, &states, &count); + val = ((guint64)states [1]) << 32; + val += states [0]; + reading_material->states = val; + dbus_message_iter_next (&iter); + + /* get localized role name */ + dbus_message_iter_get_basic (&iter, &name); + reading_material->localized_role_name = g_strdup (name); + dbus_message_iter_next (&iter); + + /* get child count */ + dbus_message_iter_get_basic (&iter, &child_count); + reading_material->child_count = child_count; + dbus_message_iter_next (&iter); + + /* get current value */ + dbus_message_iter_get_basic (&iter, ¤t_value); + reading_material->value = current_value; + dbus_message_iter_next (&iter); + + /* get minimum increment */ + dbus_message_iter_get_basic (&iter, ¤t_value); + reading_material->increment = current_value; + dbus_message_iter_next (&iter); + + /* get maximum value */ + dbus_message_iter_get_basic (&iter, ¤t_value); + reading_material->upper = current_value; + dbus_message_iter_next (&iter); + + /* get minimum value */ + dbus_message_iter_get_basic (&iter, ¤t_value); + reading_material->lower = current_value; + dbus_message_iter_next (&iter); + + /* get description */ + dbus_message_iter_get_basic (&iter, &name); + reading_material->description = g_strdup (name); + dbus_message_iter_next (&iter); + + /* get index in parent */ + dbus_message_iter_get_basic (&iter, &index_in_parent); + reading_material->index_in_parent = index_in_parent; + dbus_message_iter_next (&iter); + + /* get selected in parent */ + dbus_message_iter_get_basic (&iter, &is_selected); + reading_material->is_selected_in_parent = is_selected; + dbus_message_iter_next (&iter); + + /* get has checkbox child */ + dbus_message_iter_get_basic (&iter, &is_selected); + reading_material->has_checkbox_child = is_selected; + dbus_message_iter_next (&iter); + + /* get list children count */ + dbus_message_iter_get_basic (&iter, &child_count); + reading_material->list_children_count = child_count; + dbus_message_iter_next (&iter); + + /* get first selected child index */ + dbus_message_iter_get_basic (&iter, &index_in_parent); + reading_material->first_selected_child_index = index_in_parent; + dbus_message_iter_next (&iter); + + //////////////// + /* get parent */ + parent = _atspi_dbus_return_accessible_from_iter (&iter); + reading_material->parent = parent; + + /* parent states */ + dbus_message_iter_recurse (&iter, &iter_array); + dbus_message_iter_get_fixed_array (&iter_array, &states, &count); + val = ((guint64)states [1]) << 32; + val += states [0]; + reading_material->parent_states = val; + dbus_message_iter_next (&iter); + + /* get parent child count */ + dbus_message_iter_get_basic (&iter, &child_count); + reading_material->parent_child_count = child_count; + dbus_message_iter_next (&iter); + + /* get parent role */ + dbus_message_iter_get_basic (&iter, &role); + reading_material->parent_role = role; + dbus_message_iter_next (&iter); + + /* get parent selected child count */ + dbus_message_iter_get_basic (&iter, &child_count); + reading_material->parent_selected_child_count = child_count; + dbus_message_iter_next (&iter); + + //////////////////////////////////////// + /* get relation object - DESCRIBED_BY */ + parent = _atspi_dbus_return_accessible_from_iter (&iter); + reading_material->described_by_accessible = parent; + + return reading_material; +} + +/** + * atspi_accessible_get_default_label_info: + * @obj: a pointer to the #AtspiAccessible object would be window. + * + * Gets default label information + * + * Returns: default label information to be used screen-reader side. + * This is not stable. And this depends on toolkit side UI definition. + * The candidate of default label object could be changed by UI definition. + * You have to handle all alocated memory as below on screen-reader side. + * + * AtspiAccessibleDefaultLabelInfo *dli + * g_hash_table_unref(dli->attributes); + + * g_object_unref(dli->obj); + * free(dli); + **/ +AtspiAccessibleDefaultLabelInfo * +atspi_accessible_get_default_label_info (AtspiAccessible *obj, GError **error) +{ + AtspiAccessibleDefaultLabelInfo *default_label_info = NULL; + AtspiAccessible *default_label_object; + dbus_uint32_t role; + DBusMessage *reply; + DBusMessageIter iter; + + g_return_val_if_fail (obj != NULL, NULL); + + reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetDefaultLabelInfo", error, ""); + + _ATSPI_DBUS_CHECK_SIG (reply, "(so)ua{ss}", NULL, NULL); + + default_label_info = calloc(1, sizeof(AtspiAccessibleDefaultLabelInfo)); + if (!default_label_info) + { + return default_label_info; + } + + dbus_message_iter_init (reply, &iter); + + default_label_object = _atspi_dbus_return_accessible_from_iter (&iter); + default_label_info->obj = default_label_object; + + dbus_message_iter_get_basic (&iter, &role); + default_label_info->role = role; + dbus_message_iter_next (&iter); + + default_label_info->attributes = _atspi_dbus_hash_from_iter (&iter); + dbus_message_iter_next (&iter); + + return default_label_info; +} + +static unsigned char are_objects_on_the_same_bus(AtspiAccessible *obj1, AtspiAccessible *obj2) +{ + const char *bus_name_1 = obj1->parent.app->bus_name; + const char *bus_name_2 = obj2->parent.app->bus_name; + return strcmp(bus_name_1, bus_name_2) == 0; +} + +static unsigned char object_is_valid(AtspiAccessible *obj) +{ + if (!obj) + return 0; + AtspiStateSet *ss = atspi_accessible_get_state_set(obj); + if (!ss) + return 0; + unsigned char valid = atspi_state_set_contains(ss, ATSPI_STATE_DEFUNCT) == 0; + g_object_unref(ss); + return valid; +} + +typedef enum { + NEIGHBOR_SEARCH_MODE_NORMAL = 0, + NEIGHBOR_SEARCH_MODE_RECURSE_FROM_ROOT = 1, + NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING = 2, + NEIGHBOR_SEARCH_MODE_RECURSE_TO_OUTSIDE = 3, +} GetNeighborSearchMode; +/** + * atspi_accessible_get_neighbor: + * @root: a pointer to a #AtspiAccessible, which represents current root of subtree to search + * @start: a pointer to the #AtspiAccessible to start search from (can be null, which means start from root) + * @direction: direction, in which search (forward or backward) + * + * Calculates next (or previous) accessible element in logical order or null if none found. + * + * Returns: (nullable) (transfer full): a pointer to an + * #AtspiAccessible element, which is next (previous) in logical order or null if none found. + **/ +AtspiAccessible * +atspi_accessible_get_neighbor (AtspiAccessible *root, + AtspiAccessible *start, + AtspiNeighborSearchDirection direction, + GError **error) +{ + g_return_val_if_fail (object_is_valid(root), NULL); + if (!object_is_valid(start)) + start = root; + const char *root_path = ATSPI_OBJECT(root)->path; + AtspiAccessible *return_value = NULL; + g_object_ref(start); + unsigned char recurse; + GetNeighborSearchMode search_mode = NEIGHBOR_SEARCH_MODE_NORMAL; + GQueue *children_root_stack = g_queue_new(); + DBusMessageIter iter; + + while(1) { + const char *path = are_objects_on_the_same_bus(root, start) ? root_path : ""; + DBusMessage *reply = _atspi_dbus_call_partial (start, atspi_interface_accessible, "GetNeighbor", error, "sii", path, (int)direction, (int)search_mode); + // call failed, error is set, so we bail out + if (!reply) break; + + _ATSPI_DBUS_CHECK_SIG (reply, "(so)y", error, NULL); + dbus_message_iter_init (reply, &iter); + AtspiAccessible *ret = _atspi_dbus_return_accessible_from_iter (&iter); + + unsigned char value = 0; + dbus_message_iter_get_basic (&iter, &value); + dbus_message_iter_next (&iter); + recurse = (value != 0); + + dbus_message_unref(reply); + + // got return value and request for recursive search, it means ret is on another bridge, than start + // thus we're recursing. should the recurse failed to find anything it will end with + if (ret && recurse) { + g_object_unref(G_OBJECT(start)); + start = ret; + g_object_ref(start); + if (are_objects_on_the_same_bus(root, ret)) + { + search_mode = NEIGHBOR_SEARCH_MODE_RECURSE_TO_OUTSIDE; + } + else + { + g_queue_push_tail(children_root_stack, ret); + search_mode = NEIGHBOR_SEARCH_MODE_RECURSE_FROM_ROOT; + } + continue; + } + // found the one we've been looking for + if (ret) { + g_object_unref(G_OBJECT(start)); + return_value = ret; + break; + } + + // we've stepped into different bridges previously and now we're going back to the last one + // and continuing search where we left + if (!g_queue_is_empty(children_root_stack)) { + g_object_unref(G_OBJECT(start)); + start = g_queue_pop_tail(children_root_stack); + + search_mode = NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING; + continue; + } + // there's no more bridges to check, but we might have started from one + // in that case there might be bridges "below" start, which we yet have to visit + if (!are_objects_on_the_same_bus(root, start)) { + unsigned char continue_loop = 1; + while(continue_loop) { + AtspiAccessible *parent = atspi_accessible_get_parent(start, NULL); + continue_loop = parent ? are_objects_on_the_same_bus(start, parent) : 0; + g_object_unref(G_OBJECT(start)); + start = parent; + } + + // going up thru parents put us in weird place (we didnt meet root on the way) + // so we bail out + if (!start) + break; + + // start object now points to different bridge and must be treated as "resume after recursing" + search_mode = NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING; + continue; + } + + // nothing found + g_object_unref(start); + break; + } + while(!g_queue_is_empty(children_root_stack)) + g_object_unref(g_queue_pop_tail(children_root_stack)); + g_queue_free(children_root_stack); + + return return_value; } /** * atspi_accessible_get_description: * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Get the description of an #AtspiAccessible object. + * Gets the description of an #AtspiAccessible object. * - * Returns: a UTF-8 string describing the #AtspiAccessible object. - * or NULL on exception + * Returns: a UTF-8 string describing the #AtspiAccessible object + * or NULL on exception. **/ gchar * atspi_accessible_get_description (AtspiAccessible *obj, GError **error) @@ -351,11 +862,12 @@ const char *str_parent = "Parent"; * atspi_accessible_get_parent: * @obj: a pointer to the #AtspiAccessible object to query. * - * Get an #AtspiAccessible object's parent container. + * Gets an #AtspiAccessible object's parent container. * - * Returns: (transfer full): a pointer to the #AtspiAccessible object which - * contains the given #AtspiAccessible instance, or NULL if the @obj - * has no parent container. + * Returns: (nullable) (transfer full): a pointer to the + * #AtspiAccessible object which contains the given + * #AtspiAccessible instance, or NULL if the @obj has no + * parent container. * **/ AtspiAccessible * @@ -363,11 +875,12 @@ atspi_accessible_get_parent (AtspiAccessible *obj, GError **error) { g_return_val_if_fail (obj != NULL, NULL); - if (obj->parent.app && - !_atspi_accessible_test_cache (obj, ATSPI_CACHE_PARENT)) + if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_PARENT)) { DBusMessage *message, *reply; DBusMessageIter iter, iter_variant; + if (!obj->parent.app) + return NULL; message = dbus_message_new_method_call (obj->parent.app->bus_name, obj->parent.path, DBUS_INTERFACE_PROPERTIES, "Get"); @@ -399,10 +912,10 @@ atspi_accessible_get_parent (AtspiAccessible *obj, GError **error) * atspi_accessible_get_child_count: * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Get the number of children contained by an #AtspiAccessible object. + * Gets the number of children contained by an #AtspiAccessible object. * * Returns: a #long indicating the number of #AtspiAccessible children - * contained by an #AtspiAccessible object. or -1 on exception + * contained by an #AtspiAccessible object or -1 on exception. * **/ gint @@ -419,7 +932,10 @@ atspi_accessible_get_child_count (AtspiAccessible *obj, GError **error) return ret; } - return g_list_length (obj->children); + if (!obj->children) + return 0; /* assume it's disposed */ + + return obj->children->len; } /** @@ -427,10 +943,10 @@ atspi_accessible_get_child_count (AtspiAccessible *obj, GError **error) * @obj: a pointer to the #AtspiAccessible object on which to operate. * @child_index: a #long indicating which child is specified. * - * Get the #AtspiAccessible child of an #AtspiAccessible object at a given index. + * Gets the #AtspiAccessible child of an #AtspiAccessible object at a given index. * * Returns: (transfer full): a pointer to the #AtspiAccessible child object at - * index @child_index. or NULL on exception + * index @child_index or NULL on exception. **/ AtspiAccessible * atspi_accessible_get_child_at_index (AtspiAccessible *obj, @@ -438,59 +954,71 @@ atspi_accessible_get_child_at_index (AtspiAccessible *obj, GError **error) { AtspiAccessible *child; + DBusMessage *reply; g_return_val_if_fail (obj != NULL, NULL); - if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_CHILDREN)) + if (_atspi_accessible_test_cache (obj, ATSPI_CACHE_CHILDREN)) { - DBusMessage *reply; - reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible, - "GetChildAtIndex", error, "i", - child_index); - return _atspi_dbus_return_accessible_from_message (reply); + if (!obj->children) + return NULL; /* assume disposed */ + + child = g_ptr_array_index (obj->children, child_index); + if (child) + return g_object_ref (child); } - child = g_list_nth_data (obj->children, child_index); + reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible, + "GetChildAtIndex", error, "i", child_index); + child = _atspi_dbus_return_accessible_from_message (reply); + if (!child) return NULL; - return g_object_ref (child); + + if (_atspi_accessible_test_cache (obj, ATSPI_CACHE_CHILDREN)) + { + if (child_index >= obj->children->len) + g_ptr_array_set_size (obj->children, child_index + 1); + g_ptr_array_index (obj->children, child_index) = g_object_ref (child); + } + return child; } /** - * atspi_accessible_get_index_in_parent + * atspi_accessible_get_index_in_parent: * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Get the index of an #AtspiAccessible object in its containing #AtspiAccessible. + * Gets the index of an #AtspiAccessible object within its parent's + * #AtspiAccessible children list. * * Returns: a #glong indicating the index of the #AtspiAccessible object - * in its parent (i.e. containing) #AtspiAccessible instance, + * in its parent, * or -1 if @obj has no containing parent or on exception. **/ gint atspi_accessible_get_index_in_parent (AtspiAccessible *obj, GError **error) { - GList *l; gint i = 0; + dbus_int32_t ret = -1; g_return_val_if_fail (obj != NULL, -1); - if (!obj->accessible_parent) return -1; - if (!_atspi_accessible_test_cache (obj->accessible_parent, - ATSPI_CACHE_CHILDREN)) + if (_atspi_accessible_test_cache (obj, ATSPI_CACHE_PARENT)) { - dbus_uint32_t ret = -1; - _atspi_dbus_call (obj, atspi_interface_accessible, - "GetIndexInParent", NULL, "=>u", &ret); - return ret; - } + if (!obj->accessible_parent) + return -1; - l = obj->accessible_parent->children; - while (l) - { - if (l->data == obj) return i; - l = g_list_next (l); - i++; + if (!_atspi_accessible_test_cache (obj->accessible_parent, ATSPI_CACHE_CHILDREN) || !obj->accessible_parent->children) + goto dbus; + + for (i = 0; i < obj->accessible_parent->children->len; i++) + if (g_ptr_array_index (obj->accessible_parent->children, i) == obj) + return i; } - return -1; + +dbus: + _atspi_dbus_call (obj, atspi_interface_accessible, + "GetIndexInParent", NULL, "=>i", &ret); + return ret; } typedef struct @@ -503,11 +1031,11 @@ typedef struct * atspi_accessible_get_relation_set: * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Get the set of #AtspiRelation objects which describe this #AtspiAccessible object's - * relationships with other #AtspiAccessible objects. + * Gets the set of #AtspiRelation objects which describes this #AtspiAccessible object's + * relationships with other #AtspiAccessible objects. * - * Returns: (element-type AtspiAccessible*) (transfer full): an array of - * #AtspiAccessibleRelation pointers. or NULL on exception + * Returns: (element-type AtspiRelation*) (transfer full): a #GArray of + * #AtspiRelation pointers or NULL on exception. **/ GArray * atspi_accessible_get_relation_set (AtspiAccessible *obj, GError **error) @@ -541,10 +1069,10 @@ atspi_accessible_get_relation_set (AtspiAccessible *obj, GError **error) * atspi_accessible_get_role: * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Get the UI role of an #AtspiAccessible object. - * A UTF-8 string describing this role can be obtained via atspi_accessible_getRoleName (). + * Gets the UI role played by an #AtspiAccessible object. + * This role's name can be obtained via atspi_accessible_get_role_name (). * - * Returns: the #AtspiRole of the object. + * Returns: the #AtspiRole of an #AtspiAccessible object. * **/ AtspiRole @@ -569,24 +1097,25 @@ atspi_accessible_get_role (AtspiAccessible *obj, GError **error) * atspi_accessible_get_role_name: * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Get a UTF-8 string describing the role this object plays in the UI. + * Gets a UTF-8 string corresponding to the name of the role played by an object. * This method will return useful values for roles that fall outside the - * enumeration used in atspi_accessible_getRole (). + * enumeration used in atspi_accessible_get_role (). * - * Returns: a UTF-8 string specifying the role of this #AtspiAccessible object. + * Returns: a UTF-8 string specifying the type of UI role played by an + * #AtspiAccessible object. * **/ gchar * atspi_accessible_get_role_name (AtspiAccessible *obj, GError **error) { - char *retval = NULL; + gchar *retval = NULL; AtspiRole role; g_return_val_if_fail (obj != NULL, NULL); role = atspi_accessible_get_role (obj, error); - if (role >= 0 && role < MAX_ROLES && role != ATSPI_ROLE_EXTENDED) - return g_strdup (role_names [role]); + if (role >= 0 && role < ATSPI_ROLE_COUNT && role != ATSPI_ROLE_EXTENDED) + return atspi_role_get_name (role); _atspi_dbus_call (obj, atspi_interface_accessible, "GetRoleName", error, "=>s", &retval); @@ -600,11 +1129,13 @@ atspi_accessible_get_role_name (AtspiAccessible *obj, GError **error) * atspi_accessible_get_localized_role_name: * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Get a UTF-8 string describing the (localized) role this object plays in the UI. + * Gets a UTF-8 string corresponding to the name of the role played by an + * object, translated to the current locale. * This method will return useful values for roles that fall outside the * enumeration used in atspi_accessible_getRole (). * - * Returns: a UTF-8 string specifying the role of this #AtspiAccessible object. + * Returns: a localized, UTF-8 string specifying the type of UI role played + * by an #AtspiAccessible object. * **/ gchar * @@ -634,18 +1165,18 @@ defunct_set () * atspi_accessible_get_state_set: * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Gets the current state of an object. + * Gets the states currently held by an object. * - * Returns: (transfer full): a pointer to an #AtspiStateSet representing the - * object's current state. + * Returns: (transfer full): a pointer to an #AtspiStateSet representing an + * object's current state set. **/ AtspiStateSet * atspi_accessible_get_state_set (AtspiAccessible *obj) { + /* TODO: Should take a GError **, but would be an API break */ if (!obj->parent.app || !obj->parent.app->bus) return defunct_set (); - if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_STATES)) { DBusMessage *reply; @@ -658,7 +1189,6 @@ atspi_accessible_get_state_set (AtspiAccessible *obj) dbus_message_unref (reply); _atspi_accessible_add_cache (obj, ATSPI_CACHE_STATES); } - return g_object_ref (obj->states); } @@ -666,13 +1196,13 @@ atspi_accessible_get_state_set (AtspiAccessible *obj) * atspi_accessible_get_attributes: * @obj: The #AtspiAccessible being queried. * - * Get the #AttributeSet representing any assigned + * Gets the #AttributeSet representing any assigned * name-value pair attributes or annotations for this object. * For typographic, textual, or textually-semantic attributes, see * atspi_text_get_attributes instead. * * Returns: (element-type gchar* gchar*) (transfer full): The name-value-pair - * attributes assigned to this object. + * attributes assigned to this object. */ GHashTable * atspi_accessible_get_attributes (AtspiAccessible *obj, GError **error) @@ -681,6 +1211,13 @@ atspi_accessible_get_attributes (AtspiAccessible *obj, GError **error) g_return_val_if_fail (obj != NULL, NULL); + if (obj->priv->cache) + { + GValue *val = g_hash_table_lookup (obj->priv->cache, "Attributes"); + if (val) + return g_value_dup_boxed (val); + } + if (!_atspi_accessible_test_cache (obj, ATSPI_CACHE_ATTRIBUTES)) { message = _atspi_dbus_call_partial (obj, atspi_interface_accessible, @@ -706,7 +1243,7 @@ add_to_attribute_array (gpointer key, gpointer value, gpointer data) * atspi_accessible_get_attributes_as_array: * @obj: The #AtspiAccessible being queried. * - * Get the #AttributeSet representing any assigned + * Gets a #GArray representing any assigned * name-value pair attributes or annotations for this object. * For typographic, textual, or textually-semantic attributes, see * atspi_text_get_attributes_as_array instead. @@ -721,15 +1258,16 @@ atspi_accessible_get_attributes_as_array (AtspiAccessible *obj, GError **error) g_return_val_if_fail (obj != NULL, NULL); - if (_atspi_accessible_get_cache_mask (obj) & ATSPI_CACHE_ATTRIBUTES) + if (obj->priv->cache) { - GArray *array = g_array_new (TRUE, TRUE, sizeof (gchar *)); - GHashTable *attributes = atspi_accessible_get_attributes (obj, error); - if (!attributes) - return NULL; - g_hash_table_foreach (attributes, add_to_attribute_array, &array); - g_hash_table_unref (attributes); - return array; + GValue *val = g_hash_table_lookup (obj->priv->cache, "Attributes"); + if (val) + { + GArray *array = g_array_new (TRUE, TRUE, sizeof (gchar *)); + GHashTable *attributes = g_value_get_boxed (val); + g_hash_table_foreach (attributes, add_to_attribute_array, &array); + return array; + } } message = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetAttributes", error, ""); @@ -740,9 +1278,9 @@ atspi_accessible_get_attributes_as_array (AtspiAccessible *obj, GError **error) * atspi_accessible_get_application: * @obj: The #AtspiAccessible being queried. * - * Get the containing #AtspiApplication for an object. + * Gets the containing #AtspiApplication for an object. * - * Returns: (transfer full): the containing AtspiApplication instance for + * Returns: (transfer full): the containing #AtspiApplication instance for * this object. */ AtspiAccessible * @@ -771,7 +1309,11 @@ atspi_accessible_get_application (AtspiAccessible *obj, GError **error) } if (!parent || parent == obj || atspi_accessible_get_role (parent, NULL) == ATSPI_ROLE_DESKTOP_FRAME) + { + if (parent) + g_object_unref (parent); return obj; + } g_object_unref (obj); obj = parent; } @@ -783,11 +1325,10 @@ atspi_accessible_get_application (AtspiAccessible *obj, GError **error) * atspi_accessible_get_toolkit_name: * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Get the toolkit for a #AtspiAccessible object. + * Gets the toolkit name for an #AtspiAccessible object. * Only works on application root objects. * - * Returns: a UTF-8 string indicating the toolkit name for the #AtspiAccessible object. - * or NULL on exception + * Returns: a UTF-8 string indicating the toolkit name for the #AtspiAccessible object or NULL on exception. **/ gchar * atspi_accessible_get_toolkit_name (AtspiAccessible *obj, GError **error) @@ -808,11 +1349,10 @@ atspi_accessible_get_toolkit_name (AtspiAccessible *obj, GError **error) * atspi_accessible_get_toolkit_version: * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Get the toolkit version for a #AtspiAccessible object. + * Gets the toolkit version for an #AtspiAccessible object. * Only works on application root objects. * - * Returns: a UTF-8 string indicating the toolkit ersion for the #AtspiAccessible object. - * or NULL on exception + * Returns: a UTF-8 string indicating the toolkit version for the #AtspiAccessible object or NULL on exception. **/ gchar * atspi_accessible_get_toolkit_version (AtspiAccessible *obj, GError **error) @@ -833,12 +1373,11 @@ atspi_accessible_get_toolkit_version (AtspiAccessible *obj, GError **error) * atspi_accessible_get_atspi_version: * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Get the AT-SPI IPC specification version supported by the application + * Gets the AT-SPI IPC specification version supported by the application * pointed to by the #AtspiAccessible object. * Only works on application root objects. * - * Returns: a UTF-8 string indicating the AT-SPI ersion for the #AtspiAccessible object. - * or NULL on exception + * Returns: a UTF-8 string indicating the AT-SPI version for the #AtspiAccessible object or NULL on exception. **/ gchar * atspi_accessible_get_atspi_version (AtspiAccessible *obj, GError **error) @@ -856,14 +1395,14 @@ atspi_accessible_get_atspi_version (AtspiAccessible *obj, GError **error) } /** - * atspi_accessible_get_toolkit_version: + * atspi_accessible_get_id: * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Get the application id for a #AtspiAccessible object. + * Gets the application id for a #AtspiAccessible object. * Only works on application root objects. * - * Returns: a gint indicating the id for the #AtspiAccessible object. - * or -1 on exception + * Returns: a positive #gint indicating the id for the #AtspiAccessible object + * or -1 on exception. **/ gint atspi_accessible_get_id (AtspiAccessible *obj, GError **error) @@ -913,7 +1452,8 @@ _atspi_accessible_is_a (AtspiAccessible *accessible, * atspi_accessible_is_action: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements #AtspiAction. + * Query whether the specified #AtspiAccessible implements the + * #AtspiAction interface. * * Returns: #TRUE if @obj implements the #AtspiAction interface, * #FALSE otherwise. @@ -929,7 +1469,8 @@ atspi_accessible_is_action (AtspiAccessible *obj) * atspi_accessible_is_application: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements #AtspiApplication. + * Query whether the specified #AtspiAccessible implements the + * #AtspiApplication interface. * * Returns: #TRUE if @obj implements the #AtspiApplication interface, * #FALSE otherwise. @@ -941,11 +1482,14 @@ atspi_accessible_is_application (AtspiAccessible *obj) atspi_interface_application); } -/** - * atspi_accessible_is_collection: * @obj: a pointer to the #AtspiAccessible instance to query. - * - * Query whether the specified #AtspiAccessible implements #AtspiCollection. - * Returns: #TRUE if @obj implements the #AtspiCollection interface, +/** + * atspi_accessible_is_collection: + * @obj: a pointer to the #AtspiAccessible instance to query. + * + * Query whether the specified #AtspiAccessible implements the + * #AtspiCollection interface. + * + * Returns: #TRUE if @obj implements the #AtspiCollection interface, * #FALSE otherwise. **/ gboolean @@ -975,7 +1519,8 @@ atspi_accessible_is_component (AtspiAccessible *obj) * atspi_accessible_is_document: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements #AtspiDocument. + * Query whether the specified #AtspiAccessible implements the + * #AtspiDocument interface. * * Returns: #TRUE if @obj implements the #AtspiDocument interface, * #FALSE otherwise. @@ -991,7 +1536,8 @@ atspi_accessible_is_document (AtspiAccessible *obj) * atspi_accessible_is_editable_text: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements #AtspiEditableText. + * Query whether the specified #AtspiAccessible implements the + * #AtspiEditableText interface. * * Returns: #TRUE if @obj implements the #AtspiEditableText interface, * #FALSE otherwise. @@ -1002,12 +1548,13 @@ atspi_accessible_is_editable_text (AtspiAccessible *obj) return _atspi_accessible_is_a (obj, atspi_interface_editable_text); } - + /** * atspi_accessible_is_hypertext: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements #AtspiHypertext. + * Query whether the specified #AtspiAccessible implements the + * #AtspiHypertext interface. * * Returns: #TRUE if @obj implements the #AtspiHypertext interface, * #FALSE otherwise. @@ -1023,7 +1570,8 @@ atspi_accessible_is_hypertext (AtspiAccessible *obj) * atspi_accessible_is_hyperlink: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements #AtspiHyperlink. + * Query whether the specified #AtspiAccessible implements the + * #AtspiHyperlink interface. * * Returns: #TRUE if @obj implements the #AtspiHypertext interface, * #FALSE otherwise. @@ -1039,7 +1587,8 @@ atspi_accessible_is_hyperlink (AtspiAccessible *obj) * atspi_accessible_is_image: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements #AtspiImage. + * Query whether the specified #AtspiAccessible implements the + * #AtspiImage interface. * * Returns: #TRUE if @obj implements the #AtspiImage interface, * #FALSE otherwise. @@ -1055,7 +1604,8 @@ atspi_accessible_is_image (AtspiAccessible *obj) * atspi_accessible_is_selection: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements #AtspiSelection. + * Query whether the specified #AtspiAccessible implements the + * #AtspiSelection interface. * * Returns: #TRUE if @obj implements the #AtspiSelection interface, * #FALSE otherwise. @@ -1071,7 +1621,8 @@ atspi_accessible_is_selection (AtspiAccessible *obj) * atspi_accessible_is_table: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements #AtspiTable. + * Query whether the specified #AtspiAccessible implements the + * #AtspiTable interface. * * Returns: #TRUE if @obj implements the #AtspiTable interface, * #FALSE otherwise. @@ -1084,11 +1635,28 @@ atspi_accessible_is_table (AtspiAccessible *obj) } /** + * atspi_accessible_is_table_cell: + * @obj: a pointer to the #AtspiAccessible instance to query. + * + * Query whether the specified #AtspiAccessible implements the + * #AtspiTableCell interface. + * + * Returns: #TRUE if @obj implements the #AtspiTable interface, + * #FALSE otherwise. +**/ +gboolean +atspi_accessible_is_table_cell (AtspiAccessible *obj) +{ + return _atspi_accessible_is_a (obj, + atspi_interface_table_cell); +} + +/** * atspi_accessible_is_streamable_content: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements - * #AtspiStreamableContent. + * Query whether the specified #AtspiAccessible implements the + * #AtspiStreamableContent interface. * * Returns: #TRUE if @obj implements the #AtspiStreamableContent interface, * #FALSE otherwise. @@ -1109,7 +1677,8 @@ atspi_accessible_is_streamable_content (AtspiAccessible *obj) * atspi_accessible_is_text: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements #AtspiText. + * Query whether the specified #AtspiAccessible implements the + * #AtspiText interface. * * Returns: #TRUE if @obj implements the #AtspiText interface, * #FALSE otherwise. @@ -1125,7 +1694,8 @@ atspi_accessible_is_text (AtspiAccessible *obj) * atspi_accessible_is_value: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements #AtspiValue. + * Query whether the specified #AtspiAccessible implements the + * #AtspiValue interface. * * Returns: #TRUE if @obj implements the #AtspiValue interface, * #FALSE otherwise. @@ -1138,45 +1708,83 @@ atspi_accessible_is_value (AtspiAccessible *obj) } /** - * atspi_accessible_get_action: + * atspi_accessible_get_action: (rename-to atspi_accessible_get_action_iface) * @obj: a pointer to the #AtspiAccessible instance to query. * - * Get the #AtspiAction interface for an #AtspiAccessible. + * Gets the #AtspiAction interface for an #AtspiAccessible. * * Returns: (transfer full): a pointer to an #AtspiAction interface * instance, or NULL if @obj does not implement #AtspiAction. + * + * Deprecated: 2.10: Use atspi_accessible_get_action_iface instead. **/ AtspiAction * atspi_accessible_get_action (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_action) ? - g_object_ref (ATSPI_ACTION (accessible)) : NULL); + g_object_ref (ATSPI_ACTION (accessible)) : NULL); +} + +/** + * atspi_accessible_get_action_iface: + * @obj: a pointer to the #AtspiAccessible instance to query. + * + * Gets the #AtspiAction interface for an #AtspiAccessible. + * + * Returns: (transfer full): a pointer to an #AtspiAction interface + * instance, or NULL if @obj does not implement #AtspiAction. + **/ +AtspiAction * +atspi_accessible_get_action_iface (AtspiAccessible *accessible) +{ + return (_atspi_accessible_is_a (accessible, atspi_interface_action) ? + g_object_ref (ATSPI_ACTION (accessible)) : NULL); } /** - * atspi_accessible_get_collection: + * atspi_accessible_get_collection: (rename-to atspi_accessible_get_collection_iface) * @obj: a pointer to the #AtspiAccessible instance to query. * - * Get the #AtspiCollection interface for an #AtspiAccessible. + * Gets the #AtspiCollection interface for an #AtspiAccessible. * * Returns: (transfer full): a pointer to an #AtspiCollection interface * instance, or NULL if @obj does not implement #AtspiCollection. + * + * Deprecated: 2.10: Use atspi_accessible_get_collection_iface instead. **/ AtspiCollection * atspi_accessible_get_collection (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_collection) ? - g_object_ref (ATSPI_COLLECTION (accessible)) : NULL); + g_object_ref (ATSPI_COLLECTION (accessible)) : NULL); +} + +/** + * atspi_accessible_get_collection_iface: + * @obj: a pointer to the #AtspiAccessible instance to query. + * + * Gets the #AtspiCollection interface for an #AtspiAccessible. + * + * Returns: (transfer full): a pointer to an #AtspiCollection interface + * instance, or NULL if @obj does not implement #AtspiCollection. + **/ +AtspiCollection * +atspi_accessible_get_collection_iface (AtspiAccessible *accessible) +{ + return (_atspi_accessible_is_a (accessible, atspi_interface_collection) ? + g_object_ref (ATSPI_COLLECTION (accessible)) : NULL); } /** - * atspi_accessible_get_component: + * atspi_accessible_get_component: (rename-to atspi_accessible_get_component_iface) * @obj: a pointer to the #AtspiAccessible instance to query. * - * Get the #AtspiComponent interface for an #AtspiAccessible. + * Gets the #AtspiComponent interface for an #AtspiAccessible. * * Returns: (transfer full): a pointer to an #AtspiComponent interface * instance, or NULL if @obj does not implement #AtspiComponent. + * + * Deprecated: 2.10: Use atspi_accessible_get_component_iface instead. **/ AtspiComponent * atspi_accessible_get_component (AtspiAccessible *obj) @@ -1186,43 +1794,94 @@ atspi_accessible_get_component (AtspiAccessible *obj) } /** - * atspi_accessible_get_document: + * atspi_accessible_get_component_iface: + * @obj: a pointer to the #AtspiAccessible instance to query. + * + * Gets the #AtspiComponent interface for an #AtspiAccessible. + * + * Returns: (transfer full): a pointer to an #AtspiComponent interface + * instance, or NULL if @obj does not implement #AtspiComponent. + **/ +AtspiComponent * +atspi_accessible_get_component_iface (AtspiAccessible *obj) +{ + return (_atspi_accessible_is_a (obj, atspi_interface_component) ? + g_object_ref (ATSPI_COMPONENT (obj)) : NULL); +} + +/** + * atspi_accessible_get_document: (rename-to atspi_accessible_get_document_iface) * @obj: a pointer to the #AtspiAccessible instance to query. * - * Get the #AtspiDocument interface for an #AtspiAccessible. + * Gets the #AtspiDocument interface for an #AtspiAccessible. * * Returns: (transfer full): a pointer to an #AtspiDocument interface * instance, or NULL if @obj does not implement #AtspiDocument. + * + * Deprecated: 2.10: Use atspi_accessible_get_document_iface instead. **/ AtspiDocument * atspi_accessible_get_document (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_document) ? - g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL); + g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL); +} + +/** + * atspi_accessible_get_document_iface: + * @obj: a pointer to the #AtspiAccessible instance to query. + * + * Gets the #AtspiDocument interface for an #AtspiAccessible. + * + * Returns: (transfer full): a pointer to an #AtspiDocument interface + * instance, or NULL if @obj does not implement #AtspiDocument. + **/ +AtspiDocument * +atspi_accessible_get_document_iface (AtspiAccessible *accessible) +{ + return (_atspi_accessible_is_a (accessible, atspi_interface_document) ? + g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL); } /** - * atspi_accessible_get_editable_text: + * atspi_accessible_get_editable_text: (rename-to atspi_accessible_get_editable_text_iface) * @obj: a pointer to the #AtspiAccessible instance to query. * - * Get the #AtspiEditableText interface for an #AtspiAccessible. + * Gets the #AtspiEditableText interface for an #AtspiAccessible. * * Returns: (transfer full): a pointer to an #AtspiEditableText interface * instance, or NULL if @obj does not implement #AtspiEditableText. + * + * Deprecated: 2.10: Use atspi_accessible_get_editable_text_iface instead. **/ AtspiEditableText * atspi_accessible_get_editable_text (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_editable_text) ? - g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL); + g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL); +} + +/** + * atspi_accessible_get_editable_text_iface: + * @obj: a pointer to the #AtspiAccessible instance to query. + * + * Gets the #AtspiEditableText interface for an #AtspiAccessible. + * + * Returns: (transfer full): a pointer to an #AtspiEditableText interface + * instance, or NULL if @obj does not implement #AtspiEditableText. + **/ +AtspiEditableText * +atspi_accessible_get_editable_text_iface (AtspiAccessible *accessible) +{ + return (_atspi_accessible_is_a (accessible, atspi_interface_editable_text) ? + g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL); } /** * atspi_accessible_get_hyperlink: * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Get the #AtspiHyperlink associated with the given #AtspiAccessible, if - * supported. + * Gets the #AtspiHyperlink interface for an #AtspiAccessible. * * Returns: (transfer full): the #AtspiHyperlink object associated with * the given #AtspiAccessible, or NULL if not supported. @@ -1231,55 +1890,109 @@ AtspiHyperlink * atspi_accessible_get_hyperlink (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_hyperlink) ? - atspi_hyperlink_new (accessible->parent.app, accessible->parent.path) : NULL); + _atspi_hyperlink_new (accessible->parent.app, accessible->parent.path) : NULL); } /** - * atspi_accessible_get_hypertext: + * atspi_accessible_get_hypertext: (rename-to atspi_accessible_get_hypertext_iface) * @obj: a pointer to the #AtspiAccessible instance to query. * - * Get the #AtspiHypertext interface for an #AtspiAccessible. + * Gets the #AtspiHypertext interface for an #AtspiAccessible. * * Returns: (transfer full): a pointer to an #AtspiHypertext interface * instance, or NULL if @obj does not implement #AtspiHypertext. + * + * Deprecated: 2.10: Use atspi_accessible_get_hypertext_iface instead. **/ AtspiHypertext * atspi_accessible_get_hypertext (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_hypertext) ? - g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL); + g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL); +} + +/** + * atspi_accessible_get_hypertext_iface: + * @obj: a pointer to the #AtspiAccessible instance to query. + * + * Gets the #AtspiHypertext interface for an #AtspiAccessible. + * + * Returns: (transfer full): a pointer to an #AtspiHypertext interface + * instance, or NULL if @obj does not implement #AtspiHypertext. + **/ +AtspiHypertext * +atspi_accessible_get_hypertext_iface (AtspiAccessible *accessible) +{ + return (_atspi_accessible_is_a (accessible, atspi_interface_hypertext) ? + g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL); } /** - * atspi_accessible_get_image: + * atspi_accessible_get_image: (rename-to atspi_accessible_get_image_iface) * @obj: a pointer to the #AtspiAccessible instance to query. * - * Get the #AtspiImage interface for an #AtspiAccessible. + * Gets the #AtspiImage interface for an #AtspiAccessible. * * Returns: (transfer full): a pointer to an #AtspiImage interface instance, or * NULL if @obj does not implement #AtspiImage. + * + * Deprecated: 2.10: Use atspi_accessible_get_image_iface instead. **/ AtspiImage * atspi_accessible_get_image (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_image) ? - g_object_ref (ATSPI_IMAGE (accessible)) : NULL); + g_object_ref (ATSPI_IMAGE (accessible)) : NULL); +} + +/** + * atspi_accessible_get_image_iface: + * @obj: a pointer to the #AtspiAccessible instance to query. + * + * Gets the #AtspiImage interface for an #AtspiAccessible. + * + * Returns: (transfer full): a pointer to an #AtspiImage interface instance, or + * NULL if @obj does not implement #AtspiImage. + **/ +AtspiImage * +atspi_accessible_get_image_iface (AtspiAccessible *accessible) +{ + return (_atspi_accessible_is_a (accessible, atspi_interface_image) ? + g_object_ref (ATSPI_IMAGE (accessible)) : NULL); } /** - * atspi_accessible_get_selection: + * atspi_accessible_get_selection: (rename-to atspi_accessible_get_selection_iface) * @obj: a pointer to the #AtspiAccessible instance to query. * - * Get the #AtspiSelection interface for an #AtspiAccessible. + * Gets the #AtspiSelection interface for an #AtspiAccessible. * * Returns: (transfer full): a pointer to an #AtspiSelection interface * instance, or NULL if @obj does not implement #AtspiSelection. + * + * Deprecated: 2.10: Use atspi_accessible_get_selection_iface instead. **/ AtspiSelection * atspi_accessible_get_selection (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_selection) ? - g_object_ref (ATSPI_SELECTION (accessible)) : NULL); + g_object_ref (ATSPI_SELECTION (accessible)) : NULL); +} + +/** + * atspi_accessible_get_selection_iface: + * @obj: a pointer to the #AtspiAccessible instance to query. + * + * Gets the #AtspiSelection interface for an #AtspiAccessible. + * + * Returns: (transfer full): a pointer to an #AtspiSelection interface + * instance, or NULL if @obj does not implement #AtspiSelection. + **/ +AtspiSelection * +atspi_accessible_get_selection_iface (AtspiAccessible *accessible) +{ + return (_atspi_accessible_is_a (accessible, atspi_interface_selection) ? + g_object_ref (ATSPI_SELECTION (accessible)) : NULL); } #if 0 @@ -1287,7 +2000,7 @@ atspi_accessible_get_selection (AtspiAccessible *accessible) * atspi_accessible_get_streamable_content: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Get the #AtspiStreamableContent interface for an #AtspiAccessible. + * Gets the #AtspiStreamableContent interface for an #AtspiAccessible. * * Returns: (transfer full): a pointer to an #AtspiStreamableContent interface * instance, or NULL if @obj does not implement #AtspiStreamableContent. @@ -1296,34 +2009,70 @@ AtspiStreamableContent * atspi_accessible_get_streamable_content (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_streamable_content) ? - accessible : NULL); + accessible : NULL); } #endif /** - * atspi_accessible_get_table: + * atspi_accessible_get_table: (rename-to atspi_accessible_get_table_iface) * @obj: a pointer to the #AtspiAccessible instance to query. * - * Get the #AtspiTable interface for an #AtspiAccessible. + * Gets the #AtspiTable interface for an #AtspiAccessible. * * Returns: (transfer full): a pointer to an #AtspiTable interface instance, or * NULL if @obj does not implement #AtspiTable. + * + * Deprecated: 2.10: Use atspi_accessible_get_table_iface instead. **/ AtspiTable * atspi_accessible_get_table (AtspiAccessible *obj) { return (_atspi_accessible_is_a (obj, atspi_interface_table) ? - g_object_ref (ATSPI_TABLE (obj)) : NULL); + g_object_ref (ATSPI_TABLE (obj)) : NULL); } /** - * atspi_accessible_get_text: + * atspi_accessible_get_table_iface: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Get the #AtspiTable interface for an #AtspiAccessible. + * Gets the #AtspiTable interface for an #AtspiAccessible. + * + * Returns: (transfer full): a pointer to an #AtspiTable interface instance, or + * NULL if @obj does not implement #AtspiTable. + **/ +AtspiTable * +atspi_accessible_get_table_iface (AtspiAccessible *obj) +{ + return (_atspi_accessible_is_a (obj, atspi_interface_table) ? + g_object_ref (ATSPI_TABLE (obj)) : NULL); +} + +/** + * atspi_accessible_get_table_cell: + * @obj: a pointer to the #AtspiAccessible instance to query. + * + * Gets the #AtspiTableCell interface for an #AtspiAccessible. + * + * Returns: (transfer full): a pointer to an #AtspiTableCell interface instance, + * or NULL if @obj does not implement #AtspiTable. + **/ +AtspiTableCell * +atspi_accessible_get_table_cell (AtspiAccessible *obj) +{ + return (_atspi_accessible_is_a (obj, atspi_interface_table_cell) ? + g_object_ref (ATSPI_TABLE_CELL (obj)) : NULL); +} + +/** + * atspi_accessible_get_text: (rename-to atspi_accessible_get_text_iface) + * @obj: a pointer to the #AtspiAccessible instance to query. + * + * Gets the #AtspiTable interface for an #AtspiAccessible. * * Returns: (transfer full): a pointer to an #AtspiText interface instance, or * NULL if @obj does not implement #AtspiText. + * + * Deprecated: 2.10: Use atspi_accessible_get_text_iface instead. **/ AtspiText * atspi_accessible_get_text (AtspiAccessible *obj) @@ -1333,19 +2082,53 @@ atspi_accessible_get_text (AtspiAccessible *obj) } /** - * atspi_accessible_get_value: + * atspi_accessible_get_text_iface: + * @obj: a pointer to the #AtspiAccessible instance to query. + * + * Gets the #AtspiTable interface for an #AtspiAccessible. + * + * Returns: (transfer full): a pointer to an #AtspiText interface instance, or + * NULL if @obj does not implement #AtspiText. + **/ +AtspiText * +atspi_accessible_get_text_iface (AtspiAccessible *obj) +{ + return (_atspi_accessible_is_a (obj, atspi_interface_text) ? + g_object_ref (ATSPI_TEXT (obj)) : NULL); +} + +/** + * atspi_accessible_get_value: (rename-to atspi_accessible_get_value_iface) * @obj: a pointer to the #AtspiAccessible instance to query. * - * Get the #AtspiTable interface for an #AtspiAccessible. + * Gets the #AtspiTable interface for an #AtspiAccessible. * * Returns: (transfer full): a pointer to an #AtspiValue interface instance, or * NULL if @obj does not implement #AtspiValue. + * + * Deprecated: 2.10: Use atspi_accessible_get_value_iface instead. **/ AtspiValue * atspi_accessible_get_value (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_value) ? - g_object_ref (ATSPI_VALUE (accessible)) : NULL); + g_object_ref (ATSPI_VALUE (accessible)) : NULL); +} + +/** + * atspi_accessible_get_value_iface: + * @obj: a pointer to the #AtspiAccessible instance to query. + * + * Gets the #AtspiTable interface for an #AtspiAccessible. + * + * Returns: (transfer full): a pointer to an #AtspiValue interface instance, or + * NULL if @obj does not implement #AtspiValue. + **/ +AtspiValue * +atspi_accessible_get_value_iface (AtspiAccessible *accessible) +{ + return (_atspi_accessible_is_a (accessible, atspi_interface_value) ? + g_object_ref (ATSPI_VALUE (accessible)) : NULL); } static void @@ -1359,20 +2142,23 @@ append_const_val (GArray *array, const gchar *val) /** * atspi_accessible_get_interfaces: + * @obj: The #AtspiAccessible to query. * - * #obj: The #AtspiAccessible to query. + * A set of pointers to all interfaces supported by an #AtspiAccessible. * * Returns: (element-type gchar*) (transfer full): A #GArray of strings * describing the interfaces supported by the object. Interfaces are - * denoted in short-hand (ie, "Component", "Text", etc.) + * denoted in short-hand (i.e. "Component", "Text" etc.). **/ GArray * atspi_accessible_get_interfaces (AtspiAccessible *obj) { - GArray *ret = g_array_new (TRUE, TRUE, sizeof (gchar *)); + GArray *ret; g_return_val_if_fail (obj != NULL, NULL); + ret = g_array_new (TRUE, TRUE, sizeof (gchar *)); + append_const_val (ret, "Accessible"); if (atspi_accessible_is_action (obj)) append_const_val (ret, "Action"); @@ -1394,6 +2180,8 @@ atspi_accessible_get_interfaces (AtspiAccessible *obj) append_const_val (ret, "Selection"); if (atspi_accessible_is_table (obj)) append_const_val (ret, "Table"); + if (atspi_accessible_is_table_cell (obj)) + append_const_val (ret, "TableCell"); if (atspi_accessible_is_text (obj)) append_const_val (ret, "Text"); if (atspi_accessible_is_value (obj)) @@ -1403,10 +2191,10 @@ atspi_accessible_get_interfaces (AtspiAccessible *obj) } AtspiAccessible * -atspi_accessible_new (AtspiApplication *app, const gchar *path) +_atspi_accessible_new (AtspiApplication *app, const gchar *path) { AtspiAccessible *accessible; - + accessible = g_object_new (ATSPI_TYPE_ACCESSIBLE, NULL); g_return_val_if_fail (accessible != NULL, NULL); @@ -1418,10 +2206,9 @@ atspi_accessible_new (AtspiApplication *app, const gchar *path) /** * atspi_accessible_set_cache_mask: - * * @accessible: The #AtspiAccessible to operate on. Must be the desktop or * the root of an application. - * @mask: (type int): An #AtspiCache specifying a bit mask of the types of data to cache. + * @mask: An #AtspiCache specifying a bit mask of the types of data to cache. * * Sets the type of data to cache for accessibles. * If this is not set for an application or is reset to ATSPI_CACHE_UNDEFINED, @@ -1438,26 +2225,77 @@ atspi_accessible_set_cache_mask (AtspiAccessible *accessible, AtspiCache mask) g_return_if_fail (accessible->parent.app != NULL); g_return_if_fail (accessible == accessible->parent.app->root); accessible->parent.app->cache = mask; + enable_caching = TRUE; } /** * atspi_accessible_clear_cache: - * @accessible: The #AtspiAccessible whose cache to clear. + * @obj: The #AtspiAccessible whose cache to clear. * * Clears the cached information for the given accessible and all of its * descendants. */ void -atspi_accessible_clear_cache (AtspiAccessible *accessible) +atspi_accessible_clear_cache (AtspiAccessible *obj) +{ + gint i; + + if (obj) + { + obj->cached_properties = ATSPI_CACHE_NONE; + if (obj->children) + for (i = 0; i < obj->children->len; i++) + atspi_accessible_clear_cache (g_ptr_array_index (obj->children, i)); + } +} + +/** + * atspi_accessible_get_process_id: + * @accessible: The #AtspiAccessible to query. + * @error: a pointer to a %NULL #GError pointer + * + * Returns the process id associated with the given accessible. Mainly + * added for debugging; it is a shortcut to explicitly querying the + * accessible's app->bus_name and then calling GetConnectionUnixProcessID. + * + * Returns: The process ID or undetermined value if @error is set. + **/ +guint +atspi_accessible_get_process_id (AtspiAccessible *accessible, GError **error) { - GList *l; + DBusMessage *message, *reply; + DBusConnection *bus = _atspi_bus (); + dbus_uint32_t pid = -1; + DBusError d_error; + + if (!accessible->parent.app || !accessible->parent.app->bus_name) + { + g_set_error_literal(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "Process is defunct"); + return -1; + } - if (accessible) + message = dbus_message_new_method_call ("org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "GetConnectionUnixProcessID"); + dbus_message_append_args (message, DBUS_TYPE_STRING, + &accessible->parent.app->bus_name, + DBUS_TYPE_INVALID); + dbus_error_init (&d_error); + reply = dbus_connection_send_with_reply_and_block (bus, message, -1, &d_error); + dbus_message_unref (message); + if (reply) { - accessible->cached_properties = ATSPI_CACHE_NONE; - for (l = accessible->children; l; l = l->next) - atspi_accessible_clear_cache (l->data); + if (!strcmp (dbus_message_get_signature (reply), "u")) + dbus_message_get_args (reply, NULL, DBUS_TYPE_UINT32, &pid, DBUS_TYPE_INVALID); + dbus_message_unref (reply); } + if (dbus_error_is_set (&d_error)) + { + g_set_error_literal(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "Process is defunct"); + dbus_error_free (&d_error); + } + return pid; } AtspiCache @@ -1489,7 +2327,11 @@ _atspi_accessible_test_cache (AtspiAccessible *accessible, AtspiCache flag) { AtspiCache mask = _atspi_accessible_get_cache_mask (accessible); AtspiCache result = accessible->cached_properties & mask & flag; - return (result != 0 && atspi_main_loop && !atspi_no_cache); + if (accessible->states && atspi_state_set_contains (accessible->states, ATSPI_STATE_TRANSIENT)) + return FALSE; + return (result != 0 && (atspi_main_loop || enable_caching || + flag == ATSPI_CACHE_INTERFACES) && + !atspi_no_cache); } void @@ -1499,3 +2341,97 @@ _atspi_accessible_add_cache (AtspiAccessible *accessible, AtspiCache flag) accessible->cached_properties |= flag & mask; } + +/** + * atspi_accessible_get_locale: + * @accessible: an #AtspiAccessible + * + * Gets a UTF-8 string indicating the POSIX-style LC_MESSAGES locale + * of @accessible. + * + * Since: 2.7.91 + * + * Returns: a UTF-8 string indicating the POSIX-style LC_MESSAGES + * locale of @accessible. + **/ +const gchar* +atspi_accessible_get_object_locale (AtspiAccessible *accessible, GError **error) +{ + gchar *locale; + + g_return_val_if_fail (accessible != NULL, NULL); + + locale = g_object_get_qdata (G_OBJECT (accessible), quark_locale); + if (!locale) + { + if (!_atspi_dbus_get_property (accessible, atspi_interface_accessible, + "Locale", error, "s", &locale)) + return NULL; + if (locale) + g_object_set_qdata_full (G_OBJECT (accessible), quark_locale, locale, + g_free); + } + return locale; +} + +/** + * atspi_accessible_get_accessible_id: + * @obj: an #AtspiAccessible + * + * Gets the accessible id of the accessible. This is not meant to be presented + * to the user, but to be an id which is stable over application development. + * Typically, this is the gtkbuilder id. + * + * Since: 2.34 + * + * Returns: a character string representing the accessible id of the + * #AtspiAccessible object or NULL on exception. + **/ +gchar* +atspi_accessible_get_accessible_id (AtspiAccessible *obj, GError **error) +{ + gchar *accessible_id; + + g_return_val_if_fail (obj != NULL, NULL); + + if (!_atspi_dbus_get_property (obj, atspi_interface_accessible, + "AccessibleId", error, "s", &accessible_id)) + return NULL; + + return accessible_id; +} + +void +free_value (gpointer data) +{ + GValue *value = data; + + g_value_unset (value); + g_free (value); +} + +GHashTable * +_atspi_accessible_ref_cache (AtspiAccessible *accessible) +{ + AtspiAccessiblePrivate *priv = accessible->priv; + + priv->cache_ref_count++; + if (priv->cache) + return g_hash_table_ref (priv->cache); + priv->cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, + free_value); + return priv->cache; +} + +void +_atspi_accessible_unref_cache (AtspiAccessible *accessible) +{ + AtspiAccessiblePrivate *priv = accessible->priv; + + if (priv->cache) + { + g_hash_table_unref (priv->cache); + if (--priv->cache_ref_count == 0) + priv->cache = NULL; + } +}