summaryrefslogtreecommitdiff
path: root/src/lib/elementary
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/elementary')
-rw-r--r--src/lib/elementary/elm_atspi_access_adaptor.c574
-rw-r--r--src/lib/elementary/elm_atspi_access_adaptor.h6
-rw-r--r--src/lib/elementary/elm_atspi_access_adaptor_private.h0
-rw-r--r--src/lib/elementary/elm_atspi_adaptor_common.c104
-rw-r--r--src/lib/elementary/elm_atspi_adaptor_common.h35
-rw-r--r--src/lib/elementary/elm_atspi_bridge.c629
6 files changed, 732 insertions, 616 deletions
diff --git a/src/lib/elementary/elm_atspi_access_adaptor.c b/src/lib/elementary/elm_atspi_access_adaptor.c
new file mode 100644
index 0000000..746aee7
--- /dev/null
+++ b/src/lib/elementary/elm_atspi_access_adaptor.c
@@ -0,0 +1,574 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define EFL_ACCESS_PROTECTED
6
7#include <Elementary.h>
8#include "atspi/atspi-constants.h"
9#include "elm_priv.h"
10#include "elm_atspi_adaptor_common.h"
11
12#define SIZE(x) sizeof(x)/sizeof(x[0])
13
14static const int elm_roles_to_atspi_roles[][2] = {
15 { EFL_ACCESS_ROLE_INVALID, ATSPI_ROLE_INVALID },
16 { EFL_ACCESS_ROLE_ACCELERATOR_LABEL, ATSPI_ROLE_ACCELERATOR_LABEL },
17 { EFL_ACCESS_ROLE_ALERT, ATSPI_ROLE_ALERT },
18 { EFL_ACCESS_ROLE_ANIMATION, ATSPI_ROLE_ANIMATION },
19 { EFL_ACCESS_ROLE_ARROW, ATSPI_ROLE_ARROW },
20 { EFL_ACCESS_ROLE_CALENDAR, ATSPI_ROLE_CALENDAR },
21 { EFL_ACCESS_ROLE_CANVAS, ATSPI_ROLE_CANVAS },
22 { EFL_ACCESS_ROLE_CHECK_BOX, ATSPI_ROLE_CHECK_BOX },
23 { EFL_ACCESS_ROLE_CHECK_MENU_ITEM, ATSPI_ROLE_CHECK_MENU_ITEM },
24 { EFL_ACCESS_ROLE_COLOR_CHOOSER, ATSPI_ROLE_COLOR_CHOOSER },
25 { EFL_ACCESS_ROLE_COLUMN_HEADER, ATSPI_ROLE_COLUMN_HEADER },
26 { EFL_ACCESS_ROLE_COMBO_BOX, ATSPI_ROLE_COMBO_BOX },
27 { EFL_ACCESS_ROLE_DATE_EDITOR, ATSPI_ROLE_DATE_EDITOR },
28 { EFL_ACCESS_ROLE_DESKTOP_ICON, ATSPI_ROLE_DESKTOP_ICON },
29 { EFL_ACCESS_ROLE_DESKTOP_FRAME, ATSPI_ROLE_DESKTOP_FRAME },
30 { EFL_ACCESS_ROLE_DIAL, ATSPI_ROLE_DIAL },
31 { EFL_ACCESS_ROLE_DIALOG, ATSPI_ROLE_DIALOG },
32 { EFL_ACCESS_ROLE_DIRECTORY_PANE, ATSPI_ROLE_DIRECTORY_PANE },
33 { EFL_ACCESS_ROLE_DRAWING_AREA, ATSPI_ROLE_DRAWING_AREA },
34 { EFL_ACCESS_ROLE_FILE_CHOOSER, ATSPI_ROLE_FILE_CHOOSER },
35 { EFL_ACCESS_ROLE_FILLER, ATSPI_ROLE_FILLER },
36 { EFL_ACCESS_ROLE_FOCUS_TRAVERSABLE, ATSPI_ROLE_FOCUS_TRAVERSABLE },
37 { EFL_ACCESS_ROLE_FONT_CHOOSER, ATSPI_ROLE_FONT_CHOOSER },
38 { EFL_ACCESS_ROLE_FRAME, ATSPI_ROLE_FRAME },
39 { EFL_ACCESS_ROLE_GLASS_PANE, ATSPI_ROLE_GLASS_PANE },
40 { EFL_ACCESS_ROLE_HTML_CONTAINER, ATSPI_ROLE_HTML_CONTAINER },
41 { EFL_ACCESS_ROLE_ICON, ATSPI_ROLE_ICON },
42 { EFL_ACCESS_ROLE_IMAGE, ATSPI_ROLE_IMAGE },
43 { EFL_ACCESS_ROLE_INTERNAL_FRAME, ATSPI_ROLE_INTERNAL_FRAME },
44 { EFL_ACCESS_ROLE_LABEL, ATSPI_ROLE_LABEL },
45 { EFL_ACCESS_ROLE_LAYERED_PANE, ATSPI_ROLE_LAYERED_PANE },
46 { EFL_ACCESS_ROLE_LIST, ATSPI_ROLE_LIST },
47 { EFL_ACCESS_ROLE_LIST_ITEM, ATSPI_ROLE_LIST_ITEM },
48 { EFL_ACCESS_ROLE_MENU, ATSPI_ROLE_MENU },
49 { EFL_ACCESS_ROLE_MENU_BAR, ATSPI_ROLE_MENU_BAR },
50 { EFL_ACCESS_ROLE_MENU_ITEM, ATSPI_ROLE_MENU_ITEM },
51 { EFL_ACCESS_ROLE_OPTION_PANE, ATSPI_ROLE_OPTION_PANE },
52 { EFL_ACCESS_ROLE_PAGE_TAB, ATSPI_ROLE_PAGE_TAB },
53 { EFL_ACCESS_ROLE_PAGE_TAB_LIST, ATSPI_ROLE_PAGE_TAB_LIST },
54 { EFL_ACCESS_ROLE_PANEL, ATSPI_ROLE_PANEL },
55 { EFL_ACCESS_ROLE_PASSWORD_TEXT, ATSPI_ROLE_PASSWORD_TEXT },
56 { EFL_ACCESS_ROLE_POPUP_MENU, ATSPI_ROLE_POPUP_MENU },
57 { EFL_ACCESS_ROLE_PROGRESS_BAR, ATSPI_ROLE_PROGRESS_BAR },
58 { EFL_ACCESS_ROLE_PUSH_BUTTON, ATSPI_ROLE_PUSH_BUTTON },
59 { EFL_ACCESS_ROLE_RADIO_BUTTON, ATSPI_ROLE_RADIO_BUTTON },
60 { EFL_ACCESS_ROLE_RADIO_MENU_ITEM, ATSPI_ROLE_RADIO_MENU_ITEM },
61 { EFL_ACCESS_ROLE_ROOT_PANE, ATSPI_ROLE_ROOT_PANE },
62 { EFL_ACCESS_ROLE_ROW_HEADER, ATSPI_ROLE_ROW_HEADER },
63 { EFL_ACCESS_ROLE_SCROLL_BAR, ATSPI_ROLE_SCROLL_BAR },
64 { EFL_ACCESS_ROLE_SCROLL_PANE, ATSPI_ROLE_SCROLL_PANE },
65 { EFL_ACCESS_ROLE_SEPARATOR, ATSPI_ROLE_SEPARATOR },
66 { EFL_ACCESS_ROLE_SLIDER, ATSPI_ROLE_SLIDER },
67 { EFL_ACCESS_ROLE_SPIN_BUTTON, ATSPI_ROLE_SPIN_BUTTON },
68 { EFL_ACCESS_ROLE_SPLIT_PANE, ATSPI_ROLE_SPLIT_PANE },
69 { EFL_ACCESS_ROLE_STATUS_BAR, ATSPI_ROLE_STATUS_BAR },
70 { EFL_ACCESS_ROLE_TABLE, ATSPI_ROLE_TABLE },
71 { EFL_ACCESS_ROLE_TABLE_CELL, ATSPI_ROLE_TABLE_CELL },
72 { EFL_ACCESS_ROLE_TABLE_COLUMN_HEADER, ATSPI_ROLE_TABLE_COLUMN_HEADER },
73 { EFL_ACCESS_ROLE_TABLE_ROW_HEADER, ATSPI_ROLE_TABLE_ROW_HEADER },
74 { EFL_ACCESS_ROLE_TEAROFF_MENU_ITEM, ATSPI_ROLE_TEAROFF_MENU_ITEM },
75 { EFL_ACCESS_ROLE_TERMINAL, ATSPI_ROLE_TERMINAL },
76 { EFL_ACCESS_ROLE_TEXT, ATSPI_ROLE_TEXT },
77 { EFL_ACCESS_ROLE_TOGGLE_BUTTON, ATSPI_ROLE_TOGGLE_BUTTON },
78 { EFL_ACCESS_ROLE_TOOL_BAR, ATSPI_ROLE_TOOL_BAR },
79 { EFL_ACCESS_ROLE_TOOL_TIP, ATSPI_ROLE_TOOL_TIP },
80 { EFL_ACCESS_ROLE_TREE, ATSPI_ROLE_TREE },
81 { EFL_ACCESS_ROLE_TREE_TABLE, ATSPI_ROLE_TREE_TABLE },
82 { EFL_ACCESS_ROLE_UNKNOWN, ATSPI_ROLE_UNKNOWN },
83 { EFL_ACCESS_ROLE_VIEWPORT, ATSPI_ROLE_VIEWPORT },
84 { EFL_ACCESS_ROLE_WINDOW, ATSPI_ROLE_WINDOW },
85 { EFL_ACCESS_ROLE_EXTENDED, ATSPI_ROLE_EXTENDED },
86 { EFL_ACCESS_ROLE_HEADER, ATSPI_ROLE_HEADER },
87 { EFL_ACCESS_ROLE_FOOTER, ATSPI_ROLE_FOOTER },
88 { EFL_ACCESS_ROLE_PARAGRAPH, ATSPI_ROLE_PARAGRAPH },
89 { EFL_ACCESS_ROLE_RULER, ATSPI_ROLE_RULER },
90 { EFL_ACCESS_ROLE_APPLICATION, ATSPI_ROLE_APPLICATION },
91 { EFL_ACCESS_ROLE_AUTOCOMPLETE, ATSPI_ROLE_AUTOCOMPLETE },
92 { EFL_ACCESS_ROLE_EDITBAR, ATSPI_ROLE_EDITBAR },
93 { EFL_ACCESS_ROLE_EMBEDDED, ATSPI_ROLE_EMBEDDED },
94 { EFL_ACCESS_ROLE_ENTRY, ATSPI_ROLE_ENTRY },
95 { EFL_ACCESS_ROLE_CHART, ATSPI_ROLE_CHART },
96 { EFL_ACCESS_ROLE_CAPTION, ATSPI_ROLE_CAPTION },
97 { EFL_ACCESS_ROLE_DOCUMENT_FRAME, ATSPI_ROLE_DOCUMENT_FRAME },
98 { EFL_ACCESS_ROLE_HEADING, ATSPI_ROLE_HEADING },
99 { EFL_ACCESS_ROLE_PAGE, ATSPI_ROLE_PAGE },
100 { EFL_ACCESS_ROLE_SECTION, ATSPI_ROLE_SECTION },
101 { EFL_ACCESS_ROLE_REDUNDANT_OBJECT, ATSPI_ROLE_REDUNDANT_OBJECT },
102 { EFL_ACCESS_ROLE_FORM, ATSPI_ROLE_FORM },
103 { EFL_ACCESS_ROLE_LINK, ATSPI_ROLE_LINK },
104 { EFL_ACCESS_ROLE_INPUT_METHOD_WINDOW, ATSPI_ROLE_INPUT_METHOD_WINDOW },
105 { EFL_ACCESS_ROLE_TABLE_ROW, ATSPI_ROLE_TABLE_ROW },
106 { EFL_ACCESS_ROLE_TREE_ITEM, ATSPI_ROLE_TREE_ITEM },
107 { EFL_ACCESS_ROLE_DOCUMENT_SPREADSHEET, ATSPI_ROLE_DOCUMENT_SPREADSHEET },
108 { EFL_ACCESS_ROLE_DOCUMENT_PRESENTATION, ATSPI_ROLE_DOCUMENT_PRESENTATION },
109 { EFL_ACCESS_ROLE_DOCUMENT_TEXT, ATSPI_ROLE_DOCUMENT_TEXT },
110 { EFL_ACCESS_ROLE_DOCUMENT_WEB, ATSPI_ROLE_DOCUMENT_WEB },
111 { EFL_ACCESS_ROLE_DOCUMENT_EMAIL, ATSPI_ROLE_DOCUMENT_EMAIL },
112 { EFL_ACCESS_ROLE_COMMENT, ATSPI_ROLE_COMMENT },
113 { EFL_ACCESS_ROLE_LIST_BOX, ATSPI_ROLE_LIST_BOX },
114 { EFL_ACCESS_ROLE_GROUPING, ATSPI_ROLE_GROUPING },
115 { EFL_ACCESS_ROLE_IMAGE_MAP, ATSPI_ROLE_IMAGE_MAP },
116 { EFL_ACCESS_ROLE_NOTIFICATION, ATSPI_ROLE_NOTIFICATION },
117 { EFL_ACCESS_ROLE_INFO_BAR, ATSPI_ROLE_INFO_BAR },
118 { EFL_ACCESS_ROLE_LAST_DEFINED, ATSPI_ROLE_LAST_DEFINED },
119};
120
121static const int elm_relation_to_atspi_relation_mapping[] = {
122 [EFL_ACCESS_RELATION_NULL] = ATSPI_RELATION_NULL,
123 [EFL_ACCESS_RELATION_LABEL_FOR] = ATSPI_RELATION_LABEL_FOR,
124 [EFL_ACCESS_RELATION_LABELLED_BY] = ATSPI_RELATION_LABELLED_BY,
125 [EFL_ACCESS_RELATION_CONTROLLER_FOR] = ATSPI_RELATION_CONTROLLER_FOR,
126 [EFL_ACCESS_RELATION_CONTROLLED_BY] = ATSPI_RELATION_CONTROLLED_BY,
127 [EFL_ACCESS_RELATION_MEMBER_OF] = ATSPI_RELATION_MEMBER_OF,
128 [EFL_ACCESS_RELATION_TOOLTIP_FOR] = ATSPI_RELATION_TOOLTIP_FOR,
129 [EFL_ACCESS_RELATION_NODE_CHILD_OF] = ATSPI_RELATION_NODE_CHILD_OF,
130 [EFL_ACCESS_RELATION_NODE_PARENT_OF] = ATSPI_RELATION_NODE_PARENT_OF,
131 [EFL_ACCESS_RELATION_EXTENDED] = ATSPI_RELATION_EXTENDED,
132 [EFL_ACCESS_RELATION_FLOWS_TO] = ATSPI_RELATION_FLOWS_TO,
133 [EFL_ACCESS_RELATION_FLOWS_FROM] = ATSPI_RELATION_FLOWS_FROM,
134 [EFL_ACCESS_RELATION_SUBWINDOW_OF] = ATSPI_RELATION_SUBWINDOW_OF,
135 [EFL_ACCESS_RELATION_EMBEDS] = ATSPI_RELATION_EMBEDS,
136 [EFL_ACCESS_RELATION_EMBEDDED_BY] = ATSPI_RELATION_EMBEDDED_BY,
137 [EFL_ACCESS_RELATION_POPUP_FOR] = ATSPI_RELATION_POPUP_FOR,
138 [EFL_ACCESS_RELATION_PARENT_WINDOW_OF] = ATSPI_RELATION_PARENT_WINDOW_OF,
139 [EFL_ACCESS_RELATION_DESCRIPTION_FOR] = ATSPI_RELATION_DESCRIPTION_FOR,
140 [EFL_ACCESS_RELATION_DESCRIBED_BY] = ATSPI_RELATION_DESCRIBED_BY,
141 [EFL_ACCESS_RELATION_LAST_DEFINED] = ATSPI_RELATION_LAST_DEFINED,
142};
143
144static AtspiRelationType _elm_relation_to_atspi_relation(Efl_Access_Relation_Type type)
145{
146 if ((type < EFL_ACCESS_RELATION_LAST_DEFINED) && (type > EFL_ACCESS_RELATION_NULL))
147 return elm_relation_to_atspi_relation_mapping[type];
148 return ATSPI_RELATION_NULL;
149}
150
151struct atspi_state_desc
152{
153 Efl_Access_State_Type elm_state;
154 AtspiStateType atspi_state;
155 const char *name;
156};
157
158static const struct atspi_state_desc elm_states_to_atspi_state[] = {
159 { EFL_ACCESS_STATE_INVALID, ATSPI_STATE_INVALID, "invalid" },
160 { EFL_ACCESS_STATE_ACTIVE, ATSPI_STATE_ACTIVE, "active" },
161 { EFL_ACCESS_STATE_ARMED, ATSPI_STATE_ARMED, "armed" },
162 { EFL_ACCESS_STATE_BUSY, ATSPI_STATE_BUSY, "busy" },
163 { EFL_ACCESS_STATE_CHECKED, ATSPI_STATE_CHECKED, "checked" },
164 { EFL_ACCESS_STATE_COLLAPSED, ATSPI_STATE_COLLAPSED, "collapsed" },
165 { EFL_ACCESS_STATE_DEFUNCT, ATSPI_STATE_DEFUNCT, "defunct" },
166 { EFL_ACCESS_STATE_EDITABLE, ATSPI_STATE_EDITABLE, "editable" },
167 { EFL_ACCESS_STATE_ENABLED, ATSPI_STATE_ENABLED, "enabled" },
168 { EFL_ACCESS_STATE_EXPANDABLE, ATSPI_STATE_EXPANDABLE, "expandable" },
169 { EFL_ACCESS_STATE_EXPANDED, ATSPI_STATE_EXPANDED, "expanded" },
170 { EFL_ACCESS_STATE_FOCUSABLE, ATSPI_STATE_FOCUSABLE, "focusable" },
171 { EFL_ACCESS_STATE_FOCUSED, ATSPI_STATE_FOCUSED, "focused" },
172 { EFL_ACCESS_STATE_HAS_TOOLTIP, ATSPI_STATE_HAS_TOOLTIP, "has-tooltip" },
173 { EFL_ACCESS_STATE_HORIZONTAL, ATSPI_STATE_HORIZONTAL, "horizontal" },
174 { EFL_ACCESS_STATE_ICONIFIED, ATSPI_STATE_ICONIFIED, "iconified" },
175 { EFL_ACCESS_STATE_MODAL, ATSPI_STATE_MODAL, "modal" },
176 { EFL_ACCESS_STATE_MULTI_LINE, ATSPI_STATE_MULTI_LINE, "multi-line" },
177 { EFL_ACCESS_STATE_MULTISELECTABLE, ATSPI_STATE_MULTISELECTABLE, "multiselectable" },
178 { EFL_ACCESS_STATE_OPAQUE, ATSPI_STATE_OPAQUE, "opaque" },
179 { EFL_ACCESS_STATE_PRESSED, ATSPI_STATE_PRESSED, "pressed" },
180 { EFL_ACCESS_STATE_RESIZABLE, ATSPI_STATE_RESIZABLE, "resizable" },
181 { EFL_ACCESS_STATE_SELECTABLE, ATSPI_STATE_SELECTABLE, "selectable" },
182 { EFL_ACCESS_STATE_SELECTED, ATSPI_STATE_SELECTED, "selected" },
183 { EFL_ACCESS_STATE_SENSITIVE, ATSPI_STATE_SENSITIVE, "sensitive" },
184 { EFL_ACCESS_STATE_SHOWING, ATSPI_STATE_SHOWING, "showing" },
185 { EFL_ACCESS_STATE_SINGLE_LINE, ATSPI_STATE_SINGLE_LINE, "single-line" },
186 { EFL_ACCESS_STATE_STALE, ATSPI_STATE_STALE, "stale" },
187 { EFL_ACCESS_STATE_TRANSIENT, ATSPI_STATE_TRANSIENT, "transient" },
188 { EFL_ACCESS_STATE_VERTICAL, ATSPI_STATE_VERTICAL, "vertical" },
189 { EFL_ACCESS_STATE_VISIBLE, ATSPI_STATE_VISIBLE, "visible" },
190 { EFL_ACCESS_STATE_MANAGES_DESCENDANTS, ATSPI_STATE_MANAGES_DESCENDANTS, "manages-descendants" },
191 { EFL_ACCESS_STATE_INDETERMINATE, ATSPI_STATE_INDETERMINATE, "indeterminate" },
192 { EFL_ACCESS_STATE_REQUIRED, ATSPI_STATE_REQUIRED, "required" },
193 { EFL_ACCESS_STATE_TRUNCATED, ATSPI_STATE_TRUNCATED, "truncated" },
194 { EFL_ACCESS_STATE_ANIMATED, ATSPI_STATE_ANIMATED, "animated" },
195 { EFL_ACCESS_STATE_INVALID_ENTRY, ATSPI_STATE_INVALID_ENTRY, "invalid-entry" },
196 { EFL_ACCESS_STATE_SUPPORTS_AUTOCOMPLETION, ATSPI_STATE_SUPPORTS_AUTOCOMPLETION, "supports-autocompletion" },
197 { EFL_ACCESS_STATE_SELECTABLE_TEXT, ATSPI_STATE_SELECTABLE_TEXT, "selectable-text" },
198 { EFL_ACCESS_STATE_IS_DEFAULT, ATSPI_STATE_IS_DEFAULT, "is-default" },
199 { EFL_ACCESS_STATE_VISITED, ATSPI_STATE_VISITED, "visited" },
200 { EFL_ACCESS_STATE_LAST_DEFINED, ATSPI_STATE_LAST_DEFINED, "last-defined" },
201};
202
203static uint64_t
204_elm_atspi_state_set_to_atspi_state_set(Efl_Access_State_Set states)
205{
206 uint64_t ret = 0;
207 unsigned int i = 0;
208
209 for (i = 0; i < SIZE(elm_states_to_atspi_state); i++)
210 {
211 if (STATE_TYPE_GET(states, elm_states_to_atspi_state[i].elm_state))
212 STATE_TYPE_SET(ret, elm_states_to_atspi_state[i].atspi_state);
213 }
214 return ret;
215}
216
217static Eldbus_Message*
218_accessible_get_state(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
219{
220 Eldbus_Message *ret;
221 Eldbus_Message_Iter *iter, *iter_array;
222 Efl_Access_State_Set states;
223 uint64_t atspi_states = 0;
224
225 Efl_Access *obj = efl_access_unmarshal(msg);
226 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
227
228 ret = eldbus_message_method_return_new(msg);
229 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
230
231 iter = eldbus_message_iter_get(ret);
232 iter_array = eldbus_message_iter_container_new(iter, 'a', "u");
233 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
234
235 states = efl_access_state_set_get(obj);
236
237 atspi_states = _elm_atspi_state_set_to_atspi_state_set(states);
238
239 unsigned int s1 = atspi_states & 0xFFFFFFFF;
240 unsigned int s2 = (atspi_states >> 32) & 0xFFFFFFFF;
241
242 eldbus_message_iter_basic_append(iter_array, 'u', s1);
243 eldbus_message_iter_basic_append(iter_array, 'u', s2);
244 eldbus_message_iter_container_close(iter, iter_array);
245
246 return ret;
247
248fail:
249 if (ret) eldbus_message_unref(ret);
250 return NULL;
251}
252
253static Eldbus_Message *
254_accessible_get_index_in_parent(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
255{
256 Eldbus_Message *ret;
257 int idx = -1;
258
259 Efl_Access *obj = efl_access_unmarshal(msg);
260 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
261
262 ret = eldbus_message_method_return_new(msg);
263 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
264
265 idx = efl_access_index_in_parent_get(obj);
266
267 eldbus_message_arguments_append(ret, "i", idx);
268
269 return ret;
270}
271
272static Eldbus_Message *
273_accessible_child_at_index(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
274{
275 Eo *child = NULL;
276 Eina_List *children = NULL;
277 int idx;
278 Eldbus_Message *ret;
279 Eldbus_Message_Iter *iter;
280
281 Efl_Access *obj = efl_access_unmarshal(msg);
282 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
283
284 if (!eldbus_message_arguments_get(msg, "i", &idx))
285 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
286
287 ret = eldbus_message_method_return_new(msg);
288 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
289
290 iter = eldbus_message_iter_get(ret);
291 children = efl_access_children_get(obj);
292 child = eina_list_nth(children, idx);
293
294 eldbus_message_iter_efl_access_reference_append(iter, eldbus_service_connection_get(iface), child);
295 eina_list_free(children);
296
297 return ret;
298}
299
300static Eldbus_Message *
301_accessible_get_relation_set(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
302{
303 Eo *rel_obj;
304 Eldbus_Message *ret = NULL;
305 Eldbus_Message_Iter *iter = NULL, *iter_array = NULL, *iter_array2 = NULL, *iter_struct;
306 Efl_Access_Relation *rel;
307 Eina_List *l, *l2;
308 Efl_Access_Relation_Set rels;
309
310 Efl_Access *obj = efl_access_unmarshal(msg);
311 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
312
313 ret = eldbus_message_method_return_new(msg);
314 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
315
316 iter = eldbus_message_iter_get(ret);
317 iter_array = eldbus_message_iter_container_new(iter, 'a', "(ua(so))");
318 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
319
320 rels = efl_access_relation_set_get(obj);
321
322 EINA_LIST_FOREACH(rels, l, rel)
323 {
324 iter_struct = eldbus_message_iter_container_new(iter_array, 'r', NULL);
325 eldbus_message_iter_basic_append(iter_struct, 'u', _elm_relation_to_atspi_relation(rel->type));
326 eldbus_message_iter_efl_access_reference_array_append(iter_struct, eldbus_service_connection_get(iface), rel->objects);
327 eldbus_message_iter_container_close(iter_array, iter_struct);
328 }
329 efl_access_relation_set_free(rels);
330 eldbus_message_iter_container_close(iter, iter_array);
331
332 return ret;
333
334fail:
335 eldbus_message_unref(ret);
336 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to get relation set.");
337}
338
339static Eldbus_Message *
340_accessible_get_role(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
341{
342 AtspiRole atspi_role = ATSPI_ROLE_INVALID;
343 Efl_Access_Role role;
344
345 Efl_Access *obj = efl_access_unmarshal(msg);
346 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
347
348 role = efl_access_role_get(obj);
349
350 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
351 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
352
353 atspi_role = role > EFL_ACCESS_ROLE_LAST_DEFINED ? ATSPI_ROLE_LAST_DEFINED : elm_roles_to_atspi_roles[role][1];
354 eldbus_message_arguments_append(ret, "u", atspi_role);
355 return ret;
356}
357
358static Eldbus_Message *
359_accessible_get_role_name(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
360{
361 Efl_Access *obj = efl_access_unmarshal(msg);
362 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
363
364 const char *role_name = efl_access_role_name_get(obj);
365
366 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
367 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
368 eldbus_message_arguments_append(ret, "s", role_name);
369
370 return ret;
371}
372
373static Eldbus_Message *
374_accessible_get_localized_role_name(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
375{
376 Efl_Access *obj = efl_access_unmarshal(msg);
377 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
378
379 const char *l_role_name = efl_access_localized_role_name_get(obj);
380 EINA_SAFETY_ON_NULL_RETURN_VAL(l_role_name, NULL);
381
382 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
383 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
384 eldbus_message_arguments_append(ret, "s", l_role_name);
385
386 return ret;
387}
388
389static Eldbus_Message *
390_accessible_get_children(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
391{
392 Eina_List *children_list = NULL, *l;
393 Eldbus_Message *ret;
394 Eldbus_Message_Iter *iter, *iter_array;
395 Eo *child;
396
397 Efl_Access *obj = efl_access_unmarshal(msg);
398 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
399
400 children_list = efl_access_children_get(obj);
401
402 ret = eldbus_message_method_return_new(msg);
403 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
404
405 iter = eldbus_message_iter_get(ret);
406 eldbus_message_iter_efl_access_reference_array_append(iter, eldbus_service_connection_get(iface), children_list);
407 eina_list_free(children_list);
408
409 return ret;
410
411fail:
412 if (ret) eldbus_message_unref(ret);
413 return NULL;
414}
415
416static Eldbus_Message *
417_accessible_get_application(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
418{
419 Eo *root;
420 Eldbus_Message *ret;
421
422 Efl_Access *obj = efl_access_unmarshal(msg);
423 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
424
425 ret = eldbus_message_method_return_new(msg);
426 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
427
428 Eldbus_Message_Iter *iter = eldbus_message_iter_get(ret);
429 root = efl_access_root_get(EFL_ACCESS_MIXIN);
430 eldbus_message_iter_efl_access_reference_append(iter, eldbus_service_connection_get(iface), root);
431
432 return ret;
433}
434
435static Eldbus_Message *
436_accessible_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
437{
438 Eina_List *attrs = NULL, *l;
439 Efl_Access_Attribute *attr;
440 Eldbus_Message_Iter *iter, *iter_dict = NULL, *iter_entry;
441 Eldbus_Message *ret;
442
443 Efl_Access *obj = efl_access_unmarshal(msg);
444 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
445
446 ret = eldbus_message_method_return_new(msg);
447 if (!ret) goto error;
448
449 attrs = efl_access_attributes_get(obj);
450
451 iter = eldbus_message_iter_get(ret);
452 if (!iter) goto error;
453
454 iter_dict = eldbus_message_iter_container_new(iter, 'a', "{ss}");
455 if (!iter_dict) goto error;
456
457 EINA_LIST_FOREACH(attrs, l, attr)
458 {
459 iter_entry = eldbus_message_iter_container_new(iter_dict, 'e', NULL);
460 if (!iter_entry) goto error;
461 eldbus_message_iter_arguments_append(iter_entry, "ss", attr->key, attr->value);
462 eldbus_message_iter_container_close(iter_dict, iter_entry);
463 }
464
465 eldbus_message_iter_container_close(iter, iter_dict);
466 efl_access_attributes_list_free(attrs);
467 return ret;
468
469error:
470 if (iter_dict) eldbus_message_iter_container_close(iter, iter_dict);
471 if (ret) eldbus_message_unref(ret);
472 efl_access_attributes_list_free(attrs);
473 return NULL;
474}
475
476static Eldbus_Message *
477_accessible_interfaces_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
478{
479 Eldbus_Message *ret;
480 Eldbus_Message_Iter *iter;
481
482 Efl_Access *obj = efl_access_unmarshal(msg);
483 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
484
485 ret = eldbus_message_method_return_new(msg);
486 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
487
488 iter = eldbus_message_iter_get(ret);
489 eldbus_message_iter_efl_access_interfaces_append(iter, obj);
490
491 return ret;
492}
493
494static const Eldbus_Method accessible_methods[] = {
495 { "GetChildAtIndex", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"(so)", "Accessible"}), _accessible_child_at_index, 0 },
496 { "GetChildren", NULL, ELDBUS_ARGS({"a(so)", "children"}), _accessible_get_children, 0 },
497 { "GetIndexInParent", NULL, ELDBUS_ARGS({"i", "index"}), _accessible_get_index_in_parent, 0 },
498 { "GetRelationSet", NULL, ELDBUS_ARGS({"a(ua(so))", NULL}), _accessible_get_relation_set, 0 },
499 { "GetRole", NULL, ELDBUS_ARGS({"u", "Role"}), _accessible_get_role, 0 },
500 { "GetRoleName", NULL, ELDBUS_ARGS({"s", "Name"}), _accessible_get_role_name, 0 },
501 { "GetLocalizedRoleName", NULL, ELDBUS_ARGS({"s", "LocalizedName"}), _accessible_get_localized_role_name, 0},
502 { "GetState", NULL, ELDBUS_ARGS({"au", NULL}), _accessible_get_state, 0},
503 { "GetApplication", NULL, ELDBUS_ARGS({"(so)", NULL}), _accessible_get_application, 0},
504 { "GetAttributes", NULL, ELDBUS_ARGS({"a{ss}", NULL}), _accessible_attributes_get, 0},
505 { "GetInterfaces", NULL, ELDBUS_ARGS({"as", NULL}), _accessible_interfaces_get, 0},
506 { NULL, NULL, NULL, NULL, 0 }
507};
508
509static Eina_Bool
510_accessible_property_get(const Eldbus_Service_Interface *interface, const char *property,
511 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg,
512 Eldbus_Message **error)
513{
514 const char *ret = NULL;
515 Eo *ret_obj = NULL;
516
517 Efl_Access *obj = efl_access_unmarshal(request_msg);
518 ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, request_msg, error);
519
520 if (!strcmp(property, "Name"))
521 {
522 ret = efl_access_name_get(obj);
523 if (!ret)
524 ret = "";
525 eldbus_message_iter_basic_append(iter, 's', ret);
526 return EINA_TRUE;
527 }
528 else if (!strcmp(property, "Description"))
529 {
530 ret = efl_access_description_get(obj);
531 if (!ret)
532 ret = "";
533 eldbus_message_iter_basic_append(iter, 's', ret);
534 return EINA_TRUE;
535 }
536 else if (!strcmp(property, "Parent"))
537 {
538 ret_obj = efl_access_parent_get(obj);
539 eldbus_message_iter_efl_access_reference_append(iter, eldbus_service_connection_get(interface), ret_obj);
540 return EINA_TRUE;
541 }
542 else if (!strcmp(property, "ChildCount"))
543 {
544 Eina_List *l = NULL;
545 l = efl_access_children_get(obj);
546 eldbus_message_iter_basic_append(iter, 'i', eina_list_count(l));
547 eina_list_free(l);
548 return EINA_TRUE;
549 }
550 return EINA_FALSE;
551}
552
553static const Eldbus_Property accessible_properties[] = {
554 { "Name", "s", NULL, NULL, 0 },
555 { "Description", "s", NULL, NULL, 0 },
556 { "Parent", "(so)", NULL, NULL, 0 },
557 { "ChildCount", "i", NULL, NULL, 0 },
558 { NULL, NULL, NULL, NULL, 0 }
559};
560
561static const Eldbus_Service_Interface_Desc accessible_iface_desc = {
562 ATSPI_DBUS_INTERFACE_ACCESSIBLE,
563 accessible_methods,
564 NULL,
565 accessible_properties,
566 _accessible_property_get,
567 NULL
568};
569
570Eldbus_Service_Interface*
571_elm_atspi_access_adaptor_register(Eldbus_Connection *conn)
572{
573 return eldbus_service_interface_fallback_register(conn, ELM_ACCESS_OBJECT_PATH_PREFIX2, &accessible_iface_desc);
574}
diff --git a/src/lib/elementary/elm_atspi_access_adaptor.h b/src/lib/elementary/elm_atspi_access_adaptor.h
new file mode 100644
index 0000000..cf21f6d
--- /dev/null
+++ b/src/lib/elementary/elm_atspi_access_adaptor.h
@@ -0,0 +1,6 @@
1#ifndef ELM_ATSPI_ACCESS_ADAPTOR
2#define ELM_ATSPI_ACCESS_ADAPTOR
3
4static Eldbus_Service_Interface* _elm_atspi_access_adaptor_register(Eldbus_Connection *conn);
5
6#endif
diff --git a/src/lib/elementary/elm_atspi_access_adaptor_private.h b/src/lib/elementary/elm_atspi_access_adaptor_private.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/lib/elementary/elm_atspi_access_adaptor_private.h
diff --git a/src/lib/elementary/elm_atspi_adaptor_common.c b/src/lib/elementary/elm_atspi_adaptor_common.c
new file mode 100644
index 0000000..a0dc2ed
--- /dev/null
+++ b/src/lib/elementary/elm_atspi_adaptor_common.c
@@ -0,0 +1,104 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define EFL_ACCESS_PROTECTED
6
7#include <Elementary.h>
8#include "atspi/atspi-constants.h"
9#include "elm_priv.h"
10#include "elm_atspi_adaptor_common.h"
11
12#define ELM_ACCESS_OBJECT_PATH_PREFIX "/org/a11y/atspi/accessible/"
13#define ELM_ACCESS_OBJECT_REFERENCE_TEMPLATE ELM_ACCESS_OBJECT_PATH_PREFIX "%llu"
14#define ELM_ACCESS_OBJECT_PATH_ROOT "root"
15
16Efl_Access*
17efl_access_unmarshal(const Eldbus_Message *msg)
18{
19 return NULL;
20}
21
22void
23efl_access_marshal(Efl_Access *obj, Eldbus_Message_Iter *iter)
24{
25}
26
27static const char*
28_path_from_object(const Eo *eo)
29{
30 static char path[64];
31
32 if (!eo)
33 return ATSPI_DBUS_PATH_NULL;
34
35 if (eo == efl_access_root_get(EFL_ACCESS_MIXIN))
36 snprintf(path, sizeof(path), "%s%s", ELM_ACCESS_OBJECT_PATH_PREFIX, ELM_ACCESS_OBJECT_PATH_ROOT);
37 else
38 snprintf(path, sizeof(path), ELM_ACCESS_OBJECT_REFERENCE_TEMPLATE, (unsigned long long)(uintptr_t)eo);
39
40 return path;
41}
42
43void
44eldbus_message_iter_efl_access_reference_append(Eldbus_Message_Iter *iter, Eldbus_Connection *conn, Efl_Access *obj)
45{
46 EINA_SAFETY_ON_NULL_RETURN(iter);
47 EINA_SAFETY_ON_NULL_RETURN(conn);
48
49 Eldbus_Message_Iter *iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
50 if (!iter_struct) return;
51
52 eldbus_message_iter_basic_append(iter_struct, 's', eldbus_connection_unique_name_get(conn));
53 eldbus_message_iter_basic_append(iter_struct, 'o', _path_from_object(obj));
54 eldbus_message_iter_container_close(iter, iter_struct);
55}
56
57void
58eldbus_message_iter_efl_access_reference_array_append(Eldbus_Message_Iter *iter, Eldbus_Connection *conn, Eina_List *obj_list)
59{
60 Eina_List *l;
61 Efl_Access *obj;
62
63 EINA_SAFETY_ON_NULL_RETURN(iter);
64 EINA_SAFETY_ON_NULL_RETURN(conn);
65
66 Eldbus_Message_Iter *iter_array = eldbus_message_iter_container_new(iter, 'a', "(so)");
67 if (!iter_array) return;
68
69 EINA_LIST_FOREACH(obj_list, l, obj)
70 eldbus_message_iter_efl_access_reference_append(iter_array, conn, obj);
71
72 eldbus_message_iter_container_close(iter, iter_array);
73}
74
75void
76eldbus_message_iter_efl_access_interfaces_append(Eldbus_Message_Iter *iter, Efl_Access *obj)
77{
78 Eldbus_Message_Iter *iter_array = eldbus_message_iter_container_new(iter, 'a', "s");
79 if (!iter_array) return;
80
81 if (efl_isa(obj, EFL_ACCESS_MIXIN))
82 {
83 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_ACCESSIBLE);
84 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_COLLECTION);
85 }
86 if (efl_isa(obj, EFL_ACCESS_ACTION_MIXIN))
87 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_ACTION);
88 if (efl_isa(obj, ELM_ATSPI_APP_OBJECT_CLASS))
89 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_APPLICATION);
90 if (efl_isa(obj, EFL_ACCESS_COMPONENT_MIXIN))
91 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_COMPONENT);
92 if (efl_isa(obj, EFL_ACCESS_EDITABLE_TEXT_INTERFACE))
93 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_EDITABLE_TEXT);
94 if (efl_isa(obj, EFL_ACCESS_IMAGE_MIXIN))
95 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_IMAGE);
96 if (efl_isa(obj, EFL_ACCESS_SELECTION_INTERFACE))
97 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_SELECTION);
98 if (efl_isa(obj, EFL_ACCESS_TEXT_INTERFACE))
99 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_TEXT);
100 if (efl_isa(obj, EFL_ACCESS_VALUE_INTERFACE))
101 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_VALUE);
102
103 eldbus_message_iter_container_close(iter, iter_array);
104}
diff --git a/src/lib/elementary/elm_atspi_adaptor_common.h b/src/lib/elementary/elm_atspi_adaptor_common.h
new file mode 100644
index 0000000..2d92468
--- /dev/null
+++ b/src/lib/elementary/elm_atspi_adaptor_common.h
@@ -0,0 +1,35 @@
1
2#define ELM_ACCESS_OBJECT_PATH_PREFIX2 "/org/a11y/atspi/accessible"
3
4#define ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, class, msg, error) \
5 if (!(obj) || !efl_isa(obj, class)) \
6 { \
7 *(error) = _dbus_invalid_ref_error_new(msg); \
8 return EINA_FALSE; \
9 }
10
11#define ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, class, msg, error) \
12 if (!(obj) || !efl_isa(obj, class)) \
13 { \
14 *(error) = _dbus_invalid_ref_error_new(msg); \
15 return EINA_FALSE; \
16 }
17
18#define ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, class, msg) \
19 if (!(obj) || !efl_isa(obj, class)) \
20 return _dbus_invalid_ref_error_new(msg);
21
22static inline Eldbus_Message *_dbus_invalid_ref_error_new(const Eldbus_Message *msg)
23{
24 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.UnknownObject", "Path is not valid accessible object reference.");
25}
26
27Efl_Access* efl_access_unmarshal(const Eldbus_Message *msg);
28
29void efl_access_marshal(Efl_Access *obj, Eldbus_Message_Iter *iter);
30
31void eldbus_message_iter_efl_access_reference_append(Eldbus_Message_Iter *iter, Eldbus_Connection *conn, Efl_Access *obj);
32
33void eldbus_message_iter_efl_access_interfaces_append(Eldbus_Message_Iter *iter, Efl_Access *obj);
34
35void eldbus_message_iter_efl_access_reference_array_append(Eldbus_Message_Iter *iter, Eldbus_Connection *conn, Eina_List *obj);
diff --git a/src/lib/elementary/elm_atspi_bridge.c b/src/lib/elementary/elm_atspi_bridge.c
index 2de63c7..01d6012 100644
--- a/src/lib/elementary/elm_atspi_bridge.c
+++ b/src/lib/elementary/elm_atspi_bridge.c
@@ -18,6 +18,8 @@
18#include <stdint.h> 18#include <stdint.h>
19#include <Elementary.h> 19#include <Elementary.h>
20#include "elm_priv.h" 20#include "elm_priv.h"
21#include "elm_atspi_access_adaptor.h"
22#include "elm_atspi_adaptor_common.h"
21 23
22/* 24/*
23 * Accessibility Bus info not defined in atspi-constants.h 25 * Accessibility Bus info not defined in atspi-constants.h
@@ -35,7 +37,6 @@
35 37
36#define ELM_ACCESS_OBJECT_PATH_ROOT "root" 38#define ELM_ACCESS_OBJECT_PATH_ROOT "root"
37#define ELM_ACCESS_OBJECT_PATH_PREFIX "/org/a11y/atspi/accessible/" 39#define ELM_ACCESS_OBJECT_PATH_PREFIX "/org/a11y/atspi/accessible/"
38#define ELM_ACCESS_OBJECT_PATH_PREFIX2 "/org/a11y/atspi/accessible"
39#define ELM_ACCESS_OBJECT_REFERENCE_TEMPLATE ELM_ACCESS_OBJECT_PATH_PREFIX "%llu" 40#define ELM_ACCESS_OBJECT_REFERENCE_TEMPLATE ELM_ACCESS_OBJECT_PATH_PREFIX "%llu"
40 41
41#define SIZE(x) sizeof(x)/sizeof(x[0]) 42#define SIZE(x) sizeof(x)/sizeof(x[0])
@@ -49,16 +50,6 @@
49 Elm_Atspi_Bridge_Data *sd = efl_data_scope_get(obj, ELM_ATSPI_BRIDGE_CLASS); \ 50 Elm_Atspi_Bridge_Data *sd = efl_data_scope_get(obj, ELM_ATSPI_BRIDGE_CLASS); \
50 if (!sd) return val; 51 if (!sd) return val;
51 52
52#define ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, class, msg, error) \
53 if (!(obj) || !efl_isa(obj, class)) \
54 { \
55 *(error) = _dbus_invalid_ref_error_new(msg); \
56 return EINA_FALSE; \
57 }
58
59#define ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, class, msg) \
60 if (!(obj) || !efl_isa(obj, class)) \
61 return _dbus_invalid_ref_error_new(msg);
62 53
63typedef struct Key_Event_Info { 54typedef struct Key_Event_Info {
64 Ecore_Event_Key event; 55 Ecore_Event_Key event;
@@ -290,395 +281,6 @@ static const Eldbus_Signal _window_obj_signals[] = {
290 {NULL, ELDBUS_ARGS({NULL, NULL}), 0} 281 {NULL, ELDBUS_ARGS({NULL, NULL}), 0}
291}; 282};
292 283
293static const int elm_roles_to_atspi_roles[][2] = {
294 { EFL_ACCESS_ROLE_INVALID, ATSPI_ROLE_INVALID },
295 { EFL_ACCESS_ROLE_ACCELERATOR_LABEL, ATSPI_ROLE_ACCELERATOR_LABEL },
296 { EFL_ACCESS_ROLE_ALERT, ATSPI_ROLE_ALERT },
297 { EFL_ACCESS_ROLE_ANIMATION, ATSPI_ROLE_ANIMATION },
298 { EFL_ACCESS_ROLE_ARROW, ATSPI_ROLE_ARROW },
299 { EFL_ACCESS_ROLE_CALENDAR, ATSPI_ROLE_CALENDAR },
300 { EFL_ACCESS_ROLE_CANVAS, ATSPI_ROLE_CANVAS },
301 { EFL_ACCESS_ROLE_CHECK_BOX, ATSPI_ROLE_CHECK_BOX },
302 { EFL_ACCESS_ROLE_CHECK_MENU_ITEM, ATSPI_ROLE_CHECK_MENU_ITEM },
303 { EFL_ACCESS_ROLE_COLOR_CHOOSER, ATSPI_ROLE_COLOR_CHOOSER },
304 { EFL_ACCESS_ROLE_COLUMN_HEADER, ATSPI_ROLE_COLUMN_HEADER },
305 { EFL_ACCESS_ROLE_COMBO_BOX, ATSPI_ROLE_COMBO_BOX },
306 { EFL_ACCESS_ROLE_DATE_EDITOR, ATSPI_ROLE_DATE_EDITOR },
307 { EFL_ACCESS_ROLE_DESKTOP_ICON, ATSPI_ROLE_DESKTOP_ICON },
308 { EFL_ACCESS_ROLE_DESKTOP_FRAME, ATSPI_ROLE_DESKTOP_FRAME },
309 { EFL_ACCESS_ROLE_DIAL, ATSPI_ROLE_DIAL },
310 { EFL_ACCESS_ROLE_DIALOG, ATSPI_ROLE_DIALOG },
311 { EFL_ACCESS_ROLE_DIRECTORY_PANE, ATSPI_ROLE_DIRECTORY_PANE },
312 { EFL_ACCESS_ROLE_DRAWING_AREA, ATSPI_ROLE_DRAWING_AREA },
313 { EFL_ACCESS_ROLE_FILE_CHOOSER, ATSPI_ROLE_FILE_CHOOSER },
314 { EFL_ACCESS_ROLE_FILLER, ATSPI_ROLE_FILLER },
315 { EFL_ACCESS_ROLE_FOCUS_TRAVERSABLE, ATSPI_ROLE_FOCUS_TRAVERSABLE },
316 { EFL_ACCESS_ROLE_FONT_CHOOSER, ATSPI_ROLE_FONT_CHOOSER },
317 { EFL_ACCESS_ROLE_FRAME, ATSPI_ROLE_FRAME },
318 { EFL_ACCESS_ROLE_GLASS_PANE, ATSPI_ROLE_GLASS_PANE },
319 { EFL_ACCESS_ROLE_HTML_CONTAINER, ATSPI_ROLE_HTML_CONTAINER },
320 { EFL_ACCESS_ROLE_ICON, ATSPI_ROLE_ICON },
321 { EFL_ACCESS_ROLE_IMAGE, ATSPI_ROLE_IMAGE },
322 { EFL_ACCESS_ROLE_INTERNAL_FRAME, ATSPI_ROLE_INTERNAL_FRAME },
323 { EFL_ACCESS_ROLE_LABEL, ATSPI_ROLE_LABEL },
324 { EFL_ACCESS_ROLE_LAYERED_PANE, ATSPI_ROLE_LAYERED_PANE },
325 { EFL_ACCESS_ROLE_LIST, ATSPI_ROLE_LIST },
326 { EFL_ACCESS_ROLE_LIST_ITEM, ATSPI_ROLE_LIST_ITEM },
327 { EFL_ACCESS_ROLE_MENU, ATSPI_ROLE_MENU },
328 { EFL_ACCESS_ROLE_MENU_BAR, ATSPI_ROLE_MENU_BAR },
329 { EFL_ACCESS_ROLE_MENU_ITEM, ATSPI_ROLE_MENU_ITEM },
330 { EFL_ACCESS_ROLE_OPTION_PANE, ATSPI_ROLE_OPTION_PANE },
331 { EFL_ACCESS_ROLE_PAGE_TAB, ATSPI_ROLE_PAGE_TAB },
332 { EFL_ACCESS_ROLE_PAGE_TAB_LIST, ATSPI_ROLE_PAGE_TAB_LIST },
333 { EFL_ACCESS_ROLE_PANEL, ATSPI_ROLE_PANEL },
334 { EFL_ACCESS_ROLE_PASSWORD_TEXT, ATSPI_ROLE_PASSWORD_TEXT },
335 { EFL_ACCESS_ROLE_POPUP_MENU, ATSPI_ROLE_POPUP_MENU },
336 { EFL_ACCESS_ROLE_PROGRESS_BAR, ATSPI_ROLE_PROGRESS_BAR },
337 { EFL_ACCESS_ROLE_PUSH_BUTTON, ATSPI_ROLE_PUSH_BUTTON },
338 { EFL_ACCESS_ROLE_RADIO_BUTTON, ATSPI_ROLE_RADIO_BUTTON },
339 { EFL_ACCESS_ROLE_RADIO_MENU_ITEM, ATSPI_ROLE_RADIO_MENU_ITEM },
340 { EFL_ACCESS_ROLE_ROOT_PANE, ATSPI_ROLE_ROOT_PANE },
341 { EFL_ACCESS_ROLE_ROW_HEADER, ATSPI_ROLE_ROW_HEADER },
342 { EFL_ACCESS_ROLE_SCROLL_BAR, ATSPI_ROLE_SCROLL_BAR },
343 { EFL_ACCESS_ROLE_SCROLL_PANE, ATSPI_ROLE_SCROLL_PANE },
344 { EFL_ACCESS_ROLE_SEPARATOR, ATSPI_ROLE_SEPARATOR },
345 { EFL_ACCESS_ROLE_SLIDER, ATSPI_ROLE_SLIDER },
346 { EFL_ACCESS_ROLE_SPIN_BUTTON, ATSPI_ROLE_SPIN_BUTTON },
347 { EFL_ACCESS_ROLE_SPLIT_PANE, ATSPI_ROLE_SPLIT_PANE },
348 { EFL_ACCESS_ROLE_STATUS_BAR, ATSPI_ROLE_STATUS_BAR },
349 { EFL_ACCESS_ROLE_TABLE, ATSPI_ROLE_TABLE },
350 { EFL_ACCESS_ROLE_TABLE_CELL, ATSPI_ROLE_TABLE_CELL },
351 { EFL_ACCESS_ROLE_TABLE_COLUMN_HEADER, ATSPI_ROLE_TABLE_COLUMN_HEADER },
352 { EFL_ACCESS_ROLE_TABLE_ROW_HEADER, ATSPI_ROLE_TABLE_ROW_HEADER },
353 { EFL_ACCESS_ROLE_TEAROFF_MENU_ITEM, ATSPI_ROLE_TEAROFF_MENU_ITEM },
354 { EFL_ACCESS_ROLE_TERMINAL, ATSPI_ROLE_TERMINAL },
355 { EFL_ACCESS_ROLE_TEXT, ATSPI_ROLE_TEXT },
356 { EFL_ACCESS_ROLE_TOGGLE_BUTTON, ATSPI_ROLE_TOGGLE_BUTTON },
357 { EFL_ACCESS_ROLE_TOOL_BAR, ATSPI_ROLE_TOOL_BAR },
358 { EFL_ACCESS_ROLE_TOOL_TIP, ATSPI_ROLE_TOOL_TIP },
359 { EFL_ACCESS_ROLE_TREE, ATSPI_ROLE_TREE },
360 { EFL_ACCESS_ROLE_TREE_TABLE, ATSPI_ROLE_TREE_TABLE },
361 { EFL_ACCESS_ROLE_UNKNOWN, ATSPI_ROLE_UNKNOWN },
362 { EFL_ACCESS_ROLE_VIEWPORT, ATSPI_ROLE_VIEWPORT },
363 { EFL_ACCESS_ROLE_WINDOW, ATSPI_ROLE_WINDOW },
364 { EFL_ACCESS_ROLE_EXTENDED, ATSPI_ROLE_EXTENDED },
365 { EFL_ACCESS_ROLE_HEADER, ATSPI_ROLE_HEADER },
366 { EFL_ACCESS_ROLE_FOOTER, ATSPI_ROLE_FOOTER },
367 { EFL_ACCESS_ROLE_PARAGRAPH, ATSPI_ROLE_PARAGRAPH },
368 { EFL_ACCESS_ROLE_RULER, ATSPI_ROLE_RULER },
369 { EFL_ACCESS_ROLE_APPLICATION, ATSPI_ROLE_APPLICATION },
370 { EFL_ACCESS_ROLE_AUTOCOMPLETE, ATSPI_ROLE_AUTOCOMPLETE },
371 { EFL_ACCESS_ROLE_EDITBAR, ATSPI_ROLE_EDITBAR },
372 { EFL_ACCESS_ROLE_EMBEDDED, ATSPI_ROLE_EMBEDDED },
373 { EFL_ACCESS_ROLE_ENTRY, ATSPI_ROLE_ENTRY },
374 { EFL_ACCESS_ROLE_CHART, ATSPI_ROLE_CHART },
375 { EFL_ACCESS_ROLE_CAPTION, ATSPI_ROLE_CAPTION },
376 { EFL_ACCESS_ROLE_DOCUMENT_FRAME, ATSPI_ROLE_DOCUMENT_FRAME },
377 { EFL_ACCESS_ROLE_HEADING, ATSPI_ROLE_HEADING },
378 { EFL_ACCESS_ROLE_PAGE, ATSPI_ROLE_PAGE },
379 { EFL_ACCESS_ROLE_SECTION, ATSPI_ROLE_SECTION },
380 { EFL_ACCESS_ROLE_REDUNDANT_OBJECT, ATSPI_ROLE_REDUNDANT_OBJECT },
381 { EFL_ACCESS_ROLE_FORM, ATSPI_ROLE_FORM },
382 { EFL_ACCESS_ROLE_LINK, ATSPI_ROLE_LINK },
383 { EFL_ACCESS_ROLE_INPUT_METHOD_WINDOW, ATSPI_ROLE_INPUT_METHOD_WINDOW },
384 { EFL_ACCESS_ROLE_TABLE_ROW, ATSPI_ROLE_TABLE_ROW },
385 { EFL_ACCESS_ROLE_TREE_ITEM, ATSPI_ROLE_TREE_ITEM },
386 { EFL_ACCESS_ROLE_DOCUMENT_SPREADSHEET, ATSPI_ROLE_DOCUMENT_SPREADSHEET },
387 { EFL_ACCESS_ROLE_DOCUMENT_PRESENTATION, ATSPI_ROLE_DOCUMENT_PRESENTATION },
388 { EFL_ACCESS_ROLE_DOCUMENT_TEXT, ATSPI_ROLE_DOCUMENT_TEXT },
389 { EFL_ACCESS_ROLE_DOCUMENT_WEB, ATSPI_ROLE_DOCUMENT_WEB },
390 { EFL_ACCESS_ROLE_DOCUMENT_EMAIL, ATSPI_ROLE_DOCUMENT_EMAIL },
391 { EFL_ACCESS_ROLE_COMMENT, ATSPI_ROLE_COMMENT },
392 { EFL_ACCESS_ROLE_LIST_BOX, ATSPI_ROLE_LIST_BOX },
393 { EFL_ACCESS_ROLE_GROUPING, ATSPI_ROLE_GROUPING },
394 { EFL_ACCESS_ROLE_IMAGE_MAP, ATSPI_ROLE_IMAGE_MAP },
395 { EFL_ACCESS_ROLE_NOTIFICATION, ATSPI_ROLE_NOTIFICATION },
396 { EFL_ACCESS_ROLE_INFO_BAR, ATSPI_ROLE_INFO_BAR },
397 { EFL_ACCESS_ROLE_LAST_DEFINED, ATSPI_ROLE_LAST_DEFINED },
398};
399
400struct atspi_state_desc
401{
402 Efl_Access_State_Type elm_state;
403 AtspiStateType atspi_state;
404 const char *name;
405};
406
407static const struct atspi_state_desc elm_states_to_atspi_state[] = {
408 { EFL_ACCESS_STATE_INVALID, ATSPI_STATE_INVALID, "invalid" },
409 { EFL_ACCESS_STATE_ACTIVE, ATSPI_STATE_ACTIVE, "active" },
410 { EFL_ACCESS_STATE_ARMED, ATSPI_STATE_ARMED, "armed" },
411 { EFL_ACCESS_STATE_BUSY, ATSPI_STATE_BUSY, "busy" },
412 { EFL_ACCESS_STATE_CHECKED, ATSPI_STATE_CHECKED, "checked" },
413 { EFL_ACCESS_STATE_COLLAPSED, ATSPI_STATE_COLLAPSED, "collapsed" },
414 { EFL_ACCESS_STATE_DEFUNCT, ATSPI_STATE_DEFUNCT, "defunct" },
415 { EFL_ACCESS_STATE_EDITABLE, ATSPI_STATE_EDITABLE, "editable" },
416 { EFL_ACCESS_STATE_ENABLED, ATSPI_STATE_ENABLED, "enabled" },
417 { EFL_ACCESS_STATE_EXPANDABLE, ATSPI_STATE_EXPANDABLE, "expandable" },
418 { EFL_ACCESS_STATE_EXPANDED, ATSPI_STATE_EXPANDED, "expanded" },
419 { EFL_ACCESS_STATE_FOCUSABLE, ATSPI_STATE_FOCUSABLE, "focusable" },
420 { EFL_ACCESS_STATE_FOCUSED, ATSPI_STATE_FOCUSED, "focused" },
421 { EFL_ACCESS_STATE_HAS_TOOLTIP, ATSPI_STATE_HAS_TOOLTIP, "has-tooltip" },
422 { EFL_ACCESS_STATE_HORIZONTAL, ATSPI_STATE_HORIZONTAL, "horizontal" },
423 { EFL_ACCESS_STATE_ICONIFIED, ATSPI_STATE_ICONIFIED, "iconified" },
424 { EFL_ACCESS_STATE_MODAL, ATSPI_STATE_MODAL, "modal" },
425 { EFL_ACCESS_STATE_MULTI_LINE, ATSPI_STATE_MULTI_LINE, "multi-line" },
426 { EFL_ACCESS_STATE_MULTISELECTABLE, ATSPI_STATE_MULTISELECTABLE, "multiselectable" },
427 { EFL_ACCESS_STATE_OPAQUE, ATSPI_STATE_OPAQUE, "opaque" },
428 { EFL_ACCESS_STATE_PRESSED, ATSPI_STATE_PRESSED, "pressed" },
429 { EFL_ACCESS_STATE_RESIZABLE, ATSPI_STATE_RESIZABLE, "resizable" },
430 { EFL_ACCESS_STATE_SELECTABLE, ATSPI_STATE_SELECTABLE, "selectable" },
431 { EFL_ACCESS_STATE_SELECTED, ATSPI_STATE_SELECTED, "selected" },
432 { EFL_ACCESS_STATE_SENSITIVE, ATSPI_STATE_SENSITIVE, "sensitive" },
433 { EFL_ACCESS_STATE_SHOWING, ATSPI_STATE_SHOWING, "showing" },
434 { EFL_ACCESS_STATE_SINGLE_LINE, ATSPI_STATE_SINGLE_LINE, "single-line" },
435 { EFL_ACCESS_STATE_STALE, ATSPI_STATE_STALE, "stale" },
436 { EFL_ACCESS_STATE_TRANSIENT, ATSPI_STATE_TRANSIENT, "transient" },
437 { EFL_ACCESS_STATE_VERTICAL, ATSPI_STATE_VERTICAL, "vertical" },
438 { EFL_ACCESS_STATE_VISIBLE, ATSPI_STATE_VISIBLE, "visible" },
439 { EFL_ACCESS_STATE_MANAGES_DESCENDANTS, ATSPI_STATE_MANAGES_DESCENDANTS, "manages-descendants" },
440 { EFL_ACCESS_STATE_INDETERMINATE, ATSPI_STATE_INDETERMINATE, "indeterminate" },
441 { EFL_ACCESS_STATE_REQUIRED, ATSPI_STATE_REQUIRED, "required" },
442 { EFL_ACCESS_STATE_TRUNCATED, ATSPI_STATE_TRUNCATED, "truncated" },
443 { EFL_ACCESS_STATE_ANIMATED, ATSPI_STATE_ANIMATED, "animated" },
444 { EFL_ACCESS_STATE_INVALID_ENTRY, ATSPI_STATE_INVALID_ENTRY, "invalid-entry" },
445 { EFL_ACCESS_STATE_SUPPORTS_AUTOCOMPLETION, ATSPI_STATE_SUPPORTS_AUTOCOMPLETION, "supports-autocompletion" },
446 { EFL_ACCESS_STATE_SELECTABLE_TEXT, ATSPI_STATE_SELECTABLE_TEXT, "selectable-text" },
447 { EFL_ACCESS_STATE_IS_DEFAULT, ATSPI_STATE_IS_DEFAULT, "is-default" },
448 { EFL_ACCESS_STATE_VISITED, ATSPI_STATE_VISITED, "visited" },
449 { EFL_ACCESS_STATE_LAST_DEFINED, ATSPI_STATE_LAST_DEFINED, "last-defined" },
450};
451
452static const int elm_relation_to_atspi_relation_mapping[] = {
453 [EFL_ACCESS_RELATION_NULL] = ATSPI_RELATION_NULL,
454 [EFL_ACCESS_RELATION_LABEL_FOR] = ATSPI_RELATION_LABEL_FOR,
455 [EFL_ACCESS_RELATION_LABELLED_BY] = ATSPI_RELATION_LABELLED_BY,
456 [EFL_ACCESS_RELATION_CONTROLLER_FOR] = ATSPI_RELATION_CONTROLLER_FOR,
457 [EFL_ACCESS_RELATION_CONTROLLED_BY] = ATSPI_RELATION_CONTROLLED_BY,
458 [EFL_ACCESS_RELATION_MEMBER_OF] = ATSPI_RELATION_MEMBER_OF,
459 [EFL_ACCESS_RELATION_TOOLTIP_FOR] = ATSPI_RELATION_TOOLTIP_FOR,
460 [EFL_ACCESS_RELATION_NODE_CHILD_OF] = ATSPI_RELATION_NODE_CHILD_OF,
461 [EFL_ACCESS_RELATION_NODE_PARENT_OF] = ATSPI_RELATION_NODE_PARENT_OF,
462 [EFL_ACCESS_RELATION_EXTENDED] = ATSPI_RELATION_EXTENDED,
463 [EFL_ACCESS_RELATION_FLOWS_TO] = ATSPI_RELATION_FLOWS_TO,
464 [EFL_ACCESS_RELATION_FLOWS_FROM] = ATSPI_RELATION_FLOWS_FROM,
465 [EFL_ACCESS_RELATION_SUBWINDOW_OF] = ATSPI_RELATION_SUBWINDOW_OF,
466 [EFL_ACCESS_RELATION_EMBEDS] = ATSPI_RELATION_EMBEDS,
467 [EFL_ACCESS_RELATION_EMBEDDED_BY] = ATSPI_RELATION_EMBEDDED_BY,
468 [EFL_ACCESS_RELATION_POPUP_FOR] = ATSPI_RELATION_POPUP_FOR,
469 [EFL_ACCESS_RELATION_PARENT_WINDOW_OF] = ATSPI_RELATION_PARENT_WINDOW_OF,
470 [EFL_ACCESS_RELATION_DESCRIPTION_FOR] = ATSPI_RELATION_DESCRIPTION_FOR,
471 [EFL_ACCESS_RELATION_DESCRIBED_BY] = ATSPI_RELATION_DESCRIBED_BY,
472 [EFL_ACCESS_RELATION_LAST_DEFINED] = ATSPI_RELATION_LAST_DEFINED,
473};
474
475static inline Eldbus_Message *_dbus_invalid_ref_error_new(const Eldbus_Message *msg)
476{
477 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.UnknownObject", "Path is not valid accessible object reference.");
478}
479
480static AtspiRelationType _elm_relation_to_atspi_relation(Efl_Access_Relation_Type type)
481{
482 if ((type < EFL_ACCESS_RELATION_LAST_DEFINED) && (type > EFL_ACCESS_RELATION_NULL))
483 return elm_relation_to_atspi_relation_mapping[type];
484 return ATSPI_RELATION_NULL;
485}
486
487static Eldbus_Message *
488_accessible_get_role(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
489{
490 const char *obj_path = eldbus_message_path_get(msg);
491 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
492 Eo *obj = _bridge_object_from_path(bridge, obj_path);
493 AtspiRole atspi_role = ATSPI_ROLE_INVALID;
494 Efl_Access_Role role;
495
496 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
497
498 role = efl_access_role_get(obj);
499
500 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
501 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
502
503 atspi_role = role > EFL_ACCESS_ROLE_LAST_DEFINED ? ATSPI_ROLE_LAST_DEFINED : elm_roles_to_atspi_roles[role][1];
504 eldbus_message_arguments_append(ret, "u", atspi_role);
505 return ret;
506}
507
508static Eldbus_Message *
509_accessible_get_role_name(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
510{
511 const char *role_name = NULL, *obj_path = eldbus_message_path_get(msg);
512 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
513 Eo *obj = _bridge_object_from_path(bridge, obj_path);
514
515 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
516
517 role_name = efl_access_role_name_get(obj);
518
519 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
520 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
521 eldbus_message_arguments_append(ret, "s", role_name);
522
523 return ret;
524}
525
526static Eldbus_Message *
527_accessible_get_localized_role_name(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
528{
529 const char *l_role_name = NULL, *obj_path = eldbus_message_path_get(msg);
530 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
531 Eo *obj = _bridge_object_from_path(bridge, obj_path);
532
533 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
534
535 l_role_name = efl_access_localized_role_name_get(obj);
536 EINA_SAFETY_ON_NULL_RETURN_VAL(l_role_name, NULL);
537
538 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
539 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
540 eldbus_message_arguments_append(ret, "s", l_role_name);
541
542 return ret;
543}
544
545static Eldbus_Message *
546_accessible_get_children(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
547{
548 const char *obj_path = eldbus_message_path_get(msg);
549 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
550 Eo *obj = _bridge_object_from_path(bridge, obj_path);
551 Eina_List *children_list = NULL, *l;
552 Eldbus_Message *ret;
553 Eldbus_Message_Iter *iter, *iter_array;
554 Eo *children;
555
556 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
557
558 children_list = efl_access_children_get(obj);
559
560 ret = eldbus_message_method_return_new(msg);
561 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
562
563 iter = eldbus_message_iter_get(ret);
564 iter_array = eldbus_message_iter_container_new(iter, 'a', "(so)");
565 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
566
567 EINA_LIST_FOREACH(children_list, l, children)
568 {
569 _bridge_iter_object_reference_append(bridge, iter_array, children);
570 _bridge_object_register(bridge, children);
571 }
572
573 eldbus_message_iter_container_close(iter, iter_array);
574 eina_list_free(children_list);
575
576 return ret;
577
578fail:
579 if (ret) eldbus_message_unref(ret);
580 return NULL;
581}
582
583static Eldbus_Message *
584_accessible_get_application(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
585{
586 Eldbus_Message *ret;
587 const char *obj_path = eldbus_message_path_get(msg);
588 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
589 Eo *root, *obj = _bridge_object_from_path(bridge, obj_path);
590
591 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
592
593 ret = eldbus_message_method_return_new(msg);
594 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
595
596 Eldbus_Message_Iter *iter = eldbus_message_iter_get(ret);
597 root = efl_access_root_get(EFL_ACCESS_MIXIN);
598 _bridge_iter_object_reference_append(bridge, iter, root);
599
600 return ret;
601}
602
603static Eldbus_Message *
604_accessible_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
605{
606 Eina_List *attrs = NULL, *l;
607 Efl_Access_Attribute *attr;
608 Eldbus_Message_Iter *iter, *iter_dict = NULL, *iter_entry;
609 Eldbus_Message *ret;
610
611 const char *obj_path = eldbus_message_path_get(msg);
612 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
613 Eo *obj = _bridge_object_from_path(bridge, obj_path);
614
615 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
616
617 ret = eldbus_message_method_return_new(msg);
618 if (!ret) goto error;
619
620 attrs = efl_access_attributes_get(obj);
621
622 iter = eldbus_message_iter_get(ret);
623 if (!iter) goto error;
624
625 iter_dict = eldbus_message_iter_container_new(iter, 'a', "{ss}");
626 if (!iter_dict) goto error;
627
628
629 EINA_LIST_FOREACH(attrs, l, attr)
630 {
631 iter_entry = eldbus_message_iter_container_new(iter_dict, 'e', NULL);
632 if (!iter_entry) goto error;
633 eldbus_message_iter_arguments_append(iter_entry, "ss", attr->key, attr->value);
634 eldbus_message_iter_container_close(iter_dict, iter_entry);
635 }
636
637 eldbus_message_iter_container_close(iter, iter_dict);
638 efl_access_attributes_list_free(attrs);
639 return ret;
640
641error:
642 if (iter_dict) eldbus_message_iter_container_close(iter, iter_dict);
643 if (ret) eldbus_message_unref(ret);
644 efl_access_attributes_list_free(attrs);
645 return NULL;
646}
647
648static Eldbus_Message *
649_accessible_interfaces_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
650{
651 Eldbus_Message *ret;
652 Eldbus_Message_Iter *iter;
653 const char *obj_path = eldbus_message_path_get(msg);
654 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
655 Eo *obj = _bridge_object_from_path(bridge, obj_path);
656
657 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
658
659 ret = eldbus_message_method_return_new(msg);
660 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
661
662 iter = eldbus_message_iter_get(ret);
663 _iter_interfaces_append(iter, obj);
664
665 return ret;
666}
667
668static uint64_t
669_elm_atspi_state_set_to_atspi_state_set(Efl_Access_State_Set states)
670{
671 uint64_t ret = 0;
672 unsigned int i = 0;
673
674 for (i = 0; i < SIZE(elm_states_to_atspi_state); i++)
675 {
676 if (STATE_TYPE_GET(states, elm_states_to_atspi_state[i].elm_state))
677 STATE_TYPE_SET(ret, elm_states_to_atspi_state[i].atspi_state);
678 }
679 return ret;
680}
681
682static Efl_Access_State_Set 284static Efl_Access_State_Set
683_atspi_state_set_to_elm_atspi_state_set(uint64_t states) 285_atspi_state_set_to_elm_atspi_state_set(uint64_t states)
684{ 286{
@@ -691,6 +293,7 @@ _atspi_state_set_to_elm_atspi_state_set(uint64_t states)
691static Eina_Hash* 293static Eina_Hash*
692_elm_atspi_state_hash_build(void) 294_elm_atspi_state_hash_build(void)
693{ 295{
296#if 0
694 Eina_Hash *ret = eina_hash_string_superfast_new(NULL); 297 Eina_Hash *ret = eina_hash_string_superfast_new(NULL);
695 unsigned int i = 0; 298 unsigned int i = 0;
696 299
@@ -698,6 +301,8 @@ _elm_atspi_state_hash_build(void)
698 eina_hash_add(ret, elm_states_to_atspi_state[i].name, &elm_states_to_atspi_state[i]); 301 eina_hash_add(ret, elm_states_to_atspi_state[i].name, &elm_states_to_atspi_state[i]);
699 302
700 return ret; 303 return ret;
304#endif
305 return NULL;
701} 306}
702 307
703static Eina_Hash* 308static Eina_Hash*
@@ -713,159 +318,6 @@ _elm_atspi_event_hash_build(void)
713} 318}
714 319
715static Eldbus_Message * 320static Eldbus_Message *
716_accessible_get_state(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
717{
718 Eldbus_Message *ret;
719 Eldbus_Message_Iter *iter, *iter_array;
720 Efl_Access_State_Set states;
721 uint64_t atspi_states = 0;
722
723 const char *obj_path = eldbus_message_path_get(msg);
724 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
725 Eo *obj = _bridge_object_from_path(bridge, obj_path);
726
727 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
728
729 ret = eldbus_message_method_return_new(msg);
730 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
731
732 iter = eldbus_message_iter_get(ret);
733 iter_array = eldbus_message_iter_container_new(iter, 'a', "u");
734 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
735
736 states = efl_access_state_set_get(obj);
737
738 atspi_states = _elm_atspi_state_set_to_atspi_state_set(states);
739
740 unsigned int s1 = atspi_states & 0xFFFFFFFF;
741 unsigned int s2 = (atspi_states >> 32) & 0xFFFFFFFF;
742
743 eldbus_message_iter_basic_append(iter_array, 'u', s1);
744 eldbus_message_iter_basic_append(iter_array, 'u', s2);
745 eldbus_message_iter_container_close(iter, iter_array);
746
747 return ret;
748
749fail:
750 if (ret) eldbus_message_unref(ret);
751 return NULL;
752}
753
754static Eldbus_Message *
755_accessible_get_index_in_parent(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
756{
757 const char *obj_path = eldbus_message_path_get(msg);
758 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
759 Eo *obj = _bridge_object_from_path(bridge, obj_path);
760 Eldbus_Message *ret;
761 int idx = -1;
762
763 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
764
765 ret = eldbus_message_method_return_new(msg);
766 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
767
768 idx = efl_access_index_in_parent_get(obj);
769
770 eldbus_message_arguments_append(ret, "i", idx);
771
772 return ret;
773}
774
775static Eldbus_Message *
776_accessible_child_at_index(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
777{
778 const char *obj_path = eldbus_message_path_get(msg);
779 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
780 Eo *obj = _bridge_object_from_path(bridge, obj_path);
781 Eo *child = NULL;
782 Eina_List *children = NULL;
783 int idx;
784 Eldbus_Message *ret;
785 Eldbus_Message_Iter *iter;
786
787 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
788
789 if (!eldbus_message_arguments_get(msg, "i", &idx))
790 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
791
792 ret = eldbus_message_method_return_new(msg);
793 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
794
795 iter = eldbus_message_iter_get(ret);
796 children = efl_access_children_get(obj);
797
798 child = eina_list_nth(children, idx);
799 _bridge_iter_object_reference_append(bridge, iter, child);
800 _bridge_object_register(bridge, child);
801 eina_list_free(children);
802
803 return ret;
804}
805
806static Eldbus_Message *
807_accessible_get_relation_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
808{
809 const char *obj_path = eldbus_message_path_get(msg);
810 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
811 Eo *rel_obj, *obj = _bridge_object_from_path(bridge, obj_path);
812 Eldbus_Message *ret = NULL;
813 Eldbus_Message_Iter *iter = NULL, *iter_array = NULL, *iter_array2 = NULL, *iter_struct;
814 Efl_Access_Relation *rel;
815 Eina_List *l, *l2;
816 Efl_Access_Relation_Set rels;
817
818 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, msg);
819
820 ret = eldbus_message_method_return_new(msg);
821 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
822
823 iter = eldbus_message_iter_get(ret);
824 iter_array = eldbus_message_iter_container_new(iter, 'a', "(ua(so))");
825 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
826
827 rels = efl_access_relation_set_get(obj);
828
829 EINA_LIST_FOREACH(rels, l, rel)
830 {
831 iter_struct = eldbus_message_iter_container_new(iter_array, 'r', NULL);
832 eldbus_message_iter_basic_append(iter_struct, 'u', _elm_relation_to_atspi_relation(rel->type));
833 iter_array2 = eldbus_message_iter_container_new(iter_struct, 'a', "(so)");
834 EINA_SAFETY_ON_NULL_GOTO(iter_array2, fail);
835 EINA_LIST_FOREACH(rel->objects, l2, rel_obj)
836 {
837 _bridge_iter_object_reference_append(bridge, iter_array2, rel_obj);
838 _bridge_object_register(bridge, rel_obj);
839 }
840 eldbus_message_iter_container_close(iter_struct, iter_array2);
841 eldbus_message_iter_container_close(iter_array, iter_struct);
842 }
843 efl_access_relation_set_free(rels);
844 eldbus_message_iter_container_close(iter, iter_array);
845
846 return ret;
847
848fail:
849 eldbus_message_unref(ret);
850 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to get relation set.");
851}
852
853static const Eldbus_Method accessible_methods[] = {
854 { "GetChildAtIndex", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"(so)", "Accessible"}), _accessible_child_at_index, 0 },
855 { "GetChildren", NULL, ELDBUS_ARGS({"a(so)", "children"}), _accessible_get_children, 0 },
856 { "GetIndexInParent", NULL, ELDBUS_ARGS({"i", "index"}), _accessible_get_index_in_parent, 0 },
857 { "GetRelationSet", NULL, ELDBUS_ARGS({"a(ua(so))", NULL}), _accessible_get_relation_set, 0 },
858 { "GetRole", NULL, ELDBUS_ARGS({"u", "Role"}), _accessible_get_role, 0 },
859 { "GetRoleName", NULL, ELDBUS_ARGS({"s", "Name"}), _accessible_get_role_name, 0 },
860 { "GetLocalizedRoleName", NULL, ELDBUS_ARGS({"s", "LocalizedName"}), _accessible_get_localized_role_name, 0},
861 { "GetState", NULL, ELDBUS_ARGS({"au", NULL}), _accessible_get_state, 0},
862 { "GetApplication", NULL, ELDBUS_ARGS({"(so)", NULL}), _accessible_get_application, 0},
863 { "GetAttributes", NULL, ELDBUS_ARGS({"a{ss}", NULL}), _accessible_attributes_get, 0},
864 { "GetInterfaces", NULL, ELDBUS_ARGS({"as", NULL}), _accessible_interfaces_get, 0},
865 { NULL, NULL, NULL, NULL, 0 }
866};
867
868static Eldbus_Message *
869_selection_selected_child_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) 321_selection_selected_child_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
870{ 322{
871 const char *obj_path = eldbus_message_path_get(msg); 323 const char *obj_path = eldbus_message_path_get(msg);
@@ -2071,55 +1523,6 @@ _path_from_object(const Eo *eo)
2071} 1523}
2072 1524
2073static Eina_Bool 1525static Eina_Bool
2074_accessible_property_get(const Eldbus_Service_Interface *interface, const char *property,
2075 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg,
2076 Eldbus_Message **error)
2077{
2078 const char *ret = NULL, *obj_path = eldbus_message_path_get(request_msg);
2079 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2080 Eo *ret_obj = NULL, *obj = _bridge_object_from_path(bridge, obj_path);
2081
2082 ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, EFL_ACCESS_MIXIN, request_msg, error);
2083
2084 if (!strcmp(property, "Name"))
2085 {
2086 ret = efl_access_name_get(obj);
2087 if (!ret)
2088 ret = "";
2089 eldbus_message_iter_basic_append(iter, 's', ret);
2090 return EINA_TRUE;
2091 }
2092 else if (!strcmp(property, "Description"))
2093 {
2094 ret = efl_access_description_get(obj);
2095 if (!ret)
2096 ret = "";
2097 eldbus_message_iter_basic_append(iter, 's', ret);
2098 return EINA_TRUE;
2099 }
2100 else if (!strcmp(property, "Parent"))
2101 {
2102 ret_obj = efl_access_parent_get(obj);
2103 Efl_Access_Role role = EFL_ACCESS_ROLE_INVALID;
2104 role = efl_access_role_get(obj);
2105 if ((!ret_obj) && (EFL_ACCESS_ROLE_APPLICATION == role))
2106 _object_desktop_reference_append(iter);
2107 else
2108 _bridge_iter_object_reference_append(bridge, iter, ret_obj);
2109 return EINA_TRUE;
2110 }
2111 else if (!strcmp(property, "ChildCount"))
2112 {
2113 Eina_List *l = NULL;
2114 l = efl_access_children_get(obj);
2115 eldbus_message_iter_basic_append(iter, 'i', eina_list_count(l));
2116 eina_list_free(l);
2117 return EINA_TRUE;
2118 }
2119 return EINA_FALSE;
2120}
2121
2122static Eina_Bool
2123_selection_property_get(const Eldbus_Service_Interface *interface, const char *property, 1526_selection_property_get(const Eldbus_Service_Interface *interface, const char *property,
2124 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg, 1527 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg,
2125 Eldbus_Message **error) 1528 Eldbus_Message **error)
@@ -2344,14 +1747,6 @@ _application_properties_get(const Eldbus_Service_Interface *interface, const cha
2344 return EINA_FALSE; 1747 return EINA_FALSE;
2345} 1748}
2346 1749
2347static const Eldbus_Property accessible_properties[] = {
2348 { "Name", "s", NULL, NULL, 0 },
2349 { "Description", "s", NULL, NULL, 0 },
2350 { "Parent", "(so)", NULL, NULL, 0 },
2351 { "ChildCount", "i", NULL, NULL, 0 },
2352 { NULL, NULL, NULL, NULL, 0 }
2353};
2354
2355static const Eldbus_Property action_properties[] = { 1750static const Eldbus_Property action_properties[] = {
2356 { "NActions", "i", _action_property_get, NULL, 0 }, 1751 { "NActions", "i", _action_property_get, NULL, 0 },
2357 { NULL, NULL, NULL, NULL, 0 } 1752 { NULL, NULL, NULL, NULL, 0 }
@@ -2389,10 +1784,6 @@ static const Eldbus_Property application_properties[] = {
2389 { NULL, NULL, NULL, NULL, 0 } 1784 { NULL, NULL, NULL, NULL, 0 }
2390}; 1785};
2391 1786
2392static const Eldbus_Service_Interface_Desc accessible_iface_desc = {
2393 ATSPI_DBUS_INTERFACE_ACCESSIBLE, accessible_methods, NULL, accessible_properties, _accessible_property_get, NULL
2394};
2395
2396static const Eldbus_Service_Interface_Desc action_iface_desc = { 1787static const Eldbus_Service_Interface_Desc action_iface_desc = {
2397 ATSPI_DBUS_INTERFACE_ACTION, action_methods, NULL, action_properties, NULL, NULL 1788 ATSPI_DBUS_INTERFACE_ACTION, action_methods, NULL, action_properties, NULL, NULL
2398}; 1789};
@@ -3691,9 +3082,12 @@ _set_broadcast_flag(const char *event, Eo *bridge)
3691 if (!tokens[2] || *tokens[2] == '\0') 3082 if (!tokens[2] || *tokens[2] == '\0')
3692 pd->object_state_broadcast_mask = -1; // broadcast all 3083 pd->object_state_broadcast_mask = -1; // broadcast all
3693 eina_str_tolower(&tokens[2]); 3084 eina_str_tolower(&tokens[2]);
3085 //FIXME
3086 /*
3694 struct atspi_state_desc *sd = eina_hash_find(pd->state_hash, tokens[2]); 3087 struct atspi_state_desc *sd = eina_hash_find(pd->state_hash, tokens[2]);
3695 if (sd) 3088 if (sd)
3696 STATE_TYPE_SET(pd->object_state_broadcast_mask, sd->elm_state); 3089 STATE_TYPE_SET(pd->object_state_broadcast_mask, sd->elm_state);
3090 */
3697 } 3091 }
3698 else if (!strcmp(tokens[1], "PropertyChange")) 3092 else if (!strcmp(tokens[1], "PropertyChange"))
3699 { 3093 {
@@ -3819,7 +3213,7 @@ static void
3819_state_changed_signal_send(void *data, const Efl_Event *event) 3213_state_changed_signal_send(void *data, const Efl_Event *event)
3820{ 3214{
3821 Efl_Access_Event_State_Changed_Data *state_data = event->info; 3215 Efl_Access_Event_State_Changed_Data *state_data = event->info;
3822 const char *type_desc; 3216 const char *type_desc = NULL;
3823 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd); 3217 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd);
3824 3218
3825 if (!STATE_TYPE_GET(pd->object_state_broadcast_mask, state_data->type)) 3219 if (!STATE_TYPE_GET(pd->object_state_broadcast_mask, state_data->type))
@@ -3835,7 +3229,7 @@ _state_changed_signal_send(void *data, const Efl_Event *event)
3835 return; 3229 return;
3836 } 3230 }
3837 3231
3838 type_desc = elm_states_to_atspi_state[state_data->type].name; 3232 //FIXME type_desc = elm_states_to_atspi_state[state_data->type].name;
3839 3233
3840 _bridge_signal_send(data, event->object, ATSPI_DBUS_INTERFACE_EVENT_OBJECT, 3234 _bridge_signal_send(data, event->object, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
3841 &_event_obj_signals[ATSPI_OBJECT_EVENT_STATE_CHANGED], type_desc, state_data->new_value, 0, NULL); 3235 &_event_obj_signals[ATSPI_OBJECT_EVENT_STATE_CHANGED], type_desc, state_data->new_value, 0, NULL);
@@ -4319,9 +3713,12 @@ _interfaces_register(Eo *bridge)
4319{ 3713{
4320 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 3714 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4321 3715
3716 pd->interfaces.accessible = _elm_atspi_access_adaptor_register(pd->a11y_bus);
3717#if 0
4322 pd->interfaces.accessible = 3718 pd->interfaces.accessible =
4323 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &accessible_iface_desc); 3719 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &accessible_iface_desc);
4324 eldbus_service_object_data_set(pd->interfaces.accessible, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge); 3720 eldbus_service_object_data_set(pd->interfaces.accessible, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
3721#endif
4325 3722
4326 pd->interfaces.application = 3723 pd->interfaces.application =
4327 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &application_iface_desc); 3724 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &application_iface_desc);