From: Artur Świgoń Date: Fri, 7 Feb 2020 13:01:49 +0000 (+0100) Subject: Merge tag 'upstream/2.34.0' into tizen X-Git-Tag: submit/tizen/20200213.221652^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5016c77a44ff9bb5ce595a32429319d189839063;hp=-c;p=platform%2Fupstream%2Fat-spi2-core.git Merge tag 'upstream/2.34.0' into tizen Change-Id: I480c8e572f5fe7d3d7d2d6f1f0aa2a76f009c9a8 --- 5016c77a44ff9bb5ce595a32429319d189839063 diff --combined atspi/atspi-accessible.c index d2afcd1,fd6737d..b5d7616 --- a/atspi/atspi-accessible.c +++ b/atspi/atspi-accessible.c @@@ -7,28 -7,82 +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) { @@@ -109,6 -163,13 +163,13 @@@ 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 @@@ -119,7 -180,7 +180,7 @@@ accessible->priv = atspi_accessible_get_instance_private (accessible); - accessible->children = g_ptr_array_new_with_free_func (g_object_unref); + accessible->children = g_ptr_array_new_with_free_func (atspi_accessible_unref); } static void @@@ -189,6 -250,8 +250,8 @@@ atspi_accessible_finalize (GObject *obj #endif G_OBJECT_CLASS (atspi_accessible_parent_class)->finalize (object); + + /* TODO: remove emission hook */ } static void @@@ -200,6 -263,33 +263,33 @@@ atspi_accessible_class_init (AtspiAcces 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); } /** @@@ -225,522 -315,6 +315,522 @@@ atspi_accessible_get_name (AtspiAccessi return g_strdup (obj->name); } + +/** + * atspi_accessible_get_unique_id: + * @obj: a pointer to the #AtspiAccessible object on which to operate. + * + * Gets the identificator, uniquely identifying object, or NULL if an error occured. + * + * Returns: a UTF-8 string describing the #AtspiAccessible object + * or NULL on exception or NULL object passed. + **/ +gchar * +atspi_accessible_get_unique_id(AtspiAccessible *obj, GError **error) +{ + 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 + g_set_error(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "failed to get bus name"); + g_free(bus_name); + return id; +} + +/** + * atspi_accessible_get_bus_name: + * @obj: a pointer to the #AtspiAccessible object on which to operate. + * + * Gets the bus name, where object belongs. + * + * 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_bus_name(AtspiAccessible *obj, GError **error) +{ + 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) + { + return reading_material; + } + + 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. @@@ -1039,12 -613,12 +1129,12 @@@ atspi_accessible_get_role_name (AtspiAc * atspi_accessible_get_localized_role_name: * @obj: a pointer to the #AtspiAccessible object on which to operate. * - * Gets a UTF-8 string corresponding to the name of the role played by an + * 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 localized, UTF-8 string specifying the type of UI role played + * Returns: a localized, UTF-8 string specifying the type of UI role played * by an #AtspiAccessible object. * **/ @@@ -1099,6 -673,7 +1189,6 @@@ atspi_accessible_get_state_set (AtspiAc dbus_message_unref (reply); _atspi_accessible_add_cache (obj, ATSPI_CACHE_STATES); } - return g_object_ref (obj->states); } @@@ -1106,7 -681,7 +1196,7 @@@ * atspi_accessible_get_attributes: * @obj: The #AtspiAccessible being queried. * - * Gets 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. @@@ -1153,7 -728,7 +1243,7 @@@ add_to_attribute_array (gpointer key, g * atspi_accessible_get_attributes_as_array: * @obj: The #AtspiAccessible being queried. * - * Gets a #GArray 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. @@@ -1311,7 -886,7 +1401,7 @@@ atspi_accessible_get_atspi_version (Ats * Gets the application id for a #AtspiAccessible object. * Only works on application root objects. * - * Returns: a positive #gint indicating the id for the #AtspiAccessible object + * Returns: a positive #gint indicating the id for the #AtspiAccessible object * or -1 on exception. **/ gint @@@ -1362,7 -937,7 +1452,7 @@@ _atspi_accessible_is_a (AtspiAccessibl * atspi_accessible_is_action: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements the + * Query whether the specified #AtspiAccessible implements the * #AtspiAction interface. * * Returns: #TRUE if @obj implements the #AtspiAction interface, @@@ -1392,7 -967,7 +1482,7 @@@ atspi_accessible_is_application (AtspiA atspi_interface_application); } -/** +/** * atspi_accessible_is_collection: * @obj: a pointer to the #AtspiAccessible instance to query. * @@@ -1458,7 -1033,7 +1548,7 @@@ atspi_accessible_is_editable_text (Atsp return _atspi_accessible_is_a (obj, atspi_interface_editable_text); } - + /** * atspi_accessible_is_hypertext: * @obj: a pointer to the #AtspiAccessible instance to query. @@@ -1480,7 -1055,7 +1570,7 @@@ atspi_accessible_is_hypertext (AtspiAcc * atspi_accessible_is_hyperlink: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements the + * Query whether the specified #AtspiAccessible implements the * #AtspiHyperlink interface. * * Returns: #TRUE if @obj implements the #AtspiHypertext interface, @@@ -1587,7 -1162,7 +1677,7 @@@ atspi_accessible_is_streamable_content * atspi_accessible_is_text: * @obj: a pointer to the #AtspiAccessible instance to query. * - * Query whether the specified #AtspiAccessible implements the + * Query whether the specified #AtspiAccessible implements the * #AtspiText interface. * * Returns: #TRUE if @obj implements the #AtspiText interface, @@@ -1632,7 -1207,7 +1722,7 @@@ 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); } /** @@@ -1648,7 -1223,7 +1738,7 @@@ AtspiAction atspi_accessible_get_action_iface (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); } /** @@@ -1666,7 -1241,7 +1756,7 @@@ 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); } /** @@@ -1682,7 -1257,7 +1772,7 @@@ AtspiCollection atspi_accessible_get_collection_iface (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); } /** @@@ -1734,7 -1309,7 +1824,7 @@@ 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); } /** @@@ -1750,7 -1325,7 +1840,7 @@@ AtspiDocument atspi_accessible_get_document_iface (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); } /** @@@ -1768,7 -1343,7 +1858,7 @@@ 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); } /** @@@ -1784,7 -1359,7 +1874,7 @@@ 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); + g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL); } /** @@@ -1818,7 -1393,7 +1908,7 @@@ 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); } /** @@@ -1834,7 -1409,7 +1924,7 @@@ AtspiHypertext atspi_accessible_get_hypertext_iface (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); } /** @@@ -1852,7 -1427,7 +1942,7 @@@ 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); } /** @@@ -1868,7 -1443,7 +1958,7 @@@ AtspiImage atspi_accessible_get_image_iface (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); } /** @@@ -1886,7 -1461,7 +1976,7 @@@ 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); } /** @@@ -1902,7 -1477,7 +1992,7 @@@ AtspiSelection atspi_accessible_get_selection_iface (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); } #if 0 @@@ -1919,7 -1494,7 +2009,7 @@@ AtspiStreamableContent atspi_accessible_get_streamable_content (AtspiAccessible *accessible) { return (_atspi_accessible_is_a (accessible, atspi_interface_streamable_content) ? - accessible : NULL); + accessible : NULL); } #endif @@@ -1938,7 -1513,7 +2028,7 @@@ 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); } /** @@@ -1954,7 -1529,7 +2044,7 @@@ AtspiTable atspi_accessible_get_table_iface (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); } /** @@@ -1970,7 -1545,7 +2060,7 @@@ 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); + g_object_ref (ATSPI_TABLE_CELL (obj)) : NULL); } /** @@@ -2022,7 -1597,7 +2112,7 @@@ 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); } /** @@@ -2038,7 -1613,7 +2128,7 @@@ AtspiValue atspi_accessible_get_value_iface (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); } static void @@@ -2063,12 -1638,10 +2153,12 @@@ append_const_val (GArray *array, const 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"); @@@ -2100,11 -1673,11 +2190,11 @@@ return ret; } -AtspiAccessible * +AtspiAccessible * _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); @@@ -2284,6 -1857,33 +2374,33 @@@ atspi_accessible_get_object_locale (Ats 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) { diff --combined atspi/atspi-accessible.h index 9e209e3,13e4962..a1fe314 --- a/atspi/atspi-accessible.h +++ b/atspi/atspi-accessible.h @@@ -5,22 -5,22 +5,22 @@@ * Copyright 2002 Ximian, Inc. * 2002 Sun Microsystems Inc. * 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. */ #ifndef _ATSPI_ACCESSIBLE_H_ @@@ -45,41 -45,6 +45,41 @@@ G_BEGIN_DECL typedef struct _AtspiAccessiblePrivate AtspiAccessiblePrivate; +struct _AtspiAccessibleDefaultLabelInfo +{ + AtspiAccessible *obj; + AtspiRole role; + GHashTable *attributes; +}; + +struct _AtspiAccessibleReadingMaterial +{ + AtspiAccessible *parent; + AtspiAccessible *described_by_accessible; + GHashTable *attributes; + AtspiRole role; + AtspiRole parent_role; + char *name; + char *labeled_by_name; + char *text_interface_name; + char *localized_role_name; + char *description; + gdouble value; + gdouble increment; + gdouble lower; + gdouble upper; + gint64 states; + gint64 parent_states; + gint child_count; + gint index_in_parent; + gint list_children_count; + gint first_selected_child_index; + gint parent_child_count; + gint parent_selected_child_count; + gboolean is_selected_in_parent; + gboolean has_checkbox_child; +}; + struct _AtspiAccessible { AtspiObject parent; @@@ -99,9 -64,11 +99,11 @@@ typedef struct _AtspiAccessibleClass At struct _AtspiAccessibleClass { AtspiObjectClass parent_class; + + void (*region_changed) (AtspiAccessible *accessible, gint current_offset, gint last_offset); }; -GType atspi_accessible_get_type (void); +GType atspi_accessible_get_type (void); AtspiAccessible * _atspi_accessible_new (AtspiApplication *app, const gchar *path); @@@ -110,20 -77,6 +112,20 @@@ gchar * atspi_accessible_get_name (Atsp gchar * atspi_accessible_get_description (AtspiAccessible *obj, GError **error); +gchar * atspi_accessible_get_path (AtspiAccessible *obj, GError **error); + +gchar * atspi_accessible_get_bus_name (AtspiAccessible *obj, GError **error); + +gchar * atspi_accessible_get_unique_id (AtspiAccessible *obj, GError **error); + +AtspiAccessible *atspi_accessible_get_navigable_at_point (AtspiAccessible *root, gint x, gint y, AtspiCoordType ctype, GError **error); + +AtspiAccessible *atspi_accessible_get_neighbor (AtspiAccessible *root, AtspiAccessible *start, AtspiNeighborSearchDirection direction, GError **error); + +AtspiAccessibleReadingMaterial *atspi_accessible_get_reading_material (AtspiAccessible *obj, GError **error); + +AtspiAccessibleDefaultLabelInfo *atspi_accessible_get_default_label_info (AtspiAccessible *obj, GError **error); + AtspiAccessible * atspi_accessible_get_parent (AtspiAccessible *obj, GError **error); gint atspi_accessible_get_child_count (AtspiAccessible *obj, GError **error); @@@ -216,6 -169,8 +218,8 @@@ void atspi_accessible_clear_cache (Atsp guint atspi_accessible_get_process_id (AtspiAccessible *accessible, GError **error); + gchar * atspi_accessible_get_accessible_id (AtspiAccessible *obj, GError **error); + /* private */ void _atspi_accessible_add_cache (AtspiAccessible *accessible, AtspiCache flag); AtspiCache _atspi_accessible_get_cache_mask (AtspiAccessible *accessible); diff --combined atspi/atspi-action.c index ccf05bd,bc9cb7b..317673a --- a/atspi/atspi-action.c +++ b/atspi/atspi-action.c @@@ -6,19 -6,19 +6,19 @@@ * Copyright 2001, 2002 Ximian, 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" @@@ -214,28 -214,6 +214,28 @@@ atspi_action_do_action (AtspiAction *ob return retval; } +/** + * atspi_action_do_action_name: + * @obj: a pointer to the #AtspiAction to query. + * @name: a action name specifying which action to invoke. + * + * Invoke the action indicated by name. + * + * Returns: #TRUE if the action is successfully invoked, otherwise #FALSE. + **/ +gboolean +atspi_action_do_action_name (AtspiAction *obj, const gchar *name, GError **error) +{ + const char *action_name = name; + dbus_bool_t retval = FALSE; + + g_return_val_if_fail (obj != NULL, FALSE); + + _atspi_dbus_call (obj, atspi_interface_action, "DoActionName", error, "s=>b", action_name, &retval); + + return retval; +} + static void atspi_action_base_init (AtspiAction *klass) { diff --combined atspi/atspi-action.h index d30395e,e1056e7..ef66ef8 --- a/atspi/atspi-action.h +++ b/atspi/atspi-action.h @@@ -7,19 -7,19 +7,19 @@@ * * * 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. */ #ifndef _ATSPI_ACTION_H_ @@@ -57,7 -57,6 +57,7 @@@ gchar * atspi_action_get_key_binding (A gchar * atspi_action_get_localized_name (AtspiAction *obj, gint i, GError **error); gboolean atspi_action_do_action (AtspiAction *obj, gint i, GError **error); +gboolean atspi_action_do_action_name (AtspiAction *obj, const gchar *name, GError **error); #ifndef ATSPI_DISABLE_DEPRECATED gchar * atspi_action_get_description (AtspiAction *obj, gint i, GError **error); diff --combined atspi/atspi-collection.c index 97c4e05,d4d1537..5a44100 --- a/atspi/atspi-collection.c +++ b/atspi/atspi-collection.c @@@ -6,19 -6,19 +6,19 @@@ * 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" @@@ -81,12 -81,10 +81,12 @@@ static GArray return_accessibles (DBusMessage *message) { DBusMessageIter iter, iter_array; - GArray *ret = g_array_new (TRUE, TRUE, sizeof (AtspiAccessible *)); + GArray *ret; _ATSPI_DBUS_CHECK_SIG (message, "a(so)", NULL, NULL); + ret = g_array_new (TRUE, TRUE, sizeof (AtspiAccessible *)); + dbus_message_iter_init (message, &iter); dbus_message_iter_recurse (&iter, &iter_array); diff --combined atspi/atspi-component.c index f6f72f8,59879bb..320312a --- a/atspi/atspi-component.c +++ b/atspi/atspi-component.c @@@ -6,19 -6,19 +6,19 @@@ * Copyright 2001, 2002 Ximian, 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. */ /* @@@ -122,7 -122,6 +122,7 @@@ atspi_component_get_accessible_at_poin return _atspi_dbus_return_accessible_from_message (reply); } + /** * atspi_component_get_extents: * @obj: a pointer to the #AtspiComponent to query. @@@ -130,6 -129,8 +130,8 @@@ * (e.g. ATSPI_COORD_TYPE_WINDOW, ATSPI_COORD_TYPE_SCREEN). * * Gets the bounding box of the specified #AtspiComponent. + * The returned values are meaningful only if the Component has both + * STATE_VISIBLE and STATE_SHOWING. * * Returns: An #AtspiRect giving the accessible's extents. **/ @@@ -165,6 -166,8 +167,8 @@@ atspi_component_get_extents (AtspiCompo * (e.g. ATSPI_COORD_TYPE_WINDOW, ATSPI_COORD_TYPE_SCREEN). * * Gets the minimum x and y coordinates of the specified #AtspiComponent. + * The returned values are meaningful only if the Component has both + * STATE_VISIBLE and STATE_SHOWING. * * returns: An #AtspiPoint giving the @obj's position. **/ @@@ -193,6 -196,8 +197,8 @@@ atspi_component_get_position (AtspiComp * @obj: a pointer to the #AtspiComponent to query. * * Gets the size of the specified #AtspiComponent. + * The returned values are meaningful only if the Component has both + * STATE_VISIBLE and STATE_SHOWING. * * returns: An #AtspiPoint giving the @obj's size. **/ @@@ -216,7 -221,7 +222,7 @@@ atspi_component_get_size (AtspiComponen * atspi_component_get_layer: * @obj: a pointer to the #AtspiComponent to query. * - * Queries which layer the component is painted into, to help determine its + * Queries which layer the component is painted into, to help determine its * visibility in terms of stacking order. * * Returns: the #AtspiComponentLayer into which this component is painted. @@@ -238,7 -243,7 +244,7 @@@ atspi_component_get_layer (AtspiCompone * Queries the z stacking order of a component which is in the MDI or window * layer. (Bigger z-order numbers mean nearer the top) * - * Returns: a #gshort indicating the stacking order of the component + * Returns: a #gshort indicating the stacking order of the component * in the MDI layer, or -1 if the component is not in the MDI layer. **/ gshort @@@ -272,54 -277,14 +278,54 @@@ atspi_component_grab_focus (AtspiCompon } /** + * atspi_component_grab_highlight: + * @obj: a pointer to the #AtspiComponent on which to operate. + * + * Attempts to set highlight to the specified + * #AtspiComponent. + * + * Returns: #TRUE if successful, #FALSE otherwise. + * + **/ +gboolean +atspi_component_grab_highlight (AtspiComponent *obj, GError **error) +{ + dbus_bool_t retval = FALSE; + + _atspi_dbus_call (obj, atspi_interface_component, "GrabHighlight", error, "=>b", &retval); + + return retval; +} + +/** + * atspi_component_clear_highlight: + * @obj: a pointer to the #AtspiComponent on which to operate. + * + * Attempts to clear highlight on the specified + * #AtspiComponent. + * + * Returns: #TRUE if successful, #FALSE otherwise. + * + **/ +gboolean +atspi_component_clear_highlight (AtspiComponent *obj, GError **error) +{ + dbus_bool_t retval = FALSE; + + _atspi_dbus_call (obj, atspi_interface_component, "ClearHighlight", error, "=>b", &retval); + + return retval; +} + +/** * atspi_component_get_alpha: * @obj: The #AtspiComponent to be queried. * * Gets the opacity/alpha value of a component, if alpha blending is in use. * - * Returns: the opacity value of a component, as a #gdouble between 0.0 and 1.0. + * Returns: the opacity value of a component, as a #gdouble between 0.0 and 1.0. **/ -gdouble +gdouble atspi_component_get_alpha (AtspiComponent *obj, GError **error) { double retval = 1; @@@ -454,7 -419,6 +460,7 @@@ atspi_component_set_size (AtspiComponen } /** +<<<<<<< HEAD * atspi_component_scroll_to: * @obj: a pointer to the #AtspiComponent object on which to operate. * @type: a #AtspiScrollType indicating where the object should be placed on the @@@ -511,23 -475,6 +517,23 @@@ atspi_component_scroll_to_point (AtspiC return retval; } +/** + * atspi_component_get_highlight_index + * @obj: a pointer to the #AtspiComponent to query. + * + * Returns: highlight index of object if (>0), 0 if highlight index is not set + * or -1 if an error occured. + **/ +int +atspi_component_get_highlight_index (AtspiComponent *obj, GError **error) +{ + gint ret = -1; + g_return_val_if_fail (obj != NULL, -1); + _atspi_dbus_get_property (obj, atspi_interface_component, + "HighlightIndex", error, "i", &ret); + return ret; +} + static void atspi_component_base_init (AtspiComponent *klass) { diff --combined atspi/atspi-component.h index a97e83f,4e8f0ad..a812251 --- a/atspi/atspi-component.h +++ b/atspi/atspi-component.h @@@ -4,22 -4,22 +4,22 @@@ * * Copyright 2002 Ximian, Inc. * 2002 Sun Microsystems 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. */ #ifndef _ATSPI_COMPONENT_H_ @@@ -44,7 -44,7 +44,7 @@@ struct _AtspiRec /** * ATSPI_TYPE_RECT: - * + * * The #GType for a boxed type holding a #AtspiRect. */ #define ATSPI_TYPE_RECT (atspi_rect_get_type ()) @@@ -62,7 -62,7 +62,7 @@@ struct _AtspiPoin /** * ATSPI_TYPE_POINT: - * + * * The #GType for a boxed type holding a #AtspiPoint. */ #define ATSPI_TYPE_POINT (atspi_point_get_type ()) @@@ -111,12 -111,6 +111,12 @@@ gboolean atspi_component_scroll_to (Ats gboolean atspi_component_scroll_to_point (AtspiComponent *obj, AtspiCoordType coords, gint x, gint y, GError **error); +gboolean atspi_component_grab_highlight (AtspiComponent *obj, GError **error); + +gboolean atspi_component_clear_highlight (AtspiComponent *obj, GError **error); + +int atspi_component_get_highlight_index(AtspiComponent *obj, GError **error); + G_END_DECLS #endif /* _ATSPI_COMPONENT_H_ */ diff --combined atspi/atspi-constants.h index 67c42bf,8657ead..848ec8e --- a/atspi/atspi-constants.h +++ b/atspi/atspi-constants.h @@@ -6,19 -6,19 +6,19 @@@ * Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany. * * 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. */ /* TODO: Auto-generate this file again @@@ -93,13 -93,13 +93,13 @@@ extern "C" /** * AtspiLocaleType: * @ATSPI_LOCALE_TYPE_MESSAGES: For localizable natural-language messages. - * @ATSPI_LOCALE_TYPE_COLLATE: For regular expression matching and string - * collation. - * @ATSPI_LOCALE_TYPE_CTYPE: For regular expression matching, character - * classification, conversion, case-sensitive comparison, and wide character - * functions. + * @ATSPI_LOCALE_TYPE_COLLATE: For regular expression matching and string + * collation. + * @ATSPI_LOCALE_TYPE_CTYPE: For regular expression matching, character + * classification, conversion, case-sensitive comparison, and wide character + * functions. * @ATSPI_LOCALE_TYPE_MONETARY: For monetary formatting. - * @ATSPI_LOCALE_TYPE_NUMERIC: For number formatting (such as the decimal + * @ATSPI_LOCALE_TYPE_NUMERIC: For number formatting (such as the decimal * point and the thousands separator). * @ATSPI_LOCALE_TYPE_TIME: For time and date formatting. * @@@ -141,11 -141,6 +141,11 @@@ typedef enum ATSPI_COORD_TYPE_PARENT, } AtspiCoordType; +typedef enum { + ATSPI_NEIGHBOR_SEARCH_FORWARD = 1, + ATSPI_NEIGHBOR_SEARCH_BACKWARD = 2, +} AtspiNeighborSearchDirection; + /** * ATSPI_COORD_TYPE_COUNT: * @@@ -257,9 -252,9 +257,9 @@@ typedef enum * UI #AtspiComponent containers. * @ATSPI_LAYER_WIDGET: The layer in which the majority of ordinary * 'foreground' widgets reside. - * @ATSPI_LAYER_MDI: A special layer between @ATSPI_LAYER_CANVAS and - * @ATSPI_LAYER_WIDGET, in which the 'pseudo windows' (e.g. the MDI frames) - * reside. See #atspi_component_get_mdi_z_order. + * @ATSPI_LAYER_MDI: A special layer between @ATSPI_LAYER_CANVAS and + * @ATSPI_LAYER_WIDGET, in which the 'pseudo windows' (e.g. the MDI frames) + * reside. See #atspi_component_get_mdi_z_order. * @ATSPI_LAYER_POPUP: A layer for popup window content, above * @ATSPI_LAYER_WIDGET. * @ATSPI_LAYER_OVERLAY: The topmost layer. @@@ -268,23 -263,23 +268,23 @@@ * @ATSPI_LAYER_LAST_DEFINED: Used only to determine the end of the * enumeration. * - * The #AtspiComponentLayer of an #AtspiComponent instance indicates its - * relative stacking order with respect to the onscreen visual representation - * of the UI. #AtspiComponentLayer, in combination with #AtspiComponent bounds - * information, can be used to compute the visibility of all or part of a - * component. This is important in programmatic determination of - * region-of-interest for magnification, and in + * The #AtspiComponentLayer of an #AtspiComponent instance indicates its + * relative stacking order with respect to the onscreen visual representation + * of the UI. #AtspiComponentLayer, in combination with #AtspiComponent bounds + * information, can be used to compute the visibility of all or part of a + * component. This is important in programmatic determination of + * region-of-interest for magnification, and in * flat screen review models of the screen, as well as - * for other uses. Objects residing in two of the #AtspiComponentLayer - * categories support further z-ordering information, with respect to their - * peers in the same layer: namely, @ATSPI_LAYER_WINDOW and - * @ATSPI_LAYER_MDI. Relative stacking order for other objects within the - * same layer is not available; the recommended heuristic is - * first child paints first. In other words, assume that the - * first siblings in the child list are subject to being overpainted by later + * for other uses. Objects residing in two of the #AtspiComponentLayer + * categories support further z-ordering information, with respect to their + * peers in the same layer: namely, @ATSPI_LAYER_WINDOW and + * @ATSPI_LAYER_MDI. Relative stacking order for other objects within the + * same layer is not available; the recommended heuristic is + * first child paints first. In other words, assume that the + * first siblings in the child list are subject to being overpainted by later * siblings if their bounds intersect. The order of layers, from bottom to top, * is: @ATSPI_LAYER_BACKGROUND, @ATSPI_LAYER_WINDOW, @ATSPI_LAYER_MDI, - * @ATSPI_LAYER_CANVAS, @ATSPI_LAYER_WIDGET, @ATSPI_LAYER_POPUP, and + * @ATSPI_LAYER_CANVAS, @ATSPI_LAYER_WIDGET, @ATSPI_LAYER_POPUP, and * @ATSPI_LAYER_OVERLAY. * */ @@@ -309,15 -304,15 +309,15 @@@ typedef enum /** * AtspiTextBoundaryType: - * @ATSPI_TEXT_BOUNDARY_CHAR: An #AtspiText instance is bounded by this - * character only. Start and end offsets differ by one, by definition, + * @ATSPI_TEXT_BOUNDARY_CHAR: An #AtspiText instance is bounded by this + * character only. Start and end offsets differ by one, by definition, * for this value. * @ATSPI_TEXT_BOUNDARY_WORD_START: Boundary condition is start of a word; i.e. * range is from start of one word to the start of another word. * @ATSPI_TEXT_BOUNDARY_WORD_END: Boundary condition is the end of a word; i.e. * range is from the end of one word to the end of another. Some locales * may not distinguish between words and characters or glyphs. In particular, - * those locales which use wholly or partially ideographic character sets. + * those locales which use wholly or partially ideographic character sets. * In these cases, characters may be returned in lieu of multi-character * substrings. * @ATSPI_TEXT_BOUNDARY_SENTENCE_START: Boundary condition is start of a @@@ -336,7 -331,7 +336,7 @@@ * generally means that an end-of-line character will appear at the end of * the range. * @ATSPI_TEXT_BOUNDARY_LINE_END: Boundary condition is the end of a line; i.e. - * range is from start of one line to the start of another. This generally + * range is from start of one line to the start of another. This generally * means that an end-of-line character will be the first character of the * range. * @@@ -422,7 -417,7 +422,7 @@@ typedef enum /** * AtspiStateType: - * @ATSPI_STATE_INVALID: Indicates an invalid state - probably an error + * @ATSPI_STATE_INVALID: Indicates an invalid state - probably an error * condition. * @ATSPI_STATE_ACTIVE: Indicates a window is currently the active window, or * an object is the active subelement within a container or table. @@@ -445,7 -440,7 +445,7 @@@ * @ATSPI_STATE_ENABLED: Indicates that this object is enabled, i.e. that it * currently reflects some application state. Objects that are "greyed out" * may lack this state, and may lack the @ATSPI_STATE_SENSITIVE if direct - * user interaction cannot cause them to acquire @ATSPI_STATE_ENABLED. + * user interaction cannot cause them to acquire @ATSPI_STATE_ENABLED. * See @ATSPI_STATE_SENSITIVE. * @ATSPI_STATE_EXPANDABLE: Indicates this object allows progressive * disclosure of its children. @@@ -482,10 -477,10 +482,10 @@@ * children that has been selected. * @ATSPI_STATE_SENSITIVE: Indicates this object is sensitive, e.g. to user * interaction. @ATSPI_STATE_SENSITIVE usually accompanies. - * @ATSPI_STATE_ENABLED for user-actionable controls, but may be found in the - * absence of @ATSPI_STATE_ENABLED if the current visible state of the control + * @ATSPI_STATE_ENABLED for user-actionable controls, but may be found in the + * absence of @ATSPI_STATE_ENABLED if the current visible state of the control * is "disconnected" from the application state. In such cases, direct user - * interaction can often result in the object gaining @ATSPI_STATE_SENSITIVE, + * interaction can often result in the object gaining @ATSPI_STATE_SENSITIVE, * for instance if a user makes an explicit selection using an object whose * current state is ambiguous or undefined. See @ATSPI_STATE_ENABLED, * @ATSPI_STATE_INDETERMINATE. @@@ -497,19 -492,19 +497,19 @@@ * single line of text. * @ATSPI_STATE_STALE: Indicates that the information returned for this object * may no longer be synchronized with the application state. This can occur - * if the object has @ATSPI_STATE_TRANSIENT, and can also occur towards the + * if the object has @ATSPI_STATE_TRANSIENT, and can also occur towards the * end of the object peer's lifecycle. * @ATSPI_STATE_TRANSIENT: Indicates this object is transient. * @ATSPI_STATE_VERTICAL: Indicates the orientation of this object is vertical; * for example this state may appear on such objects as scrollbars, text * objects (with vertical text flow), separators, etc. * @ATSPI_STATE_VISIBLE: Indicates this object is visible, e.g. has been - * explicitly marked for exposure to the user. @ATSPI_STATE_VISIBLE is no - * guarantee that the object is actually unobscured on the screen, only that - * it is 'potentially' visible, barring obstruction, being scrolled or clipped - * out of the field of view, or having an ancestor container that has not yet - * made visible. A widget is potentially onscreen if it has both - * @ATSPI_STATE_VISIBLE and @ATSPI_STATE_SHOWING. The absence of + * explicitly marked for exposure to the user. @ATSPI_STATE_VISIBLE is no + * guarantee that the object is actually unobscured on the screen, only that + * it is 'potentially' visible, barring obstruction, being scrolled or clipped + * out of the field of view, or having an ancestor container that has not yet + * made visible. A widget is potentially onscreen if it has both + * @ATSPI_STATE_VISIBLE and @ATSPI_STATE_SHOWING. The absence of * @ATSPI_STATE_VISIBLE and @ATSPI_STATE_SHOWING is * semantically equivalent to saying that an object is 'hidden'. * @ATSPI_STATE_MANAGES_DESCENDANTS: Indicates that "active-descendant-changed" @@@ -518,14 -513,14 +518,14 @@@ * in very large containers, like tables. The presence of * @ATSPI_STATE_MANAGES_DESCENDANTS is an indication to the client that the * children should not, and need not, be enumerated by the client. - * Objects implementing this state are expected to provide relevant state - * notifications to listening clients, for instance notifications of - * visibility changes and activation of their contained child objects, without + * Objects implementing this state are expected to provide relevant state + * notifications to listening clients, for instance notifications of + * visibility changes and activation of their contained child objects, without * the client having previously requested references to those children. * @ATSPI_STATE_INDETERMINATE: Indicates that a check box or other boolean * indicator is in a state other than checked or not checked. This * usually means that the boolean value reflected or controlled by the - * object does not apply consistently to the entire current context. + * object does not apply consistently to the entire current context. * For example, a checkbox for the "Bold" attribute of text may have * @ATSPI_STATE_INDETERMINATE if the currently selected text contains a mixture * of weight attributes. In many cases interacting with a @@@ -544,13 -539,13 +544,13 @@@ * representation becomes static. Some applications, notably content viewers, * may not be able to detect all kinds of animated content. Therefore the * absence of this state should not be taken as - * definitive evidence that the object's visual representation is + * definitive evidence that the object's visual representation is * static; this state is advisory. * @ATSPI_STATE_INVALID_ENTRY: This object has indicated an error condition * due to failure of input validation. For instance, a form control may * acquire this state in response to invalid or malformed user input. * @ATSPI_STATE_SUPPORTS_AUTOCOMPLETION: This state indicates that the object - * in question implements some form of typeahead or + * in question implements some form of typeahead or * pre-selection behavior whereby entering the first character of one or more * sub-elements causes those elements to scroll into view or become * selected. Subsequent character input may narrow the selection further as @@@ -563,7 -558,7 +563,7 @@@ * question supports text selection. It should only be exposed on objects * which implement the #AtspiText interface, in order to distinguish this state * from @ATSPI_STATE_SELECTABLE, which infers that the object in question is a - * selectable child of an object which implements #AtspiSelection. While + * selectable child of an object which implements #AtspiSelection. While * similar, text selection and subelement selection are distinct operations. * @ATSPI_STATE_IS_DEFAULT: This state indicates that the object in question is * the 'default' interaction object in a dialog, i.e. the one that gets @@@ -583,18 -578,12 +583,18 @@@ * @ATSPI_STATE_READ_ONLY: Indicates that an object which is ENABLED and * SENSITIVE has a value which can be read, but not modified, by the * user. @Since: 2.16 + * @ATSPI_STATE_HIGHLIGHTED: Indicates that an object which is HIGHLIGHTABLE + * has been graphically marked to assits visally impared users. Only one + * object per window can have ATSPI_STATE_HIGHLIGHTED state. + * @ATSPI_STATE_HIGHLIGHTABLE: Indicates that an object can be graphically + * marked to assist visially impaired users. + * user. @Since: 2.16 * @ATSPI_STATE_LAST_DEFINED: This value of the enumeration should not be used * as a parameter, it indicates the number of items in the #AtspiStateType * enumeration. * - * - * Enumeration used by various interfaces indicating every possible state + * + * Enumeration used by various interfaces indicating every possible state * an #AtspiAccesible object can assume. * **/ @@@ -643,8 -632,6 +643,8 @@@ typedef enum ATSPI_STATE_CHECKABLE, ATSPI_STATE_HAS_POPUP, ATSPI_STATE_READ_ONLY, + ATSPI_STATE_HIGHLIGHTED, + ATSPI_STATE_HIGHLIGHTABLE, ATSPI_STATE_LAST_DEFINED, } AtspiStateType; @@@ -677,18 -664,18 +677,18 @@@ typedef enum /** * AtspiEventType: - * @ATSPI_KEY_PRESSED_EVENT: Indicates that a key on a keyboard device was + * @ATSPI_KEY_PRESSED_EVENT: Indicates that a key on a keyboard device was * pressed. - * @ATSPI_KEY_RELEASED_EVENT: Indicates that a key on a keyboard device was + * @ATSPI_KEY_RELEASED_EVENT: Indicates that a key on a keyboard device was * released. - * @ATSPI_BUTTON_PRESSED_EVENT: Indicates that a button on a non-keyboard + * @ATSPI_BUTTON_PRESSED_EVENT: Indicates that a button on a non-keyboard * human interface device (HID) was pressed. * @ATSPI_BUTTON_RELEASED_EVENT: Indicates that a button on a non-keyboard * human interface device (HID) was released. * - * Enumeration used to specify the event types of interest to an - * #AtspiEventListener, or - * to identify the type of an event for which notification has been sent. + * Enumeration used to specify the event types of interest to an + * #AtspiEventListener, or + * to identify the type of an event for which notification has been sent. * **/ typedef enum { @@@ -713,14 -700,14 +713,14 @@@ * of a hardware keyboard key. * @ATSPI_KEY_SYM: A symbolic key event is generated, without specifying a * hardware key. Note: if the keysym is not present in the current keyboard - * map, the #AtspiDeviceEventController instance has a limited ability to - * generate such keysyms on-the-fly. Reliability of GenerateKeyboardEvent - * calls using out-of-keymap keysyms will vary from system to system, and on + * map, the #AtspiDeviceEventController instance has a limited ability to + * generate such keysyms on-the-fly. Reliability of GenerateKeyboardEvent + * calls using out-of-keymap keysyms will vary from system to system, and on * the number of different out-of-keymap keysyms being generated in quick - * succession. - * In practice this is rarely significant, since the keysyms of interest to - * AT clients and keyboard emulators are usually part of the current keymap, - * i.e., present on the system keyboard for the current locale (even if a + * succession. + * In practice this is rarely significant, since the keysyms of interest to + * AT clients and keyboard emulators are usually part of the current keymap, + * i.e., present on the system keyboard for the current locale (even if a * physical hardware keyboard is not connected). * @ATSPI_KEY_STRING: A string is converted to its equivalent keyboard events * and emitted. If the string consists of complex characters or composed @@@ -801,7 -788,7 +801,7 @@@ typedef enum * modifies the state, onscreen location, or other attributes of one or more * target objects. * @ATSPI_RELATION_CONTROLLED_BY: Object state, position, etc. is - * modified/controlled by user interaction with one or more other objects. + * modified/controlled by user interaction with one or more other objects. * For instance a viewport or scroll pane may be @ATSPI_RELATION_CONTROLLED_BY * scrollbars. * @ATSPI_RELATION_MEMBER_OF: Object has a grouping relationship (e.g. 'same @@@ -817,10 -804,10 +817,10 @@@ * object which is not the 'next sibling' in the accessibility hierarchy. * @ATSPI_RELATION_FLOWS_FROM: Reciprocal of @ATSPI_RELATION_FLOWS_TO. * @ATSPI_RELATION_SUBWINDOW_OF: Object is visually and semantically considered - * a subwindow of another object, even though it is not the object's child. + * a subwindow of another object, even though it is not the object's child. * Useful when dealing with embedded applications and other cases where the * widget hierarchy does not map cleanly to the onscreen presentation. - * @ATSPI_RELATION_EMBEDS: Similar to @ATSPI_RELATION_SUBWINDOW_OF, but + * @ATSPI_RELATION_EMBEDS: Similar to @ATSPI_RELATION_SUBWINDOW_OF, but * specifically used for cross-process embedding. * @ATSPI_RELATION_EMBEDDED_BY: Reciprocal of @ATSPI_RELATION_EMBEDS. Used to * denote content rendered by embedded renderers that live in a separate process @@@ -828,9 -815,9 +828,9 @@@ * @ATSPI_RELATION_POPUP_FOR: Denotes that the object is a transient window or * frame associated with another onscreen object. Similar to @ATSPI_TOOLTIP_FOR, * but more general. Useful for windows which are technically toplevels - * but which, for one or more reasons, do not explicitly cause their + * but which, for one or more reasons, do not explicitly cause their * associated window to lose 'window focus'. Creation of an @ATSPI_ROLE_WINDOW - * object with the @ATSPI_RELATION_POPUP_FOR relation usually requires + * object with the @ATSPI_RELATION_POPUP_FOR relation usually requires * some presentation action on the part * of assistive technology clients, even though the previous toplevel * @ATSPI_ROLE_FRAME object may still be the active window. @@@ -872,17 -859,17 +872,17 @@@ * Indicates that this object contains an error message describing an invalid * condition in the target object(s). @Since: 2.26. * @ATSPI_RELATION_LAST_DEFINED: Do not use as a parameter value, used to - * determine the size of the enumeration. + * determine the size of the enumeration. * - * #AtspiRelationType specifies a relationship between objects + * #AtspiRelationType specifies a relationship between objects * (possibly one-to-many * or many-to-one) outside of the normal parent/child hierarchical * relationship. It allows better semantic identification of how objects - * are associated with one another. For instance the + * are associated with one another. For instance the * @ATSPI_RELATION_LABELLED_BY * relationship may be used to identify labelling information that should * accompany the accessible name property when presenting an object's content or - * identity to the end user. Similarly, + * identity to the end user. Similarly, * @ATSPI_RELATION_CONTROLLER_FOR can be used * to further specify the context in which a valuator is useful, and/or the * other UI components which are directly effected by user interactions with @@@ -971,7 -958,7 +971,7 @@@ typedef enum * etc. * @ATSPI_ROLE_GLASS_PANE: A pane that is guaranteed to be painted on top of * all panes beneath it. - * @ATSPI_ROLE_HTML_CONTAINER: A document container for HTML, whose children + * @ATSPI_ROLE_HTML_CONTAINER: A document container for HTML, whose children * represent the document content. * @ATSPI_ROLE_ICON: A small fixed size picture, typically used to decorate * components. @@@ -1022,7 -1009,7 +1022,7 @@@ * @ATSPI_ROLE_SCROLL_PANE: An object that allows a user to incrementally view * a large amount of information. @ATSPI_ROLE_SCROLL_PANE objects are usually * accompanied by @ATSPI_ROLE_SCROLL_BAR controllers, on which the - * @ATSPI_RELATION_CONTROLLER_FOR and @ATSPI_RELATION_CONTROLLED_BY + * @ATSPI_RELATION_CONTROLLER_FOR and @ATSPI_RELATION_CONTROLLED_BY * reciprocal relations are set. See #atspi_get_relation_set. * @ATSPI_ROLE_SEPARATOR: An object usually contained in a menu to provide a * visible and logical separation of the contents in a menu. @@@ -1030,7 -1017,7 +1030,7 @@@ * range. * @ATSPI_ROLE_SPIN_BUTTON: An object which allows one of a set of choices to * be selected, and which displays the current choice. Unlike - * @ATSPI_ROLE_SCROLL_BAR, @ATSPI_ROLE_SLIDER objects need not control + * @ATSPI_ROLE_SCROLL_BAR, @ATSPI_ROLE_SLIDER objects need not control * 'viewport'-like objects. * @ATSPI_ROLE_SPLIT_PANE: A specialized panel that presents two other panels * at the same time. @@@ -1039,7 -1026,7 +1039,7 @@@ * @ATSPI_ROLE_TABLE: An object used to repesent information in terms of rows * and columns. * @ATSPI_ROLE_TABLE_CELL: A 'cell' or discrete child within a Table. Note: - * Table cells need not have @ATSPI_ROLE_TABLE_CELL, other + * Table cells need not have @ATSPI_ROLE_TABLE_CELL, other * #AtspiRoleType values are valid as well. * @ATSPI_ROLE_TABLE_COLUMN_HEADER: An object which labels a particular column * in an #AtspiTable. @@@ -1068,7 -1055,7 +1068,7 @@@ * user. * @ATSPI_ROLE_TREE_TABLE: An object that presents both tabular and * hierarchical info to the user. - * @ATSPI_ROLE_UNKNOWN: The object contains some #AtspiAccessible information, + * @ATSPI_ROLE_UNKNOWN: The object contains some #AtspiAccessible information, * but its role is not known. * @ATSPI_ROLE_VIEWPORT: An object usually used in a scroll pane, or to * otherwise clip a larger object or content renderer to a specific @@@ -1080,11 -1067,11 +1080,11 @@@ * @ATSPI_ROLE_FOOTER: An object that serves as a document footer. * @ATSPI_ROLE_PARAGRAPH: An object which is contains a single paragraph of * text content. See also @ATSPI_ROLE_TEXT. - * @ATSPI_ROLE_RULER: An object which describes margins and tab stops, etc. - * for text objects which it controls (should have + * @ATSPI_ROLE_RULER: An object which describes margins and tab stops, etc. + * for text objects which it controls (should have * @ATSPI_RELATION_CONTROLLER_FOR relation to such). * @ATSPI_ROLE_APPLICATION: An object corresponding to the toplevel accessible - * of an application, which may contain @ATSPI_ROLE_FRAME objects or other + * of an application, which may contain @ATSPI_ROLE_FRAME objects or other * accessible objects. Children of #AccessibleDesktop objects are generally * @ATSPI_ROLE_APPLICATION objects. * @ATSPI_ROLE_AUTOCOMPLETE: The object is a dialog or list containing items @@@ -1098,13 -1085,13 +1098,13 @@@ * and for embedding of out-of-process component, "panel applets", etc. * @ATSPI_ROLE_ENTRY: The object is a component whose textual content may be * entered or modified by the user, provided @ATSPI_STATE_EDITABLE is present. - * A readonly @ATSPI_ROLE_ENTRY object (i.e. where @ATSPI_STATE_EDITABLE is - * not present) implies a read-only 'text field' in a form, as opposed to a + * A readonly @ATSPI_ROLE_ENTRY object (i.e. where @ATSPI_STATE_EDITABLE is + * not present) implies a read-only 'text field' in a form, as opposed to a * title, label, or caption. * @ATSPI_ROLE_CHART: The object is a graphical depiction of quantitative data. * It may contain multiple subelements whose attributes and/or description * may be queried to obtain both the quantitative data and information about - * how the data is being presented. The @ATSPI_LABELLED_BY relation is + * how the data is being presented. The @ATSPI_LABELLED_BY relation is * particularly important in interpreting objects of this type, as is the * accessible description property. See @ATSPI_ROLE_CAPTION. * @ATSPI_ROLE_CAPTION: The object contains descriptive information, usually @@@ -1114,7 -1101,7 +1114,7 @@@ * contains a view of document content. #AtspiDocument frames may occur within * another #AtspiDocument instance, in which case the second document may be * said to be embedded in the containing instance. HTML frames are often - * ATSPI_ROLE_DOCUMENT_FRAME: Either this object, or a singleton descendant, + * ATSPI_ROLE_DOCUMENT_FRAME: Either this object, or a singleton descendant, * should implement the #AtspiDocument interface. * @ATSPI_ROLE_HEADING: The object serves as a heading for content which * follows it in a document. The 'heading level' of the heading, if @@@ -1132,22 -1119,22 +1132,22 @@@ * this role should be ignored by clients, if they are encountered at all. * @ATSPI_ROLE_FORM: The object is a containing instance of document content * which has within it components with which the user can interact in order - * to input information; i.e. the object is a container for pushbuttons, + * to input information; i.e. the object is a container for pushbuttons, * comboboxes, text input fields, and other 'GUI' components. @ATSPI_ROLE_FORM * should not, in general, be used for toplevel GUI containers or dialogs, * but should be reserved for 'GUI' containers which occur within document * content, for instance within Web documents, presentations, or text - * documents. Unlike other GUI containers and dialogs which occur inside + * documents. Unlike other GUI containers and dialogs which occur inside * application instances, @ATSPI_ROLE_FORM containers' components are - * associated with the current document, rather than the current foreground + * associated with the current document, rather than the current foreground * application or viewer instance. - * @ATSPI_ROLE_LINK: The object is a hypertext anchor, i.e. a "link" in a + * @ATSPI_ROLE_LINK: The object is a hypertext anchor, i.e. a "link" in a * hypertext document. Such objects are distinct from 'inline' content * which may also use the #AtspiHypertext/#AtspiHyperlink interfacesto indicate * the range/location within a text object where an inline or embedded object * lies. * @ATSPI_ROLE_INPUT_METHOD_WINDOW: The object is a window or similar viewport - * which is used to allow composition or input of a 'complex character', + * which is used to allow composition or input of a 'complex character', * in other words it is an "input method window". * @ATSPI_ROLE_TABLE_ROW: A row in a table. * @ATSPI_ROLE_TREE_ITEM: An object that represents an element of a tree. @@@ -1247,6 -1234,12 +1247,12 @@@ * @ATSPI_ROLE_DESCRIPTION_VALUE: An object that represents the description, * definition, or value of a term. @Since: 2.26. * @ATSPI_ROLE_FOOTNOTE: An object that contains the text of a footnote. @Since: 2.26. + * @ATSPI_ROLE_CONTENT_DELETION: Content previously deleted or proposed to be + * deleted, e.g. in revision history or a content view providing suggestions + * from reviewers. @Since: 2.34. + * @ATSPI_ROLE_CONTENT_INSERTION: Content previously inserted or proposed to be + * inserted, e.g. in revision history or a content view providing suggestions + * from reviewers. @Since: 2.34. * @ATSPI_ROLE_LAST_DEFINED: Not a valid role, used for finding end of * enumeration. * @@@ -1380,6 -1373,8 +1386,8 @@@ typedef enum ATSPI_ROLE_DESCRIPTION_TERM, ATSPI_ROLE_DESCRIPTION_VALUE, ATSPI_ROLE_FOOTNOTE, + ATSPI_ROLE_CONTENT_DELETION, + ATSPI_ROLE_CONTENT_INSERTION, ATSPI_ROLE_LAST_DEFINED, } AtspiRole; @@@ -1388,28 -1383,8 +1396,28 @@@ * * One higher than the highest valid value of #AtspiRole. */ - #define ATSPI_ROLE_COUNT (125+1) + #define ATSPI_ROLE_COUNT (127+1) +/** + * AtspiMoveOutedType: The type of signal that occurs when an object outted the screen. + * @ATSPI_MOVE_OUTED_TOP_LEFT: Object has outted top or left of the screen. + * @ATSPI_MOVE_OUTED_BOTTOM_RIGHT: Object has outted bottom or right of the screen. + **/ + +typedef enum { + ATSPI_MOVE_OUTED_NULL, + ATSPI_MOVE_OUTED_TOP_LEFT, + ATSPI_MOVE_OUTED_BOTTOM_RIGHT, + ATSPI_MOVE_OUTED_LAST_DEFINDED +} AtspiMoveOutedType; + +/** + * ATSPI_MOVE_OUTED_COUNT: + * + * One higher than the highest valid value of #AtspiScreenOuttedType. + **/ +#define ATSPI_MOVE_OUTED_COUNT (3+1) + typedef enum { ATSPI_CACHE_NONE = 0, @@@ -1495,6 -1470,9 +1503,9 @@@ typedef enum #define ATSPI_DBUS_INTERFACE_VALUE "org.a11y.atspi.Value" #define ATSPI_DBUS_INTERFACE_SOCKET "org.a11y.atspi.Socket" + #define ATSPI_DBUS_PATH_SCREEN_READER "/org/a11y/atspi/screenreader" + #define ATSPI_DBUS_INTERFACE_EVENT_SCREEN_READER "org.a11y.atspi.Event.ScreenReader" + #ifdef __cplusplus } #endif diff --combined atspi/atspi-event-listener.c index 065b4a0,249890b..6bab4c8 --- a/atspi/atspi-event-listener.c +++ b/atspi/atspi-event-listener.c @@@ -7,24 -7,25 +7,25 @@@ * 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 + #include #include typedef struct @@@ -169,12 -170,15 +170,15 @@@ static GList *event_listeners = NULL static gchar * convert_name_from_dbus (const char *name, gboolean path_hack) { - gchar *ret = g_malloc (g_utf8_strlen (name, -1) * 2 + 1); + gchar *ret; const char *p = name; - gchar *q = ret; + gchar *q; - if (!ret) - return NULL; + if (!name) + return g_strdup (""); + + ret = g_malloc (g_utf8_strlen (name, -1) * 2 + 1); + q = ret; while (*p) { @@@ -378,14 -382,14 +382,14 @@@ convert_event_type_to_dbus (const char if (matchrule_array) { gchar *matchrule; + (*matchrule_array) = g_ptr_array_new (); matchrule = g_strdup_printf ("type='signal',interface='org.a11y.atspi.Event.%s'", category); if (name && name [0]) { - gchar *new_str = g_strconcat (matchrule, ",member='", name, "'", NULL); - g_free (matchrule); - matchrule = new_str; + gchar *new_str = g_strconcat (matchrule, ",member='", name, "'", NULL); + g_free (matchrule); + matchrule = new_str; } - (*matchrule_array) = g_ptr_array_new (); if (detail && detail [0]) { gchar *new_str = g_strconcat (matchrule, ",arg0='", detail, "'", NULL); @@@ -467,6 -471,9 +471,9 @@@ listener_entry_free (EventListenerEntr * object:model-changed * object:active-descendant-changed * + * (screen reader events) + * screen-reader:region-changed + * * (window events) * * window:minimize @@@ -506,6 -513,9 +513,9 @@@ * In general, listening to * toolkit-specific events is not recommended. * + * Currently, object:text-reading-position needs to be specified explicitly + * (it is not implied by object:text), since it is generated by the screen + * reader and is thus a special case internally. * * Returns: #TRUE if successful, otherwise #FALSE. **/ @@@ -786,16 -796,15 +796,16 @@@ atspi_event_listener_deregister_from_ca GPtrArray *matchrule_array; gint i; GList *l; + gboolean result = TRUE; + if (!callback) + { + return FALSE; + } if (!convert_event_type_to_dbus (event_type, &category, &name, &detail, &matchrule_array)) { return FALSE; } - if (!callback) - { - return FALSE; - } for (l = event_listeners; l;) { @@@ -821,10 -830,8 +831,10 @@@ atspi_path_registry, atspi_interface_registry, "DeregisterEvent"); - if (!message) - return FALSE; + if (!message) { + result = FALSE; + break; + } dbus_message_append_args (message, DBUS_TYPE_STRING, &event_type, DBUS_TYPE_INVALID); reply = _atspi_dbus_send_with_reply_and_block (message, error); if (reply) @@@ -840,7 -847,7 +850,7 @@@ for (i = 0; i < matchrule_array->len; i++) g_free (g_ptr_array_index (matchrule_array, i)); g_ptr_array_free (matchrule_array, TRUE); - return TRUE; + return result; } /** @@@ -875,6 -882,7 +885,7 @@@ atspi_event_copy (AtspiEvent *src dst->detail2 = src->detail2; g_value_init (&dst->any_data, G_VALUE_TYPE (&src->any_data)); g_value_copy (&src->any_data, &dst->any_data); + dst->sender = g_object_ref (src->sender); return dst; } @@@ -884,6 -892,7 +895,7 @@@ atspi_event_free (AtspiEvent *event g_object_unref (event->source); g_free (event->type); g_value_unset (&event->any_data); + g_object_unref (event->sender); g_free (event); } @@@ -894,7 -903,7 +906,7 @@@ detail_matches_listener (const char *ev return TRUE; if (!event_detail) - return (listener_detail ? FALSE : TRUE); + return FALSE; return !(listener_detail [strcspn (listener_detail, ":")] == '\0' ? strncmp (listener_detail, event_detail, @@@ -954,6 -963,7 +966,7 @@@ _atspi_dbus_handle_event (DBusConnectio { char *detail = NULL; const char *category = dbus_message_get_interface (message); + const char *sender = dbus_message_get_sender (message); const char *member = dbus_message_get_member (message); const char *signature = dbus_message_get_signature (message); gchar *name; @@@ -968,26 -978,22 +981,26 @@@ if (strcmp (signature, "siiv(so)") != 0 && strcmp (signature, "siiva{sv}") != 0) { - g_warning ("Got invalid signature %s for signal %s from interface %s\n", signature, member, category); + g_warning ("Got invalid signature %s for signal %s from interface %s\n", signature, member, category); return DBUS_HANDLER_RESULT_HANDLED; } memset (&e, 0, sizeof (e)); - if (category) + if (!category) { - category = g_utf8_strrchr (category, -1, '.'); - if (category == NULL) - { - // TODO: Error - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - category++; + // TODO: Error + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } + + category = g_utf8_strrchr (category, -1, '.'); + if (category == NULL) + { + // TODO: Error + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + category++; + dbus_message_iter_get_basic (&iter, &detail); dbus_message_iter_next (&iter); dbus_message_iter_get_basic (&iter, &detail1); @@@ -1021,14 -1027,17 +1034,17 @@@ converted_type = p; } e.type = converted_type; - e.source = _atspi_ref_accessible (dbus_message_get_sender(message), dbus_message_get_path(message)); - if (e.source == NULL) + if (strcmp (category, "ScreenReader") != 0) { - g_warning ("Got no valid source accessible for signal for signal %s from interface %s\n", member, category); - g_free (converted_type); - g_free (name); - g_free (detail); - return DBUS_HANDLER_RESULT_HANDLED; + e.source = _atspi_ref_accessible (sender, dbus_message_get_path (message)); + if (e.source == NULL) + { + g_warning ("Got no valid source accessible for signal %s from interface %s\n", member, category); + g_free (converted_type); + g_free (name); + g_free (detail); + return DBUS_HANDLER_RESULT_HANDLED; + } } dbus_message_iter_recurse (&iter, &iter_variant); @@@ -1039,17 -1048,24 +1055,24 @@@ AtspiRect rect; if (demarshal_rect (&iter_variant, &rect)) { - g_value_init (&e.any_data, ATSPI_TYPE_RECT); - g_value_set_boxed (&e.any_data, &rect); + g_value_init (&e.any_data, ATSPI_TYPE_RECT); + g_value_set_boxed (&e.any_data, &rect); } else { AtspiAccessible *accessible; - accessible = _atspi_dbus_return_accessible_from_iter (&iter_variant); - g_value_init (&e.any_data, ATSPI_TYPE_ACCESSIBLE); - g_value_set_instance (&e.any_data, accessible); - if (accessible) - g_object_unref (accessible); /* value now owns it */ + accessible = _atspi_dbus_return_accessible_from_iter (&iter_variant); + if (!strcmp (category, "ScreenReader")) + { + e.source = accessible; + } + else + { + g_value_init (&e.any_data, ATSPI_TYPE_ACCESSIBLE); + g_value_set_instance (&e.any_data, accessible); + if (accessible) + g_object_unref (accessible); /* value now owns it */ + } } break; } @@@ -1071,6 -1087,8 +1094,8 @@@ cache = _atspi_dbus_update_cache_from_dict (e.source, &iter); } + e.sender = _atspi_ref_accessible (sender, ATSPI_DBUS_PATH_ROOT); + if (!strncmp (e.type, "object:children-changed", 23)) { cache_process_children_changed (&e); diff --combined atspi/atspi-misc-private.h index 44b4dc6,f0b5adb..fb40277 --- a/atspi/atspi-misc-private.h +++ b/atspi/atspi-misc-private.h @@@ -5,22 -5,22 +5,22 @@@ * Copyright 2002 Ximian, Inc. * 2002 Sun Microsystems Inc. * 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. */ #ifndef _ATSPI_MISC_PRIVATE_H_ @@@ -166,6 -166,8 +166,8 @@@ gboolean _atspi_get_allow_sync () gboolean _atspi_set_allow_sync (gboolean val); void _atspi_set_error_no_sync (GError **error); + + gboolean _atspi_prepare_screen_reader_interface (); G_END_DECLS #endif /* _ATSPI_MISC_PRIVATE_H_ */ diff --combined atspi/atspi-misc.c index 7dacde2,9e8595a..a7efb66 --- a/atspi/atspi-misc.c +++ b/atspi/atspi-misc.c @@@ -7,19 -7,19 +7,19 @@@ * 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. */ /* @@@ -110,7 -110,7 +110,7 @@@ _atspi_get_iface_num (const char *iface GHashTable * _atspi_get_live_refs (void) { - if (!live_refs) + if (!live_refs) { live_refs = g_hash_table_new (g_direct_hash, g_direct_equal); } @@@ -159,7 -159,8 +159,8 @@@ cleanup ( for (i = desktop->children->len - 1; i >= 0; i--) { AtspiAccessible *child = g_ptr_array_index (desktop->children, i); - g_object_run_dispose (G_OBJECT (child->parent.app)); + if (child->parent.app) + g_object_run_dispose (G_OBJECT (child->parent.app)); g_object_run_dispose (G_OBJECT (child)); } @@@ -180,7 -181,6 +181,7 @@@ handle_get_bus_address (DBusPendingCal DBusMessage *message; const char *address; DBusPendingCall *new_pending; + dbus_bool_t result; if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN) { @@@ -219,9 -219,9 +220,9 @@@ "/org/a11y/atspi/cache", atspi_interface_cache, "GetItems"); - dbus_connection_send_with_reply (app->bus, message, &new_pending, 2000); + result = dbus_connection_send_with_reply (app->bus, message, &new_pending, 2000); dbus_message_unref (message); - if (!new_pending) + if (!result || !new_pending) return; dbus_pending_call_set_notify (new_pending, handle_get_items, app, NULL); } @@@ -233,7 -233,6 +234,7 @@@ get_application (const char *bus_name char *bus_name_dup; DBusMessage *message; DBusPendingCall *pending = NULL; + dbus_bool_t result; if (!app_hash) { @@@ -254,9 -253,9 +255,9 @@@ message = dbus_message_new_method_call (bus_name, atspi_path_root, atspi_interface_application, "GetApplicationBusAddress"); - dbus_connection_send_with_reply (app->bus, message, &pending, 2000); + result = dbus_connection_send_with_reply (app->bus, message, &pending, 2000); dbus_message_unref (message); - if (!pending) + if (!result || !pending) { g_hash_table_remove (app_hash, bus_name_dup); return NULL; @@@ -265,7 -264,7 +266,7 @@@ return app; } -static AtspiAccessible * +AtspiAccessible * ref_accessible (const char *app_name, const char *path) { AtspiApplication *app; @@@ -392,7 -391,7 +393,7 @@@ handle_name_owner_changed (DBusConnecti else if (app_hash) { AtspiApplication *app = g_hash_table_lookup (app_hash, old); - if (app && !strcmp (app->bus_name, old)) + if (app && app->bus_name && !strcmp(app->bus_name, name)) g_object_run_dispose (G_OBJECT (app)); } return DBUS_HANDLER_RESULT_HANDLED; @@@ -533,8 -532,9 +534,9 @@@ handle_get_items (DBusPendingCall *pend { const char *sender = dbus_message_get_sender (reply); const char *error = NULL; - if (!strcmp (dbus_message_get_error_name (reply), - DBUS_ERROR_SERVICE_UNKNOWN)) + const char *error_name = dbus_message_get_error_name (reply); + if (!strcmp (error_name, DBUS_ERROR_SERVICE_UNKNOWN) + || !strcmp (error_name, DBUS_ERROR_NO_REPLY)) { } else @@@ -674,7 -674,7 +676,7 @@@ _atspi_dbus_return_hyperlink_from_messa DBusMessageIter iter; AtspiHyperlink *retval = NULL; const char *signature; - + if (!message) return NULL; @@@ -889,7 -889,7 +891,7 @@@ spi_display_name (void * * Connects to the accessibility registry and initializes the SPI. * - * Returns: 0 on success, 1 if already initialized, or an integer error code. + * Returns: 0 on success, 1 if already initialized, or an integer error code. **/ int atspi_init (void) @@@ -909,8 -909,7 +911,8 @@@ bus = atspi_get_a11y_bus (); if (!bus) return 2; - dbus_bus_register (bus, NULL); + if (!dbus_bus_register (bus, NULL)) + return 2; atspi_dbus_connection_setup_with_g_main(bus, g_main_context_default()); dbus_connection_add_filter (bus, atspi_dbus_filter, NULL, NULL); match = g_strdup_printf ("type='signal',interface='%s',member='AddAccessible'", atspi_interface_cache); @@@ -987,7 -986,7 +989,7 @@@ atspi_event_quit (void /** * atspi_exit: * - * Disconnects from #AtspiRegistry instances and releases + * Disconnects from #AtspiRegistry instances and releases * any floating resources. Call only once at exit. * * Returns: 0 if there were no leaks, otherwise other integer values. @@@ -1038,7 -1037,6 +1040,7 @@@ check_for_hang (DBusMessage *message, D DBusMessage *message; gchar *bus_name_dup; DBusPendingCall *pending = NULL; + dbus_bool_t result; for (l = hung_processes; l; l = l->next) if (!strcmp (l->data, bus_name)) return; @@@ -1047,9 -1045,9 +1049,9 @@@ "Ping"); if (!message) return; - dbus_connection_send_with_reply (bus, message, &pending, -1); + result = dbus_connection_send_with_reply (bus, message, &pending, -1); dbus_message_unref (message); - if (!pending) + if (!result || !pending) return; bus_name_dup = g_strdup (bus_name); hung_processes = g_slist_append (hung_processes, bus_name_dup); @@@ -1146,11 -1144,9 +1148,11 @@@ _atspi_dbus_call_partial (gpointer obj const char *type, ...) { va_list args; - + DBusMessage * result; va_start (args, type); - return _atspi_dbus_call_partial_va (obj, interface, method, error, type, args); + result = _atspi_dbus_call_partial_va (obj, interface, method, error, type, args); + va_end (args); + return result; } @@@ -1164,9 -1160,9 +1166,9 @@@ _atspi_dbus_call_partial_va (gpointer o { AtspiObject *aobj = ATSPI_OBJECT (obj); DBusError err; - DBusMessage *msg = NULL, *reply = NULL; - DBusMessageIter iter; - const char *p; + DBusMessage *msg = NULL, *reply = NULL; + DBusMessageIter iter; + const char *p; dbus_error_init (&err); @@@ -1191,13 -1187,11 +1193,13 @@@ out process_deferred_messages (); if (dbus_error_is_set (&err)) { - /* TODO: Set gerror */ + g_set_error_literal(error, ATSPI_ERROR, ATSPI_ERROR_IPC, err.message); dbus_error_free (&err); + if (reply) + dbus_message_unref(reply); + return NULL; } - - if (reply && dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) + else if (reply && dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { const char *err_str = NULL; dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &err_str, DBUS_TYPE_INVALID); @@@ -1206,6 -1200,7 +1208,6 @@@ dbus_message_unref (reply); return NULL; } - return reply; } @@@ -1494,7 -1489,7 +1496,7 @@@ get_accessibility_bus_address_x11 (void g_warning ("Could not open X display"); return NULL; } - + AT_SPI_BUS = XInternAtom (bridge_display, "AT_SPI_BUS", False); XGetWindowProperty (bridge_display, XDefaultRootWindow (bridge_display), @@@ -1542,7 -1537,7 +1544,7 @@@ get_accessibility_bus_address_dbus (voi dbus_error_free (&error); goto out; } - + { const char *tmp_address; if (!dbus_message_get_args (reply, @@@ -1597,7 -1592,8 +1599,8 @@@ atspi_get_a11y_bus (void if (address_env != NULL && *address_env != 0) address = g_strdup (address_env); #ifdef HAVE_X11 - if (!address) + if (!address && g_getenv ("DISPLAY") != NULL && + g_getenv ("WAYLAND_DISPLAY") == NULL) address = get_accessibility_bus_address_x11 (); #endif if (!address) @@@ -1628,7 -1624,7 +1631,7 @@@ return NULL; } } - + /* Simulate a weak ref on the bus */ dbus_connection_set_data (a11y_bus, a11y_dbus_slot, a11y_bus, a11y_bus_free); @@@ -1828,7 -1824,7 +1831,7 @@@ _atspi_dbus_update_cache_from_dict (Ats g_value_set_boxed (val, &extents); } if (val) - g_hash_table_insert (cache, g_strdup (key), val); + g_hash_table_insert (cache, g_strdup (key), val); dbus_message_iter_next (&iter_dict); } @@@ -1856,3 -1852,50 +1859,50 @@@ _atspi_set_error_no_sync (GError **erro g_set_error_literal (error, ATSPI_ERROR, ATSPI_ERROR_SYNC_NOT_ALLOWED, _("Attempted synchronous call where prohibited")); } + + static const char *sr_introspection = "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + ""; + + static DBusHandlerResult + screen_reader_filter (DBusConnection *bus, DBusMessage *message, void *user_data) + { + if (dbus_message_is_method_call (message, DBUS_INTERFACE_INTROSPECTABLE, + "Introspect")) + { + DBusMessage *reply = dbus_message_new_method_return (message); + dbus_message_append_args (reply, DBUS_TYPE_STRING, &sr_introspection, + DBUS_TYPE_INVALID); + dbus_connection_send (bus, reply, NULL); + dbus_message_unref (reply); + return DBUS_HANDLER_RESULT_HANDLED; + } + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + gboolean + _atspi_prepare_screen_reader_interface () + { + static gint initialized = 0; + DBusConnection *a11y_bus = _atspi_bus (); + + if (initialized) + return (initialized > 0); + + if (dbus_bus_request_name (a11y_bus, "org.a11y.Atspi.ScreenReader", 0, NULL) < 0) + { + initialized = -1; + return FALSE; + } + + initialized = 1; + dbus_connection_add_filter (a11y_bus, screen_reader_filter, NULL, NULL); + return TRUE; + } diff --combined atspi/atspi-misc.h index e39d7b8,0461728..fe5f2a4 --- a/atspi/atspi-misc.h +++ b/atspi/atspi-misc.h @@@ -8,19 -8,19 +8,19 @@@ * * * 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. */ #ifndef _ATSPI_MISC_H_ @@@ -47,9 -47,6 +47,9 @@@ voi atspi_set_main_context (GMainContext *cnx); gchar * atspi_role_get_name (AtspiRole role); + +AtspiAccessible *ref_accessible(const char *app_name, const char *path); + G_END_DECLS #endif /* _ATSPI_MISC_H_ */ diff --combined atspi/atspi-registry.c index 07af2c5,c50ae20..a79f435 --- a/atspi/atspi-registry.c +++ b/atspi/atspi-registry.c @@@ -7,19 -7,19 +7,19 @@@ * Copyright 2001, 2002 Ximian, 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. */ /* atspi_registry.c: Global functions wrapping the registry */ @@@ -270,7 -270,7 +270,7 @@@ atspi_deregister_keystroke_listener (At GError **error) { GArray *d_key_set; - gchar *path = _atspi_device_listener_get_path (listener); + gchar *path; gint i; dbus_uint32_t d_modmask = modmask; dbus_uint32_t d_event_types = event_types; @@@ -282,7 -282,6 +282,7 @@@ { return FALSE; } + path = _atspi_device_listener_get_path (listener); /* copy the keyval filter values from the C api into the DBind KeySet */ if (key_set) @@@ -364,7 -363,7 +364,7 @@@ atspi_register_device_event_listener (A { gboolean retval = FALSE; dbus_uint32_t d_event_types = event_types; - gchar *path = _atspi_device_listener_get_path (listener); + gchar *path; DBusError d_error; dbus_error_init (&d_error); @@@ -372,7 -371,6 +372,7 @@@ { return retval; } + path = _atspi_device_listener_get_path (listener); dbind_method_call_reentrant (_atspi_bus(), atspi_bus_registry, atspi_path_dec, atspi_interface_dec, "RegisterDeviceEventListener", &d_error, "ou=>b", path, d_event_types, &retval); if (dbus_error_is_set (&d_error)) @@@ -402,7 -400,7 +402,7 @@@ atspi_deregister_device_event_listener void *filter, GError **error) { dbus_uint32_t event_types = 0; - gchar *path = _atspi_device_listener_get_path (listener); + gchar *path; DBusError d_error; dbus_error_init (&d_error); @@@ -411,7 -409,6 +411,7 @@@ { return FALSE; } + path = _atspi_device_listener_get_path (listener); event_types |= (1 << ATSPI_BUTTON_PRESSED_EVENT); event_types |= (1 << ATSPI_BUTTON_RELEASED_EVENT); @@@ -427,6 -424,12 +427,12 @@@ return TRUE; } + static gboolean + using_mutter () + { + return (g_getenv ("WAYLAND_DISPLAY") != NULL); + } + /** * atspi_generate_keyboard_event: * @keyval: a #gint indicating the keycode or keysym or modifier mask of the @@@ -459,6 -462,12 +465,12 @@@ atspi_generate_keyboard_event (glong ke dbus_int32_t d_keyval = keyval; DBusError d_error; + if (using_mutter ()) + { + if (_atspi_mutter_generate_keyboard_event (keyval, keystring, synth_type, error)) + return TRUE; + } + dbus_error_init (&d_error); if (!keystring) keystring = ""; @@@ -495,6 -504,14 +507,14 @@@ atspi_generate_mouse_event (glong x, gl dbus_int32_t d_x = x, d_y = y; DBusError d_error; + g_return_val_if_fail (name != NULL, FALSE); + + if (using_mutter ()) + { + if (_atspi_mutter_generate_mouse_event (x, y, name, error)) + return TRUE; + } + dbus_error_init (&d_error); dbind_method_call_reentrant (_atspi_bus(), atspi_bus_registry, atspi_path_dec, atspi_interface_dec, @@@ -509,6 -526,27 +529,27 @@@ return TRUE; } + /** + * atspi_set_reference_window: + * + * @accessible: the #AtspiAccessible corresponding to the window to select. + * should be a top-level window with a role of + * ATSPI_ROLE_APPLICATION. + * + * Sets the reference window that will be used when atspi_generate_mouse_event + * is called. Coordinates will be assumed to be relative to this window. This + * is needed because, due to Wayland's security model, it is not currently + * possible to retrieve global coordinates. + * If NULL is passed, then AT-SPI will use the window that has focus at the + * time that atspi_generate_mouse_event is called. + */ + void + atspi_set_reference_window (AtspiAccessible *accessible) + { + if (using_mutter ()) + _atspi_mutter_set_reference_window (accessible); + } + AtspiKeyDefinition * atspi_key_definition_copy (AtspiKeyDefinition *src) { diff --combined atspi/atspi-stateset.c index 3a53a8c,dd99d91..c7e1fe2 --- a/atspi/atspi-stateset.c +++ b/atspi/atspi-stateset.c @@@ -7,19 -7,19 +7,19 @@@ * 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" @@@ -101,7 -101,6 +101,7 @@@ atspi_state_set_set_by_name (AtspiState if (!value) { g_warning ("AT-SPI: Attempt to set unknown state '%s'", name); + return; } else if (enabled) diff --combined atspi/atspi-types.h index d09a972,2631baf..7b85556 --- a/atspi/atspi-types.h +++ b/atspi/atspi-types.h @@@ -7,19 -7,19 +7,19 @@@ * * * 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. */ #ifndef _ATSPI_TYPES_H_ @@@ -43,8 -43,6 +43,8 @@@ typedef struct _AtspiTable AtspiTable typedef struct _AtspiTableCell AtspiTableCell; typedef struct _AtspiText AtspiText; typedef struct _AtspiValue AtspiValue; +typedef struct _AtspiAccessibleReadingMaterial AtspiAccessibleReadingMaterial; +typedef struct _AtspiAccessibleDefaultLabelInfo AtspiAccessibleDefaultLabelInfo; typedef guint AtspiControllerEventMask; @@@ -91,6 -89,7 +91,7 @@@ struct _AtspiEven gint detail1; gint detail2; GValue any_data; + AtspiAccessible *sender; }; /** diff --combined bus/at-spi-bus-launcher.c index 91bdd48,b4f49b8..afd4edb --- a/bus/at-spi-bus-launcher.c +++ b/bus/at-spi-bus-launcher.c @@@ -1,23 -1,23 +1,23 @@@ /* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- - * - * at-spi-bus-launcher: Manage the a11y bus as a child process + * + * at-spi-bus-launcher: Manage the a11y bus as a child process * * Copyright 2011-2018 Red Hat, 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 "config.h" @@@ -40,44 -40,6 +40,44 @@@ #include #endif +//TODO: move to vconf/vconf-internal-setting-keys.h? +#define VCONFKEY_SETAPPL_ACCESSIBILITY_UNIVERSAL_SWITCH_CONFIGURATION_SERVICE "db/setting/accessibility/universal-switch/configuration-service" +#define VCONFKEY_SETAPPL_ACCESSIBILITY_UNIVERSAL_SWITCH_INTERACTION_SERVICE "db/setting/accessibility/universal-switch/interaction-service" + +#define MAX_NUMBER_OF_KEYS_PER_CLIENT 2 + +#define APP_CONTROL_OPERATION_SCREEN_READ "http://tizen.org/appcontrol/operation/read_screen" +#define APP_CONTROL_OPERATION_UNIVERSAL_SWITCH "http://tizen.org/appcontrol/operation/universal_switch" +#include +#include + +//uncomment if you want debug +//#ifndef TIZEN_ENGINEER_MODE +//#define TIZEN_ENGINEER_MODE +//#endif +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "ATSPI_BUS_LAUNCHER" + +#include +#include + +//uncomment this if you want log suring startup +//seems like dlog is not working at startup time +#define ATSPI_BUS_LAUNCHER_LOG_TO_FILE + +#ifdef ATSPI_BUS_LAUNCHER_LOG_TO_FILE +FILE *log_file; +#ifdef LOGD +#undef LOGD +#endif +#define LOGD(arg...) do {if (log_file) {fprintf(log_file, ##arg);fprintf(log_file, "\n"); fflush(log_file);}} while(0) +#endif + +static gboolean _launch_process_repeat_until_success(gpointer user_data); + typedef enum { A11Y_BUS_STATE_IDLE = 0, A11Y_BUS_STATE_READING_ADDRESS, @@@ -86,35 -48,24 +86,38 @@@ } A11yBusState; typedef struct { + const char * name; + const char * app_control_operation; + const char * vconf_key[MAX_NUMBER_OF_KEYS_PER_CLIENT]; + int number_of_keys; + int launch_repeats; + int pid; +} A11yBusClient; + +typedef struct { GMainLoop *loop; gboolean launch_immediately; gboolean a11y_enabled; gboolean screen_reader_enabled; + GHashTable *client_watcher_id; GDBusConnection *session_bus; GSettings *a11y_schema; GSettings *interface_schema; int name_owner_id; + A11yBusClient screen_reader; + A11yBusClient universal_switch; + GDBusProxy *client_proxy; A11yBusState state; + /* -1 == error, 0 == pending, > 0 == running */ int a11y_bus_pid; char *a11y_bus_address; + #ifdef HAVE_X11 + gboolean x11_prop_set; + #endif int pipefd[2]; int listenfd; char *a11y_launch_error_message; @@@ -303,7 -254,7 +306,7 @@@ on_bus_exited (GPid pid gpointer data) { A11yBusLauncher *app = data; - + app->a11y_bus_pid = -1; app->state = A11Y_BUS_STATE_ERROR; if (app->a11y_launch_error_message == NULL) @@@ -316,7 -267,7 +319,7 @@@ app->a11y_launch_error_message = g_strdup_printf ("Bus stopped by signal %d", WSTOPSIG (status)); } g_main_loop_quit (app->loop); -} +} #ifdef DBUS_DAEMON static void @@@ -343,17 -294,8 +346,17 @@@ ensure_a11y_bus_daemon (A11yBusLaunche char addr_buf[2048]; GError *error = NULL; + if (app->a11y_bus_pid != 0) + return FALSE; + + argv[1] = (char*)config_path; + if (pipe (app->pipefd) < 0) - g_error ("Failed to create pipe: %s", strerror (errno)); + { + char buf[4096] = { 0 }; + strerror_r (errno, buf, sizeof(buf)); + g_error ("Failed to create pipe: %s", buf); + } g_clear_pointer (&app->a11y_launch_error_message, g_free); @@@ -379,13 -321,12 +382,14 @@@ app->state = A11Y_BUS_STATE_READING_ADDRESS; app->a11y_bus_pid = pid; - g_debug ("Launched a11y bus, child is %ld", (long) pid); + LOGD("Launched a11y bus, child is %ld", (long) pid); if (!unix_read_all_fd_to_string (app->pipefd[0], addr_buf, sizeof (addr_buf))) { - app->a11y_launch_error_message = g_strdup_printf ("Failed to read address: %s", strerror (errno)); + char buf[4096] = { 0 }; + strerror_r (errno, buf, sizeof(buf)); + app->a11y_launch_error_message = g_strdup_printf ("Failed to read address: %s", buf); kill (app->a11y_bus_pid, SIGTERM); + app->a11y_bus_pid = -1; goto error; } close (app->pipefd[0]); @@@ -393,15 -334,14 +397,15 @@@ app->state = A11Y_BUS_STATE_RUNNING; /* Trim the trailing newline */ + if (app->a11y_bus_address) g_free(app->a11y_bus_address); app->a11y_bus_address = g_strchomp (g_strdup (addr_buf)); - g_debug ("a11y bus address: %s", app->a11y_bus_address); + LOGD("a11y bus address: %s", app->a11y_bus_address); return TRUE; error: - close (app->pipefd[0]); - close (app->pipefd[1]); + if (app->pipefd[0] > 0) close (app->pipefd[0]); + if (app->pipefd[1] > 0) close (app->pipefd[1]); app->state = A11Y_BUS_STATE_ERROR; return FALSE; @@@ -444,32 -384,16 +448,32 @@@ ensure_a11y_bus_broker (A11yBusLaunche GError *error = NULL; if ((app->listenfd = socket (PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) < 0) - g_error ("Failed to create listening socket: %s", strerror (errno)); + { + char buf[4096] = { 0 }; + strerror_r (errno, buf, sizeof(buf)); + g_error ("Failed to create listening socket: %s", buf); + } if (bind (app->listenfd, (struct sockaddr *)&addr, sizeof(sa_family_t)) < 0) - g_error ("Failed to bind listening socket: %s", strerror (errno)); + { + char buf[4096] = { 0 }; + strerror_r (errno, buf, sizeof(buf)); + g_error ("Failed to bind listening socket: %s", buf); + } if (getsockname (app->listenfd, (struct sockaddr *)&addr, &addr_len) < 0) - g_error ("Failed to get socket name for listening socket: %s", strerror(errno)); + { + char buf[4096] = { 0 }; + strerror_r (errno, buf, sizeof(buf)); + g_error ("Failed to get socket name for listening socket: %s", buf); + } if (listen (app->listenfd, 1024) < 0) - g_error ("Failed to listen on socket: %s", strerror(errno)); + { + char buf[4096] = { 0 }; + strerror_r (errno, buf, sizeof(buf)); + g_error ("Failed to listen on socket: %s", buf); + } g_clear_pointer (&app->a11y_launch_error_message, g_free); @@@ -546,20 -470,22 +550,22 @@@ ensure_a11y_bus (A11yBusLauncher *app #endif #ifdef HAVE_X11 - { - Display *display = XOpenDisplay (NULL); - if (display) - { - Atom bus_address_atom = XInternAtom (display, "AT_SPI_BUS", False); - XChangeProperty (display, - XDefaultRootWindow (display), - bus_address_atom, - XA_STRING, 8, PropModeReplace, - (guchar *) app->a11y_bus_address, strlen (app->a11y_bus_address)); - XFlush (display); - XCloseDisplay (display); - } - } + if (g_getenv ("DISPLAY") != NULL && g_getenv ("WAYLAND_DISPLAY") == NULL) + { + Display *display = XOpenDisplay (NULL); + if (display) + { + Atom bus_address_atom = XInternAtom (display, "AT_SPI_BUS", False); + XChangeProperty (display, + XDefaultRootWindow (display), + bus_address_atom, + XA_STRING, 8, PropModeReplace, + (guchar *) app->a11y_bus_address, strlen (app->a11y_bus_address)); + XFlush (display); + XCloseDisplay (display); + app->x11_prop_set = TRUE; + } + } #endif return TRUE; @@@ -655,6 -581,11 +661,6 @@@ handle_screen_reader_enabled_change (A1 if (enabled == app->screen_reader_enabled) return; - /* If the screen reader is being enabled, we should enable accessibility - * if it isn't enabled already */ - if (enabled) - handle_a11y_enabled_change (app, enabled, notify_gsettings); - app->screen_reader_enabled = enabled; if (notify_gsettings && app->a11y_schema) @@@ -676,66 -607,12 +682,66 @@@ &builder, &invalidated_builder), NULL); - g_variant_builder_clear (&builder); g_variant_builder_clear (&invalidated_builder); } static gboolean +is_client_connected(A11yBusLauncher *app) +{ + guint watchers = g_hash_table_size(app->client_watcher_id); + LOGD("clients connected: %d", watchers); + return watchers > 0; +} + +static void +remove_client_watch(A11yBusLauncher *app, + const gchar *sender) +{ + LOGD("Remove client watcher for %s", sender); + guint watcher_id = GPOINTER_TO_UINT(g_hash_table_lookup(app->client_watcher_id, sender)); + if (watcher_id) + g_bus_unwatch_name(watcher_id); + + g_hash_table_remove(app->client_watcher_id, sender); + if (!is_client_connected(app)) + handle_a11y_enabled_change (app, FALSE, TRUE); +} + +static void +on_client_name_vanished (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + A11yBusLauncher *app = user_data; + remove_client_watch(app, name); +} + +static void +add_client_watch(A11yBusLauncher *app, + const gchar *sender) +{ + LOGD("Add client watcher for %s", sender); + + if (g_hash_table_contains(app->client_watcher_id, sender)) + { + LOGI("Watcher for %s already registered", sender); + return; + } + + guint watcher_id = g_bus_watch_name(G_BUS_TYPE_SESSION, + sender, + G_BUS_NAME_WATCHER_FLAGS_NONE, + NULL, + on_client_name_vanished, + app, + NULL); + + g_hash_table_insert(app->client_watcher_id, g_strdup(sender), GUINT_TO_POINTER(watcher_id)); + handle_a11y_enabled_change (app, TRUE, TRUE); +} + +static gboolean handle_set_property (GDBusConnection *connection, const gchar *sender, const gchar *object_path, @@@ -748,7 -625,7 +754,7 @@@ A11yBusLauncher *app = user_data; const gchar *type = g_variant_get_type_string (value); gboolean enabled; - + if (g_strcmp0 (type, "b") != 0) { g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, @@@ -760,10 -637,7 +766,10 @@@ if (g_strcmp0 (property_name, "IsEnabled") == 0) { - handle_a11y_enabled_change (app, enabled, TRUE); + if (enabled) + add_client_watch(app, sender); + else + remove_client_watch(app, sender); return TRUE; } else if (g_strcmp0 (property_name, "ScreenReaderEnabled") == 0) @@@ -801,7 -675,7 +807,7 @@@ on_bus_acquired (GDBusConnection *conne A11yBusLauncher *app = user_data; GError *error; guint registration_id; - + if (connection == NULL) { g_main_loop_quit (app->loop); @@@ -809,16 -683,6 +815,6 @@@ } app->session_bus = connection; - if (app->launch_immediately) - { - ensure_a11y_bus (app); - if (app->state == A11Y_BUS_STATE_ERROR) - { - g_main_loop_quit (app->loop); - return; - } - } - error = NULL; registration_id = g_dbus_connection_register_object (connection, "/org/a11y/bus", @@@ -860,6 -724,18 +856,18 @@@ on_name_acquired (GDBusConnection *conn const gchar *name, gpointer user_data) { + A11yBusLauncher *app = user_data; + + if (app->launch_immediately) + { + ensure_a11y_bus (app); + if (app->state == A11Y_BUS_STATE_ERROR) + { + g_main_loop_quit (app->loop); + return; + } + } + g_bus_watch_name (G_BUS_TYPE_SESSION, "org.gnome.SessionManager", G_BUS_NAME_WATCHER_FLAGS_NONE, @@@ -881,7 -757,7 +889,7 @@@ on_sigterm_pipe (GIOChannel *channel gpointer data) { A11yBusLauncher *app = data; - + g_main_loop_quit (app->loop); return FALSE; @@@ -893,11 -769,7 +901,11 @@@ init_sigterm_handling (A11yBusLauncher GIOChannel *sigterm_channel; if (pipe (sigterm_pipefd) < 0) - g_error ("Failed to create pipe: %s", strerror (errno)); + { + char buf[4096] = { 0 }; + strerror_r (errno, buf, sizeof(buf)); + g_error ("Failed to create pipe: %s", buf); + } signal (SIGTERM, sigterm_handler); sigterm_channel = g_io_channel_unix_new (sigterm_pipefd[0]); @@@ -907,57 -779,11 +915,13 @@@ app); } - static gboolean - already_running () - { - #ifdef HAVE_X11 - Atom AT_SPI_BUS; - Atom actual_type; - Display *bridge_display; - int actual_format; - unsigned char *data = NULL; - unsigned long nitems; - unsigned long leftover; - gboolean result = FALSE; - - bridge_display = XOpenDisplay (NULL); - if (!bridge_display) - return FALSE; - - AT_SPI_BUS = XInternAtom (bridge_display, "AT_SPI_BUS", False); - XGetWindowProperty (bridge_display, - XDefaultRootWindow (bridge_display), - AT_SPI_BUS, 0L, - (long) BUFSIZ, False, - (Atom) 31, &actual_type, &actual_format, - &nitems, &leftover, &data); - - if (data) - { - GDBusConnection *bus; - bus = g_dbus_connection_new_for_address_sync ((const gchar *)data, 0, - NULL, NULL, NULL); - if (bus != NULL) - { - result = TRUE; - g_object_unref (bus); - } - } - - XCloseDisplay (bridge_display); - return result; - #else - return FALSE; - #endif - } - static GSettings * get_schema (const gchar *name) { #if GLIB_CHECK_VERSION (2, 32, 0) GSettingsSchemaSource *source = g_settings_schema_source_get_default (); + if (!source) return NULL; + GSettingsSchema *schema = g_settings_schema_source_lookup (source, name, FALSE); if (schema == NULL) @@@ -990,263 -816,16 +954,257 @@@ gsettings_key_changed (GSettings *gsett handle_screen_reader_enabled_change (_global_app, new_val, FALSE); } +static int +_process_dead_tracker (int pid, void *data) +{ + A11yBusLauncher *app = data; + + if (app->screen_reader.pid > 0 && pid == app->screen_reader.pid) + { + LOGE("screen reader is dead, pid: %d, restarting", pid); + app->screen_reader.pid = 0; + g_timeout_add_seconds (2, _launch_process_repeat_until_success, &app->screen_reader); + } + + if (app->universal_switch.pid > 0 && pid == app->universal_switch.pid) + { + LOGE("universal switch is dead, pid: %d, restarting", pid); + app->universal_switch.pid = 0; + g_timeout_add_seconds (2, _launch_process_repeat_until_success, &app->universal_switch); + } + return 0; +} + +static void +_register_process_dead_tracker () +{ + if(_global_app->screen_reader.pid > 0 || _global_app->universal_switch.pid > 0) { + LOGD("registering process dead tracker"); + aul_listen_app_dead_signal(_process_dead_tracker, _global_app); + } else { + LOGD("unregistering process dead tracker"); + aul_listen_app_dead_signal(NULL, NULL); + } +} + + +static gboolean +_launch_client(A11yBusClient *client, gboolean by_vconf_change) +{ + LOGD("Launching %s", client->name); + + bundle *kb = NULL; + gboolean ret = FALSE; + + kb = bundle_create(); + + if (kb == NULL) + { + LOGD("Can't create bundle"); + return FALSE; + } + + if (by_vconf_change) + { + if (bundle_add_str(kb, "by_vconf_change", "yes") != BUNDLE_ERROR_NONE) + { + LOGD("Can't add information to bundle"); + } + } + + int operation_error = appsvc_set_operation(kb, client->app_control_operation); + LOGD("appsvc_set_operation: %i", operation_error); + + client->pid = appsvc_run_service(kb, 0, NULL, NULL); + + if (client->pid > 0) + { + LOGD("Process launched with pid: %i", client->pid); + _register_process_dead_tracker(); + ret = TRUE; + } + else + { + LOGD("Can't start %s - error code: %i", client->name, client->pid); + } + + bundle_free(kb); + return ret; +} + +static gboolean +_launch_process_repeat_until_success(gpointer user_data) { + A11yBusClient *client = user_data; + + if (client->launch_repeats > 100 || client->pid > 0) + { + //do not try anymore + return FALSE; + } + + gboolean ret = _launch_client(client, FALSE); + + if (ret) + { + //we managed to + client->launch_repeats = 0; + return FALSE; + } + client->launch_repeats++; + //try again + return TRUE; +} + +static gboolean +_terminate_process(int pid) +{ + int ret; + int ret_aul; + if (pid <= 0) + return FALSE; + + int status = aul_app_get_status_bypid(pid); + + if (status < 0) + { + LOGD("App with pid %d already terminated", pid); + return TRUE; + } + + LOGD("terminate process with pid %d", pid); + ret_aul = aul_terminate_pid(pid); + if (ret_aul >= 0) + { + LOGD("Terminating with aul_terminate_pid: return is %d", ret_aul); + return TRUE; + } + else + LOGD("aul_terminate_pid failed: return is %d", ret_aul); + + LOGD("Unable to terminate process using aul api. Sending SIGTERM signal"); + ret = kill(pid, SIGTERM); + if (!ret) + { + return TRUE; + } + + LOGD("Unable to terminate process: %d with api or signal.", pid); + return FALSE; +} + +static gboolean +_terminate_client(A11yBusClient *client) +{ + LOGD("Terminating %s", client->name); + int pid = client->pid; + client->pid = 0; + _register_process_dead_tracker(); + gboolean ret = _terminate_process(pid); + return ret; +} + +void vconf_client_cb(keynode_t *node, void *user_data) +{ + A11yBusClient *client = user_data; + + gboolean client_needed = FALSE; + int i; + for (i = 0; i < client->number_of_keys; i++) { + int status = 0; + int ret =vconf_get_bool(client->vconf_key[i], &status); + if (ret != 0) + { + LOGD("Could not read %s key value.\n", client->vconf_key[i]); + return; + } + LOGD("vconf_keynode_get_bool(node): %i", status); + if (status < 0) + return; + + if (status == 1) { + client_needed = TRUE; + break; + } + } + + //check if process really exists (e.g didn't crash) + if (client->pid > 0) + { + int err = kill(client->pid,0); + //process doesn't exist + if (err == ESRCH) + client->pid = 0; + } + + LOGD("client_needed: %i, client->pid: %i", client_needed, client->pid); + if (!client_needed && (client->pid > 0)) + _terminate_client(client); + else if (client_needed && (client->pid <= 0)) + _launch_client(client, TRUE); +} + + +static gboolean register_executable(A11yBusClient *client) +{ + gboolean client_needed = FALSE; + + int i; + for (i = 0; i < client->number_of_keys; i++) { + if (!client->vconf_key[i]) { + LOGE("Vconf_key missing for client: %d \n", i); + return FALSE; + } + + int status = 0; + int ret = vconf_get_bool(client->vconf_key[i], &status); + if (ret != 0) + { + LOGD("Could not read %s key value.\n", client->vconf_key[i]); + return FALSE; + } + ret = vconf_notify_key_changed(client->vconf_key[i], vconf_client_cb, client); + if (ret != 0) + { + LOGD("Could not add information level callback\n"); + return FALSE; + } + if (status) + client_needed = TRUE; + } + + if (client_needed) + g_timeout_add_seconds(2,_launch_process_repeat_until_success, client); + return TRUE; +} + int main (int argc, char **argv) { +#ifdef ATSPI_BUS_LAUNCHER_LOG_TO_FILE + log_file = fopen("/tmp/at-spi-bus-launcher.log", "a"); +#endif + + LOGD("Starting atspi bus launcher"); + gboolean a11y_set = FALSE; gboolean screen_reader_set = FALSE; gint i; - if (already_running ()) - { - LOGD("atspi bus launcher is already running"); - return 0; - } - _global_app = g_slice_new0 (A11yBusLauncher); _global_app->loop = g_main_loop_new (NULL, FALSE); + _global_app->client_watcher_id = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + + _global_app->screen_reader.name = "screen-reader"; + _global_app->screen_reader.app_control_operation = APP_CONTROL_OPERATION_SCREEN_READ; + _global_app->screen_reader.vconf_key[0] = VCONFKEY_SETAPPL_ACCESSIBILITY_TTS; + _global_app->screen_reader.number_of_keys = 1; + + _global_app->universal_switch.name = "universal-switch"; + _global_app->universal_switch.app_control_operation = APP_CONTROL_OPERATION_UNIVERSAL_SWITCH; + _global_app->universal_switch.vconf_key[0] = VCONFKEY_SETAPPL_ACCESSIBILITY_UNIVERSAL_SWITCH_CONFIGURATION_SERVICE; + _global_app->universal_switch.vconf_key[1] = VCONFKEY_SETAPPL_ACCESSIBILITY_UNIVERSAL_SWITCH_INTERACTION_SERVICE; + _global_app->universal_switch.number_of_keys = 2; for (i = 1; i < argc; i++) { @@@ -1293,41 -872,40 +1251,42 @@@ introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); g_assert (introspection_data != NULL); - _global_app->name_owner_id = - g_bus_own_name (G_BUS_TYPE_SESSION, - "org.a11y.Bus", - G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, - on_bus_acquired, - on_name_acquired, - on_name_lost, - _global_app, - NULL); + g_bus_own_name (G_BUS_TYPE_SESSION, + "org.a11y.Bus", + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, + on_bus_acquired, + on_name_acquired, + on_name_lost, + _global_app, + NULL); + + register_executable (&_global_app->screen_reader); + register_executable (&_global_app->universal_switch); g_main_loop_run (_global_app->loop); if (_global_app->a11y_bus_pid > 0) kill (_global_app->a11y_bus_pid, SIGTERM); - /* Clear the X property if our bus is gone; in the case where e.g. + /* Clear the X property if our bus is gone; in the case where e.g. * GDM is launching a login on an X server it was using before, * we don't want early login processes to pick up the stale address. */ #ifdef HAVE_X11 - { - Display *display = XOpenDisplay (NULL); - if (display) - { - Atom bus_address_atom = XInternAtom (display, "AT_SPI_BUS", False); - XDeleteProperty (display, - XDefaultRootWindow (display), - bus_address_atom); + if (_global_app->x11_prop_set) + { + Display *display = XOpenDisplay (NULL); + if (display) + { + Atom bus_address_atom = XInternAtom (display, "AT_SPI_BUS", False); + XDeleteProperty (display, + XDefaultRootWindow (display), + bus_address_atom); - XFlush (display); - XCloseDisplay (display); - } - } + XFlush (display); + XCloseDisplay (display); + } + } #endif if (_global_app->a11y_launch_error_message) diff --combined bus/meson.build index 75c6591,155dc53..402f78b --- a/bus/meson.build +++ b/bus/meson.build @@@ -34,7 -34,6 +34,7 @@@ configure_file(input: 'at-spi-dbus-bus. launcher_args = [ '-DSYSCONFDIR="@0@"'.format(atspi_sysconfdir), '-DDATADIR="@0@"'.format(atspi_datadir), + '-fPIE' ] if get_option('dbus_daemon') != 'default' @@@ -45,6 -44,7 +45,7 @@@ els '/usr/sbin/dbus-daemon', '/libexec/dbus-daemon', '/usr/libexec/dbus-daemon', + '/usr/lib/dbus-daemon', '/usr/pkg/bin/dbus-daemon', required: false) if dbus_daemon.found() @@@ -68,8 -68,7 +69,8 @@@ endi executable('at-spi-bus-launcher', 'at-spi-bus-launcher.c', include_directories: [ root_inc, include_directories('.') ], - dependencies: [ gio_dep, x11_deps ], + dependencies: [ gio_dep, x11_deps, app_svc_dep ], c_args: launcher_args, + link_args: '-pie', install: true, install_dir: atspi_libexecdir) diff --combined meson.build index 777f821,0a2f75e..8fed991 --- a/meson.build +++ b/meson.build @@@ -1,12 -1,12 +1,12 @@@ project('at-spi2-core', 'c', - version: '2.31.1', + version: '2.34.0', license: 'LGPLv2.1+', default_options: [ 'buildtype=debugoptimized', 'warning_level=1', 'c_std=c99', ], - meson_version: '>= 0.40.1') + meson_version: '>= 0.50.0') add_project_arguments([ '-D_POSIX_C_SOURCE=200809L', '-D_DEFAULT_SOURCE' ], language: 'c') @@@ -28,7 -28,6 +28,7 @@@ atspi_datadir = join_paths(atspi_prefix atspi_libexecdir = join_paths(atspi_prefix, get_option('libexecdir')) atspi_sysconfdir = join_paths(atspi_prefix, get_option('sysconfdir')) atspi_libdir = join_paths(atspi_prefix, get_option('libdir')) +atspi_bindir = join_paths(atspi_prefix, get_option('bindir')) atspi_includedir = join_paths(atspi_prefix, get_option('includedir')) if get_option('dbus_services_dir') != 'default' @@@ -48,17 -47,21 +48,23 @@@ libdbus_req_version = '>= 1.5 glib_req_version = '>= 2.32.0' gobject_req_version = '>= 2.0.0' gio_req_version = '>= 2.28.0' +app_svc_req_version = '>= 0.0.0' libdbus_dep = dependency('dbus-1', version: libdbus_req_version) glib_dep = dependency('glib-2.0', version: glib_req_version) gobject_dep = dependency('gobject-2.0', version: gobject_req_version) gio_dep = dependency('gio-2.0', version: gio_req_version) +app_svc_dep = dependency('appsvc', version: app_svc_req_version) - dl_dep = cc.find_library('dl', required: false) + if cc.has_function('dlopen') + dl_dep = [] + elif cc.has_function('dlopen', args: '-ldl') + dl_dep = cc.find_library('dl') + else + error('Could not find a library with the dlopen function') + endif x11_deps = [] - x11_option = get_option('enable-x11') + x11_option = get_option('x11') if x11_option != 'no' x11_dep = dependency('x11', required: false) @@@ -99,7 -102,7 +105,7 @@@ at_spi_conf.set('ALIGNOF_DBIND_STRUCT' # introspection support have_gir = false - introspection_option = get_option('enable-introspection') + introspection_option = get_option('introspection') if introspection_option != 'no' gir_dep = dependency('gobject-introspection-1.0', version: '>= 0.6.7', required: false) @@@ -120,7 -123,7 +126,7 @@@ subdir('bus' subdir('registryd') subdir('test') - if get_option('enable_docs') + if get_option('docs') subdir('doc/libatspi') endif diff --combined packaging/at-spi2-core.spec index c2db81e,0000000..6316fb2 mode 100644,000000..100644 --- a/packaging/at-spi2-core.spec +++ b/packaging/at-spi2-core.spec @@@ -1,129 -1,0 +1,129 @@@ +%bcond_with x + +Name: at-spi2-core - Version: 2.31.1 ++Version: 2.34.0 +Release: 0 +Summary: Assistive Technology Service Provider Interface - D-Bus based implementation +License: LGPL-2.0+ +Group: System/Libraries +Url: http://www.gnome.org/ +Source: http://ftp.gnome.org/pub/GNOME/sources/at-spi2-core/2.31/%{name}-%{version}.tar.xz +Source1001: %{name}.manifest +Requires: dbus +BuildRequires: python-devel +BuildRequires: python-xml +BuildRequires: intltool +BuildRequires: dbus-devel +BuildRequires: glib2-devel +BuildRequires: gettext +BuildRequires: gtk-doc +%if %{with x} +BuildRequires: libX11-devel +BuildRequires: libXtst-devel +BuildRequires: libXi-devel +%endif +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(appsvc) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(aul) +BuildRequires: gobject-introspection +BuildRequires: meson +BuildRequires: app-svc-devel + +%description +AT-SPI is a general interface for applications to make use of the +accessibility toolkit. This version is based on dbus. + +This package contains the AT-SPI registry daemon. It provides a +mechanism for all assistive technologies to discover and interact +with applications running on the desktop. + +%package -n libatspi0 +Summary: An Accessibility ToolKit -- Library +Group: System/Libraries + +%description -n libatspi0 +AT-SPI is a general interface for applications to make use of the +accessibility toolkit. This version is based on dbus. + +%package -n typelib-1_0-Atspi-2_0 +Summary: An Accessibility ToolKit -- Introspection bindings +Group: System/Libraries + +%description -n typelib-1_0-Atspi-2_0 +AT-SPI is a general interface for applications to make use of the +accessibility toolkit. This version is based on dbus. + +This package provides the GObject Introspection bindings for the +libatspi library. + +%package devel +Summary: Include Files and Libraries mandatory for Development +Group: Development/Libraries +Requires: %{name} = %{version} +Requires: libatspi0 = %{version} +Requires: typelib-1_0-Atspi-2_0 = %{version} + +%description devel +This package contains all necessary include files and libraries needed +to develop applications that require these. + +%prep +%setup -q +cp %{SOURCE1001} . + +%build +meson --prefix /usr --libdir %{_libdir} build -Dwith-dbus-daemondir=%{_bindir} -Ddbus_daemon=/usr/bin/dbus-daemon \ +%if !%{with x} + -Denable-x11=no \ +%else + -Denable-x11=yes \ +%endif + -Denable-static=no + +ninja -C build all + +%install +find %{buildroot} -name '*.la' -or -name '*.a' | xargs rm -f + +export DESTDIR=%{buildroot} +ninja -C build install + +%find_lang %{name} + +%clean +rm -fr %{buildroot} + +%post -n libatspi0 -p /sbin/ldconfig + +%postun -n libatspi0 -p /sbin/ldconfig + +%files -f %{name}.lang +%manifest %{name}.manifest +%defattr(-,root,root) +%{_bindir}/at_spi2_tool + +%doc AUTHORS README +%license COPYING +%{_libexecdir}/at-spi-bus-launcher +%{_libexecdir}/at-spi2-registryd +%{_datadir}/defaults/at-spi2/accessibility.conf +%{_sysconfdir}/xdg/autostart/at-spi-dbus-bus.desktop +%{_datadir}/dbus-1/accessibility-services/org.a11y.atspi.Registry.service +%{_datadir}/dbus-1/services/org.a11y.Bus.service +%{_prefix}/lib/systemd/user/at-spi-dbus-bus.service +%files -n libatspi0 +%manifest %{name}.manifest +%defattr(-, root, root) +%{_libdir}/libatspi.so.0* + +%files -n typelib-1_0-Atspi-2_0 +%manifest %{name}.manifest +%defattr(-, root, root) + +%files devel +%manifest %{name}.manifest +%defattr(-, root, root) +%{_includedir}/at-spi-2.0 +%{_libdir}/libatspi.so +%{_libdir}/pkgconfig/atspi-2.pc diff --combined registryd/deviceeventcontroller.c index 686f2cd,acd089b..2a0721d --- a/registryd/deviceeventcontroller.c +++ b/registryd/deviceeventcontroller.c @@@ -6,19 -6,19 +6,19 @@@ * Copyright 2001, 2002 Ximian, 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. */ /* deviceeventcontroller.c: implement the DeviceEventController interface */ @@@ -927,7 -927,6 +927,7 @@@ send_and_allow_reentry (DBusConnection { const char *dest = dbus_message_get_destination (message); GSList *l; + dbus_bool_t result; gchar *bus_name_dup; dbus_message_ref (message); dbus_pending_call_set_notify (pending, reset_hung_process, message, @@@ -937,9 -936,9 +937,9 @@@ "Ping"); if (!message) return NULL; - dbus_connection_send_with_reply (bus, message, &pending, -1); + result = dbus_connection_send_with_reply (bus, message, &pending, -1); dbus_message_unref (message); - if (!pending) + if (!result || !pending) return NULL; bus_name_dup = g_strdup (dest); dbus_pending_call_set_notify (pending, reset_hung_process_from_ping, @@@ -1366,7 -1365,6 +1366,7 @@@ impl_register_keystroke_listener (DBusC Accessibility_KeyDefinition *kd = (Accessibility_KeyDefinition *)g_malloc(sizeof(Accessibility_KeyDefinition)); if (!spi_dbus_message_iter_get_struct(&iter_array, DBUS_TYPE_INT32, &kd->keycode, DBUS_TYPE_INT32, &kd->keysym, DBUS_TYPE_STRING, &keystring, DBUS_TYPE_INVALID)) { + g_free (kd); break; } kd->keystring = g_strdup (keystring); @@@ -1577,7 -1575,6 +1577,7 @@@ impl_deregister_keystroke_listener (DBu if (!spi_dbus_message_iter_get_struct(&iter_array, DBUS_TYPE_INT32, &kd->keycode, DBUS_TYPE_INT32, &kd->keysym, DBUS_TYPE_STRING, &keystring, DBUS_TYPE_INVALID)) { + g_free(kd); break; } kd->keystring = g_strdup (keystring); @@@ -1859,7 -1856,7 +1859,7 @@@ spi_device_event_controller_class_init object_class->finalize = spi_device_event_controller_object_finalize; #ifdef HAVE_X11 - if (g_getenv ("DISPLAY")) + if (g_getenv ("DISPLAY") != NULL && g_getenv ("WAYLAND_DISPLAY") == NULL) spi_dec_setup_x11 (klass); else #endif diff --combined registryd/meson.build index be0fe95,c2404d2..d0d5e6b --- a/registryd/meson.build +++ b/registryd/meson.build @@@ -16,7 -16,7 +16,7 @@@ registryd_deps = dl_dep, ] - x11_option = get_option('enable-x11') + x11_option = get_option('x11') if x11_option != 'no' if x11_dep.found() registryd_sources += [ @@@ -32,8 -32,6 +32,8 @@@ endi executable('at-spi2-registryd', registryd_sources, dependencies: registryd_deps, + c_args: '-fPIE', + link_args: '-pie', install: true, install_dir: atspi_libexecdir) diff --combined registryd/registry.c index 1cb4431,8d35f8e..aa867ca --- a/registryd/registry.c +++ b/registryd/registry.c @@@ -7,19 -7,19 +7,19 @@@ * Copyright 2001, 2002 Ximian, 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 @@@ -542,30 -542,6 +542,30 @@@ impl_GrabFocus (DBusConnection * bus, D } static DBusMessage * +impl_ClearHighlight (DBusConnection * bus, DBusMessage * message, void *user_data) +{ + DBusMessage *reply; + dbus_bool_t retval = FALSE; + + reply = dbus_message_new_method_return (message); + dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &retval, + DBUS_TYPE_INVALID); + return reply; +} + +static DBusMessage * +impl_GrabHighlight (DBusConnection * bus, DBusMessage * message, void *user_data) +{ + DBusMessage *reply; + dbus_bool_t retval = FALSE; + + reply = dbus_message_new_method_return (message); + dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &retval, + DBUS_TYPE_INVALID); + return reply; +} + +static DBusMessage * impl_GetAlpha (DBusConnection * bus, DBusMessage * message, void *user_data) { double rv = 1.0; @@@ -1272,10 -1248,6 +1272,10 @@@ handle_method_root (DBusConnection *bus reply = impl_GetMDIZOrder (bus, message, user_data); else if (!strcmp (member, "GrabFocus")) reply = impl_GrabFocus (bus, message, user_data); + else if (!strcmp (member, "GrabHighlight")) + reply = impl_GrabHighlight (bus, message, user_data); + else if (!strcmp (member, "ClearHighlight")) + reply = impl_ClearHighlight (bus, message, user_data); else if (!strcmp (member, "GetAlpha")) reply = impl_GetAlpha (bus, message, user_data); else