svn update: 48958 (latest:48959)
[framework/uifw/ecore.git] / src / lib / ecore_input_evas / ecore_input_evas.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #ifdef HAVE_CONFIG_H
6 # include <config.h>
7 #endif
8
9 #include <string.h>
10
11 #include "Ecore.h"
12 #include "Ecore_Input.h"
13
14 #include "Ecore_Input_Evas.h"
15 #include "ecore_input_evas_private.h"
16
17 int _ecore_input_evas_log_dom = -1;
18
19 typedef struct _Ecore_Input_Window Ecore_Input_Window;
20 struct _Ecore_Input_Window
21 {
22    Evas *evas;
23    void *window;
24    Ecore_Event_Mouse_Move_Cb move_mouse;
25    int ignore_event;
26 };
27
28 static int _ecore_event_evas_init_count = 0;
29 static Ecore_Event_Handler *ecore_event_evas_handlers[8];
30 static Eina_Hash *_window_hash = NULL;
31
32 EAPI void
33 ecore_event_evas_modifier_lock_update(Evas *e, unsigned int modifiers)
34 {
35    if (modifiers & ECORE_EVENT_MODIFIER_SHIFT)
36      evas_key_modifier_on(e, "Shift");
37    else evas_key_modifier_off(e, "Shift");
38
39    if (modifiers & ECORE_EVENT_MODIFIER_CTRL)
40      evas_key_modifier_on(e, "Control");
41    else evas_key_modifier_off(e, "Control");
42
43    if (modifiers & ECORE_EVENT_MODIFIER_ALT)
44      evas_key_modifier_on(e, "Alt");
45    else evas_key_modifier_off(e, "Alt");
46
47    if (modifiers & ECORE_EVENT_MODIFIER_WIN)
48      {
49         evas_key_modifier_on(e, "Super");
50         evas_key_modifier_on(e, "Hyper");
51      }
52    else
53      {
54         evas_key_modifier_off(e, "Super");
55         evas_key_modifier_off(e, "Hyper");
56      }
57
58    if (modifiers & ECORE_EVENT_LOCK_SCROLL)
59      evas_key_lock_on(e, "Scroll_Lock");
60    else evas_key_lock_off(e, "Scroll_Lock");
61
62    if (modifiers & ECORE_EVENT_LOCK_NUM)
63      evas_key_lock_on(e, "Num_Lock");
64    else evas_key_lock_off(e, "Num_Lock");
65
66    if (modifiers & ECORE_EVENT_LOCK_CAPS)
67      evas_key_lock_on(e, "Caps_Lock");
68    else evas_key_lock_off(e, "Caps_Lock");
69 }
70
71 EAPI void
72 ecore_event_window_register(Ecore_Window id, void *window, Evas *evas, Ecore_Event_Mouse_Move_Cb move_mouse)
73 {
74    Ecore_Input_Window *w;
75
76    w = calloc(1, sizeof(Ecore_Input_Window));
77    if (!w) return;
78
79    w->evas = evas;
80    w->window = window;
81    w->move_mouse = move_mouse;
82    w->ignore_event = 0;
83
84    eina_hash_add(_window_hash, &id, w);
85
86    evas_key_modifier_add(evas, "Shift");
87    evas_key_modifier_add(evas, "Control");
88    evas_key_modifier_add(evas, "Alt");
89    evas_key_modifier_add(evas, "Meta");
90    evas_key_modifier_add(evas, "Hyper");
91    evas_key_modifier_add(evas, "Super");
92    evas_key_lock_add(evas, "Caps_Lock");
93    evas_key_lock_add(evas, "Num_Lock");
94    evas_key_lock_add(evas, "Scroll_Lock");
95 }
96
97 EAPI void
98 ecore_event_window_unregister(Ecore_Window id)
99 {
100    eina_hash_del(_window_hash, &id, NULL);
101 }
102
103 EAPI void *
104 ecore_event_window_match(Ecore_Window id)
105 {
106    Ecore_Input_Window *lookup;
107
108    lookup = eina_hash_find(_window_hash, &id);
109    if (lookup) return lookup->window;
110    return NULL;
111 }
112
113 EAPI void
114 ecore_event_window_ignore_events(Ecore_Window id, int ignore_event)
115 {
116    Ecore_Input_Window *lookup;
117
118    lookup = eina_hash_find(_window_hash, &id);
119    if (!lookup) return;
120    lookup->ignore_event = ignore_event;
121 }
122
123 static Ecore_Input_Window*
124 _ecore_event_window_match(Ecore_Window id)
125 {
126    Ecore_Input_Window *lookup;
127
128    lookup = eina_hash_find(_window_hash, &id);
129    if (!lookup) return NULL;
130    if (lookup->ignore_event) return NULL; /* Pass on event. */
131    return lookup;
132 }
133
134 static int
135 _ecore_event_evas_key(Ecore_Event_Key *e, Ecore_Event_Press press)
136 {
137    Ecore_Input_Window *lookup;
138
139    lookup = _ecore_event_window_match(e->window);
140    if (!lookup) return 1;
141    ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers);
142    if (press == ECORE_DOWN)
143      evas_event_feed_key_down(lookup->evas, e->keyname, e->key, e->string, e->compose, e->timestamp, NULL);
144    else
145      evas_event_feed_key_up(lookup->evas, e->keyname, e->key, e->string, e->compose, e->timestamp, NULL);
146    return 1;
147 }
148
149 static int
150 _ecore_event_evas_mouse_button(Ecore_Event_Mouse_Button *e, Ecore_Event_Press press)
151 {
152    Ecore_Input_Window *lookup;
153    Evas_Button_Flags flags = EVAS_BUTTON_NONE;
154
155    lookup = _ecore_event_window_match(e->window);
156    if (!lookup) return 1;
157    if (e->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
158    if (e->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
159    if (e->multi.device == 0)
160      {
161         ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers);
162         if (press == ECORE_DOWN)
163           evas_event_feed_mouse_down(lookup->evas, e->buttons, flags, e->timestamp, NULL);
164         else
165           evas_event_feed_mouse_up(lookup->evas, e->buttons, flags, e->timestamp, NULL);
166      }
167    else
168      {
169         if (press == ECORE_DOWN)
170           evas_event_feed_multi_down(lookup->evas, e->multi.device, e->x, e->y, e->multi.radius, e->multi.radius_x, e->multi.radius_y, e->multi.pressure, e->multi.angle, e->multi.x, e->multi.y, flags, e->timestamp, NULL);
171         else
172           evas_event_feed_multi_up(lookup->evas, e->multi.device, e->x, e->y, e->multi.radius, e->multi.radius_x, e->multi.radius_y, e->multi.pressure, e->multi.angle, e->multi.x, e->multi.y, flags, e->timestamp, NULL);
173      }
174    return 1;
175 }
176
177 EAPI int
178 ecore_event_evas_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
179 {
180    Ecore_Event_Mouse_Move *e;
181    Ecore_Input_Window *lookup;
182
183    e = event;
184    lookup = _ecore_event_window_match(e->window);
185    if (!lookup) return 1;
186    if (e->multi.device == 0)
187      {
188         ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers);
189         lookup->move_mouse(lookup->window, e->x, e->y, e->timestamp);
190      }
191    else
192      {
193         evas_event_feed_multi_move(lookup->evas, e->multi.device, e->x, e->y, e->multi.radius, e->multi.radius_x, e->multi.radius_y, e->multi.pressure, e->multi.angle, e->multi.x, e->multi.y, e->timestamp, NULL);
194      }
195    return 1;
196 }
197
198 EAPI int
199 ecore_event_evas_mouse_button_down(void *data __UNUSED__, int type __UNUSED__, void *event)
200 {
201    return _ecore_event_evas_mouse_button((Ecore_Event_Mouse_Button *)event, ECORE_DOWN);
202 }
203
204 EAPI int
205 ecore_event_evas_mouse_button_up(void *data __UNUSED__, int type __UNUSED__, void *event)
206 {
207    return _ecore_event_evas_mouse_button((Ecore_Event_Mouse_Button *)event, ECORE_UP);
208 }
209
210 static int
211 _ecore_event_evas_mouse_io(Ecore_Event_Mouse_IO *e, Ecore_Event_IO io)
212 {
213    Ecore_Input_Window *lookup;
214
215    lookup = _ecore_event_window_match(e->window);
216    if (!lookup) return 1;
217    ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers);
218    switch (io)
219      {
220       case ECORE_IN:
221          evas_event_feed_mouse_in(lookup->evas, e->timestamp, NULL);
222          break;
223       case ECORE_OUT:
224          evas_event_feed_mouse_out(lookup->evas, e->timestamp, NULL);
225          break;
226       default:
227          break;
228      }
229
230    lookup->move_mouse(lookup->window, e->x, e->y, e->timestamp);
231    return 1;
232 }
233
234 EAPI int
235 ecore_event_evas_key_down(void *data __UNUSED__, int type __UNUSED__, void *event)
236 {
237    return _ecore_event_evas_key((Ecore_Event_Key *)event, ECORE_DOWN);
238 }
239
240 EAPI int
241 ecore_event_evas_key_up(void *data __UNUSED__, int type __UNUSED__, void *event)
242 {
243    return _ecore_event_evas_key((Ecore_Event_Key *)event, ECORE_UP);
244 }
245
246 EAPI int
247 ecore_event_evas_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event)
248 {
249    Ecore_Event_Mouse_Wheel *e;
250    Ecore_Input_Window *lookup;
251
252    e = event;
253    lookup = _ecore_event_window_match(e->window);
254    if (!lookup) return 1;
255    ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers);
256    evas_event_feed_mouse_wheel(lookup->evas, e->direction, e->z, e->timestamp, NULL);
257    return 1;
258 }
259
260 EAPI int
261 ecore_event_evas_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
262 {
263    return _ecore_event_evas_mouse_io((Ecore_Event_Mouse_IO *)event, ECORE_IN);
264 }
265
266 EAPI int
267 ecore_event_evas_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event)
268 {
269    return _ecore_event_evas_mouse_io((Ecore_Event_Mouse_IO *)event, ECORE_OUT);
270 }
271
272 EAPI int
273 ecore_event_evas_init(void)
274 {
275    if (++_ecore_event_evas_init_count !=  1)
276      return _ecore_event_evas_init_count;
277
278    _ecore_input_evas_log_dom = eina_log_domain_register("EcoreInputEvas",  ECORE_INPUT_EVAS_DEFAULT_LOG_COLOR);
279    if (_ecore_input_evas_log_dom < 0)
280      {
281         EINA_LOG_ERR("Impossible to create a log domain for the ecore input evas_module.");
282         return --_ecore_event_evas_init_count;
283      }
284
285    if (!ecore_init())
286      {
287         return --_ecore_event_evas_init_count;
288      }
289
290    if (!ecore_event_init())
291      {
292         goto shutdown_ecore;
293      }
294
295    ecore_event_evas_handlers[0] = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
296                                                           ecore_event_evas_key_down,
297                                                           NULL);
298    ecore_event_evas_handlers[1] = ecore_event_handler_add(ECORE_EVENT_KEY_UP,
299                                                           ecore_event_evas_key_up,
300                                                           NULL);
301    ecore_event_evas_handlers[2] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
302                                                           ecore_event_evas_mouse_button_down,
303                                                           NULL);
304    ecore_event_evas_handlers[3] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
305                                                           ecore_event_evas_mouse_button_up,
306                                                           NULL);
307    ecore_event_evas_handlers[4] = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
308                                                           ecore_event_evas_mouse_move,
309                                                           NULL);
310    ecore_event_evas_handlers[5] = ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL,
311                                                           ecore_event_evas_mouse_wheel,
312                                                           NULL);
313    ecore_event_evas_handlers[6] = ecore_event_handler_add(ECORE_EVENT_MOUSE_IN,
314                                                           ecore_event_evas_mouse_in,
315                                                           NULL);
316    ecore_event_evas_handlers[7] = ecore_event_handler_add(ECORE_EVENT_MOUSE_OUT,
317                                                           ecore_event_evas_mouse_out,
318                                                           NULL);
319    
320    _window_hash = eina_hash_pointer_new(free);
321    
322    return _ecore_event_evas_init_count;
323    
324    shutdown_ecore:
325    ecore_shutdown();
326    
327    return --_ecore_event_evas_init_count;
328 }
329
330 EAPI int
331 ecore_event_evas_shutdown(void)
332 {
333    size_t i;
334    
335    if (--_ecore_event_evas_init_count != 0)
336      return _ecore_event_evas_init_count;
337    
338    eina_hash_free(_window_hash);
339    _window_hash = NULL;
340    for (i = 0; i < sizeof(ecore_event_evas_handlers) / sizeof(Ecore_Event_Handler *); i++)
341      {
342         ecore_event_handler_del(ecore_event_evas_handlers[i]);
343         ecore_event_evas_handlers[i] = NULL;
344      }
345    
346    ecore_event_shutdown();
347    ecore_shutdown();
348    
349    eina_log_domain_unregister(_ecore_input_evas_log_dom);
350    _ecore_input_evas_log_dom = -1;
351    
352    return _ecore_event_evas_init_count;
353 }