summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Stanislawski <l.stanislaws@samsung.com>2017-06-14 17:09:12 +0200
committerLukasz Stanislawski <l.stanislaws@samsung.com>2017-06-16 08:51:15 +0200
commit56b1843ac11258bc1ce9ecfa66eeb1bb47a29b21 (patch)
tree8dca827f3011070449033eaed7a88a6a89e4f84a
parent99010452cc2c78dc2fb51abb469dc086d744ae01 (diff)
elementary: move keyboard event forwarding out of bridge
Change-Id: I6467b70489cad348a27ff871c72652cc793e6a38
-rw-r--r--src/Makefile_Elementary.am3
-rw-r--r--src/lib/elementary/elm_atspi_bridge.c189
-rw-r--r--src/lib/elementary/elm_atspi_device_event_controller.c273
-rw-r--r--src/lib/elementary/elm_atspi_device_event_controller.eo21
-rw-r--r--src/lib/elementary/elm_atspi_event_controller.c0
5 files changed, 308 insertions, 178 deletions
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index dbb8c6841c..4f20a7e935 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -147,6 +147,7 @@ elm_legacy_eolian_files = \
147 lib/elementary/elm_access.eo \ 147 lib/elementary/elm_access.eo \
148 lib/elementary/elm_actionslider.eo \ 148 lib/elementary/elm_actionslider.eo \
149 lib/elementary/elm_atspi_status_monitor.eo \ 149 lib/elementary/elm_atspi_status_monitor.eo \
150 lib/elementary/elm_atspi_device_event_controller.eo \
150 lib/elementary/elm_box.eo \ 151 lib/elementary/elm_box.eo \
151 lib/elementary/elm_bubble.eo \ 152 lib/elementary/elm_bubble.eo \
152 lib/elementary/elm_diskselector.eo \ 153 lib/elementary/elm_diskselector.eo \
@@ -568,7 +569,7 @@ lib_elementary_libelementary_la_SOURCES = \
568 lib/elementary/elm_atspi_app_object.c \ 569 lib/elementary/elm_atspi_app_object.c \
569 lib/elementary/elm_atspi_bridge.c \ 570 lib/elementary/elm_atspi_bridge.c \
570 lib/elementary/elm_atspi_cache.c \ 571 lib/elementary/elm_atspi_cache.c \
571 lib/elementary/elm_atspi_event_controller.c \ 572 lib/elementary/elm_atspi_device_event_controller.c \
572 lib/elementary/elm_atspi_plug.c \ 573 lib/elementary/elm_atspi_plug.c \
573 lib/elementary/elm_atspi_proxy.c \ 574 lib/elementary/elm_atspi_proxy.c \
574 lib/elementary/elm_atspi_socket.c \ 575 lib/elementary/elm_atspi_socket.c \
diff --git a/src/lib/elementary/elm_atspi_bridge.c b/src/lib/elementary/elm_atspi_bridge.c
index cb92b0618f..6c32834901 100644
--- a/src/lib/elementary/elm_atspi_bridge.c
+++ b/src/lib/elementary/elm_atspi_bridge.c
@@ -21,14 +21,12 @@
21//FIXME 21//FIXME
22#include "elm_atspi_status_monitor.eo.h" 22#include "elm_atspi_status_monitor.eo.h"
23#include "elm_atspi_status_monitor.eo.legacy.h" 23#include "elm_atspi_status_monitor.eo.legacy.h"
24#include "elm_atspi_device_event_controller.eo.h"
25#include "elm_atspi_device_event_controller.eo.legacy.h"
24 26
25/* 27/*
26 * Accessibility Bus info not defined in atspi-constants.h 28 * Accessibility Bus info not defined in atspi-constants.h
27 */ 29 */
28#define A11Y_DBUS_NAME "org.a11y.Bus"
29#define A11Y_DBUS_PATH "/org/a11y/bus"
30#define A11Y_DBUS_INTERFACE "org.a11y.Bus"
31#define A11Y_DBUS_STATUS_INTERFACE "org.a11y.Status"
32#define ATSPI_DBUS_INTERFACE_EVENT_WINDOW "org.a11y.atspi.Event.Window" 30#define ATSPI_DBUS_INTERFACE_EVENT_WINDOW "org.a11y.atspi.Event.Window"
33 31
34#define CACHE_ITEM_SIGNATURE "((so)(so)(so)a(so)assusau)" 32#define CACHE_ITEM_SIGNATURE "((so)(so)(so)a(so)assusau)"
@@ -61,24 +59,16 @@
61 if (!(obj) || !efl_isa(obj, class)) \ 59 if (!(obj) || !efl_isa(obj, class)) \
62 return _dbus_invalid_ref_error_new(msg); 60 return _dbus_invalid_ref_error_new(msg);
63 61
64typedef struct Key_Event_Info {
65 Ecore_Event_Key event;
66 int type;
67 Eo *bridge;
68} Key_Event_Info;
69
70typedef struct _Elm_Atspi_Bridge_Data 62typedef struct _Elm_Atspi_Bridge_Data
71{ 63{
72 Elm_Atspi_Status_Monitor *monitor; 64 Elm_Atspi_Status_Monitor *monitor;
65 Elm_Atspi_Device_Event_Controller *device_event_controller;
73 66
74 // bridge 67 // connection
75 Eldbus_Connection *a11y_bus; 68 Eldbus_Connection *a11y_bus;
76 69
77 // device controller
78 Eina_List *reemited_events;
79 Eldbus_Signal_Handler *register_hdl; 70 Eldbus_Signal_Handler *register_hdl;
80 Eldbus_Signal_Handler *unregister_hdl; 71 Eldbus_Signal_Handler *unregister_hdl;
81 Ecore_Event_Filter *key_flr;
82 72
83 // cache 73 // cache
84 Eina_Hash *cache; 74 Eina_Hash *cache;
@@ -107,9 +97,6 @@ typedef struct _Elm_Atspi_Bridge_Data
107 } interfaces; 97 } interfaces;
108 Elm_Interface_Atspi_Accessible *root; 98 Elm_Interface_Atspi_Accessible *root;
109 Eina_List *plugs; 99 Eina_List *plugs;
110 Eldbus_Pending *connect_request;
111 Eldbus_Pending *stack_status_request;
112 Eldbus_Proxy *status_proxy;
113 Eina_List *pending_requests; 100 Eina_List *pending_requests;
114 Eina_Bool connected : 1; 101 Eina_Bool connected : 1;
115 Eina_Bool activated : 1; 102 Eina_Bool activated : 1;
@@ -174,7 +161,6 @@ static void _bridge_object_removed_signal_send(Elm_Atspi_Bridge *bridge, Elm_Int
174 161
175// utility functions 162// utility functions
176static void _iter_interfaces_append(Eldbus_Message_Iter *iter, const Eo *obj); 163static void _iter_interfaces_append(Eldbus_Message_Iter *iter, const Eo *obj);
177static Eina_Bool _elm_atspi_bridge_key_filter(void *data, void *loop, int type, void *event);
178static Eina_Bool _id_parse(const char *id, struct dbus_address *addr); 164static Eina_Bool _id_parse(const char *id, struct dbus_address *addr);
179static char *_id_make(const struct dbus_address *addr); 165static char *_id_make(const struct dbus_address *addr);
180static void _socket_hooks_install(Elm_Atspi_Socket *socket); 166static void _socket_hooks_install(Elm_Atspi_Socket *socket);
@@ -4172,8 +4158,6 @@ _bridge_event_handlers_register(Eo *bridge)
4172 // register signal handlers in order to update list of registered listeners of ATSPI-Clients 4158 // register signal handlers in order to update list of registered listeners of ATSPI-Clients
4173 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); 4159 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);
4174 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); 4160 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);
4175
4176 pd->key_flr = ecore_event_filter_add(NULL, _elm_atspi_bridge_key_filter, NULL, bridge);
4177} 4161}
4178 4162
4179static void 4163static void
@@ -4519,155 +4503,6 @@ _elm_atspi_bridge_shutdown(Eina_Bool force_destroy)
4519 } 4503 }
4520} 4504}
4521 4505
4522static Key_Event_Info*
4523_key_event_info_new(int event_type, const Ecore_Event_Key *data, Eo *bridge)
4524{
4525 Key_Event_Info *ret;
4526 EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL);
4527
4528 ret = calloc(1, sizeof(Key_Event_Info));
4529
4530 ret->type = event_type;
4531 ret->event = *data;
4532 ret->bridge = bridge;
4533
4534 ret->event.keyname = eina_stringshare_add(data->keyname);
4535 ret->event.key = eina_stringshare_add(data->key);
4536 ret->event.string = eina_stringshare_add(data->string);
4537 ret->event.compose = eina_stringshare_add(data->compose);
4538 ret->event.modifiers = data->modifiers;
4539
4540 // not sure why it is here, but explicite keep it NULLed.
4541 ret->event.data = NULL;
4542
4543 return ret;
4544}
4545
4546static void
4547_key_event_info_free(Key_Event_Info *data)
4548{
4549 EINA_SAFETY_ON_NULL_RETURN(data);
4550
4551 eina_stringshare_del(data->event.keyname);
4552 eina_stringshare_del(data->event.key);
4553 eina_stringshare_del(data->event.string);
4554 eina_stringshare_del(data->event.compose);
4555
4556 free(data);
4557}
4558
4559static short
4560_ecore_modifiers_2_atspi(unsigned int modifiers)
4561{
4562 short ret = 0;
4563
4564 if (modifiers & ECORE_EVENT_MODIFIER_SHIFT)
4565 ret |= (1 << ATSPI_MODIFIER_SHIFT);
4566 if (modifiers & ECORE_EVENT_MODIFIER_CAPS)
4567 ret |= (1 << ATSPI_MODIFIER_SHIFTLOCK);
4568 if (modifiers & ECORE_EVENT_MODIFIER_CTRL)
4569 ret |= (1 << ATSPI_MODIFIER_CONTROL);
4570 if (modifiers & ECORE_EVENT_MODIFIER_ALT)
4571 ret |= (1 << ATSPI_MODIFIER_ALT);
4572 if (modifiers & ECORE_EVENT_MODIFIER_WIN)
4573 ret |= (1 << ATSPI_MODIFIER_META);
4574 if (modifiers & ECORE_EVENT_MODIFIER_NUM)
4575 ret |= (1 << ATSPI_MODIFIER_NUMLOCK);
4576
4577 return ret;
4578}
4579
4580static void
4581_iter_marshall_key_event(Eldbus_Message_Iter *iter, Key_Event_Info *data)
4582{
4583 Eldbus_Message_Iter *struct_iter;
4584 EINA_SAFETY_ON_NULL_RETURN(data);
4585
4586 struct_iter = eldbus_message_iter_container_new(iter, 'r', NULL);
4587
4588 const char *str = data->event.keyname ? data->event.keyname : "";
4589 int is_text = data->event.keyname ? 1 : 0;
4590 int type;
4591 if (data->type == ECORE_EVENT_KEY_DOWN)
4592 type = ATSPI_KEY_PRESSED_EVENT;
4593 else
4594 type = ATSPI_KEY_RELEASED_EVENT;
4595
4596 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);
4597 eldbus_message_iter_container_close(iter, struct_iter);
4598}
4599
4600static void
4601_on_event_del(void *user_data, void *func_data EINA_UNUSED)
4602{
4603 Key_Event_Info *info = user_data;
4604 _key_event_info_free(info);
4605}
4606
4607static void
4608_on_listener_answer(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
4609{
4610 Key_Event_Info *info = data;
4611 const char *errname, *errmsg;
4612 Eina_Bool ret = EINA_TRUE;
4613
4614 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(info->bridge, pd);
4615
4616 if (eldbus_message_error_get(msg, &errname, &errmsg))
4617 {
4618 ERR("%s %s", errname, errmsg);
4619 goto reemit;
4620 }
4621 if (!eldbus_message_arguments_get(msg, "b", &ret))
4622 {
4623 ERR("Return message doen not contian return value");
4624 goto reemit;
4625 }
4626 if (ret)
4627 {
4628 _key_event_info_free(info);
4629 return;
4630 }
4631reemit:
4632 ecore_event_add(info->type, &info->event, _on_event_del, info);
4633 pd->reemited_events = eina_list_append(pd->reemited_events, &info->event);
4634}
4635
4636static Eina_Bool
4637_elm_atspi_bridge_key_filter(void *data, void *loop EINA_UNUSED, int type, void *event)
4638{
4639 Eldbus_Message *msg;
4640 Eldbus_Message_Iter *iter;
4641 Ecore_Event_Key *key_event = event;
4642 Key_Event_Info *ke;
4643 Eo *bridge = data;
4644
4645 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, EINA_TRUE);
4646
4647 if ((type != ECORE_EVENT_KEY_DOWN) && (type != ECORE_EVENT_KEY_UP)) return EINA_TRUE;
4648
4649 // check if reemited
4650 if (eina_list_data_find(pd->reemited_events, event))
4651 {
4652 pd->reemited_events = eina_list_remove(pd->reemited_events, event);
4653 return EINA_TRUE;
4654 }
4655
4656 ke = _key_event_info_new(type, key_event, bridge);
4657 if (!ke) return EINA_TRUE;
4658
4659 msg = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_DEC,
4660 ATSPI_DBUS_INTERFACE_DEC, "NotifyListenersSync");
4661 iter = eldbus_message_iter_get(msg);
4662 _iter_marshall_key_event(iter, ke);
4663
4664 // timeout should be kept reasonaby low to avoid delays
4665 if (!eldbus_connection_send(pd->a11y_bus, msg, _on_listener_answer, ke, 100))
4666 return EINA_TRUE;
4667
4668 return EINA_FALSE;
4669}
4670
4671EOLIAN Eina_Bool 4506EOLIAN Eina_Bool
4672_elm_atspi_bridge_connected_get(Eo *obj EINA_UNUSED, Elm_Atspi_Bridge_Data *pd) 4507_elm_atspi_bridge_connected_get(Eo *obj EINA_UNUSED, Elm_Atspi_Bridge_Data *pd)
4673{ 4508{
@@ -4873,7 +4708,7 @@ _bridge_connect(Elm_Atspi_Bridge *bridge)
4873{ 4708{
4874 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 4709 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4875 4710
4876 if (pd->connected || pd->connect_request) 4711 if (pd->connected)
4877 return; 4712 return;
4878 4713
4879 _bridge_connection_init(bridge, elm_atspi_status_monitor_address_get(pd->monitor)); 4714 _bridge_connection_init(bridge, elm_atspi_status_monitor_address_get(pd->monitor));
@@ -4884,12 +4719,6 @@ _bridge_disconnect(Elm_Atspi_Bridge *bridge)
4884{ 4719{
4885 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 4720 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4886 4721
4887 if (pd->connect_request)
4888 {
4889 eldbus_pending_cancel(pd->connect_request);
4890 pd->connect_request = NULL;
4891 }
4892
4893 if (!pd->connected) 4722 if (!pd->connected)
4894 return; 4723 return;
4895 4724
@@ -4931,7 +4760,6 @@ _bridge_event_handlers_unregister(Eo *bridge)
4931 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 4760 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4932 eldbus_signal_handler_del(pd->register_hdl); 4761 eldbus_signal_handler_del(pd->register_hdl);
4933 eldbus_signal_handler_del(pd->unregister_hdl); 4762 eldbus_signal_handler_del(pd->unregister_hdl);
4934 ecore_event_filter_del(pd->key_flr);
4935} 4763}
4936 4764
4937/** 4765/**
@@ -4942,10 +4770,13 @@ _bridge_event_handlers_unregister(Eo *bridge)
4942static void 4770static void
4943_bridge_on_disconnected(Elm_Atspi_Bridge *bridge) 4771_bridge_on_disconnected(Elm_Atspi_Bridge *bridge)
4944{ 4772{
4773 ERR("On disconnected");
4945 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 4774 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4946 4775
4947 _bridge_pending_cancel_all(bridge); 4776 _bridge_pending_cancel_all(bridge);
4948 4777
4778 efl_del(pd->device_event_controller);
4779
4949 _bridge_plugs_unregister(bridge); 4780 _bridge_plugs_unregister(bridge);
4950 _bridge_event_handlers_unregister(bridge); 4781 _bridge_event_handlers_unregister(bridge);
4951 _bridge_interfaces_unregister(bridge); 4782 _bridge_interfaces_unregister(bridge);
@@ -4963,8 +4794,12 @@ _bridge_on_connected(Elm_Atspi_Bridge *bridge)
4963{ 4794{
4964 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd); 4795 ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
4965 4796
4797 ERR("On connected");
4966 pd->cache = eina_hash_pointer_new(NULL); 4798 pd->cache = eina_hash_pointer_new(NULL);
4967 pd->state_hash = _elm_atspi_state_hash_build(); 4799 pd->state_hash = _elm_atspi_state_hash_build();
4800 pd->device_event_controller =
4801 efl_add(ELM_ATSPI_DEVICE_EVENT_CONTROLLER_CLASS, NULL,
4802 elm_obj_atspi_event_controller_constructor(efl_added, pd->a11y_bus));
4968 4803
4969 _bridge_interfaces_register(bridge); 4804 _bridge_interfaces_register(bridge);
4970 _bridge_event_handlers_register(bridge); 4805 _bridge_event_handlers_register(bridge);
diff --git a/src/lib/elementary/elm_atspi_device_event_controller.c b/src/lib/elementary/elm_atspi_device_event_controller.c
new file mode 100644
index 0000000000..661112bd9d
--- /dev/null
+++ b/src/lib/elementary/elm_atspi_device_event_controller.c
@@ -0,0 +1,273 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#include <Elementary.h>
6#include <assert.h>
7
8#include "atspi/atspi-constants.h"
9#include "elm_priv.h"
10#include "elm_atspi_device_event_controller.eo.h"
11
12typedef struct _Elm_Atspi_Device_Event_Controller_Data {
13 Eldbus_Connection *conn;
14 Eina_List *events_history;
15 Ecore_Event_Filter *events_filter;
16 Eina_List *pendings;
17} Elm_Atspi_Device_Event_Controller_Data;
18
19struct Keybard_Event_Info {
20 Ecore_Event_Key event;
21 int type;
22 void *data;
23};
24
25static void
26_key_event_info_free(struct Keybard_Event_Info *data)
27{
28 EINA_SAFETY_ON_NULL_RETURN(data);
29
30 eina_stringshare_del(data->event.keyname);
31 eina_stringshare_del(data->event.key);
32 eina_stringshare_del(data->event.string);
33 eina_stringshare_del(data->event.compose);
34
35 free(data);
36}
37
38static short
39_ecore_modifiers_2_atspi(unsigned int modifiers)
40{
41 short ret = 0;
42
43 if (modifiers & ECORE_EVENT_MODIFIER_SHIFT)
44 ret |= (1 << ATSPI_MODIFIER_SHIFT);
45 if (modifiers & ECORE_EVENT_MODIFIER_CAPS)
46 ret |= (1 << ATSPI_MODIFIER_SHIFTLOCK);
47 if (modifiers & ECORE_EVENT_MODIFIER_CTRL)
48 ret |= (1 << ATSPI_MODIFIER_CONTROL);
49 if (modifiers & ECORE_EVENT_MODIFIER_ALT)
50 ret |= (1 << ATSPI_MODIFIER_ALT);
51 if (modifiers & ECORE_EVENT_MODIFIER_WIN)
52 ret |= (1 << ATSPI_MODIFIER_META);
53 if (modifiers & ECORE_EVENT_MODIFIER_NUM)
54 ret |= (1 << ATSPI_MODIFIER_NUMLOCK);
55
56 return ret;
57}
58
59static void
60_on_event_del(void *user_data, void *func_data EINA_UNUSED)
61{
62 struct Keybard_Event_Info *info = user_data;
63 _key_event_info_free(info);
64}
65
66static Eina_Bool
67_is_in_history(Elm_Atspi_Device_Event_Controller_Data *pd, Ecore_Event_Key *event)
68{
69 if (eina_list_data_find(pd->events_history, event))
70 return EINA_TRUE;
71 else
72 return EINA_FALSE;
73}
74
75static void
76_remove_from_history(Elm_Atspi_Device_Event_Controller_Data *pd, Ecore_Event_Key *event)
77{
78 pd->events_history = eina_list_remove(pd->events_history, event);
79}
80
81static void
82_add_to_history(Elm_Atspi_Device_Event_Controller_Data *pd, Ecore_Event_Key *event)
83{
84 pd->events_history = eina_list_append(pd->events_history, event);
85}
86
87static void
88_add_to_pendings(Elm_Atspi_Device_Event_Controller_Data *pd, Eldbus_Pending *p)
89{
90 pd->pendings = eina_list_append(pd->pendings, p);
91}
92
93static void
94_remove_from_pendings(Elm_Atspi_Device_Event_Controller_Data *pd, Eldbus_Pending *p)
95{
96 pd->pendings = eina_list_remove(pd->pendings, p);
97}
98
99static void
100_reemit_event(Elm_Atspi_Device_Event_Controller_Data *pd, struct Keybard_Event_Info *info)
101{
102 ecore_event_add(info->type, &info->event, _on_event_del, info);
103 _add_to_history(pd, &info->event);
104}
105
106static void
107_on_listener_answer(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
108{
109 struct Keybard_Event_Info *info = data;
110 const char *errname, *errmsg;
111 Eina_Bool ret = EINA_TRUE;
112 Elm_Atspi_Device_Event_Controller_Data *pd = info->data;
113
114 _remove_from_pendings(pd, pending);
115
116 if (eldbus_message_error_get(msg, &errname, &errmsg) ||
117 !eldbus_message_arguments_get(msg, "b", &ret) ||
118 !ret)
119 {
120 _reemit_event(pd, info);
121 }
122 else
123 {
124 _key_event_info_free(info);
125 }
126}
127
128static struct Keybard_Event_Info*
129_key_event_info_new(int event_type, const Ecore_Event_Key *data, void *user_data)
130{
131 struct Keybard_Event_Info *ret;
132 EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL);
133 ret = calloc(1, sizeof(struct Keybard_Event_Info));
134 if (!ret) return NULL;
135
136 ret->type = event_type;
137 ret->event = *data;
138
139 ret->event.keyname = eina_stringshare_add(data->keyname);
140 ret->event.key = eina_stringshare_add(data->key);
141 ret->event.string = eina_stringshare_add(data->string);
142 ret->event.compose = eina_stringshare_add(data->compose);
143 ret->event.modifiers = data->modifiers;
144 ret->data = user_data;
145
146 // not sure what this field is for, but explicite keep it NULLed.
147 ret->event.data = NULL;
148
149 return ret;
150}
151
152static void
153_iter_marshall_key_event(Eldbus_Message_Iter *iter, struct Keybard_Event_Info *data)
154{
155 Eldbus_Message_Iter *struct_iter;
156 EINA_SAFETY_ON_NULL_RETURN(data);
157
158 struct_iter = eldbus_message_iter_container_new(iter, 'r', NULL);
159
160 const char *str = data->event.keyname ? data->event.keyname : "";
161 int is_text = data->event.keyname ? 1 : 0;
162 int type;
163 if (data->type == ECORE_EVENT_KEY_DOWN)
164 type = ATSPI_KEY_PRESSED_EVENT;
165 else
166 type = ATSPI_KEY_RELEASED_EVENT;
167
168 eldbus_message_iter_arguments_append(
169 struct_iter, "uinnisb", type, 0, data->event.keycode,
170 _ecore_modifiers_2_atspi(data->event.modifiers), data->event.timestamp,
171 str, is_text);
172
173 eldbus_message_iter_container_close(iter, struct_iter);
174}
175
176static Eina_Bool
177_is_keyboard_event(int type)
178{
179 if ((type != ECORE_EVENT_KEY_DOWN) &&
180 (type != ECORE_EVENT_KEY_UP))
181 return EINA_FALSE;
182 else
183 return EINA_TRUE;
184}
185
186static Eina_Bool
187_notify_listener_sync(Elm_Atspi_Device_Event_Controller_Data *pd, struct Keybard_Event_Info *ke)
188{
189 Eldbus_Message *msg;
190 Eldbus_Message_Iter *iter;
191 Eldbus_Pending *p;
192
193 msg = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY,
194 ATSPI_DBUS_PATH_DEC,
195 ATSPI_DBUS_INTERFACE_DEC,
196 "NotifyListenersSync");
197 iter = eldbus_message_iter_get(msg);
198 _iter_marshall_key_event(iter, ke);
199
200 // timeout should be kept reasonaby low to avoid delays
201 p = eldbus_connection_send(pd->conn, msg, _on_listener_answer, ke, 100);
202 if (p)
203 {
204 _add_to_pendings(pd, p);
205 return EINA_TRUE;
206 }
207 else
208 return EINA_FALSE;
209}
210
211static Eina_Bool
212_ecore_filter_cb(void *data, void *loop EINA_UNUSED, int type, void *event)
213{
214 Ecore_Event_Key *key_event = event;
215 struct Keybard_Event_Info *ke;
216 Elm_Atspi_Device_Event_Controller_Data *pd = data;
217
218 if (!_is_keyboard_event(type))
219 return EINA_TRUE; // do not hold
220
221 // check if event mark to reemission
222 if (_is_in_history(pd, key_event))
223 {
224 _remove_from_history(pd, key_event);
225 return EINA_TRUE; // do not hold
226 }
227
228 // create event description so event could be reemited after
229 // confirmation from atspi2 registryd
230 ke = _key_event_info_new(type, key_event, pd);
231 if (!ke) return EINA_TRUE;
232
233 // notify atspi2 registryd about event
234 if (_notify_listener_sync(pd, ke))
235 return EINA_FALSE; // hold event
236 else
237 return EINA_TRUE;
238}
239
240EOLIAN static void
241_elm_atspi_device_event_controller_constructor(
242 Elm_Atspi_Device_Event_Controller *obj EINA_UNUSED,
243 Elm_Atspi_Device_Event_Controller_Data *pd EINA_UNUSED,
244 Eldbus_Connection *conn)
245{
246 pd->conn = eldbus_connection_ref(conn);
247 assert (pd->conn != NULL);
248
249 pd->events_filter = ecore_event_filter_add(NULL,
250 _ecore_filter_cb,
251 NULL,
252 pd);
253 assert (pd->events_filter != NULL);
254}
255
256EOLIAN static void
257_elm_atspi_device_event_controller_efl_object_destructor(
258 Elm_Atspi_Device_Event_Controller *obj EINA_UNUSED,
259 Elm_Atspi_Device_Event_Controller_Data *pd)
260{
261 Eldbus_Pending *p;
262 // flush all holded events
263 EINA_LIST_FREE(pd->pendings, p)
264 eldbus_pending_cancel(p);
265
266 eina_list_free(pd->events_history);
267 ecore_event_filter_del(pd->events_filter);
268 eldbus_connection_unref(pd->conn);
269
270 efl_destructor(efl_super(obj, ELM_ATSPI_DEVICE_EVENT_CONTROLLER_CLASS));
271}
272
273#include "elm_atspi_device_event_controller.eo.c"
diff --git a/src/lib/elementary/elm_atspi_device_event_controller.eo b/src/lib/elementary/elm_atspi_device_event_controller.eo
new file mode 100644
index 0000000000..49107d4dd7
--- /dev/null
+++ b/src/lib/elementary/elm_atspi_device_event_controller.eo
@@ -0,0 +1,21 @@
1import eldbus_types;
2
3class Elm.Atspi.Device.Event.Controller (Efl.Object)
4{
5 legacy_prefix: elm_atspi_event_controller;
6 eo_prefix: elm_obj_atspi_event_controller;
7 methods {
8 constructor {
9 params {
10 @in conn: ptr(Eldbus.Connection);
11 }
12 }
13 }
14 implements {
15 Efl.Object.destructor;
16 }
17 constructors {
18 .constructor;
19 }
20}
21
diff --git a/src/lib/elementary/elm_atspi_event_controller.c b/src/lib/elementary/elm_atspi_event_controller.c
deleted file mode 100644
index e69de29bb2..0000000000
--- a/src/lib/elementary/elm_atspi_event_controller.c
+++ /dev/null