Index: configure.ac
===================================================================
--- configure.ac	(revision 79436)
+++ configure.ac	(working copy)
@@ -1170,6 +1170,7 @@ if ! test "x$have_ecore_x_xcb" = "xyes" ; then
     ECORE_CHECK_X_EXTENSION([Xtest], [XTest.h], [Xtst], [XTestFakeKeyEvent], [$want_ecore_x_xtest])
     ECORE_CHECK_X_EXTENSION([Xss], [scrnsaver.h], [Xss], [XScreenSaverSelectInput], [$want_ecore_x_screensaver])
     ECORE_CHECK_X_EXTENSION([Xi2], [XInput2.h], [Xi], [XIQueryDevice], [$want_ecore_x_input])
+    ECORE_CHECK_X_EXTENSION([Xi2_2], [XInput2.h], [Xi], [XIGrabTouchBegin], [$want_ecore_x_input])
 
     ecore_x_libs_private="${Xcursor_libs} ${XKB_LIBS} ${XCOMPOSITE_LIBS} ${XGESTURE_LIBS} ${XDAMAGE_LIBS} ${XDPMS_LIBS} ${XFIXES_LIBS} ${XINERAMA_LIBS} ${XPRINT_LIBS} ${XRANDR_LIBS} ${XRENDER_LIBS} ${XTEST_LIBS} ${XSS_LIBS} ${XI2_LIBS}"
 
@@ -2129,6 +2130,7 @@ if test "x$have_ecore_x" = "xyes" ; then
     echo "    Xtest......................: $use_xtest"
     echo "    XIM........................: $want_xim"
     echo "    Xi2........................: $use_xi2"
+    echo "    Xi2.2......................: $use_xi22"
   fi
 else
   echo "  Ecore_X......................: $have_ecore_x"
Index: src/lib/ecore_x/xlib/ecore_x_xi2.c
===================================================================
--- src/lib/ecore_x/xlib/ecore_x_xi2.c	(revision 79436)
+++ src/lib/ecore_x/xlib/ecore_x_xi2.c	(working copy)
@@ -21,6 +21,9 @@ int _ecore_x_xi2_opcode = -1;
 #ifdef ECORE_XI2
 static XIDeviceInfo *_ecore_x_xi2_devs = NULL;
 static int _ecore_x_xi2_num = 0;
+#ifdef ECORE_XI2_2
+static  Ecore_X_Touch_Device_Info *_ecore_x_xi2_touch = NULL;
+#endif /* ifdef ECORE_XI2_2 */
 #endif /* ifdef ECORE_XI2 */
 
 void
@@ -28,7 +31,7 @@ _ecore_x_input_init(void)
 {
 #ifdef ECORE_XI2
    int event, error;
-   int major = 2, minor = 0;
+   int major = XI_2_Major, minor = XI_2_Minor;
 
    if (!XQueryExtension(_ecore_x_disp, "XInputExtension",
                         &_ecore_x_xi2_opcode, &event, &error))
@@ -63,6 +66,124 @@ _ecore_x_input_shutdown(void)
 #endif /* ifdef ECORE_XI2 */
 }
 
