forked from enlightenment/efl
231 lines
5.9 KiB
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"
|