Index: src/lib/include/evas_private.h
===================================================================
--- src/lib/include/evas_private.h	(revision 63404)
+++ src/lib/include/evas_private.h	(working copy)
@@ -377,6 +377,8 @@ struct _Evas
    unsigned char  invalidate : 1;
    unsigned char  cleanup : 1;
    unsigned char  focus : 1;
+
+   Eina_List     *touch_points;
 };
 
 struct _Evas_Layer
@@ -1004,6 +1006,11 @@ void evas_render_object_recalc(Evas_Object *obj);
 Eina_Bool evas_map_inside_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y);
 Eina_Bool evas_map_coords_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y, Evas_Coord *mx, Evas_Coord *my, int grab);
 
+/* for touch event */
+void _evas_event_touch_down(Evas *e, Evas_Coord x, Evas_Coord y, int id, unsigned int timestamp);
+void _evas_event_touch_up(Evas *e, Evas_Coord x, Evas_Coord y, int id, unsigned int timestamp);
+void _evas_event_touch_move(Evas *e, Evas_Coord x, Evas_Coord y, int id, unsigned int timestamp);
+
 /****************************************************************************/
 /*****************************************/
 /********************/
Index: src/lib/Evas.h
===================================================================
--- src/lib/Evas.h	(revision 63404)
+++ src/lib/Evas.h	(working copy)
@@ -430,6 +430,7 @@ typedef enum _Evas_Callback_Type
     * More Evas object event types - see evas_object_event_callback_add():
     */
    EVAS_CALLBACK_IMAGE_UNLOADED, /**< Image data has been unloaded (by some mechanims in Evas that throw out original image data) */
+   EVAS_CALLBACK_TOUCH, /**< Touch Event */
 
    EVAS_CALLBACK_LAST /**< kept as last element/sentinel -- not really an event */
 } Evas_Callback_Type; /**< The types of events triggering a callback */
@@ -488,6 +489,29 @@ typedef enum _Evas_Event_Flags
 } Evas_Event_Flags; /**< Flags for Events */
 
 /**
+ * State of Evas_Coord_Touch_Point
+ */
+typedef enum _Evas_Touch_Point_State
+{
+   EVAS_TOUCH_POINT_RELEASED, /**< Touch point is released */
+   EVAS_TOUCH_POINT_PRESSED, /**< Touch point is pressed */
+   EVAS_TOUCH_POINT_MOVED, /**< Touch point is moved */
+   EVAS_TOUCH_POINT_STATIONARY, /**< Touch point is not moved after pressed */
+   EVAS_TOUCH_POINT_CANCELLED /**< Touch point is calcelled */
+} Evas_Touch_Point_State;
+
+/**
+ * Types for Evas_Touch_Event
+ */
+typedef enum _Evas_Event_Touch_Type
+{
+   EVAS_EVENT_TOUCH_START, /**< Start touch event with pressed new touch point */
+   EVAS_EVENT_TOUCH_END, /**< End touch event with released touch point */
+   EVAS_EVENT_TOUCH_MOVE, /**< Any touch point in the touch_points list is moved */
+   EVAS_EVENT_TOUCH_CANCEL /**< Touch event is cancelled */
+} Evas_Event_Touch_Type;
+
+/**
  * Flags for Font Hinting
  * @ingroup Evas_Font_Group
  */
@@ -534,6 +558,7 @@ typedef struct _Evas_Point                   Evas_
 
 typedef struct _Evas_Coord_Point             Evas_Coord_Point;  /**< Evas_Coord point */
 typedef struct _Evas_Coord_Precision_Point   Evas_Coord_Precision_Point; /**< Evas_Coord point with sub-pixel precision */
+typedef struct _Evas_Coord_Touch_Point       Evas_Coord_Touch_Point; /**< Evas_Coord point with touch type and id */
 
 typedef struct _Evas_Position                Evas_Position; /**< associates given point in Canvas and Output */
 typedef struct _Evas_Precision_Position      Evas_Precision_Position; /**< associates given point in Canvas and Output, with sub-pixel precision */
@@ -623,6 +648,13 @@ struct _Evas_Coord_Precision_Point
    double xsub, ysub;
 };
 
