merge with master 30/9030/1
authorJinkun Jang <jinkun.jang@samsung.com>
Fri, 15 Mar 2013 16:03:35 +0000 (01:03 +0900)
committerBoram Park <boram1288.park@samsung.com>
Mon, 2 Sep 2013 08:05:41 +0000 (17:05 +0900)
Change-Id: I971414baf5cccf8dcfa0ae027451164975bf27d1

packaging/xorg-x11-drv-gesture.spec
src/gesture.c
src/gesture.h

index 0787892..288a6ad 100644 (file)
@@ -2,7 +2,7 @@
 Name:  xorg-x11-drv-gesture
 Summary:    X.Org X server -- Xserver gesture driver
 Version: 0.1.2
-Release:    2
+Release:    6
 Group:      System/X Hardware Support
 License:    MIT
 Source0:    %{name}-%{version}.tar.gz
@@ -32,9 +32,8 @@ xorg-x11-drv-gesture development files
 
 %build
 
-autoreconf -vfi
-./configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
-#./configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info CFLAGS="$CFLAGS -D__DETAIL_DEBUG__ -D__DEBUG_EVENT_HANDLER__ " LDFLAGS="$LDFLAGS"
+%autogen -ivf
+%configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
 
 make %{?jobs:-j%jobs}
 
index a483b7f..bcf0a2e 100755 (executable)
@@ -33,6 +33,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "config.h"
 #endif
 
+#include <xorg/inputstr.h>
 #include <linux/input.h>
 #include <linux/types.h>
 
@@ -73,7 +74,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <xorg/mi.h>
 
 //Basic functions
-static InputInfoPtr GesturePreInit(InputDriverPtr  drv, InputInfoPtr pInfo, int flags);
+static int GesturePreInit(InputDriverPtr  drv, InputInfoPtr pInfo, int flags);
 static void GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
 static pointer GesturePlug(pointer module, pointer options, int *errmaj, int  *errmin);
 static void GestureUnplug(pointer p);
@@ -94,8 +95,12 @@ void GestureEventsDrop(void);
 
 //utility functions
 ErrorStatus GestureRegionsReinit(void);
-void GestureSetDisable(InputInfoPtr pInfo, int enable);
+void GestureEnable(int enable, Bool prop, DeviceIntPtr dev);
+static inline void GestureEnableDisable();
+void GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent);
+void GestureCbEventsSelected(Window win, Mask *pEventMask);
 WindowPtr GestureGetEventsWindow(void);
+static uint32_t GestureTouchFindDDXIDByTouchID(DeviceIntPtr device, uint32_t touchid);
 
 //Enqueued event handlers and enabler/disabler
 static ErrorStatus GestureEnableEventHandler(InputInfoPtr pInfo);
@@ -103,9 +108,9 @@ static ErrorStatus GestureDisableEventHandler(void);
 static CARD32 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
 static CARD32 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
 void GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
-void GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
-void GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
-void GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+void GestureHandleTouchBeginEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+void GestureHandleTouchUpdateEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+void GestureHandleTouchEndEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
 
 //Gesture recognizer helper
 static Bool PointInBorderSize(WindowPtr pWin, int x, int y);
@@ -126,7 +131,7 @@ void GestureHandleGesture_PinchRotation(int num_of_fingers, double zoom, double
 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds);
 void GestureHandleGesture_TapNHold(int num_fingers, int cx, int cy, Time interval, Time holdtime, int kinds);
 void GestureHandleGesture_Pan(int num_fingers, short int dx, short int dy, int direction, int distance, Time duration, int kinds);
-void GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device);
+void GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device, int idx);
 ErrorStatus GestureFlushOrDrop(void);
 
 #ifdef HAVE_PROPERTIES
@@ -637,7 +642,7 @@ GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr de
 
        switch( type )
        {
-               case ET_ButtonPress:
+               case ET_TouchBegin:
                        g_pGesture->fingers[idx].flags |= PressFlagPinchRotation;
 
                        if( g_pGesture->num_pressed < 2 )
@@ -683,7 +688,7 @@ GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr de
 #endif//__DETAIL_DEBUG__
                        break;
 
-               case ET_Motion:
+               case ET_TouchUpdate:
                        if( !(g_pGesture->fingers[idx].flags & PressFlagPinchRotation) )
                                break;
 
@@ -796,7 +801,7 @@ gesture_begin_handle:
                        }
                        break;
 
