summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Stanislawski <l.stanislaws@samsung.com>2014-02-07 23:03:07 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2014-02-07 23:03:07 +0900
commit71cd5a1a077807bc32a67d309fba9e1474fffa4d (patch)
treecfb1f6cfb868921e08845bf73432e29bd7f13cf7
parente20875ffc315c68f17f51c49ec1f62fe1013de5b (diff)
atspi: event broadcast added. Orca screen reader now ables to read UI.
Summary: added broadcast of focus, window activate/deactivate events on a11y bus Orca screen reader is now able to read elementary application. Reviewers: raster, seoz, z.kosinski, kimcinoo Reviewed By: raster Differential Revision: https://phab.enlightenment.org/D508
-rw-r--r--src/lib/elm_atspi_bridge.c726
-rw-r--r--src/lib/elm_atspi_object.c971
-rw-r--r--src/lib/elm_atspi_object_common.h23
-rw-r--r--src/lib/elm_atspi_object_eo.h90
-rw-r--r--src/lib/elm_atspi_object_legacy.h3
-rw-r--r--src/lib/elm_widget.c16
6 files changed, 1361 insertions, 468 deletions
diff --git a/src/lib/elm_atspi_bridge.c b/src/lib/elm_atspi_bridge.c
index 5963e6a87..cbede6cf4 100644
--- a/src/lib/elm_atspi_bridge.c
+++ b/src/lib/elm_atspi_bridge.c
@@ -5,6 +5,7 @@
5#include <stdint.h> 5#include <stdint.h>
6#include <Elementary.h> 6#include <Elementary.h>
7#include "elm_priv.h" 7#include "elm_priv.h"
8#include <assert.h>
8 9
9#include "atspi/atspi-constants.h" 10#include "atspi/atspi-constants.h"
10 11
@@ -14,6 +15,7 @@
14#define A11Y_DBUS_NAME "org.a11y.Bus" 15#define A11Y_DBUS_NAME "org.a11y.Bus"
15#define A11Y_DBUS_PATH "/org/a11y/bus" 16#define A11Y_DBUS_PATH "/org/a11y/bus"
16#define A11Y_DBUS_INTERFACE "org.a11y.Bus" 17#define A11Y_DBUS_INTERFACE "org.a11y.Bus"
18#define ATSPI_DBUS_INTERFACE_EVENT_WINDOW "org.a11y.atspi.Event.Window"
17 19
18#define CACHE_ITEM_SIGNATURE "((so)(so)(so)a(so)assusau)" 20#define CACHE_ITEM_SIGNATURE "((so)(so)(so)a(so)assusau)"
19#define CACHE_INTERFACE_PATH "/org/a11y/atspi/cache" 21#define CACHE_INTERFACE_PATH "/org/a11y/atspi/cache"
@@ -23,24 +25,137 @@
23#define ELM_ACCESS_OBJECT_REFERENCE_TEMPLATE ELM_ACCESS_OBJECT_PATH_PREFIX "%llu" 25#define ELM_ACCESS_OBJECT_REFERENCE_TEMPLATE ELM_ACCESS_OBJECT_PATH_PREFIX "%llu"
24 26
25static int _init_count = 0; 27static int _init_count = 0;
28
26static Eldbus_Connection *_a11y_bus = NULL; 29static Eldbus_Connection *_a11y_bus = NULL;
27static Elm_Atspi_Object *_root; 30static Elm_Atspi_Object *_root;
28static Eina_Hash *_cache; 31static Eina_Hash *_cache;
29static Eldbus_Service_Interface *_cache_interface = NULL; 32static Eldbus_Service_Interface *_cache_interface = NULL;
33static Eldbus_Signal_Handler *_register_hdl;
34static Eldbus_Signal_Handler *_unregister_hdl;
35static unsigned short _object_property_broadcast_mask;
36static unsigned short _object_children_broadcast_mask;
37static unsigned long long _object_state_broadcast_mask;
38static unsigned long long _window_signal_broadcast_mask;
39
40static void _cache_update(void);
30static Elm_Atspi_Object * _access_object_from_path(const char *path); 41static Elm_Atspi_Object * _access_object_from_path(const char *path);
31static char * _path_from_access_object(Elm_Atspi_Object *eo); 42static char * _path_from_access_object(Elm_Atspi_Object *eo);
32static void object_append_reference(Eldbus_Message_Iter *iter, Elm_Atspi_Object *obj); 43static void object_append_reference(Eldbus_Message_Iter *iter, Elm_Atspi_Object *obj);
33static void object_append_desktop_reference(Eldbus_Message_Iter *iter); 44static void object_append_desktop_reference(Eldbus_Message_Iter *iter);
34static const Eldbus_Service_Interface_Desc accessible_iface_desc; 45static const Eldbus_Service_Interface_Desc accessible_iface_desc;
46static void _cache_object_register(Elm_Atspi_Object *node, Eina_Bool rec);
47
48
49enum _Atspi_Object_Child_Event_Type
50{
51 ATSPI_OBJECT_CHILD_ADDED = 0,
52 ATSPI_OBJECT_CHILD_REMOVED
53};
54
55enum _Atspi_Object_Property
56{
57 ATSPI_OBJECT_PROPERTY_NAME = 0,
58 ATSPI_OBJECT_PROPERTY_DESCRIPTION,
59 ATSPI_OBJECT_PROPERTY_VALUE,
60 ATSPI_OBJECT_PROPERTY_ROLE,
61 ATSPI_OBJECT_PROPERTY_PARENT,
62};
63
64enum _Atspi_Object_Signals {
65 ATSPI_OBJECT_EVENT_PROPERTY_CHANGED,
66 ATSPI_OBJECT_EVENT_BOUNDS_CHANGED,
67 ATSPI_OBJECT_EVENT_LINK_SELECTED,
68 ATSPI_OBJECT_EVENT_STATE_CHANGED,
69 ATSPI_OBJECT_EVENT_CHILDREN_CHANGED,
70 ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED,
71 ATSPI_OBJECT_EVENT_SELECTION_CHANGED,
72 ATSPI_OBJECT_EVENT_MODEL_CHANGED,
73 ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED,
74 ATSPI_OBJECT_EVENT_ROW_INSERTED,
75 ATSPI_OBJECT_EVENT_ROW_REORDERED,
76 ATSPI_OBJECT_EVENT_ROW_DELETED,
77 ATSPI_OBJECT_EVENT_COLUMN_INSERTED,
78 ATSPI_OBJECT_EVENT_COLUMN_REORDERED,
79 ATSPI_OBJECT_EVENT_COLUMN_DELETED,
80 ATSPI_OBJECT_EVENT_TEXT_BOUNDS_CHANGED,
81 ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED,
82 ATSPI_OBJECT_EVENT_TEXT_CHANGED,
83 ATSPI_OBJECT_EVENT_TEXT_ATTRIBUTES_CHANGED,
84 ATSPI_OBJECT_EVENT_TEXT_CARET_MOVED,
85 ATSPI_OBJECT_EVENT_ATTRIBUTES_CHANGED,
86};
35 87
36enum 88enum _Atspi_Window_Signals
37{ 89{
38 ADD_ACCESSIBLE = 0, 90 ATSPI_WINDOW_EVENT_PROPERTY_CHANGE,
39 REMOVE_ACCESSIBLE 91 ATSPI_WINDOW_EVENT_MINIMIZE,
92 ATSPI_WINDOW_EVENT_MAXIMIZE,
93 ATSPI_WINDOW_EVENT_RESTORE,
94 ATSPI_WINDOW_EVENT_CLOSE,
95 ATSPI_WINDOW_EVENT_CREATE,
96 ATSPI_WINDOW_EVENT_REPARENT,
97 ATSPI_WINDOW_EVENT_DESKTOPCREATE,
98 ATSPI_WINDOW_EVENT_DESKTOPDESTROY,
99 ATSPI_WINDOW_EVENT_DESTROY,
100 ATSPI_WINDOW_EVENT_ACTIVATE,
101 ATSPI_WINDOW_EVENT_DEACTIVATE,
102 ATSPI_WINDOW_EVENT_RAISE,
103 ATSPI_WINDOW_EVENT_LOWER,
104 ATSPI_WINDOW_EVENT_MOVE,
105 ATSPI_WINDOW_EVENT_RESIZE,
106 ATSPI_WINDOW_EVENT_SHADE,
107 ATSPI_WINDOW_EVENT_UUSHADE,
108 ATSPI_WINDOW_EVENT_RESTYLE,
109};
110
111static const Eldbus_Signal _event_obj_signals[] = {
112 [ATSPI_OBJECT_EVENT_PROPERTY_CHANGED] = {"PropertyChange", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
113 [ATSPI_OBJECT_EVENT_BOUNDS_CHANGED] = {"BoundsChange", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
114 [ATSPI_OBJECT_EVENT_LINK_SELECTED] = {"LinkSelected", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
115 [ATSPI_OBJECT_EVENT_STATE_CHANGED] = {"StateChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
116 [ATSPI_OBJECT_EVENT_CHILDREN_CHANGED] = {"ChildrenChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
117 [ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED] = {"VisibleDataChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
118 [ATSPI_OBJECT_EVENT_SELECTION_CHANGED] = {"SelectionChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
119 [ATSPI_OBJECT_EVENT_MODEL_CHANGED] = {"ModelChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
120 [ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED] = {"ActiveDescendantsChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
121 [ATSPI_OBJECT_EVENT_ROW_INSERTED] = {"RowInserted", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
122 [ATSPI_OBJECT_EVENT_ROW_REORDERED] = {"RowReordered", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
123 [ATSPI_OBJECT_EVENT_ROW_DELETED] = {"RowDeleted", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
124 [ATSPI_OBJECT_EVENT_COLUMN_INSERTED] = {"ColumnInserted", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
125 [ATSPI_OBJECT_EVENT_COLUMN_REORDERED] = {"ColumnReordered", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
126 [ATSPI_OBJECT_EVENT_COLUMN_DELETED] = {"ColumnDeleted", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
127 [ATSPI_OBJECT_EVENT_TEXT_BOUNDS_CHANGED] = {"TextBoundsChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
128 [ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED] = {"SelectionChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
129 [ATSPI_OBJECT_EVENT_TEXT_CHANGED] = {"TextChaged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
130 [ATSPI_OBJECT_EVENT_TEXT_ATTRIBUTES_CHANGED] = {"TextAttributesChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
131 [ATSPI_OBJECT_EVENT_TEXT_CARET_MOVED] = {"TextCaretMoved", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
132 [ATSPI_OBJECT_EVENT_ATTRIBUTES_CHANGED] = {"AttributesChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
133};
134
135static const Eldbus_Signal _window_obj_signals[] = {
136 [ATSPI_WINDOW_EVENT_PROPERTY_CHANGE] = {"PropertyChange", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
137 [ATSPI_WINDOW_EVENT_MINIMIZE] = {"Minimize", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
138 [ATSPI_WINDOW_EVENT_MAXIMIZE] = {"Maximize", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
139 [ATSPI_WINDOW_EVENT_RESTORE] = {"Restore", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
140 [ATSPI_WINDOW_EVENT_CLOSE] = {"Close", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
141 [ATSPI_WINDOW_EVENT_CREATE] = {"Create", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
142 [ATSPI_WINDOW_EVENT_REPARENT] = {"Reparent", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
143 [ATSPI_WINDOW_EVENT_DESKTOPCREATE] = {"DesktopCreate", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
144 [ATSPI_WINDOW_EVENT_DESKTOPDESTROY] = {"DesktopDestroy", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
145 [ATSPI_WINDOW_EVENT_DESTROY] = {"Destroy", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
146 [ATSPI_WINDOW_EVENT_ACTIVATE] = {"Activate", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
147 [ATSPI_WINDOW_EVENT_DEACTIVATE] = {"Deactivate", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
148 [ATSPI_WINDOW_EVENT_RAISE] = {"Raise", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
149 [ATSPI_WINDOW_EVENT_LOWER] = {"Lower", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
150 [ATSPI_WINDOW_EVENT_MOVE] = {"Move", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
151 [ATSPI_WINDOW_EVENT_RESIZE] = {"Resize", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
152 [ATSPI_WINDOW_EVENT_SHADE] = {"Shade", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
153 [ATSPI_WINDOW_EVENT_UUSHADE] = {"uUshade", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
154 [ATSPI_WINDOW_EVENT_RESTYLE] = {"Restyle", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
40}; 155};
41 156
42static Eldbus_Message * 157static Eldbus_Message *
43_accessible_get_role(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) 158_accessible_get_role(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
44{ 159{
45 const char *obj_path = eldbus_service_object_path_get(iface); 160 const char *obj_path = eldbus_service_object_path_get(iface);
46 Elm_Atspi_Object *obj = _access_object_from_path(obj_path); 161 Elm_Atspi_Object *obj = _access_object_from_path(obj_path);
@@ -48,64 +163,77 @@ _accessible_get_role(const Eldbus_Service_Interface *iface EINA_UNUSED, const El
48 163
49 eo_do(obj, elm_atspi_obj_role_get(&role)); 164 eo_do(obj, elm_atspi_obj_role_get(&role));
50 Eldbus_Message *ret = eldbus_message_method_return_new(msg); 165 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
166 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
51 eldbus_message_arguments_append(ret, "u", role); 167 eldbus_message_arguments_append(ret, "u", role);
52 return ret; 168 return ret;
53} 169}
54 170
55static Eldbus_Message * 171static Eldbus_Message *
56_accessible_get_role_name(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) 172_accessible_get_role_name(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
57{ 173{
58 const char *role_name, *obj_path = eldbus_service_object_path_get(iface); 174 const char *role_name, *obj_path = eldbus_service_object_path_get(iface);
59 Elm_Atspi_Object *obj = _access_object_from_path(obj_path); 175 Elm_Atspi_Object *obj = _access_object_from_path(obj_path);
60 176
61 eo_do(obj, elm_atspi_obj_role_name_get(&role_name)); 177 eo_do(obj, elm_atspi_obj_role_name_get(&role_name));
62 Eldbus_Message *ret = eldbus_message_method_return_new(msg); 178 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
179 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
63 eldbus_message_arguments_append(ret, "s", role_name); 180 eldbus_message_arguments_append(ret, "s", role_name);
64 181
65 return ret; 182 return ret;
66} 183}
67 184
68static Eldbus_Message * 185static Eldbus_Message *
69_accessible_get_localized_role_name(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) 186_accessible_get_localized_role_name(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
70{ 187{
71 const char *l_role_name, *obj_path = eldbus_service_object_path_get(iface); 188 const char *l_role_name, *obj_path = eldbus_service_object_path_get(iface);
72 Elm_Atspi_Object *obj = _access_object_from_path(obj_path); 189 Elm_Atspi_Object *obj = _access_object_from_path(obj_path);
73 190
74 eo_do(obj, elm_atspi_obj_localized_role_name_get(&l_role_name)); 191 eo_do(obj, elm_atspi_obj_localized_role_name_get(&l_role_name));
75 Eldbus_Message *ret = eldbus_message_method_return_new(msg); 192 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
193 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
76 eldbus_message_arguments_append(ret, "s", l_role_name); 194 eldbus_message_arguments_append(ret, "s", l_role_name);
77 195
78 return ret; 196 return ret;
79} 197}
80 198
81static Eldbus_Message * 199static Eldbus_Message *
82_accessible_get_children(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) 200_accessible_get_children(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
83{ 201{
84 const char *obj_path = eldbus_service_object_path_get(iface); 202 const char *obj_path = eldbus_service_object_path_get(iface);
85 Elm_Atspi_Object *obj = _access_object_from_path(obj_path); 203 Elm_Atspi_Object *obj = _access_object_from_path(obj_path);
86 Eina_List *children_list = NULL, *l; 204 Eina_List *children_list = NULL, *l;
87 Eldbus_Message *ret; 205 Eldbus_Message *ret;
206
88 Eldbus_Message_Iter *iter, *iter_array; 207 Eldbus_Message_Iter *iter, *iter_array;
89 Elm_Atspi_Object *children; 208 Elm_Atspi_Object *children;
90 209
91 eo_do(obj, elm_atspi_obj_children_get(&children_list)); 210 eo_do(obj, elm_atspi_obj_children_get(&children_list));
92 211
93 ret = eldbus_message_method_return_new(msg); 212 ret = eldbus_message_method_return_new(msg);
213 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
214
94 iter = eldbus_message_iter_get(ret); 215 iter = eldbus_message_iter_get(ret);
95 iter_array = eldbus_message_iter_container_new(iter, 'a', "(so)"); 216 iter_array = eldbus_message_iter_container_new(iter, 'a', "(so)");
217 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
96 218
97 EINA_LIST_FOREACH(children_list, l, children) 219 EINA_LIST_FOREACH(children_list, l, children)
98 object_append_reference(iter_array, children); 220 object_append_reference(iter_array, children);
99 221
100 eldbus_message_iter_container_close(iter, iter_array); 222 eldbus_message_iter_container_close(iter, iter_array);
101 eina_list_free(children_list); 223 eina_list_free(children_list);
224
102 return ret; 225 return ret;
226
227fail:
228 if (ret) eldbus_message_unref(ret);
229 return NULL;
103} 230}
104 231
105static Eldbus_Message * 232static Eldbus_Message *
106_accessible_get_application(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) 233_accessible_get_application(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
107{ 234{
108 Eldbus_Message *ret = eldbus_message_method_return_new(msg); 235 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
236 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
109 Eldbus_Message_Iter *iter = eldbus_message_iter_get(ret); 237 Eldbus_Message_Iter *iter = eldbus_message_iter_get(ret);
110 object_append_reference(iter, _root); 238 object_append_reference(iter, _root);
111 239
@@ -113,17 +241,42 @@ _accessible_get_application(const Eldbus_Service_Interface *iface EINA_UNUSED, c
113} 241}
114 242
115static Eldbus_Message * 243static Eldbus_Message *
116_accessible_get_state(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) 244_accessible_get_state(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
117{ 245{
118 Eldbus_Message *ret = eldbus_message_method_return_new(msg); 246 Eldbus_Message *ret;
119 Eldbus_Message_Iter *iter = eldbus_message_iter_get(ret); 247 Eldbus_Message_Iter *iter, *iter_array;
120 Eldbus_Message_Iter *iter_array; 248 Elm_Atspi_State states;
249
250 const char *obj_path = eldbus_service_object_path_get(iface);
251 Elm_Atspi_Object *obj = _access_object_from_path(obj_path);
252
253 if (!obj)
254 {
255 ERR("Atspi Object %s not found in cache!", obj_path);
256 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid object path.");
257 }
121 258
259 ret = eldbus_message_method_return_new(msg);
260 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
261
262 iter = eldbus_message_iter_get(ret);
122 iter_array = eldbus_message_iter_container_new(iter, 'a', "u"); 263 iter_array = eldbus_message_iter_container_new(iter, 'a', "u");
123 /* TODO: states are not implemented yet*/ 264 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
265
266 eo_do(obj, elm_atspi_obj_state_get(&states));
267
268 unsigned int s1 = states & 0xFFFFFFFF;
269 unsigned int s2 = (states >> 32) & 0xFFFFFFFF;
270
271 eldbus_message_iter_basic_append(iter_array, 'u', s1);
272 eldbus_message_iter_basic_append(iter_array, 'u', s2);
124 eldbus_message_iter_container_close(iter, iter_array); 273 eldbus_message_iter_container_close(iter, iter_array);
125 274
126 return ret; 275 return ret;
276
277fail:
278 if (ret) eldbus_message_unref(ret);
279 return NULL;
127} 280}
128 281
129static Eldbus_Message * 282static Eldbus_Message *
@@ -131,9 +284,12 @@ _accessible_get_index_in_parent(const Eldbus_Service_Interface *iface EINA_UNUSE
131{ 284{
132 const char *obj_path = eldbus_service_object_path_get(iface); 285 const char *obj_path = eldbus_service_object_path_get(iface);
133 Elm_Atspi_Object *obj = _access_object_from_path(obj_path); 286 Elm_Atspi_Object *obj = _access_object_from_path(obj_path);
134 Eldbus_Message *ret = eldbus_message_method_return_new(msg); 287 Eldbus_Message *ret;
135 int idx; 288 int idx;
136 289
290 ret = eldbus_message_method_return_new(msg);
291 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
292
137 eo_do(obj, elm_atspi_obj_index_in_parent_get(&idx)); 293 eo_do(obj, elm_atspi_obj_index_in_parent_get(&idx));
138 eldbus_message_arguments_append(ret, "i", idx); 294 eldbus_message_arguments_append(ret, "i", idx);
139 295
@@ -154,6 +310,8 @@ _accessible_child_at_index(const Eldbus_Service_Interface *iface EINA_UNUSED, co
154 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type."); 310 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
155 311
156 ret = eldbus_message_method_return_new(msg); 312 ret = eldbus_message_method_return_new(msg);
313 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
314
157 iter = eldbus_message_iter_get(ret); 315 iter = eldbus_message_iter_get(ret);
158 eo_do(obj, elm_atspi_obj_child_at_index_get(idx, &child)); 316 eo_do(obj, elm_atspi_obj_child_at_index_get(idx, &child));
159 object_append_reference(iter, child); 317 object_append_reference(iter, child);
@@ -161,11 +319,17 @@ _accessible_child_at_index(const Eldbus_Service_Interface *iface EINA_UNUSED, co
161 return ret; 319 return ret;
162} 320}
163 321
322static Eldbus_Message *
323_accessible_get_relation_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
324{
325 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.NotSupported", "Relation states not implemented.");
326}
327
164static const Eldbus_Method accessible_methods[] = { 328static const Eldbus_Method accessible_methods[] = {
165 { "GetChildAtIndex", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"(so)", "Accessible"}), _accessible_child_at_index, 0 }, 329 { "GetChildAtIndex", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"(so)", "Accessible"}), _accessible_child_at_index, 0 },
166 { "GetChildren", NULL, ELDBUS_ARGS({"a(so)", "children"}), _accessible_get_children, 0 }, 330 { "GetChildren", NULL, ELDBUS_ARGS({"a(so)", "children"}), _accessible_get_children, 0 },
167 { "GetIndexInParent", NULL, ELDBUS_ARGS({"i", "index"}), _accessible_get_index_in_parent, 0 }, 331 { "GetIndexInParent", NULL, ELDBUS_ARGS({"i", "index"}), _accessible_get_index_in_parent, 0 },
168 { "GetRelationSet", NULL, ELDBUS_ARGS({"a(ua(so))", NULL}), _accessible_get_state, 0 }, 332 { "GetRelationSet", NULL, ELDBUS_ARGS({"a(ua(so))", NULL}), _accessible_get_relation_set, 0 },
169 { "GetRole", NULL, ELDBUS_ARGS({"u", "Role"}), _accessible_get_role, 0 }, 333 { "GetRole", NULL, ELDBUS_ARGS({"u", "Role"}), _accessible_get_role, 0 },
170 { "GetRoleName", NULL, ELDBUS_ARGS({"s", "Name"}), _accessible_get_role_name, 0 }, 334 { "GetRoleName", NULL, ELDBUS_ARGS({"s", "Name"}), _accessible_get_role_name, 0 },
171 { "GetLocalizedRoleName", NULL, ELDBUS_ARGS({"s", "LocalizedName"}), _accessible_get_localized_role_name, 0}, 335 { "GetLocalizedRoleName", NULL, ELDBUS_ARGS({"s", "LocalizedName"}), _accessible_get_localized_role_name, 0},
@@ -216,9 +380,7 @@ _accessible_property_get(const Eldbus_Service_Interface *interface, const char *
216 Eldbus_Message **error EINA_UNUSED) 380 Eldbus_Message **error EINA_UNUSED)
217{ 381{
218 const char *ret, *obj_path = eldbus_service_object_path_get(interface); 382 const char *ret, *obj_path = eldbus_service_object_path_get(interface);
219
220 Elm_Atspi_Object *ret_obj = NULL, *obj = _access_object_from_path(obj_path); 383 Elm_Atspi_Object *ret_obj = NULL, *obj = _access_object_from_path(obj_path);
221
222 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE); 384 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
223 385
224 if (!strcmp(property, "Name")) 386 if (!strcmp(property, "Name"))
@@ -260,10 +422,10 @@ _accessible_property_get(const Eldbus_Service_Interface *interface, const char *
260} 422}
261 423
262static const Eldbus_Property accessible_properties[] = { 424static const Eldbus_Property accessible_properties[] = {
263 { "Name", "s", NULL, NULL, 0 }, 425 { "Name", "s", _accessible_property_get, NULL, 0 },
264 { "Description", "s", NULL, NULL, 0 }, 426 { "Description", "s", _accessible_property_get, NULL, 0 },
265 { "Parent", "(so)", NULL, NULL, 0 }, 427 { "Parent", "(so)", _accessible_property_get, NULL, 0 },
266 { "ChildCount", "i", NULL, NULL, 0 }, 428 { "ChildCount", "i", _accessible_property_get, NULL, 0 },
267 { NULL, NULL, NULL, NULL, 0 } 429 { NULL, NULL, NULL, NULL, 0 }
268}; 430};
269 431
@@ -271,10 +433,19 @@ static const Eldbus_Service_Interface_Desc accessible_iface_desc = {
271 ATSPI_DBUS_INTERFACE_ACCESSIBLE, accessible_methods, NULL, accessible_properties, _accessible_property_get, NULL 433 ATSPI_DBUS_INTERFACE_ACCESSIBLE, accessible_methods, NULL, accessible_properties, _accessible_property_get, NULL
272}; 434};
273 435
274static void 436static const Eldbus_Service_Interface_Desc event_iface_desc = {
275object_append_reference(Eldbus_Message_Iter *iter, Elm_Atspi_Object *obj){ 437 ATSPI_DBUS_INTERFACE_EVENT_OBJECT, NULL, _event_obj_signals, NULL, NULL, NULL
438};
439
440static const Eldbus_Service_Interface_Desc window_iface_desc = {
441 ATSPI_DBUS_INTERFACE_EVENT_WINDOW, NULL, _window_obj_signals, NULL, NULL, NULL
442};
276 443
444static void
445object_append_reference(Eldbus_Message_Iter *iter, Elm_Atspi_Object *obj)
446{
277 Eldbus_Message_Iter *iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL); 447 Eldbus_Message_Iter *iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
448 EINA_SAFETY_ON_NULL_RETURN(iter);
278 char *path = _path_from_access_object(obj); 449 char *path = _path_from_access_object(obj);
279 eldbus_message_iter_basic_append(iter_struct, 's', eldbus_connection_unique_name_get(_a11y_bus)); 450 eldbus_message_iter_basic_append(iter_struct, 's', eldbus_connection_unique_name_get(_a11y_bus));
280 eldbus_message_iter_basic_append(iter_struct, 'o', path); 451 eldbus_message_iter_basic_append(iter_struct, 'o', path);
@@ -283,9 +454,10 @@ object_append_reference(Eldbus_Message_Iter *iter, Elm_Atspi_Object *obj){
283} 454}
284 455
285static void 456static void
286object_append_desktop_reference(Eldbus_Message_Iter *iter){ 457object_append_desktop_reference(Eldbus_Message_Iter *iter)
287 458{
288 Eldbus_Message_Iter *iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL); 459 Eldbus_Message_Iter *iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
460 EINA_SAFETY_ON_NULL_RETURN(iter);
289 461
290 eldbus_message_iter_basic_append(iter_struct, 's', ATSPI_DBUS_NAME_REGISTRY); 462 eldbus_message_iter_basic_append(iter_struct, 's', ATSPI_DBUS_NAME_REGISTRY);
291 eldbus_message_iter_basic_append(iter_struct, 'o', ATSPI_DBUS_PATH_ROOT); 463 eldbus_message_iter_basic_append(iter_struct, 'o', ATSPI_DBUS_PATH_ROOT);
@@ -295,17 +467,19 @@ object_append_desktop_reference(Eldbus_Message_Iter *iter){
295static Eina_Bool 467static Eina_Bool
296_append_item_fn(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata) 468_append_item_fn(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
297{ 469{
298
299 if (!eo_ref_get(data) || eo_destructed_is(data)) 470 if (!eo_ref_get(data) || eo_destructed_is(data))
300 return EINA_TRUE; 471 return EINA_TRUE;
301 472
302 Eldbus_Message_Iter *iter_struct, *iter_sub_array; 473 Eldbus_Message_Iter *iter_struct, *iter_sub_array;
303 Eldbus_Message_Iter *iter_array = fdata; 474 Eldbus_Message_Iter *iter_array = fdata;
304 475 Elm_Atspi_State states;
305 AtspiRole role; 476 AtspiRole role;
477
306 eo_do(data, elm_atspi_obj_role_get(&role)); 478 eo_do(data, elm_atspi_obj_role_get(&role));
307 479
308 iter_struct = eldbus_message_iter_container_new(iter_array, 'r', NULL); 480 iter_struct = eldbus_message_iter_container_new(iter_array, 'r', NULL);
481 EINA_SAFETY_ON_NULL_RETURN_VAL(iter_struct, EINA_TRUE);
482
309 /* Marshall object path */ 483 /* Marshall object path */
310 object_append_reference(iter_struct, data); 484 object_append_reference(iter_struct, data);
311 485
@@ -326,6 +500,8 @@ _append_item_fn(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED,
326 500
327 eo_do(data, elm_atspi_obj_children_get(&children_list)); 501 eo_do(data, elm_atspi_obj_children_get(&children_list));
328 iter_sub_array = eldbus_message_iter_container_new(iter_struct, 'a', "(so)"); 502 iter_sub_array = eldbus_message_iter_container_new(iter_struct, 'a', "(so)");
503 EINA_SAFETY_ON_NULL_GOTO(iter_sub_array, fail);
504
329 EINA_LIST_FOREACH(children_list, l, child) 505 EINA_LIST_FOREACH(children_list, l, child)
330 object_append_reference(iter_sub_array, child); 506 object_append_reference(iter_sub_array, child);
331 507
@@ -334,6 +510,7 @@ _append_item_fn(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED,
334 510
335 /* Marshall interfaces */ 511 /* Marshall interfaces */
336 iter_sub_array = eldbus_message_iter_container_new(iter_struct, 'a', "s"); 512 iter_sub_array = eldbus_message_iter_container_new(iter_struct, 'a', "s");
513 EINA_SAFETY_ON_NULL_GOTO(iter_sub_array, fail);
337 514
338 eldbus_message_iter_basic_append(iter_sub_array, 's', ATSPI_DBUS_INTERFACE_ACCESSIBLE); 515 eldbus_message_iter_basic_append(iter_sub_array, 's', ATSPI_DBUS_INTERFACE_ACCESSIBLE);
339 if (eo_isa(data, ELM_ATSPI_COMPONENT_INTERFACE)) 516 if (eo_isa(data, ELM_ATSPI_COMPONENT_INTERFACE))
@@ -360,24 +537,44 @@ _append_item_fn(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED,
360 537
361 /* Marshall state set */ 538 /* Marshall state set */
362 iter_sub_array = eldbus_message_iter_container_new(iter_struct, 'a', "u"); 539 iter_sub_array = eldbus_message_iter_container_new(iter_struct, 'a', "u");
363 /* TODO: states are not implemented yet*/ 540 EINA_SAFETY_ON_NULL_GOTO(iter_sub_array, fail);
364 eldbus_message_iter_container_close(iter_struct, iter_sub_array);
365 541
542 eo_do(data, elm_atspi_obj_state_get(&states));
543 unsigned int s1 = states & 0xFFFFFFFF;
544 unsigned int s2 = (states >> 32) & 0xFFFFFFFF;
545 eldbus_message_iter_basic_append(iter_sub_array, 'u', s1);
546 eldbus_message_iter_basic_append(iter_sub_array, 'u', s2);
547
548 eldbus_message_iter_container_close(iter_struct, iter_sub_array);
366 eldbus_message_iter_container_close(iter_array, iter_struct); 549 eldbus_message_iter_container_close(iter_array, iter_struct);
367 550
368 return EINA_TRUE; 551 return EINA_TRUE;
552
553fail:
554 if (iter_struct) eldbus_message_iter_del(iter_struct);
555 return EINA_TRUE;
369} 556}
370 557
371static Eldbus_Message * 558static Eldbus_Message *
372_cache_get_items(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) 559_cache_get_items(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
373{ 560{
374 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
375 Eldbus_Message_Iter *iter, *iter_array; 561 Eldbus_Message_Iter *iter, *iter_array;
562 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
563 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
564
565 _cache_update();
566
376 iter = eldbus_message_iter_get(ret); 567 iter = eldbus_message_iter_get(ret);
377 iter_array = eldbus_message_iter_container_new(iter, 'a', CACHE_ITEM_SIGNATURE); 568 iter_array = eldbus_message_iter_container_new(iter, 'a', CACHE_ITEM_SIGNATURE);
569 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
570
378 eina_hash_foreach(_cache, _append_item_fn, iter_array); 571 eina_hash_foreach(_cache, _append_item_fn, iter_array);
379 eldbus_message_iter_container_close(iter, iter_array); 572 eldbus_message_iter_container_close(iter, iter_array);
573
380 return ret; 574 return ret;
575fail:
576 if (ret) eldbus_message_unref(ret);
577 return NULL;
381} 578}
382 579
383static const Eldbus_Method cache_methods[] = { 580static const Eldbus_Method cache_methods[] = {
@@ -386,8 +583,8 @@ static const Eldbus_Method cache_methods[] = {
386}; 583};
387 584
388static const Eldbus_Signal cache_signals[] = { 585static const Eldbus_Signal cache_signals[] = {
389 [ADD_ACCESSIBLE] = { "AddAccessible", ELDBUS_ARGS({"((so)(so)a(so)assusau)", "added"}), 0}, 586 [ATSPI_OBJECT_CHILD_ADDED] = { "AddAccessible", ELDBUS_ARGS({"((so)(so)a(so)assusau)", "added"}), 0},
390 [REMOVE_ACCESSIBLE] = { "RemoveAccessible", ELDBUS_ARGS({ "(so)", "removed" }), 0}, 587 [ATSPI_OBJECT_CHILD_REMOVED] = { "RemoveAccessible", ELDBUS_ARGS({ "(so)", "removed" }), 0},
391 {NULL, NULL, 0} 588 {NULL, NULL, 0}
392}; 589};
393 590
@@ -412,6 +609,8 @@ _component_contains(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eld
412 eo_do(obj, elm_atspi_component_interface_contains(x, y, coord_type, &contains)); 609 eo_do(obj, elm_atspi_component_interface_contains(x, y, coord_type, &contains));
413 610
414 ret = eldbus_message_method_return_new(msg); 611 ret = eldbus_message_method_return_new(msg);
612 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
613
415 eldbus_message_arguments_append(ret, "b", contains); 614 eldbus_message_arguments_append(ret, "b", contains);
416 615
417 return ret; 616 return ret;
@@ -432,6 +631,8 @@ _component_get_accessible_at_point(const Eldbus_Service_Interface *iface EINA_UN
432 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type."); 631 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
433 632
434 ret = eldbus_message_method_return_new(msg); 633 ret = eldbus_message_method_return_new(msg);
634 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
635
435 iter = eldbus_message_iter_get(ret); 636 iter = eldbus_message_iter_get(ret);
436 eo_do(obj, elm_atspi_component_interface_accessible_at_point_get(x, y, coord_type, &accessible)); 637 eo_do(obj, elm_atspi_component_interface_accessible_at_point_get(x, y, coord_type, &accessible));
437 object_append_reference(iter, accessible); 638 object_append_reference(iter, accessible);
@@ -447,23 +648,30 @@ _component_get_extents(const Eldbus_Service_Interface *iface EINA_UNUSED, const
447 int x, y, w, h; 648 int x, y, w, h;
448 AtspiCoordType coord_type; 649 AtspiCoordType coord_type;
449 Eldbus_Message *ret; 650 Eldbus_Message *ret;
450 Eldbus_Message_Iter *iter, *iter_struct; 651 Eldbus_Message_Iter *iter, *iter_struct;
451
452 if (!eldbus_message_arguments_get(msg, "u", &coord_type)) 652 if (!eldbus_message_arguments_get(msg, "u", &coord_type))
453 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type."); 653 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
454 654
455 ret = eldbus_message_method_return_new(msg); 655 ret = eldbus_message_method_return_new(msg);
656 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
657
456 iter = eldbus_message_iter_get(ret); 658 iter = eldbus_message_iter_get(ret);
457 659
458 eo_do(obj, elm_atspi_component_interface_extents_get(&x, &y, &w, &h, coord_type)); 660 eo_do(obj, elm_atspi_component_interface_extents_get(&x, &y, &w, &h, coord_type));
459 iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL); 661 iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
662 EINA_SAFETY_ON_NULL_GOTO(iter_struct, fail);
663
460 eldbus_message_iter_basic_append(iter_struct, 'i', x); 664 eldbus_message_iter_basic_append(iter_struct, 'i', x);
461 eldbus_message_iter_basic_append(iter_struct, 'i', y); 665 eldbus_message_iter_basic_append(iter_struct, 'i', y);
462 eldbus_message_iter_basic_append(iter_struct, 'i', w); 666 eldbus_message_iter_basic_append(iter_struct, 'i', w);
463 eldbus_message_iter_basic_append(iter_struct, 'i', h); 667 eldbus_message_iter_basic_append(iter_struct, 'i', h);
668
464 eldbus_message_iter_container_close(iter, iter_struct); 669 eldbus_message_iter_container_close(iter, iter_struct);
465 670
466 return ret; 671 return ret;
672fail:
673 if (iter_struct) eldbus_message_iter_del(iter_struct);
674 return NULL;
467} 675}
468 676
469static Eldbus_Message * 677static Eldbus_Message *
@@ -481,6 +689,8 @@ _component_get_position(const Eldbus_Service_Interface *iface EINA_UNUSED, const
481 eo_do(obj, elm_atspi_component_interface_position_get(&x, &y, coord_type)); 689 eo_do(obj, elm_atspi_component_interface_position_get(&x, &y, coord_type));
482 690
483 ret = eldbus_message_method_return_new(msg); 691 ret = eldbus_message_method_return_new(msg);
692 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
693
484 eldbus_message_arguments_append(ret, "i", x); 694 eldbus_message_arguments_append(ret, "i", x);
485 eldbus_message_arguments_append(ret, "i", y); 695 eldbus_message_arguments_append(ret, "i", y);
486 696
@@ -498,6 +708,8 @@ _component_get_size(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eld
498 eo_do(obj, elm_atspi_component_interface_size_get(&x, &y)); 708 eo_do(obj, elm_atspi_component_interface_size_get(&x, &y));
499 709
500 ret = eldbus_message_method_return_new(msg); 710 ret = eldbus_message_method_return_new(msg);
711 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
712
501 eldbus_message_arguments_append(ret, "i", x); 713 eldbus_message_arguments_append(ret, "i", x);
502 eldbus_message_arguments_append(ret, "i", y); 714 eldbus_message_arguments_append(ret, "i", y);
503 715
@@ -515,6 +727,8 @@ _component_get_layer(const Eldbus_Service_Interface *iface EINA_UNUSED, const El
515 eo_do(obj, elm_atspi_component_interface_layer_get(&layer)); 727 eo_do(obj, elm_atspi_component_interface_layer_get(&layer));
516 728
517 ret = eldbus_message_method_return_new(msg); 729 ret = eldbus_message_method_return_new(msg);
730 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
731
518 eldbus_message_arguments_append(ret, "u", layer); 732 eldbus_message_arguments_append(ret, "u", layer);
519 733
520 return ret; 734 return ret;
@@ -531,6 +745,8 @@ _component_grab_focus(const Eldbus_Service_Interface *iface EINA_UNUSED, const E
531 eo_do(obj, elm_atspi_component_interface_focus_grab(&focus)); 745 eo_do(obj, elm_atspi_component_interface_focus_grab(&focus));
532 746
533 ret = eldbus_message_method_return_new(msg); 747 ret = eldbus_message_method_return_new(msg);
748 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
749
534 eldbus_message_arguments_append(ret, "b", focus); 750 eldbus_message_arguments_append(ret, "b", focus);
535 751
536 return ret; 752 return ret;
@@ -547,6 +763,8 @@ _component_get_alpha(const Eldbus_Service_Interface *iface EINA_UNUSED, const El
547 eo_do(obj, elm_atspi_component_interface_alpha_get(&alpha)); 763 eo_do(obj, elm_atspi_component_interface_alpha_get(&alpha));
548 764
549 ret = eldbus_message_method_return_new(msg); 765 ret = eldbus_message_method_return_new(msg);
766 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
767
550 eldbus_message_arguments_append(ret, "d", alpha); 768 eldbus_message_arguments_append(ret, "d", alpha);
551 769
552 return ret; 770 return ret;
@@ -568,6 +786,8 @@ _component_set_extends(const Eldbus_Service_Interface *iface EINA_UNUSED, const
568 eo_do(obj, elm_atspi_component_interface_extents_set(x, y, w, h, coord_type, &result)); 786 eo_do(obj, elm_atspi_component_interface_extents_set(x, y, w, h, coord_type, &result));
569 787
570 ret = eldbus_message_method_return_new(msg); 788 ret = eldbus_message_method_return_new(msg);
789 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
790
571 eldbus_message_arguments_append(ret, "b", result); 791 eldbus_message_arguments_append(ret, "b", result);
572 792
573 return ret; 793 return ret;
@@ -589,6 +809,8 @@ _component_set_position(const Eldbus_Service_Interface *iface EINA_UNUSED, const
589 eo_do(obj, elm_atspi_component_interface_position_set(x, y, coord_type, &result)); 809 eo_do(obj, elm_atspi_component_interface_position_set(x, y, coord_type, &result));
590 810
591 ret = eldbus_message_method_return_new(msg); 811 ret = eldbus_message_method_return_new(msg);
812 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
813
592 eldbus_message_arguments_append(ret, "b", result); 814 eldbus_message_arguments_append(ret, "b", result);
593 815
594 return ret; 816 return ret;
@@ -609,6 +831,8 @@ _component_set_size(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eld
609 eo_do(obj, elm_atspi_component_interface_size_set(w, h, &result)); 831 eo_do(obj, elm_atspi_component_interface_size_set(w, h, &result));
610 832
611 ret = eldbus_message_method_return_new(msg); 833 ret = eldbus_message_method_return_new(msg);
834 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
835
612 eldbus_message_arguments_append(ret, "b", result); 836 eldbus_message_arguments_append(ret, "b", result);
613 837
614 return ret; 838 return ret;
@@ -635,19 +859,17 @@ static const Eldbus_Service_Interface_Desc component_iface_desc = {
635}; 859};
636 860
637static Eina_Bool 861static Eina_Bool
638_atspi_object_del_cb(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED) 862_cache_object_del_cb(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
639{ 863{
640 Eldbus_Message *msg; 864 Eldbus_Message *msg;
641 Eldbus_Message_Iter *iter; 865 Eldbus_Message_Iter *iter;
642 char* path; 866 char* path;
643 867
644 msg = eldbus_service_signal_new(_cache_interface, REMOVE_ACCESSIBLE); 868 msg = eldbus_service_signal_new(_cache_interface, ATSPI_OBJECT_CHILD_REMOVED);
645 iter = eldbus_message_iter_get(msg); 869 iter = eldbus_message_iter_get(msg);
646 object_append_reference(iter, obj); 870 object_append_reference(iter, obj);
647 path = _path_from_access_object(obj); 871 path = _path_from_access_object(obj);
648 872
649 //ERR("_atspi_object_del_cbi: %d", eo_ref_get(obj));
650
651 eldbus_service_signal_send(_cache_interface, msg); 873 eldbus_service_signal_send(_cache_interface, msg);
652 eina_hash_del(_cache, path, obj); 874 eina_hash_del(_cache, path, obj);
653 875
@@ -658,37 +880,50 @@ _atspi_object_del_cb(void *data, Eo *obj, const Eo_Event_Description *desc EINA_
658} 880}
659 881
660static void 882static void
661_atspi_object_register_interfaces(const char* path, Elm_Atspi_Object *node) 883_cache_object_register_interfaces(const char *path, Elm_Atspi_Object *node)
662{ 884{
663 Eldbus_Service_Interface *accessible = NULL; 885 Eldbus_Service_Interface *accessible = NULL;
886 Eldbus_Service_Interface *events = NULL;
887 Eldbus_Service_Interface *window = NULL;
664 888
665 if (eo_isa(node, ELM_ATSPI_CLASS)) 889 if (eina_hash_find(_cache, path))
666 { 890 return;
667 accessible = eldbus_service_interface_register(_a11y_bus, path, &accessible_iface_desc); 891 else
668 eo_do(node, eo_event_callback_add(EO_EV_DEL, _atspi_object_del_cb, accessible)); 892 eina_hash_add(_cache, path, node);
669 } 893
894 if (!eo_isa(node, ELM_ATSPI_CLASS)) return;
895
896 accessible = eldbus_service_interface_register(_a11y_bus, path, &accessible_iface_desc);
897 events = eldbus_service_interface_register(_a11y_bus, path, &event_iface_desc);
898 eo_do(node, eo_base_data_set("atspi_event_interface", events, NULL));
899 eo_do(node, eo_event_callback_add(EO_EV_DEL, _cache_object_del_cb, accessible));
670 900
671 if (eo_isa(node, ELM_ATSPI_COMPONENT_INTERFACE)) 901 if (eo_isa(node, ELM_ATSPI_COMPONENT_INTERFACE))
672 eldbus_service_interface_register(_a11y_bus, path, &component_iface_desc); 902 eldbus_service_interface_register(_a11y_bus, path, &component_iface_desc);
903
904 if (eo_isa(node, ELM_ATSPI_WINDOW_INTERFACE))
905 {
906 window = eldbus_service_interface_register(_a11y_bus, path, &window_iface_desc);
907 eo_do(node, eo_base_data_set("window_event_interface", window, NULL));
908 }
673} 909}
674 910
675static void 911static void
676_atspi_objects_register_rec(Elm_Atspi_Object *node) 912_cache_object_register(Elm_Atspi_Object *node, Eina_Bool rec)
677{ 913{
678 EINA_SAFETY_ON_NULL_RETURN(node); 914 EINA_SAFETY_ON_NULL_RETURN(node);
679 Eina_List *children_list = NULL, *l; 915 Eina_List *children_list = NULL, *l;
680 Elm_Atspi_Object *child; 916 Elm_Atspi_Object *child;
681 char* path = _path_from_access_object(node); 917 char* path = _path_from_access_object(node);
682 918
683 // register in cache 919 _cache_object_register_interfaces(path, node);
684 eina_hash_add(_cache, path, node);
685
686 _atspi_object_register_interfaces(path, node);
687 free(path); 920 free(path);
688 921
922 if (!rec) return;
923
689 eo_do(node, elm_atspi_obj_children_get(&children_list)); 924 eo_do(node, elm_atspi_obj_children_get(&children_list));
690 EINA_LIST_FOREACH(children_list, l, child) 925 EINA_LIST_FOREACH(children_list, l, child)
691 _atspi_objects_register_rec(child); 926 _cache_object_register(child, rec);
692 927
693 eina_list_free(children_list); 928 eina_list_free(children_list);
694} 929}
@@ -707,7 +942,7 @@ _on_app_register(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pendi
707} 942}
708 943
709static Eina_Bool 944static Eina_Bool
710_app_register(Eldbus_Connection *a11y_bus) 945_app_register(void)
711{ 946{
712 Eldbus_Message *message = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY, 947 Eldbus_Message *message = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY,
713 ATSPI_DBUS_PATH_ROOT, 948 ATSPI_DBUS_PATH_ROOT,
@@ -716,27 +951,381 @@ _app_register(Eldbus_Connection *a11y_bus)
716 Eldbus_Message_Iter *iter = eldbus_message_iter_get(message); 951 Eldbus_Message_Iter *iter = eldbus_message_iter_get(message);
717 952
718 object_append_reference(iter, _root); 953 object_append_reference(iter, _root);
954 eldbus_connection_send(_a11y_bus, message, _on_app_register, NULL, -1);
955
956 return EINA_TRUE;
957}
719 958
720 eldbus_connection_send(a11y_bus, message, _on_app_register, NULL, -1); 959static void
960_cache_update(void)
961{
962 _cache_object_register(_root, EINA_TRUE);
963}
964
965static void
966_bus_objects_register(void)
967{
968 _cache_interface = eldbus_service_interface_register(_a11y_bus, CACHE_INTERFACE_PATH, &cache_iface_desc);
969}
970
971static void
972_set_broadcast_flag(const char *event)
973{
974 char **tokens;
975
976 tokens = eina_str_split(event, ":", 3);
977
978 if (!tokens) return;
979
980 if (!strcmp(tokens[0], "Object"))
981 {
982 if (!tokens[1] || *tokens[1] == '\0') return; // do not handle "Object:*"
983 else if (!strcmp(tokens[1], "StateChanged"))
984 {
985 if (!tokens[2] || *tokens[2] == '\0')
986 _object_state_broadcast_mask = -1; // broadcast all
987 else if (!strcmp(tokens[2], "Focused"))
988 BIT_FLAG_SET(_object_state_broadcast_mask, ATSPI_STATE_FOCUSED);
989 else if (!strcmp(tokens[2], "Showing"))
990 BIT_FLAG_SET(_object_state_broadcast_mask, ATSPI_STATE_SHOWING);
991 }
992 else if (!strcmp(tokens[1], "PropertyChange"))
993 {
994 if (!tokens[2] || *tokens[2] == '\0')
995 _object_property_broadcast_mask = -1; //broadcast all
996 else if (!strcmp(tokens[2], "AccessibleValue"))
997 BIT_FLAG_SET(_object_property_broadcast_mask, ATSPI_OBJECT_PROPERTY_VALUE);
998 else if (!strcmp(tokens[2], "AccessibleName"))
999 BIT_FLAG_SET(_object_property_broadcast_mask, ATSPI_OBJECT_PROPERTY_NAME);
1000 else if (!strcmp(tokens[2], "AccessibleDescription"))
1001 BIT_FLAG_SET(_object_property_broadcast_mask, ATSPI_OBJECT_PROPERTY_DESCRIPTION);
1002 else if (!strcmp(tokens[2], "AccessibleParent"))
1003 BIT_FLAG_SET(_object_property_broadcast_mask, ATSPI_OBJECT_PROPERTY_PARENT);
1004 else if (!strcmp(tokens[2], "AccessibleRole"))
1005 BIT_FLAG_SET(_object_property_broadcast_mask, ATSPI_OBJECT_PROPERTY_ROLE);
1006 }
1007 else if (!strcmp(tokens[1], "ChildrenChanged"))
1008 {
1009 if (!tokens[2] || *tokens[2] == '\0')
1010 _object_children_broadcast_mask = -1; // broadcast all
1011 else if (!strcmp(tokens[2], "add"))
1012 BIT_FLAG_SET(_object_children_broadcast_mask, ATSPI_OBJECT_CHILD_ADDED);
1013 else if (!strcmp(tokens[2], "remove"))
1014 BIT_FLAG_SET(_object_children_broadcast_mask, ATSPI_OBJECT_CHILD_ADDED);
1015 }
1016 }
1017 else if (!strcmp(tokens[0], "Window"))
1018 {
1019 if (!tokens[1] || *tokens[1] == '\0')
1020 _window_signal_broadcast_mask = -1; // broadcast all
1021 else if (!strcmp(tokens[1], "Create"))
1022 BIT_FLAG_SET(_window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_CREATE);
1023 else if (!strcmp(tokens[1], "Activate"))
1024 BIT_FLAG_SET(_window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_ACTIVATE);
1025 else if (!strcmp(tokens[1], "Deactivate"))
1026 BIT_FLAG_SET(_window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_DEACTIVATE);
1027 }
1028
1029 free(tokens[0]);
1030 free(tokens);
1031}
1032
1033static void
1034_registered_listeners_get(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
1035{
1036 DBG("Updating ATSPI2 clients registered events list.");
1037 _object_children_broadcast_mask = 0;
1038 _object_property_broadcast_mask = 0;
1039 _object_state_broadcast_mask = 0;
1040 _window_signal_broadcast_mask = 0;
1041
1042 const char *event, *bus;
1043 Eldbus_Message_Iter *iter, *siter;
1044 if (!eldbus_message_arguments_get(msg, "a(ss)", &iter))
1045 {
1046 ERR("Invalid answer type from GetRegisteredEvents method call!");
1047 return;
1048 }
1049 while (eldbus_message_iter_get_and_next(iter, 'r', &siter))
1050 {
1051 eldbus_message_iter_arguments_get(siter, "ss", &bus, &event);
1052 _set_broadcast_flag(event);
1053 }
1054}
1055
1056static void
1057_registered_events_list_update(void)
1058{
1059 Eldbus_Message *msg;
1060 msg = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_REGISTRY, ATSPI_DBUS_INTERFACE_REGISTRY, "GetRegisteredEvents");
1061 eldbus_connection_send(_a11y_bus, msg, _registered_listeners_get, NULL, -1);
1062}
1063
1064static void
1065_handle_listener_change(void *data EINA_UNUSED, const Eldbus_Message *msg)
1066{
1067 const char *bus, *event;
1068 if (!eldbus_message_arguments_get(msg, "ss", &bus, &event))
1069 {
1070 ERR("Invalid org.a11y.Registry signal message args.");
1071 return;
1072 }
1073 _registered_events_list_update();
1074}
1075
1076static void
1077_send_signal_state_changed(Elm_Atspi_Object *obj, AtspiStateType type, Eina_Bool new_value)
1078{
1079 Eldbus_Message *msg;
1080 Eldbus_Message_Iter *iter, *viter;
1081 Eldbus_Service_Interface *events = NULL;
1082 char *desc;
1083
1084 if (!BIT_FLAG_GET(_object_state_broadcast_mask, type))
1085 {
1086 DBG("Masking event: %d", type);
1087 return;
1088 }
1089
1090 switch (type) {
1091 case ATSPI_STATE_FOCUSED:
1092 desc = "focused";
1093 break;
1094 case ATSPI_STATE_SHOWING:
1095 desc = "showing";
1096 break;
1097 case ATSPI_STATE_VISIBLE:
1098 desc = "visible";
1099 break;
1100 default:
1101 desc = NULL;
1102 }
1103
1104 eo_do(obj, eo_base_data_get("atspi_event_interface", (void **)&events));
1105 if (!events)
1106 {
1107 ERR("Atspi object does not have event interface!");
1108 return;
1109 }
1110 msg = eldbus_service_signal_new(events, ATSPI_OBJECT_EVENT_STATE_CHANGED);
1111 iter = eldbus_message_iter_get(msg);
1112
1113 eldbus_message_iter_arguments_append(iter, "sii", desc, new_value, 0);
1114
1115 viter = eldbus_message_iter_container_new(iter, 'v', "i");
1116 EINA_SAFETY_ON_NULL_RETURN(viter);
1117
1118 eldbus_message_iter_arguments_append(viter, "i", 0);
1119 eldbus_message_iter_container_close(iter, viter);
1120
1121 object_append_reference(iter, obj);
1122
1123 eldbus_service_signal_send(events, msg);
1124 DBG("signal sent StateChanged:%s:%d", desc, new_value);
1125}
1126
1127static void
1128_send_signal_property_changed(Elm_Atspi_Object *ao, enum _Atspi_Object_Property prop)
1129{
1130 const char *desc;
1131 Eldbus_Message *msg;
1132 Eldbus_Message_Iter *iter, *siter, *viter;
1133 Eldbus_Service_Interface *events = NULL;
1134
1135 if (!BIT_FLAG_GET(_object_property_broadcast_mask, prop))
1136 return;
1137
1138 switch(prop)
1139 {
1140 case ATSPI_OBJECT_PROPERTY_NAME:
1141 desc = "accessible-name";
1142 break;
1143 case ATSPI_OBJECT_PROPERTY_DESCRIPTION:
1144 desc = "accessible-description";
1145 break;
1146 case ATSPI_OBJECT_PROPERTY_ROLE:
1147 desc = "accessible-role";
1148 break;
1149 case ATSPI_OBJECT_PROPERTY_PARENT:
1150 desc = "accessible-parent";
1151 break;
1152 case ATSPI_OBJECT_PROPERTY_VALUE:
1153 desc = "accessible-value";
1154 break;
1155 default:
1156 desc = NULL;
1157 }
1158 eo_do(ao, eo_base_data_get("atspi_event_interface", (void**)&events));
1159 if (!events)
1160 {
1161 ERR("Atspi object does not have event interface!");
1162 return;
1163 }
1164 msg = eldbus_service_signal_new(events, ATSPI_OBJECT_EVENT_PROPERTY_CHANGED);
1165 EINA_SAFETY_ON_NULL_RETURN(msg);
1166
1167 iter = eldbus_message_iter_get(msg);
1168 siter = eldbus_message_iter_container_new(iter, 'r', NULL);
1169 EINA_SAFETY_ON_NULL_RETURN(siter);
1170
1171 eldbus_message_iter_arguments_append(siter, "suu", desc, 0, 0);
1172
1173 viter = eldbus_message_iter_container_new(siter, 'v', "s");
1174 EINA_SAFETY_ON_NULL_RETURN(viter);
1175
1176 eldbus_message_iter_arguments_append(viter, "s", _path_from_access_object(ao));
1177
1178 eldbus_message_iter_arguments_append(siter, "v", viter);
1179 eldbus_message_iter_container_close(siter, viter);
1180
1181 eldbus_message_iter_container_close(iter, siter);
1182 eldbus_service_signal_send(events, msg);
1183 DBG("signal sent PropertyChanged:%s", desc);
1184}
1185
1186static void
1187_send_signal_children_changed(Elm_Atspi_Object *parent, Elm_Atspi_Object *child, enum _Atspi_Object_Child_Event_Type type)
1188{
1189 Eldbus_Service_Interface *events = NULL;
1190 Eldbus_Message_Iter *iter, *viter;
1191 Eldbus_Message *msg;
1192 const char *desc = NULL;
1193 int idx;
1194
1195 if (!BIT_FLAG_GET(_object_children_broadcast_mask, type))
1196 return;
1197
1198 _cache_object_register(parent, EINA_FALSE);
1199 _cache_object_register(child, EINA_FALSE);
1200
1201 eo_do(parent, eo_base_data_get("atspi_event_interface", (void **)&events));
1202 if (!events)
1203 {
1204 ERR("Atspi object does not have event interface! %p %p %s", parent, _root, eo_class_name_get(eo_class_get(parent)));
1205 return;
1206 }
1207
1208 switch(type)
1209 {
1210 case ATSPI_OBJECT_CHILD_ADDED:
1211 desc = "add";
1212 eo_do(child, elm_atspi_obj_index_in_parent_get(&idx));
1213 break;
1214 case ATSPI_OBJECT_CHILD_REMOVED:
1215 desc = "remove";
1216 idx = -1;
1217 break;
1218 }
1219 msg = eldbus_service_signal_new(events, ATSPI_OBJECT_EVENT_CHILDREN_CHANGED);
1220 EINA_SAFETY_ON_NULL_RETURN(msg);
1221
1222 iter = eldbus_message_iter_get(msg);
1223 eldbus_message_iter_arguments_append(iter, "sii", desc, idx, 0);
1224
1225 viter = eldbus_message_iter_container_new(iter, 'v', "(so)");
1226 EINA_SAFETY_ON_NULL_RETURN(viter);
1227
1228 object_append_reference(viter, child);
1229 eldbus_message_iter_container_close(iter, viter);
1230
1231 object_append_reference(iter, _root);
1232
1233 eldbus_service_signal_send(events, msg);
1234 DBG("signal sent childrenChanged:%s:%d", desc, idx);
1235}
1236
1237static void
1238_send_signal_window(Elm_Atspi_Object *eo, enum _Atspi_Window_Signals type)
1239{
1240 const char *desc;
1241 Eldbus_Message *msg;
1242 Eldbus_Message_Iter *iter, *viter;
1243 Eldbus_Service_Interface *window = NULL;
1244
1245 if (!BIT_FLAG_GET(_window_signal_broadcast_mask, type))
1246 return;
1247
1248 eo_do(eo, eo_base_data_get("window_event_interface", (void**)&window));
1249 if (!window)
1250 {
1251 ERR("Atspi object does not have window interface!");
1252 return;
1253 }
1254
1255 switch(type)
1256 {
1257 case ATSPI_WINDOW_EVENT_DEACTIVATE:
1258 desc = "Deactivate";
1259 break;
1260 case ATSPI_WINDOW_EVENT_ACTIVATE:
1261 desc = "Activate";
1262 break;
1263 default:
1264 desc = "";
1265 }
1266
1267 msg = eldbus_service_signal_new(window, type);
1268 EINA_SAFETY_ON_NULL_RETURN(msg);
1269
1270 iter = eldbus_message_iter_get(msg);
1271 eldbus_message_iter_arguments_append(iter, "sii", desc, 0, 0);
1272
1273 viter = eldbus_message_iter_container_new(iter, 'v', "i");
1274 EINA_SAFETY_ON_NULL_RETURN(viter);
1275
1276 eldbus_message_iter_arguments_append(viter, "i", 0);
1277 eldbus_message_iter_container_close(iter, viter);
1278
1279 object_append_reference(iter, eo);
1280
1281 eldbus_service_signal_send(window, msg);
1282 DBG("signal sent Window:%s", desc);
1283}
1284
1285static Eina_Bool
1286_handle_atspi_event(void *data EINA_UNUSED, Elm_Atspi_Object *ao, const Eo_Event_Description *desc, void *event_info)
1287{
1288 if (desc == EV_ATSPI_OBJ_NAME_CHANGED)
1289 _send_signal_property_changed(ao, ATSPI_OBJECT_PROPERTY_NAME);
1290 else if (desc == EV_ATSPI_OBJ_STATE_CHANGED)
1291 {
1292 int *event_data = event_info;
1293 _send_signal_state_changed(ao, (AtspiStateType)event_data[0], (Eina_Bool)event_data[1]);
1294 }
1295 else if (desc == EV_ATSPI_OBJ_CHILD_ADD)
1296 _send_signal_children_changed(ao, event_info, ATSPI_OBJECT_CHILD_ADDED);
1297 else if (desc == EV_ATSPI_OBJ_CHILD_DEL)
1298 _send_signal_children_changed(ao, event_info, ATSPI_OBJECT_CHILD_REMOVED);
1299 else if (desc == EV_ATSPI_OBJ_WINDOW_ACTIVATED)
1300 _send_signal_window(ao, ATSPI_WINDOW_EVENT_ACTIVATE);
1301 else if (desc == EV_ATSPI_OBJ_WINDOW_DEACTIVATED)
1302 _send_signal_window(ao, ATSPI_WINDOW_EVENT_DEACTIVATE);
721 1303
722 return EINA_TRUE; 1304 return EINA_TRUE;
723} 1305}
724 1306
725static void 1307static void
726_bus_objects_register(Eldbus_Connection *a11y_bus) 1308_event_handlers_register(void)
727{ 1309{
728 _cache_interface = eldbus_service_interface_register(a11y_bus, CACHE_INTERFACE_PATH, &cache_iface_desc); 1310 _registered_events_list_update();
729 _atspi_objects_register_rec(_root); 1311
730 DBG("%d elements registered in cache", eina_hash_population(_cache)); 1312 // register signal handlers in order to update list of registered listeners of ATSPI-Clients
1313 _register_hdl = eldbus_signal_handler_add(_a11y_bus, ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_REGISTRY, ATSPI_DBUS_INTERFACE_REGISTRY, "EventListenerRegistered", _handle_listener_change, NULL);
1314 _unregister_hdl = eldbus_signal_handler_add(_a11y_bus, ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_REGISTRY, ATSPI_DBUS_INTERFACE_REGISTRY, "EventListenerDeregistered", _handle_listener_change, NULL);
1315
1316 // handle incoming events from Elm_Atspi_Objects
1317 _elm_atspi_object_global_callback_add(_handle_atspi_event, NULL);
731} 1318}
732 1319
733static void 1320static void
734_a11y_bus_initialize(const char *socket_addr) 1321_a11y_bus_initialize(const char *socket_addr)
735{ 1322{
736 Eldbus_Connection *a11y_bus = eldbus_address_connection_get(socket_addr); 1323 _a11y_bus = eldbus_address_connection_get(socket_addr);
737 _a11y_bus = a11y_bus; 1324
738 _bus_objects_register(a11y_bus); 1325 _cache_update();
739 _app_register(a11y_bus); 1326 _bus_objects_register();
1327 _app_register();
1328 _event_handlers_register();
740} 1329}
741 1330
742static void 1331static void
@@ -771,11 +1360,18 @@ _elm_atspi_bridge_init(void)
771 1360
772 if (!_init_count && _elm_config->access_mode == ELM_ACCESS_MODE_ON) 1361 if (!_init_count && _elm_config->access_mode == ELM_ACCESS_MODE_ON)
773 { 1362 {
1363 _elm_atspi_object_init();
774 session_bus = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION); 1364 session_bus = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
1365 EINA_SAFETY_ON_NULL_RETURN(session_bus);
775 msg = eldbus_message_method_call_new(A11Y_DBUS_NAME, A11Y_DBUS_PATH, A11Y_DBUS_INTERFACE, "GetAddress"); 1366 msg = eldbus_message_method_call_new(A11Y_DBUS_NAME, A11Y_DBUS_PATH, A11Y_DBUS_INTERFACE, "GetAddress");
1367 if (!msg)
1368 {
1369 eldbus_connection_unref(session_bus);
1370 return;
1371 }
776 eldbus_connection_send(session_bus, msg, _a11y_bus_address_get, session_bus, -1); 1372 eldbus_connection_send(session_bus, msg, _a11y_bus_address_get, session_bus, -1);
777 _cache = eina_hash_string_superfast_new(NULL); 1373 _cache = eina_hash_string_superfast_new(NULL);
778 _root = elm_atspi_root_object_get(); 1374 _root = _elm_atspi_root_object_get();
779 _init_count = 1; 1375 _init_count = 1;
780 } 1376 }
781} 1377}
@@ -785,7 +1381,15 @@ _elm_atspi_bridge_shutdown(void)
785{ 1381{
786 if (_init_count) 1382 if (_init_count)
787 { 1383 {
788 eo_unref(_root); 1384 _elm_atspi_object_shutdown();
1385
1386 if (_register_hdl)
1387 eldbus_signal_handler_del(_register_hdl);
1388 _register_hdl = NULL;
1389
1390 if (_unregister_hdl)
1391 eldbus_signal_handler_del(_unregister_hdl);
1392 _unregister_hdl = NULL;
789 1393
790 if (_cache_interface) 1394 if (_cache_interface)
791 eldbus_service_object_unregister(_cache_interface); 1395 eldbus_service_object_unregister(_cache_interface);
diff --git a/src/lib/elm_atspi_object.c b/src/lib/elm_atspi_object.c
index 612130a0c..790d3d2ed 100644
--- a/src/lib/elm_atspi_object.c
+++ b/src/lib/elm_atspi_object.c
@@ -5,9 +5,21 @@
5#include <Elementary.h> 5#include <Elementary.h>
6#include "elm_widget.h" 6#include "elm_widget.h"
7#include "elm_priv.h" 7#include "elm_priv.h"
8#include "assert.h"
8 9
9#include "atspi/atspi-constants.h" 10#include "atspi/atspi-constants.h"
10 11
12static Elm_Atspi_Object *_app;
13static Eina_List *_global_callbacks;
14
15typedef struct _Elm_Atspi_Global_Callback_Info Elm_Atspi_Global_Callback_Info;
16
17struct _Elm_Atspi_Global_Callback_Info
18{
19 Eo_Event_Cb cb;
20 void *user_data;
21};
22
11const char* Atspi_Name[] = { 23const char* Atspi_Name[] = {
12 "invalid", 24 "invalid",
13 "accelerator label", 25 "accelerator label",
@@ -115,177 +127,313 @@ const char* Atspi_Name[] = {
115 "last defined" 127 "last defined"
116}; 128};
117 129
118#define ARG_GET(valist, type) va_arg(*valist, type) 130extern Eina_List *_elm_win_list;
119 131
120static Elm_Atspi_Object * _elm_atspi_factory_construct(Evas_Object *obj, Elm_Atspi_Object *); 132EAPI Eo_Op ELM_ATSPI_OBJ_BASE_ID = EO_NOOP;
121 133
122extern Eina_List *_elm_win_list; 134EAPI const Eo_Event_Description _EV_ATSPI_OBJ_NAME_CHANGED =
135 EO_EVENT_DESCRIPTION("name,changed", "Called when accessible object text has changed.");
123 136
124typedef struct _Atspi_Object_Data Atspi_Object_Data; 137EAPI const Eo_Event_Description _EV_ATSPI_OBJ_CHILD_ADD =
138 EO_EVENT_DESCRIPTION("child,added", "Called when accessible object children was created.");
125 139
126struct _Atspi_Object_Data 140EAPI const Eo_Event_Description _EV_ATSPI_OBJ_CHILD_DEL =
127{ 141 EO_EVENT_DESCRIPTION("child,removed", "Called when accessible object children was destroyed.");
128 const char *name;
129 const char *description;
130 AtspiRole role;
131};
132 142
133EAPI Eo_Op ELM_ATSPI_OBJ_BASE_ID = EO_NOOP; 143EAPI const Eo_Event_Description _EV_ATSPI_OBJ_STATE_CHANGED =
144 EO_EVENT_DESCRIPTION("state,changed", "Called when accessible object state has changed.");
145
146EAPI const Eo_Event_Description _EV_ATSPI_OBJ_WINDOW_ACTIVATED =
147 EO_EVENT_DESCRIPTION("widnow,created", "Called when new window has been activated. (unfocuesed)");
148
149EAPI const Eo_Event_Description _EV_ATSPI_OBJ_WINDOW_DEACTIVATED =
150 EO_EVENT_DESCRIPTION("widnow,created", "Called when new window has been deactivated (unfocused).");
151
152static void
153_eo_emit_state_changed_event(void *data, Evas *e EINA_UNUSED, Evas_Object *eo EINA_UNUSED, void *event_info EINA_UNUSED)
154{
155 Elm_Atspi_Object *ao = data;
156 int event_data[2] = {ATSPI_STATE_VISIBLE, 1};
157 eo_do(ao, eo_event_callback_call(EV_ATSPI_OBJ_STATE_CHANGED, &event_data[0], NULL));
158}
134 159
135static void 160static void
136_description_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list) 161_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
137{ 162{
138 const char **ret = ARG_GET(list, const char **); 163 Evas_Object *internal_obj = NULL;
139 Atspi_Object_Data *ad = _pd; 164 eo_do_super(obj, ELM_ATSPI_CLASS, eo_constructor());
165
166 eo_do(obj, eo_parent_get(&internal_obj));
140 167
141 *ret = ad->description; 168 /* Evas_Object can only hold refs to atspi-object */
169 assert(eo_isa(internal_obj, EVAS_OBJ_SMART_CLASS));
170
171 evas_object_data_set(internal_obj, "_atspi_object", obj);
172 evas_object_event_callback_add(internal_obj, EVAS_CALLBACK_SHOW, _eo_emit_state_changed_event, obj);
173}
174
175static void
176_destructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
177{
178 eo_do_super(obj, ELM_ATSPI_CLASS, eo_destructor());
142} 179}
143 180
144static void 181static void
145_description_set(Eo *obj EINA_UNUSED, void *_pd, va_list *list) 182_child_at_index_get(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
146{ 183{
147 const char *desc = ARG_GET(list, const char *); 184 EO_PARAMETER_GET(int, idx, list);
148 Atspi_Object_Data *ad = _pd; 185 EO_PARAMETER_GET(Elm_Atspi_Object**, ao, list);
186 Eina_List *children = NULL;
149 187
150 if (ad->description) 188 eo_do(obj, elm_atspi_obj_children_get(&children));
151 eina_stringshare_del(ad->description); 189 if (!children) return;
152 190
153 ad->description = eina_stringshare_add(desc); 191 if (ao) *ao = eina_list_nth(children, idx);
192 eina_list_free(children);
154} 193}
155 194
156static void 195static void
157_parent_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list) 196_object_get(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
158{ 197{
159 Elm_Atspi_Object **ret = ARG_GET(list, Elm_Atspi_Object**); 198 EO_PARAMETER_GET(Evas_Object**, ret, list);
160 eo_do(obj, eo_parent_get(ret)); 199 eo_do(obj, eo_parent_get(ret));
161} 200}
162 201
163static void 202static void
164_name_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) 203_index_in_parent_get(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
165{ 204{
166 const char **ret = ARG_GET(list, const char **); 205 EO_PARAMETER_GET(unsigned int*, idx, list);
167 Atspi_Object_Data *ad = _pd; 206 Elm_Atspi_Object *chld, *parent = NULL;
207 Eina_List *l, *children = NULL;
208 unsigned int tmp = 0;
209
210 eo_do(obj, elm_atspi_obj_parent_get(&parent));
211 if (!parent) return;
212 eo_do(parent, elm_atspi_obj_children_get(&children));
168 213
169 *ret = ad->name; 214 EINA_LIST_FOREACH(children, l, chld)
215 {
216 if (chld == obj)
217 {
218 if (idx) *idx = tmp;
219 break;
220 }
221 tmp++;
222 }
223 if (tmp == eina_list_count(children))
224 ERR("Access object not present in parent's children list!");
225
226 eina_list_free(children);
170} 227}
171 228
172static void 229static void
173_name_set(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) 230_role_name_get(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
174{ 231{
175 const char *name = ARG_GET(list, const char *); 232 EO_PARAMETER_GET(const char **, ret, list);
176 Atspi_Object_Data *ad = _pd; 233 AtspiRole role = ATSPI_ROLE_INVALID;
234
235 eo_do(obj, elm_atspi_obj_role_get(&role));
236
237 if (role >= ATSPI_ROLE_LAST_DEFINED)
238 {
239 ERR("Invalid role enum for atspi-object: %d.", role);
240 return;
241 }
177 242
178 if (ad->name) 243 if (ret) *ret = Atspi_Name[role];
179 eina_stringshare_del(ad->name); 244}
180 245
181 ad->name = eina_stringshare_add(name); 246static void
247_description_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
248{
249 EO_PARAMETER_GET(const char **, ret, list);
250 *ret = NULL;
182} 251}
183 252
184static void 253static void
185_role_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) 254_localized_role_name_get(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
186{ 255{
187 AtspiRole *ret = ARG_GET(list, AtspiRole *); 256 EO_PARAMETER_GET(const char **, ret, list);
188 Atspi_Object_Data *ad = _pd; 257 const char *name = NULL;
189 258
190 *ret = ad->role; 259 eo_do(obj, elm_atspi_obj_role_name_get(&name));
260 if (!name) return;
261#ifdef ENABLE_NLS
262 if (ret) *ret = gettext(name);
263#else
264 if (ret) *ret = name;
265#endif
191} 266}
192 267
193static void 268static void
194_role_set(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) 269_state_get(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
195{ 270{
196 AtspiRole role = ARG_GET(list, int); 271 EO_PARAMETER_GET(Elm_Atspi_State *, ret, list);
197 Atspi_Object_Data *ad = _pd; 272 Evas_Object *evobj = NULL;
273 Elm_Atspi_State states = 0;
274 eo_do(obj, elm_atspi_obj_object_get(&evobj));
198 275
199 ad->role = role; 276 if (evas_object_visible_get(evobj))
277 BIT_FLAG_SET(states, ATSPI_STATE_VISIBLE);
278
279 if (ret) *ret = states;
200} 280}
201 281
202static void 282static void
203_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) 283_comp_access_at_point_get(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
204{ 284{
205 eo_do_super(obj, ELM_ATSPI_CLASS, eo_constructor()); 285 EO_PARAMETER_GET(int, x, list);
206 Atspi_Object_Data *ad = _pd; 286 EO_PARAMETER_GET(int, y, list);
207 ad->name = ad->description = NULL; 287 EO_PARAMETER_GET(AtspiCoordType, type, list);
288 EO_PARAMETER_GET(Evas_Object **, ret, list);
289 int ee_x, ee_y;
290 Eina_List *l, *objs;
291 Evas_Object *evobj = NULL;
292
293 eo_do(obj, elm_atspi_obj_object_get(&evobj));
294
295 if (!evobj) return;
296 if (type == ATSPI_COORD_TYPE_SCREEN)
297 {
298 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(evobj));
299 if (!ee) return;
300 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
301 x -= ee_x;
302 y -= ee_y;
303 }
304 objs = evas_objects_at_xy_get(evas_object_evas_get(evobj), x, y, EINA_TRUE, EINA_TRUE);
305 EINA_LIST_FOREACH(objs, l, evobj)
306 {
307 // return first only, test if there is atspi interface for eo
308 Elm_Atspi_Object *acc = _elm_atspi_factory_construct(evobj);
309 if (acc)
310 {
311 *ret = evobj;
312 break;
313 }
314 }
315 eina_list_free(objs);
208} 316}
209 317
210static void 318static void
211_destructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) 319_comp_extents_get(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
212{ 320{
213 Atspi_Object_Data *ad = _pd; 321 EO_PARAMETER_GET(int *, x, list);
322 EO_PARAMETER_GET(int*, y, list);
323 EO_PARAMETER_GET(int*, w, list);
324 EO_PARAMETER_GET(int*, h, list);
325 EO_PARAMETER_GET(AtspiCoordType, type, list);
326 int ee_x, ee_y;
327 Evas_Object *evobj = NULL;
214 328
215 eina_stringshare_del(ad->name); 329 eo_do(obj, elm_atspi_obj_object_get(&evobj));
216 eina_stringshare_del(ad->description); 330 if (!evobj) return;
217 331
218 eo_do_super(obj, ELM_ATSPI_CLASS, eo_destructor()); 332 evas_object_geometry_get(evobj, x, y, w, h);
333 if (type == ATSPI_COORD_TYPE_SCREEN)
334 {
335 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(evobj));
336 if (!ee) return;
337 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
338 if (x) *x += ee_x;
339 if (y) *y += ee_y;
340 }
219} 341}
220 342
221static void 343static void
222_role_name_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) 344_comp_extents_set(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
223{ 345{
224 const char **ret = ARG_GET(list, const char **); 346 EO_PARAMETER_GET(int, x, list);
225 Atspi_Object_Data *ad = _pd; 347 EO_PARAMETER_GET(int, y, list);
348 EO_PARAMETER_GET(int, w, list);
349 EO_PARAMETER_GET(int, h, list);
350 EO_PARAMETER_GET(AtspiCoordType, type, list);
351 EO_PARAMETER_GET(Eina_Bool *, ret, list);
352 int wx, wy;
353 Evas_Object *evobj = NULL;
354
355 if (ret) *ret = EINA_FALSE;
356 if ((x < 0) || (y < 0) || (w < 0) || (h < 0)) return;
357
358 eo_do(obj, elm_atspi_obj_object_get(&evobj));
359 if (!evobj) return;
360
361 if (type == ATSPI_COORD_TYPE_SCREEN)
362 {
363 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(evobj));
364 if (!ee) return;
365 evas_object_geometry_get(evobj, &wx, &wy, NULL, NULL);
366 ecore_evas_move(ee, x - wx, y - wy);
367 }
368 else
369 evas_object_move(evobj, x, y);
226 370
227 *ret = Atspi_Name[ad->role]; 371 evas_object_resize(evobj, w, h);
372 if (ret) *ret = EINA_TRUE;
228} 373}
229 374
230static void 375static void
231_localized_role_name_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) 376_comp_layer_get(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
232{ 377{
233 const char **ret = ARG_GET(list, const char **); 378 EO_PARAMETER_GET(int *, ret, list);
234 Atspi_Object_Data *ad = _pd; 379 Elm_Object_Layer layer;
380 Evas_Object *evobj = NULL;
381 AtspiComponentLayer spi_layer;
382
383 eo_do(obj, elm_atspi_obj_object_get(&evobj));
384 if (!evobj) return;
385
386 layer = evas_object_layer_get(evobj);
387 switch (layer) {
388 case ELM_OBJECT_LAYER_BACKGROUND:
389 spi_layer = ATSPI_LAYER_BACKGROUND;
390 break;
391 case ELM_OBJECT_LAYER_FOCUS:
392 case ELM_OBJECT_LAYER_TOOLTIP:
393 case ELM_OBJECT_LAYER_CURSOR:
394 spi_layer = ATSPI_LAYER_OVERLAY;
395 break;
396 default:
397 spi_layer = ATSPI_LAYER_WIDGET;
398 }
399 if (ret) *ret = spi_layer;
400}
235 401
236#ifdef ENABLE_NLS 402static void
237 *ret = gettext(Atspi_Name[ad->role]); 403_comp_z_order_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
238#else 404{
239 *ret = Atspi_Name[ad->role]; 405 // FIXME
240#endif
241} 406}
242 407
243static void 408static void
244_child_at_index_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list) 409_cb_call(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
245{ 410{
246 int idx = ARG_GET(list, int); 411 Elm_Atspi_Global_Callback_Info *info;
247 Elm_Atspi_Object **ao = ARG_GET(list, Elm_Atspi_Object**); 412 Eina_List *l;
248 Eina_List *children = NULL; 413 EO_PARAMETER_GET(const Eo_Event_Description *, desc, list);
249 eo_do(obj, elm_atspi_obj_children_get(&children)); 414 EO_PARAMETER_GET(void *, event_info, list);
415 EO_PARAMETER_GET(Eina_Bool *, ret, list);
250 416
251 if (children) 417 EINA_LIST_FOREACH(_global_callbacks, l, info)
252 *ao = eina_list_nth(children, idx); 418 {
253 else 419 if (info->cb) info->cb(info->user_data, obj, desc, event_info);
254 *ao = NULL; 420 }
255 421
256 eina_list_free(children); 422 eo_do_super(obj, ELM_ATSPI_CLASS, eo_event_callback_call(desc, event_info, ret));
257} 423}
258 424
259static void 425static void
260_index_in_parent_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list) 426_comp_alpha_get(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
261{ 427{
262 unsigned int *idx = ARG_GET(list, unsigned int*); 428 EO_PARAMETER_GET(double *, ret, list);
263 Elm_Atspi_Object *chld, *parent = NULL; 429 Evas_Object *evobj = NULL;
264 Eina_List *l, *children = NULL; 430 int alpha;
265 unsigned int tmp = 0;
266 eo_do(obj, elm_atspi_obj_parent_get(&parent));
267 431
268 if (parent) 432 eo_do(obj, elm_atspi_obj_object_get(&evobj));
269 { 433 if (!evobj) return;
270 eo_do(parent, elm_atspi_obj_children_get(&children));
271 EINA_LIST_FOREACH(children, l, chld)
272 {
273 if (chld == obj)
274 {
275 *idx = tmp;
276 break;
277 }
278 tmp++;
279 }
280 if (tmp == eina_list_count(children))
281 ERR("Access object not present in parent's children list!");
282 EINA_LIST_FREE(children, chld)
283 eo_unref(chld);
284 434
285 eo_unref(parent); 435 evas_object_color_get(evobj, NULL, NULL, NULL, &alpha);
286 } 436 if (ret) *ret = (double)alpha / 255.0;
287 else
288 DBG("Access Object has no parent.");
289} 437}
290 438
291static void 439static void
@@ -294,17 +442,20 @@ _class_constructor(Eo_Class *klass)
294 const Eo_Op_Func_Description func_desc[] = { 442 const Eo_Op_Func_Description func_desc[] = {
295 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor), 443 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
296 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor), 444 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor),
297 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_NAME_GET), _name_get), 445 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_CALL), _cb_call),
298 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_NAME_SET), _name_set), 446 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_OBJECT_GET), _object_get),
299 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_DESCRIPTION_GET), _description_get),
300 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_DESCRIPTION_SET), _description_set),
301 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_PARENT_GET), _parent_get),
302 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_CHILD_AT_INDEX_GET), _child_at_index_get), 447 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_CHILD_AT_INDEX_GET), _child_at_index_get),
303 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_INDEX_IN_PARENT_GET), _index_in_parent_get), 448 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_INDEX_IN_PARENT_GET), _index_in_parent_get),
304 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_ROLE_GET), _role_get),
305 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_ROLE_SET), _role_set),
306 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_ROLE_NAME_GET), _role_name_get), 449 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_ROLE_NAME_GET), _role_name_get),
450 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_DESCRIPTION_GET), _description_get),
307 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_LOCALIZED_ROLE_NAME_GET), _localized_role_name_get), 451 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_LOCALIZED_ROLE_NAME_GET), _localized_role_name_get),
452 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_STATE_GET), _state_get),
453 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_ACCESSIBLE_AT_POINT_GET), _comp_access_at_point_get),
454 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_EXTENTS_GET), _comp_extents_get),
455 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_EXTENTS_SET), _comp_extents_set),
456 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_LAYER_GET), _comp_layer_get),
457 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_Z_ORDER_GET), _comp_z_order_get),
458 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_ALPHA_GET), _comp_alpha_get),
308 EO_OP_FUNC_SENTINEL 459 EO_OP_FUNC_SENTINEL
309 }; 460 };
310 eo_class_funcs_set(klass, func_desc); 461 eo_class_funcs_set(klass, func_desc);
@@ -312,17 +463,14 @@ _class_constructor(Eo_Class *klass)
312 463
313static const Eo_Op_Description op_desc[] = { 464static const Eo_Op_Description op_desc[] = {
314 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_NAME_GET, ""), 465 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_NAME_GET, ""),
315 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_NAME_SET, ""),
316 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_DESCRIPTION_GET, ""), 466 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_DESCRIPTION_GET, ""),
317 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_DESCRIPTION_SET, ""),
318 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_PARENT_GET, ""),
319 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_CHILD_AT_INDEX_GET, ""), 467 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_CHILD_AT_INDEX_GET, ""),
320 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_CHILDREN_GET, ""), 468 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_CHILDREN_GET, ""),
469 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_PARENT_GET, ""),
470 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_OBJECT_GET, ""),
321 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_INDEX_IN_PARENT_GET, ""), 471 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_INDEX_IN_PARENT_GET, ""),
322 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_RELATION_SET_GET, ""), 472 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_RELATION_SET_GET, ""),
323 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_RELATION_SET_SET, ""),
324 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_ROLE_GET, ""), 473 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_ROLE_GET, ""),
325 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_ROLE_SET, ""),
326 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_ROLE_NAME_GET, ""), 474 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_ROLE_NAME_GET, ""),
327 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_LOCALIZED_ROLE_NAME_GET, ""), 475 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_LOCALIZED_ROLE_NAME_GET, ""),
328 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_STATE_GET, ""), 476 EO_OP_DESCRIPTION(ELM_ATSPI_OBJ_SUB_ID_STATE_GET, ""),
@@ -330,18 +478,26 @@ static const Eo_Op_Description op_desc[] = {
330 EO_OP_DESCRIPTION_SENTINEL 478 EO_OP_DESCRIPTION_SENTINEL
331}; 479};
332 480
481static const Eo_Event_Description *event_desc[] = {
482 EV_ATSPI_OBJ_NAME_CHANGED,
483 EV_ATSPI_OBJ_STATE_CHANGED,
484 EV_ATSPI_OBJ_CHILD_ADD,
485 EV_ATSPI_OBJ_CHILD_DEL,
486 NULL
487};
488
333static const Eo_Class_Description class_desc = { 489static const Eo_Class_Description class_desc = {
334 EO_VERSION, 490 EO_VERSION,
335 "Access_Object", 491 "Elm_Atspi_Object",
336 EO_CLASS_TYPE_REGULAR, 492 EO_CLASS_TYPE_REGULAR,
337 EO_CLASS_DESCRIPTION_OPS(&ELM_ATSPI_OBJ_BASE_ID, op_desc, ELM_ATSPI_OBJ_SUB_ID_LAST), 493 EO_CLASS_DESCRIPTION_OPS(&ELM_ATSPI_OBJ_BASE_ID, op_desc, ELM_ATSPI_OBJ_SUB_ID_LAST),
338 NULL, 494 event_desc,
339 sizeof(Atspi_Object_Data), 495 0,
340 _class_constructor, 496 _class_constructor,
341 NULL 497 NULL
342}; 498};
343 499
344EO_DEFINE_CLASS(elm_atspi_obj_class_get, &class_desc, EO_BASE_CLASS, NULL); 500EO_DEFINE_CLASS(elm_atspi_obj_class_get, &class_desc, EO_BASE_CLASS, ELM_ATSPI_COMPONENT_INTERFACE, NULL);
345 501
346// Component interface 502// Component interface
347EAPI Eo_Op ELM_ATSPI_COMPONENT_INTERFACE_BASE_ID = EO_NOOP; 503EAPI Eo_Op ELM_ATSPI_COMPONENT_INTERFACE_BASE_ID = EO_NOOP;
@@ -349,9 +505,9 @@ EAPI Eo_Op ELM_ATSPI_COMPONENT_INTERFACE_BASE_ID = EO_NOOP;
349static void 505static void
350_comp_interface_position_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) 506_comp_interface_position_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
351{ 507{
352 int *x = ARG_GET(list, int*); 508 EO_PARAMETER_GET(int *, x, list);
353 int *y = ARG_GET(list, int*); 509 EO_PARAMETER_GET(int *, y, list);
354 AtspiCoordType type = ARG_GET(list, AtspiCoordType); 510 EO_PARAMETER_GET(AtspiCoordType, type, list);
355 511
356 eo_do(obj, elm_atspi_component_interface_extents_get(x, y, NULL, NULL, type)); 512 eo_do(obj, elm_atspi_component_interface_extents_get(x, y, NULL, NULL, type));
357} 513}
@@ -359,10 +515,10 @@ _comp_interface_position_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list
359static void 515static void
360_comp_interface_position_set(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) 516_comp_interface_position_set(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
361{ 517{
362 int x = ARG_GET(list, int); 518 EO_PARAMETER_GET(int, x, list);
363 int y = ARG_GET(list, int); 519 EO_PARAMETER_GET(int, y, list);
364 AtspiCoordType type = ARG_GET(list, AtspiCoordType); 520 EO_PARAMETER_GET(AtspiCoordType, type, list);
365 Eina_Bool *ret = ARG_GET(list, Eina_Bool*); 521 EO_PARAMETER_GET(Eina_Bool*, ret, list);
366 int c_w, c_h; 522 int c_w, c_h;
367 523
368 eo_do(obj, elm_atspi_component_interface_extents_get(NULL, NULL, &c_w, &c_h, type)); 524 eo_do(obj, elm_atspi_component_interface_extents_get(NULL, NULL, &c_w, &c_h, type));
@@ -372,9 +528,9 @@ _comp_interface_position_set(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list
372static void 528static void
373_comp_interface_size_set(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) 529_comp_interface_size_set(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
374{ 530{
375 int w = ARG_GET(list, int); 531 EO_PARAMETER_GET(int, w, list);
376 int h = ARG_GET(list, int); 532 EO_PARAMETER_GET(int, h, list);
377 Eina_Bool *ret = ARG_GET(list, Eina_Bool*); 533 EO_PARAMETER_GET(Eina_Bool*, ret, list);
378 int c_x, c_y; 534 int c_x, c_y;
379 535
380 eo_do(obj, elm_atspi_component_interface_extents_get(&c_x, &c_y, NULL, NULL, ATSPI_COORD_TYPE_WINDOW)); 536 eo_do(obj, elm_atspi_component_interface_extents_get(&c_x, &c_y, NULL, NULL, ATSPI_COORD_TYPE_WINDOW));
@@ -384,8 +540,8 @@ _comp_interface_size_set(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *li
384static void 540static void
385_comp_interface_size_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) 541_comp_interface_size_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
386{ 542{
387 int *w = ARG_GET(list, int*); 543 EO_PARAMETER_GET(int*, w, list);
388 int *h = ARG_GET(list, int*); 544 EO_PARAMETER_GET(int*, h, list);
389 545
390 eo_do(obj, elm_atspi_component_interface_extents_get(NULL, NULL, w, h, ATSPI_COORD_TYPE_WINDOW)); 546 eo_do(obj, elm_atspi_component_interface_extents_get(NULL, NULL, w, h, ATSPI_COORD_TYPE_WINDOW));
391} 547}
@@ -393,32 +549,25 @@ _comp_interface_size_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *li
393static void 549static void
394_comp_interface_contains(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list) 550_comp_interface_contains(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list)
395{ 551{
396 int x = ARG_GET(list, int); 552 EO_PARAMETER_GET(int, x, list);
397 int y = ARG_GET(list, int); 553 EO_PARAMETER_GET(int, y, list);
398 AtspiCoordType type = ARG_GET(list, AtspiCoordType); 554 EO_PARAMETER_GET(AtspiCoordType, type, list);
399 Eina_Bool *ret = ARG_GET(list, Eina_Bool*); 555 EO_PARAMETER_GET(Eina_Bool*, ret, list);
400 int w_x, w_y, w_w, w_h; 556 int w_x, w_y, w_w, w_h;
401 557
402 *ret = EINA_FALSE; 558 if (ret) *ret = EINA_FALSE;
403 559
404 if (!eo_do(obj, elm_atspi_component_interface_extents_get(&w_x, &w_y, &w_w, &w_h, type))) 560 if (!eo_do(obj, elm_atspi_component_interface_extents_get(&w_x, &w_y, &w_w, &w_h, type)))
405 return; 561 return;
406 562
407 if ((x >= w_x) && (x <= w_x + w_w) && (y >= w_y) && (y <= w_y + w_h)) 563 if ((x >= w_x) && (x <= w_x + w_w) && (y >= w_y) && (y <= w_y + w_h))
408 *ret = EINA_TRUE; 564 if (ret) *ret = EINA_TRUE;
409}
410
411static void
412_component_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
413{
414 eo_do_super(obj, ELM_ATSPI_COMPONENT_INTERFACE, eo_constructor());
415} 565}
416 566
417static void 567static void
418_component_interface_constructor(Eo_Class *klass) 568_component_interface_constructor(Eo_Class *klass)
419{ 569{
420 const Eo_Op_Func_Description func_desc[] = { 570 const Eo_Op_Func_Description func_desc[] = {
421 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _component_constructor),
422 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_POSITION_GET), _comp_interface_position_get), 571 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_POSITION_GET), _comp_interface_position_get),
423 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_POSITION_SET), _comp_interface_position_set), 572 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_POSITION_SET), _comp_interface_position_set),
424 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_CONTAINS), _comp_interface_contains), 573 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_CONTAINS), _comp_interface_contains),
@@ -459,232 +608,174 @@ static const Eo_Class_Description component_interface_desc = {
459 608
460EO_DEFINE_CLASS(elm_atspi_component_interface_get, &component_interface_desc, NULL, NULL); 609EO_DEFINE_CLASS(elm_atspi_component_interface_get, &component_interface_desc, NULL, NULL);
461 610
462/// Elm_Atspi_Widget base class 611// Window Interface
463#define ELM_ATSPI_WIDGET_CLASS elm_atspi_widget_obj_class_get()
464 612
465const Eo_Class *elm_atspi_widget_obj_class_get(void) EINA_CONST; 613static const Eo_Event_Description *window_event_desc[] = {
466 614 EV_ATSPI_OBJ_WINDOW_ACTIVATED,
467typedef struct _Access_Widget_Object_Data Access_Widget_Object_Data; 615 EV_ATSPI_OBJ_WINDOW_DEACTIVATED,
616 NULL
617};
468 618
469struct _Access_Widget_Object_Data 619static const Eo_Class_Description window_interface_desc = {
470{ 620 EO_VERSION,
471 Evas_Object *obj; 621 "Elm_Atspi_Window_Interface",
622 EO_CLASS_TYPE_INTERFACE,
623 EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
624 window_event_desc,
625 0,
626 NULL,
627 NULL
472}; 628};
473 629
474static void 630EO_DEFINE_CLASS(elm_atspi_window_interface_get, &window_interface_desc, NULL, NULL);
475_del_ao_obj(void *data, Evas *e EINA_UNUSED, Evas_Object *eo EINA_UNUSED, void *event_info EINA_UNUSED)
476{
477 Elm_Atspi_Object *obj = data;
478 Access_Widget_Object_Data *ad = eo_data_scope_get(obj, ELM_ATSPI_WIDGET_CLASS);
479 ad->obj = NULL;
480 // below will cause Accessibility object destruction while evas object is destroyed and access object has none extra refs
481 eo_unref(obj);
482}
483 631
632/// Elm_Atspi_Widget base class
484static void 633static void
485_widget_constructor(Eo *obj, void *_pd, va_list *list) 634_emit_atspi_state_changed_focused_event(void *data, Evas_Object *eo EINA_UNUSED, void *event_info EINA_UNUSED)
486{ 635{
487 Evas_Object *widget = ARG_GET(list, Evas_Object*); 636 Elm_Atspi_Object *ao = data;
488 Access_Widget_Object_Data *ad = _pd; 637 int evdata[2] = {ATSPI_STATE_FOCUSED, 1};
489 const char *name; 638 eo_do(ao, eo_event_callback_call(EV_ATSPI_OBJ_STATE_CHANGED, &evdata[0], NULL));
490
491 eo_do_super(obj, ELM_ATSPI_WIDGET_CLASS, eo_constructor());
492 name = evas_object_type_get(widget);
493
494 evas_object_event_callback_add(widget, EVAS_CALLBACK_DEL, _del_ao_obj, obj);
495
496 ad->obj = widget;
497 eo_do(obj, elm_atspi_obj_name_set(name));
498 eo_do(obj, elm_atspi_obj_role_set(ATSPI_ROLE_UNKNOWN));
499} 639}
500 640
501static void 641static void
502_widget_destructor(Eo *obj, void *_pd, va_list *list EINA_UNUSED) 642_emit_atspi_state_changed_unfocused_event(void *data, Evas_Object *eo EINA_UNUSED, void *event_info EINA_UNUSED)
503{ 643{
504 Access_Widget_Object_Data *ad = _pd; 644 Elm_Atspi_Object *ao = data;
505 if (ad->obj) 645 int evdata[2] = {ATSPI_STATE_FOCUSED, 0};
506 evas_object_event_callback_del(ad->obj, EVAS_CALLBACK_DEL, _del_ao_obj); 646 eo_do(ao, eo_event_callback_call(EV_ATSPI_OBJ_STATE_CHANGED, &evdata[0], NULL));
507
508 eo_do_super(obj, ELM_ATSPI_WIDGET_CLASS, eo_destructor());
509} 647}
510 648
511static void 649static void
512_widget_children_get(Eo *obj, void *_pd, va_list *list) 650_widget_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
513{ 651{
514 Eina_List **ret = ARG_GET(list, Eina_List**); 652 Evas_Object *internal_obj = NULL;
515 Access_Widget_Object_Data *ad = _pd; 653 eo_do_super(obj, ELM_ATSPI_WIDGET_CLASS, eo_constructor());
516 Eina_List *l, *al = NULL;
517 Evas_Object *sub;
518 Elm_Atspi_Object *ao;
519 Elm_Widget_Smart_Data *sd;
520
521 EINA_SAFETY_ON_NULL_GOTO(ad->obj, fail);
522 654
523 sd = eo_data_scope_get(ad->obj, ELM_OBJ_WIDGET_CLASS); 655 eo_do(obj, eo_parent_get(&internal_obj));
524 EINA_SAFETY_ON_NULL_GOTO(sd, fail);
525 656
526 EINA_LIST_FOREACH(sd->subobjs, l, sub) { 657 /* Evas_Object can only hold refs to atspi-object */
527 if (!sub) continue; 658 assert(eo_isa(internal_obj, ELM_OBJ_WIDGET_CLASS));
528 ao = _elm_atspi_factory_construct(sub, obj);
529 if (ao)
530 al = eina_list_append(al, ao);
531 }
532 659
533 *ret = al; 660 evas_object_smart_callback_add(internal_obj, "focused", _emit_atspi_state_changed_focused_event, obj);
534 return; 661 evas_object_smart_callback_add(internal_obj, "unfocused", _emit_atspi_state_changed_unfocused_event, obj);
535
536fail:
537 *ret = NULL;
538 return;
539} 662}
540 663
541
542static void 664static void
543_widget_state_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) 665_widget_name_get(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
544{ 666{
545 // FIXME 667 EO_PARAMETER_GET(const char **, ret, list);
546} 668 Evas_Object *widget = NULL;
669 const char *name = NULL;
547 670
548 671 eo_do(obj, elm_atspi_obj_object_get(&widget));
549static void 672 name = elm_object_text_get(widget);
550_widget_comp_access_at_point_get(Eo *obj, void *_pd, va_list *list) 673 if (ret) *ret = name;
551{
552 int x = ARG_GET(list, int);
553 int y = ARG_GET(list, int);
554 AtspiCoordType type = ARG_GET(list, AtspiCoordType);
555 Elm_Atspi_Object **ret = ARG_GET(list, Elm_Atspi_Object**);
556 int ee_x, ee_y;
557 Access_Widget_Object_Data *ad = _pd;
558 Eina_List *l, *objs;
559 Evas_Object *wid;
560
561 if (ad->obj)
562 {
563 if (type == ATSPI_COORD_TYPE_SCREEN)
564 {
565 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(ad->obj));
566 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
567 x -= ee_x;
568 y -= ee_y;
569 }
570 objs = evas_objects_at_xy_get(evas_object_evas_get(ad->obj), x, y, EINA_TRUE, EINA_TRUE);
571 EINA_LIST_FOREACH(objs, l, wid)
572 {
573 // return first only
574 if (elm_object_widget_check(wid))
575 {
576 *ret = _elm_atspi_factory_construct(wid, obj);
577 break;
578 }
579 }
580 eina_list_free(objs);
581 }
582} 674}
583 675
584static void 676static void
585_widget_comp_extents_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list) 677_widget_role_get(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
586{ 678{
587 Access_Widget_Object_Data *ad = _pd; 679 EO_PARAMETER_GET(AtspiRole*, ret, list);
588 int *x, *y, *w, *h; 680 const char *type;
589 int ee_x, ee_y; 681 AtspiRole role;
590 x = ARG_GET(list, int*); 682 Evas_Object *widget = NULL;
591 y = ARG_GET(list, int*); 683 eo_do(obj, elm_atspi_obj_object_get(&widget));
592 w = ARG_GET(list, int*); 684 if (!widget) return;
593 h = ARG_GET(list, int*); 685 type = evas_object_type_get(widget);
594 AtspiCoordType type = ARG_GET(list, AtspiCoordType); 686
687 // FIXME make it hash or cast some first bytes to int.
688 if (!strcmp(type, "elm_win"))
689 role = ATSPI_ROLE_WINDOW;
690 else if (!strcmp(type, "elm_button"))
691 role = ATSPI_ROLE_PUSH_BUTTON;
692 else
693 role = ATSPI_ROLE_UNKNOWN;
595 694
596 if (ad->obj) 695 if (ret) *ret = role;
597 {
598 evas_object_geometry_get(ad->obj, x, y, w, h);
599 if (type == ATSPI_COORD_TYPE_SCREEN)
600 {
601 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(ad->obj));
602 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
603 if (x) *x += ee_x;
604 if (y) *y += ee_y;
605 }
606 }
607} 696}
608 697
609static void 698static void
610_widget_comp_extents_set(Eo *obj EINA_UNUSED, void *_pd, va_list *list) 699_widget_parent_get(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
611{ 700{
612 Access_Widget_Object_Data *ad = _pd; 701 EO_PARAMETER_GET(Elm_Atspi_Object **, ret, list);
613 int x, y, w, h; 702 Evas_Object *widget = NULL;
614 int wx, wy; 703 Elm_Atspi_Object *parent;
615 x = ARG_GET(list, int);
616 y = ARG_GET(list, int);
617 w = ARG_GET(list, int);
618 h = ARG_GET(list, int);
619 AtspiCoordType type = ARG_GET(list, AtspiCoordType);
620 Eina_Bool *ret = ARG_GET(list, Eina_Bool*);
621 704
622 *ret = EINA_FALSE; 705 eo_do(obj, elm_atspi_obj_object_get(&widget));
706 widget = elm_object_parent_widget_get(widget);
623 707
624 if ((x < 0) || (y < 0) || (w < 0) || (h < 0)) return; 708 if (widget)
709 parent = _elm_atspi_factory_construct(widget);
710 else // if parent is not found, attach it to atspi root object.
711 parent = _elm_atspi_root_object_get();
625 712
626 if (ad->obj) 713 if (ret) *ret = parent;
627 {
628 if (type == ATSPI_COORD_TYPE_SCREEN)
629 {
630 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(ad->obj));
631 evas_object_geometry_get(ad->obj, &wx, &wy, NULL, NULL);
632 ecore_evas_move(ee, x - wx, y - wy);
633 }
634 else
635 evas_object_move(ad->obj, x, y);
636
637 evas_object_resize(ad->obj, w, h);
638 *ret = EINA_TRUE;
639 }
640} 714}
641 715
642
643static void 716static void
644_widget_comp_layer_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list) 717_widget_children_get(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
645{ 718{
646 int *l = ARG_GET(list, int *); 719 EO_PARAMETER_GET(Eina_List **, ret, list);
647 Access_Widget_Object_Data *ad = _pd; 720 Evas_Object *widget = NULL;
721 Eina_List *l, *accs = NULL;
722 Elm_Widget_Smart_Data *sd;
723 Elm_Atspi_Object *aobj;
648 724
649 if (ad->obj) 725 eo_do(obj, elm_atspi_obj_object_get(&widget));
650 *l = evas_object_layer_get(ad->obj);
651}
652 726
653static void 727 sd = eo_data_scope_get(widget, ELM_OBJ_WIDGET_CLASS);
654_widget_comp_z_order_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) 728 if (!sd) return;
655{ 729
656 // FIXME 730 EINA_LIST_FOREACH(sd->subobjs, l, widget)
731 {
732 if (!elm_object_widget_check(widget)) continue;
733 aobj = _elm_atspi_factory_construct(widget);
734 if (aobj)
735 accs = eina_list_append(accs, aobj);
736 }
737 if (ret)
738 *ret = accs;
739 else
740 eina_list_free(accs);
657} 741}
658 742
659static void 743static void
660_widget_comp_focus_grab(Eo *obj EINA_UNUSED, void *_pd, va_list *list) 744_widget_state_get(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
661{ 745{
662 Eina_Bool *ret = ARG_GET(list, Eina_Bool*); 746 EO_PARAMETER_GET(Elm_Atspi_State *, ret, list);
663 Access_Widget_Object_Data *ad = _pd; 747 Evas_Object *widget;
748 Elm_Atspi_State states;
749 eo_do(obj, elm_atspi_obj_object_get(&widget));
664 750
665 *ret = EINA_FALSE; 751 eo_do_super(obj, ELM_ATSPI_WIDGET_CLASS, elm_atspi_obj_state_get(&states));
666 752
667 if (ad->obj && elm_object_focus_allow_get(ad->obj)) 753 if (elm_object_focus_get(widget))
668 { 754 BIT_FLAG_SET(states, ATSPI_STATE_FOCUSED);
669 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(ad->obj)); 755 if (elm_object_focus_allow_get(widget))
756 BIT_FLAG_SET(states, ATSPI_STATE_FOCUSABLE);
757 if (!elm_object_disabled_get(widget))
758 BIT_FLAG_SET(states, ATSPI_STATE_ENABLED);
670 759
671 ecore_evas_activate(ee); 760 if (ret) *ret = states;
672 elm_object_focus_set(ad->obj, EINA_TRUE);
673 *ret = EINA_TRUE;
674 }
675} 761}
676 762
677static void 763static void
678_widget_comp_alpha_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list) 764_widget_comp_focus_grab(Eo *obj, void *_pd EINA_UNUSED, va_list *list)
679{ 765{
680 double *ret = ARG_GET(list, double*); 766 EO_PARAMETER_GET(Eina_Bool*, ret, list);
681 int alpha; 767 Evas_Object *evobj = NULL;
682 Access_Widget_Object_Data *ad = _pd; 768 if (ret) *ret = EINA_FALSE;
683 769
684 if (ad->obj) 770 eo_do(obj, elm_atspi_obj_object_get(&evobj));
771 EINA_SAFETY_ON_NULL_RETURN(evobj);
772 if (elm_object_focus_allow_get(evobj))
685 { 773 {
686 evas_object_color_get(ad->obj, NULL, NULL, NULL, &alpha); 774 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(evobj));
687 *ret = (double)alpha/255.0; 775 if (!ee) return;
776 ecore_evas_activate(ee);
777 elm_object_focus_set(evobj, EINA_TRUE);
778 if (ret) *ret = EINA_TRUE;
688 } 779 }
689} 780}
690 781
@@ -693,16 +784,12 @@ _widget_class_constructor(Eo_Class *klass)
693{ 784{
694 const Eo_Op_Func_Description func_desc[] = { 785 const Eo_Op_Func_Description func_desc[] = {
695 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _widget_constructor), 786 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _widget_constructor),
696 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _widget_destructor), 787 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_NAME_GET), _widget_name_get),
788 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_ROLE_GET), _widget_role_get),
789 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_PARENT_GET), _widget_parent_get),
697 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_CHILDREN_GET), _widget_children_get), 790 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_CHILDREN_GET), _widget_children_get),
698 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_STATE_GET), _widget_state_get), 791 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_STATE_GET), _widget_state_get),
699 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_ACCESSIBLE_AT_POINT_GET), _widget_comp_access_at_point_get),
700 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_EXTENTS_GET), _widget_comp_extents_get),
701 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_EXTENTS_SET), _widget_comp_extents_set),
702 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_LAYER_GET), _widget_comp_layer_get),
703 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_Z_ORDER_GET), _widget_comp_z_order_get),
704 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_FOCUS_GRAB), _widget_comp_focus_grab), 792 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_FOCUS_GRAB), _widget_comp_focus_grab),
705 EO_OP_FUNC(ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_ALPHA_GET), _widget_comp_alpha_get),
706 EO_OP_FUNC_SENTINEL 793 EO_OP_FUNC_SENTINEL
707 }; 794 };
708 eo_class_funcs_set(klass, func_desc); 795 eo_class_funcs_set(klass, func_desc);
@@ -710,77 +797,65 @@ _widget_class_constructor(Eo_Class *klass)
710 797
711static const Eo_Class_Description widget_class_desc = { 798static const Eo_Class_Description widget_class_desc = {
712 EO_VERSION, 799 EO_VERSION,
713 "Elm_Widget Access_Object", 800 "Elm_Widget_Access_Object",
714 EO_CLASS_TYPE_REGULAR, 801 EO_CLASS_TYPE_REGULAR,
715 EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0), 802 EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
716 NULL, 803 NULL,
717 sizeof(Access_Widget_Object_Data), 804 0,
718 _widget_class_constructor, 805 _widget_class_constructor,
719 NULL 806 NULL
720}; 807};
721 808
722EO_DEFINE_CLASS(elm_atspi_widget_obj_class_get, &widget_class_desc, ELM_ATSPI_CLASS, ELM_ATSPI_COMPONENT_INTERFACE, NULL); 809EO_DEFINE_CLASS(elm_atspi_widget_obj_class_get, &widget_class_desc, ELM_ATSPI_CLASS, NULL);
723 810
724static Elm_Atspi_Object *
725_elm_atspi_factory_construct(Evas_Object *obj, Elm_Atspi_Object *parent)
726{
727 Elm_Atspi_Object *ret;
728 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
729 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
730
731 if (!elm_object_widget_check(obj))
732 return NULL;
733
734 if (!strcmp(evas_object_type_get(obj), "elm_access"))
735 return NULL;
736
737 ret = evas_object_data_get(obj, "_atspi_object");
738 if (!ret)
739 {
740 ret = eo_add(ELM_ATSPI_WIDGET_CLASS, parent, obj);
741 evas_object_data_set(obj, "_atspi_object", ret);
742 eo_unref(ret); // only parent should hold reference to atspi object
743 }
744 else
745 {
746 Elm_Atspi_Object *tmp;
747 eo_do(ret, eo_parent_get(&tmp));
748 if (!tmp)
749 eo_do(ret, eo_parent_set(parent));
750 }
751
752 return ret;
753}
754 811
755/// Elm_Atspi_App base class 812/// Elm_Atspi_App base class
756const Eo_Class *elm_atspi_app_obj_class_get(void) EINA_CONST;
757#define ELM_ATSPI_APP_CLASS elm_atspi_app_obj_class_get() 813#define ELM_ATSPI_APP_CLASS elm_atspi_app_obj_class_get()
758 814
759static void 815static void
760_app_children_get(Eo *obj, void *_pd EINA_UNUSED, va_list *list) 816_app_children_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list)
761{ 817{
762 Eina_List **ret = ARG_GET(list, Eina_List**); 818 EO_PARAMETER_GET(Eina_List **, ret, list);
763 Eina_List *l, *objs = NULL; 819 Eina_List *l, *accs = NULL;
820 Elm_Atspi_Object *aobj;
764 Evas_Object *win; 821 Evas_Object *win;
765 Elm_Atspi_Object *o = NULL;
766 822
767 EINA_LIST_FOREACH(_elm_win_list, l, win) 823 EINA_LIST_FOREACH(_elm_win_list, l, win)
768 { 824 {
769 if (!win) continue; 825 if (!win) continue;
770 o = _elm_atspi_factory_construct(win, obj); 826 aobj = _elm_atspi_factory_construct(win);
771 if (o) 827 if (aobj)
772 objs = eina_list_append(objs, o); 828 accs = eina_list_append(accs, aobj);
773 } 829 }
774 *ret = objs; 830
831 if (ret) *ret = accs;
775} 832}
776 833
777static void 834static void
778_app_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED) 835_app_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
779{ 836{
780 eo_do_super(obj, ELM_ATSPI_APP_CLASS, eo_constructor()); 837 eo_do_super(obj, ELM_ATSPI_CLASS, eo_constructor());
838}
781 839
782 eo_do(obj, elm_atspi_obj_name_set(elm_app_name_get())); 840static void
783 eo_do(obj, elm_atspi_obj_role_set(ATSPI_ROLE_APPLICATION)); 841_app_name_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
842{
843 EO_PARAMETER_GET(const char **, name, list);
844 if (name) *name = elm_app_name_get();
845}
846
847static void
848_app_role_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
849{
850 EO_PARAMETER_GET(AtspiRole *, ret, list);
851 if (ret) *ret = ATSPI_ROLE_APPLICATION;
852}
853
854static void
855_app_parent_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
856{
857 EO_PARAMETER_GET(Elm_Atspi_Object **, ret, list);
858 if (ret) *ret = NULL;
784} 859}
785 860
786static void 861static void
@@ -788,6 +863,9 @@ _app_class_constructor(Eo_Class *klass)
788{ 863{
789 const Eo_Op_Func_Description func_desc[] = { 864 const Eo_Op_Func_Description func_desc[] = {
790 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _app_constructor), 865 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _app_constructor),
866 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_NAME_GET), _app_name_get),
867 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_ROLE_GET), _app_role_get),
868 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_PARENT_GET), _app_parent_get),
791 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_CHILDREN_GET), _app_children_get), 869 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_CHILDREN_GET), _app_children_get),
792 EO_OP_FUNC_SENTINEL 870 EO_OP_FUNC_SENTINEL
793 }; 871 };
@@ -800,7 +878,7 @@ static const Eo_Op_Description app_op_desc[] = {
800 878
801static const Eo_Class_Description app_class_desc = { 879static const Eo_Class_Description app_class_desc = {
802 EO_VERSION, 880 EO_VERSION,
803 "App Access_Object", 881 "Elm_App_Access_Object",
804 EO_CLASS_TYPE_REGULAR, 882 EO_CLASS_TYPE_REGULAR,
805 EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0), 883 EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
806 NULL, 884 NULL,
@@ -811,14 +889,165 @@ static const Eo_Class_Description app_class_desc = {
811 889
812EO_DEFINE_CLASS(elm_atspi_app_obj_class_get, &app_class_desc, ELM_ATSPI_CLASS, NULL); 890EO_DEFINE_CLASS(elm_atspi_app_obj_class_get, &app_class_desc, ELM_ATSPI_CLASS, NULL);
813 891
814Elm_Atspi_Object * elm_atspi_root_object_get(void) 892// elm_win wrapper
893
894const Eo_Class *elm_atspi_win_obj_class_get(void) EINA_CONST;
895#define ELM_ATSPI_WIN_CLASS elm_atspi_win_obj_class_get()
896
897static void
898_win_focused(void *data, Evas_Object *eo EINA_UNUSED, void *event_info EINA_UNUSED)
899{
900 Elm_Atspi_Object *ao = data;
901 eo_do(ao, eo_event_callback_call(EV_ATSPI_OBJ_WINDOW_ACTIVATED, NULL, NULL));
902}
903
904static void
905_win_unfocused(void *data, Evas_Object *eo EINA_UNUSED, void *event_info EINA_UNUSED)
815{ 906{
816 static Elm_Atspi_Object *app; 907 Elm_Atspi_Object *ao = data;
908 eo_do(ao, eo_event_callback_call(EV_ATSPI_OBJ_WINDOW_DEACTIVATED, NULL, NULL));
909}
817 910
818 if (!app) 911static void
819 app = eo_add(ELM_ATSPI_APP_CLASS, NULL); 912_win_constructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
913{
914 eo_do_super(obj, ELM_ATSPI_WIN_CLASS, eo_constructor());
915 Evas_Object *evobj = NULL;
916
917 eo_do(obj, elm_atspi_obj_object_get(&evobj));
918
919 evas_object_smart_callback_add(evobj, "focused", _win_focused, obj);
920 evas_object_smart_callback_add(evobj, "unfocused", _win_unfocused, obj);
921}
922
923static void
924_win_destructor(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
925{
926 Elm_Atspi_Object *root = _elm_atspi_root_object_get();
927 eo_do(root, eo_event_callback_call(EV_ATSPI_OBJ_CHILD_DEL, obj, NULL));
928
929 eo_do_super(obj, ELM_ATSPI_WIN_CLASS, eo_destructor());
930}
931
932static void
933_win_name_get(Eo *obj, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
934{
935 EO_PARAMETER_GET(const char **, ret, list);
936 Evas_Object *evobj = NULL;
937
938 eo_do(obj, elm_atspi_obj_object_get(&evobj));
939 EINA_SAFETY_ON_NULL_RETURN(evobj);
940
941 if (ret) *ret = elm_win_title_get(evobj);
942}
943
944static void
945_win_parent_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
946{
947 EO_PARAMETER_GET(Elm_Atspi_Object **, ret, list);
948 if (ret) *ret = _elm_atspi_root_object_get();
949}
950
951static void
952_win_class_constructor(Eo_Class *klass)
953{
954 const Eo_Op_Func_Description func_desc[] = {
955 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _win_constructor),
956 EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _win_destructor),
957 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_NAME_GET), _win_name_get),
958 EO_OP_FUNC(ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_PARENT_GET), _win_parent_get),
959 EO_OP_FUNC_SENTINEL
960 };
961 eo_class_funcs_set(klass, func_desc);
962}
963
964static const Eo_Class_Description win_class_desc = {
965 EO_VERSION,
966 "Elm_Win_Access_Object",
967 EO_CLASS_TYPE_REGULAR,
968 EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
969 NULL,
970 0,
971 _win_class_constructor,
972 NULL
973};
974
975EO_DEFINE_CLASS(elm_atspi_win_obj_class_get, &win_class_desc, ELM_ATSPI_WIDGET_CLASS, ELM_ATSPI_WINDOW_INTERFACE, NULL);
976
977Elm_Atspi_Object*
978_elm_atspi_root_object_get(void)
979{
980 if (!_app)
981 _app = eo_add(ELM_ATSPI_APP_CLASS, NULL);
820 else 982 else
821 eo_ref(app); 983 eo_ref(_app);
984
985 return _app;
986}
987
988Elm_Atspi_Object *
989_elm_atspi_factory_construct(Evas_Object *obj)
990{
991 Elm_Atspi_Object *ret;
992 const char *type;
993
994 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
995
996 ret = evas_object_data_get(obj, "_atspi_object");
997 if (ret) return ret;
822 998
823 return app; 999 type = evas_object_type_get(obj);
1000
1001 //FIXME add possibility to install new handlers
1002 if (!strcmp(type, "elm_access"))
1003 {
1004 DBG("Unable to create ATSPI object for elm_access widget.");
1005 return NULL;
1006 }
1007 else if (!strcmp(type, "elm_win"))
1008 ret = eo_add(ELM_ATSPI_WIN_CLASS, obj);
1009 else if (!strncmp(type, "elm_", 4)) // defaults to implementation for elm_widget class.
1010 ret = eo_add(ELM_ATSPI_WIDGET_CLASS, obj);
1011
1012 eo_unref(ret); // only evas_object should hold reference to atspi object
1013
1014 return ret;
1015}
1016
1017void _elm_atspi_object_init(void)
1018{
1019}
1020
1021void _elm_atspi_object_shutdown(void)
1022{
1023 Elm_Atspi_Global_Callback_Info *info;
1024 if (_app)
1025 eo_del(_app);
1026
1027 EINA_LIST_FREE(_global_callbacks, info)
1028 free(info);
1029 _global_callbacks = NULL;
1030}
1031
1032void _elm_atspi_object_global_callback_add(Eo_Event_Cb cb, void *user_data)
1033{
1034 Elm_Atspi_Global_Callback_Info *info = calloc(1, sizeof(Elm_Atspi_Global_Callback_Info));
1035 if (!info) return;
1036 info->user_data = user_data;
1037 info->cb = cb;
1038 _global_callbacks = eina_list_append(_global_callbacks, info);
1039}
1040
1041void _elm_atspi_object_global_callback_del(Eo_Event_Cb cb)
1042{
1043 Elm_Atspi_Global_Callback_Info *info;
1044 Eina_List *l;
1045 EINA_LIST_FOREACH(_global_callbacks, l, info)
1046 {
1047 if ((info->cb == cb))
1048 {
1049 _global_callbacks = eina_list_remove(_global_callbacks, info);
1050 free(info);
1051 }
1052 }
824} 1053}
diff --git a/src/lib/elm_atspi_object_common.h b/src/lib/elm_atspi_object_common.h
index fdc533b48..767f74bb7 100644
--- a/src/lib/elm_atspi_object_common.h
+++ b/src/lib/elm_atspi_object_common.h
@@ -1 +1,24 @@
1typedef Eo Elm_Atspi_Object; 1typedef Eo Elm_Atspi_Object;
2
3typedef uint64_t Elm_Atspi_State;
4
5typedef enum _Elm_Atspi_Event Elm_Atspi_Event;
6
7#define BIT_FLAG_SET(mask, bit) (mask |= (1 << bit))
8#define BIT_FLAG_UNSET(mask, bit) (mask &= ~(1 << bit))
9#define BIT_FLAG_GET(mask, bit) (mask & (1 << bit))
10
11/*
12 * @brief Gets root (application) type atspi-object.
13 */
14Elm_Atspi_Object * _elm_atspi_root_object_get(void);
15
16/*
17 * @brief Constructs atspi-object for evas_object
18 */
19Elm_Atspi_Object * _elm_atspi_factory_construct(Evas_Object *obj);
20
21void _elm_atspi_object_init(void);
22
23void _elm_atspi_object_shutdown(void);
24
diff --git a/src/lib/elm_atspi_object_eo.h b/src/lib/elm_atspi_object_eo.h
index 67a07c697..d1ff2b7a2 100644
--- a/src/lib/elm_atspi_object_eo.h
+++ b/src/lib/elm_atspi_object_eo.h
@@ -1,32 +1,47 @@
1#define ELM_ATSPI_CLASS elm_atspi_obj_class_get() 1void _elm_atspi_object_global_callback_add(Eo_Event_Cb cv, void *user_data);
2void _elm_atspi_object_global_callback_del(Eo_Event_Cb cv);
2 3
4#define ELM_ATSPI_CLASS elm_atspi_obj_class_get()
3const Eo_Class *elm_atspi_obj_class_get(void) EINA_CONST; 5const Eo_Class *elm_atspi_obj_class_get(void) EINA_CONST;
4 6
7#define ELM_ATSPI_WIDGET_CLASS elm_atspi_widget_obj_class_get()
8const Eo_Class *elm_atspi_widget_obj_class_get(void) EINA_CONST;
9
5extern EAPI Eo_Op ELM_ATSPI_OBJ_BASE_ID; 10extern EAPI Eo_Op ELM_ATSPI_OBJ_BASE_ID;
6 11
7enum 12enum
8{ 13{
9 ELM_ATSPI_OBJ_SUB_ID_NAME_GET, 14 ELM_ATSPI_OBJ_SUB_ID_NAME_GET, /* virtual */
10 ELM_ATSPI_OBJ_SUB_ID_NAME_SET, 15 ELM_ATSPI_OBJ_SUB_ID_DESCRIPTION_GET, /* virtual */
11 ELM_ATSPI_OBJ_SUB_ID_DESCRIPTION_GET,
12 ELM_ATSPI_OBJ_SUB_ID_DESCRIPTION_SET,
13 ELM_ATSPI_OBJ_SUB_ID_PARENT_GET,
14 ELM_ATSPI_OBJ_SUB_ID_CHILD_AT_INDEX_GET, 16 ELM_ATSPI_OBJ_SUB_ID_CHILD_AT_INDEX_GET,
15 ELM_ATSPI_OBJ_SUB_ID_CHILDREN_GET, 17 ELM_ATSPI_OBJ_SUB_ID_CHILDREN_GET, /* virtual */
18 ELM_ATSPI_OBJ_SUB_ID_PARENT_GET, /* virtual */
19 ELM_ATSPI_OBJ_SUB_ID_OBJECT_GET,
16 ELM_ATSPI_OBJ_SUB_ID_INDEX_IN_PARENT_GET, 20 ELM_ATSPI_OBJ_SUB_ID_INDEX_IN_PARENT_GET,
17 ELM_ATSPI_OBJ_SUB_ID_RELATION_SET_GET, 21 ELM_ATSPI_OBJ_SUB_ID_RELATION_SET_GET, /* virtual */
18 ELM_ATSPI_OBJ_SUB_ID_RELATION_SET_SET, 22 ELM_ATSPI_OBJ_SUB_ID_ROLE_GET, /* virtual */
19 ELM_ATSPI_OBJ_SUB_ID_ROLE_GET,
20 ELM_ATSPI_OBJ_SUB_ID_ROLE_SET,
21 ELM_ATSPI_OBJ_SUB_ID_ROLE_NAME_GET, 23 ELM_ATSPI_OBJ_SUB_ID_ROLE_NAME_GET,
22 ELM_ATSPI_OBJ_SUB_ID_LOCALIZED_ROLE_NAME_GET, 24 ELM_ATSPI_OBJ_SUB_ID_LOCALIZED_ROLE_NAME_GET,
23 ELM_ATSPI_OBJ_SUB_ID_STATE_GET, 25 ELM_ATSPI_OBJ_SUB_ID_STATE_GET, /* virtual */
24 ELM_ATSPI_OBJ_SUB_ID_ATTRIBUTES_GET, 26 ELM_ATSPI_OBJ_SUB_ID_ATTRIBUTES_GET, /* virtual */
25 ELM_ATSPI_OBJ_SUB_ID_LAST 27 ELM_ATSPI_OBJ_SUB_ID_LAST
26}; 28};
27 29
28#define ELM_ATSPI_OBJ_ID(sub_id) (ELM_ATSPI_OBJ_BASE_ID + sub_id) 30#define ELM_ATSPI_OBJ_ID(sub_id) (ELM_ATSPI_OBJ_BASE_ID + sub_id)
29 31
32/* Elm_Atspi_Object events */
33extern const Eo_Event_Description _EV_ATSPI_OBJ_NAME_CHANGED;
34#define EV_ATSPI_OBJ_NAME_CHANGED (&(_EV_ATSPI_OBJ_NAME_CHANGED))
35
36extern const Eo_Event_Description _EV_ATSPI_OBJ_CHILD_ADD;
37#define EV_ATSPI_OBJ_CHILD_ADD (&(_EV_ATSPI_OBJ_CHILD_ADD))
38
39extern const Eo_Event_Description _EV_ATSPI_OBJ_CHILD_DEL;
40#define EV_ATSPI_OBJ_CHILD_DEL (&(_EV_ATSPI_OBJ_CHILD_DEL))
41
42extern const Eo_Event_Description _EV_ATSPI_OBJ_STATE_CHANGED;
43#define EV_ATSPI_OBJ_STATE_CHANGED (&(_EV_ATSPI_OBJ_STATE_CHANGED))
44
30/* Component Interface */ 45/* Component Interface */
31#define ELM_ATSPI_COMPONENT_INTERFACE elm_atspi_component_interface_get() 46#define ELM_ATSPI_COMPONENT_INTERFACE elm_atspi_component_interface_get()
32 47
@@ -54,6 +69,17 @@ enum
54#define ELM_ATSPI_COMPONENT_INTERFACE_ID(sub_id) (ELM_ATSPI_COMPONENT_INTERFACE_BASE_ID + sub_id) 69#define ELM_ATSPI_COMPONENT_INTERFACE_ID(sub_id) (ELM_ATSPI_COMPONENT_INTERFACE_BASE_ID + sub_id)
55/* Component Interface - END */ 70/* Component Interface - END */
56 71
72/* Window Interface */
73#define ELM_ATSPI_WINDOW_INTERFACE elm_atspi_window_interface_get()
74const Eo_Class *elm_atspi_window_interface_get(void) EINA_CONST;
75
76extern const Eo_Event_Description _EV_ATSPI_OBJ_WINDOW_ACTIVATED;
77#define EV_ATSPI_OBJ_WINDOW_ACTIVATED (&(_EV_ATSPI_OBJ_WINDOW_ACTIVATED))
78
79extern const Eo_Event_Description _EV_ATSPI_OBJ_WINDOW_DEACTIVATED;
80#define EV_ATSPI_OBJ_WINDOW_DEACTIVATED (&(_EV_ATSPI_OBJ_WINDOW_DEACTIVATED))
81/* Window Interface - END */
82
57/* Action Interface */ 83/* Action Interface */
58#define ELM_ATSPI_ACTION_INTERFACE elm_accessible_action_interface_get() 84#define ELM_ATSPI_ACTION_INTERFACE elm_accessible_action_interface_get()
59 85
@@ -108,6 +134,7 @@ enum
108}; 134};
109/* Text Interface - END */ 135/* Text Interface - END */
110 136
137
111/* EditableText Interface */ 138/* EditableText Interface */
112#define ELM_ATSPI_EDITABLE_TEXT_INTERFACE elm_accessible_editable_text_interface_get() 139#define ELM_ATSPI_EDITABLE_TEXT_INTERFACE elm_accessible_editable_text_interface_get()
113 140
@@ -127,10 +154,9 @@ enum
127}; 154};
128/* EditableText Interface - END */ 155/* EditableText Interface - END */
129 156
157/* Value Interface */
130#define ELM_ATSPI_VALUE_INTERFACE elm_accessible_value_interface_get() 158#define ELM_ATSPI_VALUE_INTERFACE elm_accessible_value_interface_get()
131 159
132
133/* Value Interface */
134const Eo_Class *elm_accessible_value_interface_get(void) EINA_CONST; 160const Eo_Class *elm_accessible_value_interface_get(void) EINA_CONST;
135 161
136extern EAPI Eo_Op ELM_ATSPI_VALUE_INTERFACE_BASE_ID; 162extern EAPI Eo_Op ELM_ATSPI_VALUE_INTERFACE_BASE_ID;
@@ -184,18 +210,10 @@ enum
184 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_NAME_GET), \ 210 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_NAME_GET), \
185 EO_TYPECHECK(const char **, ret) 211 EO_TYPECHECK(const char **, ret)
186 212
187#define elm_atspi_obj_name_set(name)\
188 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_NAME_SET),\
189 EO_TYPECHECK(const char *, name)
190
191#define elm_atspi_obj_role_get(role)\ 213#define elm_atspi_obj_role_get(role)\
192 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_ROLE_GET), \ 214 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_ROLE_GET), \
193 EO_TYPECHECK(AtspiRole*, role) 215 EO_TYPECHECK(AtspiRole*, role)
194 216
195#define elm_atspi_obj_role_set(role)\
196 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_ROLE_SET),\
197 EO_TYPECHECK(AtspiRole, role)
198
199#define elm_atspi_obj_role_name_get(ret)\ 217#define elm_atspi_obj_role_name_get(ret)\
200 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_ROLE_NAME_GET),\ 218 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_ROLE_NAME_GET),\
201 EO_TYPECHECK(const char **, ret) 219 EO_TYPECHECK(const char **, ret)
@@ -208,14 +226,6 @@ enum
208 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_DESCRIPTION_GET),\ 226 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_DESCRIPTION_GET),\
209 EO_TYPECHECK(const char **, ret) 227 EO_TYPECHECK(const char **, ret)
210 228
211#define elm_atspi_obj_description_set(desc)\
212 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_DESCRIPTION_SET),\
213 EO_TYPECHECK(const char *, desc)
214
215#define elm_atspi_obj_parent_get(ret)\
216 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_PARENT_GET),\
217 EO_TYPECHECK(Elm_Atspi_Object**, ret)
218
219#define elm_atspi_obj_child_at_index_get(idx, ret)\ 229#define elm_atspi_obj_child_at_index_get(idx, ret)\
220 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_CHILD_AT_INDEX_GET), \ 230 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_CHILD_AT_INDEX_GET), \
221 EO_TYPECHECK(int, idx),\ 231 EO_TYPECHECK(int, idx),\
@@ -225,6 +235,14 @@ enum
225 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_CHILDREN_GET),\ 235 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_CHILDREN_GET),\
226 EO_TYPECHECK(Eina_List**, ret) 236 EO_TYPECHECK(Eina_List**, ret)
227 237
238#define elm_atspi_obj_parent_get(ret)\
239 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_PARENT_GET),\
240 EO_TYPECHECK(Elm_Atspi_Object**, ret)
241
242#define elm_atspi_obj_object_get(ret)\
243 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_OBJECT_GET),\
244 EO_TYPECHECK(Evas_Object**, ret)
245
228#define elm_atspi_obj_index_in_parent_get(ret)\ 246#define elm_atspi_obj_index_in_parent_get(ret)\
229 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_INDEX_IN_PARENT_GET),\ 247 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_INDEX_IN_PARENT_GET),\
230 EO_TYPECHECK(int*, ret) 248 EO_TYPECHECK(int*, ret)
@@ -233,11 +251,13 @@ enum
233 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_RELATION_SET_GET),\ 251 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_RELATION_SET_GET),\
234 EO_TYPECHECK() 252 EO_TYPECHECK()
235 253
236#define elm_atspi_obj_relation_set_set() ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_RELATION_SET_SET), EO_TYPECHECK() 254#define elm_atspi_obj_state_get(ret)\
237 255 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_STATE_GET),\
238#define elm_atspi_obj_state_get() ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_STATE_GET), EO_TYPECHECK() 256 EO_TYPECHECK(Elm_Atspi_State*, ret)
239 257
240#define elm_atspi_obj_attributes_get() ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_ATTRIBUTES_GET), EO_TYPECHECK() 258#define elm_atspi_obj_attributes_get()\
259 ELM_ATSPI_OBJ_ID(ELM_ATSPI_OBJ_SUB_ID_ATTRIBUTES_GET),\
260 EO_TYPECHECK()
241 261
242#define elm_atspi_component_interface_contains(x, y, type, ret)\ 262#define elm_atspi_component_interface_contains(x, y, type, ret)\
243 ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_CONTAINS),\ 263 ELM_ATSPI_COMPONENT_INTERFACE_ID(ELM_ATSPI_COMPONENT_INTERFACE_SUB_ID_CONTAINS),\
diff --git a/src/lib/elm_atspi_object_legacy.h b/src/lib/elm_atspi_object_legacy.h
index ea5e93bed..5ec21a383 100644
--- a/src/lib/elm_atspi_object_legacy.h
+++ b/src/lib/elm_atspi_object_legacy.h
@@ -1 +1,2 @@
1EAPI Elm_Atspi_Object * elm_atspi_root_object_get(void); 1// to be removed to private:
2
diff --git a/src/lib/elm_widget.c b/src/lib/elm_widget.c
index 4cb6010b6..5671efb13 100644
--- a/src/lib/elm_widget.c
+++ b/src/lib/elm_widget.c
@@ -6318,6 +6318,19 @@ elm_widget_tree_dot_dump(const Evas_Object *top,
6318#endif 6318#endif
6319} 6319}
6320 6320
6321static Eina_Bool
6322_atspi_obj_create(void *data)
6323{
6324 Elm_Atspi_Object *parent = NULL;
6325 Elm_Atspi_Object *obj = _elm_atspi_factory_construct(data);
6326 if (obj)
6327 {
6328 eo_do(obj, elm_atspi_obj_parent_get(&parent));
6329 eo_do(parent, eo_event_callback_call(EV_ATSPI_OBJ_CHILD_ADD, obj, NULL));
6330 }
6331 return EINA_FALSE;
6332}
6333
6321static void 6334static void
6322_constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED) 6335_constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
6323{ 6336{
@@ -6331,6 +6344,9 @@ _constructor(Eo *obj, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED)
6331 eo_parent_get(&parent)); 6344 eo_parent_get(&parent));
6332 eo_do(obj, elm_wdg_parent_set(parent)); 6345 eo_do(obj, elm_wdg_parent_set(parent));
6333 sd->on_create = EINA_FALSE; 6346 sd->on_create = EINA_FALSE;
6347
6348 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
6349 ecore_idle_enterer_add(_atspi_obj_create, obj);
6334} 6350}
6335 6351
6336static void 6352static void