+struct _Evas_Coord_Touch_Point
+{
+   Evas_Coord x, y;
+   int id; /**< id in order to distinguish each point */
+   Evas_Touch_Point_State state;
+};
+
 struct _Evas_Position
 {
     Evas_Point output;
@@ -659,6 +691,7 @@ typedef struct _Evas_Event_Multi_Move Evas_Event_M
 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 */
+typedef struct _Evas_Event_Touch      Evas_Event_Touch; /**< Event structure for #EVAS_CALLBACK_TOUCH event callbacks */
 
 typedef enum _Evas_Load_Error
 {
@@ -995,6 +1028,14 @@ struct _Evas_Event_Hold /** Hold change event */
    Evas_Device      *dev;
 };
 
+struct _Evas_Event_Touch /** Touch event */
+{
+   Eina_List            *points; /**< Evas_Coord_Touch_Point list */
+   Evas_Modifier        *modifiers;
+   unsigned int          timestamp;
+   Evas_Event_Touch_Type type; /**< Type for Evas_Event_Touch */
+};
+
 /**
  * How the mouse pointer should be handled by Evas.
  *
Index: src/lib/canvas/evas_events.c
===================================================================
--- src/lib/canvas/evas_events.c	(revision 63404)
+++ src/lib/canvas/evas_events.c	(working copy)
@@ -267,6 +267,9 @@ evas_event_feed_mouse_down(Evas *e, int b, Evas_Bu
    e->last_mouse_down_counter++;
    _evas_post_event_callback_call(e);
    _evas_unwalk(e);
+
+   /* process mouse down for touch */
+   _evas_event_touch_down(e, e->pointer.x, e->pointer.y, 0, timestamp);
 }
 
 static int
@@ -452,6 +455,9 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Butt
      }
  */
    _evas_unwalk(e);
+
+   /* process mouse up for touch */
+   _evas_event_touch_up(e, e->pointer.x, e->pointer.y, 0, timestamp);
 }
 
 EAPI void
@@ -768,6 +774,9 @@ evas_event_feed_mouse_move(Evas *e, int x, int y,
         _evas_post_event_callback_call(e);
      }
    _evas_unwalk(e);
+
+   /* process mouse move for touch */
+   _evas_event_touch_move(e, e->pointer.x, e->pointer.y, 0, timestamp);
 }
 
 EAPI void
@@ -954,6 +963,9 @@ evas_event_feed_multi_down(Evas *e,
    if (copy) eina_list_free(copy);
    _evas_post_event_callback_call(e);
    _evas_unwalk(e);
+
+   /* process multi down for touch */
+   _evas_event_touch_down(e, x, y, d, timestamp);
 }
 
 EAPI void
@@ -1024,6 +1036,9 @@ evas_event_feed_multi_up(Evas *e,
    if ((e->pointer.mouse_grabbed == 0) && !_post_up_handle(e, timestamp, data))
       _evas_post_event_callback_call(e);
    _evas_unwalk(e);
+
+   /* process multi up for touch */
+   _evas_event_touch_up(e, x, y, d, timestamp);
 }
 
 EAPI void
@@ -1172,6 +1187,9 @@ evas_event_feed_multi_move(Evas *e,
         _evas_post_event_callback_call(e);
      }
    _evas_unwalk(e);
+
+   /* process multi move for touch */
+   _evas_event_touch_move(e, x, y, d, timestamp);
 }
 
 EAPI void
