2013-06-20 03:53:29 -07:00
|
|
|
#include "evas_common_private.h"
|
2012-09-17 03:12:48 -07:00
|
|
|
#include "evas_private.h"
|
|
|
|
|
2016-04-28 01:08:14 -07:00
|
|
|
#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).
|
|
|
|
*/
|
|
|
|
|
2016-10-19 10:57:18 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_is_pointer(Evas_Device_Class clas)
|
|
|
|
{
|
|
|
|
if (clas == EVAS_DEVICE_CLASS_MOUSE ||
|
|
|
|
clas == EVAS_DEVICE_CLASS_TOUCH ||
|
2016-10-21 05:25:41 -07:00
|
|
|
clas == EVAS_DEVICE_CLASS_PEN ||
|
|
|
|
clas == EVAS_DEVICE_CLASS_POINTER ||
|
|
|
|
clas == EVAS_DEVICE_CLASS_WAND)
|
2016-10-19 10:57:18 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Device *
|
|
|
|
_new_default_device_find(Evas_Public_Data *e, Evas_Device *old_dev)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
Evas_Device *dev, *def, *old_parent;
|
|
|
|
Evas_Device_Class old_class;
|
|
|
|
|
|
|
|
old_class = efl_input_device_type_get(old_dev);
|
|
|
|
old_parent = efl_input_device_parent_get(old_dev);
|
|
|
|
def = NULL;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(e->devices, l, dev)
|
|
|
|
{
|
|
|
|
if (efl_input_device_type_get(dev) != old_class)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
def = dev;
|
|
|
|
//Prefer devices with the same parent.
|
|
|
|
if (efl_input_device_parent_get(dev) == old_parent)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!def)
|
|
|
|
{
|
|
|
|
const char *class_str;
|
|
|
|
if (old_class == EVAS_DEVICE_CLASS_SEAT)
|
|
|
|
class_str = "seat";
|
|
|
|
else if (old_class == EVAS_DEVICE_CLASS_KEYBOARD)
|
|
|
|
class_str = "keyboard";
|
|
|
|
else
|
|
|
|
class_str = "mouse";
|
|
|
|
WRN("Could not find a default %s device.", class_str);
|
|
|
|
}
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
2016-06-20 07:31:31 -07:00
|
|
|
static void
|
2016-08-30 05:34:10 -07:00
|
|
|
_del_cb(void *data, const Efl_Event *ev)
|
2016-04-28 01:08:14 -07:00
|
|
|
{
|
|
|
|
Evas_Public_Data *e = data;
|
|
|
|
|
|
|
|
// can not be done in std destructor
|
|
|
|
e->devices = eina_list_remove(e->devices, ev->object);
|
2016-10-19 10:57:18 -07:00
|
|
|
|
|
|
|
if (e->default_seat == ev->object)
|
|
|
|
e->default_seat = _new_default_device_find(e, ev->object);
|
|
|
|
else if (e->default_mouse == ev->object)
|
|
|
|
e->default_mouse = _new_default_device_find(e, ev->object);
|
|
|
|
else if (e->default_keyboard == ev->object)
|
|
|
|
e->default_keyboard = _new_default_device_find(e, ev->object);
|
|
|
|
|
2016-10-21 05:25:41 -07:00
|
|
|
_evas_pointer_data_remove(e, ev->object);
|
2016-09-20 08:10:08 -07:00
|
|
|
efl_event_callback_call(e->evas, EFL_CANVAS_EVENT_DEVICE_REMOVED,
|
|
|
|
ev->object);
|
2016-04-28 01:08:14 -07:00
|
|
|
}
|
|
|
|
|
2012-09-17 03:12:48 -07:00
|
|
|
EAPI Evas_Device *
|
2013-04-08 04:08:43 -07:00
|
|
|
evas_device_add(Evas *eo_e)
|
2016-09-20 09:44:23 -07:00
|
|
|
{
|
2016-09-29 13:51:14 -07:00
|
|
|
return evas_device_add_full(eo_e, NULL, NULL, NULL, NULL,
|
2016-09-20 09:44:23 -07:00
|
|
|
EVAS_DEVICE_CLASS_NONE,
|
|
|
|
EVAS_DEVICE_SUBCLASS_NONE);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Evas_Device *
|
2016-09-29 13:51:14 -07:00
|
|
|
evas_device_add_full(Evas *eo_e, const char *name, const char *desc,
|
2016-09-20 09:44:23 -07:00
|
|
|
Evas_Device *parent_dev, Evas_Device *emulation_dev,
|
|
|
|
Evas_Device_Class clas, Evas_Device_Subclass sub_clas)
|
2012-09-17 03:12:48 -07:00
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
Efl_Input_Device_Data *d;
|
|
|
|
Evas_Public_Data *e;
|
2012-09-17 03:12:48 -07:00
|
|
|
Evas_Device *dev;
|
2016-04-28 01:08:14 -07:00
|
|
|
|
|
|
|
SAFETY_CHECK(eo_e, EVAS_CANVAS_CLASS, NULL);
|
|
|
|
|
2016-09-20 09:44:23 -07:00
|
|
|
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));
|
2016-04-28 01:08:14 -07:00
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS);
|
2016-04-28 01:08:14 -07:00
|
|
|
d->evas = eo_e;
|
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-10-19 10:57:18 -07:00
|
|
|
|
|
|
|
/* This is the case when the user is using wayland backend,
|
|
|
|
since evas itself will not create the devices we must set them here. */
|
|
|
|
if (!e->default_seat && clas == EVAS_DEVICE_CLASS_SEAT)
|
|
|
|
e->default_seat = dev;
|
|
|
|
else if (!e->default_keyboard && clas == EVAS_DEVICE_CLASS_KEYBOARD)
|
|
|
|
e->default_keyboard = dev;
|
2016-10-21 05:25:41 -07:00
|
|
|
else if (_is_pointer(clas))
|
|
|
|
{
|
|
|
|
if (!_evas_pointer_data_add(e, dev))
|
|
|
|
{
|
|
|
|
efl_del(dev);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!e->default_mouse)
|
|
|
|
e->default_mouse = dev;
|
|
|
|
}
|
2016-10-19 10:57:18 -07:00
|
|
|
|
2016-11-01 11:03:52 -07:00
|
|
|
e->devices = eina_list_append(e->devices, dev);
|
2016-08-10 07:23:04 -07:00
|
|
|
efl_event_callback_add(dev, EFL_EVENT_DEL, _del_cb, e);
|
2016-04-28 01:08:14 -07:00
|
|
|
|
2016-09-20 08:10:08 -07:00
|
|
|
efl_event_callback_call(eo_e, EFL_CANVAS_EVENT_DEVICE_ADDED, dev);
|
|
|
|
// Keeping this event to do not break things...
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_event_callback_call(eo_e, EVAS_CALLBACK_DEVICE_CHANGED, dev);
|
2016-04-28 01:08:14 -07:00
|
|
|
|
2012-09-17 03:12:48 -07:00
|
|
|
return dev;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2013-04-08 04:08:43 -07:00
|
|
|
evas_device_del(Evas_Device *dev)
|
2012-09-17 03:12:48 -07:00
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS);
|
|
|
|
|
2016-09-20 10:49:57 -07:00
|
|
|
efl_del(dev);
|
2012-09-17 03:12:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_device_push(Evas *eo_e, Evas_Device *dev)
|
2012-09-17 03:12:48 -07:00
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
SAFETY_CHECK(eo_e, EVAS_CANVAS_CLASS);
|
|
|
|
SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS);
|
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2012-09-17 03:12:48 -07:00
|
|
|
if (!e->cur_device)
|
|
|
|
{
|
|
|
|
e->cur_device = eina_array_new(4);
|
|
|
|
if (!e->cur_device) return;
|
|
|
|
}
|
2016-08-15 06:44:41 -07:00
|
|
|
efl_ref(dev);
|
2012-09-17 03:12:48 -07:00
|
|
|
eina_array_push(e->cur_device, dev);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_device_pop(Evas *eo_e)
|
2012-09-17 03:12:48 -07:00
|
|
|
{
|
|
|
|
Evas_Device *dev;
|
2016-04-28 01:08:14 -07:00
|
|
|
|
|
|
|
SAFETY_CHECK(eo_e, EVAS_CANVAS_CLASS);
|
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2012-09-17 03:12:48 -07:00
|
|
|
dev = eina_array_pop(e->cur_device);
|
2016-08-15 06:44:41 -07:00
|
|
|
if (dev) efl_unref(dev);
|
2012-09-17 03:12:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI const Eina_List *
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_device_list(Evas *eo_e, const Evas_Device *dev)
|
2012-09-17 03:12:48 -07:00
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
SAFETY_CHECK(eo_e, EVAS_CANVAS_CLASS, NULL);
|
|
|
|
|
2012-09-17 03:12:48 -07:00
|
|
|
if (dev)
|
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS, NULL);
|
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
Efl_Input_Device_Data *d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS);
|
2016-04-28 01:08:14 -07:00
|
|
|
return d->children;
|
2012-09-17 03:12:48 -07:00
|
|
|
}
|
2016-04-28 01:08:14 -07:00
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2012-09-17 03:12:48 -07:00
|
|
|
return e->devices;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_device_name_set(Evas_Device *dev, const char *name)
|
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS);
|
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
Efl_Input_Device_Data *d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS);
|
2016-04-28 01:08:14 -07:00
|
|
|
|
|
|
|
efl_input_device_name_set(dev, name);
|
|
|
|
evas_event_callback_call(d->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev);
|
2012-09-17 03:12:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI const char *
|
|
|
|
evas_device_name_get(const Evas_Device *dev)
|
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
return efl_input_device_name_get(dev);
|
2012-09-17 03:12:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_device_description_set(Evas_Device *dev, const char *desc)
|
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS);
|
|
|
|
|
|
|
|
efl_input_device_description_set(dev, desc);
|
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
Efl_Input_Device_Data *d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS);
|
2016-04-28 01:08:14 -07:00
|
|
|
evas_event_callback_call(d->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev);
|
2012-09-17 03:12:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI const char *
|
|
|
|
evas_device_description_get(const Evas_Device *dev)
|
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
return efl_input_device_description_get(dev);
|
2012-09-17 03:12:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_device_parent_set(Evas_Device *dev, Evas_Device *parent)
|
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS);
|
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
Efl_Input_Device_Data *d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS);
|
2012-09-17 03:12:48 -07:00
|
|
|
if (parent)
|
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
SAFETY_CHECK(parent, EFL_INPUT_DEVICE_CLASS);
|
|
|
|
}
|
|
|
|
|
2016-09-20 09:40:31 -07:00
|
|
|
efl_input_device_parent_set(dev, parent);
|
2016-04-28 01:08:14 -07:00
|
|
|
evas_event_callback_call(d->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev);
|
2012-09-17 03:12:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI const Evas_Device *
|
|
|
|
evas_device_parent_get(const Evas_Device *dev)
|
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
return efl_input_device_parent_get(dev);
|
2012-09-17 03:12:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_device_class_set(Evas_Device *dev, Evas_Device_Class clas)
|
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS);
|
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
Efl_Input_Device_Data *d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS);
|
2016-10-21 05:25:41 -07:00
|
|
|
Evas_Public_Data *edata = efl_data_scope_get(d->evas, EVAS_CANVAS_CLASS);
|
|
|
|
|
|
|
|
if (d->klass == clas)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (_is_pointer(d->klass))
|
|
|
|
_evas_pointer_data_remove(edata, dev);
|
2016-04-28 01:08:14 -07:00
|
|
|
|
|
|
|
efl_input_device_type_set(dev, clas);
|
2016-10-21 05:25:41 -07:00
|
|
|
|
|
|
|
if (_is_pointer(clas))
|
|
|
|
_evas_pointer_data_add(edata, dev);
|
|
|
|
|
2016-04-28 01:08:14 -07:00
|
|
|
evas_event_callback_call(d->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev);
|
2012-09-17 03:12:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Evas_Device_Class
|
|
|
|
evas_device_class_get(const Evas_Device *dev)
|
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
return efl_input_device_type_get(dev);
|
2012-09-17 03:12:48 -07:00
|
|
|
}
|
|
|
|
|
2013-04-12 04:04:34 -07:00
|
|
|
EAPI void
|
|
|
|
evas_device_subclass_set(Evas_Device *dev, Evas_Device_Subclass clas)
|
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS);
|
2016-08-15 06:44:41 -07:00
|
|
|
Efl_Input_Device_Data *d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS);
|
2016-04-28 01:08:14 -07:00
|
|
|
|
|
|
|
efl_input_device_subtype_set(dev, clas);
|
|
|
|
evas_event_callback_call(d->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev);
|
2013-04-12 04:04:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Evas_Device_Subclass
|
|
|
|
evas_device_subclass_get(const Evas_Device *dev)
|
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
return efl_input_device_subtype_get(dev);
|
2013-04-12 04:04:34 -07:00
|
|
|
}
|
|
|
|
|
2012-09-17 03:12:48 -07:00
|
|
|
EAPI void
|
|
|
|
evas_device_emulation_source_set(Evas_Device *dev, Evas_Device *src)
|
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS);
|
2016-08-15 06:44:41 -07:00
|
|
|
Efl_Input_Device_Data *d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS);
|
2016-04-28 01:08:14 -07:00
|
|
|
|
|
|
|
efl_input_device_source_set(dev, src);
|
|
|
|
evas_event_callback_call(d->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev);
|
2012-09-17 03:12:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI const Evas_Device *
|
|
|
|
evas_device_emulation_source_get(const Evas_Device *dev)
|
|
|
|
{
|
2016-04-28 01:08:14 -07:00
|
|
|
return efl_input_device_source_get(dev);
|
2012-09-17 03:12:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-10-08 18:58:41 -07:00
|
|
|
_evas_device_cleanup(Evas *eo_e)
|
2012-09-17 03:12:48 -07:00
|
|
|
{
|
2016-11-01 11:03:52 -07:00
|
|
|
Eina_List *cpy;
|
2012-09-17 03:12:48 -07:00
|
|
|
Evas_Device *dev;
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2016-11-01 11:03:52 -07:00
|
|
|
|
2012-09-17 03:12:48 -07:00
|
|
|
if (e->cur_device)
|
|
|
|
{
|
|
|
|
while ((dev = eina_array_pop(e->cur_device)))
|
2016-08-15 06:44:41 -07:00
|
|
|
efl_unref(dev);
|
2012-09-17 03:12:48 -07:00
|
|
|
eina_array_free(e->cur_device);
|
|
|
|
e->cur_device = NULL;
|
|
|
|
}
|
2016-11-01 11:03:52 -07:00
|
|
|
|
|
|
|
/* 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.
|
|
|
|
*/
|
2012-09-17 03:12:48 -07:00
|
|
|
EINA_LIST_FREE(e->devices, dev)
|
|
|
|
{
|
2016-11-01 11:03:52 -07:00
|
|
|
efl_event_callback_call(e->evas,
|
|
|
|
EFL_CANVAS_EVENT_DEVICE_REMOVED,
|
|
|
|
dev);
|
|
|
|
efl_event_callback_del(dev, EFL_EVENT_DEL, _del_cb, e);
|
2012-09-17 03:12:48 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Evas_Device *
|
2012-10-08 18:58:41 -07:00
|
|
|
_evas_device_top_get(const Evas *eo_e)
|
2012-09-17 03:12:48 -07:00
|
|
|
{
|
|
|
|
int num;
|
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
2012-09-17 03:12:48 -07:00
|
|
|
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);
|
|
|
|
}
|