#include "evas_common_private.h" #include "evas_private.h" #define EFL_INTERNAL_UNSTABLE #include "interfaces/efl_common_internal.h" /* WARNING: This API is not used across EFL, hard to test! */ #ifdef DEBUG_UNTESTED_ // booh #define SAFETY_CHECK(obj, klass, ...) \ do { MAGIC_CHECK(dev, Evas_Device, 1); \ return __VA_ARGS__; \ MAGIC_CHECK_END(); \ } while (0) #else #define SAFETY_CHECK(obj, klass, ...) \ do { if (!obj) return __VA_ARGS__; } while (0) #endif /* FIXME: Ideally no work besides calling the Efl_Input_Device API * should be done here. But unfortunately, some knowledge of Evas is required * here (callbacks and canvas private data). */ static void _del_cb(void *data, const Efl_Event *ev) { Evas_Public_Data *e = data; // can not be done in std destructor e->devices = eina_list_remove(e->devices, ev->object); efl_event_callback_call(e->evas, EFL_CANVAS_EVENT_DEVICE_REMOVED, ev->object); } EAPI Evas_Device * evas_device_add(Evas *eo_e) { return evas_device_full_add(eo_e, NULL, NULL, NULL, NULL, EVAS_DEVICE_CLASS_NONE, EVAS_DEVICE_SUBCLASS_NONE); } EAPI Evas_Device * evas_device_full_add(Evas *eo_e, const char *name, const char *desc, Evas_Device *parent_dev, Evas_Device *emulation_dev, Evas_Device_Class clas, Evas_Device_Subclass sub_clas) { Efl_Input_Device_Data *d; Evas_Public_Data *e; Evas_Device *dev; SAFETY_CHECK(eo_e, EVAS_CANVAS_CLASS, NULL); dev = efl_add(EFL_INPUT_DEVICE_CLASS, eo_e, efl_input_device_name_set(efl_added, name), efl_input_device_description_set(efl_added, desc), efl_input_device_type_set(efl_added, clas), efl_input_device_subtype_set(efl_added, sub_clas), efl_input_device_source_set(efl_added, emulation_dev), efl_input_device_parent_set(efl_added, parent_dev)); d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS); d->evas = eo_e; e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS); if (!parent_dev) e->devices = eina_list_append(e->devices, dev); efl_event_callback_add(dev, EFL_EVENT_DEL, _del_cb, e); efl_event_callback_call(eo_e, EFL_CANVAS_EVENT_DEVICE_ADDED, dev); // Keeping this event to do not break things... evas_event_callback_call(eo_e, EVAS_CALLBACK_DEVICE_CHANGED, dev); return dev; } EAPI void evas_device_del(Evas_Device *dev) { SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS); efl_unref(dev); } EAPI void evas_device_push(Evas *eo_e, Evas_Device *dev) { SAFETY_CHECK(eo_e, EVAS_CANVAS_CLASS); SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS); Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS); if (!e->cur_device) { e->cur_device = eina_array_new(4); if (!e->cur_device) return; } efl_ref(dev); eina_array_push(e->cur_device, dev); } EAPI void evas_device_pop(Evas *eo_e) { Evas_Device *dev; SAFETY_CHECK(eo_e, EVAS_CANVAS_CLASS); Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS); dev = eina_array_pop(e->cur_device); if (dev) efl_unref(dev); } EAPI const Eina_List * evas_device_list(Evas *eo_e, const Evas_Device *dev) { SAFETY_CHECK(eo_e, EVAS_CANVAS_CLASS, NULL); if (dev) { SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS, NULL); Efl_Input_Device_Data *d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS); return d->children; } Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS); return e->devices; } EAPI void evas_device_name_set(Evas_Device *dev, const char *name) { SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS); Efl_Input_Device_Data *d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS); efl_input_device_name_set(dev, name); evas_event_callback_call(d->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev); } EAPI const char * evas_device_name_get(const Evas_Device *dev) { return efl_input_device_name_get(dev); } EAPI void evas_device_description_set(Evas_Device *dev, const char *desc) { SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS); efl_input_device_description_set(dev, desc); Efl_Input_Device_Data *d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS); evas_event_callback_call(d->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev); } EAPI const char * evas_device_description_get(const Evas_Device *dev) { return efl_input_device_description_get(dev); } EAPI void evas_device_parent_set(Evas_Device *dev, Evas_Device *parent) { SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS); Efl_Input_Device_Data *d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS); Evas_Public_Data *e = efl_data_scope_get(d->evas, EVAS_CANVAS_CLASS); if (parent) { SAFETY_CHECK(parent, EFL_INPUT_DEVICE_CLASS); } efl_input_device_parent_set(dev, parent); if (parent) e->devices = eina_list_remove(e->devices, dev); else e->devices = eina_list_append(e->devices, dev); evas_event_callback_call(d->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev); } EAPI const Evas_Device * evas_device_parent_get(const Evas_Device *dev) { return efl_input_device_parent_get(dev); } EAPI void evas_device_class_set(Evas_Device *dev, Evas_Device_Class clas) { SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS); Efl_Input_Device_Data *d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS); efl_input_device_type_set(dev, clas); evas_event_callback_call(d->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev); } EAPI Evas_Device_Class evas_device_class_get(const Evas_Device *dev) { return efl_input_device_type_get(dev); } EAPI void evas_device_subclass_set(Evas_Device *dev, Evas_Device_Subclass clas) { SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS); Efl_Input_Device_Data *d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS); efl_input_device_subtype_set(dev, clas); evas_event_callback_call(d->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev); } EAPI Evas_Device_Subclass evas_device_subclass_get(const Evas_Device *dev) { return efl_input_device_subtype_get(dev); } EAPI void evas_device_emulation_source_set(Evas_Device *dev, Evas_Device *src) { SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS); Efl_Input_Device_Data *d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS); efl_input_device_source_set(dev, src); evas_event_callback_call(d->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev); } EAPI const Evas_Device * evas_device_emulation_source_get(const Evas_Device *dev) { return efl_input_device_source_get(dev); } void _evas_device_cleanup(Evas *eo_e) { Evas_Device *dev; Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS); if (e->cur_device) { while ((dev = eina_array_pop(e->cur_device))) efl_unref(dev); eina_array_free(e->cur_device); e->cur_device = NULL; } EINA_LIST_FREE(e->devices, dev) { evas_device_del(dev); } } Evas_Device * _evas_device_top_get(const Evas *eo_e) { int num; Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS); if (!e->cur_device) return NULL; num = eina_array_count(e->cur_device); if (num < 1) return NULL; return eina_array_data_get(e->cur_device, num - 1); }