+#ifdef ECORE_XI2
+#ifdef ECORE_XI2_2
+static int
+_ecore_x_input_touch_index_get(int devid, int detail, int event_type)
+{
+   int i;
+   Ecore_X_Touch_Device_Info *touchdev;
+   Eina_Bool find = EINA_FALSE;
+
+   if (!_ecore_x_xi2_devs || !_ecore_x_xi2_touch)
+     return 0;
+
+   touchdev = _ecore_x_xi2_touch;
+
+   while (touchdev)
+     {
+        if (touchdev->devid == devid)
+          {
+             find = EINA_TRUE;
+             break;
+          }
+
+        if (touchdev->next) touchdev = touchdev->next;
+        else break;
+     }
+
+   if (EINA_TRUE != find || !touchdev->slot)
+     return 0;
+
+   for (i = 0; i < touchdev->max_touch ; i++)
+     {
+        int *p = &(touchdev->slot[i]);
+
+        if ((event_type == XI_TouchBegin) && (*p < 0))
+          {
+             *p = detail;
+             return i;
+          }
+
+        if (*p == detail)
+          return i;
+     }
+
+   return 0;
+}
+
+static void
+_ecore_x_input_touch_index_clear(int devid, int idx)
+{
+   Ecore_X_Touch_Device_Info *touchdev;
+
+   if (!_ecore_x_xi2_devs || !_ecore_x_xi2_touch)
+     return;
+
+   touchdev = _ecore_x_xi2_touch;
+
+   while (touchdev)
+     {
+        if (touchdev->devid == devid && touchdev->slot)
+          {
+             touchdev->slot[idx] = -1;
+             return;
+          }
+
+        if (touchdev->next) touchdev = touchdev->next;
+        else return;
+     }
+}
+
+static Ecore_X_Touch_Device_Info* _ecore_x_input_touch_info_get(XIDeviceInfo* dev)
+{
+   int k;
+   XITouchClassInfo *t = NULL;
+   Ecore_X_Touch_Device_Info *touchdev = NULL;
+
+   if (!dev)
+     return NULL;
+
+   for (k = 0; k < dev->num_classes; k++)
+     {
+        XIAnyClassInfo *class = dev->classes[k];
+
+        if (class && (class->type == XITouchClass))
+          {
+             t = (XITouchClassInfo*)class;
+             break;
+          }
+     }
+
+   if (t && (t->type == XITouchClass))
+     {
+        touchdev = calloc(1, sizeof(Ecore_X_Touch_Device_Info));
+
+        if(touchdev)
+          {
+             touchdev->devid = dev->deviceid;							
+             touchdev->max_touch = t->num_touches +1;
+             touchdev->mode = t->mode;
+             touchdev->name = dev->name;
+             touchdev->next = NULL;
+             touchdev->slot = (int*)malloc(sizeof(int)*touchdev->max_touch);
+
+             if (!touchdev->slot)
+               {
+                  free(touchdev);
+                  touchdev = NULL;
+                  return touchdev;
+               }
+
+             memset(touchdev->slot, -1, sizeof(int)*touchdev->max_touch);
+          }
+     }
+
+   return touchdev;
+}
+#endif /* ifdef ECORE_XI2_2 */
+#endif
+
 void
 _ecore_x_input_handler(XEvent *xevent)
 {
@@ -165,6 +286,9 @@ _ecore_x_input_handler(XEvent *xevent)
 
 #ifdef XI_TouchUpdate
       case XI_TouchUpdate:
+#ifdef ECORE_XI2_2
+        i = _ecore_x_input_touch_index_get(devid, evd->detail, XI_TouchUpdate);
+#endif /* #ifdef ECORE_XI2_2 */
         _ecore_mouse_move
           (evd->time,
           0,   // state
@@ -174,16 +298,23 @@ _ecore_x_input_handler(XEvent *xevent)
           (evd->child ? evd->child : evd->event),
           evd->root,
           1,   // same_screen
+#ifdef ECORE_XI2_2
+          i, 1, 1,
+#else
           devid, 1, 1,
+#endif /* #ifdef ECORE_XI2_2 */
           1.0,   // pressure
           0.0,   // angle
           evd->event_x, evd->event_y,
           evd->root_x, evd->root_y);
         break;
+#endif
 
-#endif
 #ifdef XI_TouchBegin
       case XI_TouchBegin:
+#ifdef ECORE_XI2_2
+        i = _ecore_x_input_touch_index_get(devid, evd->detail, XI_TouchBegin);
+#endif /* #ifdef ECORE_XI2_2 */
         _ecore_mouse_button
           (ECORE_EVENT_MOUSE_BUTTON_DOWN,
           evd->time,
@@ -195,16 +326,23 @@ _ecore_x_input_handler(XEvent *xevent)
           (evd->child ? evd->child : evd->event),
           evd->root,
           1,   // same_screen
+#ifdef ECORE_XI2_2
+          i, 1, 1,
+#else
           devid, 1, 1,
+#endif /* #ifdef ECORE_XI2_2 */
           1.0,   // pressure
           0.0,   // angle
           evd->event_x, evd->event_y,
           evd->root_x, evd->root_y);
         break;
+#endif
 
-#endif
 #ifdef XI_TouchEnd
       case XI_TouchEnd:
+#ifdef ECORE_XI2_2
+        i = _ecore_x_input_touch_index_get(devid, evd->detail, XI_TouchEnd);
+#endif /* #ifdef ECORE_XI2_2 */
         _ecore_mouse_button
           (ECORE_EVENT_MOUSE_BUTTON_UP,
           evd->time,
@@ -216,14 +354,21 @@ _ecore_x_input_handler(XEvent *xevent)
           (evd->child ? evd->child : evd->event),
           evd->root,
           1,   // same_screen
+#ifdef ECORE_XI2_2
+          i, 1, 1,
+#else
           devid, 1, 1,
+#endif /* #ifdef ECORE_XI2_2 */
           1.0,   // pressure
           0.0,   // angle
           evd->event_x, evd->event_y,
           evd->root_x, evd->root_y);
+#ifdef ECORE_XI2_2
+        _ecore_x_input_touch_index_clear(devid,  i);
+#endif /* #ifdef ECORE_XI2_2 */
         break;
+#endif
 
-#endif
       default:
         break;
      }
