forked from enlightenment/efl
281 lines
7.5 KiB
C
281 lines
7.5 KiB
C
#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_add_full(eo_e, NULL, NULL, NULL, NULL,
|
|
EVAS_DEVICE_CLASS_NONE,
|
|
EVAS_DEVICE_SUBCLASS_NONE);
|
|
}
|
|
|
|
EAPI Evas_Device *
|
|
evas_device_add_full(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);
|
|
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_del(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);
|
|
if (parent)
|
|
{
|
|
SAFETY_CHECK(parent, EFL_INPUT_DEVICE_CLASS);
|
|
}
|
|
|
|
efl_input_device_parent_set(dev, parent);
|
|
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)
|
|
{
|
|
Eina_List *cpy;
|
|
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;
|
|
}
|
|
|
|
/* If the device is deleted, _del_cb will remove the device
|
|
from the devices list. */
|
|
cpy = eina_list_clone(e->devices);
|
|
EINA_LIST_FREE(cpy, dev)
|
|
evas_device_del(dev);
|
|
|
|
/* Not all devices were deleted. The user probably will unref them later.
|
|
Since Evas will be deleted, remove the del callback from them and
|
|
tell the user that the device was removed.
|
|
*/
|
|
EINA_LIST_FREE(e->devices, dev)
|
|
{
|
|
efl_event_callback_call(e->evas,
|
|
EFL_CANVAS_EVENT_DEVICE_REMOVED,
|
|
dev);
|
|
efl_event_callback_del(dev, EFL_EVENT_DEL, _del_cb, e);
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|