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