2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
12 #include "ecore_private.h"
15 struct _Ecore_Event_Handler
20 int (*func) (void *data, int type, void *event);
23 Eina_Bool delete_me : 1;
26 struct _Ecore_Event_Filter
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);
36 Eina_Bool delete_me : 1;
45 void (*func_free) (void *data, void *ev);
48 Eina_Bool delete_me : 1;
52 static int events_num = 0;
53 static Ecore_Event *events = NULL;
54 static Ecore_Event *event_current = NULL;
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;
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;
70 static void _ecore_event_purge_deleted(void);
71 static void *_ecore_event_del(Ecore_Event *event);
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
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.
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.
97 EAPI Ecore_Event_Handler *
98 ecore_event_handler_add(int type, int (*func) (void *data, int type, void *event), const void *data)
100 Ecore_Event_Handler *eh;
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);
109 eh->data = (void *)data;
110 if (type >= (event_handlers_num - 1))
114 p_alloc_num = event_handlers_alloc_num;
115 event_handlers_num = type + 1;
116 if (event_handlers_num > event_handlers_alloc_num)
118 Ecore_Event_Handler **new_handlers;
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 *));
128 event_handlers = new_handlers;
129 for (i = p_alloc_num; i < event_handlers_alloc_num; i++)
130 event_handlers[i] = NULL;
133 event_handlers[type] = (Ecore_Event_Handler *) eina_inlist_append(EINA_INLIST_GET(event_handlers[type]), EINA_INLIST_GET(eh));
138 * Delete an event handler.
139 * @param event_handler Event handler handle to delete
140 * @return Data passed to handler
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.
148 ecore_event_handler_del(Ecore_Event_Handler *event_handler)
150 if (!ECORE_MAGIC_CHECK(event_handler, ECORE_MAGIC_EVENT_HANDLER))
152 ECORE_MAGIC_FAIL(event_handler, ECORE_MAGIC_EVENT_HANDLER,
153 "ecore_event_handler_del");
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;
162 _ecore_event_generic_free (void *data __UNUSED__, void *event)
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
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.
186 ecore_event_add(int type, void *ev, void (*func_free) (void *data, void *ev), void *data)
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);
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
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.
207 ecore_event_del(Ecore_Event *event)
209 if (!ECORE_MAGIC_CHECK(event, ECORE_MAGIC_EVENT))
211 ECORE_MAGIC_FAIL(event, ECORE_MAGIC_EVENT, "ecore_event_del");
214 event->delete_me = 1;
219 * Allocate a new event type id sensibly and return the new id.
220 * @return A new event type id.
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
229 ecore_event_type_new(void)
232 return event_id_max - 1;
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
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.
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)
258 Ecore_Event_Filter *ef;
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));
273 * Delete an event filter.
274 * @param ef The event filter handle
275 * @return The data set for the filter
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
282 ecore_event_filter_del(Ecore_Event_Filter *ef)
284 if (!ECORE_MAGIC_CHECK(ef, ECORE_MAGIC_EVENT_FILTER))
286 ECORE_MAGIC_FAIL(ef, ECORE_MAGIC_EVENT_FILTER, "ecore_event_filter_del");
290 event_filters_delete_me = 1;
295 * Return the current event type being handled.
296 * @return The current event type being handled if inside a handler callback
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.
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
309 ecore_event_current_type_get(void)
311 return ecore_raw_event_type;
315 * Return the current event type pointer handled.
316 * @return The current event pointer being handled if inside a handler callback
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.
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
329 ecore_event_current_event_get(void)
331 return ecore_raw_event_event;
335 _ecore_event_shutdown(void)
338 Ecore_Event_Handler *eh;
339 Ecore_Event_Filter *ef;
341 while (events) _ecore_event_del(events);
342 event_current = NULL;
343 for (i = 0; i < event_handlers_num; i++)
345 while ((eh = event_handlers[i]))
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);
352 EINA_LIST_FREE(event_handlers_delete_list, 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))
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);
364 event_filters_delete_me = 0;
365 event_filter_current = NULL;
369 _ecore_event_exist(void)
371 if (events) return 1;
376 _ecore_event_add(int type, void *ev, void (*func_free) (void *data, void *ev), void *data)
380 e = calloc(1, sizeof(Ecore_Event));
382 ECORE_MAGIC_SET(e, ECORE_MAGIC_EVENT);
385 e->func_free = func_free;
387 events = (Ecore_Event *) eina_inlist_append(EINA_INLIST_GET(events), EINA_INLIST_GET(e));
393 _ecore_event_del(Ecore_Event *event)
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);
407 _ecore_event_purge_deleted(void)
409 Ecore_Event *itr = events;
413 Ecore_Event *next = (Ecore_Event *)EINA_INLIST_GET(itr)->next;
414 if (!itr->references)
415 _ecore_event_del(itr);
421 _ecore_event_call(void)
423 Eina_List *l, *l_next;
424 Ecore_Event_Handler *eh;
426 if (!event_filter_current)
428 /* regular main loop, start from head */
429 event_filter_current = event_filters;
433 /* recursive main loop, continue from where we were */
434 event_filter_current = (Ecore_Event_Filter *)EINA_INLIST_GET(event_filter_current)->next;
437 while (event_filter_current)
439 Ecore_Event_Filter *ef = event_filter_current;
446 ef->loop_data = ef->func_start(ef->data);
450 /* regular main loop, start from head */
451 event_current = events;
455 /* recursive main loop, continue from where we were */
456 event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next;
459 while (event_current)
461 Ecore_Event *e = event_current;
463 if (!ef->func_filter(ef->loop_data, ef->data,
466 // printf("FILTER SAID TO DEL ev %p\n", e->event);
470 if (event_current) /* may have changed in recursive main loops */
471 event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next;
474 ef->func_end(ef->data, ef->loop_data);
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;
482 if (event_filters_delete_me)
484 int deleted_in_use = 0;
485 Ecore_Event_Filter *l;
486 for (l = event_filters; l;)
488 Ecore_Event_Filter *ef = l;
489 l = (Ecore_Event_Filter *) EINA_INLIST_GET(l)->next;
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);
504 event_filters_delete_me = 0;
507 // printf("EVENT BATCH...\n");
511 /* regular main loop, start from head */
512 event_current = events;
513 event_handler_current = NULL;
516 while (event_current)
518 Ecore_Event *e = event_current;
522 int handle_count = 0;
523 ecore_raw_event_type = e->type;
524 ecore_raw_event_event = e->event;
526 // printf("HANDLE ev type %i, %p\n", e->type, e->event);
527 if ((e->type >= 0) && (e->type < event_handlers_num))
529 if (!event_handler_current)
531 /* regular main loop, start from head */
532 event_handler_current = event_handlers[e->type];
536 /* recursive main loop, continue from where we were */
537 event_handler_current= (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next;
540 while ((event_handler_current) && (!e->delete_me))
542 Ecore_Event_Handler *eh = event_handler_current;
550 ret = eh->func(eh->data, e->type, e->event);
555 event_handler_current = NULL;
556 break; /* 0 == "call no further handlers" */
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;
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();
570 if (event_current) /* may have changed in recursive main loops */
571 event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next;
573 // printf("EVENT BATCH DONE\n");
574 ecore_raw_event_type = ECORE_EVENT_NONE;
575 ecore_raw_event_event = NULL;
577 _ecore_event_purge_deleted();
578 EINA_LIST_FOREACH_SAFE(event_handlers_delete_list, l, l_next, eh)
580 if (eh->references) continue;
582 event_handlers_delete_list = eina_list_remove_list(event_handlers_delete_list, l);
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);
591 _ecore_event_signal_user_new(void)
593 Ecore_Event_Signal_User *e;
595 e = calloc(1, sizeof(Ecore_Event_Signal_User));
600 _ecore_event_signal_hup_new(void)
602 Ecore_Event_Signal_Hup *e;
604 e = calloc(1, sizeof(Ecore_Event_Signal_Hup));
609 _ecore_event_signal_exit_new(void)
611 Ecore_Event_Signal_Exit *e;
613 e = calloc(1, sizeof(Ecore_Event_Signal_Exit));
618 _ecore_event_signal_power_new(void)
620 Ecore_Event_Signal_Power *e;
622 e = calloc(1, sizeof(Ecore_Event_Signal_Power));
627 _ecore_event_signal_realtime_new(void)
629 return calloc(1, sizeof(Ecore_Event_Signal_Realtime));