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}
223 ELM_ACCESSIBLE_DEFAULT_LABEL_ENABLED = 0,
224 ELM_ACCESSIBLE_DEFAULT_LABEL_DISABLED = 1 << 0,
227 enum _Atspi_Object_Child_Event_Type
229 ATSPI_OBJECT_CHILD_ADDED = 0,
230 ATSPI_OBJECT_CHILD_REMOVED
233 enum _Atspi_Object_Property
235 ATSPI_OBJECT_PROPERTY_NAME = 0,
236 ATSPI_OBJECT_PROPERTY_DESCRIPTION,
237 ATSPI_OBJECT_PROPERTY_VALUE,
238 ATSPI_OBJECT_PROPERTY_ROLE,
239 ATSPI_OBJECT_PROPERTY_PARENT,
240 ATSPI_OBJECT_PROPERTY_LAST
243 enum _Atspi_Object_Signals {
244 ATSPI_OBJECT_EVENT_PROPERTY_CHANGED = 0,
245 ATSPI_OBJECT_EVENT_BOUNDS_CHANGED,
246 ATSPI_OBJECT_EVENT_LINK_SELECTED,
247 ATSPI_OBJECT_EVENT_STATE_CHANGED,
248 ATSPI_OBJECT_EVENT_CHILDREN_CHANGED,
249 ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED,
250 ATSPI_OBJECT_EVENT_SELECTION_CHANGED,
251 ATSPI_OBJECT_EVENT_MODEL_CHANGED,
252 ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED,
253 ATSPI_OBJECT_EVENT_ROW_INSERTED,
254 ATSPI_OBJECT_EVENT_ROW_REORDERED,
255 ATSPI_OBJECT_EVENT_ROW_DELETED,
256 ATSPI_OBJECT_EVENT_COLUMN_INSERTED,
257 ATSPI_OBJECT_EVENT_COLUMN_REORDERED,
258 ATSPI_OBJECT_EVENT_COLUMN_DELETED,
259 ATSPI_OBJECT_EVENT_TEXT_BOUNDS_CHANGED,
260 ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED,
261 ATSPI_OBJECT_EVENT_TEXT_CHANGED,
262 ATSPI_OBJECT_EVENT_TEXT_ATTRIBUTES_CHANGED,
263 ATSPI_OBJECT_EVENT_TEXT_CARET_MOVED,
264 ATSPI_OBJECT_EVENT_ATTRIBUTES_CHANGED,
265 //TIZEN_ONLY(20160623): atspi: moved highlight when object is out of screen
266 ATSPI_OBJECT_EVENT_MOVE_OUTED
270 enum _Atspi_Window_Signals
272 ATSPI_WINDOW_EVENT_PROPERTY_CHANGE = 0,
273 ATSPI_WINDOW_EVENT_MINIMIZE,
274 ATSPI_WINDOW_EVENT_MAXIMIZE,
275 ATSPI_WINDOW_EVENT_RESTORE,
276 ATSPI_WINDOW_EVENT_CLOSE,
277 ATSPI_WINDOW_EVENT_CREATE,
278 ATSPI_WINDOW_EVENT_REPARENT,
279 ATSPI_WINDOW_EVENT_DESKTOPCREATE,
280 ATSPI_WINDOW_EVENT_DESKTOPDESTROY,
281 ATSPI_WINDOW_EVENT_DESTROY,
282 ATSPI_WINDOW_EVENT_ACTIVATE,
283 ATSPI_WINDOW_EVENT_DEACTIVATE,
284 ATSPI_WINDOW_EVENT_RAISE,
285 ATSPI_WINDOW_EVENT_LOWER,
286 ATSPI_WINDOW_EVENT_MOVE,
287 ATSPI_WINDOW_EVENT_RESIZE,
288 ATSPI_WINDOW_EVENT_SHADE,
289 ATSPI_WINDOW_EVENT_UUSHADE,
290 ATSPI_WINDOW_EVENT_RESTYLE,
293 static const Eldbus_Signal _event_obj_signals[] = {
294 [ATSPI_OBJECT_EVENT_PROPERTY_CHANGED] = {"PropertyChange", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
295 [ATSPI_OBJECT_EVENT_BOUNDS_CHANGED] = {"BoundsChanged", ELDBUS_ARGS({"siiv(iiii)", NULL}), 0},
296 [ATSPI_OBJECT_EVENT_LINK_SELECTED] = {"LinkSelected", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
297 [ATSPI_OBJECT_EVENT_STATE_CHANGED] = {"StateChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
298 [ATSPI_OBJECT_EVENT_CHILDREN_CHANGED] = {"ChildrenChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
299 [ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED] = {"VisibleDataChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
300 [ATSPI_OBJECT_EVENT_SELECTION_CHANGED] = {"SelectionChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
301 [ATSPI_OBJECT_EVENT_MODEL_CHANGED] = {"ModelChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
302 [ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED] = {"ActiveDescendantChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
303 [ATSPI_OBJECT_EVENT_ROW_INSERTED] = {"RowInserted", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
304 [ATSPI_OBJECT_EVENT_ROW_REORDERED] = {"RowReordered", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
305 [ATSPI_OBJECT_EVENT_ROW_DELETED] = {"RowDeleted", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
306 [ATSPI_OBJECT_EVENT_COLUMN_INSERTED] = {"ColumnInserted", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
307 [ATSPI_OBJECT_EVENT_COLUMN_REORDERED] = {"ColumnReordered", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
308 [ATSPI_OBJECT_EVENT_COLUMN_DELETED] = {"ColumnDeleted", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
309 [ATSPI_OBJECT_EVENT_TEXT_BOUNDS_CHANGED] = {"TextBoundsChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
310 [ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED] = {"TextSelectionChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
311 [ATSPI_OBJECT_EVENT_TEXT_CHANGED] = {"TextChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
312 [ATSPI_OBJECT_EVENT_TEXT_ATTRIBUTES_CHANGED] = {"TextAttributesChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
313 [ATSPI_OBJECT_EVENT_TEXT_CARET_MOVED] = {"TextCaretMoved", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
314 [ATSPI_OBJECT_EVENT_ATTRIBUTES_CHANGED] = {"AttributesChanged", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
315 //TIZEN_ONLY(20160623): atspi: moved highlight when object is out of screen
316 [ATSPI_OBJECT_EVENT_MOVE_OUTED] = {"MoveOuted", ELDBUS_ARGS({"siiv(i)", NULL}), 0},
318 {NULL, ELDBUS_ARGS({NULL, NULL}), 0}
321 static const Eldbus_Signal _window_obj_signals[] = {
322 [ATSPI_WINDOW_EVENT_PROPERTY_CHANGE] = {"PropertyChange", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
323 [ATSPI_WINDOW_EVENT_MINIMIZE] = {"Minimize", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
324 [ATSPI_WINDOW_EVENT_MAXIMIZE] = {"Maximize", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
325 [ATSPI_WINDOW_EVENT_RESTORE] = {"Restore", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
326 [ATSPI_WINDOW_EVENT_CLOSE] = {"Close", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
327 [ATSPI_WINDOW_EVENT_CREATE] = {"Create", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
328 [ATSPI_WINDOW_EVENT_REPARENT] = {"Reparent", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
329 [ATSPI_WINDOW_EVENT_DESKTOPCREATE] = {"DesktopCreate", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
330 [ATSPI_WINDOW_EVENT_DESKTOPDESTROY] = {"DesktopDestroy", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
331 [ATSPI_WINDOW_EVENT_DESTROY] = {"Destroy", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
332 [ATSPI_WINDOW_EVENT_ACTIVATE] = {"Activate", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
333 [ATSPI_WINDOW_EVENT_DEACTIVATE] = {"Deactivate", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
334 [ATSPI_WINDOW_EVENT_RAISE] = {"Raise", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
335 [ATSPI_WINDOW_EVENT_LOWER] = {"Lower", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
336 [ATSPI_WINDOW_EVENT_MOVE] = {"Move", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
337 [ATSPI_WINDOW_EVENT_RESIZE] = {"Resize", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
338 [ATSPI_WINDOW_EVENT_SHADE] = {"Shade", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
339 [ATSPI_WINDOW_EVENT_UUSHADE] = {"uUshade", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
340 [ATSPI_WINDOW_EVENT_RESTYLE] = {"Restyle", ELDBUS_ARGS({"siiv(so)", NULL}), 0},
341 {NULL, ELDBUS_ARGS({NULL, NULL}), 0}
344 const int elm_roles_to_atspi_roles[][2] = {
345 { ELM_ATSPI_ROLE_INVALID, ATSPI_ROLE_INVALID },
346 { ELM_ATSPI_ROLE_ACCELERATOR_LABEL, ATSPI_ROLE_ACCELERATOR_LABEL },
347 { ELM_ATSPI_ROLE_ALERT, ATSPI_ROLE_ALERT },
348 { ELM_ATSPI_ROLE_ANIMATION, ATSPI_ROLE_ANIMATION },
349 { ELM_ATSPI_ROLE_ARROW, ATSPI_ROLE_ARROW },
350 { ELM_ATSPI_ROLE_CALENDAR, ATSPI_ROLE_CALENDAR },
351 { ELM_ATSPI_ROLE_CANVAS, ATSPI_ROLE_CANVAS },
352 { ELM_ATSPI_ROLE_CHECK_BOX, ATSPI_ROLE_CHECK_BOX },
353 { ELM_ATSPI_ROLE_CHECK_MENU_ITEM, ATSPI_ROLE_CHECK_MENU_ITEM },
354 { ELM_ATSPI_ROLE_COLOR_CHOOSER, ATSPI_ROLE_COLOR_CHOOSER },
355 { ELM_ATSPI_ROLE_COLUMN_HEADER, ATSPI_ROLE_COLUMN_HEADER },
356 { ELM_ATSPI_ROLE_COMBO_BOX, ATSPI_ROLE_COMBO_BOX },
357 { ELM_ATSPI_ROLE_DATE_EDITOR, ATSPI_ROLE_DATE_EDITOR },
358 { ELM_ATSPI_ROLE_DESKTOP_ICON, ATSPI_ROLE_DESKTOP_ICON },
359 { ELM_ATSPI_ROLE_DESKTOP_FRAME, ATSPI_ROLE_DESKTOP_FRAME },
360 { ELM_ATSPI_ROLE_DIAL, ATSPI_ROLE_DIAL },
361 { ELM_ATSPI_ROLE_DIALOG, ATSPI_ROLE_DIALOG },
362 { ELM_ATSPI_ROLE_DIRECTORY_PANE, ATSPI_ROLE_DIRECTORY_PANE },
363 { ELM_ATSPI_ROLE_DRAWING_AREA, ATSPI_ROLE_DRAWING_AREA },
364 { ELM_ATSPI_ROLE_FILE_CHOOSER, ATSPI_ROLE_FILE_CHOOSER },
365 { ELM_ATSPI_ROLE_FILLER, ATSPI_ROLE_FILLER },
366 { ELM_ATSPI_ROLE_FOCUS_TRAVERSABLE, ATSPI_ROLE_FOCUS_TRAVERSABLE },
367 { ELM_ATSPI_ROLE_FONT_CHOOSER, ATSPI_ROLE_FONT_CHOOSER },
368 { ELM_ATSPI_ROLE_FRAME, ATSPI_ROLE_FRAME },
369 { ELM_ATSPI_ROLE_GLASS_PANE, ATSPI_ROLE_GLASS_PANE },
370 { ELM_ATSPI_ROLE_HTML_CONTAINER, ATSPI_ROLE_HTML_CONTAINER },
371 { ELM_ATSPI_ROLE_ICON, ATSPI_ROLE_ICON },
372 { ELM_ATSPI_ROLE_IMAGE, ATSPI_ROLE_IMAGE },
373 { ELM_ATSPI_ROLE_INTERNAL_FRAME, ATSPI_ROLE_INTERNAL_FRAME },
374 { ELM_ATSPI_ROLE_LABEL, ATSPI_ROLE_LABEL },
375 { ELM_ATSPI_ROLE_LAYERED_PANE, ATSPI_ROLE_LAYERED_PANE },
376 { ELM_ATSPI_ROLE_LIST, ATSPI_ROLE_LIST },
377 { ELM_ATSPI_ROLE_LIST_ITEM, ATSPI_ROLE_LIST_ITEM },
378 { ELM_ATSPI_ROLE_MENU, ATSPI_ROLE_MENU },
379 { ELM_ATSPI_ROLE_MENU_BAR, ATSPI_ROLE_MENU_BAR },
380 { ELM_ATSPI_ROLE_MENU_ITEM, ATSPI_ROLE_MENU_ITEM },
381 { ELM_ATSPI_ROLE_OPTION_PANE, ATSPI_ROLE_OPTION_PANE },
382 { ELM_ATSPI_ROLE_PAGE_TAB, ATSPI_ROLE_PAGE_TAB },
383 { ELM_ATSPI_ROLE_PAGE_TAB_LIST, ATSPI_ROLE_PAGE_TAB_LIST },
384 { ELM_ATSPI_ROLE_PANEL, ATSPI_ROLE_PANEL },
385 { ELM_ATSPI_ROLE_PASSWORD_TEXT, ATSPI_ROLE_PASSWORD_TEXT },
386 { ELM_ATSPI_ROLE_POPUP_MENU, ATSPI_ROLE_POPUP_MENU },
387 { ELM_ATSPI_ROLE_PROGRESS_BAR, ATSPI_ROLE_PROGRESS_BAR },
388 { ELM_ATSPI_ROLE_PUSH_BUTTON, ATSPI_ROLE_PUSH_BUTTON },
389 { ELM_ATSPI_ROLE_RADIO_BUTTON, ATSPI_ROLE_RADIO_BUTTON },
390 { ELM_ATSPI_ROLE_RADIO_MENU_ITEM, ATSPI_ROLE_RADIO_MENU_ITEM },
391 { ELM_ATSPI_ROLE_ROOT_PANE, ATSPI_ROLE_ROOT_PANE },
392 { ELM_ATSPI_ROLE_ROW_HEADER, ATSPI_ROLE_ROW_HEADER },
393 { ELM_ATSPI_ROLE_SCROLL_BAR, ATSPI_ROLE_SCROLL_BAR },
394 { ELM_ATSPI_ROLE_SCROLL_PANE, ATSPI_ROLE_SCROLL_PANE },
395 { ELM_ATSPI_ROLE_SEPARATOR, ATSPI_ROLE_SEPARATOR },
396 { ELM_ATSPI_ROLE_SLIDER, ATSPI_ROLE_SLIDER },
397 { ELM_ATSPI_ROLE_SPIN_BUTTON, ATSPI_ROLE_SPIN_BUTTON },
398 { ELM_ATSPI_ROLE_SPLIT_PANE, ATSPI_ROLE_SPLIT_PANE },
399 { ELM_ATSPI_ROLE_STATUS_BAR, ATSPI_ROLE_STATUS_BAR },
400 { ELM_ATSPI_ROLE_TABLE, ATSPI_ROLE_TABLE },
401 { ELM_ATSPI_ROLE_TABLE_CELL, ATSPI_ROLE_TABLE_CELL },
402 { ELM_ATSPI_ROLE_TABLE_COLUMN_HEADER, ATSPI_ROLE_TABLE_COLUMN_HEADER },
403 { ELM_ATSPI_ROLE_TABLE_ROW_HEADER, ATSPI_ROLE_TABLE_ROW_HEADER },
404 { ELM_ATSPI_ROLE_TEAROFF_MENU_ITEM, ATSPI_ROLE_TEAROFF_MENU_ITEM },
405 { ELM_ATSPI_ROLE_TERMINAL, ATSPI_ROLE_TERMINAL },
406 { ELM_ATSPI_ROLE_TEXT, ATSPI_ROLE_TEXT },
407 { ELM_ATSPI_ROLE_TOGGLE_BUTTON, ATSPI_ROLE_TOGGLE_BUTTON },
408 { ELM_ATSPI_ROLE_TOOL_BAR, ATSPI_ROLE_TOOL_BAR },
409 { ELM_ATSPI_ROLE_TOOL_TIP, ATSPI_ROLE_TOOL_TIP },
410 { ELM_ATSPI_ROLE_TREE, ATSPI_ROLE_TREE },
411 { ELM_ATSPI_ROLE_TREE_TABLE, ATSPI_ROLE_TREE_TABLE },
412 { ELM_ATSPI_ROLE_UNKNOWN, ATSPI_ROLE_UNKNOWN },
413 { ELM_ATSPI_ROLE_VIEWPORT, ATSPI_ROLE_VIEWPORT },
414 { ELM_ATSPI_ROLE_WINDOW, ATSPI_ROLE_WINDOW },
415 { ELM_ATSPI_ROLE_EXTENDED, ATSPI_ROLE_EXTENDED },
416 { ELM_ATSPI_ROLE_HEADER, ATSPI_ROLE_HEADER },
417 { ELM_ATSPI_ROLE_FOOTER, ATSPI_ROLE_FOOTER },
418 { ELM_ATSPI_ROLE_PARAGRAPH, ATSPI_ROLE_PARAGRAPH },
419 { ELM_ATSPI_ROLE_RULER, ATSPI_ROLE_RULER },
420 { ELM_ATSPI_ROLE_APPLICATION, ATSPI_ROLE_APPLICATION },
421 { ELM_ATSPI_ROLE_AUTOCOMPLETE, ATSPI_ROLE_AUTOCOMPLETE },
422 { ELM_ATSPI_ROLE_EDITBAR, ATSPI_ROLE_EDITBAR },
423 { ELM_ATSPI_ROLE_EMBEDDED, ATSPI_ROLE_EMBEDDED },
424 { ELM_ATSPI_ROLE_ENTRY, ATSPI_ROLE_ENTRY },
425 { ELM_ATSPI_ROLE_CHART, ATSPI_ROLE_CHART },
426 { ELM_ATSPI_ROLE_CAPTION, ATSPI_ROLE_CAPTION },
427 { ELM_ATSPI_ROLE_DOCUMENT_FRAME, ATSPI_ROLE_DOCUMENT_FRAME },
428 { ELM_ATSPI_ROLE_HEADING, ATSPI_ROLE_HEADING },
429 { ELM_ATSPI_ROLE_PAGE, ATSPI_ROLE_PAGE },
430 { ELM_ATSPI_ROLE_SECTION, ATSPI_ROLE_SECTION },
431 { ELM_ATSPI_ROLE_REDUNDANT_OBJECT, ATSPI_ROLE_REDUNDANT_OBJECT },
432 { ELM_ATSPI_ROLE_FORM, ATSPI_ROLE_FORM },
433 { ELM_ATSPI_ROLE_LINK, ATSPI_ROLE_LINK },
434 { ELM_ATSPI_ROLE_INPUT_METHOD_WINDOW, ATSPI_ROLE_INPUT_METHOD_WINDOW },
435 { ELM_ATSPI_ROLE_TABLE_ROW, ATSPI_ROLE_TABLE_ROW },
436 { ELM_ATSPI_ROLE_TREE_ITEM, ATSPI_ROLE_TREE_ITEM },
437 { ELM_ATSPI_ROLE_DOCUMENT_SPREADSHEET, ATSPI_ROLE_DOCUMENT_SPREADSHEET },
438 { ELM_ATSPI_ROLE_DOCUMENT_PRESENTATION, ATSPI_ROLE_DOCUMENT_PRESENTATION },
439 { ELM_ATSPI_ROLE_DOCUMENT_TEXT, ATSPI_ROLE_DOCUMENT_TEXT },
440 { ELM_ATSPI_ROLE_DOCUMENT_WEB, ATSPI_ROLE_DOCUMENT_WEB },
441 { ELM_ATSPI_ROLE_DOCUMENT_EMAIL, ATSPI_ROLE_DOCUMENT_EMAIL },
442 { ELM_ATSPI_ROLE_COMMENT, ATSPI_ROLE_COMMENT },
443 { ELM_ATSPI_ROLE_LIST_BOX, ATSPI_ROLE_LIST_BOX },
444 { ELM_ATSPI_ROLE_GROUPING, ATSPI_ROLE_GROUPING },
445 { ELM_ATSPI_ROLE_IMAGE_MAP, ATSPI_ROLE_IMAGE_MAP },
446 { ELM_ATSPI_ROLE_NOTIFICATION, ATSPI_ROLE_NOTIFICATION },
447 { ELM_ATSPI_ROLE_INFO_BAR, ATSPI_ROLE_INFO_BAR },
448 { ELM_ATSPI_ROLE_LAST_DEFINED, ATSPI_ROLE_LAST_DEFINED },
451 struct atspi_state_desc
453 Elm_Atspi_State_Type elm_state;
454 AtspiStateType atspi_state;
458 const struct atspi_state_desc elm_states_to_atspi_state[] = {
459 { ELM_ATSPI_STATE_INVALID, ATSPI_STATE_INVALID, "invalid" },
460 { ELM_ATSPI_STATE_ACTIVE, ATSPI_STATE_ACTIVE, "active" },
461 { ELM_ATSPI_STATE_ARMED, ATSPI_STATE_ARMED, "armed" },
462 { ELM_ATSPI_STATE_BUSY, ATSPI_STATE_BUSY, "busy" },
463 { ELM_ATSPI_STATE_CHECKED, ATSPI_STATE_CHECKED, "checked" },
464 { ELM_ATSPI_STATE_COLLAPSED, ATSPI_STATE_COLLAPSED, "collapsed" },
465 { ELM_ATSPI_STATE_DEFUNCT, ATSPI_STATE_DEFUNCT, "defunct" },
466 { ELM_ATSPI_STATE_EDITABLE, ATSPI_STATE_EDITABLE, "editable" },
467 { ELM_ATSPI_STATE_ENABLED, ATSPI_STATE_ENABLED, "enabled" },
468 { ELM_ATSPI_STATE_EXPANDABLE, ATSPI_STATE_EXPANDABLE, "expandable" },
469 { ELM_ATSPI_STATE_EXPANDED, ATSPI_STATE_EXPANDED, "expanded" },
470 { ELM_ATSPI_STATE_FOCUSABLE, ATSPI_STATE_FOCUSABLE, "focusable" },
471 { ELM_ATSPI_STATE_FOCUSED, ATSPI_STATE_FOCUSED, "focused" },
472 { ELM_ATSPI_STATE_HAS_TOOLTIP, ATSPI_STATE_HAS_TOOLTIP, "has-tooltip" },
473 { ELM_ATSPI_STATE_HORIZONTAL, ATSPI_STATE_HORIZONTAL, "horizontal" },
474 { ELM_ATSPI_STATE_ICONIFIED, ATSPI_STATE_ICONIFIED, "iconified" },
475 { ELM_ATSPI_STATE_MODAL, ATSPI_STATE_MODAL, "modal" },
476 { ELM_ATSPI_STATE_MULTI_LINE, ATSPI_STATE_MULTI_LINE, "multi-line" },
477 { ELM_ATSPI_STATE_MULTISELECTABLE, ATSPI_STATE_MULTISELECTABLE, "multiselectable" },
478 { ELM_ATSPI_STATE_OPAQUE, ATSPI_STATE_OPAQUE, "opaque" },
479 { ELM_ATSPI_STATE_PRESSED, ATSPI_STATE_PRESSED, "pressed" },
480 { ELM_ATSPI_STATE_RESIZABLE, ATSPI_STATE_RESIZABLE, "resizable" },
481 { ELM_ATSPI_STATE_SELECTABLE, ATSPI_STATE_SELECTABLE, "selectable" },
482 { ELM_ATSPI_STATE_SELECTED, ATSPI_STATE_SELECTED, "selected" },
483 { ELM_ATSPI_STATE_SENSITIVE, ATSPI_STATE_SENSITIVE, "sensitive" },
484 { ELM_ATSPI_STATE_SHOWING, ATSPI_STATE_SHOWING, "showing" },
485 { ELM_ATSPI_STATE_SINGLE_LINE, ATSPI_STATE_SINGLE_LINE, "single-line" },
486 { ELM_ATSPI_STATE_STALE, ATSPI_STATE_STALE, "stale" },
487 { ELM_ATSPI_STATE_TRANSIENT, ATSPI_STATE_TRANSIENT, "transient" },
488 { ELM_ATSPI_STATE_VERTICAL, ATSPI_STATE_VERTICAL, "vertical" },
489 { ELM_ATSPI_STATE_VISIBLE, ATSPI_STATE_VISIBLE, "visible" },
490 { ELM_ATSPI_STATE_MANAGES_DESCENDANTS, ATSPI_STATE_MANAGES_DESCENDANTS, "manages-descendants" },
491 { ELM_ATSPI_STATE_INDETERMINATE, ATSPI_STATE_INDETERMINATE, "indeterminate" },
492 { ELM_ATSPI_STATE_REQUIRED, ATSPI_STATE_REQUIRED, "required" },
493 { ELM_ATSPI_STATE_TRUNCATED, ATSPI_STATE_TRUNCATED, "truncated" },
494 { ELM_ATSPI_STATE_ANIMATED, ATSPI_STATE_ANIMATED, "animated" },
495 { ELM_ATSPI_STATE_INVALID_ENTRY, ATSPI_STATE_INVALID_ENTRY, "invalid-entry" },
496 { ELM_ATSPI_STATE_SUPPORTS_AUTOCOMPLETION, ATSPI_STATE_SUPPORTS_AUTOCOMPLETION, "supports-autocompletion" },
497 { ELM_ATSPI_STATE_SELECTABLE_TEXT, ATSPI_STATE_SELECTABLE_TEXT, "selectable-text" },
498 { ELM_ATSPI_STATE_IS_DEFAULT, ATSPI_STATE_IS_DEFAULT, "is-default" },
499 { ELM_ATSPI_STATE_VISITED, ATSPI_STATE_VISITED, "visited" },
500 //TIZEN_ONLY(20160329): atspi: implement HighlightGrab and HighlightClear methods (29e253e2f7ef3c632ac3a64c489bf569df407f30)
501 { ELM_ATSPI_STATE_CHECKABLE, ATSPI_STATE_CHECKABLE, "checkable" },
502 { ELM_ATSPI_STATE_HAS_POPUP, ATSPI_STATE_HAS_POPUP, "has-popup" },
503 { ELM_ATSPI_STATE_READ_ONLY, ATSPI_STATE_READ_ONLY, "read-only" },
504 { ELM_ATSPI_STATE_HIGHLIGHTED, ATSPI_STATE_HIGHLIGHTED, "highlighted" },
505 { ELM_ATSPI_STATE_HIGHLIGHTABLE, ATSPI_STATE_HIGHLIGHTABLE, "highlightable" },
507 { ELM_ATSPI_STATE_LAST_DEFINED, ATSPI_STATE_LAST_DEFINED, "last-defined" }
510 const int elm_relation_to_atspi_relation_mapping[] = {
511 [ELM_ATSPI_RELATION_NULL] = ATSPI_RELATION_NULL,
512 [ELM_ATSPI_RELATION_LABEL_FOR] = ATSPI_RELATION_LABEL_FOR,
513 [ELM_ATSPI_RELATION_LABELLED_BY] = ATSPI_RELATION_LABELLED_BY,
514 [ELM_ATSPI_RELATION_CONTROLLER_FOR] = ATSPI_RELATION_CONTROLLER_FOR,
515 [ELM_ATSPI_RELATION_CONTROLLED_BY] = ATSPI_RELATION_CONTROLLED_BY,
516 [ELM_ATSPI_RELATION_MEMBER_OF] = ATSPI_RELATION_MEMBER_OF,
517 [ELM_ATSPI_RELATION_TOOLTIP_FOR] = ATSPI_RELATION_TOOLTIP_FOR,
518 [ELM_ATSPI_RELATION_NODE_CHILD_OF] = ATSPI_RELATION_NODE_CHILD_OF,
519 [ELM_ATSPI_RELATION_NODE_PARENT_OF] = ATSPI_RELATION_NODE_PARENT_OF,
520 [ELM_ATSPI_RELATION_EXTENDED] = ATSPI_RELATION_EXTENDED,
521 [ELM_ATSPI_RELATION_FLOWS_TO] = ATSPI_RELATION_FLOWS_TO,
522 [ELM_ATSPI_RELATION_FLOWS_FROM] = ATSPI_RELATION_FLOWS_FROM,
523 [ELM_ATSPI_RELATION_SUBWINDOW_OF] = ATSPI_RELATION_SUBWINDOW_OF,
524 [ELM_ATSPI_RELATION_EMBEDS] = ATSPI_RELATION_EMBEDS,
525 [ELM_ATSPI_RELATION_EMBEDDED_BY] = ATSPI_RELATION_EMBEDDED_BY,
526 [ELM_ATSPI_RELATION_POPUP_FOR] = ATSPI_RELATION_POPUP_FOR,
527 [ELM_ATSPI_RELATION_PARENT_WINDOW_OF] = ATSPI_RELATION_PARENT_WINDOW_OF,
528 [ELM_ATSPI_RELATION_DESCRIPTION_FOR] = ATSPI_RELATION_DESCRIPTION_FOR,
529 [ELM_ATSPI_RELATION_DESCRIBED_BY] = ATSPI_RELATION_DESCRIBED_BY,
530 [ELM_ATSPI_RELATION_LAST_DEFINED] = ATSPI_RELATION_LAST_DEFINED,
533 static inline Eldbus_Message *_dbus_invalid_ref_error_new(const Eldbus_Message *msg)
535 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.UnknownObject", "Path is not valid accessible object reference.");
538 static AtspiRelationType _elm_relation_to_atspi_relation(Elm_Atspi_Relation_Type type)
540 if ((type < ELM_ATSPI_RELATION_LAST_DEFINED) && (type > ELM_ATSPI_RELATION_NULL))
541 return elm_relation_to_atspi_relation_mapping[type];
542 return ATSPI_RELATION_NULL;
545 static Elm_Atspi_Relation_Type _atspi_relation_to_elm_relation(AtspiRelationType type)
548 for(i = 0; i < sizeof(elm_relation_to_atspi_relation_mapping) / sizeof(elm_relation_to_atspi_relation_mapping[0]); ++i)
550 if (elm_relation_to_atspi_relation_mapping[i] == (int)type) return (Elm_Atspi_Relation_Type)i;
552 return ELM_ATSPI_RELATION_NULL;
555 static AtspiRole _elm_role_to_atspi_role(Elm_Atspi_Role role)
557 return role > ELM_ATSPI_ROLE_LAST_DEFINED ? ATSPI_ROLE_LAST_DEFINED : elm_roles_to_atspi_roles[role][1];
560 static Eldbus_Message *
561 _accessible_get_role(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
563 const char *obj_path = eldbus_message_path_get(msg);
564 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
565 Eo *obj = _bridge_object_from_path(bridge, obj_path);
568 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
570 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
572 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
573 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
575 AtspiRole atspi_role = _elm_role_to_atspi_role(role);
576 eldbus_message_arguments_append(ret, "u", atspi_role);
580 static Eldbus_Message *
581 _accessible_get_role_name(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
583 const char *role_name = NULL, *obj_path = eldbus_message_path_get(msg);
584 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
585 Eo *obj = _bridge_object_from_path(bridge, obj_path);
587 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
589 eo_do(obj, role_name = elm_interface_atspi_accessible_role_name_get());
591 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
592 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
593 eldbus_message_arguments_append(ret, "s", role_name);
598 static Eldbus_Message *
599 _accessible_get_localized_role_name(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
601 const char *l_role_name = NULL, *obj_path = eldbus_message_path_get(msg);
602 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
603 Eo *obj = _bridge_object_from_path(bridge, obj_path);
605 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
607 eo_do(obj, l_role_name = elm_interface_atspi_accessible_localized_role_name_get());
608 EINA_SAFETY_ON_NULL_RETURN_VAL(l_role_name, NULL);
610 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
611 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
612 eldbus_message_arguments_append(ret, "s", l_role_name);
617 static Eldbus_Message *
618 _accessible_get_children(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
620 const char *obj_path = eldbus_message_path_get(msg);
621 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
622 Eo *obj = _bridge_object_from_path(bridge, obj_path);
623 Eina_List *children_list = NULL, *l;
625 Eldbus_Message_Iter *iter, *iter_array;
628 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
630 eo_do(obj, children_list = elm_interface_atspi_accessible_children_get());
632 ret = eldbus_message_method_return_new(msg);
633 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
635 iter = eldbus_message_iter_get(ret);
636 iter_array = eldbus_message_iter_container_new(iter, 'a', "(so)");
637 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
639 EINA_LIST_FOREACH(children_list, l, children)
641 _bridge_iter_object_reference_append(bridge, iter_array, children);
642 _bridge_object_register(bridge, children);
645 eldbus_message_iter_container_close(iter, iter_array);
646 eina_list_free(children_list);
651 if (ret) eldbus_message_unref(ret);
655 static Eldbus_Message *
656 _accessible_get_application(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
659 const char *obj_path = eldbus_message_path_get(msg);
660 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
661 Eo *obj = _bridge_object_from_path(bridge, obj_path);
663 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
665 ret = eldbus_message_method_return_new(msg);
666 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
668 Eldbus_Message_Iter *iter = eldbus_message_iter_get(ret);
669 _bridge_iter_object_reference_append(bridge, iter, elm_atspi_bridge_root_get(bridge));
674 static Eldbus_Message *
675 _accessible_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
677 Eina_List *attrs, *l;
678 Elm_Atspi_Attribute *attr;
679 Eldbus_Message_Iter *iter, *iter_dict, *iter_entry;
682 const char *obj_path = eldbus_message_path_get(msg);
683 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
684 Eo *obj = _bridge_object_from_path(bridge, obj_path);
686 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
688 ret = eldbus_message_method_return_new(msg);
689 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
691 eo_do(obj, attrs = elm_interface_atspi_accessible_attributes_get());
693 iter = eldbus_message_iter_get(ret);
694 iter_dict = eldbus_message_iter_container_new(iter, 'a', "{ss}");
695 EINA_SAFETY_ON_NULL_RETURN_VAL(iter_dict, NULL);
697 EINA_LIST_FOREACH(attrs, l, attr)
699 iter_entry = eldbus_message_iter_container_new(iter_dict, 'e', NULL);
700 EINA_SAFETY_ON_NULL_RETURN_VAL(iter_entry, NULL);
701 eldbus_message_iter_arguments_append(iter_entry, "ss", attr->key, attr->value);
702 eldbus_message_iter_container_close(iter_dict, iter_entry);
705 eldbus_message_iter_container_close(iter, iter_dict);
706 elm_atspi_attributes_list_free(attrs);
711 static Eldbus_Message *
712 _accessible_interfaces_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
715 Eldbus_Message_Iter *iter;
716 const char *obj_path = eldbus_message_path_get(msg);
717 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
718 Eo *obj = _bridge_object_from_path(bridge, obj_path);
720 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
722 ret = eldbus_message_method_return_new(msg);
723 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
725 iter = eldbus_message_iter_get(ret);
726 _iter_interfaces_append(iter, obj);
732 _elm_atspi_state_set_to_atspi_state_set(Elm_Atspi_State_Set states)
737 for (i = 0; i < SIZE(elm_states_to_atspi_state); i++)
739 if (STATE_TYPE_GET(states, elm_states_to_atspi_state[i].elm_state))
740 STATE_TYPE_SET(ret, elm_states_to_atspi_state[i].atspi_state);
745 static Elm_Atspi_State_Set
746 _atspi_state_set_to_elm_atspi_state_set(uint64_t states)
748 //Currently Elm_Atspi_State and Atspi_State_Set are binary compatible,
749 //implement proper coversion when it will be needed.
750 Elm_Atspi_State_Set ret = states;
755 _elm_atspi_state_hash_build(void)
757 Eina_Hash *ret = eina_hash_string_superfast_new(NULL);
760 for (i = 0; i < SIZE(elm_states_to_atspi_state); i++)
761 eina_hash_add(ret, elm_states_to_atspi_state[i].name, &elm_states_to_atspi_state[i]);
767 _elm_atspi_event_hash_build(void)
769 Eina_Hash *ret = eina_hash_pointer_new(NULL);
772 for (i = 0; i < SIZE(event_handlers); i++)
773 eina_hash_add(ret, &(event_handlers[i].desc), event_handlers[i].callback);
778 static Eldbus_Message *
779 _accessible_get_state(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
782 Eldbus_Message_Iter *iter, *iter_array;
783 Elm_Atspi_State_Set states;
784 uint64_t atspi_states = 0;
786 const char *obj_path = eldbus_message_path_get(msg);
787 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
788 Eo *obj = _bridge_object_from_path(bridge, obj_path);
790 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
792 ret = eldbus_message_method_return_new(msg);
793 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
795 iter = eldbus_message_iter_get(ret);
796 iter_array = eldbus_message_iter_container_new(iter, 'a', "u");
797 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
799 eo_do(obj, states = elm_interface_atspi_accessible_state_set_get());
801 atspi_states = _elm_atspi_state_set_to_atspi_state_set(states);
803 unsigned int s1 = atspi_states & 0xFFFFFFFF;
804 unsigned int s2 = (atspi_states >> 32) & 0xFFFFFFFF;
806 eldbus_message_iter_basic_append(iter_array, 'u', s1);
807 eldbus_message_iter_basic_append(iter_array, 'u', s2);
808 eldbus_message_iter_container_close(iter, iter_array);
813 if (ret) eldbus_message_unref(ret);
817 static Eldbus_Message *
818 _accessible_get_index_in_parent(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
820 const char *obj_path = eldbus_message_path_get(msg);
821 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
822 Eo *obj = _bridge_object_from_path(bridge, obj_path);
826 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
828 ret = eldbus_message_method_return_new(msg);
829 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
831 eo_do(obj, idx = elm_interface_atspi_accessible_index_in_parent_get());
833 eldbus_message_arguments_append(ret, "i", idx);
838 static Eldbus_Message *
839 _accessible_child_at_index(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
841 const char *obj_path = eldbus_message_path_get(msg);
842 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
843 Eo *obj = _bridge_object_from_path(bridge, obj_path);
845 Eina_List *children = NULL;
848 Eldbus_Message_Iter *iter;
850 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
852 if (!eldbus_message_arguments_get(msg, "i", &idx))
853 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
855 ret = eldbus_message_method_return_new(msg);
856 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
858 iter = eldbus_message_iter_get(ret);
859 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
861 child = eina_list_nth(children, idx);
862 _bridge_iter_object_reference_append(bridge, iter, child);
863 _bridge_object_register(bridge, child);
864 eina_list_free(children);
869 static Eldbus_Message *
870 _accessible_get_relation_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
872 const char *obj_path = eldbus_message_path_get(msg);
873 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
874 Eo *rel_obj, *obj = _bridge_object_from_path(bridge, obj_path);
875 Eldbus_Message *ret = NULL;
876 Eldbus_Message_Iter *iter = NULL, *iter_array = NULL, *iter_array2 = NULL, *iter_struct;
877 Elm_Atspi_Relation *rel;
879 Elm_Atspi_Relation_Set rels;
881 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
883 ret = eldbus_message_method_return_new(msg);
884 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
886 iter = eldbus_message_iter_get(ret);
887 iter_array = eldbus_message_iter_container_new(iter, 'a', "(ua(so))");
888 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
890 eo_do(obj, rels = elm_interface_atspi_accessible_relation_set_get());
892 EINA_LIST_FOREACH(rels, l, rel)
894 iter_struct = eldbus_message_iter_container_new(iter_array, 'r', NULL);
895 eldbus_message_iter_basic_append(iter_struct, 'u', _elm_relation_to_atspi_relation(rel->type));
896 iter_array2 = eldbus_message_iter_container_new(iter_struct, 'a', "(so)");
897 EINA_SAFETY_ON_NULL_GOTO(iter_array2, fail);
898 EINA_LIST_FOREACH(rel->objects, l2, rel_obj)
900 _bridge_iter_object_reference_append(bridge, iter_array2, rel_obj);
901 _bridge_object_register(bridge, rel_obj);
903 eldbus_message_iter_container_close(iter_struct, iter_array2);
904 eldbus_message_iter_container_close(iter_array, iter_struct);
906 elm_atspi_relation_set_free(&rels);
907 eldbus_message_iter_container_close(iter, iter_array);
912 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to get relation set.");
915 //TIZEN_ONLY(20170405) Add gesture method to accessible interface
916 static Eldbus_Message *
917 _accessible_gesture_do(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
919 const char *obj_path = eldbus_message_path_get(msg);
920 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
921 Eo *obj = _bridge_object_from_path(bridge, obj_path);
922 int type, x_beg, y_beg, x_end, y_end, state;
923 unsigned int event_time;
925 Eina_Bool result = EINA_FALSE;
927 if (!eldbus_message_arguments_get(msg, "iiiiiiu", &type, &x_beg, &y_beg,
928 &x_end, &y_end, &state, &event_time))
929 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
931 ret = eldbus_message_method_return_new(msg);
932 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
934 Elm_Atspi_Gesture_Info gesture_info;
935 gesture_info.type = (Elm_Atspi_Gesture_Type)type;
936 gesture_info.x_beg = x_beg;
937 gesture_info.y_beg = y_beg;
938 gesture_info.x_end = x_end;
939 gesture_info.y_end = y_end;
940 gesture_info.state = (Elm_Atspi_Gesture_State)state;
941 gesture_info.event_time = event_time;
942 eo_do(obj, result = elm_interface_atspi_accessible_gesture_do(gesture_info));
943 eldbus_message_arguments_append(ret, "b", result);
948 // TIZEN_ONLY(20170310) - implementation of get object under coordinates for accessibility
949 static Eldbus_Message *
950 _accessible_get_neighbor(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
952 const char *start_path = eldbus_message_path_get(msg);
953 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
954 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
955 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, NULL);
957 Eo *start = _bridge_object_from_path(bridge, start_path);
959 Eldbus_Message_Iter *iter;
960 int direction, search_mode;
962 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(start, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
964 char *root_path = "";
965 if (!eldbus_message_arguments_get(msg, "sii", &root_path, &direction, &search_mode))
966 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
968 Eo *root = _bridge_object_from_path(bridge, root_path);
970 // TIZEN_ONLY(20161213) - do not response if ecore evas is obscured
973 const Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(root));
974 if (ecore_evas_obscured_get(ee))
975 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "ecore evas is obscured.");
979 ret = eldbus_message_method_return_new(msg);
980 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
982 iter = eldbus_message_iter_get(ret);
984 Eo *accessible = _calculate_neighbor(bridge, root, start, direction == 1, search_mode);
985 _bridge_iter_object_reference_append(bridge, iter, accessible);
986 _bridge_object_register(bridge, accessible);
988 const char *obj_bus_name = NULL, *ret_bus_name = NULL;
989 _object_get_bus_name_and_path(bridge, start, &obj_bus_name, NULL);
990 if (accessible) _object_get_bus_name_and_path(bridge, accessible, &ret_bus_name, NULL);
992 unsigned char recurse = obj_bus_name && ret_bus_name && strcmp(obj_bus_name, ret_bus_name) != 0;
993 eldbus_message_iter_basic_append(iter, 'y', recurse);
997 static Eldbus_Message *
998 _accessible_get_navigable_at_point(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
1000 const char *obj_path = eldbus_message_path_get(msg);
1001 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1002 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
1003 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, NULL);
1005 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1007 Eldbus_Message *ret;
1008 AtspiCoordType coord_type;
1009 Eldbus_Message_Iter *iter;
1011 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
1013 // TIZEN_ONLY(20161213) - do not response if ecore evas is obscured
1014 const Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
1015 if (ecore_evas_obscured_get(ee))
1016 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "ecore evas is obscured.");
1019 if (!eldbus_message_arguments_get(msg, "iiu", &x, &y, &coord_type))
1020 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1022 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
1023 Evas_Object *top = elm_object_top_widget_get(obj);
1026 eo_do(top, elm_interface_atspi_component_socket_offset_get(&sx, &sy));
1031 ret = eldbus_message_method_return_new(msg);
1032 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1034 iter = eldbus_message_iter_get(ret);
1036 Eina_Bool type = coord_type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
1037 Eo *accessible = _calculate_navigable_accessible_at_point(bridge, obj, type, x, y);
1041 if (accessible && eo_isa(accessible, ELM_ACCESS_CLASS))
1043 Evas_Object *parent = elm_widget_parent_get(accessible);
1045 Elm_Widget_Smart_Data *wd;
1046 wd = eo_data_scope_get(parent, ELM_WIDGET_CLASS);
1050 Evas_Object *widget;
1052 EINA_LIST_FOREACH(wd->subobjs, l, widget)
1056 proxy = evas_object_data_get(widget, "__widget_proxy");
1060 evas_object_geometry_get(widget, &px, &py, &pw, &ph);
1061 if (x >= px && x <= px + pw && y >= py && y <= py +ph)
1063 /* proxy is also selectable */
1064 deputy = accessible;
1073 _bridge_iter_object_reference_append(bridge, iter, accessible);
1074 _bridge_object_register(bridge, accessible);
1076 const char *obj_bus_name = NULL, *ret_bus_name = NULL;
1077 _object_get_bus_name_and_path(bridge, obj, &obj_bus_name, NULL);
1078 if (accessible) _object_get_bus_name_and_path(bridge, accessible, &ret_bus_name, NULL);
1079 unsigned char recurse = obj_bus_name && ret_bus_name && strcmp(obj_bus_name, ret_bus_name) != 0;
1080 eldbus_message_iter_basic_append(iter, 'y', recurse);
1083 _bridge_iter_object_reference_append(bridge, iter, deputy);
1084 if (deputy) _bridge_object_register(bridge, deputy);
1090 //TIZEN_ONLY(20170531): add "GetReadingMaterial" interface method
1092 _list_children_count_check(Eo *obj)
1096 Eina_List *children;
1098 Elm_Atspi_Role role;
1103 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
1104 if (role == ELM_ATSPI_ROLE_LIST)
1106 int children_count = 0;
1107 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
1108 children_count = eina_list_count(children);
1110 for (i = 0; i < children_count; i++)
1112 child = eina_list_nth(children, i);
1113 eo_do(child, role = elm_interface_atspi_accessible_role_get());
1114 if (role == ELM_ATSPI_ROLE_LIST_ITEM)
1117 eina_list_free(children);
1124 _list_children_count(Eo *obj)
1126 Eina_List *children;
1127 int list_items_count = 0;
1128 int children_count = 0;
1130 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
1131 children_count = eina_list_count(children);
1136 list_items_count = _list_children_count_check(obj);
1137 if (list_items_count > 0)
1139 eina_list_free(children);
1140 return list_items_count;
1143 for (i = 0; i < children_count; i++)
1145 child = eina_list_nth(children, i);
1146 list_items_count = _list_children_count(child);
1147 if (list_items_count > 0)
1149 eina_list_free(children);
1150 return list_items_count;
1157 static Eldbus_Message *
1158 _accessible_reading_material_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1160 Eldbus_Message *ret;
1161 Eldbus_Message_Iter *iter, *iter_array, *iter_dict, *iter_entry;
1162 Eina_List *attrs, *l, *children;
1163 const char *name = NULL;
1164 unsigned int s1, s2;
1166 double increment = 0;
1167 double max_value = 0;
1168 double min_value = 0;
1170 int child_count = 0;
1171 int selected_child_count = 0;
1172 uint64_t atspi_states = 0;
1173 Elm_Atspi_Role role;
1174 Elm_Atspi_Attribute *attr;
1175 Elm_Atspi_State_Set states;
1176 Elm_Atspi_Relation_Set rels = NULL;
1177 Elm_Atspi_Relation *rel;
1178 Eo *relation_obj = NULL;
1181 Eina_Bool is_selected = EINA_FALSE;
1182 AtspiRole atspi_role = ATSPI_ROLE_INVALID;
1184 const char *obj_path = eldbus_message_path_get(msg);
1185 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1186 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1188 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
1190 ret = eldbus_message_method_return_new(msg);
1191 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1193 iter = eldbus_message_iter_get(ret);
1195 eo_do(obj, attrs = elm_interface_atspi_accessible_attributes_get());
1196 iter_dict = eldbus_message_iter_container_new(iter, 'a', "{ss}");
1197 EINA_SAFETY_ON_NULL_RETURN_VAL(iter_dict, NULL);
1198 EINA_LIST_FOREACH(attrs, l, attr)
1200 iter_entry = eldbus_message_iter_container_new(iter_dict, 'e', NULL);
1201 EINA_SAFETY_ON_NULL_RETURN_VAL(iter_entry, NULL);
1202 eldbus_message_iter_arguments_append(iter_entry, "ss", attr->key, attr->value);
1203 eldbus_message_iter_container_close(iter_dict, iter_entry);
1206 eldbus_message_iter_container_close(iter, iter_dict);
1207 elm_atspi_attributes_list_free(attrs);
1210 eo_do(obj, name = elm_interface_atspi_accessible_name_get());
1213 eldbus_message_iter_basic_append(iter, 's', name);
1215 /* name - LABELED_BY relation */
1216 eo_do(obj, rels = elm_interface_atspi_accessible_relation_set_get());
1217 EINA_LIST_FOREACH(rels, l, rel)
1219 if (rel->type == ELM_ATSPI_RELATION_LABELLED_BY)
1221 int last_index = eina_list_count(rel->objects) - 1;
1222 relation_obj = eina_list_nth(rel->objects, last_index);
1226 eo_do(relation_obj, name = elm_interface_atspi_accessible_name_get());
1229 eldbus_message_iter_basic_append(iter, 's', name);
1231 /* name - text interface */
1233 if (eo_isa(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE))
1236 eo_do(obj, val = elm_interface_atspi_text_character_count_get());
1237 eo_do(obj, name = elm_interface_atspi_text_get(0, val));
1241 eldbus_message_iter_basic_append(iter, 's', name);
1244 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
1245 atspi_role = role > ELM_ATSPI_ROLE_LAST_DEFINED ? ATSPI_ROLE_LAST_DEFINED : elm_roles_to_atspi_roles[role][1];
1246 eldbus_message_iter_basic_append(iter, 'u', atspi_role);
1249 iter_array = eldbus_message_iter_container_new(iter, 'a', "u");
1250 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
1251 eo_do(obj, states = elm_interface_atspi_accessible_state_set_get());
1252 atspi_states = _elm_atspi_state_set_to_atspi_state_set(states);
1253 s1 = atspi_states & 0xFFFFFFFF;
1254 s2 = (atspi_states >> 32) & 0xFFFFFFFF;
1255 eldbus_message_iter_basic_append(iter_array, 'u', s1);
1256 eldbus_message_iter_basic_append(iter_array, 'u', s2);
1257 eldbus_message_iter_container_close(iter, iter_array);
1259 /* localized role name */
1260 eo_do(obj, name = elm_interface_atspi_accessible_localized_role_name_get());
1263 eldbus_message_iter_basic_append(iter, 's', name);
1266 eo_do(obj, l = elm_interface_atspi_accessible_children_get());
1267 eldbus_message_iter_basic_append(iter, 'i', eina_list_count(l));
1270 /* current value, increment, max, min */
1275 if (eo_isa(obj, ELM_INTERFACE_ATSPI_VALUE_INTERFACE))
1277 eo_do(obj, elm_interface_atspi_value_and_text_get(&value, NULL));
1278 eo_do(obj, increment = elm_interface_atspi_value_increment_get());
1279 eo_do(obj, elm_interface_atspi_value_range_get(&min_value, &max_value, NULL));
1281 eldbus_message_iter_basic_append(iter, 'd', value);
1282 eldbus_message_iter_basic_append(iter, 'd', increment);
1283 eldbus_message_iter_basic_append(iter, 'd', max_value);
1284 eldbus_message_iter_basic_append(iter, 'd', min_value);
1287 eo_do(obj, name = elm_interface_atspi_accessible_description_get());
1290 eldbus_message_iter_basic_append(iter, 's', name);
1292 /* index in parent */
1293 eo_do(obj, idx = elm_interface_atspi_accessible_index_in_parent_get());
1294 eldbus_message_iter_basic_append(iter, 'i', idx);
1296 /* is selected in parent */
1297 eo_do(obj, parent = elm_interface_atspi_accessible_parent_get());
1298 if (eo_isa(parent, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE))
1300 eo_do(parent, is_selected = elm_interface_atspi_selection_is_child_selected(idx));
1302 eldbus_message_arguments_append(ret, "b", is_selected);
1304 /* has checkbox child */
1305 is_selected = EINA_FALSE;
1306 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
1307 EINA_LIST_FOREACH(children, l, child)
1309 if (eo_isa(child, ELM_CHECK_CLASS))
1311 is_selected = EINA_TRUE;
1315 eldbus_message_iter_basic_append(iter, 'b', is_selected);
1316 eina_list_free(children);
1318 /* list children count */
1320 if (role == ELM_ATSPI_ROLE_DIALOG)
1322 child_count = _list_children_count(obj);
1324 eldbus_message_iter_basic_append(iter, 'i', child_count);
1326 /* first selected child index */
1328 if (eo_isa(obj, ELM_INDEX_CLASS))
1330 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
1331 EINA_LIST_FOREACH(children, l, child)
1333 eo_do(child, states = elm_interface_atspi_accessible_state_set_get());
1334 if (STATE_TYPE_GET(states, ELM_ATSPI_STATE_SELECTED))
1338 eina_list_free(children);
1340 eldbus_message_iter_basic_append(iter, 'i', idx);
1343 role = ELM_ATSPI_ROLE_INVALID;
1344 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
1345 if ((!parent) && (ELM_ATSPI_ROLE_APPLICATION == role))
1346 _object_desktop_reference_append(iter);
1348 _bridge_iter_object_reference_append(bridge, iter, parent);
1350 /* parent - states */
1351 iter_array = eldbus_message_iter_container_new(iter, 'a', "u");
1352 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
1353 eo_do(parent, states = elm_interface_atspi_accessible_state_set_get());
1354 atspi_states = _elm_atspi_state_set_to_atspi_state_set(states);
1355 s1 = atspi_states & 0xFFFFFFFF;
1356 s2 = (atspi_states >> 32) & 0xFFFFFFFF;
1357 eldbus_message_iter_basic_append(iter_array, 'u', s1);
1358 eldbus_message_iter_basic_append(iter_array, 'u', s2);
1359 eldbus_message_iter_container_close(iter, iter_array);
1361 /* parent - child count */
1362 eo_do(parent, l = elm_interface_atspi_accessible_children_get());
1363 eldbus_message_iter_basic_append(iter, 'i', eina_list_count(l));
1367 eo_do(parent, role = elm_interface_atspi_accessible_role_get());
1368 atspi_role = role > ELM_ATSPI_ROLE_LAST_DEFINED ? ATSPI_ROLE_LAST_DEFINED : elm_roles_to_atspi_roles[role][1];
1369 eldbus_message_iter_basic_append(iter, 'u', atspi_role);
1371 /* parent - child count */
1372 if (eo_isa(parent, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE))
1374 eo_do(parent, selected_child_count = elm_interface_atspi_selection_selected_children_count_get());
1376 eldbus_message_iter_basic_append(iter, 'i', selected_child_count);
1378 /* relation object - DESCRIBED_BY */
1379 relation_obj = NULL;
1380 EINA_LIST_FOREACH(rels, l, rel)
1382 if (rel->type == ELM_ATSPI_RELATION_DESCRIBED_BY)
1384 int last_index = eina_list_count(rel->objects) - 1;
1385 relation_obj = eina_list_nth(rel->objects, last_index);
1389 _bridge_iter_object_reference_append(bridge, iter, relation_obj);
1390 elm_atspi_relation_set_free(&rels);
1395 if (rels) elm_atspi_relation_set_free(&rels);
1396 if (ret) eldbus_message_unref(ret);
1400 //TIZEN_ONLY(20170919): Handle default label object
1401 static Eldbus_Message *
1402 _accessible_default_label_info_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1404 Eldbus_Message *ret;
1405 Eldbus_Message_Iter *iter;
1406 const char *obj_path = eldbus_message_path_get(msg);
1407 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1408 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1409 Eo *default_label_obj;
1410 Elm_Atspi_Role role;
1411 AtspiRole atspi_role = ATSPI_ROLE_INVALID;
1413 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
1415 ret = eldbus_message_method_return_new(msg);
1416 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1418 iter = eldbus_message_iter_get(ret);
1420 default_label_obj = _elm_win_default_label_obj_get(obj);
1421 if (!default_label_obj) default_label_obj = obj;
1422 _bridge_iter_object_reference_append(bridge, iter, default_label_obj);
1423 _bridge_object_register(bridge, default_label_obj);
1425 eo_do(default_label_obj, role = elm_interface_atspi_accessible_role_get());
1426 atspi_role = role > ELM_ATSPI_ROLE_LAST_DEFINED ? ATSPI_ROLE_LAST_DEFINED : elm_roles_to_atspi_roles[role][1];
1427 eldbus_message_iter_basic_append(iter, 'u', atspi_role);
1433 static const Eldbus_Method accessible_methods[] = {
1434 // TIZEN_ONLY(20170310) - implementation of get object under coordinates for accessibility
1435 { "GetNavigableAtPoint", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"u", "coord_type"}), ELDBUS_ARGS({"(so)y", "accessible"}, {"(so)", "deputy"}), _accessible_get_navigable_at_point, 0 },
1436 { "GetNeighbor", ELDBUS_ARGS({"s", "current"}, {"i", "direction"}, {"i", "force_next"}), ELDBUS_ARGS({"(so)y", "accessible"}), _accessible_get_neighbor, 0 },
1438 { "GetChildAtIndex", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"(so)", "Accessible"}), _accessible_child_at_index, 0 },
1439 { "GetChildren", NULL, ELDBUS_ARGS({"a(so)", "children"}), _accessible_get_children, 0 },
1440 { "GetIndexInParent", NULL, ELDBUS_ARGS({"i", "index"}), _accessible_get_index_in_parent, 0 },
1441 { "GetRelationSet", NULL, ELDBUS_ARGS({"a(ua(so))", NULL}), _accessible_get_relation_set, 0 },
1442 { "GetRole", NULL, ELDBUS_ARGS({"u", "Role"}), _accessible_get_role, 0 },
1443 { "GetRoleName", NULL, ELDBUS_ARGS({"s", "Name"}), _accessible_get_role_name, 0 },
1444 { "GetLocalizedRoleName", NULL, ELDBUS_ARGS({"s", "LocalizedName"}), _accessible_get_localized_role_name, 0},
1445 { "GetState", NULL, ELDBUS_ARGS({"au", NULL}), _accessible_get_state, 0},
1446 { "GetApplication", NULL, ELDBUS_ARGS({"(so)", NULL}), _accessible_get_application, 0},
1447 { "GetAttributes", NULL, ELDBUS_ARGS({"a{ss}", NULL}), _accessible_attributes_get, 0},
1448 { "GetInterfaces", NULL, ELDBUS_ARGS({"as", NULL}), _accessible_interfaces_get, 0},
1449 //TIZEN_ONLY(20170405) Add gesture method to accessible interface
1451 ELDBUS_ARGS({"i", "type"}, {"i", "x_beg"}, {"i", "y_beg"},
1452 {"i", "x_end"}, {"i", "y_end"}, {"i", "state"},
1453 {"u", "event_time"}),
1454 ELDBUS_ARGS({"b", "result"}), _accessible_gesture_do, 0},
1456 //TIZEN_ONLY(20170531): add "GetReadingMaterial" interface method
1457 { "GetReadingMaterial",
1459 ELDBUS_ARGS({"a{ss}", "attributes"}, {"s", "name"},
1460 {"s", "labledByName"},{"s", "textIfceName"},
1461 {"u", "role"}, {"au", "stateSet"},
1462 {"s", "localizedName"}, {"i", "childCount"},
1463 {"d", "currentValue"},{"d", "minimumIncrement"},
1464 {"d", "maximumValue"},{"d", "minimumValue"},
1465 {"s", "description"}, {"i", "indexInParent"},
1466 {"b", "isSelectedInParent"}, {"b", "hasCheckboxChild"},
1467 {"i", "listChildrenCount"},
1468 {"i", "firstSelectedChildIndex"},
1469 {"(so)", "parent"}, {"au", "parentStateSet"},
1470 {"i", "parentChildCount"}, {"u", "parentRole"},
1471 {"i", "selectedChildCount"},
1472 {"(so)", "describecByObject"}),
1473 _accessible_reading_material_get, 0},
1475 //TIZEN_ONLY(20170919): Handle default label object
1476 { "GetDefaultLabelInfo",
1477 NULL, ELDBUS_ARGS({"(so)", "defaultLabelObject"}, {"u", "defaultLabelRole"}),
1478 _accessible_default_label_info_get, 0},
1480 { NULL, NULL, NULL, NULL, 0 }
1484 _is_operation_permitted(Eo *obj)
1486 Elm_Atspi_State_Set states;
1487 eo_do(obj, states = elm_interface_atspi_accessible_state_set_get());
1489 if (!STATE_TYPE_GET(states, ELM_ATSPI_STATE_SHOWING)) return EINA_FALSE;
1494 if (evas_object_freeze_events_get(parent)) return EINA_FALSE;
1495 parent = evas_object_smart_parent_get(parent);
1500 static Eldbus_Message *
1501 _selection_selected_child_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
1503 const char *obj_path = eldbus_message_path_get(msg);
1504 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1505 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1509 Eldbus_Message *ret;
1510 Eldbus_Message_Iter *iter;
1512 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE, msg);
1514 if (!eldbus_message_arguments_get(msg, "i", &idx))
1515 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1517 ret = eldbus_message_method_return_new(msg);
1518 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1520 iter = eldbus_message_iter_get(ret);
1521 eo_do(obj, child = elm_interface_atspi_selection_selected_child_get(idx));
1523 _bridge_iter_object_reference_append(bridge, iter, child);
1524 _bridge_object_register(bridge, child);
1529 static Eldbus_Message *
1530 _selection_child_select(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1532 const char *obj_path = eldbus_message_path_get(msg);
1533 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1534 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1536 Eldbus_Message *ret;
1537 Eina_Bool result = EINA_FALSE;
1539 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE, msg);
1541 if (!eldbus_message_arguments_get(msg, "i", &idx))
1542 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1544 ret = eldbus_message_method_return_new(msg);
1545 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1547 if (_is_operation_permitted(obj))
1548 eo_do(obj, result = elm_interface_atspi_selection_child_select(idx));
1549 eldbus_message_arguments_append(ret, "b", result);
1554 static Eldbus_Message *
1555 _selection_selected_child_deselect(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1557 const char *obj_path = eldbus_message_path_get(msg);
1558 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1559 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1561 Eldbus_Message *ret;
1562 Eina_Bool result = EINA_FALSE;
1564 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE, msg);
1566 if (!eldbus_message_arguments_get(msg, "i", &idx))
1567 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1569 ret = eldbus_message_method_return_new(msg);
1570 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1572 if (_is_operation_permitted(obj))
1573 eo_do(obj, result = elm_interface_atspi_selection_selected_child_deselect(idx));
1574 eldbus_message_arguments_append(ret, "b", result);
1579 static Eldbus_Message *
1580 _selection_is_child_selected(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1582 const char *obj_path = eldbus_message_path_get(msg);
1583 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1584 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1586 Eldbus_Message *ret;
1589 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE, msg);
1591 if (!eldbus_message_arguments_get(msg, "i", &idx))
1592 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1594 ret = eldbus_message_method_return_new(msg);
1595 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1597 eo_do(obj, result = elm_interface_atspi_selection_is_child_selected(idx));
1598 eldbus_message_arguments_append(ret, "b", result);
1603 static Eldbus_Message *
1604 _selection_all_children_select(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1606 const char *obj_path = eldbus_message_path_get(msg);
1607 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1608 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1609 Eldbus_Message *ret;
1610 Eina_Bool result = EINA_FALSE;
1612 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE, msg);
1614 ret = eldbus_message_method_return_new(msg);
1615 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1617 if (_is_operation_permitted(obj))
1618 eo_do(obj, result = elm_interface_atspi_selection_all_children_select());
1619 eldbus_message_arguments_append(ret, "b", result);
1624 static Eldbus_Message *
1625 _selection_clear(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1627 const char *obj_path = eldbus_message_path_get(msg);
1628 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1629 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1630 Eldbus_Message *ret;
1631 Eina_Bool result = EINA_FALSE;
1633 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE, msg);
1635 ret = eldbus_message_method_return_new(msg);
1636 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1638 if (_is_operation_permitted(obj))
1639 eo_do(obj, result = elm_interface_atspi_selection_clear());
1640 eldbus_message_arguments_append(ret, "b", result);
1645 static Eldbus_Message *
1646 _selection_child_deselect(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1648 const char *obj_path = eldbus_message_path_get(msg);
1649 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1650 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1652 Eldbus_Message *ret;
1653 Eina_Bool result = EINA_FALSE;
1655 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE, msg);
1657 if (!eldbus_message_arguments_get(msg, "i", &idx))
1658 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1660 ret = eldbus_message_method_return_new(msg);
1661 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1663 if (_is_operation_permitted(obj))
1664 eo_do(obj, result = elm_interface_atspi_selection_child_deselect(idx));
1665 eldbus_message_arguments_append(ret, "b", result);
1670 static const Eldbus_Method selection_methods[] = {
1671 { "GetSelectedChild", ELDBUS_ARGS({"i", "selectedChildIndex"}), ELDBUS_ARGS({"(so)", "Accessible"}), _selection_selected_child_get, 0 },
1672 { "SelectChild", ELDBUS_ARGS({"i", "childIndex"}), ELDBUS_ARGS({"b", "result"}), _selection_child_select, 0 },
1673 { "DeselectSelectedChild", ELDBUS_ARGS({"i", "selectedChildIndex"}), ELDBUS_ARGS({"b", "result"}), _selection_selected_child_deselect, 0 },
1674 { "IsChildSelected", ELDBUS_ARGS({"i", "childIndex"}), ELDBUS_ARGS({"b", "result"}), _selection_is_child_selected, 0 },
1675 { "SelectAll", NULL, ELDBUS_ARGS({"b", "result"}), _selection_all_children_select, 0},
1676 { "ClearSelection", NULL, ELDBUS_ARGS({"b", "result"}), _selection_clear, 0},
1677 { "DeselectChild", ELDBUS_ARGS({"i", "childIndex"}), ELDBUS_ARGS({"b", "result"}), _selection_child_deselect, 0 },
1678 { NULL, NULL, NULL, NULL, 0 }
1681 static Eldbus_Message *
1682 _action_description_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1684 const char *description, *obj_path = eldbus_message_path_get(msg);
1685 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1686 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1688 Eldbus_Message *ret;
1690 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN, msg);
1692 if (!eldbus_message_arguments_get(msg, "i", &idx))
1693 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1695 ret = eldbus_message_method_return_new(msg);
1696 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1698 eo_do(obj, description = elm_interface_atspi_action_description_get(idx));
1699 description = description ? description : "";
1700 eldbus_message_arguments_append(ret, "s", description);
1705 static Eldbus_Message *
1706 _action_name_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1708 const char *name, *obj_path = eldbus_message_path_get(msg);
1709 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1710 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1712 Eldbus_Message *ret;
1714 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN, msg);
1716 if (!eldbus_message_arguments_get(msg, "i", &idx))
1717 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1719 ret = eldbus_message_method_return_new(msg);
1720 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1722 eo_do(obj, name = elm_interface_atspi_action_name_get(idx));
1723 name = name ? name : "";
1724 eldbus_message_arguments_append(ret, "s", name);
1729 static Eldbus_Message *
1730 _action_localized_name_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1732 const char *name, *obj_path = eldbus_message_path_get(msg);
1733 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1734 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1736 Eldbus_Message *ret;
1738 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN, msg);
1740 if (!eldbus_message_arguments_get(msg, "i", &idx))
1741 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1743 ret = eldbus_message_method_return_new(msg);
1744 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1746 eo_do(obj, name = elm_interface_atspi_action_localized_name_get(idx));
1747 name = name ? name : "";
1748 eldbus_message_arguments_append(ret, "s", name);
1753 static Eldbus_Message *
1754 _action_key_binding_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1756 const char *obj_path = eldbus_message_path_get(msg);
1758 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1759 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1761 Eldbus_Message *ret;
1763 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN, msg);
1765 if (!eldbus_message_arguments_get(msg, "i", &idx))
1766 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1768 ret = eldbus_message_method_return_new(msg);
1769 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1771 eo_do(obj, key = elm_interface_atspi_action_keybinding_get(idx));
1772 eldbus_message_arguments_append(ret, "s", key ? key : "");
1778 static Eldbus_Message *
1779 _action_actions_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1781 const char *action, *obj_path = eldbus_message_path_get(msg);
1782 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1783 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1785 Eldbus_Message *ret;
1786 Eldbus_Message_Iter *iter, *iter_array;
1788 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN, msg);
1790 ret = eldbus_message_method_return_new(msg);
1791 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1793 iter = eldbus_message_iter_get(ret);
1794 EINA_SAFETY_ON_NULL_RETURN_VAL(iter, NULL);
1796 iter_array = eldbus_message_iter_container_new(iter, 'a', "sss");
1797 EINA_SAFETY_ON_NULL_RETURN_VAL(iter_array, NULL);
1799 eo_do(obj, actions = elm_interface_atspi_action_actions_get());
1802 EINA_LIST_FREE(actions, action)
1806 eo_do(obj, key = elm_interface_atspi_action_keybinding_get(id));
1807 eo_do(obj, descr = elm_interface_atspi_action_description_get(id));
1808 descr = descr ? descr : "";
1809 eldbus_message_iter_arguments_append(iter_array, "sss", action, descr, key ? key : "");
1814 eldbus_message_iter_container_close(iter, iter_array);
1819 static Eldbus_Message *
1820 _action_action_do(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1822 const char *obj_path = eldbus_message_path_get(msg);
1823 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1824 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1826 Eldbus_Message *ret;
1827 Eina_Bool result = EINA_FALSE;
1829 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN, msg);
1831 if (!eldbus_message_arguments_get(msg, "i", &idx))
1832 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1834 ret = eldbus_message_method_return_new(msg);
1835 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1837 if (_is_operation_permitted(obj))
1838 eo_do(obj, result = elm_interface_atspi_action_do(idx));
1840 eldbus_message_arguments_append(ret, "b", result);
1845 static Eldbus_Message *
1846 _action_action_name_do(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1848 const char *obj_path = eldbus_message_path_get(msg);
1849 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1850 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1855 Eldbus_Message *ret;
1856 Eina_Bool result = EINA_FALSE;
1858 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN, msg);
1860 if (!eldbus_message_arguments_get(msg, "s", &action_name))
1861 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1863 ret = eldbus_message_method_return_new(msg);
1864 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1866 eo_do(obj, actions = elm_interface_atspi_action_actions_get());
1867 EINA_LIST_FREE(actions, action)
1869 if (!result && action && !strcmp(action, action_name))
1877 eo_do(obj, result = elm_interface_atspi_action_do(idx));
1879 eldbus_message_arguments_append(ret, "b", result);
1884 static const Eldbus_Method action_methods[] = {
1885 { "GetDescription", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"s", "description"}), _action_description_get, 0 },
1886 { "GetName", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"s", "name"}), _action_name_get, 0 },
1887 { "GetLocalizedName", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"s", "name"}), _action_localized_name_get, 0 },
1888 { "GetKeyBinding", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"s", "key"}), _action_key_binding_get, 0 },
1889 { "GetActions", NULL, ELDBUS_ARGS({"a(sss)", "actions"}), _action_actions_get, 0 },
1890 { "DoAction", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"b", "result"}), _action_action_do, 0 },
1891 { "DoActionName", ELDBUS_ARGS({"s", "name"}), ELDBUS_ARGS({"b", "result"}), _action_action_name_do, 0 },
1892 { NULL, NULL, NULL, NULL, 0 }
1895 static Eldbus_Message *
1896 _image_extents_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1898 AtspiCoordType type;
1899 Eldbus_Message *ret;
1900 const char *obj_path = eldbus_message_path_get(msg);
1902 Eina_Bool screen_coords;
1903 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1904 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1908 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_IMAGE_MIXIN, msg);
1910 if (!eldbus_message_arguments_get(msg, "u", &type))
1911 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1913 ret = eldbus_message_method_return_new(msg);
1914 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1916 screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
1917 eo_do(obj, elm_interface_atspi_image_extents_get(screen_coords, &x, &y, &w, &h));
1918 eldbus_message_arguments_append(ret, "iiii", x, y, w, h);
1923 static Eldbus_Message *
1924 _image_position_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1926 AtspiCoordType type;
1927 Eldbus_Message *ret;
1928 const char *obj_path = eldbus_message_path_get(msg);
1929 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1930 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1932 Eina_Bool screen_coords;
1934 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_IMAGE_MIXIN, msg);
1936 if (!eldbus_message_arguments_get(msg, "u", &type))
1937 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
1939 ret = eldbus_message_method_return_new(msg);
1940 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1942 screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
1943 eo_do(obj, elm_interface_atspi_image_extents_get(screen_coords, &x, &y, NULL, NULL));
1944 eldbus_message_arguments_append(ret, "i", x);
1945 eldbus_message_arguments_append(ret, "i", y);
1950 static Eldbus_Message *
1951 _image_size_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1953 Eldbus_Message *ret;
1954 const char *obj_path = eldbus_message_path_get(msg);
1955 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1956 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1959 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_IMAGE_MIXIN, msg);
1961 ret = eldbus_message_method_return_new(msg);
1962 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1964 eo_do(obj, elm_interface_atspi_image_extents_get(EINA_FALSE, NULL, NULL, &w, &h));
1965 eldbus_message_arguments_append(ret, "i", w);
1966 eldbus_message_arguments_append(ret, "i", h);
1971 static const Eldbus_Method image_methods[] = {
1972 { "GetImageExtents", ELDBUS_ARGS({"u", "coordType"}), ELDBUS_ARGS({"iiii", "extents"}), _image_extents_get, 0 },
1973 { "GetImagePosition", ELDBUS_ARGS({"u", "coordType"}), ELDBUS_ARGS({"i", "x"}, {"i", "y"}), _image_position_get, 0 },
1974 { "GetImageSize", NULL, ELDBUS_ARGS({"i", "width"}, {"i", "height"}), _image_size_get, 0 },
1975 { NULL, NULL, NULL, NULL, 0 }
1978 static Eldbus_Message *
1979 _text_string_at_offset_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
1981 const char *obj_path = eldbus_message_path_get(msg);
1983 Elm_Atspi_Text_Granularity gran;
1985 Eldbus_Message *ret;
1986 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1987 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1989 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
1991 if (!eldbus_message_arguments_get(msg, "iu", &start, &gran))
1992 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and granularity expected.");
1994 ret = eldbus_message_method_return_new(msg);
1995 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
1997 eo_do(obj, str = elm_interface_atspi_text_string_get(gran, &start, &end));
1998 str = str ? str : strdup("");
2000 eldbus_message_arguments_append(ret, "sii", str, start, end);
2006 static Eldbus_Message *
2007 _text_text_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2009 const char *obj_path = eldbus_message_path_get(msg);
2011 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2012 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2015 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2017 if (!eldbus_message_arguments_get(msg, "ii", &start, &end))
2018 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and granularity expected.");
2020 Eldbus_Message *ret = eldbus_message_method_return_new(msg);
2021 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2023 eo_do(obj, str = elm_interface_atspi_text_get(start, end));
2024 str = str ? str : strdup("");
2026 eldbus_message_arguments_append(ret, "s", str);
2032 static Eldbus_Message *
2033 _text_caret_offset_set(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2035 const char *obj_path = eldbus_message_path_get(msg);
2036 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2037 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2039 Eldbus_Message *ret;
2042 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2044 if (!eldbus_message_arguments_get(msg, "i", &offset))
2045 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset expected.");
2047 ret = eldbus_message_method_return_new(msg);
2048 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2050 eo_do(obj, res = elm_interface_atspi_text_caret_offset_set(offset));
2052 eldbus_message_arguments_append(ret, "b", res);
2057 static Eldbus_Message *
2058 _text_character_at_offset_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2060 const char *obj_path = eldbus_message_path_get(msg);
2061 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2062 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2064 Eldbus_Message *ret;
2067 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2069 if (!eldbus_message_arguments_get(msg, "i", &offset))
2070 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset expected.");
2072 ret = eldbus_message_method_return_new(msg);
2073 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2075 eo_do(obj, res = elm_interface_atspi_text_character_get(offset));
2077 eldbus_message_arguments_append(ret, "i", res);
2082 static Eldbus_Message *
2083 _text_attribute_value_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2085 const char *name, *obj_path = eldbus_message_path_get(msg);
2087 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2088 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2090 Eldbus_Message *ret;
2093 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2095 if (!eldbus_message_arguments_get(msg, "is", &start, &name))
2096 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and attribute name expected.");
2098 ret = eldbus_message_method_return_new(msg);
2099 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2101 eo_do(obj, res = elm_interface_atspi_text_attribute_get(name, &start, &end, &value));
2102 eldbus_message_arguments_append(ret, "siib", value ? value : "", start, end, res);
2104 if (value) free(value);
2108 static Eldbus_Message *
2109 _text_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2111 const char *obj_path = eldbus_message_path_get(msg);
2112 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2113 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2115 Eldbus_Message *ret;
2116 Eldbus_Message_Iter *iter, *iter_array;
2118 Elm_Atspi_Text_Attribute *attr;
2120 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2122 if (!eldbus_message_arguments_get(msg, "i", &start))
2123 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset expected.");
2125 ret = eldbus_message_method_return_new(msg);
2126 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2128 iter = eldbus_message_iter_get(ret);
2129 iter_array = eldbus_message_iter_container_new(iter, 'a', "{ss}");
2130 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
2132 eo_do(obj, attrs = elm_interface_atspi_text_attributes_get(&start, &end));
2134 EINA_LIST_FREE(attrs, attr)
2136 eldbus_message_iter_arguments_append(iter_array, "ss", attr->name, attr->value);
2137 elm_atspi_text_text_attribute_free(attr);
2140 eldbus_message_iter_container_close(iter, iter_array);
2141 eldbus_message_iter_arguments_append(iter, "ii", start, end);
2146 if (ret) eldbus_message_unref(ret);
2150 static Eldbus_Message *
2151 _text_default_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2153 const char *obj_path = eldbus_message_path_get(msg);
2154 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2155 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2156 int start = -1, end;
2157 Eldbus_Message *ret;
2158 Eldbus_Message_Iter *iter, *iter_array;
2160 Elm_Atspi_Text_Attribute *attr;
2162 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2164 ret = eldbus_message_method_return_new(msg);
2165 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2167 iter = eldbus_message_iter_get(ret);
2168 iter_array = eldbus_message_iter_container_new(iter, 'a', "{ss}");
2169 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
2171 eo_do(obj, attrs = elm_interface_atspi_text_attributes_get(&start, &end));
2173 EINA_LIST_FREE(attrs, attr)
2175 eldbus_message_iter_arguments_append(iter_array, "ss", attr->name, attr->value);
2176 elm_atspi_text_text_attribute_free(attr);
2179 eldbus_message_iter_container_close(iter, iter_array);
2180 eldbus_message_iter_arguments_append(iter, "ii", start, end);
2185 if (ret) eldbus_message_unref(ret);
2189 static Eldbus_Message *
2190 _text_character_extents_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2192 const char *obj_path = eldbus_message_path_get(msg);
2193 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2194 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2196 Eina_Rectangle rect;
2197 AtspiCoordType type;
2198 Eina_Bool screen_coords, res;
2199 Eldbus_Message *ret;
2201 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2203 if (!eldbus_message_arguments_get(msg, "iu", &offset, &type))
2204 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and coordinates type expected.");
2206 ret = eldbus_message_method_return_new(msg);
2207 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2209 screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
2211 eo_do(obj, res = elm_interface_atspi_text_character_extents_get(offset, screen_coords, &rect));
2215 eldbus_message_unref(ret);
2216 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to get character extents.");
2218 eldbus_message_arguments_append(ret, "iiii", rect.x, rect.y, rect.w, rect.h);
2223 static Eldbus_Message *
2224 _text_offset_at_point_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2226 const char *obj_path = eldbus_message_path_get(msg);
2227 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2228 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2230 AtspiCoordType type;
2231 Eina_Bool screen_coords;
2232 Eldbus_Message *ret;
2234 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2236 if (!eldbus_message_arguments_get(msg, "iiu", &x, &y, &type))
2237 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and coordinates type expected.");
2239 ret = eldbus_message_method_return_new(msg);
2240 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2243 screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
2245 eo_do(obj, offset = elm_interface_atspi_text_offset_at_point_get(screen_coords, x, y));
2247 eldbus_message_arguments_append(ret, "i", offset);
2252 static Eldbus_Message *
2253 _text_n_selections_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2255 const char *obj_path = eldbus_message_path_get(msg);
2256 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2257 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2259 Eldbus_Message *ret;
2261 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2263 ret = eldbus_message_method_return_new(msg);
2264 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2266 eo_do(obj, n = elm_interface_atspi_text_selections_count_get());
2268 eldbus_message_arguments_append(ret, "i", n);
2273 static Eldbus_Message *
2274 _text_selection_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2276 const char *obj_path = eldbus_message_path_get(msg);
2277 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2278 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2279 int sel_num, start, end;
2280 Eldbus_Message *ret;
2282 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2284 if (!eldbus_message_arguments_get(msg, "i", &sel_num))
2285 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Selection number expected.");
2287 ret = eldbus_message_method_return_new(msg);
2288 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2290 eo_do(obj, elm_interface_atspi_text_selection_get(sel_num, &start, &end));
2292 eldbus_message_arguments_append(ret, "ii", start, end);
2297 static Eldbus_Message *
2298 _text_selection_add(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2300 const char *obj_path = eldbus_message_path_get(msg);
2301 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2302 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2305 Eldbus_Message *ret;
2307 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2309 if (!eldbus_message_arguments_get(msg, "ii", &start, &end))
2310 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Start and end text offset expected.");
2312 ret = eldbus_message_method_return_new(msg);
2313 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2315 eo_do(obj, res = elm_interface_atspi_text_selection_add(start, end));
2317 eldbus_message_arguments_append(ret, "b", res);
2322 static Eldbus_Message *
2323 _text_selection_remove(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2325 const char *obj_path = eldbus_message_path_get(msg);
2326 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2327 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2330 Eldbus_Message *ret;
2332 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2334 if (!eldbus_message_arguments_get(msg, "i", &sel_num))
2335 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Selection number expected.");
2337 ret = eldbus_message_method_return_new(msg);
2338 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2340 eo_do(obj, res = elm_interface_atspi_text_selection_remove(sel_num));
2342 eldbus_message_arguments_append(ret, "b", res);
2347 static Eldbus_Message *
2348 _text_selection_set(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2350 const char *obj_path = eldbus_message_path_get(msg);
2351 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2352 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2353 int sel_num, start, end;
2355 Eldbus_Message *ret;
2357 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2359 if (!eldbus_message_arguments_get(msg, "iii", &sel_num, &start, &end))
2360 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Selection number expected.");
2362 ret = eldbus_message_method_return_new(msg);
2363 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2365 eo_do(obj, res = elm_interface_atspi_text_selection_set(sel_num, start, end));
2367 eldbus_message_arguments_append(ret, "b", res);
2372 static Eldbus_Message *
2373 _text_range_extents_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2375 const char *obj_path = eldbus_message_path_get(msg);
2376 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2377 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2379 Eina_Rectangle rect;
2380 Eina_Bool screen_coords, res;
2381 AtspiCoordType type;
2382 Eldbus_Message *ret;
2384 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2386 if (!eldbus_message_arguments_get(msg, "iiu", &start, &end, &type))
2387 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Selection number expected.");
2389 ret = eldbus_message_method_return_new(msg);
2390 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2392 screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
2393 eo_do(obj, res = elm_interface_atspi_text_range_extents_get(screen_coords, start, end, &rect));
2396 eldbus_message_unref(ret);
2397 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Can't get range extents.");
2400 eldbus_message_arguments_append(ret, "iiii", rect.x, rect.y, rect.w, rect.h);
2405 static Eldbus_Message *
2406 _text_bounded_ranges_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2408 const char *obj_path = eldbus_message_path_get(msg);
2409 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2410 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2411 Eina_Rectangle rect;
2412 Eina_Bool screen_coords;
2413 AtspiCoordType type;
2414 Elm_Atspi_Text_Clip_Type xclip, yclip;
2416 Eldbus_Message *ret;
2417 Elm_Atspi_Text_Range *range;
2418 Eldbus_Message_Iter *iter, *iter_array, *iter_struct, *iter_var;
2420 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2422 if (!eldbus_message_arguments_get(msg, "iiiiuuu", &rect.x, &rect.y, &rect.w, &rect.h, &type, &xclip, &yclip))
2423 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.");
2425 ret = eldbus_message_method_return_new(msg);
2426 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2428 iter = eldbus_message_iter_get(ret);
2429 iter_array = eldbus_message_iter_container_new(iter, 'a', "(iisv)");
2430 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
2432 screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
2433 eo_do(obj, ranges = elm_interface_atspi_text_bounded_ranges_get(screen_coords, rect, xclip, yclip));
2435 EINA_LIST_FREE(ranges, range)
2437 iter_struct = eldbus_message_iter_container_new(iter_array, 'r', NULL);
2440 eldbus_message_iter_basic_append(iter_struct, 'i', range->start_offset);
2441 eldbus_message_iter_basic_append(iter_struct, 'i', range->end_offset);
2442 range->content = range->content ? range->content : strdup("");
2443 eldbus_message_iter_basic_append(iter_struct, 's', range->content);
2444 /* AT-SPI specification requires variant type in return, however
2445 * ATK or other implementations as well as AT Clients don't use it .
2446 * To cover spec a dummy value will be returned */
2447 iter_var = eldbus_message_iter_container_new(iter_struct, 'v', "i");
2450 eldbus_message_iter_basic_append(iter_var, 'i', 0);
2451 eldbus_message_iter_container_close(iter_struct, iter_var);
2453 eldbus_message_iter_container_close(iter_array, iter_struct);
2455 if (range->content) free(range->content);
2459 eldbus_message_iter_container_close(iter, iter_array);
2464 if (ret) eldbus_message_unref(ret);
2468 static Eldbus_Message *
2469 _text_run_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2471 const char *obj_path = eldbus_message_path_get(msg);
2472 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2473 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2475 Eldbus_Message *ret;
2476 Eldbus_Message_Iter *iter, *iter_array;
2477 Eina_List *attrs, *defaults;
2478 Elm_Atspi_Text_Attribute *attr;
2481 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
2483 if (!eldbus_message_arguments_get(msg, "ib", &start, &incl_def))
2484 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Offset and include defaults flag expected.");
2486 ret = eldbus_message_method_return_new(msg);
2487 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2489 iter = eldbus_message_iter_get(ret);
2490 iter_array = eldbus_message_iter_container_new(iter, 'a', "{ss}");
2491 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
2493 eo_do(obj, attrs = elm_interface_atspi_text_attributes_get(&start, &end));
2497 eo_do(obj, defaults = elm_interface_atspi_text_default_attributes_get());
2498 attrs = eina_list_merge(attrs, defaults);
2501 EINA_LIST_FREE(attrs, attr)
2503 eldbus_message_iter_arguments_append(iter_array, "ss", attr->name, attr->value);
2504 elm_atspi_text_text_attribute_free(attr);
2507 eldbus_message_iter_container_close(iter, iter_array);
2508 eldbus_message_iter_arguments_append(iter, "ii", start, end);
2513 if (ret) eldbus_message_unref(ret);
2517 static const Eldbus_Method text_methods[] = {
2518 { "GetTextAtOffset", ELDBUS_ARGS({"i", "offset"}, {"u", "granularity"}), ELDBUS_ARGS({"s", "string"}, {"i", "startOffset"}, {"i", "endOffset"}), _text_string_at_offset_get, 0 },
2519 { "GetText", ELDBUS_ARGS({"i", "startOffset"}, {"i", "endOffset"}), ELDBUS_ARGS({"s", "string"}), _text_text_get, 0 },
2520 { "SetCaretOffset", ELDBUS_ARGS({"i", "offset"}), ELDBUS_ARGS({"b", NULL}), _text_caret_offset_set, 0 },
2521 { "GetCharacterAtOffset", ELDBUS_ARGS({"i", "offset"}), ELDBUS_ARGS({"i", NULL}), _text_character_at_offset_get, 0 },
2522 { "GetAttributeValue", ELDBUS_ARGS({"i", "offset"}, {"s", "attributeName"}), ELDBUS_ARGS({"s", NULL}, {"i", "startOffset"}, {"i", "endOffset"}, {"b", "defined"}), _text_attribute_value_get, 0 },
2523 { "GetAttributes", ELDBUS_ARGS({"i", "offset"}), ELDBUS_ARGS({"a(ss)", NULL}, {"i", "startOffset"}, {"i", "endOffset"}), _text_attributes_get, 0 },
2524 { "GetDefaultAttributes", NULL, ELDBUS_ARGS({"a(ss)", NULL}), _text_default_attributes_get, 0 },
2525 { "GetCharacterExtents", ELDBUS_ARGS({"i", "offset"}, {"u", "coordType"}), ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"i","w"}, {"i","h"}), _text_character_extents_get, 0 },
2526 { "GetOffsetAtPoint", ELDBUS_ARGS({"i", "x"}, {"i","y"}, {"u", "coordType"}), ELDBUS_ARGS({"i", NULL}), _text_offset_at_point_get, 0 },
2527 { "GetNSelections", NULL, ELDBUS_ARGS({"i", NULL}), _text_n_selections_get, 0 },
2528 { "GetSelection", ELDBUS_ARGS({"i", "selectionNum"}), ELDBUS_ARGS({"i", "startOffset"}, {"i", "endOffset"}), _text_selection_get, 0 },
2529 { "AddSelection", ELDBUS_ARGS({"i", "startOffset"}, {"i", "endOffset"}), ELDBUS_ARGS({"b", NULL}), _text_selection_add, 0 },
2530 { "RemoveSelection", ELDBUS_ARGS({"i", "selectionNum"}), ELDBUS_ARGS({"b", NULL}), _text_selection_remove, 0 },
2531 { "SetSelection", ELDBUS_ARGS({"i", "selectionNum"}, {"i", "startOffset"}, {"i", "endOffset"}), ELDBUS_ARGS({"b", NULL}), _text_selection_set, 0 },
2532 { "GetRangeExtents", ELDBUS_ARGS({"i", "startOffset"}, {"i", "endOffset"}, {"u", "coordType"}), ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"i","w"}, {"i","h"}), _text_range_extents_get, 0 },
2533 { "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 },
2534 { "GetAttributeRun", ELDBUS_ARGS({"i", "offset"}, {"b", "includeDefaults"}), ELDBUS_ARGS({"a(ss)", NULL}, {"i", "startOffset"}, {"i", "endOffset"}), _text_run_attributes_get, 0 },
2535 { "GetDefaultAttributeSet", NULL, ELDBUS_ARGS({"a(ss)", NULL}), _text_default_attributes_get, 0 },
2536 { NULL, NULL, NULL, NULL, 0 }
2539 static Eldbus_Message *
2540 _editable_text_text_content_set(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2542 const char *obj_path = eldbus_message_path_get(msg);
2543 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2544 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2545 const char *content;
2546 Eldbus_Message *ret;
2549 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE, msg);
2551 if (!eldbus_message_arguments_get(msg, "s", &content))
2552 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "String expected.");
2554 ret = eldbus_message_method_return_new(msg);
2555 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2557 eo_do(obj, res = elm_interface_atspi_editable_text_content_set(content));
2559 eldbus_message_arguments_append(ret, "b", res);
2564 static Eldbus_Message *
2565 _editable_text_text_insert(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2567 const char *obj_path = eldbus_message_path_get(msg);
2568 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2569 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2571 Eldbus_Message *ret;
2575 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE, msg);
2577 if (!eldbus_message_arguments_get(msg, "isi", &pos, &text, &len))
2578 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Postion, string, length expected.");
2580 ret = eldbus_message_method_return_new(msg);
2581 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2583 eo_do(obj, res = elm_interface_atspi_editable_text_insert(text, pos));
2585 eldbus_message_arguments_append(ret, "b", res);
2590 static Eldbus_Message *
2591 _editable_text_text_copy(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2593 const char *obj_path = eldbus_message_path_get(msg);
2594 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2595 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2596 Eldbus_Message *ret;
2600 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE, msg);
2602 if (!eldbus_message_arguments_get(msg, "ii", &start, &end))
2603 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Start and end index expected.");
2605 ret = eldbus_message_method_return_new(msg);
2606 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2608 eo_do(obj, res = elm_interface_atspi_editable_text_copy(start, end));
2610 eldbus_message_arguments_append(ret, "b", res);
2615 static Eldbus_Message *
2616 _editable_text_text_cut(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2618 const char *obj_path = eldbus_message_path_get(msg);
2619 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2620 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2621 Eldbus_Message *ret;
2625 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE, msg);
2627 if (!eldbus_message_arguments_get(msg, "ii", &start, &end))
2628 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Start and end index expected.");
2630 ret = eldbus_message_method_return_new(msg);
2631 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2633 eo_do(obj, res = elm_interface_atspi_editable_text_cut(start, end));
2635 eldbus_message_arguments_append(ret, "b", res);
2640 static Eldbus_Message *
2641 _editable_text_text_delete(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2643 const char *obj_path = eldbus_message_path_get(msg);
2644 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2645 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2646 Eldbus_Message *ret;
2650 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE, msg);
2652 if (!eldbus_message_arguments_get(msg, "ii", &start, &end))
2653 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Start and end index expected.");
2655 ret = eldbus_message_method_return_new(msg);
2656 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2658 eo_do(obj, res = elm_interface_atspi_editable_text_delete(start, end));
2660 eldbus_message_arguments_append(ret, "b", res);
2665 static Eldbus_Message *
2666 _editable_text_text_paste(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2668 const char *obj_path = eldbus_message_path_get(msg);
2669 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2670 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2671 Eldbus_Message *ret;
2675 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE, msg);
2677 if (!eldbus_message_arguments_get(msg, "i", &pos))
2678 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Start and end index expected.");
2680 ret = eldbus_message_method_return_new(msg);
2681 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
2683 eo_do(obj, res = elm_interface_atspi_editable_text_paste(pos));
2685 eldbus_message_arguments_append(ret, "b", res);
2691 _elm_atspi_bridge_plug_id_split(const char *plug_id, char **bus, char **path)
2693 if (!plug_id || !strcmp(plug_id, "")) return EINA_FALSE;
2694 unsigned int tokens = 0;
2695 char **split = eina_str_split_full(plug_id, ":", 0, &tokens);
2696 Eina_Bool ret = EINA_FALSE;
2699 if (!split[0] || !split[1])
2703 if (bus) *bus = strdup(split[0]);
2704 if (path) *path = strdup(split[1]);
2708 else if (tokens == 3)
2710 if (!split[0] || !split[1] || !split[2])
2715 snprintf(buf, sizeof(buf), "%s:%s",split[0], split[1]);
2716 if (bus) *bus = strdup(buf);
2717 if (path) *path = strdup(split[2]);
2727 static Eldbus_Message *
2728 _socket_embedded(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
2731 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
2732 const char *obj_path = eldbus_message_path_get(msg);
2734 const char *bus, *path;
2735 Eo *bridge = _elm_atspi_bridge_get();
2736 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2737 eo_do(obj, proxy = elm_interface_atspi_accessible_parent_get());
2739 if (!eo_isa(proxy, ELM_ATSPI_PROXY_CLASS))
2740 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to embed object.");
2742 if (!eldbus_message_arguments_get(msg, "s", &path))
2743 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Plug id expected.");
2745 bus = eldbus_message_sender_get(msg);
2747 eo_do(proxy, elm_obj_atspi_proxy_address_set(bus, path));
2749 _bridge_cache_build(bridge, proxy);
2751 return eldbus_message_method_return_new(msg);
2754 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
2755 static Eldbus_Message *
2756 _socket_offset_set(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
2760 Eo *obj = eldbus_service_object_data_get(iface, "_atspi_obj");
2761 eo_do(obj, parent = eo_parent_get());
2762 Evas_Object *top = elm_object_top_widget_get(parent);
2764 if (!eldbus_message_arguments_get(msg, "ii", &x, &y))
2765 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
2767 eo_do(top, elm_interface_atspi_component_socket_offset_set(x, y));
2769 return eldbus_message_method_return_new(msg);
2773 static const Eldbus_Method editable_text_methods[] = {
2774 { "SetTextContents", ELDBUS_ARGS({"s", "newcontents"}), ELDBUS_ARGS({"b", NULL}), _editable_text_text_content_set, 0 },
2775 { "InsertText", ELDBUS_ARGS({"i", "position"}, {"s", "text"}, {"i", "length"}), ELDBUS_ARGS({"b", NULL}), _editable_text_text_insert, 0 },
2776 { "CopyText", ELDBUS_ARGS({"i", "startPos"}, {"i", "endPos"}), NULL, _editable_text_text_copy, 0 },
2777 { "CutText", ELDBUS_ARGS({"i", "startPos"}, {"i", "endPos"}), ELDBUS_ARGS({"b", NULL}), _editable_text_text_cut, 0 },
2778 { "DeleteText", ELDBUS_ARGS({"i", "startPos"}, {"i", "endPos"}), ELDBUS_ARGS({"b", NULL}), _editable_text_text_delete, 0 },
2779 { "PasteText", ELDBUS_ARGS({"i", "position"}), ELDBUS_ARGS({"b", NULL}), _editable_text_text_paste, 0 },
2780 { NULL, NULL, NULL, NULL, 0 }
2783 static const Eldbus_Method socket_methods[] = {
2784 { "Embedded", ELDBUS_ARGS({"s", "id"}), ELDBUS_ARGS({NULL, NULL}), _socket_embedded, 0 },
2785 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
2786 { "SetOffset", ELDBUS_ARGS({"i", "x"}, {"i", "y"}), ELDBUS_ARGS({NULL, NULL}), _socket_offset_set, 0 },
2788 { NULL, NULL, NULL, NULL, 0 }
2791 static const Eldbus_Service_Interface_Desc socket_iface_desc = {
2792 ATSPI_DBUS_INTERFACE_SOCKET, socket_methods, NULL, NULL, NULL, NULL
2796 _bridge_object_from_path(Eo *bridge, const char *path)
2798 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
2799 unsigned long long eo_ptr = 0;
2801 const char *tmp = path;
2804 int len = strlen(ELM_ACCESS_OBJECT_PATH_PREFIX);
2805 if (strncmp(path, ELM_ACCESS_OBJECT_PATH_PREFIX, len))
2808 tmp = path + len; /* Skip over the prefix */
2809 if (!strcmp(ELM_ACCESS_OBJECT_PATH_ROOT, tmp))
2810 return elm_atspi_bridge_root_get(bridge);
2812 sscanf(tmp, "%llu", &eo_ptr);
2813 eo = (Eo *) (uintptr_t) eo_ptr;
2815 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, NULL);
2816 if (!eina_hash_find(pd->cache, &eo))
2818 WRN("Request for non-registered object: %s", path);
2822 ret = eo_isa(eo, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN) ? eo : NULL;
2828 _bridge_path_from_object(Eo *bridge, const Eo *eo)
2830 static char path[64];
2833 return ATSPI_DBUS_PATH_NULL;
2835 if (eo == elm_atspi_bridge_root_get(bridge))
2836 snprintf(path, sizeof(path), "%s%s", ELM_ACCESS_OBJECT_PATH_PREFIX, ELM_ACCESS_OBJECT_PATH_ROOT);
2838 snprintf(path, sizeof(path), ELM_ACCESS_OBJECT_REFERENCE_TEMPLATE, (unsigned long long)(uintptr_t)eo);
2843 _accessible_property_get(const Eldbus_Service_Interface *interface, const char *property,
2844 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg,
2845 Eldbus_Message **error)
2847 const char *ret = NULL, *obj_path = eldbus_message_path_get(request_msg);
2848 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2849 Eo *ret_obj = NULL, *obj = _bridge_object_from_path(bridge, obj_path);
2851 ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, request_msg, error);
2853 if (!strcmp(property, "Name"))
2855 eo_do(obj, ret = elm_interface_atspi_accessible_name_get());
2858 eldbus_message_iter_basic_append(iter, 's', ret);
2861 else if (!strcmp(property, "Description"))
2863 eo_do(obj, ret = elm_interface_atspi_accessible_description_get());
2866 eldbus_message_iter_basic_append(iter, 's', ret);
2869 else if (!strcmp(property, "Parent"))
2871 eo_do(obj, ret_obj = elm_interface_atspi_accessible_parent_get());
2872 Elm_Atspi_Role role = ELM_ATSPI_ROLE_INVALID;
2873 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
2874 if ((!ret_obj) && (ELM_ATSPI_ROLE_APPLICATION == role))
2875 _object_desktop_reference_append(iter);
2877 _bridge_iter_object_reference_append(bridge, iter, ret_obj);
2880 else if (!strcmp(property, "ChildCount"))
2882 Eina_List *l = NULL;
2883 eo_do(obj, l = elm_interface_atspi_accessible_children_get());
2884 eldbus_message_iter_basic_append(iter, 'i', eina_list_count(l));
2892 _selection_property_get(const Eldbus_Service_Interface *interface, const char *property,
2893 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg,
2894 Eldbus_Message **error)
2897 const char *obj_path = eldbus_message_path_get(request_msg);
2898 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2899 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2901 ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE, request_msg, error);
2903 if (!strcmp(property, "NSelectedChildren"))
2905 eo_do(obj, n = elm_interface_atspi_selection_selected_children_count_get());
2906 eldbus_message_iter_basic_append(iter, 'i', n);
2913 _action_property_get(const Eldbus_Service_Interface *interface, const char *property,
2914 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg,
2915 Eldbus_Message **error)
2918 const char *obj_path = eldbus_message_path_get(request_msg);
2919 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2920 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2922 ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN, request_msg, error);
2924 if (!strcmp(property, "NActions"))
2926 eo_do(obj, actions = elm_interface_atspi_action_actions_get());
2927 eldbus_message_iter_basic_append(iter, 'i', eina_list_count(actions));
2928 eina_list_free(actions);
2934 static Eldbus_Message*
2935 _value_properties_set(const Eldbus_Service_Interface *interface, const char *property,
2936 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg)
2940 const char *obj_path = eldbus_message_path_get(request_msg);
2941 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2942 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2944 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_VALUE_INTERFACE, request_msg);
2946 if (!eldbus_message_iter_arguments_get(iter, "d", &value))
2948 return eldbus_message_error_new(request_msg, "org.freedesktop.DBus.Error.InvalidArgs", "Expected value of type: double.");
2951 if (!strcmp(property, "CurrentValue"))
2953 eo_do(obj, ret = elm_interface_atspi_value_and_text_set(value, NULL));
2954 Eldbus_Message *answer = eldbus_message_method_return_new(request_msg);
2955 eldbus_message_arguments_append(answer, "b", ret);
2963 _value_properties_get(const Eldbus_Service_Interface *interface, const char *property,
2964 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg,
2965 Eldbus_Message **error)
2968 const char *obj_path = eldbus_message_path_get(request_msg);
2969 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
2970 Eo *obj = _bridge_object_from_path(bridge, obj_path);
2972 ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_VALUE_INTERFACE, request_msg, error);
2974 if (!strcmp(property, "CurrentValue"))
2976 eo_do(obj, elm_interface_atspi_value_and_text_get(&value, NULL));
2977 eldbus_message_iter_basic_append(iter, 'd', value);
2980 if (!strcmp(property, "MinimumValue"))
2982 eo_do(obj, elm_interface_atspi_value_range_get(&value, NULL, NULL));
2983 eldbus_message_iter_basic_append(iter, 'd', value);
2986 if (!strcmp(property, "MaximumValue"))
2988 eo_do(obj, elm_interface_atspi_value_range_get(NULL, &value, NULL));
2989 eldbus_message_iter_basic_append(iter, 'd', value);
2992 if (!strcmp(property, "MinimumIncrement"))
2994 eo_do(obj, value = elm_interface_atspi_value_increment_get());
2995 eldbus_message_iter_basic_append(iter, 'd', value);
3002 _image_properties_get(const Eldbus_Service_Interface *interface, const char *property,
3003 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg,
3004 Eldbus_Message **error)
3007 const char *obj_path = eldbus_message_path_get(request_msg);
3008 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
3009 Eo *obj = _bridge_object_from_path(bridge, obj_path);
3011 ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_IMAGE_MIXIN, request_msg, error);
3013 if (!strcmp(property, "ImageDescription"))
3015 eo_do(obj, value = elm_interface_atspi_image_description_get());
3016 value = value ? value : "";
3017 eldbus_message_iter_basic_append(iter, 's', value);
3020 if (!strcmp(property, "ImageLocale"))
3022 eo_do(obj, value = elm_interface_atspi_image_locale_get());
3023 value = value ? value : "";
3024 eldbus_message_iter_basic_append(iter, 's', value);
3031 _text_properties_get(const Eldbus_Service_Interface *interface, const char *property,
3032 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg,
3033 Eldbus_Message **error)
3035 const char *obj_path = eldbus_message_path_get(request_msg);
3036 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
3037 Eo *obj = _bridge_object_from_path(bridge, obj_path);
3040 ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, request_msg, error);
3042 if (!strcmp(property, "CharacterCount"))
3044 eo_do(obj, val = elm_interface_atspi_text_character_count_get());
3045 eldbus_message_iter_basic_append(iter, 'i', val);
3048 if (!strcmp(property, "CaretOffset"))
3050 eo_do(obj, val = elm_interface_atspi_text_caret_offset_get());
3051 eldbus_message_iter_basic_append(iter, 'i', val);
3057 static Eldbus_Message*
3058 _application_properties_set(const Eldbus_Service_Interface *iface, const char *property, Eldbus_Message_Iter *iter, const Eldbus_Message *input_msg)
3060 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
3061 const char *obj_path = eldbus_message_path_get(input_msg);
3062 Eo *obj = _bridge_object_from_path(bridge, obj_path);
3065 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, NULL);
3066 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_ATSPI_APP_OBJECT_CLASS, input_msg);
3068 if (!eldbus_message_iter_arguments_get(iter, "i", &value))
3070 return eldbus_message_error_new(input_msg, "org.freedesktop.DBus.Error.InvalidArgs", "Expected value of type: int.");
3073 if (!strcmp(property, "Id"))
3076 Eldbus_Message *answer = eldbus_message_method_return_new(input_msg);
3077 eldbus_message_arguments_append(answer, "b", EINA_TRUE);
3085 _application_properties_get(const Eldbus_Service_Interface *interface, const char *property,
3086 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg,
3087 Eldbus_Message **error)
3089 const char *obj_path = eldbus_message_path_get(request_msg);
3090 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
3091 Eo *obj = _bridge_object_from_path(bridge, obj_path);
3093 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE);
3094 ELM_ATSPI_PROPERTY_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_ATSPI_APP_OBJECT_CLASS, request_msg, error);
3096 if (!strcmp(property, "ToolkitName"))
3098 eldbus_message_iter_basic_append(iter, 's', "elementary");
3101 if (!strcmp(property, "Version"))
3104 snprintf(buf, sizeof(buf), "%d.%d", ELM_VERSION_MAJOR, ELM_VERSION_MINOR);
3105 eldbus_message_iter_basic_append(iter, 's', buf);
3108 if (!strcmp(property, "Id"))
3110 eldbus_message_iter_basic_append(iter, 'i', pd->id);
3116 static const Eldbus_Property accessible_properties[] = {
3117 { "Name", "s", NULL, NULL, 0 },
3118 { "Description", "s", NULL, NULL, 0 },
3119 { "Parent", "(so)", NULL, NULL, 0 },
3120 { "ChildCount", "i", NULL, NULL, 0 },
3121 { NULL, NULL, NULL, NULL, 0 }
3124 static const Eldbus_Property action_properties[] = {
3125 { "NActions", "i", _action_property_get, NULL, 0 },
3126 { NULL, NULL, NULL, NULL, 0 }
3129 static const Eldbus_Property value_properties[] = {
3130 { "MinimumValue", "d", NULL, NULL, 0 },
3131 { "MaximumValue", "d", NULL, NULL, 0 },
3132 { "MinimumIncrement", "d", NULL, NULL, 0 },
3133 { "CurrentValue", "d", NULL, NULL, 0 },
3134 { NULL, NULL, NULL, NULL, 0 }
3137 static const Eldbus_Property image_properties[] = {
3138 { "ImageDescription", "s", NULL, NULL, 0 },
3139 { "ImageLocale", "s", NULL, NULL, 0 },
3140 { NULL, NULL, NULL, NULL, 0 }
3143 static const Eldbus_Property selection_properties[] = {
3144 { "NSelectedChildren", "i", _selection_property_get, NULL, 0 },
3145 { NULL, NULL, NULL, NULL, 0 }
3148 static const Eldbus_Property text_properties[] = {
3149 { "CharacterCount", "i", NULL, NULL, 0 },
3150 { "CaretOffset", "i", NULL, NULL, 0 },
3151 { NULL, NULL, NULL, NULL, 0 }
3154 static const Eldbus_Property application_properties[] = {
3155 { "ToolkitName", "s", NULL, NULL, 0 },
3156 { "Version", "s", NULL, NULL, 0 },
3157 { "Id", "i", NULL, NULL, 0 },
3158 { NULL, NULL, NULL, NULL, 0 }
3161 static const Eldbus_Service_Interface_Desc accessible_iface_desc = {
3162 ATSPI_DBUS_INTERFACE_ACCESSIBLE, accessible_methods, NULL, accessible_properties, _accessible_property_get, NULL
3165 static const Eldbus_Service_Interface_Desc action_iface_desc = {
3166 ATSPI_DBUS_INTERFACE_ACTION, action_methods, NULL, action_properties, NULL, NULL
3169 static const Eldbus_Service_Interface_Desc value_iface_desc = {
3170 ATSPI_DBUS_INTERFACE_VALUE, NULL, NULL, value_properties, _value_properties_get, _value_properties_set
3173 static const Eldbus_Service_Interface_Desc image_iface_desc = {
3174 ATSPI_DBUS_INTERFACE_IMAGE, image_methods, NULL, image_properties, _image_properties_get, NULL
3177 static const Eldbus_Service_Interface_Desc selection_iface_desc = {
3178 ATSPI_DBUS_INTERFACE_SELECTION, selection_methods, NULL, selection_properties, NULL, NULL
3181 static const Eldbus_Service_Interface_Desc text_iface_desc = {
3182 ATSPI_DBUS_INTERFACE_TEXT, text_methods, NULL, text_properties, _text_properties_get, NULL
3185 static const Eldbus_Service_Interface_Desc editable_text_iface_desc = {
3186 ATSPI_DBUS_INTERFACE_EDITABLE_TEXT, editable_text_methods, NULL, NULL, NULL, NULL
3189 static const Eldbus_Service_Interface_Desc application_iface_desc = {
3190 ATSPI_DBUS_INTERFACE_APPLICATION, NULL, NULL, application_properties, _application_properties_get, _application_properties_set
3194 _collection_match_rule_free(struct collection_match_rule *rule)
3196 Elm_Atspi_Attribute *attr;
3197 eina_list_free(rule->ifaces);
3198 EINA_LIST_FREE(rule->attributes, attr)
3200 eina_stringshare_del(attr->key);
3201 eina_stringshare_del(attr->value);
3206 _collection_roles_convert(uint64_t roles[2])
3208 // Currently elm roles and atspi roles are binary compatible.
3209 // Implement this function when it will be needed.
3214 _collection_iter_match_rule_get(Eldbus_Message_Iter *iter, struct collection_match_rule *rule)
3216 Eldbus_Message_Iter *states_iter, *attrib_iter, *iter_arg, *role_iter, *ifc_iter;
3217 unsigned int *array;
3218 int array_count, state_match, attrib_match, role_match, ifc_match, reverse;
3219 const char *ifc_name;
3221 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))
3223 ERR("Unable to get message arguments");
3227 memset(rule, 0x0, sizeof(struct collection_match_rule));
3228 rule->statematchtype = state_match;
3229 rule->attributematchtype = attrib_match;
3230 rule->rolematchtype = role_match;
3231 rule->interfacematchtype = ifc_match;
3232 rule->reverse = reverse;
3234 if (!eldbus_message_iter_fixed_array_get(states_iter, 'i', &array, &array_count))
3237 //Roles according to libatspi impementation are transferred in 2-int element fixed bit array
3238 if (array_count != 2)
3240 ERR("Unexpected states array size");
3243 uint64_t states = ((uint64_t)array[0] | ((uint64_t)array[1] << 32));
3244 rule->states = _atspi_state_set_to_elm_atspi_state_set(states);
3246 //Roles according to libatspi impementation are transferred in 4-int element fixed bit array
3247 if (!eldbus_message_iter_fixed_array_get(role_iter, 'i', &array, &array_count))
3250 if (array_count != 4)
3252 ERR("Unexpected roles array size");
3256 //convert atspi roles to elm_roles
3257 rule->roles[0] = ((uint64_t)array[0] | ((uint64_t)array[1] << 32));
3258 rule->roles[1] = ((uint64_t)array[2] | ((uint64_t)array[3] << 32));
3260 _collection_roles_convert(rule->roles);
3262 //Get matching properties
3263 while (eldbus_message_iter_get_and_next(attrib_iter, '{', &iter_arg))
3265 const char *key, *value;
3266 if (eldbus_message_iter_arguments_get(iter_arg, "ss", &key, &value))
3268 Elm_Atspi_Attribute *attrib = calloc(sizeof(Elm_Atspi_Attribute), 1);
3269 attrib->key = eina_stringshare_add(key);
3270 attrib->value = eina_stringshare_add(value);
3271 rule->attributes = eina_list_append(rule->attributes, attrib);
3275 //Get interfaces to match
3276 while (eldbus_message_iter_get_and_next(ifc_iter, 's', &ifc_name))
3278 const Eo_Class *class = NULL;
3279 if (!strcmp(ifc_name, "action"))
3280 class = ELM_INTERFACE_ATSPI_ACTION_MIXIN;
3281 else if (!strcmp(ifc_name, "component"))
3282 class = ELM_INTERFACE_ATSPI_COMPONENT_MIXIN;
3283 else if (!strcmp(ifc_name, "editabletext"))
3284 class = ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE;
3285 else if (!strcmp(ifc_name, "text"))
3286 class = ELM_INTERFACE_ATSPI_TEXT_INTERFACE;
3287 else if (!strcmp(ifc_name, "image"))
3288 class = ELM_INTERFACE_ATSPI_SELECTION_INTERFACE;
3289 else if (!strcmp(ifc_name, "value"))
3290 class = ELM_INTERFACE_ATSPI_VALUE_INTERFACE;
3293 rule->ifaces = eina_list_append(rule->ifaces, class);
3296 _collection_match_rule_free(rule);
3305 _collection_match_interfaces_helper(Eo *obj, Eina_List *ifcs, Eina_Bool condition, Eina_Bool ret_if_true, Eina_Bool ret_if_false)
3310 EINA_LIST_FOREACH(ifcs, l, class)
3312 if (eo_isa(obj, class) == condition)
3315 return ret_if_false;
3319 _collection_match_interfaces_lookup(Eo *obj, struct collection_match_rule *rule)
3321 Eina_Bool ret = EINA_FALSE;
3323 switch (rule->interfacematchtype)
3325 case ATSPI_Collection_MATCH_INVALID:
3328 case ATSPI_Collection_MATCH_ALL:
3329 ret = _collection_match_interfaces_helper(
3330 obj, rule->ifaces, EINA_FALSE, EINA_FALSE, EINA_TRUE);
3332 case ATSPI_Collection_MATCH_ANY:
3333 ret = _collection_match_interfaces_helper(
3334 obj, rule->ifaces, EINA_TRUE, EINA_TRUE, EINA_FALSE);
3336 case ATSPI_Collection_MATCH_NONE:
3337 ret = _collection_match_interfaces_helper(
3338 obj, rule->ifaces, EINA_TRUE, EINA_FALSE, EINA_TRUE);
3347 _collection_match_states_lookup(Eo *obj, struct collection_match_rule *rule)
3349 Eina_Bool ret = EINA_FALSE;
3350 Elm_Atspi_State_Set ss;
3352 eo_do(obj, ss = elm_interface_atspi_accessible_state_set_get());
3354 switch (rule->statematchtype)
3356 case ATSPI_Collection_MATCH_INVALID:
3359 case ATSPI_Collection_MATCH_ALL:
3360 ret = (ss & rule->states) == rule->states;
3362 case ATSPI_Collection_MATCH_ANY:
3363 ret = (ss & rule->states) > 0;
3365 case ATSPI_Collection_MATCH_NONE:
3366 ret = (ss & rule->states) == 0;
3376 _collection_match_roles_lookup(Eo *obj, struct collection_match_rule *rule)
3378 Eina_Bool ret = EINA_FALSE;
3379 Elm_Atspi_Role role;
3382 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
3387 role_set = rule->roles[1];
3390 role_set = rule->roles[0];
3394 ERR("Elm_Atspi_Role enum value exceeds 127. Unable to compare with roles bit field.");
3398 switch (rule->rolematchtype)
3400 case ATSPI_Collection_MATCH_INVALID:
3403 case ATSPI_Collection_MATCH_ALL:
3404 case ATSPI_Collection_MATCH_ANY:
3405 ret = (role_set & (1ULL << role)) > 0;
3407 case ATSPI_Collection_MATCH_NONE:
3408 ret = (role_set & (1ULL << role)) == 0;
3418 _collection_match_attributes_helper(Eina_List *obj_attribs, Eina_List *attribs, Eina_Bool compare, Eina_Bool ret_if_compare, Eina_Bool ret_default)
3421 Elm_Atspi_Attribute *attr, *attr2;
3423 EINA_LIST_FOREACH(attribs, l, attr)
3425 EINA_LIST_FOREACH(obj_attribs, l2, attr2)
3427 if ((attr->key && attr2->key &&
3428 attr->value && attr2->value &&
3429 !strcmp(attr->key, attr2->key) &&
3430 !strcmp(attr->value, attr2->value)) == compare)
3432 return ret_if_compare;
3441 _collection_match_attributes_lookup(Eo *obj, struct collection_match_rule *rule)
3443 Eina_Bool ret = EINA_FALSE;
3444 Eina_List *obj_attribs;
3446 eo_do(obj, obj_attribs = elm_interface_atspi_accessible_attributes_get());
3448 switch (rule->attributematchtype)
3450 case ATSPI_Collection_MATCH_INVALID:
3453 case ATSPI_Collection_MATCH_ALL:
3454 ret = _collection_match_attributes_helper(
3455 obj_attribs, rule->attributes, EINA_FALSE, EINA_FALSE, EINA_TRUE);
3457 case ATSPI_Collection_MATCH_ANY:
3458 ret = _collection_match_attributes_helper(
3459 obj_attribs, rule->attributes, EINA_TRUE, EINA_TRUE, EINA_FALSE);
3461 case ATSPI_Collection_MATCH_NONE:
3462 ret = _collection_match_attributes_helper(
3463 obj_attribs, rule->attributes, EINA_TRUE, EINA_FALSE, EINA_TRUE);
3469 elm_atspi_attributes_list_free(obj_attribs);
3475 _collection_sort_order_canonical(struct collection_match_rule *rule, Eina_List **ls,
3477 Eo *obj, long index, Eina_Bool flag,
3478 Eo *pobj, Eina_Bool recurse, Eina_Bool traverse)
3481 Eina_List *children;
3482 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
3483 long acount = eina_list_count(children);
3484 Eina_Bool prev = pobj ? EINA_TRUE : EINA_FALSE;
3486 for (; i < acount && (max == 0 || count < max); i++)
3488 Eo *child = eina_list_nth(children, i);
3490 if (prev && child == pobj)
3492 eina_list_free(children);
3496 if (flag && _collection_match_interfaces_lookup(child, rule)
3497 && _collection_match_states_lookup(child, rule)
3498 && _collection_match_roles_lookup(child, rule)
3499 && _collection_match_attributes_lookup(child, rule))
3501 *ls = eina_list_append(*ls, child);
3508 if (recurse && traverse)
3509 count = _collection_sort_order_canonical(rule, ls, count,
3510 max, child, 0, EINA_TRUE,
3511 pobj, recurse, traverse);
3513 eina_list_free(children);
3518 _collection_sort_order_reverse_canonical(struct collection_match_rule *rule, Eina_List **ls,
3519 int count, int max, Eo *obj, Eina_Bool flag, Eo *pobj)
3521 Eo *nextobj, *parent;
3523 Eina_List *children;
3525 /* This breaks us out of the recursion. */
3526 if (!obj || obj == pobj)
3531 /* Add to the list if it matches */
3532 if (flag && _collection_match_interfaces_lookup(obj, rule)
3533 && _collection_match_states_lookup(obj, rule)
3534 && _collection_match_roles_lookup(obj, rule)
3535 && _collection_match_attributes_lookup(obj, rule)
3536 && (max == 0 || count < max))
3538 *ls = eina_list_append(*ls, obj);
3545 /* Get the current nodes index in it's parent and the parent object. */
3547 indexinparent = elm_interface_atspi_accessible_index_in_parent_get(),
3548 parent = elm_interface_atspi_accessible_parent_get());
3550 if ((indexinparent > 0) && ((max == 0) || (count < max)))
3552 /* there are still some siblings to visit so get the previous sibling
3553 and get it's last descendant.
3554 First, get the previous sibling */
3555 eo_do(parent, children = elm_interface_atspi_accessible_children_get());
3556 nextobj = eina_list_nth(children, indexinparent - 1);
3557 eina_list_free(children);
3559 /* Now, drill down the right side to the last descendant */
3561 eo_do(nextobj, children = elm_interface_atspi_accessible_children_get());
3562 if (children) nextobj = eina_list_last_data_get(children);
3563 eina_list_free(children);
3566 /* recurse with the last descendant */
3567 count = _collection_sort_order_reverse_canonical(rule, ls, count, max,
3568 nextobj, EINA_TRUE, pobj);
3570 else if (max == 0 || count < max)
3572 /* no more siblings so next node must be the parent */
3573 count = _collection_sort_order_reverse_canonical(rule, ls, count, max,
3574 parent, EINA_TRUE, pobj);
3581 _collection_inbackorder(Eo *collection, struct collection_match_rule *rule, Eina_List **list,
3584 *list = eina_list_append(*list, obj);
3586 _collection_sort_order_reverse_canonical(rule, list, 0, max, obj, EINA_TRUE, collection);
3588 *list = eina_list_remove_list(*list, *list);
3594 _collection_inorder(Eo *collection, struct collection_match_rule *rule, Eina_List **list,
3595 int count, int max, Eo *obj, Eina_Bool traverse)
3599 count = _collection_sort_order_canonical(rule, list, count, max, obj, 0, EINA_TRUE, NULL, EINA_TRUE, traverse);
3601 while ((max == 0 || count < max) && obj && obj != collection)
3605 parent = elm_interface_atspi_accessible_parent_get(),
3606 idx = elm_interface_atspi_accessible_index_in_parent_get());
3607 count = _collection_sort_order_canonical(rule, list, count, max, parent,
3608 idx + 1, EINA_TRUE, NULL, EINA_TRUE, traverse);
3612 if (max == 0 || count < max)
3613 count = _collection_sort_order_canonical(rule, list, count, max,
3614 obj, idx + 1, EINA_TRUE, NULL, EINA_TRUE, traverse);
3620 _collection_query(struct collection_match_rule *rule, AtspiCollectionSortOrder sortby,
3621 Eina_List **list, int count, int max, Eo *obj, long index,
3622 Eina_Bool flag, Eo *pobj, Eina_Bool recurse, Eina_Bool traverse)
3626 case ATSPI_Collection_SORT_ORDER_CANONICAL:
3627 count = _collection_sort_order_canonical(rule, list, 0, max, obj, index, flag,
3628 pobj, recurse, traverse);
3630 case ATSPI_Collection_SORT_ORDER_REVERSE_CANONICAL:
3631 count = _collection_sort_order_canonical(rule, list, 0, max, obj, index, flag,
3632 pobj, recurse, traverse);
3633 *list = eina_list_reverse(*list);
3637 WRN("Unhandled sort method");
3643 static Eldbus_Message*
3644 _collection_return_msg_from_list(Elm_Atspi_Bridge *bridge, const Eldbus_Message *msg, const Eina_List *objs)
3646 Eldbus_Message *ret;
3648 Eldbus_Message_Iter *iter, *array_iter;
3651 ret = eldbus_message_method_return_new(msg);
3652 if (!ret) return NULL;
3654 iter = eldbus_message_iter_get(ret);
3655 array_iter = eldbus_message_iter_container_new(iter, 'a', "(so)");
3657 EINA_LIST_FOREACH(objs, l, obj)
3659 _bridge_object_register(bridge, obj);
3660 _bridge_iter_object_reference_append(bridge, array_iter, obj);
3663 eldbus_message_iter_container_close(iter, array_iter);
3668 _collection_get_matches_from_handle(Eo *collection, Eo *current, struct collection_match_rule *rule, AtspiCollectionSortOrder sortby, AtspiCollectionTreeTraversalType tree, int max, Eina_Bool traverse)
3670 Eina_List *result = NULL;
3676 case ATSPI_Collection_TREE_INORDER:
3677 _collection_inorder(collection, rule, &result, 0, max, current, traverse);
3678 if (sortby == ATSPI_Collection_SORT_ORDER_REVERSE_CANONICAL)
3679 result = eina_list_reverse(result);
3681 case ATSPI_Collection_TREE_RESTRICT_CHILDREN:
3683 idx = elm_interface_atspi_accessible_index_in_parent_get(),
3684 parent = elm_interface_atspi_accessible_parent_get());
3685 _collection_query(rule, sortby, &result, 0, max, parent, idx, EINA_FALSE, NULL, EINA_TRUE, traverse);
3687 case ATSPI_Collection_TREE_RESTRICT_SIBLING:
3688 _collection_query(rule, sortby, &result, 0, max, current, 0, EINA_FALSE, NULL, EINA_TRUE, traverse);
3691 ERR("Tree parameter value not handled");
3697 static Eldbus_Message*
3698 _collection_get_matches_from(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED)
3700 const char *obj_path = eldbus_message_path_get(msg);
3701 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
3702 Eo *current, *obj = _bridge_object_from_path(bridge, obj_path);
3703 Eldbus_Message *ret;
3704 Eldbus_Message_Iter *iter, *rule_iter;
3705 struct collection_match_rule rule;
3707 AtspiCollectionTreeTraversalType tree;
3709 AtspiCollectionSortOrder sortby;
3710 Eina_List *result = NULL;
3712 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
3714 iter = eldbus_message_iter_get(msg);
3715 EINA_SAFETY_ON_NULL_RETURN_VAL(iter, NULL);
3717 if (!eldbus_message_iter_arguments_get(iter, "o(aiia{ss}iaiiasib)uuib", &obj_path, &rule_iter, &sortby, &tree, &count, &traverse))
3719 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to get matchule, sortby, count or traverse values.");
3722 current = _bridge_object_from_path(bridge, obj_path);
3724 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(current, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
3726 if (!_collection_iter_match_rule_get(rule_iter, &rule))
3727 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Invalid match rule parameters.");
3729 result = _collection_get_matches_from_handle(obj, current, &rule, sortby, tree, count, traverse);
3730 ret = _collection_return_msg_from_list(bridge, msg, result);
3732 eina_list_free(result);
3733 _collection_match_rule_free(&rule);
3739 _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)
3741 Eina_List *result = NULL;
3742 Eo *collection = obj;
3745 eo_do(obj, collection = elm_interface_atspi_accessible_parent_get());
3749 case ATSPI_Collection_TREE_INORDER:
3750 _collection_inbackorder(obj, rule, &result, max, current);
3751 if (sortby == ATSPI_Collection_SORT_ORDER_REVERSE_CANONICAL)
3752 result = eina_list_reverse(result);
3754 case ATSPI_Collection_TREE_RESTRICT_CHILDREN:
3755 _collection_query(rule, sortby, &result, 0, max, collection, 0, EINA_FALSE, current, EINA_TRUE, traverse);
3757 case ATSPI_Collection_TREE_RESTRICT_SIBLING:
3758 _collection_query(rule, sortby, &result, 0, max, collection, 0, EINA_FALSE, current, EINA_TRUE, traverse);
3761 ERR("Tree parameter value not handled");
3768 static Eldbus_Message*
3769 _collection_get_matches_to(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg EINA_UNUSED)
3771 const char *obj_path = eldbus_message_path_get(msg);
3772 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
3773 Eo *current, *obj = _bridge_object_from_path(bridge, obj_path);
3774 Eldbus_Message *ret;
3775 Eldbus_Message_Iter *iter, *rule_iter;
3776 struct collection_match_rule rule;
3778 AtspiCollectionTreeTraversalType tree;
3780 AtspiCollectionSortOrder sortby;
3781 Eina_List *result = NULL;
3784 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
3786 iter = eldbus_message_iter_get(msg);
3787 EINA_SAFETY_ON_NULL_RETURN_VAL(iter, NULL);
3789 if (!eldbus_message_iter_arguments_get(iter, "o(aiia{ss}iaiiasib)uubib", &obj_path, &rule_iter, &sortby, &tree, &limit, &count, &traverse))
3791 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to get matchule, sortby, tree, limit count or traverse values.");
3794 current = _bridge_object_from_path(bridge, obj_path);
3796 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(current, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
3798 if (!_collection_iter_match_rule_get(rule_iter, &rule))
3799 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Invalid match rule parameters.");
3801 result = _collection_get_matches_to_handle(obj, current, &rule, sortby, tree, limit, count, traverse);
3802 ret = _collection_return_msg_from_list(bridge, msg, result);
3804 eina_list_free(result);
3805 _collection_match_rule_free(&rule);
3810 static Eldbus_Message*
3811 _collection_get_matches(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
3813 const char *obj_path = eldbus_message_path_get(msg);
3814 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
3815 Eo *obj = _bridge_object_from_path(bridge, obj_path);
3816 Eldbus_Message *ret;
3817 Eldbus_Message_Iter *iter, *rule_iter;
3818 struct collection_match_rule rule;
3821 AtspiCollectionSortOrder sortby;
3822 Eina_List *result = NULL;
3824 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
3826 iter = eldbus_message_iter_get(msg);
3827 EINA_SAFETY_ON_NULL_RETURN_VAL(iter, NULL);
3829 if (!eldbus_message_iter_arguments_get(iter, "(aiia{ss}iaiiasib)uib", &rule_iter, &sortby, &count, &traverse))
3831 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to get matchule, sortby, count or traverse values.");
3834 if (!_collection_iter_match_rule_get(rule_iter, &rule))
3835 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Invalid match rule parameters.");
3837 _collection_query(&rule, sortby, &result, 0, count, obj, 0, EINA_TRUE, NULL, EINA_TRUE, traverse);
3839 ret = _collection_return_msg_from_list(bridge, msg, result);
3841 eina_list_free(result);
3842 _collection_match_rule_free(&rule);
3847 static const Eldbus_Method collection_methods[] = {
3849 ELDBUS_ARGS({"o", "current_object"}, {"(aiia{ss}iaiiasib)", "match_rule"},
3850 {"u", "sortby"}, {"u", "tree"}, {"i", "count"}, {"b", "traverse"}),
3851 ELDBUS_ARGS({"a(so)", "objects"}), _collection_get_matches_from, 0 },
3853 ELDBUS_ARGS({"o", "current_object"}, {"(aiia{ss}iaiiasib)", "match_rule"},
3854 {"u", "sortby"}, {"u", "tree"}, {"b", "limit_scope"},
3855 {"i", "count"}, {"b", "traverse"}),
3856 ELDBUS_ARGS({"a(so)", "objects"}), _collection_get_matches_to, 0 },
3858 ELDBUS_ARGS({"(aiia{ss}iaiiasib)", "match_rule"},
3859 {"u", "sortby"}, {"i", "count"}, {"b", "traverse"}),
3860 ELDBUS_ARGS({"a(so)", "objects"}), _collection_get_matches, 0 },
3861 { NULL, NULL, NULL, NULL, 0 }
3864 static const Eldbus_Service_Interface_Desc collection_iface_desc = {
3865 ATSPI_DBUS_INTERFACE_COLLECTION, collection_methods, NULL, NULL, NULL, NULL
3869 _object_get_bus_name_and_path(Eo *bridge, const Eo *obj, const char **bus_name, const char **path)
3871 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
3873 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
3874 if (eo_isa(obj, ELM_ATSPI_PROXY_CLASS))
3876 const char *pbus = "", *ppath = ATSPI_DBUS_PATH_NULL;
3877 eo_do(obj, elm_obj_atspi_proxy_address_get(&pbus, &ppath));
3880 if (bus_name) *bus_name = pbus;
3881 if (path) *path = ppath;
3884 DBG("Invalid proxy address! Address not set before connecting/listening. Or after proxy is removed.");
3886 if (bus_name) *bus_name = eldbus_connection_unique_name_get(pd->a11y_bus);
3887 if (path) *path = _bridge_path_from_object(bridge, obj);
3892 _bridge_iter_object_reference_append(Eo *bridge, Eldbus_Message_Iter *iter, const Eo *obj)
3894 EINA_SAFETY_ON_NULL_RETURN(iter);
3896 const char *pbus = NULL, *ppath = NULL;
3897 _object_get_bus_name_and_path(bridge, obj, &pbus, &ppath);
3898 Eldbus_Message_Iter *iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
3899 eldbus_message_iter_basic_append(iter_struct, 's', pbus);
3900 eldbus_message_iter_basic_append(iter_struct, 'o', ppath);
3901 eldbus_message_iter_container_close(iter, iter_struct);
3905 _object_desktop_reference_append(Eldbus_Message_Iter *iter)
3907 Eldbus_Message_Iter *iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
3908 EINA_SAFETY_ON_NULL_RETURN(iter);
3910 eldbus_message_iter_basic_append(iter_struct, 's', ATSPI_DBUS_NAME_REGISTRY);
3911 eldbus_message_iter_basic_append(iter_struct, 'o', ATSPI_DBUS_PATH_ROOT);
3912 eldbus_message_iter_container_close(iter, iter_struct);
3916 _iter_interfaces_append(Eldbus_Message_Iter *iter, const Eo *obj)
3918 Eldbus_Message_Iter *iter_array;
3919 iter_array = eldbus_message_iter_container_new(iter, 'a', "s");
3920 if (!iter_array) return;
3922 if (eo_isa(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
3924 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_ACCESSIBLE);
3925 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_COLLECTION);
3927 if (eo_isa(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN))
3928 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_ACTION);
3929 if (eo_isa(obj, ELM_ATSPI_APP_OBJECT_CLASS))
3930 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_APPLICATION);
3931 if (eo_isa(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN))
3932 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_COMPONENT);
3933 if (eo_isa(obj, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE))
3934 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_EDITABLE_TEXT);
3935 if (eo_isa(obj, ELM_INTERFACE_ATSPI_IMAGE_MIXIN))
3936 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_IMAGE);
3937 if (eo_isa(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE))
3938 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_SELECTION);
3939 if (eo_isa(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE))
3940 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_TEXT);
3941 if (eo_isa(obj, ELM_INTERFACE_ATSPI_VALUE_INTERFACE))
3942 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_VALUE);
3944 eldbus_message_iter_container_close(iter, iter_array);
3948 _cache_item_reference_append_cb(Eo *bridge, Eo *data, Eldbus_Message_Iter *iter_array)
3950 if (!eo_ref_get(data) || eo_destructed_is(data))
3953 Eldbus_Message_Iter *iter_struct, *iter_sub_array;
3954 Elm_Atspi_State_Set states;
3955 Elm_Atspi_Role role;
3956 Eo *root = elm_atspi_bridge_root_get(bridge);
3958 eo_do(data, role = elm_interface_atspi_accessible_role_get());
3960 iter_struct = eldbus_message_iter_container_new(iter_array, 'r', NULL);
3961 EINA_SAFETY_ON_NULL_RETURN_VAL(iter_struct, EINA_TRUE);
3963 /* Marshall object path */
3964 _bridge_iter_object_reference_append(bridge, iter_struct, data);
3966 /* Marshall application */
3967 _bridge_iter_object_reference_append(bridge, iter_struct, root);
3970 eo_do(data, parent = elm_interface_atspi_accessible_parent_get());
3971 /* Marshall parent */
3972 if ((!parent) && (ELM_ATSPI_ROLE_APPLICATION == role))
3973 _object_desktop_reference_append(iter_struct);
3975 _bridge_iter_object_reference_append(bridge, iter_struct, parent);
3977 /* Marshall children */
3978 Eina_List *children_list = NULL, *l;
3981 //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
3982 Elm_Atspi_State_Set ss;
3983 eo_do(data, ss = elm_interface_atspi_accessible_state_set_get());
3985 iter_sub_array = eldbus_message_iter_container_new(iter_struct, 'a', "(so)");
3986 EINA_SAFETY_ON_NULL_GOTO(iter_sub_array, fail);
3988 //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
3989 if (!STATE_TYPE_GET(ss, ELM_ATSPI_STATE_MANAGES_DESCENDANTS))
3991 eo_do(data, children_list = elm_interface_atspi_accessible_children_get());
3993 EINA_LIST_FOREACH(children_list, l, child)
3994 _bridge_iter_object_reference_append(bridge, iter_sub_array, child);
3996 //TIZEN_ONLY(20150709) Do not register children of MANAGES_DESCENDATS objects
3997 eina_list_free(children_list);
4001 eldbus_message_iter_container_close(iter_struct, iter_sub_array);
4003 /* Marshall interfaces */
4004 _iter_interfaces_append(iter_struct, data);
4007 const char *name = NULL;
4008 eo_do(data, name = elm_interface_atspi_accessible_name_get());
4012 eldbus_message_iter_basic_append(iter_struct, 's', name);
4015 eldbus_message_iter_basic_append(iter_struct, 'u', role);
4017 /* Marshall description */
4018 const char* descritpion = NULL;
4019 eo_do(data, descritpion = elm_interface_atspi_accessible_description_get());
4022 eldbus_message_iter_basic_append(iter_struct, 's', descritpion);
4024 /* Marshall state set */
4025 iter_sub_array = eldbus_message_iter_container_new(iter_struct, 'a', "u");
4026 EINA_SAFETY_ON_NULL_GOTO(iter_sub_array, fail);
4028 eo_do(data, states = elm_interface_atspi_accessible_state_set_get());
4030 unsigned int s1 = states & 0xFFFFFFFF;
4031 unsigned int s2 = (states >> 32) & 0xFFFFFFFF;
4032 eldbus_message_iter_basic_append(iter_sub_array, 'u', s1);
4033 eldbus_message_iter_basic_append(iter_sub_array, 'u', s2);
4035 eldbus_message_iter_container_close(iter_struct, iter_sub_array);
4036 eldbus_message_iter_container_close(iter_array, iter_struct);
4041 if (iter_struct) eldbus_message_iter_del(iter_struct);
4045 static Eldbus_Message *
4046 _cache_get_items(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
4048 Eldbus_Message_Iter *iter, *iter_array;
4049 Eldbus_Message *ret;
4050 Eina_List *to_process;
4053 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
4054 if (!bridge) return NULL;
4056 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, NULL);
4058 ret = eldbus_message_method_return_new(msg);
4059 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
4061 iter = eldbus_message_iter_get(ret);
4062 iter_array = eldbus_message_iter_container_new(iter, 'a', CACHE_ITEM_SIGNATURE);
4063 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
4065 eo_do(bridge, root = elm_obj_atspi_bridge_root_get());
4066 to_process = eina_list_append(NULL, root);
4070 Eo *obj = eina_list_data_get(to_process);
4071 to_process = eina_list_remove_list(to_process, to_process);
4072 _cache_item_reference_append_cb(bridge, obj, iter_array);
4073 _bridge_object_register(bridge, obj);
4075 Eina_List *children;
4076 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
4077 to_process = eina_list_merge(to_process, children);
4080 eldbus_message_iter_container_close(iter, iter_array);
4084 if (ret) eldbus_message_unref(ret);
4088 static const Eldbus_Method cache_methods[] = {
4089 { "GetItems", NULL, ELDBUS_ARGS({CACHE_ITEM_SIGNATURE, "items"}), _cache_get_items, 0 },
4090 { NULL, NULL, NULL, NULL, 0 }
4093 static const Eldbus_Signal cache_signals[] = {
4094 [ATSPI_OBJECT_CHILD_ADDED] = { "AddAccessible", ELDBUS_ARGS({"((so)(so)a(so)assusau)", "added"}), 0},
4095 [ATSPI_OBJECT_CHILD_REMOVED] = { "RemoveAccessible", ELDBUS_ARGS({ "(so)", "removed" }), 0},
4099 static const Eldbus_Service_Interface_Desc cache_iface_desc = {
4100 ATSPI_DBUS_INTERFACE_CACHE, cache_methods, cache_signals, NULL, NULL, NULL
4103 // Component interface
4104 static Eldbus_Message *
4105 _component_contains(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4107 const char *obj_path = eldbus_message_path_get(msg);
4108 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
4109 Eo *obj = _bridge_object_from_path(bridge, obj_path);
4111 Eina_Bool contains = EINA_FALSE;
4112 AtspiCoordType coord_type;
4113 Eldbus_Message *ret;
4115 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
4117 if (!eldbus_message_arguments_get(msg, "iiu", &x, &y, &coord_type))
4118 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
4120 Eina_Bool type = coord_type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
4121 eo_do(obj, contains = elm_interface_atspi_component_contains(type, x, y));
4123 ret = eldbus_message_method_return_new(msg);
4124 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
4126 eldbus_message_arguments_append(ret, "b", contains);
4131 static Eldbus_Message *
4132 _component_get_accessible_at_point(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4134 const char *obj_path = eldbus_message_path_get(msg);
4135 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
4136 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
4137 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, NULL);
4139 Eo *obj = _bridge_object_from_path(bridge, obj_path);
4141 Eo *accessible = NULL;
4142 AtspiCoordType coord_type;
4143 Eldbus_Message *ret;
4144 Eldbus_Message_Iter *iter;
4146 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
4148 // TIZEN_ONLY(20161213) - do not response if ecore evas is obscured
4149 const Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
4150 if (ecore_evas_obscured_get(ee))
4151 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "ecore evas is obscured.");
4154 if (!eldbus_message_arguments_get(msg, "iiu", &x, &y, &coord_type))
4155 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
4157 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
4158 Evas_Object *top = elm_object_top_widget_get(obj);
4161 eo_do(top, elm_interface_atspi_component_socket_offset_get(&sx, &sy));
4167 ret = eldbus_message_method_return_new(msg);
4168 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
4170 iter = eldbus_message_iter_get(ret);
4171 Eina_Bool type = coord_type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
4172 eo_do(obj, accessible = elm_interface_atspi_component_accessible_at_point_get(type, x, y));
4173 _bridge_iter_object_reference_append(bridge, iter, accessible);
4174 _bridge_object_register(bridge, accessible);
4179 // TIZEN_ONLY(20170310) - implementation of get object under coordinates for accessibility
4181 NEIGHBOR_SEARCH_MODE_NORMAL = 0,
4182 NEIGHBOR_SEARCH_MODE_RECURSE_FROM_ROOT = 1,
4183 NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING = 2,
4184 NEIGHBOR_SEARCH_MODE_RECURSE_TO_OUTSIDE = 3,
4185 } GetNeighborSearchMode;
4187 typedef struct accessibility_navigation_pointer_table {
4188 AtspiRole (*object_get_role)(struct accessibility_navigation_pointer_table *t, void *ptr);
4189 uint64_t (*object_get_state_set)(struct accessibility_navigation_pointer_table *t, void *ptr);
4190 void *(*get_object_in_relation_by_type)(struct accessibility_navigation_pointer_table *t, void *ptr, AtspiRelationType type);
4191 unsigned char (*object_is_zero_size)(struct accessibility_navigation_pointer_table *t, void *ptr);
4192 void *(*get_parent)(struct accessibility_navigation_pointer_table *t, void *ptr);
4193 unsigned char (*object_is_scrollable)(struct accessibility_navigation_pointer_table *t, void *ptr);
4194 void *(*get_object_at_point)(struct accessibility_navigation_pointer_table *t, void *ptr, int x, int y, unsigned char coordinates_are_screen_based);
4195 unsigned char (*object_contains)(struct accessibility_navigation_pointer_table *t, void *ptr, int x, int y, unsigned char coordinates_are_screen_based);
4196 unsigned char (*object_is_proxy)(struct accessibility_navigation_pointer_table *t, void *ptr);
4197 } accessibility_navigation_pointer_table;
4199 #define CALL(fncname, ...) table->fncname(table, __VA_ARGS__)
4200 static unsigned char _accept_object_check_role(accessibility_navigation_pointer_table *table EINA_UNUSED, void *obj)
4202 return _elm_widget_atspi_role_acceptable_check(obj);
4205 static unsigned char _state_set_is_set(uint64_t state_set, AtspiStateType state)
4207 return (state_set & ((uint64_t)1 << (unsigned int)state)) != 0;
4210 static unsigned char _object_is_defunct(accessibility_navigation_pointer_table *table, void *ptr)
4212 uint64_t states = CALL(object_get_state_set, ptr);
4213 return _state_set_is_set(states, ATSPI_STATE_DEFUNCT);
4216 static unsigned char _object_role_is_acceptable_when_navigating_next_prev(accessibility_navigation_pointer_table *table, void *obj)
4218 AtspiRole role = CALL(object_get_role, obj);
4219 return role != ATSPI_ROLE_POPUP_MENU && role != ATSPI_ROLE_DIALOG;
4222 static void *_get_object_in_relation_flow(accessibility_navigation_pointer_table *table, void *source, unsigned char forward)
4224 return CALL(get_object_in_relation_by_type, source, forward ? ATSPI_RELATION_FLOWS_TO : ATSPI_RELATION_FLOWS_FROM);
4227 static unsigned char _object_is_item(accessibility_navigation_pointer_table *table, void *obj)
4229 AtspiRole role = CALL(object_get_role, obj);
4230 return role == ATSPI_ROLE_LIST_ITEM || role == ATSPI_ROLE_MENU_ITEM;
4233 static unsigned char _object_is_highlightable(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_HIGHLIGHTABLE);
4239 static unsigned char _object_is_visible(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_VISIBLE);
4245 static unsigned char _object_is_showing(accessibility_navigation_pointer_table *table, void *obj)
4247 uint64_t state_set = CALL(object_get_state_set, obj);
4248 return _state_set_is_set(state_set, ATSPI_STATE_SHOWING);
4251 static unsigned char _object_is_collapsed(accessibility_navigation_pointer_table *table, void *obj)
4253 uint64_t state_set = CALL(object_get_state_set, obj);
4255 _state_set_is_set(state_set, ATSPI_STATE_EXPANDABLE) &&
4256 !_state_set_is_set(state_set, ATSPI_STATE_EXPANDED);
4259 static unsigned char _object_has_modal_state(accessibility_navigation_pointer_table *table, void *obj)
4261 uint64_t state_set = CALL(object_get_state_set, obj);
4262 return _state_set_is_set(state_set, ATSPI_STATE_MODAL);
4265 static unsigned char _object_is_zero_size(accessibility_navigation_pointer_table *table, void *obj)
4267 return CALL(object_is_zero_size, obj);
4270 static void *_get_scrollable_parent(accessibility_navigation_pointer_table *table, void *obj)
4274 obj = CALL(get_parent, obj);
4275 if (obj && CALL(object_is_scrollable, obj)) return obj;
4279 static unsigned char _accept_object(accessibility_navigation_pointer_table *table, void *obj)
4282 if (!_object_is_visible(table, obj)) return 0;
4283 if (!_accept_object_check_role(table, obj)) return 0;
4284 if (CALL(get_object_in_relation_by_type, obj, ATSPI_RELATION_CONTROLLED_BY) != NULL) return 0;
4285 if (!_object_is_highlightable(table, obj)) return 0;
4287 if (_get_scrollable_parent(table, obj) != NULL)
4289 void *parent = CALL(get_parent, obj);
4293 return !_object_is_item(table, obj) || !_object_is_collapsed(table, parent);
4298 if (_object_is_zero_size(table, obj)) return 0;
4299 if (!_object_is_showing(table, obj)) return 0;
4304 static void *_calculate_navigable_accessible_at_point_impl(accessibility_navigation_pointer_table *table,
4305 void *root, int x, int y, unsigned char coordinates_are_screen_based)
4307 if (!root) return NULL;
4309 void *return_value = NULL;
4312 void *target = CALL(get_object_at_point, root, x, y, coordinates_are_screen_based);
4315 // always return proxy, so atspi lib can call on it again
4316 if (CALL(object_is_proxy, target)) return target;
4319 void *relation_obj = CALL(get_object_in_relation_by_type, root, ATSPI_RELATION_CONTROLLED_BY);
4320 unsigned char contains = 0;
4323 contains = CALL(object_contains, relation_obj, x, y, coordinates_are_screen_based);
4324 if (contains) root = relation_obj;
4327 if (_accept_object(table, root))
4329 return_value = root;
4330 if (contains) break;
4334 if (return_value && _object_has_modal_state(table, return_value)) return_value = NULL;
4335 return return_value;
4338 static void *_find_non_defunct_child(accessibility_navigation_pointer_table *table,
4339 Eina_List *children, unsigned int current_index, unsigned char forward)
4341 unsigned int children_count = eina_list_count(children);
4342 for(; current_index < children_count; forward ? ++current_index : --current_index)
4344 void *n = eina_list_nth(children, current_index);
4345 if (n && !_object_is_defunct(table, n)) return n;
4350 static void *_directional_depth_first_search_try_non_defunct_child(accessibility_navigation_pointer_table *table,
4351 void *node, Eina_List *children, unsigned char forward)
4353 unsigned int children_count = eina_list_count(children);
4354 if (children_count > 0)
4356 unsigned char is_showing = _get_scrollable_parent(table, node) == NULL ? _object_is_showing(table, node) : 1;
4359 return _find_non_defunct_child(table, children, forward ? 0 : children_count - 1, forward);
4365 static Eina_List *_scrollable_parent_list_get(Eo *obj)
4367 Eina_List *ret = NULL;
4372 eo_do(obj, parent = elm_interface_atspi_accessible_parent_get());
4375 if (eo_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
4377 ret = eina_list_append(ret, parent);
4379 eo_do(parent, parent = elm_interface_atspi_accessible_parent_get());
4386 static void _viewport_geometry_get(Eo *obj, int *x, int *y, int *w, int *h)
4388 eo_do(obj, elm_interface_scrollable_content_viewport_geometry_get(x, y, w, h));
4389 /* widget implements scrollable interface but does not use scoller
4390 in this case, use widget geometry */
4391 if (*w == 0 || *h == 0)
4393 INF("%s is zero sized content viewport", eo_class_name_get(eo_class_get(obj)));
4394 eo_do(obj, elm_interface_atspi_component_extents_get(EINA_FALSE, x, y, w, h));
4399 _new_scrollable_parent_viewport_geometry_get(Eo *node, Eo *start,
4400 int *x, int *y, int *w, int *h)
4402 Eina_Bool ret = EINA_FALSE;
4406 n_spl = _scrollable_parent_list_get(node);
4407 s_spl = _scrollable_parent_list_get(start);
4411 EINA_LIST_FOREACH(s_spl, l, sp)
4413 n_spl = eina_list_remove(n_spl, sp);
4416 Evas_Coord sx = 0, sy = 0, sw = 0, sh = 0;
4418 unsigned int count = eina_list_count(n_spl);
4421 sp = eina_list_nth(n_spl, count - 1);
4422 _viewport_geometry_get(sp, &sx, &sy, &sw, &sh);
4434 static Eina_List *_valid_children_get(Eina_List *children, Eo *start, Eo *root)
4436 /* condition to find first(last) object regardless of scrollable parent.
4437 looping navigation does not care scrollable parent.
4438 1. currently highlighted object exists
4439 2. both start and root are same */
4440 Eo *current = _elm_object_accessibility_currently_highlighted_get();
4441 if (current && start == root) return children;
4444 child = eina_list_nth(children, 0);
4448 Evas_Coord x = 0, y = 0, w = 0, h = 0;
4449 Evas_Coord sx = 0, sy = 0, sw = 0, sh = 0;
4451 if (_new_scrollable_parent_viewport_geometry_get(child, start,
4452 &sx, &sy, &sw, &sh))
4454 Eina_List *l, *l_next;
4455 EINA_LIST_FOREACH_SAFE(children, l, l_next, child)
4458 elm_interface_atspi_component_extents_get(EINA_FALSE,
4460 if (w == 0 || h == 0 ||
4461 !ELM_RECTS_INTERSECT(x, y, w, h, sx, sy, sw, sh))
4462 children = eina_list_remove_list(children, l);
4469 static void *_get_next_non_defunct_sibling(accessibility_navigation_pointer_table *table,
4470 void *obj, void *start, void *root, unsigned char forward)
4472 if (!obj) return NULL;
4473 void *parent = CALL(get_parent, obj);
4474 if (!parent) return NULL;
4476 Eina_List *children;
4477 eo_do(parent, children = elm_interface_atspi_accessible_children_get());
4478 children = _valid_children_get(children, start, root);
4480 unsigned int children_count = eina_list_count(children);
4481 if (children_count == 0)
4483 eina_list_free(children);
4486 unsigned int current = 0;
4487 for(; current < children_count && eina_list_nth(children, current) != obj; ++current) ;
4488 if (current >= children_count)
4490 eina_list_free(children);
4493 forward ? ++current : --current;
4494 void *ret = _find_non_defunct_child(table, children, current, forward);
4495 eina_list_free(children);
4500 _directional_depth_first_search_try_non_defunct_sibling(accessibility_navigation_pointer_table *table,
4501 unsigned char *all_children_visited_ptr,
4502 void *node, void *start, void *root,
4503 unsigned char forward)
4507 void *sibling = _get_next_non_defunct_sibling(table, node, start, root, forward);
4508 if (sibling != NULL)
4511 *all_children_visited_ptr = 0;
4516 node = CALL(get_parent, node);
4517 if (node == NULL || node == root) return NULL;
4519 // in backward traversing stop the walk up on parent
4520 if (!forward) break;
4527 unsigned int current_search_size;
4528 unsigned int counter;
4529 } cycle_detection_data;
4531 void cycle_detection_initialize(cycle_detection_data *data, const void *key)
4535 data->current_search_size = 1;
4539 unsigned char cycle_detection_check_if_in_cycle(cycle_detection_data *data, const void *key)
4541 if (!data) return 1;
4542 if (data->key == key) return 1;
4543 if (--data->counter == 0)
4545 data->current_search_size <<= 1;
4546 if (data->current_search_size == 0) return 1;
4547 data->counter = data->current_search_size;
4556 if (eo_isa(obj, ELM_ACCESS_CLASS))
4558 Elm_Access_Info *info;
4560 info = _elm_access_info_get(obj);
4561 if (info && eo_isa(info->part_object, ELM_LAYOUT_CLASS))
4563 Eina_List *attrs, *l;
4564 Elm_Atspi_Attribute *attr;
4566 eo_do(info->part_object,
4567 attrs = elm_interface_atspi_accessible_attributes_get());
4568 EINA_LIST_FOREACH(attrs, l, attr)
4570 if (!strcmp(attr->key, "___PlugID"))
4572 elm_atspi_attributes_list_free(attrs);
4576 elm_atspi_attributes_list_free(attrs);
4583 _proxy_in_parent_get(Eo *obj)
4587 Eina_List *children_list = NULL;
4588 eo_do(obj, children_list = elm_interface_atspi_accessible_children_get());
4591 EINA_LIST_FOREACH(children_list, l, child)
4593 if (eo_isa(child, ELM_ATSPI_PROXY_CLASS))
4599 eina_list_free(children_list);
4605 _deputy_of_proxy_in_parent_get(Eo *obj)
4609 Eina_List *children_list = NULL;
4610 eo_do(obj, children_list = elm_interface_atspi_accessible_children_get());
4612 unsigned int index = 0;
4614 EINA_LIST_FOREACH(children_list, l, child)
4616 if (eo_isa(child, ELM_ATSPI_PROXY_CLASS))
4620 WRN("Proxy does not have deputy object");
4624 deputy = eina_list_nth(children_list, index - 1);
4629 eina_list_free(children_list);
4634 static void *_calculate_neighbor_impl(accessibility_navigation_pointer_table *table, void *root, void *start, unsigned char forward, GetNeighborSearchMode search_mode)
4636 if (root && _object_is_defunct(table, root)) return NULL;
4637 if (start && _object_is_defunct(table, start))
4643 if (search_mode == NEIGHBOR_SEARCH_MODE_RECURSE_TO_OUTSIDE)
4645 /* This only works if we navigate backward, and it is not possible to
4646 find in embedded process. In this case the deputy should be used */
4647 return _deputy_of_proxy_in_parent_get(start);
4650 void *node = start ? start : root;
4651 if (!node) return NULL;
4653 // initialization of all-children-visited flag for start node - we assume
4654 // that when we begin at start node and we navigate backward, then all children
4655 // are visited, so navigation will ignore start's children and go to
4656 // previous sibling available.
4657 /* Regarding condtion (start != root):
4658 The last object can be found only if all_children_visited is false.
4659 The start is same with root, when looking for the last object. */
4660 unsigned char all_children_visited = (start != root) && (search_mode != NEIGHBOR_SEARCH_MODE_RECURSE_FROM_ROOT && !forward);
4662 // true, if starting element should be ignored. this is only used in rare case of
4663 // recursive search failing to find an object.
4664 // consider tree, where element A on bus BUS_A has child B on bus BUS_B. when going "next" from
4665 // element A algorithm has to descend into BUS_B and search element B and its children. this is done
4666 // by returning to our caller object B with special flag set (meaning - continue the search from B on bus BUS_B).
4667 // if next object will be found there (on BUS_B), then search ends. but if not, then our caller will find it out
4668 // and will call us again with object A and flag search_mode set to NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING.
4669 // this flag means, that object A was already checked previously and we should skip it and its children.
4670 unsigned char force_next = (search_mode == NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING);
4672 cycle_detection_data cycle_detection;
4673 cycle_detection_initialize(&cycle_detection, node);
4676 if (_object_is_defunct(table, node)) return NULL;
4678 // always accept proxy object from different world
4679 if (!force_next && CALL(object_is_proxy, node)) return node;
4681 Eina_List *children;
4682 eo_do(node, children = elm_interface_atspi_accessible_children_get());
4683 children = _valid_children_get(children, start, root);
4686 // 1. not start node
4687 // 2. parent after all children in backward traversing
4688 // 3. Nodes with roles: ATSPI_ROLE_PAGE_TAB, ATSPI_ROLE_POPUP_MENU and ATSPI_ROLE_DIALOG, only when looking for first or last element.
4689 // Objects with those roles shouldnt be reachable, when navigating next / prev.
4690 unsigned char all_children_visited_or_moving_forward = (eina_list_count(children) == 0 || forward || all_children_visited);
4691 if (!force_next && node != start && all_children_visited_or_moving_forward && _accept_object(table, node))
4693 if (start == NULL || _object_role_is_acceptable_when_navigating_next_prev(table, node))
4695 eina_list_free(children);
4700 void *next_related_in_direction = !force_next ? _get_object_in_relation_flow(table, node, forward) : NULL;
4702 /* force_next means that the search_mode is NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING
4703 in this case the node is elm_layout which is parent of proxy object.
4704 There is an access object working for the proxy object, and the access
4705 object could have relation information. This relation information should
4706 be checked first before using the elm_layout as a node. */
4707 if (force_next && forward)
4710 deputy = _deputy_of_proxy_in_parent_get(node);
4711 next_related_in_direction =
4712 _get_object_in_relation_flow(table, deputy, forward);
4715 if (next_related_in_direction && _object_is_defunct(table, next_related_in_direction))
4716 next_related_in_direction = NULL;
4717 unsigned char want_cycle_detection = 0;
4718 if (next_related_in_direction)
4720 /* Check next_related_in_direction is deputy object */
4724 /* If the prev object is deputy, then go to inside of its proxy first */
4725 if (_deputy_is(next_related_in_direction))
4727 parent = elm_widget_parent_get(next_related_in_direction);
4728 next_related_in_direction =
4729 _proxy_in_parent_get(parent);
4734 /* If current object is deputy, and it has relation next object,
4735 then do not use the relation next object, and use proxy first */
4736 if (_deputy_is(node))
4738 parent = elm_widget_parent_get(node);
4739 next_related_in_direction =
4740 _proxy_in_parent_get(parent);
4744 node = next_related_in_direction;
4745 want_cycle_detection = 1;
4748 void *child = !force_next && !all_children_visited ?
4749 _directional_depth_first_search_try_non_defunct_child(table, node, children, forward) : NULL;
4750 if (child != NULL) want_cycle_detection = 1;
4753 if (!force_next && node == root)
4755 eina_list_free(children);
4758 all_children_visited = 1;
4759 child = _directional_depth_first_search_try_non_defunct_sibling(table, &all_children_visited, node, start, root, forward);
4765 if (want_cycle_detection && cycle_detection_check_if_in_cycle(&cycle_detection, node))
4767 eina_list_free(children);
4770 eina_list_free(children);
4775 typedef struct accessibility_navigation_pointer_table_impl {
4776 accessibility_navigation_pointer_table ptrs;
4778 } accessibility_navigation_pointer_table_impl;
4780 static AtspiRole _object_get_role_impl(struct accessibility_navigation_pointer_table *table EINA_UNUSED, void *ptr)
4782 Elm_Atspi_Role role;
4784 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
4785 return _elm_role_to_atspi_role(role);
4788 static uint64_t _object_get_state_set_impl(struct accessibility_navigation_pointer_table *table EINA_UNUSED, void *ptr)
4790 Elm_Atspi_State_Set states;
4792 eo_do(obj, states = elm_interface_atspi_accessible_state_set_get());
4793 return _elm_atspi_state_set_to_atspi_state_set(states);
4796 static void *_get_object_in_relation_by_type_impl(struct accessibility_navigation_pointer_table *table EINA_UNUSED, void *ptr, AtspiRelationType type)
4800 const Eo *source = ptr;
4801 Elm_Atspi_Relation_Set relations;
4802 Elm_Atspi_Relation_Type expected_relation_type = _atspi_relation_to_elm_relation(type);
4803 eo_do(source, relations = elm_interface_atspi_accessible_relation_set_get());
4804 Elm_Atspi_Relation *rel;
4806 EINA_LIST_FOREACH(relations, l, rel)
4808 if (rel->type == expected_relation_type)
4810 Eina_List *last = eina_list_last(rel->objects);
4811 return eina_list_data_get(last);
4818 static unsigned char _object_is_zero_size_impl(struct accessibility_navigation_pointer_table *table EINA_UNUSED, void *ptr)
4822 eo_do(obj, elm_interface_atspi_component_extents_get(EINA_TRUE, &x, &y, &w, &h));
4823 return w == 0 || h == 0;
4826 unsigned char _object_is_scrollable_impl(struct accessibility_navigation_pointer_table *table EINA_UNUSED, void *ptr)
4829 return eo_isa(obj, ELM_INTERFACE_SCROLLABLE_MIXIN);
4832 void *_get_parent_impl(struct accessibility_navigation_pointer_table *table EINA_UNUSED, void *ptr)
4834 Eo *obj = (Eo*)ptr, *ret_obj;
4835 eo_do(obj, ret_obj = elm_interface_atspi_accessible_parent_get());
4839 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)
4841 Eo *obj = (Eo*)ptr, *target;
4842 eo_do(obj, target = elm_interface_atspi_component_accessible_at_point_get(coordinates_are_screen_based, x, y));
4846 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)
4849 Eina_Bool return_value;
4850 eo_do(obj, return_value = elm_interface_atspi_component_contains(coordinates_are_screen_based, x, y));
4851 return return_value ? 1 : 0;
4854 unsigned char _object_is_proxy_impl(struct accessibility_navigation_pointer_table *table_, void *obj)
4856 accessibility_navigation_pointer_table_impl *table = (accessibility_navigation_pointer_table_impl*)table_;
4857 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(table->bridge, pd, 0);
4858 const char *our_bus_name = eldbus_connection_unique_name_get(pd->a11y_bus);
4859 const char *obj_bus_name;
4860 _object_get_bus_name_and_path(table->bridge, (Eo*)obj, &obj_bus_name, NULL);
4861 return our_bus_name && obj_bus_name && strcmp(our_bus_name, obj_bus_name) != 0;
4864 accessibility_navigation_pointer_table_impl construct_accessibility_navigation_pointer_table(Eo *bridge)
4866 accessibility_navigation_pointer_table_impl table;
4867 #define INIT(n) table.ptrs.n = _## n ## _impl
4868 INIT(object_get_role);
4869 INIT(object_get_state_set);
4870 INIT(get_object_in_relation_by_type);
4871 INIT(object_is_zero_size);
4873 INIT(object_is_scrollable);
4874 INIT(get_object_at_point);
4875 INIT(object_contains);
4876 INIT(object_is_proxy);
4878 table.bridge = bridge;
4883 static Eo *_calculate_navigable_accessible_at_point(Eo *bridge, Eo *root, Eina_Bool coord_type, int x, int y)
4885 accessibility_navigation_pointer_table_impl table = construct_accessibility_navigation_pointer_table(bridge);
4886 Eo *result = (Eo*)_calculate_navigable_accessible_at_point_impl(&table.ptrs, root, x, y, coord_type ? 1 : 0);
4890 static Eo *_calculate_neighbor(Eo *bridge, Eo *root, Eo *start, Eina_Bool forward, int search_mode)
4892 accessibility_navigation_pointer_table_impl table = construct_accessibility_navigation_pointer_table(bridge);
4893 Eo *result = (Eo*)_calculate_neighbor_impl(&table.ptrs, root, start, forward ? 1 : 0, (GetNeighborSearchMode)search_mode);
4899 static Eldbus_Message *
4900 _component_get_extents(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4902 const char *obj_path = eldbus_message_path_get(msg);
4903 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
4904 Eo *obj = _bridge_object_from_path(bridge, obj_path);
4906 AtspiCoordType coord_type;
4907 Eldbus_Message *ret;
4908 Eldbus_Message_Iter *iter, *iter_struct;
4910 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
4912 if (!eldbus_message_arguments_get(msg, "u", &coord_type))
4913 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
4915 ret = eldbus_message_method_return_new(msg);
4916 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
4918 iter = eldbus_message_iter_get(ret);
4920 Eina_Bool type = coord_type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
4921 eo_do(obj, elm_interface_atspi_component_extents_get(type, &x, &y, &w, &h));
4922 iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
4923 EINA_SAFETY_ON_NULL_GOTO(iter_struct, fail);
4925 eldbus_message_iter_basic_append(iter_struct, 'i', x);
4926 eldbus_message_iter_basic_append(iter_struct, 'i', y);
4927 eldbus_message_iter_basic_append(iter_struct, 'i', w);
4928 eldbus_message_iter_basic_append(iter_struct, 'i', h);
4930 eldbus_message_iter_container_close(iter, iter_struct);
4934 if (ret) eldbus_message_unref(ret);
4938 static Eldbus_Message *
4939 _component_get_position(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4941 const char *obj_path = eldbus_message_path_get(msg);
4942 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
4943 Eo *obj = _bridge_object_from_path(bridge, obj_path);
4945 AtspiCoordType coord_type;
4946 Eldbus_Message *ret;
4948 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
4950 if (!eldbus_message_arguments_get(msg, "u", &coord_type))
4951 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
4953 Eina_Bool type = coord_type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
4954 eo_do(obj, elm_interface_atspi_component_position_get(type, &x, &y));
4956 ret = eldbus_message_method_return_new(msg);
4957 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
4959 eldbus_message_arguments_append(ret, "i", x);
4960 eldbus_message_arguments_append(ret, "i", y);
4965 static Eldbus_Message *
4966 _component_get_size(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
4968 const char *obj_path = eldbus_message_path_get(msg);
4969 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
4970 Eo *obj = _bridge_object_from_path(bridge, obj_path);
4972 Eldbus_Message *ret;
4974 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
4976 eo_do(obj, elm_interface_atspi_component_size_get(&x, &y));
4978 ret = eldbus_message_method_return_new(msg);
4979 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
4981 eldbus_message_arguments_append(ret, "i", x);
4982 eldbus_message_arguments_append(ret, "i", y);
4987 static AtspiComponentLayer
4988 _elm_layer_2_atspi_layer(int layer)
4990 if (layer <= ELM_OBJECT_LAYER_BACKGROUND) return ATSPI_LAYER_CANVAS;
4991 if (layer < ELM_OBJECT_LAYER_FOCUS) return ATSPI_LAYER_WIDGET;
4992 if (layer <= ELM_OBJECT_LAYER_TOOLTIP) return ATSPI_LAYER_POPUP;
4994 return ATSPI_LAYER_OVERLAY;
4997 static Eldbus_Message *
4998 _component_get_layer(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5000 const char *obj_path = eldbus_message_path_get(msg);
5001 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
5002 Eo *obj = _bridge_object_from_path(bridge, obj_path);
5004 Eldbus_Message *ret;
5005 AtspiComponentLayer atspi_layer;
5007 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
5009 eo_do(obj, layer = elm_interface_atspi_component_layer_get());
5011 ret = eldbus_message_method_return_new(msg);
5012 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
5014 atspi_layer = _elm_layer_2_atspi_layer(layer);
5015 eldbus_message_arguments_append(ret, "u", atspi_layer);
5020 static Eldbus_Message *
5021 _component_grab_focus(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5023 const char *obj_path = eldbus_message_path_get(msg);
5024 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
5025 Eo *obj = _bridge_object_from_path(bridge, obj_path);
5026 Eldbus_Message *ret;
5027 Eina_Bool focus = EINA_FALSE;
5030 return _dbus_invalid_ref_error_new(msg);
5032 eo_do(obj, focus = elm_interface_atspi_component_focus_grab());
5034 ret = eldbus_message_method_return_new(msg);
5035 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
5037 eldbus_message_arguments_append(ret, "b", focus);
5042 //TIZEN_ONLY(20160329): atspi: implement HighlightGrab and HighlightClear methods (29e253e2f7ef3c632ac3a64c489bf569df407f30)
5043 static Eldbus_Message *
5044 _component_grab_highlight(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5046 const char *obj_path = eldbus_message_path_get(msg);
5047 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
5048 Eo *obj = _bridge_object_from_path(bridge, obj_path);
5049 Eldbus_Message *ret;
5050 Eina_Bool highlight = EINA_FALSE;
5052 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
5054 eo_do(obj, highlight = elm_interface_atspi_component_highlight_grab());
5056 ret = eldbus_message_method_return_new(msg);
5057 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
5059 eldbus_message_arguments_append(ret, "b", highlight);
5064 static Eldbus_Message *
5065 _component_clear_highlight(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5067 const char *obj_path = eldbus_message_path_get(msg);
5068 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
5069 Eo *obj = _bridge_object_from_path(bridge, obj_path);
5070 Eldbus_Message *ret;
5071 Eina_Bool highlight = EINA_FALSE;
5073 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
5075 eo_do(obj, highlight = elm_interface_atspi_component_highlight_clear());
5077 ret = eldbus_message_method_return_new(msg);
5078 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
5080 eldbus_message_arguments_append(ret, "b", highlight);
5086 static Eldbus_Message *
5087 _component_get_alpha(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5089 const char *obj_path = eldbus_message_path_get(msg);
5090 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
5091 Eo *obj = _bridge_object_from_path(bridge, obj_path);
5092 Eldbus_Message *ret;
5096 return _dbus_invalid_ref_error_new(msg);
5098 eo_do(obj, alpha = elm_interface_atspi_component_alpha_get());
5100 ret = eldbus_message_method_return_new(msg);
5101 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
5103 eldbus_message_arguments_append(ret, "d", alpha);
5108 static Eldbus_Message *
5109 _component_set_extends(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5111 const char *obj_path = eldbus_message_path_get(msg);
5112 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
5113 Eo *obj = _bridge_object_from_path(bridge, obj_path);
5115 AtspiCoordType coord_type;
5116 Eldbus_Message *ret;
5117 Eina_Bool result = EINA_FALSE;
5119 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
5121 if (!eldbus_message_arguments_get(msg, "iiiiu", &x, &y, &w, &h, &coord_type))
5122 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
5124 Eina_Bool type = coord_type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
5125 eo_do(obj, result = elm_interface_atspi_component_extents_set(type, x, y, w, h));
5127 ret = eldbus_message_method_return_new(msg);
5128 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
5130 eldbus_message_arguments_append(ret, "b", result);
5135 static Eldbus_Message *
5136 _component_set_position(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5138 const char *obj_path = eldbus_message_path_get(msg);
5139 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
5140 Eo *obj = _bridge_object_from_path(bridge, obj_path);
5142 Eina_Bool result = EINA_FALSE;
5143 AtspiCoordType coord_type;
5144 Eldbus_Message *ret;
5146 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
5148 if (!eldbus_message_arguments_get(msg, "iiu", &x, &y, &coord_type))
5149 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
5151 Eina_Bool type = coord_type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
5152 eo_do(obj, result = elm_interface_atspi_component_position_set(type, x, y));
5154 ret = eldbus_message_method_return_new(msg);
5155 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
5157 eldbus_message_arguments_append(ret, "b", result);
5162 static Eldbus_Message *
5163 _component_set_size(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
5165 const char *obj_path = eldbus_message_path_get(msg);
5166 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
5167 Eo *obj = _bridge_object_from_path(bridge, obj_path);
5170 Eldbus_Message *ret;
5172 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
5174 if (!eldbus_message_arguments_get(msg, "ii", &w, &h))
5175 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type.");
5177 eo_do(obj, result = elm_interface_atspi_component_size_set(w, h));
5179 ret = eldbus_message_method_return_new(msg);
5180 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
5182 eldbus_message_arguments_append(ret, "b", result);
5187 static const Eldbus_Method component_methods[] = {
5188 { "Contains", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"u", "coord_type"}), ELDBUS_ARGS({"b", "contains"}), _component_contains, 0 },
5189 { "GetAccessibleAtPoint", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"u", "coord_type"}), ELDBUS_ARGS({"(so)", "accessible"}), _component_get_accessible_at_point, 0 },
5190 { "GetExtents", ELDBUS_ARGS({"u", "coord_type"}), ELDBUS_ARGS({"(iiii)", "extents"}), _component_get_extents, 0 },
5191 { "GetPosition", ELDBUS_ARGS({"u", "coord_type"}), ELDBUS_ARGS({"i", "x"}, {"i","y"}), _component_get_position, 0 },
5192 { "GetSize", NULL, ELDBUS_ARGS({"i", "w"}, {"i", "h"}), _component_get_size, 0 },
5193 { "GetLayer", NULL, ELDBUS_ARGS({"u", "layer"}), _component_get_layer, 0 },
5194 // { "GetMDIZOrder", NULL, ELDBUS_ARGS({"n", "MDIZOrder"}), _component_get_mdizorder, 0 },
5195 { "GrabFocus", NULL, ELDBUS_ARGS({"b", "focus"}), _component_grab_focus, 0 },
5196 { "GetAlpha", NULL, ELDBUS_ARGS({"d", "alpha"}), _component_get_alpha, 0 },
5197 { "SetExtents", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"i", "width"}, {"i", "height"}, {"u", "coord_type"}), ELDBUS_ARGS({"b", "result"}), _component_set_extends, 0 },
5198 { "SetPosition", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"u", "coord_type"}), ELDBUS_ARGS({"b", "result"}), _component_set_position, 0 },
5199 { "SetSize", ELDBUS_ARGS({"i", "width"}, {"i", "height"}), ELDBUS_ARGS({"b", "result"}), _component_set_size, 0 },
5201 //TIZEN_ONLY(20160329): atspi: implement HighlightGrab and HighlightClear methods (29e253e2f7ef3c632ac3a64c489bf569df407f30)
5202 { "GrabHighlight", NULL, ELDBUS_ARGS({"b", "result"}), _component_grab_highlight, 0 },
5203 { "ClearHighlight", NULL, ELDBUS_ARGS({"b", "result"}), _component_clear_highlight, 0 },
5205 { NULL, NULL, NULL, NULL, 0 }
5208 static const Eldbus_Service_Interface_Desc component_iface_desc = {
5209 ATSPI_DBUS_INTERFACE_COMPONENT, component_methods, NULL, NULL, NULL, NULL
5213 _on_elm_atspi_bridge_app_register(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
5215 const char *errname, *errmsg;
5217 if (eldbus_message_error_get(msg, &errname, &errmsg))
5219 ERR("%s %s", errname, errmsg);
5222 DBG("Application successfuly registered at ATSPI2 bus.");
5226 _elm_atspi_bridge_app_register(Eo *bridge)
5228 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE);
5230 Eldbus_Message *message = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY,
5231 ATSPI_DBUS_PATH_ROOT,
5232 ATSPI_DBUS_INTERFACE_SOCKET,
5234 Eldbus_Message_Iter *iter = eldbus_message_iter_get(message);
5236 _bridge_iter_object_reference_append(bridge, iter, elm_atspi_bridge_root_get(bridge));
5237 eldbus_connection_send(pd->a11y_bus, message, _on_elm_atspi_bridge_app_register, NULL, -1);
5243 _elm_atspi_bridge_app_unregister(Eo *bridge)
5246 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE);
5248 root = elm_atspi_bridge_root_get(bridge);
5250 Eldbus_Message *message = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY,
5251 ATSPI_DBUS_PATH_ROOT,
5252 ATSPI_DBUS_INTERFACE_SOCKET,
5254 Eldbus_Message_Iter *iter = eldbus_message_iter_get(message);
5256 _bridge_iter_object_reference_append(bridge, iter, root);
5257 eldbus_connection_send(pd->a11y_bus, message, NULL, NULL, -1);
5263 _cache_register(Eo *obj)
5265 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(obj, pd);
5266 pd->cache_interface = eldbus_service_interface_register(pd->a11y_bus, CACHE_INTERFACE_PATH, &cache_iface_desc);
5267 eldbus_service_object_data_set(pd->cache_interface, ELM_ATSPI_BRIDGE_CLASS_NAME, obj);
5271 _set_broadcast_flag(const char *event, Eo *bridge)
5274 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
5276 tokens = eina_str_split(event, ":", 3);
5278 if (!tokens) return;
5280 if (!strcmp(tokens[0], "Object"))
5282 if (!tokens[1] || *tokens[1] == '\0') return; // do not handle "Object:*"
5283 else if (!strcmp(tokens[1], "StateChanged"))
5285 if (!tokens[2] || *tokens[2] == '\0')
5286 pd->object_state_broadcast_mask = -1; // broadcast all
5287 eina_str_tolower(&tokens[2]);
5288 struct atspi_state_desc *sd = eina_hash_find(pd->state_hash, tokens[2]);
5290 STATE_TYPE_SET(pd->object_state_broadcast_mask, sd->elm_state);
5292 else if (!strcmp(tokens[1], "PropertyChange"))
5294 if (!tokens[2] || *tokens[2] == '\0')
5295 pd->object_property_broadcast_mask = -1; //broadcast all
5296 else if (!strcmp(tokens[2], "AccessibleValue"))
5297 STATE_TYPE_SET(pd->object_property_broadcast_mask, ATSPI_OBJECT_PROPERTY_VALUE);
5298 else if (!strcmp(tokens[2], "AccessibleName"))
5299 STATE_TYPE_SET(pd->object_property_broadcast_mask, ATSPI_OBJECT_PROPERTY_NAME);
5300 else if (!strcmp(tokens[2], "AccessibleDescription"))
5301 STATE_TYPE_SET(pd->object_property_broadcast_mask, ATSPI_OBJECT_PROPERTY_DESCRIPTION);
5302 else if (!strcmp(tokens[2], "AccessibleParent"))
5303 STATE_TYPE_SET(pd->object_property_broadcast_mask, ATSPI_OBJECT_PROPERTY_PARENT);
5304 else if (!strcmp(tokens[2], "AccessibleRole"))
5305 STATE_TYPE_SET(pd->object_property_broadcast_mask, ATSPI_OBJECT_PROPERTY_ROLE);
5307 else if (!strcmp(tokens[1], "ChildrenChanged"))
5309 if (!tokens[2] || *tokens[2] == '\0')
5310 pd->object_children_broadcast_mask = -1; // broadcast all
5311 else if (!strcmp(tokens[2], "add"))
5312 STATE_TYPE_SET(pd->object_children_broadcast_mask, ATSPI_OBJECT_CHILD_ADDED);
5313 else if (!strcmp(tokens[2], "remove"))
5314 STATE_TYPE_SET(pd->object_children_broadcast_mask, ATSPI_OBJECT_CHILD_REMOVED);
5316 else if (!strcmp(tokens[1], "TextChanged"))
5317 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_CHANGED);
5318 else if (!strcmp(tokens[1], "TextCaretMoved"))
5319 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_CARET_MOVED);
5320 else if (!strcmp(tokens[1], "TextBoundsChanged"))
5321 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_BOUNDS_CHANGED);
5322 else if (!strcmp(tokens[1], "TextSelectionChanged"))
5323 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED);
5324 else if (!strcmp(tokens[1], "TextAttributesChanged"))
5325 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_ATTRIBUTES_CHANGED);
5326 else if (!strcmp(tokens[1], "VisibleDataChanged"))
5327 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED);
5328 else if (!strcmp(tokens[1], "ActiveDescendantChanged"))
5329 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED);
5330 else if (!strcmp(tokens[1], "BoundsChanged"))
5331 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_BOUNDS_CHANGED);
5332 //TIZEN_ONLY(20160623): atspi: moved highlight when object is out of screen
5333 else if (!strcmp(tokens[1], "MoveOuted"))
5334 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_MOVE_OUTED);
5337 else if (!strcmp(tokens[0], "Window"))
5339 if (!tokens[1] || *tokens[1] == '\0')
5340 pd->window_signal_broadcast_mask = -1; // broadcast all
5341 else if (!strcmp(tokens[1], "Create"))
5342 STATE_TYPE_SET(pd->window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_CREATE);
5343 else if (!strcmp(tokens[1], "Destroy"))
5344 STATE_TYPE_SET(pd->window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_DESTROY);
5345 else if (!strcmp(tokens[1], "Activate"))
5346 STATE_TYPE_SET(pd->window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_ACTIVATE);
5347 else if (!strcmp(tokens[1], "Deactivate"))
5348 STATE_TYPE_SET(pd->window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_DEACTIVATE);
5349 else if (!strcmp(tokens[1], "Maximize"))
5350 STATE_TYPE_SET(pd->window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_MAXIMIZE);
5351 else if (!strcmp(tokens[1], "Minimize"))
5352 STATE_TYPE_SET(pd->window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_MINIMIZE);
5353 else if (!strcmp(tokens[1], "Resize"))
5354 STATE_TYPE_SET(pd->window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_RESIZE);
5355 else if (!strcmp(tokens[1], "Restore"))
5356 STATE_TYPE_SET(pd->window_signal_broadcast_mask, ATSPI_WINDOW_EVENT_RESTORE);
5364 _registered_listeners_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
5366 const char *event, *bus;
5368 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd);
5369 pd->pending_requests = eina_list_remove(pd->pending_requests, pending);
5371 DBG("Updating registered ATSPI signals list.");
5372 pd->object_broadcast_mask = 0;
5373 pd->object_children_broadcast_mask = 0;
5374 pd->object_property_broadcast_mask = 0;
5375 pd->object_state_broadcast_mask = 0;
5376 pd->window_signal_broadcast_mask = 0;
5378 if (eldbus_message_error_get(msg, &event, &bus))
5380 WRN("%s %s", event, bus);
5383 Eldbus_Message_Iter *iter, *siter;
5384 if (!eldbus_message_arguments_get(msg, "a(ss)", &iter))
5386 ERR("Invalid answer type from GetRegisteredEvents method call!");
5389 while (eldbus_message_iter_get_and_next(iter, 'r', &siter))
5391 eldbus_message_iter_arguments_get(siter, "ss", &bus, &event);
5392 _set_broadcast_flag(event, data);
5397 //TIZEN_ONLY(20170910) atspi: emit signal after atspi bridge is connected
5398 pd->connected = EINA_TRUE;
5399 eo_do(data, eo_event_callback_call(ELM_ATSPI_BRIDGE_EVENT_CONNECTED, NULL));
5400 _elm_win_atspi(EINA_TRUE);
5404 eo_do(data, root = elm_obj_atspi_bridge_root_get());
5405 _bridge_cache_build(data, root);
5407 // initialize pending proxy
5408 EINA_LIST_FREE(pd->socket_queue, pr)
5409 _socket_ifc_create(pd->a11y_bus, pr);
5410 EINA_LIST_FREE(pd->plug_queue, pr)
5411 _plug_connect(pd->a11y_bus, pr);
5413 pd->socket_queue = pd->plug_queue = NULL;
5418 _registered_events_list_update(Eo *bridge)
5420 Eldbus_Message *msg;
5421 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
5424 msg = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_REGISTRY, ATSPI_DBUS_INTERFACE_REGISTRY, "GetRegisteredEvents");
5425 p = eldbus_connection_send(pd->a11y_bus, msg, _registered_listeners_get, bridge, -1);
5426 pd->pending_requests = eina_list_append(pd->pending_requests, p);
5430 _handle_listener_change(void *data, const Eldbus_Message *msg EINA_UNUSED)
5432 _registered_events_list_update(data);
5435 //TIZEN_ONLY(20170802): handle "gesture_required" attribute
5437 _scroll_gesture_required_is(Eo *obj)
5439 Eina_Bool ret = EINA_FALSE;
5440 Eina_List *l, *attr_list = NULL;
5441 Elm_Atspi_Attribute *attr = NULL;
5443 eo_do(obj, attr_list = elm_interface_atspi_accessible_attributes_get());
5444 EINA_LIST_FOREACH(attr_list, l, attr)
5446 if (!strcmp(attr->key, "gesture_required") && !strcmp(attr->value, "scroll"))
5453 elm_atspi_attributes_list_free(attr_list);
5460 _state_changed_signal_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
5462 Elm_Atspi_Event_State_Changed_Data *state_data = event_info;
5463 const char *type_desc;
5464 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
5466 // TIZEN_ONLY(20160802): do not handle events if the window is not activated
5467 if ((state_data->type == ELM_ATSPI_STATE_ACTIVE) && eo_isa(obj, ELM_WIN_CLASS))
5469 pd->window_activated = state_data->new_value;
5472 // TIZEN_ONLY(20161209): reduce IPC of object:state-changed:showing
5473 if ((state_data->type == ELM_ATSPI_STATE_SHOWING) ||
5474 (state_data->type == ELM_ATSPI_STATE_VISIBLE))
5476 Elm_Atspi_Role role = ELM_ATSPI_ROLE_INVALID;
5477 Elm_Atspi_State_Set ss;
5479 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
5480 eo_do(obj, ss = elm_interface_atspi_accessible_state_set_get());
5481 if (state_data->new_value) /* Showing */
5483 if ((role != ELM_ATSPI_ROLE_WINDOW) &&
5484 (role != ELM_ATSPI_ROLE_PAGE_TAB) &&
5485 (!STATE_TYPE_GET(ss, ELM_ATSPI_STATE_MODAL)))
5488 else /* Not Showing */
5490 if ((role != ELM_ATSPI_ROLE_WINDOW) &&
5491 (!STATE_TYPE_GET(ss, ELM_ATSPI_STATE_MODAL)) &&
5492 (_elm_object_accessibility_currently_highlighted_get() != (void *)obj))
5498 if (!STATE_TYPE_GET(pd->object_state_broadcast_mask, state_data->type))
5501 if ((state_data->type > ELM_ATSPI_STATE_LAST_DEFINED) ||
5502 (int)state_data->type < 0)
5505 type_desc = elm_states_to_atspi_state[state_data->type].name;
5507 //TIZEN_ONLY(20170802): handle "gesture_required" attribute
5508 unsigned int det2 = 0;
5509 if ((state_data->type == ELM_ATSPI_STATE_HIGHLIGHTED) &&
5510 (_scroll_gesture_required_is(obj)))
5513 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5514 &_event_obj_signals[ATSPI_OBJECT_EVENT_STATE_CHANGED], type_desc, state_data->new_value, det2, NULL);
5520 _bounds_changed_signal_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
5522 Elm_Atspi_Event_Geometry_Changed_Data *geo_data = event_info;
5524 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5525 &_event_obj_signals[ATSPI_OBJECT_EVENT_BOUNDS_CHANGED], "", 0, 0, "(iiii)",
5526 geo_data->x, geo_data->y, geo_data->width, geo_data->height);
5531 _property_changed_signal_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
5533 const char *property = event_info;
5535 enum _Atspi_Object_Property prop = ATSPI_OBJECT_PROPERTY_LAST;
5537 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
5539 if (!strcmp(property, "parent"))
5541 prop = ATSPI_OBJECT_PROPERTY_PARENT;
5542 atspi_desc = "accessible-parent";
5544 else if (!strcmp(property, "name"))
5546 prop = ATSPI_OBJECT_PROPERTY_NAME;
5547 atspi_desc = "accessible-name";
5549 else if (!strcmp(property, "description"))
5551 prop = ATSPI_OBJECT_PROPERTY_DESCRIPTION;
5552 atspi_desc = "accessible-description";
5554 else if (!strcmp(property, "role"))
5556 prop = ATSPI_OBJECT_PROPERTY_ROLE;
5557 atspi_desc = "accessible-role";
5559 else if (!strcmp(property, "value"))
5561 prop = ATSPI_OBJECT_PROPERTY_VALUE;
5562 atspi_desc = "accessible-value";
5564 if (prop == ATSPI_OBJECT_PROPERTY_LAST)
5566 ERR("Unrecognized property name!");
5569 if (!STATE_TYPE_GET(pd->object_property_broadcast_mask, prop))
5571 DBG("Masking property %s changed event.", property);
5575 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5576 &_event_obj_signals[ATSPI_OBJECT_EVENT_PROPERTY_CHANGED], atspi_desc, 0, 0, NULL, NULL);
5581 _visible_data_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
5583 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
5585 if (!STATE_TYPE_GET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED))
5588 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5589 &_event_obj_signals[ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED], "",
5596 _active_descendant_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
5598 Eo *child = event_info;
5601 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
5603 if (!STATE_TYPE_GET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED))
5606 eo_do(child, idx = elm_interface_atspi_accessible_index_in_parent_get());
5608 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5609 &_event_obj_signals[ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED], "",
5610 idx, 0, "(so)", eldbus_connection_unique_name_get(pd->a11y_bus), child);
5615 _children_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
5617 const char *atspi_desc = NULL;
5618 Elm_Atspi_Event_Children_Changed_Data *ev_data = event_info;
5620 enum _Atspi_Object_Child_Event_Type type;
5622 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
5624 type = ev_data->is_added ? ATSPI_OBJECT_CHILD_ADDED : ATSPI_OBJECT_CHILD_REMOVED;
5626 // update cached objects
5627 if (ev_data->is_added)
5628 _bridge_cache_build(data, ev_data->child);
5630 if (!STATE_TYPE_GET(pd->object_children_broadcast_mask, type))
5635 case ATSPI_OBJECT_CHILD_ADDED:
5637 eo_do(ev_data->child, idx = elm_interface_atspi_accessible_index_in_parent_get());
5639 case ATSPI_OBJECT_CHILD_REMOVED:
5640 atspi_desc = "remove";
5641 eo_do(ev_data->child, idx = elm_interface_atspi_accessible_index_in_parent_get());
5645 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5646 &_event_obj_signals[ATSPI_OBJECT_EVENT_CHILDREN_CHANGED], atspi_desc,
5647 idx, 0, "(so)", eldbus_connection_unique_name_get(pd->a11y_bus), ev_data->child);
5652 //TIZEN_ONLY(20160623): atspi: moved highlight when object is out of screen
5654 _move_outed_signal_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
5656 const Elm_Atspi_Move_Outed_Type *type = event_info;
5658 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
5660 if (!STATE_TYPE_GET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_MOVE_OUTED))
5662 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5663 &_event_obj_signals[ATSPI_OBJECT_EVENT_MOVE_OUTED], "", *type, 0, NULL, NULL);
5669 _window_activated_detail_value_add(Eo *obj)
5671 unsigned int ret = ELM_ACCESSIBLE_DEFAULT_LABEL_ENABLED;
5672 Eina_List *l, *attr_list = NULL;
5673 Elm_Atspi_Attribute *attr = NULL;
5675 eo_do(obj, attr_list = elm_interface_atspi_accessible_attributes_get());
5676 EINA_LIST_FOREACH(attr_list, l, attr)
5678 if (!strcmp(attr->key, "default_label") && !strcmp(attr->value, "disabled"))
5680 ret |= ELM_ACCESSIBLE_DEFAULT_LABEL_DISABLED;
5685 elm_atspi_attributes_list_free(attr_list);
5691 _window_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info EINA_UNUSED)
5693 enum _Atspi_Window_Signals type;
5695 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
5697 if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_CREATED)
5698 type = ATSPI_WINDOW_EVENT_CREATE;
5699 else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DESTROYED)
5700 type = ATSPI_WINDOW_EVENT_DESTROY;
5701 else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DEACTIVATED)
5702 type = ATSPI_WINDOW_EVENT_DEACTIVATE;
5703 else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_ACTIVATED)
5704 type = ATSPI_WINDOW_EVENT_ACTIVATE;
5705 else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MAXIMIZED)
5706 type = ATSPI_WINDOW_EVENT_MAXIMIZE;
5707 else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MINIMIZED)
5708 type = ATSPI_WINDOW_EVENT_MINIMIZE;
5709 else if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_RESTORED)
5710 type = ATSPI_WINDOW_EVENT_RESTORE;
5714 if (!STATE_TYPE_GET(pd->window_signal_broadcast_mask, type))
5719 ERR("A11Y connection closed. Unable to send ATSPI event.");
5723 unsigned int det1 = 0;
5724 if (desc == ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_ACTIVATED)
5725 det1 = _window_activated_detail_value_add(obj);
5727 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_WINDOW,
5728 &_window_obj_signals[type], "", det1, 0, "i", 0);
5733 _selection_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
5735 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE);
5737 if (!STATE_TYPE_GET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_SELECTION_CHANGED))
5740 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5741 &_event_obj_signals[ATSPI_OBJECT_EVENT_SELECTION_CHANGED], "", 0, 0, "i", 0);
5745 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, ...)
5747 Eldbus_Message *msg;
5748 Eldbus_Message_Iter *iter , *iter_stack[64], *iter_struct;
5754 EINA_SAFETY_ON_NULL_RETURN(infc);
5755 EINA_SAFETY_ON_NULL_RETURN(signal);
5756 EINA_SAFETY_ON_NULL_RETURN(minor);
5757 EINA_SAFETY_ON_NULL_RETURN(obj);
5758 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
5760 path = _bridge_path_from_object(bridge, obj);
5762 msg = eldbus_message_signal_new(path, infc, signal->name);
5765 va_start(va, variant_sig);
5767 iter = eldbus_message_iter_get(msg);
5768 eldbus_message_iter_arguments_append(iter, "sii", minor, det1, det2);
5772 iter_stack[top] = eldbus_message_iter_container_new(iter, 'v', variant_sig);
5774 const char *tmp = variant_sig;
5780 iter_stack[top + 1] = eldbus_message_iter_container_new(iter_stack[top], 'r', NULL);
5784 eldbus_message_iter_basic_append(iter_stack[top], 's', va_arg(va, char*));
5787 eldbus_message_iter_basic_append(iter_stack[top], 'i', va_arg(va, int));
5790 atspi_obj = va_arg(va, Eo*);
5791 path = _bridge_path_from_object(bridge, atspi_obj);
5792 eldbus_message_iter_basic_append(iter_stack[top], 'o', path);
5795 eldbus_message_iter_container_close(iter_stack[top - 1], iter_stack[top]);
5799 ERR("Not supported d-bus type: %c.", *tmp);
5805 else // AT-SPI implementation forces checks on variant in signature even if not used.
5807 iter_stack[top] = eldbus_message_iter_container_new(iter, 'v', "i");
5808 eldbus_message_iter_basic_append(iter_stack[top], 'i', 0);
5813 ERR("Invalid d-bus signature: () do not match.");
5815 eldbus_message_iter_container_close(iter, iter_stack[0]);
5817 iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
5818 path = _bridge_path_from_object(bridge, elm_atspi_bridge_root_get(bridge));
5819 eldbus_message_iter_basic_append(iter_struct, 's', eldbus_connection_unique_name_get(pd->a11y_bus));
5820 eldbus_message_iter_basic_append(iter_struct, 'o', path);
5821 eldbus_message_iter_container_close(iter, iter_struct);
5823 eldbus_connection_send(pd->a11y_bus, msg, NULL, NULL, -1);
5824 DBG("Send %s.%s[%s,%d,%d]", infc, signal->name, minor, det1, det2);
5828 _text_caret_moved_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
5832 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
5834 if (!STATE_TYPE_GET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_CARET_MOVED))
5837 eo_do(obj, cursor_pos = elm_interface_atspi_text_caret_offset_get());
5839 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5840 &_event_obj_signals[ATSPI_OBJECT_EVENT_TEXT_CARET_MOVED], "", cursor_pos, 0, NULL, NULL);
5846 _text_text_inserted_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
5848 Elm_Atspi_Text_Change_Info *info = event_info;
5850 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE);
5852 if (!STATE_TYPE_GET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_CHANGED))
5855 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5856 &_event_obj_signals[ATSPI_OBJECT_EVENT_TEXT_CHANGED], "insert", info->pos, info->len, "s", info->content);
5862 _text_text_removed_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
5864 Elm_Atspi_Text_Change_Info *info = event_info;
5866 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE);
5868 if (!STATE_TYPE_GET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_CHANGED))
5871 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5872 &_event_obj_signals[ATSPI_OBJECT_EVENT_TEXT_CHANGED], "delete", info->pos, info->len, "s", info->content);
5878 _text_selection_changed_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
5880 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE);
5882 if (!STATE_TYPE_GET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED))
5885 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
5886 &_event_obj_signals[ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED], "", 0, 0, NULL, NULL);
5891 //TIZEN_ONLY(20160527) - Add direct reading feature
5893 _on_reading_state_changed(void *data EINA_UNUSED, const Eldbus_Message *msg)
5896 const char *say_signal_name = "";
5897 Elm_Atspi_Say_Info *say_info;
5899 if (eldbus_message_arguments_get(msg, "is", &i, &say_signal_name))
5900 { if (read_command_id)
5902 say_info = eina_hash_find(read_command_id, &i);
5905 if (say_info->func && say_signal_name)
5906 say_info->func(say_info->data, say_signal_name);
5907 eina_hash_del(read_command_id, &i, NULL);
5916 _event_handlers_register(Eo *bridge)
5918 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
5920 _registered_events_list_update(bridge);
5922 // register signal handlers in order to update list of registered listeners of ATSPI-Clients
5923 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);
5924 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);
5925 //TIZEN_ONLY(20160527) - Add direct reading feature
5926 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);
5928 pd->key_flr = ecore_event_filter_add(NULL, _elm_atspi_bridge_key_filter, NULL, bridge);
5932 _bridge_object_unregister(Eo *bridge, Eo *obj)
5934 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
5936 eina_hash_del(pd->cache, &obj, obj);
5940 _on_object_add(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED)
5942 Eldbus_Message *sig;
5943 Eldbus_Message_Iter *iter;
5945 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE);
5947 sig = eldbus_service_signal_new(pd->cache_interface, ATSPI_OBJECT_CHILD_ADDED);
5948 iter = eldbus_message_iter_get(sig);
5949 _cache_item_reference_append_cb(data, obj, iter);
5951 eldbus_service_signal_send(pd->cache_interface, sig);
5957 _on_object_del(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED)
5959 Eldbus_Message *sig;
5961 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE);
5963 _bridge_object_unregister(data, obj);
5965 sig = eldbus_service_signal_new(pd->cache_interface, ATSPI_OBJECT_CHILD_REMOVED);
5966 Eldbus_Message_Iter *iter = eldbus_message_iter_get(sig);
5967 _bridge_iter_object_reference_append(data, iter, obj);
5968 eldbus_service_signal_send(pd->cache_interface, sig);
5974 _bridge_cache_build(Eo *bridge, void *obj)
5976 Eina_List *children;
5977 Elm_Atspi_State_Set ss;
5980 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
5982 if (!eo_isa(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
5985 if (!eo_isa(obj, ELM_ATSPI_PROXY_CLASS))
5986 _bridge_object_register(bridge, obj);
5988 eo_do(obj, ss = elm_interface_atspi_accessible_state_set_get());
5989 if (STATE_TYPE_GET(ss, ELM_ATSPI_STATE_MANAGES_DESCENDANTS))
5991 if (eo_isa(obj, ELM_INTERFACE_ATSPI_WINDOW_INTERFACE))
5993 if (STATE_TYPE_GET(ss, ELM_ATSPI_STATE_ACTIVE))
5995 // TIZEN_ONLY(20160802): do not handle events if the window is not activated
5996 pd->window_activated = EINA_TRUE;
6001 // TIZEN_ONLY(20160802): do not handle events if the window is not activated
6002 pd->window_activated = EINA_FALSE;
6006 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
6007 EINA_LIST_FREE(children, child)
6008 _bridge_cache_build(bridge, child);
6012 _interfaces_unregister(Eo *bridge)
6014 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6016 #define INTERFACE_SAFE_FREE(ifc) \
6018 eldbus_service_interface_unregister(ifc); \
6021 INTERFACE_SAFE_FREE(pd->interfaces.accessible);
6022 INTERFACE_SAFE_FREE(pd->interfaces.application);
6023 INTERFACE_SAFE_FREE(pd->interfaces.action);
6024 INTERFACE_SAFE_FREE(pd->interfaces.component);
6025 INTERFACE_SAFE_FREE(pd->interfaces.collection);
6026 INTERFACE_SAFE_FREE(pd->interfaces.editable_text);
6027 INTERFACE_SAFE_FREE(pd->interfaces.image);
6028 INTERFACE_SAFE_FREE(pd->interfaces.selection);
6029 INTERFACE_SAFE_FREE(pd->interfaces.text);
6030 INTERFACE_SAFE_FREE(pd->interfaces.value);
6034 _a11y_connection_shutdown(Eo *bridge)
6036 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6037 Eldbus_Pending *pending;
6040 _elm_atspi_bridge_app_unregister(bridge);
6043 eina_hash_free(pd->cache);
6046 if (pd->cache_interface)
6047 eldbus_service_object_unregister(pd->cache_interface);
6048 pd->cache_interface = NULL;
6050 _interfaces_unregister(bridge);
6052 if (pd->key_flr) ecore_event_filter_del(pd->key_flr);
6055 if (pd->register_hdl) eldbus_signal_handler_del(pd->register_hdl);
6056 pd->register_hdl = NULL;
6058 if (pd->unregister_hdl) eldbus_signal_handler_del(pd->unregister_hdl);
6059 pd->unregister_hdl = NULL;
6061 //TIZEN_ONLY(20160527) - Add direct reading feature
6062 if (pd->reading_state_changed_hdl) eldbus_signal_handler_del(pd->reading_state_changed_hdl);
6063 pd->reading_state_changed_hdl = NULL;
6066 EINA_LIST_FREE(pd->pending_requests, pending)
6067 eldbus_pending_cancel(pending);
6068 pd->pending_requests = NULL;
6070 if (pd->a11y_bus) eldbus_connection_unref(pd->a11y_bus);
6071 pd->a11y_bus = NULL;
6073 if (pd->state_hash) eina_hash_free(pd->state_hash);
6074 pd->state_hash = NULL;
6076 if (pd->event_hash) eina_hash_free(pd->event_hash);
6077 pd->event_hash = NULL;
6079 eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_handler_del(pd->event_hdlr));
6080 pd->event_hdlr = NULL;
6082 eo_do(bridge, eo_event_callback_call(ELM_ATSPI_BRIDGE_EVENT_DISCONNECTED, NULL));
6083 pd->connected = EINA_FALSE;
6086 static void _disconnect_cb(void *data, Eldbus_Connection *conn EINA_UNUSED, void *event_info EINA_UNUSED)
6088 _a11y_connection_shutdown(data);
6092 _interfaces_register(Eo *bridge)
6094 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6096 pd->interfaces.accessible =
6097 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &accessible_iface_desc);
6098 eldbus_service_object_data_set(pd->interfaces.accessible, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6100 pd->interfaces.application =
6101 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &application_iface_desc);
6102 eldbus_service_object_data_set(pd->interfaces.application, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6104 pd->interfaces.action =
6105 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &action_iface_desc);
6106 eldbus_service_object_data_set(pd->interfaces.action, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6108 pd->interfaces.component =
6109 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &component_iface_desc);
6110 eldbus_service_object_data_set(pd->interfaces.component, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6112 pd->interfaces.collection =
6113 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &collection_iface_desc);
6114 eldbus_service_object_data_set(pd->interfaces.collection, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6116 pd->interfaces.editable_text =
6117 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &editable_text_iface_desc);
6118 eldbus_service_object_data_set(pd->interfaces.editable_text, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6120 pd->interfaces.image =
6121 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &image_iface_desc);
6122 eldbus_service_object_data_set(pd->interfaces.image, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6124 pd->interfaces.selection =
6125 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &selection_iface_desc);
6126 eldbus_service_object_data_set(pd->interfaces.selection, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6128 pd->interfaces.text =
6129 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &text_iface_desc);
6130 eldbus_service_object_data_set(pd->interfaces.text, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6132 pd->interfaces.value =
6133 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &value_iface_desc);
6134 eldbus_service_object_data_set(pd->interfaces.value, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
6138 _bridge_accessible_event_dispatch(void *data, Eo *accessible, const Eo_Event_Description *desc, void *event_info)
6140 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE);
6142 _bridge_object_register(data, accessible);
6144 Eo_Event_Cb cb = eina_hash_find(pd->event_hash, &desc);
6145 return cb ? cb(data, accessible, desc, event_info) : EINA_TRUE;
6149 _a11y_bus_initialize(Eo *obj, const char *socket_addr)
6151 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(obj, pd);
6152 pd->a11y_bus = eldbus_private_address_connection_get(socket_addr);
6156 eldbus_connection_event_callback_add(pd->a11y_bus, ELDBUS_CONNECTION_EVENT_DISCONNECTED, _disconnect_cb, obj);
6158 // init data structures
6159 pd->cache = eina_hash_pointer_new(NULL);
6160 pd->state_hash = _elm_atspi_state_hash_build();
6161 pd->event_hash = _elm_atspi_event_hash_build();
6164 _cache_register(obj);
6165 _interfaces_register(obj);
6166 _event_handlers_register(obj);
6167 if (!getenv("ELM_ATSPI_NO_EMBED"))
6168 _elm_atspi_bridge_app_register(obj);
6170 // register accesible object event listener
6171 eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, pd->event_hdlr = elm_interface_atspi_accessible_event_handler_add(_bridge_accessible_event_dispatch, obj));
6176 _a11y_bus_address_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
6178 const char *errname, *errmsg, *sock_addr = NULL;
6179 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd);
6181 pd->pending_requests = eina_list_remove(pd->pending_requests, pending);
6183 if (eldbus_message_error_get(msg, &errname, &errmsg))
6185 ERR("%s %s", errname, errmsg);
6189 if (!eldbus_message_arguments_get(msg, "s", &sock_addr) || !sock_addr)
6191 ERR("Could not get A11Y Bus socket address.");
6195 _a11y_socket_address = eina_stringshare_add(sock_addr);
6196 _a11y_bus_initialize((Eo*)data, sock_addr);
6199 static void _a11y_connection_init(Eo *bridge)
6201 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6202 Eina_Bool is_connected;
6204 eo_do(bridge, is_connected = elm_obj_atspi_bridge_connected_get());
6206 if (is_connected) return;
6208 // TIZEN_ONLY(20170512): send window activated event to at_spi2 only once per session
6209 pd->window_activated_broadcast_needed = EINA_TRUE;
6211 Eldbus_Message *m = eldbus_object_method_call_new(pd->bus_obj, A11Y_DBUS_INTERFACE, "GetAddress");
6212 Eldbus_Pending *p = eldbus_object_send(pd->bus_obj, m, _a11y_bus_address_get, bridge, 100);
6215 pd->pending_requests = eina_list_append(pd->pending_requests, p);
6219 _screen_reader_enabled_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
6221 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd);
6222 const char *errname, *errmsg;
6223 Eina_Bool is_enabled;
6224 Eldbus_Message_Iter *variant;
6226 pd->pending_requests = eina_list_remove(pd->pending_requests, pending);
6228 if (eldbus_message_error_get(msg, &errname, &errmsg))
6230 WRN("%s %s", errname, errmsg);
6233 if (!eldbus_message_arguments_get(msg, "v", &variant))
6235 ERR("'ScreenReaderEnabled' not packed into variant.");
6238 if (!eldbus_message_iter_arguments_get(variant, "b", &is_enabled))
6240 ERR("Could not get 'ScreenReaderEnabled' boolean property");
6243 //TIZEN_ONLY(20161027) - Export elm_atspi_bridge_utils_is_screen_reader_enabled
6244 pd->screen_reader_enabled = !!is_enabled;
6246 //TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
6247 //register/unregister access objects accordingly.
6248 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6249 _elm_win_screen_reader(is_enabled);
6254 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6256 _at_spi_client_enabled_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
6258 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd);
6259 const char *errname, *errmsg;
6260 Eina_Bool is_enabled;
6261 Eldbus_Message_Iter *variant;
6263 pd->pending_requests = eina_list_remove(pd->pending_requests, pending);
6265 if (eldbus_message_error_get(msg, &errname, &errmsg))
6267 WRN("%s %s", errname, errmsg);
6270 if (!eldbus_message_arguments_get(msg, "v", &variant))
6272 ERR("'" A11Y_DBUS_ENABLED_PROPERTY "' not packed into variant.");
6275 if (!eldbus_message_iter_arguments_get(variant, "b", &is_enabled))
6277 ERR("Could not get '" A11Y_DBUS_ENABLED_PROPERTY "' boolean property");
6281 _a11y_connection_init(data);
6284 _elm_win_atspi(EINA_FALSE);
6285 DBG("AT-SPI2 stack not enabled.");
6291 static void _bridge_object_register(Eo *bridge, Eo *obj)
6293 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6295 if (!eo_isa(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
6297 WRN("Unable to register class w/o Elm_Interface_Atspi_Accessible!");
6301 if (eina_hash_find(pd->cache, &obj))
6304 eina_hash_add(pd->cache, &obj, obj);
6308 _elm_atspi_bridge_init(void)
6312 _instance = eo_add(ELM_ATSPI_BRIDGE_CLASS, NULL);
6318 _elm_atspi_bridge_get(void)
6324 _elm_atspi_bridge_shutdown(void)
6331 if (_a11y_socket_address)
6332 eina_stringshare_del(_a11y_socket_address);
6333 _a11y_socket_address = NULL;
6336 static Key_Event_Info*
6337 _key_event_info_new(int event_type, const Ecore_Event_Key *data, Eo *bridge)
6339 Key_Event_Info *ret;
6340 EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL);
6342 ret = calloc(sizeof(Key_Event_Info), 1);
6344 ret->type = event_type;
6346 ret->bridge = bridge;
6348 ret->event.keyname = eina_stringshare_add(data->keyname);
6349 ret->event.key = eina_stringshare_add(data->key);
6350 ret->event.string = eina_stringshare_add(data->string);
6351 ret->event.compose = eina_stringshare_add(data->compose);
6353 // not sure why it is here, but explicite keep it NULLed.
6354 ret->event.data = NULL;
6360 _key_event_info_free(Key_Event_Info *data)
6362 EINA_SAFETY_ON_NULL_RETURN(data);
6364 eina_stringshare_del(data->event.keyname);
6365 eina_stringshare_del(data->event.key);
6366 eina_stringshare_del(data->event.string);
6367 eina_stringshare_del(data->event.compose);
6373 _iter_marshall_key_event(Eldbus_Message_Iter *iter, Key_Event_Info *data)
6375 Eldbus_Message_Iter *struct_iter;
6376 EINA_SAFETY_ON_NULL_RETURN(data);
6378 struct_iter = eldbus_message_iter_container_new(iter, 'r', NULL);
6380 const char *str = data->event.keyname ? data->event.keyname : "";
6381 int is_text = data->event.keyname ? 1 : 0;
6383 if (data->type == ECORE_EVENT_KEY_DOWN)
6384 type = ATSPI_KEY_PRESSED_EVENT;
6386 type = ATSPI_KEY_RELEASED_EVENT;
6388 eldbus_message_iter_arguments_append(struct_iter, "uiiiisb", type, 0, data->event.keycode, 0, data->event.timestamp, str, is_text);
6389 eldbus_message_iter_container_close(iter, struct_iter);
6393 _on_event_del(void *user_data, void *func_data EINA_UNUSED)
6395 Key_Event_Info *info = user_data;
6396 _key_event_info_free(info);
6400 _on_listener_answer(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
6402 Key_Event_Info *info = data;
6403 const char *errname, *errmsg;
6404 Eina_Bool ret = EINA_TRUE;
6406 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(info->bridge, pd);
6408 if (eldbus_message_error_get(msg, &errname, &errmsg))
6410 ERR("%s %s", errname, errmsg);
6413 if (!eldbus_message_arguments_get(msg, "b", &ret))
6415 ERR("Return message doen not contian return value");
6420 _key_event_info_free(info);
6424 ecore_event_add(info->type, &info->event, _on_event_del, info);
6425 pd->reemited_events = eina_list_append(pd->reemited_events, &info->event);
6429 _elm_atspi_bridge_key_filter(void *data, void *loop EINA_UNUSED, int type, void *event)
6431 Eldbus_Message *msg;
6432 Eldbus_Message_Iter *iter;
6433 Ecore_Event_Key *key_event = event;
6437 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_TRUE);
6439 // TIZEN_ONLY(20160802): do not handle events if the window is not activated
6440 if (!pd->window_activated) return EINA_TRUE;
6443 if ((type != ECORE_EVENT_KEY_DOWN) && (type != ECORE_EVENT_KEY_UP)) return EINA_TRUE;
6445 // check if reemited
6446 if (eina_list_data_find(pd->reemited_events, event))
6448 pd->reemited_events = eina_list_remove(pd->reemited_events, event);
6452 // TIZEN_ONLY(20170118): Not handle events if keyboard is on
6455 Eina_List *children, *l;
6457 eo_do(pd->root, children = elm_interface_atspi_accessible_children_get());
6459 EINA_LIST_FOREACH(children, l, child)
6461 if (elm_widget_focus_get(child)) break;
6463 eina_list_free(children);
6465 Elm_Win_Keyboard_Mode mode;
6466 mode = elm_win_keyboard_mode_get(child);
6467 if (mode == ELM_WIN_KEYBOARD_ON) return EINA_TRUE;
6471 ke = _key_event_info_new(type, key_event, bridge);
6472 if (!ke) return EINA_TRUE;
6474 msg = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_DEC,
6475 ATSPI_DBUS_INTERFACE_DEC, "NotifyListenersSync");
6476 iter = eldbus_message_iter_get(msg);
6477 _iter_marshall_key_event(iter, ke);
6479 // timeout should be kept reasonaby low to avoid delays
6480 if (!eldbus_connection_send(pd->a11y_bus, msg, _on_listener_answer, ke, 100))
6487 _elm_atspi_bridge_connected_get(Eo *obj EINA_UNUSED, Elm_Atspi_Bridge_Data *pd)
6489 return pd->connected;
6493 _elm_atspi_bridge_root_get(Eo *obj EINA_UNUSED, Elm_Atspi_Bridge_Data *pd)
6497 pd->root = eo_add(ELM_ATSPI_APP_OBJECT_CLASS, NULL);
6498 elm_interface_atspi_accessible_added(pd->root);
6505 _properties_changed_cb(void *data, Eldbus_Proxy *proxy EINA_UNUSED, void *event)
6507 Eldbus_Proxy_Event_Property_Changed *ev = event;
6510 const char *ifc = eldbus_proxy_interface_get(ev->proxy);
6511 if (ev->name && !strcmp(ev->name, "ScreenReaderEnabled" ) &&
6512 ifc && !strcmp(A11Y_DBUS_STATUS_INTERFACE, ifc))
6514 if (!eina_value_get(ev->value, &val))
6516 ERR("Unable to get ScreenReaderEnabled property value");
6519 //TIZEN_ONLY(20161027) - Export elm_atspi_bridge_utils_is_screen_reader_enabled
6520 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6521 pd->screen_reader_enabled = !!val;
6523 //TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
6524 //register/unregister access objects accordingly.
6525 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6526 _elm_win_screen_reader(val);
6530 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6531 if (ev->name && !strcmp(ev->name, A11Y_DBUS_ENABLED_PROPERTY) &&
6532 ifc && !strcmp(A11Y_DBUS_STATUS_INTERFACE, ifc))
6534 if (!eina_value_get(ev->value, &val))
6536 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6537 ERR("Unable to get " A11Y_DBUS_ENABLED_PROPERTY " property value");
6543 _a11y_connection_init(bridge);
6546 _elm_win_atspi(EINA_FALSE);
6547 _a11y_connection_shutdown(bridge);
6554 _elm_atspi_bridge_eo_base_constructor(Eo *obj, Elm_Atspi_Bridge_Data *pd)
6556 Eldbus_Proxy *proxy;
6557 Eldbus_Pending *req;
6559 eo_do_super(obj, ELM_ATSPI_BRIDGE_CLASS, eo_constructor());
6563 if (!(pd->session_bus = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION)))
6565 ERR("Unable to connect to Session Bus");
6568 if (!(pd->bus_obj = eldbus_object_get(pd->session_bus, A11Y_DBUS_NAME, A11Y_DBUS_PATH)))
6570 ERR("Could not get /org/a11y/bus object");
6573 if (!(proxy = eldbus_proxy_get(pd->bus_obj, A11Y_DBUS_STATUS_INTERFACE)))
6575 ERR("Could not get proxy object for %s interface", A11Y_DBUS_STATUS_INTERFACE);
6578 if (!(req = eldbus_proxy_property_get(proxy, "ScreenReaderEnabled", _screen_reader_enabled_get, obj)))
6580 ERR("Could not send PropertyGet request");
6583 pd->pending_requests = eina_list_append(pd->pending_requests, req);
6585 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
6586 if (!(req = eldbus_proxy_property_get(proxy, A11Y_DBUS_ENABLED_PROPERTY, _at_spi_client_enabled_get, obj)))
6588 ERR("Could not send PropertyGet request");
6592 pd->pending_requests = eina_list_append(pd->pending_requests, req);
6595 eldbus_proxy_properties_monitor(proxy, EINA_TRUE);
6596 eldbus_proxy_event_callback_add(proxy, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
6597 _properties_changed_cb, obj);
6602 eldbus_object_unref(pd->bus_obj);
6605 eldbus_connection_unref(pd->session_bus);
6606 pd->session_bus = NULL;
6611 _elm_atspi_bridge_eo_base_destructor(Eo *obj, Elm_Atspi_Bridge_Data *pd)
6613 _a11y_connection_shutdown(obj);
6615 if (pd->bus_obj) eldbus_object_unref(pd->bus_obj);
6616 if (pd->session_bus) eldbus_connection_unref(pd->session_bus);
6617 if (pd->root) eo_del(pd->root);
6619 eo_do_super(obj, ELM_ATSPI_BRIDGE_CLASS, eo_destructor());
6623 elm_atspi_bridge_object_address_get(Eo *obj, char **bus, char **path)
6625 Eo *bridge = _elm_atspi_bridge_get();
6628 ERR("Connection with accessibility bus not established.");
6631 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE);
6632 if (!eo_isa(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
6634 ERR("Connection with accessibility bus not established.");
6637 if (bus) *bus = strdup(eldbus_connection_unique_name_get(pd->a11y_bus));
6638 if (path) *path = strdup(_bridge_path_from_object(bridge, obj));
6644 _proxy_property_get(const Eldbus_Service_Interface *interface, const char *property,
6645 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg EINA_UNUSED,
6646 Eldbus_Message **error EINA_UNUSED)
6649 Eo *obj = eldbus_service_object_data_get(interface, "_atspi_obj");
6650 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
6652 if (!strcmp(property, "Object"))
6655 eo_do(obj, parent = eo_parent_get());
6656 if (!elm_atspi_bridge_object_address_get(parent, &bus, &path))
6659 Eldbus_Message_Iter *iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
6662 eldbus_message_iter_basic_append(iter_struct, 's', bus);
6663 eldbus_message_iter_basic_append(iter_struct, 'o', path);
6664 eldbus_message_iter_container_close(iter, iter_struct);
6673 static const Eldbus_Property proxy_properties[] = {
6674 { "Object", "(so)", _proxy_property_get, NULL, 0 },
6675 { NULL, NULL, NULL, NULL, 0 }
6678 static const Eldbus_Service_Interface_Desc _proxy_iface_desc = {
6679 ELM_ATSPI_DBUS_INTERFACE_PROXY, socket_methods, NULL, proxy_properties, NULL, NULL
6682 static void _embedded_reply_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
6684 Eo *parent, *proxy = data;
6685 const char *err, *txt;
6687 if (eldbus_message_error_get(msg, &err, &txt))
6689 ERR("AT-SPI: Embedded method call failed: %s %s", err, txt);
6690 eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_DISCONNECTED, NULL));
6693 eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_CONNECTED, NULL));
6695 eo_do(proxy, parent = eo_parent_get());
6697 elm_interface_atspi_accessible_children_changed_added_signal_emit(parent, proxy)
6701 _plug_embedded_send(Eldbus_Connection *conn, Eo *proxy, const char *bus, const char *path)
6703 char *obj_path = NULL;
6705 Eldbus_Message *msg = NULL;
6707 eo_do(proxy, parent = eo_parent_get());
6708 if (!parent) goto fail;
6710 msg = eldbus_message_method_call_new(bus, path, ATSPI_DBUS_INTERFACE_SOCKET, "Embedded");
6711 if (!msg) goto fail;
6713 if (!elm_atspi_bridge_object_address_get(parent, NULL, &obj_path))
6716 if (!eldbus_message_arguments_append(msg, "s", obj_path))
6719 if (!eldbus_connection_send(conn, msg, _embedded_reply_cb, proxy, 100))
6722 ELM_SAFE_FREE(obj_path, free);
6726 ERR("AT-SPI: Unable to send Embedded request.");
6727 if (msg) eldbus_message_unref(msg);
6728 ELM_SAFE_FREE(obj_path, free);
6729 eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_DISCONNECTED, NULL));
6732 static void _socket_addr_get_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
6735 const char *bus, *path, *err, *txt;
6736 Eldbus_Message_Iter *iter, *iter_variant, *iter_struct;
6738 Eo *bridge = _elm_atspi_bridge_get();
6741 ERR("AT-SPI: Atspi bridge is not enabled.");
6744 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6746 if (eldbus_message_error_get(msg, &err, &txt))
6748 ERR("Unable to connect to socket: %s %s", err, txt);
6752 iter = eldbus_message_iter_get(msg);
6753 if (!eldbus_message_iter_arguments_get(iter, "v", &iter_variant))
6755 ERR("Unable to get variant parameter");
6759 if (!eldbus_message_iter_arguments_get(iter_variant, "(so)", &iter_struct))
6761 ERR("Unable to get so parameters");
6765 if (!eldbus_message_iter_arguments_get(iter_struct, "so", &bus, &path))
6767 ERR("Unable to get so parameters");
6771 eo_do(proxy, elm_obj_atspi_proxy_address_set(bus, path));
6773 _plug_embedded_send(pd->a11y_bus, proxy, bus, path);
6778 eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_DISCONNECTED, NULL));
6782 eo_do(proxy, elm_obj_atspi_proxy_address_get_retry_timer_add());
6786 _plug_address_discover(Eldbus_Connection *conn, Eo *proxy, const char *svc_bus, const char *svc_path)
6788 Eldbus_Object *dobj;
6789 dobj = eldbus_object_get(conn, svc_bus, svc_path);
6792 ERR("Unable to get eldbus object from: %s %s", svc_bus, svc_path);
6796 Eldbus_Message *msg = eldbus_object_method_call_new(dobj, ELDBUS_FDO_INTERFACE_PROPERTIES, "Get");
6797 eldbus_message_arguments_append(msg, "ss", ELM_ATSPI_DBUS_INTERFACE_PROXY, "Object");
6798 eldbus_object_send(dobj, msg, _socket_addr_get_cb, proxy, 100);
6801 static void _plug_connect(Eldbus_Connection *conn, Eo *proxy)
6803 const char *bus, *path;
6805 eo_do(proxy, bus = eo_key_data_get("__svc_bus"));
6806 eo_do(proxy, path = eo_key_data_get("__svc_path"));
6810 _plug_address_discover(conn, proxy, bus, path);
6815 eo_do(proxy, elm_obj_atspi_proxy_address_get(&bus, &path));
6818 ERR("AT-SPI: Elm_Atspi_Proxy bus or path not set. Unable to connect");
6819 eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_DISCONNECTED, NULL));
6822 _plug_embedded_send(conn, proxy, bus, path);
6827 static Eina_Bool _from_list_remove(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
6829 Eina_List **list = data;
6830 *list = eina_list_remove(*list, obj);
6834 EAPI void elm_atspi_bridge_utils_proxy_connect(Eo *proxy)
6836 Eo *bridge = _elm_atspi_bridge_get();
6840 ERR("AT-SPI: Atspi bridge is not enabled.");
6841 eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_DISCONNECTED, NULL));
6844 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6848 if (!eina_list_data_find(pd->plug_queue, proxy))
6850 pd->plug_queue = eina_list_append(pd->plug_queue, proxy);
6851 eo_do(proxy, eo_event_callback_add(EO_EV_DEL, _from_list_remove, &pd->plug_queue));
6855 _plug_connect(pd->a11y_bus, proxy);
6859 * @brief Service name sanitizer according to specs:
6860 * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names
6861 * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-object-path
6863 char *_sanitize_service_name(const char *name)
6865 char ret[256] = "\0";
6867 if (!name) return NULL;
6869 const char *tmp = name;
6872 // name element should not begin with digit. Swallow non-charater prefix
6873 while ((*tmp != '\0') && !isalpha(*tmp)) tmp++;
6875 // append rest of character valid charactes [A-Z][a-z][0-9]_
6876 while ((*tmp != '\0') && (dst < &ret[sizeof(ret) - 1]))
6878 if (isalpha(*tmp) || isdigit(*tmp) || (*tmp == '_'))
6887 Eo* _elm_atspi_bridge_utils_proxy_create(Eo *parent, const char *svcname, int svcnum, Elm_Atspi_Proxy_Type type)
6890 char bus[256], path[256], *name;
6893 name = _sanitize_service_name(svcname);
6894 if (!name) return NULL;
6896 res = snprintf(bus, sizeof(bus), "elm.atspi.proxy.socket.%s-%d", name, svcnum);
6897 if (res < 0 || (res >= (int)sizeof(bus)))
6903 res = snprintf(path, sizeof(path), "/elm/atspi/proxy/socket/%s/%d", name, svcnum);
6904 if (res < 0 || (res >= (int)sizeof(path)))
6912 ret = eo_add(ELM_ATSPI_PROXY_CLASS, parent, elm_obj_atspi_proxy_constructor(type));
6913 if (!ret) return NULL;
6915 eo_do(ret, eo_key_data_set("__svc_bus", eina_stringshare_add(bus)));
6916 eo_do(ret, eo_key_data_set("__svc_path", eina_stringshare_add(path)));
6922 _on_socket_del(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED)
6924 Eldbus_Service_Interface *ifc = data;
6926 Eldbus_Connection *conn = eldbus_service_connection_get(ifc);
6927 eo_do(obj, bus = eo_key_data_get("__svc_bus"));
6928 eldbus_name_release(conn, bus, NULL, NULL);
6929 eldbus_service_interface_unregister(ifc);
6934 _proxy_interface_register(Eldbus_Connection *conn, Eo *proxy, const char *bus, const char *path)
6936 Eldbus_Service_Interface *proxy_infc;
6937 Eo *bridge = _elm_atspi_bridge_get();
6940 ERR("AT-SPI: Atspi bridge is not enabled.");
6943 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6945 eldbus_name_request(conn, bus, ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE, NULL, NULL);
6946 proxy_infc = eldbus_service_interface_register(pd->a11y_bus, path, &_proxy_iface_desc);
6948 ERR("AT-SPI: Proxy interface registration failed");
6949 eo_do(proxy, eo_event_callback_add(EO_EV_DEL, _on_socket_del, proxy_infc));
6950 eldbus_service_object_data_set(proxy_infc, "_atspi_obj", proxy);
6953 static void _socket_ifc_create(Eldbus_Connection *conn, Eo *proxy)
6955 const char *bus, *path;
6956 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6957 Eo *bridge = _elm_atspi_bridge_get();
6958 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6961 eo_do(proxy, bus = eo_key_data_get("__svc_bus"));
6962 eo_do(proxy, path = eo_key_data_get("__svc_path"));
6965 _proxy_interface_register(conn, proxy, bus, path);
6967 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6968 pd->interfaces.socket =
6969 eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &socket_iface_desc);
6973 EAPI void elm_atspi_bridge_utils_proxy_listen(Eo *proxy)
6975 Eo *bridge = _elm_atspi_bridge_get();
6978 ERR("AT-SPI: Atspi bridge is not enabled.");
6981 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
6984 if (!eina_list_data_find(pd->socket_queue, proxy))
6986 pd->socket_queue = eina_list_append(pd->socket_queue, proxy);
6987 eo_do(proxy, eo_event_callback_add(EO_EV_DEL, _from_list_remove, &pd->socket_queue));
6991 _socket_ifc_create(pd->a11y_bus, proxy);
6994 //TIZEN_ONLY(20160527) - Add direct reading feature
6996 _on_read_command_call(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
6998 const char *errname, *errmsg;
7002 Elm_Atspi_Say_Info *say_info = data;
7004 if (eldbus_message_error_get(msg, &errname, &errmsg))
7006 ERR("%s %s", errname, errmsg);
7012 // get read command id and map it to obj
7013 if (eldbus_message_arguments_get(msg, "sbi", &s, &b, &i))
7015 if (!read_command_id)
7016 read_command_id = eina_hash_int32_new(NULL);
7018 if (!read_command_id) {
7019 ERR("eina_hash_int32_new() failed to create new map to store callbacks for direct reading commands");
7023 eina_hash_add(read_command_id, &i, say_info);
7029 elm_atspi_bridge_utils_say(const char* text,
7030 Eina_Bool discardable,
7031 const Elm_Atspi_Say_Signal_Cb func,
7034 Eldbus_Message *msg;
7035 Eldbus_Message_Iter *iter;
7036 Elm_Atspi_Say_Info *say_info = NULL;
7037 Eo *bridge = _elm_atspi_bridge_get();
7040 ERR("AT-SPI: Atspi bridge is not enabled.");
7043 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
7046 ERR("AT-SPI: a11y bus is not set.");
7050 msg = eldbus_message_method_call_new(ELM_ATSPI_DIRECT_READ_BUS,
7051 ELM_ATSPI_DIRECT_READ_PATH,
7052 ELM_ATSPI_DIRECT_READ_INTERFACE,
7054 iter = eldbus_message_iter_get(msg);
7055 eldbus_message_iter_arguments_append(iter, "sb", text, discardable);
7057 say_info = calloc(1, sizeof(Elm_Atspi_Say_Info));
7059 say_info->func = func;
7060 say_info->data = (void *)data;
7063 eldbus_connection_send(pd->a11y_bus, msg, _on_read_command_call, say_info, -1);
7067 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
7069 _offset_set_reply_cb(void *data EINA_UNUSED, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
7071 const char *err, *txt;
7073 if (eldbus_message_error_get(msg, &err, &txt))
7075 ERR("AT-SPI: SetOffset method call failed: %s %s", err, txt);
7080 void elm_atspi_bridge_utils_proxy_offset_set(Eo *proxy, int x, int y)
7082 const char *bus, *path;
7083 Eo *bridge = _elm_atspi_bridge_get();
7084 if (!bridge) return;
7086 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
7088 if (!pd->a11y_bus) return;
7090 eo_do(proxy, bus = eo_key_data_get("__svc_bus"));
7091 eo_do(proxy, path = eo_key_data_get("__svc_path"));
7093 Eldbus_Message *msg = NULL;
7095 msg = eldbus_message_method_call_new(bus, path, ELM_ATSPI_DBUS_INTERFACE_PROXY, "SetOffset");
7096 if (!msg) goto fail;
7098 if (!eldbus_message_arguments_append(msg, "i", x))
7101 if (!eldbus_message_arguments_append(msg, "i", y))
7104 if (!eldbus_connection_send(pd->a11y_bus, msg, _offset_set_reply_cb, NULL, 100))
7110 ERR("AT-SPI: Unable to send SetOffset request.");
7111 if (msg) eldbus_message_unref(msg);
7114 //TIZEN_ONLY(20161027) - Export elm_atspi_bridge_utils_is_screen_reader_enabled
7115 EAPI Eina_Bool elm_atspi_bridge_utils_is_screen_reader_enabled(void)
7117 Eo *bridge = _elm_atspi_bridge_get();
7120 ERR("AT-SPI: Atspi bridge is not enabled.");
7123 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE);
7124 return pd->screen_reader_enabled;
7127 #include "elm_atspi_bridge.eo.c"