d512dc00f95544b72a119e101714981521bf3574
[framework/uifw/ecore.git] / src / lib / ecore_input_evas / ecore_input_evas.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <string.h>
6 #include <stdlib.h>
7
8 #include "Ecore.h"
9 #include "Ecore_Input.h"
10
11 #include "Ecore_Input_Evas.h"
12 #include "ecore_input_evas_private.h"
13
14 int _ecore_input_evas_log_dom = -1;
15
16 typedef struct _Ecore_Input_Window Ecore_Input_Window;
17 struct _Ecore_Input_Window
18 {
19    Evas *evas;
20    void *window;
21    Ecore_Event_Mouse_Move_Cb move_mouse;
22    Ecore_Event_Multi_Move_Cb move_multi;
23    Ecore_Event_Multi_Down_Cb down_multi;
24    Ecore_Event_Multi_Up_Cb up_multi;
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_MODIFIER_ALTGR)
59      evas_key_modifier_on(e, "AltGr");
60    else evas_key_modifier_off(e, "AltGr");
61
62    if (modifiers & ECORE_EVENT_LOCK_SCROLL)
63      evas_key_lock_on(e, "Scroll_Lock");
64    else evas_key_lock_off(e, "Scroll_Lock");
65
66    if (modifiers & ECORE_EVENT_LOCK_NUM)
67      evas_key_lock_on(e, "Num_Lock");
68    else evas_key_lock_off(e, "Num_Lock");
69
70    if (modifiers & ECORE_EVENT_LOCK_CAPS)
71      evas_key_lock_on(e, "Caps_Lock");
72    else evas_key_lock_off(e, "Caps_Lock");
73
74    if (modifiers & ECORE_EVENT_LOCK_SHIFT)
75      evas_key_lock_on(e, "Shift_Lock");
76    else evas_key_lock_off(e, "Shift_Lock");
77 }
78
79 EAPI void
80 ecore_event_window_register(Ecore_Window id, void *window, Evas *evas,
81                             Ecore_Event_Mouse_Move_Cb move_mouse,
82                             Ecore_Event_Multi_Move_Cb move_multi,
83                             Ecore_Event_Multi_Down_Cb down_multi,
84                             Ecore_Event_Multi_Up_Cb up_multi)
85 {
86    Ecore_Input_Window *w;
87
88    w = calloc(1, sizeof(Ecore_Input_Window));
89    if (!w) return;
90
91    w->evas = evas;
92    w->window = window;
93    w->move_mouse = move_mouse;
94    w->move_multi = move_multi;
95    w->down_multi = down_multi;
96    w->up_multi = up_multi;
97    w->ignore_event = 0;
98
99    eina_hash_add(_window_hash, &id, w);
100
101    evas_key_modifier_add(evas, "Shift");
102    evas_key_modifier_add(evas, "Control");
103    evas_key_modifier_add(evas, "Alt");
104    evas_key_modifier_add(evas, "Meta");
105    evas_key_modifier_add(evas, "Hyper");
106    evas_key_modifier_add(evas, "Super");
107    evas_key_modifier_add(evas, "AltGr");
108    evas_key_lock_add(evas, "Caps_Lock");
109    evas_key_lock_add(evas, "Num_Lock");
110    evas_key_lock_add(evas, "Scroll_Lock");
111 }
112
113 EAPI void
114 ecore_event_window_unregister(Ecore_Window id)
115 {
116    eina_hash_del(_window_hash, &id, NULL);
117 }
118
119 EAPI void *
120 ecore_event_window_match(Ecore_Window id)
121 {
122    Ecore_Input_Window *lookup;
123
124    lookup = eina_hash_find(_window_hash, &id);
125    if (lookup) return lookup->window;
126    return NULL;
127 }
128
129 EAPI void
130 ecore_event_window_ignore_events(Ecore_Window id, int ignore_event)
131 {
132    Ecore_Input_Window *lookup;
133
134    lookup = eina_hash_find(_window_hash, &id);
135    if (!lookup) return;
136    lookup->ignore_event = ignore_event;
137 }
138
139 static Ecore_Input_Window*
140 _ecore_event_window_match(Ecore_Window id)
141 {
142    Ecore_Input_Window *lookup;
143
144    lookup = eina_hash_find(_window_hash, &id);
145    if (!lookup) return NULL;
146    if (lookup->ignore_event) return NULL; /* Pass on event. */
147    return lookup;
148 }
149
150 static Eina_Bool
151 _ecore_event_evas_key(Ecore_Event_Key *e, Ecore_Event_Press press)
152 {
153    Ecore_Input_Window *lookup;
154
155    lookup = _ecore_event_window_match(e->event_window);
156    if (!lookup) return ECORE_CALLBACK_RENEW;
157    ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers);
158    if (press == ECORE_DOWN)
159      evas_event_feed_key_down(lookup->evas, e->keyname, e->key, e->string, e->compose, e->timestamp, NULL);
160    else
161      evas_event_feed_key_up(lookup->evas, e->keyname, e->key, e->string, e->compose, e->timestamp, NULL);
162    return ECORE_CALLBACK_RENEW;
163 }
164
165 static Eina_Bool
166 _ecore_event_evas_mouse_button(Ecore_Event_Mouse_Button *e, Ecore_Event_Press press)
167 {
168    Ecore_Input_Window *lookup;
169    Evas_Button_Flags flags = EVAS_BUTTON_NONE;
170
171    lookup = _ecore_event_window_match(e->event_window);
172    if (!lookup) return ECORE_CALLBACK_RENEW;
173    if (e->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
174    if (e->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
175    if (e->multi.device == 0)
176      {
177         ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers);
178         if (press == ECORE_DOWN)
179           evas_event_feed_mouse_down(lookup->evas, e->buttons, flags,
180                                      e->timestamp, NULL);
181         else
182           evas_event_feed_mouse_up(lookup->evas, e->buttons, flags,
183                                    e->timestamp, NULL);
184      }
185    else
186      {
187         if (press == ECORE_DOWN)
188           {
189              if (lookup->down_multi)
190                 lookup->down_multi(lookup->window, e->multi.device,
191                                    e->x, e->y, e->multi.radius,
192                                    e->multi.radius_x, e->multi.radius_y,
193                                    e->multi.pressure, e->multi.angle,
194                                    e->multi.x, e->multi.y, flags,
195                                    e->timestamp);
196              else
197                 evas_event_feed_multi_down(lookup->evas, e->multi.device,
198                                            e->x, e->y, e->multi.radius,
199                                            e->multi.radius_x, e->multi.radius_y,
200                                            e->multi.pressure, e->multi.angle,
201                                            e->multi.x, e->multi.y, flags,
202                                            e->timestamp, NULL);
203           }
204         else
205           {
206              if (lookup->up_multi)
207                 lookup->up_multi(lookup->window, e->multi.device,
208                                  e->x, e->y, e->multi.radius,
209                                  e->multi.radius_x, e->multi.radius_y,
210                                  e->multi.pressure, e->multi.angle,
211                                  e->multi.x, e->multi.y, flags,
212                                  e->timestamp);
213              else
214                 evas_event_feed_multi_up(lookup->evas, e->multi.device,
215                                          e->x, e->y, e->multi.radius,
216                                          e->multi.radius_x, e->multi.radius_y,
217                                          e->multi.pressure, e->multi.angle,
218                                          e->multi.x, e->multi.y, flags,
219                                          e->timestamp, NULL);
220           }
221      }
222    return ECORE_CALLBACK_RENEW;
223 }
224
225 EAPI Eina_Bool
226 ecore_event_evas_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
227 {
228    Ecore_Event_Mouse_Move *e;
229    Ecore_Input_Window *lookup;
230
231    e = event;
232    lookup = _ecore_event_window_match(e->event_window);
233    if (!lookup) return ECORE_CALLBACK_RENEW;
234    if (e->multi.device == 0)
235      {
236         ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers);
237         if (lookup->move_mouse)
238            lookup->move_mouse(lookup->window, e->x, e->y, e->timestamp);
239         else
240            evas_event_feed_mouse_move(lookup->evas, e->x, e->y, e->timestamp,
241                                       NULL);
242      }
243    else
244      {
245         if (lookup->move_multi)
246            lookup->move_multi(lookup->window, e->multi.device,
247                               e->x, e->y, e->multi.radius,
248                               e->multi.radius_x, e->multi.radius_y,
249                               e->multi.pressure, e->multi.angle,
250                               e->multi.x, e->multi.y, e->timestamp);
251         else
252            evas_event_feed_multi_move(lookup->evas, e->multi.device,
253                                       e->x, e->y, e->multi.radius,
254                                       e->multi.radius_x, e->multi.radius_y,
255                                       e->multi.pressure, e->multi.angle,
256                                       e->multi.x, e->multi.y, e->timestamp,
257                                       NULL);
258      }
259    return ECORE_CALLBACK_RENEW;
260 }
261
262 EAPI Eina_Bool
263 ecore_event_evas_mouse_button_down(void *data __UNUSED__, int type __UNUSED__, void *event)
264 {
265    return _ecore_event_evas_mouse_button((Ecore_Event_Mouse_Button *)event, ECORE_DOWN);
266 }
267
268 EAPI Eina_Bool
269 ecore_event_evas_mouse_button_up(void *data __UNUSED__, int type __UNUSED__, void *event)
270 {
271    return _ecore_event_evas_mouse_button((Ecore_Event_Mouse_Button *)event, ECORE_UP);
272 }
273
274 static Eina_Bool
275 _ecore_event_evas_mouse_io(Ecore_Event_Mouse_IO *e, Ecore_Event_IO io)
276 {
277    Ecore_Input_Window *lookup;
278
279    lookup = _ecore_event_window_match(e->event_window);
280    if (!lookup) return ECORE_CALLBACK_RENEW;
281    ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers);
282    switch (io)
283      {
284       case ECORE_IN:
285          evas_event_feed_mouse_in(lookup->evas, e->timestamp, NULL);
286          break;
287       case ECORE_OUT:
288          evas_event_feed_mouse_out(lookup->evas, e->timestamp, NULL);
289          break;
290       default:
291          break;
292      }
293
294    lookup->move_mouse(lookup->window, e->x, e->y, e->timestamp);
295    return ECORE_CALLBACK_RENEW;
296 }
297
298 EAPI Eina_Bool
299 ecore_event_evas_key_down(void *data __UNUSED__, int type __UNUSED__, void *event)
300 {
301    return _ecore_event_evas_key((Ecore_Event_Key *)event, ECORE_DOWN);
302 }
303
304 EAPI Eina_Bool
305 ecore_event_evas_key_up(void *data __UNUSED__, int type __UNUSED__, void *event)
306 {
307    return _ecore_event_evas_key((Ecore_Event_Key *)event, ECORE_UP);
308 }
309
310 EAPI Eina_Bool
311 ecore_event_evas_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event)
312 {
313    Ecore_Event_Mouse_Wheel *e;
314    Ecore_Input_Window *lookup;
315
316    e = event;
317    lookup = _ecore_event_window_match(e->event_window);
318    if (!lookup) return ECORE_CALLBACK_RENEW;
319    ecore_event_evas_modifier_lock_update(lookup->evas, e->modifiers);
320    evas_event_feed_mouse_wheel(lookup->evas, e->direction, e->z, e->timestamp, NULL);
321    return ECORE_CALLBACK_RENEW;
322 }
323
324 EAPI Eina_Bool
325 ecore_event_evas_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
326 {
327    return _ecore_event_evas_mouse_io((Ecore_Event_Mouse_IO *)event, ECORE_IN);
328 }
329
330 EAPI Eina_Bool
331 ecore_event_evas_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event)
332 {
333    return _ecore_event_evas_mouse_io((Ecore_Event_Mouse_IO *)event, ECORE_OUT);
334 }
335
336 EAPI int
337 ecore_event_evas_init(void)
338 {
339    if (++_ecore_event_evas_init_count !=  1)
340      return _ecore_event_evas_init_count;
341
342    _ecore_input_evas_log_dom = eina_log_domain_register
343      ("ecore_input_evas",  ECORE_INPUT_EVAS_DEFAULT_LOG_COLOR);
344    if (_ecore_input_evas_log_dom < 0)
345      {
346         EINA_LOG_ERR("Impossible to create a log domain for the ecore input evas_module.");
347         return --_ecore_event_evas_init_count;
348      }
349
350    if (!ecore_init())
351      {
352         return --_ecore_event_evas_init_count;
353      }
354
355    if (!ecore_event_init())
356      {
357         goto shutdown_ecore;
358      }
359
360    ecore_event_evas_handlers[0] = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
361                                                           ecore_event_evas_key_down,
362                                                           NULL);
363    ecore_event_evas_handlers[1] = ecore_event_handler_add(ECORE_EVENT_KEY_UP,
364                                                           ecore_event_evas_key_up,
365                                                           NULL);
366    ecore_event_evas_handlers[2] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
367                                                           ecore_event_evas_mouse_button_down,
368                                                           NULL);
369    ecore_event_evas_handlers[3] = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
370                                                           ecore_event_evas_mouse_button_up,
371                                                           NULL);
372    ecore_event_evas_handlers[4] = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
373                                                           ecore_event_evas_mouse_move,
374                                                           NULL);
375    ecore_event_evas_handlers[5] = ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL,
376                                                           ecore_event_evas_mouse_wheel,
377                                                           NULL);
378    ecore_event_evas_handlers[6] = ecore_event_handler_add(ECORE_EVENT_MOUSE_IN,
379                                                           ecore_event_evas_mouse_in,
380                                                           NULL);
381    ecore_event_evas_handlers[7] = ecore_event_handler_add(ECORE_EVENT_MOUSE_OUT,
382                                                           ecore_event_evas_mouse_out,
383                                                           NULL);
384
385    _window_hash = eina_hash_pointer_new(free);
386
387    return _ecore_event_evas_init_count;
388
389    shutdown_ecore:
390    ecore_shutdown();
391
392    return --_ecore_event_evas_init_count;
393 }
394
395 EAPI int
396 ecore_event_evas_shutdown(void)
397 {
398    size_t i;
399
400    if (--_ecore_event_evas_init_count != 0)
401      return _ecore_event_evas_init_count;
402
403    eina_hash_free(_window_hash);
404    _window_hash = NULL;
405    for (i = 0; i < sizeof(ecore_event_evas_handlers) / sizeof(Ecore_Event_Handler *); i++)
406      {
407         ecore_event_handler_del(ecore_event_evas_handlers[i]);
408         ecore_event_evas_handlers[i] = NULL;
409      }
410
411    ecore_event_shutdown();
412    ecore_shutdown();
413
414    eina_log_domain_unregister(_ecore_input_evas_log_dom);
415    _ecore_input_evas_log_dom = -1;
416
417    return _ecore_event_evas_init_count;
418 }