#include "Ecore.h"
#include "ecore_private.h"
+#ifdef USE_TIZEN_CORE
+#include "tizen-core/tcore_events.h"
+#endif // USE_TIZEN_CORE
+
static Ecore_Event_Message_Handler *_event_msg_handler = NULL;
EAPI Ecore_Event_Handler *
Ecore_Event_Handler_Cb func,
const void *data)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready())
+ {
+ return tcore_event_handler_add(type, (tcore_event_handler_cb)func,
+ (void *)data);
+ }
+#endif // USE_TIZEN_CORE
return ecore_event_message_handler_add(_event_msg_handler,
type, func, (void *)data);
}
Ecore_Event_Handler_Cb func,
const void *data)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready())
+ {
+ return tcore_event_handler_prepend(type, (tcore_event_handler_cb)func,
+ (void *)data);
+ }
+#endif // USE_TIZEN_CORE
return ecore_event_message_handler_prepend(_event_msg_handler,
type, func, (void *)data);
}
EAPI void *
ecore_event_handler_del(Ecore_Event_Handler *event_handler)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready()) return tcore_event_handler_del(event_handler);
+#endif // USE_TIZEN_CORE
return ecore_event_message_handler_del(_event_msg_handler,
event_handler);
}
EAPI void *
ecore_event_handler_data_get(Ecore_Event_Handler *eh)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready()) return tcore_event_handler_data_get(eh);
+#endif // USE_TIZEN_CORE
return ecore_event_message_handler_data_get(_event_msg_handler, eh);
}
ecore_event_handler_data_set(Ecore_Event_Handler *eh,
const void *data)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready()) return tcore_event_handler_data_set(eh, (void *)data);
+#endif // USE_TIZEN_CORE
return ecore_event_message_handler_data_set(_event_msg_handler, eh,
(void *)data);
}
Ecore_Event_Message *msg;
if (type <= ECORE_EVENT_NONE) return NULL;
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready())
+ return tcore_event_add(type, ev, (tcore_end_cb)func_free, data);
+#endif // USE_TIZEN_CORE
+
//TIZEN_ONLY(20180510): fix backword compatibility bug for ecore event
msg = ecore_event_message_handler_message_type_add(_event_msg_handler, type);
//
EAPI void *
ecore_event_del(Ecore_Event *event)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready()) return tcore_event_del(event);
+#endif // USE_TIZEN_CORE
void *data = NULL;
if (!event) return data;
ecore_event_message_data_get((Eo *)event, NULL, NULL, NULL, &data);
EAPI int
ecore_event_type_new(void)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready()) return tcore_event_type_new();
+#endif // USE_TIZEN_CORE
return ecore_event_message_handler_type_new(_event_msg_handler);
}
Ecore_End_Cb func_end,
const void *data)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready())
+ {
+ return tcore_event_filter_add((tcore_data_cb)func_start,
+ (tcore_filter_cb)func_filter,
+ (tcore_end_cb)func_end, (void *)data);
+ }
+#endif // USE_TIZEN_CORE
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)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready()) return tcore_event_filter_del(ef);
+#endif // USE_TIZEN_CORE
return ecore_event_message_handler_filter_del(_event_msg_handler, ef);
}
EAPI int
ecore_event_current_type_get(void)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready()) return tcore_event_current_type_get();
+#endif // USE_TIZEN_CORE
return ecore_event_message_handler_current_type_get(_event_msg_handler);
}
EAPI void *
ecore_event_current_event_get(void)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready()) return tcore_event_current_event_get();
+#endif // USE_TIZEN_CORE
return ecore_event_message_handler_current_event_get(_event_msg_handler);
}
const char *choice = getenv("EINA_MEMPOOL");
if ((!choice) || (!choice[0])) choice = "chained_mempool";
- _event_msg_handler = efl_add(ECORE_EVENT_MESSAGE_HANDLER_CLASS, _mainloop_singleton);
- efl_provider_register(_mainloop_singleton, ECORE_EVENT_MESSAGE_HANDLER_CLASS, _event_msg_handler);
-
- if (!_event_msg_handler)
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready())
+ {
+ tcore_event_init();
+ }
+ else
+#endif // USE_TIZEN_CORE
{
- ERR("Cannot create legacy ecore event message handler");
- return EINA_FALSE;
+ _event_msg_handler =
+ efl_add(ECORE_EVENT_MESSAGE_HANDLER_CLASS, _mainloop_singleton);
+ efl_provider_register(_mainloop_singleton,
+ ECORE_EVENT_MESSAGE_HANDLER_CLASS,
+ _event_msg_handler);
+
+ 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
void
_ecore_event_shutdown(void)
{
- efl_loop_message_handler_message_clear(_event_msg_handler);
- _event_msg_handler = NULL;
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready())
+ {
+ tcore_event_shutdown();
+ }
+ else
+#endif // USE_TIZEN_CORE
+ {
+ efl_loop_message_handler_message_clear(_event_msg_handler);
+ _event_msg_handler = NULL;
+ }
}
void *
--- /dev/null
+#include "tcore_events.h"
+
+#include <tizen_core.h>
+#include <tizen_core_event_internal.h>
+
+#include <memory>
+#include <new>
+
+#include "log_private.h"
+
+namespace {
+
+class TCoreEvent {
+ public:
+ TCoreEvent() {}
+ ~TCoreEvent() { Dispose(); }
+
+ bool Init() {
+ if (!disposed_) return true;
+
+ if (tcore_ready()) {
+ tizen_core_find("main", &core_);
+
+ if (!EventSourceAdd(&event_filter_, &event_filter_source_)) {
+ EventSourceRemove(&event_filter_, &event_filter_source_);
+ return false;
+ }
+
+ if (!EventSourceAdd(&event_, &event_source_)) {
+ EventSourceRemove(&event_, &event_source_);
+ EventSourceRemove(&event_filter_, &event_filter_source_);
+ return false;
+ }
+ }
+
+ disposed_ = false;
+ return true;
+ }
+
+ void Dispose() {
+ if (disposed_) return;
+
+ EventSourceRemove(&event_, &event_source_);
+ EventSourceRemove(&event_filter_, &event_filter_source_);
+ core_ = nullptr;
+ disposed_ = true;
+ }
+
+ tizen_core_event_h GetEvent() const { return event_; }
+
+ tizen_core_event_h GetEventFilter() const { return event_filter_; }
+
+ void SetCurrentEventType(int type) { current_event_type_ = type; }
+
+ int GetCurrentEventType() const { return current_event_type_; }
+
+ void SetCurrentEventData(void *event_data) {
+ current_event_data_ = event_data;
+ }
+
+ void* GetCurrentEventData() const { return current_event_data_; }
+
+ private:
+ bool EventSourceAdd(tizen_core_event_h* event, tizen_core_source_h* source) {
+ int ret = tizen_core_event_create(event);
+ if (ret != TIZEN_CORE_ERROR_NONE) {
+ _E("Failed to create event filter");
+ return false;
+ }
+
+ tizen_core_add_event(core_, *event, source);
+ if (*source == nullptr) {
+ _E("Failed to add event filter source");
+ return false;
+ }
+
+ return true;
+ }
+
+ void EventSourceRemove(tizen_core_event_h* event,
+ tizen_core_source_h* source) {
+ if (*source != nullptr) {
+ tizen_core_remove_source(core_, *source);
+ *source = nullptr;
+ *event = nullptr;
+ }
+
+ if (*event != nullptr) {
+ tizen_core_event_destroy(*event);
+ *event = nullptr;
+ }
+ }
+
+ private:
+ bool disposed_ = true;
+ tizen_core_h core_ = nullptr;
+ tizen_core_event_h event_ = nullptr;
+ tizen_core_source_h event_source_ = nullptr;
+ tizen_core_event_h event_filter_ = nullptr;
+ tizen_core_source_h event_filter_source_ = nullptr;
+ int current_event_type_ = -1;
+ void* current_event_data_ = nullptr;
+};
+
+TCoreEvent tcore_event;
+
+class EventHandler {
+ public:
+ EventHandler(int type, tcore_event_handler_cb func, void *user_data,
+ bool prepend)
+ : type_(type), func_(func), user_data_(user_data) {
+ if (prepend) {
+ tizen_core_event_prepend_handler(tcore_event.GetEvent(), EventHandlerCb,
+ this, &handle_);
+ } else {
+ tizen_core_event_add_handler(tcore_event.GetEvent(), EventHandlerCb, this,
+ &handle_);
+ }
+
+ if (handle_ == nullptr) {
+ _E("Failed to add event handler");
+ throw std::bad_alloc();
+ }
+ }
+
+ ~EventHandler() {
+ if (handle_ != nullptr)
+ tizen_core_event_remove_handler(tcore_event.GetEvent(), handle_);
+ }
+
+ void Dispose() {
+ if (ref_ > 0) {
+ delete_me_ = true;
+ return;
+ }
+
+ delete this;
+ }
+
+ void SetUserData(void* user_data) { user_data_ = user_data; }
+
+ void* GetUserData() const { return user_data_; }
+
+ private:
+ static bool EventHandlerCb(tizen_core_event_object_h object,
+ void *user_data) {
+ auto* handler = static_cast<EventHandler*>(user_data);
+ int type = -1;
+ tizen_core_event_object_get_id(object, &type);
+ if (type < 0) return false;
+
+ if (handler->type_ != type) return true;
+
+ void* event = nullptr;
+ tizen_core_event_object_get_data(object, &event);
+ if (event == nullptr) return true;
+
+ handler->Ref();
+ tcore_event.SetCurrentEventType(type);
+ tcore_event.SetCurrentEventData(event);
+
+ bool ret = handler->Invoke(event);
+ handler->Unref();
+
+ tcore_event.SetCurrentEventType(-1);
+ tcore_event.SetCurrentEventData(nullptr);
+
+ if (handler->delete_me_) handler->Dispose();
+
+ return ret;
+ }
+
+ void Ref() { ref_++; }
+
+ void Unref() { ref_--; }
+
+ bool Invoke(void* event) {
+ if (func_) return func_(user_data_, type_, event);
+ return true;
+ }
+
+ private:
+ tizen_core_event_handler_h handle_ = nullptr;
+ int type_ = -1;
+ tcore_event_handler_cb func_ = nullptr;
+ void* user_data_ = nullptr;
+ bool delete_me_ = false;
+ unsigned int ref_ = 0;
+};
+
+class EventFilter {
+ public:
+ EventFilter(tcore_data_cb func_start, tcore_filter_cb func_filter,
+ tcore_end_cb func_end, void *user_data)
+ : func_start_(func_start),
+ func_filter_(func_filter),
+ func_end_(func_end),
+ user_data_(user_data) {
+ tizen_core_event_add_handler(tcore_event.GetEventFilter(), EventFilterCb,
+ this, &handle_);
+ if (handle_ == nullptr) {
+ _E("Failed to add event filter");
+ throw std::bad_alloc();
+ }
+ }
+
+ ~EventFilter() {
+ if (handle_ != nullptr)
+ tizen_core_event_remove_handler(tcore_event.GetEventFilter(), handle_);
+ }
+
+ void Dispose() {
+ if (ref_ > 0) {
+ delete_me_ = true;
+ return;
+ }
+
+ delete this;
+ }
+
+ void* GetUserData() const { return user_data_; }
+
+ private:
+ static bool EventFilterCb(tizen_core_event_object_h object, void *user_data) {
+ auto* filter = static_cast<EventFilter*>(user_data);
+
+ int type = -1;
+ tizen_core_event_object_get_id(object, &type);
+ void* event = nullptr;
+ tizen_core_event_object_get_data(object, &event);
+ if (event == nullptr) return true;
+
+ filter->Ref();
+ filter->InvokeFuncStart();
+ if (!filter->InvokeFuncFilter(type, event))
+ tizen_core_event_object_destroy(object);
+
+ filter->InvokeFuncEnd();
+ filter->Unref();
+
+ if (filter->delete_me_) filter->Dispose();
+ return true;
+ }
+
+ void Ref() { ref_++; }
+
+ void Unref() { ref_--; }
+
+ void InvokeFuncStart() {
+ if (func_start_) loop_data_ = func_start_(user_data_);
+ }
+
+ bool InvokeFuncFilter(int type, void* event) {
+ if (delete_me_ && type < 0) return true;
+
+ if (func_filter_) return func_filter_(user_data_, loop_data_, type, event);
+
+ return true;
+ }
+
+ void InvokeFuncEnd() {
+ if (!delete_me_ && func_end_) func_end_(user_data_, loop_data_);
+ }
+
+ private:
+ tizen_core_event_handler_h handle_ = nullptr;
+ tcore_data_cb func_start_ = nullptr;
+ tcore_filter_cb func_filter_ = nullptr;
+ tcore_end_cb func_end_ = nullptr;
+ void* user_data_ = nullptr;
+ void* loop_data_ = nullptr;
+ bool delete_me_ = false;
+ unsigned int ref_ = 0;
+};
+
+class EventData {
+ public:
+ EventData(int type, void* event, tcore_end_cb func_free, void* func_data)
+ : type_(type),
+ event_(event),
+ func_free_(func_free),
+ func_data_(func_data) {
+ tizen_core_event_object_create(&handle_, type_, event_);
+ if (handle_ == nullptr) {
+ _E("Failed to create event object");
+ throw std::bad_alloc();
+ }
+
+ tizen_core_event_object_set_destroy_cb(handle_, EventObjectDestroyCb, this);
+ }
+
+ void Emit() {
+ tizen_core_h core = nullptr;
+ tizen_core_find("main", &core);
+ tizen_core_emit_event(core, handle_);
+ }
+
+ void Dispose() {
+ if (handle_!= nullptr) {
+ tizen_core_event_object_destroy(handle_);
+ handle_ = nullptr;
+ }
+ }
+
+ void* GetData() const { return func_data_; }
+
+ private:
+ static void EventObjectDestroyCb(void* data, void* user_data) {
+ auto* event_data = static_cast<EventData*>(user_data);
+ event_data->handle_ = nullptr;
+
+ void* event = nullptr;
+ tcore_end_cb free_func = nullptr;
+ void* free_data = nullptr;
+ event_data->Steal(&event, &free_func, &free_data);
+ if (free_func) free_func(free_data, event);
+
+ delete event_data;
+ }
+
+ void Steal(void** event, tcore_end_cb* func_free, void** func_data) {
+ if (event) *event = event_;
+ if (func_free) *func_free = func_free_;
+ if (func_data) *func_data = func_data_;
+
+ type_ = -1;
+ event_ = nullptr;
+ func_free_ = nullptr;
+ func_data_ = nullptr;
+ }
+
+ private:
+ int type_ = -1;
+ void* event_ = nullptr;
+ tcore_end_cb func_free_ = nullptr;
+ void* func_data_ = nullptr;
+ tizen_core_event_object_h handle_ = nullptr;
+};
+
+} // namespace
+
+tcore_event_handler_h tcore_event_handler_add(int type,
+ tcore_event_handler_cb func,
+ void* user_data) {
+ EventHandler* handler = nullptr;
+ try {
+ handler = new EventHandler(type, func, user_data, false);
+ } catch (const std::bad_alloc& e) {
+ _E("Allocation failed: %s", e.what());
+ return nullptr;
+ }
+
+ return handler;
+}
+
+tcore_event_handler_h tcore_event_handler_prepend(int type,
+ tcore_event_handler_cb func,
+ void* user_data) {
+ EventHandler* handler = nullptr;
+ try {
+ handler = new EventHandler(type, func, user_data, true);
+ } catch (const std::bad_alloc& e) {
+ _E("Allocation failed: %s", e.what());
+ return nullptr;
+ }
+
+ return handler;
+}
+
+void* tcore_event_handler_del(tcore_event_handler_h event_handler) {
+ if (event_handler == nullptr) return nullptr;
+
+ auto* handler = static_cast<EventHandler*>(event_handler);
+ auto* user_data = handler->GetUserData();
+ handler->Dispose();
+ return user_data;
+}
+
+void* tcore_event_handler_data_get(tcore_event_handler_h event_handler) {
+ if (event_handler == nullptr) return nullptr;
+ auto* handler = static_cast<EventHandler*>(event_handler);
+ return handler->GetUserData();
+}
+
+void* tcore_event_handler_data_set(tcore_event_handler_h event_handler,
+ void *user_data) {
+ if (event_handler == nullptr) return nullptr;
+ auto* handler = static_cast<EventHandler*>(event_handler);
+ auto* prev_data = handler->GetUserData();
+ handler->SetUserData(user_data);
+ return prev_data;
+}
+
+tcore_event_h tcore_event_add(int type, void* event, tcore_end_cb func_free,
+ void* func_data) {
+ EventData* event_data = nullptr;
+ try {
+ event_data = new EventData(type, event, func_free, func_data);
+ event_data->Emit();
+ } catch (const std::bad_alloc& e) {
+ _E("Allocation failed: %s", e.what());
+ return nullptr;
+ }
+
+ return event_data;
+}
+
+void* tcore_event_del(tcore_event_h event) {
+ if (event == nullptr) return nullptr;
+
+ auto* event_data = static_cast<EventData*>(event);
+ auto* data = event_data->GetData();
+ event_data->Dispose();
+ return data;
+}
+
+int tcore_event_type_new(void) { return tizen_core_event_generate_id(); }
+
+tcore_event_filter_h tcore_event_filter_add(tcore_data_cb func_start,
+ tcore_filter_cb func_filter,
+ tcore_end_cb func_end,
+ void *user_data) {
+ EventFilter* filter = nullptr;
+ try {
+ filter = new EventFilter(func_start, func_filter, func_end, user_data);
+ } catch (const std::bad_alloc& e) {
+ _E("Allocation failed: %s", e.what());
+ return nullptr;
+ }
+
+ return filter;
+}
+
+void* tcore_event_filter_del(tcore_event_filter_h event_filter) {
+ if (event_filter == nullptr) return nullptr;
+
+ auto* filter = static_cast<EventFilter*>(event_filter);
+ auto* user_data = filter->GetUserData();
+ filter->Dispose();
+ return user_data;
+}
+
+int tcore_event_current_type_get(void) {
+ return tcore_event.GetCurrentEventType();
+}
+
+void* tcore_event_current_event_get(void) {
+ return tcore_event.GetCurrentEventData();
+}
+
+bool tcore_event_init(void) { return tcore_event.Init(); }
+
+void tcore_event_shutdown(void) { return tcore_event.Dispose(); }