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