-               case ET_ButtonRelease:
+               case ET_TouchEnd:
                        if( state != GestureEnd && num_pressed >= 2)
                        {
 #ifdef __DETAIL_DEBUG__
@@ -833,7 +838,7 @@ cleanup_pinchrotation:
 
        if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
        {
-#if 1//def __DETAIL_DEBUG__
+#ifdef __DETAIL_DEBUG__
                ErrorF("[GroupPinchRotation][cleanup] GestureFlushOrDrop() !\n");
 #endif//__DETAIL_DEBUG__
 
@@ -869,7 +874,7 @@ GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, in
 
        switch( type )
        {
-               case ET_ButtonPress:
+               case ET_TouchBegin:
                        g_pGesture->fingers[idx].flags |= PressFlagFlick;
 
                        if( g_pGesture->num_pressed < 2 )
@@ -889,7 +894,7 @@ GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, in
 #endif//__DETAIL_DEBUG__
                        break;
 
-               case ET_Motion:
+               case ET_TouchUpdate:
                        if( !(g_pGesture->fingers[idx].flags & PressFlagFlick ) )
                                break;
 
@@ -931,7 +936,7 @@ GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, in
                        }
                        break;
 
-               case ET_ButtonRelease:
+               case ET_TouchEnd:
                        if( g_pGesture->num_pressed )
                                break;
 
@@ -1032,7 +1037,7 @@ GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int
 
        switch( type )
        {
-               case ET_ButtonPress:
+               case ET_TouchBegin:
                        g_pGesture->fingers[idx].flags |= PressFlagPan;
 
                        if( g_pGesture->num_pressed < 2 )
@@ -1065,7 +1070,7 @@ GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int
 #endif//__DETAIL_DEBUG__
                        break;
 
-               case ET_Motion:
+               case ET_TouchUpdate:
                        if( !(g_pGesture->fingers[idx].flags & PressFlagPan ) )
                                break;
 
@@ -1101,6 +1106,7 @@ GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int
 
                                cx = AREA_CENTER_X(&g_pGesture->area.extents);
                                cy = AREA_CENTER_Y(&g_pGesture->area.extents);
+
 #ifdef __DETAIL_DEBUG__
                                ErrorF("[GroupPan][M] cx=%d, prev_cx=%d, diff=%d\n", cx, prev_cx, ABS(cx-prev_cx));
                                ErrorF("[GroupPan][M] cy=%d, prev_cy=%d, diff=%d\n", cy, prev_cy, ABS(cy-prev_cy));
@@ -1143,7 +1149,7 @@ GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int
                        }
                        break;
 
-               case ET_ButtonRelease:
+               case ET_TouchEnd:
                        if( state != GestureEnd && num_pressed >= 2)
                        {
 #ifdef __DETAIL_DEBUG__
@@ -1231,7 +1237,7 @@ GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int
                                if( num_pressed )
                                {
 #ifdef __DETAIL_DEBUG__
-                                       ErrorF("[GroupTap][Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", tap_repeat, num_pressed, tap_repeat);
+                                       ErrorF("[GroupTap][Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", num_pressed, tap_repeat);
 #endif//__DETAIL_DEBUG__
                                        state = 0;
                                        goto cleanup_tap;
@@ -1262,7 +1268,7 @@ GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int
 
        switch( type )
        {
-               case ET_ButtonPress:
+               case ET_TouchBegin:
                        g_pGesture->fingers[idx].flags |= PressFlagTap;
 
                        if( g_pGesture->num_pressed < 2 )
@@ -1292,7 +1298,7 @@ GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int
 #endif//__DETAIL_DEBUG__
                        break;
 
-               case ET_Motion:
+               case ET_TouchUpdate:
                        if( !(g_pGesture->fingers[idx].flags & PressFlagTap ) )
                                break;
 
@@ -1337,7 +1343,7 @@ GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int
                        }
                        break;
 
-               case ET_ButtonRelease:
+               case ET_TouchEnd:
                        if( g_pGesture->num_pressed )
                                break;
 
@@ -1493,7 +1499,7 @@ GestureRecognize_GroupTapNHold(int type, InternalEvent *ev, DeviceIntPtr device,
 
        switch( type )
        {
-               case ET_ButtonPress:
+               case ET_TouchBegin:
                        g_pGesture->fingers[idx].flags |= PressFlagTapNHold;
 
                        if( g_pGesture->num_pressed < 2 )
@@ -1541,7 +1547,7 @@ GestureRecognize_GroupTapNHold(int type, InternalEvent *ev, DeviceIntPtr device,
 #endif//__DETAIL_DEBUG__
                        break;
 
-               case ET_Motion:
+               case ET_TouchUpdate:
                        if( !(g_pGesture->fingers[idx].flags & PressFlagTapNHold ) )
                                break;
 
@@ -1593,7 +1599,7 @@ GestureRecognize_GroupTapNHold(int type, InternalEvent *ev, DeviceIntPtr device,
                        }
                        break;
 
-               case ET_ButtonRelease:
+               case ET_TouchEnd:
                        if( state != GestureEnd && num_pressed >= 2)
                        {
 #ifdef __DETAIL_DEBUG__
@@ -1730,7 +1736,7 @@ void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device
 
        switch( type )
        {
-               case ET_ButtonPress:
+               case ET_TouchBegin:
                        g_pGesture->fingers[idx].flags |= PressFlagHold;
 
                        if( g_pGesture->num_pressed < 2 )
@@ -1764,7 +1770,7 @@ void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device
 #endif//__DETAIL_DEBUG__
                        break;
 
-               case ET_Motion:
+               case ET_TouchUpdate:
                        if( !(g_pGesture->fingers[idx].flags & PressFlagHold ) )
                                break;
 
@@ -1812,7 +1818,7 @@ void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device
                        }
                        break;
 
-               case ET_ButtonRelease:
+               case ET_TouchEnd:
                        if( state != GestureEnd && num_pressed >= 2)
                        {
 #ifdef __DETAIL_DEBUG__
@@ -1857,16 +1863,41 @@ cleanup_hold:
        return;
 }
 
+static inline void
+GestureEnableDisable()
+{
+       if((g_pGesture->grabMask) || (g_pGesture->lastSelectedWin != None))
+       {
+               GestureEnable(1, FALSE, g_pGesture->this_device);
+       }
+       else
+       {
+               GestureEnable(0, FALSE, g_pGesture->this_device);
+       }
+}
+
+void
+GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent)
+{
+       g_pGesture->grabMask = *pGrabMask;
+       g_pGesture->GrabEvents = pGrabEvent;
+       GestureEnableDisable();
+}
+
+void
+GestureCbEventsSelected(Window win, Mask *pEventMask)
+{
+       g_pGesture->lastSelectedWin = win;
+       g_pGesture->lastSelectedMask = (pEventMask) ? *pEventMask : 0;
+       GestureEnableDisable();
+}
+
 WindowPtr
 GestureGetEventsWindow(void)
 {
        Mask mask;
        WindowPtr pWin;
 
-       //check grabbed event(s)
-       if( !GestureHasGrabbedEvents(&g_pGesture->grabMask, &g_pGesture->GrabEvents) )
-               g_pGesture->grabMask = 0;
-
        pWin = GestureWindowOnXY(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py);
 
        if( pWin )
@@ -1884,21 +1915,35 @@ GestureGetEventsWindow(void)
                return NULL;
        }
 
+       if(g_pGesture->gestureWin == g_pGesture->lastSelectedWin)
+       {
+               g_pGesture->eventMask = g_pGesture->lastSelectedMask;
+               goto nonempty_eventmask;
+       }
+
        //check selected event(s)
        if( !GestureHasSelectedEvents(pWin, &g_pGesture->eventMask) )
+       {
                g_pGesture->eventMask = 0;
+       }
+       else
+       {
+               g_pGesture->lastSelectedWin = g_pGesture->gestureWin;
+               g_pGesture->lastSelectedMask = g_pGesture->eventMask;
+       }
 
-       if( !g_pGesture->grabMask && !g_pGesture->eventMask )
+       if((!g_pGesture->eventMask) && (!g_pGesture->grabMask))
        {
 #ifdef __DETAIL_DEBUG__
-               ErrorF("[X11][GestureGetEventsWindow] No events were grabbed/selected for window(0x%x) !\n", pWin->drawable.id);
+               ErrorF("[X11][GestureGetEventsWindow] No grabbed events or no events were selected for window(0x%x) !\n", pWin->drawable.id);
 #endif//__DETAIL_DEBUG__
                return NULL;
        }
 
+nonempty_eventmask:
+
 #ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureGetEventsWindow] g_pGesture->grabMask=0x%x, g_pGesture->eventMask=0x%x\n",
-                       g_pGesture->grabMask, g_pGesture->eventMask);
+       ErrorF("[X11][GestureGetEventsWindow] g_pGesture->eventMask=0x%x\n", g_pGesture->eventMask);
 #endif//__DETAIL_DEBUG__
 
        mask = (GESTURE_FILTER_MASK_ALL & ~(g_pGesture->grabMask | g_pGesture->eventMask));
@@ -1987,32 +2032,70 @@ GestureSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
        return 0;
 }
 
-void
-GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
+static uint32_t
+GestureTouchFindDDXIDByTouchID(DeviceIntPtr device, uint32_t touchid)
 {
        int i;
-       static OsTimerPtr single_finger_timer = NULL;
-       int idx = -1;
+       DDXTouchPointInfoPtr ti;
 
-       if( PROPAGATE_EVENTS == g_pGesture->ehtype ||
-               device->id < g_pGesture->first_fingerid )
-               return;
+       for( i = 0 ; i < g_pGesture->num_touches ; i++ )
+       {
+#ifdef __DETAIL_DEBUG__
+               ErrorF("[X11][GestureTouchFindDDXIDByTouchID][check existence] fingers[%d].touchid=%d, touchid=%d\n", i, g_pGesture->fingers[i].touchid, touchid);
+#endif//__DETAIL_DEBUG__
+
+               if(g_pGesture->fingers[i].touchid == touchid)
+               {
+#ifdef __DETAIL_DEBUG__
+                       ErrorF("[X11][GestureTouchFindDDXIDByTouchID][exist] ddx_id=%d was found !\n", i);
+#endif//__DETAIL_DEBUG__
+
+                       return (uint32_t)i;
+               }
+       }
 
-       for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
+       for( i = 0 ; i < device->last.num_touches ; i++)
        {
-               if( device->id == g_pGesture->mt_devices[i]->id )
+               ti = &device->last.touches[i];
+
+#ifdef __DETAIL_DEBUG__
+               ErrorF("[X11][GestureTouchFindDDXIDByTouchID][alloc new] i=%d, ti->client_id=%d, touchid=%d, ti->ddx_id=%d, ti->active=%d\n", i, ti->client_id, touchid, ti->ddx_id, ti->active);
+#endif//__DETAIL_DEBUG__
+
+               if(ti->client_id == touchid)
                {
-                       idx = i;
-                       break;
+#ifdef __DETAIL_DEBUG__
+                       ErrorF("[X11][GestureTouchFindDDXIDByTouchID][new] ddx_id=%d was found !\n", ti->ddx_id);
+#endif//__DETAIL_DEBUG__
+
+                       g_pGesture->fingers[ti->ddx_id].touchid = touchid;
+                       return ti->ddx_id;
                }
        }
 
-       if( idx < 0 )
+       return (uint32_t)-1;
+}
+
+void
+GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device, int idx)
+{
+       int i;
+       static OsTimerPtr single_finger_timer = NULL;
+
+#ifdef __DETAIL_DEBUG__
+       ErrorF("[X11][GestureRecognize] ev->any.type=%d, type=%d, device->id=%d\n", ev->any.type, type, device->id);
+#endif//__DETAIL_DEBUG__
+
+       if((PROPAGATE_EVENTS == g_pGesture->ehtype) || (device->id != g_pGesture->first_fingerid))
                return;
 
+#ifdef __DETAIL_DEBUG__
+       ErrorF("[X11][GestureRecognize] idx=%d\n", idx);
+#endif//__DETAIL_DEBUG__
+
        switch( type )
        {
-               case ET_ButtonPress:
+               case ET_TouchBegin:
                        if( idx == 0 )
                                g_pGesture->event_sum[0] = BTN_PRESSED;
                        g_pGesture->fingers[idx].ptime = ev->any.time;
@@ -2029,8 +2112,8 @@ GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
                                TimerCancel(single_finger_timer);
                        }
 
-                       if( g_pGesture->num_pressed > g_pGesture->num_mt_devices )
-                               g_pGesture->num_pressed = g_pGesture->num_mt_devices;
+                       if( g_pGesture->num_pressed > g_pGesture->num_touches )
+                               g_pGesture->num_pressed = g_pGesture->num_touches;
 
                        if( !g_pGesture->pTempWin || g_pGesture->num_pressed != g_pGesture->inc_num_pressed )
                        {
@@ -2039,7 +2122,7 @@ GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
                                if( NULL == g_pGesture->pTempWin )
                                {
 #ifdef __DETAIL_DEBUG__
-                                       ErrorF("[X11][GestureRecognize][g_pGesture->num_pressed=%d] No grabbed events and no event masks !\n", g_pGesture->num_pressed);
+                                       ErrorF("[X11][GestureRecognize][g_pGesture->num_pressed=%d] No events were selected !\n", g_pGesture->num_pressed);
 #endif//__DETAIL_DEBUG__
                                        g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
                                        goto flush_or_drop;
@@ -2073,7 +2156,7 @@ GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
                        }
                        break;
 
-               case ET_Motion:
+               case ET_TouchUpdate:
                        if( !g_pGesture->fingers[idx].ptime )
                                return;
 
@@ -2124,7 +2207,7 @@ GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
                        }
                        break;
 
-               case ET_ButtonRelease:
+               case ET_TouchEnd:
                        g_pGesture->fingers[idx].rtime = ev->any.time;
                        g_pGesture->fingers[idx].rx = ev->device_event.root_x;
                        g_pGesture->fingers[idx].ry = ev->device_event.root_y;
@@ -2255,8 +2338,11 @@ GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
                g_pGesture->recognized_gesture = 0;
                g_pGesture->num_pressed = 0;
 
-               for( i=0 ; i < g_pGesture->num_mt_devices ; i++ )
+               for( i=0 ; i < g_pGesture->num_touches ; i++ )
+               {
                        g_pGesture->fingers[i].ptime = 0;
+                       g_pGesture->fingers[i].touchid = -1;
+               }
        }
        else if( MTOUCH_FRAME_SYNC_END == ev->any_event.sync )
        {
@@ -2264,26 +2350,37 @@ GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
        }
 }
 
-void
-GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+void GestureHandleTouchBeginEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
 {
+       int idx = -1;
+       int touchid;
 #ifdef __DEBUG_EVENT_HANDLER__
-       ErrorF("[X11][GestureHandleButtonPEvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
+       ErrorF("[X11][GestureHandleTouchBeginEvent] devid=%d, touchid=%d, time:%d cur:%d\n", device->id, ev->device_event.touchid, ev->any.time, GetTimeInMillis());
 #endif//__DEBUG_EVENT_HANDLER__
 
        switch( g_pGesture->ehtype )
        {
                case KEEP_EVENTS:
+                       if( !g_pGesture->num_touches )
+                       {
+                               device->public.processInputProc(ev, device);
+                               return;
+                       }
+
                        if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device) )
                        {
                                GestureControl(g_pGesture->this_device, DEVICE_OFF);
                                return;
                        }
 
-                       if( g_pGesture->num_mt_devices )
-                               GestureRecognize(ET_ButtonPress, ev, device);
-                       else
-                               device->public.processInputProc(ev, device);
+                       if(device->id != g_pGesture->first_fingerid)
+                               return;
+
+                       touchid = ev->device_event.touchid;
+                       idx = GestureTouchFindDDXIDByTouchID(device, touchid);
+
+                       if( idx >= 0 )
+                               GestureRecognize(ET_TouchBegin, ev, device, idx);
                        break;
 
                case PROPAGATE_EVENTS:
@@ -2291,7 +2388,11 @@ GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr de
                        break;
 
                case IGNORE_EVENTS:
-                       GestureRecognize(ET_ButtonPress, ev, device);
+                       touchid = ev->device_event.touchid;
+                       idx = GestureTouchFindDDXIDByTouchID(device, touchid);
+
+                       if( idx >= 0 )
+                               GestureRecognize(ET_TouchBegin, ev, device, idx);
                        break;
 
                default:
@@ -2299,26 +2400,37 @@ GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr de
        }
 }
 
-void
-GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+void GestureHandleTouchUpdateEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
 {
+       int idx = -1;
+       int touchid;
 #ifdef __DEBUG_EVENT_HANDLER__
-       ErrorF("[X11][GestureHandleMotionEvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
+       ErrorF("[X11][GestureHandleTouchUpdateEvent] devid=%d, touchid=%d, time:%d cur:%d\n", device->id, ev->device_event.touchid, ev->any.time, GetTimeInMillis());
 #endif//__DEBUG_EVENT_HANDLER__
 
        switch( g_pGesture->ehtype )
        {
                case KEEP_EVENTS:
+                       if( !g_pGesture->num_touches )
+                       {
+                               device->public.processInputProc(ev, device);
+                               return;
+                       }
+
                        if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device) )
                        {
                                GestureControl(g_pGesture->this_device, DEVICE_OFF);
                                return;
                        }
 
-                       if( g_pGesture->num_mt_devices )
-                               GestureRecognize(ET_Motion, ev, device);
-                       else
-                               device->public.processInputProc(ev, device);
+                       if(device->id != g_pGesture->first_fingerid)
+                               return;
+
+                       touchid = ev->device_event.touchid;
+                       idx = GestureTouchFindDDXIDByTouchID(device, touchid);
+
+                       if( idx >= 0 )
+                               GestureRecognize(ET_TouchUpdate, ev, device, idx);
                        break;
 
                case PROPAGATE_EVENTS:
@@ -2326,35 +2438,52 @@ GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
                        break;
 
                case IGNORE_EVENTS:
-                       GestureRecognize(ET_Motion, ev, device);
+                       touchid = ev->device_event.touchid;
+                       idx = GestureTouchFindDDXIDByTouchID(device, touchid);
+
+                       if( idx >= 0 )
+                               GestureRecognize(ET_TouchUpdate, ev, device, idx);
                        break;
 
                default:
                        break;
        }
-
 }
 
-void
-GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+void GestureHandleTouchEndEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
 {
+       int idx = -1;
+       int touchid;
 #ifdef __DEBUG_EVENT_HANDLER__
-       ErrorF("[X11][GestureHandleButtonREvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
+       ErrorF("[X11][GestureHandleTouchEndEvent] devid=%d, touchid=%d, time:%d cur:%d\n", device->id, ev->device_event.touchid, ev->any.time, GetTimeInMillis());
 #endif//__DEBUG_EVENT_HANDLER__
 
        switch( g_pGesture->ehtype )
        {
                case KEEP_EVENTS:
+                       if( !g_pGesture->num_touches )
+                       {
+                               device->public.processInputProc(ev, device);
+                               return;
+                       }
+
                        if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device) )
                        {
                                GestureControl(g_pGesture->this_device, DEVICE_OFF);
                                return;
                        }
 
-                       if( g_pGesture->num_mt_devices )
-                               GestureRecognize(ET_ButtonRelease, ev, device);
-                       else
-                               device->public.processInputProc(ev, device);
+                       if(device->id != g_pGesture->first_fingerid)
+                               return;
+
+                       touchid = ev->device_event.touchid;
+                       idx = GestureTouchFindDDXIDByTouchID(device, touchid);
+
+                       if( idx >= 0 )
+                       {
+                               GestureRecognize(ET_TouchEnd, ev, device, idx);
+                               g_pGesture->fingers[idx].touchid = -1;
+                       }
                        break;
 
                case PROPAGATE_EVENTS:
@@ -2362,7 +2491,11 @@ GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr
                        break;
 
                case IGNORE_EVENTS:
-                       GestureRecognize(ET_ButtonRelease, ev, device);
+                       touchid = ev->device_event.touchid;
+                       idx = GestureTouchFindDDXIDByTouchID(device, touchid);
+
+                       if( idx >= 0 )
+                               GestureRecognize(ET_TouchEnd, ev, device, idx);
                        break;
 
                default:
@@ -2384,11 +2517,11 @@ GestureEnableEventHandler(InputInfoPtr pInfo)
                return ERROR_ABNORMAL;
        }
 
-       res = GestureSetMaxNumberOfFingers((int)MAX_MT_DEVICES);
+       res = GestureRegisterCallbacks(GestureCbEventsGrabbed, GestureCbEventsSelected);
 
        if( !res )
        {
-               ErrorF("[X11][GestureEnableEventHandler] Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)MAX_MT_DEVICES);
+               ErrorF("[X11][GestureEnableEventHandler] Failed to register callbacks for GestureEventsGrabbed(), GestureEventsSelected() !\n");
                goto failed;
        }
 
@@ -2414,9 +2547,9 @@ GestureDisableEventHandler(void)
 {
        ErrorStatus err = ERROR_NONE;
 
-       mieqSetHandler(ET_ButtonPress, NULL);
-       mieqSetHandler(ET_ButtonRelease, NULL);
-       mieqSetHandler(ET_Motion, NULL);
+       mieqSetHandler(ET_TouchBegin, NULL);
+       mieqSetHandler(ET_TouchUpdate, NULL);
+       mieqSetHandler(ET_TouchEnd, NULL);
        mieqSetHandler(ET_MTSync, NULL);
 
        err = GestureFiniEQ();
@@ -2426,6 +2559,7 @@ GestureDisableEventHandler(void)
                ErrorF("[X11][GestureDisableEventHandler] EQ is invalid or was freed already !\n");
        }
 
+       GestureRegisterCallbacks(NULL, NULL);
        GestureUninstallResourceStateHooks();
 
        return err;
@@ -2437,7 +2571,7 @@ GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
        InputInfoPtr pInfo = (InputInfoPtr)arg;
        GestureDevicePtr pGesture = pInfo->private;
 
-       int idx = 0;
+       Bool res;
        DeviceIntPtr dev;
        for( dev = inputInfo.pointer ; dev; dev = dev->next )
        {
@@ -2455,17 +2589,13 @@ GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
                        continue;
                }
 
-               if(IsPointerDevice(dev))
+               if(IsPointerDevice(dev) && dev->touch)
                {
-                       if( idx >= MAX_MT_DEVICES )
-                       {
-                               ErrorF("[X11][GestureTimerHandler] Number of mt device is over MAX_MT_DEVICES(%d) !\n",
-                                       MAX_MT_DEVICES);
-                               continue;
-                       }
-                       pGesture->mt_devices[idx] = dev;
-                       ErrorF("[X11][GestureTimerHandler][id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name);
-                       idx++;
+                       pGesture->num_touches = dev->touch->num_touches + 1;
+                       pGesture->first_fingerid = dev->id;
+#ifdef __DETAIL_DEBUG__
+                       ErrorF("[X11][GestureTimerHandler] num_touches = %d, first_fingerid=%d\n", pGesture->num_touches, pGesture->first_fingerid);
+#endif//__DETAIL_DEBUG__
                }
        }
 
@@ -2473,27 +2603,40 @@ GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
        {
                ErrorF("[X11][GestureTimerHandler] Failed to get info of master pointer or XTest pointer !\n");
                pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
-               pGesture->num_mt_devices = 0;
+               pGesture->num_touches = 0;
 
                return 0;
        }
 
        pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
-       pGesture->num_mt_devices = idx;
 
-       if( !pGesture->num_mt_devices )
+       if( !pGesture->num_touches )
        {
                ErrorF("[X11][GestureTimerHandler] Failed to mt device information !\n");
                pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
-               pGesture->num_mt_devices = 0;
-       pGesture->first_fingerid = -1;
+               pGesture->first_fingerid = -1;
                return 0;
        }
 
-       pGesture->first_fingerid = pGesture->mt_devices[0]->id;
-       memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices);
+       res = GestureSetMaxNumberOfFingers((int)pGesture->num_touches);
+
+       if( !res )
+       {
+               ErrorF("[X11][GestureTimerHandler] Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)pGesture->num_touches);
+               goto failed;
+       }
+
+       pGesture->finger_rects = (pixman_region16_t *)calloc(sizeof(pixman_region16_t), pGesture->num_touches);
+       pGesture->fingers = (TouchStatus *)calloc(sizeof(TouchStatus), pGesture->num_touches);
+       pGesture->event_sum = (int *)calloc(sizeof(int), pGesture->num_touches);
+
+       if( !pGesture->finger_rects || !pGesture->fingers || !pGesture->event_sum)
+       {
+               ErrorF("[X11][GestureTimerHandler] Failed to allocate memory for finger information\n");
+               goto failed;
+       }
+
        pGesture->pRootWin = RootWindow(pGesture->master_pointer);
-       g_pGesture->grabMask = g_pGesture->eventMask = 0;
        g_pGesture->pTempWin = NULL;
        g_pGesture->inc_num_pressed = 0;
 
@@ -2502,9 +2645,9 @@ GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
                goto failed;
        }
 
-       mieqSetHandler(ET_ButtonPress, GestureHandleButtonPressEvent);
-       mieqSetHandler(ET_ButtonRelease, GestureHandleButtonReleaseEvent);
-       mieqSetHandler(ET_Motion, GestureHandleMotionEvent);
+       mieqSetHandler(ET_TouchBegin, GestureHandleTouchBeginEvent);
+       mieqSetHandler(ET_TouchEnd, GestureHandleTouchEndEvent);
+       mieqSetHandler(ET_TouchUpdate, GestureHandleTouchUpdateEvent);
 
        if( pGesture->is_active )
                mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
@@ -2513,6 +2656,7 @@ GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
 
 failed:
 
+       pGesture->num_touches = 0;
        GestureUninstallResourceStateHooks();
        GestureUnsetMaxNumberOfFingers();
 
@@ -2532,22 +2676,25 @@ IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
 }
 
 void
