Merge branch 'upstream' into tizen 90/254890/1
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Wed, 10 Mar 2021 08:50:28 +0000 (09:50 +0100)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Wed, 10 Mar 2021 08:50:28 +0000 (09:50 +0100)
Change-Id: Ie83d1576e026d82e7484cba6ec71cd8ed24345ae

16 files changed:
.gbs.conf [new file with mode: 0644]
NEWS
atk-adaptor/accessible-stateset.c
atk-adaptor/adaptors/accessible-adaptor.c
atk-adaptor/adaptors/action-adaptor.c
atk-adaptor/adaptors/collection-adaptor.c
atk-adaptor/adaptors/component-adaptor.c
atk-adaptor/adaptors/socket-adaptor.c
atk-adaptor/bridge.c
atk-adaptor/event.c
atk-adaptor/introspection.c
atk-adaptor/object.c
atk-adaptor/spi-dbus.c
droute/droute.c
packaging/at-spi2-atk.manifest [new file with mode: 0644]
packaging/at-spi2-atk.spec [new file with mode: 0644]

diff --git a/.gbs.conf b/.gbs.conf
new file mode 100644 (file)
index 0000000..99e7cc8
--- /dev/null
+++ b/.gbs.conf
@@ -0,0 +1,3 @@
+[general]
+upstream_branch = upstream
+upstream_tag = upstream/${upstreamversion}
diff --git a/NEWS b/NEWS
index 6170649..2462a55 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -283,7 +283,7 @@ What's new in at-spi2-atk 2.7.2:
 
 * atk-adaptor: don't emit a critical in case the bridge was not initialized
   (BGO#684334).
-    
+
 * Remove dbind (it was only used for the droute test).
 
 * Fix a crash in socket_embed_hook if spi_global_register is NULL.
@@ -425,7 +425,7 @@ What's new in at-spi2-atk 2.3.2:
 
 * Fix for BGO#663876: Make sure the a11y hierarchy under an AtkPlug is
   generated when embedding.
-    
+
 What's new in at-spi2-atk 2.3.1:
 
 * Fix a small coding error that could generate compiler warnings.
index b7888e3..692e652 100644 (file)
@@ -141,6 +141,10 @@ spi_init_state_type_tables (void)
   atk_state_types[ATSPI_STATE_HAS_TOOLTIP] = ATK_STATE_HAS_TOOLTIP;
   accessible_state_types[ATK_STATE_READ_ONLY] = ATSPI_STATE_READ_ONLY;
   atk_state_types[ATSPI_STATE_READ_ONLY] = ATK_STATE_READ_ONLY;
+  accessible_state_types[ATK_STATE_HIGHLIGHTED] = ATSPI_STATE_HIGHLIGHTED;
+  atk_state_types[ATSPI_STATE_HIGHLIGHTED] = ATK_STATE_HIGHLIGHTED;
+  accessible_state_types[ATK_STATE_HIGHLIGHTABLE] = ATSPI_STATE_HIGHLIGHTABLE;
+  atk_state_types[ATSPI_STATE_HIGHLIGHTABLE] = ATK_STATE_HIGHLIGHTABLE;
 
   return TRUE;
 }
index baafda5..e17ab03 100644 (file)
 #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>
