efl/src/lib/evas/canvas/efl_input_device.c

231 lines
5.9 KiB
C

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "Evas.h"
#define EFL_INTERNAL_UNSTABLE
#include "Evas_Internal.h"
#define MY_CLASS EFL_INPUT_DEVICE_CLASS
/* Efl Input Device = Evas Device */
typedef struct _Child_Device_Iterator Child_Device_Iterator;
struct _Child_Device_Iterator
{
Eina_Iterator iterator;
Eina_List *list;
Eina_Iterator *real_iterator;
Eo *object;
};
static Eina_Bool
_is_pointer(Efl_Input_Device_Data *pd)
{
return (pd->klass == EFL_INPUT_DEVICE_TYPE_MOUSE ||
pd->klass == EFL_INPUT_DEVICE_TYPE_TOUCH ||
pd->klass == EFL_INPUT_DEVICE_TYPE_PEN ||
pd->klass == EFL_INPUT_DEVICE_TYPE_WAND);
}
static void
_seat_pointers_update(Efl_Input_Device_Data *seat, Efl_Input_Device_Data *dev)
{
if (seat && _is_pointer(dev))
seat->pointer_count++;
}
EOLIAN static Efl_Object *
_efl_input_device_efl_object_constructor(Eo *obj, Efl_Input_Device_Data *pd)
{
obj = efl_constructor(efl_super(obj, MY_CLASS));
pd->eo = obj;
return obj;
}
EOLIAN static void
_efl_input_device_efl_object_destructor(Eo *obj, Efl_Input_Device_Data *pd)
{
pd->children = eina_list_free(pd->children);
if (pd->klass != EFL_INPUT_DEVICE_TYPE_SEAT)
{
Efl_Input_Device_Data *p;
Eo *seat;
seat = efl_input_device_seat_get(obj);
p = efl_data_scope_get(seat, MY_CLASS);
if (p) p->children = eina_list_remove(p->children, obj);
}
efl_unref(pd->source);
return efl_destructor(efl_super(obj, MY_CLASS));
}
EOLIAN static void
_efl_input_device_efl_object_parent_set(Eo *obj, Efl_Input_Device_Data *pd EINA_UNUSED, Eo *parent)
{
Efl_Input_Device_Data *p;
if (parent)
{
if (efl_isa(parent, MY_CLASS))
{
p = efl_data_scope_get(parent, MY_CLASS);
EINA_SAFETY_ON_FALSE_RETURN(p->klass == EFL_INPUT_DEVICE_TYPE_SEAT);
if (!eina_list_data_find(p->children, obj))
{
p->children = eina_list_append(p->children, obj);
_seat_pointers_update(p, pd);
}
}
else if(!efl_isa(parent, EFL_CANVAS_SCENE_INTERFACE))
{
EINA_SAFETY_ERROR("The parent of a device must be a seat or the canvas");
return;
}
}
else
{
Eo *old_parent = efl_parent_get(obj);
if (old_parent && efl_isa(old_parent, MY_CLASS))
{
p = efl_data_scope_get(old_parent, MY_CLASS);
p->children = eina_list_remove(p->children, obj);
if (_is_pointer(pd))
p->pointer_count--;
}
}
efl_parent_set(efl_super(obj, MY_CLASS), parent);
}
EOLIAN static void
_efl_input_device_device_type_set(Eo *obj, Efl_Input_Device_Data *pd, Efl_Input_Device_Type klass)
{
EINA_SAFETY_ON_TRUE_RETURN(pd->klass);
pd->klass = klass;
if (klass != EFL_INPUT_DEVICE_TYPE_SEAT)
{
Efl_Input_Device_Data *seat = efl_data_scope_get(efl_input_device_seat_get(obj), MY_CLASS);
_seat_pointers_update(seat, pd);
}
}
EOLIAN static Efl_Input_Device_Type
_efl_input_device_device_type_get(const Eo *obj EINA_UNUSED, Efl_Input_Device_Data *pd)
{
return pd->klass;
}
EOLIAN static void
_efl_input_device_source_set(Eo *obj EINA_UNUSED, Efl_Input_Device_Data *pd, Efl_Input_Device *src)
{
if (pd->source == src) return;
efl_unref(pd->source);
pd->source = efl_ref(src);
}
EOLIAN static Efl_Input_Device *
_efl_input_device_source_get(const Eo *obj EINA_UNUSED, Efl_Input_Device_Data *pd)
{
return pd->source;
}
EOLIAN static void
_efl_input_device_seat_id_set(Eo *obj EINA_UNUSED, Efl_Input_Device_Data *pd, unsigned int id)
{
EINA_SAFETY_ON_TRUE_RETURN(pd->klass != EFL_INPUT_DEVICE_TYPE_SEAT);
pd->id = id;
}
EOLIAN static unsigned int
_efl_input_device_seat_id_get(const Eo *obj, Efl_Input_Device_Data *pd)
{
if (pd->klass == EFL_INPUT_DEVICE_TYPE_SEAT)
return pd->id;
return efl_input_device_seat_id_get(efl_input_device_seat_get(obj));
}
EOLIAN static Efl_Input_Device *
_efl_input_device_seat_get(const Eo *obj, Efl_Input_Device_Data *pd)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
if (pd->klass == EFL_INPUT_DEVICE_TYPE_SEAT)
return pd->eo;
while ((obj = efl_parent_get(obj)))
{
if (!efl_isa(obj, MY_CLASS)) break;
pd = efl_data_scope_get(obj, MY_CLASS);
if (pd->klass == EFL_INPUT_DEVICE_TYPE_SEAT)
return pd->eo;
}
return NULL;
}
static Eina_Bool
_child_device_iterator_next(Child_Device_Iterator *it, void **data)
{
Eo *sub;
if (!eina_iterator_next(it->real_iterator, (void **) &sub))
return EINA_FALSE;
if (data) *data = sub;
return EINA_TRUE;
}
static Eo *
_child_device_iterator_get_container(Child_Device_Iterator *it)
{
return it->object;
}
static void
_child_device_iterator_free(Child_Device_Iterator *it)
{
eina_iterator_free(it->real_iterator);
free(it);
}
EOLIAN static Eina_Iterator *
_efl_input_device_children_iterate(Eo *obj, Efl_Input_Device_Data *pd)
{
Child_Device_Iterator *it;
it = calloc(1, sizeof(*it));
if (!it) return NULL;
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
it->list = pd->children;
it->real_iterator = eina_list_iterator_new(it->list);
it->iterator.version = EINA_ITERATOR_VERSION;
it->iterator.next = FUNC_ITERATOR_NEXT(_child_device_iterator_next);
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_child_device_iterator_get_container);
it->iterator.free = FUNC_ITERATOR_FREE(_child_device_iterator_free);
it->object = obj;
return &it->iterator;
}
EOLIAN static int
_efl_input_device_pointer_device_count_get(const Eo *obj EINA_UNUSED, Efl_Input_Device_Data *pd)
{
if (pd->klass == EFL_INPUT_DEVICE_TYPE_SEAT)
return pd->pointer_count;
return -1;
}
EOLIAN static Eina_Bool
_efl_input_device_is_pointer_type_get(const Eo *obj EINA_UNUSED, Efl_Input_Device_Data *pd)
{
return _is_pointer(pd);
}
#include "efl_input_device.eo.c"