svn update: 48958 (latest:48959)
[framework/uifw/ecore.git] / src / lib / ecore / ecore_events.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #ifdef HAVE_CONFIG_H
6 # include <config.h>
7 #endif
8
9 #include <stdlib.h>
10
11 #include "Ecore.h"
12 #include "ecore_private.h"
13
14
15 struct _Ecore_Event_Handler
16 {
17    EINA_INLIST;
18    ECORE_MAGIC;
19    int type;
20    int (*func) (void *data, int type, void *event);
21    void  *data;
22    int       references;
23    Eina_Bool delete_me : 1;
24 };
25
26 struct _Ecore_Event_Filter
27 {
28    EINA_INLIST;
29    ECORE_MAGIC;
30    void *(*func_start) (void *data);
31    int (*func_filter) (void *data, void *loop_data, int type, void *event);
32    void (*func_end) (void *data, void *loop_data);
33    void *loop_data;
34    void *data;
35    int       references;
36    Eina_Bool delete_me : 1;
37 };
38
39 struct _Ecore_Event
40 {
41    EINA_INLIST;
42    ECORE_MAGIC;
43    int type;
44    void *event;
45    void (*func_free) (void *data, void *ev);
46    void *data;
47    int       references;
48    Eina_Bool delete_me : 1;
49 };
50
51
52 static int events_num = 0;
53 static Ecore_Event *events = NULL;
54 static Ecore_Event *event_current = 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_Filter *event_filters = NULL;
63 static Ecore_Event_Filter *event_filter_current = NULL;
64 static int event_filters_delete_me = 0;
65 static int event_id_max = ECORE_EVENT_COUNT;
66 static int ecore_raw_event_type = ECORE_EVENT_NONE;
67 static void *ecore_raw_event_event =  NULL;
68
69
70 static void _ecore_event_purge_deleted(void);
71 static void *_ecore_event_del(Ecore_Event *event);
72
73
74 /**
75  * Add an event handler.
76  * @param type The type of the event this handler will get called for
77  * @param func The function to call when the event is found in the queue
78  * @param data A data pointer to pass to the called function @p func
79  * @return A new Event handler, or NULL on failure
80  *
81  * Add an event handler to the list of handlers. This will, on success, return
82  * a handle to the event handler object that was created, that can be used
83  * later to remove the handler using ecore_event_handler_del(). The @p type
84  * parameter is the integer of the event type that will trigger this callback
85  * to be called. The callback @p func is called when this event is processed
86  * and will be passed the event type, a pointer to the private event
87  * structure that is specific to that event type, and a data pointer that is
88  * provided in this call as the @p data parameter.
89  *
90  * When the callback @p func is called, it must return 1 or 0. If it returns
91  * 1 (or ECORE_CALLBACK_RENEW), It will keep being called as per normal, for
92  * each handler set up for that event type. If it returns 0 (or
93  * ECORE_CALLBACK_CANCEL), it will cease processing handlers for that particular
94  * event, so all handler set to handle that event type that have not already
95  * been called, will not be.
96  */
97 EAPI Ecore_Event_Handler *
98 ecore_event_handler_add(int type, int (*func) (void *data, int type, void *event), const void *data)
99 {
100    Ecore_Event_Handler *eh;
101
102    if (!func) return NULL;
103    if ((type <= ECORE_EVENT_NONE) || (type >= event_id_max)) return NULL;
104    eh = calloc(1, sizeof(Ecore_Event_Handler));
105    if (!eh) return NULL;
106    ECORE_MAGIC_SET(eh, ECORE_MAGIC_EVENT_HANDLER);
107    eh->type = type;
108    eh->func = func;
109    eh->data = (void *)data;
110    if (type >= (event_handlers_num - 1))
111      {
112         int p_alloc_num;
113
114         p_alloc_num = event_handlers_alloc_num;
115         event_handlers_num = type + 1;
116         if (event_handlers_num > event_handlers_alloc_num)
117           {
118              Ecore_Event_Handler **new_handlers;
119              int i;
120
121              event_handlers_alloc_num = ((event_handlers_num + 16) / 16) * 16;
122              new_handlers = realloc(event_handlers, event_handlers_alloc_num * sizeof(Ecore_Event_Handler *));
123              if (!new_handlers)
124                {
125                   free(eh);
126                   return NULL;
127                }
128              event_handlers = new_handlers;
129              for (i = p_alloc_num; i < event_handlers_alloc_num; i++)
130                event_handlers[i] = NULL;
131           }
132      }
133    event_handlers[type] = (Ecore_Event_Handler *) eina_inlist_append(EINA_INLIST_GET(event_handlers[type]), EINA_INLIST_GET(eh));
134    return eh;
135 }
136
137 /**
138  * Delete an event handler.
139  * @param event_handler Event handler handle to delete
140  * @return Data passed to handler
141  *
142  * Delete a specified event handler from the handler list. On success this will
143  * delete the event handler and return the pointer passed as @p data when the
144  * handler was added by ecore_event_handler_add(). On failure NULL will be
145  * returned. Once a handler is deleted it will no longer be called.
146  */
147 EAPI void *
148 ecore_event_handler_del(Ecore_Event_Handler *event_handler)
149 {
150    if (!ECORE_MAGIC_CHECK(event_handler, ECORE_MAGIC_EVENT_HANDLER))
151      {
152         ECORE_MAGIC_FAIL(event_handler, ECORE_MAGIC_EVENT_HANDLER,
153                          "ecore_event_handler_del");
154         return NULL;
155      }
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, void (*func_free) (void *data, void *ev), 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    event->delete_me = 1;
215    return event->data;
216 }
217
218 /**
219  * Allocate a new event type id sensibly and return the new id.
220  * @return A new event type id.
221  *
222  * This function allocates a new event type id and returns it. Once an event
223  * type has been allocated it can never be de-allocated during the life of
224  * the program. There is no guarantee of the contents of this event ID, or how
225  * it is calculated, except that the ID will be unique to the current instance
226  * of the process.
227  */
228 EAPI int
229 ecore_event_type_new(void)
230 {
231    event_id_max++;
232    return event_id_max - 1;
233 }
234
235 /**
236  * Add a filter the current event queue.
237  * @param func_start Function to call just before filtering and return data
238  * @param func_filter Function to call on each event
239  * @param func_end Function to call after the queu has been filtered
240  * @param data Data to pass to the filter functions
241  * @return A filter handle
242  *
243  * This adds a filter to call callbacks to loop through the event queue and
244  * filter events out of the queue. On failure NULL is returned. On success a
245  * Filter handle is returned. Filters are called on the queue just before
246  * Event handler processing to try and remove redundant events. Just as
247  * processing starts @p func_start is called and passed the @p data pointer.
248  * This function returns a pointer that is used as loop_data that is now passed to
249  * @p func_filter as loop_data. @p func_filter is also passed @p data and the
250  * event type and private event structure. If this callback returns 0, the
251  * event is removed from the queue. If it returns 1, the event is kept. When
252  * processing is finished @p func_end is called and is passed the loop_data
253  * and @p data pointer to clean up.
254  */
255 EAPI Ecore_Event_Filter *
256 ecore_event_filter_add(void * (*func_start) (void *data), int (*func_filter) (void *data, void *loop_data, int type, void *event), void (*func_end) (void *data, void *loop_data), const void *data)
257 {
258    Ecore_Event_Filter *ef;
259
260    if (!func_filter) return NULL;
261    ef = calloc(1, sizeof(Ecore_Event_Filter));
262    if (!ef) return NULL;
263    ECORE_MAGIC_SET(ef, ECORE_MAGIC_EVENT_FILTER);
264    ef->func_start = func_start;
265    ef->func_filter = func_filter;
266    ef->func_end = func_end;
267    ef->data = (void *)data;
268    event_filters = (Ecore_Event_Filter *) eina_inlist_append(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
269    return ef;
270 }
271
272 /**
273  * Delete an event filter.
274  * @param ef The event filter handle
275  * @return The data set for the filter
276  *
277  * Delete a filter that has been added by its @p ef handle. On success this
278  * will return the data pointer set when this filter was added. On failure
279  * NULL is returned.
280  */
281 EAPI void *
282 ecore_event_filter_del(Ecore_Event_Filter *ef)
283 {
284    if (!ECORE_MAGIC_CHECK(ef, ECORE_MAGIC_EVENT_FILTER))
285      {
286         ECORE_MAGIC_FAIL(ef, ECORE_MAGIC_EVENT_FILTER, "ecore_event_filter_del");
287         return NULL;
288      }
289    ef->delete_me = 1;
290    event_filters_delete_me = 1;
291    return ef->data;
292 }
293
294 /**
295  * Return the current event type being handled.
296  * @return The current event type being handled if inside a handler callback
297  *
298  * If the program is currently inside an Ecore event handler callback this
299  * will return the type of the current event being processed. If Ecore is
300  * not inside an event handler, ECORE_EVENT_NONE is returned.
301  *
302  * This is useful when certain Ecore modules such as Ecore_Evas "swallow"
303  * events and not all the original information is passed on. In special cases
304  * this extra information may be useful or needed and using this call can let
305  * the program know if the event type being handled is one it wants to get more
306  * information about.
307  */
308 EAPI int
309 ecore_event_current_type_get(void)
310 {
311    return ecore_raw_event_type;
312 }
313
314 /**
315  * Return the current event type pointer handled.
316  * @return The current event pointer being handled if inside a handler callback
317  *
318  * If the program is currently inside an Ecore event handler callback this
319  * will return the pointer of the current event being processed. If Ecore is
320  * not inside an event handler, NULL will be returned.
321  *
322  * This is useful when certain Ecore modules such as Ecore_Evas "swallow"
323  * events and not all the original information is passed on. In special cases
324  * this extra information may be useful or needed and using this call can let
325  * the program access the event data if the type of the event is handled by
326  * the program.
327  */
328 EAPI void *
329 ecore_event_current_event_get(void)
330 {
331    return ecore_raw_event_event;
332 }
333
334 void
335 _ecore_event_shutdown(void)
336 {
337    int i;
338    Ecore_Event_Handler *eh;
339    Ecore_Event_Filter *ef;
340
341    while (events) _ecore_event_del(events);
342    event_current = NULL;
343    for (i = 0; i < event_handlers_num; i++)
344      {
345         while ((eh = event_handlers[i]))
346           {
347              event_handlers[i] = (Ecore_Event_Handler *) eina_inlist_remove(EINA_INLIST_GET(event_handlers[i]), EINA_INLIST_GET(event_handlers[i]));
348              ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
349              if (!eh->delete_me) free(eh);
350           }
351      }
352    EINA_LIST_FREE(event_handlers_delete_list, eh)
353      free(eh);
354    if (event_handlers) free(event_handlers);
355    event_handlers = NULL;
356    event_handlers_num = 0;
357    event_handlers_alloc_num = 0;
358    while ((ef = event_filters))
359      {
360         event_filters = (Ecore_Event_Filter *) eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(event_filters));
361         ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
362         free(ef);
363      }
364    event_filters_delete_me = 0;
365    event_filter_current = NULL;
366 }
367
368 int
369 _ecore_event_exist(void)
370 {
371    if (events) return 1;
372    return 0;
373 }
374
375 Ecore_Event *
376 _ecore_event_add(int type, void *ev, void (*func_free) (void *data, void *ev), void *data)
377 {
378    Ecore_Event *e;
379
380    e = calloc(1, sizeof(Ecore_Event));
381    if (!e) return NULL;
382    ECORE_MAGIC_SET(e, ECORE_MAGIC_EVENT);
383    e->type = type;
384    e->event = ev;
385    e->func_free = func_free;
386    e->data = data;
387    events = (Ecore_Event *) eina_inlist_append(EINA_INLIST_GET(events), EINA_INLIST_GET(e));
388    events_num++;
389    return e;
390 }
391
392 void *
393 _ecore_event_del(Ecore_Event *event)
394 {
395    void *data;
396
397    data = event->data;
398    if (event->func_free) event->func_free(event->data, event->event);
399    events = (Ecore_Event *) eina_inlist_remove(EINA_INLIST_GET(events), EINA_INLIST_GET(event));
400    ECORE_MAGIC_SET(event, ECORE_MAGIC_NONE);
401    free(event);
402    events_num--;
403    return data;
404 }
405
406 static void
407 _ecore_event_purge_deleted(void)
408 {
409    Ecore_Event *itr = events;
410
411    while (itr)
412      {
413         Ecore_Event *next = (Ecore_Event *)EINA_INLIST_GET(itr)->next;
414         if (!itr->references)
415           _ecore_event_del(itr);
416         itr = next;
417      }
418 }
419
420 void
421 _ecore_event_call(void)
422 {
423    Eina_List *l, *l_next;
424    Ecore_Event_Handler *eh;
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 = ef->func_start(ef->data);
447
448              if (!event_current)
449                {
450                   /* regular main loop, start from head */
451                   event_current = events;
452                }
453              else
454                {
455                   /* recursive main loop, continue from where we were */
456                   event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next;
457                }
458
459              while (event_current)
460                {
461                   Ecore_Event *e = event_current;
462
463                   if (!ef->func_filter(ef->loop_data, ef->data,
464                                        e->type, e->event))
465                     {
466 //                     printf("FILTER SAID TO DEL ev %p\n", e->event);
467                        ecore_event_del(e);
468                     }
469
470                   if (event_current) /* may have changed in recursive main loops */
471                     event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next;
472                }
473              if (ef->func_end)
474                ef->func_end(ef->data, ef->loop_data);
475
476              ef->references--;
477           }
478
479         if (event_filter_current) /* may have changed in recursive main loops */
480           event_filter_current = (Ecore_Event_Filter *)EINA_INLIST_GET(event_filter_current)->next;
481      }
482    if (event_filters_delete_me)
483      {
484         int deleted_in_use = 0;
485         Ecore_Event_Filter *l;
486         for (l = event_filters; l;)
487           {
488              Ecore_Event_Filter *ef = l;
489              l = (Ecore_Event_Filter *) EINA_INLIST_GET(l)->next;
490              if (ef->delete_me)
491                {
492                   if (ef->references)
493                     {
494                        deleted_in_use++;
495                        continue;
496                     }
497
498                   event_filters = (Ecore_Event_Filter *) eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
499                   ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
500                   free(ef);
501                }
502           }
503         if (!deleted_in_use)
504           event_filters_delete_me = 0;
505      }
506
507 //   printf("EVENT BATCH...\n");
508
509    if (!event_current)
510      {
511         /* regular main loop, start from head */
512         event_current = events;
513         event_handler_current = NULL;
514      }
515
516    while (event_current)
517      {
518         Ecore_Event *e = event_current;
519
520         if (!e->delete_me)
521           {
522              int handle_count = 0;
523              ecore_raw_event_type = e->type;
524              ecore_raw_event_event = e->event;
525              e->references++;
526 //           printf("HANDLE ev type %i, %p\n", e->type, e->event);
527              if ((e->type >= 0) && (e->type < event_handlers_num))
528                {
529                   if (!event_handler_current)
530                     {
531                        /* regular main loop, start from head */
532                        event_handler_current = event_handlers[e->type];
533                     }
534                   else
535                     {
536                        /* recursive main loop, continue from where we were */
537                        event_handler_current= (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next;
538                     }
539
540                   while ((event_handler_current) && (!e->delete_me))
541                     {
542                        Ecore_Event_Handler *eh = event_handler_current;
543                        if (!eh->delete_me)
544                          {
545                             int ret;
546
547                             handle_count++;
548
549                             eh->references++;
550                             ret = eh->func(eh->data, e->type, e->event);
551                             eh->references--;
552
553                             if (!ret)
554                               {
555                                  event_handler_current = NULL;
556                                  break;  /* 0 == "call no further handlers" */
557                               }
558                          }
559                        if (event_handler_current) /* may have changed in recursive main loops */
560                          event_handler_current= (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next;
561                     }
562                }
563              /* if no handlers were set for EXIT signal - then default is */
564              /* to quit the main loop */
565              if ((e->type == ECORE_EVENT_SIGNAL_EXIT) && (handle_count == 0))
566                ecore_main_loop_quit();
567              e->references--;
568           }
569
570         if (event_current) /* may have changed in recursive main loops */
571           event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next;
572      }
573 //   printf("EVENT BATCH DONE\n");
574    ecore_raw_event_type = ECORE_EVENT_NONE;
575    ecore_raw_event_event = NULL;
576
577    _ecore_event_purge_deleted();
578    EINA_LIST_FOREACH_SAFE(event_handlers_delete_list, l, l_next, eh)
579      {
580         if (eh->references) continue;
581
582         event_handlers_delete_list = eina_list_remove_list(event_handlers_delete_list, l);
583
584         event_handlers[eh->type] = (Ecore_Event_Handler *) eina_inlist_remove(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh));
585         ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
586         free(eh);
587      }
588 }
589
590 EAPI void *
591 _ecore_event_signal_user_new(void)
592 {
593    Ecore_Event_Signal_User *e;
594
595    e = calloc(1, sizeof(Ecore_Event_Signal_User));
596    return e;
597 }
598
599 void *
600 _ecore_event_signal_hup_new(void)
601 {
602    Ecore_Event_Signal_Hup *e;
603
604    e = calloc(1, sizeof(Ecore_Event_Signal_Hup));
605    return e;
606 }
607
608 void *
609 _ecore_event_signal_exit_new(void)
610 {
611    Ecore_Event_Signal_Exit *e;
612
613    e = calloc(1, sizeof(Ecore_Event_Signal_Exit));
614    return e;
615 }
616
617 void *
618 _ecore_event_signal_power_new(void)
619 {
620    Ecore_Event_Signal_Power *e;
621
622    e = calloc(1, sizeof(Ecore_Event_Signal_Power));
623    return e;
624 }
625
626 void *
627 _ecore_event_signal_realtime_new(void)
628 {
629    return calloc(1, sizeof(Ecore_Event_Signal_Realtime));
630 }