#include "atspi/atspi.h"
#include "spi-dbus.h"
#include "accessible-stateset.h"
+#include "accessible-register.h"
#include "object.h"
#include "introspection.h"
#include <string.h>
+#include <stdint.h>
+
+
+
+
+
+
+
+
+
+
+
+
+
+// TIZEN_ONLY(20170310) - implementation of get object under coordinates for accessibility
+static AtspiRelationType spi_relation_type_from_atk_relation_type (AtkRelationType type);
+
+static AtspiRole _object_get_role_impl(void *ptr)
+{
+ AtkObject *obj = (AtkObject*)ptr;
+ AtkRole role = atk_object_get_role (obj);
+ AtspiRole rv = spi_accessible_role_from_atk_role (role);
+ return rv;
+}
+
+static uint64_t _object_get_state_set_impl(void *ptr)
+{
+ dbus_uint32_t array[2];
+ spi_atk_state_to_dbus_array((AtkObject*)ptr, array);
+ uint64_t res = array[0] | ((uint64_t)array[1] << 32);
+ return res;
+}
+
+static void *_get_object_in_relation_by_type_impl(void *ptr, AtspiRelationType expected_relation_type)
+{
+ if (ptr) {
+ g_return_val_if_fail (ATK_IS_OBJECT (ptr), NULL);
+ AtkRelationSet *set = atk_object_ref_relation_set (ptr);
+ if (!set)
+ return NULL;
+ gint count = atk_relation_set_get_n_relations (set), i;
+ 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);
+ AtspiRelationType type = spi_relation_type_from_atk_relation_type (rt);
+ if (expected_relation_type == type)
+ {
+ GPtrArray *target = atk_relation_get_target (r);
+ if (target && target->len > 0)
+ return target->pdata[0];
+ }
+ }
+ g_object_unref (set);
+ }
+ return NULL;
+}
+
+static unsigned char _object_is_zero_size_impl(void *ptr)
+{
+ AtkObject *obj = (AtkObject*)obj;
+ g_return_val_if_fail(ATK_IS_COMPONENT (obj), 0);
+ gint x, y, w, h;
+ atk_component_get_extents (ATK_COMPONENT(obj), &x, &y, &w, &h, ATSPI_COORD_TYPE_SCREEN);
+ return w == 0 || h == 0;
+}
+
+unsigned char _object_is_scrollable_impl(void *ptr)
+{
+ AtspiRole role = _object_get_role_impl(ptr);
+ switch (role) {
+ case ATSPI_ROLE_SCROLL_PANE: //scroller
+ case ATSPI_ROLE_LIST: //genlist, list
+ case ATSPI_ROLE_TREE_TABLE: //gengrid
+ case ATSPI_ROLE_TOOL_BAR: //toolbar
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+void *_get_parent_impl(void *ptr)
+{
+ return atk_object_get_parent((AtkObject*)ptr);
+}
+
+void *_object_at_point_get_impl(void *ptr, int x, int y, unsigned char coordinates_are_screen_based)
+{
+ AtkObject *obj = (AtkObject*)ptr;
+ g_return_val_if_fail(ATK_IS_COMPONENT (obj), 0);
+ return atk_component_ref_accessible_at_point (ATK_COMPONENT(obj), x, y,
+ coordinates_are_screen_based ? ATSPI_COORD_TYPE_SCREEN : ATSPI_COORD_TYPE_WINDOW);
+}
+
+unsigned char _object_contains_impl(void *ptr, int x, int y, unsigned char coordinates_are_screen_based)
+{
+ AtkObject *obj = (AtkObject*)ptr;
+ g_return_val_if_fail(ATK_IS_COMPONENT (obj), 0);
+
+ return atk_component_contains (ATK_COMPONENT(obj), x, y,
+ coordinates_are_screen_based ? ATSPI_COORD_TYPE_SCREEN : ATSPI_COORD_TYPE_WINDOW);
+}
+
+unsigned char _object_is_proxy_impl(void *ptr)
+{
+ return 0;
+}
+
+typedef struct {
+ AtspiRole (*object_get_role)(void *ptr);
+ uint64_t (*object_get_state_set)(void *ptr);
+ void *(*get_object_in_relation_by_type)(void *ptr, AtspiRelationType type);
+ unsigned char (*object_is_zero_size)(void *ptr);
+ void *(*get_parent)(void *ptr);
+ unsigned char (*object_is_scrollable)(void *ptr);
+ void *(*object_at_point_get)(void *ptr, int x, int y, unsigned char coordinates_are_screen_based);
+ unsigned char (*object_contains)(void *ptr, int x, int y, unsigned char coordinates_are_screen_based);
+ unsigned char (*object_is_proxy)(void *ptr);
+} accessibility_navigation_pointer_table;
+
+static unsigned char _accept_object_check_role(accessibility_navigation_pointer_table *table, void *obj)
+{
+ AtspiRole role = table->object_get_role(obj);
+ switch (role)
+ {
+ case ATSPI_ROLE_APPLICATION:
+ case ATSPI_ROLE_FILLER:
+ case ATSPI_ROLE_SCROLL_PANE:
+ case ATSPI_ROLE_SPLIT_PANE:
+ case ATSPI_ROLE_WINDOW:
+ case ATSPI_ROLE_IMAGE:
+ case ATSPI_ROLE_LIST:
+ case ATSPI_ROLE_ICON:
+ case ATSPI_ROLE_TOOL_BAR:
+ case ATSPI_ROLE_REDUNDANT_OBJECT:
+ case ATSPI_ROLE_COLOR_CHOOSER:
+ case ATSPI_ROLE_PANEL:
+ case ATSPI_ROLE_TREE_TABLE:
+ case ATSPI_ROLE_PAGE_TAB_LIST:
+ case ATSPI_ROLE_PAGE_TAB:
+ case ATSPI_ROLE_SPIN_BUTTON:
+ case ATSPI_ROLE_INPUT_METHOD_WINDOW:
+ case ATSPI_ROLE_EMBEDDED:
+ case ATSPI_ROLE_INVALID:
+ case ATSPI_ROLE_NOTIFICATION:
+ return 0;
+ default:
+ break;
+ }
+ return 1;
+}
+
+static unsigned char _state_set_is_set(uint64_t state_set, AtspiStateType state)
+{
+ return (state_set & ((uint64_t)1 << (unsigned int)state)) != 0;
+}
+
+static unsigned char _object_is_item(accessibility_navigation_pointer_table *table, void *obj)
+{
+ AtspiRole role = table->object_get_role(obj);
+ return role == ATSPI_ROLE_LIST_ITEM || role == ATSPI_ROLE_MENU_ITEM;
+}
+
+static unsigned char _object_is_highlightable(accessibility_navigation_pointer_table *table, void *obj)
+{
+ uint64_t state_set = table->object_get_state_set(obj);
+ return _state_set_is_set(state_set, ATSPI_STATE_HIGHLIGHTABLE);
+}
+
+static unsigned char _object_is_showing(accessibility_navigation_pointer_table *table, void *obj)
+{
+ uint64_t state_set = table->object_get_state_set(obj);
+ return _state_set_is_set(state_set, ATSPI_STATE_SHOWING);
+}
+
+static unsigned char _object_is_collapsed(accessibility_navigation_pointer_table *table, void *obj)
+{
+ uint64_t state_set = table->object_get_state_set(obj);
+ return
+ _state_set_is_set(state_set, ATSPI_STATE_EXPANDABLE) &&
+ !_state_set_is_set(state_set, ATSPI_STATE_EXPANDED);
+}
+
+static unsigned char _object_has_modal_state(accessibility_navigation_pointer_table *table, void *obj)
+{
+ uint64_t state_set = table->object_get_state_set(obj);
+ return _state_set_is_set(state_set, ATSPI_STATE_MODAL);
+}
+
+static unsigned char _object_is_zero_size(accessibility_navigation_pointer_table *table, void *obj)
+{
+ return table->object_is_zero_size(obj);
+}
+
+static void *_get_scrollable_parent(accessibility_navigation_pointer_table *table, void *obj)
+{
+ while(obj)
+ {
+ obj = table->get_parent(obj);
+ if (obj && table->object_is_scrollable(obj)) return obj;
+ }
+ return NULL;
+}
+static unsigned char _accept_object(accessibility_navigation_pointer_table *table, void *obj)
+{
+ if (!obj) return 0;
+ if (!_accept_object_check_role(table, obj)) return 0;
+ if (table->get_object_in_relation_by_type(obj, ATSPI_RELATION_CONTROLLED_BY) != NULL) return 0;
+ if (!_object_is_highlightable(table, obj)) return 0;
+
+ if (_get_scrollable_parent(table, obj) != NULL)
+ {
+ void *parent = table->get_parent(obj);
+
+ if (parent)
+ {
+ return !_object_is_item(table, obj) || !_object_is_collapsed(table, parent);
+ }
+ }
+ else
+ {
+ if (_object_is_zero_size(table, obj)) return 0;
+ if (!_object_is_showing(table, obj)) return 0;
+ }
+ return 1;
+}
+
+static void *_calculate_navigable_accessible_at_point_impl(accessibility_navigation_pointer_table *table,
+ void *root, int x, int y, unsigned char coordinates_are_screen_based)
+{
+ if (!root) return NULL;
+
+ void *return_value = NULL;
+ while (1)
+ {
+ void *target = table->object_at_point_get(root, x, y, coordinates_are_screen_based);
+ if (!target) break;
+
+ // always return proxy, so atspi lib can call on it again
+ if (table->object_is_proxy(target)) return target;
+
+ root = target;
+ void *relation_obj = table->get_object_in_relation_by_type(root, ATSPI_RELATION_CONTROLLED_BY);
+ unsigned char contains = 0;
+ if (relation_obj)
+ {
+ contains = table->object_contains(relation_obj, x, y, coordinates_are_screen_based);
+ if (contains) root = relation_obj;
+ }
+
+ if (_accept_object(table, root))
+ {
+ return_value = root;
+ if (contains) break;
+ }
+ }
+
+ if (return_value && _object_has_modal_state(table, return_value)) return_value = NULL;
+ return return_value;
+}
+
+accessibility_navigation_pointer_table construct_accessibility_navigation_pointer_table(void)
+{
+ accessibility_navigation_pointer_table table;
+#define INIT(n) table.n = _## n ## _impl
+ INIT(object_get_role);
+ INIT(object_get_state_set);
+ INIT(get_object_in_relation_by_type);
+ INIT(object_is_zero_size);
+ INIT(get_parent);
+ INIT(object_is_scrollable);
+ INIT(object_at_point_get);
+ INIT(object_contains);
+ INIT(object_is_proxy);
+#undef INIT
+ return table;
+}
+static AtkObject *_calculate_navigable_accessible_at_point(AtkObject *root, unsigned char coord_type, int x, int y)
+{
+ accessibility_navigation_pointer_table table = construct_accessibility_navigation_pointer_table();
+ AtkObject *result = (AtkObject*)_calculate_navigable_accessible_at_point_impl(&table, root, x, y, coord_type ? 1 : 0);
+ return result;
+}
+
+static DBusMessage *
+impl_GetNavigableAtPoint (DBusConnection * bus, DBusMessage * message,
+ void *user_data)
+{
+ AtkObject *object = (AtkObject *) user_data;
+ dbus_int32_t x, y;
+ dbus_uint32_t coord_type;
+ DBusMessage *reply;
+ AtkObject *child;
+
+ g_return_val_if_fail (ATK_IS_COMPONENT (object),
+ droute_not_yet_handled_error (message));
+
+ if (!dbus_message_get_args
+ (message, NULL, DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y,
+ DBUS_TYPE_UINT32, &coord_type, DBUS_TYPE_INVALID))
+ {
+ return droute_invalid_arguments_error (message);
+ }
+ child = (AtkObject*)
+ _calculate_navigable_accessible_at_point (object, coord_type == ATSPI_COORD_TYPE_SCREEN, x, y);
+
+ reply = spi_object_return_reference_and_recurse_flag (message, child, 0);
+ if (child)
+ g_object_unref (child);
+
+ return reply;
+}
+//
static dbus_bool_t
impl_get_Name (DBusMessageIter * iter, void *user_data)
g_return_val_if_fail (ATK_IS_OBJECT (user_data),
droute_not_yet_handled_error (message));
- if (!dbus_message_get_args
+ if (!dbus_message_get_args
(message, NULL, DBUS_TYPE_INT32, &i, DBUS_TYPE_INVALID))
{
return droute_invalid_arguments_error (message);
for (i = 0; i < count; i++)
{
AtkObject *child = atk_object_ref_accessible_child (object, i);
- spi_object_append_reference (&iter_array, child);
+ spi_object_append_reference (&iter_array, child);
if (child)
g_object_unref (child);
}
}
static DRouteMethod methods[] = {
+// TIZEN_ONLY(20170310) - implementation of get object under coordinates for accessibility
+ {impl_GetNavigableAtPoint, "GetNavigableAtPoint"},
+//
{impl_GetChildAtIndex, "GetChildAtIndex"},
{impl_GetChildren, "GetChildren"},
{impl_GetIndexInParent, "GetIndexInParent"},
{
spi_atk_add_interface (path,
ATSPI_DBUS_INTERFACE_ACCESSIBLE,
- spi_org_a11y_atspi_Accessible,
+ spi_org_a11y_atspi_Accessible,
methods, properties);
};