Tizen 2.1 base
[framework/uifw/ecore.git] / src / lib / ecore / ecore_events.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <stdlib.h>
6
7 #include "Ecore.h"
8 #include "ecore_private.h"
9
10 static int inpurge = 0;
11
12 struct _Ecore_Event_Handler
13 {
14    EINA_INLIST;
15                           ECORE_MAGIC;
16    int                    type;
17    Ecore_Event_Handler_Cb func;
18    void                  *data;
19    int                    references;
20    Eina_Bool              delete_me : 1;
21 };
22 GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event_Handler);
23
24 struct _Ecore_Event_Filter
25 {
26    EINA_INLIST;
27                    ECORE_MAGIC;
28    Ecore_Data_Cb   func_start;
29    Ecore_Filter_Cb func_filter;
30    Ecore_End_Cb    func_end;
31    void           *loop_data;
32    void           *data;
33    int             references;
34    Eina_Bool       delete_me : 1;
35 };
36 GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event_Filter);
37
38 struct _Ecore_Event
39 {
40    EINA_INLIST;
41                 ECORE_MAGIC;
42    int          type;
43    void        *event;
44    Ecore_End_Cb func_free;
45    void        *data;
46    int          references;
47    Eina_Bool    delete_me : 1;
48 };
49 GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event);
50
51 static int events_num = 0;
52 static Ecore_Event *events = NULL;
53 static Ecore_Event *event_current = NULL;
54 static Ecore_Event *purge_events = NULL;
55
56 static Ecore_Event_Handler **event_handlers = NULL;
57 static Ecore_Event_Handler *event_handler_current = NULL;
58 static int event_handlers_num = 0;
59 static int event_handlers_alloc_num = 0;
60 static Eina_List *event_handlers_delete_list = NULL;
61
62 static Ecore_Event_Handler *event_handlers_add_list = NULL;
63
64 static Ecore_Event_Filter *event_filters = NULL;
65 static Ecore_Event_Filter *event_filter_current = NULL;
66 static Ecore_Event *event_filter_event_current = NULL;
67 static int event_filters_delete_me = 0;
68 static int event_id_max = ECORE_EVENT_COUNT;
69 static int ecore_raw_event_type = ECORE_EVENT_NONE;
70 static void *ecore_raw_event_event = NULL;
71
72 static void  _ecore_event_purge_deleted(void);
73 static void *_ecore_event_del(Ecore_Event *event);
74
75 EAPI Ecore_Event_Handler *
76 ecore_event_handler_add(int                    type,
77                         Ecore_Event_Handler_Cb func,
78                         const void            *data)
79 {
80    Ecore_Event_Handler *eh = NULL;
81
82    EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
83    _ecore_lock();
84
85    if (!func) goto unlock;
86    if ((type <= ECORE_EVENT_NONE) || (type >= event_id_max)) goto unlock;
87    eh = ecore_event_handler_calloc(1);
88    if (!eh) goto unlock;
89    ECORE_MAGIC_SET(eh, ECORE_MAGIC_EVENT_HANDLER);
90    eh->type = type;
91    eh->func = func;
92    eh->data = (void *)data;
93    if (type >= (event_handlers_num - 1))
94      {
95         int p_alloc_num;
96
97         p_alloc_num = event_handlers_alloc_num;
98         event_handlers_num = type + 1;
99         if (event_handlers_num > event_handlers_alloc_num)
100           {
101              Ecore_Event_Handler **new_handlers;
102              int i;
103
104              event_handlers_alloc_num = ((event_handlers_num + 16) / 16) * 16;
105              new_handlers = realloc(event_handlers, event_handlers_alloc_num * sizeof(Ecore_Event_Handler *));
106              if (!new_handlers)
107                {
108                   ecore_event_handler_mp_free(eh);
109                   goto unlock;
110                }
111              event_handlers = new_handlers;
112              for (i = p_alloc_num; i < event_handlers_alloc_num; i++)
113                event_handlers[i] = NULL;
114           }
115      }
116    if (ecore_raw_event_type == type)
117      event_handlers_add_list = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers_add_list), EINA_INLIST_GET(eh));
118    else if (type < event_handlers_alloc_num)
119      event_handlers[type] = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers[type]), EINA_INLIST_GET(eh));
120
121 unlock:
122    _ecore_unlock();
123    return eh;
124 }
125
126 EAPI void *
127 ecore_event_handler_del(Ecore_Event_Handler *event_handler)
128 {
129    void *data = NULL;
130
131    EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
132    _ecore_lock();
133    if (!ECORE_MAGIC_CHECK(event_handler, ECORE_MAGIC_EVENT_HANDLER))
134      {
135         ECORE_MAGIC_FAIL(event_handler, ECORE_MAGIC_EVENT_HANDLER,
136                          "ecore_event_handler_del");
137         goto unlock;
138      }
139    data = _ecore_event_handler_del(event_handler);
140 unlock:
141    _ecore_unlock();
142
143    return data;
144 }
145
146 EAPI void *
147 ecore_event_handler_data_get(Ecore_Event_Handler *eh)
148 {
149    void *data = NULL;
150
151    EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
152    _ecore_lock();
153    if (!ECORE_MAGIC_CHECK(eh, ECORE_MAGIC_EVENT_HANDLER))
154      {
155         ECORE_MAGIC_FAIL(eh, ECORE_MAGIC_EVENT_HANDLER, "ecore_event_handler_data_get");
156         goto unlock;
157      }
158    data = eh->data;
159 unlock:
160    _ecore_unlock();
161    return data;
162 }
163
164 EAPI void *
165 ecore_event_handler_data_set(Ecore_Event_Handler *eh,
166                              const void          *data)
167 {
168    void *old = NULL;
169
170    EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
171    _ecore_lock();
172    if (!ECORE_MAGIC_CHECK(eh, ECORE_MAGIC_EVENT_HANDLER))
173      {
174         ECORE_MAGIC_FAIL(eh, ECORE_MAGIC_EVENT_HANDLER, "ecore_event_handler_data_set");
175         goto unlock;
176      }
177    old = eh->data;
178    eh->data = (void *)data;
179 unlock:
180    _ecore_unlock();
181
182    return old;
183 }
184
185 static void
186 _ecore_event_generic_free(void *data __UNUSED__,
187                           void *event)
188 { /* DO NOT MEMPOOL FREE THIS */
189    free(event);
190 }
191
192 EAPI Ecore_Event *
193 ecore_event_add(int          type,
194                 void        *ev,
195                 Ecore_End_Cb func_free,
196                 void        *data)
197 {
198    Ecore_Event *event = NULL;
199
200    EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
201    _ecore_lock();
202
203 /*   if (!ev) goto unlock; */
204    if (type <= ECORE_EVENT_NONE) goto unlock;
205    if (type >= event_id_max) goto unlock;
206    if ((ev) && (!func_free)) func_free = _ecore_event_generic_free;
207    event = _ecore_event_add(type, ev, func_free, data);
208 unlock:
209    _ecore_unlock();
210    return event;
211 }
212
213 EAPI void *
214 ecore_event_del(Ecore_Event *event)
215 {
216    void *data = NULL;
217
218    EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
219    _ecore_lock();
220    if (!ECORE_MAGIC_CHECK(event, ECORE_MAGIC_EVENT))
221      {
222         ECORE_MAGIC_FAIL(event, ECORE_MAGIC_EVENT, "ecore_event_del");
223         goto unlock;
224      }
225    EINA_SAFETY_ON_TRUE_GOTO(event->delete_me, unlock);
226    event->delete_me = 1;
227    data = event->data;
228 unlock:
229    _ecore_unlock();
230    return data;
231 }
232
233 EAPI int
234 ecore_event_type_new(void)
235 {
236    int id;
237
238    EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
239    _ecore_lock();
240    id = event_id_max++;
241    _ecore_unlock();
242
243    return id;
244 }
245
246 EAPI Ecore_Event_Filter *
247 ecore_event_filter_add(Ecore_Data_Cb   func_start,
248                        Ecore_Filter_Cb func_filter,
249                        Ecore_End_Cb    func_end,
250                        const void     *data)
251 {
252    Ecore_Event_Filter *ef = NULL;
253
254    EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
255    _ecore_lock();
256    if (!func_filter) goto unlock;
257    ef = ecore_event_filter_calloc(1);
258    if (!ef) goto unlock;
259    ECORE_MAGIC_SET(ef, ECORE_MAGIC_EVENT_FILTER);
260    ef->func_start = func_start;
261    ef->func_filter = func_filter;
262    ef->func_end = func_end;
263    ef->data = (void *)data;
264    event_filters = (Ecore_Event_Filter *)eina_inlist_append(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
265 unlock:
266    _ecore_unlock();
267    return ef;
268 }
269
270 EAPI void *
271 ecore_event_filter_del(Ecore_Event_Filter *ef)
272 {
273    void *data = NULL;
274
275    EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
276    _ecore_lock();
277    if (!ECORE_MAGIC_CHECK(ef, ECORE_MAGIC_EVENT_FILTER))
278      {
279         ECORE_MAGIC_FAIL(ef, ECORE_MAGIC_EVENT_FILTER, "ecore_event_filter_del");
280         goto unlock;
281      }
282    EINA_SAFETY_ON_TRUE_GOTO(ef->delete_me, unlock);
283    ef->delete_me = 1;
284    event_filters_delete_me = 1;
285    data = ef->data;
286 unlock:
287    _ecore_unlock();
288
289    return data;
290 }
291
292 EAPI int
293 ecore_event_current_type_get(void)
294 {
295    EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
296    return ecore_raw_event_type;
297 }
298
299 EAPI void *
300 ecore_event_current_event_get(void)
301 {
302    EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
303    return ecore_raw_event_event;
304 }
305
306 EAPI void *
307 _ecore_event_handler_del(Ecore_Event_Handler *event_handler)
308 {
309    EINA_SAFETY_ON_TRUE_RETURN_VAL(event_handler->delete_me, NULL);
310    event_handler->delete_me = 1;
311    event_handlers_delete_list = eina_list_append(event_handlers_delete_list, event_handler);
312    return event_handler->data;
313 }
314
315 void
316 _ecore_event_shutdown(void)
317 {
318    int i;
319    Ecore_Event_Handler *eh;
320    Ecore_Event_Filter *ef;
321
322    while (events) _ecore_event_del(events);
323    event_current = NULL;
324    for (i = 0; i < event_handlers_num; i++)
325      {
326         while ((eh = event_handlers[i]))
327           {
328              event_handlers[i] = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers[i]), EINA_INLIST_GET(event_handlers[i]));
329              ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
330              if (!eh->delete_me) ecore_event_handler_mp_free(eh);
331           }
332      }
333    EINA_LIST_FREE(event_handlers_delete_list, eh)
334      ecore_event_handler_mp_free(eh);
335    if (event_handlers) free(event_handlers);
336    event_handlers = NULL;
337    event_handlers_num = 0;
338    event_handlers_alloc_num = 0;
339    while ((ef = event_filters))
340      {
341         event_filters = (Ecore_Event_Filter *)eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(event_filters));
342         ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
343         ecore_event_filter_mp_free(ef);
344      }
345    event_filters_delete_me = 0;
346    event_filter_current = NULL;
347    event_filter_event_current = NULL;
348 }
349
350 int
351 _ecore_event_exist(void)
352 {
353    Ecore_Event *e;
354    EINA_INLIST_FOREACH(events, e)
355      if (!e->delete_me) return 1;
356    return 0;
357 }
358
359 Ecore_Event *
360 _ecore_event_add(int          type,
361                  void        *ev,
362                  Ecore_End_Cb func_free,
363                  void        *data)
364 {
365    Ecore_Event *e;
366
367    e = ecore_event_calloc(1);
368    if (!e) return NULL;
369    ECORE_MAGIC_SET(e, ECORE_MAGIC_EVENT);
370    e->type = type;
371    e->event = ev;
372    e->func_free = func_free;
373    e->data = data;
374    if (inpurge > 0)
375      {
376         purge_events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(purge_events), EINA_INLIST_GET(e));
377         events_num++;
378      }
379    else
380      {
381         events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(events), EINA_INLIST_GET(e));
382         events_num++;
383      }
384    return e;
385 }
386
387 void *
388 _ecore_event_del(Ecore_Event *event)
389 {
390    void *data;
391
392    data = event->data;
393    if (event->func_free) _ecore_call_end_cb(event->func_free, event->data, event->event);
394    events = (Ecore_Event *)eina_inlist_remove(EINA_INLIST_GET(events), EINA_INLIST_GET(event));
395    ECORE_MAGIC_SET(event, ECORE_MAGIC_NONE);
396    ecore_event_mp_free(event);
397    events_num--;
398    return data;
399 }
400
401 static void
402 _ecore_event_purge_deleted(void)
403 {
404    Ecore_Event *itr = events;
405
406    inpurge++;
407    while (itr)
408      {
409         Ecore_Event *next = (Ecore_Event *)EINA_INLIST_GET(itr)->next;
410         if ((!itr->references) && (itr->delete_me))
411           _ecore_event_del(itr);
412         itr = next;
413      }
414    inpurge--;
415    while (purge_events)
416      {
417         Ecore_Event *e = purge_events;
418         purge_events = (Ecore_Event *)eina_inlist_remove(EINA_INLIST_GET(purge_events), EINA_INLIST_GET(purge_events));
419         events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(events), EINA_INLIST_GET(e));
420      }
421 }
422
423 static inline void
424 _ecore_event_filters_apply()
425 {
426    if (!event_filter_current)
427      {
428         /* regular main loop, start from head */
429          event_filter_current = event_filters;
430      }
431    else
432      {
433         /* recursive main loop, continue from where we were */
434          event_filter_current = (Ecore_Event_Filter *)EINA_INLIST_GET(event_filter_current)->next;
435      }
436
437    while (event_filter_current)
438      {
439         Ecore_Event_Filter *ef = event_filter_current;
440
441         if (!ef->delete_me)
442           {
443              ef->references++;
444
445              if (ef->func_start)
446                ef->loop_data = _ecore_call_data_cb(ef->func_start, ef->data);
447
448              if (!event_filter_event_current)
449                {
450      /* regular main loop, start from head */
451                    event_filter_event_current = events;
452                }
453              else
454                {
455      /* recursive main loop, continue from where we were */
456                    event_filter_event_current = (Ecore_Event *)EINA_INLIST_GET(event_filter_event_current)->next;
457                }
458
459              while (event_filter_event_current)
460                {
461                   Ecore_Event *e = event_filter_event_current;
462
463                   if (!_ecore_call_filter_cb(ef->func_filter, ef->data,
464                                              ef->loop_data, e->type, e->event))
465                     {
466                        ecore_event_del(e);
467                     }
468
469                   if (event_filter_event_current) /* may have changed in recursive main loops */
470                     event_filter_event_current = (Ecore_Event *)EINA_INLIST_GET(event_filter_event_current)->next;
471                }
472              if (ef->func_end)
473                _ecore_call_end_cb(ef->func_end, ef->data, ef->loop_data);
474
475              ef->references--;
476           }
477
478         if (event_filter_current) /* may have changed in recursive main loops */
479           event_filter_current = (Ecore_Event_Filter *)EINA_INLIST_GET(event_filter_current)->next;
480      }
481    if (event_filters_delete_me)
482      {
483         int deleted_in_use = 0;
484         Ecore_Event_Filter *l;
485         for (l = event_filters; l; )
486           {
487              Ecore_Event_Filter *ef = l;
488              l = (Ecore_Event_Filter *)EINA_INLIST_GET(l)->next;
489              if (ef->delete_me)
490                {
491                   if (ef->references)
492                     {
493                        deleted_in_use++;
494                        continue;
495                     }
496
497                   event_filters = (Ecore_Event_Filter *)eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
498                   ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
499                   ecore_event_filter_mp_free(ef);
500                }
501           }
502         if (!deleted_in_use)
503           event_filters_delete_me = 0;
504      }
505 }
506
507 void
508 _ecore_event_call(void)
509 {
510    Eina_List *l, *l_next;
511    Ecore_Event_Handler *eh;
512
513    _ecore_event_filters_apply();
514
515    if (!event_current)
516      {
517         /* regular main loop, start from head */
518          event_current = events;
519          event_handler_current = NULL;
520      }
521
522    while (event_current)
523      {
524         Ecore_Event *e = event_current;
525         int handle_count = 0;
526
527         if (e->delete_me)
528           {
529              event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next;
530              continue;
531           }
532
533         ecore_raw_event_type = e->type;
534         ecore_raw_event_event = e->event;
535         e->references++;
536         if ((e->type >= 0) && (e->type < event_handlers_num))
537           {
538              if (!event_handler_current)
539                {
540      /* regular main loop, start from head */
541                    event_handler_current = event_handlers[e->type];
542                }
543              else
544                {
545      /* recursive main loop, continue from where we were */
546                    event_handler_current = (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next;
547                }
548
549              while ((event_handler_current) && (!e->delete_me))
550                {
551                   eh = event_handler_current;
552                   if (!eh->delete_me)
553                     {
554                        Eina_Bool ret;
555
556                        handle_count++;
557
558                        eh->references++;
559                        ret = _ecore_call_handler_cb(eh->func, eh->data, e->type, e->event);
560                        eh->references--;
561
562                        if (!ret)
563                          {
564                             event_handler_current = NULL;
565                             break;  /* 0 == "call no further handlers" */
566                          }
567                     }
568
569                   if (event_handler_current) /* may have changed in recursive main loops */
570                     event_handler_current = (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next;
571                }
572           }
573         while (event_handlers_add_list)
574           {
575              eh = event_handlers_add_list;
576              event_handlers_add_list = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers_add_list), EINA_INLIST_GET(eh));
577              event_handlers[eh->type] = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh));
578           }
579         /* if no handlers were set for EXIT signal - then default is */
580         /* to quit the main loop */
581         if ((e->type == ECORE_EVENT_SIGNAL_EXIT) && (handle_count == 0))
582           ecore_main_loop_quit();
583         e->references--;
584         e->delete_me = 1;
585
586         if (event_current) /* may have changed in recursive main loops */
587           event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next;
588      }
589
590    ecore_raw_event_type = ECORE_EVENT_NONE;
591    ecore_raw_event_event = NULL;
592
593    _ecore_event_purge_deleted();
594
595    EINA_LIST_FOREACH_SAFE(event_handlers_delete_list, l, l_next, eh)
596      {
597         if (eh->references) continue;
598
599         event_handlers_delete_list = eina_list_remove_list(event_handlers_delete_list, l);
600
601         event_handlers[eh->type] = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh));
602         ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
603         ecore_event_handler_mp_free(eh);
604      }
605 }
606
607 void *
608 _ecore_event_signal_user_new(void)
609 {
610    Ecore_Event_Signal_User *e;
611
612    e = calloc(1, sizeof(Ecore_Event_Signal_User));
613    return e;
614 }
615
616 void *
617 _ecore_event_signal_hup_new(void)
618 {
619    Ecore_Event_Signal_Hup *e;
620
621    e = calloc(1, sizeof(Ecore_Event_Signal_Hup));
622    return e;
623 }
624
625 void *
626 _ecore_event_signal_exit_new(void)
627 {
628    Ecore_Event_Signal_Exit *e;
629
630    e = calloc(1, sizeof(Ecore_Event_Signal_Exit));
631    return e;
632 }
633
634 void *
635 _ecore_event_signal_power_new(void)
636 {
637    Ecore_Event_Signal_Power *e;
638
639    e = calloc(1, sizeof(Ecore_Event_Signal_Power));
640    return e;
641 }
642
643 void *
644 _ecore_event_signal_realtime_new(void)
645 {
646    return calloc(1, sizeof(Ecore_Event_Signal_Realtime));
647 }
648