summaryrefslogtreecommitdiff
path: root/src/lib/elementary/elm_atspi_access_adaptor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/elementary/elm_atspi_access_adaptor.c')
-rw-r--r--src/lib/elementary/elm_atspi_access_adaptor.c574
1 files changed, 574 insertions, 0 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}