evas: send eo pointer events on mouse move

This is still VERY experimental and not fully done yet.
All other pointer events need to be sent as well.

The legacy event system is used as a transportation mechanism,
as it is too hard to change the logic. This only adds an extra
eo event in case of move. Obviously for performance we might
want to listen to callback_add,del but that's an optimization
for later.

The whole point of sending those pointer events is to carry more
information than can be sent over legacy evas events, and unify
the events in a common format.
This commit is contained in:
Jean-Philippe Andre 2016-05-12 16:48:54 +09:00
parent 8e31929aab
commit 37d894abb1
9 changed files with 138 additions and 28 deletions

View File

@ -599,6 +599,9 @@ ecore_event_evas_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *
e = event;
lookup = _ecore_event_window_match(e->event_window);
if (!lookup) return ECORE_CALLBACK_PASS_ON;
if (lookup->direct &&
lookup->direct(lookup->window, ECORE_EVENT_MOUSE_MOVE, e))
return ECORE_CALLBACK_PASS_ON;
if (e->multi.device == 0)
{
_ecore_event_evas_push_mouse_move(e);

View File

@ -1,4 +1,4 @@
type @extern Eo_Event_Description: __undefined_type;
import eo_base;
interface Efl.Event
{
@ -31,7 +31,7 @@ interface Efl.Event
set {}
get {}
values {
type: const(Eo_Event_Description)*;
type: const(Eo.Event.Description)*;
}
}
reset {

View File

@ -123,4 +123,8 @@ interface Efl.Gfx {
}
}
}
events {
/* FIXME: eolian thinks there's a cyclic dependency here. wtf */
pointer /*: Efl.Pointer.Event*/; [[New generic pointer (mouse, finger, pen...) event.]]
}
}

View File

@ -97,7 +97,8 @@ _efl_pointer_event_efl_event_dup(Eo *obj, Efl_Pointer_Event_Data *pd)
Efl_Pointer_Event_Data *ev;
Efl_Pointer_Event *evt;
evt = _efl_pointer_event_instance_get(EFL_POINTER_EVENT_CLASS, NULL, obj, &ev);
evt = _efl_pointer_event_instance_get((Eo_Class *) EFL_POINTER_EVENT_CLASS,
NULL, obj, (void **) &ev);
if (!evt) return NULL;
memcpy(ev, pd, sizeof(*ev));

View File

@ -85,7 +85,7 @@ class Efl.Pointer.Event (Eo.Base, Efl.Event)
propagation or repetition of the event.
]]
values {
src: Efl.Gfx;
src: Eo.Base; [[Source object: $Efl.Gfx]]
}
}
/* FIXME: why not double_click() and triple_click() */

View File

@ -441,6 +441,7 @@ struct _Evas_Event_Mouse_Move /** Mouse move event */
Evas_Event_Flags event_flags;
Evas_Device *dev;
Evas_Object *event_src; /**< The Evas Object which actually triggered the event, used in cases of proxy event propagation */
void *reserved; /* internal use only */
};
struct _Evas_Event_Mouse_Wheel /** Wheel event */

View File

@ -58,10 +58,29 @@ typedef struct
Evas_Callback_Type type;
} _eo_evas_object_cb_info;
static inline void *
_pointer_event_get(const _eo_evas_object_cb_info *info, const Eo_Event *event)
{
if (!info->data) return NULL;
switch (info->type)
{
case EVAS_CALLBACK_MOUSE_MOVE:
return ((Evas_Event_Mouse_Move *) event->info)->reserved;
default:
return NULL;
}
}
static Eina_Bool
_eo_evas_object_cb(void *data, const Eo_Event *event)
{
_eo_evas_object_cb_info *info = data;
void *pe = _pointer_event_get(info, event);
if (pe)
{
DBG("triggering eo pointer event!");
eo_event_callback_call(event->object, EFL_GFX_EVENT_POINTER, pe);
}
if (info->func) info->func(info->data, evas_object_evas_get(event->object), event->object, event->info);
return EINA_TRUE;
}

View File

@ -1327,6 +1327,6 @@ class Evas.Canvas (Eo.Base, Evas.Common_Interface, Efl.Animator)
device,changed;
axis,update;
viewport,resize;
pointer;
pointer: Efl.Pointer.Event; [[Generic pointer event (mouse, finger...)]]
}
}

