#ifdef HAVE_CONFIG_H # include #endif #include #include "Ecore.h" #include "ecore_private.h" typedef struct _Ecore_Future_Schedule_Entry { Eina_Future_Schedule_Entry base; Eina_Future_Scheduler_Cb cb; Eina_Future *future; Ecore_Event *event; Eina_Value value; } Ecore_Future_Schedule_Entry; ////// // XXX: still using legacy ecore events static Ecore_Event_Handler *future_handler = NULL; static Eina_Bool shutting_down = EINA_FALSE; static Eina_Mempool *mp_future_schedule_entry = NULL; static int ECORE_EV_FUTURE_ID = -1; // ////// static Ecore_Event_Message_Handler *_event_msg_handler = NULL; EAPI Ecore_Event_Handler * ecore_event_handler_add(int type, Ecore_Event_Handler_Cb func, const void *data) { return ecore_event_message_handler_add(_event_msg_handler, type, func, (void *)data); } EAPI void * ecore_event_handler_del(Ecore_Event_Handler *event_handler) { return ecore_event_message_handler_del(_event_msg_handler, event_handler); } EAPI void * ecore_event_handler_data_get(Ecore_Event_Handler *eh) { return ecore_event_message_handler_data_get(_event_msg_handler, eh); } EAPI void * ecore_event_handler_data_set(Ecore_Event_Handler *eh, const void *data) { return ecore_event_message_handler_data_set(_event_msg_handler, eh, (void *)data); } EAPI Ecore_Event * ecore_event_add(int type, void *ev, Ecore_End_Cb func_free, void *data) { Ecore_Event_Message *msg; msg = ecore_event_message_handler_message_type_add(_event_msg_handler); ecore_event_message_data_set(msg, type, ev, func_free, data); efl_loop_message_handler_message_send(_event_msg_handler, msg); return (Ecore_Event *)msg; } EAPI void * ecore_event_del(Ecore_Event *event) { void *data = NULL; ecore_event_message_data_get((Eo *)event, NULL, &data, NULL, NULL); _efl_loop_message_unsend((Eo *)event); return data; } EAPI int ecore_event_type_new(void) { return ecore_event_message_handler_type_new(_event_msg_handler); } EAPI Ecore_Event_Filter * ecore_event_filter_add(Ecore_Data_Cb func_start, Ecore_Filter_Cb func_filter, Ecore_End_Cb func_end, const void *data) { return ecore_event_message_handler_filter_add(_event_msg_handler, func_start, func_filter, func_end, (void *)data); } EAPI void * ecore_event_filter_del(Ecore_Event_Filter *ef) { return ecore_event_message_handler_filter_del(_event_msg_handler, ef); } EAPI int ecore_event_current_type_get(void) { return ecore_event_message_handler_current_type_get(_event_msg_handler); } EAPI void * ecore_event_current_event_get(void) { return ecore_event_message_handler_current_event_get(_event_msg_handler); } static Eina_Bool ecore_future_dispatched(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { Ecore_Future_Schedule_Entry *entry = event; entry->event = NULL; entry->cb(entry->future, entry->value); return EINA_FALSE; } static void ecore_future_free(void *user_data, void *func_data EINA_UNUSED) { Ecore_Future_Schedule_Entry *entry = user_data; if (entry->event) { eina_future_cancel(entry->future); eina_value_flush(&entry->value); } eina_mempool_free(mp_future_schedule_entry, entry); } static Eina_Future_Schedule_Entry * ecore_future_schedule(Eina_Future_Scheduler *sched, Eina_Future_Scheduler_Cb cb, Eina_Future *future, Eina_Value value) { Ecore_Future_Schedule_Entry *entry = eina_mempool_malloc(mp_future_schedule_entry, sizeof(Ecore_Future_Schedule_Entry)); EINA_SAFETY_ON_NULL_RETURN_VAL(entry, NULL); entry->base.scheduler = sched; entry->cb = cb; entry->future = future; entry->value = value; entry->event = ecore_event_add(ECORE_EV_FUTURE_ID, entry, ecore_future_free, entry); EINA_SAFETY_ON_NULL_GOTO(entry->event, err); return &entry->base; err: eina_mempool_free(mp_future_schedule_entry, entry); return NULL; } static void ecore_future_recall(Eina_Future_Schedule_Entry *s_entry) { if (shutting_down) return; Ecore_Future_Schedule_Entry *entry = (Ecore_Future_Schedule_Entry *)s_entry; EINA_SAFETY_ON_NULL_RETURN(entry->event); ecore_event_del(entry->event); eina_value_flush(&entry->value); entry->event = NULL; } static Eina_Future_Scheduler ecore_future_scheduler = { .schedule = ecore_future_schedule, .recall = ecore_future_recall, }; Eina_Future_Scheduler * _ecore_event_future_scheduler_get(void) { return &ecore_future_scheduler; } Eina_Bool _ecore_event_init(void) { const char *choice = getenv("EINA_MEMPOOL"); if ((!choice) || (!choice[0])) choice = "chained_mempool"; _event_msg_handler = efl_loop_message_handler_get(EFL_LOOP_CLASS, _mainloop_singleton, ECORE_EVENT_MESSAGE_HANDLER_CLASS); if (!_event_msg_handler) { ERR("Cannot create legacy ecore event message handler"); return EINA_FALSE; } // init some core legacy event types in t he same order and numbering as before // ECORE_EVENT_NONE 0 // no need to do as ev types start at 1 // ECORE_EVENT_SIGNAL_USER 1 ecore_event_message_handler_type_new(_event_msg_handler); // ECORE_EVENT_SIGNAL_HUP 2 ecore_event_message_handler_type_new(_event_msg_handler); // ECORE_EVENT_SIGNAL_EXIT 3 ecore_event_message_handler_type_new(_event_msg_handler); // ECORE_EVENT_SIGNAL_POWER 4 ecore_event_message_handler_type_new(_event_msg_handler); // ECORE_EVENT_SIGNAL_REALTIME 5 ecore_event_message_handler_type_new(_event_msg_handler); // ECORE_EVENT_MEMORY_STATE 6 ecore_event_message_handler_type_new(_event_msg_handler); // ECORE_EVENT_POWER_STATE 7 ecore_event_message_handler_type_new(_event_msg_handler); // ECORE_EVENT_LOCALE_CHANGED 8 ecore_event_message_handler_type_new(_event_msg_handler); // ECORE_EVENT_HOSTNAME_CHANGED 9 ecore_event_message_handler_type_new(_event_msg_handler); // ECORE_EVENT_SYSTEM_TIMEDATE_CHANGED 10 ecore_event_message_handler_type_new(_event_msg_handler); // ECORE_EVENT_COUNT 11 // no need to do as it was a count, nto an event ////// // XXX: ecore future still using legacy... shutting_down = EINA_FALSE; ECORE_EV_FUTURE_ID = ecore_event_type_new(); future_handler = ecore_event_handler_add(ECORE_EV_FUTURE_ID, ecore_future_dispatched, NULL); EINA_SAFETY_ON_NULL_GOTO(future_handler, err_handler); //FIXME: Is 512 too high? mp_future_schedule_entry = eina_mempool_add(choice, "Ecore_Future_Event", NULL, sizeof(Ecore_Future_Schedule_Entry), 512); EINA_SAFETY_ON_NULL_GOTO(mp_future_schedule_entry, err_pool); // ////// return EINA_TRUE; err_pool: ecore_event_handler_del(future_handler); future_handler = NULL; err_handler: ECORE_EV_FUTURE_ID = -1; return EINA_FALSE; } void _ecore_event_shutdown(void) { shutting_down = EINA_TRUE; ////// // XXX: ecore future still using legacy... ecore_event_handler_del(future_handler); future_handler = NULL; ECORE_EV_FUTURE_ID = -1; // ////// efl_loop_message_handler_message_clear(_event_msg_handler); _event_msg_handler = NULL; } void * _ecore_event_signal_user_new(void) { return calloc(1, sizeof(Ecore_Event_Signal_User)); } void * _ecore_event_signal_hup_new(void) { return calloc(1, sizeof(Ecore_Event_Signal_Hup)); } void * _ecore_event_signal_exit_new(void) { return calloc(1, sizeof(Ecore_Event_Signal_Exit)); } void * _ecore_event_signal_power_new(void) { return calloc(1, sizeof(Ecore_Event_Signal_Power)); } void * _ecore_event_signal_realtime_new(void) { return calloc(1, sizeof(Ecore_Event_Signal_Realtime)); } EAPI void ecore_event_type_flush_internal(int type, ...) { va_list args; if (type == ECORE_EVENT_NONE) return; ecore_event_message_handler_type_flush(_event_msg_handler, type); va_start(args, type); for (;;) { type = va_arg(args, int); if (type == ECORE_EVENT_NONE) break; ecore_event_message_handler_type_flush(_event_msg_handler, type); } va_end(args); }