-GestureSetDisable(InputInfoPtr pInfo, int enable)
+GestureEnable(int enable, Bool prop, DeviceIntPtr dev)
 {
-       if( !enable )
+       if((!enable) && (g_pGesture->is_active))
        {
                g_pGesture->ehtype = PROPAGATE_EVENTS;
                mieqSetHandler(ET_MTSync, NULL);
                g_pGesture->is_active = 0;
-               ErrorF("[X11][GestureSetDisable] Disabled !\n");
+               ErrorF("[X11][GestureEnable] Disabled !\n");
        }
-       else
+       else if((enable) && (!g_pGesture->is_active))
        {
                g_pGesture->ehtype = KEEP_EVENTS;
                mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
                g_pGesture->is_active = 1;
-               ErrorF("[X11][GestureSetDisable] Enabled !\n");
+               ErrorF("[X11][GestureEnable] Enabled !\n");
        }
+
+       if(!prop)
+                XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
 }
 
 ErrorStatus
@@ -2560,7 +2707,7 @@ GestureRegionsInit(void)
 
        pixman_region_init(&g_pGesture->area);
 
-       for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
+       for( i = 0 ; i < g_pGesture->num_touches; i++ )
        {
                pixman_region_init_rect (&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
        }
@@ -2658,7 +2805,7 @@ GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
 
        if( tail >= GESTURE_EQ_SIZE )
        {
-               ErrorF("[X11][GestureEnqueueEvent] Gesture EQ is full !\n");
+               ErrorF("[X11][GestureEnqueueEvent] Gesture EQ is full...Force Gesture Flush \n");
                printk("[X11][GestureEnqueueEvent] Gesture EQ is full...Force Gesture Flush !\n");
                GestureEventsFlush();
                return ERROR_EQFULL;
@@ -2667,16 +2814,16 @@ GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
 #ifdef __DETAIL_DEBUG__
        switch( ev->any.type )
        {
-               case ET_ButtonPress:
-                       ErrorF("[X11][GestureEnqueueEvent] ET_ButtonPress (id:%d)\n", device->id);
+               case ET_TouchBegin:
+                       ErrorF("[X11][GestureEnqueueEvent] ET_TouchBegin (id:%d)\n", device->id);
                        break;
 
-               case ET_ButtonRelease:
-                       ErrorF("[X11][GestureEnqueueEvent] ET_ButtonRelease (id:%d)\n", device->id);
+               case ET_TouchEnd:
+                       ErrorF("[X11][GestureEnqueueEvent] ET_TouchEnd (id:%d)\n", device->id);
                        break;
 
-               case ET_Motion:
-                       ErrorF("[X11][GestureEnqueueEvent] ET_Motion (id:%d)\n", device->id);
+               case ET_TouchUpdate:
+                       ErrorF("[X11][GestureEnqueueEvent] ET_TouchUpdate (id:%d)\n", device->id);
                        break;
        }
 #endif//__DETAIL_DEBUG__
@@ -2711,7 +2858,7 @@ GestureEventsFlush(void)
                device->public.processInputProc(g_pGesture->EQ[i].event, device);
        }
 
-       for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
+       for( i = 0 ; i < g_pGesture->num_touches; i++ )
                g_pGesture->event_sum[i] = 0;
 
        g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
@@ -2755,7 +2902,7 @@ GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
                if( !checkonly )
                {
                        data = *((int *)val->data);
-                       GestureSetDisable(pInfo, data);
+                       GestureEnable(data, TRUE, dev);
                }
        }
 