View File

@ -35,6 +35,86 @@ _evas_event_havemap_adjust(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protecte
}
}
static inline Efl_Pointer_Event *
_pointer_event_create(Evas_Callback_Type type, void *ev,
Efl_Pointer_Event_Data *parentev,
Efl_Pointer_Event_Data **evdata)
{
Efl_Pointer_Event *evt = NULL;
Efl_Pointer_Event *pev = parentev ? parentev->eo : NULL;
if (!ev) return NULL;
/* This function converts an existing evas info struct to the efl pointer
* event. All pointers must be valid.
*
* FIXME: evas event logic should not use legacy structs anymore... this
* should be temporary code. Should be.
*/
switch (type)
{
case EVAS_CALLBACK_MOUSE_MOVE:
evt = efl_pointer_event_instance_get(EFL_POINTER_EVENT_CLASS, pev, (void **) evdata);
efl_pointer_event_legacy_info_set(evt, ev, type);
((Evas_Event_Mouse_Move *) ev)->reserved = evt;
break;
default:
DBG("Support for event type %d not implemented yet.", type);
break;
}
if (!evt && evdata) *evdata = NULL;
return evt;
}
static inline void
_pointer_event_adjust(Evas_Callback_Type type, void *ev,
Efl_Pointer_Event_Data *evdata)
{
if (!evdata) return;
/* FIXME: remove OR 1 */
#if defined(DEBUG) || 1
# define CHKACT(a) do { if (evdata->action != EFL_POINTER_ACTION_ ## a) abort(); } while (0)
#else
# define CHKACT(a) do {} while(0)
#endif
switch (type)
{
case EVAS_CALLBACK_MOUSE_MOVE:
CHKACT(MOVE);
evdata->cur.x = ((Evas_Event_Mouse_Move *) ev)->cur.canvas.x;
evdata->cur.y = ((Evas_Event_Mouse_Move *) ev)->cur.canvas.y;
evdata->cur.xsub = ((Evas_Event_Mouse_Move *) ev)->cur.canvas.x;
evdata->cur.ysub = ((Evas_Event_Mouse_Move *) ev)->cur.canvas.y;
break;
case EVAS_CALLBACK_MOUSE_OUT:
CHKACT(OUT);
evdata->cur.x = ((Evas_Event_Mouse_Out *) ev)->canvas.x;
evdata->cur.y = ((Evas_Event_Mouse_Out *) ev)->canvas.y;
evdata->cur.xsub = ((Evas_Event_Mouse_Out *) ev)->canvas.x;
evdata->cur.ysub = ((Evas_Event_Mouse_Out *) ev)->canvas.y;
break;
case EVAS_CALLBACK_MOUSE_IN:
CHKACT(IN);
evdata->cur.x = ((Evas_Event_Mouse_In *) ev)->canvas.x;
evdata->cur.y = ((Evas_Event_Mouse_In *) ev)->canvas.y;
evdata->cur.xsub = ((Evas_Event_Mouse_In *) ev)->canvas.x;
evdata->cur.ysub = ((Evas_Event_Mouse_In *) ev)->canvas.y;
break;
default: break;
}
}
#define EV_CALL(_eo_obj, _obj, _typ, _ev, _id, _pe) do { \
if (!_pe) _pe = _pointer_event_create(_typ, _ev, parent_pe, & _pe ## data); \
else _pointer_event_adjust(_typ, _ev, _pe ## data); \
evas_object_event_callback_call(_eo_obj, _obj, _typ, _ev, _id); \
} while (0)
#define EV_DEL(a) do { eo_unref(a); a = NULL; } while (0)
static Eina_List *
_evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
const Eina_Inlist *list, Evas_Object *stop,
@ -1422,9 +1502,13 @@ evas_event_feed_mouse_wheel(Eo *eo_e, int direction, int z, unsigned int timesta
}
static void
_canvas_event_feed_mouse_move_internal(Eo *eo_e, Evas_Public_Data *e, int x, int y, unsigned int timestamp, const void *data)
_canvas_event_feed_mouse_move_internal(Eo *eo_e, Evas_Public_Data *e, int x, int y,
unsigned int timestamp, const void *data,
Efl_Pointer_Event_Data *parent_pe)
{
Evas_Object *nogrep_obj = NULL;
Efl_Pointer_Event_Data *pemovedata = NULL, *peoutdata = NULL, *peindata = NULL;
Efl_Pointer_Event *pemove = NULL, *peout = NULL, *pein = NULL;
int px, py;
px = e->pointer.x;
@ -1471,6 +1555,7 @@ _canvas_event_feed_mouse_move_internal(Eo *eo_e, Evas_Public_Data *e, int x, int
ev.event_flags = e->default_event_flags;
ev.dev = _evas_device_top_get(eo_e);
if (ev.dev) eo_ref(ev.dev);
copy = evas_event_list_copy(e->pointer.object.in);
EINA_LIST_FOREACH(copy, l, eo_obj)
{
@ -1492,8 +1577,7 @@ _canvas_event_feed_mouse_move_internal(Eo *eo_e, Evas_Public_Data *e, int x, int
if ((px != x) || (py != y))
{
evas_object_event_callback_call(eo_obj, obj,
EVAS_CALLBACK_MOUSE_MOVE, &ev, event_id);
EV_CALL(eo_obj, obj, EVAS_CALLBACK_MOUSE_MOVE, &ev, event_id, pemove);
if ((obj->proxy->is_proxy) &&
(obj->proxy->src_events))
_evas_event_source_mouse_move_events(eo_obj, eo_e,
@ -1514,6 +1598,7 @@ _canvas_event_feed_mouse_move_internal(Eo *eo_e, Evas_Public_Data *e, int x, int
}
_evas_post_event_callback_call(eo_e, e);
if (ev.dev) eo_unref(ev.dev);
EV_DEL(pemove);
}
{
Evas_Event_Mouse_Out ev;
@ -1554,9 +1639,7 @@ _canvas_event_feed_mouse_move_internal(Eo *eo_e, Evas_Public_Data *e, int x, int
&ev.canvas.y,
obj->mouse_grabbed);
e->pointer.object.in = eina_list_remove(e->pointer.object.in, eo_obj);
evas_object_event_callback_call(eo_obj, obj,
EVAS_CALLBACK_MOUSE_OUT,
&ev, event_id);
EV_CALL(eo_obj, obj, EVAS_CALLBACK_MOUSE_OUT, &ev, event_id, pein);
if ((obj->proxy->is_proxy) &&
(obj->proxy->src_events))
_evas_event_source_mouse_out_events(eo_obj, eo_e, &ev,
@ -1565,6 +1648,7 @@ _canvas_event_feed_mouse_move_internal(Eo *eo_e, Evas_Public_Data *e, int x, int
}
_evas_post_event_callback_call(eo_e, e);
if (ev.dev) eo_unref(ev.dev);
EV_DEL(peout);
}
}
else
@ -1652,7 +1736,7 @@ _canvas_event_feed_mouse_move_internal(Eo *eo_e, Evas_Public_Data *e, int x, int
ev.cur.canvas.x = e->pointer.x;
ev.cur.canvas.y = e->pointer.y;
_evas_event_havemap_adjust(eo_obj, obj, &ev.cur.canvas.x, &ev.cur.canvas.y, obj->mouse_grabbed);
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_MOVE, &ev, event_id);
EV_CALL(eo_obj, obj, EVAS_CALLBACK_MOUSE_MOVE, &ev, event_id, pemove);
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
_evas_event_source_mouse_move_events(eo_obj, eo_e, &ev,
event_id);
@ -1670,9 +1754,7 @@ _canvas_event_feed_mouse_move_internal(Eo *eo_e, Evas_Public_Data *e, int x, int
_evas_event_havemap_adjust(eo_obj, obj, &ev2.canvas.x,
&ev2.canvas.y,
obj->mouse_grabbed);
evas_object_event_callback_call(eo_obj, obj,
EVAS_CALLBACK_MOUSE_OUT,
&ev2, event_id);
EV_CALL(eo_obj, obj, EVAS_CALLBACK_MOUSE_OUT, &ev2, event_id, peout);
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
_evas_event_source_mouse_out_events(eo_obj, eo_e, &ev2,
event_id);
@ -1703,9 +1785,7 @@ _canvas_event_feed_mouse_move_internal(Eo *eo_e, Evas_Public_Data *e, int x, int
_evas_event_havemap_adjust(eo_obj, obj, &ev3.canvas.x,
&ev3.canvas.y,
obj->mouse_grabbed);
evas_object_event_callback_call(eo_obj, obj,
EVAS_CALLBACK_MOUSE_IN,
&ev3, event_id2);
EV_CALL(eo_obj, obj, EVAS_CALLBACK_MOUSE_IN, &ev3, event_id2, pein);
if ((obj->proxy->is_proxy) &&
(obj->proxy->src_events))
_evas_event_source_mouse_in_events(eo_obj, eo_e, &ev3,
@ -1728,6 +1808,9 @@ _canvas_event_feed_mouse_move_internal(Eo *eo_e, Evas_Public_Data *e, int x, int
}
_evas_post_event_callback_call(eo_e, e);
if (ev.dev) eo_unref(ev.dev);
EV_DEL(pemove);
EV_DEL(peout);
EV_DEL(pein);
}
_evas_unwalk(e);
return;
@ -1844,7 +1927,7 @@ nogrep:
ev.cur.canvas.x = e->pointer.x;
ev.cur.canvas.y = e->pointer.y;
_evas_event_havemap_adjust(eo_obj, obj, &ev.cur.canvas.x, &ev.cur.canvas.y, obj->mouse_grabbed);
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_MOVE, &ev, event_id);
EV_CALL(eo_obj, obj, EVAS_CALLBACK_MOUSE_MOVE, &ev, event_id, pemove);
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
_evas_event_source_mouse_move_events(eo_obj, eo_e, &ev,
event_id);
@ -1860,9 +1943,7 @@ nogrep:
ev2.canvas.y = e->pointer.y;
_evas_event_havemap_adjust(eo_obj, obj, &ev2.canvas.x,
&ev2.canvas.y, obj->mouse_grabbed);
evas_object_event_callback_call(eo_obj, obj,
EVAS_CALLBACK_MOUSE_OUT, &ev2,
event_id);
EV_CALL(eo_obj, obj, EVAS_CALLBACK_MOUSE_OUT, &ev2, event_id, peout);
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
_evas_event_source_mouse_out_events(eo_obj, eo_e, &ev2,
event_id);
@ -1890,9 +1971,7 @@ nogrep:
ev3.canvas.y = e->pointer.y;
_evas_event_havemap_adjust(eo_obj, obj, &ev3.canvas.x,
&ev3.canvas.y, obj->mouse_grabbed);
evas_object_event_callback_call(eo_obj, obj,
EVAS_CALLBACK_MOUSE_IN, &ev3,
event_id2);
EV_CALL(eo_obj, obj, EVAS_CALLBACK_MOUSE_IN, &ev3, event_id2, pein);
if ((obj->proxy->is_proxy) && (obj->proxy->src_events))
_evas_event_source_mouse_in_events(eo_obj, eo_e, &ev3,
event_id2);
@ -1906,6 +1985,9 @@ nogrep:
_evas_post_event_callback_call(eo_e, e);
if (ev.dev) eo_unref(ev.dev);
EV_DEL(pemove);
EV_DEL(peout);
EV_DEL(pein);
}
_evas_unwalk(e);
}
@ -1914,14 +1996,14 @@ EAPI void
evas_event_input_mouse_move(Eo *eo_e, int x, int y, unsigned int timestamp, const void *data)
{
Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
_canvas_event_feed_mouse_move_internal(eo_e, e, x - e->framespace.x, y - e->framespace.y, timestamp, data);
_canvas_event_feed_mouse_move_internal(eo_e, e, x - e->framespace.x, y - e->framespace.y, timestamp, data, NULL);
}
EAPI void
evas_event_feed_mouse_move(Eo *eo_e, int x, int y, unsigned int timestamp, const void *data)
{
Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
_canvas_event_feed_mouse_move_internal(eo_e, e, x, y, timestamp, data);
_canvas_event_feed_mouse_move_internal(eo_e, e, x, y, timestamp, data, NULL);
}
EAPI void
@ -3059,7 +3141,7 @@ _evas_canvas_event_pointer_cb(void *data, const Eo_Event *event)
if (ev->finger == 0)
{
_canvas_event_feed_mouse_move_internal(eo_e, e, ev->cur.x, ev->cur.y,
ev->timestamp, ev->data);
ev->timestamp, ev->data, ev);
}
else
{