From: Shinwoo Kim Date: Fri, 26 May 2017 13:05:11 +0000 (+0900) Subject: atspi: add "GetReadingMaterial" interface method X-Git-Tag: submit/tizen_3.0/20170705.022822~12 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=395809c19b17c8cf376463bc9aa15606a72a733e;p=platform%2Fupstream%2Felementary.git atspi: 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/ (this one, elementary) https://review.tizen.org/gerrit/#/c/131511/ (at-spi2-atk) https://review.tizen.org/gerrit/#/c/131714/ (screen-reader) @tizen_only Change-Id: Ib17d34fd8af7b5856908692c617938116d02305e --- diff --git a/src/lib/elm_atspi_bridge.c b/src/lib/elm_atspi_bridge.c index 9923a0e84..5192ae4ee 100644 --- a/src/lib/elm_atspi_bridge.c +++ b/src/lib/elm_atspi_bridge.c @@ -1027,6 +1027,311 @@ _accessible_get_navigable_at_point(const Eldbus_Service_Interface *iface EINA_UN } // +//TIZEN_ONLY(20170531): add "GetReadingMaterial" interface method +static int +_list_children_count_check(Eo *obj) +{ + int i; + int list_count = 0; + Eina_List *children; + Eo *child = NULL; + Elm_Atspi_Role role; + + if (!obj) + return 0; + + eo_do(obj, role = elm_interface_atspi_accessible_role_get()); + if (role == ELM_ATSPI_ROLE_LIST) + { + int children_count = 0; + eo_do(obj, children = elm_interface_atspi_accessible_children_get()); + children_count = eina_list_count(children); + + for (i = 0; i < children_count; i++) + { + child = eina_list_nth(children, i); + eo_do(child, role = elm_interface_atspi_accessible_role_get()); + if (role == ELM_ATSPI_ROLE_LIST_ITEM) + list_count++; + } + eina_list_free(children); + } + + return list_count; +} + +static int +_list_children_count(Eo *obj) +{ + Eina_List *children; + int list_items_count = 0; + int children_count = 0; + + eo_do(obj, children = elm_interface_atspi_accessible_children_get()); + children_count = eina_list_count(children); + + int i; + Eo *child = NULL; + + list_items_count = _list_children_count_check(obj); + if (list_items_count > 0) + { + eina_list_free(children); + return list_items_count; + } + + for (i = 0; i < children_count; i++) + { + child = eina_list_nth(children, i); + list_items_count = _list_children_count(child); + if (list_items_count > 0) + { + eina_list_free(children); + return list_items_count; + } + } + + return 0; +} + +static Eldbus_Message * +_accessible_reading_material_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + Eldbus_Message *ret; + Eldbus_Message_Iter *iter, *iter_array, *iter_dict, *iter_entry; + Eina_List *attrs, *l, *children; + const char *name = NULL; + unsigned int s1, s2; + double value = 0; + double increment = 0; + double max_value = 0; + double min_value = 0; + int idx = 0; + int child_count = 0; + int selected_child_count = 0; + uint64_t atspi_states = 0; + Elm_Atspi_Role role; + Elm_Atspi_Attribute *attr; + Elm_Atspi_State_Set states; + Elm_Atspi_Relation_Set rels = NULL; + Elm_Atspi_Relation *rel; + Eo *relation_obj = NULL; + Eo *parent = NULL; + Eo *child = NULL; + Eina_Bool is_selected = EINA_FALSE; + AtspiRole atspi_role = ATSPI_ROLE_INVALID; + + const char *obj_path = eldbus_message_path_get(msg); + Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME); + Eo *obj = _bridge_object_from_path(bridge, obj_path); + + ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + iter = eldbus_message_iter_get(ret); + /* attributes */ + eo_do(obj, attrs = elm_interface_atspi_accessible_attributes_get()); + iter_dict = eldbus_message_iter_container_new(iter, 'a', "{ss}"); + EINA_SAFETY_ON_NULL_RETURN_VAL(iter_dict, NULL); + EINA_LIST_FOREACH(attrs, l, attr) + { + iter_entry = eldbus_message_iter_container_new(iter_dict, 'e', NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(iter_entry, NULL); + eldbus_message_iter_arguments_append(iter_entry, "ss", attr->key, attr->value); + eldbus_message_iter_container_close(iter_dict, iter_entry); + } + + eldbus_message_iter_container_close(iter, iter_dict); + elm_atspi_attributes_list_free(attrs); + + /* name */ + eo_do(obj, name = elm_interface_atspi_accessible_name_get()); + if (!name) + name = ""; + eldbus_message_iter_basic_append(iter, 's', name); + + /* name - LABELED_BY relation */ + eo_do(obj, rels = elm_interface_atspi_accessible_relation_set_get()); + EINA_LIST_FOREACH(rels, l, rel) + { + if (rel->type == ELM_ATSPI_RELATION_LABELLED_BY) + { + int last_index = eina_list_count(rel->objects) - 1; + relation_obj = eina_list_nth(rel->objects, last_index); + break; + } + } + eo_do(relation_obj, name = elm_interface_atspi_accessible_name_get()); + if (!name) + name = ""; + eldbus_message_iter_basic_append(iter, 's', name); + + /* name - text interface */ + name = NULL; + if (eo_isa(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE)) + { + int val; + eo_do(obj, val = elm_interface_atspi_text_character_count_get()); + eo_do(obj, name = elm_interface_atspi_text_get(0, val)); + } + if (!name) + name = ""; + eldbus_message_iter_basic_append(iter, 's', name); + + /* role */ + eo_do(obj, role = elm_interface_atspi_accessible_role_get()); + atspi_role = role > ELM_ATSPI_ROLE_LAST_DEFINED ? ATSPI_ROLE_LAST_DEFINED : elm_roles_to_atspi_roles[role][1]; + eldbus_message_iter_basic_append(iter, 'u', atspi_role); + + /* states */ + iter_array = eldbus_message_iter_container_new(iter, 'a', "u"); + EINA_SAFETY_ON_NULL_GOTO(iter_array, fail); + eo_do(obj, states = elm_interface_atspi_accessible_state_set_get()); + atspi_states = _elm_atspi_state_set_to_atspi_state_set(states); + s1 = atspi_states & 0xFFFFFFFF; + s2 = (atspi_states >> 32) & 0xFFFFFFFF; + eldbus_message_iter_basic_append(iter_array, 'u', s1); + eldbus_message_iter_basic_append(iter_array, 'u', s2); + eldbus_message_iter_container_close(iter, iter_array); + + /* localized role name */ + eo_do(obj, name = elm_interface_atspi_accessible_localized_role_name_get()); + if (!name) + name = ""; + eldbus_message_iter_basic_append(iter, 's', name); + + /* child count */ + eo_do(obj, l = elm_interface_atspi_accessible_children_get()); + eldbus_message_iter_basic_append(iter, 'i', eina_list_count(l)); + eina_list_free(l); + + /* current value, increment, max, min */ + value = 0; + increment = 0; + max_value = 0; + min_value = 0; + if (eo_isa(obj, ELM_INTERFACE_ATSPI_VALUE_INTERFACE)) + { + eo_do(obj, elm_interface_atspi_value_and_text_get(&value, NULL)); + eo_do(obj, increment = elm_interface_atspi_value_increment_get()); + eo_do(obj, elm_interface_atspi_value_range_get(&min_value, &max_value, NULL)); + } + eldbus_message_iter_basic_append(iter, 'd', value); + eldbus_message_iter_basic_append(iter, 'd', increment); + eldbus_message_iter_basic_append(iter, 'd', max_value); + eldbus_message_iter_basic_append(iter, 'd', min_value); + + /* description */ + eo_do(obj, name = elm_interface_atspi_accessible_description_get()); + if (!name) + name = ""; + eldbus_message_iter_basic_append(iter, 's', name); + + /* index in parent */ + eo_do(obj, idx = elm_interface_atspi_accessible_index_in_parent_get()); + eldbus_message_iter_basic_append(iter, 'i', idx); + + /* is selected in parent */ + eo_do(obj, parent = elm_interface_atspi_accessible_parent_get()); + eo_do(parent, is_selected = elm_interface_atspi_selection_is_child_selected(idx)); + eldbus_message_arguments_append(ret, "b", is_selected); + + /* has checkbox child */ + is_selected = EINA_FALSE; + eo_do(obj, children = elm_interface_atspi_accessible_children_get()); + EINA_LIST_FOREACH(children, l, child) + { + if (eo_isa(child, ELM_CHECK_CLASS)) + { + is_selected = EINA_TRUE; + break; + } + } + eldbus_message_iter_basic_append(iter, 'b', is_selected); + eina_list_free(children); + + /* list children count */ + child_count = 0; + if (role == ELM_ATSPI_ROLE_DIALOG) + { + child_count = _list_children_count(obj); + } + eldbus_message_iter_basic_append(iter, 'i', child_count); + + /* first selected child index */ + idx = 0; + if (eo_isa(obj, ELM_INDEX_CLASS)) + { + eo_do(obj, children = elm_interface_atspi_accessible_children_get()); + EINA_LIST_FOREACH(children, l, child) + { + eo_do(child, states = elm_interface_atspi_accessible_state_set_get()); + if (STATE_TYPE_GET(states, ELM_ATSPI_STATE_SELECTED)) + break; + idx++; + } + eina_list_free(children); + } + eldbus_message_iter_basic_append(iter, 'i', idx); + + /* parent */ + role = ELM_ATSPI_ROLE_INVALID; + eo_do(obj, role = elm_interface_atspi_accessible_role_get()); + if ((!parent) && (ELM_ATSPI_ROLE_APPLICATION == role)) + _object_desktop_reference_append(iter); + else + _bridge_iter_object_reference_append(bridge, iter, parent); + + /* parent - states */ + iter_array = eldbus_message_iter_container_new(iter, 'a', "u"); + EINA_SAFETY_ON_NULL_GOTO(iter_array, fail); + eo_do(parent, states = elm_interface_atspi_accessible_state_set_get()); + atspi_states = _elm_atspi_state_set_to_atspi_state_set(states); + s1 = atspi_states & 0xFFFFFFFF; + s2 = (atspi_states >> 32) & 0xFFFFFFFF; + eldbus_message_iter_basic_append(iter_array, 'u', s1); + eldbus_message_iter_basic_append(iter_array, 'u', s2); + eldbus_message_iter_container_close(iter, iter_array); + + /* parent - child count */ + eo_do(parent, l = elm_interface_atspi_accessible_children_get()); + eldbus_message_iter_basic_append(iter, 'i', eina_list_count(l)); + eina_list_free(l); + + /* parent - role */ + eo_do(parent, role = elm_interface_atspi_accessible_role_get()); + atspi_role = role > ELM_ATSPI_ROLE_LAST_DEFINED ? ATSPI_ROLE_LAST_DEFINED : elm_roles_to_atspi_roles[role][1]; + eldbus_message_iter_basic_append(iter, 'u', atspi_role); + + /* parent - child count */ + eo_do(parent, selected_child_count = elm_interface_atspi_selection_selected_children_count_get()); + eldbus_message_iter_basic_append(iter, 'i', selected_child_count); + + /* relation object - DESCRIBED_BY */ + relation_obj = NULL; + EINA_LIST_FOREACH(rels, l, rel) + { + if (rel->type == ELM_ATSPI_RELATION_DESCRIBED_BY) + { + int last_index = eina_list_count(rel->objects) - 1; + relation_obj = eina_list_nth(rel->objects, last_index); + break; + } + } + _bridge_iter_object_reference_append(bridge, iter, relation_obj); + elm_atspi_relation_set_free(&rels); + + return ret; + +fail: + if (rels) elm_atspi_relation_set_free(&rels); + if (ret) eldbus_message_unref(ret); + return NULL; +} +// + static const Eldbus_Method accessible_methods[] = { // TIZEN_ONLY(20170310) - implementation of get object under coordinates for accessibility { "GetNavigableAtPoint", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"u", "coord_type"}), ELDBUS_ARGS({"(so)y", "accessible"}), _accessible_get_navigable_at_point, 0 }, @@ -1048,7 +1353,26 @@ static const Eldbus_Method accessible_methods[] = { ELDBUS_ARGS({"i", "type"}, {"i", "x_beg"}, {"i", "y_beg"}, {"i", "x_end"}, {"i", "y_end"}, {"i", "state"}, {"u", "event_time"}), - ELDBUS_ARGS({"b", "result"}), _accessible_gesture_do, 0 }, + ELDBUS_ARGS({"b", "result"}), _accessible_gesture_do, 0}, + // + //TIZEN_ONLY(20170531): add "GetReadingMaterial" interface method + { "GetReadingMaterial", + NULL, + ELDBUS_ARGS({"a{ss}", "attributes"}, {"s", "name"}, + {"s", "labledByName"},{"s", "textIfceName"}, + {"u", "role"}, {"au", "stateSet"}, + {"s", "localizedName"}, {"i", "childCount"}, + {"d", "currentValue"},{"d", "minimumIncrement"}, + {"d", "maximumValue"},{"d", "minimumValue"}, + {"s", "description"}, {"i", "indexInParent"}, + {"b", "isSelectedInParent"}, {"b", "hasCheckboxChild"}, + {"i", "listChildrenCount"}, + {"i", "firstSelectedChildIndex"}, + {"(so)", "parent"}, {"au", "parentStateSet"}, + {"i", "parentChildCount"}, {"u", "parentRole"}, + {"i", "selectedChildCount"}, + {"(so)", "describecByObject"}), + _accessible_reading_material_get, 0}, // { NULL, NULL, NULL, NULL, 0 } };