@@ -2795,7 +2942,7 @@ GestureUnplug(pointer p)
 {
 }
 
-static InputInfoPtr
+static int
 GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
 {
     int rc = BadAlloc;
@@ -2819,6 +2966,9 @@ GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
     pGesture->device = xf86SetStrOption(pInfo->options, "Device", "/dev/null");
     pGesture->is_active = xf86SetIntOption(pInfo->options, "Activate", 0);
     pGesture->gestureWin = None;
+    pGesture->lastSelectedWin = None;
+    pGesture->num_touches = GESTURE_MAX_TOUCH;
+    g_pGesture->grabMask = g_pGesture->eventMask = 0;
 
     xf86Msg(X_INFO, "%s: Using device %s.\n", pInfo->name, pGesture->device);
 
@@ -2827,7 +2977,6 @@ GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
     xf86ProcessCommonOptions(pInfo, pInfo->options);
 
     pInfo->fd = -1;
-
     return Success;
 
 error:
@@ -2868,7 +3017,7 @@ GestureControl(DeviceIntPtr device, int what)
 
             device->public.on = TRUE;
             pGesture->this_device = device;
-            pGesture->num_mt_devices = 0;
+            GestureSetMaxNumberOfFingers((int)pGesture->num_touches);
             if( ERROR_ABNORMAL == GestureEnableEventHandler(pInfo) )
                goto device_off;
             break;
index 7d59dae..709dee7 100755 (executable)
@@ -46,7 +46,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define CLIENT_BITS(id) ((id) & RESOURCE_CLIENT_MASK)
 #define CLIENT_ID(id) ((int)(CLIENT_BITS(id) >> CLIENTOFFSET))
 
-#define MAX_MT_DEVICES         3
+#define GESTURE_MAX_TOUCH      sizeof(unsigned short)
 #define GESTURE_EQ_SIZE        256
 
 #define GESTURE_RECOGNIZER_ONOFF       "GESTURE_RECOGNIZER_ONOFF"
@@ -160,6 +160,10 @@ enum EventType
     ET_ButtonPress,
     ET_ButtonRelease,
     ET_Motion,
+    ET_TouchBegin,
+    ET_TouchUpdate,
+    ET_TouchEnd,
+    ET_TouchOwnership,
     /*
     ...
     */
@@ -348,6 +352,7 @@ typedef struct _tagTouchStatus
        Time ptime;     //press time
        Time mtime;     //motion time
        Time rtime;     //current/previous release time
+       uint32_t touchid;//touch client_id
 } TouchStatus;
 
 typedef struct _GestureDeviceRec
