From a9804de0ee0e62cc8ebc2b9799bb5268f9927c5a Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Mon, 29 May 2017 20:43:25 +0900 Subject: [PATCH] Add "GetReadingMaterial" interface method The atspi_accessible_get_reading_material of at-spi2-core calls this method to get reading material to be used screen-reader side. This is for reducing IPC. It seems that the number of IPC is changed from 30 to 1. Related patch set: https://review.tizen.org/gerrit/#/c/131358/ (at-spi2-core) https://review.tizen.org/gerrit/#/c/131359/ (elementary) https://review.tizen.org/gerrit/#/c/131511/ (this one, at-spi2-atk) https://review.tizen.org/gerrit/#/c/131714/ (screen-reader) Change-Id: I6e5b64c5e7d6a3c448f9b108dc5b36bc824621c7 --- atk-adaptor/adaptors/accessible-adaptor.c | 306 ++++++++++++++++++++++++++++++ atk-adaptor/introspection.c | 4 + 2 files changed, 310 insertions(+) diff --git a/atk-adaptor/adaptors/accessible-adaptor.c b/atk-adaptor/adaptors/accessible-adaptor.c index b0a7d8b..ce719ce 100644 --- a/atk-adaptor/adaptors/accessible-adaptor.c +++ b/atk-adaptor/adaptors/accessible-adaptor.c @@ -667,6 +667,311 @@ impl_GetNavigableAtPoint (DBusConnection * bus, DBusMessage * message, return reply; } + +static int +_list_children_count_check(AtkObject * object) +{ + gint role; + gint i; + gint list_count = 0; + + if (!object) + return 0; + + role = atk_object_get_role (object); + if (role == ATK_ROLE_LIST) + { + gint children_count = 0; + children_count = atk_object_get_n_accessible_children (object); + for (i = 0; i < children_count; i++) + { + AtkObject *child = atk_object_ref_accessible_child (object, i); + role = atk_object_get_role (child); + if (role == ATK_ROLE_LIST_ITEM) + list_count++; + if (child) + g_object_unref (child); + } + } + + return list_count; +} + +static gint +_list_children_count (AtkObject * object) +{ + gint list_items_count = 0; + gint count = 0; + gint i; + + list_items_count = _list_children_count_check(object); + if (list_items_count > 0) + { + return list_items_count; + } + + count = atk_object_get_n_accessible_children (object); + for (i = 0; i < count; i++) + { + AtkObject *child = atk_object_ref_accessible_child (object, i); + list_items_count = _list_children_count(child); + if (child) + g_object_unref (child); + if (list_items_count > 0) + { + return list_items_count; + } + } + + return 0; +} + +static DBusMessage * +impl_GetReadingMaterial (DBusConnection * bus, DBusMessage * message, void *user_data) +{ + AtkObject *object = (AtkObject *) user_data; + AtkObject *parent; + AtkAttributeSet *attributes; + const char *name; + AtkRelationSet *set; + gint count, i; + AtkObject *rel_object = NULL; + unsigned int size = 0; + gint role; + dbus_uint32_t rv_role; + dbus_int32_t rv_index; + dbus_uint32_t states[2]; + dbus_bool_t rv_is_selected = 0; + DBusMessage *reply = NULL; + DBusMessageIter iter; + DBusMessageIter iter_variant; + + g_return_val_if_fail (ATK_IS_OBJECT (user_data), + droute_not_yet_handled_error (message)); + + reply = dbus_message_new_method_return (message); + dbus_message_iter_init_append (reply, &iter); + + /* attributes */ + attributes = atk_object_get_attributes (object); + spi_object_append_attribute_set (&iter, attributes); + atk_attribute_set_free (attributes); + + /* name */ + name = atk_object_get_name (object); + if (!name) + name = ""; + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &name); + + /* name - LABELED_BY relation */ + name = NULL; + set = atk_object_ref_relation_set (object); + count = atk_relation_set_get_n_relations (set); + for (i = 0; i < count; i++) + { + AtkRelation *r = atk_relation_set_get_relation (set, i); + if (!r) + continue; + AtkRelationType rt = atk_relation_get_relation_type (r); + if (rt == ATK_RELATION_LABELLED_BY) + { + GPtrArray *target = atk_relation_get_target (r); + if (target && target->len > 0) + { + rel_object = target->pdata[target->len - 1]; + name = atk_object_get_name (rel_object); + break; + } + } + } + if (!name) + name = ""; + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &name); + + /* name - text interface */ + AtkText *text = (AtkText *) object; + size = atk_text_get_character_count (text); + name = atk_text_get_text (text, 0, size); + if (!name) + name = ""; + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &name); + + /* role */ + role = atk_object_get_role (object); + rv_role = spi_accessible_role_from_atk_role (role); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &rv_role); + + /* states */ + spi_atk_state_to_dbus_array (object, states); + dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "u", &iter_variant); + for (count = 0; count < 2; count++) + { + dbus_message_iter_append_basic (&iter_variant, DBUS_TYPE_UINT32, + &states[count]); + } + dbus_message_iter_close_container (&iter, &iter_variant); + + /* localized role name */ + name = atk_role_get_localized_name (role); + if (!name) + name = ""; + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &name); + + /* child count */ + count = atk_object_get_n_accessible_children (object); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &count); + + /* current value, increment, max, min */ + AtkValue *value = (AtkValue *) object; + gdouble current_value = 0; + gdouble increment = 0; + gdouble min_value = 0; + gdouble max_value = 0; + if (ATK_IS_VALUE(value)) + { + gchar *desc = NULL; + atk_value_get_value_and_text (value, ¤t_value, &desc); + + increment = atk_value_get_increment (value); + + AtkRange *range = atk_value_get_range(value); + if (range) + { + min_value = atk_range_get_lower_limit (range); + max_value = atk_range_get_upper_limit (range); + atk_range_free (range); + } + } + dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, ¤t_value); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &increment); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &max_value); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &min_value); + + /* description */ + name = atk_object_get_description (object); + if (!name) + name = ""; + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &name); + + /* index in parent */ + rv_index = atk_object_get_index_in_parent (object); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &rv_index); + + /* is selected in parent */ + parent = atk_object_get_parent (object); + if (parent) + { + AtkSelection *selection = (AtkSelection *) parent; + if (ATK_IS_SELECTION(selection)) + { + rv_is_selected = atk_selection_is_child_selected (selection, rv_index); + } + } + dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &rv_is_selected); + + /* has checkbox child */ + rv_is_selected = 0; + count = atk_object_get_n_accessible_children (object); + for (i = 0; i < count; i++) + { + AtkObject *child = atk_object_ref_accessible_child (object, i); + gint _role = atk_object_get_role (child); + if (child) + g_object_unref (child); + if (_role == ATK_ROLE_CHECK_BOX) + { + rv_is_selected = 1; + break; + } + } + dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &rv_is_selected); + + /* list children count */ + count = 0; + if (role == ATK_ROLE_DIALOG) + { + count = _list_children_count(object); + } + dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &count); + + /* first selected child index */ + /* it is too UX dependent, this is not necessary */ + rv_index = 0; + dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &rv_index); + + /* parent */ + if (!parent) + { + /* does it have to handle PLUG, APPLICATION? */ + spi_object_append_null_reference (&iter); + } + else + { + spi_object_append_reference (&iter, parent); + } + + /* parent - states */ + spi_atk_state_to_dbus_array (parent, states); + dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "u", &iter_variant); + for (count = 0; count < 2; count++) + { + dbus_message_iter_append_basic (&iter_variant, DBUS_TYPE_UINT32, + &states[count]); + } + dbus_message_iter_close_container (&iter, &iter_variant); + + /* parent - child count */ + count = atk_object_get_n_accessible_children (parent); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &count); + + /* parent role */ + role = atk_object_get_role (parent); + rv_role = spi_accessible_role_from_atk_role (role); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &rv_role); + + /* parent selected child count */ + count = 0; + if (parent) + { + AtkSelection *selection = (AtkSelection *) parent; + if (ATK_IS_SELECTION(selection)) + { + count = atk_selection_get_selection_count (selection); + } + } + dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &count); + + /* relation object - DESCRIBED_BY */ + rel_object = NULL; + set = atk_object_ref_relation_set (object); + count = atk_relation_set_get_n_relations (set); + for (i = 0; i < count; i++) + { + AtkRelation *r = atk_relation_set_get_relation (set, i); + if (!r) + continue; + AtkRelationType rt = atk_relation_get_relation_type (r); + if (rt == ATK_RELATION_DESCRIBED_BY) + { + GPtrArray *target = atk_relation_get_target (r); + if (target && target->len > 0) + { + rel_object = target->pdata[target->len - 1]; + break; + } + } + } + if (!rel_object) + { + spi_object_append_null_reference (&iter); + } + else + { + spi_object_append_reference (&iter, rel_object); + } + + return reply; +} // static dbus_bool_t @@ -1163,6 +1468,7 @@ static DRouteMethod methods[] = { // TIZEN_ONLY(20170310) - implementation of get object under coordinates for accessibility {impl_GetNavigableAtPoint, "GetNavigableAtPoint"}, {impl_GetNeighbor, "GetNeighbor"}, + {impl_GetReadingMaterial, "GetReadingMaterial"}, // {impl_GetChildAtIndex, "GetChildAtIndex"}, {impl_GetChildren, "GetChildren"}, diff --git a/atk-adaptor/introspection.c b/atk-adaptor/introspection.c index bc1f332..800bff2 100644 --- a/atk-adaptor/introspection.c +++ b/atk-adaptor/introspection.c @@ -25,6 +25,10 @@ const char *spi_org_a11y_atspi_Accessible = "" " " "" +" " +" " +" " +"" " " " " " " -- 2.7.4