2 # include "elementary_config.h"
5 #define ELM_INTERFACE_ATSPI_COMPONENT_PROTECTED
6 #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
7 #define ELM_INTERFACE_ATSPI_ACTION_PROTECTED
8 #define ELM_INTERFACE_ATSPI_VALUE_PROTECTED
9 #define ELM_INTERFACE_ATSPI_IMAGE_PROTECTED
10 #define ELM_INTERFACE_ATSPI_SELECTION_PROTECTED
11 #define ELM_INTERFACE_ATSPI_TEXT_PROTECTED
12 #define ELM_INTERFACE_ATSPI_EDITABLE_TEXT_PROTECTED
14 #include "atspi/atspi-constants.h"
17 #include <Elementary.h>
21 * Accessibility Bus info not defined in atspi-constants.h
23 #define A11Y_DBUS_NAME "org.a11y.Bus"
24 #define A11Y_DBUS_PATH "/org/a11y/bus"
25 #define A11Y_DBUS_INTERFACE "org.a11y.Bus"
26 #define A11Y_DBUS_STATUS_INTERFACE "org.a11y.Status"
27 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
28 #define A11Y_DBUS_ENABLED_PROPERTY "IsEnabled"
30 #define ATSPI_DBUS_INTERFACE_EVENT_WINDOW "org.a11y.atspi.Event.Window"
32 #define CACHE_ITEM_SIGNATURE "((so)(so)(so)a(so)assusau)"
33 #define CACHE_INTERFACE_PATH "/org/a11y/atspi/cache"
35 #define ELM_ACCESS_OBJECT_PATH_ROOT "root"
36 #define ELM_ACCESS_OBJECT_PATH_PREFIX "/org/a11y/atspi/accessible/"
37 #define ELM_ACCESS_OBJECT_PATH_PREFIX2 "/org/a11y/atspi/accessible"
38 #define ELM_ACCESS_OBJECT_REFERENCE_TEMPLATE ELM_ACCESS_OBJECT_PATH_PREFIX "%llu"
40 #define ELM_ATSPI_DBUS_INTERFACE_PROXY "elm.atspi.bridge.proxy.Socket"
41 //TIZEN_ONLY(20160527) - Add direct reading feature
42 #define ELM_ATSPI_DIRECT_READ_BUS "org.tizen.ScreenReader"
43 #define ELM_ATSPI_DIRECT_READ_PATH "/org/tizen/DirectReading"
44 #define ELM_ATSPI_DIRECT_READ_INTERFACE "org.tizen.DirectReading"
45 struct _Elm_Atspi_Say_Info
48 Elm_Atspi_Say_Signal_Cb func; //this function will be called when state of related reading is changed
50 typedef struct _Elm_Atspi_Say_Info Elm_Atspi_Say_Info;
51 static Eina_Hash *read_command_id = NULL;
53 #define SIZE(x) sizeof(x)/sizeof(x[0])
54 #define ELM_ATSPI_BRIDGE_CLASS_NAME "__Elm_Atspi_Bridge"
56 #define ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(obj, sd) \
57 Elm_Atspi_Bridge_Data *sd = eo_data_scope_get(obj, ELM_ATSPI_BRIDGE_CLASS); \
60 #define ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(obj, sd, val) \
61 Elm_Atspi_Bridge_Data *sd = eo_data_scope_get(obj, ELM_ATSPI_BRIDGE_CLASS); \
64 #define ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, class, msg, error) \
65 if (!(obj) || !eo_isa(obj, class)) \
67 *(error) = _dbus_invalid_ref_error_new(msg); \
71 #define ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, class, msg) \
72 if (!(obj) || !eo_isa(obj, class)) \
73 return _dbus_invalid_ref_error_new(msg);
75 typedef struct Key_Event_Info {
76 Ecore_Event_Key event;
81 typedef struct _Elm_Atspi_Bridge_Data
83 Eldbus_Connection *session_bus;
84 Eldbus_Connection *a11y_bus;
85 Eina_List *reemited_events;
88 Eldbus_Service_Interface *cache_interface;
89 Eldbus_Signal_Handler *register_hdl;
90 Eldbus_Signal_Handler *unregister_hdl;
91 //TIZEN_ONLY(20160614):apply callbacks on direct reading stop/cancel/skipp
92 Eldbus_Signal_Handler *reading_state_changed_hdl;
94 unsigned long object_broadcast_mask;
95 unsigned long object_property_broadcast_mask;
96 unsigned long object_children_broadcast_mask;
97 unsigned long long object_state_broadcast_mask;
98 unsigned long long window_signal_broadcast_mask;
99 Ecore_Event_Filter *key_flr;
100 Eldbus_Object *bus_obj;
101 Eina_List *pending_requests;
103 Eina_Hash *state_hash;
105 Eldbus_Service_Interface *accessible;
106 Eldbus_Service_Interface *application;
107 Eldbus_Service_Interface *action;
108 Eldbus_Service_Interface *component;
109 Eldbus_Service_Interface *collection;
110 Eldbus_Service_Interface *editable_text;
111 Eldbus_Service_Interface *image;
112 Eldbus_Service_Interface *selection;
113 Eldbus_Service_Interface *text;
114 Eldbus_Service_Interface *value;
115 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
116 Eldbus_Service_Interface *socket;
119 Elm_Atspi_Event_Handler *event_hdlr;
120 Eina_Hash *event_hash;
121 Eina_List *socket_queue;
122 Eina_List *plug_queue;
123 Eina_Bool connected : 1;
124 // TIZEN_ONLY(20160802): do not handle events if the window is not activated
125 Eina_Bool window_activated : 1;
126 // TIZEN_ONLY(20170512): send window activated event to at_spi2 only once per session
127 Eina_Bool window_activated_broadcast_needed : 1;
128 //TIZEN_ONLY(20161027) - Export elm_atspi_bridge_utils_is_screen_reader_enabled
129 Eina_Bool screen_reader_enabled : 1;
131 } Elm_Atspi_Bridge_Data;
134 struct collection_match_rule {
135 Elm_Atspi_State_Set states;
136 AtspiCollectionMatchType statematchtype;
137 Eina_List *attributes;
138 AtspiCollectionMatchType attributematchtype;
140 AtspiCollectionMatchType rolematchtype;
142 AtspiCollectionMatchType interfacematchtype;
143 Eina_Bool reverse : 1;
146 static Eo *_instance;
147 static int _init_count = 0;
148 static const char *_a11y_socket_address;
150 // Object Event handlers
151 static Eina_Bool _state_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
152 static Eina_Bool _property_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info);
153 static Eina_Bool _bounds_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info);
154 static Eina_Bool _children_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info);
155 static Eina_Bool _window_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
156 static Eina_Bool _visible_data_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
157 static Eina_Bool _active_descendant_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
158 static Eina_Bool _selection_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
159 static Eina_Bool _text_text_inserted_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
160 static Eina_Bool _text_text_removed_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
161 static Eina_Bool _text_caret_moved_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
162 static Eina_Bool _text_selection_changed_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info EINA_UNUSED);
163 //TIZEN_ONLY(20160623): atspi: moved highlight when object is out of screen
164 static Eina_Bool _move_outed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info);
167 // bridge private methods
168 static void _bridge_cache_build(Eo *bridge, void *obj);
169 static void _bridge_object_register(Eo *bridge, Eo *obj);
170 static void _bridge_object_unregister(Eo *bridge, Eo *obj);
171 static const char * _bridge_path_from_object(Eo *bridge, const Eo *eo);
172 static void _bridge_signal_send(Eo *bridge, Eo *obj, const char *ifc, const Eldbus_Signal *signal, const char *minor, unsigned int det1, unsigned int det2, const char *variant_sig, ...);
173 static Eo * _bridge_object_from_path(Eo *bridge, const char *path);
174 static void _bridge_iter_object_reference_append(Eo *bridge, Eldbus_Message_Iter *iter, const Eo *obj);
177 static void _iter_interfaces_append(Eldbus_Message_Iter *iter, const Eo *obj);
178 static Eina_Bool _elm_atspi_bridge_key_filter(void *data, void *loop, int type, void *event);
179 static void _object_desktop_reference_append(Eldbus_Message_Iter *iter);
180 static Eina_Bool _on_object_add(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED);
181 static Eina_Bool _on_object_del(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED);
182 static void _plug_connect(Eldbus_Connection *conn, Eo *proxy);
183 static void _socket_ifc_create(Eldbus_Connection *conn, Eo *proxy);
184 static void _object_get_bus_name_and_path(Eo *bridge, const Eo *obj, const char **bus_name, const char **path);
185 // TIZEN_ONLY(20170310) - implementation of get object under coordinates for accessibility
186 static Eo *_calculate_navigable_accessible_at_point(Eo *bridge, Eo *root, Eina_Bool coord_type, int x, int y);
187 static Eo *_calculate_neighbor(Eo *bridge, Eo *root, Eo *current, Eina_Bool forward, int search_mode);
191 const Eo_Event_Description *desc;
192 const Eo_Event_Cb callback;
193 } Elm_Atspi_Bridge_Event_Handler;
195 static const Elm_Atspi_Bridge_Event_Handler event_handlers[] = {
196 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, _children_changed_signal_send},
197 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_PROPERTY_CHANGED, _property_changed_signal_send},
198 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_BOUNDS_CHANGED, _bounds_changed_signal_send},
199 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_STATE_CHANGED, _state_changed_signal_send},
200 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_VISIBLE_DATA_CHANGED, _visible_data_changed_signal_send},
201 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_ACTIVE_DESCENDANT_CHANGED, _active_descendant_changed_signal_send},
202 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_ADDED, _on_object_add},
203 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_REMOVED, _on_object_del},
204 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_CREATED, _window_signal_send},
205 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DESTROYED, _window_signal_send},
206 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_ACTIVATED, _window_signal_send},
207 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DEACTIVATED, _window_signal_send},
208 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MAXIMIZED, _window_signal_send},
209 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MINIMIZED, _window_signal_send},
210 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_RESTORED, _window_signal_send},
211 { ELM_INTERFACE_ATSPI_SELECTION_EVENT_SELECTION_CHANGED, _selection_signal_send},
212 { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, _text_caret_moved_send },
213 { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_INSERTED, _text_text_inserted_send },
214 { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_REMOVED, _text_text_removed_send },
215 { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_SELECTION_CHANGED, _text_selection_changed_send },
216 //TIZEN_ONLY(20160623): atspi: moved highlight when object is out of screen
217 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_MOVE_OUTED, _move_outed_signal_send}
221 enum _Atspi_Object_Child_Event_Type
223 ATSPI_OBJECT_CHILD_ADDED = 0,
224 ATSPI_OBJECT_CHILD_REMOVED
227 enum _Atspi_Object_Property
229 ATSPI_OBJECT_PROPERTY_NAME = 0,
230 ATSPI_OBJECT_PROPERTY_DESCRIPTION,
231 ATSPI_OBJECT_PROPERTY_VALUE,
232 ATSPI_OBJECT_PROPERTY_ROLE,
233 ATSPI_OBJECT_PROPERTY_PARENT,
234 ATSPI_OBJECT_PROPERTY_LAST
237 enum _Atspi_Object_Signals {
238 ATSPI_OBJECT_EVENT_PROPERTY_CHANGED = 0,
239 ATSPI_OBJECT_EVENT_BOUNDS_CHANGED,
240 ATSPI_OBJECT_EVENT_LINK_SELECTED,
241 ATSPI_OBJECT_EVENT_STATE_CHANGED,
242 ATSPI_OBJECT_EVENT_CHILDREN_CHANGED,
243 ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED,
244 ATSPI_OBJECT_EVENT_SELECTION_CHANGED,
245 ATSPI_OBJECT_EVENT_MODEL_CHANGED,
246 ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED,
247 ATSPI_OBJECT_EVENT_ROW_INSERTED,
248 ATSPI_OBJECT_EVENT_ROW_REORDERED,
249 ATSPI_OBJECT_EVENT_ROW_DELETED,
250 ATSPI_OBJECT_EVENT_COLUMN_INSERTED,
251 ATSPI_OBJECT_EVENT_COLUMN_REORDERED,
252 ATSPI_OBJECT_EVENT_COLUMN_DELETED,
253 ATSPI_OBJECT_EVENT_TEXT_BOUNDS_CHANGED,
254 ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED,
255 ATSPI_OBJECT_EVENT_TEXT_CHANGED,
256 ATSPI_OBJECT_EVENT_TEXT_ATTRIBUTES_CHANGED,
257 ATSPI_OBJECT_EVENT_TEXT_CARET_MOVED,
258 ATSPI_OBJECT_EVENT_ATTRIBUTES_CHANGED,
259 //TIZEN_ONLY(20160623): atspi: moved highlight when object is out of screen
260 ATSPI_OBJECT_EVENT_MOVE_OUTED
264 enum _Atspi_Window_Signals
266 ATSPI_WINDOW_EVENT_PROPERTY_CHANGE = 0,
267 ATSPI_WINDOW_EVENT_MINIMIZE,
268 ATSPI_WINDOW_EVENT_MAXIMIZE,
269 ATSPI_WINDOW_EVENT_RESTORE,
270 ATSPI_WINDOW_EVENT_CLOSE,
271 ATSPI_WINDOW_EVENT_CREATE,
272 ATSPI_WINDOW_EVENT_REPARENT,
273 ATSPI_WINDOW_EVENT_DESKTOPCREATE,
274 ATSPI_WINDOW_EVENT_DESKTOPDESTROY,
275 ATSPI_WINDOW_EVENT_DESTROY,
276 ATSPI_WINDOW_EVENT_ACTIVATE,
277 ATSPI_WINDOW_EVENT_DEACTIVATE,
278 ATSPI_WINDOW_EVENT_RAISE,
279 ATSPI_WINDOW_EVENT_LOWER,
280 ATSPI_WINDOW_EVENT_MOVE,
281 ATSPI_WINDOW_EVENT_RESIZE,
282 ATSPI_WINDOW_EVENT_SHADE,
283 ATSPI_WINDOW_EVENT_UUSHADE,
284 ATSPI_WINDOW_EVENT_RESTYLE,
287 static const Eldbus_Signal _event_obj_signals[] = {
288 [ATSPI_OBJECT_EVENT_PROPERTY_CHANGED] = {"PropertyChange", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
289 [ATSPI_OBJECT_EVENT_BOUNDS_CHANGED] = {"BoundsChanged", ELDBUS_ARGS({"siiv(iiii)", NULL}), 0},
290 [ATSPI_OBJECT_EVENT_LINK_SELECTED] = {"LinkSelected", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
291 [ATSPI_OBJECT_EVENT_STATE_CHANGED] = {"StateChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
292 [ATSPI_OBJECT_EVENT_CHILDREN_CHANGED] = {"ChildrenChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
293 [ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED] = {"VisibleDataChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
294 [ATSPI_OBJECT_EVENT_SELECTION_CHANGED] = {"SelectionChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
295 [ATSPI_OBJECT_EVENT_MODEL_CHANGED] = {"ModelChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
296 [ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED] = {"ActiveDescendantChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
297 [ATSPI_OBJECT_EVENT_ROW_INSERTED] = {"RowInserted", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
298 [ATSPI_OBJECT_EVENT_ROW_REORDERED] = {"RowReordered", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
299 [ATSPI_OBJECT_EVENT_ROW_DELETED] = {"RowDeleted", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
300 [ATSPI_OBJECT_EVENT_COLUMN_INSERTED] = {"ColumnInserted", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
301 [ATSPI_OBJECT_EVENT_COLUMN_REORDERED] = {"ColumnReordered", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
302 [ATSPI_OBJECT_EVENT_COLUMN_DELETED] = {"ColumnDeleted", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
303 [ATSPI_OBJECT_EVENT_TEXT_BOUNDS_CHANGED] = {"TextBoundsChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
304 [ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED] = {"TextSelectionChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
305 [ATSPI_OBJECT_EVENT_TEXT_CHANGED] = {"TextChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
306 [ATSPI_OBJECT_EVENT_TEXT_ATTRIBUTES_CHANGED] = {"TextAttributesChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
307 [ATSPI_OBJECT_EVENT_TEXT_CARET_MOVED] = {"TextCaretMoved", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
308 [ATSPI_OBJECT_EVENT_ATTRIBUTES_CHANGED] = {"AttributesChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
309 //TIZEN_ONLY(20160623): atspi: moved highlight when object is out of screen
310 [ATSPI_OBJECT_EVENT_MOVE_OUTED] = {"MoveOuted", ELDBUS_ARGS({"siiv(i)", NULL}), 0},
312 {NULL, ELDBUS_ARGS({NULL, NULL}), 0}
315 static const Eldbus_Signal _window_obj_signals[] = {
316 [ATSPI_WINDOW_EVENT_PROPERTY_CHANGE] = {"PropertyChange", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
317 [ATSPI_WINDOW_EVENT_MINIMIZE] = {"Minimize", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
318 [ATSPI_WINDOW_EVENT_MAXIMIZE] = {"Maximize", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
319 [ATSPI_WINDOW_EVENT_RESTORE] = {"Restore", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
320 [ATSPI_WINDOW_EVENT_CLOSE] = {"Close", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
321 [ATSPI_WINDOW_EVENT_CREATE] = {"Create", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
322 [ATSPI_WINDOW_EVENT_REPARENT] = {"Reparent", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
323 [ATSPI_WINDOW_EVENT_DESKTOPCREATE] = {"DesktopCreate", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
324 [ATSPI_WINDOW_EVENT_DESKTOPDESTROY] = {"DesktopDestroy", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
325 [ATSPI_WINDOW_EVENT_DESTROY] = {"Destroy", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
326 [ATSPI_WINDOW_EVENT_ACTIVATE] = {"Activate", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
327 [ATSPI_WINDOW_EVENT_DEACTIVATE] = {"Deactivate", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
328 [ATSPI_WINDOW_EVENT_RAISE] = {"Raise", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
329 [ATSPI_WINDOW_EVENT_LOWER] = {"Lower", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
330 [ATSPI_WINDOW_EVENT_MOVE] = {"Move", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
331 [ATSPI_WINDOW_EVENT_RESIZE] = {"Resize", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
332 [ATSPI_WINDOW_EVENT_SHADE] = {"Shade", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
333 [ATSPI_WINDOW_EVENT_UUSHADE] = {"uUshade", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
334 [ATSPI_WINDOW_EVENT_RESTYLE] = {"Restyle", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
335 {NULL, ELDBUS_ARGS({NULL, NULL}), 0}
338 const int elm_roles_to_atspi_roles[][2] = {
339 { ELM_ATSPI_ROLE_INVALID, ATSPI_ROLE_INVALID },
340 { ELM_ATSPI_ROLE_ACCELERATOR_LABEL, ATSPI_ROLE_ACCELERATOR_LABEL },
341 { ELM_ATSPI_ROLE_ALERT, ATSPI_ROLE_ALERT },
342 { ELM_ATSPI_ROLE_ANIMATION, ATSPI_ROLE_ANIMATION },
343 { ELM_ATSPI_ROLE_ARROW, ATSPI_ROLE_ARROW },
344 { ELM_ATSPI_ROLE_CALENDAR, ATSPI_ROLE_CALENDAR },
345 { ELM_ATSPI_ROLE_CANVAS, ATSPI_ROLE_CANVAS },
346 { ELM_ATSPI_ROLE_CHECK_BOX, ATSPI_ROLE_CHECK_BOX },
347 { ELM_ATSPI_ROLE_CHECK_MENU_ITEM, ATSPI_ROLE_CHECK_MENU_ITEM },
348 { ELM_ATSPI_ROLE_COLOR_CHOOSER, ATSPI_ROLE_COLOR_CHOOSER },
349 { ELM_ATSPI_ROLE_COLUMN_HEADER, ATSPI_ROLE_COLUMN_HEADER },
350 { ELM_ATSPI_ROLE_COMBO_BOX, ATSPI_ROLE_COMBO_BOX },
351 { ELM_ATSPI_ROLE_DATE_EDITOR, ATSPI_ROLE_DATE_EDITOR },
352 { ELM_ATSPI_ROLE_DESKTOP_ICON, ATSPI_ROLE_DESKTOP_ICON },
353 { ELM_ATSPI_ROLE_DESKTOP_FRAME, ATSPI_ROLE_DESKTOP_FRAME },
354 { ELM_ATSPI_ROLE_DIAL, ATSPI_ROLE_DIAL },
355 { ELM_ATSPI_ROLE_DIALOG, ATSPI_ROLE_DIALOG },
356 { ELM_ATSPI_ROLE_DIRECTORY_PANE, ATSPI_ROLE_DIRECTORY_PANE },
357 { ELM_ATSPI_ROLE_DRAWING_AREA, ATSPI_ROLE_DRAWING_AREA },
358 { ELM_ATSPI_ROLE_FILE_CHOOSER, ATSPI_ROLE_FILE_CHOOSER },
359 { ELM_ATSPI_ROLE_FILLER, ATSPI_ROLE_FILLER },
360 { ELM_ATSPI_ROLE_FOCUS_TRAVERSABLE, ATSPI_ROLE_FOCUS_TRAVERSABLE },
361 { ELM_ATSPI_ROLE_FONT_CHOOSER, ATSPI_ROLE_FONT_CHOOSER },
362 { ELM_ATSPI_ROLE_FRAME, ATSPI_ROLE_FRAME },
363 { ELM_ATSPI_ROLE_GLASS_PANE, ATSPI_ROLE_GLASS_PANE },
364 { ELM_ATSPI_ROLE_HTML_CONTAINER, ATSPI_ROLE_HTML_CONTAINER },
365 { ELM_ATSPI_ROLE_ICON, ATSPI_ROLE_ICON },
366 { ELM_ATSPI_ROLE_IMAGE, ATSPI_ROLE_IMAGE },
367 { ELM_ATSPI_ROLE_INTERNAL_FRAME, ATSPI_ROLE_INTERNAL_FRAME },
368 { ELM_ATSPI_ROLE_LABEL, ATSPI_ROLE_LABEL },
369 { ELM_ATSPI_ROLE_LAYERED_PANE, ATSPI_ROLE_LAYERED_PANE },
370 { ELM_ATSPI_ROLE_LIST, ATSPI_ROLE_LIST },
371 { ELM_ATSPI_ROLE_LIST_ITEM, ATSPI_ROLE_LIST_ITEM },
372 { ELM_ATSPI_ROLE_MENU, ATSPI_ROLE_MENU },
373 { ELM_ATSPI_ROLE_MENU_BAR, ATSPI_ROLE_MENU_BAR },
374 { ELM_ATSPI_ROLE_MENU_ITEM, ATSPI_ROLE_MENU_ITEM },
375 { ELM_ATSPI_ROLE_OPTION_PANE, ATSPI_ROLE_OPTION_PANE },
376 { ELM_ATSPI_ROLE_PAGE_TAB, ATSPI_ROLE_PAGE_TAB },
377 { ELM_ATSPI_ROLE_PAGE_TAB_LIST, ATSPI_ROLE_PAGE_TAB_LIST },
378 { ELM_ATSPI_ROLE_PANEL, ATSPI_ROLE_PANEL },
379 { ELM_ATSPI_ROLE_PASSWORD_TEXT, ATSPI_ROLE_PASSWORD_TEXT },
380 { ELM_ATSPI_ROLE_POPUP_MENU, ATSPI_ROLE_POPUP_MENU },
381 { ELM_ATSPI_ROLE_PROGRESS_BAR, ATSPI_ROLE_PROGRESS_BAR },
382 { ELM_ATSPI_ROLE_PUSH_BUTTON, ATSPI_ROLE_PUSH_BUTTON },
383 { ELM_ATSPI_ROLE_RADIO_BUTTON, ATSPI_ROLE_RADIO_BUTTON },
384 { ELM_ATSPI_ROLE_RADIO_MENU_ITEM, ATSPI_ROLE_RADIO_MENU_ITEM },
385 { ELM_ATSPI_ROLE_ROOT_PANE, ATSPI_ROLE_ROOT_PANE },
386 { ELM_ATSPI_ROLE_ROW_HEADER, ATSPI_ROLE_ROW_HEADER },
387 { ELM_ATSPI_ROLE_SCROLL_BAR, ATSPI_ROLE_SCROLL_BAR },
388 { ELM_ATSPI_ROLE_SCROLL_PANE, ATSPI_ROLE_SCROLL_PANE },
389 { ELM_ATSPI_ROLE_SEPARATOR, ATSPI_ROLE_SEPARATOR },
390 { ELM_ATSPI_ROLE_SLIDER, ATSPI_ROLE_SLIDER },
391 { ELM_ATSPI_ROLE_SPIN_BUTTON, ATSPI_ROLE_SPIN_BUTTON },
392 { ELM_ATSPI_ROLE_SPLIT_PANE, ATSPI_ROLE_SPLIT_PANE },
393 { ELM_ATSPI_ROLE_STATUS_BAR, ATSPI_ROLE_STATUS_BAR },
394 { ELM_ATSPI_ROLE_TABLE, ATSPI_ROLE_TABLE },
395 { ELM_ATSPI_ROLE_TABLE_CELL, ATSPI_ROLE_TABLE_CELL },
396 { ELM_ATSPI_ROLE_TABLE_COLUMN_HEADER, ATSPI_ROLE_TABLE_COLUMN_HEADER },
397 { ELM_ATSPI_ROLE_TABLE_ROW_HEADER, ATSPI_ROLE_TABLE_ROW_HEADER },
398 { ELM_ATSPI_ROLE_TEAROFF_MENU_ITEM, ATSPI_ROLE_TEAROFF_MENU_ITEM },
399 { ELM_ATSPI_ROLE_TERMINAL, ATSPI_ROLE_TERMINAL },
400 { ELM_ATSPI_ROLE_TEXT, ATSPI_ROLE_TEXT },
401 { ELM_ATSPI_ROLE_TOGGLE_BUTTON, ATSPI_ROLE_TOGGLE_BUTTON },
402 { ELM_ATSPI_ROLE_TOOL_BAR, ATSPI_ROLE_TOOL_BAR },
403 { ELM_ATSPI_ROLE_TOOL_TIP, ATSPI_ROLE_TOOL_TIP },
404 { ELM_ATSPI_ROLE_TREE, ATSPI_ROLE_TREE },
405 { ELM_ATSPI_ROLE_TREE_TABLE, ATSPI_ROLE_TREE_TABLE },
406 { ELM_ATSPI_ROLE_UNKNOWN, ATSPI_ROLE_UNKNOWN },
407 { ELM_ATSPI_ROLE_VIEWPORT, ATSPI_ROLE_VIEWPORT },
408 { ELM_ATSPI_ROLE_WINDOW, ATSPI_ROLE_WINDOW },
409 { ELM_ATSPI_ROLE_EXTENDED, ATSPI_ROLE_EXTENDED },
410 { ELM_ATSPI_ROLE_HEADER, ATSPI_ROLE_HEADER },
411 { ELM_ATSPI_ROLE_FOOTER, ATSPI_ROLE_FOOTER },
412 { ELM_ATSPI_ROLE_PARAGRAPH, ATSPI_ROLE_PARAGRAPH },
413 { ELM_ATSPI_ROLE_RULER, ATSPI_ROLE_RULER },
414 { ELM_ATSPI_ROLE_APPLICATION, ATSPI_ROLE_APPLICATION },
415 { ELM_ATSPI_ROLE_AUTOCOMPLETE, ATSPI_ROLE_AUTOCOMPLETE },
416 { ELM_ATSPI_ROLE_EDITBAR, ATSPI_ROLE_EDITBAR },
417 { ELM_ATSPI_ROLE_EMBEDDED, ATSPI_ROLE_EMBEDDED },
418 { ELM_ATSPI_ROLE_ENTRY, ATSPI_ROLE_ENTRY },
419 { ELM_ATSPI_ROLE_CHART, ATSPI_ROLE_CHART },
420 { ELM_ATSPI_ROLE_CAPTION, ATSPI_ROLE_CAPTION },
421 { ELM_ATSPI_ROLE_DOCUMENT_FRAME, ATSPI_ROLE_DOCUMENT_FRAME },
422 { ELM_ATSPI_ROLE_HEADING, ATSPI_ROLE_HEADING },
423 { ELM_ATSPI_ROLE_PAGE, ATSPI_ROLE_PAGE },
424 { ELM_ATSPI_ROLE_SECTION, ATSPI_ROLE_SECTION },
425 { ELM_ATSPI_ROLE_REDUNDANT_OBJECT, ATSPI_ROLE_REDUNDANT_OBJECT },
426 { ELM_ATSPI_ROLE_FORM, ATSPI_ROLE_FORM },
427 { ELM_ATSPI_ROLE_LINK, ATSPI_ROLE_LINK },
428 { ELM_ATSPI_ROLE_INPUT_METHOD_WINDOW, ATSPI_ROLE_INPUT_METHOD_WINDOW },
429 { ELM_ATSPI_ROLE_TABLE_ROW, ATSPI_ROLE_TABLE_ROW },
430 { ELM_ATSPI_ROLE_TREE_ITEM, ATSPI_ROLE_TREE_ITEM },
431 { ELM_ATSPI_ROLE_DOCUMENT_SPREADSHEET, ATSPI_ROLE_DOCUMENT_SPREADSHEET },
432 { ELM_ATSPI_ROLE_DOCUMENT_PRESENTATION, ATSPI_ROLE_DOCUMENT_PRESENTATION },
433 { ELM_ATSPI_ROLE_DOCUMENT_TEXT, ATSPI_ROLE_DOCUMENT_TEXT },
434 { ELM_ATSPI_ROLE_DOCUMENT_WEB, ATSPI_ROLE_DOCUMENT_WEB },
435 { ELM_ATSPI_ROLE_DOCUMENT_EMAIL, ATSPI_ROLE_DOCUMENT_EMAIL },
436 { ELM_ATSPI_ROLE_COMMENT, ATSPI_ROLE_COMMENT },
437 { ELM_ATSPI_ROLE_LIST_BOX, ATSPI_ROLE_LIST_BOX },
438 { ELM_ATSPI_ROLE_GROUPING, ATSPI_ROLE_GROUPING },
439 { ELM_ATSPI_ROLE_IMAGE_MAP, ATSPI_ROLE_IMAGE_MAP },
440 { ELM_ATSPI_ROLE_NOTIFICATION, ATSPI_ROLE_NOTIFICATION },
441 { ELM_ATSPI_ROLE_INFO_BAR, ATSPI_ROLE_INFO_BAR },
442 { ELM_ATSPI_ROLE_LAST_DEFINED, ATSPI_ROLE_LAST_DEFINED },
445 struct atspi_state_desc
447 Elm_Atspi_State_Type elm_state;
448 AtspiStateType atspi_state;
452 const struct atspi_state_desc elm_states_to_atspi_state[] = {
453 { ELM_ATSPI_STATE_INVALID, ATSPI_STATE_INVALID, "invalid" },
454 { ELM_ATSPI_STATE_ACTIVE, ATSPI_STATE_ACTIVE, "active" },
455 { ELM_ATSPI_STATE_ARMED, ATSPI_STATE_ARMED, "armed" },
456 { ELM_ATSPI_STATE_BUSY, ATSPI_STATE_BUSY, "busy" },
457 { ELM_ATSPI_STATE_CHECKED, ATSPI_STATE_CHECKED, "checked" },
458 { ELM_ATSPI_STATE_COLLAPSED, ATSPI_STATE_COLLAPSED, "collapsed" },
459 { ELM_ATSPI_STATE_DEFUNCT, ATSPI_STATE_DEFUNCT, "defunct" },
460 { ELM_ATSPI_STATE_EDITABLE, ATSPI_STATE_EDITABLE, "editable" },
461 { ELM_ATSPI_STATE_ENABLED, ATSPI_STATE_ENABLED, "enabled" },
462 { ELM_ATSPI_STATE_EXPANDABLE, ATSPI_STATE_EXPANDABLE, "expandable" },
463 { ELM_ATSPI_STATE_EXPANDED, ATSPI_STATE_EXPANDED, "expanded" },
464 { ELM_ATSPI_STATE_FOCUSABLE, ATSPI_STATE_FOCUSABLE, "focusable" },
465 { ELM_ATSPI_STATE_FOCUSED, ATSPI_STATE_FOCUSED, "focused" },
466 { ELM_ATSPI_STATE_HAS_TOOLTIP, ATSPI_STATE_HAS_TOOLTIP, "has-tooltip" },
467 { ELM_ATSPI_STATE_HORIZONTAL, ATSPI_STATE_HORIZONTAL, "horizontal" },
468 { ELM_ATSPI_STATE_ICONIFIED, ATSPI_STATE_ICONIFIED, "iconified" },
469 { ELM_ATSPI_STATE_MODAL, ATSPI_STATE_MODAL, "modal" },
470 { ELM_ATSPI_STATE_MULTI_LINE, ATSPI_STATE_MULTI_LINE, "multi-line" },
471 { ELM_ATSPI_STATE_MULTISELECTABLE, ATSPI_STATE_MULTISELECTABLE, "multiselectable" },
472 { ELM_ATSPI_STATE_OPAQUE, ATSPI_STATE_OPAQUE, "opaque" },
473 { ELM_ATSPI_STATE_PRESSED, ATSPI_STATE_PRESSED, "pressed" },
474 { ELM_ATSPI_STATE_RESIZABLE, ATSPI_STATE_RESIZABLE, "resizable" },
475 { ELM_ATSPI_STATE_SELECTABLE, ATSPI_STATE_SELECTABLE, "selectable" },
476 { ELM_ATSPI_STATE_SELECTED, ATSPI_STATE_SELECTED, "selected" },
477 { ELM_ATSPI_STATE_SENSITIVE, ATSPI_STATE_SENSITIVE, "sensitive" },
478 { ELM_ATSPI_STATE_SHOWING, ATSPI_STATE_SHOWING, "showing" },
479 { ELM_ATSPI_STATE_SINGLE_LINE, ATSPI_STATE_SINGLE_LINE, "single-line" },
480 { ELM_ATSPI_STATE_STALE, ATSPI_STATE_STALE, "stale" },
481 { ELM_ATSPI_STATE_TRANSIENT, ATSPI_STATE_TRANSIENT, "transient" },
482 { ELM_ATSPI_STATE_VERTICAL, ATSPI_STATE_VERTICAL, "vertical" },
483 { ELM_ATSPI_STATE_VISIBLE, ATSPI_STATE_VISIBLE, "visible" },
484 { ELM_ATSPI_STATE_MANAGES_DESCENDANTS, ATSPI_STATE_MANAGES_DESCENDANTS, "manages-descendants" },
485 { ELM_ATSPI_STATE_INDETERMINATE, ATSPI_STATE_INDETERMINATE, "indeterminate" },
486 { ELM_ATSPI_STATE_REQUIRED, ATSPI_STATE_REQUIRED, "required" },
487 { ELM_ATSPI_STATE_TRUNCATED, ATSPI_STATE_TRUNCATED, "truncated" },
488 { ELM_ATSPI_STATE_ANIMATED, ATSPI_STATE_ANIMATED, "animated" },
489 { ELM_ATSPI_STATE_INVALID_ENTRY, ATSPI_STATE_INVALID_ENTRY, "invalid-entry" },
490 { ELM_ATSPI_STATE_SUPPORTS_AUTOCOMPLETION, ATSPI_STATE_SUPPORTS_AUTOCOMPLETION, "supports-autocompletion" },
491 { ELM_ATSPI_STATE_SELECTABLE_TEXT, ATSPI_STATE_SELECTABLE_TEXT, "selectable-text" },
492 { ELM_ATSPI_STATE_IS_DEFAULT, ATSPI_STATE_IS_DEFAULT, "is-default" },
493 { ELM_ATSPI_STATE_VISITED, ATSPI_STATE_VISITED, "visited" },
494 //TIZEN_ONLY(20160329): atspi: implement HighlightGrab and HighlightClear methods (29e253e2f7ef3c632ac3a64c489bf569df407f30)
495 { ELM_ATSPI_STATE_CHECKABLE, ATSPI_STATE_CHECKABLE, "checkable" },
496 { ELM_ATSPI_STATE_HAS_POPUP, ATSPI_STATE_HAS_POPUP, "has-popup" },
497 { ELM_ATSPI_STATE_READ_ONLY, ATSPI_STATE_READ_ONLY, "read-only" },
498 { ELM_ATSPI_STATE_HIGHLIGHTED, ATSPI_STATE_HIGHLIGHTED, "highlighted" },
499 { ELM_ATSPI_STATE_HIGHLIGHTABLE, ATSPI_STATE_HIGHLIGHTABLE, "highlightable" },
501 { ELM_ATSPI_STATE_LAST_DEFINED, ATSPI_STATE_LAST_DEFINED, "last-defined" }
504 const int elm_relation_to_atspi_relation_mapping[] = {
505 [ELM_ATSPI_RELATION_NULL] = ATSPI_RELATION_NULL,
506 [ELM_ATSPI_RELATION_LABEL_FOR] = ATSPI_RELATION_LABEL_FOR,
507 [ELM_ATSPI_RELATION_LABELLED_BY] = ATSPI_RELATION_LABELLED_BY,
508 [ELM_ATSPI_RELATION_CONTROLLER_FOR] = ATSPI_RELATION_CONTROLLER_FOR,
509 [ELM_ATSPI_RELATION_CONTROLLED_BY] = ATSPI_RELATION_CONTROLLED_BY,
510 [ELM_ATSPI_RELATION_MEMBER_OF] = ATSPI_RELATION_MEMBER_OF,
511 [ELM_ATSPI_RELATION_TOOLTIP_FOR] = ATSPI_RELATION_TOOLTIP_FOR,
512 [ELM_ATSPI_RELATION_NODE_CHILD_OF] = ATSPI_RELATION_NODE_CHILD_OF,
513 [ELM_ATSPI_RELATION_NODE_PARENT_OF] = ATSPI_RELATION_NODE_PARENT_OF,
514 [ELM_ATSPI_RELATION_EXTENDED] = ATSPI_RELATION_EXTENDED,
515 [ELM_ATSPI_RELATION_FLOWS_TO] = ATSPI_RELATION_FLOWS_TO,
516 [ELM_ATSPI_RELATION_FLOWS_FROM] = ATSPI_RELATION_FLOWS_FROM,
517 [ELM_ATSPI_RELATION_SUBWINDOW_OF] = ATSPI_RELATION_SUBWINDOW_OF,
518 [ELM_ATSPI_RELATION_EMBEDS] = ATSPI_RELATION_EMBEDS,
519 [ELM_ATSPI_RELATION_EMBEDDED_BY] = ATSPI_RELATION_EMBEDDED_BY,
520 [ELM_ATSPI_RELATION_POPUP_FOR] = ATSPI_RELATION_POPUP_FOR,
521 [ELM_ATSPI_RELATION_PARENT_WINDOW_OF] = ATSPI_RELATION_PARENT_WINDOW_OF,
522 [ELM_ATSPI_RELATION_DESCRIPTION_FOR] = ATSPI_RELATION_DESCRIPTION_FOR,
523 [ELM_ATSPI_RELATION_DESCRIBED_BY] = ATSPI_RELATION_DESCRIBED_BY,
524 [ELM_ATSPI_RELATION_LAST_DEFINED] = ATSPI_RELATION_LAST_DEFINED,
527 static inline Eldbus_Message *_dbus_invalid_ref_error_new(const Eldbus_Message *msg)
529 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.UnknownObject", "Path is not valid accessible object reference.");
532 static AtspiRelationType _elm_relation_to_atspi_relation(Elm_Atspi_Relation_Type type)
534 if ((type < ELM_ATSPI_RELATION_LAST_DEFINED) && (type > ELM_ATSPI_RELATION_NULL))
535 return elm_relation_to_atspi_relation_mapping[type];
536 return ATSPI_RELATION_NULL;
539 static Elm_Atspi_Relation_Type _atspi_relation_to_elm_relation(AtspiRelationType type)
542 for(i = 0; i < sizeof(elm_relation_to_atspi_relation_mapping) / sizeof(elm_relation_to_atspi_relation_mapping[0]); ++i)
544 if (elm_relation_to_atspi_relation_mapping[i] == (int)type) return (Elm_Atspi_Relation_Type)i;
546 return ELM_ATSPI_RELATION_NULL;
549 static AtspiRole _elm_role_to_atspi_role(Elm_Atspi_Role role)
551 return role > ELM_ATSPI_ROLE_LAST_DEFINED ? ATSPI_ROLE_LAST_DEFINED : elm_roles_to_atspi_roles[role][1];
554 static Eldbus_Message *
555 _accessible_get_role(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
557 const char *obj_path = eldbus_message_path_get(msg);
558 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
559 Eo *obj = _bridge_object_from_path(bridge, obj_path);
562 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
564 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
566 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
567 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
569 AtspiRole atspi_role = _elm_role_to_atspi_role(role);
570 eldbus_message_arguments_append(ret, "u", atspi_role);
574 static Eldbus_Message *
575 _accessible_get_role_name(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
577 const char *role_name = NULL, *obj_path = eldbus_message_path_get(msg);
578 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
579 Eo *obj = _bridge_object_from_path(bridge, obj_path);
581 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
583 eo_do(obj, role_name = elm_interface_atspi_accessible_role_name_get());
585 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
586 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
587 eldbus_message_arguments_append(ret, "s", role_name);
592 static Eldbus_Message *
593 _accessible_get_localized_role_name(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
595 const char *l_role_name = NULL, *obj_path = eldbus_message_path_get(msg);
596 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
597 Eo *obj = _bridge_object_from_path(bridge, obj_path);
599 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
601 eo_do(obj, l_role_name = elm_interface_atspi_accessible_localized_role_name_get());
602 EINA_SAFETY_ON_NULL_RETURN_VAL(l_role_name, NULL);
604 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
605 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
606 eldbus_message_arguments_append(ret, "s", l_role_name);
611 static Eldbus_Message *
612 _accessible_get_children(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
614 const char *obj_path = eldbus_message_path_get(msg);
615 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
616 Eo *obj = _bridge_object_from_path(bridge, obj_path);
617 Eina_List *children_list = NULL, *l;
619 Eldbus_Message_Iter *iter, *iter_array;
622 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
624 eo_do(obj, children_list = elm_interface_atspi_accessible_children_get());
626 ret = eldbus_message_method_return_new(msg);
627 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
629 iter = eldbus_message_iter_get(ret);
630 iter_array = eldbus_message_iter_container_new(iter, 'a', "(so)");
631 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
633 EINA_LIST_FOREACH(children_list, l, children)
635 _bridge_iter_object_reference_append(bridge, iter_array, children);
636 _bridge_object_register(bridge, children);
639 eldbus_message_iter_container_close(iter, iter_array);
640 eina_list_free(children_list);
645 if (ret) eldbus_message_unref(ret);
649 static Eldbus_Message *
650 _accessible_get_application(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
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);
657 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
659 ret = eldbus_message_method_return_new(msg);
660 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
662 Eldbus_Message_Iter *iter = eldbus_message_iter_get(ret);
663 _bridge_iter_object_reference_append(bridge, iter, elm_atspi_bridge_root_get(bridge));
668 static Eldbus_Message *
669 _accessible_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
671 Eina_List *attrs, *l;
672 Elm_Atspi_Attribute *attr;
673 Eldbus_Message_Iter *iter, *iter_dict, *iter_entry;
676 const char *obj_path = eldbus_message_path_get(msg);
677 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
678 Eo *obj = _bridge_object_from_path(bridge, obj_path);
680 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
682 ret = eldbus_message_method_return_new(msg);
683 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
685 eo_do(obj, attrs = elm_interface_atspi_accessible_attributes_get());
687 iter = eldbus_message_iter_get(ret);
688 iter_dict = eldbus_message_iter_container_new(iter, 'a', "{ss}");
689 EINA_SAFETY_ON_NULL_RETURN_VAL(iter_dict, NULL);
691 EINA_LIST_FOREACH(attrs, l, attr)
693 iter_entry = eldbus_message_iter_container_new(iter_dict, 'e', NULL);
694 EINA_SAFETY_ON_NULL_RETURN_VAL(iter_entry, NULL);
695 eldbus_message_iter_arguments_append(iter_entry, "ss", attr->key, attr->value);
696 eldbus_message_iter_container_close(iter_dict, iter_entry);
699 eldbus_message_iter_container_close(iter, iter_dict);
700 elm_atspi_attributes_list_free(attrs);
705 static Eldbus_Message *
706 _accessible_interfaces_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
709 Eldbus_Message_Iter *iter;
710 const char *obj_path = eldbus_message_path_get(msg);
711 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
712 Eo *obj = _bridge_object_from_path(bridge, obj_path);
714 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
716 ret = eldbus_message_method_return_new(msg);
717 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
719 iter = eldbus_message_iter_get(ret);
720 _iter_interfaces_append(iter, obj);
726 _elm_atspi_state_set_to_atspi_state_set(Elm_Atspi_State_Set states)
731 for (i = 0; i < SIZE(elm_states_to_atspi_state); i++)
733 if (STATE_TYPE_GET(states, elm_states_to_atspi_state[i].elm_state))
734 STATE_TYPE_SET(ret, elm_states_to_atspi_state[i].atspi_state);
739 static Elm_Atspi_State_Set
740 _atspi_state_set_to_elm_atspi_state_set(uint64_t states)
742 //Currently Elm_Atspi_State and Atspi_State_Set are binary compatible,
743 //implement proper coversion when it will be needed.
744 Elm_Atspi_State_Set ret = states;
749 _elm_atspi_state_hash_build(void)
751 Eina_Hash *ret = eina_hash_string_superfast_new(NULL);
754 for (i = 0; i < SIZE(elm_states_to_atspi_state); i++)
755 eina_hash_add(ret, elm_states_to_atspi_state[i].name, &elm_states_to_atspi_state[i]);
761 _elm_atspi_event_hash_build(void)
763 Eina_Hash *ret = eina_hash_pointer_new(NULL);
766 for (i = 0; i < SIZE(event_handlers); i++)
767 eina_hash_add(ret, &(event_handlers[i].desc), event_handlers[i].callback);
772 static Eldbus_Message *
773 _accessible_get_state(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
776 Eldbus_Message_Iter *iter, *iter_array;
777 Elm_Atspi_State_Set states;
778 uint64_t atspi_states = 0;
780 const char *obj_path = eldbus_message_path_get(msg);
781 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
782 Eo *obj = _bridge_object_from_path(bridge, obj_path);
784 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
786 ret = eldbus_message_method_return_new(msg);
787 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
789 iter = eldbus_message_iter_get(ret);
790 iter_array = eldbus_message_iter_container_new(iter, 'a', "u");
791 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
793 eo_do(obj, states = elm_interface_atspi_accessible_state_set_get());
795 atspi_states = _elm_atspi_state_set_to_atspi_state_set(states);
797 unsigned int s1 = atspi_states & 0xFFFFFFFF;
798 unsigned int s2 = (atspi_states >> 32) & 0xFFFFFFFF;
800 eldbus_message_iter_basic_append(iter_array, 'u', s1);
801 eldbus_message_iter_basic_append(iter_array, 'u', s2);
802 eldbus_message_iter_container_close(iter, iter_array);
807 if (ret) eldbus_message_unref(ret);
811 static Eldbus_Message *
812 _accessible_get_index_in_parent(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
814 const char *obj_path = eldbus_message_path_get(msg);
815 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
816 Eo *obj = _bridge_object_from_path(bridge, obj_path);
820 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
822 ret = eldbus_message_method_return_new(msg);
823 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
825 eo_do(obj, idx = elm_interface_atspi_accessible_index_in_parent_get());
827 eldbus_message_arguments_append(ret, "i", idx);
832 static Eldbus_Message *
833 _accessible_child_at_index(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
835 const char *obj_path = eldbus_message_path_get(msg);
836 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
837 Eo *obj = _bridge_object_from_path(bridge, obj_path);
839 Eina_List *children = NULL;
842 Eldbus_Message_Iter *iter;
844 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
846 if (!eldbus_message_arguments_get(msg, "i", &idx))
847 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
849 ret = eldbus_message_method_return_new(msg);
850 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
852 iter = eldbus_message_iter_get(ret);
853 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
855 child = eina_list_nth(children, idx);
856 _bridge_iter_object_reference_append(bridge, iter, child);
857 _bridge_object_register(bridge, child);
858 eina_list_free(children);
863 static Eldbus_Message *
864 _accessible_get_relation_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
866 const char *obj_path = eldbus_message_path_get(msg);
867 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
868 Eo *rel_obj, *obj = _bridge_object_from_path(bridge, obj_path);
869 Eldbus_Message *ret = NULL;
870 Eldbus_Message_Iter *iter = NULL, *iter_array = NULL, *iter_array2 = NULL, *iter_struct;
871 Elm_Atspi_Relation *rel;
873 Elm_Atspi_Relation_Set rels;
875 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
877 ret = eldbus_message_method_return_new(msg);
878 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
880 iter = eldbus_message_iter_get(ret);
881 iter_array = eldbus_message_iter_container_new(iter, 'a', "(ua(so))");
882 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
884 eo_do(obj, rels = elm_interface_atspi_accessible_relation_set_get());
886 EINA_LIST_FOREACH(rels, l, rel)
888 iter_struct = eldbus_message_iter_container_new(iter_array, 'r', NULL);
889 eldbus_message_iter_basic_append(iter_struct, 'u', _elm_relation_to_atspi_relation(rel->type));
890 iter_array2 = eldbus_message_iter_container_new(iter_struct, 'a', "(so)");
891 EINA_SAFETY_ON_NULL_GOTO(iter_array2, fail);
892 EINA_LIST_FOREACH(rel->objects, l2, rel_obj)
894 _bridge_iter_object_reference_append(bridge, iter_array2, rel_obj);
895 _bridge_object_register(bridge, rel_obj);
897 eldbus_message_iter_container_close(iter_struct, iter_array2);
898 eldbus_message_iter_container_close(iter_array, iter_struct);
900 elm_atspi_relation_set_free(&rels);
901 eldbus_message_iter_container_close(iter, iter_array);
906 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to get relation set.");
909 //TIZEN_ONLY(20170405) Add gesture method to accessible interface
910 static Eldbus_Message *
911 _accessible_gesture_do(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
913 const char *obj_path = eldbus_message_path_get(msg);
914 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
915 Eo *obj = _bridge_object_from_path(bridge, obj_path);
916 int type, x_beg, y_beg, x_end, y_end, state;
917 unsigned int event_time;
919 Eina_Bool result = EINA_FALSE;
921 if (!eldbus_message_arguments_get(msg, "iiiiiiu", &type, &x_beg, &y_beg,
922 &x_end, &y_end, &state, &event_time))
923 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
925 ret = eldbus_message_method_return_new(msg);
926 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
928 Elm_Atspi_Gesture_Info gesture_info;
929 gesture_info.type = (Elm_Atspi_Gesture_Type)type;
930 gesture_info.x_beg = x_beg;
931 gesture_info.y_beg = y_beg;
932 gesture_info.x_end = x_end;
933 gesture_info.y_end = y_end;
934 gesture_info.state = (Elm_Atspi_Gesture_State)state;
935 gesture_info.event_time = event_time;
936 eo_do(obj, result = elm_interface_atspi_accessible_gesture_do(gesture_info));
937 eldbus_message_arguments_append(ret, "b", result);
942 // TIZEN_ONLY(20170310) - implementation of get object under coordinates for accessibility
943 static Eldbus_Message *
944 _accessible_get_neighbor(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
946 const char *start_path = eldbus_message_path_get(msg);
947 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
948 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
949 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, NULL);
951 Eo *start = _bridge_object_from_path(bridge, start_path);
953 Eldbus_Message_Iter *iter;
954 int direction, search_mode;
956 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(start, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
958 char *root_path = "";
959 if (!eldbus_message_arguments_get(msg, "sii", &root_path, &direction, &search_mode))
960 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
962 Eo *root = _bridge_object_from_path(bridge, root_path);
964 // TIZEN_ONLY(20161213) - do not response if ecore evas is obscured
967 const Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(root));
968 if (ecore_evas_obscured_get(ee))
969 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "ecore evas is obscured.");
973 ret = eldbus_message_method_return_new(msg);
974 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
976 iter = eldbus_message_iter_get(ret);
978 Eo *accessible = _calculate_neighbor(bridge, root, start, direction == 1, search_mode);
979 _bridge_iter_object_reference_append(bridge, iter, accessible);
980 _bridge_object_register(bridge, accessible);
982 const char *obj_bus_name = NULL, *ret_bus_name = NULL;
983 _object_get_bus_name_and_path(bridge, start, &obj_bus_name, NULL);
984 if (accessible) _object_get_bus_name_and_path(bridge, accessible, &ret_bus_name, NULL);
986 unsigned char recurse = obj_bus_name && ret_bus_name && strcmp(obj_bus_name, ret_bus_name) != 0;
987 eldbus_message_iter_basic_append(iter, 'y', recurse);
991 static Eldbus_Message *
992 _accessible_get_navigable_at_point(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
994 const char *obj_path = eldbus_message_path_get(msg);
995 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
996 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
997 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, NULL);
999 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1001 Eldbus_Message *ret;
1002 AtspiCoordType coord_type;
1003 Eldbus_Message_Iter *iter;
1005 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
1007 // TIZEN_ONLY(20161213) - do not response if ecore evas is obscured
1008 const Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
1009 if (ecore_evas_obscured_get(ee))
1010 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "ecore evas is obscured.");
1013 if (!eldbus_message_arguments_get(msg, "iiu", &x, &y, &coord_type))
1014 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1016 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
1017 Evas_Object *top = elm_object_top_widget_get(obj);
1020 eo_do(top, elm_interface_atspi_component_socket_offset_get(&sx, &sy));
1025 ret = eldbus_message_method_return_new(msg);
1026 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1028 iter = eldbus_message_iter_get(ret);
1030 Eina_Bool type = coord_type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
1031 Eo *accessible = _calculate_navigable_accessible_at_point(bridge, obj, type, x, y);
1035 if (accessible && eo_isa(accessible, ELM_ACCESS_CLASS))
1037 Evas_Object *parent = elm_widget_parent_get(accessible);
1039 Elm_Widget_Smart_Data *wd;
1040 wd = eo_data_scope_get(parent, ELM_WIDGET_CLASS);
1044 Evas_Object *widget;
1046 EINA_LIST_FOREACH(wd->subobjs, l, widget)
1050 proxy = evas_object_data_get(widget, "__widget_proxy");
1054 evas_object_geometry_get(widget, &px, &py, &pw, &ph);
1055 if (x >= px && x <= px + pw && y >= py && y <= py +ph)
1057 /* proxy is also selectable */
1058 deputy = accessible;
1067 _bridge_iter_object_reference_append(bridge, iter, accessible);
1068 _bridge_object_register(bridge, accessible);
1070 const char *obj_bus_name = NULL, *ret_bus_name = NULL;
1071 _object_get_bus_name_and_path(bridge, obj, &obj_bus_name, NULL);
1072 if (accessible) _object_get_bus_name_and_path(bridge, accessible, &ret_bus_name, NULL);
1073 unsigned char recurse = obj_bus_name && ret_bus_name && strcmp(obj_bus_name, ret_bus_name) != 0;
1074 eldbus_message_iter_basic_append(iter, 'y', recurse);
1077 _bridge_iter_object_reference_append(bridge, iter, deputy);
1078 if (deputy) _bridge_object_register(bridge, deputy);
1084 //TIZEN_ONLY(20170531): add "GetReadingMaterial" interface method
1086 _list_children_count_check(Eo *obj)
1090 Eina_List *children;
1092 Elm_Atspi_Role role;
1097 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
1098 if (role == ELM_ATSPI_ROLE_LIST)
1100 int children_count = 0;
1101 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
1102 children_count = eina_list_count(children);
1104 for (i = 0; i < children_count; i++)
1106 child = eina_list_nth(children, i);
1107 eo_do(child, role = elm_interface_atspi_accessible_role_get());
1108 if (role == ELM_ATSPI_ROLE_LIST_ITEM)
1111 eina_list_free(children);
1118 _list_children_count(Eo *obj)
1120 Eina_List *children;
1121 int list_items_count = 0;
1122 int children_count = 0;
1124 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
1125 children_count = eina_list_count(children);
1130 list_items_count = _list_children_count_check(obj);
1131 if (list_items_count > 0)
1133 eina_list_free(children);
1134 return list_items_count;
1137 for (i = 0; i < children_count; i++)
1139 child = eina_list_nth(children, i);
1140 list_items_count = _list_children_count(child);
1141 if (list_items_count > 0)
1143 eina_list_free(children);
1144 return list_items_count;
1151 static Eldbus_Message *
1152 _accessible_reading_material_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1154 Eldbus_Message *ret;
1155 Eldbus_Message_Iter *iter, *iter_array, *iter_dict, *iter_entry;
1156 Eina_List *attrs, *l, *children;
1157 const char *name = NULL;
1158 unsigned int s1, s2;
1160 double increment = 0;
1161 double max_value = 0;
1162 double min_value = 0;
1164 int child_count = 0;
1165 int selected_child_count = 0;
1166 uint64_t atspi_states = 0;
1167 Elm_Atspi_Role role;
1168 Elm_Atspi_Attribute *attr;
1169 Elm_Atspi_State_Set states;
1170 Elm_Atspi_Relation_Set rels = NULL;
1171 Elm_Atspi_Relation *rel;
1172 Eo *relation_obj = NULL;
1175 Eina_Bool is_selected = EINA_FALSE;
1176 AtspiRole atspi_role = ATSPI_ROLE_INVALID;
1178 const char *obj_path = eldbus_message_path_get(msg);
1179 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1180 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1182 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
1184 ret = eldbus_message_method_return_new(msg);
1185 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1187 iter = eldbus_message_iter_get(ret);
1189 eo_do(obj, attrs = elm_interface_atspi_accessible_attributes_get());
1190 iter_dict = eldbus_message_iter_container_new(iter, 'a', "{ss}");
1191 EINA_SAFETY_ON_NULL_RETURN_VAL(iter_dict, NULL);
1192 EINA_LIST_FOREACH(attrs, l, attr)
1194 iter_entry = eldbus_message_iter_container_new(iter_dict, 'e', NULL);
1195 EINA_SAFETY_ON_NULL_RETURN_VAL(iter_entry, NULL);
1196 eldbus_message_iter_arguments_append(iter_entry, "ss", attr->key, attr->value);
1197 eldbus_message_iter_container_close(iter_dict, iter_entry);
1200 eldbus_message_iter_container_close(iter, iter_dict);
1201 elm_atspi_attributes_list_free(attrs);
1204 eo_do(obj, name = elm_interface_atspi_accessible_name_get());
1207 eldbus_message_iter_basic_append(iter, 's', name);
1209 /* name - LABELED_BY relation */
1210 eo_do(obj, rels = elm_interface_atspi_accessible_relation_set_get());
1211 EINA_LIST_FOREACH(rels, l, rel)
1213 if (rel->type == ELM_ATSPI_RELATION_LABELLED_BY)
1215 int last_index = eina_list_count(rel->objects) - 1;
1216 relation_obj = eina_list_nth(rel->objects, last_index);
1220 eo_do(relation_obj, name = elm_interface_atspi_accessible_name_get());
1223 eldbus_message_iter_basic_append(iter, 's', name);
1225 /* name - text interface */
1227 if (eo_isa(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE))
1230 eo_do(obj, val = elm_interface_atspi_text_character_count_get());
1231 eo_do(obj, name = elm_interface_atspi_text_get(0, val));
1235 eldbus_message_iter_basic_append(iter, 's', name);
1238 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
1239 atspi_role = role > ELM_ATSPI_ROLE_LAST_DEFINED ? ATSPI_ROLE_LAST_DEFINED : elm_roles_to_atspi_roles[role][1];
1240 eldbus_message_iter_basic_append(iter, 'u', atspi_role);
1243 iter_array = eldbus_message_iter_container_new(iter, 'a', "u");
1244 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
1245 eo_do(obj, states = elm_interface_atspi_accessible_state_set_get());
1246 atspi_states = _elm_atspi_state_set_to_atspi_state_set(states);
1247 s1 = atspi_states & 0xFFFFFFFF;
1248 s2 = (atspi_states >> 32) & 0xFFFFFFFF;
1249 eldbus_message_iter_basic_append(iter_array, 'u', s1);
1250 eldbus_message_iter_basic_append(iter_array, 'u', s2);
1251 eldbus_message_iter_container_close(iter, iter_array);
1253 /* localized role name */
1254 eo_do(obj, name = elm_interface_atspi_accessible_localized_role_name_get());
1257 eldbus_message_iter_basic_append(iter, 's', name);
1260 eo_do(obj, l = elm_interface_atspi_accessible_children_get());
1261 eldbus_message_iter_basic_append(iter, 'i', eina_list_count(l));
1264 /* current value, increment, max, min */
1269 if (eo_isa(obj, ELM_INTERFACE_ATSPI_VALUE_INTERFACE))
1271 eo_do(obj, elm_interface_atspi_value_and_text_get(&value, NULL));
1272 eo_do(obj, increment = elm_interface_atspi_value_increment_get());
1273 eo_do(obj, elm_interface_atspi_value_range_get(&min_value, &max_value, NULL));
1275 eldbus_message_iter_basic_append(iter, 'd', value);
1276 eldbus_message_iter_basic_append(iter, 'd', increment);
1277 eldbus_message_iter_basic_append(iter, 'd', max_value);
1278 eldbus_message_iter_basic_append(iter, 'd', min_value);
1281 eo_do(obj, name = elm_interface_atspi_accessible_description_get());
1284 eldbus_message_iter_basic_append(iter, 's', name);
1286 /* index in parent */
1287 eo_do(obj, idx = elm_interface_atspi_accessible_index_in_parent_get());
1288 eldbus_message_iter_basic_append(iter, 'i', idx);
1290 /* is selected in parent */
1291 eo_do(obj, parent = elm_interface_atspi_accessible_parent_get());
1292 if (eo_isa(parent, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE))
1294 eo_do(parent, is_selected = elm_interface_atspi_selection_is_child_selected(idx));
1296 eldbus_message_arguments_append(ret, "b", is_selected);
1298 /* has checkbox child */
1299 is_selected = EINA_FALSE;
1300 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
1301 EINA_LIST_FOREACH(children, l, child)
1303 if (eo_isa(child, ELM_CHECK_CLASS))
1305 is_selected = EINA_TRUE;
1309 eldbus_message_iter_basic_append(iter, 'b', is_selected);
1310 eina_list_free(children);
1312 /* list children count */
1314 if (role == ELM_ATSPI_ROLE_DIALOG)
1316 child_count = _list_children_count(obj);
1318 eldbus_message_iter_basic_append(iter, 'i', child_count);
1320 /* first selected child index */
1322 if (eo_isa(obj, ELM_INDEX_CLASS))
1324 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
1325 EINA_LIST_FOREACH(children, l, child)
1327 eo_do(child, states = elm_interface_atspi_accessible_state_set_get());
1328 if (STATE_TYPE_GET(states, ELM_ATSPI_STATE_SELECTED))
1332 eina_list_free(children);
1334 eldbus_message_iter_basic_append(iter, 'i', idx);
1337 role = ELM_ATSPI_ROLE_INVALID;
1338 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
1339 if ((!parent) && (ELM_ATSPI_ROLE_APPLICATION == role))
1340 _object_desktop_reference_append(iter);
1342 _bridge_iter_object_reference_append(bridge, iter, parent);
1344 /* parent - states */
1345 iter_array = eldbus_message_iter_container_new(iter, 'a', "u");
1346 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
1347 eo_do(parent, states = elm_interface_atspi_accessible_state_set_get());
1348 atspi_states = _elm_atspi_state_set_to_atspi_state_set(states);
1349 s1 = atspi_states & 0xFFFFFFFF;
1350 s2 = (atspi_states >> 32) & 0xFFFFFFFF;
1351 eldbus_message_iter_basic_append(iter_array, 'u', s1);
1352 eldbus_message_iter_basic_append(iter_array, 'u', s2);
1353 eldbus_message_iter_container_close(iter, iter_array);
1355 /* parent - child count */
1356 eo_do(parent, l = elm_interface_atspi_accessible_children_get());
1357 eldbus_message_iter_basic_append(iter, 'i', eina_list_count(l));
1361 eo_do(parent, role = elm_interface_atspi_accessible_role_get());
1362 atspi_role = role > ELM_ATSPI_ROLE_LAST_DEFINED ? ATSPI_ROLE_LAST_DEFINED : elm_roles_to_atspi_roles[role][1];
1363 eldbus_message_iter_basic_append(iter, 'u', atspi_role);
1365 /* parent - child count */
1366 if (eo_isa(parent, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE))
1368 eo_do(parent, selected_child_count = elm_interface_atspi_selection_selected_children_count_get());
1370 eldbus_message_iter_basic_append(iter, 'i', selected_child_count);
1372 /* relation object - DESCRIBED_BY */
1373 relation_obj = NULL;
1374 EINA_LIST_FOREACH(rels, l, rel)
1376 if (rel->type == ELM_ATSPI_RELATION_DESCRIBED_BY)
1378 int last_index = eina_list_count(rel->objects) - 1;
1379 relation_obj = eina_list_nth(rel->objects, last_index);
1383 _bridge_iter_object_reference_append(bridge, iter, relation_obj);
1384 elm_atspi_relation_set_free(&rels);
1389 if (rels) elm_atspi_relation_set_free(&rels);
1390 if (ret) eldbus_message_unref(ret);
1394 //TIZEN_ONLY(20170919): Handle default label object
1395 static Eldbus_Message *
1396 _accessible_default_label_info_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1398 Eldbus_Message *ret;
1399 Eldbus_Message_Iter *iter;
1400 const char *obj_path = eldbus_message_path_get(msg);
1401 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1402 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1403 Eo *default_label_obj;
1404 Elm_Atspi_Role role;
1405 AtspiRole atspi_role = ATSPI_ROLE_INVALID;
1407 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
1409 ret = eldbus_message_method_return_new(msg);
1410 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1412 iter = eldbus_message_iter_get(ret);
1414 default_label_obj = _elm_win_default_label_obj_get(obj);
1415 if (!default_label_obj) default_label_obj = obj;
1416 _bridge_iter_object_reference_append(bridge, iter, default_label_obj);
1417 _bridge_object_register(bridge, default_label_obj);
1419 eo_do(default_label_obj, role = elm_interface_atspi_accessible_role_get());
1420 atspi_role = role > ELM_ATSPI_ROLE_LAST_DEFINED ? ATSPI_ROLE_LAST_DEFINED : elm_roles_to_atspi_roles[role][1];
1421 eldbus_message_iter_basic_append(iter, 'u', atspi_role);
1427 static const Eldbus_Method accessible_methods[] = {
1428 // TIZEN_ONLY(20170310) - implementation of get object under coordinates for accessibility
1429 { "GetNavigableAtPoint", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"u", "coord_type"}), ELDBUS_ARGS({"(so)y", "accessible"}, {"(so)", "deputy"}), _accessible_get_navigable_at_point, 0 },
1430 { "GetNeighbor", ELDBUS_ARGS({"s", "current"}, {"i", "direction"}, {"i", "force_next"}), ELDBUS_ARGS({"(so)y", "accessible"}), _accessible_get_neighbor, 0 },
1432 { "GetChildAtIndex", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"(so)", "Accessible"}), _accessible_child_at_index, 0 },
1433 { "GetChildren", NULL, ELDBUS_ARGS({"a(so)", "children"}), _accessible_get_children, 0 },
1434 { "GetIndexInParent", NULL, ELDBUS_ARGS({"i", "index"}), _accessible_get_index_in_parent, 0 },
1435 { "GetRelationSet", NULL, ELDBUS_ARGS({"a(ua(so))", NULL}), _accessible_get_relation_set, 0 },
1436 { "GetRole", NULL, ELDBUS_ARGS({"u", "Role"}), _accessible_get_role, 0 },
1437 { "GetRoleName", NULL, ELDBUS_ARGS({"s", "Name"}), _accessible_get_role_name, 0 },
1438 { "GetLocalizedRoleName", NULL, ELDBUS_ARGS({"s", "LocalizedName"}), _accessible_get_localized_role_name, 0},
1439 { "GetState", NULL, ELDBUS_ARGS({"au", NULL}), _accessible_get_state, 0},
1440 { "GetApplication", NULL, ELDBUS_ARGS({"(so)", NULL}), _accessible_get_application, 0},
1441 { "GetAttributes", NULL, ELDBUS_ARGS({"a{ss}", NULL}), _accessible_attributes_get, 0},
1442 { "GetInterfaces", NULL, ELDBUS_ARGS({"as", NULL}), _accessible_interfaces_get, 0},
1443 //TIZEN_ONLY(20170405) Add gesture method to accessible interface
1445 ELDBUS_ARGS({"i", "type"}, {"i", "x_beg"}, {"i", "y_beg"},
1446 {"i", "x_end"}, {"i", "y_end"}, {"i", "state"},
1447 {"u", "event_time"}),
1448 ELDBUS_ARGS({"b", "result"}), _accessible_gesture_do, 0},
1450 //TIZEN_ONLY(20170531): add "GetReadingMaterial" interface method
1451 { "GetReadingMaterial",
1453 ELDBUS_ARGS({"a{ss}", "attributes"}, {"s", "name"},
1454 {"s", "labledByName"},{"s", "textIfceName"},
1455 {"u", "role"}, {"au", "stateSet"},
1456 {"s", "localizedName"}, {"i", "childCount"},
1457 {"d", "currentValue"},{"d", "minimumIncrement"},
1458 {"d", "maximumValue"},{"d", "minimumValue"},
1459 {"s", "description"}, {"i", "indexInParent"},
1460 {"b", "isSelectedInParent"}, {"b", "hasCheckboxChild"},
1461 {"i", "listChildrenCount"},
1462 {"i", "firstSelectedChildIndex"},
1463 {"(so)", "parent"}, {"au", "parentStateSet"},
1464 {"i", "parentChildCount"}, {"u", "parentRole"},
1465 {"i", "selectedChildCount"},
1466 {"(so)", "describecByObject"}),
1467 _accessible_reading_material_get, 0},
1469 //TIZEN_ONLY(20170919): Handle default label object
1470 { "GetDefaultLabelInfo",
1471 NULL, ELDBUS_ARGS({"(so)", "defaultLabelObject"}, {"u", "defaultLabelRole"}),
1472 _accessible_default_label_info_get, 0},
1474 { NULL, NULL, NULL, NULL, 0 }
1478 _is_operation_permitted(Eo *obj)
1480 Elm_Atspi_State_Set states;
1481 eo_do(obj, states = elm_interface_atspi_accessible_state_set_get());
1483 if (!STATE_TYPE_GET(states, ELM_ATSPI_STATE_SHOWING)) return EINA_FALSE;
1488 if (evas_object_freeze_events_get(parent)) return EINA_FALSE;
1489 parent = evas_object_smart_parent_get(parent);
1494 static Eldbus_Message *
1495 _selection_selected_child_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
1497 const char *obj_path = eldbus_message_path_get(msg);
1498 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1499 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1503 Eldbus_Message *ret;
1504 Eldbus_Message_Iter *iter;
1506 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE, msg);
1508 if (!eldbus_message_arguments_get(msg, "i", &idx))
1509 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1511 ret = eldbus_message_method_return_new(msg);
1512 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1514 iter = eldbus_message_iter_get(ret);
1515 eo_do(obj, child = elm_interface_atspi_selection_selected_child_get(idx));
1517 _bridge_iter_object_reference_append(bridge, iter, child);
1518 _bridge_object_register(bridge, child);
1523 static Eldbus_Message *
1524 _selection_child_select(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1526 const char *obj_path = eldbus_message_path_get(msg);
1527 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1528 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1530 Eldbus_Message *ret;
1531 Eina_Bool result = EINA_FALSE;
1533 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE, msg);
1535 if (!eldbus_message_arguments_get(msg, "i", &idx))
1536 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1538 ret = eldbus_message_method_return_new(msg);
1539 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1541 if (_is_operation_permitted(obj))
1542 eo_do(obj, result = elm_interface_atspi_selection_child_select(idx));
1543 eldbus_message_arguments_append(ret, "b", result);
1548 static Eldbus_Message *
1549 _selection_selected_child_deselect(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1551 const char *obj_path = eldbus_message_path_get(msg);
1552 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1553 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1555 Eldbus_Message *ret;
1556 Eina_Bool result = EINA_FALSE;
1558 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE, msg);
1560 if (!eldbus_message_arguments_get(msg, "i", &idx))
1561 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1563 ret = eldbus_message_method_return_new(msg);
1564 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1566 if (_is_operation_permitted(obj))
1567 eo_do(obj, result = elm_interface_atspi_selection_selected_child_deselect(idx));
1568 eldbus_message_arguments_append(ret, "b", result);
1573 static Eldbus_Message *
1574 _selection_is_child_selected(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1576 const char *obj_path = eldbus_message_path_get(msg);
1577 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1578 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1580 Eldbus_Message *ret;
1583 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE, msg);
1585 if (!eldbus_message_arguments_get(msg, "i", &idx))
1586 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1588 ret = eldbus_message_method_return_new(msg);
1589 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1591 eo_do(obj, result = elm_interface_atspi_selection_is_child_selected(idx));
1592 eldbus_message_arguments_append(ret, "b", result);
1597 static Eldbus_Message *
1598 _selection_all_children_select(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1600 const char *obj_path = eldbus_message_path_get(msg);
1601 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1602 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1603 Eldbus_Message *ret;
1604 Eina_Bool result = EINA_FALSE;
1606 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE, msg);
1608 ret = eldbus_message_method_return_new(msg);
1609 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1611 if (_is_operation_permitted(obj))
1612 eo_do(obj, result = elm_interface_atspi_selection_all_children_select());
1613 eldbus_message_arguments_append(ret, "b", result);
1618 static Eldbus_Message *
1619 _selection_clear(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1621 const char *obj_path = eldbus_message_path_get(msg);
1622 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1623 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1624 Eldbus_Message *ret;
1625 Eina_Bool result = EINA_FALSE;
1627 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE, msg);
1629 ret = eldbus_message_method_return_new(msg);
1630 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1632 if (_is_operation_permitted(obj))
1633 eo_do(obj, result = elm_interface_atspi_selection_clear());
1634 eldbus_message_arguments_append(ret, "b", result);
1639 static Eldbus_Message *
1640 _selection_child_deselect(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1642 const char *obj_path = eldbus_message_path_get(msg);
1643 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1644 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1646 Eldbus_Message *ret;
1647 Eina_Bool result = EINA_FALSE;
1649 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE, msg);
1651 if (!eldbus_message_arguments_get(msg, "i", &idx))
1652 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1654 ret = eldbus_message_method_return_new(msg);
1655 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1657 if (_is_operation_permitted(obj))
1658 eo_do(obj, result = elm_interface_atspi_selection_child_deselect(idx));
1659 eldbus_message_arguments_append(ret, "b", result);
1664 static const Eldbus_Method selection_methods[] = {
1665 { "GetSelectedChild", ELDBUS_ARGS({"i", "selectedChildIndex"}), ELDBUS_ARGS({"(so)", "Accessible"}), _selection_selected_child_get, 0 },
1666 { "SelectChild", ELDBUS_ARGS({"i", "childIndex"}), ELDBUS_ARGS({"b", "result"}), _selection_child_select, 0 },
1667 { "DeselectSelectedChild", ELDBUS_ARGS({"i", "selectedChildIndex"}), ELDBUS_ARGS({"b", "result"}), _selection_selected_child_deselect, 0 },
1668 { "IsChildSelected", ELDBUS_ARGS({"i", "childIndex"}), ELDBUS_ARGS({"b", "result"}), _selection_is_child_selected, 0 },
1669 { "SelectAll", NULL, ELDBUS_ARGS({"b", "result"}), _selection_all_children_select, 0},
1670 { "ClearSelection", NULL, ELDBUS_ARGS({"b", "result"}), _selection_clear, 0},
1671 { "DeselectChild", ELDBUS_ARGS({"i", "childIndex"}), ELDBUS_ARGS({"b", "result"}), _selection_child_deselect, 0 },
1672 { NULL, NULL, NULL, NULL, 0 }
1675 static Eldbus_Message *
1676 _action_description_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1678 const char *description, *obj_path = eldbus_message_path_get(msg);
1679 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1680 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1682 Eldbus_Message *ret;
1684 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN, msg);
1686 if (!eldbus_message_arguments_get(msg, "i", &idx))
1687 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1689 ret = eldbus_message_method_return_new(msg);
1690 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1692 eo_do(obj, description = elm_interface_atspi_action_description_get(idx));
1693 description = description ? description : "";
1694 eldbus_message_arguments_append(ret, "s", description);
1699 static Eldbus_Message *
1700 _action_name_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1702 const char *name, *obj_path = eldbus_message_path_get(msg);
1703 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1704 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1706 Eldbus_Message *ret;
1708 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN, msg);
1710 if (!eldbus_message_arguments_get(msg, "i", &idx))
1711 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1713 ret = eldbus_message_method_return_new(msg);
1714 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1716 eo_do(obj, name = elm_interface_atspi_action_name_get(idx));
1717 name = name ? name : "";
1718 eldbus_message_arguments_append(ret, "s", name);
1723 static Eldbus_Message *
1724 _action_localized_name_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1726 const char *name, *obj_path = eldbus_message_path_get(msg);
1727 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1728 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1730 Eldbus_Message *ret;
1732 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN, msg);
1734 if (!eldbus_message_arguments_get(msg, "i", &idx))
1735 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1737 ret = eldbus_message_method_return_new(msg);
1738 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1740 eo_do(obj, name = elm_interface_atspi_action_localized_name_get(idx));
1741 name = name ? name : "";
1742 eldbus_message_arguments_append(ret, "s", name);
1747 static Eldbus_Message *
1748 _action_key_binding_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1750 const char *obj_path = eldbus_message_path_get(msg);
1752 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1753 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1755 Eldbus_Message *ret;
1757 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN, msg);
1759 if (!eldbus_message_arguments_get(msg, "i", &idx))
1760 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1762 ret = eldbus_message_method_return_new(msg);
1763 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1765 eo_do(obj, key = elm_interface_atspi_action_keybinding_get(idx));
1766 eldbus_message_arguments_append(ret, "s", key ? key : "");
1772 static Eldbus_Message *
1773 _action_actions_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1775 const char *action, *obj_path = eldbus_message_path_get(msg);
1776 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1777 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1779 Eldbus_Message *ret;
1780 Eldbus_Message_Iter *iter, *iter_array;
1782 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN, msg);
1784 ret = eldbus_message_method_return_new(msg);
1785 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1787 iter = eldbus_message_iter_get(ret);
1788 EINA_SAFETY_ON_NULL_RETURN_VAL(iter, NULL);
1790 iter_array = eldbus_message_iter_container_new(iter, 'a', "sss");
1791 EINA_SAFETY_ON_NULL_RETURN_VAL(iter_array, NULL);
1793 eo_do(obj, actions = elm_interface_atspi_action_actions_get());
1796 EINA_LIST_FREE(actions, action)
1800 eo_do(obj, key = elm_interface_atspi_action_keybinding_get(id));
1801 eo_do(obj, descr = elm_interface_atspi_action_description_get(id));
1802 descr = descr ? descr : "";
1803 eldbus_message_iter_arguments_append(iter_array, "sss", action, descr, key ? key : "");
1808 eldbus_message_iter_container_close(iter, iter_array);
1813 static Eldbus_Message *
1814 _action_action_do(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1816 const char *obj_path = eldbus_message_path_get(msg);
1817 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1818 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1820 Eldbus_Message *ret;
1821 Eina_Bool result = EINA_FALSE;
1823 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN, msg);
1825 if (!eldbus_message_arguments_get(msg, "i", &idx))
1826 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1828 ret = eldbus_message_method_return_new(msg);
1829 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1831 if (_is_operation_permitted(obj))
1832 eo_do(obj, result = elm_interface_atspi_action_do(idx));
1834 eldbus_message_arguments_append(ret, "b", result);
1839 static Eldbus_Message *
1840 _action_action_name_do(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1842 const char *obj_path = eldbus_message_path_get(msg);
1843 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1844 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1849 Eldbus_Message *ret;
1850 Eina_Bool result = EINA_FALSE;
1852 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN, msg);
1854 if (!eldbus_message_arguments_get(msg, "s", &action_name))
1855 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1857 ret = eldbus_message_method_return_new(msg);
1858 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1860 eo_do(obj, actions = elm_interface_atspi_action_actions_get());
1861 EINA_LIST_FREE(actions, action)
1863 if (!result && action && !strcmp(action, action_name))
1871 eo_do(obj, result = elm_interface_atspi_action_do(idx));
1873 eldbus_message_arguments_append(ret, "b", result);
1878 static const Eldbus_Method action_methods[] = {
1879 { "GetDescription", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"s", "description"}), _action_description_get, 0 },
1880 { "GetName", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"s", "name"}), _action_name_get, 0 },
1881 { "GetLocalizedName", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"s", "name"}), _action_localized_name_get, 0 },
1882 { "GetKeyBinding", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"s", "key"}), _action_key_binding_get, 0 },
1883 { "GetActions", NULL, ELDBUS_ARGS({"a(sss)", "actions"}), _action_actions_get, 0 },
1884 { "DoAction", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"b", "result"}), _action_action_do, 0 },
1885 { "DoActionName", ELDBUS_ARGS({"s", "name"}), ELDBUS_ARGS({"b", "result"}), _action_action_name_do, 0 },
1886 { NULL, NULL, NULL, NULL, 0 }
1889 static Eldbus_Message *
1890 _image_extents_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1892 AtspiCoordType type;
1893 Eldbus_Message *ret;
1894 const char *obj_path = eldbus_message_path_get(msg);
1896 Eina_Bool screen_coords;
1897 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1898 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1902 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_IMAGE_MIXIN, msg);
1904 if (!eldbus_message_arguments_get(msg, "u", &type))
1905 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1907 ret = eldbus_message_method_return_new(msg);
1908 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1910 screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
1911 eo_do(obj, elm_interface_atspi_image_extents_get(screen_coords, &x, &y, &w, &h));
1912 eldbus_message_arguments_append(ret, "iiii", x, y, w, h);
1917 static Eldbus_Message *
1918 _image_position_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1920 AtspiCoordType type;
1921 Eldbus_Message *ret;
1922 const char *obj_path = eldbus_message_path_get(msg);
1923 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1924 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1926 Eina_Bool screen_coords;
1928 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_IMAGE_MIXIN, msg);
1930 if (!eldbus_message_arguments_get(msg, "u", &type))
1931 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1933 ret = eldbus_message_method_return_new(msg);
1934 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1936 screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
1937 eo_do(obj, elm_interface_atspi_image_extents_get(screen_coords, &x, &y, NULL, NULL));
1938 eldbus_message_arguments_append(ret, "i", x);
1939 eldbus_message_arguments_append(ret, "i", y);
1944 static Eldbus_Message *
1945 _image_size_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1947 Eldbus_Message *ret;
1948 const char *obj_path = eldbus_message_path_get(msg);
1949 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1950 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1953 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_IMAGE_MIXIN, msg);
1955 ret = eldbus_message_method_return_new(msg);
1956 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1958 eo_do(obj, elm_interface_atspi_image_extents_get(EINA_FALSE, NULL, NULL, &w, &h));
1959 eldbus_message_arguments_append(ret, "i", w);
1960 eldbus_message_arguments_append(ret, "i", h);
1965 static const Eldbus_Method image_methods[] = {
1966 { "GetImageExtents", ELDBUS_ARGS({"u", "coordType"}), ELDBUS_ARGS({"iiii", "extents"}), _image_extents_get, 0 },
1967 { "GetImagePosition", ELDBUS_ARGS({"u", "coordType"}), ELDBUS_ARGS({"i", "x"}, {"i", "y"}), _image_position_get, 0 },
1968 { "GetImageSize", NULL, ELDBUS_ARGS({"i", "width"}, {"i", "height"}), _image_size_get, 0 },
1969 { NULL, NULL, NULL, NULL, 0 }
1972 static Eldbus_Message *
1973 _text_string_at_offset_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1975 const char *obj_path = eldbus_message_path_get(msg);
1977 Elm_Atspi_Text_Granularity gran;
1979 Eldbus_Message *ret;
1980 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1981 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1983 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
1985 if (!eldbus_message_arguments_get(msg, "iu", &start, &gran))
1986 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and granularity expected.");
1988 ret = eldbus_message_method_return_new(msg);
1989 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1991 eo_do(obj, str = elm_interface_atspi_text_string_get(gran, &start, &end));
1992 str = str ? str : strdup("");
1994 eldbus_message_arguments_append(ret, "sii", str, start, end);
2000 static Eldbus_Message *
2001 _text_text_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2003 const char *obj_path = eldbus_message_path_get(msg);
2005 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2006 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2009 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2011 if (!eldbus_message_arguments_get(msg, "ii", &start, &end))
2012 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and granularity expected.");
2014 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
2015 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2017 eo_do(obj, str = elm_interface_atspi_text_get(start, end));
2018 str = str ? str : strdup("");
2020 eldbus_message_arguments_append(ret, "s", str);
2026 static Eldbus_Message *
2027 _text_caret_offset_set(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2029 const char *obj_path = eldbus_message_path_get(msg);
2030 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2031 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2033 Eldbus_Message *ret;
2036 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2038 if (!eldbus_message_arguments_get(msg, "i", &offset))
2039 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset expected.");
2041 ret = eldbus_message_method_return_new(msg);
2042 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2044 eo_do(obj, res = elm_interface_atspi_text_caret_offset_set(offset));
2046 eldbus_message_arguments_append(ret, "b", res);
2051 static Eldbus_Message *
2052 _text_character_at_offset_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2054 const char *obj_path = eldbus_message_path_get(msg);
2055 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2056 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2058 Eldbus_Message *ret;
2061 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2063 if (!eldbus_message_arguments_get(msg, "i", &offset))
2064 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset expected.");
2066 ret = eldbus_message_method_return_new(msg);
2067 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2069 eo_do(obj, res = elm_interface_atspi_text_character_get(offset));
2071 eldbus_message_arguments_append(ret, "i", res);
2076 static Eldbus_Message *
2077 _text_attribute_value_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2079 const char *name, *obj_path = eldbus_message_path_get(msg);
2081 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2082 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2084 Eldbus_Message *ret;
2087 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2089 if (!eldbus_message_arguments_get(msg, "is", &start, &name))
2090 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and attribute name expected.");
2092 ret = eldbus_message_method_return_new(msg);
2093 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2095 eo_do(obj, res = elm_interface_atspi_text_attribute_get(name, &start, &end, &value));
2096 eldbus_message_arguments_append(ret, "siib", value ? value : "", start, end, res);
2098 if (value) free(value);
2102 static Eldbus_Message *
2103 _text_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2105 const char *obj_path = eldbus_message_path_get(msg);
2106 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2107 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2109 Eldbus_Message *ret;
2110 Eldbus_Message_Iter *iter, *iter_array;
2112 Elm_Atspi_Text_Attribute *attr;
2114 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2116 if (!eldbus_message_arguments_get(msg, "i", &start))
2117 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset expected.");
2119 ret = eldbus_message_method_return_new(msg);
2120 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2122 iter = eldbus_message_iter_get(ret);
2123 iter_array = eldbus_message_iter_container_new(iter, 'a', "{ss}");
2124 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
2126 eo_do(obj, attrs = elm_interface_atspi_text_attributes_get(&start, &end));
2128 EINA_LIST_FREE(attrs, attr)
2130 eldbus_message_iter_arguments_append(iter_array, "ss", attr->name, attr->value);
2131 elm_atspi_text_text_attribute_free(attr);
2134 eldbus_message_iter_container_close(iter, iter_array);
2135 eldbus_message_iter_arguments_append(iter, "ii", start, end);
2140 if (ret) eldbus_message_unref(ret);
2144 static Eldbus_Message *
2145 _text_default_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2147 const char *obj_path = eldbus_message_path_get(msg);
2148 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2149 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2150 int start = -1, end;
2151 Eldbus_Message *ret;
2152 Eldbus_Message_Iter *iter, *iter_array;
2154 Elm_Atspi_Text_Attribute *attr;
2156 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2158 ret = eldbus_message_method_return_new(msg);
2159 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2161 iter = eldbus_message_iter_get(ret);
2162 iter_array = eldbus_message_iter_container_new(iter, 'a', "{ss}");
2163 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
2165 eo_do(obj, attrs = elm_interface_atspi_text_attributes_get(&start, &end));
2167 EINA_LIST_FREE(attrs, attr)
2169 eldbus_message_iter_arguments_append(iter_array, "ss", attr->name, attr->value);
2170 elm_atspi_text_text_attribute_free(attr);
2173 eldbus_message_iter_container_close(iter, iter_array);
2174 eldbus_message_iter_arguments_append(iter, "ii", start, end);
2179 if (ret) eldbus_message_unref(ret);
2183 static Eldbus_Message *
2184 _text_character_extents_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2186 const char *obj_path = eldbus_message_path_get(msg);
2187 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2188 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2190 Eina_Rectangle rect;
2191 AtspiCoordType type;
2192 Eina_Bool screen_coords, res;
2193 Eldbus_Message *ret;
2195 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2197 if (!eldbus_message_arguments_get(msg, "iu", &offset, &type))
2198 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and coordinates type expected.");
2200 ret = eldbus_message_method_return_new(msg);
2201 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2203 screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
2205 eo_do(obj, res = elm_interface_atspi_text_character_extents_get(offset, screen_coords, &rect));
2209 eldbus_message_unref(ret);
2210 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to get character extents.");
2212 eldbus_message_arguments_append(ret, "iiii", rect.x, rect.y, rect.w, rect.h);
2217 static Eldbus_Message *
2218 _text_offset_at_point_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2220 const char *obj_path = eldbus_message_path_get(msg);
2221 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2222 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2224 AtspiCoordType type;
2225 Eina_Bool screen_coords;
2226 Eldbus_Message *ret;
2228 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2230 if (!eldbus_message_arguments_get(msg, "iiu", &x, &y, &type))
2231 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and coordinates type expected.");
2233 ret = eldbus_message_method_return_new(msg);
2234 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2237 screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
2239 eo_do(obj, offset = elm_interface_atspi_text_offset_at_point_get(screen_coords, x, y));
2241 eldbus_message_arguments_append(ret, "i", offset);
2246 static Eldbus_Message *
2247 _text_n_selections_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2249 const char *obj_path = eldbus_message_path_get(msg);
2250 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2251 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2253 Eldbus_Message *ret;
2255 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2257 ret = eldbus_message_method_return_new(msg);
2258 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2260 eo_do(obj, n = elm_interface_atspi_text_selections_count_get());
2262 eldbus_message_arguments_append(ret, "i", n);
2267 static Eldbus_Message *
2268 _text_selection_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2270 const char *obj_path = eldbus_message_path_get(msg);
2271 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2272 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2273 int sel_num, start, end;
2274 Eldbus_Message *ret;
2276 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2278 if (!eldbus_message_arguments_get(msg, "i", &sel_num))
2279 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Selection number expected.");
2281 ret = eldbus_message_method_return_new(msg);
2282 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2284 eo_do(obj, elm_interface_atspi_text_selection_get(sel_num, &start, &end));
2286 eldbus_message_arguments_append(ret, "ii", start, end);
2291 static Eldbus_Message *
2292 _text_selection_add(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2294 const char *obj_path = eldbus_message_path_get(msg);
2295 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2296 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2299 Eldbus_Message *ret;
2301 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2303 if (!eldbus_message_arguments_get(msg, "ii", &start, &end))
2304 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Start and end text offset expected.");
2306 ret = eldbus_message_method_return_new(msg);
2307 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2309 eo_do(obj, res = elm_interface_atspi_text_selection_add(start, end));
2311 eldbus_message_arguments_append(ret, "b", res);
2316 static Eldbus_Message *
2317 _text_selection_remove(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2319 const char *obj_path = eldbus_message_path_get(msg);
2320 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2321 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2324 Eldbus_Message *ret;
2326 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2328 if (!eldbus_message_arguments_get(msg, "i", &sel_num))
2329 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Selection number expected.");
2331 ret = eldbus_message_method_return_new(msg);
2332 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2334 eo_do(obj, res = elm_interface_atspi_text_selection_remove(sel_num));
2336 eldbus_message_arguments_append(ret, "b", res);
2341 static Eldbus_Message *
2342 _text_selection_set(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2344 const char *obj_path = eldbus_message_path_get(msg);
2345 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2346 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2347 int sel_num, start, end;
2349 Eldbus_Message *ret;
2351 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2353 if (!eldbus_message_arguments_get(msg, "iii", &sel_num, &start, &end))
2354 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Selection number expected.");
2356 ret = eldbus_message_method_return_new(msg);
2357 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2359 eo_do(obj, res = elm_interface_atspi_text_selection_set(sel_num, start, end));
2361 eldbus_message_arguments_append(ret, "b", res);
2366 static Eldbus_Message *
2367 _text_range_extents_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2369 const char *obj_path = eldbus_message_path_get(msg);
2370 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2371 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2373 Eina_Rectangle rect;
2374 Eina_Bool screen_coords, res;
2375 AtspiCoordType type;
2376 Eldbus_Message *ret;
2378 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2380 if (!eldbus_message_arguments_get(msg, "iiu", &start, &end, &type))
2381 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Selection number expected.");
2383 ret = eldbus_message_method_return_new(msg);
2384 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2386 screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
2387 eo_do(obj, res = elm_interface_atspi_text_range_extents_get(screen_coords, start, end, &rect));
2390 eldbus_message_unref(ret);
2391 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Can't get range extents.");
2394 eldbus_message_arguments_append(ret, "iiii", rect.x, rect.y, rect.w, rect.h);
2399 static Eldbus_Message *
2400 _text_bounded_ranges_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2402 const char *obj_path = eldbus_message_path_get(msg);
2403 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2404 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2405 Eina_Rectangle rect;
2406 Eina_Bool screen_coords;
2407 AtspiCoordType type;
2408 Elm_Atspi_Text_Clip_Type xclip, yclip;
2410 Eldbus_Message *ret;
2411 Elm_Atspi_Text_Range *range;
2412 Eldbus_Message_Iter *iter, *iter_array, *iter_struct, *iter_var;
2414 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2416 if (!eldbus_message_arguments_get(msg, "iiiiuuu", &rect.x, &rect.y, &rect.w, &rect.h, &type, &xclip, &yclip))
2417 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Expected (x,y,w,h) of bounding box, screen coord type and x, y text clip types.");
2419 ret = eldbus_message_method_return_new(msg);
2420 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2422 iter = eldbus_message_iter_get(ret);
2423 iter_array = eldbus_message_iter_container_new(iter, 'a', "(iisv)");
2424 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
2426 screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
2427 eo_do(obj, ranges = elm_interface_atspi_text_bounded_ranges_get(screen_coords, rect, xclip, yclip));
2429 EINA_LIST_FREE(ranges, range)
2431 iter_struct = eldbus_message_iter_container_new(iter_array, 'r', NULL);
2434 eldbus_message_iter_basic_append(iter_struct, 'i', range->start_offset);
2435 eldbus_message_iter_basic_append(iter_struct, 'i', range->end_offset);
2436 range->content = range->content ? range->content : strdup("");
2437 eldbus_message_iter_basic_append(iter_struct, 's', range->content);
2438 /* AT-SPI specification requires variant type in return, however
2439 * ATK or other implementations as well as AT Clients don't use it .
2440 * To cover spec a dummy value will be returned */
2441 iter_var = eldbus_message_iter_container_new(iter_struct, 'v', "i");
2444 eldbus_message_iter_basic_append(iter_var, 'i', 0);
2445 eldbus_message_iter_container_close(iter_struct, iter_var);
2447 eldbus_message_iter_container_close(iter_array, iter_struct);
2449 if (range->content) free(range->content);
2453 eldbus_message_iter_container_close(iter, iter_array);
2458 if (ret) eldbus_message_unref(ret);
2462 static Eldbus_Message *
2463 _text_run_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2465 const char *obj_path = eldbus_message_path_get(msg);
2466 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2467 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2469 Eldbus_Message *ret;
2470 Eldbus_Message_Iter *iter, *iter_array;
2471 Eina_List *attrs, *defaults;
2472 Elm_Atspi_Text_Attribute *attr;
2475 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2477 if (!eldbus_message_arguments_get(msg, "ib", &start, &incl_def))
2478 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and include defaults flag expected.");
2480 ret = eldbus_message_method_return_new(msg);
2481 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2483 iter = eldbus_message_iter_get(ret);
2484 iter_array = eldbus_message_iter_container_new(iter, 'a', "{ss}");
2485 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
2487 eo_do(obj, attrs = elm_interface_atspi_text_attributes_get(&start, &end));
2491 eo_do(obj, defaults = elm_interface_atspi_text_default_attributes_get());
2492 attrs = eina_list_merge(attrs, defaults);
2495 EINA_LIST_FREE(attrs, attr)
2497 eldbus_message_iter_arguments_append(iter_array, "ss", attr->name, attr->value);
2498 elm_atspi_text_text_attribute_free(attr);
2501 eldbus_message_iter_container_close(iter, iter_array);
2502 eldbus_message_iter_arguments_append(iter, "ii", start, end);
2507 if (ret) eldbus_message_unref(ret);
2511 static const Eldbus_Method text_methods[] = {
2512 { "GetTextAtOffset", ELDBUS_ARGS({"i", "offset"}, {"u", "granularity"}), ELDBUS_ARGS({"s", "string"}, {"i", "startOffset"}, {"i", "endOffset"}), _text_string_at_offset_get, 0 },
2513 { "GetText", ELDBUS_ARGS({"i", "startOffset"}, {"i", "endOffset"}), ELDBUS_ARGS({"s", "string"}), _text_text_get, 0 },
2514 { "SetCaretOffset", ELDBUS_ARGS({"i", "offset"}), ELDBUS_ARGS({"b", NULL}), _text_caret_offset_set, 0 },
2515 { "GetCharacterAtOffset", ELDBUS_ARGS({"i", "offset"}), ELDBUS_ARGS({"i", NULL}), _text_character_at_offset_get, 0 },
2516 { "GetAttributeValue", ELDBUS_ARGS({"i", "offset"}, {"s", "attributeName"}), ELDBUS_ARGS({"s", NULL}, {"i", "startOffset"}, {"i", "endOffset"}, {"b", "defined"}), _text_attribute_value_get, 0 },
2517 { "GetAttributes", ELDBUS_ARGS({"i", "offset"}), ELDBUS_ARGS({"a(ss)", NULL}, {"i", "startOffset"}, {"i", "endOffset"}), _text_attributes_get, 0 },
2518 { "GetDefaultAttributes", NULL, ELDBUS_ARGS({"a(ss)", NULL}), _text_default_attributes_get, 0 },
2519 { "GetCharacterExtents", ELDBUS_ARGS({"i", "offset"}, {"u", "coordType"}), ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"i","w"}, {"i","h"}), _text_character_extents_get, 0 },
2520 { "GetOffsetAtPoint", ELDBUS_ARGS({"i", "x"}, {"i","y"}, {"u", "coordType"}), ELDBUS_ARGS({"i", NULL}), _text_offset_at_point_get, 0 },
2521 { "GetNSelections", NULL, ELDBUS_ARGS({"i", NULL}), _text_n_selections_get, 0 },
2522 { "GetSelection", ELDBUS_ARGS({"i", "selectionNum"}), ELDBUS_ARGS({"i", "startOffset"}, {"i", "endOffset"}), _text_selection_get, 0 },
2523 { "AddSelection", ELDBUS_ARGS({"i", "startOffset"}, {"i", "endOffset"}), ELDBUS_ARGS({"b", NULL}), _text_selection_add, 0 },
2524 { "RemoveSelection", ELDBUS_ARGS({"i", "selectionNum"}), ELDBUS_ARGS({"b", NULL}), _text_selection_remove, 0 },
2525 { "SetSelection", ELDBUS_ARGS({"i", "selectionNum"}, {"i", "startOffset"}, {"i", "endOffset"}), ELDBUS_ARGS({"b", NULL}), _text_selection_set, 0 },
2526 { "GetRangeExtents", ELDBUS_ARGS({"i", "startOffset"}, {"i", "endOffset"}, {"u", "coordType"}), ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"i","w"}, {"i","h"}), _text_range_extents_get, 0 },
2527 { "GetBoundedRanges", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"i", "w"}, {"i", "h"}, {"u", "coordType"}, {"u", "xClipType"}, {"u", "yClipType"}), ELDBUS_ARGS({"a(issv)", NULL}), _text_bounded_ranges_get, 0 },
2528 { "GetAttributeRun", ELDBUS_ARGS({"i", "offset"}, {"b", "includeDefaults"}), ELDBUS_ARGS({"a(ss)", NULL}, {"i", "startOffset"}, {"i", "endOffset"}), _text_run_attributes_get, 0 },
2529 { "GetDefaultAttributeSet", NULL, ELDBUS_ARGS({"a(ss)", NULL}), _text_default_attributes_get, 0 },
2530 { NULL, NULL, NULL, NULL, 0 }
2533 static Eldbus_Message *
2534 _editable_text_text_content_set(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2536 const char *obj_path = eldbus_message_path_get(msg);
2537 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2538 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2539 const char *content;
2540 Eldbus_Message *ret;
2543 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE, msg);
2545 if (!eldbus_message_arguments_get(msg, "s", &content))
2546 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "String expected.");
2548 ret = eldbus_message_method_return_new(msg);
2549 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2551 eo_do(obj, res = elm_interface_atspi_editable_text_content_set(content));
2553 eldbus_message_arguments_append(ret, "b", res);
2558 static Eldbus_Message *
2559 _editable_text_text_insert(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2561 const char *obj_path = eldbus_message_path_get(msg);
2562 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2563 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2565 Eldbus_Message *ret;
2569 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE, msg);
2571 if (!eldbus_message_arguments_get(msg, "isi", &pos, &text, &len))
2572 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Postion, string, length expected.");
2574 ret = eldbus_message_method_return_new(msg);
2575 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2577 eo_do(obj, res = elm_interface_atspi_editable_text_insert(text, pos));
2579 eldbus_message_arguments_append(ret, "b", res);
2584 static Eldbus_Message *
2585 _editable_text_text_copy(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2587 const char *obj_path = eldbus_message_path_get(msg);
2588 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2589 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2590 Eldbus_Message *ret;
2594 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE, msg);
2596 if (!eldbus_message_arguments_get(msg, "ii", &start, &end))
2597 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Start and end index expected.");
2599 ret = eldbus_message_method_return_new(msg);
2600 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2602 eo_do(obj, res = elm_interface_atspi_editable_text_copy(start, end));
2604 eldbus_message_arguments_append(ret, "b", res);
2609 static Eldbus_Message *
2610 _editable_text_text_cut(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2612 const char *obj_path = eldbus_message_path_get(msg);
2613 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2614 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2615 Eldbus_Message *ret;
2619 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE, msg);
2621 if (!eldbus_message_arguments_get(msg, "ii", &start, &end))
2622 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Start and end index expected.");
2624 ret = eldbus_message_method_return_new(msg);
2625 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2627 eo_do(obj, res = elm_interface_atspi_editable_text_cut(start, end));
2629 eldbus_message_arguments_append(ret, "b", res);
2634 static Eldbus_Message *
2635 _editable_text_text_delete(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2637 const char *obj_path = eldbus_message_path_get(msg);
2638 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2639 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2640 Eldbus_Message *ret;
2644 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE, msg);
2646 if (!eldbus_message_arguments_get(msg, "ii", &start, &end))
2647 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Start and end index expected.");
2649 ret = eldbus_message_method_return_new(msg);
2650 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2652 eo_do(obj, res = elm_interface_atspi_editable_text_delete(start, end));
2654 eldbus_message_arguments_append(ret, "b", res);
2659 static Eldbus_Message *
2660 _editable_text_text_paste(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2662 const char *obj_path = eldbus_message_path_get(msg);
2663 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2664 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2665 Eldbus_Message *ret;
2669 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE, msg);
2671 if (!eldbus_message_arguments_get(msg, "i", &pos))
2672 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Start and end index expected.");
2674 ret = eldbus_message_method_return_new(msg);
2675 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2677 eo_do(obj, res = elm_interface_atspi_editable_text_paste(pos));
2679 eldbus_message_arguments_append(ret, "b", res);
2685 _elm_atspi_bridge_plug_id_split(const char *plug_id, char **bus, char **path)
2687 if (!plug_id || !strcmp(plug_id, "")) return EINA_FALSE;
2688 unsigned int tokens = 0;
2689 char **split = eina_str_split_full(plug_id, ":", 0, &tokens);
2690 Eina_Bool ret = EINA_FALSE;
2693 if (!split[0] || !split[1])
2697 if (bus) *bus = strdup(split[0]);
2698 if (path) *path = strdup(split[1]);
2702 else if (tokens == 3)
2704 if (!split[0] || !split[1] || !split[2])
2709 snprintf(buf, sizeof(buf), "%s:%s",split[0], split[1]);
2710 if (bus) *bus = strdup(buf);
2711 if (path) *path = strdup(split[2]);
2721 static Eldbus_Message *
2722 _socket_embedded(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
2725 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
2726 const char *obj_path = eldbus_message_path_get(msg);
2728 const char *bus, *path;
2729 Eo *bridge = _elm_atspi_bridge_get();
2730 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2731 eo_do(obj, proxy = elm_interface_atspi_accessible_parent_get());
2733 if (!eo_isa(proxy, ELM_ATSPI_PROXY_CLASS))
2734 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to embed object.");
2736 if (!eldbus_message_arguments_get(msg, "s", &path))
2737 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Plug id expected.");
2739 bus = eldbus_message_sender_get(msg);
2741 eo_do(proxy, elm_obj_atspi_proxy_address_set(bus, path));
2743 _bridge_cache_build(bridge, proxy);
2745 return eldbus_message_method_return_new(msg);
2748 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
2749 static Eldbus_Message *
2750 _socket_offset_set(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2754 Eo *obj = eldbus_service_object_data_get(iface, "_atspi_obj");
2755 eo_do(obj, parent = eo_parent_get());
2756 Evas_Object *top = elm_object_top_widget_get(parent);
2758 if (!eldbus_message_arguments_get(msg, "ii", &x, &y))
2759 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
2761 eo_do(top, elm_interface_atspi_component_socket_offset_set(x, y));
2763 return eldbus_message_method_return_new(msg);
2767 static const Eldbus_Method editable_text_methods[] = {
2768 { "SetTextContents", ELDBUS_ARGS({"s", "newcontents"}), ELDBUS_ARGS({"b", NULL}), _editable_text_text_content_set, 0 },
2769 { "InsertText", ELDBUS_ARGS({"i", "position"}, {"s", "text"}, {"i", "length"}), ELDBUS_ARGS({"b", NULL}), _editable_text_text_insert, 0 },
2770 { "CopyText", ELDBUS_ARGS({"i", "startPos"}, {"i", "endPos"}), NULL, _editable_text_text_copy, 0 },
2771 { "CutText", ELDBUS_ARGS({"i", "startPos"}, {"i", "endPos"}), ELDBUS_ARGS({"b", NULL}), _editable_text_text_cut, 0 },
2772 { "DeleteText", ELDBUS_ARGS({"i", "startPos"}, {"i", "endPos"}), ELDBUS_ARGS({"b", NULL}), _editable_text_text_delete, 0 },
2773 { "PasteText", ELDBUS_ARGS({"i", "position"}), ELDBUS_ARGS({"b", NULL}), _editable_text_text_paste, 0 },
2774 { NULL, NULL, NULL, NULL, 0 }
2777 static const Eldbus_Method socket_methods[] = {
2778 { "Embedded", ELDBUS_ARGS({"s", "id"}), ELDBUS_ARGS({NULL, NULL}), _socket_embedded, 0 },
2779 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
2780 { "SetOffset", ELDBUS_ARGS({"i", "x"}, {"i", "y"}), ELDBUS_ARGS({NULL, NULL}), _socket_offset_set, 0 },
2782 { NULL, NULL, NULL, NULL, 0 }
2785 static const Eldbus_Service_Interface_Desc socket_iface_desc = {
2786 ATSPI_DBUS_INTERFACE_SOCKET, socket_methods, NULL, NULL, NULL, NULL
2790 _bridge_object_from_path(Eo *bridge, const char *path)
2792 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
2793 unsigned long long eo_ptr = 0;
2795 const char *tmp = path;
2798 int len = strlen(ELM_ACCESS_OBJECT_PATH_PREFIX);
2799 if (strncmp(path, ELM_ACCESS_OBJECT_PATH_PREFIX, len))
2802 tmp = path + len; /* Skip over the prefix */
2803 if (!strcmp(ELM_ACCESS_OBJECT_PATH_ROOT, tmp))
2804 return elm_atspi_bridge_root_get(bridge);
2806 sscanf(tmp, "%llu", &eo_ptr);
2807 eo = (Eo *) (uintptr_t) eo_ptr;
2809 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, NULL);
2810 if (!eina_hash_find(pd->cache, &eo))
2812 WRN("Request for non-registered object: %s", path);
2816 ret = eo_isa(eo, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN) ? eo : NULL;
2822 _bridge_path_from_object(Eo *bridge, const Eo *eo)
2824 static char path[64];
2827 return ATSPI_DBUS_PATH_NULL;
2829 if (eo == elm_atspi_bridge_root_get(bridge))
2830 snprintf(path, sizeof(path), "%s%s", ELM_ACCESS_OBJECT_PATH_PREFIX, ELM_ACCESS_OBJECT_PATH_ROOT);
2832 snprintf(path, sizeof(path), ELM_ACCESS_OBJECT_REFERENCE_TEMPLATE, (unsigned long long)(uintptr_t)eo);
2837 _accessible_property_get(const Eldbus_Service_Interface *interface, const char *property,
2838 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg,
2839 Eldbus_Message **error)
2841 const char *ret = NULL, *obj_path = eldbus_message_path_get(request_msg);
2842 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2843 Eo *ret_obj = NULL, *obj = _bridge_object_from_path(bridge, obj_path);
2845 ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, request_msg, error);
2847 if (!strcmp(property, "Name"))
2849 eo_do(obj, ret = elm_interface_atspi_accessible_name_get());
2852 eldbus_message_iter_basic_append(iter, 's', ret);
2855 else if (!strcmp(property, "Description"))
2857 eo_do(obj, ret = elm_interface_atspi_accessible_description_get());
2860 eldbus_message_iter_basic_append(iter, 's', ret);
2863 else if (!strcmp(property, "Parent"))
2865 eo_do(obj, ret_obj = elm_interface_atspi_accessible_parent_get());
2866 Elm_Atspi_Role role = ELM_ATSPI_ROLE_INVALID;
2867 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
2868 if ((!ret_obj) && (ELM_ATSPI_ROLE_APPLICATION == role))
2869 _object_desktop_reference_append(iter);
2871 _bridge_iter_object_reference_append(bridge, iter, ret_obj);
2874 else if (!strcmp(property, "ChildCount"))
2876 Eina_List *l = NULL;
2877 eo_do(obj, l = elm_interface_atspi_accessible_children_get());
2878 eldbus_message_iter_basic_append(iter, 'i', eina_list_count(l));
2886 _selection_property_get(const Eldbus_Service_Interface *interface, const char *property,
2887 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg,
2888 Eldbus_Message **error)
2891 const char *obj_path = eldbus_message_path_get(request_msg);
2892 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2893 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2895 ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE, request_msg, error);
2897 if (!strcmp(property, "NSelectedChildren"))
2899 eo_do(obj, n = elm_interface_atspi_selection_selected_children_count_get());
2900 eldbus_message_iter_basic_append(iter, 'i', n);
2907 _action_property_get(const Eldbus_Service_Interface *interface, const char *property,
2908 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg,
2909 Eldbus_Message **error)
2912 const char *obj_path = eldbus_message_path_get(request_msg);
2913 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2914 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2916 ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN, request_msg, error);
2918 if (!strcmp(property, "NActions"))
2920 eo_do(obj, actions = elm_interface_atspi_action_actions_get());
2921 eldbus_message_iter_basic_append(iter, 'i', eina_list_count(actions));
2922 eina_list_free(actions);
2928 static Eldbus_Message*
2929 _value_properties_set(const Eldbus_Service_Interface *interface, const char *property,
2930 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg)
2934 const char *obj_path = eldbus_message_path_get(request_msg);
2935 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2936 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2938 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_VALUE_INTERFACE, request_msg);
2940 if (!eldbus_message_iter_arguments_get(iter, "d", &value))
2942 return eldbus_message_error_new(request_msg, "org.freedesktop.DBus.Error.InvalidArgs", "Expected value of type: double.");
2945 if (!strcmp(property, "CurrentValue"))
2947 eo_do(obj, ret = elm_interface_atspi_value_and_text_set(value, NULL));
2948 Eldbus_Message *answer = eldbus_message_method_return_new(request_msg);
2949 eldbus_message_arguments_append(answer, "b", ret);
2957 _value_properties_get(const Eldbus_Service_Interface *interface, const char *property,
2958 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg,
2959 Eldbus_Message **error)
2962 const char *obj_path = eldbus_message_path_get(request_msg);
2963 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2964 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2966 ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_VALUE_INTERFACE, request_msg, error);
2968 if (!strcmp(property, "CurrentValue"))
2970 eo_do(obj, elm_interface_atspi_value_and_text_get(&value, NULL));
2971 eldbus_message_iter_basic_append(iter, 'd', value);
2974 if (!strcmp(property, "MinimumValue"))
2976 eo_do(obj, elm_interface_atspi_value_range_get(&value, NULL, NULL));
2977 eldbus_message_iter_basic_append(iter, 'd', value);
2980 if (!strcmp(property, "MaximumValue"))
2982 eo_do(obj, elm_interface_atspi_value_range_get(NULL, &value, NULL));
2983 eldbus_message_iter_basic_append(iter, 'd', value);
2986 if (!strcmp(property, "MinimumIncrement"))
2988 eo_do(obj, value = elm_interface_atspi_value_increment_get());
2989 eldbus_message_iter_basic_append(iter, 'd', value);
2996 _image_properties_get(const Eldbus_Service_Interface *interface, const char *property,
2997 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg,
2998 Eldbus_Message **error)
3001 const char *obj_path = eldbus_message_path_get(request_msg);
3002 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
3003 Eo *obj = _bridge_object_from_path(bridge, obj_path);
3005 ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_IMAGE_MIXIN, request_msg, error);
3007 if (!strcmp(property, "ImageDescription"))
3009 eo_do(obj, value = elm_interface_atspi_image_description_get());
3010 value = value ? value : "";
3011 eldbus_message_iter_basic_append(iter, 's', value);
3014 if (!strcmp(property, "ImageLocale"))
3016 eo_do(obj, value = elm_interface_atspi_image_locale_get());
3017 value = value ? value : "";
3018 eldbus_message_iter_basic_append(iter, 's', value);
3025 _text_properties_get(const Eldbus_Service_Interface *interface, const char *property,
3026 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg,
3027 Eldbus_Message **error)
3029 const char *obj_path = eldbus_message_path_get(request_msg);
3030 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
3031 Eo *obj = _bridge_object_from_path(bridge, obj_path);
3034 ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, request_msg, error);
3036 if (!strcmp(property, "CharacterCount"))
3038 eo_do(obj, val = elm_interface_atspi_text_character_count_get());
3039 eldbus_message_iter_basic_append(iter, 'i', val);
3042 if (!strcmp(property, "CaretOffset"))
3044 eo_do(obj, val = elm_interface_atspi_text_caret_offset_get());
3045 eldbus_message_iter_basic_append(iter, 'i', val);
3051 static Eldbus_Message*
3052 _application_properties_set(const Eldbus_Service_Interface *iface, const char *property, Eldbus_Message_Iter *iter, const Eldbus_Message *input_msg)
3054 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
3055 const char *obj_path = eldbus_message_path_get(input_msg);
3056 Eo *obj = _bridge_object_from_path(bridge, obj_path);
3059 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, NULL);
3060 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_ATSPI_APP_OBJECT_CLASS, input_msg);
3062 if (!eldbus_message_iter_arguments_get(iter, "i", &value))
3064 return eldbus_message_error_new(input_msg, "org.freedesktop.DBus.Error.InvalidArgs", "Expected value of type: int.");
3067 if (!strcmp(property, "Id"))
3070 Eldbus_Message *answer = eldbus_message_method_return_new(input_msg);
3071 eldbus_message_arguments_append(answer, "b", EINA_TRUE);
3079 _application_properties_get(const Eldbus_Service_Interface *interface, const char *property,
3080 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg,
3081 Eldbus_Message **error)
3083 const char *obj_path = eldbus_message_path_get(request_msg);
3084 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
3085 Eo *obj = _bridge_object_from_path(bridge, obj_path);
3087 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE);
3088 ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_ATSPI_APP_OBJECT_CLASS, request_msg, error);
3090 if (!strcmp(property, "ToolkitName"))
3092 eldbus_message_iter_basic_append(iter, 's', "elementary");
3095 if (!strcmp(property, "Version"))
3098 snprintf(buf, sizeof(buf), "%d.%d", ELM_VERSION_MAJOR, ELM_VERSION_MINOR);
3099 eldbus_message_iter_basic_append(iter, 's', buf);
3102 if (!strcmp(property, "Id"))
3104 eldbus_message_iter_basic_append(iter, 'i', pd->id);
3110 static const Eldbus_Property accessible_properties[] = {
3111 { "Name", "s", NULL, NULL, 0 },
3112 { "Description", "s", NULL, NULL, 0 },
3113 { "Parent", "(so)", NULL, NULL, 0 },
3114 { "ChildCount", "i", NULL, NULL, 0 },
3115 { NULL, NULL, NULL, NULL, 0 }
3118 static const Eldbus_Property action_properties[] = {
3119 { "NActions", "i", _action_property_get, NULL, 0 },
3120 { NULL, NULL, NULL, NULL, 0 }
3123 static const Eldbus_Property value_properties[] = {
3124 { "MinimumValue", "d", NULL, NULL, 0 },
3125 { "MaximumValue", "d", NULL, NULL, 0 },
3126 { "MinimumIncrement", "d", NULL, NULL, 0 },
3127 { "CurrentValue", "d", NULL, NULL, 0 },
3128 { NULL, NULL, NULL, NULL, 0 }
3131 static const Eldbus_Property image_properties[] = {
3132 { "ImageDescription", "s", NULL, NULL, 0 },
3133 { "ImageLocale", "s", NULL, NULL, 0 },
3134 { NULL, NULL, NULL, NULL, 0 }
3137 static const Eldbus_Property selection_properties[] = {
3138 { "NSelectedChildren", "i", _selection_property_get, NULL, 0 },
3139 { NULL, NULL, NULL, NULL, 0 }
3142 static const Eldbus_Property text_properties[] = {
3143 { "CharacterCount", "i", NULL, NULL, 0 },
3144 { "CaretOffset", "i", NULL, NULL, 0 },
3145 { NULL, NULL, NULL, NULL, 0 }
3148 static const Eldbus_Property application_properties[] = {
3149 { "ToolkitName", "s", NULL, NULL, 0 },
3150 { "Version", "s", NULL, NULL, 0 },
3151 { "Id", "i", NULL, NULL, 0 },
3152 { NULL, NULL, NULL, NULL, 0 }
3155 static const Eldbus_Service_Interface_Desc accessible_iface_desc = {
3156 ATSPI_DBUS_INTERFACE_ACCESSIBLE, accessible_methods, NULL, accessible_properties, _accessible_property_get, NULL
3159 static const Eldbus_Service_Interface_Desc action_iface_desc = {
3160 ATSPI_DBUS_INTERFACE_ACTION, action_methods, NULL, action_properties, NULL, NULL
3163 static const Eldbus_Service_Interface_Desc value_iface_desc = {
3164 ATSPI_DBUS_INTERFACE_VALUE, NULL, NULL, value_properties, _value_properties_get, _value_properties_set
3167 static const Eldbus_Service_Interface_Desc image_iface_desc = {
3168 ATSPI_DBUS_INTERFACE_IMAGE, image_methods, NULL, image_properties, _image_properties_get, NULL
3171 static const Eldbus_Service_Interface_Desc selection_iface_desc = {
3172 ATSPI_DBUS_INTERFACE_SELECTION, selection_methods, NULL, selection_properties, NULL, NULL
3175 static const Eldbus_Service_Interface_Desc text_iface_desc = {
3176 ATSPI_DBUS_INTERFACE_TEXT, text_methods, NULL, text_properties, _text_properties_get, NULL
3179 static const Eldbus_Service_Interface_Desc editable_text_iface_desc = {
3180 ATSPI_DBUS_INTERFACE_EDITABLE_TEXT, editable_text_methods, NULL, NULL, NULL, NULL
3183 static const Eldbus_Service_Interface_Desc application_iface_desc = {
3184 ATSPI_DBUS_INTERFACE_APPLICATION, NULL, NULL, application_properties, _application_properties_get, _application_properties_set
3188 _collection_match_rule_free(struct collection_match_rule *rule)
3190 Elm_Atspi_Attribute *attr;
3191 eina_list_free(rule->ifaces);
3192 EINA_LIST_FREE(rule->attributes, attr)
3194 eina_stringshare_del(attr->key);
3195 eina_stringshare_del(attr->value);
3200 _collection_roles_convert(uint64_t roles[2])
3202 // Currently elm roles and atspi roles are binary compatible.
3203 // Implement this function when it will be needed.
3208 _collection_iter_match_rule_get(Eldbus_Message_Iter *iter, struct collection_match_rule *rule)
3210 Eldbus_Message_Iter *states_iter, *attrib_iter, *iter_arg, *role_iter, *ifc_iter;
3211 unsigned int *array;
3212 int array_count, state_match, attrib_match, role_match, ifc_match, reverse;
3213 const char *ifc_name;
3215 if (!eldbus_message_iter_arguments_get(iter, "aiia{ss}iaiiasib", &states_iter, &state_match, &attrib_iter, &attrib_match, &role_iter, &role_match, &ifc_iter, &ifc_match, &reverse))
3217 ERR("Unable to get message arguments");
3221 memset(rule, 0x0, sizeof(struct collection_match_rule));
3222 rule->statematchtype = state_match;
3223 rule->attributematchtype = attrib_match;
3224 rule->rolematchtype = role_match;
3225 rule->interfacematchtype = ifc_match;
3226 rule->reverse = reverse;
3228 if (!eldbus_message_iter_fixed_array_get(states_iter, 'i', &array, &array_count))
3231 //Roles according to libatspi impementation are transferred in 2-int element fixed bit array
3232 if (array_count != 2)
3234 ERR("Unexpected states array size");
3237 uint64_t states = ((uint64_t)array[0] | ((uint64_t)array[1] << 32));
3238 rule->states = _atspi_state_set_to_elm_atspi_state_set(states);
3240 //Roles according to libatspi impementation are transferred in 4-int element fixed bit array
3241 if (!eldbus_message_iter_fixed_array_get(role_iter, 'i', &array, &array_count))
3244 if (array_count != 4)
3246 ERR("Unexpected roles array size");
3250 //convert atspi roles to elm_roles
3251 rule->roles[0] = ((uint64_t)array[0] | ((uint64_t)array[1] << 32));
3252 rule->roles[1] = ((uint64_t)array[2] | ((uint64_t)array[3] << 32));
3254 _collection_roles_convert(rule->roles);
3256 //Get matching properties
3257 while (eldbus_message_iter_get_and_next(attrib_iter, '{', &iter_arg))
3259 const char *key, *value;
3260 if (eldbus_message_iter_arguments_get(iter_arg, "ss", &key, &value))
3262 Elm_Atspi_Attribute *attrib = calloc(sizeof(Elm_Atspi_Attribute), 1);
3263 attrib->key = eina_stringshare_add(key);
3264 attrib->value = eina_stringshare_add(value);
3265 rule->attributes = eina_list_append(rule->attributes, attrib);
3269 //Get interfaces to match
3270 while (eldbus_message_iter_get_and_next(ifc_iter, 's', &ifc_name))
3272 const Eo_Class *class = NULL;
3273 if (!strcmp(ifc_name, "action"))
3274 class = ELM_INTERFACE_ATSPI_ACTION_MIXIN;
3275 else if (!strcmp(ifc_name, "component"))
3276 class = ELM_INTERFACE_ATSPI_COMPONENT_MIXIN;
3277 else if (!strcmp(ifc_name, "editabletext"))
3278 class = ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE;
3279 else if (!strcmp(ifc_name, "text"))
3280 class = ELM_INTERFACE_ATSPI_TEXT_INTERFACE;
3281 else if (!strcmp(ifc_name, "image"))
3282 class = ELM_INTERFACE_ATSPI_SELECTION_INTERFACE;
3283 else if (!strcmp(ifc_name, "value"))
3284 class = ELM_INTERFACE_ATSPI_VALUE_INTERFACE;
3287 rule->ifaces = eina_list_append(rule->ifaces, class);
3290 _collection_match_rule_free(rule);
3299 _collection_match_interfaces_helper(Eo *obj, Eina_List *ifcs, Eina_Bool condition, Eina_Bool ret_if_true, Eina_Bool ret_if_false)
3304 EINA_LIST_FOREACH(ifcs, l, class)
3306 if (eo_isa(obj, class) == condition)
3309 return ret_if_false;
3313 _collection_match_interfaces_lookup(Eo *obj, struct collection_match_rule *rule)
3315 Eina_Bool ret = EINA_FALSE;
3317 switch (rule->interfacematchtype)
3319 case ATSPI_Collection_MATCH_INVALID:
3322 case ATSPI_Collection_MATCH_ALL:
3323 ret = _collection_match_interfaces_helper(
3324 obj, rule->ifaces, EINA_FALSE, EINA_FALSE, EINA_TRUE);
3326 case ATSPI_Collection_MATCH_ANY:
3327 ret = _collection_match_interfaces_helper(
3328 obj, rule->ifaces, EINA_TRUE, EINA_TRUE, EINA_FALSE);
3330 case ATSPI_Collection_MATCH_NONE:
3331 ret = _collection_match_interfaces_helper(
3332 obj, rule->ifaces, EINA_TRUE, EINA_FALSE, EINA_TRUE);
3341 _collection_match_states_lookup(Eo *obj, struct collection_match_rule *rule)
3343 Eina_Bool ret = EINA_FALSE;
3344 Elm_Atspi_State_Set ss;
3346 eo_do(obj, ss = elm_interface_atspi_accessible_state_set_get());
3348 switch (rule->statematchtype)
3350 case ATSPI_Collection_MATCH_INVALID:
3353 case ATSPI_Collection_MATCH_ALL:
3354 ret = (ss & rule->states) == rule->states;
3356 case ATSPI_Collection_MATCH_ANY:
3357 ret = (ss & rule->states) > 0;
3359 case ATSPI_Collection_MATCH_NONE:
3360 ret = (ss & rule->states) == 0;
3370 _collection_match_roles_lookup(Eo *obj, struct collection_match_rule *rule)
3372 Eina_Bool ret = EINA_FALSE;
3373 Elm_Atspi_Role role;
3376 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
3381 role_set = rule->roles[1];
3384 role_set = rule->roles[0];
3388 ERR("Elm_Atspi_Role enum value exceeds 127. Unable to compare with roles bit field.");
3392 switch (rule->rolematchtype)
3394 case ATSPI_Collection_MATCH_INVALID:
3397 case ATSPI_Collection_MATCH_ALL:
3398 case ATSPI_Collection_MATCH_ANY:
3399 ret = (role_set & (1ULL << role)) > 0;
3401 case ATSPI_Collection_MATCH_NONE:
3402 ret = (role_set & (1ULL << role)) == 0;
3412 _collection_match_attributes_helper(Eina_List *obj_attribs, Eina_List *attribs, Eina_Bool compare, Eina_Bool ret_if_compare, Eina_Bool ret_default)
3415 Elm_Atspi_Attribute *attr, *attr2;
3417 EINA_LIST_FOREACH(attribs, l, attr)
3419 EINA_LIST_FOREACH(obj_attribs, l2, attr2)
3421 if ((attr->key && attr2->key &&
3422 attr->value && attr2->value &&
3423 !strcmp(attr->key, attr2->key) &&
3424 !strcmp(attr->value, attr2->value)) == compare)
3426 return ret_if_compare;
3435 _collection_match_attributes_lookup(Eo *obj, struct collection_match_rule *rule)
3437 Eina_Bool ret = EINA_FALSE;
3438 Eina_List *obj_attribs;
3440 eo_do(obj, obj_attribs = elm_interface_atspi_accessible_attributes_get());
3442 switch (rule->attributematchtype)
3444 case ATSPI_Collection_MATCH_INVALID:
3447 case ATSPI_Collection_MATCH_ALL:
3448 ret = _collection_match_attributes_helper(
3449 obj_attribs, rule->attributes, EINA_FALSE, EINA_FALSE, EINA_TRUE);
3451 case ATSPI_Collection_MATCH_ANY:
3452 ret = _collection_match_attributes_helper(
3453 obj_attribs, rule->attributes, EINA_TRUE, EINA_TRUE, EINA_FALSE);
3455 case ATSPI_Collection_MATCH_NONE:
3456 ret = _collection_match_attributes_helper(
3457 obj_attribs, rule->attributes, EINA_TRUE, EINA_FALSE, EINA_TRUE);
3463 elm_atspi_attributes_list_free(obj_attribs);
3469 _collection_sort_order_canonical(struct collection_match_rule *rule, Eina_List **ls,
3471 Eo *obj, long index, Eina_Bool flag,
3472 Eo *pobj, Eina_Bool recurse, Eina_Bool traverse)
3475 Eina_List *children;
3476 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
3477 long acount = eina_list_count(children);
3478 Eina_Bool prev = pobj ? EINA_TRUE : EINA_FALSE;
3480 for (; i < acount && (max == 0 || count < max); i++)
3482 Eo *child = eina_list_nth(children, i);
3484 if (prev && child == pobj)
3486 eina_list_free(children);
3490 if (flag && _collection_match_interfaces_lookup(child, rule)
3491 && _collection_match_states_lookup(child, rule)
3492 && _collection_match_roles_lookup(child, rule)
3493 && _collection_match_attributes_lookup(child, rule))
3495 *ls = eina_list_append(*ls, child);
3502 if (recurse && traverse)
3503 count = _collection_sort_order_canonical(rule, ls, count,
3504 max, child, 0, EINA_TRUE,
3505 pobj, recurse, traverse);
3507 eina_list_free(children);
3512 _collection_sort_order_reverse_canonical(struct collection_match_rule *rule, Eina_List **ls,
3513 int count, int max, Eo *obj, Eina_Bool flag, Eo *pobj)
3515 Eo *nextobj, *parent;
3517 Eina_List *children;
3519 /* This breaks us out of the recursion. */
3520 if (!obj || obj == pobj)
3525 /* Add to the list if it matches */
3526 if (flag && _collection_match_interfaces_lookup(obj, rule)
3527 && _collection_match_states_lookup(obj, rule)
3528 && _collection_match_roles_lookup(obj, rule)
3529 && _collection_match_attributes_lookup(obj, rule)
3530 && (max == 0 || count < max))
3532 *ls = eina_list_append(*ls, obj);
3539 /* Get the current nodes index in it's parent and the parent object. */
3541 indexinparent = elm_interface_atspi_accessible_index_in_parent_get(),
3542 parent = elm_interface_atspi_accessible_parent_get());
3544 if ((indexinparent > 0) && ((max == 0) || (count < max)))
3546 /* there are still some siblings to visit so get the previous sibling
3547 and get it's last descendant.
3548 First, get the previous sibling */
3549 eo_do(parent, children = elm_interface_atspi_accessible_children_get());
3550 nextobj = eina_list_nth(children, indexinparent - 1);
3551 eina_list_free(children);
3553 /* Now, drill down the right side to the last descendant */
3555 eo_do(nextobj, children = elm_interface_atspi_accessible_children_get());
3556 if (children) nextobj = eina_list_last_data_get(children);
3557 eina_list_free(children);
3560 /* recurse with the last descendant */
3561 count = _collection_sort_order_reverse_canonical(rule, ls, count, max,
3562 nextobj, EINA_TRUE, pobj);
3564 else if (max == 0 || count < max)
3566 /* no more siblings so next node must be the parent */
3567 count = _collection_sort_order_reverse_canonical(rule, ls, count, max,
3568 parent, EINA_TRUE, pobj);
3575 _collection_inbackorder(Eo *collection, struct collection_match_rule *rule, Eina_List **list,
3578 *list = eina_list_append(*list, obj);
3580 _collection_sort_order_reverse_canonical(rule, list, 0, max, obj, EINA_TRUE, collection);
3582 *list = eina_list_remove_list(*list, *list);
3588 _collection_inorder(Eo *collection, struct collection_match_rule *rule, Eina_List **list,
3589 int count, int max, Eo *obj, Eina_Bool traverse)
3593 count = _collection_sort_order_canonical(rule, list, count, max, obj, 0, EINA_TRUE, NULL, EINA_TRUE, traverse);
3595 while ((max == 0 || count < max) && obj && obj != collection)
3599 parent = elm_interface_atspi_accessible_parent_get(),
3600 idx = elm_interface_atspi_accessible_index_in_parent_get());
3601 count = _collection_sort_order_canonical(rule, list, count, max, parent,
3602 idx + 1, EINA_TRUE, NULL, EINA_TRUE, traverse);
3606 if (max == 0 || count < max)
3607 count = _collection_sort_order_canonical(rule, list, count, max,
3608 obj, idx + 1, EINA_TRUE, NULL, EINA_TRUE, traverse);
3614 _collection_query(struct collection_match_rule *rule, AtspiCollectionSortOrder sortby,
3615 Eina_List **list, int count, int max, Eo *obj, long index,
3616 Eina_Bool flag, Eo *pobj, Eina_Bool recurse, Eina_Bool traverse)
3620 case ATSPI_Collection_SORT_ORDER_CANONICAL:
3621 count = _collection_sort_order_canonical(rule, list, 0, max, obj, index, flag,
3622 pobj, recurse, traverse);
3624 case ATSPI_Collection_SORT_ORDER_REVERSE_CANONICAL:
3625 count = _collection_sort_order_canonical(rule, list, 0, max, obj, index, flag,
3626 pobj, recurse, traverse);
3627 *list = eina_list_reverse(*list);
3631 WRN("Unhandled sort method");
3637 static Eldbus_Message*
3638 _collection_return_msg_from_list(Elm_Atspi_Bridge *bridge, const Eldbus_Message *msg, const Eina_List *objs)
3640 Eldbus_Message *ret;
3642 Eldbus_Message_Iter *iter, *array_iter;
3645 ret = eldbus_message_method_return_new(msg);
3646 if (!ret) return NULL;
3648 iter = eldbus_message_iter_get(ret);
3649 array_iter = eldbus_message_iter_container_new(iter, 'a', "(so)");
3651 EINA_LIST_FOREACH(objs, l, obj)
3653 _bridge_object_register(bridge, obj);
3654 _bridge_iter_object_reference_append(bridge, array_iter, obj);
3657 eldbus_message_iter_container_close(iter, array_iter);
3662 _collection_get_matches_from_handle(Eo *collection, Eo *current, struct collection_match_rule *rule, AtspiCollectionSortOrder sortby, AtspiCollectionTreeTraversalType tree, int max, Eina_Bool traverse)
3664 Eina_List *result = NULL;
3670 case ATSPI_Collection_TREE_INORDER:
3671 _collection_inorder(collection, rule, &result, 0, max, current, traverse);
3672 if (sortby == ATSPI_Collection_SORT_ORDER_REVERSE_CANONICAL)
3673 result = eina_list_reverse(result);
3675 case ATSPI_Collection_TREE_RESTRICT_CHILDREN:
3677 idx = elm_interface_atspi_accessible_index_in_parent_get(),
3678 parent = elm_interface_atspi_accessible_parent_get());
3679 _collection_query(rule, sortby, &result, 0, max, parent, idx, EINA_FALSE, NULL, EINA_TRUE, traverse);
3681 case ATSPI_Collection_TREE_RESTRICT_SIBLING:
3682 _collection_query(rule, sortby, &result, 0, max, current, 0, EINA_FALSE, NULL, EINA_TRUE, traverse);
3685 ERR("Tree parameter value not handled");
3691 static Eldbus_Message*
3692 _collection_get_matches_from(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED)
3694 const char *obj_path = eldbus_message_path_get(msg);
3695 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
3696 Eo *current, *obj = _bridge_object_from_path(bridge, obj_path);
3697 Eldbus_Message *ret;
3698 Eldbus_Message_Iter *iter, *rule_iter;
3699 struct collection_match_rule rule;
3701 AtspiCollectionTreeTraversalType tree;
3703 AtspiCollectionSortOrder sortby;
3704 Eina_List *result = NULL;
3706 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
3708 iter = eldbus_message_iter_get(msg);
3709 EINA_SAFETY_ON_NULL_RETURN_VAL(iter, NULL);
3711 if (!eldbus_message_iter_arguments_get(iter, "o(aiia{ss}iaiiasib)uuib", &obj_path, &rule_iter, &sortby, &tree, &count, &traverse))
3713 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to get matchule, sortby, count or traverse values.");
3716 current = _bridge_object_from_path(bridge, obj_path);
3718 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(current, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
3720 if (!_collection_iter_match_rule_get(rule_iter, &rule))
3721 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Invalid match rule parameters.");
3723 result = _collection_get_matches_from_handle(obj, current, &rule, sortby, tree, count, traverse);
3724 ret = _collection_return_msg_from_list(bridge, msg, result);
3726 eina_list_free(result);
3727 _collection_match_rule_free(&rule);
3733 _collection_get_matches_to_handle(Eo *obj, Eo *current, struct collection_match_rule *rule, AtspiCollectionSortOrder sortby, AtspiCollectionTreeTraversalType tree, Eina_Bool limit, int max, Eina_Bool traverse)
3735 Eina_List *result = NULL;
3736 Eo *collection = obj;
3739 eo_do(obj, collection = elm_interface_atspi_accessible_parent_get());
3743 case ATSPI_Collection_TREE_INORDER:
3744 _collection_inbackorder(obj, rule, &result, max, current);
3745 if (sortby == ATSPI_Collection_SORT_ORDER_REVERSE_CANONICAL)
3746 result = eina_list_reverse(result);
3748 case ATSPI_Collection_TREE_RESTRICT_CHILDREN:
3749 _collection_query(rule, sortby, &result, 0, max, collection, 0, EINA_FALSE, current, EINA_TRUE, traverse);
3751 case ATSPI_Collection_TREE_RESTRICT_SIBLING:
3752 _collection_query(rule, sortby, &result, 0, max, collection, 0, EINA_FALSE, current, EINA_TRUE, traverse);
3755 ERR("Tree parameter value not handled");
3762 static Eldbus_Message*
3763 _collection_get_matches_to(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED)
3765 const char *obj_path = eldbus_message_path_get(msg);
3766 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
3767 Eo *current, *obj = _bridge_object_from_path(bridge, obj_path);
3768 Eldbus_Message *ret;
3769 Eldbus_Message_Iter *iter, *rule_iter;
3770 struct collection_match_rule rule;
3772 AtspiCollectionTreeTraversalType tree;
3774 AtspiCollectionSortOrder sortby;
3775 Eina_List *result = NULL;
3778 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
3780 iter = eldbus_message_iter_get(msg);
3781 EINA_SAFETY_ON_NULL_RETURN_VAL(iter, NULL);
3783 if (!eldbus_message_iter_arguments_get(iter, "o(aiia{ss}iaiiasib)uubib", &obj_path, &rule_iter, &sortby, &tree, &limit, &count, &traverse))
3785 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to get matchule, sortby, tree, limit count or traverse values.");
3788 current = _bridge_object_from_path(bridge, obj_path);
3790 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(current, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
3792 if (!_collection_iter_match_rule_get(rule_iter, &rule))
3793 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Invalid match rule parameters.");
3795 result = _collection_get_matches_to_handle(obj, current, &rule, sortby, tree, limit, count, traverse);
3796 ret = _collection_return_msg_from_list(bridge, msg, result);
3798 eina_list_free(result);
3799 _collection_match_rule_free(&rule);
3804 static Eldbus_Message*
3805 _collection_get_matches(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
3807 const char *obj_path = eldbus_message_path_get(msg);
3808 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
3809 Eo *obj = _bridge_object_from_path(bridge, obj_path);
3810 Eldbus_Message *ret;
3811 Eldbus_Message_Iter *iter, *rule_iter;
3812 struct collection_match_rule rule;
3815 AtspiCollectionSortOrder sortby;
3816 Eina_List *result = NULL;
3818 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
3820 iter = eldbus_message_iter_get(msg);
3821 EINA_SAFETY_ON_NULL_RETURN_VAL(iter, NULL);
3823 if (!eldbus_message_iter_arguments_get(iter, "(aiia{ss}iaiiasib)uib", &rule_iter, &sortby, &count, &traverse))
3825 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to get matchule, sortby, count or traverse values.");
3828 if (!_collection_iter_match_rule_get(rule_iter, &rule))
3829 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Invalid match rule parameters.");
3831 _collection_query(&rule, sortby, &result, 0, count, obj, 0, EINA_TRUE, NULL, EINA_TRUE, traverse);
3833 ret = _collection_return_msg_from_list(bridge, msg, result);
3835 eina_list_free(result);
3836 _collection_match_rule_free(&rule);
3841 static const Eldbus_Method collection_methods[] = {
3843 ELDBUS_ARGS({"o", "current_object"}, {"(aiia{ss}iaiiasib)", "match_rule"},
3844 {"u", "sortby"}, {"u", "tree"}, {"i", "count"}, {"b", "traverse"}),
3845 ELDBUS_ARGS({"a(so)", "objects"}), _collection_get_matches_from, 0 },
3847 ELDBUS_ARGS({"o", "current_object"}, {"(aiia{ss}iaiiasib)", "match_rule"},
3848 {"u", "sortby"}, {"u", "tree"}, {"b", "limit_scope"},
3849 {"i", "count"}, {"b", "traverse"}),
3850 ELDBUS_ARGS({"a(so)", "objects"}), _collection_get_matches_to, 0 },
3852 ELDBUS_ARGS({"(aiia{ss}iaiiasib)", "match_rule"},
3853 {"u", "sortby"}, {"i", "count"}, {"b", "traverse"}),
3854 ELDBUS_ARGS({"a(so)", "objects"}), _collection_get_matches, 0 },
3855 { NULL, NULL, NULL, NULL, 0 }
3858 static const Eldbus_Service_Interface_Desc collection_iface_desc = {
3859 ATSPI_DBUS_INTERFACE_COLLECTION, collection_methods, NULL, NULL, NULL, NULL
3863 _object_get_bus_name_and_path(Eo *bridge, const Eo *obj, const char **bus_name, const char **path)
3865 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
3867 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
3868 if (eo_isa(obj, ELM_ATSPI_PROXY_CLASS))
3870 const char *pbus = "", *ppath = ATSPI_DBUS_PATH_NULL;
3871 eo_do(obj, elm_obj_atspi_proxy_address_get(&pbus, &ppath));
3874 if (bus_name) *bus_name = pbus;
3875 if (path) *path = ppath;
3878 DBG("Invalid proxy address! Address not set before connecting/listening. Or after proxy is removed.");
3880 if (bus_name) *bus_name = eldbus_connection_unique_name_get(pd->a11y_bus);
3881 if (path) *path = _bridge_path_from_object(bridge, obj);
3886 _bridge_iter_object_reference_append(Eo *bridge, Eldbus_Message_Iter *iter, const Eo *obj)
3888 EINA_SAFETY_ON_NULL_RETURN(iter);
3890 const char *pbus = NULL, *ppath = NULL;
3891 _object_get_bus_name_and_path(bridge, obj, &pbus, &ppath);
3892 Eldbus_Message_Iter *iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
3893 eldbus_message_iter_basic_append(iter_struct, 's', pbus);
3894 eldbus_message_iter_basic_append(iter_struct, 'o', ppath);
3895 eldbus_message_iter_container_close(iter, iter_struct);
3899 _object_desktop_reference_append(Eldbus_Message_Iter *iter)
3901 Eldbus_Message_Iter *iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
3902 EINA_SAFETY_ON_NULL_RETURN(iter);
3904 eldbus_message_iter_basic_append(iter_struct, 's', ATSPI_DBUS_NAME_REGISTRY);
3905 eldbus_message_iter_basic_append(iter_struct, 'o', ATSPI_DBUS_PATH_ROOT);
3906 eldbus_message_iter_container_close(iter, iter_struct);
3910 _iter_interfaces_append(Eldbus_Message_Iter *iter, const Eo *obj)
3912 Eldbus_Message_Iter *iter_array;
3913 iter_array = eldbus_message_iter_container_new(iter, 'a', "s");
3914 if (!iter_array) return;
3916 if (eo_isa(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
3918 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_ACCESSIBLE);
3919 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_COLLECTION);
3921 if (eo_isa(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN))
3922 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_ACTION);
3923 if (eo_isa(obj, ELM_ATSPI_APP_OBJECT_CLASS))
3924 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_APPLICATION);
3925 if (eo_isa(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN))
3926 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_COMPONENT);
3927 if (eo_isa(obj, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE))
3928 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_EDITABLE_TEXT);
3929 if (eo_isa(obj, ELM_INTERFACE_ATSPI_IMAGE_MIXIN))
3930 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_IMAGE);
3931 if (eo_isa(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE))
3932 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_SELECTION);
3933 if (eo_isa(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE))
3934 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_TEXT);
3935 if (eo_isa(obj, ELM_INTERFACE_ATSPI_VALUE_INTERFACE))
3936 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_VALUE);
3938 eldbus_message_iter_container_close(iter, iter_array);
3942 _cache_item_reference_append_cb(Eo *bridge, Eo *data, Eldbus_Message_Iter *iter_array)
3944 if (!eo_ref_get(data) || eo_destructed_is(data))
3947 Eldbus_Message_Iter *iter_struct, *iter_sub_array;
3948 Elm_Atspi_State_Set states;
3949 Elm_Atspi_Role role;
3950 Eo *root = elm_atspi_bridge_root_get(bridge);
3952 eo_do(data, role = elm_interface_atspi_accessible_role_get());
3954 iter_struct = eldbus_message_iter_container_new(iter_array, 'r', NULL);
3955 EINA_SAFETY_ON_NULL_RETURN_VAL(iter_struct, EINA_TRUE);
3957 /* Marshall object path */
3958 _bridge_iter_object_reference_append(bridge, iter_struct, data);
3960 /* Marshall application */
3961 _bridge_iter_object_reference_append(bridge, iter_struct, root);
3964 eo_do(data, parent = elm_interface_atspi_accessible_parent_get());
3965 /* Marshall parent */
3966 if ((!parent) && (ELM_ATSPI_ROLE_APPLICATION == role))
3967 _object_desktop_reference_append(iter_struct);
3969 _bridge_iter_object_reference_append(bridge, iter_struct, parent);
3971 /* Marshall children */
3972 Eina_List *children_list = NULL, *l;
3975 //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
3976 Elm_Atspi_State_Set ss;
3977 eo_do(data, ss = elm_interface_atspi_accessible_state_set_get());
3979 iter_sub_array = eldbus_message_iter_container_new(iter_struct, 'a', "(so)");
3980 EINA_SAFETY_ON_NULL_GOTO(iter_sub_array, fail);
3982 //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
3983 if (!STATE_TYPE_GET(ss, ELM_ATSPI_STATE_MANAGES_DESCENDANTS))
3985 eo_do(data, children_list = elm_interface_atspi_accessible_children_get());
3987 EINA_LIST_FOREACH(children_list, l, child)
3988 _bridge_iter_object_reference_append(bridge, iter_sub_array, child);
3990 //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
3991 eina_list_free(children_list);
3995 eldbus_message_iter_container_close(iter_struct, iter_sub_array);
3997 /* Marshall interfaces */
3998 _iter_interfaces_append(iter_struct, data);
4001 const char *name = NULL;
4002 eo_do(data, name = elm_interface_atspi_accessible_name_get());
4006 eldbus_message_iter_basic_append(iter_struct, 's', name);
4009 eldbus_message_iter_basic_append(iter_struct, 'u', role);
4011 /* Marshall description */
4012 const char* descritpion = NULL;
4013 eo_do(data, descritpion = elm_interface_atspi_accessible_description_get());
4016 eldbus_message_iter_basic_append(iter_struct, 's', descritpion);
4018 /* Marshall state set */
4019 iter_sub_array = eldbus_message_iter_container_new(iter_struct, 'a', "u");
4020 EINA_SAFETY_ON_NULL_GOTO(iter_sub_array, fail);
4022 eo_do(data, states = elm_interface_atspi_accessible_state_set_get());
4024 unsigned int s1 = states & 0xFFFFFFFF;
4025 unsigned int s2 = (states >> 32) & 0xFFFFFFFF;
4026 eldbus_message_iter_basic_append(iter_sub_array, 'u', s1);
4027 eldbus_message_iter_basic_append(iter_sub_array, 'u', s2);
4029 eldbus_message_iter_container_close(iter_struct, iter_sub_array);
4030 eldbus_message_iter_container_close(iter_array, iter_struct);
4035 if (iter_struct) eldbus_message_iter_del(iter_struct);
4039 static Eldbus_Message *
4040 _cache_get_items(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
4042 Eldbus_Message_Iter *iter, *iter_array;
4043 Eldbus_Message *ret;
4044 Eina_List *to_process;
4047 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
4048 if (!bridge) return NULL;
4050 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, NULL);
4052 ret = eldbus_message_method_return_new(msg);
4053 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
4055 iter = eldbus_message_iter_get(ret);
4056 iter_array = eldbus_message_iter_container_new(iter, 'a', CACHE_ITEM_SIGNATURE);
4057 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
4059 eo_do(bridge, root = elm_obj_atspi_bridge_root_get());
4060 to_process = eina_list_append(NULL, root);
4064 Eo *obj = eina_list_data_get(to_process);
4065 to_process = eina_list_remove_list(to_process, to_process);
4066 _cache_item_reference_append_cb(bridge, obj, iter_array);
4067 _bridge_object_register(bridge, obj);
4069 Eina_List *children;
4070 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
4071 to_process = eina_list_merge(to_process, children);
4074 eldbus_message_iter_container_close(iter, iter_array);
4078 if (ret) eldbus_message_unref(ret);
4082 static const Eldbus_Method cache_methods[] = {
4083 { "GetItems", NULL, ELDBUS_ARGS({CACHE_ITEM_SIGNATURE, "items"}), _cache_get_items, 0 },
4084 { NULL, NULL, NULL, NULL, 0 }
4087 static const Eldbus_Signal cache_signals[] = {
4088 [ATSPI_OBJECT_CHILD_ADDED] = { "AddAccessible", ELDBUS_ARGS({"((so)(so)a(so)assusau)", "added"}), 0},
4089 [ATSPI_OBJECT_CHILD_REMOVED] = { "RemoveAccessible", ELDBUS_ARGS({ "(so)", "removed" }), 0},
4093 static const Eldbus_Service_Interface_Desc cache_iface_desc = {
4094 ATSPI_DBUS_INTERFACE_CACHE, cache_methods, cache_signals, NULL, NULL, NULL
4097 // Component interface
4098 static Eldbus_Message *
4099 _component_contains(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4101 const char *obj_path = eldbus_message_path_get(msg);
4102 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
4103 Eo *obj = _bridge_object_from_path(bridge, obj_path);
4105 Eina_Bool contains = EINA_FALSE;
4106 AtspiCoordType coord_type;
4107 Eldbus_Message *ret;
4109 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
4111 if (!eldbus_message_arguments_get(msg, "iiu", &x, &y, &coord_type))
4112 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
4114 Eina_Bool type = coord_type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
4115 eo_do(obj, contains = elm_interface_atspi_component_contains(type, x, y));
4117 ret = eldbus_message_method_return_new(msg);
4118 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
4120 eldbus_message_arguments_append(ret, "b", contains);
4125 static Eldbus_Message *
4126 _component_get_accessible_at_point(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4128 const char *obj_path = eldbus_message_path_get(msg);
4129 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
4130 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
4131 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, NULL);
4133 Eo *obj = _bridge_object_from_path(bridge, obj_path);
4135 Eo *accessible = NULL;
4136 AtspiCoordType coord_type;
4137 Eldbus_Message *ret;
4138 Eldbus_Message_Iter *iter;
4140 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
4142 // TIZEN_ONLY(20161213) - do not response if ecore evas is obscured
4143 const Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
4144 if (ecore_evas_obscured_get(ee))
4145 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "ecore evas is obscured.");
4148 if (!eldbus_message_arguments_get(msg, "iiu", &x, &y, &coord_type))
4149 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
4151 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
4152 Evas_Object *top = elm_object_top_widget_get(obj);
4155 eo_do(top, elm_interface_atspi_component_socket_offset_get(&sx, &sy));
4161 ret = eldbus_message_method_return_new(msg);
4162 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
4164 iter = eldbus_message_iter_get(ret);
4165 Eina_Bool type = coord_type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
4166 eo_do(obj, accessible = elm_interface_atspi_component_accessible_at_point_get(type, x, y));
4167 _bridge_iter_object_reference_append(bridge, iter, accessible);
4168 _bridge_object_register(bridge, accessible);
4173 // TIZEN_ONLY(20170310) - implementation of get object under coordinates for accessibility
4175 NEIGHBOR_SEARCH_MODE_NORMAL = 0,
4176 NEIGHBOR_SEARCH_MODE_RECURSE_FROM_ROOT = 1,
4177 NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING = 2,
4178 NEIGHBOR_SEARCH_MODE_RECURSE_TO_OUTSIDE = 3,
4179 } GetNeighborSearchMode;
4181 typedef struct accessibility_navigation_pointer_table {
4182 AtspiRole (*object_get_role)(struct accessibility_navigation_pointer_table *t, void *ptr);
4183 uint64_t (*object_get_state_set)(struct accessibility_navigation_pointer_table *t, void *ptr);
4184 void *(*get_object_in_relation_by_type)(struct accessibility_navigation_pointer_table *t, void *ptr, AtspiRelationType type);
4185 unsigned char (*object_is_zero_size)(struct accessibility_navigation_pointer_table *t, void *ptr);
4186 void *(*get_parent)(struct accessibility_navigation_pointer_table *t, void *ptr);
4187 unsigned char (*object_is_scrollable)(struct accessibility_navigation_pointer_table *t, void *ptr);
4188 void *(*get_object_at_point)(struct accessibility_navigation_pointer_table *t, void *ptr, int x, int y, unsigned char coordinates_are_screen_based);
4189 unsigned char (*object_contains)(struct accessibility_navigation_pointer_table *t, void *ptr, int x, int y, unsigned char coordinates_are_screen_based);
4190 unsigned char (*object_is_proxy)(struct accessibility_navigation_pointer_table *t, void *ptr);
4191 } accessibility_navigation_pointer_table;
4193 #define CALL(fncname, ...) table->fncname(table, __VA_ARGS__)
4194 static unsigned char _accept_object_check_role(accessibility_navigation_pointer_table *table EINA_UNUSED, void *obj)
4196 return _elm_widget_atspi_role_acceptable_check(obj);
4199 static unsigned char _state_set_is_set(uint64_t state_set, AtspiStateType state)
4201 return (state_set & ((uint64_t)1 << (unsigned int)state)) != 0;
4204 static unsigned char _object_is_defunct(accessibility_navigation_pointer_table *table, void *ptr)
4206 uint64_t states = CALL(object_get_state_set, ptr);
4207 return _state_set_is_set(states, ATSPI_STATE_DEFUNCT);
4210 static unsigned char _object_role_is_acceptable_when_navigating_next_prev(accessibility_navigation_pointer_table *table, void *obj)
4212 AtspiRole role = CALL(object_get_role, obj);
4213 return role != ATSPI_ROLE_POPUP_MENU && role != ATSPI_ROLE_DIALOG;
4216 static void *_get_object_in_relation_flow(accessibility_navigation_pointer_table *table, void *source, unsigned char forward)
4218 return CALL(get_object_in_relation_by_type, source, forward ? ATSPI_RELATION_FLOWS_TO : ATSPI_RELATION_FLOWS_FROM);
4221 static unsigned char _object_is_item(accessibility_navigation_pointer_table *table, void *obj)
4223 AtspiRole role = CALL(object_get_role, obj);
4224 return role == ATSPI_ROLE_LIST_ITEM || role == ATSPI_ROLE_MENU_ITEM;
4227 static unsigned char _object_is_highlightable(accessibility_navigation_pointer_table *table, void *obj)
4229 uint64_t state_set = CALL(object_get_state_set, obj);
4230 return _state_set_is_set(state_set, ATSPI_STATE_HIGHLIGHTABLE);
4233 static unsigned char _object_is_visible(accessibility_navigation_pointer_table *table, void *obj)
4235 uint64_t state_set = CALL(object_get_state_set, obj);
4236 return _state_set_is_set(state_set, ATSPI_STATE_VISIBLE);
4239 static unsigned char _object_is_showing(accessibility_navigation_pointer_table *table, void *obj)
4241 uint64_t state_set = CALL(object_get_state_set, obj);
4242 return _state_set_is_set(state_set, ATSPI_STATE_SHOWING);
4245 static unsigned char _object_is_collapsed(accessibility_navigation_pointer_table *table, void *obj)
4247 uint64_t state_set = CALL(object_get_state_set, obj);
4249 _state_set_is_set(state_set, ATSPI_STATE_EXPANDABLE) &&
4250 !_state_set_is_set(state_set, ATSPI_STATE_EXPANDED);
4253 static unsigned char _object_has_modal_state(accessibility_navigation_pointer_table *table, void *obj)
4255 uint64_t state_set = CALL(object_get_state_set, obj);
4256 return _state_set_is_set(state_set, ATSPI_STATE_MODAL);
4259 static unsigned char _object_is_zero_size(accessibility_navigation_pointer_table *table, void *obj)
4261 return CALL(object_is_zero_size, obj);
4264 static void *_get_scrollable_parent(accessibility_navigation_pointer_table *table, void *obj)
4268 obj = CALL(get_parent, obj);
4269 if (obj && CALL(object_is_scrollable, obj)) return obj;
4273 static unsigned char _accept_object(accessibility_navigation_pointer_table *table, void *obj)
4276 if (!_object_is_visible(table, obj)) return 0;
4277 if (!_accept_object_check_role(table, obj)) return 0;
4278 if (CALL(get_object_in_relation_by_type, obj, ATSPI_RELATION_CONTROLLED_BY) != NULL) return 0;
4279 if (!_object_is_highlightable(table, obj)) return 0;
4281 if (_get_scrollable_parent(table, obj) != NULL)
4283 void *parent = CALL(get_parent, obj);
4287 return !_object_is_item(table, obj) || !_object_is_collapsed(table, parent);
4292 if (_object_is_zero_size(table, obj)) return 0;
4293 if (!_object_is_showing(table, obj)) return 0;
4298 static void *_calculate_navigable_accessible_at_point_impl(accessibility_navigation_pointer_table *table,
4299 void *root, int x, int y, unsigned char coordinates_are_screen_based)
4301 if (!root) return NULL;
4303 void *return_value = NULL;
4306 void *target = CALL(get_object_at_point, root, x, y, coordinates_are_screen_based);
4309 // always return proxy, so atspi lib can call on it again
4310 if (CALL(object_is_proxy, target)) return target;
4313 void *relation_obj = CALL(get_object_in_relation_by_type, root, ATSPI_RELATION_CONTROLLED_BY);
4314 unsigned char contains = 0;
4317 contains = CALL(object_contains, relation_obj, x, y, coordinates_are_screen_based);
4318 if (contains) root = relation_obj;
4321 if (_accept_object(table, root))
4323 return_value = root;
4324 if (contains) break;
4328 if (return_value && _object_has_modal_state(table, return_value)) return_value = NULL;
4329 return return_value;
4332 static void *_find_non_defunct_child(accessibility_navigation_pointer_table *table,
4333 Eina_List *children, unsigned int current_index, unsigned char forward)
4335 unsigned int children_count = eina_list_count(children);
4336 for(; current_index < children_count; forward ? ++current_index : --current_index)
4338 void *n = eina_list_nth(children, current_index);
4339 if (n && !_object_is_defunct(table, n)) return n;
4344 static void *_directional_depth_first_search_try_non_defunct_child(accessibility_navigation_pointer_table *table,
4345 void *node, Eina_List *children, unsigned char forward)
4347 unsigned int children_count = eina_list_count(children);
4348 if (children_count > 0)
4350 unsigned char is_showing = _get_scrollable_parent(table, node) == NULL ? _object_is_showing(table, node) : 1;
4353 return _find_non_defunct_child(table, children, forward ? 0 : children_count - 1, forward);
4359 static Eina_List *_scrollable_parent_list_get(Eo *obj)
4361 Eina_List *ret = NULL;
4366 eo_do(obj, parent = elm_interface_atspi_accessible_parent_get());
4369 if (eo_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
4371 ret = eina_list_append(ret, parent);
4373 eo_do(parent, parent = elm_interface_atspi_accessible_parent_get());
4380 static void _viewport_geometry_get(Eo *obj, int *x, int *y, int *w, int *h)
4382 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get(x, y, w, h));
4383 /* widget implements scrollable interface but does not use scoller
4384 in this case, use widget geometry */
4385 if (*w == 0 || *h == 0)
4387 INF("%s is zero sized content viewport", eo_class_name_get(eo_class_get(obj)));
4388 eo_do(obj, elm_interface_atspi_component_extents_get(EINA_FALSE, x, y, w, h));
4393 _new_scrollable_parent_viewport_geometry_get(Eo *node, Eo *start,
4394 int *x, int *y, int *w, int *h)
4396 Eina_Bool ret = EINA_FALSE;
4400 n_spl = _scrollable_parent_list_get(node);
4401 s_spl = _scrollable_parent_list_get(start);
4405 EINA_LIST_FOREACH(s_spl, l, sp)
4407 n_spl = eina_list_remove(n_spl, sp);
4410 Evas_Coord sx = 0, sy = 0, sw = 0, sh = 0;
4412 unsigned int count = eina_list_count(n_spl);
4415 sp = eina_list_nth(n_spl, count - 1);
4416 _viewport_geometry_get(sp, &sx, &sy, &sw, &sh);
4428 static Eina_List *_valid_children_get(Eina_List *children, Eo *start, Eo *root)
4430 /* condition to find first(last) object regardless of scrollable parent.
4431 looping navigation does not care scrollable parent.
4432 1. currently highlighted object exists
4433 2. both start and root are same */
4434 Eo *current = _elm_object_accessibility_currently_highlighted_get();
4435 if (current && start == root) return children;
4438 child = eina_list_nth(children, 0);
4442 Evas_Coord x = 0, y = 0, w = 0, h = 0;
4443 Evas_Coord sx = 0, sy = 0, sw = 0, sh = 0;
4445 if (_new_scrollable_parent_viewport_geometry_get(child, start,
4446 &sx, &sy, &sw, &sh))
4448 Eina_List *l, *l_next;
4449 EINA_LIST_FOREACH_SAFE(children, l, l_next, child)
4452 elm_interface_atspi_component_extents_get(EINA_FALSE,
4454 if (w == 0 || h == 0 ||
4455 !ELM_RECTS_INTERSECT(x, y, w, h, sx, sy, sw, sh))
4456 children = eina_list_remove_list(children, l);
4463 static void *_get_next_non_defunct_sibling(accessibility_navigation_pointer_table *table,
4464 void *obj, void *start, void *root, unsigned char forward)
4466 if (!obj) return NULL;
4467 void *parent = CALL(get_parent, obj);
4468 if (!parent) return NULL;
4470 Eina_List *children;
4471 eo_do(parent, children = elm_interface_atspi_accessible_children_get());
4472 children = _valid_children_get(children, start, root);
4474 unsigned int children_count = eina_list_count(children);
4475 if (children_count == 0)
4477 eina_list_free(children);
4480 unsigned int current = 0;
4481 for(; current < children_count && eina_list_nth(children, current) != obj; ++current) ;
4482 if (current >= children_count)
4484 eina_list_free(children);
4487 forward ? ++current : --current;
4488 void *ret = _find_non_defunct_child(table, children, current, forward);
4489 eina_list_free(children);
4494 _directional_depth_first_search_try_non_defunct_sibling(accessibility_navigation_pointer_table *table,
4495 unsigned char *all_children_visited_ptr,
4496 void *node, void *start, void *root,
4497 unsigned char forward)
4501 void *sibling = _get_next_non_defunct_sibling(table, node, start, root, forward);
4502 if (sibling != NULL)
4505 *all_children_visited_ptr = 0;
4510 node = CALL(get_parent, node);
4511 if (node == NULL || node == root) return NULL;
4513 // in backward traversing stop the walk up on parent
4514 if (!forward) break;
4521 unsigned int current_search_size;
4522 unsigned int counter;
4523 } cycle_detection_data;
4525 void cycle_detection_initialize(cycle_detection_data *data, const void *key)
4529 data->current_search_size = 1;
4533 unsigned char cycle_detection_check_if_in_cycle(cycle_detection_data *data, const void *key)
4535 if (!data) return 1;
4536 if (data->key == key) return 1;
4537 if (--data->counter == 0)
4539 data->current_search_size <<= 1;
4540 if (data->current_search_size == 0) return 1;
4541 data->counter = data->current_search_size;
4550 if (eo_isa(obj, ELM_ACCESS_CLASS))
4552 Elm_Access_Info *info;
4554 info = _elm_access_info_get(obj);
4555 if (info && eo_isa(info->part_object, ELM_LAYOUT_CLASS))
4557 Eina_List *attrs, *l;
4558 Elm_Atspi_Attribute *attr;
4560 eo_do(info->part_object,
4561 attrs = elm_interface_atspi_accessible_attributes_get());
4562 EINA_LIST_FOREACH(attrs, l, attr)
4564 if (!strcmp(attr->key, "___PlugID"))
4566 elm_atspi_attributes_list_free(attrs);
4570 elm_atspi_attributes_list_free(attrs);
4577 _proxy_in_parent_get(Eo *obj)
4581 Eina_List *children_list = NULL;
4582 eo_do(obj, children_list = elm_interface_atspi_accessible_children_get());
4585 EINA_LIST_FOREACH(children_list, l, child)
4587 if (eo_isa(child, ELM_ATSPI_PROXY_CLASS))
4593 eina_list_free(children_list);
4599 _deputy_of_proxy_in_parent_get(Eo *obj)
4603 Eina_List *children_list = NULL;
4604 eo_do(obj, children_list = elm_interface_atspi_accessible_children_get());
4606 unsigned int index = 0;
4608 EINA_LIST_FOREACH(children_list, l, child)
4610 if (eo_isa(child, ELM_ATSPI_PROXY_CLASS))
4614 WRN("Proxy does not have deputy object");
4618 deputy = eina_list_nth(children_list, index - 1);
4623 eina_list_free(children_list);
4628 static void *_calculate_neighbor_impl(accessibility_navigation_pointer_table *table, void *root, void *start, unsigned char forward, GetNeighborSearchMode search_mode)
4630 if (root && _object_is_defunct(table, root)) return NULL;
4631 if (start && _object_is_defunct(table, start))
4637 if (search_mode == NEIGHBOR_SEARCH_MODE_RECURSE_TO_OUTSIDE)
4639 /* This only works if we navigate backward, and it is not possible to
4640 find in embedded process. In this case the deputy should be used */
4641 return _deputy_of_proxy_in_parent_get(start);
4644 void *node = start ? start : root;
4645 if (!node) return NULL;
4647 // initialization of all-children-visited flag for start node - we assume
4648 // that when we begin at start node and we navigate backward, then all children
4649 // are visited, so navigation will ignore start's children and go to
4650 // previous sibling available.
4651 /* Regarding condtion (start != root):
4652 The last object can be found only if all_children_visited is false.
4653 The start is same with root, when looking for the last object. */
4654 unsigned char all_children_visited = (start != root) && (search_mode != NEIGHBOR_SEARCH_MODE_RECURSE_FROM_ROOT && !forward);
4656 // true, if starting element should be ignored. this is only used in rare case of
4657 // recursive search failing to find an object.
4658 // consider tree, where element A on bus BUS_A has child B on bus BUS_B. when going "next" from
4659 // element A algorithm has to descend into BUS_B and search element B and its children. this is done
4660 // by returning to our caller object B with special flag set (meaning - continue the search from B on bus BUS_B).
4661 // if next object will be found there (on BUS_B), then search ends. but if not, then our caller will find it out
4662 // and will call us again with object A and flag search_mode set to NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING.
4663 // this flag means, that object A was already checked previously and we should skip it and its children.
4664 unsigned char force_next = (search_mode == NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING);
4666 cycle_detection_data cycle_detection;
4667 cycle_detection_initialize(&cycle_detection, node);
4670 if (_object_is_defunct(table, node)) return NULL;
4672 // always accept proxy object from different world
4673 if (!force_next && CALL(object_is_proxy, node)) return node;
4675 Eina_List *children;
4676 eo_do(node, children = elm_interface_atspi_accessible_children_get());
4677 children = _valid_children_get(children, start, root);
4680 // 1. not start node
4681 // 2. parent after all children in backward traversing
4682 // 3. Nodes with roles: ATSPI_ROLE_PAGE_TAB, ATSPI_ROLE_POPUP_MENU and ATSPI_ROLE_DIALOG, only when looking for first or last element.
4683 // Objects with those roles shouldnt be reachable, when navigating next / prev.
4684 unsigned char all_children_visited_or_moving_forward = (eina_list_count(children) == 0 || forward || all_children_visited);
4685 if (!force_next && node != start && all_children_visited_or_moving_forward && _accept_object(table, node))
4687 if (start == NULL || _object_role_is_acceptable_when_navigating_next_prev(table, node))
4689 eina_list_free(children);
4694 void *next_related_in_direction = !force_next ? _get_object_in_relation_flow(table, node, forward) : NULL;
4696 /* force_next means that the search_mode is NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING
4697 in this case the node is elm_layout which is parent of proxy object.
4698 There is an access object working for the proxy object, and the access
4699 object could have relation information. This relation information should
4700 be checked first before using the elm_layout as a node. */
4701 if (force_next && forward)
4704 deputy = _deputy_of_proxy_in_parent_get(node);
4705 next_related_in_direction =
4706 _get_object_in_relation_flow(table, deputy, forward);
4709 if (next_related_in_direction && _object_is_defunct(table, next_related_in_direction))
4710 next_related_in_direction = NULL;
4711 unsigned char want_cycle_detection = 0;
4712 if (next_related_in_direction)
4714 /* Check next_related_in_direction is deputy object */
4718 /* If the prev object is deputy, then go to inside of its proxy first */
4719 if (_deputy_is(next_related_in_direction))
4721 parent = elm_widget_parent_get(next_related_in_direction);
4722 next_related_in_direction =
4723 _proxy_in_parent_get(parent);
4728 /* If current object is deputy, and it has relation next object,
4729 then do not use the relation next object, and use proxy first */
4730 if (_deputy_is(node))
4732 parent = elm_widget_parent_get(node);
4733 next_related_in_direction =
4734 _proxy_in_parent_get(parent);
4738 node = next_related_in_direction;
4739 want_cycle_detection = 1;
4742 void *child = !force_next && !all_children_visited ?
4743 _directional_depth_first_search_try_non_defunct_child(table, node, children, forward) : NULL;
4744 if (child != NULL) want_cycle_detection = 1;
4747 if (!force_next && node == root)
4749 eina_list_free(children);
4752 all_children_visited = 1;
4753 child = _directional_depth_first_search_try_non_defunct_sibling(table, &all_children_visited, node, start, root, forward);
4759 if (want_cycle_detection && cycle_detection_check_if_in_cycle(&cycle_detection, node))
4761 eina_list_free(children);
4764 eina_list_free(children);
4769 typedef struct accessibility_navigation_pointer_table_impl {
4770 accessibility_navigation_pointer_table ptrs;
4772 } accessibility_navigation_pointer_table_impl;
4774 static AtspiRole _object_get_role_impl(struct accessibility_navigation_pointer_table *table EINA_UNUSED, void *ptr)
4776 Elm_Atspi_Role role;
4778 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
4779 return _elm_role_to_atspi_role(role);
4782 static uint64_t _object_get_state_set_impl(struct accessibility_navigation_pointer_table *table EINA_UNUSED, void *ptr)
4784 Elm_Atspi_State_Set states;
4786 eo_do(obj, states = elm_interface_atspi_accessible_state_set_get());
4787 return _elm_atspi_state_set_to_atspi_state_set(states);
4790 static void *_get_object_in_relation_by_type_impl(struct accessibility_navigation_pointer_table *table EINA_UNUSED, void *ptr, AtspiRelationType type)
4794 const Eo *source = ptr;
4795 Elm_Atspi_Relation_Set relations;
4796 Elm_Atspi_Relation_Type expected_relation_type = _atspi_relation_to_elm_relation(type);
4797 eo_do(source, relations = elm_interface_atspi_accessible_relation_set_get());
4798 Elm_Atspi_Relation *rel;
4800 EINA_LIST_FOREACH(relations, l, rel)
4802 if (rel->type == expected_relation_type)
4804 Eina_List *last = eina_list_last(rel->objects);
4805 return eina_list_data_get(last);
4812 static unsigned char _object_is_zero_size_impl(struct accessibility_navigation_pointer_table *table EINA_UNUSED, void *ptr)
4816 eo_do(obj, elm_interface_atspi_component_extents_get(EINA_TRUE, &x, &y, &w, &h));
4817 return w == 0 || h == 0;
4820 unsigned char _object_is_scrollable_impl(struct accessibility_navigation_pointer_table *table EINA_UNUSED, void *ptr)
4823 return eo_isa(obj, ELM_INTERFACE_SCROLLABLE_MIXIN);
4826 void *_get_parent_impl(struct accessibility_navigation_pointer_table *table EINA_UNUSED, void *ptr)
4828 Eo *obj = (Eo*)ptr, *ret_obj;
4829 eo_do(obj, ret_obj = elm_interface_atspi_accessible_parent_get());
4833 void *_get_object_at_point_impl(struct accessibility_navigation_pointer_table *table EINA_UNUSED, void *ptr, int x, int y, unsigned char coordinates_are_screen_based)
4835 Eo *obj = (Eo*)ptr, *target;
4836 eo_do(obj, target = elm_interface_atspi_component_accessible_at_point_get(coordinates_are_screen_based, x, y));
4840 unsigned char _object_contains_impl(struct accessibility_navigation_pointer_table *table EINA_UNUSED, void *ptr, int x, int y, unsigned char coordinates_are_screen_based)
4843 Eina_Bool return_value;
4844 eo_do(obj, return_value = elm_interface_atspi_component_contains(coordinates_are_screen_based, x, y));
4845 return return_value ? 1 : 0;
4848 unsigned char _object_is_proxy_impl(struct accessibility_navigation_pointer_table *table_, void *obj)
4850 accessibility_navigation_pointer_table_impl *table = (accessibility_navigation_pointer_table_impl*)table_;
4851 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(table->bridge, pd, 0);
4852 const char *our_bus_name = eldbus_connection_unique_name_get(pd->a11y_bus);
4853 const char *obj_bus_name;
4854 _object_get_bus_name_and_path(table->bridge, (Eo*)obj, &obj_bus_name, NULL);
4855 return our_bus_name && obj_bus_name && strcmp(our_bus_name, obj_bus_name) != 0;
4858 accessibility_navigation_pointer_table_impl construct_accessibility_navigation_pointer_table(Eo *bridge)
4860 accessibility_navigation_pointer_table_impl table;
4861 #define INIT(n) table.ptrs.n = _## n ## _impl
4862 INIT(object_get_role);
4863 INIT(object_get_state_set);
4864 INIT(get_object_in_relation_by_type);
4865 INIT(object_is_zero_size);
4867 INIT(object_is_scrollable);
4868 INIT(get_object_at_point);
4869 INIT(object_contains);
4870 INIT(object_is_proxy);
4872 table.bridge = bridge;
4877 static Eo *_calculate_navigable_accessible_at_point(Eo *bridge, Eo *root, Eina_Bool coord_type, int x, int y)
4879 accessibility_navigation_pointer_table_impl table = construct_accessibility_navigation_pointer_table(bridge);
4880 Eo *result = (Eo*)_calculate_navigable_accessible_at_point_impl(&table.ptrs, root, x, y, coord_type ? 1 : 0);
4884 static Eo *_calculate_neighbor(Eo *bridge, Eo *root, Eo *start, Eina_Bool forward, int search_mode)
4886 accessibility_navigation_pointer_table_impl table = construct_accessibility_navigation_pointer_table(bridge);
4887 Eo *result = (Eo*)_calculate_neighbor_impl(&table.ptrs, root, start, forward ? 1 : 0, (GetNeighborSearchMode)search_mode);
4893 static Eldbus_Message *
4894 _component_get_extents(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4896 const char *obj_path = eldbus_message_path_get(msg);
4897 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
4898 Eo *obj = _bridge_object_from_path(bridge, obj_path);
4900 AtspiCoordType coord_type;
4901 Eldbus_Message *ret;
4902 Eldbus_Message_Iter *iter, *iter_struct;
4904 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
4906 if (!eldbus_message_arguments_get(msg, "u", &coord_type))
4907 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
4909 ret = eldbus_message_method_return_new(msg);
4910 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
4912 iter = eldbus_message_iter_get(ret);
4914 Eina_Bool type = coord_type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
4915 eo_do(obj, elm_interface_atspi_component_extents_get(type, &x, &y, &w, &h));
4916 iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
4917 EINA_SAFETY_ON_NULL_GOTO(iter_struct, fail);
4919 eldbus_message_iter_basic_append(iter_struct, 'i', x);
4920 eldbus_message_iter_basic_append(iter_struct, 'i', y);
4921 eldbus_message_iter_basic_append(iter_struct, 'i', w);
4922 eldbus_message_iter_basic_append(iter_struct, 'i', h);
4924 eldbus_message_iter_container_close(iter, iter_struct);
4928 if (ret) eldbus_message_unref(ret);
4932 static Eldbus_Message *
4933 _component_get_position(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4935 const char *obj_path = eldbus_message_path_get(msg);
4936 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
4937 Eo *obj = _bridge_object_from_path(bridge, obj_path);
4939 AtspiCoordType coord_type;
4940 Eldbus_Message *ret;
4942 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
4944 if (!eldbus_message_arguments_get(msg, "u", &coord_type))
4945 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
4947 Eina_Bool type = coord_type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
4948 eo_do(obj, elm_interface_atspi_component_position_get(type, &x, &y));
4950 ret = eldbus_message_method_return_new(msg);
4951 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
4953 eldbus_message_arguments_append(ret, "i", x);
4954 eldbus_message_arguments_append(ret, "i", y);
4959 static Eldbus_Message *
4960 _component_get_size(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4962 const char *obj_path = eldbus_message_path_get(msg);
4963 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
4964 Eo *obj = _bridge_object_from_path(bridge, obj_path);
4966 Eldbus_Message *ret;
4968 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
4970 eo_do(obj, elm_interface_atspi_component_size_get(&x, &y));
4972 ret = eldbus_message_method_return_new(msg);
4973 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
4975 eldbus_message_arguments_append(ret, "i", x);
4976 eldbus_message_arguments_append(ret, "i", y);
4981 static AtspiComponentLayer
4982 _elm_layer_2_atspi_layer(int layer)
4984 if (layer <= ELM_OBJECT_LAYER_BACKGROUND) return ATSPI_LAYER_CANVAS;
4985 if (layer < ELM_OBJECT_LAYER_FOCUS) return ATSPI_LAYER_WIDGET;
4986 if (layer <= ELM_OBJECT_LAYER_TOOLTIP) return ATSPI_LAYER_POPUP;
4988 return ATSPI_LAYER_OVERLAY;
4991 static Eldbus_Message *
4992 _component_get_layer(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4994 const char *obj_path = eldbus_message_path_get(msg);
4995 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
4996 Eo *obj = _bridge_object_from_path(bridge, obj_path);
4998 Eldbus_Message *ret;
4999 AtspiComponentLayer atspi_layer;
5001 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
5003 eo_do(obj, layer = elm_interface_atspi_component_layer_get());
5005 ret = eldbus_message_method_return_new(msg);
5006 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
5008 atspi_layer = _elm_layer_2_atspi_layer(layer);
5009 eldbus_message_arguments_append(ret, "u", atspi_layer);
5014 static Eldbus_Message *
5015 _component_grab_focus(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5017 const char *obj_path = eldbus_message_path_get(msg);
5018 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
5019 Eo *obj = _bridge_object_from_path(bridge, obj_path);
5020 Eldbus_Message *ret;
5021 Eina_Bool focus = EINA_FALSE;
5024 return _dbus_invalid_ref_error_new(msg);
5026 eo_do(obj, focus = elm_interface_atspi_component_focus_grab());
5028 ret = eldbus_message_method_return_new(msg);
5029 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
5031 eldbus_message_arguments_append(ret, "b", focus);
5036 //TIZEN_ONLY(20160329): atspi: implement HighlightGrab and HighlightClear methods (29e253e2f7ef3c632ac3a64c489bf569df407f30)
5037 static Eldbus_Message *
5038 _component_grab_highlight(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5040 const char *obj_path = eldbus_message_path_get(msg);
5041 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
5042 Eo *obj = _bridge_object_from_path(bridge, obj_path);
5043 Eldbus_Message *ret;
5044 Eina_Bool highlight = EINA_FALSE;
5046 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
5048 eo_do(obj, highlight = elm_interface_atspi_component_highlight_grab());
5050 ret = eldbus_message_method_return_new(msg);
5051 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
5053 eldbus_message_arguments_append(ret, "b", highlight);
5058 static Eldbus_Message *
5059 _component_clear_highlight(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5061 const char *obj_path = eldbus_message_path_get(msg);
5062 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
5063 Eo *obj = _bridge_object_from_path(bridge, obj_path);
5064 Eldbus_Message *ret;
5065 Eina_Bool highlight = EINA_FALSE;
5067 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
5069 eo_do(obj, highlight = elm_interface_atspi_component_highlight_clear());
5071 ret = eldbus_message_method_return_new(msg);
5072 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
5074 eldbus_message_arguments_append(ret, "b", highlight);
5080 static Eldbus_Message *
5081 _component_get_alpha(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5083 const char *obj_path = eldbus_message_path_get(msg);
5084 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
5085 Eo *obj = _bridge_object_from_path(bridge, obj_path);
5086 Eldbus_Message *ret;
5090 return _dbus_invalid_ref_error_new(msg);
5092 eo_do(obj, alpha = elm_interface_atspi_component_alpha_get());
5094 ret = eldbus_message_method_return_new(msg);
5095 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
5097 eldbus_message_arguments_append(ret, "d", alpha);
5102 static Eldbus_Message *
5103 _component_set_extends(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5105 const char *obj_path = eldbus_message_path_get(msg);
5106 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
5107 Eo *obj = _bridge_object_from_path(bridge, obj_path);
5109 AtspiCoordType coord_type;
5110 Eldbus_Message *ret;
5111 Eina_Bool result = EINA_FALSE;
5113 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
5115 if (!eldbus_message_arguments_get(msg, "iiiiu", &x, &y, &w, &h, &coord_type))
5116 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
5118 Eina_Bool type = coord_type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
5119 eo_do(obj, result = elm_interface_atspi_component_extents_set(type, x, y, w, h));
5121 ret = eldbus_message_method_return_new(msg);
5122 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
5124 eldbus_message_arguments_append(ret, "b", result);
5129 static Eldbus_Message *
5130 _component_set_position(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5132 const char *obj_path = eldbus_message_path_get(msg);
5133 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
5134 Eo *obj = _bridge_object_from_path(bridge, obj_path);
5136 Eina_Bool result = EINA_FALSE;
5137 AtspiCoordType coord_type;
5138 Eldbus_Message *ret;
5140 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
5142 if (!eldbus_message_arguments_get(msg, "iiu", &x, &y, &coord_type))
5143 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
5145 Eina_Bool type = coord_type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
5146 eo_do(obj, result = elm_interface_atspi_component_position_set(type, x, y));
5148 ret = eldbus_message_method_return_new(msg);
5149 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
5151 eldbus_message_arguments_append(ret, "b", result);
5156 static Eldbus_Message *
5157 _component_set_size(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5159 const char *obj_path = eldbus_message_path_get(msg);
5160 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
5161 Eo *obj = _bridge_object_from_path(bridge, obj_path);
5164 Eldbus_Message *ret;
5166 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
5168 if (!eldbus_message_arguments_get(msg, "ii", &w, &h))
5169 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
5171 eo_do(obj, result = elm_interface_atspi_component_size_set(w, h));
5173 ret = eldbus_message_method_return_new(msg);
5174 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
5176 eldbus_message_arguments_append(ret, "b", result);
5181 static const Eldbus_Method component_methods[] = {
5182 { "Contains", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"u", "coord_type"}), ELDBUS_ARGS({"b", "contains"}), _component_contains, 0 },
5183 { "GetAccessibleAtPoint", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"u", "coord_type"}), ELDBUS_ARGS({"(so)", "accessible"}), _component_get_accessible_at_point, 0 },
5184 { "GetExtents", ELDBUS_ARGS({"u", "coord_type"}), ELDBUS_ARGS({"(iiii)", "extents"}), _component_get_extents, 0 },
5185 { "GetPosition", ELDBUS_ARGS({"u", "coord_type"}), ELDBUS_ARGS({"i", "x"}, {"i","y"}), _component_get_position, 0 },
5186 { "GetSize", NULL, ELDBUS_ARGS({"i", "w"}, {"i", "h"}), _component_get_size, 0 },
5187 { "GetLayer", NULL, ELDBUS_ARGS({"u", "layer"}), _component_get_layer, 0 },
5188 // { "GetMDIZOrder", NULL, ELDBUS_ARGS({"n", "MDIZOrder"}), _component_get_mdizorder, 0 },
5189 { "GrabFocus", NULL, ELDBUS_ARGS({"b", "focus"}), _component_grab_focus, 0 },
5190 { "GetAlpha", NULL, ELDBUS_ARGS({"d", "alpha"}), _component_get_alpha, 0 },
5191 { "SetExtents", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"i", "width"}, {"i", "height"}, {"u", "coord_type"}), ELDBUS_ARGS({"b", "result"}), _component_set_extends, 0 },
5192 { "SetPosition", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"u", "coord_type"}), ELDBUS_ARGS({"b", "result"}), _component_set_position, 0 },
5193 { "SetSize", ELDBUS_ARGS({"i", "width"}, {"i", "height"}), ELDBUS_ARGS({"b", "result"}), _component_set_size, 0 },
5195 //TIZEN_ONLY(20160329): atspi: implement HighlightGrab and HighlightClear methods (29e253e2f7ef3c632ac3a64c489bf569df407f30)
5196 { "GrabHighlight", NULL, ELDBUS_ARGS({"b", "result"}), _component_grab_highlight, 0 },
5197 { "ClearHighlight", NULL, ELDBUS_ARGS({"b", "result"}), _component_clear_highlight, 0 },
5199 { NULL, NULL, NULL, NULL, 0 }
5202 static const Eldbus_Service_Interface_Desc component_iface_desc = {
5203 ATSPI_DBUS_INTERFACE_COMPONENT, component_methods, NULL, NULL, NULL, NULL
5207 _on_elm_atspi_bridge_app_register(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
5209 const char *errname, *errmsg;
5211 if (eldbus_message_error_get(msg, &errname, &errmsg))
5213 ERR("%s %s", errname, errmsg);
5216 DBG("Application successfuly registered at ATSPI2 bus.");
5220 _elm_atspi_bridge_app_register(Eo *bridge)
5222 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE);
5224 Eldbus_Message *message = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY,
5225 ATSPI_DBUS_PATH_ROOT,
5226 ATSPI_DBUS_INTERFACE_SOCKET,
5228 Eldbus_Message_Iter *iter = eldbus_message_iter_get(message);
5230 _bridge_iter_object_reference_append(bridge, iter, elm_atspi_bridge_root_get(bridge));
5231 eldbus_connection_send(pd->a11y_bus, message, _on_elm_atspi_bridge_app_register, NULL, -1);
5237 _elm_atspi_bridge_app_unregister(Eo *bridge)
5240 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE);
5242 root = elm_atspi_bridge_root_get(bridge);
5244 Eldbus_Message *message = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY,
5245 ATSPI_DBUS_PATH_ROOT,
5246 ATSPI_DBUS_INTERFACE_SOCKET,
5248 Eldbus_Message_Iter *iter = eldbus_message_iter_get(message);
5250 _bridge_iter_object_reference_append(bridge, iter, root);
5251 eldbus_connection_send(pd->a11y_bus, message, NULL, NULL, -1);
5257 _cache_register(Eo *obj)
5259 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(obj, pd);
5260 pd->cache_interface = eldbus_service_interface_register(pd->a11y_bus, CACHE_INTERFACE_PATH, &cache_iface_desc);
5261 eldbus_service_object_data_set(pd->cache_interface, ELM_ATSPI_BRIDGE_CLASS_NAME, obj);
5265 _set_broadcast_flag(const char *event, Eo *bridge)
5268 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
5270 tokens = eina_str_split(event, ":", 3);
5272 if (!tokens) return;
5274 if (!strcmp(tokens[0], "Object"))
5276 if (!tokens[1] || *tokens[1] == '\0') return; // do not handle "Object:*"
5277 else if (!strcmp(tokens[1], "StateChanged"))
5279 if (!tokens[2] || *tokens[2] == '\0')
5280 pd->object_state_broadcast_mask = -1; // broadcast all
5281 eina_str_tolower(&tokens[2]);
5282 struct atspi_state_desc *sd = eina_hash_find(pd->state_hash, tokens[2]);
5284 STATE_TYPE_SET(pd->object_state_broadcast_mask, sd->elm_state);
5286 else if (!strcmp(tokens[1], "PropertyChange"))
5288 if (!tokens[2] || *tokens[2] == '\0')
5289 pd->object_property_broadcast_mask = -1; //broadcast all
5290 else if (!strcmp(tokens[2], "AccessibleValue"))
5291 STATE_TYPE_SET(pd->object_property_broadcast_mask, ATSPI_OBJECT_PROPERTY_VALUE);
5292 else if (!strcmp(tokens[2], "AccessibleName"))
5293 STATE_TYPE_SET(pd->object_property_broadcast_mask, ATSPI_OBJECT_PROPERTY_NAME);
5294 else if (!strcmp(tokens[2], "AccessibleDescription"))
5295 STATE_TYPE_SET(pd->object_property_broadcast_mask, ATSPI_OBJECT_PROPERTY_DESCRIPTION);
5296 else if (!strcmp(tokens[2], "AccessibleParent"))
5297 STATE_TYPE_SET(pd->object_property_broadcast_mask, ATSPI_OBJECT_PROPERTY_PARENT);
5298 else if (!strcmp(tokens[2], "AccessibleRole"))
5299 STATE_TYPE_SET(pd->object_property_broadcast_mask, ATSPI_OBJECT_PROPERTY_ROLE);
5301 else if (!strcmp(tokens[1], "ChildrenChanged"))
5303 if (!tokens[2] || *tokens[2] == '\0')
5304 pd->object_children_broadcast_mask = -1; // broadcast all
5305 else if (!strcmp(tokens[2], "add"))
5306 STATE_TYPE_SET(pd->object_children_broadcast_mask, ATSPI_OBJECT_CHILD_ADDED);
5307 else if (!strcmp(tokens[2], "remove"))
5308 STATE_TYPE_SET(pd->object_children_broadcast_mask, ATSPI_OBJECT_CHILD_REMOVED);
5310 else if (!strcmp(tokens[1], "TextChanged"))
5311 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_CHANGED);
5312 else if (!strcmp(tokens[1], "TextCaretMoved"))
5313 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_CARET_MOVED);
5314 else if (!strcmp(tokens[1], "TextBoundsChanged"))
5315 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_BOUNDS_CHANGED);
5316 else if (!strcmp(tokens[1], "TextSelectionChanged"))
5317 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED);
5318 else if (!strcmp(tokens[1], "TextAttributesChanged"))
5319 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_ATTRIBUTES_CHANGED);
5320 else if (!strcmp(tokens[1], "VisibleDataChanged"))
5321 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED);
5322 else if (!strcmp(tokens[1], "ActiveDescendantChanged"))
5323 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED);
5324 else if (!strcmp(tokens[1], "BoundsChanged"))
5325 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_BOUNDS_CHANGED);
5326 //TIZEN_ONLY(20160623): atspi: moved highlight when object is out of screen
5327 else if (!strcmp(tokens[1], "MoveOuted"))
5328 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_MOVE_OUTED);
5331 else if (!strcmp(tokens[0], "Window"))
5333 if (!tokens[1] || *tokens[1] == '\0')
5334 pd->window_signal_broadcast_mask = -1; // broadcast all
5335 else if (!strcmp(tokens[1], "Create"))
5336 STATE_TYPE_SET(pd->window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_CREATE);
5337 else if (!strcmp(tokens[1], "Destroy"))
5338 STATE_TYPE_SET(pd->window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_DESTROY);
5339 else if (!strcmp(tokens[1], "Activate"))
5340 STATE_TYPE_SET(pd->window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_ACTIVATE);
5341 else if (!strcmp(tokens[1], "Deactivate"))
5342 STATE_TYPE_SET(pd->window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_DEACTIVATE);
5343 else if (!strcmp(tokens[1], "Maximize"))
5344 STATE_TYPE_SET(pd->window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_MAXIMIZE);
5345 else if (!strcmp(tokens[1], "Minimize"))
5346 STATE_TYPE_SET(pd->window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_MINIMIZE);
5347 else if (!strcmp(tokens[1], "Resize"))
5348 STATE_TYPE_SET(pd->window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_RESIZE);
5349 else if (!strcmp(tokens[1], "Restore"))
5350 STATE_TYPE_SET(pd->window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_RESTORE);
5358 _registered_listeners_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
5360 const char *event, *bus;
5362 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd);
5363 pd->pending_requests = eina_list_remove(pd->pending_requests, pending);
5365 DBG("Updating registered ATSPI signals list.");
5366 pd->object_broadcast_mask = 0;
5367 pd->object_children_broadcast_mask = 0;
5368 pd->object_property_broadcast_mask = 0;
5369 pd->object_state_broadcast_mask = 0;
5370 pd->window_signal_broadcast_mask = 0;
5372 if (eldbus_message_error_get(msg, &event, &bus))
5374 WRN("%s %s", event, bus);
5377 Eldbus_Message_Iter *iter, *siter;
5378 if (!eldbus_message_arguments_get(msg, "a(ss)", &iter))
5380 ERR("Invalid answer type from GetRegisteredEvents method call!");
5383 while (eldbus_message_iter_get_and_next(iter, 'r', &siter))
5385 eldbus_message_iter_arguments_get(siter, "ss", &bus, &event);
5386 _set_broadcast_flag(event, data);
5391 //TIZEN_ONLY(20170910) atspi: emit signal after atspi bridge is connected
5392 pd->connected = EINA_TRUE;
5393 eo_do(data, eo_event_callback_call(ELM_ATSPI_BRIDGE_EVENT_CONNECTED, NULL));
5394 _elm_win_atspi(EINA_TRUE);
5398 eo_do(data, root = elm_obj_atspi_bridge_root_get());
5399 _bridge_cache_build(data, root);
5401 // initialize pending proxy
5402 EINA_LIST_FREE(pd->socket_queue, pr)
5403 _socket_ifc_create(pd->a11y_bus, pr);
5404 EINA_LIST_FREE(pd->plug_queue, pr)
5405 _plug_connect(pd->a11y_bus, pr);
5407 pd->socket_queue = pd->plug_queue = NULL;
5412 _registered_events_list_update(Eo *bridge)
5414 Eldbus_Message *msg;
5415 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
5418 msg = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_REGISTRY, ATSPI_DBUS_INTERFACE_REGISTRY, "GetRegisteredEvents");
5419 p = eldbus_connection_send(pd->a11y_bus, msg, _registered_listeners_get, bridge, -1);
5420 pd->pending_requests = eina_list_append(pd->pending_requests, p);
5424 _handle_listener_change(void *data, const Eldbus_Message *msg EINA_UNUSED)
5426 _registered_events_list_update(data);
5429 //TIZEN_ONLY(20170802): handle "gesture_required" attribute
5431 _scroll_gesture_required_is(Eo *obj)
5433 Eina_Bool ret = EINA_FALSE;
5434 Eina_List *l, *attr_list = NULL;
5435 Elm_Atspi_Attribute *attr = NULL;
5437 eo_do(obj, attr_list = elm_interface_atspi_accessible_attributes_get());
5438 EINA_LIST_FOREACH(attr_list, l, attr)
5440 if (!strcmp(attr->key, "gesture_required") && !strcmp(attr->value, "scroll"))
5447 elm_atspi_attributes_list_free(attr_list);
5454 _state_changed_signal_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
5456 Elm_Atspi_Event_State_Changed_Data *state_data = event_info;
5457 const char *type_desc;
5458 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
5460 // TIZEN_ONLY(20160802): do not handle events if the window is not activated
5461 if ((state_data->type == ELM_ATSPI_STATE_ACTIVE) && eo_isa(obj, ELM_WIN_CLASS))
5463 pd->window_activated = state_data->new_value;
5466 // TIZEN_ONLY(20161209): reduce IPC of object:state-changed:showing
5467 if ((state_data->type == ELM_ATSPI_STATE_SHOWING) ||
5468 (state_data->type == ELM_ATSPI_STATE_VISIBLE))
5470 Elm_Atspi_Role role = ELM_ATSPI_ROLE_INVALID;
5471 Elm_Atspi_State_Set ss;
5473 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
5474 eo_do(obj, ss = elm_interface_atspi_accessible_state_set_get());
5475 if (state_data->new_value) /* Showing */
5477 if ((role != ELM_ATSPI_ROLE_WINDOW) &&
5478 (role != ELM_ATSPI_ROLE_PAGE_TAB) &&
5479 (!STATE_TYPE_GET(ss, ELM_ATSPI_STATE_MODAL)))
5482 else /* Not Showing */
5484 if ((role != ELM_ATSPI_ROLE_WINDOW) &&
5485 (!STATE_TYPE_GET(ss, ELM_ATSPI_STATE_MODAL)) &&
5486 (_elm_object_accessibility_currently_highlighted_get() != (void *)obj))
5492 if (!STATE_TYPE_GET(pd->object_state_broadcast_mask, state_data->type))
5495 if ((state_data->type > ELM_ATSPI_STATE_LAST_DEFINED) ||
5496 (int)state_data->type < 0)
5499 type_desc = elm_states_to_atspi_state[state_data->type].name;
5501 //TIZEN_ONLY(20170802): handle "gesture_required" attribute
5502 unsigned int det2 = 0;
5503 if ((state_data->type == ELM_ATSPI_STATE_HIGHLIGHTED) &&
5504 (_scroll_gesture_required_is(obj)))
5507 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5508 &_event_obj_signals[ATSPI_OBJECT_EVENT_STATE_CHANGED], type_desc, state_data->new_value, det2, NULL);
5514 _bounds_changed_signal_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
5516 Elm_Atspi_Event_Geometry_Changed_Data *geo_data = event_info;
5518 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5519 &_event_obj_signals[ATSPI_OBJECT_EVENT_BOUNDS_CHANGED], "", 0, 0, "(iiii)",
5520 geo_data->x, geo_data->y, geo_data->width, geo_data->height);
5525 _property_changed_signal_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
5527 const char *property = event_info;
5529 enum _Atspi_Object_Property prop = ATSPI_OBJECT_PROPERTY_LAST;
5531 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
5533 if (!strcmp(property, "parent"))
5535 prop = ATSPI_OBJECT_PROPERTY_PARENT;
5536 atspi_desc = "accessible-parent";
5538 else if (!strcmp(property, "name"))
5540 prop = ATSPI_OBJECT_PROPERTY_NAME;
5541 atspi_desc = "accessible-name";
5543 else if (!strcmp(property, "description"))
5545 prop = ATSPI_OBJECT_PROPERTY_DESCRIPTION;
5546 atspi_desc = "accessible-description";
5548 else if (!strcmp(property, "role"))
5550 prop = ATSPI_OBJECT_PROPERTY_ROLE;
5551 atspi_desc = "accessible-role";
5553 else if (!strcmp(property, "value"))
5555 prop = ATSPI_OBJECT_PROPERTY_VALUE;
5556 atspi_desc = "accessible-value";
5558 if (prop == ATSPI_OBJECT_PROPERTY_LAST)
5560 ERR("Unrecognized property name!");
5563 if (!STATE_TYPE_GET(pd->object_property_broadcast_mask, prop))
5565 DBG("Masking property %s changed event.", property);
5569 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5570 &_event_obj_signals[ATSPI_OBJECT_EVENT_PROPERTY_CHANGED], atspi_desc, 0, 0, NULL, NULL);
5575 _visible_data_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
5577 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
5579 if (!STATE_TYPE_GET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED))
5582 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5583 &_event_obj_signals[ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED], "",
5590 _active_descendant_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
5592 Eo *child = event_info;
5595 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
5597 if (!STATE_TYPE_GET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED))
5600 eo_do(child, idx = elm_interface_atspi_accessible_index_in_parent_get());
5602 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5603 &_event_obj_signals[ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED], "",
5604 idx, 0, "(so)", eldbus_connection_unique_name_get(pd->a11y_bus), child);
5609 _children_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
5611 const char *atspi_desc = NULL;
5612 Elm_Atspi_Event_Children_Changed_Data *ev_data = event_info;
5614 enum _Atspi_Object_Child_Event_Type type;
5616 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
5618 type = ev_data->is_added ? ATSPI_OBJECT_CHILD_ADDED : ATSPI_OBJECT_CHILD_REMOVED;
5620 // update cached objects
5621 if (ev_data->is_added)
5622 _bridge_cache_build(data, ev_data->child);
5624 if (!STATE_TYPE_GET(pd->object_children_broadcast_mask, type))
5629 case ATSPI_OBJECT_CHILD_ADDED:
5631 eo_do(ev_data->child, idx = elm_interface_atspi_accessible_index_in_parent_get());
5633 case ATSPI_OBJECT_CHILD_REMOVED:
5634 atspi_desc = "remove";
5635 eo_do(ev_data->child, idx = elm_interface_atspi_accessible_index_in_parent_get());
5639 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5640 &_event_obj_signals[ATSPI_OBJECT_EVENT_CHILDREN_CHANGED], atspi_desc,
5641 idx, 0, "(so)", eldbus_connection_unique_name_get(pd->a11y_bus), ev_data->child);
5646 //TIZEN_ONLY(20160623): atspi: moved highlight when object is out of screen
5648 _move_outed_signal_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
5650 const Elm_Atspi_Move_Outed_Type *type = event_info;
5652 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
5654 if (!STATE_TYPE_GET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_MOVE_OUTED))
5656 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5657 &_event_obj_signals[ATSPI_OBJECT_EVENT_MOVE_OUTED], "", *type, 0, NULL, NULL);
5663 _window_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info EINA_UNUSED)
5665 enum _Atspi_Window_Signals type;
5667 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
5669 if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_CREATED)
5670 type = ATSPI_WINDOW_EVENT_CREATE;
5671 else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DESTROYED)
5672 type = ATSPI_WINDOW_EVENT_DESTROY;
5673 else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DEACTIVATED)
5674 type = ATSPI_WINDOW_EVENT_DEACTIVATE;
5675 else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_ACTIVATED)
5676 type = ATSPI_WINDOW_EVENT_ACTIVATE;
5677 else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MAXIMIZED)
5678 type = ATSPI_WINDOW_EVENT_MAXIMIZE;
5679 else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MINIMIZED)
5680 type = ATSPI_WINDOW_EVENT_MINIMIZE;
5681 else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_RESTORED)
5682 type = ATSPI_WINDOW_EVENT_RESTORE;
5686 if (!STATE_TYPE_GET(pd->window_signal_broadcast_mask, type))
5691 ERR("A11Y connection closed. Unable to send ATSPI event.");
5695 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_WINDOW,
5696 &_window_obj_signals[type], "", 0, 0, "i", 0);
5701 _selection_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
5703 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE);
5705 if (!STATE_TYPE_GET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_SELECTION_CHANGED))
5708 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5709 &_event_obj_signals[ATSPI_OBJECT_EVENT_SELECTION_CHANGED], "", 0, 0, "i", 0);
5713 static void _bridge_signal_send(Eo *bridge, Eo *obj, const char *infc, const Eldbus_Signal *signal, const char *minor, unsigned int det1, unsigned int det2, const char *variant_sig, ...)
5715 Eldbus_Message *msg;
5716 Eldbus_Message_Iter *iter , *iter_stack[64], *iter_struct;
5722 EINA_SAFETY_ON_NULL_RETURN(infc);
5723 EINA_SAFETY_ON_NULL_RETURN(signal);
5724 EINA_SAFETY_ON_NULL_RETURN(minor);
5725 EINA_SAFETY_ON_NULL_RETURN(obj);
5726 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
5728 path = _bridge_path_from_object(bridge, obj);
5730 msg = eldbus_message_signal_new(path, infc, signal->name);
5733 va_start(va, variant_sig);
5735 iter = eldbus_message_iter_get(msg);
5736 eldbus_message_iter_arguments_append(iter, "sii", minor, det1, det2);
5740 iter_stack[top] = eldbus_message_iter_container_new(iter, 'v', variant_sig);
5742 const char *tmp = variant_sig;
5748 iter_stack[top + 1] = eldbus_message_iter_container_new(iter_stack[top], 'r', NULL);
5752 eldbus_message_iter_basic_append(iter_stack[top], 's', va_arg(va, char*));
5755 eldbus_message_iter_basic_append(iter_stack[top], 'i', va_arg(va, int));
5758 atspi_obj = va_arg(va, Eo*);
5759 path = _bridge_path_from_object(bridge, atspi_obj);
5760 eldbus_message_iter_basic_append(iter_stack[top], 'o', path);
5763 eldbus_message_iter_container_close(iter_stack[top - 1], iter_stack[top]);
5767 ERR("Not supported d-bus type: %c.", *tmp);
5773 else // AT-SPI implementation forces checks on variant in signature even if not used.
5775 iter_stack[top] = eldbus_message_iter_container_new(iter, 'v', "i");
5776 eldbus_message_iter_basic_append(iter_stack[top], 'i', 0);
5781 ERR("Invalid d-bus signature: () do not match.");
5783 eldbus_message_iter_container_close(iter, iter_stack[0]);
5785 iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
5786 path = _bridge_path_from_object(bridge, elm_atspi_bridge_root_get(bridge));
5787 eldbus_message_iter_basic_append(iter_struct, 's', eldbus_connection_unique_name_get(pd->a11y_bus));
5788 eldbus_message_iter_basic_append(iter_struct, 'o', path);
5789 eldbus_message_iter_container_close(iter, iter_struct);
5791 eldbus_connection_send(pd->a11y_bus, msg, NULL, NULL, -1);
5792 DBG("Send %s.%s[%s,%d,%d]", infc, signal->name, minor, det1, det2);
5796 _text_caret_moved_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
5800 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
5802 if (!STATE_TYPE_GET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_CARET_MOVED))
5805 eo_do(obj, cursor_pos = elm_interface_atspi_text_caret_offset_get());
5807 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5808 &_event_obj_signals[ATSPI_OBJECT_EVENT_TEXT_CARET_MOVED], "", cursor_pos, 0, NULL, NULL);
5814 _text_text_inserted_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
5816 Elm_Atspi_Text_Change_Info *info = event_info;
5818 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE);
5820 if (!STATE_TYPE_GET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_CHANGED))
5823 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5824 &_event_obj_signals[ATSPI_OBJECT_EVENT_TEXT_CHANGED], "insert", info->pos, info->len, "s", info->content);
5830 _text_text_removed_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
5832 Elm_Atspi_Text_Change_Info *info = event_info;
5834 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE);
5836 if (!STATE_TYPE_GET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_CHANGED))
5839 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5840 &_event_obj_signals[ATSPI_OBJECT_EVENT_TEXT_CHANGED], "delete", info->pos, info->len, "s", info->content);
5846 _text_selection_changed_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
5848 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE);
5850 if (!STATE_TYPE_GET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED))
5853 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5854 &_event_obj_signals[ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED], "", 0, 0, NULL, NULL);
5859 //TIZEN_ONLY(20160527) - Add direct reading feature
5861 _on_reading_state_changed(void *data EINA_UNUSED, const Eldbus_Message *msg)
5864 const char *say_signal_name = "";
5865 Elm_Atspi_Say_Info *say_info;
5867 if (eldbus_message_arguments_get(msg, "is", &i, &say_signal_name))
5868 { if (read_command_id)
5870 say_info = eina_hash_find(read_command_id, &i);
5873 if (say_info->func && say_signal_name)
5874 say_info->func(say_info->data, say_signal_name);
5875 eina_hash_del(read_command_id, &i, NULL);
5884 _event_handlers_register(Eo *bridge)
5886 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
5888 _registered_events_list_update(bridge);
5890 // register signal handlers in order to update list of registered listeners of ATSPI-Clients
5891 pd->register_hdl = eldbus_signal_handler_add(pd->a11y_bus, ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_REGISTRY, ATSPI_DBUS_INTERFACE_REGISTRY, "EventListenerRegistered", _handle_listener_change, bridge);
5892 pd->unregister_hdl = eldbus_signal_handler_add(pd->a11y_bus, ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_REGISTRY, ATSPI_DBUS_INTERFACE_REGISTRY, "EventListenerDeregistered", _handle_listener_change, bridge);
5893 //TIZEN_ONLY(20160527) - Add direct reading feature
5894 pd->reading_state_changed_hdl = eldbus_signal_handler_add(pd->a11y_bus, ELM_ATSPI_DIRECT_READ_BUS, ELM_ATSPI_DIRECT_READ_PATH, ELM_ATSPI_DIRECT_READ_INTERFACE, "ReadingStateChanged", _on_reading_state_changed, bridge);
5896 pd->key_flr = ecore_event_filter_add(NULL, _elm_atspi_bridge_key_filter, NULL, bridge);
5900 _bridge_object_unregister(Eo *bridge, Eo *obj)
5902 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
5904 eina_hash_del(pd->cache, &obj, obj);
5908 _on_object_add(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED)
5910 Eldbus_Message *sig;
5911 Eldbus_Message_Iter *iter;
5913 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE);
5915 sig = eldbus_service_signal_new(pd->cache_interface, ATSPI_OBJECT_CHILD_ADDED);
5916 iter = eldbus_message_iter_get(sig);
5917 _cache_item_reference_append_cb(data, obj, iter);
5919 eldbus_service_signal_send(pd->cache_interface, sig);
5925 _on_object_del(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED)
5927 Eldbus_Message *sig;
5929 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE);
5931 _bridge_object_unregister(data, obj);
5933 sig = eldbus_service_signal_new(pd->cache_interface, ATSPI_OBJECT_CHILD_REMOVED);
5934 Eldbus_Message_Iter *iter = eldbus_message_iter_get(sig);
5935 _bridge_iter_object_reference_append(data, iter, obj);
5936 eldbus_service_signal_send(pd->cache_interface, sig);
5942 _bridge_cache_build(Eo *bridge, void *obj)
5944 Eina_List *children;
5945 Elm_Atspi_State_Set ss;
5948 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
5950 if (!eo_isa(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
5953 if (!eo_isa(obj, ELM_ATSPI_PROXY_CLASS))
5954 _bridge_object_register(bridge, obj);
5956 eo_do(obj, ss = elm_interface_atspi_accessible_state_set_get());
5957 if (STATE_TYPE_GET(ss, ELM_ATSPI_STATE_MANAGES_DESCENDANTS))
5959 if (eo_isa(obj, ELM_INTERFACE_ATSPI_WINDOW_INTERFACE))
5961 if (STATE_TYPE_GET(ss, ELM_ATSPI_STATE_ACTIVE))
5963 // TIZEN_ONLY(20160802): do not handle events if the window is not activated
5964 pd->window_activated = EINA_TRUE;
5969 // TIZEN_ONLY(20160802): do not handle events if the window is not activated
5970 pd->window_activated = EINA_FALSE;
5974 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
5975 EINA_LIST_FREE(children, child)
5976 _bridge_cache_build(bridge, child);
5980 _interfaces_unregister(Eo *bridge)
5982 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
5984 #define INTERFACE_SAFE_FREE(ifc) \
5986 eldbus_service_interface_unregister(ifc); \
5989 INTERFACE_SAFE_FREE(pd->interfaces.accessible);
5990 INTERFACE_SAFE_FREE(pd->interfaces.application);
5991 INTERFACE_SAFE_FREE(pd->interfaces.action);
5992 INTERFACE_SAFE_FREE(pd->interfaces.component);
5993 INTERFACE_SAFE_FREE(pd->interfaces.collection);
5994 INTERFACE_SAFE_FREE(pd->interfaces.editable_text);
5995 INTERFACE_SAFE_FREE(pd->interfaces.image);
5996 INTERFACE_SAFE_FREE(pd->interfaces.selection);
5997 INTERFACE_SAFE_FREE(pd->interfaces.text);
5998 INTERFACE_SAFE_FREE(pd->interfaces.value);
6002 _a11y_connection_shutdown(Eo *bridge)
6004 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6005 Eldbus_Pending *pending;
6008 _elm_atspi_bridge_app_unregister(bridge);
6011 eina_hash_free(pd->cache);
6014 if (pd->cache_interface)
6015 eldbus_service_object_unregister(pd->cache_interface);
6016 pd->cache_interface = NULL;
6018 _interfaces_unregister(bridge);
6020 if (pd->key_flr) ecore_event_filter_del(pd->key_flr);
6023 if (pd->register_hdl) eldbus_signal_handler_del(pd->register_hdl);
6024 pd->register_hdl = NULL;
6026 if (pd->unregister_hdl) eldbus_signal_handler_del(pd->unregister_hdl);
6027 pd->unregister_hdl = NULL;
6029 //TIZEN_ONLY(20160527) - Add direct reading feature
6030 if (pd->reading_state_changed_hdl) eldbus_signal_handler_del(pd->reading_state_changed_hdl);
6031 pd->reading_state_changed_hdl = NULL;
6034 EINA_LIST_FREE(pd->pending_requests, pending)
6035 eldbus_pending_cancel(pending);
6036 pd->pending_requests = NULL;
6038 if (pd->a11y_bus) eldbus_connection_unref(pd->a11y_bus);
6039 pd->a11y_bus = NULL;
6041 if (pd->state_hash) eina_hash_free(pd->state_hash);
6042 pd->state_hash = NULL;
6044 if (pd->event_hash) eina_hash_free(pd->event_hash);
6045 pd->event_hash = NULL;
6047 eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_handler_del(pd->event_hdlr));
6048 pd->event_hdlr = NULL;
6050 eo_do(bridge, eo_event_callback_call(ELM_ATSPI_BRIDGE_EVENT_DISCONNECTED, NULL));
6051 pd->connected = EINA_FALSE;
6054 static void _disconnect_cb(void *data, Eldbus_Connection *conn EINA_UNUSED, void *event_info EINA_UNUSED)
6056 _a11y_connection_shutdown(data);
6060 _interfaces_register(Eo *bridge)
6062 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6064 pd->interfaces.accessible =
6065 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &accessible_iface_desc);
6066 eldbus_service_object_data_set(pd->interfaces.accessible, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6068 pd->interfaces.application =
6069 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &application_iface_desc);
6070 eldbus_service_object_data_set(pd->interfaces.application, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6072 pd->interfaces.action =
6073 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &action_iface_desc);
6074 eldbus_service_object_data_set(pd->interfaces.action, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6076 pd->interfaces.component =
6077 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &component_iface_desc);
6078 eldbus_service_object_data_set(pd->interfaces.component, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6080 pd->interfaces.collection =
6081 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &collection_iface_desc);
6082 eldbus_service_object_data_set(pd->interfaces.collection, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6084 pd->interfaces.editable_text =
6085 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &editable_text_iface_desc);
6086 eldbus_service_object_data_set(pd->interfaces.editable_text, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6088 pd->interfaces.image =
6089 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &image_iface_desc);
6090 eldbus_service_object_data_set(pd->interfaces.image, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6092 pd->interfaces.selection =
6093 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &selection_iface_desc);
6094 eldbus_service_object_data_set(pd->interfaces.selection, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6096 pd->interfaces.text =
6097 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &text_iface_desc);
6098 eldbus_service_object_data_set(pd->interfaces.text, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6100 pd->interfaces.value =
6101 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &value_iface_desc);
6102 eldbus_service_object_data_set(pd->interfaces.value, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6106 _bridge_accessible_event_dispatch(void *data, Eo *accessible, const Eo_Event_Description *desc, void *event_info)
6108 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE);
6110 _bridge_object_register(data, accessible);
6112 Eo_Event_Cb cb = eina_hash_find(pd->event_hash, &desc);
6113 return cb ? cb(data, accessible, desc, event_info) : EINA_TRUE;
6117 _a11y_bus_initialize(Eo *obj, const char *socket_addr)
6119 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(obj, pd);
6120 pd->a11y_bus = eldbus_private_address_connection_get(socket_addr);
6124 eldbus_connection_event_callback_add(pd->a11y_bus, ELDBUS_CONNECTION_EVENT_DISCONNECTED, _disconnect_cb, obj);
6126 // init data structures
6127 pd->cache = eina_hash_pointer_new(NULL);
6128 pd->state_hash = _elm_atspi_state_hash_build();
6129 pd->event_hash = _elm_atspi_event_hash_build();
6132 _cache_register(obj);
6133 _interfaces_register(obj);
6134 _event_handlers_register(obj);
6135 if (!getenv("ELM_ATSPI_NO_EMBED"))
6136 _elm_atspi_bridge_app_register(obj);
6138 // register accesible object event listener
6139 eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, pd->event_hdlr = elm_interface_atspi_accessible_event_handler_add(_bridge_accessible_event_dispatch, obj));
6144 _a11y_bus_address_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
6146 const char *errname, *errmsg, *sock_addr = NULL;
6147 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd);
6149 pd->pending_requests = eina_list_remove(pd->pending_requests, pending);
6151 if (eldbus_message_error_get(msg, &errname, &errmsg))
6153 ERR("%s %s", errname, errmsg);
6157 if (!eldbus_message_arguments_get(msg, "s", &sock_addr) || !sock_addr)
6159 ERR("Could not get A11Y Bus socket address.");
6163 _a11y_socket_address = eina_stringshare_add(sock_addr);
6164 _a11y_bus_initialize((Eo*)data, sock_addr);
6167 static void _a11y_connection_init(Eo *bridge)
6169 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6170 Eina_Bool is_connected;
6172 eo_do(bridge, is_connected = elm_obj_atspi_bridge_connected_get());
6174 if (is_connected) return;
6176 // TIZEN_ONLY(20170512): send window activated event to at_spi2 only once per session
6177 pd->window_activated_broadcast_needed = EINA_TRUE;
6179 Eldbus_Message *m = eldbus_object_method_call_new(pd->bus_obj, A11Y_DBUS_INTERFACE, "GetAddress");
6180 Eldbus_Pending *p = eldbus_object_send(pd->bus_obj, m, _a11y_bus_address_get, bridge, 100);
6183 pd->pending_requests = eina_list_append(pd->pending_requests, p);
6187 _screen_reader_enabled_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
6189 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd);
6190 const char *errname, *errmsg;
6191 Eina_Bool is_enabled;
6192 Eldbus_Message_Iter *variant;
6194 pd->pending_requests = eina_list_remove(pd->pending_requests, pending);
6196 if (eldbus_message_error_get(msg, &errname, &errmsg))
6198 WRN("%s %s", errname, errmsg);
6201 if (!eldbus_message_arguments_get(msg, "v", &variant))
6203 ERR("'ScreenReaderEnabled' not packed into variant.");
6206 if (!eldbus_message_iter_arguments_get(variant, "b", &is_enabled))
6208 ERR("Could not get 'ScreenReaderEnabled' boolean property");
6211 //TIZEN_ONLY(20161027) - Export elm_atspi_bridge_utils_is_screen_reader_enabled
6212 pd->screen_reader_enabled = !!is_enabled;
6214 //TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
6215 //register/unregister access objects accordingly.
6216 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6217 _elm_win_screen_reader(is_enabled);
6222 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6224 _at_spi_client_enabled_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
6226 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd);
6227 const char *errname, *errmsg;
6228 Eina_Bool is_enabled;
6229 Eldbus_Message_Iter *variant;
6231 pd->pending_requests = eina_list_remove(pd->pending_requests, pending);
6233 if (eldbus_message_error_get(msg, &errname, &errmsg))
6235 WRN("%s %s", errname, errmsg);
6238 if (!eldbus_message_arguments_get(msg, "v", &variant))
6240 ERR("'" A11Y_DBUS_ENABLED_PROPERTY "' not packed into variant.");
6243 if (!eldbus_message_iter_arguments_get(variant, "b", &is_enabled))
6245 ERR("Could not get '" A11Y_DBUS_ENABLED_PROPERTY "' boolean property");
6249 _a11y_connection_init(data);
6252 _elm_win_atspi(EINA_FALSE);
6253 DBG("AT-SPI2 stack not enabled.");
6259 static void _bridge_object_register(Eo *bridge, Eo *obj)
6261 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6263 if (!eo_isa(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
6265 WRN("Unable to register class w/o Elm_Interface_Atspi_Accessible!");
6269 if (eina_hash_find(pd->cache, &obj))
6272 eina_hash_add(pd->cache, &obj, obj);
6276 _elm_atspi_bridge_init(void)
6280 _instance = eo_add(ELM_ATSPI_BRIDGE_CLASS, NULL);
6286 _elm_atspi_bridge_get(void)
6292 _elm_atspi_bridge_shutdown(void)
6299 if (_a11y_socket_address)
6300 eina_stringshare_del(_a11y_socket_address);
6301 _a11y_socket_address = NULL;
6304 static Key_Event_Info*
6305 _key_event_info_new(int event_type, const Ecore_Event_Key *data, Eo *bridge)
6307 Key_Event_Info *ret;
6308 EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL);
6310 ret = calloc(sizeof(Key_Event_Info), 1);
6312 ret->type = event_type;
6314 ret->bridge = bridge;
6316 ret->event.keyname = eina_stringshare_add(data->keyname);
6317 ret->event.key = eina_stringshare_add(data->key);
6318 ret->event.string = eina_stringshare_add(data->string);
6319 ret->event.compose = eina_stringshare_add(data->compose);
6321 // not sure why it is here, but explicite keep it NULLed.
6322 ret->event.data = NULL;
6328 _key_event_info_free(Key_Event_Info *data)
6330 EINA_SAFETY_ON_NULL_RETURN(data);
6332 eina_stringshare_del(data->event.keyname);
6333 eina_stringshare_del(data->event.key);
6334 eina_stringshare_del(data->event.string);
6335 eina_stringshare_del(data->event.compose);
6341 _iter_marshall_key_event(Eldbus_Message_Iter *iter, Key_Event_Info *data)
6343 Eldbus_Message_Iter *struct_iter;
6344 EINA_SAFETY_ON_NULL_RETURN(data);
6346 struct_iter = eldbus_message_iter_container_new(iter, 'r', NULL);
6348 const char *str = data->event.keyname ? data->event.keyname : "";
6349 int is_text = data->event.keyname ? 1 : 0;
6351 if (data->type == ECORE_EVENT_KEY_DOWN)
6352 type = ATSPI_KEY_PRESSED_EVENT;
6354 type = ATSPI_KEY_RELEASED_EVENT;
6356 eldbus_message_iter_arguments_append(struct_iter, "uiiiisb", type, 0, data->event.keycode, 0, data->event.timestamp, str, is_text);
6357 eldbus_message_iter_container_close(iter, struct_iter);
6361 _on_event_del(void *user_data, void *func_data EINA_UNUSED)
6363 Key_Event_Info *info = user_data;
6364 _key_event_info_free(info);
6368 _on_listener_answer(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
6370 Key_Event_Info *info = data;
6371 const char *errname, *errmsg;
6372 Eina_Bool ret = EINA_TRUE;
6374 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(info->bridge, pd);
6376 if (eldbus_message_error_get(msg, &errname, &errmsg))
6378 ERR("%s %s", errname, errmsg);
6381 if (!eldbus_message_arguments_get(msg, "b", &ret))
6383 ERR("Return message doen not contian return value");
6388 _key_event_info_free(info);
6392 ecore_event_add(info->type, &info->event, _on_event_del, info);
6393 pd->reemited_events = eina_list_append(pd->reemited_events, &info->event);
6397 _elm_atspi_bridge_key_filter(void *data, void *loop EINA_UNUSED, int type, void *event)
6399 Eldbus_Message *msg;
6400 Eldbus_Message_Iter *iter;
6401 Ecore_Event_Key *key_event = event;
6405 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_TRUE);
6407 // TIZEN_ONLY(20160802): do not handle events if the window is not activated
6408 if (!pd->window_activated) return EINA_TRUE;
6411 if ((type != ECORE_EVENT_KEY_DOWN) && (type != ECORE_EVENT_KEY_UP)) return EINA_TRUE;
6413 // check if reemited
6414 if (eina_list_data_find(pd->reemited_events, event))
6416 pd->reemited_events = eina_list_remove(pd->reemited_events, event);
6420 // TIZEN_ONLY(20170118): Not handle events if keyboard is on
6423 Eina_List *children, *l;
6425 eo_do(pd->root, children = elm_interface_atspi_accessible_children_get());
6427 EINA_LIST_FOREACH(children, l, child)
6429 if (elm_widget_focus_get(child)) break;
6431 eina_list_free(children);
6433 Elm_Win_Keyboard_Mode mode;
6434 mode = elm_win_keyboard_mode_get(child);
6435 if (mode == ELM_WIN_KEYBOARD_ON) return EINA_TRUE;
6439 ke = _key_event_info_new(type, key_event, bridge);
6440 if (!ke) return EINA_TRUE;
6442 msg = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_DEC,
6443 ATSPI_DBUS_INTERFACE_DEC, "NotifyListenersSync");
6444 iter = eldbus_message_iter_get(msg);
6445 _iter_marshall_key_event(iter, ke);
6447 // timeout should be kept reasonaby low to avoid delays
6448 if (!eldbus_connection_send(pd->a11y_bus, msg, _on_listener_answer, ke, 100))
6455 _elm_atspi_bridge_connected_get(Eo *obj EINA_UNUSED, Elm_Atspi_Bridge_Data *pd)
6457 return pd->connected;
6461 _elm_atspi_bridge_root_get(Eo *obj EINA_UNUSED, Elm_Atspi_Bridge_Data *pd)
6465 pd->root = eo_add(ELM_ATSPI_APP_OBJECT_CLASS, NULL);
6466 elm_interface_atspi_accessible_added(pd->root);
6473 _properties_changed_cb(void *data, Eldbus_Proxy *proxy EINA_UNUSED, void *event)
6475 Eldbus_Proxy_Event_Property_Changed *ev = event;
6478 const char *ifc = eldbus_proxy_interface_get(ev->proxy);
6479 if (ev->name && !strcmp(ev->name, "ScreenReaderEnabled" ) &&
6480 ifc && !strcmp(A11Y_DBUS_STATUS_INTERFACE, ifc))
6482 if (!eina_value_get(ev->value, &val))
6484 ERR("Unable to get ScreenReaderEnabled property value");
6487 //TIZEN_ONLY(20161027) - Export elm_atspi_bridge_utils_is_screen_reader_enabled
6488 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6489 pd->screen_reader_enabled = !!val;
6491 //TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
6492 //register/unregister access objects accordingly.
6493 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6494 _elm_win_screen_reader(val);
6498 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6499 if (ev->name && !strcmp(ev->name, A11Y_DBUS_ENABLED_PROPERTY) &&
6500 ifc && !strcmp(A11Y_DBUS_STATUS_INTERFACE, ifc))
6502 if (!eina_value_get(ev->value, &val))
6504 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6505 ERR("Unable to get " A11Y_DBUS_ENABLED_PROPERTY " property value");
6511 _a11y_connection_init(bridge);
6514 _elm_win_atspi(EINA_FALSE);
6515 _a11y_connection_shutdown(bridge);
6522 _elm_atspi_bridge_eo_base_constructor(Eo *obj, Elm_Atspi_Bridge_Data *pd)
6524 Eldbus_Proxy *proxy;
6525 Eldbus_Pending *req;
6527 eo_do_super(obj, ELM_ATSPI_BRIDGE_CLASS, eo_constructor());
6531 if (!(pd->session_bus = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION)))
6533 ERR("Unable to connect to Session Bus");
6536 if (!(pd->bus_obj = eldbus_object_get(pd->session_bus, A11Y_DBUS_NAME, A11Y_DBUS_PATH)))
6538 ERR("Could not get /org/a11y/bus object");
6541 if (!(proxy = eldbus_proxy_get(pd->bus_obj, A11Y_DBUS_STATUS_INTERFACE)))
6543 ERR("Could not get proxy object for %s interface", A11Y_DBUS_STATUS_INTERFACE);
6546 if (!(req = eldbus_proxy_property_get(proxy, "ScreenReaderEnabled", _screen_reader_enabled_get, obj)))
6548 ERR("Could not send PropertyGet request");
6551 pd->pending_requests = eina_list_append(pd->pending_requests, req);
6553 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6554 if (!(req = eldbus_proxy_property_get(proxy, A11Y_DBUS_ENABLED_PROPERTY, _at_spi_client_enabled_get, obj)))
6556 ERR("Could not send PropertyGet request");
6560 pd->pending_requests = eina_list_append(pd->pending_requests, req);
6563 eldbus_proxy_properties_monitor(proxy, EINA_TRUE);
6564 eldbus_proxy_event_callback_add(proxy, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
6565 _properties_changed_cb, obj);
6570 eldbus_object_unref(pd->bus_obj);
6573 eldbus_connection_unref(pd->session_bus);
6574 pd->session_bus = NULL;
6579 _elm_atspi_bridge_eo_base_destructor(Eo *obj, Elm_Atspi_Bridge_Data *pd)
6581 _a11y_connection_shutdown(obj);
6583 if (pd->bus_obj) eldbus_object_unref(pd->bus_obj);
6584 if (pd->session_bus) eldbus_connection_unref(pd->session_bus);
6585 if (pd->root) eo_del(pd->root);
6587 eo_do_super(obj, ELM_ATSPI_BRIDGE_CLASS, eo_destructor());
6591 elm_atspi_bridge_object_address_get(Eo *obj, char **bus, char **path)
6593 Eo *bridge = _elm_atspi_bridge_get();
6596 ERR("Connection with accessibility bus not established.");
6599 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE);
6600 if (!eo_isa(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
6602 ERR("Connection with accessibility bus not established.");
6605 if (bus) *bus = strdup(eldbus_connection_unique_name_get(pd->a11y_bus));
6606 if (path) *path = strdup(_bridge_path_from_object(bridge, obj));
6612 _proxy_property_get(const Eldbus_Service_Interface *interface, const char *property,
6613 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg EINA_UNUSED,
6614 Eldbus_Message **error EINA_UNUSED)
6617 Eo *obj = eldbus_service_object_data_get(interface, "_atspi_obj");
6618 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6620 if (!strcmp(property, "Object"))
6623 eo_do(obj, parent = eo_parent_get());
6624 if (!elm_atspi_bridge_object_address_get(parent, &bus, &path))
6627 Eldbus_Message_Iter *iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
6630 eldbus_message_iter_basic_append(iter_struct, 's', bus);
6631 eldbus_message_iter_basic_append(iter_struct, 'o', path);
6632 eldbus_message_iter_container_close(iter, iter_struct);
6641 static const Eldbus_Property proxy_properties[] = {
6642 { "Object", "(so)", _proxy_property_get, NULL, 0 },
6643 { NULL, NULL, NULL, NULL, 0 }
6646 static const Eldbus_Service_Interface_Desc _proxy_iface_desc = {
6647 ELM_ATSPI_DBUS_INTERFACE_PROXY, socket_methods, NULL, proxy_properties, NULL, NULL
6650 static void _embedded_reply_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
6652 Eo *parent, *proxy = data;
6653 const char *err, *txt;
6655 if (eldbus_message_error_get(msg, &err, &txt))
6657 ERR("AT-SPI: Embedded method call failed: %s %s", err, txt);
6658 eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_DISCONNECTED, NULL));
6661 eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_CONNECTED, NULL));
6663 eo_do(proxy, parent = eo_parent_get());
6665 elm_interface_atspi_accessible_children_changed_added_signal_emit(parent, proxy)
6669 _plug_embedded_send(Eldbus_Connection *conn, Eo *proxy, const char *bus, const char *path)
6671 char *obj_path = NULL;
6673 Eldbus_Message *msg = NULL;
6675 eo_do(proxy, parent = eo_parent_get());
6676 if (!parent) goto fail;
6678 msg = eldbus_message_method_call_new(bus, path, ATSPI_DBUS_INTERFACE_SOCKET, "Embedded");
6679 if (!msg) goto fail;
6681 if (!elm_atspi_bridge_object_address_get(parent, NULL, &obj_path))
6684 if (!eldbus_message_arguments_append(msg, "s", obj_path))
6687 if (!eldbus_connection_send(conn, msg, _embedded_reply_cb, proxy, 100))
6690 ELM_SAFE_FREE(obj_path, free);
6694 ERR("AT-SPI: Unable to send Embedded request.");
6695 if (msg) eldbus_message_unref(msg);
6696 ELM_SAFE_FREE(obj_path, free);
6697 eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_DISCONNECTED, NULL));
6700 static void _socket_addr_get_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
6703 const char *bus, *path, *err, *txt;
6704 Eldbus_Message_Iter *iter, *iter_variant, *iter_struct;
6706 Eo *bridge = _elm_atspi_bridge_get();
6709 ERR("AT-SPI: Atspi bridge is not enabled.");
6712 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6714 if (eldbus_message_error_get(msg, &err, &txt))
6716 ERR("Unable to connect to socket: %s %s", err, txt);
6720 iter = eldbus_message_iter_get(msg);
6721 if (!eldbus_message_iter_arguments_get(iter, "v", &iter_variant))
6723 ERR("Unable to get variant parameter");
6727 if (!eldbus_message_iter_arguments_get(iter_variant, "(so)", &iter_struct))
6729 ERR("Unable to get so parameters");
6733 if (!eldbus_message_iter_arguments_get(iter_struct, "so", &bus, &path))
6735 ERR("Unable to get so parameters");
6739 eo_do(proxy, elm_obj_atspi_proxy_address_set(bus, path));
6741 _plug_embedded_send(pd->a11y_bus, proxy, bus, path);
6746 eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_DISCONNECTED, NULL));
6750 eo_do(proxy, elm_obj_atspi_proxy_address_get_retry_timer_add());
6754 _plug_address_discover(Eldbus_Connection *conn, Eo *proxy, const char *svc_bus, const char *svc_path)
6756 Eldbus_Object *dobj;
6757 dobj = eldbus_object_get(conn, svc_bus, svc_path);
6760 ERR("Unable to get eldbus object from: %s %s", svc_bus, svc_path);
6764 Eldbus_Message *msg = eldbus_object_method_call_new(dobj, ELDBUS_FDO_INTERFACE_PROPERTIES, "Get");
6765 eldbus_message_arguments_append(msg, "ss", ELM_ATSPI_DBUS_INTERFACE_PROXY, "Object");
6766 eldbus_object_send(dobj, msg, _socket_addr_get_cb, proxy, 100);
6769 static void _plug_connect(Eldbus_Connection *conn, Eo *proxy)
6771 const char *bus, *path;
6773 eo_do(proxy, bus = eo_key_data_get("__svc_bus"));
6774 eo_do(proxy, path = eo_key_data_get("__svc_path"));
6778 _plug_address_discover(conn, proxy, bus, path);
6783 eo_do(proxy, elm_obj_atspi_proxy_address_get(&bus, &path));
6786 ERR("AT-SPI: Elm_Atspi_Proxy bus or path not set. Unable to connect");
6787 eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_DISCONNECTED, NULL));
6790 _plug_embedded_send(conn, proxy, bus, path);
6795 static Eina_Bool _from_list_remove(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
6797 Eina_List **list = data;
6798 *list = eina_list_remove(*list, obj);
6802 EAPI void elm_atspi_bridge_utils_proxy_connect(Eo *proxy)
6804 Eo *bridge = _elm_atspi_bridge_get();
6808 ERR("AT-SPI: Atspi bridge is not enabled.");
6809 eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_DISCONNECTED, NULL));
6812 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6816 if (!eina_list_data_find(pd->plug_queue, proxy))
6818 pd->plug_queue = eina_list_append(pd->plug_queue, proxy);
6819 eo_do(proxy, eo_event_callback_add(EO_EV_DEL, _from_list_remove, &pd->plug_queue));
6823 _plug_connect(pd->a11y_bus, proxy);
6827 * @brief Service name sanitizer according to specs:
6828 * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names
6829 * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-object-path
6831 char *_sanitize_service_name(const char *name)
6833 char ret[256] = "\0";
6835 if (!name) return NULL;
6837 const char *tmp = name;
6840 // name element should not begin with digit. Swallow non-charater prefix
6841 while ((*tmp != '\0') && !isalpha(*tmp)) tmp++;
6843 // append rest of character valid charactes [A-Z][a-z][0-9]_
6844 while ((*tmp != '\0') && (dst < &ret[sizeof(ret) - 1]))
6846 if (isalpha(*tmp) || isdigit(*tmp) || (*tmp == '_'))
6855 Eo* _elm_atspi_bridge_utils_proxy_create(Eo *parent, const char *svcname, int svcnum, Elm_Atspi_Proxy_Type type)
6858 char bus[256], path[256], *name;
6861 name = _sanitize_service_name(svcname);
6862 if (!name) return NULL;
6864 res = snprintf(bus, sizeof(bus), "elm.atspi.proxy.socket.%s-%d", name, svcnum);
6865 if (res < 0 || (res >= (int)sizeof(bus)))
6871 res = snprintf(path, sizeof(path), "/elm/atspi/proxy/socket/%s/%d", name, svcnum);
6872 if (res < 0 || (res >= (int)sizeof(path)))
6880 ret = eo_add(ELM_ATSPI_PROXY_CLASS, parent, elm_obj_atspi_proxy_constructor(type));
6881 if (!ret) return NULL;
6883 eo_do(ret, eo_key_data_set("__svc_bus", eina_stringshare_add(bus)));
6884 eo_do(ret, eo_key_data_set("__svc_path", eina_stringshare_add(path)));
6890 _on_socket_del(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED)
6892 Eldbus_Service_Interface *ifc = data;
6894 Eldbus_Connection *conn = eldbus_service_connection_get(ifc);
6895 eo_do(obj, bus = eo_key_data_get("__svc_bus"));
6896 eldbus_name_release(conn, bus, NULL, NULL);
6897 eldbus_service_interface_unregister(ifc);
6902 _proxy_interface_register(Eldbus_Connection *conn, Eo *proxy, const char *bus, const char *path)
6904 Eldbus_Service_Interface *proxy_infc;
6905 Eo *bridge = _elm_atspi_bridge_get();
6908 ERR("AT-SPI: Atspi bridge is not enabled.");
6911 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6913 eldbus_name_request(conn, bus, ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE, NULL, NULL);
6914 proxy_infc = eldbus_service_interface_register(pd->a11y_bus, path, &_proxy_iface_desc);
6916 ERR("AT-SPI: Proxy interface registration failed");
6917 eo_do(proxy, eo_event_callback_add(EO_EV_DEL, _on_socket_del, proxy_infc));
6918 eldbus_service_object_data_set(proxy_infc, "_atspi_obj", proxy);
6921 static void _socket_ifc_create(Eldbus_Connection *conn, Eo *proxy)
6923 const char *bus, *path;
6924 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6925 Eo *bridge = _elm_atspi_bridge_get();
6926 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6929 eo_do(proxy, bus = eo_key_data_get("__svc_bus"));
6930 eo_do(proxy, path = eo_key_data_get("__svc_path"));
6933 _proxy_interface_register(conn, proxy, bus, path);
6935 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6936 pd->interfaces.socket =
6937 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &socket_iface_desc);
6941 EAPI void elm_atspi_bridge_utils_proxy_listen(Eo *proxy)
6943 Eo *bridge = _elm_atspi_bridge_get();
6946 ERR("AT-SPI: Atspi bridge is not enabled.");
6949 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6952 if (!eina_list_data_find(pd->socket_queue, proxy))
6954 pd->socket_queue = eina_list_append(pd->socket_queue, proxy);
6955 eo_do(proxy, eo_event_callback_add(EO_EV_DEL, _from_list_remove, &pd->socket_queue));
6959 _socket_ifc_create(pd->a11y_bus, proxy);
6962 //TIZEN_ONLY(20160527) - Add direct reading feature
6964 _on_read_command_call(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
6966 const char *errname, *errmsg;
6970 Elm_Atspi_Say_Info *say_info = data;
6972 if (eldbus_message_error_get(msg, &errname, &errmsg))
6974 ERR("%s %s", errname, errmsg);
6980 // get read command id and map it to obj
6981 if (eldbus_message_arguments_get(msg, "sbi", &s, &b, &i))
6983 if (!read_command_id)
6984 read_command_id = eina_hash_int32_new(NULL);
6986 if (!read_command_id) {
6987 ERR("eina_hash_int32_new() failed to create new map to store callbacks for direct reading commands");
6991 eina_hash_add(read_command_id, &i, say_info);
6997 elm_atspi_bridge_utils_say(const char* text,
6998 Eina_Bool discardable,
6999 const Elm_Atspi_Say_Signal_Cb func,
7002 Eldbus_Message *msg;
7003 Eldbus_Message_Iter *iter;
7004 Elm_Atspi_Say_Info *say_info = NULL;
7005 Eo *bridge = _elm_atspi_bridge_get();
7008 ERR("AT-SPI: Atspi bridge is not enabled.");
7011 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
7014 ERR("AT-SPI: a11y bus is not set.");
7018 msg = eldbus_message_method_call_new(ELM_ATSPI_DIRECT_READ_BUS,
7019 ELM_ATSPI_DIRECT_READ_PATH,
7020 ELM_ATSPI_DIRECT_READ_INTERFACE,
7022 iter = eldbus_message_iter_get(msg);
7023 eldbus_message_iter_arguments_append(iter, "sb", text, discardable);
7025 say_info = calloc(1, sizeof(Elm_Atspi_Say_Info));
7027 say_info->func = func;
7028 say_info->data = (void *)data;
7031 eldbus_connection_send(pd->a11y_bus, msg, _on_read_command_call, say_info, -1);
7035 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
7037 _offset_set_reply_cb(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
7039 const char *err, *txt;
7041 if (eldbus_message_error_get(msg, &err, &txt))
7043 ERR("AT-SPI: SetOffset method call failed: %s %s", err, txt);
7048 void elm_atspi_bridge_utils_proxy_offset_set(Eo *proxy, int x, int y)
7050 const char *bus, *path;
7051 Eo *bridge = _elm_atspi_bridge_get();
7052 if (!bridge) return;
7054 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
7056 if (!pd->a11y_bus) return;
7058 eo_do(proxy, bus = eo_key_data_get("__svc_bus"));
7059 eo_do(proxy, path = eo_key_data_get("__svc_path"));
7061 Eldbus_Message *msg = NULL;
7063 msg = eldbus_message_method_call_new(bus, path, ELM_ATSPI_DBUS_INTERFACE_PROXY, "SetOffset");
7064 if (!msg) goto fail;
7066 if (!eldbus_message_arguments_append(msg, "i", x))
7069 if (!eldbus_message_arguments_append(msg, "i", y))
7072 if (!eldbus_connection_send(pd->a11y_bus, msg, _offset_set_reply_cb, NULL, 100))
7078 ERR("AT-SPI: Unable to send SetOffset request.");
7079 if (msg) eldbus_message_unref(msg);
7082 //TIZEN_ONLY(20161027) - Export elm_atspi_bridge_utils_is_screen_reader_enabled
7083 EAPI Eina_Bool elm_atspi_bridge_utils_is_screen_reader_enabled(void)
7085 Eo *bridge = _elm_atspi_bridge_get();
7088 ERR("AT-SPI: Atspi bridge is not enabled.");
7091 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE);
7092 return pd->screen_reader_enabled;
7095 #include "elm_atspi_bridge.eo.c"