@@ -360,11 +365,13 @@ typedef struct _GestureDeviceRec
 
        WindowPtr pRootWin;
        Window gestureWin;
-       int num_mt_devices;
+       unsigned short num_touches;
 
        Mask grabMask;
        Mask eventMask;
        GestureGrabEventPtr GrabEvents;
+       Mask lastSelectedMask;
+       Window lastSelectedWin;
 
        EventHandleType ehtype;
        IEventPtr       EQ;
@@ -372,21 +379,20 @@ typedef struct _GestureDeviceRec
        int tailEQ;
 
        pixman_region16_t area;
-       pixman_region16_t finger_rects[MAX_MT_DEVICES];
+       pixman_region16_t *finger_rects;
 
        WindowPtr pTempWin;
        int inc_num_pressed;
 
        int first_fingerid;
        int num_pressed;
-       TouchStatus fingers[MAX_MT_DEVICES];
+       TouchStatus *fingers;
 
-       int event_sum[MAX_MT_DEVICES];
+       int *event_sum;
        uint32_t recognized_gesture;
        uint32_t filter_mask;
 
        DeviceIntPtr this_device;
-       DeviceIntPtr mt_devices[MAX_MT_DEVICES];
        DeviceIntPtr master_pointer;
        DeviceIntPtr xtest_pointer;
 } GestureDeviceRec, *GestureDevicePtr ;