@@ -281,6 +426,33 @@ ecore_x_input_multi_select(Ecore_X_Window win)
                   XISetMask(mask, XI_ButtonPress);
                   XISetMask(mask, XI_ButtonRelease);
                   XISetMask(mask, XI_Motion);
+#ifdef ECORE_XI2_2
+                  Ecore_X_Touch_Device_Info *touchdev;
+                  touchdev = _ecore_x_input_touch_info_get(dev);
+
+                  if (touchdev)
+                    {
+                       XISetMask(mask, XI_TouchUpdate);
+                       XISetMask(mask, XI_TouchBegin);
+                       XISetMask(mask, XI_TouchEnd);
+
+                       if (_ecore_x_xi2_touch)
+                         {
+                            Ecore_X_Touch_Device_Info *last = _ecore_x_xi2_touch;
+
+                            while (last)
+                              {
+                                 if (last->next) last = last->next;
+                                 else break;
+                              }
+                            last->next = touchdev;
+                         }
+                       else
+                         {
+                            _ecore_x_xi2_touch = touchdev;
+                         }
+                    }
+#else
 # ifdef XI_TouchUpdate
                   XISetMask(mask, XI_TouchUpdate);
 # endif
@@ -290,9 +462,51 @@ ecore_x_input_multi_select(Ecore_X_Window win)
 # ifdef XI_TouchEnd
                   XISetMask(mask, XI_TouchEnd);
 # endif
+#endif /* #ifdef ECORE_XI2_2 */
+
                   XISelectEvents(_ecore_x_disp, win, &eventmask, 1);
                   find = EINA_TRUE;
                }
+#ifdef ECORE_XI2_2
+             else if ((atdev) && (atdev->use == XIMasterPointer))
+               {
+                  Ecore_X_Touch_Device_Info *touchdev;
+                  touchdev = _ecore_x_input_touch_info_get(dev);
+
+                  if (touchdev)
+                    {
+                       XIEventMask eventmask;
+                       unsigned char mask[4] = { 0 };
+
+                       eventmask.deviceid = dev->deviceid;
+                       eventmask.mask_len = sizeof(mask);
+                       eventmask.mask = mask;
+
+                       XISetMask(mask, XI_TouchUpdate);
+                       XISetMask(mask, XI_TouchBegin);
+                       XISetMask(mask, XI_TouchEnd);
+
+                       XISelectEvents(_ecore_x_disp, win, &eventmask, 1);
+
+                       if (_ecore_x_xi2_touch)
+                         {
+                            Ecore_X_Touch_Device_Info *last = _ecore_x_xi2_touch;
+
+                            while (last)
+                              {
+                                 if (last->next) last = last->next;
+                                 else break;
+                              }
+                            last->next = touchdev;
+                         }
+                       else
+                         {
+                            _ecore_x_xi2_touch = touchdev;
+                         }
+                       find = EINA_TRUE;
+                    }
+               }
+#endif /* #ifdef ECORE_XI2_2 */
           }
      }
 
Index: src/lib/ecore_x/xlib/ecore_x_private.h
===================================================================
--- src/lib/ecore_x/xlib/ecore_x_private.h	(revision 79436)
+++ src/lib/ecore_x/xlib/ecore_x_private.h	(working copy)
@@ -182,6 +182,18 @@ typedef struct _Ecore_X_DND_Target
    int          will_accept;
 } Ecore_X_DND_Target;
 
+#ifdef ECORE_XI2_2
+typedef struct _Ecore_X_Touch_Device_Info
+{
+    int                               devid;
+    int                               mode;
+    const char                        *name;
+    int                               max_touch;
+    int                               *slot;
+    struct _Ecore_X_Touch_Device_Info *next;
+} Ecore_X_Touch_Device_Info;
+#endif /* ifdef ECORE_XI2_2 */
+
 extern Display *_ecore_x_disp;
 extern double _ecore_x_double_click_time;
 extern Time _ecore_x_event_last_time;
