From d5469fc0df150bb22d52b89269e00c646417d934 Mon Sep 17 00:00:00 2001 From: raster Date: Sat, 16 Jan 2010 12:20:22 +0000 Subject: [PATCH] initial multi-touch support. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@45212 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/Evas.h | 70 +++++++++++++++ src/lib/canvas/evas_events.c | 199 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+) diff --git a/src/lib/Evas.h b/src/lib/Evas.h index 75e089f..b60ea91 100644 --- a/src/lib/Evas.h +++ b/src/lib/Evas.h @@ -49,6 +49,9 @@ typedef enum _Evas_Callback_Type EVAS_CALLBACK_MOUSE_UP, /**< Mouse Button Up Event */ EVAS_CALLBACK_MOUSE_MOVE, /**< Mouse Move Event */ EVAS_CALLBACK_MOUSE_WHEEL, /**< Mouse Wheel Event */ + EVAS_CALLBACK_MULTI_DOWN, /**< Multi-touch Down Event */ + EVAS_CALLBACK_MULTI_UP, /**< Multi-touch Up Event */ + EVAS_CALLBACK_MULTI_MOVE, /**< Multi-touch Move Event */ EVAS_CALLBACK_FREE, /**< Object Being Freed (Called after Del) */ EVAS_CALLBACK_KEY_DOWN, /**< Key Press Event */ EVAS_CALLBACK_KEY_UP, /**< Key Release Event */ @@ -378,6 +381,9 @@ typedef struct _Evas_Event_Mouse_In Evas_Event_Mouse_In; /**< Event structure typedef struct _Evas_Event_Mouse_Out Evas_Event_Mouse_Out; /**< Event structure for #EVAS_CALLBACK_MOUSE_OUT event callbacks */ typedef struct _Evas_Event_Mouse_Move Evas_Event_Mouse_Move; /**< Event structure for #EVAS_CALLBACK_MOUSE_MOVE event callbacks */ typedef struct _Evas_Event_Mouse_Wheel Evas_Event_Mouse_Wheel; /**< Event structure for #EVAS_CALLBACK_MOUSE_WHEEL event callbacks */ +typedef struct _Evas_Event_Multi_Down Evas_Event_Multi_Down; /**< Event structure for #EVAS_CALLBACK_MULTI_DOWN event callbacks */ +typedef struct _Evas_Event_Multi_Up Evas_Event_Multi_Up; /**< Event structure for #EVAS_CALLBACK_MULTI_UP event callbacks */ +typedef struct _Evas_Event_Multi_Move Evas_Event_Multi_Move; /**< Event structure for #EVAS_CALLBACK_MULTI_MOVE event callbacks */ typedef struct _Evas_Event_Key_Down Evas_Event_Key_Down; /**< Event structure for #EVAS_CALLBACK_KEY_DOWN event callbacks */ typedef struct _Evas_Event_Key_Up Evas_Event_Key_Up; /**< Event structure for #EVAS_CALLBACK_KEY_UP event callbacks */ typedef struct _Evas_Event_Hold Evas_Event_Hold; /**< Event structure for #EVAS_CALLBACK_HOLD event callbacks */ @@ -584,6 +590,66 @@ struct _Evas_Event_Mouse_Wheel /** Wheel event */ Evas_Device *dev; }; +struct _Evas_Event_Multi_Down /** Multi button press event */ +{ + int device; /**< Multi device number that went down (1 or more) */ + int radius, radius_x, radius_y; + struct { + int x, y; + } output; + struct { + Evas_Coord x, y; + } canvas; + void *data; + Evas_Modifier *modifiers; + Evas_Lock *locks; + + Evas_Button_Flags flags; + unsigned int timestamp; + Evas_Event_Flags event_flags; + Evas_Device *dev; +}; + +struct _Evas_Event_Multi_Up /** Multi button release event */ +{ + int device; /**< Multi button number that was raised (1 - 32) */ + int radius, radius_x, radius_y; + struct { + int x, y; + } output; + struct { + Evas_Coord x, y; + } canvas; + void *data; + Evas_Modifier *modifiers; + Evas_Lock *locks; + + Evas_Button_Flags flags; + unsigned int timestamp; + Evas_Event_Flags event_flags; + Evas_Device *dev; +}; + +struct _Evas_Event_Multi_Move /** Multi button down event */ +{ + int device; /**< Button pressed mask, Bits set to 1 are buttons currently pressed (bit 0 = mouse button 1, bit 1 = mouse button 2 etc.) */ + int radius, radius_x, radius_y; + struct { + struct { + int x, y; + } output; + struct { + Evas_Coord x, y; + } canvas; + } cur; + void *data; + Evas_Modifier *modifiers; + Evas_Lock *locks; + unsigned int timestamp; + Evas_Event_Flags event_flags; + Evas_Device *dev; +}; + struct _Evas_Event_Key_Down /** Key press event */ { char *keyname; /**< The string name of the key pressed */ @@ -1110,6 +1176,10 @@ extern "C" { EAPI void evas_event_feed_mouse_move (Evas *e, int x, int y, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1); EAPI void evas_event_feed_mouse_in (Evas *e, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1); EAPI void evas_event_feed_mouse_out (Evas *e, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1); + EAPI void evas_event_feed_multi_down (Evas *e, int d, int x, int y, int rad, int radx, int rady, Evas_Button_Flags flags, unsigned int timestamp, const void *data); + EAPI void evas_event_feed_multi_up (Evas *e, int d, int x, int y, int rad, int radx, int rady, Evas_Button_Flags flags, unsigned int timestamp, const void *data); + EAPI void evas_event_feed_multi_move (Evas *e, int d, int x, int y, int rad, int radx, int rady, unsigned int timestamp, const void *data); + EAPI void evas_event_feed_mouse_cancel (Evas *e, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1); EAPI void evas_event_feed_mouse_wheel (Evas *e, int direction, int z, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1); EAPI void evas_event_feed_key_down (Evas *e, const char *keyname, const char *key, const char *string, const char *compose, unsigned int timestamp, const void *data) EINA_ARG_NONNULL(1); diff --git a/src/lib/canvas/evas_events.c b/src/lib/canvas/evas_events.c index 460ce15..742769a 100644 --- a/src/lib/canvas/evas_events.c +++ b/src/lib/canvas/evas_events.c @@ -944,6 +944,205 @@ evas_event_feed_mouse_out(Evas *e, unsigned int timestamp, const void *data) _evas_unwalk(e); } +EAPI void +evas_event_feed_multi_down(Evas *e, int d, int x, int y, int rad, int radx, int rady, Evas_Button_Flags flags, unsigned int timestamp, const void *data) +{ + Eina_List *l, *copy; + Evas_Event_Multi_Down ev; + Evas_Object *obj; + + MAGIC_CHECK(e, Evas, MAGIC_EVAS); + return; + MAGIC_CHECK_END(); + + if (e->events_frozen > 0) return; + e->last_timestamp = timestamp; + + ev.device = d; + ev.output.x = x; + ev.output.y = y; + ev.canvas.x = x; + ev.canvas.y = y; + ev.radius = rad; + ev.radius_x = radx; + ev.radius_y = rady; + ev.data = (void *)data; + ev.modifiers = &(e->modifiers); + ev.locks = &(e->locks); + ev.flags = flags; + ev.timestamp = timestamp; + ev.event_flags = EVAS_EVENT_FLAG_NONE; + + _evas_walk(e); + copy = evas_event_list_copy(e->pointer.object.in); + EINA_LIST_FOREACH(copy, l, obj) + { + ev.canvas.x = x; + ev.canvas.y = y; + _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y); + if (e->events_frozen <= 0) + evas_object_event_callback_call(obj, EVAS_CALLBACK_MULTI_DOWN, &ev); + if (e->delete_me) break; + } + if (copy) eina_list_free(copy); + _evas_unwalk(e); +} + +EAPI void +evas_event_feed_multi_up(Evas *e, int d, int x, int y, int rad, int radx, int rady, Evas_Button_Flags flags, unsigned int timestamp, const void *data) +{ + Eina_List *l, *copy; + Evas_Event_Multi_Up ev; + Evas_Object *obj; + + MAGIC_CHECK(e, Evas, MAGIC_EVAS); + return; + MAGIC_CHECK_END(); + + if (e->events_frozen > 0) return; + e->last_timestamp = timestamp; + + ev.device = d; + ev.output.x = x; + ev.output.y = y; + ev.canvas.x = x; + ev.canvas.y = y; + ev.radius = rad; + ev.radius_x = radx; + ev.radius_y = rady; + ev.data = (void *)data; + ev.modifiers = &(e->modifiers); + ev.locks = &(e->locks); + ev.flags = flags; + ev.timestamp = timestamp; + ev.event_flags = EVAS_EVENT_FLAG_NONE; + + _evas_walk(e); + copy = evas_event_list_copy(e->pointer.object.in); + EINA_LIST_FOREACH(copy, l, obj) + { + ev.canvas.x = x; + ev.canvas.y = y; + _evas_event_havemap_adjust(obj, &ev.canvas.x, &ev.canvas.y); + if (e->events_frozen <= 0) + evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_UP, &ev); + if (e->delete_me) break; + } + if (copy) copy = eina_list_free(copy); + + _evas_unwalk(e); +} + +EAPI void +evas_event_feed_multi_move(Evas *e, int d, int x, int y, int rad, int radx, int rady, unsigned int timestamp, const void *data) +{ + MAGIC_CHECK(e, Evas, MAGIC_EVAS); + return; + MAGIC_CHECK_END(); + + if (e->events_frozen > 0) return; + e->last_timestamp = timestamp; + + if (!e->pointer.inside) return; + + _evas_walk(e); + /* if our mouse button is grabbed to any objects */ + if (e->pointer.mouse_grabbed > 0) + { + /* go thru old list of in objects */ + Eina_List *outs = NULL; + Eina_List *l, *copy; + Evas_Event_Multi_Move ev; + Evas_Object *obj; + + ev.device = d; + ev.cur.output.x = x; + ev.cur.output.y = y; + ev.cur.canvas.x = x; + ev.cur.canvas.y = y; + ev.radius = rad; + ev.radius_x = radx; + ev.radius_y = rady; + ev.data = (void *)data; + ev.modifiers = &(e->modifiers); + ev.locks = &(e->locks); + ev.timestamp = timestamp; + ev.event_flags = EVAS_EVENT_FLAG_NONE; + + copy = evas_event_list_copy(e->pointer.object.in); + EINA_LIST_FOREACH(copy, l, obj) + { + if ((obj->cur.visible) && + (evas_object_clippers_is_visible(obj)) && + (!evas_event_passes_through(obj)) && + (!obj->clip.clipees)) + { + ev.cur.canvas.x = e->pointer.x; + ev.cur.canvas.y = e->pointer.y; + _evas_event_havemap_adjust(obj, &ev.cur.canvas.x, &ev.cur.canvas.y); + if (e->events_frozen <= 0) + evas_object_event_callback_call(obj, EVAS_CALLBACK_MULTI_MOVE, &ev); + } + if (e->delete_me) break; + } + } + else + { + Eina_List *ins; + Eina_List *l, *copy; + Evas_Event_Multi_Move ev; + Evas_Object *obj; + + ev.device = d; + ev.cur.output.x = x; + ev.cur.output.y = y; + ev.cur.canvas.x = x; + ev.cur.canvas.y = y; + ev.radius = rad; + ev.radius_x = radx; + ev.radius_y = rady; + ev.data = (void *)data; + ev.modifiers = &(e->modifiers); + ev.locks = &(e->locks); + ev.timestamp = timestamp; + ev.event_flags = EVAS_EVENT_FLAG_NONE; + + /* get all new in objects */ + ins = evas_event_objects_event_list(e, NULL, x, y); + /* go thru old list of in objects */ + copy = evas_event_list_copy(e->pointer.object.in); + EINA_LIST_FOREACH(copy, l, obj) + { + /* if its under the pointer and its visible and its in the new */ + /* in list */ +// FIXME: i don't think we need this +// evas_object_clip_recalc(obj); + if (evas_object_is_in_output_rect(obj, x, y, 1, 1) && + (obj->cur.visible) && + (evas_object_clippers_is_visible(obj)) && + (eina_list_data_find(ins, obj)) && + (!evas_event_passes_through(obj)) && + (!obj->clip.clipees) && + ((!obj->precise_is_inside) || + (evas_object_is_inside(obj, x, y)))) + { + ev.cur.canvas.x = x; + ev.cur.canvas.y = y; + _evas_event_havemap_adjust(obj, &ev.cur.canvas.x, &ev.cur.canvas.y); + if (e->events_frozen <= 0) + evas_object_event_callback_call(obj, EVAS_CALLBACK_MULTI_MOVE, &ev); + } + if (e->delete_me) break; + } + if (copy) copy = eina_list_free(copy); + /* free our old list of ins */ + eina_list_free(e->pointer.object.in); + /* and set up the new one */ + e->pointer.object.in = ins; + } + _evas_unwalk(e); +} + /** * Key down event feed * -- 2.7.4