From: Jinkun Jang Date: Fri, 15 Mar 2013 16:03:35 +0000 (+0900) Subject: merge with master X-Git-Tag: accepted/tizen/20130910.110909~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F30%2F9030%2F1;p=platform%2Fadaptation%2Fxf86-input-gesture.git merge with master Change-Id: I971414baf5cccf8dcfa0ae027451164975bf27d1 --- diff --git a/packaging/xorg-x11-drv-gesture.spec b/packaging/xorg-x11-drv-gesture.spec index 0787892..288a6ad 100644 --- a/packaging/xorg-x11-drv-gesture.spec +++ b/packaging/xorg-x11-drv-gesture.spec @@ -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} diff --git a/src/gesture.c b/src/gesture.c index a483b7f..bcf0a2e 100755 --- a/src/gesture.c +++ b/src/gesture.c @@ -33,6 +33,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "config.h" #endif +#include #include #include @@ -73,7 +74,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include //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; diff --git a/src/gesture.h b/src/gesture.h index 7d59dae..709dee7 100755 --- a/src/gesture.h +++ b/src/gesture.h @@ -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 ;