summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Stanislawski <l.stanislaws@samsung.com>2015-12-31 15:32:57 +0100
committerLukasz Stanislawski <l.stanislaws@samsung.com>2015-12-31 15:32:57 +0100
commite883c890a8e5b1a54fc5b8b6ed512f51ce201ccb (patch)
tree75929d6f11e0dde3ea839139b80d41d5c95abaa3
parent0d1f157f9d1b943a320281cb5dbc5f443a6c71f9 (diff)
proxy implem.devs/stanluk/proxy
Change-Id: I3b5eed02e9b9e5fe0367b04dda5145918fa6a0a0
-rw-r--r--src/lib/elm_atspi_bridge.c777
-rw-r--r--src/lib/elm_atspi_proxy.c101
-rw-r--r--src/lib/elm_atspi_proxy.eo44
3 files changed, 687 insertions, 235 deletions
diff --git a/src/lib/elm_atspi_bridge.c b/src/lib/elm_atspi_bridge.c
index 782d1fdd2..c5f51a147 100644
--- a/src/lib/elm_atspi_bridge.c
+++ b/src/lib/elm_atspi_bridge.c
@@ -10,6 +10,7 @@
10#define ELM_INTERFACE_ATSPI_SELECTION_PROTECTED 10#define ELM_INTERFACE_ATSPI_SELECTION_PROTECTED
11#define ELM_INTERFACE_ATSPI_TEXT_PROTECTED 11#define ELM_INTERFACE_ATSPI_TEXT_PROTECTED
12#define ELM_INTERFACE_ATSPI_EDITABLE_TEXT_PROTECTED 12#define ELM_INTERFACE_ATSPI_EDITABLE_TEXT_PROTECTED
13#define ELM_ATSPI_BRIDGE_PROTECTED
13 14
14#include "atspi/atspi-constants.h" 15#include "atspi/atspi-constants.h"
15 16
@@ -67,6 +68,7 @@ typedef struct _Elm_Atspi_Bridge_Data
67 Eldbus_Connection *session_bus; 68 Eldbus_Connection *session_bus;
68 Eldbus_Connection *a11y_bus; 69 Eldbus_Connection *a11y_bus;
69 Eina_List *reemited_events; 70 Eina_List *reemited_events;
71 Eo *root;
70 Eina_Hash *cache; 72 Eina_Hash *cache;
71 Eldbus_Service_Interface *cache_interface; 73 Eldbus_Service_Interface *cache_interface;
72 Eldbus_Signal_Handler *register_hdl; 74 Eldbus_Signal_Handler *register_hdl;
@@ -93,11 +95,15 @@ typedef struct _Elm_Atspi_Bridge_Data
93 Eldbus_Service_Interface *text; 95 Eldbus_Service_Interface *text;
94 Eldbus_Service_Interface *value; 96 Eldbus_Service_Interface *value;
95 } interfaces; 97 } interfaces;
96 Elm_Atspi_Event_Handler *event_hdlr; 98 Eina_List *socket_queue;
97 Eina_Hash *event_hash; 99 Eina_List *plug_queue;
98 Eina_Bool connected : 1; 100 Eina_Bool connected : 1;
99} Elm_Atspi_Bridge_Data; 101} Elm_Atspi_Bridge_Data;
100 102
103struct cache_closure {
104 Eo *bridge;
105 Eldbus_Message_Iter *iter;
106};
101 107
102struct collection_match_rule { 108struct collection_match_rule {
103 Elm_Atspi_State_Set states; 109 Elm_Atspi_State_Set states;
@@ -119,18 +125,18 @@ static Eina_Bool _state_changed_signal_send(void *data, Eo *obj, const Eo_Event_
119static Eina_Bool _property_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info); 125static Eina_Bool _property_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info);
120static Eina_Bool _children_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info); 126static Eina_Bool _children_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info);
121static Eina_Bool _window_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info); 127static Eina_Bool _window_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
122static Eina_Bool _visible_data_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
123static Eina_Bool _active_descendant_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
124static Eina_Bool _selection_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info); 128static Eina_Bool _selection_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
125static Eina_Bool _text_text_inserted_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info); 129static Eina_Bool _text_text_inserted_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
126static Eina_Bool _text_text_removed_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info); 130static Eina_Bool _text_text_removed_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
127static Eina_Bool _text_caret_moved_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info); 131static Eina_Bool _text_caret_moved_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
128static Eina_Bool _text_selection_changed_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info EINA_UNUSED); 132static Eina_Bool _text_selection_changed_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info EINA_UNUSED);
133static Eina_Bool _active_descendant_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc, void *event_info);
129 134
130// bridge private methods 135// bridge private methods
136static void _bridge_cache_build(Eo *bridge, void *obj);
131static void _bridge_object_register(Eo *bridge, Eo *obj); 137static void _bridge_object_register(Eo *bridge, Eo *obj);
132static void _bridge_object_unregister(Eo *bridge, Eo *obj); 138static void _bridge_object_unregister(Eo *bridge, Eo *obj);
133static const char * _path_from_object(const Eo *eo); 139static const char * _bridge_path_from_object(Eo *bridge, const Eo *eo);
134static 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, ...); 140static 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, ...);
135static Eo * _bridge_object_from_path(Eo *bridge, const char *path); 141static Eo * _bridge_object_from_path(Eo *bridge, const char *path);
136static void _bridge_iter_object_reference_append(Eo *bridge, Eldbus_Message_Iter *iter, const Eo *obj); 142static void _bridge_iter_object_reference_append(Eo *bridge, Eldbus_Message_Iter *iter, const Eo *obj);
@@ -138,36 +144,40 @@ static void _bridge_iter_object_reference_append(Eo *bridge, Eldbus_Message_Iter
138// utility functions 144// utility functions
139static void _iter_interfaces_append(Eldbus_Message_Iter *iter, const Eo *obj); 145static void _iter_interfaces_append(Eldbus_Message_Iter *iter, const Eo *obj);
140static Eina_Bool _elm_atspi_bridge_key_filter(void *data, void *loop, int type, void *event); 146static Eina_Bool _elm_atspi_bridge_key_filter(void *data, void *loop, int type, void *event);
147static void _object_unregister(Eo *obj, void *data);
141static void _object_desktop_reference_append(Eldbus_Message_Iter *iter); 148static void _object_desktop_reference_append(Eldbus_Message_Iter *iter);
142static Eina_Bool _on_object_add(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED);
143static Eina_Bool _on_object_del(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED); 149static Eina_Bool _on_object_del(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED);
150static void _plug_connect(Eldbus_Connection *conn, Eo *proxy);
151static void _socket_interface_register(Eldbus_Connection *conn, Eo *proxy);
144 152
145typedef struct { 153EO_CALLBACKS_ARRAY_DEFINE(_events_cb,
146 const Eo_Event_Description *desc; 154 { EO_EV_DEL, _on_object_del},
147 const Eo_Event_Cb callback;
148} Elm_Atspi_Bridge_Event_Handler;
149
150static const Elm_Atspi_Bridge_Event_Handler event_handlers[] = {
151 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, _children_changed_signal_send},
152 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_PROPERTY_CHANGED, _property_changed_signal_send}, 155 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_PROPERTY_CHANGED, _property_changed_signal_send},
156 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, _children_changed_signal_send},
153 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_STATE_CHANGED, _state_changed_signal_send}, 157 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_STATE_CHANGED, _state_changed_signal_send},
154 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_VISIBLE_DATA_CHANGED, _visible_data_changed_signal_send}, 158 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_ACTIVE_DESCENDANT_CHANGED, _active_descendant_changed_signal_send}
155 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_ACTIVE_DESCENDANT_CHANGED, _active_descendant_changed_signal_send}, 159);
156 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_ADDED, _on_object_add}, 160
157 { ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_REMOVED, _on_object_del}, 161EO_CALLBACKS_ARRAY_DEFINE(_window_cb,
158 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_CREATED, _window_signal_send}, 162 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_CREATED, _window_signal_send},
159 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DESTROYED, _window_signal_send}, 163 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DESTROYED, _window_signal_send},
160 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_ACTIVATED, _window_signal_send}, 164 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_ACTIVATED, _window_signal_send},
161 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DEACTIVATED, _window_signal_send}, 165 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DEACTIVATED, _window_signal_send},
162 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MAXIMIZED, _window_signal_send}, 166 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MAXIMIZED, _window_signal_send},
163 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MINIMIZED, _window_signal_send}, 167 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_MINIMIZED, _window_signal_send},
164 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_RESTORED, _window_signal_send}, 168 { ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_RESTORED, _window_signal_send}
165 { ELM_INTERFACE_ATSPI_SELECTION_EVENT_SELECTION_CHANGED, _selection_signal_send}, 169);
170
171EO_CALLBACKS_ARRAY_DEFINE(_selection_cb,
172 { ELM_INTERFACE_ATSPI_SELECTION_EVENT_SELECTION_CHANGED, _selection_signal_send}
173);
174
175EO_CALLBACKS_ARRAY_DEFINE(_text_cb,
166 { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, _text_caret_moved_send }, 176 { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_CARET_MOVED, _text_caret_moved_send },
167 { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_INSERTED, _text_text_inserted_send }, 177 { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_INSERTED, _text_text_inserted_send },
168 { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_REMOVED, _text_text_removed_send }, 178 { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_REMOVED, _text_text_removed_send },
169 { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_SELECTION_CHANGED, _text_selection_changed_send } 179 { ELM_INTERFACE_ATSPI_TEXT_EVENT_ACCESS_TEXT_SELECTION_CHANGED, _text_selection_changed_send }
170}; 180);
171 181
172enum _Atspi_Object_Child_Event_Type 182enum _Atspi_Object_Child_Event_Type
173{ 183{
@@ -436,7 +446,9 @@ const struct atspi_state_desc elm_states_to_atspi_state[] = {
436 { ELM_ATSPI_STATE_SELECTABLE_TEXT, ATSPI_STATE_SELECTABLE_TEXT, "selectable-text" }, 446 { ELM_ATSPI_STATE_SELECTABLE_TEXT, ATSPI_STATE_SELECTABLE_TEXT, "selectable-text" },
437 { ELM_ATSPI_STATE_IS_DEFAULT, ATSPI_STATE_IS_DEFAULT, "is-default" }, 447 { ELM_ATSPI_STATE_IS_DEFAULT, ATSPI_STATE_IS_DEFAULT, "is-default" },
438 { ELM_ATSPI_STATE_VISITED, ATSPI_STATE_VISITED, "visited" }, 448 { ELM_ATSPI_STATE_VISITED, ATSPI_STATE_VISITED, "visited" },
439 { ELM_ATSPI_STATE_LAST_DEFINED, ATSPI_STATE_LAST_DEFINED, "last-defined" }, 449 { ELM_ATSPI_STATE_HIGHLIGHTED, ATSPI_STATE_HIGHLIGHTED, "highlighted"},
450 { ELM_ATSPI_STATE_HIGHLIGHTABLE, ATSPI_STATE_HIGHLIGHTABLE, "highlightable" },
451 { ELM_ATSPI_STATE_LAST_DEFINED, ATSPI_STATE_LAST_DEFINED, "last-defined" }
440}; 452};
441 453
442const int elm_relation_to_atspi_relation_mapping[] = { 454const int elm_relation_to_atspi_relation_mapping[] = {
@@ -471,7 +483,7 @@ static AtspiRelationType _elm_relation_to_atspi_relation(Elm_Atspi_Relation_Type
471{ 483{
472 if ((type < ELM_ATSPI_RELATION_LAST_DEFINED) && (type > ELM_ATSPI_RELATION_NULL)) 484 if ((type < ELM_ATSPI_RELATION_LAST_DEFINED) && (type > ELM_ATSPI_RELATION_NULL))
473 return elm_relation_to_atspi_relation_mapping[type]; 485 return elm_relation_to_atspi_relation_mapping[type];
474 return ATSPI_RELATION_NULL; 486 return ELM_ATSPI_RELATION_NULL;
475} 487}
476 488
477static Eldbus_Message * 489static Eldbus_Message *
@@ -556,8 +568,10 @@ _accessible_get_children(const Eldbus_Service_Interface *iface, const Eldbus_Mes
556 568
557 EINA_LIST_FOREACH(children_list, l, children) 569 EINA_LIST_FOREACH(children_list, l, children)
558 { 570 {
559 _bridge_iter_object_reference_append(bridge, iter_array, children); 571//TIZEN_ONLY(20150731) : add utility function to ensure object registration
560 _bridge_object_register(bridge, children); 572 _bridge_object_register(bridge, children);
573///
574 _bridge_iter_object_reference_append(bridge, iter_array, children);
561 } 575 }
562 576
563 eldbus_message_iter_container_close(iter, iter_array); 577 eldbus_message_iter_container_close(iter, iter_array);
@@ -574,9 +588,10 @@ static Eldbus_Message *
574_accessible_get_application(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) 588_accessible_get_application(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
575{ 589{
576 Eldbus_Message *ret; 590 Eldbus_Message *ret;
591 Eo *root;
577 const char *obj_path = eldbus_message_path_get(msg); 592 const char *obj_path = eldbus_message_path_get(msg);
578 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME); 593 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
579 Eo *root, *obj = _bridge_object_from_path(bridge, obj_path); 594 Eo *obj = _bridge_object_from_path(bridge, obj_path);
580 595
581 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg); 596 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
582 597
@@ -584,7 +599,7 @@ _accessible_get_application(const Eldbus_Service_Interface *iface, const Eldbus_
584 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); 599 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
585 600
586 Eldbus_Message_Iter *iter = eldbus_message_iter_get(ret); 601 Eldbus_Message_Iter *iter = eldbus_message_iter_get(ret);
587 eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, root = elm_interface_atspi_accessible_root_get()); 602 eo_do(bridge, root = elm_obj_atspi_bridge_root_get());
588 _bridge_iter_object_reference_append(bridge, iter, root); 603 _bridge_iter_object_reference_append(bridge, iter, root);
589 604
590 return ret; 605 return ret;
@@ -664,8 +679,7 @@ _elm_atspi_state_set_to_atspi_state_set(Elm_Atspi_State_Set states)
664static Elm_Atspi_State_Set 679static Elm_Atspi_State_Set
665_atspi_state_set_to_elm_atspi_state_set(uint64_t states) 680_atspi_state_set_to_elm_atspi_state_set(uint64_t states)
666{ 681{
667 //Currently Elm_Atspi_State and Atspi_State_Set are binary compatible, 682 //FIXME all mapping instead of assignment
668 //implement proper coversion when it will be needed.
669 Elm_Atspi_State_Set ret = states; 683 Elm_Atspi_State_Set ret = states;
670 return ret; 684 return ret;
671} 685}
@@ -682,18 +696,6 @@ _elm_atspi_state_hash_build(void)
682 return ret; 696 return ret;
683} 697}
684 698
685static Eina_Hash*
686_elm_atspi_event_hash_build(void)
687{
688 Eina_Hash *ret = eina_hash_pointer_new(NULL);
689 unsigned int i = 0;
690
691 for (i = 0; i < SIZE(event_handlers); i++)
692 eina_hash_add(ret, &(event_handlers[i].desc), event_handlers[i].callback);
693
694 return ret;
695}
696
697static Eldbus_Message * 699static Eldbus_Message *
698_accessible_get_state(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) 700_accessible_get_state(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
699{ 701{
@@ -778,19 +780,22 @@ _accessible_child_at_index(const Eldbus_Service_Interface *iface EINA_UNUSED, co
778 eo_do(obj, children = elm_interface_atspi_accessible_children_get()); 780 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
779 781
780 child = eina_list_nth(children, idx); 782 child = eina_list_nth(children, idx);
781 _bridge_iter_object_reference_append(bridge, iter, child); 783//TIZEN_ONLY(20150731) : add utility function to ensure object registration
782 _bridge_object_register(bridge, child); 784 _bridge_object_register(bridge, child);
785//
786 _bridge_iter_object_reference_append(bridge, iter, child);
783 eina_list_free(children); 787 eina_list_free(children);
784 788
785 return ret; 789 return ret;
786} 790}
787 791
792//TIZEN_ONLY(20150709)
788static Eldbus_Message * 793static Eldbus_Message *
789_accessible_get_relation_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) 794_accessible_get_relation_set(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
790{ 795{
791 const char *obj_path = eldbus_message_path_get(msg); 796 const char *obj_path = eldbus_message_path_get(msg);
792 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME); 797 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
793 Eo *rel_obj, *obj = _bridge_object_from_path(bridge, obj_path); 798 Eo *obj = _bridge_object_from_path(bridge, obj_path);
794 Eldbus_Message *ret = NULL; 799 Eldbus_Message *ret = NULL;
795 Eldbus_Message_Iter *iter = NULL, *iter_array = NULL, *iter_array2 = NULL, *iter_struct; 800 Eldbus_Message_Iter *iter = NULL, *iter_array = NULL, *iter_array2 = NULL, *iter_struct;
796 Elm_Atspi_Relation *rel; 801 Elm_Atspi_Relation *rel;
@@ -810,6 +815,7 @@ _accessible_get_relation_set(const Eldbus_Service_Interface *iface EINA_UNUSED,
810 815
811 EINA_LIST_FOREACH(rels, l, rel) 816 EINA_LIST_FOREACH(rels, l, rel)
812 { 817 {
818 Eo *rel_obj;
813 iter_struct = eldbus_message_iter_container_new(iter_array, 'r', NULL); 819 iter_struct = eldbus_message_iter_container_new(iter_array, 'r', NULL);
814 eldbus_message_iter_basic_append(iter_struct, 'u', _elm_relation_to_atspi_relation(rel->type)); 820 eldbus_message_iter_basic_append(iter_struct, 'u', _elm_relation_to_atspi_relation(rel->type));
815 iter_array2 = eldbus_message_iter_container_new(iter_struct, 'a', "(so)"); 821 iter_array2 = eldbus_message_iter_container_new(iter_struct, 'a', "(so)");
@@ -822,7 +828,7 @@ _accessible_get_relation_set(const Eldbus_Service_Interface *iface EINA_UNUSED,
822 eldbus_message_iter_container_close(iter_struct, iter_array2); 828 eldbus_message_iter_container_close(iter_struct, iter_array2);
823 eldbus_message_iter_container_close(iter_array, iter_struct); 829 eldbus_message_iter_container_close(iter_array, iter_struct);
824 } 830 }
825 elm_atspi_relation_set_free(rels); 831 elm_atspi_relation_set_free(&rels);
826 eldbus_message_iter_container_close(iter, iter_array); 832 eldbus_message_iter_container_close(iter, iter_array);
827 833
828 return ret; 834 return ret;
@@ -830,6 +836,7 @@ _accessible_get_relation_set(const Eldbus_Service_Interface *iface EINA_UNUSED,
830fail: 836fail:
831 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to get relation set."); 837 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to get relation set.");
832} 838}
839/////////////////////////
833 840
834static const Eldbus_Method accessible_methods[] = { 841static const Eldbus_Method accessible_methods[] = {
835 { "GetChildAtIndex", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"(so)", "Accessible"}), _accessible_child_at_index, 0 }, 842 { "GetChildAtIndex", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"(so)", "Accessible"}), _accessible_child_at_index, 0 },
@@ -870,7 +877,6 @@ _selection_selected_child_get(const Eldbus_Service_Interface *iface EINA_UNUSED,
870 eo_do(obj, child = elm_interface_atspi_selection_selected_child_get(idx)); 877 eo_do(obj, child = elm_interface_atspi_selection_selected_child_get(idx));
871 878
872 _bridge_iter_object_reference_append(bridge, iter, child); 879 _bridge_iter_object_reference_append(bridge, iter, child);
873 _bridge_object_register(bridge, child);
874 880
875 return ret; 881 return ret;
876} 882}
@@ -1282,7 +1288,7 @@ _text_string_at_offset_get(const Eldbus_Service_Interface *iface, const Eldbus_M
1282{ 1288{
1283 const char *obj_path = eldbus_message_path_get(msg); 1289 const char *obj_path = eldbus_message_path_get(msg);
1284 char *str; 1290 char *str;
1285 Elm_Atspi_Text_Granularity gran; 1291 AtspiTextGranularity gran;
1286 int start, end; 1292 int start, end;
1287 Eldbus_Message *ret; 1293 Eldbus_Message *ret;
1288 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME); 1294 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
@@ -1455,6 +1461,7 @@ _text_default_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus
1455 const char *obj_path = eldbus_message_path_get(msg); 1461 const char *obj_path = eldbus_message_path_get(msg);
1456 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME); 1462 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
1457 Eo *obj = _bridge_object_from_path(bridge, obj_path); 1463 Eo *obj = _bridge_object_from_path(bridge, obj_path);
1464 int start = -1, end;
1458 Eldbus_Message *ret; 1465 Eldbus_Message *ret;
1459 Eldbus_Message_Iter *iter, *iter_array; 1466 Eldbus_Message_Iter *iter, *iter_array;
1460 Eina_List *attrs; 1467 Eina_List *attrs;
@@ -1469,7 +1476,7 @@ _text_default_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus
1469 iter_array = eldbus_message_iter_container_new(iter, 'a', "{ss}"); 1476 iter_array = eldbus_message_iter_container_new(iter, 'a', "{ss}");
1470 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail); 1477 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
1471 1478
1472 eo_do(obj, attrs = elm_interface_atspi_text_default_attributes_get()); 1479 eo_do(obj, attrs = elm_interface_atspi_text_attributes_get(&start, &end));
1473 1480
1474 EINA_LIST_FREE(attrs, attr) 1481 EINA_LIST_FREE(attrs, attr)
1475 { 1482 {
@@ -1478,6 +1485,7 @@ _text_default_attributes_get(const Eldbus_Service_Interface *iface, const Eldbus
1478 } 1485 }
1479 1486
1480 eldbus_message_iter_container_close(iter, iter_array); 1487 eldbus_message_iter_container_close(iter, iter_array);
1488 eldbus_message_iter_arguments_append(iter, "ii", start, end);
1481 1489
1482 return ret; 1490 return ret;
1483 1491
@@ -1711,6 +1719,7 @@ _text_bounded_ranges_get(const Eldbus_Service_Interface *iface, const Eldbus_Mes
1711 Eina_Rectangle rect; 1719 Eina_Rectangle rect;
1712 Eina_Bool screen_coords; 1720 Eina_Bool screen_coords;
1713 AtspiCoordType type; 1721 AtspiCoordType type;
1722 AtspiTextClipType xc, yc;
1714 Elm_Atspi_Text_Clip_Type xclip, yclip; 1723 Elm_Atspi_Text_Clip_Type xclip, yclip;
1715 Eina_List *ranges; 1724 Eina_List *ranges;
1716 Eldbus_Message *ret; 1725 Eldbus_Message *ret;
@@ -1719,7 +1728,7 @@ _text_bounded_ranges_get(const Eldbus_Service_Interface *iface, const Eldbus_Mes
1719 1728
1720 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg); 1729 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE, msg);
1721 1730
1722 if (!eldbus_message_arguments_get(msg, "iiiiuuu", &rect.x, &rect.y, &rect.w, &rect.h, &type, &xclip, &yclip)) 1731 if (!eldbus_message_arguments_get(msg, "iiiiuuu", &rect.x, &rect.y, &rect.w, &rect.h, &type, &xc, &yc))
1723 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."); 1732 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.");
1724 1733
1725 ret = eldbus_message_method_return_new(msg); 1734 ret = eldbus_message_method_return_new(msg);
@@ -1729,6 +1738,9 @@ _text_bounded_ranges_get(const Eldbus_Service_Interface *iface, const Eldbus_Mes
1729 iter_array = eldbus_message_iter_container_new(iter, 'a', "(iisv)"); 1738 iter_array = eldbus_message_iter_container_new(iter, 'a', "(iisv)");
1730 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail); 1739 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
1731 1740
1741 xclip = xc;
1742 yclip = yc;
1743
1732 screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE; 1744 screen_coords = type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
1733 eo_do(obj, ranges = elm_interface_atspi_text_bounded_ranges_get(screen_coords, rect, xclip, yclip)); 1745 eo_do(obj, ranges = elm_interface_atspi_text_bounded_ranges_get(screen_coords, rect, xclip, yclip));
1734 1746
@@ -1832,6 +1844,7 @@ static const Eldbus_Method text_methods[] = {
1832 { "GetRangeExtents", ELDBUS_ARGS({"i", "startOffset"}, {"i", "endOffset"}, {"u", "coordType"}), ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"i","w"}, {"i","h"}), _text_range_extents_get, 0 }, 1844 { "GetRangeExtents", ELDBUS_ARGS({"i", "startOffset"}, {"i", "endOffset"}, {"u", "coordType"}), ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"i","w"}, {"i","h"}), _text_range_extents_get, 0 },
1833 { "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 }, 1845 { "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 },
1834 { "GetAttributeRun", ELDBUS_ARGS({"i", "offset"}, {"b", "includeDefaults"}), ELDBUS_ARGS({"a(ss)", NULL}, {"i", "startOffset"}, {"i", "endOffset"}), _text_run_attributes_get, 0 }, 1846 { "GetAttributeRun", ELDBUS_ARGS({"i", "offset"}, {"b", "includeDefaults"}), ELDBUS_ARGS({"a(ss)", NULL}, {"i", "startOffset"}, {"i", "endOffset"}), _text_run_attributes_get, 0 },
1847 { "GetDefaultAttributeSet", NULL, ELDBUS_ARGS({"a(ss)", NULL}), _text_default_attributes_get, 0 },
1835 { NULL, NULL, NULL, NULL, 0 } 1848 { NULL, NULL, NULL, NULL, 0 }
1836}; 1849};
1837 1850
@@ -2003,7 +2016,8 @@ _bridge_object_from_path(Eo *bridge, const char *path)
2003 unsigned long long eo_ptr = 0; 2016 unsigned long long eo_ptr = 0;
2004 Eo *eo = NULL; 2017 Eo *eo = NULL;
2005 const char *tmp = path; 2018 const char *tmp = path;
2006 Eo *ret, *root; 2019 Eo *ret;
2020 Eo *root;
2007 2021
2008 int len = strlen(ELM_ACCESS_OBJECT_PATH_PREFIX); 2022 int len = strlen(ELM_ACCESS_OBJECT_PATH_PREFIX);
2009 if (strncmp(path, ELM_ACCESS_OBJECT_PATH_PREFIX, len)) 2023 if (strncmp(path, ELM_ACCESS_OBJECT_PATH_PREFIX, len))
@@ -2012,7 +2026,7 @@ _bridge_object_from_path(Eo *bridge, const char *path)
2012 tmp = path + len; /* Skip over the prefix */ 2026 tmp = path + len; /* Skip over the prefix */
2013 if (!strcmp(ELM_ACCESS_OBJECT_PATH_ROOT, tmp)) 2027 if (!strcmp(ELM_ACCESS_OBJECT_PATH_ROOT, tmp))
2014 { 2028 {
2015 eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, root = elm_interface_atspi_accessible_root_get()); 2029 eo_do(bridge, root = elm_obj_atspi_bridge_root_get());
2016 return root; 2030 return root;
2017 } 2031 }
2018 2032
@@ -2032,15 +2046,14 @@ _bridge_object_from_path(Eo *bridge, const char *path)
2032} 2046}
2033 2047
2034static const char * 2048static const char *
2035_path_from_object(const Eo *eo) 2049_bridge_path_from_object(Eo *bridge, const Eo *eo)
2036{ 2050{
2037 static char path[64];
2038 Eo *root; 2051 Eo *root;
2052 static char path[64];
2039 2053
2040 if (!eo) 2054 if (!eo) return ATSPI_DBUS_PATH_NULL;
2041 return ATSPI_DBUS_PATH_NULL;
2042 eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, root = elm_interface_atspi_accessible_root_get());
2043 2055
2056 eo_do(bridge, root = elm_obj_atspi_bridge_root_get());
2044 if (eo == root) 2057 if (eo == root)
2045 snprintf(path, sizeof(path), "%s%s", ELM_ACCESS_OBJECT_PATH_PREFIX, ELM_ACCESS_OBJECT_PATH_ROOT); 2058 snprintf(path, sizeof(path), "%s%s", ELM_ACCESS_OBJECT_PATH_PREFIX, ELM_ACCESS_OBJECT_PATH_ROOT);
2046 else 2059 else
@@ -2240,8 +2253,8 @@ _image_properties_get(const Eldbus_Service_Interface *interface, const char *pro
2240 2253
2241static Eina_Bool 2254static Eina_Bool
2242_text_properties_get(const Eldbus_Service_Interface *interface, const char *property, 2255_text_properties_get(const Eldbus_Service_Interface *interface, const char *property,
2243 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg, 2256 Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg EINA_UNUSED,
2244 Eldbus_Message **error) 2257 Eldbus_Message **error EINA_UNUSED)
2245{ 2258{
2246 const char *obj_path = eldbus_message_path_get(request_msg); 2259 const char *obj_path = eldbus_message_path_get(request_msg);
2247 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME); 2260 Eo *bridge = eldbus_service_object_data_get(interface, ELM_ATSPI_BRIDGE_CLASS_NAME);
@@ -2445,7 +2458,7 @@ _collection_iter_match_rule_get(Eldbus_Message_Iter *iter, struct collection_mat
2445 if (!eldbus_message_iter_fixed_array_get(states_iter, 'i', &array, &array_count)) 2458 if (!eldbus_message_iter_fixed_array_get(states_iter, 'i', &array, &array_count))
2446 return EINA_FALSE; 2459 return EINA_FALSE;
2447 2460
2448 //Roles according to libatspi impementation are transferred in 2-int element fixed bit array 2461 //Roles according to libatspi impementation are transfered in 2-int element fixed bit array
2449 if (array_count != 2) 2462 if (array_count != 2)
2450 { 2463 {
2451 ERR("Unexpected states array size"); 2464 ERR("Unexpected states array size");
@@ -2454,7 +2467,7 @@ _collection_iter_match_rule_get(Eldbus_Message_Iter *iter, struct collection_mat
2454 uint64_t states = ((uint64_t)array[0] | ((uint64_t)array[1] << 32)); 2467 uint64_t states = ((uint64_t)array[0] | ((uint64_t)array[1] << 32));
2455 rule->states = _atspi_state_set_to_elm_atspi_state_set(states); 2468 rule->states = _atspi_state_set_to_elm_atspi_state_set(states);
2456 2469
2457 //Roles according to libatspi impementation are transferred in 4-int element fixed bit array 2470 //Roles according to libatspi impementation are transfered in 4-int element fixed bit array
2458 if (!eldbus_message_iter_fixed_array_get(role_iter, 'i', &array, &array_count)) 2471 if (!eldbus_message_iter_fixed_array_get(role_iter, 'i', &array, &array_count))
2459 return EINA_FALSE; 2472 return EINA_FALSE;
2460 2473
@@ -2476,7 +2489,7 @@ _collection_iter_match_rule_get(Eldbus_Message_Iter *iter, struct collection_mat
2476 const char *key, *value; 2489 const char *key, *value;
2477 if (eldbus_message_iter_arguments_get(iter_arg, "ss", &key, &value)) 2490 if (eldbus_message_iter_arguments_get(iter_arg, "ss", &key, &value))
2478 { 2491 {
2479 Elm_Atspi_Attribute *attrib = calloc(1, sizeof(Elm_Atspi_Attribute)); 2492 Elm_Atspi_Attribute *attrib = calloc(sizeof(Elm_Atspi_Attribute), 1);
2480 attrib->key = eina_stringshare_add(key); 2493 attrib->key = eina_stringshare_add(key);
2481 attrib->value = eina_stringshare_add(value); 2494 attrib->value = eina_stringshare_add(value);
2482 rule->attributes = eina_list_append(rule->attributes, attrib); 2495 rule->attributes = eina_list_append(rule->attributes, attrib);
@@ -2592,7 +2605,7 @@ _collection_match_roles_lookup(Eo *obj, struct collection_match_rule *rule)
2592 2605
2593 eo_do(obj, role = elm_interface_atspi_accessible_role_get()); 2606 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
2594 2607
2595 if (role >= 64) 2608 if (role > 64)
2596 { 2609 {
2597 role -= 64; 2610 role -= 64;
2598 role_set = rule->roles[1]; 2611 role_set = rule->roles[1];
@@ -2600,12 +2613,6 @@ _collection_match_roles_lookup(Eo *obj, struct collection_match_rule *rule)
2600 else 2613 else
2601 role_set = rule->roles[0]; 2614 role_set = rule->roles[0];
2602 2615
2603 if (role >= 64)
2604 {
2605 ERR("Elm_Atspi_Role enum value exceeds 127. Unable to compare with roles bit field.");
2606 return EINA_FALSE;
2607 }
2608
2609 switch (rule->rolematchtype) 2616 switch (rule->rolematchtype)
2610 { 2617 {
2611 case ATSPI_Collection_MATCH_INVALID: 2618 case ATSPI_Collection_MATCH_INVALID:
@@ -3082,9 +3089,22 @@ _bridge_iter_object_reference_append(Eo *bridge, Eldbus_Message_Iter *iter, cons
3082 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 3089 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
3083 Eldbus_Message_Iter *iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL); 3090 Eldbus_Message_Iter *iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
3084 EINA_SAFETY_ON_NULL_RETURN(iter); 3091 EINA_SAFETY_ON_NULL_RETURN(iter);
3085 const char *path = _path_from_object(obj); 3092 if (eo_isa(obj, ELM_ATSPI_PROXY_CLASS))
3086 eldbus_message_iter_basic_append(iter_struct, 's', eldbus_connection_unique_name_get(pd->a11y_bus)); 3093 {
3087 eldbus_message_iter_basic_append(iter_struct, 'o', path); 3094 const char *pbus = "", *ppath = ATSPI_DBUS_PATH_NULL;
3095 eo_do(obj, elm_obj_atspi_proxy_address_get(&pbus, &ppath));
3096 if (!pbus || !ppath)
3097 ERR("Invalid proxy address! Address not set before connecting/listening?");
3098 eldbus_message_iter_basic_append(iter_struct, 's', pbus);
3099 eldbus_message_iter_basic_append(iter_struct, 'o', ppath);
3100 }
3101 else
3102 {
3103 const char *path = _bridge_path_from_object(bridge, obj);
3104 eldbus_message_iter_basic_append(iter_struct, 's', eldbus_connection_unique_name_get(pd->a11y_bus));
3105 eldbus_message_iter_basic_append(iter_struct, 'o', path);
3106 }
3107
3088 eldbus_message_iter_container_close(iter, iter_struct); 3108 eldbus_message_iter_container_close(iter, iter_struct);
3089} 3109}
3090 3110
@@ -3113,18 +3133,18 @@ _iter_interfaces_append(Eldbus_Message_Iter *iter, const Eo *obj)
3113 } 3133 }
3114 if (eo_isa(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN)) 3134 if (eo_isa(obj, ELM_INTERFACE_ATSPI_ACTION_MIXIN))
3115 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_ACTION); 3135 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_ACTION);
3116 if (eo_isa(obj, ELM_ATSPI_APP_OBJECT_CLASS))
3117 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_APPLICATION);
3118 if (eo_isa(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN)) 3136 if (eo_isa(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN))
3119 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_COMPONENT); 3137 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_COMPONENT);
3120 if (eo_isa(obj, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE)) 3138 if (eo_isa(obj, ELM_INTERFACE_ATSPI_EDITABLE_TEXT_INTERFACE))
3121 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_EDITABLE_TEXT); 3139 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_EDITABLE_TEXT);
3140 if (eo_isa(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE))
3141 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_TEXT);
3122 if (eo_isa(obj, ELM_INTERFACE_ATSPI_IMAGE_MIXIN)) 3142 if (eo_isa(obj, ELM_INTERFACE_ATSPI_IMAGE_MIXIN))
3123 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_IMAGE); 3143 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_IMAGE);
3124 if (eo_isa(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE)) 3144 if (eo_isa(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE))
3125 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_SELECTION); 3145 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_SELECTION);
3126 if (eo_isa(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE)) 3146 if (eo_isa(obj, ELM_ATSPI_APP_OBJECT_CLASS))
3127 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_TEXT); 3147 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_APPLICATION);
3128 if (eo_isa(obj, ELM_INTERFACE_ATSPI_VALUE_INTERFACE)) 3148 if (eo_isa(obj, ELM_INTERFACE_ATSPI_VALUE_INTERFACE))
3129 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_VALUE); 3149 eldbus_message_iter_basic_append(iter_array, 's', ATSPI_DBUS_INTERFACE_VALUE);
3130 3150
@@ -3132,16 +3152,18 @@ _iter_interfaces_append(Eldbus_Message_Iter *iter, const Eo *obj)
3132} 3152}
3133 3153
3134static Eina_Bool 3154static Eina_Bool
3135_cache_item_reference_append_cb(Eo *bridge, Eo *data, Eldbus_Message_Iter *iter_array) 3155_cache_item_reference_append_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
3136{ 3156{
3137 if (!eo_ref_get(data) || eo_destructed_is(data)) 3157 if (!eo_ref_get(data) || eo_destructed_is(data))
3138 return EINA_TRUE; 3158 return EINA_TRUE;
3139 3159
3160 struct cache_closure *cl = fdata;
3140 Eldbus_Message_Iter *iter_struct, *iter_sub_array; 3161 Eldbus_Message_Iter *iter_struct, *iter_sub_array;
3162 Eldbus_Message_Iter *iter_array = cl->iter;
3141 Elm_Atspi_State_Set states; 3163 Elm_Atspi_State_Set states;
3142 Elm_Atspi_Role role; 3164 Elm_Atspi_Role role;
3143 Eo *root; 3165 Eo *root;
3144 eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, root = elm_interface_atspi_accessible_root_get()); 3166 eo_do(cl->bridge, root = elm_obj_atspi_bridge_root_get());
3145 3167
3146 eo_do(data, role = elm_interface_atspi_accessible_role_get()); 3168 eo_do(data, role = elm_interface_atspi_accessible_role_get());
3147 3169
@@ -3149,10 +3171,10 @@ _cache_item_reference_append_cb(Eo *bridge, Eo *data, Eldbus_Message_Iter *iter_
3149 EINA_SAFETY_ON_NULL_RETURN_VAL(iter_struct, EINA_TRUE); 3171 EINA_SAFETY_ON_NULL_RETURN_VAL(iter_struct, EINA_TRUE);
3150 3172
3151 /* Marshall object path */ 3173 /* Marshall object path */
3152 _bridge_iter_object_reference_append(bridge, iter_struct, data); 3174 _bridge_iter_object_reference_append(cl->bridge, iter_struct, data);
3153 3175
3154 /* Marshall application */ 3176 /* Marshall application */
3155 _bridge_iter_object_reference_append(bridge, iter_struct, root); 3177 _bridge_iter_object_reference_append(cl->bridge, iter_struct, root);
3156 3178
3157 Eo *parent = NULL; 3179 Eo *parent = NULL;
3158 eo_do(data, parent = elm_interface_atspi_accessible_parent_get()); 3180 eo_do(data, parent = elm_interface_atspi_accessible_parent_get());
@@ -3160,21 +3182,27 @@ _cache_item_reference_append_cb(Eo *bridge, Eo *data, Eldbus_Message_Iter *iter_
3160 if ((!parent) && (ELM_ATSPI_ROLE_APPLICATION == role)) 3182 if ((!parent) && (ELM_ATSPI_ROLE_APPLICATION == role))
3161 _object_desktop_reference_append(iter_struct); 3183 _object_desktop_reference_append(iter_struct);
3162 else 3184 else
3163 _bridge_iter_object_reference_append(bridge, iter_struct, parent); 3185 _bridge_iter_object_reference_append(cl->bridge, iter_struct, parent);
3164 3186
3165 /* Marshall children */ 3187 /* Marshall children */
3166 Eina_List *children_list = NULL, *l; 3188 Eina_List *children_list = NULL, *l;
3167 Eo *child; 3189 Eo *child;
3168 3190
3169 eo_do(data, children_list = elm_interface_atspi_accessible_children_get()); 3191 Elm_Atspi_State_Set ss;
3192 eo_do(data, ss = elm_interface_atspi_accessible_state_set_get());
3170 iter_sub_array = eldbus_message_iter_container_new(iter_struct, 'a', "(so)"); 3193 iter_sub_array = eldbus_message_iter_container_new(iter_struct, 'a', "(so)");
3171 EINA_SAFETY_ON_NULL_GOTO(iter_sub_array, fail); 3194 EINA_SAFETY_ON_NULL_GOTO(iter_sub_array, fail);
3172 3195
3173 EINA_LIST_FOREACH(children_list, l, child) 3196 if (!STATE_TYPE_GET(ss, ELM_ATSPI_STATE_MANAGES_DESCENDANTS))
3174 _bridge_iter_object_reference_append(bridge, iter_sub_array, child); 3197 {
3198 eo_do(data, children_list = elm_interface_atspi_accessible_children_get());
3199 EINA_LIST_FOREACH(children_list, l, child)
3200 _bridge_iter_object_reference_append(cl->bridge, iter_sub_array, child);
3201
3202 eina_list_free(children_list);
3203 }
3175 3204
3176 eldbus_message_iter_container_close(iter_struct, iter_sub_array); 3205 eldbus_message_iter_container_close(iter_struct, iter_sub_array);
3177 eina_list_free(children_list);
3178 3206
3179 /* Marshall interfaces */ 3207 /* Marshall interfaces */
3180 _iter_interfaces_append(iter_struct, data); 3208 _iter_interfaces_append(iter_struct, data);
@@ -3222,10 +3250,9 @@ fail:
3222static Eldbus_Message * 3250static Eldbus_Message *
3223_cache_get_items(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) 3251_cache_get_items(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
3224{ 3252{
3225 Eldbus_Message_Iter *iter, *iter_array; 3253 Eldbus_Message_Iter *iter;
3226 Eldbus_Message *ret; 3254 Eldbus_Message *ret;
3227 Eina_List *to_process; 3255 struct cache_closure cl;
3228 Eo *root;
3229 3256
3230 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME); 3257 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
3231 if (!bridge) return NULL; 3258 if (!bridge) return NULL;
@@ -3236,25 +3263,13 @@ _cache_get_items(const Eldbus_Service_Interface *iface, const Eldbus_Message *ms
3236 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); 3263 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
3237 3264
3238 iter = eldbus_message_iter_get(ret); 3265 iter = eldbus_message_iter_get(ret);
3239 iter_array = eldbus_message_iter_container_new(iter, 'a', CACHE_ITEM_SIGNATURE); 3266 cl.iter = eldbus_message_iter_container_new(iter, 'a', CACHE_ITEM_SIGNATURE);
3240 EINA_SAFETY_ON_NULL_GOTO(iter_array, fail); 3267 EINA_SAFETY_ON_NULL_GOTO(cl.iter, fail);
3241
3242 eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, root = elm_interface_atspi_accessible_root_get());
3243 to_process = eina_list_append(NULL, root);
3244
3245 while (to_process)
3246 {
3247 Eo *obj = eina_list_data_get(to_process);
3248 to_process = eina_list_remove_list(to_process, to_process);
3249 _cache_item_reference_append_cb(bridge, obj, iter_array);
3250 _bridge_object_register(bridge, obj);
3251 3268
3252 Eina_List *children; 3269 cl.bridge = bridge;
3253 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
3254 to_process = eina_list_merge(to_process, children);
3255 }
3256 3270
3257 eldbus_message_iter_container_close(iter, iter_array); 3271 eina_hash_foreach(pd->cache, _cache_item_reference_append_cb, &cl);
3272 eldbus_message_iter_container_close(iter, cl.iter);
3258 3273
3259 return ret; 3274 return ret;
3260fail: 3275fail:
@@ -3328,8 +3343,10 @@ _component_get_accessible_at_point(const Eldbus_Service_Interface *iface EINA_UN
3328 iter = eldbus_message_iter_get(ret); 3343 iter = eldbus_message_iter_get(ret);
3329 Eina_Bool type = coord_type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE; 3344 Eina_Bool type = coord_type == ATSPI_COORD_TYPE_SCREEN ? EINA_TRUE : EINA_FALSE;
3330 eo_do(obj, accessible = elm_interface_atspi_component_accessible_at_point_get(type, x, y)); 3345 eo_do(obj, accessible = elm_interface_atspi_component_accessible_at_point_get(type, x, y));
3331 _bridge_iter_object_reference_append(bridge, iter, accessible); 3346//TIZEN_ONLY(20150731) : add utility function to ensure object registration
3332 _bridge_object_register(bridge, accessible); 3347 _bridge_object_register(bridge, accessible);
3348///
3349 _bridge_iter_object_reference_append(bridge, iter, accessible);
3333 3350
3334 return ret; 3351 return ret;
3335} 3352}
@@ -3464,8 +3481,7 @@ _component_grab_focus(const Eldbus_Service_Interface *iface EINA_UNUSED, const E
3464 Eldbus_Message *ret; 3481 Eldbus_Message *ret;
3465 Eina_Bool focus = EINA_FALSE; 3482 Eina_Bool focus = EINA_FALSE;
3466 3483
3467 if (!obj) 3484 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
3468 return _dbus_invalid_ref_error_new(msg);
3469 3485
3470 eo_do(obj, focus = elm_interface_atspi_component_focus_grab()); 3486 eo_do(obj, focus = elm_interface_atspi_component_focus_grab());
3471 3487
@@ -3478,6 +3494,48 @@ _component_grab_focus(const Eldbus_Service_Interface *iface EINA_UNUSED, const E
3478} 3494}
3479 3495
3480static Eldbus_Message * 3496static Eldbus_Message *
3497_component_grab_highlight(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3498{
3499 const char *obj_path = eldbus_message_path_get(msg);
3500 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
3501 Eo *obj = _bridge_object_from_path(bridge, obj_path);
3502 Eldbus_Message *ret;
3503 Eina_Bool highlight = EINA_FALSE;
3504
3505 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
3506
3507 eo_do(obj, highlight = elm_interface_atspi_component_highlight_grab());
3508
3509 ret = eldbus_message_method_return_new(msg);
3510 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
3511
3512 eldbus_message_arguments_append(ret, "b", highlight);
3513
3514 return ret;
3515}
3516
3517static Eldbus_Message *
3518_component_clear_highlight(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3519{
3520 const char *obj_path = eldbus_message_path_get(msg);
3521 Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
3522 Eo *obj = _bridge_object_from_path(bridge, obj_path);
3523 Eldbus_Message *ret;
3524 Eina_Bool highlight = EINA_FALSE;
3525
3526 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
3527
3528 eo_do(obj, highlight = elm_interface_atspi_component_highlight_clear());
3529
3530 ret = eldbus_message_method_return_new(msg);
3531 EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
3532
3533 eldbus_message_arguments_append(ret, "b", highlight);
3534
3535 return ret;
3536}
3537
3538static Eldbus_Message *
3481_component_get_alpha(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg) 3539_component_get_alpha(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
3482{ 3540{
3483 const char *obj_path = eldbus_message_path_get(msg); 3541 const char *obj_path = eldbus_message_path_get(msg);
@@ -3486,8 +3544,7 @@ _component_get_alpha(const Eldbus_Service_Interface *iface EINA_UNUSED, const El
3486 Eldbus_Message *ret; 3544 Eldbus_Message *ret;
3487 double alpha = 0; 3545 double alpha = 0;
3488 3546
3489 if (!obj) 3547 ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_COMPONENT_MIXIN, msg);
3490 return _dbus_invalid_ref_error_new(msg);
3491 3548
3492 eo_do(obj, alpha = elm_interface_atspi_component_alpha_get()); 3549 eo_do(obj, alpha = elm_interface_atspi_component_alpha_get());
3493 3550
@@ -3585,12 +3642,13 @@ static const Eldbus_Method component_methods[] = {
3585 { "GetPosition", ELDBUS_ARGS({"u", "coord_type"}), ELDBUS_ARGS({"i", "x"}, {"i","y"}), _component_get_position, 0 }, 3642 { "GetPosition", ELDBUS_ARGS({"u", "coord_type"}), ELDBUS_ARGS({"i", "x"}, {"i","y"}), _component_get_position, 0 },
3586 { "GetSize", NULL, ELDBUS_ARGS({"i", "w"}, {"i", "h"}), _component_get_size, 0 }, 3643 { "GetSize", NULL, ELDBUS_ARGS({"i", "w"}, {"i", "h"}), _component_get_size, 0 },
3587 { "GetLayer", NULL, ELDBUS_ARGS({"u", "layer"}), _component_get_layer, 0 }, 3644 { "GetLayer", NULL, ELDBUS_ARGS({"u", "layer"}), _component_get_layer, 0 },
3588// { "GetMDIZOrder", NULL, ELDBUS_ARGS({"n", "MDIZOrder"}), _component_get_mdizorder, 0 },
3589 { "GrabFocus", NULL, ELDBUS_ARGS({"b", "focus"}), _component_grab_focus, 0 }, 3645 { "GrabFocus", NULL, ELDBUS_ARGS({"b", "focus"}), _component_grab_focus, 0 },
3590 { "GetAlpha", NULL, ELDBUS_ARGS({"d", "alpha"}), _component_get_alpha, 0 }, 3646 { "GetAlpha", NULL, ELDBUS_ARGS({"d", "alpha"}), _component_get_alpha, 0 },
3591 { "SetExtents", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"i", "width"}, {"i", "height"}, {"u", "coord_type"}), ELDBUS_ARGS({"b", "result"}), _component_set_extends, 0 }, 3647 { "SetExtents", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"i", "width"}, {"i", "height"}, {"u", "coord_type"}), ELDBUS_ARGS({"b", "result"}), _component_set_extends, 0 },
3592 { "SetPosition", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"u", "coord_type"}), ELDBUS_ARGS({"b", "result"}), _component_set_position, 0 }, 3648 { "SetPosition", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"u", "coord_type"}), ELDBUS_ARGS({"b", "result"}), _component_set_position, 0 },
3593 { "SetSize", ELDBUS_ARGS({"i", "width"}, {"i", "height"}), ELDBUS_ARGS({"b", "result"}), _component_set_size, 0 }, 3649 { "SetSize", ELDBUS_ARGS({"i", "width"}, {"i", "height"}), ELDBUS_ARGS({"b", "result"}), _component_set_size, 0 },
3650 { "GrabHighlight", NULL, ELDBUS_ARGS({"b", "result"}), _component_grab_highlight, 0 },
3651 { "ClearHighlight", NULL, ELDBUS_ARGS({"b", "result"}), _component_clear_highlight, 0 },
3594 { NULL, NULL, NULL, NULL, 0 } 3652 { NULL, NULL, NULL, NULL, 0 }
3595}; 3653};
3596 3654
@@ -3623,7 +3681,7 @@ _elm_atspi_bridge_app_register(Eo *bridge)
3623 "Embed"); 3681 "Embed");
3624 Eldbus_Message_Iter *iter = eldbus_message_iter_get(message); 3682 Eldbus_Message_Iter *iter = eldbus_message_iter_get(message);
3625 3683
3626 eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, root = elm_interface_atspi_accessible_root_get()); 3684 eo_do(bridge, root = elm_obj_atspi_bridge_root_get());
3627 _bridge_iter_object_reference_append(bridge, iter, root); 3685 _bridge_iter_object_reference_append(bridge, iter, root);
3628 eldbus_connection_send(pd->a11y_bus, message, _on_elm_atspi_bridge_app_register, NULL, -1); 3686 eldbus_connection_send(pd->a11y_bus, message, _on_elm_atspi_bridge_app_register, NULL, -1);
3629 3687
@@ -3636,7 +3694,7 @@ _elm_atspi_bridge_app_unregister(Eo *bridge)
3636 Eo *root; 3694 Eo *root;
3637 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE); 3695 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE);
3638 3696
3639 eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, root = elm_interface_atspi_accessible_root_get()); 3697 eo_do(bridge, root = elm_obj_atspi_bridge_root_get());
3640 3698
3641 Eldbus_Message *message = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY, 3699 Eldbus_Message *message = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY,
3642 ATSPI_DBUS_PATH_ROOT, 3700 ATSPI_DBUS_PATH_ROOT,
@@ -3653,7 +3711,7 @@ _elm_atspi_bridge_app_unregister(Eo *bridge)
3653static void 3711static void
3654_cache_register(Eo *obj) 3712_cache_register(Eo *obj)
3655{ 3713{
3656 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(obj, pd); 3714 Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(obj, ELM_ATSPI_BRIDGE_CLASS);
3657 pd->cache_interface = eldbus_service_interface_register(pd->a11y_bus, CACHE_INTERFACE_PATH, &cache_iface_desc); 3715 pd->cache_interface = eldbus_service_interface_register(pd->a11y_bus, CACHE_INTERFACE_PATH, &cache_iface_desc);
3658 eldbus_service_object_data_set(pd->cache_interface, ELM_ATSPI_BRIDGE_CLASS_NAME, obj); 3716 eldbus_service_object_data_set(pd->cache_interface, ELM_ATSPI_BRIDGE_CLASS_NAME, obj);
3659} 3717}
@@ -3662,7 +3720,7 @@ static void
3662_set_broadcast_flag(const char *event, Eo *bridge) 3720_set_broadcast_flag(const char *event, Eo *bridge)
3663{ 3721{
3664 char **tokens; 3722 char **tokens;
3665 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 3723 Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(bridge, ELM_ATSPI_BRIDGE_CLASS);
3666 3724
3667 tokens = eina_str_split(event, ":", 3); 3725 tokens = eina_str_split(event, ":", 3);
3668 3726
@@ -3714,12 +3772,8 @@ _set_broadcast_flag(const char *event, Eo *bridge)
3714 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED); 3772 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_SELECTION_CHANGED);
3715 else if (!strcmp(tokens[1], "TextAttributesChanged")) 3773 else if (!strcmp(tokens[1], "TextAttributesChanged"))
3716 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_ATTRIBUTES_CHANGED); 3774 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_TEXT_ATTRIBUTES_CHANGED);
3717 else if (!strcmp(tokens[1], "VisibleDataChanged"))
3718 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED);
3719 else if (!strcmp(tokens[1], "ActiveDescendantChanged")) 3775 else if (!strcmp(tokens[1], "ActiveDescendantChanged"))
3720 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED); 3776 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED);
3721 else if (!strcmp(tokens[1], "SelectionChanged"))
3722 STATE_TYPE_SET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_SELECTION_CHANGED);
3723 } 3777 }
3724 else if (!strcmp(tokens[0], "Window")) 3778 else if (!strcmp(tokens[0], "Window"))
3725 { 3779 {
@@ -3751,7 +3805,7 @@ static void
3751_registered_listeners_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending) 3805_registered_listeners_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
3752{ 3806{
3753 const char *event, *bus; 3807 const char *event, *bus;
3754 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd); 3808 Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(data, ELM_ATSPI_BRIDGE_CLASS);
3755 pd->pending_requests = eina_list_remove(pd->pending_requests, pending); 3809 pd->pending_requests = eina_list_remove(pd->pending_requests, pending);
3756 3810
3757 DBG("Updating registered ATSPI signals list."); 3811 DBG("Updating registered ATSPI signals list.");
@@ -3779,15 +3833,31 @@ _registered_listeners_get(void *data, const Eldbus_Message *msg, Eldbus_Pending
3779 } 3833 }
3780 3834
3781 if (!pd->connected) 3835 if (!pd->connected)
3782 eo_do(data, eo_event_callback_call(ELM_ATSPI_BRIDGE_EVENT_CONNECTED, NULL)); 3836 {
3783 pd->connected = EINA_TRUE; 3837 Eo *root, *pr;
3838 eo_do(data, eo_event_callback_call(ELM_ATSPI_BRIDGE_EVENT_CONNECTED, NULL));
3839
3840 // buid cache
3841 eo_do(data, root = elm_obj_atspi_bridge_root_get());
3842 _bridge_cache_build(data, root);
3843
3844 // initialize pending proxy
3845 EINA_LIST_FREE(pd->socket_queue, pr)
3846 _socket_interface_register(pd->a11y_bus, pr);
3847 EINA_LIST_FREE(pd->plug_queue, pr)
3848 _plug_connect(pd->a11y_bus, pr);
3849
3850 pd->socket_queue = pd->plug_queue = NULL;
3851 }
3852
3853 pd->connected = 1;
3784} 3854}
3785 3855
3786static void 3856static void
3787_registered_events_list_update(Eo *bridge) 3857_registered_events_list_update(Eo *bridge)
3788{ 3858{
3789 Eldbus_Message *msg; 3859 Eldbus_Message *msg;
3790 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 3860 Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(bridge, ELM_ATSPI_BRIDGE_CLASS);
3791 Eldbus_Pending *p; 3861 Eldbus_Pending *p;
3792 3862
3793 msg = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_REGISTRY, ATSPI_DBUS_INTERFACE_REGISTRY, "GetRegisteredEvents"); 3863 msg = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_REGISTRY, ATSPI_DBUS_INTERFACE_REGISTRY, "GetRegisteredEvents");
@@ -3802,6 +3872,23 @@ _handle_listener_change(void *data, const Eldbus_Message *msg EINA_UNUSED)
3802} 3872}
3803 3873
3804static Eina_Bool 3874static Eina_Bool
3875_active_descendant_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
3876{
3877 int idx;
3878 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
3879
3880 if (!STATE_TYPE_GET(pd->object_broadcast_mask, ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED))
3881 return EINA_FALSE;
3882
3883 eo_do(event_info, idx = elm_interface_atspi_accessible_index_in_parent_get());
3884 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
3885 &_event_obj_signals[ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED], "",
3886 idx, 0, "(so)", eldbus_connection_unique_name_get(pd->a11y_bus),
3887 event_info);
3888 return EINA_TRUE;
3889}
3890
3891static Eina_Bool
3805_state_changed_signal_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info) 3892_state_changed_signal_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
3806{ 3893{
3807 Elm_Atspi_Event_State_Changed_Data *state_data = event_info; 3894 Elm_Atspi_Event_State_Changed_Data *state_data = event_info;
@@ -3812,7 +3899,7 @@ _state_changed_signal_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Descr
3812 return EINA_FALSE; 3899 return EINA_FALSE;
3813 3900
3814 if ((state_data->type > ELM_ATSPI_STATE_LAST_DEFINED) || 3901 if ((state_data->type > ELM_ATSPI_STATE_LAST_DEFINED) ||
3815 (int)state_data->type < 0) 3902 state_data->type < 0)
3816 return EINA_FALSE; 3903 return EINA_FALSE;
3817 3904
3818 type_desc = elm_states_to_atspi_state[state_data->type].name; 3905 type_desc = elm_states_to_atspi_state[state_data->type].name;
@@ -3873,51 +3960,27 @@ _property_changed_signal_send(void *data, Eo *obj EINA_UNUSED, const Eo_Event_De
3873} 3960}
3874 3961
3875static Eina_Bool 3962static Eina_Bool
3876_visible_data_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
3877{
3878 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
3879
3880 if (!STATE_TYPE_GET(pd->object_children_broadcast_mask, ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED))
3881 return EINA_FALSE;
3882
3883 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
3884 &_event_obj_signals[ATSPI_OBJECT_EVENT_VISIBLE_DATA_CHANGED], "",
3885 0, 0, NULL, NULL);
3886
3887 return EINA_TRUE;
3888}
3889
3890static Eina_Bool
3891_active_descendant_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
3892{
3893 Eo *child = event_info;
3894 int idx;
3895
3896 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
3897
3898 if (!STATE_TYPE_GET(pd->object_children_broadcast_mask, ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED))
3899 return EINA_FALSE;
3900
3901 eo_do(child, idx = elm_interface_atspi_accessible_index_in_parent_get());
3902
3903 _bridge_signal_send(data, obj, ATSPI_DBUS_INTERFACE_EVENT_OBJECT,
3904 &_event_obj_signals[ATSPI_OBJECT_EVENT_ACTIVE_DESCENDANT_CHANGED], "",
3905 idx, 0, "(so)", eldbus_connection_unique_name_get(pd->a11y_bus), child);
3906 return EINA_TRUE;
3907}
3908
3909static Eina_Bool
3910_children_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info) 3963_children_changed_signal_send(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info)
3911{ 3964{
3912 const char *atspi_desc = NULL; 3965 const char *atspi_desc = NULL;
3913 Elm_Atspi_Event_Children_Changed_Data *ev_data = event_info; 3966 Elm_Atspi_Event_Children_Changed_Data *ev_data = event_info;
3914 int idx; 3967 int idx;
3915 enum _Atspi_Object_Child_Event_Type type; 3968 enum _Atspi_Object_Child_Event_Type type;
3969 Elm_Atspi_State_Set ss;
3916 3970
3917 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE); 3971 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_FALSE);
3918 3972
3919 type = ev_data->is_added ? ATSPI_OBJECT_CHILD_ADDED : ATSPI_OBJECT_CHILD_REMOVED; 3973 type = ev_data->is_added ? ATSPI_OBJECT_CHILD_ADDED : ATSPI_OBJECT_CHILD_REMOVED;
3920 3974
3975 eo_do(obj, ss = elm_interface_atspi_accessible_state_set_get());
3976
3977 if (STATE_TYPE_GET(ss, ELM_ATSPI_STATE_MANAGES_DESCENDANTS))
3978 return EINA_TRUE;
3979
3980 // update cached objects
3981 if (ev_data->is_added)
3982 _bridge_cache_build(data, ev_data->child);
3983
3921 if (!STATE_TYPE_GET(pd->object_children_broadcast_mask, type)) 3984 if (!STATE_TYPE_GET(pd->object_children_broadcast_mask, type))
3922 return EINA_FALSE; 3985 return EINA_FALSE;
3923 3986
@@ -4008,8 +4071,7 @@ static void _bridge_signal_send(Eo *bridge, Eo *obj, const char *infc, const Eld
4008 EINA_SAFETY_ON_NULL_RETURN(obj); 4071 EINA_SAFETY_ON_NULL_RETURN(obj);
4009 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 4072 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4010 4073
4011 path = _path_from_object(obj); 4074 path = _bridge_path_from_object(bridge, obj);
4012 eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, root = elm_interface_atspi_accessible_root_get());
4013 4075
4014 msg = eldbus_message_signal_new(path, infc, signal->name); 4076 msg = eldbus_message_signal_new(path, infc, signal->name);
4015 if (!msg) return; 4077 if (!msg) return;
@@ -4040,7 +4102,7 @@ static void _bridge_signal_send(Eo *bridge, Eo *obj, const char *infc, const Eld
4040 break; 4102 break;
4041 case 'o': 4103 case 'o':
4042 atspi_obj = va_arg(va, Eo*); 4104 atspi_obj = va_arg(va, Eo*);
4043 path = _path_from_object(atspi_obj); 4105 path = _bridge_path_from_object(bridge, atspi_obj);
4044 eldbus_message_iter_basic_append(iter_stack[top], 'o', path); 4106 eldbus_message_iter_basic_append(iter_stack[top], 'o', path);
4045 break; 4107 break;
4046 case ')': 4108 case ')':
@@ -4067,7 +4129,8 @@ static void _bridge_signal_send(Eo *bridge, Eo *obj, const char *infc, const Eld
4067 eldbus_message_iter_container_close(iter, iter_stack[0]); 4129 eldbus_message_iter_container_close(iter, iter_stack[0]);
4068 4130
4069 iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL); 4131 iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
4070 path = _path_from_object(root); 4132 eo_do(bridge, root = elm_obj_atspi_bridge_root_get());
4133 path = _bridge_path_from_object(bridge, root);
4071 eldbus_message_iter_basic_append(iter_struct, 's', eldbus_connection_unique_name_get(pd->a11y_bus)); 4134 eldbus_message_iter_basic_append(iter_struct, 's', eldbus_connection_unique_name_get(pd->a11y_bus));
4072 eldbus_message_iter_basic_append(iter_struct, 'o', path); 4135 eldbus_message_iter_basic_append(iter_struct, 'o', path);
4073 eldbus_message_iter_container_close(iter, iter_struct); 4136 eldbus_message_iter_container_close(iter, iter_struct);
@@ -4143,7 +4206,7 @@ _text_selection_changed_send(void *data, Eo *obj, const Eo_Event_Description *de
4143static void 4206static void
4144_event_handlers_register(Eo *bridge) 4207_event_handlers_register(Eo *bridge)
4145{ 4208{
4146 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 4209 Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(bridge, ELM_ATSPI_BRIDGE_CLASS);
4147 4210
4148 _registered_events_list_update(bridge); 4211 _registered_events_list_update(bridge);
4149 4212
@@ -4157,49 +4220,72 @@ _event_handlers_register(Eo *bridge)
4157static void 4220static void
4158_bridge_object_unregister(Eo *bridge, Eo *obj) 4221_bridge_object_unregister(Eo *bridge, Eo *obj)
4159{ 4222{
4223 Eldbus_Message *sig;
4224
4160 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 4225 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4161 4226
4227//TIZEN_ONLY(20150722) atspi: setting defunc state before unregistering object
4228 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_DEFUNCT, EINA_TRUE);
4229///
4230 _object_unregister(obj, bridge);
4231 sig = eldbus_service_signal_new(pd->cache_interface, ATSPI_OBJECT_CHILD_REMOVED);
4232 Eldbus_Message_Iter *iter = eldbus_message_iter_get(sig);
4233 _bridge_iter_object_reference_append(bridge, iter, obj);
4234 eldbus_service_signal_send(pd->cache_interface, sig);
4235
4162 eina_hash_del(pd->cache, &obj, obj); 4236 eina_hash_del(pd->cache, &obj, obj);
4163} 4237}
4164 4238
4165static Eina_Bool 4239static Eina_Bool
4166_on_object_add(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED) 4240_on_object_del(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED)
4167{ 4241{
4168 Eldbus_Message *sig; 4242 Eo *bridge = data;
4169 Eldbus_Message_Iter *iter;
4170 4243
4171 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE); 4244 _bridge_object_unregister(bridge, obj);
4172
4173 sig = eldbus_service_signal_new(pd->cache_interface, ATSPI_OBJECT_CHILD_ADDED);
4174 iter = eldbus_message_iter_get(sig);
4175 _cache_item_reference_append_cb(data, obj, iter);
4176
4177 eldbus_service_signal_send(pd->cache_interface, sig);
4178 4245
4179 return EINA_TRUE; 4246 return EINA_TRUE;
4180} 4247}
4181 4248
4182static Eina_Bool 4249static void
4183_on_object_del(void *data, Eo *obj, const Eo_Event_Description *event EINA_UNUSED, void *event_info EINA_UNUSED) 4250_bridge_cache_build(Eo *bridge, void *obj)
4184{ 4251{
4185 Eldbus_Message *sig; 4252 Eina_List *children;
4253 Elm_Atspi_State_Set ss;
4254 Eo *child;
4186 4255
4187 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE); 4256 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4257
4258 if (!eo_isa(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
4259 return;
4188 4260
4189 _bridge_object_unregister(data, obj); 4261 if (!eo_isa(obj, ELM_ATSPI_PROXY_CLASS))
4262 _bridge_object_register(bridge, obj);
4190 4263
4191 sig = eldbus_service_signal_new(pd->cache_interface, ATSPI_OBJECT_CHILD_REMOVED); 4264 eo_do(obj, ss = elm_interface_atspi_accessible_state_set_get());
4192 Eldbus_Message_Iter *iter = eldbus_message_iter_get(sig); 4265 if (STATE_TYPE_GET(ss, ELM_ATSPI_STATE_MANAGES_DESCENDANTS))
4193 _bridge_iter_object_reference_append(data, iter, obj); 4266 return;
4194 eldbus_service_signal_send(pd->cache_interface, sig); 4267 if (eo_isa(obj, ELM_INTERFACE_ATSPI_WINDOW_INTERFACE))
4268 {
4269 if (STATE_TYPE_GET(ss, ELM_ATSPI_STATE_ACTIVE))
4270 _window_signal_send(bridge, obj, ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_ACTIVATED, NULL);
4271 else
4272 _window_signal_send(bridge, obj, ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DEACTIVATED, NULL);
4273 }
4274 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
4275 EINA_LIST_FREE(children, child)
4276 _bridge_cache_build(bridge, child);
4277}
4195 4278
4279static Eina_Bool _unregister_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
4280{
4281 _object_unregister(data, fdata);
4196 return EINA_TRUE; 4282 return EINA_TRUE;
4197} 4283}
4198 4284
4199static void 4285static void
4200_interfaces_unregister(Eo *bridge) 4286_interfaces_unregister(Eo *bridge)
4201{ 4287{
4202 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 4288 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4203 4289
4204#define INTERFACE_SAFE_FREE(ifc) \ 4290#define INTERFACE_SAFE_FREE(ifc) \
4205 if (ifc) \ 4291 if (ifc) \
@@ -4221,14 +4307,17 @@ _interfaces_unregister(Eo *bridge)
4221static void 4307static void
4222_a11y_connection_shutdown(Eo *bridge) 4308_a11y_connection_shutdown(Eo *bridge)
4223{ 4309{
4224 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 4310 Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(bridge, ELM_ATSPI_BRIDGE_CLASS);
4225 Eldbus_Pending *pending; 4311 Eldbus_Pending *pending;
4226 4312
4227 if (pd->connected) 4313 if (pd->connected)
4228 _elm_atspi_bridge_app_unregister(bridge); 4314 _elm_atspi_bridge_app_unregister(bridge);
4229 4315
4230 if (pd->cache) 4316 if (pd->cache)
4231 eina_hash_free(pd->cache); 4317 {
4318 eina_hash_foreach(pd->cache, _unregister_cb, bridge);
4319 eina_hash_free(pd->cache);
4320 }
4232 pd->cache = NULL; 4321 pd->cache = NULL;
4233 4322
4234 if (pd->cache_interface) 4323 if (pd->cache_interface)
@@ -4256,12 +4345,6 @@ _a11y_connection_shutdown(Eo *bridge)
4256 if (pd->state_hash) eina_hash_free(pd->state_hash); 4345 if (pd->state_hash) eina_hash_free(pd->state_hash);
4257 pd->state_hash = NULL; 4346 pd->state_hash = NULL;
4258 4347
4259 if (pd->event_hash) eina_hash_free(pd->event_hash);
4260 pd->event_hash = NULL;
4261
4262 eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, elm_interface_atspi_accessible_event_handler_del(pd->event_hdlr));
4263 pd->event_hdlr = NULL;
4264
4265 eo_do(bridge, eo_event_callback_call(ELM_ATSPI_BRIDGE_EVENT_DISCONNECTED, NULL)); 4348 eo_do(bridge, eo_event_callback_call(ELM_ATSPI_BRIDGE_EVENT_DISCONNECTED, NULL));
4266 pd->connected = EINA_FALSE; 4349 pd->connected = EINA_FALSE;
4267} 4350}
@@ -4317,23 +4400,12 @@ _interfaces_register(Eo *bridge)
4317 eldbus_service_object_data_set(pd->interfaces.value, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge); 4400 eldbus_service_object_data_set(pd->interfaces.value, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
4318} 4401}
4319 4402
4320static Eina_Bool
4321_bridge_accessible_event_dispatch(void *data, Eo *accessible, const Eo_Event_Description *desc, void *event_info)
4322{
4323 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(data, pd, EINA_TRUE);
4324
4325 _bridge_object_register(data, accessible);
4326
4327 Eo_Event_Cb cb = eina_hash_find(pd->event_hash, &desc);
4328 return cb ? cb(data, accessible, desc, event_info) : EINA_TRUE;
4329}
4330
4331static void 4403static void
4332_a11y_bus_initialize(Eo *obj, const char *socket_addr) 4404_a11y_bus_initialize(Eo *obj, const char *socket_addr)
4333{ 4405{
4334 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(obj, pd); 4406 Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(obj, ELM_ATSPI_BRIDGE_CLASS);
4335 4407 if (!pd->a11y_bus)
4336 pd->a11y_bus = eldbus_private_address_connection_get(socket_addr); 4408 pd->a11y_bus = eldbus_private_address_connection_get(socket_addr);
4337 if (!pd->a11y_bus) 4409 if (!pd->a11y_bus)
4338 return; 4410 return;
4339 4411
@@ -4342,7 +4414,6 @@ _a11y_bus_initialize(Eo *obj, const char *socket_addr)
4342 // init data structures 4414 // init data structures
4343 pd->cache = eina_hash_pointer_new(NULL); 4415 pd->cache = eina_hash_pointer_new(NULL);
4344 pd->state_hash = _elm_atspi_state_hash_build(); 4416 pd->state_hash = _elm_atspi_state_hash_build();
4345 pd->event_hash = _elm_atspi_event_hash_build();
4346 4417
4347 // dbus init 4418 // dbus init
4348 _cache_register(obj); 4419 _cache_register(obj);
@@ -4350,15 +4421,13 @@ _a11y_bus_initialize(Eo *obj, const char *socket_addr)
4350 _event_handlers_register(obj); 4421 _event_handlers_register(obj);
4351 _elm_atspi_bridge_app_register(obj); 4422 _elm_atspi_bridge_app_register(obj);
4352 4423
4353 // register accesible object event listener
4354 eo_do(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, pd->event_hdlr = elm_interface_atspi_accessible_event_handler_add(_bridge_accessible_event_dispatch, obj));
4355} 4424}
4356 4425
4357static void 4426static void
4358_a11y_bus_address_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending) 4427_a11y_bus_address_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
4359{ 4428{
4360 const char *errname, *errmsg, *sock_addr = NULL; 4429 const char *errname, *errmsg, *sock_addr = NULL;
4361 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd); 4430 Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(data, ELM_ATSPI_BRIDGE_CLASS);
4362 4431
4363 pd->pending_requests = eina_list_remove(pd->pending_requests, pending); 4432 pd->pending_requests = eina_list_remove(pd->pending_requests, pending);
4364 4433
@@ -4379,7 +4448,7 @@ _a11y_bus_address_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pen
4379 4448
4380static void _a11y_connection_init(Eo *bridge) 4449static void _a11y_connection_init(Eo *bridge)
4381{ 4450{
4382 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 4451 Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(bridge, ELM_ATSPI_BRIDGE_CLASS);
4383 Eina_Bool is_connected; 4452 Eina_Bool is_connected;
4384 4453
4385 eo_do(bridge, is_connected = elm_obj_atspi_bridge_connected_get()); 4454 eo_do(bridge, is_connected = elm_obj_atspi_bridge_connected_get());
@@ -4396,7 +4465,7 @@ static void _a11y_connection_init(Eo *bridge)
4396static void 4465static void
4397_screen_reader_enabled_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending) 4466_screen_reader_enabled_get(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
4398{ 4467{
4399 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(data, pd); 4468 Elm_Atspi_Bridge_Data *pd = eo_data_scope_get(data, ELM_ATSPI_BRIDGE_CLASS);
4400 const char *errname, *errmsg; 4469 const char *errname, *errmsg;
4401 Eina_Bool is_enabled; 4470 Eina_Bool is_enabled;
4402 Eldbus_Message_Iter *variant; 4471 Eldbus_Message_Iter *variant;
@@ -4427,6 +4496,9 @@ _screen_reader_enabled_get(void *data, const Eldbus_Message *msg, Eldbus_Pending
4427 4496
4428static void _bridge_object_register(Eo *bridge, Eo *obj) 4497static void _bridge_object_register(Eo *bridge, Eo *obj)
4429{ 4498{
4499 struct cache_closure cc;
4500 Eldbus_Message *sig;
4501
4430 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 4502 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4431 4503
4432 if (!eo_isa(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN)) 4504 if (!eo_isa(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
@@ -4436,9 +4508,41 @@ static void _bridge_object_register(Eo *bridge, Eo *obj)
4436 } 4508 }
4437 4509
4438 if (eina_hash_find(pd->cache, &obj)) 4510 if (eina_hash_find(pd->cache, &obj))
4511 {
4512 WRN("Object %p already registered", obj);
4439 return; 4513 return;
4514 }
4440 4515
4441 eina_hash_add(pd->cache, &obj, obj); 4516 eina_hash_add(pd->cache, &obj, obj);
4517
4518 eo_do(obj, eo_event_callback_array_add(_events_cb(), bridge));
4519
4520 if (eo_isa(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE))
4521 eo_do(obj, eo_event_callback_array_add(_selection_cb(), bridge));
4522
4523 if (eo_isa(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE))
4524 eo_do(obj, eo_event_callback_array_add(_text_cb(), bridge));
4525
4526 if (eo_isa(obj, ELM_INTERFACE_ATSPI_WINDOW_INTERFACE))
4527 eo_do(obj, eo_event_callback_array_add(_window_cb(), bridge));
4528
4529 sig = eldbus_service_signal_new(pd->cache_interface, ATSPI_OBJECT_CHILD_ADDED);
4530 cc.iter = eldbus_message_iter_get(sig);
4531 cc.bridge = bridge;
4532 _cache_item_reference_append_cb(NULL, NULL, obj, &cc);
4533
4534 eldbus_service_signal_send(pd->cache_interface, sig);
4535}
4536
4537static void _object_unregister(Eo *obj, void *data)
4538{
4539 eo_do(obj, eo_event_callback_array_del(_events_cb(), data));
4540 if (eo_isa(obj, ELM_INTERFACE_ATSPI_WINDOW_INTERFACE))
4541 eo_do(obj, eo_event_callback_array_del(_window_cb(), data));
4542 if (eo_isa(obj, ELM_INTERFACE_ATSPI_SELECTION_INTERFACE))
4543 eo_do(obj, eo_event_callback_array_del(_selection_cb(), data));
4544 if (eo_isa(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE))
4545 eo_do(obj, eo_event_callback_array_del(_text_cb(), data));
4442} 4546}
4443 4547
4444void 4548void
@@ -4473,7 +4577,7 @@ _key_event_info_new(int event_type, const Ecore_Event_Key *data, Eo *bridge)
4473 Key_Event_Info *ret; 4577 Key_Event_Info *ret;
4474 EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL); 4578 EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL);
4475 4579
4476 ret = calloc(1, sizeof(Key_Event_Info)); 4580 ret = calloc(sizeof(Key_Event_Info), 1);
4477 4581
4478 ret->type = event_type; 4582 ret->type = event_type;
4479 ret->event = *data; 4583 ret->event = *data;
@@ -4483,7 +4587,6 @@ _key_event_info_new(int event_type, const Ecore_Event_Key *data, Eo *bridge)
4483 ret->event.key = eina_stringshare_add(data->key); 4587 ret->event.key = eina_stringshare_add(data->key);
4484 ret->event.string = eina_stringshare_add(data->string); 4588 ret->event.string = eina_stringshare_add(data->string);
4485 ret->event.compose = eina_stringshare_add(data->compose); 4589 ret->event.compose = eina_stringshare_add(data->compose);
4486 ret->event.modifiers = data->modifiers;
4487 4590
4488 // not sure why it is here, but explicite keep it NULLed. 4591 // not sure why it is here, but explicite keep it NULLed.
4489 ret->event.data = NULL; 4592 ret->event.data = NULL;
@@ -4504,27 +4607,6 @@ _key_event_info_free(Key_Event_Info *data)
4504 free(data); 4607 free(data);
4505} 4608}
4506 4609
4507static short
4508_ecore_modifiers_2_atspi(unsigned int modifiers)
4509{
4510 short ret = 0;
4511
4512 if (modifiers & ECORE_EVENT_MODIFIER_SHIFT)
4513 ret |= (1 << ATSPI_MODIFIER_SHIFT);
4514 if (modifiers & ECORE_EVENT_MODIFIER_CAPS)
4515 ret |= (1 << ATSPI_MODIFIER_SHIFTLOCK);
4516 if (modifiers & ECORE_EVENT_MODIFIER_CTRL)
4517 ret |= (1 << ATSPI_MODIFIER_CONTROL);
4518 if (modifiers & ECORE_EVENT_MODIFIER_ALT)
4519 ret |= (1 << ATSPI_MODIFIER_ALT);
4520 if (modifiers & ECORE_EVENT_MODIFIER_WIN)
4521 ret |= (1 << ATSPI_MODIFIER_META);
4522 if (modifiers & ECORE_EVENT_MODIFIER_NUM)
4523 ret |= (1 << ATSPI_MODIFIER_NUMLOCK);
4524
4525 return ret;
4526}
4527
4528static void 4610static void
4529_iter_marshall_key_event(Eldbus_Message_Iter *iter, Key_Event_Info *data) 4611_iter_marshall_key_event(Eldbus_Message_Iter *iter, Key_Event_Info *data)
4530{ 4612{
@@ -4541,7 +4623,7 @@ _iter_marshall_key_event(Eldbus_Message_Iter *iter, Key_Event_Info *data)
4541 else 4623 else
4542 type = ATSPI_KEY_RELEASED_EVENT; 4624 type = ATSPI_KEY_RELEASED_EVENT;
4543 4625
4544 eldbus_message_iter_arguments_append(struct_iter, "uinnisb", type, 0, data->event.keycode, _ecore_modifiers_2_atspi(data->event.modifiers), data->event.timestamp, str, is_text); 4626 eldbus_message_iter_arguments_append(struct_iter, "uiiiisb", type, 0, data->event.keycode, 0, data->event.timestamp, str, is_text);
4545 eldbus_message_iter_container_close(iter, struct_iter); 4627 eldbus_message_iter_container_close(iter, struct_iter);
4546} 4628}
4547 4629
@@ -4622,6 +4704,15 @@ _elm_atspi_bridge_connected_get(Eo *obj EINA_UNUSED, Elm_Atspi_Bridge_Data *pd)
4622 return pd->connected; 4704 return pd->connected;
4623} 4705}
4624 4706
4707EOLIAN Eo*
4708_elm_atspi_bridge_root_get(Eo *obj EINA_UNUSED, Elm_Atspi_Bridge_Data *pd)
4709{
4710 if (!pd->root)
4711 pd->root = eo_add(ELM_ATSPI_APP_OBJECT_CLASS, NULL);
4712
4713 return pd->root;
4714}
4715
4625static void 4716static void
4626_properties_changed_cb(void *data, Eldbus_Proxy *proxy EINA_UNUSED, void *event) 4717_properties_changed_cb(void *data, Eldbus_Proxy *proxy EINA_UNUSED, void *event)
4627{ 4718{
@@ -4644,7 +4735,7 @@ _properties_changed_cb(void *data, Eldbus_Proxy *proxy EINA_UNUSED, void *event)
4644 } 4735 }
4645} 4736}
4646 4737
4647EOLIAN Eo_Base* 4738EOLIAN void
4648_elm_atspi_bridge_eo_base_constructor(Eo *obj, Elm_Atspi_Bridge_Data *pd) 4739_elm_atspi_bridge_eo_base_constructor(Eo *obj, Elm_Atspi_Bridge_Data *pd)
4649{ 4740{
4650 Eldbus_Proxy *proxy; 4741 Eldbus_Proxy *proxy;
@@ -4657,7 +4748,7 @@ _elm_atspi_bridge_eo_base_constructor(Eo *obj, Elm_Atspi_Bridge_Data *pd)
4657 if (!(pd->session_bus = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION))) 4748 if (!(pd->session_bus = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION)))
4658 { 4749 {
4659 ERR("Unable to connect to Session Bus"); 4750 ERR("Unable to connect to Session Bus");
4660 return NULL; 4751 return;
4661 } 4752 }
4662 if (!(pd->bus_obj = eldbus_object_get(pd->session_bus, A11Y_DBUS_NAME, A11Y_DBUS_PATH))) 4753 if (!(pd->bus_obj = eldbus_object_get(pd->session_bus, A11Y_DBUS_NAME, A11Y_DBUS_PATH)))
4663 { 4754 {
@@ -4680,7 +4771,7 @@ _elm_atspi_bridge_eo_base_constructor(Eo *obj, Elm_Atspi_Bridge_Data *pd)
4680 eldbus_proxy_event_callback_add(proxy, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED, 4771 eldbus_proxy_event_callback_add(proxy, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
4681 _properties_changed_cb, obj); 4772 _properties_changed_cb, obj);
4682 4773
4683 return obj; 4774 return;
4684 4775
4685proxy_err: 4776proxy_err:
4686 eldbus_object_unref(pd->bus_obj); 4777 eldbus_object_unref(pd->bus_obj);
@@ -4688,7 +4779,7 @@ proxy_err:
4688obj_err: 4779obj_err:
4689 eldbus_connection_unref(pd->session_bus); 4780 eldbus_connection_unref(pd->session_bus);
4690 pd->session_bus = NULL; 4781 pd->session_bus = NULL;
4691 return NULL; 4782 return;
4692} 4783}
4693 4784
4694EOLIAN void 4785EOLIAN void
@@ -4698,8 +4789,224 @@ _elm_atspi_bridge_eo_base_destructor(Eo *obj, Elm_Atspi_Bridge_Data *pd)
4698 4789
4699 if (pd->bus_obj) eldbus_object_unref(pd->bus_obj); 4790 if (pd->bus_obj) eldbus_object_unref(pd->bus_obj);
4700 if (pd->session_bus) eldbus_connection_unref(pd->session_bus); 4791 if (pd->session_bus) eldbus_connection_unref(pd->session_bus);
4792 if (pd->root) eo_del(pd->root);
4793 if (pd->socket_queue) eina_list_free(pd->socket_queue);
4794 if (pd->plug_queue) eina_list_free(pd->plug_queue);
4701 4795
4702 eo_do_super(obj, ELM_ATSPI_BRIDGE_CLASS, eo_destructor()); 4796 eo_do_super(obj, ELM_ATSPI_BRIDGE_CLASS, eo_destructor());
4703} 4797}
4704 4798
4799EAPI Eina_Bool
4800elm_atspi_bridge_object_address_get(Eo *obj, char **bus, char **path)
4801{
4802 Eo *bridge = _elm_atspi_bridge_get();
4803 if (!bridge)
4804 {
4805 ERR("Connection with accessibility bus not established.");
4806 return EINA_FALSE;
4807 }
4808 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_FALSE);
4809 if (!eo_isa(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
4810 {
4811 ERR("Connection with accessibility bus not established.");
4812 return EINA_FALSE;
4813 }
4814 if (bus) *bus = strdup(eldbus_connection_unique_name_get(pd->a11y_bus));
4815 if (path) *path = strdup(_bridge_path_from_object(bridge, obj));
4816
4817 return EINA_TRUE;
4818}
4819
4820static void _embedded_reply_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
4821{
4822 Eo *parent, *proxy = data;
4823 const char *err, *txt;
4824
4825 if (eldbus_message_error_get(msg, &err, &txt))
4826 {
4827 ERR("AT-SPI: Embedded method call failed: %s %s", err, txt);
4828 eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_DISCONNECTED, NULL));
4829 return;
4830 }
4831 eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_CONNECTED, NULL));
4832
4833 eo_do(proxy, parent = eo_parent_get());
4834 if (parent)
4835 elm_interface_atspi_accessible_children_changed_added_signal_emit(parent, proxy)
4836}
4837
4838static void
4839_plug_embedded_send(Eldbus_Connection *conn, Eo *proxy, const char *bus, const char *path)
4840{
4841 char *obj_path = NULL;
4842 Eo *parent;
4843 Eldbus_Message *msg = NULL;
4844
4845 eo_do(proxy, parent = eo_parent_get());
4846 if (!parent) goto fail;
4847
4848 msg = eldbus_message_method_call_new(bus, path, ATSPI_DBUS_INTERFACE_SOCKET, "Embedded");
4849 if (!msg) goto fail;
4850
4851 if (!elm_atspi_bridge_object_address_get(parent, NULL, &obj_path))
4852 goto fail;
4853
4854 if (!eldbus_message_arguments_append(msg, "s", obj_path))
4855 goto fail;
4856
4857 if (!eldbus_connection_send(conn, msg, _embedded_reply_cb, proxy, 100))
4858 goto fail;
4859
4860 free(obj_path);
4861
4862 return;
4863
4864fail:
4865 ERR("AT-SPI: Unable to send Embedded request.");
4866 if (msg) eldbus_message_unref(msg);
4867 free(obj_path);
4868 eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_DISCONNECTED, NULL));
4869}
4870
4871static void _plug_connect(Eldbus_Connection *conn, Eo *proxy)
4872{
4873 const char *bus, *path;
4874
4875 eo_do(proxy, elm_obj_atspi_proxy_address_get(&bus, &path));
4876
4877 if (!bus || !path)
4878 {
4879 ERR("AT-SPI: Elm_Atspi_Proxy bus or path not set. Unable to connect");
4880 eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_DISCONNECTED, NULL));
4881 return;
4882 }
4883 _plug_embedded_send(conn, proxy, bus, path);
4884}
4885
4886static Eina_Bool _from_list_remove(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
4887{
4888 Eina_List **list = data;
4889 *list = eina_list_remove(*list, obj);
4890 return EINA_TRUE;
4891}
4892
4893EAPI void elm_atspi_bridge_utils_proxy_connect(Eo *proxy)
4894{
4895 Eo *bridge = _elm_atspi_bridge_get();
4896
4897 if (!bridge)
4898 {
4899 ERR("AT-SPI: Atspi bridge is not enabled.");
4900 eo_do(proxy, eo_event_callback_call(ELM_ATSPI_PROXY_EVENT_DISCONNECTED, NULL));
4901 return;
4902 }
4903 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4904
4905 if (!pd->a11y_bus)
4906 {
4907 if (!eina_list_data_find(pd->plug_queue, proxy))
4908 {
4909 pd->plug_queue = eina_list_append(pd->plug_queue, proxy);
4910 eo_do(proxy, eo_event_callback_add(EO_EV_DEL, _from_list_remove, &pd->plug_queue));
4911 }
4912 return;
4913 }
4914 _plug_connect(pd->a11y_bus, proxy);
4915}
4916
4917static Eldbus_Message *
4918_socket_embedded(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
4919{
4920 Eo *proxy;
4921 const char *obj_path = eldbus_service_object_path_get(iface);
4922 const char *bus, *path;
4923 Eo *bridge = _elm_atspi_bridge_get();
4924 Eo *obj = _bridge_object_from_path(bridge, obj_path);
4925 eo_do(obj, proxy = elm_interface_atspi_accessible_parent_get());
4926
4927 if (!eo_isa(proxy, ELM_ATSPI_PROXY_CLASS))
4928 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.Failed", "Unable to embed object.");
4929
4930 if (!eldbus_message_arguments_get(msg, "s", &path))
4931 return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Plug id expected.");
4932
4933 bus = eldbus_message_sender_get(msg);
4934
4935 eo_do(proxy, elm_obj_atspi_proxy_address_set(bus, path));
4936
4937 _bridge_cache_build(bridge, proxy);
4938
4939 return eldbus_message_method_return_new(msg);
4940}
4941
4942static const Eldbus_Method socket_methods[] = {
4943 { "Embedded", ELDBUS_ARGS({"s", "id"}), ELDBUS_ARGS({NULL, NULL}), _socket_embedded, 0 },
4944 { NULL, NULL, NULL, NULL, 0 }
4945};
4946
4947static const Eldbus_Service_Interface_Desc socket_iface_desc = {
4948 ATSPI_DBUS_INTERFACE_SOCKET, socket_methods, NULL, NULL, NULL, NULL
4949};
4950
4951static void _socket_interface_register(Eldbus_Connection *conn, Eo *proxy)
4952{
4953 Eo *parent;
4954 Eo *bridge = _elm_atspi_bridge_get();
4955
4956 eo_do(proxy, parent = eo_parent_get());
4957 if (!eo_isa(parent, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
4958 return;
4959
4960 const char *path = _bridge_path_from_object(bridge, parent);
4961 eldbus_service_interface_register(conn, path, &socket_iface_desc);
4962}
4963
4964EAPI void elm_atspi_bridge_utils_proxy_listen(Eo *proxy)
4965{
4966 Eo *bridge = _elm_atspi_bridge_get();
4967 if (!bridge)
4968 {
4969 ERR("AT-SPI: Atspi bridge is not enabled.");
4970 return;
4971 }
4972 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4973 if (!pd->a11y_bus)
4974 {
4975 if (!eina_list_data_find(pd->socket_queue, proxy))
4976 {
4977 pd->socket_queue = eina_list_append(pd->socket_queue, proxy);
4978 eo_do(proxy, eo_event_callback_add(EO_EV_DEL, _from_list_remove, &pd->socket_queue));
4979 }
4980 return;
4981 }
4982 _socket_interface_register(pd->a11y_bus, proxy);
4983}
4984
4985Eina_Bool
4986_elm_atspi_bridge_plug_id_split(const char *plug_id, char **bus, char **path)
4987{
4988 if (!plug_id || !strcmp(plug_id, "")) return EINA_FALSE;
4989 unsigned int tokens = 0;
4990 char **split = eina_str_split_full(plug_id, ":", 0, &tokens);
4991 Eina_Bool ret = EINA_FALSE;
4992 if (tokens == 2)
4993 {
4994 if (bus) *bus = strdup(split[1]);
4995 if (path) *path = strdup(split[2]);
4996 ret = EINA_TRUE;
4997 }
4998 else if (tokens == 3)
4999 {
5000 char buf[128];
5001 snprintf(buf, sizeof(buf), ":%s", split[1]);
5002 if (bus) *bus = strdup(buf);
5003 if (path) *path = strdup(split[2]);
5004 ret = EINA_TRUE;
5005 }
5006
5007 free(split[0]);
5008 free(split);
5009 return ret;
5010}
5011
4705#include "elm_atspi_bridge.eo.c" 5012#include "elm_atspi_bridge.eo.c"
diff --git a/src/lib/elm_atspi_proxy.c b/src/lib/elm_atspi_proxy.c
new file mode 100644
index 000000000..3aac6d589
--- /dev/null
+++ b/src/lib/elm_atspi_proxy.c
@@ -0,0 +1,101 @@
1#ifdef HAVE_CONFIG_H
2 #include "elementary_config.h"
3#endif
4
5#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
6
7#include <Elementary.h>
8#include "elm_widget.h"
9#include "elm_priv.h"
10
11
12static Eina_List *_socket_list;
13
14typedef struct _Elm_Atspi_Proxy_Data Elm_Atspi_Proxy_Data;
15
16struct _Elm_Atspi_Proxy_Data
17{
18 Elm_Atspi_Proxy_Type type;
19 const char *bus;
20 const char *path;
21};
22
23EOLIAN static void
24_elm_atspi_proxy_eo_base_destructor(Eo *obj, Elm_Atspi_Proxy_Data *_pd)
25{
26 if (_pd->type == ELM_ATSPI_PROXY_TYPE_SOCKET)
27 _socket_list = eina_list_remove(_socket_list, obj);
28
29 if (_pd->bus) eina_stringshare_del(_pd->bus);
30 if (_pd->path) eina_stringshare_del(_pd->path);
31
32 eo_do_super(obj, ELM_ATSPI_PROXY_CLASS, eo_destructor());
33}
34
35EOLIAN static void
36_elm_atspi_proxy_constructor(Eo *obj, Elm_Atspi_Proxy_Data *_pd, Elm_Atspi_Proxy_Type type)
37{
38 Eo *parent;
39
40 _pd->type = type;
41 eo_do(obj, parent = eo_parent_get());
42 if (!parent || !eo_isa(parent, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
43 {
44 CRI("Elm_Atspi_Proxy parent (%s) must implement ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN", eo_class_name_get(eo_class_get(parent)));
45 abort();
46 }
47 if (type == ELM_ATSPI_PROXY_TYPE_SOCKET)
48 _socket_list = eina_list_append(_socket_list, obj);
49}
50
51EOLIAN Elm_Atspi_Proxy_Type
52_elm_atspi_proxy_type_get(Eo *obj EINA_UNUSED, Elm_Atspi_Proxy_Data *_pd)
53{
54 return _pd->type;
55}
56
57EOLIAN void
58_elm_atspi_proxy_address_get(Eo *obj EINA_UNUSED, Elm_Atspi_Proxy_Data *_pd, const char **bus, const char **path)
59{
60 if (bus) *bus = _pd->bus;
61 if (path) *path = _pd->path;
62}
63
64EOLIAN void
65_elm_atspi_proxy_address_set(Eo *obj EINA_UNUSED, Elm_Atspi_Proxy_Data *_pd, const char *bus, const char *path)
66{
67 if (bus) eina_stringshare_replace(&_pd->bus, bus);
68 if (path) eina_stringshare_replace(&_pd->path, path);
69}
70
71EOLIAN Eina_List*
72_elm_atspi_proxy_elm_interface_atspi_accessible_children_get(Eo *obj EINA_UNUSED, Elm_Atspi_Proxy_Data *_pd)
73{
74 Eina_List *ret = NULL;
75 if (_pd->type == ELM_ATSPI_PROXY_TYPE_SOCKET)
76 {
77 Eo *parent;
78 eo_do(obj, parent = eo_parent_get());
79 ret = eina_list_append(ret, parent);
80 }
81 return ret;
82}
83
84EOLIAN Eo*
85_elm_atspi_proxy_elm_interface_atspi_accessible_parent_get(Eo *obj EINA_UNUSED, Elm_Atspi_Proxy_Data *_pd)
86{
87 Eo *ret = NULL;
88 if (_pd->type == ELM_ATSPI_PROXY_TYPE_PLUG)
89 {
90 eo_do(obj, ret = eo_parent_get());
91 }
92 return ret;
93}
94
95Eina_List*
96_elm_atspi_proxy_socket_list_get(void)
97{
98 return eina_list_clone(_socket_list);
99}
100
101#include "elm_atspi_proxy.eo.c"
diff --git a/src/lib/elm_atspi_proxy.eo b/src/lib/elm_atspi_proxy.eo
new file mode 100644
index 000000000..1085dfb32
--- /dev/null
+++ b/src/lib/elm_atspi_proxy.eo
@@ -0,0 +1,44 @@
1class Elm_Atspi_Proxy (Eo.Base, Elm_Interface_Atspi_Accessible)
2{
3 eo_prefix: elm_obj_atspi_proxy;
4 data: Elm_Atspi_Proxy_Data;
5 properties {
6 address {
7 set {
8 }
9 get {
10 }
11 values {
12 const(char)* bus;
13 const(char)* path;
14 }
15 }
16 type {
17 get {
18 }
19 values {
20 Elm_Atspi_Proxy_Type ret;
21 }
22 }
23 }
24 methods {
25 constructor {
26 /*@ No description supplied by the EAPI. */
27 params {
28 @in Elm_Atspi_Proxy_Type type;
29 }
30 }
31 }
32 constructors {
33 .constructor;
34 }
35 implements {
36 Eo.Base.destructor;
37 Elm_Interface_Atspi_Accessible.children.get;
38 Elm_Interface_Atspi_Accessible.parent.get;
39 }
40 events {
41 connected;
42 disconnected;
43 }
44}