Index: src/lib/canvas/evas_main.c
===================================================================
--- src/lib/canvas/evas_main.c	(revision 63404)
+++ src/lib/canvas/evas_main.c	(working copy)
@@ -143,6 +143,7 @@ EAPI void
 evas_free(Evas *e)
 {
    Eina_Rectangle *r;
+   Evas_Coord_Touch_Point *touch_point;
    Evas_Layer *lay;
    int i;
    int del;
@@ -249,6 +250,9 @@ evas_free(Evas *e)
    eina_array_flush(&e->calculate_objects);
    eina_array_flush(&e->clip_changes);
 
+   EINA_LIST_FREE(e->touch_points, touch_point)
+     free(touch_point);
+
    eina_list_free(e->calc_list);
    
    e->magic = 0;
Index: src/lib/canvas/evas_touch_events.c
===================================================================
--- src/lib/canvas/evas_touch_events.c	(revision 0)
+++ src/lib/canvas/evas_touch_events.c	(revision 0)
@@ -0,0 +1,127 @@
+#include "evas_common.h"
+#include "evas_private.h"
+
+static void
+_evas_touch_point_append(Evas *e, int id, int x, int y)
+{
+   Evas_Coord_Touch_Point *point;
+
+   /* create new Evas_Coord_Touch_Point */
+   point = (Evas_Coord_Touch_Point *)calloc(1, sizeof(Evas_Coord_Touch_Point));
+   point->x = x;
+   point->y = y;
+   point->id = id;
+   point->state = EVAS_TOUCH_POINT_PRESSED;
+
+   _evas_walk(e);
+   e->touch_points = eina_list_append(e->touch_points, point);
+   _evas_unwalk(e);
+}
+
+static Evas_Coord_Touch_Point *
+_evas_touch_point_update(Evas *e, int id, int x, int y, Evas_Touch_Point_State state)
+{
+   Eina_List *l;
+   Evas_Coord_Touch_Point *point = NULL;
+
+   _evas_walk(e);
+   EINA_LIST_FOREACH(e->touch_points, l, point)
+     {
+        if (point->id == id)
+          {
+             point->x = x;
+             point->y = y;
+             point->state = state;
+             break;
+          }
+     }
+   _evas_unwalk(e);
+
+   return point;
+}
+
+static void
+_evas_event_feed_touch(Evas *e, unsigned int timestamp, Evas_Event_Touch_Type type)
+{
+   Evas_Event_Touch ev;
+   Eina_List *l, *copy;
+   Evas_Coord_Touch_Point *point;
+   Evas_Object *obj;
+   const void *data;
+
+   _evas_walk(e);
+   /* set Evas_Event_Touch's members */
+   ev.points = NULL;
+   EINA_LIST_FOREACH(e->touch_points, l, point)
+     ev.points = eina_list_append(ev.points, point);
+   ev.modifiers = &(e->modifiers);
+   ev.timestamp = timestamp;
+   ev.type = type;
+
+   /* make copy of object list */
+   copy = NULL;
+   EINA_LIST_FOREACH(e->pointer.object.in, l, data)
+     copy = eina_list_append(copy, data);
+
+   /* call all EVAS_CALLBACK_TOUCH's callbacks */
+   EINA_LIST_FOREACH(copy, l, obj)
+     {
+        if (!obj->delete_me && (e->events_frozen <= 0))
+           evas_object_event_callback_call(obj, EVAS_CALLBACK_TOUCH, &ev);
+        if (e->delete_me) break;
+     }
+   if (copy) eina_list_free(copy);
+   if (ev.points) eina_list_free(ev.points);
+
+   /* if finger is released or pressed, reset all touch point's state */
+   if (type != EVAS_EVENT_TOUCH_MOVE)
+     {
+        EINA_LIST_FOREACH(e->touch_points, l, point)
+          point->state = EVAS_TOUCH_POINT_STATIONARY;
+     }
+   _evas_unwalk(e);
+}
+
+void
+_evas_event_touch_down(Evas *e, Evas_Coord x, Evas_Coord y, int id, unsigned int timestamp)
+{
+   _evas_touch_point_append(e, id, x, y);
+   _evas_event_feed_touch(e, timestamp, EVAS_EVENT_TOUCH_START);
+}
+
+void
+_evas_event_touch_up(Evas *e, Evas_Coord x, Evas_Coord y, int id, unsigned int timestamp)
+{
+   Evas_Coord_Touch_Point *point;
+
+   /* update touch point in the touch_points list */
+   point = _evas_touch_point_update(e, id, x, y, EVAS_TOUCH_POINT_RELEASED);
+   if (!point) return;
+
+   _evas_walk(e);
+   _evas_event_feed_touch(e, timestamp, EVAS_EVENT_TOUCH_END);
+   e->touch_points = eina_list_remove(e->touch_points, point);
+   _evas_unwalk(e);
+}
+
+void
+_evas_event_touch_move(Evas *e, Evas_Coord x, Evas_Coord y, int id, unsigned int timestamp)
+{
+   Eina_List *l;
+   Evas_Coord_Touch_Point *point;
+
+   _evas_walk(e);
+   EINA_LIST_FOREACH(e->touch_points, l, point)
+     {
+        if (point->id == id)
+          {
+             /* update touch point */
+             point->x = x;
+             point->y = y;
+             point->state = EVAS_TOUCH_POINT_MOVED;
+
+             _evas_event_feed_touch(e, timestamp, EVAS_EVENT_TOUCH_MOVE);
+          }
+     }
+   _evas_unwalk(e);
+}
Index: src/lib/canvas/Makefile.am
===================================================================
--- src/lib/canvas/Makefile.am	(revision 63404)
+++ src/lib/canvas/Makefile.am	(working copy)
@@ -51,6 +51,7 @@ evas_smart.c \
 evas_stack.c \
 evas_async_events.c \
 evas_stats.c \
+evas_touch_events.c \
 evas_map.c \
 evas_gl.c
 
Index: src/lib/canvas/evas_callbacks.c
===================================================================
--- src/lib/canvas/evas_callbacks.c	(revision 63404)
+++ src/lib/canvas/evas_callbacks.c	(working copy)
@@ -249,7 +249,7 @@ evas_object_event_callback_call(Evas_Object *obj,
 	if (!obj->no_propagate)
 	  {
 	     if ((obj->smart.parent) && (type != EVAS_CALLBACK_FREE) &&
-		 (type <= EVAS_CALLBACK_KEY_UP))
+                 ((type <= EVAS_CALLBACK_KEY_UP) || (type == EVAS_CALLBACK_TOUCH)))
 	       evas_object_event_callback_call(obj->smart.parent, type, event_info);
 	  }
      }
