a213a007ea3ec5a77f31c03111a6c62ee7f174be
[profile/ivi/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
23 struct _Ecore_Event_Filter
24 {
25    EINA_INLIST;
26    ECORE_MAGIC;
27    Ecore_Data_Cb func_start;
28    Ecore_Filter_Cb func_filter;
29    Ecore_End_Cb func_end;
30    void *loop_data;
31    void *data;
32    int       references;
33    Eina_Bool delete_me : 1;
34 };
35
36 struct _Ecore_Event
37 {
38    EINA_INLIST;
39    ECORE_MAGIC;
40    int type;
41    void *event;
42    Ecore_End_Cb func_free;
43    void *data;
44    int       references;
45    Eina_Bool delete_me : 1;
46 };
47
48
49 static int events_num = 0;
50 static Ecore_Event *events = NULL;
51 static Ecore_Event *event_current = NULL;
52 static Ecore_Event *purge_events = NULL;
53
54 static Ecore_Event_Handler **event_handlers = NULL;
55 static Ecore_Event_Handler *event_handler_current = NULL;
56 static int event_handlers_num = 0;
57 static int event_handlers_alloc_num = 0;
58 static Eina_List *event_handlers_delete_list = NULL;
59
60 static Ecore_Event_Filter *event_filters = NULL;
61 static Ecore_Event_Filter *event_filter_current = NULL;
62 static Ecore_Event *event_filter_event_current = NULL;
63 static int event_filters_delete_me = 0;
64 static int event_id_max = ECORE_EVENT_COUNT;
65 static int ecore_raw_event_type = ECORE_EVENT_NONE;
66 static void *ecore_raw_event_event =  NULL;
67
68
69 static void _ecore_event_purge_deleted(void);
70 static void *_ecore_event_del(Ecore_Event *event);
71
72
73 /**
74  * Add an event handler.
75  * @param type The type of the event this handler will get called for
76  * @param func The function to call when the event is found in the queue
77  * @param data A data pointer to pass to the called function @p func
78  * @return A new Event handler, or NULL on failure
79  *
80  * Add an event handler to the list of handlers. This will, on success, return
81  * a handle to the event handler object that was created, that can be used
82  * later to remove the handler using ecore_event_handler_del(). The @p type
83  * parameter is the integer of the event type that will trigger this callback
84  * to be called. The callback @p func is called when this event is processed
85  * and will be passed the event type, a pointer to the private event
86  * structure that is specific to that event type, and a data pointer that is
87  * provided in this call as the @p data parameter.
88  *
89  * When the callback @p func is called, it must return 1 or 0. If it returns
90  * 1 (or ECORE_CALLBACK_RENEW), It will keep being called as per normal, for
91  * each handler set up for that event type. If it returns 0 (or
92  * ECORE_CALLBACK_CANCEL), it will cease processing handlers for that particular
93  * event, so all handler set to handle that event type that have not already
94  * been called, will not be.
95  */
96 EAPI Ecore_Event_Handler *
97 ecore_event_handler_add(int type, Ecore_Event_Handler_Cb func, const void *data)
98 {
99    Ecore_Event_Handler *eh;
100
101    if (!func) return NULL;
102    if ((type <= ECORE_EVENT_NONE) || (type >= event_id_max)) return NULL;
103    eh = calloc(1, sizeof(Ecore_Event_Handler));
104    if (!eh) return NULL;
105    ECORE_MAGIC_SET(eh, ECORE_MAGIC_EVENT_HANDLER);
106    eh->type = type;
107    eh->func = func;
108    eh->data = (void *)data;
109    if (type >= (event_handlers_num - 1))
110      {
111         int p_alloc_num;
112
113         p_alloc_num = event_handlers_alloc_num;
114         event_handlers_num = type + 1;
115         if (event_handlers_num > event_handlers_alloc_num)
116           {
117              Ecore_Event_Handler **new_handlers;
118              int i;
119
120              event_handlers_alloc_num = ((event_handlers_num + 16) / 16) * 16;
121              new_handlers = realloc(event_handlers, event_handlers_alloc_num * sizeof(Ecore_Event_Handler *));
122              if (!new_handlers)
123                {
124                   free(eh);
125                   return NULL;
126                }
127              event_handlers = new_handlers;
128              for (i = p_alloc_num; i < event_handlers_alloc_num; i++)
129                event_handlers[i] = NULL;
130           }
131      }
132    event_handlers[type] = (Ecore_Event_Handler *) eina_inlist_append(EINA_INLIST_GET(event_handlers[type]), EINA_INLIST_GET(eh));
133    return eh;
134 }
135
136 /**
137  * Delete an event handler.
138  * @param event_handler Event handler handle to delete
139  * @return Data passed to handler
140  *
141  * Delete a specified event handler from the handler list. On success this will
142  * delete the event handler and return the pointer passed as @p data when the
143  * handler was added by ecore_event_handler_add(). On failure NULL will be
144  * returned. Once a handler is deleted it will no longer be called.
145  */
146 EAPI void *
147 ecore_event_handler_del(Ecore_Event_Handler *event_handler)
148 {
149    if (!ECORE_MAGIC_CHECK(event_handler, ECORE_MAGIC_EVENT_HANDLER))
150      {
151         ECORE_MAGIC_FAIL(event_handler, ECORE_MAGIC_EVENT_HANDLER,
152                          "ecore_event_handler_del");
153         return NULL;
154      }
155    EINA_SAFETY_ON_TRUE_RETURN_VAL(event_handler->delete_me, NULL);
156    event_handler->delete_me = 1;
157    event_handlers_delete_list = eina_list_append(event_handlers_delete_list, event_handler);
158    return event_handler->data;
159 }
160
161 static void
162 _ecore_event_generic_free (void *data __UNUSED__, void *event)
163 {
164    free (event);
165 }
166
167 /**
168  * Add an event to the event queue.
169  * @param type The event type to add to the end of the event queue
170  * @param ev The private data structure for this event type
171  * @param func_free The function to be called to free this private structure
172  * @param data The data pointer to be passed to the free function
173  * @return A Handle for that event
174  *
175  * On success this function returns a handle to an event on the event queue, or
176  * NULL if it fails. If it succeeds, an event of type @p type will be added
177  * to the queue for processing by event handlers added by
178  * ecore_event_handler_add(). The @p ev parameter will be a pointer to the event
179  * private data that is specific to that event type. When the event is no
180  * longer needed, @p func_free will be called and passed the private structure
181  * pointer for cleaning up. If @p func_free is NULL, free() will be called
182  * with the private structure pointer.
183  * func_free is passed @p data as its data parameter.
184  */
185 EAPI Ecore_Event *
186 ecore_event_add(int type, void *ev, Ecore_End_Cb func_free, void *data)
187 {
188 /*   if (!ev) return NULL;*/
189    if (type <= ECORE_EVENT_NONE) return NULL;
190    if (type >= event_id_max) return NULL;
191    if ((ev) && (!func_free)) func_free = _ecore_event_generic_free;
192    return _ecore_event_add(type, ev, func_free, data);
193 }
194
195 /**
196  * Delete an event from the queue.
197  * @param event The event handle to delete
198  * @return The data pointer originally set for the event free function
199  *
200  * This deletes the event @p event from the event queue, and returns the
201  * @p data parameer originally set when adding it with ecore_event_add(). This
202  * does not immediately call the free function, and it may be called later on
203  * cleanup, and so if the free function depends on the data pointer to work,
204  * you should defer cleaning of this till the free function is called later.
205  */
206 EAPI void *
207 ecore_event_del(Ecore_Event *event)
208 {
209    if (!ECORE_MAGIC_CHECK(event, ECORE_MAGIC_EVENT))
210      {
211         ECORE_MAGIC_FAIL(event, ECORE_MAGIC_EVENT, "ecore_event_del");
212         return NULL;
213      }
214    EINA_SAFETY_ON_TRUE_RETURN_VAL(event->delete_me, NULL);
215    event->delete_me = 1;
216    return event->data;
217 }
218
219 /**
220  * Allocate a new event type id sensibly and return the new id.
221  * @return A new event type id.
222  *
223  * This function allocates a new event type id and returns it. Once an event
224  * type has been allocated it can never be de-allocated during the life of
225  * the program. There is no guarantee of the contents of this event ID, or how
226  * it is calculated, except that the ID will be unique to the current instance
227  * of the process.
228  */
229 EAPI int
230 ecore_event_type_new(void)
231 {
232    event_id_max++;
233    return event_id_max - 1;
234 }
235
236 /**
237  * Add a filter the current event queue.
238  * @param func_start Function to call just before filtering and return data
239  * @param func_filter Function to call on each event
240  * @param func_end Function to call after the queu has been filtered
241  * @param data Data to pass to the filter functions
242  * @return A filter handle
243  *
244  * This adds a filter to call callbacks to loop through the event queue and
245  * filter events out of the queue. On failure NULL is returned. On success a
246  * Filter handle is returned. Filters are called on the queue just before
247  * Event handler processing to try and remove redundant events. Just as
248  * processing starts @p func_start is called and passed the @p data pointer.
249  * This function returns a pointer that is used as loop_data that is now passed to
250  * @p func_filter as loop_data. @p func_filter is also passed @p data and the
251  * event type and private event structure. If this callback returns 0, the
252  * event is removed from the queue. If it returns 1, the event is kept. When
253  * processing is finished @p func_end is called and is passed the loop_data
254  * and @p data pointer to clean up.
255  */
256 EAPI Ecore_Event_Filter *
257 ecore_event_filter_add(Ecore_Data_Cb func_start, Ecore_Filter_Cb func_filter, Ecore_End_Cb func_end, const void *data)
258 {
259    Ecore_Event_Filter *ef;
260
261    if (!func_filter) return NULL;
262    ef = calloc(1, sizeof(Ecore_Event_Filter));
263    if (!ef) return NULL;
264    ECORE_MAGIC_SET(ef, ECORE_MAGIC_EVENT_FILTER);
265    ef->func_start = func_start;
266    ef->func_filter = func_filter;
267    ef->func_end = func_end;
268    ef->data = (void *)data;
269    event_filters = (Ecore_Event_Filter *) eina_inlist_append(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
270    return ef;
271 }
272
273 /**
274  * Delete an event filter.
275  * @param ef The event filter handle
276  * @return The data set for the filter
277  *
278  * Delete a filter that has been added by its @p ef handle. On success this
279  * will return the data pointer set when this filter was added. On failure
280  * NULL is returned.
281  */
282 EAPI void *
283 ecore_event_filter_del(Ecore_Event_Filter *ef)
284 {
285    if (!ECORE_MAGIC_CHECK(ef, ECORE_MAGIC_EVENT_FILTER))
286      {
287         ECORE_MAGIC_FAIL(ef, ECORE_MAGIC_EVENT_FILTER, "ecore_event_filter_del");
288         return NULL;
289      }
290    EINA_SAFETY_ON_TRUE_RETURN_VAL(ef->delete_me, NULL);
291    ef->delete_me = 1;
292    event_filters_delete_me = 1;
293    return ef->data;
294 }
295
296 /**
297  * Return the current event type being handled.
298  * @return The current event type being handled if inside a handler callback
299  *
300  * If the program is currently inside an Ecore event handler callback this
301  * will return the type of the current event being processed. If Ecore is
302  * not inside an event handler, ECORE_EVENT_NONE is returned.
303  *
304  * This is useful when certain Ecore modules such as Ecore_Evas "swallow"
305  * events and not all the original information is passed on. In special cases
306  * this extra information may be useful or needed and using this call can let
307  * the program know if the event type being handled is one it wants to get more
308  * information about.
309  */
310 EAPI int
311 ecore_event_current_type_get(void)
312 {
313    return ecore_raw_event_type;
314 }
315
316 /**
317  * Return the current event type pointer handled.
318  * @return The current event pointer being handled if inside a handler callback
319  *
320  * If the program is currently inside an Ecore event handler callback this
321  * will return the pointer of the current event being processed. If Ecore is
322  * not inside an event handler, NULL will be returned.
323  *
324  * This is useful when certain Ecore modules such as Ecore_Evas "swallow"
325  * events and not all the original information is passed on. In special cases
326  * this extra information may be useful or needed and using this call can let
327  * the program access the event data if the type of the event is handled by
328  * the program.
329  */
330 EAPI void *
331 ecore_event_current_event_get(void)
332 {
333    return ecore_raw_event_event;
334 }
335
336 void
337 _ecore_event_shutdown(void)
338 {
339    int i;
340    Ecore_Event_Handler *eh;
341    Ecore_Event_Filter *ef;
342
343    while (events) _ecore_event_del(events);
344    event_current = NULL;
345    for (i = 0; i < event_handlers_num; i++)
346      {
347         while ((eh = event_handlers[i]))
348           {
349              event_handlers[i] = (Ecore_Event_Handler *) eina_inlist_remove(EINA_INLIST_GET(event_handlers[i]), EINA_INLIST_GET(event_handlers[i]));
350              ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
351              if (!eh->delete_me) free(eh);
352           }
353      }
354    EINA_LIST_FREE(event_handlers_delete_list, eh)
355      free(eh);
356    if (event_handlers) free(event_handlers);
357    event_handlers = NULL;
358    event_handlers_num = 0;
359    event_handlers_alloc_num = 0;
360    while ((ef = event_filters))
361      {
362         event_filters = (Ecore_Event_Filter *) eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(event_filters));
363         ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
364         free(ef);
365      }
366    event_filters_delete_me = 0;
367    event_filter_current = NULL;
368    event_filter_event_current = NULL;
369 }
370
371 int
372 _ecore_event_exist(void)
373 {
374    Ecore_Event *e;
375    EINA_INLIST_FOREACH(events, e)
376       if (!e->delete_me) return 1;
377    return 0;
378 }
379
380 Ecore_Event *
381 _ecore_event_add(int type, void *ev, Ecore_End_Cb func_free, void *data)
382 {
383    Ecore_Event *e;
384
385    e = calloc(1, sizeof(Ecore_Event));
386    if (!e) return NULL;
387    ECORE_MAGIC_SET(e, ECORE_MAGIC_EVENT);
388    e->type = type;
389    e->event = ev;
390    e->func_free = func_free;
391    e->data = data;
392    if (inpurge > 0)
393      {
394         purge_events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(purge_events), EINA_INLIST_GET(e));
395         events_num++;
396      }
397    else
398      {
399         events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(events), EINA_INLIST_GET(e));
400         events_num++;
401      }
402    return e;
403 }
404
405 void *
406 _ecore_event_del(Ecore_Event *event)
407 {
408    void *data;
409
410    data = event->data;
411    if (event->func_free) event->func_free(event->data, event->event);
412    events = (Ecore_Event *) eina_inlist_remove(EINA_INLIST_GET(events), EINA_INLIST_GET(event));
413    ECORE_MAGIC_SET(event, ECORE_MAGIC_NONE);
414    free(event);
415    events_num--;
416    return data;
417 }
418
419 static void
420 _ecore_event_purge_deleted(void)
421 {
422    Ecore_Event *itr = events;
423
424    inpurge++;
425    while (itr)
426      {
427         Ecore_Event *next = (Ecore_Event *)EINA_INLIST_GET(itr)->next;
428         if ((!itr->references) && (itr->delete_me))
429           _ecore_event_del(itr);
430         itr = next;
431      }
432    inpurge--;
433    while (purge_events)
434      {
435         Ecore_Event *e = purge_events;
436         purge_events = (Ecore_Event *)eina_inlist_remove(EINA_INLIST_GET(purge_events), EINA_INLIST_GET(purge_events));
437         events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(events), EINA_INLIST_GET(e));
438      }
439 }
440
441 static inline void
442 _ecore_event_filters_apply()
443 {
444
445    if (!event_filter_current)
446      {
447         /* regular main loop, start from head */
448         event_filter_current = event_filters;
449      }
450    else
451      {
452         /* recursive main loop, continue from where we were */
453         event_filter_current = (Ecore_Event_Filter *)EINA_INLIST_GET(event_filter_current)->next;
454      }
455
456    while (event_filter_current)
457      {
458         Ecore_Event_Filter *ef = event_filter_current;
459
460         if (!ef->delete_me)
461           {
462              ef->references++;
463
464              if (ef->func_start)
465                ef->loop_data = ef->func_start(ef->data);
466
467              if (!event_filter_event_current)
468                {
469                   /* regular main loop, start from head */
470                   event_filter_event_current = events;
471                }
472              else
473                {
474                   /* recursive main loop, continue from where we were */
475                   event_filter_event_current = (Ecore_Event *)EINA_INLIST_GET(event_filter_event_current)->next;
476                }
477
478              while (event_filter_event_current)
479                {
480                   Ecore_Event *e = event_filter_event_current;
481
482                   if (!ef->func_filter(ef->data, ef->loop_data,
483                                        e->type, e->event))
484                     {
485                        ecore_event_del(e);
486                     }
487
488                   if (event_filter_event_current) /* may have changed in recursive main loops */
489                     event_filter_event_current = (Ecore_Event *)EINA_INLIST_GET(event_filter_event_current)->next;
490                }
491              if (ef->func_end)
492                ef->func_end(ef->data, ef->loop_data);
493
494              ef->references--;
495           }
496
497         if (event_filter_current) /* may have changed in recursive main loops */
498           event_filter_current = (Ecore_Event_Filter *)EINA_INLIST_GET(event_filter_current)->next;
499      }
500    if (event_filters_delete_me)
501      {
502         int deleted_in_use = 0;
503         Ecore_Event_Filter *l;
504         for (l = event_filters; l;)
505           {
506              Ecore_Event_Filter *ef = l;
507              l = (Ecore_Event_Filter *) EINA_INLIST_GET(l)->next;
508              if (ef->delete_me)
509                {
510                   if (ef->references)
511                     {
512                        deleted_in_use++;
513                        continue;
514                     }
515
516                   event_filters = (Ecore_Event_Filter *) eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
517                   ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
518                   free(ef);
519                }
520           }
521         if (!deleted_in_use)
522           event_filters_delete_me = 0;
523      }
524 }
525 void
526 _ecore_event_call(void)
527 {
528    Eina_List *l, *l_next;
529    Ecore_Event_Handler *eh;
530
531    _ecore_event_filters_apply();
532
533    if (!event_current)
534      {
535         /* regular main loop, start from head */
536         event_current = events;
537         event_handler_current = NULL;
538      }
539
540    while (event_current)
541      {
542         Ecore_Event *e = event_current;
543         int handle_count = 0;
544
545         if (e->delete_me)
546           {
547              event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next;
548              continue;
549           }
550
551         ecore_raw_event_type = e->type;
552         ecore_raw_event_event = e->event;
553         e->references++;
554         if ((e->type >= 0) && (e->type < event_handlers_num))
555           {
556              if (!event_handler_current)
557                {
558                   /* regular main loop, start from head */
559                   event_handler_current = event_handlers[e->type];
560                }
561              else
562                {
563                   /* recursive main loop, continue from where we were */
564                   event_handler_current = (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next;
565                }
566
567              while ((event_handler_current) && (!e->delete_me))
568                {
569                   Ecore_Event_Handler *eh = event_handler_current;
570                   if (!eh->delete_me)
571                     {
572                        Eina_Bool ret;
573
574                        handle_count++;
575
576                        eh->references++;
577                        ret = eh->func(eh->data, e->type, e->event);
578                        eh->references--;
579
580                        if (!ret)
581                          {
582                             event_handler_current = NULL;
583                             break;  /* 0 == "call no further handlers" */
584                          }
585                     }
586
587                   if (event_handler_current) /* may have changed in recursive main loops */
588                     event_handler_current = (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next;
589                }
590           }
591         /* if no handlers were set for EXIT signal - then default is */
592         /* to quit the main loop */
593         if ((e->type == ECORE_EVENT_SIGNAL_EXIT) && (handle_count == 0))
594           ecore_main_loop_quit();
595         e->references--;
596         e->delete_me = 1;
597
598         if (event_current) /* may have changed in recursive main loops */
599           event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next;
600      }
601
602    ecore_raw_event_type = ECORE_EVENT_NONE;
603    ecore_raw_event_event = NULL;
604
605    _ecore_event_purge_deleted();
606
607    EINA_LIST_FOREACH_SAFE(event_handlers_delete_list, l, l_next, eh)
608      {
609         if (eh->references) continue;
610
611         event_handlers_delete_list = eina_list_remove_list(event_handlers_delete_list, l);
612
613         event_handlers[eh->type] = (Ecore_Event_Handler *) eina_inlist_remove(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh));
614         ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
615         free(eh);
616      }
617 }
618
619 EAPI void *
620 _ecore_event_signal_user_new(void)
621 {
622    Ecore_Event_Signal_User *e;
623
624    e = calloc(1, sizeof(Ecore_Event_Signal_User));
625    return e;
626 }
627
628 void *
629 _ecore_event_signal_hup_new(void)
630 {
631    Ecore_Event_Signal_Hup *e;
632
633    e = calloc(1, sizeof(Ecore_Event_Signal_Hup));
634    return e;
635 }
636
637 void *
638 _ecore_event_signal_exit_new(void)
639 {
640    Ecore_Event_Signal_Exit *e;
641
642    e = calloc(1, sizeof(Ecore_Event_Signal_Exit));
643    return e;
644 }
645
646 void *
647 _ecore_event_signal_power_new(void)
648 {
649    Ecore_Event_Signal_Power *e;
650
651    e = calloc(1, sizeof(Ecore_Event_Signal_Power));
652    return e;
653 }
654
655 void *
656 _ecore_event_signal_realtime_new(void)
657 {
658    return calloc(1, sizeof(Ecore_Event_Signal_Realtime));
659 }