+#include <stdlib.h>
+
+// TIZEN_ONLY(20170310) - implementation of get object under coordinates for accessibility
+typedef struct {
+   void **objects;
+   unsigned int capacity;
+   unsigned int size;
+} vector;
+
+typedef enum {
+  NEIGHBOR_SEARCH_MODE_NORMAL = 0,
+  NEIGHBOR_SEARCH_MODE_RECURSE_FROM_ROOT = 1,
+  NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING = 2,
+} GetNeighborSearchMode;
+
+typedef struct accessibility_navigation_pointer_table {
+   AtspiRole (*object_get_role)(struct accessibility_navigation_pointer_table *t, void *ptr);
+   uint64_t (*object_get_state_set)(struct accessibility_navigation_pointer_table *t, void *ptr);
+   void *(*get_object_in_relation_by_type)(struct accessibility_navigation_pointer_table *t, void *ptr, AtspiRelationType type);
+   unsigned char (*object_is_zero_size)(struct accessibility_navigation_pointer_table *t, void *ptr);
+   void *(*get_parent)(struct accessibility_navigation_pointer_table *t, void *ptr);
+   unsigned char (*object_is_scrollable)(struct accessibility_navigation_pointer_table *t, void *ptr);
+   void *(*get_object_at_point)(struct accessibility_navigation_pointer_table *t, void *ptr, int x, int y, unsigned char coordinates_are_screen_based);
+   unsigned char (*object_contains)(struct accessibility_navigation_pointer_table *t, void *ptr, int x, int y, unsigned char coordinates_are_screen_based);
+   unsigned char (*object_is_proxy)(struct accessibility_navigation_pointer_table *t, void *ptr);
+   void (*get_children)(struct accessibility_navigation_pointer_table *t, void *ptr, vector *v);
+} accessibility_navigation_pointer_table;
+
+static vector vector_init(void)
+{
+   vector v;
+   v.objects = NULL;
+   v.capacity = 0;
+   v.size = 0;
+   return v;
+}
+
+static void vector_free(vector *v)
+{
+   free(v->objects);
+   v->objects = NULL;
+   v->capacity = 0;
+   v->size = 0;
+}
+static void vector_reserve(vector *v, unsigned int s)
+{
+   if (s > v->capacity)
+     {
+       v->objects = (void**)realloc(v->objects, sizeof(v->objects[0]) * s);
+       v->capacity = s;
+     }
+}
+
+static void vector_resize(vector *v, unsigned int s)
+{
+   vector_reserve(v, s);
+   v->size = s;
+}
+
+static void *vector_get(vector *v, unsigned int index)
+{
+   return v->objects[index];
+}
+
+static void vector_set(vector *v, unsigned int index, void *data)
+{
+   v->objects[index] = data;
+}
+
+static unsigned int vector_size(vector *v)
+{
+   return v->size;
+}
+
+#define CALL(fncname, ...) table->fncname(table, __VA_ARGS__)
+static unsigned char _accept_object_check_role(accessibility_navigation_pointer_table *table, void *obj)
+{
+   AtspiRole role = CALL(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_defunct(accessibility_navigation_pointer_table *table, void *ptr)
+{
+   uint64_t states = CALL(object_get_state_set, ptr);
+   return _state_set_is_set(states, ATSPI_STATE_DEFUNCT);
+}
+
+static unsigned char _object_role_is_acceptable_when_navigating_next_prev(accessibility_navigation_pointer_table *table, void *obj)
+{
+   AtspiRole role = CALL(object_get_role, obj);
+   return role != ATSPI_ROLE_POPUP_MENU && role != ATSPI_ROLE_DIALOG;
+}
+
+static void *_get_object_in_relation_flow(accessibility_navigation_pointer_table *table, void *source, unsigned char forward)
+{
+    return CALL(get_object_in_relation_by_type, source, forward ? ATSPI_RELATION_FLOWS_TO : ATSPI_RELATION_FLOWS_FROM);
+}
+
+static unsigned char _object_is_item(accessibility_navigation_pointer_table *table, void *obj)
+{
+   AtspiRole role = CALL(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 = CALL(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 = CALL(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 = CALL(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 = CALL(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 CALL(object_is_zero_size, obj);
+}
+
+static void *_get_scrollable_parent(accessibility_navigation_pointer_table *table, void *obj)
+{
+   while(obj)
+     {
+       obj = CALL(get_parent, obj);
+       if (obj && CALL(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 (CALL(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 = CALL(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 = CALL(get_object_at_point, root, x, y, coordinates_are_screen_based);
+       if (!target) break;
+
+       // always return proxy, so atspi lib can call on it again
+       if (CALL(object_is_proxy, target)) return target;
+
+       if (root == target) {
+           // browser likes small cycles in trees
+           // lets decline this party
+           return_value = target;
+           break;
+       }
+
+       root = target;
+       void *relation_obj = CALL(get_object_in_relation_by_type, root, ATSPI_RELATION_CONTROLLED_BY);
+       unsigned char contains = 0;
+       if (relation_obj)
+         {
+           contains = CALL(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;
+}
+
+
+
+
+
+
+
+static void *_find_non_defunct_child(accessibility_navigation_pointer_table *table,
+            vector *objects, unsigned int current_index, unsigned char forward)
+{
+   for(; current_index < vector_size(objects); forward ? ++current_index : --current_index)
+     {
+       void *n = vector_get(objects, current_index);
+       if (n && !_object_is_defunct(table, n)) return n;
+     }
+   return NULL;
+}
+
+static void *_directional_depth_first_search_try_non_defunct_child(accessibility_navigation_pointer_table *table,
+            void *node, vector *children, unsigned char forward)
+{
+   if (vector_size(children) > 0)
+     {
+       unsigned char is_showing = _get_scrollable_parent(table, node) == NULL ? _object_is_showing(table, node) : 1;
+       if (is_showing)
+         {
+           return _find_non_defunct_child(table, children, forward ? 0 : vector_size(children) - 1, forward);
+         }
+     }
+   return NULL;
+}
+
+static void *_get_next_non_defunct_sibling(accessibility_navigation_pointer_table *table,
+            void *obj, unsigned char forward)
+{
+   if (!obj) return NULL;
+   void *parent = CALL(get_parent, obj);
+   if (!parent) return NULL;
+
+   vector children = vector_init();
+   CALL(get_children, parent, &children);
+   if (vector_size(&children) == 0)
+     {
+       vector_free(&children);
+       return NULL;
+     }
+   unsigned int current = 0;
+   for(; current < vector_size(&children) && vector_get(&children, current) != obj; ++current) ;
+   if (current >= vector_size(&children))
+     {
+       vector_free(&children);
+       return NULL;
+     }
+   forward ? ++current : --current;
+   void *ret = _find_non_defunct_child(table, &children, current, forward);
+   vector_free(&children);
+   return ret;
+}
+
+static void *_directional_depth_first_search_try_non_defunct_sibling(accessibility_navigation_pointer_table *table,
+            unsigned char *all_children_visited_ptr, void *node, void *root, unsigned char forward)
+{
+   while(1)
+     {
+       void *sibling = _get_next_non_defunct_sibling(table, node, forward);
+       if (sibling != NULL)
+         {
+           node = sibling;
+           *all_children_visited_ptr = 0;
+           break;
+         }
+
+       // walk up...
+       node = CALL(get_parent, node);
+       if (node == NULL || node == root) return NULL;
+
+       // in backward traversing stop the walk up on parent
+       if (!forward) break;
+     }
+   return node;
+}
+
+typedef struct {
+    const void *key;
+    unsigned int current_search_size;
+    unsigned int counter;
+} cycle_detection_data;
+
+void cycle_detection_initialize(cycle_detection_data *data, const void *key)
+{
+   if (!data) return;
+   data->key = key;
+   data->current_search_size = 1;
+   data->counter = 1;
+}
+
+unsigned char cycle_detection_check_if_in_cycle(cycle_detection_data *data, const void *key)
+{
+   if (!data) return 1;
+   if (data->key == key) return 1;
+   if (--data->counter == 0)
+     {
+       data->current_search_size <<= 1;
+       if (data->current_search_size == 0) return 1;
+       data->counter = data->current_search_size;
+       data->key = key;
+     }
+   return 0;
+}
+
+static void *_calculate_neighbor_impl(accessibility_navigation_pointer_table *table, void *root, void *start, unsigned char forward, GetNeighborSearchMode search_mode)
+{
+   if (root && _object_is_defunct(table, root)) return NULL;
+   if (start && _object_is_defunct(table, start))
+     {
+       start = root;
+       forward = 1;
+     }
+   void *node = start;
+   if (!node) return NULL;
+
+   // initialization of all-children-visiten flag for start node - we assume
+   // that when we begin at start node and we navigate backward, then all children
+   // are visited, so navigation will ignore start's children and go to
+   // previous sibling available.
+   unsigned char all_children_visited = search_mode != NEIGHBOR_SEARCH_MODE_RECURSE_FROM_ROOT && !forward;
+   unsigned char force_next = search_mode == NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING;
+
+   cycle_detection_data cycle_detection;
+   cycle_detection_initialize(&cycle_detection, node);
+   while (node)
+     {
+       if (_object_is_defunct(table, node)) return NULL;
+
+       // always accept proxy object from different world
+       if (!force_next && CALL(object_is_proxy, node)) return node;
+
+       vector children = vector_init();
+       CALL(get_children, node, &children);
+
+       // do accept:
+       // 1. not start node
+       // 2. parent after all children in backward traversing
+       // 3. Nodes with roles: ATSPI_ROLE_PAGE_TAB, ATSPI_ROLE_POPUP_MENU and ATSPI_ROLE_DIALOG, only when looking for first or last element.
+       //    Objects with those roles shouldnt be reachable, when navigating next / prev.
+       unsigned char all_children_visited_or_moving_forward = (vector_size(&children) == 0 || forward || all_children_visited);
+       if (!force_next && node != start && all_children_visited_or_moving_forward && _accept_object(table, node))
+         {
+           if (start == NULL || _object_role_is_acceptable_when_navigating_next_prev(table, node))
+             {
+               vector_free(&children);
+               return node;
+             }
+         }
+
+       void *next_related_in_direction = !force_next ? _get_object_in_relation_flow(table, node, forward) : NULL;
+
+       if (next_related_in_direction && _object_is_defunct(table, next_related_in_direction))
+           next_related_in_direction = NULL;
+       unsigned char want_cycle_detection = 0;
+       if (next_related_in_direction)
+         {
+           node = next_related_in_direction;
+           want_cycle_detection = 1;
+         }
+       else {
+           void *child = !force_next && !all_children_visited ?
+                          _directional_depth_first_search_try_non_defunct_child(table, node, &children, forward) : NULL;
+           if (child != NULL) want_cycle_detection = 1;
+           else
+             {
+               if (!force_next && node == root)
+                 {
+                   vector_free(&children);
+                   return NULL;
+                 }
+               all_children_visited = 1;
+               child = _directional_depth_first_search_try_non_defunct_sibling(table, &all_children_visited, node, root, forward);
+             }
+           node = child;
+       }
+
+       force_next = 0;
+       if (want_cycle_detection && cycle_detection_check_if_in_cycle(&cycle_detection, node))
+         {
+           vector_free(&children);
+           return NULL;
+         }
+       vector_free(&children);
+     }
+   return NULL;
+}
+
+
+
+
+static AtspiRelationType spi_relation_type_from_atk_relation_type (AtkRelationType type);
+#define MARK_AS_UNUSED(v) do { (void)(v); } while(0)
+
+static AtspiRole _object_get_role_impl(accessibility_navigation_pointer_table *table, void *ptr)
+{
+  MARK_AS_UNUSED(table);
+  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(accessibility_navigation_pointer_table *table, void *ptr)
+{
+  MARK_AS_UNUSED(table);
+  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(accessibility_navigation_pointer_table *table, void *ptr, AtspiRelationType expected_relation_type)
+{
+  MARK_AS_UNUSED(table);
+  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(accessibility_navigation_pointer_table *table, void *ptr)
+{
+  MARK_AS_UNUSED(table);
+  AtkObject *obj = (AtkObject*)ptr;
+  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(accessibility_navigation_pointer_table *table, void *ptr)
+{
+  AtspiRole role = _object_get_role_impl(table, 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(accessibility_navigation_pointer_table *table, void *ptr)
+{
+  MARK_AS_UNUSED(table);
+  return atk_object_get_parent((AtkObject*)ptr);
+}
+
+void *_get_object_at_point_impl(accessibility_navigation_pointer_table *table, void *ptr, int x, int y, unsigned char coordinates_are_screen_based)
+{
+  MARK_AS_UNUSED(table);
+  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(accessibility_navigation_pointer_table *table, void *ptr, int x, int y, unsigned char coordinates_are_screen_based)
+{
+  MARK_AS_UNUSED(table);
+  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(accessibility_navigation_pointer_table *table, void *ptr)
+{
+  MARK_AS_UNUSED(table);
+  return 0;
+}
+
+void _get_children_impl(accessibility_navigation_pointer_table *table, void *ptr, vector *v)
+{
+  MARK_AS_UNUSED(table);
+    AtkObject *obj = (AtkObject*)ptr;
+    gint count = atk_object_get_n_accessible_children (obj);
+    vector_resize(v, (unsigned int)count);
+
+    gint i, index = 0;
+    for (i = 0; i < count; i++) {
+        AtkObject *child = atk_object_ref_accessible_child (obj, i);
+        if (child) {
+            vector_set(v, index, child);
+            ++index;
+            g_object_unref (child);
+        }
+    }
+    vector_resize(v, index);
+}
+
+
+
+
+
+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(get_object_at_point);
+   INIT(object_contains);
+   INIT(object_is_proxy);
+   INIT(get_children);
+#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 AtkObject *_calculate_neighbor(AtkObject *root, AtkObject *start, unsigned char forward, GetNeighborSearchMode search_mode)
+{
+   accessibility_navigation_pointer_table table = construct_accessibility_navigation_pointer_table();
+   AtkObject *result = (AtkObject*)_calculate_neighbor_impl(&table, root, start, forward ? 1 : 0, search_mode);
+   return result;
+}
+
+static DBusMessage *
+impl_GetNeighbor (DBusConnection * bus, DBusMessage * message, void *user_data)
+{
+  AtkObject *start = (AtkObject *) user_data;
+  dbus_uint32_t direction, search_mode;
+  const char *root_path = NULL;
+  DBusMessage *reply;
+  AtkObject *child;
+
+  if (!dbus_message_get_args
+      (message, NULL, DBUS_TYPE_STRING, &root_path, DBUS_TYPE_INT32, &direction, DBUS_TYPE_INT32, &search_mode, DBUS_TYPE_INVALID))
+    {
+      return droute_invalid_arguments_error (message);
+    }
+
+  AtkObject *root_object = (AtkObject*)spi_global_register_path_to_object(root_path);
+  child = _calculate_neighbor (root_object, start, direction == 1, search_mode);
+  reply = dbus_message_new_method_return (message);
+  if (reply)
+    {
+      DBusMessageIter iter;
+      dbus_message_iter_init_append (reply, &iter);
+      spi_object_append_reference (&iter, child);
+
+      unsigned char recurse = 0;
+      dbus_message_iter_append_basic (&iter, DBUS_TYPE_BYTE, &recurse);
+    }
+
+  return reply;
+}
+
+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;
+
+  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 = _calculate_navigable_accessible_at_point (object, coord_type == ATSPI_COORD_TYPE_SCREEN, x, y);
+  reply = dbus_message_new_method_return (message);
+  if (reply)
+    {
+      DBusMessageIter iter;
+      dbus_message_iter_init_append (reply, &iter);
+      spi_object_append_reference (&iter, child);
+
+      unsigned char recurse = 0;
+      dbus_message_iter_append_basic (&iter, DBUS_TYPE_BYTE, &recurse);
+
+      /* deputy */
+      spi_object_append_null_reference (&iter);
+    }
+
+  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, &current_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, &current_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
 impl_get_Name (DBusMessageIter * iter, void *user_data)
@@ -151,7 +1120,7 @@ impl_GetChildAtIndex (DBusConnection * bus,
 
   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);
@@ -168,8 +1137,10 @@ impl_GetChildAtIndex (DBusConnection * bus,
           DBusMessageIter iter, iter_socket;
           *(child_path++) = '\0';
           reply = dbus_message_new_method_return (message);
-          if (!reply)
+          if (!reply) {
+            g_free (child_name);
             return NULL;
+          }
           dbus_message_iter_init_append (reply, &iter);
           dbus_message_iter_open_container (&iter, DBUS_TYPE_STRUCT, NULL,
                                             &iter_socket);
@@ -211,7 +1182,7 @@ impl_GetChildren (DBusConnection * bus,
   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);
     }
@@ -539,6 +1510,11 @@ impl_get_AccessibleId (DBusMessageIter * iter, void *user_data)
 }
 
 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"},
   {impl_GetIndexInParent, "GetIndexInParent"},
@@ -569,6 +1545,6 @@ spi_initialize_accessible (DRoutePath * path)
 {
   spi_atk_add_interface (path,
                          ATSPI_DBUS_INTERFACE_ACCESSIBLE,
-                         spi_org_a11y_atspi_Accessible,        
+                         spi_org_a11y_atspi_Accessible,
                          methods, properties);
 };
index 784d136..0c5bd03 100644 (file)
@@ -22,6 +22,7 @@
  * Boston, MA 02110-1301, USA.
  */
 
+#include <string.h>
 #include <atk/atk.h>
 #include <droute/droute.h>
 #include "bridge.h"
@@ -227,6 +228,46 @@ impl_DoAction (DBusConnection * bus, DBusMessage * message, void *user_data)
   return NULL;
 }
 
+static DBusMessage *
+impl_DoActionName (DBusConnection * bus, DBusMessage * message, void *user_data)
+{
+  AtkAction *action = (AtkAction *) user_data;
+  const char *action_name = NULL;
+  gint count;
+  gint i, index = -1;
+  dbus_bool_t rv = TRUE;
+  DBusMessage *reply;
+
+  g_return_val_if_fail (ATK_IS_ACTION (user_data),
+                        droute_not_yet_handled_error (message));
+  if (!dbus_message_get_args
+      (message, NULL, DBUS_TYPE_STRING, &action_name, DBUS_TYPE_INVALID))
+    {
+      return droute_invalid_arguments_error (message);
+    }
+  reply = dbus_message_new_method_return (message);
+  if (reply)
+    {
+      dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &rv,
+                                DBUS_TYPE_INVALID);
+    }
+  dbus_connection_send (bus, reply, NULL);
+  dbus_message_unref (reply);
+
+  count = atk_action_get_n_actions (action);
+  for (i = 0; i < count; i++)
+    {
+      const char *name = atk_action_get_name (action, i);
+      if (name && !strcmp(name, action_name))
+        {
+          index = i;
+          break;
+        }
+    }
+  atk_action_do_action (action, index);
+  return NULL;
+}
+
 DRouteMethod methods[] = {
   {impl_get_description, "GetDescription"}
   ,
@@ -240,6 +281,8 @@ DRouteMethod methods[] = {
   ,
   {impl_DoAction, "DoAction"}
   ,
+  {impl_DoActionName, "DoActionName"}
+  ,
   {NULL, NULL}
 };
 
index a6ec282..296c91a 100644 (file)
@@ -1181,7 +1181,7 @@ skip (const char **p)
   }
   *p = sig;
 }
+
 static gboolean
 types_match (DBusMessageIter *iter, char c)
 {
@@ -1232,7 +1232,7 @@ walk (DBusMessageIter *iter, const char *sig, gboolean array)
         dbus_message_iter_recurse (iter, &iter_struct);
         walk (&iter_struct, sig + 1, FALSE);
         skip (&sig);
-      }   
+      }
     }
     dbus_message_iter_next (iter);
     if (!array)
@@ -1270,12 +1270,12 @@ impl_GetTree (DBusConnection * bus,
   if (strcmp (dbus_message_get_signature (message), "(aiia{ss}iaiiasib)as") != 0)
     return droute_invalid_arguments_error (message);
 
-  properties = g_array_new (TRUE, TRUE, sizeof (char *));
   dbus_message_iter_init (message, &iter);
   if (!read_mr (&iter, &rule))
     {
       return spi_dbus_general_error (message);
     }
+  properties = g_array_new (TRUE, TRUE, sizeof (char *));
 
   dbus_message_iter_recurse (&iter, &iter_array);
   while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
@@ -1298,6 +1298,7 @@ impl_GetTree (DBusConnection * bus,
 #if 0
   walkm (reply);
 #endif
+  g_array_free (properties, TRUE);
   return reply;
 }
 
index 11bded0..b5eb77c 100644 (file)
@@ -252,6 +252,46 @@ impl_GrabFocus (DBusConnection * bus, DBusMessage * message, void *user_data)
   return reply;
 }
 
+static DBusMessage *
+impl_GrabHighlight (DBusConnection * bus, DBusMessage * message, void *user_data)
+{
+  AtkComponent *component = (AtkComponent *) user_data;
+  dbus_bool_t rv;
+  DBusMessage *reply;
+
+  g_return_val_if_fail (ATK_IS_COMPONENT (user_data),
+                        droute_not_yet_handled_error (message));
+
+  rv = atk_component_grab_highlight (component);
+  reply = dbus_message_new_method_return (message);
+  if (reply)
+    {
+      dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &rv,
+                                DBUS_TYPE_INVALID);
+    }
+  return reply;
+}
+
+static DBusMessage *
+impl_ClearHighlight (DBusConnection * bus, DBusMessage * message, void *user_data)
+{
+  AtkComponent *component = (AtkComponent *) user_data;
+  dbus_bool_t rv;
+  DBusMessage *reply;
+
+  g_return_val_if_fail (ATK_IS_COMPONENT (user_data),
+                        droute_not_yet_handled_error (message));
+
+  rv = atk_component_clear_highlight (component);
+  reply = dbus_message_new_method_return (message);
+  if (reply)
+    {
+      dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &rv,
+                                DBUS_TYPE_INVALID);
+    }
+  return reply;
+}
+
 #if 0
 static DBusMessage *
 impl_registerFocusHandler (DBusConnection * bus, DBusMessage * message,
@@ -388,6 +428,14 @@ impl_get_ScreenExtents (DBusMessageIter * iter, void *user_data)
   return TRUE;
 }
 
+static dbus_bool_t
+impl_get_HighlightIndex (DBusMessageIter * iter, void *user_data)
+{
+  AtkComponent *component = (AtkComponent *) user_data;
+  g_return_val_if_fail (ATK_IS_COMPONENT (user_data), -1);
+  return droute_return_v_int32 (iter, atk_component_get_highlight_index (component));
+}
+
 static DBusMessage *
 impl_SetSize (DBusConnection * bus, DBusMessage * message, void *user_data)
 {
@@ -489,6 +537,8 @@ static DRouteMethod methods[] = {
   {impl_GetLayer, "GetLayer"},
   {impl_GetMDIZOrder, "GetMDIZOrder"},
   {impl_GrabFocus, "GrabFocus"},
+  {impl_GrabHighlight, "GrabHighlight"},
+  {impl_ClearHighlight, "ClearHighlight"},
   //{impl_registerFocusHandler, "registerFocusHandler"},
   //{impl_deregisterFocusHandler, "deregisterFocusHandler"},
   {impl_GetAlpha, "GetAlpha"},
@@ -502,6 +552,7 @@ static DRouteMethod methods[] = {
 
 static DRouteProperty properties[] = {
   {impl_get_ScreenExtents, NULL, "ScreenExtents"},
+  {impl_get_HighlightIndex, NULL, "HighlightIndex"},
   {NULL, NULL, NULL}
 };
 void
index 0f7c1b3..5e0ae7b 100644 (file)
@@ -202,9 +202,18 @@ impl_Embedded (DBusConnection *bus,
     {
       AtkComponent *component = ATK_COMPONENT (object);
       AtkComponentIface *iface = ATK_COMPONENT_GET_IFACE (component);
-      iface->get_extents = atspi_plug_component_get_extents;
-      iface->get_size = atspi_plug_component_get_size;
-      iface->get_position = atspi_plug_component_get_position;
+      if (!iface->get_extents)
+        {
+          iface->get_extents = atspi_plug_component_get_extents;
+        }
+      if (!iface->get_size)
+        {
+          iface->get_size = atspi_plug_component_get_size;
+        }
+      if (!iface->get_position)
+        {
+          iface->get_position = atspi_plug_component_get_position;
+        }
     }
 
   /* Retrieve some info about the children, if they exist, when
index 8579185..d4a9d87 100644 (file)
@@ -201,7 +201,11 @@ add_property_to_event (event_data *evdata, const char *property)
   }
 
   prop->name = g_strdup (property);
-  evdata->properties = g_slist_append (evdata->properties, prop);
+
+  if (evdata)
+  {
+    evdata->properties = g_slist_append (evdata->properties, prop);
+  }
 }
 
 static void
@@ -303,6 +307,7 @@ get_registered_event_listeners (SpiBridge *app)
 {
   DBusMessage *message;
   DBusPendingCall *pending = NULL;
+  dbus_bool_t result;
 
   message = dbus_message_new_method_call (SPI_DBUS_NAME_REGISTRY,
                                          ATSPI_DBUS_PATH_REGISTRY,
@@ -311,9 +316,9 @@ get_registered_event_listeners (SpiBridge *app)
   if (!message)
     return;
 
-  dbus_connection_send_with_reply (app->bus, message, &pending, -1);
+  result = dbus_connection_send_with_reply (app->bus, message, &pending, -1);
   dbus_message_unref (message);
-  if (!pending)
+  if (!result || !pending)
     {
       spi_global_app_data->events_initialized = TRUE;
       return;
@@ -327,9 +332,9 @@ get_registered_event_listeners (SpiBridge *app)
   if (!message)
     return;
   pending = NULL;
-  dbus_connection_send_with_reply (app->bus, message, &pending, -1);
+  result = dbus_connection_send_with_reply (app->bus, message, &pending, -1);
   dbus_message_unref (message);
-  if (!pending)
+  if (!result || !pending)
     {
       spi_global_app_data->events_initialized = TRUE;
       return;
@@ -343,9 +348,9 @@ get_registered_event_listeners (SpiBridge *app)
   if (!message)
     return;
   pending = NULL;
-  dbus_connection_send_with_reply (app->bus, message, &pending, -1);
+  result = dbus_connection_send_with_reply (app->bus, message, &pending, -1);
   dbus_message_unref (message);
-  if (!pending)
+  if (!result || !pending)
     {
       spi_global_app_data->events_initialized = TRUE;
       return;
@@ -420,7 +425,7 @@ register_application (gpointer data)
 
   dbus_message_iter_init_append (message, &iter);
   spi_object_append_reference (&iter, app->root);
-  
+
     if (!dbus_connection_send_with_reply (app->bus, message, &pending, -1)
         || !pending)
     {
@@ -1072,7 +1077,7 @@ atk_bridge_adaptor_init (gint * argc, gchar ** argv[])
   /* Hook our plug-and socket functions */
   install_plug_hooks ();
 
-  /* 
+  /*
    * Create the leasing, register and cache objects.
    * The order is important here, the cache depends on the
    * register object.
index bd38eef..280973f 100644 (file)
@@ -972,7 +972,7 @@ text_insert_event_listener (GSignalInvocationHint * signal_hint,
   guint text_changed_signal_id;
   GSignalQuery signal_query;
   const gchar *name;
-  const gchar *minor_raw, *text;
+  const gchar *minor_raw, *text = NULL;
   gchar *minor;
   gint detail1 = 0, detail2 = 0;
 
@@ -1003,8 +1003,9 @@ text_insert_event_listener (GSignalInvocationHint * signal_hint,
   else
     text = "";
 
-  emit_event (accessible, ITF_EVENT_OBJECT, name, minor, detail1, detail2,
-              DBUS_TYPE_STRING_AS_STRING, text, append_basic);
+  if (text != NULL)
+    emit_event (accessible, ITF_EVENT_OBJECT, name, minor, detail1, detail2,
+                DBUS_TYPE_STRING_AS_STRING, text, append_basic);
   g_free (minor);
   return TRUE;
 }
@@ -1023,7 +1024,7 @@ text_remove_event_listener (GSignalInvocationHint * signal_hint,
   guint text_changed_signal_id;
   GSignalQuery signal_query;
   const gchar *name;
-  const gchar *minor_raw, *text;
+  const gchar *minor_raw, *text = NULL;
   gchar *minor;
   gint detail1 = 0, detail2 = 0;
 
@@ -1054,8 +1055,9 @@ text_remove_event_listener (GSignalInvocationHint * signal_hint,
   else
     text = "";
 
-  emit_event (accessible, ITF_EVENT_OBJECT, name, minor, detail1, detail2,
-              DBUS_TYPE_STRING_AS_STRING, text, append_basic);
+  if (text != NULL)
+    emit_event (accessible, ITF_EVENT_OBJECT, name, minor, detail1, detail2,
+                DBUS_TYPE_STRING_AS_STRING, text, append_basic);
   g_free (minor);
   return TRUE;
 }
index e017449..6709e2c 100644 (file)
@@ -25,6 +25,10 @@ const char *spi_org_a11y_atspi_Accessible =
 ""
 "  <property access=\"read\" name=\"Locale\" type=\"s\" />"
 ""
+"  <method name=\"impl_GetReadingMaterial\">"
+"    <arg direction=\"out\" type=\"a{ss}sssuausiddddsibbii(so)auiui(so)\" />"
+"  </method>"
+""
 "  <method name=\"GetChildAtIndex\">"
 "    <arg direction=\"in\" name=\"index\" type=\"i\" />"
 "    <arg direction=\"out\" type=\"(so)\" />"
@@ -190,6 +194,8 @@ const char *spi_org_a11y_atspi_Collection =
 const char *spi_org_a11y_atspi_Component = 
 "<interface name=\"org.a11y.atspi.Component\" version=\"0.1.7\">"
 ""
+"  <property access=\"read\" name=\"HighlightIndex\" type=\"i\" />"
+""
 "  <method name=\"Contains\">"
 "    <arg direction=\"in\" name=\"x\" type=\"i\" />"
 "    <arg direction=\"in\" name=\"y\" type=\"i\" />"
@@ -234,6 +240,14 @@ const char *spi_org_a11y_atspi_Component =
 "    <arg direction=\"out\" type=\"b\" />"
 "  </method>"
 ""
+"  <method name=\"GrabHighlight\">"
+"    <arg direction=\"out\" type=\"b\" />"
+"  </method>"
+""
+"  <method name=\"ClearHighlight\">"
+"    <arg direction=\"out\" type=\"b\" />"
+"  </method>"
+""
 "  <method name=\"GetAlpha\">"
 "    <arg direction=\"out\" type=\"d\" />"
 "  </method>"
index 27b660b..d84e64e 100644 (file)
@@ -114,7 +114,7 @@ spi_object_append_reference (DBusMessageIter * iter, AtkObject * obj)
   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
   dbus_message_iter_close_container (iter, &iter_struct);
-  
+
   g_free (path);
 }
 
@@ -145,7 +145,7 @@ spi_hyperlink_append_reference (DBusMessageIter * iter, AtkHyperlink * obj)
   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
   dbus_message_iter_close_container (iter, &iter_struct);
-  
+
   g_free (path);
 }
 
index 4bc2a5b..0df986a 100644 (file)
@@ -76,7 +76,10 @@ void spi_dbus_emit_valist(DBusConnection *bus, const char *path, const char *int
   sig = dbus_message_new_signal(path, interface, name);
   if (first_arg_type != DBUS_TYPE_INVALID)
   {
-    dbus_message_append_args_valist(sig, first_arg_type, args);
+    if (dbus_message_append_args_valist(sig, first_arg_type, args) == FALSE) {
+      dbus_message_unref(sig);
+      return;
+    }
   }
   dbus_connection_send(bus, sig, NULL);
   dbus_message_unref(sig);
index 3955a91..fb0d0b2 100644 (file)
@@ -354,7 +354,7 @@ impl_prop_GetSet (DBusMessage *message,
 
     if (get && prop_funcs->get)
       {
-        
+
         DBusMessageIter iter;
 
         _DROUTE_DEBUG ("DRoute (handle prop Get): %s|%s on %s\n", pair.one, pair.two, pathstr);
@@ -603,7 +603,7 @@ handle_message (DBusConnection *bus, DBusMessage *message, void *user_data)
     if (result == DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
         g_print ("DRoute | Unhandled message: %s|%s of type %d on %s\n", member, iface, type, pathstr);
 #endif
-      
+
     return result;
 }
 
diff --git a/packaging/at-spi2-atk.manifest b/packaging/at-spi2-atk.manifest
new file mode 100644 (file)
index 0000000..017d22d
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+ <request>
+    <domain name="_"/>
+ </request>
+</manifest>
diff --git a/packaging/at-spi2-atk.spec b/packaging/at-spi2-atk.spec
new file mode 100644 (file)
index 0000000..fa469ea
--- /dev/null
@@ -0,0 +1,83 @@
+Name: at-spi2-atk
+Version: 2.34.1
+Release: 1
+Summary: Assistive Technology Service Provider Interface - GTK+ module
+License: LGPL-2.1+
+Group: System/Libraries
+Url: http://www.gnome.org/
+Source: http://download.gnome.org/sources/at-spi2-atk/2.30/%{name}-%{version}.tar.xz
+Source1001: %{name}.manifest
+Requires: at-spi2-core
+BuildRequires: dbus-devel
+BuildRequires: glib2-devel
+BuildRequires: atk-devel
+BuildRequires: at-spi2-core-devel
+BuildRequires: gettext
+BuildRequires: libxml2-devel >= 2.9.1
+BuildRequires: meson
+
+%description
+AT-SPI is a general interface for applications to make use of the
+accessibility toolkit. This version is based on dbus.
+
+%package -n libatk-bridge-2_0-0
+Summary: ATK/D-Bus bridging library
+Group: System/Libraries
+
+%description -n libatk-bridge-2_0-0
+AT-SPI is a general interface for applications to make use of the
+accessibility toolkit. This version is based on dbus.
+
+The package contains a ATK/D-Bus bridge library.
+
+%package devel
+Summary: Assistive Technology Service Provider Interface - Developent files
+Group: System/Libraries
+Requires: libatk-bridge-2_0-0 = %{version}
+
+%description devel
+AT-SPI is a general interface for applications to make use of the
+accessibility toolkit. This version is based on dbus.
+
+%prep
+%setup -q
+cp %{SOURCE1001} .
+
+%build
+meson --prefix /usr --libdir %{_libdir} build -Ddisable_p2p=true
+ninja -C build all
+
+%install
+rm -rf %{buildroot}
+
+export DESTDIR=%{buildroot}
+ninja -C build install
+
+find %{buildroot} -name '*.la' -or -name '*.a' | xargs rm -f
+find %{buildroot} -name '*.desktop' | xargs rm -f
+
+%clean
+rm -rf %{buildroot}
+
+%post -n libatk-bridge-2_0-0 -p /sbin/ldconfig
+
+%postun -n libatk-bridge-2_0-0 -p /sbin/ldconfig
+
+%files -n libatk-bridge-2_0-0
+%manifest %{name}.manifest
+%defattr(-,root,root)
+%{_libdir}/libatk-bridge-2.0.so.*
+%{_libdir}/gtk-2.0/modules/libatk-bridge.so
+%license COPYING
+
+%files devel
+%manifest %{name}.manifest
+%defattr(-,root,root)
+%{_includedir}/at-spi2-atk/2.0/atk-bridge.h
+%{_libdir}/libatk-bridge-2.0.so
+%{_libdir}/pkgconfig/atk-bridge-2.0.pc
+
+%changelog
+* Mon Mar 25 2013 tomasz.duszynski@comarch.com
+- Initial packaging of at-spi2-atk (2.5.92)
+