efl/src/lib/ecore/ecore_events.c

310 lines
8.7 KiB
C

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#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);
}