From 3eae2ccaabcb4c63f03de0926991e75f4d977acd Mon Sep 17 00:00:00 2001 From: "jk7744.park" Date: Sun, 1 Feb 2015 13:00:28 +0900 Subject: [PATCH] tizen 2.3 release --- mobile/src/gesture.c | 1881 +++++++++----- mobile/src/gesture.h | 73 +- packaging/xorg-x11-drv-gesture.spec | 11 +- wearable/configure.ac | 2 +- wearable/src/gesture.c | 4603 ++++++++++++++++++++++------------- wearable/src/gesture.h | 85 +- 6 files changed, 4289 insertions(+), 2366 deletions(-) diff --git a/mobile/src/gesture.c b/mobile/src/gesture.c index 1dddb27..af7fd87 100755 --- a/mobile/src/gesture.c +++ b/mobile/src/gesture.c @@ -58,6 +58,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #endif +#include + #include #include #include @@ -75,9 +77,34 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define MGEST XDBG_M('G','E','S','T') +static const void(*PalmRecognize)(int, InternalEvent*, DeviceIntPtr); + +#define _GESTUREPALMRECOGNIZE_(function, type, ev, device) \ + if(function) \ + { \ + XDBG_WARNING(MGEST, "[_GESTUREPALMRECOGNIZE_] Enable GesturePalmRecognize. type=%d\n", type); \ + function(type, ev, device); \ + } \ + else \ + { \ + XDBG_WARNING(MGEST, "[_GESTUREPALMRECOGNIZE_] Disable GesturePalmRecognize \n"); \ + } \ + static void printk(const char* fmt, ...) __attribute__((format(printf, 1, 0))); extern char *strcasestr(const char *s, const char *find); extern ScreenPtr miPointerCurrentScreen(void); +extern EventQueuePtr mieqGetEventQueuePtr(); + +static Bool GestureIsEventInMIEQ(int finger_index, enum EventType type); +static int GestureGetFingerIndexFromDevice(DeviceIntPtr device); +static int GestureGetDeviceIdFromFingerIndex(int finger_index); +static Bool GestureIsPalmEventInMIEQ(void); +static Bool GestureIsPalmEvent(InternalEvent *event); +static int GestureGetMTToolValuator(InternalEvent *ev, DeviceIntPtr device); +static void GestureRegisterTouchInfo(InternalEvent *ev, DeviceIntPtr device); +static void GestureSetToolData(InternalEvent *ev, double val_tool); +static void GestureCleanupTouch(int screen_num, InternalEvent *ev, DeviceIntPtr device); +static void GestureChangeEventToFirstFingerEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device); //Basic functions static int GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags); @@ -111,17 +138,20 @@ static Bool GestureHasFingersEvents(int eventType); //Enqueued event handlers and enabler/disabler static ErrorStatus GestureEnableEventHandler(InputInfoPtr pInfo); static ErrorStatus GestureDisableEventHandler(void); -static CARD32 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg); static CARD32 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg); -static CARD32 GesturePalmEventTimerHandler(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 GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device); +void GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device); + +static void GestureRegisterDeviceInfo(DeviceIntPtr device); //Gesture recognizer helper +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21 static Bool PointInBorderSize(WindowPtr pWin, int x, int y); +#endif static WindowPtr GestureWindowOnXY(int x, int y); Bool GestureHasFingerEventMask(int eventType, int num_finger); #ifdef _F_SUPPORT_BEZEL_FLICK_ @@ -151,7 +181,6 @@ ErrorStatus GestureFlushOrDrop(void); static int GesturePalmGetHorizIndexWithX(int x, int type); static int GesturePalmGetVertiIndexWithY(int y, int type); -static void GesturePalmRecognize_Hold(int type, int idx, int timer_expired); static void GesturePalmRecognize_FlickHorizen(int type, int idx); static void GesturePalmRecognize_FlickVertical(int type,int idx); static int GesturePalmGetScreenInfo(); @@ -173,6 +202,13 @@ static int GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr va #endif static Atom prop_gesture_recognizer_onoff = None; +static Atom prop_gesture_palm_rejection_mode = None; + +#ifdef SUPPORT_ANR_WITH_INPUT_EVENT +static Atom prop_anr_in_input_event = None; +static Atom prop_anr_event_window = None; +static Window prop_anr_event_window_xid = None; +#endif GestureDevicePtr g_pGesture = NULL; _X_EXPORT InputDriverRec GESTURE = { @@ -228,15 +264,54 @@ printk(const char* fmt, ...) va_end(argptr); } +#ifdef SUPPORT_ANR_WITH_INPUT_EVENT +static WindowPtr +_GestureFindANRWindow(DeviceIntPtr device) +{ + WindowPtr root=NULL; + WindowPtr anr_window=NULL; + Window anr_xid=0; + PropertyPtr pProp; + int rc=0; + + root = RootWindow(device); + + if( prop_anr_event_window == None ) + prop_anr_event_window = MakeAtom(ANR_EVENT_WINDOW, strlen(ANR_EVENT_WINDOW), TRUE); + + rc = dixLookupProperty (&pProp, root, prop_anr_event_window, serverClient, DixReadAccess); + if (rc == Success && pProp->data){ + anr_xid = *(int*)pProp->data; + } + + if( anr_xid != 0 ) + { + rc = dixLookupWindow(&anr_window, anr_xid, serverClient, DixSetPropAccess); + if( rc == BadWindow ) + { + XDBG_ERROR(MGEST, "Can't find ANR window !!\n"); + anr_window = NULL; + } + prop_anr_event_window_xid = anr_xid; + } + + XDBG_DEBUG(MGEST, "ANR Window is %#x. Ptr is %#x\n", anr_xid, anr_window); + return anr_window; +} +#endif + +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21 static Bool PointInBorderSize(WindowPtr pWin, int x, int y) { BoxRec box; - if( pixman_region_contains_point (&pWin->borderSize, x, y, &box) ) - return TRUE; - + if (pixman_region_contains_point (&pWin->borderSize, x, y, &box)) + { + return TRUE; + } return FALSE; } +#endif static WindowPtr GestureWindowOnXY(int x, int y) @@ -424,14 +499,13 @@ GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int if(direction == FLICK_NORTHWARD || direction == FLICK_SOUTHWARD) g_pGesture->recognized_palm |= PalmFlickVertiFilterMask; } - #ifdef _F_SUPPORT_BEZEL_FLICK_ else if(num_of_fingers == 1) { g_pGesture->bezel_recognized_mask |= BezelFlickFilterMask; } - else #endif + else g_pGesture->recognized_gesture |= FlickFilterMask; memset(&fev, 0, sizeof(xGestureNotifyFlickEvent)); @@ -583,7 +657,7 @@ void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, i #endif//__DETAIL_DEBUG__ if(num_fingers == 0) - g_pGesture->recognized_palm |= PalmHoldFilterMask; + g_pGesture->hold_detected = TRUE; else g_pGesture->recognized_gesture |= HoldFilterMask; memset(&hev, 0, sizeof(xGestureNotifyHoldEvent)); @@ -917,7 +991,7 @@ GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr de static Time base_time = 0; Time current_time; - if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 + if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 || g_pGesture->hold_detected #ifdef _F_SUPPORT_BEZEL_FLICK_ || g_pGesture->bezel_recognized_mask) #else @@ -1184,7 +1258,7 @@ GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, in int area_size; int flicked = 0; - if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 + if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 || g_pGesture->hold_detected #ifdef _F_SUPPORT_BEZEL_FLICK_ || g_pGesture->bezel_recognized_mask) #else @@ -1334,7 +1408,7 @@ GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int static OsTimerPtr pan_event_timer = NULL; static int event_type = GestureNotifyPan; - if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 + if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 || g_pGesture->hold_detected #ifdef _F_SUPPORT_BEZEL_FLICK_ || g_pGesture->bezel_recognized_mask) #else @@ -1545,7 +1619,6 @@ GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int static int base_area_size = 0; static Time base_time = 0; - Time current_time; int cx, cy; int area_size; @@ -1557,13 +1630,12 @@ GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int static pixman_box16_t base_box_ext; static int tap_repeat = 0; - static int prev_tap_repeat = 0; static int prev_num_pressed = 0; static OsTimerPtr tap_event_timer = NULL; static int event_type = GestureNotifyTap; - if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 + if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 || g_pGesture->hold_detected #ifdef _F_SUPPORT_BEZEL_FLICK_ || g_pGesture->bezel_recognized_mask) #else @@ -1583,7 +1655,7 @@ GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int if( num_pressed ) { #ifdef __DETAIL_DEBUG__ - XDBG_DEBUG(MGEST, "[Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", tap_repeat, num_pressed, tap_repeat); + XDBG_DEBUG(MGEST, "[Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", num_pressed, tap_repeat); #endif//__DETAIL_DEBUG__ state = GestureEnd; goto cleanup_tap; @@ -1601,7 +1673,7 @@ GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int } #ifdef __DETAIL_DEBUG__ - XDBG_DEBUG(MGEST, "[Timer][state=2] tap_repeat=%d, prev_tap_repeat=%d, num_pressed=%d\n", tap_repeat, prev_tap_repeat, num_pressed); + XDBG_DEBUG(MGEST, "[Timer][state=2] tap_repeat=%d, num_pressed=%d\n", tap_repeat, num_pressed); #endif//__DETAIL_DEBUG__ if( GestureHasFingerEventMask(GestureNotifyTap, prev_num_pressed) ) { @@ -1647,10 +1719,8 @@ GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int num_pressed = g_pGesture->num_pressed; - current_time = GetTimeInMillis(); - #ifdef __DETAIL_DEBUG__ - XDBG_DEBUG(MGEST, "[P][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d, base_time=%d, current_time=%d\n", num_pressed, base_area_size, base_cx, base_cy, base_time, current_time); + XDBG_DEBUG(MGEST, "[P][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d, base_time=%d, current_time=%d\n", num_pressed, base_area_size, base_cx, base_cy, base_time, GetTimeInMillis()); #endif//__DETAIL_DEBUG__ break; @@ -1715,12 +1785,11 @@ GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int prev_num_pressed = num_pressed; } - prev_tap_repeat = tap_repeat; tap_repeat++; g_pGesture->tap_repeated = tap_repeat; #ifdef __DETAIL_DEBUG__ - XDBG_DEBUG(MGEST, "[R] tap_repeat=%d, prev_tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, prev_tap_repeat, num_pressed, prev_num_pressed); + XDBG_DEBUG(MGEST, "[R] tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, num_pressed, prev_num_pressed); #endif//__DETAIL_DEBUG__ if( num_pressed != prev_num_pressed || !GestureHasFingerEventMask(GestureNotifyTap, num_pressed) ) @@ -1812,7 +1881,7 @@ GestureRecognize_GroupTapNHold(int type, InternalEvent *ev, DeviceIntPtr device, Time interval = 0; Time holdtime = 0; - if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 + if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 || g_pGesture->hold_detected #ifdef _F_SUPPORT_BEZEL_FLICK_ || g_pGesture->bezel_recognized_mask) #else @@ -2081,7 +2150,7 @@ void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device static OsTimerPtr hold_event_timer = NULL; static int event_type = GestureNotifyHold; - if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 + if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 || g_pGesture->hold_detected #ifdef _F_SUPPORT_BEZEL_FLICK_ || g_pGesture->bezel_recognized_mask) #else @@ -2390,8 +2459,6 @@ nonempty_eventmask: #endif #endif//__DETAIL_DEBUG__ g_pGesture->palm_filter_mask = 0; - if(mask & HoldFilterMask) - g_pGesture->palm_filter_mask |= PalmHoldFilterMask; if(mask & FlickFilterMask) { g_pGesture->palm_filter_mask |= PalmFlickHorizFilterMask; @@ -2506,30 +2573,6 @@ GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg) return 0; } -static CARD32 -GesturePalmEventTimerHandler(OsTimerPtr timer,CARD32 time,pointer arg) -{ - int event_type = *(int *)arg; - - switch( event_type ) - { - case GestureNotifyHold: -#ifdef __PALM_DETAIL_LOG__ - XDBG_DEBUG(MGEST, "GestureNotifyHold (event_type = %d)\n", event_type); -#endif//__PALM_DETAIL_LOG__ - GesturePalmRecognize_Hold(event_type, 0, 1); - break; - - default: -#ifdef __PALM_DETAIL_LOG__ - XDBG_DEBUG(MGEST, "unknown event_type (=%d)\n", event_type); -#endif//__PALM_DETAIL_LOG__ - break; - } - - return 0; -} - #ifdef _F_SUPPORT_BEZEL_FLICK_ static CARD32 GestureBezelSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg) @@ -2583,17 +2626,6 @@ GesturePalmSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg) return 0; } -static CARD32 -GesturePalmHoldRapidHandler(OsTimerPtr timer, CARD32 time, pointer arg) -{ -#ifdef __PALM_DETAIL_LOG__ - XDBG_DEBUG(MGEST, "[%d] rapid timer in.....\n", __LINE__); -#endif - GesturePalmRecognize_Hold(0, 0, 0); - return 0; -} - - static int GesturePalmGetHorizIndexWithX(int x, int type) { @@ -2668,7 +2700,7 @@ GesturePalmGetVertiIndexWithY(int y, int type) for(i = 0 ; i < PALM_VERTI_ARRAY_COUNT ; i++) { #ifdef __PALM_DETAIL_LOG__ - XDBG_DEBUG(MGEST, "pPalmMisc->horiz_coord[%d]=%d, x=%d\n", i, pPalmMisc->horiz_coord[i], y); + XDBG_DEBUG(MGEST, "pPalmMisc->verti_coord[%d]=%d, x=%d\n", i, pPalmMisc->verti_coord[i], y); #endif//__PALM_DETAIL_LOG__ if(y <= pPalmMisc->verti_coord[i]) { @@ -2735,54 +2767,61 @@ index_check: } static void -GesturePalmRecognize_Hold(int type, int idx, int timer_expired) +GesturePalmRecognize_FlickHorizen(int type, int idx) { - static int is_holding = 1; + static int curTouched = 0; static int num_pressed = 0; - static Time base_time = 0; - static int cx, cy; static int base_width_size = 0; + static Time base_time = 0; + static int base_x; + static pixman_box16_t base_box_ext; +#ifdef __PALM_GESTURE_LOG__ + int i; +#endif - static int state = GestureEnd; - static int false_base_width_size_count = 0; - static int max_num_finger = 0; + int line_idx; + static int prev_line_idx; + static int horiz_line[PALM_HORIZ_ARRAY_COUNT]; - static OsTimerPtr palm_hold_event_timer = NULL; - static int event_type = GestureNotifyHold; - PalmStatusPtr pPalm = &g_pGesture->palm; - static int hold_occured = 0; - static int rapid_hold = 0; - static OsTimerPtr palm_hold_rapid_timer = NULL; + Time duration; + int distx=0, disty=0; + int distance, direction; + + int width_size; + static int is_flicking = 1; + //static int is_surface = 0; + static int pass_count = 0; + static int base_cx=0, base_cy=0; + static int release_flag = 0; + PalmStatusPtr pPalm = &g_pGesture->palm; #ifdef __PALM_GESTURE_LOG__ XDBG_DEBUG(MGEST, "recognized_palm= 0x%x, palm_filter_mask= 0x%x\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask); - XDBG_DEBUG(MGEST, "num_pressed: %d, cur_touched: %d, palm_flag: %d, is_holding: %d hold_occured %.f\n", num_pressed, pPalm->cur_touched, pPalm->palmflag, is_holding, hold_occured); - XDBG_DEBUG(MGEST, "pPalm->biggest_wmajor: %.f, pPalm->bigger_wmajor: %.f, pPalm->biggest_tmajor: %.f\n", pPalm->biggest_wmajor, pPalm->bigger_wmajor, pPalm->biggest_tmajor); + XDBG_DEBUG(MGEST, "num_pressed: %d, cur_touched: %d palmflag: %d\n", num_pressed, pPalm->cur_touched, pPalm->palmflag); + XDBG_DEBUG(MGEST, "idx: %d, cx: %d, cy: %d, type: %d, touch_status: %d\n", idx, pPalm->cx, pPalm->cy, type, pPalm->pti[idx].touch_status); #endif + + if( idx < 0 ) + goto flick_failed; + if(g_pGesture->enqueue_fulled == 1) { #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "EQ Event is full.... palm recognize drop..\n"); -#endif - goto hold_failed; - } - if(rapid_hold && type==0 && idx==0 && timer_expired == 0) - { -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "rapid timer is released .....\n"); + XDBG_DEBUG(MGEST, "EQ Event is full.... palm recognize drop..\n"); #endif - rapid_hold = 0; - goto release_hold; + goto flick_failed; } - if(pPalm->single_timer_expired && (pPalm->biggest_tmajor < PALM_HOLD_FINGER_MIN_TOUCH_MAJOR) && (max_num_finger < (PALM_HOLD_MIN_FINGER - 1))) + + if(pPalm->single_timer_expired) { #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "No Hold single finger...expired, biggest_tmajor: %.f\n", pPalm->biggest_tmajor); + XDBG_DEBUG(MGEST, "No flick single finger...expired\n"); #endif - goto hold_failed; + goto flick_failed; } - if(g_pGesture->recognized_gesture || (g_pGesture->recognized_palm && !(g_pGesture->recognized_palm & PalmHoldFilterMask)) || (g_pGesture->palm_filter_mask & PalmHoldFilterMask) + if(g_pGesture->recognized_gesture || g_pGesture->hold_detected || + (g_pGesture->recognized_palm && !(g_pGesture->recognized_palm & PalmFlickHorizFilterMask)) || (g_pGesture->palm_filter_mask & PalmFlickHorizFilterMask) #ifdef _F_SUPPORT_BEZEL_FLICK_ || g_pGesture->bezel_recognized_mask) #else @@ -2794,452 +2833,130 @@ GesturePalmRecognize_Hold(int type, int idx, int timer_expired) XDBG_DEBUG(MGEST, "type(%d) recognized_palm= 0x%x, palm_filter_mask= 0x%x\n", type, g_pGesture->recognized_palm, g_pGesture->palm_filter_mask); XDBG_DEBUG(MGEST, "type(%d) recognized_gesture= 0x%x, filter_mask= 0x%x\n", type, g_pGesture->recognized_gesture, g_pGesture->filter_mask); #endif - goto hold_failed; + goto flick_failed; } - if( timer_expired && !pPalm->palmflag) + switch( type ) { + case ET_ButtonPress: + if(!is_flicking) + break; + if(!base_width_size || pPalm->cur_touched > curTouched) + { + if(!base_time) + { + base_time = GetTimeInMillis(); + base_x = AREA_CENTER_X(&pPalm->area.extents); + line_idx = GesturePalmGetHorizIndexWithX(base_x, type); #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "No Palm is comming \n"); -#endif - if( (pPalm->biggest_wmajor > PALM_HOLD_FINGER_MIN_WIDTH_MAJOR) && (max_num_finger >= PALM_HOLD_MIN_FINGER) ) - { -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "It seemed palm hold (biggest_wmajor: %.f max_num_finger: %d) \n", pPalm->biggest_wmajor, max_num_finger); + XDBG_DEBUG(MGEST, "[P] cx: %d, cy: %d, x1: %d, x2: %d, y1: %d, y2: %d, line_idx: %d\n", pPalm->cx, pPalm->cy, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2, line_idx); #endif - pPalm->palmflag = 1; - } - else - { + if(line_idx < 0) + { #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "No Palm and No Hold \n"); + XDBG_DEBUG(MGEST, "[P] No line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x, line_idx); #endif - goto hold_failed; - } - } + goto flick_failed; + } - if( timer_expired && pPalm->palmflag) - { + horiz_line[line_idx]++; + pass_count++; + prev_line_idx = line_idx; + release_flag = 0; #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "state: %d\n", state); + XDBG_DEBUG(MGEST, "[P] Base_width=%d, base_x=%d, line_idx=%d\n", base_width_size, base_x, line_idx); #endif - if(max_num_finger < PALM_HOLD_MIN_FINGER) - { + } + + base_width_size = AREA_WIDTH(&pPalm->area.extents); + if(base_width_size > PALM_FLICK_HORIZ_MAX_BASE_WIDTH) + { #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "palm hold false : max_num_finger(%d) < %d\n", max_num_finger, PALM_HOLD_MIN_FINGER); + XDBG_DEBUG(MGEST, "[P] No flickBase_width=%d > %d: MAX_WIDTH\n", base_width_size, PALM_FLICK_HORIZ_MAX_BASE_WIDTH); #endif - goto hold_failed; - } - if( state <= GestureBegin ) - state++; - - switch( state ) - { - case GestureBegin: + goto flick_failed; + } #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "HOLD Begin !(state=%d)\n", state); + XDBG_DEBUG(MGEST, "[P] Base_width=%d, cur_touched=%d\n", base_width_size, pPalm->cur_touched); #endif - break; + if(pPalm->max_touched == 1) + { + base_cx = AREA_CENTER_X(&pPalm->area.extents); + base_cy = AREA_CENTER_Y(&pPalm->area.extents); + base_box_ext.x1 = base_cx-HOLD_MOVE_THRESHOLD; + base_box_ext.y1 = base_cy-HOLD_MOVE_THRESHOLD; + base_box_ext.x2 = base_cx+HOLD_MOVE_THRESHOLD; + base_box_ext.y2 = base_cy+HOLD_MOVE_THRESHOLD; + } + } + curTouched = pPalm->cur_touched; + num_pressed++; + break; - case GestureUpdate: + case ET_Motion: + if(!num_pressed || !is_flicking) + { #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "HOLD Update !(state=%d)\n", state); + XDBG_DEBUG(MGEST, "[M] num_pressed: %d, is_flicking: %d\n", num_pressed, is_flicking); #endif break; - } + } - if(base_width_size < PALM_HOLD_MIN_BASE_WIDTH) - { + distx = AREA_CENTER_X(&pPalm->area.extents); + disty = AREA_CENTER_Y(&pPalm->area.extents); + line_idx = GesturePalmGetHorizIndexWithX(distx, type); #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[P] No Hold base_width_size: %d < %d\n", base_width_size, PALM_HOLD_MIN_BASE_WIDTH); -#endif - goto hold_failed; - } - - if( GestureHasFingerEventMask(GestureNotifyHold, 0) ) - { - if(state == GestureBegin) + for(i=0; iarea.extents); -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[P] Hold base_width_size: %d\n", base_width_size); -#endif - false_base_width_size_count = 0; - num_pressed++; - if(max_num_finger < num_pressed) - max_num_finger = num_pressed; - break; - - case ET_Motion: - if(!num_pressed || !is_holding) - return; - if(state < GestureBegin) + if(pPalm->max_touched == 1) { - if( !(pPalm->palmflag) && pPalm->max_palm >= PALM_FLICK_MIN_PALM) - pPalm->palmflag = 1; - if(base_width_size < PALM_HOLD_MIN_BASE_WIDTH) + if(ABS(disty - base_cy) > PALM_FLICK_HORIZ_MAX_MOVE_Y) { - false_base_width_size_count++; -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[M] increase false_base_width_size_count: %d!, width: %.f\n", false_base_width_size_count, base_width_size); -#endif - if(false_base_width_size_count > PALM_HOLD_FALSE_WIDTH) - { #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[M] No hold width!\n"); + XDBG_DEBUG(MGEST, "[M] No flick ! (move too long toward y coordination %d(%d - %d) > %d\n", ABS(disty - base_cy), disty, base_cy, PALM_FLICK_HORIZ_MAX_MOVE_Y); #endif - goto hold_failed; - } + goto flick_failed; } } - cx = AREA_CENTER_X(&pPalm->area.extents); - cy = AREA_CENTER_Y(&pPalm->area.extents); - break; - - case ET_ButtonRelease: - if(--num_pressed < 0) - num_pressed = 0; - - if(pPalm->cur_touched || num_pressed) - break; -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[R] All fingers were released ! state=%d, is_holding=%d, cur_touched=%d, num_pressed=%d\n", - state, is_holding, pPalm->cur_touched, num_pressed); -#endif - if(!is_holding) - goto cleanup_hold; - - if (hold_occured == 0 && state == GestureEnd) + if(prev_line_idx != line_idx) { -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[R] Fast Release..\n"); -#endif - if( (pPalm->palmflag) && (base_width_size > PALM_HOLD_MIN_BASE_WIDTH)) - { -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[R] seemed hold palm is came, base_width_size: %d..\n", base_width_size); -#endif - if( GestureHasFingerEventMask(GestureNotifyHold, 0) ) - { - hold_occured = 1; - state = GestureBegin; - GestureHandleGesture_Hold(0, cx, cy, GetTimeInMillis()-base_time, state); - rapid_hold = 1; - palm_hold_rapid_timer = TimerSet(palm_hold_rapid_timer, 0, PALM_HOLD_TIME_THRESHOLD, GesturePalmHoldRapidHandler, NULL); -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[R] rapid hold begin !!\n"); -#endif - goto hold_failed; - } - } - else if( (pPalm->biggest_wmajor > PALM_HOLD_FINGER_MIN_WIDTH_MAJOR) && (max_num_finger >= PALM_HOLD_MIN_FINGER) ) + horiz_line[line_idx]++; + if(horiz_line[line_idx] > 2) { #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[R] seemed hold.. biggest_wmajor: %.f, max_num_finger: %d", pPalm->biggest_wmajor, max_num_finger); + XDBG_DEBUG(MGEST, "[M] No flick ! horiz_line[%d]: %d > 2\n", line_idx, horiz_line[line_idx]); #endif - if( GestureHasFingerEventMask(GestureNotifyHold, 0) ) - { - hold_occured = 1; - state = GestureBegin; - GestureHandleGesture_Hold(0, cx, cy, GetTimeInMillis()-base_time, state); - rapid_hold = 1; - palm_hold_rapid_timer = TimerSet(palm_hold_rapid_timer, 0, PALM_HOLD_TIME_THRESHOLD, GesturePalmHoldRapidHandler, NULL); -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[R] rapid hold begin !!\n"); -#endif - goto hold_failed; - } + goto flick_failed; } + pass_count++; } -release_hold: - if(hold_occured == 0 && num_pressed == 0) + if(pass_count > 6) { #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[R] release all finger and No hold base_width_size: %d, biggest_wmajor: %.f, max_num_finger: %d\n", base_width_size, pPalm->biggest_wmajor, max_num_finger); + XDBG_DEBUG(MGEST, "[M] No flick !(visit same place twice !)\n"); #endif - goto hold_failed; + goto flick_failed; } - - if( state == GestureBegin || state == GestureUpdate ) +#if 0 + if((prev_line_idx != line_idx) && horiz_line[line_idx] && !release_flag) { - state = GestureEnd; #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[R] HOLD End !(state=%d)\n", state); + XDBG_DEBUG(MGEST, "[M] No flick !(visit same place twice !)\n"); #endif - hold_occured = 0; - //g_pGesture->recognized_palm = GESTURE_PALM_FILTER_MASK_ALL; - if( GestureHasFingerEventMask(GestureNotifyHold, 0) ) - { - GestureHandleGesture_Hold(0, cx, cy, GetTimeInMillis()-base_time, state); - } - //else - //XDBG_DEBUG(MGEST, "[END] \n"); - } - else - { -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[R] Gesture Hold End is already occured\n"); -#endif - goto hold_failed; - } - goto cleanup_hold; - } - return; - -hold_failed: - is_holding = 0; - TimerCancel(palm_hold_event_timer); - g_pGesture->palm_filter_mask |= PalmHoldFilterMask; - if( g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL ) - { - if( ERROR_INVALPTR == GestureFlushOrDrop() ) - { - GestureControl(g_pGesture->this_device, DEVICE_OFF); - } - } -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[F] recognized_palm= 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask); -#endif - goto cleanup_hold; - return; - -cleanup_hold: -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[F] HOLD Cleanup (state: %d)\n", state); -#endif - TimerCancel(palm_hold_event_timer); - if(state == GestureBegin || state == GestureUpdate) - { - if( GestureHasFingerEventMask(GestureNotifyHold, 0) ) - { - GestureHandleGesture_Hold(0, cx, cy, GetTimeInMillis()-base_time, GestureEnd); - } - } - is_holding = 1; - num_pressed = 0; - false_base_width_size_count = 0; - base_time = 0; - cx = cy = 0; - max_num_finger = 0; - state = GestureEnd; - base_width_size = 0; - hold_occured = 0; - rapid_hold = 0; - return; -} - -static void -GesturePalmRecognize_FlickHorizen(int type, int idx) -{ - static int curTouched = 0; - static int num_pressed = 0; - static int base_width_size = 0; - static Time base_time = 0; - static int base_x; - static pixman_box16_t base_box_ext; -#ifdef __PALM_GESTURE_LOG__ - int i; -#endif - - int line_idx; - static int press_idx; - static int prev_line_idx; - static int horiz_line[PALM_HORIZ_ARRAY_COUNT]; - - Time duration; - int distx=0, disty=0; - int distance, direction; - - int width_size; - static int is_flicking = 1; - //static int is_surface = 0; - static int pass_count = 0; - static int base_cx=0, base_cy=0; - static int release_flag = 0; - - PalmStatusPtr pPalm = &g_pGesture->palm; -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "recognized_palm= 0x%x, palm_filter_mask= 0x%x\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask); - XDBG_DEBUG(MGEST, "num_pressed: %d, cur_touched: %d palmflag: %d\n", num_pressed, pPalm->cur_touched, pPalm->palmflag); - XDBG_DEBUG(MGEST, "idx: %d, cx: %d, cy: %d\n", idx, pPalm->cx, pPalm->cy); -#endif - - if(g_pGesture->enqueue_fulled == 1) - { -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "EQ Event is full.... palm recognize drop..\n"); -#endif - goto flick_failed; - } - - if(pPalm->single_timer_expired) - { -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "No flick single finger...expired\n"); -#endif - goto flick_failed; - } - - if(g_pGesture->recognized_gesture || (g_pGesture->recognized_palm && !(g_pGesture->recognized_palm & PalmFlickHorizFilterMask)) || (g_pGesture->palm_filter_mask & PalmFlickHorizFilterMask) -#ifdef _F_SUPPORT_BEZEL_FLICK_ - || g_pGesture->bezel_recognized_mask) -#else - ) -#endif - { -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "zoom_enabled: %d\n", g_pGesture->zoom_enabled); - XDBG_DEBUG(MGEST, "type(%d) recognized_palm= 0x%x, palm_filter_mask= 0x%x\n", type, g_pGesture->recognized_palm, g_pGesture->palm_filter_mask); - XDBG_DEBUG(MGEST, "type(%d) recognized_gesture= 0x%x, filter_mask= 0x%x\n", type, g_pGesture->recognized_gesture, g_pGesture->filter_mask); -#endif - goto flick_failed; - } - switch( type ) - { - case ET_ButtonPress: - if(!is_flicking) - break; - if(!base_width_size || pPalm->cur_touched > curTouched) - { - if(!base_time) - { - base_time = GetTimeInMillis(); - base_x = AREA_CENTER_X(&pPalm->area.extents); - line_idx = GesturePalmGetHorizIndexWithX(base_x, type); -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[P] cx: %d, cy: %d, x1: %d, x2: %d, y1: %d, y2: %d, line_idx: %d\n", pPalm->cx, pPalm->cy, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2, line_idx); -#endif - if(line_idx < 0) - { -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[P] line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x, line_idx); -#endif - goto flick_failed; - } - - horiz_line[line_idx]++; - pass_count++; - press_idx = prev_line_idx = line_idx; - release_flag = 0; -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[P] Base_width=%d, base_x=%d, line_idx=%d\n", base_width_size, base_x, line_idx); -#endif - } - - base_width_size = AREA_WIDTH(&pPalm->area.extents); - if(base_width_size > PALM_FLICK_HORIZ_MAX_BASE_WIDTH) - { -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[P] No flickBase_width=%d > MAX_WIDTH\n", base_width_size, PALM_FLICK_HORIZ_MAX_BASE_WIDTH); -#endif - goto flick_failed; - } -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[P] Base_width=%d, cur_touched=%d\n", base_width_size, pPalm->cur_touched); -#endif - if(pPalm->max_touched == 1) - { - base_cx = AREA_CENTER_X(&pPalm->area.extents); - base_cy = AREA_CENTER_Y(&pPalm->area.extents); - base_box_ext.x1 = base_cx-HOLD_MOVE_THRESHOLD; - base_box_ext.y1 = base_cy-HOLD_MOVE_THRESHOLD; - base_box_ext.x2 = base_cx+HOLD_MOVE_THRESHOLD; - base_box_ext.y2 = base_cy+HOLD_MOVE_THRESHOLD; - } - } - curTouched = pPalm->cur_touched; - num_pressed++; - break; - - case ET_Motion: - if(!num_pressed || !is_flicking) - { -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[M] num_pressed: %d, is_flicking: %d\n", num_pressed, is_flicking); -#endif - break; - } - - distx = AREA_CENTER_X(&pPalm->area.extents); - disty = AREA_CENTER_Y(&pPalm->area.extents); - line_idx = GesturePalmGetHorizIndexWithX(distx, type); -#ifdef __PALM_GESTURE_LOG__ - for(i=0; imax_touched == 1) - { - if(ABS(disty - base_cy) > PALM_FLICK_HORIZ_MAX_MOVE_Y) - { -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[M] No flick ! (move too long toward y coordination %d(%d - %d) > %d\n", ABS(disty - base_cy), disty, base_cy, PALM_FLICK_HORIZ_MAX_MOVE_Y); -#endif - goto flick_failed; - } - } - - if(prev_line_idx != line_idx) - { - horiz_line[line_idx]++; - if(horiz_line[line_idx] > 2) - goto flick_failed; - pass_count++; - } - if(pass_count > 6) - { -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[M] No flick !(visit same place twice !)\n"); -#endif - goto flick_failed; - } -#if 0 - if((prev_line_idx != line_idx) && horiz_line[line_idx] && !release_flag) - { -#ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[M] No flick !(visit same place twice !)\n"); -#endif - goto flick_failed; + goto flick_failed; } #endif prev_line_idx = line_idx; @@ -3252,7 +2969,8 @@ GesturePalmRecognize_FlickHorizen(int type, int idx) #ifdef __PALM_GESTURE_LOG__ XDBG_DEBUG(MGEST, "[M] duration =%d !\n", duration); #endif - if(!pPalm->palmflag && (duration >= PALM_FLICK_INITIAL_TIMEOUT)) + if(((!pPalm->palmflag) && (pPalm->biggest_tmajor < PALM_FLICK_TOUCH_MAJOR-20) && (pPalm->biggest_wmajor < PALM_FLICK_TOUCH_MAJOR-20)) && + (duration >= PALM_FLICK_INITIAL_TIMEOUT)) { #ifdef __PALM_GESTURE_LOG__ XDBG_DEBUG(MGEST, "[M] No flick !(initial flick timeout : duration=%d)\n", duration); @@ -3266,10 +2984,10 @@ GesturePalmRecognize_FlickHorizen(int type, int idx) #endif goto flick_failed; } - if( (duration >= PALM_FLICK_FALSE_TIMEOUT) && (pPalm->biggest_tmajor < PALM_FLICK_TOUCH_MAJOR) ) + if( (duration >= PALM_FLICK_FALSE_TIMEOUT) && (pPalm->biggest_tmajor < PALM_FLICK_TOUCH_MAJOR) && (pPalm->biggest_wmajor < PALM_FLICK_TOUCH_MAJOR)) { #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[M] No flick !(press touch major(%.f < %.f) is little in duration(%d))\n", pPalm->biggest_tmajor, PALM_FLICK_TOUCH_MAJOR, duration); + XDBG_DEBUG(MGEST, "[M] No flick !(press touch major(%.f) width major (%.f) < (%.f) is little in duration(%d))\n", pPalm->biggest_tmajor, pPalm->biggest_wmajor, PALM_FLICK_TOUCH_MAJOR, duration); #endif goto flick_failed; } @@ -3290,7 +3008,8 @@ GesturePalmRecognize_FlickHorizen(int type, int idx) base_width_size = AREA_WIDTH(&pPalm->area.extents); if(num_pressed) break; - if(!pPalm->palmflag) + + if((!pPalm->palmflag) && (pPalm->biggest_tmajor < 100) && (pPalm->bigger_wmajor < 100)) { #ifdef __PALM_GESTURE_LOG__ XDBG_DEBUG(MGEST, "[R] No flick (No palm comming and all finger release))\n"); @@ -3329,10 +3048,10 @@ GesturePalmRecognize_FlickHorizen(int type, int idx) #endif goto flick_failed; } - if(pPalm->biggest_tmajor < PALM_FLICK_TOUCH_MAJOR) + if((pPalm->biggest_tmajor < PALM_FLICK_TOUCH_MAJOR) && (pPalm->biggest_wmajor < PALM_FLICK_TOUCH_MAJOR)) { #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[R] No flick !(touch major(%.f < %d) is small...)\n", pPalm->biggest_tmajor, PALM_FLICK_TOUCH_MAJOR); + XDBG_DEBUG(MGEST, "[R] No flick !(touch major(%.f) width major(%.f) < %d) is small...)\n", pPalm->biggest_tmajor, pPalm->biggest_wmajor, PALM_FLICK_TOUCH_MAJOR); #endif goto flick_failed; } @@ -3393,7 +3112,6 @@ GesturePalmRecognize_FlickVertical(int type,int idx) static pixman_box16_t base_box_ext; int line_idx; - static int press_idx; static int prev_line_idx; static int verti_line[PALM_VERTI_ARRAY_COUNT]; @@ -3411,16 +3129,20 @@ GesturePalmRecognize_FlickVertical(int type,int idx) XDBG_DEBUG(MGEST, "recognized_palm= 0x%x, palm_filter_mask= 0x%x\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask); XDBG_DEBUG(MGEST, "num_pressed: %d, cur_touched: %d, palm_flag: %d, single_timer_expired: %d\n", num_pressed, pPalm->cur_touched, pPalm->palmflag, pPalm->single_timer_expired); #endif + + if( idx < 0 ) + goto flick_failed; + if(g_pGesture->enqueue_fulled == 1) { #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "EQ Event is full.... palm recognize drop..\n"); + XDBG_DEBUG(MGEST, "EQ Event is full.... No palm recognize drop..\n"); #endif goto flick_failed; } - - if(g_pGesture->recognized_gesture || (g_pGesture->recognized_palm && !(g_pGesture->recognized_palm & PalmFlickVertiFilterMask)) || (g_pGesture->palm_filter_mask & PalmFlickVertiFilterMask) + if(g_pGesture->recognized_gesture || g_pGesture->hold_detected || + (g_pGesture->recognized_palm && !(g_pGesture->recognized_palm & PalmFlickVertiFilterMask)) || (g_pGesture->palm_filter_mask & PalmFlickVertiFilterMask) #ifdef _F_SUPPORT_BEZEL_FLICK_ || g_pGesture->bezel_recognized_mask) #else @@ -3460,11 +3182,16 @@ GesturePalmRecognize_FlickVertical(int type,int idx) XDBG_DEBUG(MGEST, "[P] Base_height=%d, base_y=%d, line_idx=%d\n", base_height_size, base_y, line_idx); #endif if(line_idx < 0) + { +#ifdef __PALM_GESTURE_LOG__ + XDBG_DEBUG(MGEST, "[P] No Base_height=%d, base_y=%d, line_idx=%d\n", base_height_size, base_y, line_idx); +#endif goto flick_failed; + } verti_line[line_idx] = 1; pass_count++; - press_idx = prev_line_idx = line_idx; + prev_line_idx = line_idx; release_flag = 0; #ifdef __PALM_GESTURE_LOG__ XDBG_DEBUG(MGEST, "[P] Base_height=%d, base_y=%d, line_idx=%d\n", base_height_size, base_y, line_idx); @@ -3510,7 +3237,12 @@ GesturePalmRecognize_FlickVertical(int type,int idx) #endif if(line_idx < 0) + { +#ifdef __PALM_GESTURE_LOG__ + XDBG_DEBUG(MGEST, "[M] No line_idx: %d\n", line_idx); +#endif goto flick_failed; + } if((prev_line_idx != line_idx) && verti_line[line_idx] && !release_flag) { #ifdef __PALM_GESTURE_LOG__ @@ -3518,7 +3250,7 @@ GesturePalmRecognize_FlickVertical(int type,int idx) #endif goto flick_failed; } - +#if 0 if(pPalm->max_touched == 1) { if(ABS(AREA_CENTER_X(&pPalm->area.extents) - base_cx) > PALM_FLICK_VERTI_MAX_MOVE_X) @@ -3529,7 +3261,7 @@ GesturePalmRecognize_FlickVertical(int type,int idx) goto flick_failed; } } - +#endif verti_line[line_idx] = 1; if(prev_line_idx != line_idx) pass_count++; @@ -3545,7 +3277,8 @@ GesturePalmRecognize_FlickVertical(int type,int idx) XDBG_DEBUG(MGEST, "[M] duration =%d !\n", duration); #endif - if(!pPalm->palmflag && (duration >= PALM_FLICK_INITIAL_TIMEOUT)) + if(!pPalm->palmflag && (pPalm->biggest_tmajor < PALM_FLICK_TOUCH_MAJOR-20) && (pPalm->biggest_wmajor < PALM_FLICK_TOUCH_MAJOR-20) + && (duration >= PALM_FLICK_INITIAL_TIMEOUT)) { #ifdef __PALM_GESTURE_LOG__ XDBG_DEBUG(MGEST, "[M] No flick !(initial flick timeout : duration=%d)\n", duration); @@ -3571,17 +3304,16 @@ GesturePalmRecognize_FlickVertical(int type,int idx) case ET_ButtonRelease: release_flag = 1; - if(pPalm->cur_touched) - break; if(--num_pressed < 0) num_pressed = 0; if(num_pressed) break; - if(!pPalm->palmflag) + + if(!pPalm->palmflag && (pPalm->biggest_tmajor < 100) && (pPalm->bigger_wmajor < 100)) { #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[R] num_pressed is 0\n"); + XDBG_DEBUG(MGEST, "[R] No flick (No palm comming and all finger release))\n"); #endif goto flick_failed; } @@ -3597,7 +3329,12 @@ GesturePalmRecognize_FlickVertical(int type,int idx) #endif if(line_idx < 0) + { +#ifdef __PALM_GESTURE_LOG__ + XDBG_DEBUG(MGEST, "[R] No line_idx: %d\n", line_idx); +#endif goto flick_failed; + } #ifdef __PALM_GESTURE_LOG__ XDBG_DEBUG(MGEST, "[R] duration=%d, disty=%d\n", duration, disty); #endif @@ -3616,10 +3353,10 @@ GesturePalmRecognize_FlickVertical(int type,int idx) #endif goto flick_failed; } - if(pPalm->biggest_tmajor < PALM_FLICK_TOUCH_MAJOR) + if(pPalm->biggest_tmajor < PALM_FLICK_TOUCH_MAJOR && pPalm->biggest_wmajor < PALM_FLICK_TOUCH_MAJOR) { #ifdef __PALM_GESTURE_LOG__ - XDBG_DEBUG(MGEST, "[R] No flick !(flick touch major(%.f < %d) is small!)\n", pPalm->biggest_tmajor, PALM_FLICK_TOUCH_MAJOR); + XDBG_DEBUG(MGEST, "[R] No flick !(flick touch major(%.f) width major(%.f) < %d) is small!)\n", pPalm->biggest_tmajor, pPalm->biggest_wmajor, PALM_FLICK_TOUCH_MAJOR); #endif goto flick_failed; } @@ -3691,7 +3428,7 @@ GesturePalmGetScreenInfo() pixman_region_init(&tarea); pixman_region_init_rect(&tarea, 0, 0, pPalmMisc->scrn_width, pPalmMisc->scrn_height); pPalmMisc->half_scrn_area_size = AREA_SIZE(&tarea.extents); - pPalmMisc->half_scrn_area_size = (unsigned int)((double)pPalmMisc->half_scrn_area_size / 2); + pPalmMisc->half_scrn_area_size = (unsigned int)((double)pPalmMisc->half_scrn_area_size / 2.4f); #ifdef __HOLD_DETECTOR_DEBUG__ XDBG_DEBUG(MGEST, "pPalmMisc->half_scrn_area_size = %d\n", pPalmMisc->half_scrn_area_size); #endif//__HOLD_DETECTOR_DEBUG__ @@ -3734,6 +3471,7 @@ GesturePalmGetAbsAxisInfo(DeviceIntPtr dev) Atom atom_mt_slot; Atom atom_tracking_id; Atom atom_distance; + Atom atom_mt_tool; g_pGesture->wmajor_idx = -1; g_pGesture->tmajor_idx = -1; @@ -3742,6 +3480,7 @@ GesturePalmGetAbsAxisInfo(DeviceIntPtr dev) g_pGesture->tpalm_idx = -1; g_pGesture->mt_px_idx = -1; g_pGesture->mt_py_idx = -1; + g_pGesture->mt_tool_idx = -1; memset(&g_pGesture->palm, 0, sizeof(PalmStatus)); @@ -3762,12 +3501,17 @@ GesturePalmGetAbsAxisInfo(DeviceIntPtr dev) atom_mt_slot = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_SLOT); atom_tracking_id = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TRACKING_ID); atom_distance = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_DISTANCE); + atom_mt_tool = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOOL_TYPE); if (!numAxes || !atom_mt_px || !atom_mt_py || !atom_tmajor || !atom_tminor || !atom_tangle || !atom_tpalm) { XDBG_WARNING(MGEST, "one or more axes is/are not supported!\n"); goto out; } + if (!atom_mt_tool) + { + XDBG_WARNING(MGEST, "multitouch various type was not supported\n"); + } for( i = 0 ; i < numAxes ; i++ ) { @@ -3811,12 +3555,21 @@ GesturePalmGetAbsAxisInfo(DeviceIntPtr dev) g_pGesture->tpalm_idx = i; found += 7; } + else if ( atom_mt_tool && axes->label == atom_mt_tool ) + { + g_pGesture->mt_tool_idx = i; + found += 8; + } } - if (found != 28) + if (found != 36) { - XDBG_WARNING(MGEST, "Axes for palm recognization are not supported !\n"); - goto out; + XDBG_WARNING(MGEST, "Various multitouch devices are not supported !\n"); + if (found != 28) + { + XDBG_WARNING(MGEST, "Axes for palm recognization are not supported !\n"); + goto out; + } } pPalm = &g_pGesture->palm; @@ -4140,18 +3893,12 @@ GesturePalmRecognize(int type, InternalEvent *ev, DeviceIntPtr device) int idx = -1; PalmStatusPtr pPalm = &g_pGesture->palm; static int calc_touched = 0; + static int event_sum_palm_first_finger = 0, event_sum_palm_second_finger=0; if( device->id < g_pGesture->first_fingerid ) return; - for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ ) - { - if( device->id == g_pGesture->mt_devices[i]->id ) - { - idx = i; - break; - } - } + idx = GestureGetFingerIndexFromDevice(device); if( idx < 0 ) return; @@ -4161,22 +3908,39 @@ GesturePalmRecognize(int type, InternalEvent *ev, DeviceIntPtr device) if(!g_pGesture->pTempPalmWin) { g_pGesture->pTempPalmWin = GestureGetEventsWindow(); - if(!g_pGesture->pTempPalmWin) + if(!g_pGesture->pTempPalmWin || g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL) { #ifdef __PALM_DETAIL_LOG__ XDBG_DEBUG(MGEST, "No events are grabbed/selected !\n"); #endif//__PALM_DETAIL_LOG__ - g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL; - goto flush_or_drop; - } - } - GesturePalmDataUpdate(idx, type, ev, device); - GesturePalmUpdateAreaInfo(type, idx); - + g_pGesture->no_palm_events = TRUE; + if (g_pGesture->palm_rejection_mode == 0) + { + g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL; + goto flush_or_drop; + } + else + { + g_pGesture->palm_filter_mask = 0; + } + } + } + GesturePalmDataUpdate(idx, type, ev, device); + GesturePalmUpdateAreaInfo(type, idx); +#ifdef __PALM_DETAIL_LOG__ + XDBG_DEBUG(MGEST, "[idx: %d: %d](%d, %d)max_tmajor: %lf, palmflag: %d, max_wmajor: %lf\n", idx, type, pPalm->pti[idx].x, pPalm->pti[idx].y, pPalm->max_tmajor, pPalm->palmflag, pPalm->max_wmajor); + XDBG_DEBUG(MGEST, "bigger_wmajor: %lf, biggest_tmajor: %lf, biggest_wmajor: %lf\n", pPalm->bigger_wmajor, pPalm->biggest_tmajor, pPalm->biggest_wmajor); + XDBG_DEBUG(MGEST, "area: %d, deviationX: %lf, deviationY: %lf, dispersionX: %lf, dispersion: %lf\n", pPalm->area, pPalm->deviationX, pPalm->deviationY, pPalm->dispersionX, pPalm->dispersionY); +#endif switch(type) { case ET_ButtonPress: + if( idx == 0 ) + event_sum_palm_first_finger = BTN_PRESSED; + else if( idx == 1) + event_sum_palm_second_finger = BTN_PRESSED; pPalm->max_touched++; + if( g_pGesture->num_pressed == 1 ) { pPalm->palm_single_finger_timer = TimerSet(pPalm->palm_single_finger_timer, 0, 50, GesturePalmSingleFingerTimerHandler, NULL); @@ -4187,9 +3951,83 @@ GesturePalmRecognize(int type, InternalEvent *ev, DeviceIntPtr device) } break; case ET_Motion: - if(pPalm->cur_touched == 0) + if(pPalm->cur_touched == 0 || pPalm->pti[idx].touch_status != 1) { - break; + return; + } + if((pPalm->cur_touched == 1 && idx == 0 && event_sum_palm_first_finger == BTN_PRESSED) || + (pPalm->cur_touched == 2 && idx == 1 && event_sum_palm_second_finger == BTN_PRESSED)) + { + if(idx == 0) + { + event_sum_palm_first_finger = BTN_MOVING; +#ifdef __PALM_DETAIL_LOG__ + XDBG_DEBUG(MGEST, "First move detected!\n"); +#endif//__PALM_DETAIL_LOG__ + } + else // idx == 1 + { + event_sum_palm_second_finger = BTN_MOVING; +#ifdef __PALM_DETAIL_LOG__ + XDBG_DEBUG(MGEST, "Second finger First move detected!\n"); +#endif//__PALM_DETAIL_LOG__ + } + if (pPalm->palmflag < 1 && pPalm->biggest_tmajor < g_pGesture->palm_min_touch_major && pPalm->biggest_wmajor < g_pGesture->palm_min_width_major) + { +#ifdef __PALM_DETAIL_LOG__ + XDBG_DEBUG(MGEST, "No palm coming.\n"); +#endif//__PALM_DETAIL_LOG__ + Bool exist; + exist = GestureIsPalmEventInMIEQ(); +#ifdef __PALM_DETAIL_LOG__ + XDBG_DEBUG(MGEST, "palm event exist: %d\n", exist); +#endif//__PALM_DETAIL_LOG__ + + if (exist) + { + pPalm->palmflag = 1; + g_pGesture->palm_detected = TRUE; + } + else + { + /* + * The following is the bezel condition for palm + * -- palm touch area can be smaller than that of non-bezel regions, so the threshold value is reduced. + */ + if(!(g_pGesture->palm_filter_mask & PalmFlickHorizFilterMask) && + (pPalm->cx >= g_pGesture->screen_width - g_pGesture->palm_bezel || pPalm->cx < g_pGesture->palm_bezel) && + (pPalm->biggest_tmajor >= g_pGesture->palm_min_touch_major_bezel || pPalm->biggest_wmajor >= g_pGesture->palm_min_width_major_bezel)) + { + g_pGesture->palm_detected = TRUE; + break; + } + if(!(g_pGesture->palm_filter_mask & PalmFlickVertiFilterMask) && + (pPalm->cy >= g_pGesture->screen_height - g_pGesture->palm_bezel || pPalm->cy < g_pGesture->palm_bezel) && + (pPalm->biggest_tmajor >= g_pGesture->palm_min_touch_major_bezel || pPalm->biggest_wmajor >= g_pGesture->palm_min_width_major_bezel)) + { + g_pGesture->palm_detected = TRUE; + break; + } + + if (g_pGesture->palm_rejection_mode == 1 && g_pGesture->no_palm_events == TRUE) + g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL; + g_pGesture->recognized_palm = 0; + if(!(g_pGesture->palm_filter_mask & PalmFlickHorizFilterMask)) + { + GesturePalmRecognize_FlickHorizen(type, -1); + } + if(!(g_pGesture->palm_filter_mask & PalmFlickVertiFilterMask)) + { + GesturePalmRecognize_FlickVertical(type, -1); + } + if (g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL) + goto flush_or_drop; + } + } + else + { + g_pGesture->palm_detected = TRUE; + } } calc_touched++; if(calc_touched == pPalm->cur_touched) @@ -4198,12 +4036,22 @@ GesturePalmRecognize(int type, InternalEvent *ev, DeviceIntPtr device) } break; case ET_ButtonRelease: + if( idx == 0 ) + event_sum_palm_first_finger = BTN_RELEASED; + else if( idx == 1) + event_sum_palm_second_finger = BTN_RELEASED; if(calc_touched) { calc_touched--; } break; } + if( g_pGesture->palm_rejection_mode == 1 && g_pGesture->palm_detected == TRUE && g_pGesture->no_palm_events == TRUE) + { + g_pGesture->recognized_palm = 0; + g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL; + goto flush_or_drop; + } if( GestureHasFingerEventMask(GestureNotifyFlick, 0) ) { @@ -4216,13 +4064,6 @@ GesturePalmRecognize(int type, InternalEvent *ev, DeviceIntPtr device) GesturePalmRecognize_FlickVertical(type, idx); } } - if( GestureHasFingerEventMask(GestureNotifyHold, 0) ) - { - if(!(g_pGesture->palm_filter_mask & PalmHoldFilterMask)) - { - GesturePalmRecognize_Hold(type, idx, 0); - } - } if(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL) { @@ -4485,6 +4326,188 @@ bezel_cleanup: } #endif +static EventQueuePtr +GestureGetMIEQ(void) +{ + if (*checkForInput[0] == *checkForInput[1]) + { +#ifdef __DETAIL_DEBUG__ + XDBG_DEBUG(MGEST, "mieq is empty !\n"); +#endif//__DETAIL_DEBUG__ + return NULL; + } + + EventQueuePtr mieqEQPtr = NULL; + mieqEQPtr = mieqGetEventQueuePtr(); + + if (!mieqEQPtr) + { +#ifdef __DETAIL_DEBUG__ + XDBG_DEBUG(MGEST, "mieqEQPtr is NULL !\n"); +#endif//__DETAIL_DEBUG__ + + return NULL; + } + + int num = mieqNumEnqueued(mieqEQPtr); +#ifdef __DETAIL_DEBUG__ + XDBG_DEBUG(MGEST, " num of event in mieq = %d\n", num); +#endif//__DETAIL_DEBUG__ + if (num <= 0) + return NULL; + + return mieqEQPtr; +} + +static Bool +GestureIsEventInMIEQ(int finger_index, enum EventType type) +{ + EventQueuePtr mieqEQPtr = NULL; + mieqEQPtr = GestureGetMIEQ(); + if (!mieqEQPtr) + { +#ifdef __DETAIL_DEBUG__ + XDBG_DEBUG(MGEST, "failed to get mieq\n"); +#endif//__DETAIL_DEBUG__ + return FALSE; + } + + int deviceid = GestureGetDeviceIdFromFingerIndex(finger_index); + if (deviceid < 0) + { + XDBG_ERROR(MGEST, "Failed to get deviceid from finger index !\n"); + return FALSE; + } + + EventRec *e = NULL; + static InternalEvent event; + HWEventQueueType head, tail; + head = mieqEQPtr->head; + tail = mieqEQPtr->tail; + + while (head != tail) + { + e = &mieqEQPtr->events[head]; + if (e) + { + event = *e->events; + + if (e->pDev && (deviceid == e->pDev->id) && (event.any.type == type)) + { + return TRUE; + } + } + + head = (head + 1) % mieqEQPtr->nevents; + } + + return FALSE; +} + +static Bool +GestureIsPalmEventInMIEQ(void) +{ + EventQueuePtr mieqEQPtr = NULL; + mieqEQPtr = GestureGetMIEQ(); + if (!mieqEQPtr) + { +#ifdef __PALM_DETAIL_LOG__ + XDBG_DEBUG(MGEST, "failed to get mieq\n"); +#endif//__PALM_DETAIL_LOG__ + return FALSE; + } + + EventRec *e = NULL; + static InternalEvent event; + HWEventQueueType head, tail; + head = mieqEQPtr->head; + tail = mieqEQPtr->tail; + + while (head != tail) + { + e = &mieqEQPtr->events[head]; + if (e) + { + event = *e->events; + + if (GestureIsPalmEvent(&event)) + { + return TRUE; + } + } + + head = (head + 1) % mieqEQPtr->nevents; + } + + return FALSE; +} + +static Bool +GestureIsPalmEvent(InternalEvent *event) +{ + int wmajor_idx = g_pGesture->wmajor_idx; + int tmajor_idx = g_pGesture->tmajor_idx; + int tpalm_idx = g_pGesture->tpalm_idx; + + double width_major = 0.0f; + double touch_major = 0.0f; + double touch_palm = 0.0f; + + if (event->any.type != ET_ButtonPress && event->any.type != ET_Motion && event->any.type != ET_ButtonRelease) + return FALSE; + + DeviceEvent *de = &event->device_event; + + if (!de || !de->valuators.data) + { + XDBG_WARNING(MGEST, "de or de->valuators.data are NULL !\n"); + return FALSE; + } + + if ((wmajor_idx < 0) || (tmajor_idx < 0) || (tpalm_idx < 0)) + { + XDBG_WARNING(MGEST, "One or more of axes are not supported !\n"); + return FALSE; + } + + width_major = de->valuators.data[wmajor_idx]; + touch_major = de->valuators.data[tmajor_idx]; + touch_palm = de->valuators.data[tpalm_idx]; +#ifdef __PALM_DETAIL_LOG__ + XDBG_DEBUG(MGEST, "width_major: %.f, touch_major: %.f, touch_palm: %.f\n", width_major, touch_major, touch_palm); +#endif//__PALM_DETAIL_LOG__ + + if (touch_palm >= 1 || touch_major >= g_pGesture->palm_min_touch_major || width_major >= g_pGesture->palm_min_width_major) + return TRUE; + return FALSE; +} + +static int +GestureGetFingerIndexFromDevice(DeviceIntPtr device) +{ + int i; + + for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ ) + { + if( device->id == g_pGesture->mt_devices[i]->id ) + { + return i; + } + } + + return -1; +} + +static int +GestureGetDeviceIdFromFingerIndex(int finger_index) +{ + if (g_pGesture->num_mt_devices <= finger_index) + return -1; + + return g_pGesture->mt_devices[finger_index]->id; +} + + void GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device) { @@ -4496,14 +4519,7 @@ GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device) device->id < g_pGesture->first_fingerid ) return; - for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ ) - { - if( device->id == g_pGesture->mt_devices[i]->id ) - { - idx = i; - break; - } - } + idx = GestureGetFingerIndexFromDevice(device); if( idx < 0 ) return; @@ -4531,7 +4547,7 @@ GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device) if( g_pGesture->num_pressed == 1 ) { - single_finger_timer = TimerSet(single_finger_timer, 0, g_pGesture->singlefinger_threshold, GestureSingleFingerTimerHandler, NULL); + single_finger_timer = TimerSet(single_finger_timer, 0, g_pGesture->tap_repeated ? 80 : g_pGesture->singlefinger_threshold, GestureSingleFingerTimerHandler, NULL); } else { @@ -4545,7 +4561,7 @@ GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device) { g_pGesture->pTempWin = GestureGetEventsWindow(); - if( NULL == g_pGesture->pTempWin ) + if( NULL == g_pGesture->pTempWin || g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL) { #ifdef __DETAIL_DEBUG__ XDBG_DEBUG(MGEST, "[g_pGesture->num_pressed=%d] No events were selected !\n", g_pGesture->num_pressed); @@ -4562,82 +4578,96 @@ GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device) g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT; g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT; - if( g_pGesture->inc_num_pressed == 1 ) + pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]); + for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ ) { - pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]); -#ifdef __DETAIL_DEBUG__ - XDBG_DEBUG(MGEST, "[P][g_pGesture->inc_num_pressed=1] AREA_SIZE(area.extents)=%d\n", AREA_SIZE(&g_pGesture->area.extents)); -#endif//__DETAIL_DEBUG__ + pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]); } - else - { - pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]); - for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ ) - { - pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]); - } #ifdef __DETAIL_DEBUG__ - XDBG_DEBUG(MGEST, "[P][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area.extents)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents)); + XDBG_DEBUG(MGEST, "[M][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents)); #endif//__DETAIL_DEBUG__ - } break; case ET_Motion: if( !g_pGesture->fingers[idx].ptime ) return; + + g_pGesture->fingers[idx].mx = ev->device_event.root_x; + g_pGesture->fingers[idx].my = ev->device_event.root_y; + if( (g_pGesture->inc_num_pressed < 2) && (idx == 0)) { g_pGesture->event_sum[0] += BTN_MOVING; #ifdef __DETAIL_DEBUG__ XDBG_DEBUG(MGEST, "no seconds finger comming\n"); #endif//__DETAIL_DEBUG__ - - // tolerate false motion events only when second double-finger press is applied if(!g_pGesture->tap_repeated) { + if(g_pGesture->event_sum[0] >= 3) + { #ifdef __DETAIL_DEBUG__ - XDBG_DEBUG(MGEST, "single finger!\n"); + XDBG_DEBUG(MGEST, "single finger!\n"); #endif//__DETAIL_DEBUG__ - g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL; - goto flush_or_drop; + Bool exist; + exist = GestureIsEventInMIEQ(1, ET_ButtonPress); +#ifdef __DETAIL_DEBUG__ + XDBG_DEBUG(MGEST, "two finger touch in queue, exist: %d\n", exist); +#endif//__DETAIL_DEBUG__ + if (exist) + g_pGesture->event_sum[0] -= BTN_MOVING; + else + { + g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL; + goto flush_or_drop; + } + } } - else if(g_pGesture->event_sum[0] >= 7) + else { + if(ABS(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) > FINGER_WIDTH + || ABS(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) > FINGER_HEIGHT) + { #ifdef __DETAIL_DEBUG__ - XDBG_DEBUG(MGEST, "tap repeat Moving Limit Exceeded.\n"); + XDBG_DEBUG(MGEST, "tap repeat Moving Limit Exceeded.\n"); #endif//__DETAIL_DEBUG__ - g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL; - goto flush_or_drop; + g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL; + goto flush_or_drop; + } + else if(g_pGesture->event_sum[0] >= 15) + { +#ifdef __DETAIL_DEBUG__ + XDBG_DEBUG(MGEST, "tap repeat Moving Limit Exceeded.\n"); +#endif//__DETAIL_DEBUG__ + Bool exist; + exist = GestureIsEventInMIEQ(1, ET_ButtonPress); +#ifdef __DETAIL_DEBUG__ + XDBG_DEBUG(MGEST, "two finger touch in queue, exist: %d\n", exist); +#endif//__DETAIL_DEBUG__ + if (exist) + g_pGesture->event_sum[0] -= BTN_MOVING; + else + { + g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL; + goto flush_or_drop; + } + } } } - g_pGesture->fingers[idx].mx = ev->device_event.root_x; - g_pGesture->fingers[idx].my = ev->device_event.root_y; - g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH; g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH; g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT; g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT; - if( g_pGesture->inc_num_pressed == 1 ) + pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]); + for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ ) { - pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]); -#ifdef __DETAIL_DEBUG__ - XDBG_DEBUG(MGEST, "[M][g_pGesture->inc_num_pressed=1] AREA_SIZE(area)=%d\n", AREA_SIZE(&g_pGesture->area.extents)); -#endif//__DETAIL_DEBUG__ + pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]); } - else - { - pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]); - for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ ) - { - pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]); - } #ifdef __DETAIL_DEBUG__ - XDBG_DEBUG(MGEST, "[M][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents)); + XDBG_DEBUG(MGEST, "[M][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents)); #endif//__DETAIL_DEBUG__ - } break; case ET_ButtonRelease: @@ -4712,7 +4742,7 @@ GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device) return; flush_or_drop: - + TimerCancel(single_finger_timer); #ifdef __DETAIL_DEBUG__ XDBG_DEBUG(MGEST, "GestureFlushOrDrop() !\n"); #endif//__DETAIL_DEBUG__ @@ -4768,10 +4798,16 @@ ErrorStatus GestureFlushOrDrop(void) #endif { g_pGesture->ehtype = PROPAGATE_EVENTS; - err = GestureEventsFlush(); - if( ERROR_NONE != err ) - return err; - + if (g_pGesture->palm_rejection_mode == 1 && g_pGesture->palm_detected == TRUE) + { + GestureEventsDrop(); + } + else + { + err = GestureEventsFlush(); + if( ERROR_NONE != err ) + return err; + } err = GestureRegionsReinit(); for(i=0; inum_mt_devices ; i++ ) g_pGesture->fingers[i].ptime = 0; } + g_pGesture->stylusInfo.stylus_id = 0; + g_pGesture->stylusInfo.pen_detected = FALSE; + g_pGesture->no_palm_events = FALSE; + g_pGesture->stylusInfo.fake_events = FALSE; + g_pGesture->palm_detected = FALSE; + } + else if( MTOUCH_FRAME_SYNC_END == ev->any_event.sync ) + { +#ifdef __DEBUG_EVENT_HANDLER__ + XDBG_DEBUG(MGEST, "SYNC_END\n"); +#endif//__DEBUG_EVENT_HANDLER + g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_END; + + if(g_pGesture->is_active) + { + g_pGesture->ehtype = PROPAGATE_EVENTS; + g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL; + pPalm->cur_touched = 0; + pPalm->palmflag = 0; + pPalm->max_palm = 0; + g_pGesture->pTempPalmWin = NULL; + if(pPalm->palm_single_finger_timer) + TimerCancel(pPalm->palm_single_finger_timer); + g_pGesture->pTempWin = NULL; + g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0; + g_pGesture->event_sum[0] = 0; + pPalm->max_touched = 0; + g_pGesture->hold_detected = FALSE; +#ifdef _F_SUPPORT_BEZEL_FLICK_ + pBezel->is_active = BEZEL_END; + g_pGesture->bezel_filter_mask = BezelFlickFilterMask; +#endif + } + for(i=0; istylusInfo.t_status[i].status = BTN_RELEASED; + } + } +} + +static int +GestureGetMTToolValuator(InternalEvent *ev, DeviceIntPtr device) +{ + int mt_tool_idx = g_pGesture->mt_tool_idx; + double mt_tool = 0.0f; + + DeviceEvent *de = &ev->device_event; + + if (!de || !de->valuators.data) + { + XDBG_WARNING(MGEST, "de or de->valuators.data are NULL !\n"); + return -1; + } + + if (mt_tool_idx < 0) + { + XDBG_WARNING(MGEST, "One or more of axes are not supported !\n"); + return -1; + } + + if (ev->any.type == ET_ButtonPress || ev->any.type == ET_ButtonRelease) + { + if (device->id == g_pGesture->master_pointer->id && g_pGesture->stylusInfo.stylus_id == g_pGesture->first_fingerid) + de->valuators.data[mt_tool_idx] = 1; + + if (g_pGesture->stylusInfo.stylus_id == device->id) + de->valuators.data[mt_tool_idx] = 1; + } + + mt_tool = de->valuators.data[mt_tool_idx]; + + return (int)mt_tool; +} + +static void +GestureRegisterTouchInfo(InternalEvent *ev, DeviceIntPtr device) +{ + int idx; + + idx = GestureGetFingerIndexFromDevice(device); + if (idx < 0) + { + if (device->id != g_pGesture->master_pointer->id) + XDBG_WARNING(MGEST, "Failed to get correct idx(%d) device->id: %d, master_pointer: %d\n", idx, device->id, g_pGesture->master_pointer->id); + return; + } + switch(ev->any.type) + { + case ET_ButtonPress: + g_pGesture->stylusInfo.t_status[idx].status = BTN_PRESSED; + break; + case ET_Motion: + if (g_pGesture->stylusInfo.t_status[idx].status == BTN_PRESSED) + g_pGesture->stylusInfo.t_status[idx].status = BTN_MOVING; + break; + case ET_ButtonRelease: + g_pGesture->stylusInfo.t_status[idx].status = BTN_RELEASED; + break; + default: + XDBG_WARNING(MGEST, "unhandled event type(%d)\n", ev->any.type); + break; + } + g_pGesture->stylusInfo.t_status[idx].cx = ev->device_event.root_x; + g_pGesture->stylusInfo.t_status[idx].cy = ev->device_event.root_y; +} + +static void +GestureSetToolData(InternalEvent *ev, double val_tool) +{ + int mt_tool_idx = g_pGesture->mt_tool_idx; + double mt_tool = 0.0f; + + DeviceEvent *de = &ev->device_event; + + if (!de || !de->valuators.data) + { + XDBG_WARNING(MGEST, "de or de->valuators.data are NULL !\n"); + return; + } + + if (mt_tool_idx < 0) + { + XDBG_WARNING(MGEST, "One or more of axes are not supported !\n"); + return; + } + de->valuators.data[mt_tool_idx] = val_tool; +} + +static void +GestureCleanupTouch(int screen_num, InternalEvent *ev, DeviceIntPtr device) +{ + ErrorStatus err; + int i; + if (g_pGesture->stylusInfo.stylus_id == 0 && g_pGesture->stylusInfo.pen_detected == FALSE) + g_pGesture->stylusInfo.stylus_id = device->id; + + if (g_pGesture->ehtype == KEEP_EVENTS) + { + GestureEventsDrop(); + g_pGesture->ehtype = PROPAGATE_EVENTS; } - else if( MTOUCH_FRAME_SYNC_END == ev->any_event.sync ) + else if (g_pGesture->stylusInfo.pen_detected == FALSE && g_pGesture->ehtype == PROPAGATE_EVENTS) { -#ifdef __DEBUG_EVENT_HANDLER__ - XDBG_DEBUG(MGEST, "SYNC_END\n"); -#endif//__DEBUG_EVENT_HANDLER - g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_END; - - if(g_pGesture->is_active) + g_pGesture->stylusInfo.pen_detected = TRUE; + g_pGesture->stylusInfo.fake_events = TRUE; + for(i=0; iehtype = PROPAGATE_EVENTS; - g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL; - pPalm->cur_touched = 0; - pPalm->palmflag = 0; - pPalm->max_palm = 0; - g_pGesture->pTempPalmWin = NULL; - if(pPalm->palm_single_finger_timer) - TimerCancel(pPalm->palm_single_finger_timer); - g_pGesture->pTempWin = NULL; - g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0; - g_pGesture->event_sum[0] = 0; - pPalm->max_touched = 0; -#ifdef _F_SUPPORT_BEZEL_FLICK_ - pBezel->is_active = BEZEL_END; - g_pGesture->bezel_filter_mask = BezelFlickFilterMask; -#endif + if (g_pGesture->stylusInfo.t_status[i].status == BTN_PRESSED || g_pGesture->stylusInfo.t_status[i].status == BTN_MOVING) + { + InternalEvent release_ev; + memcpy(&release_ev, ev, sizeof(InternalEvent)); + release_ev.any.time = ev->any.time; + release_ev.any.type = ET_ButtonRelease; + + release_ev.device_event.detail.button = 1; + release_ev.device_event.type = ET_ButtonRelease; + release_ev.device_event.root_x = g_pGesture->stylusInfo.t_status[i].cx; + release_ev.device_event.root_y = g_pGesture->stylusInfo.t_status[i].cy; + release_ev.device_event.deviceid = g_pGesture->mt_devices[i]->id; + g_pGesture->stylusInfo.t_status[i].status = BTN_RELEASED; + GestureSetToolData(&release_ev, (double)0); + + GestureHandleButtonReleaseEvent(screen_num, &release_ev, g_pGesture->mt_devices[i]); + if (g_pGesture->mt_devices[i]->id == g_pGesture->first_fingerid) + { + InternalEvent release_mev; + memcpy(&release_mev, ev, sizeof(InternalEvent)); + release_mev.any.time = ev->any.time; + release_mev.any.type = ET_ButtonRelease; + + release_mev.device_event.detail.button = 1; + release_mev.device_event.type = ET_ButtonRelease; + release_mev.device_event.root_x = g_pGesture->stylusInfo.t_status[i].cx; + release_mev.device_event.root_y = g_pGesture->stylusInfo.t_status[i].cy; + release_mev.device_event.deviceid = g_pGesture->master_pointer->id; + GestureSetToolData(&release_mev, (double)0); + + GestureHandleButtonReleaseEvent(screen_num, &release_mev, g_pGesture->master_pointer); + } + } } + g_pGesture->stylusInfo.fake_events = FALSE; + } + g_pGesture->stylusInfo.pen_detected = TRUE; + g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL; + g_pGesture->recognized_gesture = 0; + g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL; + g_pGesture->recognized_palm = 0; +} + +static void +GestureChangeEventToFirstFingerEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) +{ + InternalEvent master_ev; + ev->device_event.deviceid = g_pGesture->first_fingerid; + + switch(ev->any.type) + { + case ET_ButtonPress: + if(!(device->id < g_pGesture->first_fingerid)) + g_pGesture->num_pressed++; + break; + case ET_ButtonRelease: + if(!(device->id < g_pGesture->first_fingerid)) + g_pGesture->num_pressed--; + break; + default: + break; } + memcpy(&master_ev, ev, sizeof(InternalEvent)); + g_pGesture->mt_devices[0]->public.processInputProc(ev, g_pGesture->mt_devices[0]); + + master_ev.device_event.deviceid = g_pGesture->master_pointer->id; + g_pGesture->master_pointer->public.processInputProc(&master_ev, g_pGesture->master_pointer); } void GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) { #ifdef __DEBUG_EVENT_HANDLER__ - XDBG_DEBUG(MGEST, "mode: %d devid=%d time:%d cur: %d\n", g_pGesture->ehtype, device->id, ev->any.time, GetTimeInMillis()); + XDBG_DEBUG(MGEST, "mode: %d devid=%d time:%d cur: %d (%d, %d)\n", + g_pGesture->ehtype, device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y); +#endif//__DEBUG_EVENT_HANDLER__ + + if (g_pGesture->stylus_able) + { + int isStylus = GestureGetMTToolValuator(ev, device); + +#ifdef __DEBUG_EVENT_HANDLER__ + XDBG_DEBUG(MGEST, "isSytlus: %d, pen_detected: %d, stylus_id: %d\n", isStylus, g_pGesture->stylusInfo.pen_detected, g_pGesture->stylusInfo.stylus_id); #endif//__DEBUG_EVENT_HANDLER__ + + if (g_pGesture->stylusInfo.pen_detected == FALSE) + { + if (!isStylus) + { + GestureRegisterTouchInfo(ev, device); + } + else + { + GestureCleanupTouch(screen_num, ev, device); + } + } + if (g_pGesture->stylusInfo.pen_detected == TRUE) + { + if (!isStylus || (device->id != g_pGesture->stylusInfo.stylus_id )) + { + if (!(g_pGesture->stylusInfo.stylus_id == g_pGesture->first_fingerid && device->id == g_pGesture->master_pointer->id)) + { + return; + } + } + else if (device->id != g_pGesture->first_fingerid) + { + GestureChangeEventToFirstFingerEvent(screen_num, ev, device); + return; + } + } + } + switch( g_pGesture->ehtype ) { case KEEP_EVENTS: @@ -4892,7 +5152,12 @@ GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr de if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL)) GestureRecognize(ET_ButtonPress, ev, device); if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL)) - GesturePalmRecognize(ET_ButtonPress, ev, device); + { + if (PalmRecognize) + _GESTUREPALMRECOGNIZE_(PalmRecognize, ET_ButtonPress, ev, device) + else + g_pGesture->ehtype = PROPAGATE_EVENTS; + } } else device->public.processInputProc(ev, device); @@ -4902,7 +5167,14 @@ GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr de case PROPAGATE_EVENTS: if(!(device->id < g_pGesture->first_fingerid)) g_pGesture->num_pressed++; - device->public.processInputProc(ev, device); + if (g_pGesture->palm_rejection_mode == 1 && g_pGesture->stylusInfo.pen_detected == TRUE) + { + device->public.processInputProc(ev, device); + } + else if (!(g_pGesture->palm_rejection_mode == 1 && g_pGesture->palm_detected == TRUE)) + { + device->public.processInputProc(ev, device); + } GestureHoldDetector(ET_ButtonPress, ev, device); break; @@ -4916,7 +5188,10 @@ GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr de if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL)) GestureRecognize(ET_ButtonPress, ev, device); if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL)) - GesturePalmRecognize(ET_ButtonPress, ev, device); + { + if (PalmRecognize) + _GESTUREPALMRECOGNIZE_(PalmRecognize, ET_ButtonPress, ev, device); + } break; default: @@ -4928,9 +5203,46 @@ void GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) { #ifdef __DEBUG_EVENT_HANDLER__ - XDBG_DEBUG(MGEST, "devid=%d time:%d cur: %d\n", device->id, ev->any.time, GetTimeInMillis()); + XDBG_DEBUG(MGEST, "mode: %d devid=%d time:%d cur: %d (%d, %d)\n", + g_pGesture->ehtype, device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y); +#endif//__DEBUG_EVENT_HANDLER__ + + if (g_pGesture->stylus_able) + { + int isStylus = GestureGetMTToolValuator(ev, device); + +#ifdef __DEBUG_EVENT_HANDLER__ + XDBG_DEBUG(MGEST, "isSytlus: %d, pen_detected: %d, stylus_id: %d\n", isStylus, g_pGesture->stylusInfo.pen_detected, g_pGesture->stylusInfo.stylus_id); #endif//__DEBUG_EVENT_HANDLER__ + if (g_pGesture->stylusInfo.pen_detected == FALSE) + { + if (!isStylus) + { + GestureRegisterTouchInfo(ev, device); + } + else + { + GestureCleanupTouch(screen_num, ev, device); + } + } + if (g_pGesture->stylusInfo.pen_detected == TRUE) + { + if (!isStylus || (device->id != g_pGesture->stylusInfo.stylus_id )) + { + if (!(g_pGesture->stylusInfo.stylus_id == g_pGesture->first_fingerid && device->id == g_pGesture->master_pointer->id)) + { + return; + } + } + else if (device->id != g_pGesture->first_fingerid) + { + GestureChangeEventToFirstFingerEvent(screen_num, ev, device); + return; + } + } + } + switch( g_pGesture->ehtype ) { case KEEP_EVENTS: @@ -4948,7 +5260,12 @@ GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL)) GestureRecognize(ET_Motion, ev, device); if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL)) - GesturePalmRecognize(ET_Motion, ev, device); + { + if (PalmRecognize) + _GESTUREPALMRECOGNIZE_(PalmRecognize, ET_Motion, ev, device) + else + g_pGesture->ehtype = PROPAGATE_EVENTS; + } } else device->public.processInputProc(ev, device); @@ -4956,7 +5273,14 @@ GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) break; case PROPAGATE_EVENTS: - device->public.processInputProc(ev, device); + if (g_pGesture->palm_rejection_mode == 1 && g_pGesture->stylusInfo.pen_detected == TRUE) + { + device->public.processInputProc(ev, device); + } + else if (!(g_pGesture->palm_rejection_mode == 1 && g_pGesture->palm_detected == TRUE)) + { + device->public.processInputProc(ev, device); + } GestureHoldDetector(ET_Motion, ev, device); break; @@ -4968,7 +5292,10 @@ GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL)) GestureRecognize(ET_Motion, ev, device); if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL)) - GesturePalmRecognize(ET_Motion, ev, device); + { + if (PalmRecognize) + _GESTUREPALMRECOGNIZE_(PalmRecognize, ET_Motion, ev, device); + } break; default: @@ -4981,8 +5308,50 @@ void GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) { #ifdef __DEBUG_EVENT_HANDLER__ - XDBG_DEBUG(MGEST, "devid=%d time:%d cur: %d\n", device->id, ev->any.time, GetTimeInMillis()); + XDBG_DEBUG(MGEST, "mode: %d devid=%d time:%d cur: %d (%d, %d)\n", + g_pGesture->ehtype, device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y); +#endif//__DEBUG_EVENT_HANDLER__ + + if (g_pGesture->stylus_able) + { + int isStylus = GestureGetMTToolValuator(ev, device); + +#ifdef __DEBUG_EVENT_HANDLER__ + XDBG_DEBUG(MGEST, "isSytlus: %d, pen_detected: %d, stylus_id: %d\n", isStylus, g_pGesture->stylusInfo.pen_detected, g_pGesture->stylusInfo.stylus_id); #endif//__DEBUG_EVENT_HANDLER__ + + if (g_pGesture->stylusInfo.pen_detected == FALSE) + { + if (!isStylus) + { + GestureRegisterTouchInfo(ev, device); + } + else + { + GestureCleanupTouch(screen_num, ev, device); + } + } + if (g_pGesture->stylusInfo.pen_detected == TRUE) + { + if (g_pGesture->stylusInfo.fake_events == TRUE) + { + goto deliver_event; + } + if (!isStylus || (device->id != g_pGesture->stylusInfo.stylus_id )) + { + if (!(g_pGesture->stylusInfo.stylus_id == g_pGesture->first_fingerid && device->id == g_pGesture->master_pointer->id)) + { + return; + } + } + else if (device->id != g_pGesture->first_fingerid) + { + GestureChangeEventToFirstFingerEvent(screen_num, ev, device); + return; + } + } + } +deliver_event: switch( g_pGesture->ehtype ) { case KEEP_EVENTS: @@ -5002,7 +5371,12 @@ GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL)) GestureRecognize(ET_ButtonRelease, ev, device); if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL)) - GesturePalmRecognize(ET_ButtonRelease, ev, device); + { + if (PalmRecognize) + _GESTUREPALMRECOGNIZE_(PalmRecognize, ET_ButtonRelease, ev, device) + else + g_pGesture->num_mt_devices = PROPAGATE_EVENTS; + } } else device->public.processInputProc(ev, device); @@ -5010,9 +5384,45 @@ GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr break; case PROPAGATE_EVENTS: +#ifdef SUPPORT_ANR_WITH_INPUT_EVENT + if( IsMaster(device) && ev->any.type == ET_ButtonRelease ) + { + if( g_pGesture->anr_window == NULL ) + { + g_pGesture->anr_window = _GestureFindANRWindow(device); + } + Time current_time; + + // Send event to the e17 process. + current_time = GetTimeInMillis(); + if( g_pGesture->anr_window != NULL ) + { + // Check anr_window validation. + if( dixLookupWindow(&g_pGesture->anr_window, prop_anr_event_window_xid, serverClient, DixSetPropAccess) != BadWindow ) + { + if( serverClient->devPrivates != NULL ) + dixChangeWindowProperty (serverClient, g_pGesture->anr_window, prop_anr_in_input_event, + XA_CARDINAL, 32, PropModeReplace, 1, ¤t_time, TRUE); + } + else + { + prop_anr_event_window_xid = 0; + g_pGesture->anr_window = NULL; + } + XDBG_DEBUG(MGEST, "Release TOUCH!! devid=%d time:%d cur: %d\n", device->id, ev->any.time, GetTimeInMillis()); + } + } +#endif if(!(device->id < g_pGesture->first_fingerid)) g_pGesture->num_pressed--; - device->public.processInputProc(ev, device); + if (g_pGesture->palm_rejection_mode == 1 && g_pGesture->stylusInfo.pen_detected == TRUE) + { + device->public.processInputProc(ev, device); + } + else if (!(g_pGesture->palm_rejection_mode == 1 && g_pGesture->palm_detected == TRUE)) + { + device->public.processInputProc(ev, device); + } GestureHoldDetector(ET_ButtonRelease, ev, device); break; @@ -5026,7 +5436,10 @@ GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL)) GestureRecognize(ET_ButtonRelease, ev, device); if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL)) - GesturePalmRecognize(ET_ButtonRelease, ev, device); + { + if (PalmRecognize) + _GESTUREPALMRECOGNIZE_(PalmRecognize, ET_ButtonRelease, ev, device); + } break; default: @@ -5040,6 +5453,7 @@ GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr devic #ifdef __DEBUG_EVENT_HANDLER__ XDBG_DEBUG(MGEST, "devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis()); #endif//__DEBUG_EVENT_HANDLER__ + static int find_dev_false_count = 0; if(DPMSPowerLevel == DPMSModeOff) { @@ -5065,16 +5479,46 @@ GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr devic } handle_keypress: + if (g_pGesture->touchkey_id <= 0 && find_dev_false_count < 10) + { + DeviceIntPtr dev; + find_dev_false_count++; + + for( dev = inputInfo.keyboard ; dev; dev = dev->next ) + { + if(strcasestr(dev->name, "touchkey")) + { + g_pGesture->touchkey_id = dev->id; + find_dev_false_count = 0; + break; + } + } + } if((g_pGesture->mtsync_status != MTOUCH_FRAME_SYNC_END) && (device->id == g_pGesture->touchkey_id)) { - XDBG_SECURE(MGEST, "Ignore TouchKey KeyPress (devid:%d, keycode:%d)\n", device->id, ev->device_event.detail.key); + if(ev->device_event.detail.key == 177) + XDBG_INFO(MGEST, "Ignore TouchKey KEY_MENU (devid:%d)\n", device->id); + else if (ev->device_event.detail.key == 166) + XDBG_INFO(MGEST, "Ignore TouchKey KEY_BACK (devid:%d)\n", device->id); + else + XDBG_SECURE(MGEST, "Ignore TouchKey KeyPress (devid:%d, keycode:%d)\n", device->id, ev->device_event.detail.key); return; } device->public.processInputProc(ev, device); } +void +GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) +{ + if (g_pGesture->pass_keycodes[3] == ev->device_event.detail.key) + { + XDBG_SECURE(MGEST, "TIME = %d, keycode = %d\n", ev->any.time, ev->device_event.detail.key); + } + device->public.processInputProc(ev, device); +} + static ErrorStatus GestureEnableEventHandler(InputInfoPtr pInfo) { @@ -5105,14 +5549,6 @@ GestureEnableEventHandler(InputInfoPtr pInfo) goto failed; } - pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 5000, GestureTimerHandler, pInfo); - - if( !pGesture->device_setting_timer ) - { - XDBG_ERROR(MGEST, "Failed to allocate memory for timer !\n"); - goto failed; - } - return ERROR_NONE; failed: @@ -5128,6 +5564,7 @@ GestureDisableEventHandler(void) ErrorStatus err = ERROR_NONE; mieqSetHandler(ET_KeyPress, NULL); + mieqSetHandler(ET_KeyRelease, NULL); mieqSetHandler(ET_ButtonPress, NULL); mieqSetHandler(ET_ButtonRelease, NULL); mieqSetHandler(ET_Motion, NULL); @@ -5146,14 +5583,24 @@ GestureDisableEventHandler(void) return err; } -static CARD32 -GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg) +static void +GestureRegisterDeviceInfo(DeviceIntPtr device) { - InputInfoPtr pInfo = (InputInfoPtr)arg; + InputInfoPtr pInfo = device->public.devicePrivate; GestureDevicePtr pGesture = pInfo->private; - - int idx = 0; DeviceIntPtr dev; + ScreenPtr pScreen = miPointerCurrentScreen(); + int width = 0, height = 0; + int idx = 0; + int i; + + XDBG_INFO(MGEST, "Get devices information\n"); + + for (i=0; imt_devices[i] = NULL; + } + for( dev = inputInfo.pointer ; dev; dev = dev->next ) { if(IsMaster(dev) && IsPointerDevice(dev)) @@ -5178,45 +5625,38 @@ GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg) MAX_MT_DEVICES); continue; } - pGesture->mt_devices[idx] = dev; - XDBG_INFO(MGEST, "[id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name); - GesturePalmGetAbsAxisInfo(dev); - idx++; - } - } - - for( dev = inputInfo.keyboard ; dev; dev = dev->next ) - { - if(strcasestr(dev->name, "touchkey")) - { - g_pGesture->touchkey_id = dev->id; - break; + if (strcasestr(dev->name, "Touchscreen")) + { + pGesture->mt_devices[idx] = dev; + XDBG_INFO(MGEST, "[id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name); + ErrorF("[id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name); + GesturePalmGetAbsAxisInfo(dev); + idx++; + } } } if( !pGesture->master_pointer || !pGesture->xtest_pointer ) { XDBG_ERROR(MGEST, "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; - return 0; + return; } - pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL); pGesture->num_mt_devices = idx; if( !pGesture->num_mt_devices ) { XDBG_ERROR(MGEST, "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; - return 0; + return; } pGesture->first_fingerid = pGesture->mt_devices[0]->id; memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices); + pGesture->pRootWin = RootWindow(pGesture->master_pointer); if(g_pGesture->palm_misc.enabled) @@ -5231,20 +5671,30 @@ GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg) goto failed; } + if (pScreen) + { + pGesture->screen_width = pScreen->width; + pGesture->screen_height = pScreen->height; + XDBG_ERROR(MGEST, "screen_width = %d, screen_height = %d\n", pGesture->screen_width, pGesture->screen_height); + } + else + { + XDBG_ERROR(MGEST, "Fail to get current screen size\n"); + } + mieqSetHandler(ET_KeyPress, GestureHandleKeyPressEvent); + mieqSetHandler(ET_KeyRelease, GestureHandleKeyReleaseEvent); mieqSetHandler(ET_ButtonPress, GestureHandleButtonPressEvent); mieqSetHandler(ET_ButtonRelease, GestureHandleButtonReleaseEvent); mieqSetHandler(ET_Motion, GestureHandleMotionEvent); mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent); - return 0; + return; failed: GestureUninstallResourceStateHooks(); GestureUnsetMaxNumberOfFingers(); - - return 0; } BOOL @@ -5428,10 +5878,6 @@ GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) } if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL)) { - if(!(g_pGesture->palm_filter_mask & PalmHoldFilterMask)) - { - GesturePalmRecognize_Hold(ev->any.type, 0, 0); - } if(!(g_pGesture->palm_filter_mask & PalmFlickHorizFilterMask)) { GesturePalmRecognize_FlickHorizen(ev->any.type, 0); @@ -5510,6 +5956,7 @@ GestureEventsFlush(void) if(g_pGesture->EQ[i].event->any.type != ET_Motion) XDBG_DEBUG(MGEST, "[%d] type: %d\n", device->id, g_pGesture->EQ[i].event->any.type); #endif//__DETAIL_DEBUG__ + for(j = 0 ; j < MAX_MT_DEVICES+1 ; j++) { if(g_pGesture->palm.qti[j].devid == device->id) @@ -5575,6 +6022,11 @@ GestureInitProperty(DeviceIntPtr dev) { int rc; +#ifdef SUPPORT_ANR_WITH_INPUT_EVENT + prop_anr_in_input_event = MakeAtom(CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT, strlen(CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT), TRUE); + prop_anr_event_window = MakeAtom(ANR_EVENT_WINDOW, strlen(ANR_EVENT_WINDOW), TRUE); +#endif + prop_gesture_recognizer_onoff = MakeAtom(GESTURE_RECOGNIZER_ONOFF, strlen(GESTURE_RECOGNIZER_ONOFF), TRUE); rc = XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE); @@ -5582,6 +6034,14 @@ GestureInitProperty(DeviceIntPtr dev) return; XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE); + + prop_gesture_palm_rejection_mode = MakeAtom(GESTURE_PALM_REJECTION_MODE, strlen(GESTURE_PALM_REJECTION_MODE), TRUE); + rc = XIChangeDeviceProperty(dev, prop_gesture_palm_rejection_mode, XA_INTEGER, 8, PropModeReplace, 1, &g_pGesture->palm_rejection_mode, FALSE); + + if (rc != Success) + return; + + XISetDevicePropertyDeletable(dev, prop_gesture_palm_rejection_mode, FALSE); } static int @@ -5600,6 +6060,60 @@ GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, GestureEnable(data, TRUE, dev); } } + else if( prop_gesture_palm_rejection_mode == atom) + { + int data; + if( val->format != 8 || val->type != XA_INTEGER || val->size != 1 ) + return BadMatch; + + if( !checkonly ) + { + int ret; + data = *((BOOL*)val->data); + int fd, fd_result; + char buf[128]; + + g_pGesture->palm_rejection_mode = (int)data; + + fd = open("/sys/class/sec/tsp/cmd", O_WRONLY); + if (fd < 0) + { + XDBG_ERROR(MGEST, "failed to open tsp node(%d)\n", fd); + return Success; + } + + sprintf(buf, "stylus_enable,%d", !!(g_pGesture->palm_rejection_mode)); + XDBG_DEBUG(MGEST, "stylus_changed: %d!\n", !!(g_pGesture->palm_rejection_mode)); + + ret = write(fd, buf, strlen(buf)); + if (ret <= 0) + { + XDBG_WARNING(MGEST, "failed to stylus_changed: %d\n", !!(g_pGesture->palm_rejection_mode)); + } + + close(fd); + + fd_result = open("/sys/class/sec/tsp/cmd_result", O_RDONLY); + if (fd_result < 0) + { + XDBG_ERROR(MGEST, "failed to open tsp node(%d)\n", fd_result); + return Success; + } + + memset(buf, 0L, sizeof(buf)); + + ret = read(fd_result, buf, sizeof(buf)); + if (ret <= 0) + { + XDBG_WARNING(MGEST, "failed to read cmd_result\n"); + } + else + { + ErrorF("stylus mode result: %s\n", buf); + } + close(fd_result); + } + } return Success; } @@ -5608,9 +6122,6 @@ GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, static int GestureInit(DeviceIntPtr device) { - InputInfoPtr pInfo; - pInfo = device->public.devicePrivate; - #ifdef HAVE_PROPERTIES GestureInitProperty(device); XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL); @@ -5663,6 +6174,19 @@ GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) /* process driver specific options */ pGesture->device = xf86SetStrOption(pInfo->options, "Device", "/dev/null"); pGesture->is_active = xf86SetIntOption(pInfo->options, "Activate", 0); + pGesture->stylus_able = xf86SetIntOption(pInfo->options, "Stylus", 0); + pGesture->support_palm = xf86SetIntOption(pInfo->options, "SupportPalm", 0); + + if (pGesture->support_palm) + { + PalmRecognize = GesturePalmRecognize; + XDBG_DEBUG(MGEST, "Palm Support !!\n"); + } + else + { + PalmRecognize = NULL; + XDBG_DEBUG(MGEST, "No Palm Support !!\n"); + } { int i; @@ -5679,6 +6203,7 @@ GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) } pGesture->gestureWin = None; + #ifdef _F_SUPPORT_BEZEL_FLICK_ pBezel = &pGesture->bezel; pBezel->is_active = xf86SetIntOption(pInfo->options, "Bezel_Activate", 0); @@ -5709,6 +6234,12 @@ GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) pGesture->singletap_threshold = xf86SetIntOption(pInfo->options, "SingleTapThresHold", SGL_TAP_TIME_THRESHOLD); pGesture->doubletap_threshold = xf86SetIntOption(pInfo->options, "DoubleTapThresHold", DBL_TAP_TIME_THRESHOLD); + pGesture->palm_min_touch_major = xf86SetIntOption(pInfo->options, "PalmMinTouchMajor", PALM_MIN_TOUCH_MAJOR); + pGesture->palm_min_width_major = xf86SetIntOption(pInfo->options, "PalmMinWidthMajor", PALM_MIN_WIDTH_MAJOR); + pGesture->palm_min_touch_major_bezel = xf86SetIntOption(pInfo->options, "PalmMinTouchMajorBezel", PALM_MIN_TOUCH_MAJOR_BEZEL); + pGesture->palm_min_width_major_bezel = xf86SetIntOption(pInfo->options, "PalmMinWidthMajorBezel", PALM_MIN_WIDTH_MAJOR_BEZEL); + pGesture->palm_bezel = xf86SetIntOption(pInfo->options, "PalmBezel", PALM_BEZEL); + if (pGesture->is_active) pGesture->ehtype = KEEP_EVENTS; else @@ -5750,6 +6281,13 @@ GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) g_pGesture->zoom_enabled = 0; memset(g_pGesture->palm.qti, 0, sizeof(g_pGesture->palm.qti[MAX_MT_DEVICES+1])); + g_pGesture->palm_rejection_mode = 0; + g_pGesture->palm_detected = FALSE; + + memset(g_pGesture->stylusInfo.t_status, 0, sizeof(g_pGesture->stylusInfo.t_status[MAX_MT_DEVICES])); + g_pGesture->stylusInfo.stylus_id = 0; + g_pGesture->stylusInfo.pen_detected = FALSE; + return Success; error: @@ -5812,6 +6350,9 @@ device_off: case DEVICE_CLOSE: /* free what we have to free */ break; + case DEVICE_READY: + GestureRegisterDeviceInfo(device); + break; } return Success; } diff --git a/mobile/src/gesture.h b/mobile/src/gesture.h index 1e737c4..1c8b83c 100755 --- a/mobile/src/gesture.h +++ b/mobile/src/gesture.h @@ -45,6 +45,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ABS_CNT (ABS_MAX+1) #endif +/** + * If there's touch event in pointed window and there's no reponse, we just assume that client looks like deadlock. + * In this case, we will make a popup window and terminate application. + * To support this feature, we use SUPPORT_ANR_WITH_INPUT_EVENT flag. + */ +#define SUPPORT_ANR_WITH_INPUT_EVENT + #define NUM_PASSKEYS 20 #define SYSCALL(call) while (((call) == -1) && (errno == EINTR)) @@ -56,6 +63,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define GESTURE_EQ_SIZE 256 #define GESTURE_RECOGNIZER_ONOFF "GESTURE_RECOGNIZER_ONOFF" +#define GESTURE_PALM_REJECTION_MODE "GESTURE_PALM_REJECTION_MODE" +#define CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT "_CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT_" +#define ANR_EVENT_WINDOW "_ANR_EVENT_WINDOW_" #define FINGER_WIDTH 10 #define FINGER_HEIGHT 10 @@ -99,6 +109,13 @@ enum FLICK_NORTHWESTWARD }; +/* Gesture query devices infomation and register handlers + * if a device_control function is called using DEVICE_READY */ +#define DEVICE_READY 11 + +#define SCREEN_WIDTH 720 +#define SCREEN_HEIGHT 1280 + #define PAN_AREA_THRESHOLD 10000//=100pixel * 100pixel #define PAN_MOVE_THRESHOLD 5//pixel #define PAN_UPDATE_MOVE_THRESHOLD 3//pixel @@ -114,12 +131,12 @@ enum #define HOLD_MOVE_THRESHOLD 10//pixel #define HOLD_TIME_THRESHOLD 500//ms -#define TAP_AREA_THRESHOLD 10000//= 100pixel * 100pixel -#define TAP_MOVE_THRESHOLD 200//pixel +#define TAP_AREA_THRESHOLD 30000//= 300pixel * 100pixel +#define TAP_MOVE_THRESHOLD 300//pixel #define SGL_FINGER_TIME_THRESHOLD 50//ms #define SGL_TAP_TIME_THRESHOLD 200//ms #define DBL_TAP_TIME_THRESHOLD 400//ms -#define MAX_TAP_REPEATS 3 +#define MAX_TAP_REPEATS 2 #define TAPNHOLD_AREA_THRESHOLD 4900//= 70pixel * 70pixel #define TAPNHOLD_MOVE_THRESHOLD 50//pixel @@ -409,11 +426,10 @@ enum #define GESTURE_FILTER_MASK_ALL 0x3f//(FlickFilterMask | PanFilterMask | PinchRotationFilterMask | TapFilterMask |TapNHoldFilterMask | HoldFilterMask) -#define PalmHoldFilterMask 0x01//(1 << 0) -#define PalmFlickHorizFilterMask 0x02//(1 << 1) -#define PalmFlickVertiFilterMask 0x04//(1 << 2) +#define PalmFlickHorizFilterMask 0x01//(1 << 0) +#define PalmFlickVertiFilterMask 0x02//(1 << 1) -#define GESTURE_PALM_FILTER_MASK_ALL 0x07//(PalmHoldFilterMask | PalmFlickHorizFilterMask | PalmFlickVertiFilterMask) +#define GESTURE_PALM_FILTER_MASK_ALL 0x03//(PalmFlickHorizFilterMask | PalmFlickVertiFilterMask) #ifdef _F_SUPPORT_BEZEL_FLICK_ #define BezelFlickFilterMask 0x01//(1 << 0) @@ -443,6 +459,13 @@ typedef struct _tagCurrentTouchStatus int cy; //current y } CurTouchStatus; +//palm global +#define PALM_MIN_TOUCH_MAJOR 30 +#define PALM_MIN_WIDTH_MAJOR 40 +#define PALM_MIN_TOUCH_MAJOR_BEZEL 16 +#define PALM_MIN_WIDTH_MAJOR_BEZEL 24 +#define PALM_BEZEL 33 + //palm flick #define PALM_FLICK_INITIAL_TIMEOUT 300//ms #define PALM_FLICK_FALSE_TIMEOUT 900//ms @@ -456,7 +479,7 @@ typedef struct _tagCurrentTouchStatus #define PALM_FALSE_FLICK_BASE_WIDTH 8 #define PALM_FLICK_TOUCH_MAJOR 80 #define PALM_FLICK_FINGER_MIN_TOUCH_MAJOR 15 -#define PALM_FLICK_HORIZ_MAX_MOVE_Y 300 +#define PALM_FLICK_HORIZ_MAX_MOVE_Y 400 #define PALM_FLICK_VERTI_MAX_MOVE_X 300 //palm tap @@ -469,13 +492,6 @@ typedef struct _tagCurrentTouchStatus //palm hold #define PALM_HOLD_TIME_THRESHOLD 150 -#define PALM_HOLD_UPDATE_THRESHOLD 500 -#define PALM_HOLD_MIN_DEVIATION 120 -#define PALM_HOLD_MIN_FINGER 4 -#define PALM_HOLD_MIN_BASE_WIDTH 400 -#define PALM_HOLD_FALSE_WIDTH 10 -#define PALM_HOLD_FINGER_MIN_TOUCH_MAJOR 10 -#define PALM_HOLD_FINGER_MIN_WIDTH_MAJOR 15 typedef struct _tagPalmTouchInfo { @@ -537,6 +553,14 @@ typedef struct _tagPalmDrvStatus int verti_coord[PALM_VERTI_ARRAY_COUNT]; } PalmMiscInfo, *PalmMiscInfoPtr; +typedef struct _tagStylusStatus +{ + CurTouchStatus t_status[MAX_MT_DEVICES]; + int stylus_id; + Bool pen_detected; + Bool fake_events; +} StylusInfo, *StylusInfoPtr; + #ifdef _F_SUPPORT_BEZEL_FLICK_ typedef struct _tagBezelStatus { @@ -569,6 +593,9 @@ typedef struct _GestureDeviceRec int is_active; + int screen_width; + int screen_height; + int pinchrotation_time_threshold; double pinchrotation_dist_threshold; double pinchrotation_angle_threshold; @@ -577,8 +604,18 @@ typedef struct _GestureDeviceRec int singletap_threshold; int doubletap_threshold; + int palm_min_touch_major; + int palm_min_width_major; + int palm_min_touch_major_bezel; + int palm_min_width_major_bezel; + int palm_bezel; + int touchkey_id; MTSyncType mtsync_status; + StylusInfo stylusInfo; + int palm_rejection_mode; + Bool palm_detected; + Bool no_palm_events; int pass_keycodes[NUM_PASSKEYS]; @@ -601,6 +638,7 @@ typedef struct _GestureDeviceRec int has_hold_grabmask; pixman_region16_t chold_area; CurTouchStatus cts[MAX_MT_DEVICES]; + Bool hold_detected; PalmStatus palm; PalmMiscInfo palm_misc; @@ -611,6 +649,7 @@ typedef struct _GestureDeviceRec int tpalm_idx; int mt_px_idx; int mt_py_idx; + int mt_tool_idx; pixman_region16_t area; pixman_region16_t finger_rects[MAX_MT_DEVICES]; @@ -643,6 +682,10 @@ typedef struct _GestureDeviceRec #ifdef _F_SUPPORT_BEZEL_FLICK_ BezelFlickStatus bezel; #endif + WindowPtr anr_window; + + int stylus_able; + int support_palm; } GestureDeviceRec, *GestureDevicePtr ; #endif//_GESTURE_H_ diff --git a/packaging/xorg-x11-drv-gesture.spec b/packaging/xorg-x11-drv-gesture.spec index 9cae527..52f87ab 100644 --- a/packaging/xorg-x11-drv-gesture.spec +++ b/packaging/xorg-x11-drv-gesture.spec @@ -1,8 +1,8 @@ #sbs-git:slp/pkgs/xorg/driver/xserver-xorg-input-gesture xorg-x11-drv-gesture 0.1.0 fb1092a8ea453d658b38d5c28e67a58462d7c931 Name: xorg-x11-drv-gesture Summary: X.Org X server -- Xserver gesture driver -Version: 0.1.29 -Release: 7 +Version: 0.1.55 +Release: 1 VCS: adaptation/xorg/driver/xserver-xorg-input-gesture#xorg-x11-drv-gesture-0.1.2-8-6-g7c67de9af10190753599a01144e865bf0a341604 Group: System/X Hardware Support License: MIT @@ -13,7 +13,8 @@ BuildRequires: pkgconfig(xproto) BuildRequires: pkgconfig(inputproto) BuildRequires: pkgconfig(resourceproto) BuildRequires: pkgconfig(xorg-macros) -%if "%{_repository}" == "mobile" +BuildRequires: pkgconfig(dlog) +%if "%{?tizen_profile_name}" == "mobile" BuildRequires: pkgconfig(xdbg) %endif @@ -35,7 +36,7 @@ xorg-x11-drv-gesture development files %build -%if "%{_repository}" == "wearable" +%if "%{?tizen_profile_name}" == "wearable" cd wearable %else cd mobile @@ -48,7 +49,7 @@ make %{?jobs:-j%jobs} %install -%if "%{_repository}" == "wearable" +%if "%{?tizen_profile_name}" == "wearable" cd wearable %else cd mobile diff --git a/wearable/configure.ac b/wearable/configure.ac index c36e7f8..109646d 100644 --- a/wearable/configure.ac +++ b/wearable/configure.ac @@ -54,7 +54,7 @@ AC_SUBST(inputdir) # Checks for pkg-config packages. We need to be able to override sdkdir # to satisfy silly distcheck requirements. -PKG_CHECK_MODULES(XORG, xorg-server xproto $REQUIRED_MODULES) +PKG_CHECK_MODULES(XORG, xorg-server xproto dlog $REQUIRED_MODULES) XORG_CFLAGS="$CWARNFLAGS $XORG_CFLAGS" AC_ARG_WITH([sdkdir], [], [sdkdir="$withval"], diff --git a/wearable/src/gesture.c b/wearable/src/gesture.c index eab747f..31cef63 100755 --- a/wearable/src/gesture.c +++ b/wearable/src/gesture.c @@ -58,6 +58,30 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #endif +//#define __DETAIL_DEBUG__ +//#define __DEBUG_EVENT_HANDLER__ +//#define __PalmFlick_DEBUG__ +//#define __HOLD_DETECTOR_DEBUG__ + +#ifdef __PalmFlick_DEBUG__ +#define PalmFlickDebugPrint ErrorF +#else +#define PalmFlickDebugPrint(...) +#endif + +#ifdef __HOLD_DETECTOR_DEBUG__ +#define HoldDetectorDebugPrint ErrorF +#else +#define HoldDetectorDebugPrint(...) +#endif + + +#ifdef __DETAIL_DEBUG__ +#define DetailDebugPrint ErrorF +#else +#define DetailDebugPrint(...) +#endif + #include #include #include @@ -72,7 +96,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "gesture.h" #include +#define LOG_TAG "GESTURE" +#include "dlog.h" + + + char *strcasestr(const char *s, const char *find); +extern ScreenPtr miPointerCurrentScreen(void); static void printk(const char* fmt, ...) __attribute__((format(printf, 1, 0))); //Basic functions @@ -117,7 +147,9 @@ void GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPt void GestureEmulateHWKey(DeviceIntPtr dev, int keycode); //Gesture recognizer helper +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21 static Bool PointInBorderSize(WindowPtr pWin, int x, int y); +#endif static WindowPtr GestureWindowOnXY(int x, int y); Bool GestureHasFingerEventMask(int eventType, int num_finger); @@ -126,11 +158,18 @@ void GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device); void GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired); void GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int start_point, int direction); void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired); +void GestureRecognize_PalmFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx); void GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction); void GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy); void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds); ErrorStatus GestureFlushOrDrop(void); +static int GestureGetPalmValuator(InternalEvent *ev, DeviceIntPtr device); +static int GesturePalmGetAbsAxisInfo(DeviceIntPtr dev); +static void GestureHoldDetector(int type, InternalEvent *ev, DeviceIntPtr device); +static int GesturePalmGetScreenInfo(); +static int GesturePalmGetHorizIndexWithX(int current_x, int idx, int type); + #ifdef HAVE_PROPERTIES //function related property handling static void GestureInitProperty(DeviceIntPtr dev); @@ -139,6 +178,13 @@ static int GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr va static Atom prop_gesture_recognizer_onoff = None; +#ifdef SUPPORT_ANR_WITH_INPUT_EVENT +static Atom prop_anr_in_input_event = None; +static Atom prop_anr_event_window = None; +static Window prop_anr_event_window_xid = None; +#endif + + GestureDevicePtr g_pGesture = NULL; _X_EXPORT InputDriverRec GESTURE = { 1, @@ -175,33 +221,72 @@ _X_EXPORT XF86ModuleData gestureModuleData = static void printk(const char* fmt, ...) { - static FILE* fp = NULL; - static char init = 0; - va_list argptr; - - if(!init && !fp) - { - fp = fopen("/dev/kmsg", "wt"); - init = 1; - } - - if(!fp) return; - - va_start(argptr, fmt); - vfprintf(fp, fmt, argptr); - fflush(fp); - va_end(argptr); + static FILE* fp = NULL; + static char init = 0; + va_list argptr; + + if (!init && !fp) + { + fp = fopen("/dev/kmsg", "wt"); + init = 1; + } + + if (!fp) return; + + va_start(argptr, fmt); + vfprintf(fp, fmt, argptr); + fflush(fp); + va_end(argptr); +} + +#ifdef SUPPORT_ANR_WITH_INPUT_EVENT +static WindowPtr +_GestureFindANRWindow(DeviceIntPtr device) +{ + WindowPtr root=NULL; + WindowPtr anr_window=NULL; + Window anr_xid=0; + PropertyPtr pProp; + int rc=0; + + root = RootWindow(device); + + if( prop_anr_event_window == None ) + prop_anr_event_window = MakeAtom(ANR_EVENT_WINDOW, strlen(ANR_EVENT_WINDOW), TRUE); + + rc = dixLookupProperty (&pProp, root, prop_anr_event_window, serverClient, DixReadAccess); + if (rc == Success && pProp->data){ + anr_xid = *(int*)pProp->data; + } + + if( anr_xid != 0 ) + { + rc = dixLookupWindow(&anr_window, anr_xid, serverClient, DixSetPropAccess); + if( rc == BadWindow ) + { + ErrorF("Can't find ANR window !!\n"); + anr_window = NULL; + } + prop_anr_event_window_xid = anr_xid; + } + + ErrorF("ANR Window is %#x. Ptr is %#x\n", anr_xid, anr_window); + return anr_window; } +#endif +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21 static Bool PointInBorderSize(WindowPtr pWin, int x, int y) { BoxRec box; - if( pixman_region_contains_point (&pWin->borderSize, x, y, &box) ) - return TRUE; - + if (pixman_region_contains_point (&pWin->borderSize, x, y, &box)) + { + return TRUE; + } return FALSE; } +#endif static WindowPtr GestureWindowOnXY(int x, int y) @@ -217,1416 +302,2467 @@ GestureWindowOnXY(int x, int y) while (pWin) { - if ((pWin->mapped) && - (x >= pWin->drawable.x - wBorderWidth (pWin)) && - (x < pWin->drawable.x + (int)pWin->drawable.width + - wBorderWidth(pWin)) && - (y >= pWin->drawable.y - wBorderWidth (pWin)) && - (y < pWin->drawable.y + (int)pWin->drawable.height + - wBorderWidth (pWin)) - /* When a window is shaped, a further check - * is made to see if the point is inside - * borderSize - */ - && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y)) - && (!wInputShape(pWin) || - RegionContainsPoint(wInputShape(pWin), - x - pWin->drawable.x, - y - pWin->drawable.y, &box)) + if ((pWin->mapped) && + (x >= pWin->drawable.x - wBorderWidth (pWin)) && + (x < pWin->drawable.x + (int)pWin->drawable.width + + wBorderWidth(pWin)) && + (y >= pWin->drawable.y - wBorderWidth (pWin)) && + (y < pWin->drawable.y + (int)pWin->drawable.height + + wBorderWidth (pWin)) + /* When a window is shaped, a further check + * is made to see if the point is inside + * borderSize + */ + && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y)) + && (!wInputShape(pWin) || + RegionContainsPoint(wInputShape(pWin), + x - pWin->drawable.x, + y - pWin->drawable.y, &box)) #ifdef ROOTLESS - /* In rootless mode windows may be offscreen, even when - * they're in X's stack. (E.g. if the native window system - * implements some form of virtual desktop system). - */ - && !pWin->rootlessUnhittable + /* In rootless mode windows may be offscreen, even when + * they're in X's stack. (E.g. if the native window system + * implements some form of virtual desktop system). + */ + && !pWin->rootlessUnhittable #endif - ) - { - if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize) - { - pSprite->spriteTraceSize += 10; - pSprite->spriteTrace = realloc(pSprite->spriteTrace, - pSprite->spriteTraceSize*sizeof(WindowPtr)); - } - pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin; - pWin = pWin->firstChild; - } - else - pWin = pWin->nextSib; + ) + { + if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize) + { + pSprite->spriteTraceSize += 10; + pSprite->spriteTrace = realloc(pSprite->spriteTrace, + pSprite->spriteTraceSize*sizeof(WindowPtr)); + } + pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin; + pWin = pWin->firstChild; + } + else + pWin = pWin->nextSib; } return pSprite->spriteTrace[pSprite->spriteTraceGood-1]; } -Bool + Bool GestureHasFingerEventMask(int eventType, int num_finger) { - Bool ret = FALSE; - Mask eventmask = (1L << eventType); + Bool ret = FALSE; + Mask eventmask = (1L << eventType); - if( (g_pGesture->grabMask & eventmask) && - (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[num_finger].window != None) ) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureHasFingerEventMask] TRUE !! Has grabMask\n"); -#endif//__DETAIL_DEBUG__ - return TRUE; - } + if ((g_pGesture->grabMask & eventmask) && + (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[num_finger].window != None)) + { + DetailDebugPrint("[GestureHasFingerEventMask] TRUE !! Has grabMask\n"); + return TRUE; + } - if( g_pGesture->eventMask & eventmask ) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureHasFingerEventMask] TRUE !! Has eventMask\n"); -#endif//__DETAIL_DEBUG__ - return TRUE; - } + if (g_pGesture->eventMask & eventmask) + { + DetailDebugPrint("[GestureHasFingerEventMask] TRUE !! Has eventMask\n"); + return TRUE; + } -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureHasFingerEventMask] FALSE !! eventType=%d, num_finger=%d\n", eventType, num_finger); -#endif//__DETAIL_DEBUG__ + DetailDebugPrint("[GestureHasFingerEventMask] FALSE !! eventType=%d, num_finger=%d\n", eventType, num_finger); - return ret; + return ret; } static CARD32 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg) { - int event_type = *(int *)arg; + int event_type = *(int *)arg; - switch( event_type ) - { - case GestureNotifyHold: -#ifdef __DETAIL_DEBUG__ - ErrorF("[GestureEventTimerHandler] GestureNotifyHold (event_type = %d)\n", event_type); -#endif//__DETAIL_DEBUG__ - GestureRecognize_GroupHold(event_type, NULL, NULL, 0, 1); - break; - case GestureNotifyTap: -#ifdef __DETAIL_DEBUG__ - ErrorF("[GestureEventTimerHandler] GestureNotifyTap (event_type = %d)\n", event_type); -#endif//__DETAIL_DEBUG__ - GestureRecognize_GroupTap(event_type, NULL, NULL, 0, 1); - break; - default: -#ifdef __DETAIL_DEBUG__ - ErrorF("[GestureEventTimerHandler] unknown event_type (=%d)\n", event_type); -#endif//__DETAIL_DEBUG__ - if(timer) - ErrorF("[GestureEventTimerHandler] timer=%x\n", (unsigned int)timer); - } + switch (event_type) + { + case GestureNotifyHold: + DetailDebugPrint("[GestureEventTimerHandler] GestureNotifyHold (event_type = %d)\n", event_type); + GestureRecognize_GroupHold(event_type, NULL, NULL, 0, 1); + break; + case GestureNotifyTap: + DetailDebugPrint("[GestureEventTimerHandler] GestureNotifyTap (event_type = %d)\n", event_type); + GestureRecognize_GroupTap(event_type, NULL, NULL, 0, 1); + break; + default: + DetailDebugPrint("[GestureEventTimerHandler] unknown event_type (=%d)\n", event_type); + if (timer) + { + DetailDebugPrint("[GestureEventTimerHandler] timer=%x\n", (unsigned int)timer); + } + } - return 0; + return 0; } void GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy) { - Window target_win; - WindowPtr target_pWin; - xGestureNotifyTapEvent tev; + Window target_win; + WindowPtr target_pWin; + xGestureNotifyTapEvent tev; - //skip non-tap events and single finger tap - if( !tap_repeat || num_finger <= 1 ) - return; + //skip non-tap events and single finger tap + if (!tap_repeat || num_finger <= 1) + { + return; + } -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureHandleGesture_Tap] num_finger=%d, tap_repeat=%d, cx=%d, cy=%d\n", - num_finger, tap_repeat, cx, cy); -#endif//__DETAIL_DEBUG__ - - g_pGesture->recognized_gesture |= WTapFilterMask; - memset(&tev, 0, sizeof(xGestureNotifyTapEvent)); - tev.type = GestureNotifyTap; - tev.kind = GestureDone; - tev.num_finger = num_finger; - tev.tap_repeat = tap_repeat; - tev.interval = 0; - tev.cx = cx; - tev.cy = cy; - - target_win = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].window; - target_pWin = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].pWin; - - if( g_pGesture->grabMask && (target_win != None) ) - { - tev.window = target_win; - } - else - { - tev.window = g_pGesture->gestureWin; - } - - ErrorF("[X11][GestureHandleGesture_Tap] tev.window=0x%x, g_pGesture->grabMask=0x%x\n", (unsigned int)tev.window, (unsigned int)g_pGesture->grabMask); - - GestureSendEvent(target_pWin, GestureNotifyTap, GestureTapMask, (xGestureCommonEvent *)&tev); + DetailDebugPrint("[GestureHandleGesture_Tap] num_finger=%d, tap_repeat=%d, cx=%d, cy=%d\n", num_finger, tap_repeat, cx, cy); + + g_pGesture->recognized_gesture |= WTapFilterMask; + memset(&tev, 0, sizeof(xGestureNotifyTapEvent)); + tev.type = GestureNotifyTap; + tev.kind = GestureDone; + tev.num_finger = num_finger; + tev.tap_repeat = tap_repeat; + tev.interval = 0; + tev.cx = cx; + tev.cy = cy; + + target_win = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].window; + target_pWin = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].pWin; + + if (g_pGesture->grabMask && (target_win != None)) + { + tev.window = target_win; + } + else + { + tev.window = g_pGesture->gestureWin; + } + + DetailDebugPrint("[GestureHandleGesture_Tap] tev.window=0x%x, g_pGesture->grabMask=0x%x\n", (unsigned int)tev.window, (unsigned int)g_pGesture->grabMask); + + GestureSendEvent(target_pWin, GestureNotifyTap, GestureTapMask, (xGestureCommonEvent *)&tev); + LOGI("GroupTap Event done. 2 fingers %d tap!", tap_repeat); } void GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction) { -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n", - num_of_fingers, distance, duration, direction); -#endif//__DETAIL_DEBUG__ - switch(direction) - { - case FLICK_NORTHWARD: - ErrorF("[X11][GestureHandleGesture_Flick] Flick Down \n"); - GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down); - break; - - case FLICK_SOUTHWARD: - ErrorF("[X11][GestureHandleGesture_Flick] Flick Up \n"); - GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up); - break; - case FLICK_WESTWARD: - if(g_pGesture->power_pressed == 2) - { - ErrorF("[X11][GestureHandleGesture_Flick] Flick Right & power_pressed\n"); - GestureEmulateHWKey(g_pGesture->hwkey_dev, 122); - } - break; - default: - break; - } - g_pGesture->recognized_gesture |= WFlickFilterMask; + if (num_of_fingers == 0) + { + Window target_win; + WindowPtr target_pWin; + xGestureNotifyFlickEvent fev; + + DetailDebugPrint("[GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n", num_of_fingers, distance, duration, direction); + + g_pGesture->recognized_gesture |= WPalmFlickFilterMask; + + memset(&fev, 0, sizeof(xGestureNotifyFlickEvent)); + fev.type = GestureNotifyFlick; + fev.kind = GestureDone; + fev.num_finger = num_of_fingers; + fev.distance = distance; + fev.duration = duration; + fev.direction = direction; + + if (g_pGesture->GrabEvents) + { + target_win = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].window; + target_pWin = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].pWin; + } + else + { + target_win = None; + target_pWin = None; + } + + if (g_pGesture->grabMask && (target_win != None)) + { + fev.window = target_win; + } + else + { + fev.window = g_pGesture->gestureWin; + } + + DetailDebugPrint("[GestureHandleGesture_Flick] fev.window=0x%x, g_pGesture->grabMask=0x%x\n", fev.window, g_pGesture->grabMask); + + GestureSendEvent(target_pWin, GestureNotifyFlick, GestureFlickMask, (xGestureCommonEvent *)&fev); + } + else + { + DetailDebugPrint("[GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n", num_of_fingers, distance, duration, direction); + + switch (direction) + { + case FLICK_NORTHWARD: + DetailDebugPrint("[GestureHandleGesture_Flick] Flick Down \n"); + GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down); + break; + + case FLICK_SOUTHWARD: + DetailDebugPrint("[GestureHandleGesture_Flick] Flick Up \n"); + GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up); + break; + case FLICK_WESTWARD: + if (g_pGesture->power_pressed == 2) + { + DetailDebugPrint("[GestureHandleGesture_Flick] Flick Right & power_pressed\n"); + GestureEmulateHWKey(g_pGesture->hwkey_dev, 122); + } + break; + default: + break; + } + g_pGesture->recognized_gesture |= WFlickFilterMask; + } } void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds) { - Window target_win; - WindowPtr target_pWin; - xGestureNotifyHoldEvent hev; + Window target_win; + WindowPtr target_pWin; + xGestureNotifyHoldEvent hev; -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureHandleGesture_Hold] num_fingers=%d, cx=%d, cy=%d, holdtime=%d, kinds=%d\n", - num_fingers, cx, cy, holdtime, kinds); -#endif//__DETAIL_DEBUG__ - - g_pGesture->recognized_gesture |= WHoldFilterMask; - memset(&hev, 0, sizeof(xGestureNotifyHoldEvent)); - hev.type = GestureNotifyHold; - hev.kind = kinds; - hev.num_finger = num_fingers; - hev.holdtime = holdtime; - hev.cx = cx; - hev.cy = cy; - - if(g_pGesture->GrabEvents) - { - target_win = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].window; - target_pWin = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].pWin; - } - else - { - target_win = None; - target_pWin = None; - } - - if( g_pGesture->grabMask && (target_win != None) ) - { - hev.window = target_win; - } - else - { - hev.window = g_pGesture->gestureWin; - } + DetailDebugPrint("[GestureHandleGesture_Hold] num_fingers=%d, cx=%d, cy=%d, holdtime=%d, kinds=%d\n", num_fingers, cx, cy, holdtime, kinds); -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureHandleGesture_Hold] hev.window=0x%x, g_pGesture->grabMask=0x%x\n", hev.window, g_pGesture->grabMask); -#endif//__DETAIL_DEBUG__ + if (num_fingers == 0) + { + g_pGesture->hold_detected = TRUE; + LOGI("[PalmHold] PalmHold success !\n"); + } + else + { + g_pGesture->recognized_gesture |= WHoldFilterMask; + } + + memset(&hev, 0, sizeof(xGestureNotifyHoldEvent)); + hev.type = GestureNotifyHold; + hev.kind = kinds; + hev.num_finger = num_fingers; + hev.holdtime = holdtime; + hev.cx = cx; + hev.cy = cy; - GestureSendEvent(target_pWin, GestureNotifyHold, GestureHoldMask, (xGestureCommonEvent *)&hev); + if (g_pGesture->GrabEvents) + { + target_win = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].window; + target_pWin = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].pWin; + } + else + { + target_win = None; + target_pWin = None; + } + + if (g_pGesture->grabMask && (target_win != None)) + { + hev.window = target_win; + } + else + { + hev.window = g_pGesture->gestureWin; + } + + DetailDebugPrint("[GestureHandleGesture_Hold] hev.window=0x%x, g_pGesture->grabMask=0x%x\n", hev.window, g_pGesture->grabMask); + + GestureSendEvent(target_pWin, GestureNotifyHold, GestureHoldMask, (xGestureCommonEvent *)&hev); + LOGI("[GroupHold] GestureHold success !\n"); } void GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired) { - static int num_pressed = 0; - static int base_area_size = 0; + static int num_pressed = 0; + static int base_area_size = 0; - int cx, cy; - int area_size; + int cx, cy; + int area_size; - static int state = 0; - static int mbits = 0; - static int base_cx; - static int base_cy; - static pixman_box16_t base_box_ext; + static int state = 0; + static int mbits = 0; + static int base_cx; + static int base_cy; + static pixman_box16_t base_box_ext; - static int tap_repeat = 0; - static int prev_num_pressed = 0; + static int tap_repeat = 0; + static int prev_num_pressed = 0; - static OsTimerPtr tap_event_timer = NULL; - static int event_type = GestureNotifyTap; + static OsTimerPtr tap_event_timer = NULL; + static int event_type = GestureNotifyTap; - if( timer_expired ) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupTap][Timer] state=%d\n", state); -#endif//__DETAIL_DEBUG__ - - switch( state ) - { - case 1://first tap initiation check - 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); -#endif//__DETAIL_DEBUG__ - state = 0; - goto cleanup_tap; - } - break; - - case 2: - if( tap_repeat <= 1 ) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupTap][Timer][state=2] %d finger SINGLE TAP !(ignored)\n", prev_num_pressed); -#endif//__DETAIL_DEBUG__ - state = 0; - goto cleanup_tap; - } + if (timer_expired) + { + DetailDebugPrint("[GroupTap][Timer] state=%d, num_pressed=%d, tap_repeat=%d\n", state, num_pressed, tap_repeat); + + switch (state) + { + case 1://first tap initiation check + if (num_pressed) + { + DetailDebugPrint("[GroupTap][Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", num_pressed, tap_repeat); + DetailDebugPrint("[GroupTap][F] 1\n"); + + state = 0; + goto cleanup_tap; + } + break; -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupTap][Timer][state=2] tap_repeat=%d, num_pressed=%d\n", tap_repeat, num_pressed); -#endif//__DETAIL_DEBUG__ - if( GestureHasFingerEventMask(GestureNotifyTap, prev_num_pressed) ) - { - GestureHandleGesture_Tap(prev_num_pressed, tap_repeat, base_cx, base_cy); - } - goto cleanup_tap; - break; - } - - return; - } - - switch( type ) - { - case ET_ButtonPress: - g_pGesture->fingers[idx].flags |= PressFlagTap; - - if( g_pGesture->num_pressed < 2 ) - return; - - if( (!base_area_size || g_pGesture->num_pressed > num_pressed) ) - { - base_area_size = AREA_SIZE(&g_pGesture->area.extents); - base_cx = AREA_CENTER_X(&g_pGesture->area.extents); - base_cy = AREA_CENTER_Y(&g_pGesture->area.extents); - base_box_ext.x1 = base_cx-TAP_MOVE_THRESHOLD; - base_box_ext.y1 = base_cy-TAP_MOVE_THRESHOLD; - base_box_ext.x2 = base_cx+TAP_MOVE_THRESHOLD; - base_box_ext.y2 = base_cy+TAP_MOVE_THRESHOLD; - state = 1; - TimerCancel(tap_event_timer); - tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->singletap_threshold, GestureEventTimerHandler, (int *)&event_type); - } - num_pressed = g_pGesture->num_pressed; + case 2: + if (tap_repeat <= 1) + { + state = 0; + DetailDebugPrint("[GroupTap][Timer][state=2] 2 finger %d tap\n", tap_repeat); + LOGI("[GroupTap][F] Second tap doesn't come up in 400ms after first tap.\n"); + goto cleanup_tap; + } + + if (GestureHasFingerEventMask(GestureNotifyTap, prev_num_pressed)) + { + DetailDebugPrint("[GroupTap] Success 1!! 2 finger %d tap\n", tap_repeat); + GestureHandleGesture_Tap(prev_num_pressed, tap_repeat, base_cx, base_cy); + goto cleanup_tap; + } + break; + } + return; + } -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupTap][P][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d\n", num_pressed, base_area_size, base_cx, base_cy); -#endif//__DETAIL_DEBUG__ - break; + switch (type) + { + case ET_ButtonPress: + g_pGesture->fingers[idx].flags |= PressFlagTap; + + if (g_pGesture->num_pressed < 2) + { + DetailDebugPrint("[GroupTap][P] num_pressed=%d, base_px=%d, base_py=%d. return \n", g_pGesture->num_pressed, g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py); + return; + } + + if ((!base_area_size || g_pGesture->num_pressed > num_pressed)) + { + base_area_size = AREA_SIZE(&g_pGesture->area.extents); + base_cx = AREA_CENTER_X(&g_pGesture->area.extents); + base_cy = AREA_CENTER_Y(&g_pGesture->area.extents); + base_box_ext.x1 = base_cx-TAP_MOVE_THRESHOLD; + base_box_ext.y1 = base_cy-TAP_MOVE_THRESHOLD; + base_box_ext.x2 = base_cx+TAP_MOVE_THRESHOLD; + base_box_ext.y2 = base_cy+TAP_MOVE_THRESHOLD; + state = 1; + TimerCancel(tap_event_timer); + tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->singletap_threshold, GestureEventTimerHandler, (int *)&event_type); + } + num_pressed = g_pGesture->num_pressed; + + DetailDebugPrint("[GroupTap][P] num_pressed=%d, area_size=%d, base_mx=%d, base_my=%d\n", num_pressed, base_area_size, g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py); + break; + + case ET_Motion: + if (!(g_pGesture->fingers[idx].flags & PressFlagTap)) + { + break; + } + + if (num_pressed < 2) + { + DetailDebugPrint("[GroupTap][M] num_pressed=%d, return \n", num_pressed); + return; + } + + if (num_pressed != g_pGesture->num_pressed) + { + DetailDebugPrint("[GroupTap][M] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed); + } + + mbits |= (1 << idx); + if (mbits == (pow(2, num_pressed)-1)) + { + area_size = AREA_SIZE(&g_pGesture->area.extents); + cx = AREA_CENTER_X(&g_pGesture->area.extents); + cy = AREA_CENTER_Y(&g_pGesture->area.extents); + + DetailDebugPrint("[GroupTap][M][num_pressed=%d] area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size)); + DetailDebugPrint("[GroupTap][M] cx=%d, base_cx=%d, diff=%d\n", cx, g_pGesture->fingers[idx].mx, ABS(cx-base_cx)); + DetailDebugPrint("[GroupTap][M] cy=%d, base_cy=%d, diff=%d\n", cy, g_pGesture->fingers[idx].my, ABS(cy-base_cy)); + + if (ABS(base_area_size-area_size) >= TAP_AREA_THRESHOLD) + { + DetailDebugPrint("[GroupTap][M] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, ABS(base_area_size-area_size)); + DetailDebugPrint("[GroupTap][F] 3\n"); + LOGI("[GroupTap][F] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, ABS(base_area_size-area_size)); + + goto cleanup_tap; + } + + if (!INBOX(&base_box_ext, cx, cy)) + { + DetailDebugPrint("[GroupTap][M] current center coordinates is not in base coordinates box !\n"); + DetailDebugPrint("[GroupTap][F] 4\n"); + LOGI("[GroupTap][F] current center coordinates is not in base coordinates box !\n"); + + goto cleanup_tap; + } + } + break; + + case ET_ButtonRelease: + if (g_pGesture->num_pressed) + { + DetailDebugPrint("[GroupTap][R] Second finger doesn't come up. g_pGesture->num_pressed=%d\n", g_pGesture->num_pressed); + break; + } + + if (!tap_repeat) + { + prev_num_pressed = num_pressed; + } + + tap_repeat++; + g_pGesture->num_tap_repeated = tap_repeat; + + DetailDebugPrint("[GroupTap][R] tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, num_pressed, prev_num_pressed); + DetailDebugPrint("[GroupTap][R] base_rx=%d, base_ry=%d,\n", g_pGesture->fingers[idx].rx, g_pGesture->fingers[idx].ry); + + if ((num_pressed != prev_num_pressed) || (!GestureHasFingerEventMask(GestureNotifyTap, num_pressed))) + { + DetailDebugPrint("[GroupTap][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n", + num_pressed, prev_num_pressed, num_pressed); + DetailDebugPrint("[GroupTap][F] 5\n"); + LOGI("[GroupTap][F] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n", + num_pressed, prev_num_pressed, num_pressed); + goto cleanup_tap; + } + + if (tap_repeat == 1) + { + DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat); + TimerCancel(tap_event_timer); + tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->doubletap_threshold, GestureEventTimerHandler, (int *)&event_type); + state = 2; + prev_num_pressed = num_pressed; + num_pressed = 0; + break; + } + + else if (tap_repeat == 2) + { + DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat); + TimerCancel(tap_event_timer); + tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->tripletap_threshold, GestureEventTimerHandler, (int *)&event_type); + state = 2; + base_area_size = num_pressed = 0; + break; + } + + DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat); + + if (tap_repeat == MAX_TAP_REPEATS) + { + if (GestureHasFingerEventMask(GestureNotifyTap, num_pressed)) + { + DetailDebugPrint("[GroupTap] Sucess 2!\n"); + GestureHandleGesture_Tap(num_pressed, tap_repeat, base_cx, base_cy); + } + goto cleanup_tap; + } + + if (tap_repeat >= MAX_TAP_REPEATS) + { + LOGI("[GroupTap][F] More than 3 taps. Ignore. \n"); + goto cleanup_tap; + } + + prev_num_pressed = num_pressed; + num_pressed = 0; + break; + } - case ET_Motion: - if( !(g_pGesture->fingers[idx].flags & PressFlagTap ) ) - break; + return; - if( num_pressed < 2 ) - return; +cleanup_tap: - if( num_pressed != g_pGesture->num_pressed ) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupTap][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed); -#endif//__DETAIL_DEBUG__ - //goto cleanup_tap; - } - - mbits |= (1 << idx); - if( mbits == (pow(2, num_pressed)-1) ) - { - area_size = AREA_SIZE(&g_pGesture->area.extents); - cx = AREA_CENTER_X(&g_pGesture->area.extents); - cy = AREA_CENTER_Y(&g_pGesture->area.extents); -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupTap][M][num_pressed=%d] area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size)); - ErrorF("[GroupTap][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx)); - ErrorF("[GroupTap][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy)); -#endif//__DETAIL_DEBUG__ + DetailDebugPrint("[GroupTap][cleanup_tap]\n"); - if( ABS(base_area_size-area_size) >= TAP_AREA_THRESHOLD ) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupTap][M] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, ABS(base_area_size-area_size)); -#endif//__DETAIL_DEBUG__ - goto cleanup_tap; - } + if (0 == state) + { + g_pGesture->recognized_gesture &= ~WTapFilterMask; + } - if( !INBOX(&base_box_ext, cx, cy) ) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupTap][M] current center coordinates is not in base coordinates box !\n"); -#endif//__DETAIL_DEBUG__ - goto cleanup_tap; - } - } - break; + g_pGesture->filter_mask |= WTapFilterMask; - case ET_ButtonRelease: - if( g_pGesture->num_pressed ) - break; + if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL) + { + DetailDebugPrint("[GroupTap][cleanup] GestureFlushOrDrop() !\n"); - if( !tap_repeat ) - { - prev_num_pressed = num_pressed; - } + if (ERROR_INVALPTR == GestureFlushOrDrop()) + { + GestureControl(g_pGesture->this_device, DEVICE_OFF); + } + } - tap_repeat++; + num_pressed = 0; + g_pGesture->num_tap_repeated = tap_repeat = 0; + prev_num_pressed = 0; + mbits = 0; + state = 0; + TimerCancel(tap_event_timer); + return; +} -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupTap][R] tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, num_pressed, prev_num_pressed); -#endif//__DETAIL_DEBUG__ +void +GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int start_point, int direction) +{ + static int num_pressed = 0; + static Time base_time = 0; + Time duration; + int distance; + static int diff_base_coord = 0; + static int diff_base_minor_coord = 0; + static int diff_current_coord = 0; + static int false_diff_count = 0; + static int false_minor_diff_count = 0; + static float angle = 0.0f; + static int angle_base_x = 0, angle_base_y = 0; + static int motion_count = 0; + + if (g_pGesture->num_pressed > 1) + { + DetailDebugPrint("[GroupFlick][F] 1\n"); + goto cleanup_flick; + } - if(( num_pressed != prev_num_pressed ) || (!GestureHasFingerEventMask(GestureNotifyTap, num_pressed)) ) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupTap][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n", - num_pressed, prev_num_pressed, num_pressed); -#endif//__DETAIL_DEBUG__ - goto cleanup_tap; - } - - if( tap_repeat < MAX_TAP_REPEATS ) - { - state = 2; - TimerCancel(tap_event_timer); - tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->doubletap_threshold, GestureEventTimerHandler, (int *)&event_type); - base_area_size = num_pressed = 0; - break; - } + if ((start_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= start_point)) + { + DetailDebugPrint("[GroupFlick][F] 2\n"); + goto cleanup_flick; + } -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupTap][R] %d finger %s\n", num_pressed, (tap_repeat==2) ? "DBL_TAP" : "TRIPLE_TAP"); -#endif//__DETAIL_DEBUG__ + switch (type) + { + case ET_ButtonPress: + g_pGesture->fingers[idx].flags = PressFlagFlick; + base_time = GetTimeInMillis(); + num_pressed = g_pGesture->num_pressed; + switch (start_point) + { + case FLICK_POINT_UP: + if (g_pGesture->fingers[idx].py > g_pGesture->flick_press_area) + { + DetailDebugPrint("[GroupFlick][FlickDown][P] press coord is out of bound. (%d, %d)\n", + g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py); + DetailDebugPrint("[GroupFlick][F] 3\n"); + LOGI("[BackKey][F] press coord is out of bound (40 pixel from upper vezel). press y=%d\n", g_pGesture->fingers[idx].py); + goto cleanup_flick; + } + + angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py; + angle_base_x = g_pGesture->fingers[idx].px; + DetailDebugPrint("[GroupFlick][FlickDown][P] px=%d, py=%d\n", g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py); + break; - if( GestureHasFingerEventMask(GestureNotifyTap, num_pressed) ) - GestureHandleGesture_Tap(num_pressed, tap_repeat, base_cx, base_cy); + case FLICK_POINT_DOWN: + if (g_pGesture->fingers[idx].py < g_pGesture->screen_height - g_pGesture->flick_press_area) + { + DetailDebugPrint("[GroupFlick][FlickUp][P] press coord is out of bound. (%d, %d)\n", + g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py); + DetailDebugPrint("[GroupFlick][F] 4\n"); + goto cleanup_flick; + } + angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py; + angle_base_x = g_pGesture->fingers[idx].px; + break; - if( tap_repeat >= MAX_TAP_REPEATS ) - { - goto cleanup_tap; - } + case FLICK_POINT_LEFT: + if (g_pGesture->fingers[idx].px > g_pGesture->flick_press_area) + { + DetailDebugPrint("[GroupFlick][FlickLeft][P] press coord is out of bound. (%d, %d)\n", + g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py); + DetailDebugPrint("[GroupFlick][F] 5\n"); + goto cleanup_flick; + } + angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py; + angle_base_x = g_pGesture->fingers[idx].px; + break; - prev_num_pressed = num_pressed; - num_pressed = 0; - break; - } + default: + DetailDebugPrint("[GroupFlick][F] 6\n"); + goto cleanup_flick; + break; + } - return; + break; -cleanup_tap: + case ET_Motion: - if( 0 == state ) - g_pGesture->recognized_gesture &= ~WTapFilterMask; - g_pGesture->filter_mask |= WTapFilterMask; + motion_count++; + + if (motion_count > 15) + { + DetailDebugPrint("[GroupFlick][F] 6-1 motion_count=%d\n", motion_count); + LOGI("[BackKey][F] More than 15 motion.\n"); + goto cleanup_flick; + } + + if (!(g_pGesture->fingers[idx].flags & PressFlagFlick)) + { + break; + } + + switch (start_point) + { + case FLICK_POINT_UP: + diff_base_coord = diff_current_coord; + diff_current_coord = g_pGesture->fingers[idx].my; + + if ((diff_current_coord - diff_base_coord) < 0) + { + DetailDebugPrint("[GroupFlick][FlickDown][M] false_diff\n"); + false_diff_count++; + } + + if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT) + { + DetailDebugPrint("[GroupFlick][FlickDown][M] false_diff_count: %d > %d\n", + false_diff_count, FLICK_FALSE_Y_DIFF_COUNT); + DetailDebugPrint("[GroupFlick][F] 7\n"); + LOGI("[BackKey][F] Direction is wrong for 7 times.\n"); + goto cleanup_flick; + } + + if ((g_pGesture->fingers[idx].my < g_pGesture->flick_press_area) && + (abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) >(int)( g_pGesture->screen_width/2))) + { + DetailDebugPrint("[GroupFlick][FlickDown][M] move x: %d - %d, y coord: %d\n", + g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].my); + DetailDebugPrint("[GroupFlick][F] 8\n"); + LOGI("[BackKey][F] From press point, moving x axis is more than half screen size.\n"); + goto cleanup_flick; + } + + if ((g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) > g_pGesture->flick_minimum_height) + { + DetailDebugPrint("[GroupFlick][FlickDown][M] %d - %d < %d(min_size), angle_base_coord (%d, %d)\n", + g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py, g_pGesture->flick_minimum_height, angle_base_x, angle_base_y); + + if (abs(g_pGesture->fingers[idx].mx - angle_base_x) == 0) + { + DetailDebugPrint("[GroupFlick][FlickDown][M] abs(%d - %d) = 0\n", + g_pGesture->fingers[idx].mx, angle_base_x); + angle = 1.0f; + } + else + { + DetailDebugPrint("[GroupFlick][FlickDown][M] angle_base_x: %d, angle_base_y: %d\n", + angle_base_x, angle_base_y); + int y_diff = abs(g_pGesture->fingers[idx].my - angle_base_y); + int x_diff = abs(g_pGesture->fingers[idx].mx - angle_base_x); + angle = (float)y_diff / (float)x_diff; + } + + if (angle < 0.23f) + { + DetailDebugPrint("[GroupFlick][FlickDown][M][F] %d / %d = %f (angle)\n", + abs(g_pGesture->fingers[idx].my - angle_base_y), abs(g_pGesture->fingers[idx].mx - angle_base_x), angle); + DetailDebugPrint("[GroupFlick][F] 9\n"); + LOGI("[BackKey][F] angle is improper. %d < 0.23\n", angle); + goto cleanup_flick; + } + + distance = g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py; + duration = GetTimeInMillis() - base_time; + + GestureHandleGesture_Flick(num_pressed, distance, duration, direction); + DetailDebugPrint("[GroupFlick][FlickDown][M] FlickDown Done!!\n"); + goto cleanup_flick_recognized; + } + else + { + if ((g_pGesture->fingers[idx].mx - diff_base_minor_coord) < 0) + { + false_minor_diff_count++; + } + + if (false_minor_diff_count> FLICK_FALSE_X_DIFF_COUNT) + { + DetailDebugPrint("[GroupFlick][FlickDown][M] false_minor_diff_count: %d > %d\n", + false_minor_diff_count, FLICK_FALSE_X_DIFF_COUNT); + DetailDebugPrint("[GroupFlick][F] 10\n"); + goto cleanup_flick; + } + } + + if (g_pGesture->fingers[idx].my < g_pGesture->flick_press_area) + { + angle_base_x = g_pGesture->fingers[idx].px; + angle_base_y = g_pGesture->fingers[idx].py; + } + DetailDebugPrint("[GroupFlick][FlickDown][M] mx=%d, my=%d, diff_x=%d, diff_y=%d\n", + g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].my, abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py)); + + break; + + case FLICK_POINT_DOWN: + diff_base_coord = diff_current_coord; + diff_current_coord = g_pGesture->fingers[idx].my; + + if ((diff_base_coord - diff_current_coord) < 0) + { + false_diff_count++; + } + + if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT) + { + DetailDebugPrint("[GroupFlick][FlickUp][M] false_diff_count: %d > %d\n", + false_diff_count, FLICK_FALSE_Y_DIFF_COUNT); + DetailDebugPrint("[GroupFlick][F] 11\n"); + goto cleanup_flick; + } + + if ((g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my) > g_pGesture->flick_minimum_height) + { + DetailDebugPrint("[GroupFlick][FlickUp][R] %d - %d < %d(min_size)\n", + g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py, g_pGesture->flick_minimum_height); + if (abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) == 0) + { + DetailDebugPrint("[GroupFlick][FlickUp][R] abs(%d - %d) = 0\n", + g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px); + angle = 1.0f; + } + else + { + int y_diff = abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py); + int x_diff = abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px); + angle = (float)y_diff / (float)x_diff; + } + + if (angle <0.5f) + { + DetailDebugPrint("[GroupFlick][FlickUp][R] %d / %d = %f (angle)\n", + abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py), abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), angle); + DetailDebugPrint("[GroupFlick][F] 12\n"); + goto cleanup_flick; + } + + distance = g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my; + duration = GetTimeInMillis() - base_time; + + GestureHandleGesture_Flick(num_pressed, distance, duration, direction); + goto cleanup_flick_recognized; + } + break; + + case FLICK_POINT_LEFT: + diff_base_coord = diff_current_coord; + diff_current_coord = g_pGesture->fingers[idx].mx; + + if ((diff_current_coord - diff_base_coord) < 0) + { + false_diff_count++; + } + + if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT) + { + DetailDebugPrint("[GroupFlick][FlickLeft][M] false_diff_count: %d > %d\n", + false_diff_count, FLICK_FALSE_Y_DIFF_COUNT); + DetailDebugPrint("[GroupFlick][F] 13\n"); + goto cleanup_flick; + } + + if ((g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) > g_pGesture->flick_minimum_height) + { + DetailDebugPrint("[GroupFlick][FlickLeft][M] %d - %d < %d(min_size)\n", + g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px, g_pGesture->flick_minimum_height); + + if (abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) == 0) + { + DetailDebugPrint("[GroupFlick][FlickLeft][M] abs(%d - %d) = 0\n", + g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py); + angle = 1.0f; + } + else + { + int y_diff = abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py); + int x_diff = abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px); + angle = (float)x_diff / (float)y_diff; + } + + if ( angle < 0.5f) + { + DetailDebugPrint("[GroupFlick][FlickLeft][M] %d / %d = %f (angle)\n", + abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py), angle); + DetailDebugPrint("[GroupFlick][F] 14\n"); + goto cleanup_flick; + } + + distance = g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px; + duration = GetTimeInMillis() - base_time; + + GestureHandleGesture_Flick(num_pressed, distance, duration, direction); + goto cleanup_flick_recognized; + } + + break; + default: + DetailDebugPrint("[GroupFlick][F] 15\n"); + goto cleanup_flick; + break; + } + break; + + case ET_ButtonRelease: + DetailDebugPrint("[GroupFlick][R][F] 16\n"); + goto cleanup_flick; + break; + } + + return; + +cleanup_flick: + DetailDebugPrint("[GroupFlick] cleanup_flick \n"); + g_pGesture->recognized_gesture &= ~WFlickFilterMask; + motion_count = 0; + +cleanup_flick_recognized: + DetailDebugPrint("[GroupFlick] Flick recognized !\n"); + g_pGesture->filter_mask |= WFlickFilterMask; + num_pressed = 0; + base_time = 0; + false_diff_count = 0; + diff_base_coord = 0; + diff_current_coord = 0; + angle = 0.0f; + angle_base_x = angle_base_y = 0; + motion_count = 0; + return; +} + +void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired) +{ + static int num_pressed = 0; + static int base_area_size = 0; + static Time base_time = 0; + static int base_cx; + static int base_cy; + int cx, cy; + static pixman_box16_t base_box_ext; + int area_size; + static int state = GestureEnd; + + static OsTimerPtr hold_event_timer = NULL; + static int event_type = GestureNotifyHold; + + if (timer_expired) + { + if (state <= GestureBegin) + { + state++; + } + + switch (state) + { + case GestureBegin: + DetailDebugPrint("[GroupHold] HOLD Begin !\n"); + break; + + case GestureUpdate: + DetailDebugPrint("[GroupHold] HOLD Update !\n"); + break; + } + + if (GestureHasFingerEventMask(GestureNotifyHold, num_pressed)) + { + DetailDebugPrint("[GroupHold] Success 1! \n"); + GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state); + + // one more time + hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type); + } + return; + } + + switch (type) + { + case ET_ButtonPress: + g_pGesture->fingers[idx].flags |= PressFlagHold; + + if (g_pGesture->num_pressed < 2) + { + DetailDebugPrint("[GroupHold][P] No num_finger changed ! num_pressed=%d\n", num_pressed); + DetailDebugPrint("[GroupHold][F] 0\n"); + return; + } + + if (!base_area_size || g_pGesture->num_pressed > num_pressed) + { + if (state != GestureEnd) + { + DetailDebugPrint("[GroupHold][P][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed); + DetailDebugPrint("[GroupHold][F] 1\n"); + + goto cleanup_hold; + } + + base_area_size = AREA_SIZE(&g_pGesture->area.extents); + base_cx = AREA_CENTER_X(&g_pGesture->area.extents); + base_cy = AREA_CENTER_Y(&g_pGesture->area.extents); + base_time = GetTimeInMillis(); + + base_box_ext.x1 = base_cx-g_pGesture->hold_move_threshold; + base_box_ext.y1 = base_cy-g_pGesture->hold_move_threshold; + base_box_ext.x2 = base_cx+g_pGesture->hold_move_threshold; + base_box_ext.y2 = base_cy+g_pGesture->hold_move_threshold; + + event_type = GestureNotifyHold; + + hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type); + } + num_pressed = g_pGesture->num_pressed; + + DetailDebugPrint("[GroupHold][P] num_pressed=%d area_size=%d, base_cx=%d, base_cy=%d\n", num_pressed, base_area_size, base_cx, base_cy); + + break; + + case ET_Motion: + if (!(g_pGesture->fingers[idx].flags & PressFlagHold)) + { + DetailDebugPrint("[GroupHold][M] No PressFlagHold\n"); + break; + } + + if (num_pressed < 2) + { + DetailDebugPrint("[GroupHold][M] No num_finger changed ! num_pressed=%d\n", num_pressed); + DetailDebugPrint("[GroupHold][F] 2\n"); + return; + } + + if (num_pressed != g_pGesture->num_pressed) + { + if (state != GestureEnd) + { + DetailDebugPrint("[GroupHold][M][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed); + DetailDebugPrint("[GroupHold][F] 3\n"); + goto cleanup_hold; + } + + DetailDebugPrint("[GroupHold][M] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed); + } + + area_size = AREA_SIZE(&g_pGesture->area.extents); + cx = AREA_CENTER_X(&g_pGesture->area.extents); + cy = AREA_CENTER_Y(&g_pGesture->area.extents); + + DetailDebugPrint("[GroupHold][M] num_pressed=%d area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size)); + DetailDebugPrint("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx)); + DetailDebugPrint("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy)); + + if (area_size > 0 && base_area_size > 0) + { + if (((area_size > base_area_size) ? (double)area_size / (double)base_area_size : (double)base_area_size / (double) area_size) >= g_pGesture->hold_area_threshold) + { + DetailDebugPrint("[GroupHold][M] No diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%lf)!\n", area_size, base_area_size, ((area_size > base_area_size) ? (double)area_size / (double)base_area_size : (double)base_area_size / (double) area_size)); + DetailDebugPrint("[GroupHold][F] 4\n"); + goto cleanup_hold; + } + } + + if (!INBOX(&base_box_ext, cx, cy)) + { + DetailDebugPrint("[GroupHold][M] No current center coordinates is not in base coordinates box !\n"); + DetailDebugPrint("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx)); + DetailDebugPrint("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy)); + DetailDebugPrint("[GroupHold][F] 5\n"); + goto cleanup_hold; + } + break; + + case ET_ButtonRelease: + if (state != GestureEnd && num_pressed >= 2) + { + DetailDebugPrint("[GroupHold][R] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed); + DetailDebugPrint("[GroupHold][F] 6\n"); + goto cleanup_hold; + } + + if (g_pGesture->num_pressed) + { + DetailDebugPrint("[GroupHold][R] num_pressed=%d\n", num_pressed); + DetailDebugPrint("[GroupHold][F] 7\n"); + break; + } + + goto cleanup_hold; + break; + } + + return; + +cleanup_hold: + + DetailDebugPrint("[GroupHold][cleanup_hold] enter!\n"); + + if (state == GestureBegin || state == GestureUpdate) + { + state = GestureEnd; + if (GestureHasFingerEventMask(GestureNotifyHold, num_pressed)) + { + DetailDebugPrint("[GroupHold] Success 2!\n"); + GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state); + } + } + else + { + g_pGesture->recognized_gesture &= ~WHoldFilterMask; + } + + g_pGesture->filter_mask |= WHoldFilterMask; + num_pressed = 0; + base_area_size = 0; + base_time = 0; + base_cx = base_cy = 0; + state = GestureEnd; + base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0; + TimerCancel(hold_event_timer); + return; +} + +int +GestureGetMaxTmajor(InternalEvent *ev, int max_tmajor) +{ + int mt_tmajor_idx = g_pGesture->tmajor_idx; + int mt_tmajor = 0; + + DeviceEvent *de = &ev->device_event; + + if (!de) + { + DetailDebugPrint("[GestureGetMaxTmajor] de is NULL !\n"); + return -1; + } + + if (mt_tmajor_idx < 0) + { + DetailDebugPrint("[GestureGetMaxTmajor] One or more of axes are not supported !\n"); + return -1; + } + + mt_tmajor = de->valuators.data[mt_tmajor_idx]; + + DetailDebugPrint("[GestureGetMaxTmajor]mt_tmajor_idx=%d, mt_tmajor=%d, max_tmajor=%d\n", mt_tmajor_idx, mt_tmajor, max_tmajor); + + return ((mt_tmajor > max_tmajor) ? mt_tmajor : max_tmajor); - if( g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL ) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupTap][cleanup] GestureFlushOrDrop() !\n"); -#endif//__DETAIL_DEBUG__ - - if( ERROR_INVALPTR == GestureFlushOrDrop() ) - { - GestureControl(g_pGesture->this_device, DEVICE_OFF); - } - } - - num_pressed = 0; - tap_repeat = 0; - prev_num_pressed = 0; - mbits = 0; - state = 0; - TimerCancel(tap_event_timer); - return; } void -GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int start_point, int direction) +GestureRecognize_PalmFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx) { - static int num_pressed = 0; - static Time base_time = 0; - Time duration; - int distance; - static int diff_base_coord = 0; - static int diff_base_minor_coord = 0; - static int diff_current_coord = 0; - static int false_diff_count = 0; - static int false_minor_diff_count = 0; - static float angle = 0.0f; - static int angle_base_x=0, angle_base_y=0; - - if( g_pGesture->num_pressed > 1 ) - goto cleanup_flick; - if( (start_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= start_point) ) - goto cleanup_flick; - - switch( type ) - { - case ET_ButtonPress: - g_pGesture->fingers[idx].flags = PressFlagFlick; - base_time = GetTimeInMillis(); - num_pressed = g_pGesture->num_pressed; - switch(start_point) - { - case FLICK_POINT_UP: - if( g_pGesture->fingers[idx].py > g_pGesture->flick_press_area) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickDown] press coord is out of bound. (%d, %d)\n", g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py); -#endif//__DETAIL_DEBUG__ - goto cleanup_flick; - } - - angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py; - angle_base_x = g_pGesture->fingers[idx].px; - break; - - case FLICK_POINT_DOWN: - if( g_pGesture->fingers[idx].py < g_pGesture->screen_height - g_pGesture->flick_press_area) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickUp] press coord is out of bound. (%d, %d)\n", g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py); -#endif//__DETAIL_DEBUG__ - goto cleanup_flick; - } - angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py; - angle_base_x = g_pGesture->fingers[idx].px; - break; - - case FLICK_POINT_LEFT: - if( g_pGesture->fingers[idx].px > g_pGesture->flick_press_area) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickLeft] press coord is out of bound. (%d, %d)\n", g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py); -#endif//__DETAIL_DEBUG__ - goto cleanup_flick; - } - angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py; - angle_base_x = g_pGesture->fingers[idx].px; - break; - - default: - goto cleanup_flick; - break; - } - - break; - - case ET_Motion: - if( !(g_pGesture->fingers[idx].flags & PressFlagFlick ) ) - break; - - switch(start_point) - { - case FLICK_POINT_UP: - diff_base_coord = diff_current_coord; - diff_current_coord = g_pGesture->fingers[idx].my; - - if( (diff_current_coord - diff_base_coord) < 0 ) - false_diff_count++; - if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickDown][M][F] false_diff_count: %d > %d\n", false_diff_count, FLICK_FALSE_Y_DIFF_COUNT); -#endif//__DETAIL_DEBUG__ - goto cleanup_flick; - } - - if ((g_pGesture->fingers[idx].my < g_pGesture->flick_press_area) && - (abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) >(int)( g_pGesture->screen_width/2)) ) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickDown][M][F] move x: %d - %d, y coord: %d\n", g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].my); -#endif//__DETAIL_DEBUG__ - goto cleanup_flick; - } + // static int num_pressed = 0; + static int base_time = 0, current_time = 0; + static int base_x[MAX_MT_DEVICES] = {0}, base_y[MAX_MT_DEVICES] = {0}; + static int update_x[MAX_MT_DEVICES] = {0}, update_y[MAX_MT_DEVICES] = {0}; - if( (g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) > g_pGesture->flick_minimum_height) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickDown][M] %d - %d < %d(min_size), angle_base_coord (%d, %d)\n", g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py, g_pGesture->flick_minimum_height, angle_base_x, angle_base_y); -#endif//__DETAIL_DEBUG__ - if(abs(g_pGesture->fingers[idx].mx - angle_base_x) == 0) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickDown][M] abs(%d - %d) = 0\n", g_pGesture->fingers[idx].mx, angle_base_x); -#endif//__DETAIL_DEBUG__ - angle = 1.0f; - } - else - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickDown][M] angle_base_x: %d, angle_base_y: %d\n", angle_base_x, angle_base_y); -#endif//__DETAIL_DEBUG__ - int y_diff = abs(g_pGesture->fingers[idx].my - angle_base_y); - int x_diff = abs(g_pGesture->fingers[idx].mx - angle_base_x); - angle = (float)y_diff / (float)x_diff; - } + static int current_x[MAX_MT_DEVICES] = {0}, current_y[MAX_MT_DEVICES] = {0}; + static Bool press_status[MAX_MT_DEVICES] = {FALSE, FALSE}; + static Bool release_status[MAX_MT_DEVICES] = {FALSE, FALSE}; - if ( angle < 0.27f) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickDown][M][F] %d / %d = %f (angle)\n", abs(g_pGesture->fingers[idx].my - angle_base_y), abs(g_pGesture->fingers[idx].mx - angle_base_x), angle); -#endif//__DETAIL_DEBUG__ - goto cleanup_flick; - } - - distance = g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py; - duration = GetTimeInMillis() - base_time; - - GestureHandleGesture_Flick(num_pressed, distance, duration, direction); - goto cleanup_flick_recognized; - } - else - { - if( (g_pGesture->fingers[idx].mx - diff_base_minor_coord) < 0 ) - false_minor_diff_count++; - if (false_minor_diff_count> FLICK_FALSE_X_DIFF_COUNT) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickDown][M][F] false_minor_diff_count: %d > %d\n", false_minor_diff_count, FLICK_FALSE_X_DIFF_COUNT); -#endif//__DETAIL_DEBUG__ - goto cleanup_flick; - } - } - - if (g_pGesture->fingers[idx].my < g_pGesture->flick_press_area) - { - angle_base_x = g_pGesture->fingers[idx].px; - angle_base_y = g_pGesture->fingers[idx].py; - } - - break; - case FLICK_POINT_DOWN: - diff_base_coord = diff_current_coord; - diff_current_coord = g_pGesture->fingers[idx].my; - - if( (diff_base_coord - diff_current_coord) < 0 ) - false_diff_count++; - if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickUp][M] false_diff_count: %d > %d\n", false_diff_count, FLICK_FALSE_Y_DIFF_COUNT); -#endif//__DETAIL_DEBUG__ - goto cleanup_flick; - } + static int line_idx[MAX_MT_DEVICES] = {0}, prev_line_idx[MAX_MT_DEVICES] = {0}, press_idx[MAX_MT_DEVICES] = {0}; + static Bool is_line_invalid[MAX_MT_DEVICES] = {TRUE, TRUE}; - if( (g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my) > g_pGesture->flick_minimum_height) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickUp][R] %d - %d < %d(min_size)\n", g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py, g_pGesture->flick_minimum_height); -#endif//__DETAIL_DEBUG__ - if(abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) == 0) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickUp][R] abs(%d - %d) = 0\n", g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px); -#endif//__DETAIL_DEBUG__ - angle = 1.0f; - } - else - { - int y_diff = abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py); - int x_diff = abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px); - angle = (float)y_diff / (float)x_diff; - } - - if ( angle <0.5f) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickUp][R] %d / %d = %f (angle)\n", abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py), abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), angle); -#endif//__DETAIL_DEBUG__ - goto cleanup_flick; - } - - distance = g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my; - duration = GetTimeInMillis() - base_time; - - GestureHandleGesture_Flick(num_pressed, distance, duration, direction); - goto cleanup_flick_recognized; - } - break; - case FLICK_POINT_LEFT: - diff_base_coord = diff_current_coord; - diff_current_coord = g_pGesture->fingers[idx].mx; - - if( (diff_current_coord - diff_base_coord) < 0 ) - false_diff_count++; - if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickLeft][M] false_diff_count: %d > %d\n", false_diff_count, FLICK_FALSE_Y_DIFF_COUNT); -#endif//__DETAIL_DEBUG__ - goto cleanup_flick; - } + static int max_tmajor[MAX_MT_DEVICES] = {0}; + static int total_max_tmajor = 0; + static Bool is_tmajor_invalid[MAX_MT_DEVICES] = {TRUE, TRUE}; - if( (g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) > g_pGesture->flick_minimum_height) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickLeft][M] %d - %d < %d(min_size)\n", g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px, g_pGesture->flick_minimum_height); -#endif//__DETAIL_DEBUG__ - if(abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) == 0) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickLeft][M] abs(%d - %d) = 0\n", g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py); -#endif//__DETAIL_DEBUG__ - angle = 1.0f; - } - else - { - int y_diff = abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py); - int x_diff = abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px); - angle = (float)x_diff / (float)y_diff; - } - - if ( angle < 0.5f) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[FlickLeft][M] %d / %d = %f (angle)\n", abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py), angle); -#endif//__DETAIL_DEBUG__ - goto cleanup_flick; - } + static int mt_sync_count[MAX_MT_DEVICES] = {0}; - distance = g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px; - duration = GetTimeInMillis() - base_time; + static Bool is_palm = FALSE; + PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc; + + static Bool is_retry = FALSE; + + int distance, direction, duration; + + if (g_pGesture->recognized_gesture && !(g_pGesture->recognized_gesture & WPalmFlickFilterMask)) + { + PalmFlickDebugPrint("[PalmFlick] recognize other gesture already( g_pGesture->recognized_gesture: %d)\n", g_pGesture->recognized_gesture); + PalmFlickDebugPrint("[PalmFlick][F] 1\n"); + goto flick_failed; + } + + // only first finger recognize + if (!(idx == 0 || idx == 1)) + { + PalmFlickDebugPrint("[PalmFlick] idx=%d, least two fingers come on\n", idx); + return; + } + + switch (type) + { + case ET_ButtonPress: + + if (!is_palm) + { + if (idx == 0) + { + base_time = GetTimeInMillis(); + } + + // press (x,y), touch major + update_x[idx] = base_x[idx] = g_pGesture->fingers[idx].px; + update_y[idx] = base_y[idx] = g_pGesture->fingers[idx].py; + max_tmajor[idx] = g_pGesture->max_mt_tmajor[idx]; + press_status[idx] = TRUE; + is_tmajor_invalid[idx] = FALSE; + is_line_invalid[idx] = FALSE; + + total_max_tmajor = (total_max_tmajor > max_tmajor[idx]) ? total_max_tmajor : max_tmajor[idx]; + + // press region + press_idx[idx] = prev_line_idx[idx] = line_idx[idx] = GesturePalmGetHorizIndexWithX(base_x[idx], idx, type); + + PalmFlickDebugPrint("[PalmFlick][P] idx: %d, num_pressed: %d\n", idx, g_pGesture->num_pressed); + PalmFlickDebugPrint("[PalmFlick][P] base_time: %d, base_x: %d, base_y: %d, line_idx: %d, touch_major=%d\n", + base_time, base_x[idx], base_y[idx], line_idx[idx], max_tmajor[idx]); + + // invalid region + if (line_idx[idx] < 0 || line_idx[idx] >= PALM_HORIZ_ARRAY_COUNT) + { + PalmFlickDebugPrint("[PalmFlick][P][F] No line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x[idx], line_idx[idx]); + PalmFlickDebugPrint("[PalmFlick][F] 2\n"); + goto flick_failed; + } + + // check press point when there are two fingers + if (idx == 1) + { + if (press_idx[0] != press_idx[1]) + { + PalmFlickDebugPrint("[PalmFlick] Press line_idx is the different between two fingers. 1st finger_line_idx=%d, 2nd finger_line_idx=%d\n", + press_idx[0], press_idx[1]); + PalmFlickDebugPrint("[PalmFlick][F] 2-1\n"); + goto flick_failed; + } + } + } + else + { + update_x[idx] = g_pGesture->fingers[idx].px; + update_y[idx] = g_pGesture->fingers[idx].py; + + PalmFlickDebugPrint("[PalmFlick][P] Already palm flick success. base_x=%d, base_y=%d, update_x=%d, update_y=%d\n", + base_x[idx], base_y[idx], update_x[idx], update_y[idx]); + } + + break; + + case ET_Motion: + + if (total_max_tmajor > g_pGesture->palm_flick_max_tmajor_threshold) + { + mt_sync_count[idx]++; + is_palm = TRUE; + DetailDebugPrint("[PalmFlick][M] Sufficient touch enough ! max_tmajor=%d\n", total_max_tmajor); + break; + } + + // motion information (touch major, x, y) + current_x[idx] = g_pGesture->fingers[idx].mx; + current_y[idx] = g_pGesture->fingers[idx].my; + max_tmajor[idx] = g_pGesture->max_mt_tmajor[idx]; + mt_sync_count[idx]++; + + //int temp_total_max_tmajor = (idx == 0 ? max_tmajor[0] : max_tmajor[0] + max_tmajor[1]); + int temp_total_max_tmajor = max_tmajor[idx]; + total_max_tmajor = (total_max_tmajor > temp_total_max_tmajor ? total_max_tmajor : temp_total_max_tmajor); + + PalmFlickDebugPrint("[PalmFlick][M] idx=%d, total_max_tmajor=%d, max_tmajor[0]=%d, max_tmajor[1]=%d, current current=(%d, %d)\n", + idx, total_max_tmajor, max_tmajor[0], max_tmajor[1], current_x[idx], current_y[idx]); + + // exception vezel end line motion + if (current_x[idx] < 5 || current_x[idx] > 355) + { + if (total_max_tmajor >= g_pGesture->palm_flick_max_tmajor_threshold) + { + PalmFlickDebugPrint("[PalmFlick][M][Vezel] Sufficient touch major was came(%d)\n", total_max_tmajor); + is_palm = TRUE; + } + else + { + mt_sync_count[idx]--; + PalmFlickDebugPrint("[PalmFlick][M] Except vezel end line condition. x=%d, sync_count=%d \n", + current_x[idx], mt_sync_count[idx]); + } + break; + } + + // get current position + line_idx[idx] = GesturePalmGetHorizIndexWithX(current_x[idx], idx, type); + + PalmFlickDebugPrint("[PalmFlick][M] line_idx: %d, prev_line_idx: %d, sync_count: %d\n", + line_idx[idx], prev_line_idx[idx], mt_sync_count[idx]); + + //error check + if (line_idx[idx] < 0 || line_idx[idx] >= PALM_HORIZ_ARRAY_COUNT) + { + PalmFlickDebugPrint("[PalmFlick][M][F] No line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x[idx], line_idx[idx]); + PalmFlickDebugPrint("[PalmFlick][F] 3\n"); + goto flick_failed; + } + + // screen capture motion validation + if (line_idx[idx] != prev_line_idx[idx]) + { + if (base_x[idx] <= pPalmMisc->horiz_coord[0]) + { + if (line_idx[idx] < prev_line_idx[idx]) + { + PalmFlickDebugPrint("[PalmFlick][M][F] Invalid line_idx.. line_idx: %d, prev_line_idx: %d, pPalmMisc->horiz_coord[0]: %d\n", + line_idx[idx], prev_line_idx[idx], pPalmMisc->horiz_coord[0]); + + is_line_invalid[idx] = TRUE; + + if (is_line_invalid[0] && is_line_invalid[1]) + { + PalmFlickDebugPrint("[PalmFlick][F] 4\n"); + goto flick_failed; + } + } + } + else if (base_x[idx] >= pPalmMisc->horiz_coord[PALM_HORIZ_ARRAY_COUNT-1]) + { + if (line_idx[idx] > prev_line_idx[idx]) + { + PalmFlickDebugPrint("[PalmFlick][M][F] Invalid line_idx.. line_idx: %d, prev_line_idx: %d, pPalmMisc->horiz_coord[%d]: %d\n", + line_idx[idx], prev_line_idx[idx], PALM_HORIZ_ARRAY_COUNT-1, pPalmMisc->horiz_coord[PALM_HORIZ_ARRAY_COUNT-1]); + + is_line_invalid[idx] = TRUE; + + if (is_line_invalid[0] && is_line_invalid[1]) + { + PalmFlickDebugPrint("[PalmFlick][F] 5\n"); + goto flick_failed; + } + } + } + prev_line_idx[idx] = line_idx[idx]; + } + + if (is_palm == FALSE) + { + switch (mt_sync_count[idx]) + { + case 1: + if (total_max_tmajor <= g_pGesture->palm_flick_min_tmajor_threshold) + { + PalmFlickDebugPrint("[PalmFlick][M][F] mtsync_count: %d, max_tmajor: %d(%d) line_idx: %d\n", + mt_sync_count[idx], total_max_tmajor, g_pGesture->palm_flick_min_tmajor_threshold, line_idx[idx]); + PalmFlickDebugPrint("[PalmFlick][F] 6\n"); + is_tmajor_invalid[idx] = TRUE; + //goto flick_failed; + } + break; + case 2: + if (total_max_tmajor <= (g_pGesture->palm_flick_max_tmajor_threshold - 10)) + { + PalmFlickDebugPrint("[PalmFlick][M][F] mtsync_count: %d, max_tmajor: %d(%d) line_idx: %d\n", + mt_sync_count[idx], total_max_tmajor, g_pGesture->palm_flick_max_tmajor_threshold-10, line_idx[idx]); + PalmFlickDebugPrint("[PalmFlick][F] 7\n"); + is_tmajor_invalid[idx] = TRUE; + //goto flick_failed; + } + break; + case 3: + if (total_max_tmajor < g_pGesture->palm_flick_max_tmajor_threshold) + { + PalmFlickDebugPrint("[PalmFlick][M][F] mtsync_count: %d, max_tmajor: %d(%d) line_idx: %d\n", + mt_sync_count[idx], total_max_tmajor, g_pGesture->palm_flick_max_tmajor_threshold, line_idx[idx]); + PalmFlickDebugPrint("[PalmFlick][F] 8\n"); + is_tmajor_invalid[idx] = TRUE; + //goto flick_failed; + } + break; + default: + PalmFlickDebugPrint("[PalmFlick][M] See more next motion...\n"); + break; + } + } + + if (is_tmajor_invalid[0] && is_tmajor_invalid[1]) + { + PalmFlickDebugPrint("[PalmFlick][M][F] max_tmajor=%d\n", total_max_tmajor); + goto flick_failed; + } + + current_time = GetTimeInMillis(); + + if (current_time - base_time > g_pGesture->palm_flick_time_threshold) + { + PalmFlickDebugPrint("[PalmFlick][M][F] Release event were not came too long time (%d - %d > %d)\n", current_time, base_time, g_pGesture->palm_flick_time_threshold); + PalmFlickDebugPrint("[PalmFlick][F] 10\n"); + goto flick_failed; + } + + break; + + case ET_ButtonRelease: + current_x[idx] = g_pGesture->fingers[idx].mx; + current_y[idx] = g_pGesture->fingers[idx].my; + release_status[idx] = TRUE; + + if ((update_x[idx] == current_x[idx]) && (update_y[idx] == current_y[idx])) + { + PalmFlickDebugPrint("[PalmFlick][R][F] Press point and release point are the same. base_x=%d, base_y=%d, current_x=%d, current_y=%d\n", + update_x[idx], update_y[idx], current_x[idx], current_y[idx]); + PalmFlickDebugPrint("[PalmFlick][F] 10-1\n"); + break; + //goto flick_failed; + } + + if (!is_palm) + { + is_tmajor_invalid[idx] = TRUE; + + if (is_tmajor_invalid[0] && is_tmajor_invalid[1]) + { + PalmFlickDebugPrint("[PalmFlick][R][F] Insufficient touch major was came(%d)\n", total_max_tmajor); + PalmFlickDebugPrint("[PalmFlick][F] 11\n"); + goto flick_failed; + } + } + + line_idx[idx] = GesturePalmGetHorizIndexWithX(current_x[idx], idx, type); + + if (is_palm && line_idx[idx] == 1) + { + PalmFlickDebugPrint("[PalmFlick][R] Enough major, but release. base_x=%d, base_y=%d, current_x=%d, current_y=%d\n", + base_x[idx], base_y[idx], current_x[idx], current_y[idx]); + is_retry = TRUE; + mt_sync_count[idx] = 0; + break; + } + + if (line_idx[idx] < 0 || line_idx[idx] > PALM_HORIZ_ARRAY_COUNT - 1) + { + is_line_invalid[idx] = TRUE; + + if (is_line_invalid[0] && is_line_invalid[1]) + { + PalmFlickDebugPrint("[PalmFlick][R][F] No line_idx is invalid.. base_x: %d, current_x: %d\n", base_x[idx], current_x[idx]); + PalmFlickDebugPrint("[PalmFlick][F] 12\n"); + goto flick_failed; + } + } + + current_time = GetTimeInMillis(); + + if (current_time - base_time > g_pGesture->palm_flick_time_threshold) + { + PalmFlickDebugPrint("[PalmFlick][R][F] Release event were came to have long delay (%d - %d > %d)\n", + current_time, base_time, g_pGesture->palm_flick_time_threshold); + PalmFlickDebugPrint("[PalmFlick][F] 13\n"); + goto flick_failed; + } + + direction = (line_idx[idx] <= 1) ? FLICK_EASTWARD : FLICK_WESTWARD; + distance = ABS(current_x[idx] - base_x[idx]); + duration = current_time - base_time; + + if (!is_retry) + { + if (GestureHasFingerEventMask(GestureNotifyFlick, 0)) + { + PalmFlickDebugPrint("[PalmFlick][R] Palm Flick1 !!!, direction=%d, distance=%d\n", direction, distance); + is_palm = FALSE; + GestureHandleGesture_Flick(0, distance, duration, direction); + } + } + else + { + if (mt_sync_count[idx] < 25) + { + PalmFlickDebugPrint("[PalmFlick][R][F] No enough motion=%d\n", mt_sync_count[idx]); + PalmFlickDebugPrint("[PalmFlick][F] 14\n"); + goto flick_failed; + } + else + { + if (GestureHasFingerEventMask(GestureNotifyFlick, 0)) + { + PalmFlickDebugPrint("[PalmFlick][R] Palm Flick2 !!!, direction=%d, distance=%d\n", direction, distance); + is_palm = FALSE; + GestureHandleGesture_Flick(0, distance, duration, direction); + } + } + } + + g_pGesture->recognized_gesture |= WPalmFlickFilterMask; + + goto cleanup_flick; + break; + } - GestureHandleGesture_Flick(num_pressed, distance, duration, direction); - goto cleanup_flick_recognized; - } + return; - break; - default: - goto cleanup_flick; - break; - } - break; +flick_failed: - case ET_ButtonRelease: - goto cleanup_flick; - break; - } + DetailDebugPrint("[PalmFlick][R] flick failed\n"); - return; + g_pGesture->recognized_gesture &= ~WPalmFlickFilterMask; + g_pGesture->filter_mask |= WPalmFlickFilterMask; + goto cleanup_flick; cleanup_flick: - ErrorF("[Flick][R] clenup_flick\n"); - g_pGesture->recognized_gesture &= ~WFlickFilterMask; -cleanup_flick_recognized: - ErrorF("[Flick][R] cleanup_flick_recognized\n"); - g_pGesture->filter_mask |= WFlickFilterMask; - num_pressed = 0; - base_time = 0; - false_diff_count = 0; - diff_base_coord = 0; - diff_current_coord = 0; - angle = 0.0f; - angle_base_x = angle_base_y = 0; - return; + DetailDebugPrint("[PalmFlick][R] cleanup_flick\n"); + + for (int i = 0; i < MAX_MT_DEVICES; i++) + { + base_x[i] = 0; + base_y[i] = 0; + update_x[i] = 0; + update_y[i] = 0; + current_x[i] = 0; + current_y[i] = 0; + line_idx[i] = 0; + press_idx[i] = 0; + prev_line_idx[i] = 0; + max_tmajor[i] = 0; + mt_sync_count[i] = 0; + press_status[i] = FALSE; + release_status[i] = FALSE; + is_tmajor_invalid[i] = TRUE; + is_line_invalid[i] = TRUE; + } + + total_max_tmajor = 0; + is_palm = FALSE; + is_retry = FALSE; + + return; } -void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired) +static int +GesturePalmGetHorizIndexWithX(int current_x, int idx, int type) { - static int num_pressed = 0; - static int base_area_size = 0; - static Time base_time = 0; - static int base_cx; - static int base_cy; - int cx, cy; - static pixman_box16_t base_box_ext; - int area_size; - static int state = GestureEnd; - - static OsTimerPtr hold_event_timer = NULL; - static int event_type = GestureNotifyHold; - - if( timer_expired ) - { - if( state <= GestureBegin ) - state++; + int i; + int ret_idx = -1; + static int pressed_idx[MAX_MT_DEVICES] = {-1, -1}; + PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc; -#ifdef __DETAIL_DEBUG__ - switch( state ) - { - case GestureBegin: - ErrorF("[GroupHold] HOLD Begin !\n"); - break; - - case GestureUpdate: - ErrorF("[GroupHold] HOLD Update !\n"); - break; - } -#endif//__DETAIL_DEBUG__ - - if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) ) - { - GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state); - hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type); - } - return; - } - - switch( type ) - { - case ET_ButtonPress: - g_pGesture->fingers[idx].flags |= PressFlagHold; - - if( g_pGesture->num_pressed < 2 ) - return; - - if( !base_area_size || g_pGesture->num_pressed > num_pressed ) - { - if( state != GestureEnd ) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupHold][P][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed); -#endif//__DETAIL_DEBUG__ - goto cleanup_hold; - } - - base_area_size = AREA_SIZE(&g_pGesture->area.extents); - base_cx = AREA_CENTER_X(&g_pGesture->area.extents); - base_cy = AREA_CENTER_Y(&g_pGesture->area.extents); - base_time = GetTimeInMillis(); - base_box_ext.x1 = base_cx-g_pGesture->hold_move_threshold; - base_box_ext.y1 = base_cy-g_pGesture->hold_move_threshold; - base_box_ext.x2 = base_cx+g_pGesture->hold_move_threshold; - base_box_ext.y2 = base_cy+g_pGesture->hold_move_threshold; - event_type = GestureNotifyHold; - hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type); - } - num_pressed = g_pGesture->num_pressed; + for (i = 0; i < PALM_HORIZ_ARRAY_COUNT; i++) + { + if (current_x <= pPalmMisc->horiz_coord[i]) + { + DetailDebugPrint("[GesturePalmGetHorizIndexWithX] index=%d, pPalmMisc->horiz_coord[%d]=%d\n", i, i, pPalmMisc->horiz_coord[i]); -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupHold][P]][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d\n", num_pressed, base_area_size, base_cx, base_cy); -#endif//__DETAIL_DEBUG__ - break; + ret_idx = i; + goto index_check; + } + } - case ET_Motion: - if( !(g_pGesture->fingers[idx].flags & PressFlagHold ) ) - break; + DetailDebugPrint("[GesturePalmGetHorizIndexWithX]Error ! Failed to get horiz coordinate index !\n"); + return ret_idx; - if( num_pressed < 2 ) - return; +index_check: - if( num_pressed != g_pGesture->num_pressed ) - { - if( state != GestureEnd ) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupHold][M][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed); -#endif//__DETAIL_DEBUG__ - goto cleanup_hold; - } -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupHold][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed); -#endif//__DETAIL_DEBUG__ - //goto cleanup_hold; - } - - area_size = AREA_SIZE(&g_pGesture->area.extents); - cx = AREA_CENTER_X(&g_pGesture->area.extents); - cy = AREA_CENTER_Y(&g_pGesture->area.extents); -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupHold][M][num_pressed=%d] area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size)); - ErrorF("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx)); - ErrorF("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy)); -#endif//__DETAIL_DEBUG__ - - if(area_size > 0 && base_area_size > 0) - { - if( ((area_size > base_area_size) ? (double)area_size / (double)base_area_size : (double)base_area_size / (double) area_size) >= g_pGesture->hold_area_threshold) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupHold][M] No diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%lf)!\n", area_size, base_area_size, ((area_size > base_area_size) ? (double)area_size / (double)base_area_size : (double)base_area_size / (double) area_size)); -#endif//__DETAIL_DEBUG__ - goto cleanup_hold; - } - } - - if( !INBOX(&base_box_ext, cx, cy) ) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupHold][M] No current center coordinates is not in base coordinates box !\n"); - ErrorF("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx)); - ErrorF("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy)); -#endif//__DETAIL_DEBUG__ - goto cleanup_hold; - } - break; - - case ET_ButtonRelease: - if( state != GestureEnd && num_pressed >= 2) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[GroupHold][R][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed); -#endif//__DETAIL_DEBUG__ - goto cleanup_hold; - } + if (type == ET_ButtonPress) + { + pressed_idx[idx] = ret_idx; - //ErrorF("[GroupHold][R] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed); - if( g_pGesture->num_pressed ) - break; + // first press is center + if (pressed_idx[idx] == PALM_HORIZ_ARRAY_COUNT -2) + { + DetailDebugPrint("[GesturePalmGetHorizIndexWithX][P] Invalid press area x=%d, idx=%d, pressed_idx=%d\n", current_x, idx, pressed_idx[idx]); + ret_idx = -1; + } - goto cleanup_hold; - break; - } + DetailDebugPrint("[GesturePalmGetHorizIndexWithX][P] pressed_idx=%d\n", pressed_idx[idx]); + } - return; + else if (type == ET_Motion) + { + DetailDebugPrint("[GesturePalmGetHorizIndexWithX][M] moving x=%d, idx=%d, pressed_idx=%d\n", current_x, idx, pressed_idx[idx]); + } -cleanup_hold: + else if (type == ET_ButtonRelease) + { + if ((pressed_idx[idx] == 0) && (ret_idx == (PALM_HORIZ_ARRAY_COUNT - 1))) + { + DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] From the left to the right ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx); + } + else if ((pressed_idx[idx] == (PALM_HORIZ_ARRAY_COUNT - 1)) && (ret_idx == 0)) + { + DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] From the right to the left ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx); + } + else if ((pressed_idx[idx] == ret_idx) && ret_idx != 1) + { + DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] Relased the same region ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx); + return 1; + } + else + { + DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] Invalid ! pressed_idx=%d, released_idx=%d\n", pressed_idx[idx], ret_idx); + ret_idx = -1; + } + + pressed_idx[idx] = -1; + } - if( state == GestureBegin || state == GestureUpdate ) - { - state = GestureEnd; - if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) ) - { - GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state); - } - } - else - { - g_pGesture->recognized_gesture &= ~WHoldFilterMask; - } - - g_pGesture->filter_mask |= WHoldFilterMask; - num_pressed = 0; - base_area_size = 0; - base_time = 0; - base_cx = base_cy = 0; - state = GestureEnd; - base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0; - TimerCancel(hold_event_timer); - return; + return ret_idx; } +static int +GesturePalmGetAbsAxisInfo(DeviceIntPtr dev) +{ + int i, found = 0; + int numAxes; + + Atom atom_tpalm; + Atom atom_mt_slot; + Atom atom_tracking_id; + Atom atom_tmajor; + Atom atom_tminor; + + g_pGesture->tpalm_idx = -1; + g_pGesture->tmajor_idx = -1; + g_pGesture->tminor_idx = -1; + + if (!dev || !dev->valuator) + goto out; + + numAxes = dev->valuator->numAxes; + + atom_tpalm = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_PALM); + atom_mt_slot = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_SLOT); + atom_tracking_id = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TRACKING_ID); + atom_tmajor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR); + atom_tminor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR); + + if (!numAxes || !atom_tpalm || !atom_tmajor || !atom_tminor) + { + ErrorF("one or more axes is/are not supported!\n"); + goto out; + } + + for (i = 0; i < numAxes; i++) + { + AxisInfoPtr axes = &dev->valuator->axes[i]; + + if (!axes || (axes->mode != Absolute)) + continue; + + if (axes->label == atom_tpalm) + { + g_pGesture->tpalm_idx = i; + found += 1; + } + else if (axes->label == atom_tmajor) + { + g_pGesture->tmajor_idx = i; + found += 2; + } + else if (axes->label == atom_tminor) + { + g_pGesture->tminor_idx = i; + found += 4; + } + } + + if (found != 7) + { + ErrorF("Axes for palm recognization are not supported !\n"); + goto out; + } + + g_pGesture->palm_misc.enabled = 1; + ErrorF("Axes for palm recognization are supported !\n"); + return 1; + +out: + g_pGesture->palm_misc.enabled = 0; + ErrorF("Palm recognization is not supported !\n"); + return 0; +} + +static int +GestureGetPalmValuator(InternalEvent *ev, DeviceIntPtr device) +{ + int mt_palm_idx = g_pGesture->tpalm_idx; + int mt_palm = 0; + + DeviceEvent *de = &ev->device_event; + + if (!de) + { + ErrorF("[GestureGetPalmValuator] de is NULL !\n"); + return -1; + } + + if (mt_palm_idx < 0) + { + ErrorF("[GestureGetPalmValuator] One or more of axes are not supported !\n"); + return -1; + } + + mt_palm = de->valuators.data[mt_palm_idx]; + + HoldDetectorDebugPrint("[GestureGetPalmValuator] mt_palm:%d\n", mt_palm); + + return mt_palm; +} + +static void GestureHoldDetector(int type, InternalEvent *ev, DeviceIntPtr device) +{ + int i; + int idx = -1; + pixman_region16_t tarea1; + static int num_pressed = 0; + unsigned int hold_area_size; + PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc; + int palm_flag = 0; + + if (!g_pGesture->has_hold_grabmask) + { + HoldDetectorDebugPrint("[GestureHoldDetector] g_pGesture->has_hold_grabmask=%d\n", g_pGesture->has_hold_grabmask); + + Mask eventmask = (1L << GestureNotifyHold); + + if ((g_pGesture->grabMask & eventmask) && + (g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[0].window != None)) + { + g_pGesture->has_hold_grabmask = 1; + + //Initialize a set of variables + num_pressed = 0; + memset(&g_pGesture->cts, 0, sizeof(g_pGesture->cts)); + pixman_region_init(&g_pGesture->chold_area); + + HoldDetectorDebugPrint("[GestureHoldDetector] Initialize...\n"); + } + else + { + //reset local hold_grab_mask variable + g_pGesture->has_hold_grabmask = 0; + + g_pGesture->hold_detector_activate = 0; + HoldDetectorDebugPrint("[GestureHoldDetector] has_hold_grabmask=0 and g_pGesture->hold_detector_activate=0\n"); + return; + } + } + + if (IGNORE_EVENTS == g_pGesture->ehtype || + device->id < g_pGesture->first_fingerid) + { + HoldDetectorDebugPrint("[GestureHoldDetector] Return (IGNORE_EVENTS or device->id:%d < first_fingerid:%d)\n", device->id, g_pGesture->first_fingerid); + return; + } + + palm_flag = GestureGetPalmValuator(ev, device); + + if (palm_flag) + { + GestureHandleGesture_Hold(0, 0, 0, PALM_HOLD_TIME_THRESHOLD, GestureBegin); + GestureHandleGesture_Hold(0, 0, 0, PALM_HOLD_TIME_THRESHOLD, GestureEnd); + + g_pGesture->hold_detector_activate = 0; + g_pGesture->has_hold_grabmask = 0; + HoldDetectorDebugPrint("[GestureHoldDetector] palm_flag:%d enable\n", palm_flag); + return; + } + else + { + HoldDetectorDebugPrint("[GestureHoldDetector] palm_flag:%d disable\n", palm_flag); + return; + } + + HoldDetectorDebugPrint("[GestureHoldDetector] g_pGesture->num_mt_devices:%d\n", g_pGesture->num_mt_devices); + + for (i = 0; i < g_pGesture->num_mt_devices; i++) + { + if ( device->id == g_pGesture->mt_devices[i]->id) + { + idx = i; + HoldDetectorDebugPrint("[GestureHoldDetector] idx:%d\n", idx); + break; + } + } + if ((idx < 0) || ((MAX_MT_DEVICES-1) < idx)) return; + + switch (type) + { + case ET_ButtonPress: + g_pGesture->cts[idx].status = BTN_PRESSED; + g_pGesture->cts[idx].cx = ev->device_event.root_x; + g_pGesture->cts[idx].cy = ev->device_event.root_y; + num_pressed++; + HoldDetectorDebugPrint("[GestureHoldDetector][P] cx:%d, cy:%d, num_pressed:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy, num_pressed); + + if (num_pressed < 2) + { + HoldDetectorDebugPrint("[GestureHoldDetector][P] num_pressed:%d\n", num_pressed); + break; + } + + if (num_pressed > g_pGesture->num_mt_devices) + num_pressed = g_pGesture->num_mt_devices; + + pixman_region_init(&tarea1); + pixman_region_init(&g_pGesture->chold_area); + pixman_region_init_rect(&tarea1, g_pGesture->cts[0].cx, g_pGesture->cts[0].cy, g_pGesture->cts[0].cx+1, g_pGesture->cts[0].cy+1); + + tarea1.extents.x1 = g_pGesture->cts[0].cx; + tarea1.extents.x2 = g_pGesture->cts[0].cx+1; + tarea1.extents.y1 = g_pGesture->cts[0].cy; + tarea1.extents.y2 = g_pGesture->cts[0].cy+1; + + pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1); + + for (i = 1; i < num_pressed; i++) + { + pixman_region_init_rect(&tarea1, g_pGesture->cts[i].cx, g_pGesture->cts[i].cy, g_pGesture->cts[i].cx + 1, g_pGesture->cts[i].cy + 1); + + tarea1.extents.x1 = g_pGesture->cts[i].cx; + tarea1.extents.x2 = g_pGesture->cts[i].cx + 1; + tarea1.extents.y1 = g_pGesture->cts[i].cy; + tarea1.extents.y2 = g_pGesture->cts[i].cy + 1; + + pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1); + } + break; + + case ET_Motion: + if (BTN_RELEASED == g_pGesture->cts[idx].status) + return; + + g_pGesture->cts[idx].status = BTN_MOVING; + g_pGesture->cts[idx].cx = ev->device_event.root_x; + g_pGesture->cts[idx].cy = ev->device_event.root_y; + + HoldDetectorDebugPrint("[GestureHoldDetector][M] cx:%d, cy:%d, num_pressed:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy, num_pressed); + + if (num_pressed < 2) + { + HoldDetectorDebugPrint("[GestureHoldDetector][M] num_pressed:%d\n", num_pressed); + break; + } + + pixman_region_init(&tarea1); + pixman_region_init(&g_pGesture->chold_area); + pixman_region_init_rect(&tarea1, g_pGesture->cts[0].cx, g_pGesture->cts[0].cy, g_pGesture->cts[0].cx+1, g_pGesture->cts[0].cy+1); + + tarea1.extents.x1 = g_pGesture->cts[0].cx; + tarea1.extents.x2 = g_pGesture->cts[0].cx+1; + tarea1.extents.y1 = g_pGesture->cts[0].cy; + tarea1.extents.y2 = g_pGesture->cts[0].cy+1; + + pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1); + + for (i = 1; i < num_pressed; i++) + { + pixman_region_init_rect(&tarea1, g_pGesture->cts[i].cx, g_pGesture->cts[i].cy, g_pGesture->cts[i].cx + 1, g_pGesture->cts[i].cy + 1); + + tarea1.extents.x1 = g_pGesture->cts[i].cx; + tarea1.extents.x2 = g_pGesture->cts[i].cx + 1; + tarea1.extents.y1 = g_pGesture->cts[i].cy; + tarea1.extents.y2 = g_pGesture->cts[i].cy + 1; + + pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1); + } + break; + + case ET_ButtonRelease: + g_pGesture->cts[idx].status = BTN_RELEASED; + g_pGesture->cts[idx].cx = ev->device_event.root_x; + g_pGesture->cts[idx].cy = ev->device_event.root_y; + + HoldDetectorDebugPrint("[GestureHoldDetector][R] cx:%d, cy:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy); + + num_pressed--; + if (num_pressed <3) + { + pixman_region_init(&g_pGesture->chold_area); + } + break; + } + + if (num_pressed >= 2) + { + hold_area_size = AREA_SIZE(&g_pGesture->chold_area.extents); + + HoldDetectorDebugPrint("[GestureHoldDetector] hold_area_size=%d, pPalmMisc->half_scrn_area_size=%d\n", hold_area_size, pPalmMisc->half_scrn_area_size); + + if (pPalmMisc->half_scrn_area_size <= hold_area_size) + { + GestureHandleGesture_Hold(0, AREA_CENTER_X(&g_pGesture->chold_area.extents), AREA_CENTER_Y(&g_pGesture->chold_area.extents), PALM_HOLD_TIME_THRESHOLD, GestureBegin); + GestureHandleGesture_Hold(0, AREA_CENTER_X(&g_pGesture->chold_area.extents), AREA_CENTER_Y(&g_pGesture->chold_area.extents), PALM_HOLD_TIME_THRESHOLD, GestureEnd); + + g_pGesture->hold_detector_activate = 0; + g_pGesture->has_hold_grabmask = 0; + } + } + else + { + hold_area_size = AREA_SIZE(&g_pGesture->chold_area.extents); + HoldDetectorDebugPrint("[GestureHoldDetector] num_pressed is under 2, hold_area_size=%d\n", hold_area_size); + } +} + + +static int +GesturePalmGetScreenInfo() +{ + int i; + pixman_region16_t tarea; + PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc; + ScreenPtr pScreen = miPointerCurrentScreen(); + + if (!pScreen) + { + DetailDebugPrint("[X11][GesturePalmGetScreenInfo]Failed to get screen information !\n"); + + pPalmMisc->scrn_width = pPalmMisc->scrn_height = 0; + return 0; + } + + pPalmMisc->scrn_width = pScreen->width; + pPalmMisc->scrn_height = pScreen->height; + pixman_region_init(&tarea); + pixman_region_init_rect(&tarea, 0, 0, pPalmMisc->scrn_width, pPalmMisc->scrn_height); + + DetailDebugPrint("[X11][GesturePalmGetScreenInfo] x2:%d, x2:%d, y2:%d, y1:%d \n", tarea.extents.x2, tarea.extents.x1, tarea.extents.y2, tarea.extents.y1); + pPalmMisc->half_scrn_area_size = AREA_SIZE(&tarea.extents); + pPalmMisc->half_scrn_area_size = (unsigned int)((double)pPalmMisc->half_scrn_area_size / 4); + + DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->half_scrn_area_size = %d\n", pPalmMisc->half_scrn_area_size); + + for (i = 0; i < PALM_HORIZ_ARRAY_COUNT; i++) + { + pPalmMisc->horiz_coord[i] = pPalmMisc->scrn_width * ((i+1)/(double)PALM_HORIZ_ARRAY_COUNT); + DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->horiz_coord[%d]=%d, pPalmMisc->scrn_width=%d\n", i, pPalmMisc->horiz_coord[i], pPalmMisc->scrn_width); + } + for (i = 0; i < PALM_VERTI_ARRAY_COUNT; i++) + { + pPalmMisc->verti_coord[i] = pPalmMisc->scrn_height * ((i+1)/(double)PALM_VERTI_ARRAY_COUNT); + DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->verti_coord[%d]=%d, pPalmMisc->scrn_height=%d\n", i, pPalmMisc->verti_coord[i], pPalmMisc->scrn_height); + } + + return 1; +} + + static inline void GestureEnableDisable() { - GestureEnable(1, FALSE, g_pGesture->this_device); + GestureEnable(1, FALSE, g_pGesture->this_device); #if 0 - if((g_pGesture->grabMask) || (g_pGesture->lastSelectedWin != None)) - { - GestureEnable(1, FALSE, g_pGesture->this_device); - } - else - { - GestureEnable(0, FALSE, g_pGesture->this_device); - } + if ((g_pGesture->grabMask) || (g_pGesture->lastSelectedWin != None)) + { + GestureEnable(1, FALSE, g_pGesture->this_device); + } + else + { + GestureEnable(0, FALSE, g_pGesture->this_device); + } #endif } void GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent) { - g_pGesture->grabMask = *pGrabMask; - g_pGesture->GrabEvents = (GestureGrabEventPtr)pGrabEvent; - GestureEnableDisable(); + g_pGesture->grabMask = *pGrabMask; + g_pGesture->GrabEvents = (GestureGrabEventPtr)pGrabEvent; + GestureEnableDisable(); } void GestureCbEventsSelected(Window win, Mask *pEventMask) { - g_pGesture->lastSelectedWin = win; - g_pGesture->lastSelectedMask = (pEventMask) ? *pEventMask : 0; - GestureEnableDisable(); + g_pGesture->lastSelectedWin = win; + g_pGesture->lastSelectedMask = (pEventMask) ? *pEventMask : 0; + GestureEnableDisable(); } WindowPtr GestureGetEventsWindow(void) { - Mask mask; - WindowPtr pWin; + Mask mask; + WindowPtr pWin; - pWin = GestureWindowOnXY(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py); + pWin = GestureWindowOnXY(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py); - if( pWin ) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureGetEventsWindow] pWin->drawable.id=0x%x\n", pWin->drawable.id); -#endif//__DETAIL_DEBUG__ - g_pGesture->gestureWin = pWin->drawable.id; - } - else - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureGetEventsWindow] GestureWindowOnXY returns NULL !\n"); -#endif//__DETAIL_DEBUG__ - 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->eventMask && !g_pGesture->grabMask) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureGetEventsWindow] No grabbed events or no events were selected for window(0x%x) !\n", pWin->drawable.id); -#endif//__DETAIL_DEBUG__ - return NULL; - } + if (pWin) + { + DetailDebugPrint("[GestureGetEventsWindow] pWin->drawable.id=0x%x\n", pWin->drawable.id); + g_pGesture->gestureWin = pWin->drawable.id; + } + else + { + DetailDebugPrint("[GestureGetEventsWindow] GestureWindowOnXY returns NULL !\n"); + 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->eventMask && !g_pGesture->grabMask) + { + DetailDebugPrint("[X11][GestureGetEventsWindow] No grabbed events or no events were selected for window(0x%x) !\n", pWin->drawable.id); + return NULL; + } nonempty_eventmask: -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureGetEventsWindow] g_pGesture->eventMask=0x%x\n", g_pGesture->eventMask); -#endif//__DETAIL_DEBUG__ + DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->eventMask=0x%x\n", g_pGesture->eventMask); + + mask = (GESTURE_FILTER_MASK_ALL & ~(g_pGesture->grabMask | g_pGesture->eventMask)); + + DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x, mask=0x%x\n", g_pGesture->filter_mask, mask); + + g_pGesture->filter_mask = mask; + + DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x\n", g_pGesture->filter_mask); + + return pWin; +} + +static CARD32 +GestureSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg) +{ + g_pGesture->filter_mask |= WTapFilterMask; + g_pGesture->filter_mask |= WHoldFilterMask; + LOGI("[GroupTap][GroupHold] 50ms after 1st finger.\n"); + + DetailDebugPrint("[GestureSingleFingerTimerHandler] TapFilterMask, HoldFilterMask \n"); + + if ((g_pGesture->event_sum[0] == BTN_PRESSED) && ((g_pGesture->flick_pressed_point <= FLICK_POINT_NONE) && (FLICK_POINT_MAX <= g_pGesture->flick_pressed_point))) + { + DetailDebugPrint("[GestureSingleFingerTimerHandler] press_point: %d\n", g_pGesture->flick_pressed_point); + DetailDebugPrint("[GestureSingleFingerTimerHandler] FlickFilterMask\n"); + g_pGesture->filter_mask |= WFlickFilterMask; + } + + if (g_pGesture->flick_pressed_point == FLICK_POINT_DOWN && abs(g_pGesture->fingers[0].py - g_pGesture->fingers[0].my) < 3) + { + DetailDebugPrint("[GestureSingleFingerTimerHandler] py: %d, my: %d\n", g_pGesture->fingers[0].py, g_pGesture->fingers[0].my); + DetailDebugPrint("[GestureSingleFingerTimerHandler] FlickFilterMask\n"); + g_pGesture->filter_mask |= WFlickFilterMask; + } + + DetailDebugPrint("[GestureSingleFingerTimerHandler] expired !\n"); + + if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL) + { + if ( ERROR_INVALPTR == GestureFlushOrDrop()) + { + DetailDebugPrint("[GestureSingleFingerTimerHandler] AllFilterMask, Flush!\n"); + GestureControl(g_pGesture->this_device, DEVICE_OFF); + } + } + + return 0; +} + +void +GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device) +{ + int i; + static OsTimerPtr single_finger_timer = NULL; + int idx = -1; + + if (PROPAGATE_EVENTS == g_pGesture->ehtype || device->id < g_pGesture->first_fingerid) + { + return; + } + + for (i = 0; i < g_pGesture->num_mt_devices; i++) + { + if (device->id == g_pGesture->mt_devices[i]->id) + { + idx = i; + break; + } + } + + if (idx < 0) + return; + + switch (type) + { + case ET_ButtonPress: + if (idx == 0) + { + g_pGesture->event_sum[0] = BTN_PRESSED; + } + + g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]); + + g_pGesture->fingers[idx].ptime = ev->any.time; + g_pGesture->fingers[idx].px = ev->device_event.root_x; + g_pGesture->fingers[idx].py = ev->device_event.root_y; + + g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH; + g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH; + g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT; + g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT; + + g_pGesture->num_pressed++; + g_pGesture->inc_num_pressed = g_pGesture->num_pressed; + + if (g_pGesture->inc_num_pressed == 1) + { + pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]); + } + else + { + pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]); + + for (i = 1; i < g_pGesture->inc_num_pressed; i++) + { + pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]); + } + } + + DetailDebugPrint("[GestureRecognize][P] num_pressed=%d, area_size=%d, px=%d, py=%d\n", + g_pGesture->num_pressed, AREA_SIZE(&g_pGesture->area.extents), g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py); + + if (g_pGesture->num_pressed == 1) + { + single_finger_timer = TimerSet(single_finger_timer, 0, 50, GestureSingleFingerTimerHandler, NULL); + + if (g_pGesture->fingers[idx].py <= g_pGesture->flick_press_area) + { + if ((!g_pGesture->activate_flick_down) + || (g_pGesture->fingers[idx].px <= (g_pGesture->flick_press_area_left_right)) + || (g_pGesture->fingers[idx].px >= (g_pGesture->screen_width - g_pGesture->flick_press_area_left_right))) + { + DetailDebugPrint("[GestureRecognize][P] px=%d, flick_press_area_left_right=%d\n", + g_pGesture->fingers[idx].px, g_pGesture->flick_press_area_left_right); + g_pGesture->flick_pressed_point = FLICK_POINT_NONE; + LOGI("[BackKey][F] Press touch within 40 pixel area from left or right vezel\n"); + } + else + { + DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_UP\n"); + g_pGesture->flick_pressed_point = FLICK_POINT_UP; + } + } + else + { + LOGI("[BackKey][F] Press touch outside 40 pixel area from upper vezel. \n"); + } + + if (g_pGesture->fingers[idx].py >= (g_pGesture->screen_height - g_pGesture->flick_press_area)) + { + if (!g_pGesture->activate_flick_up) + { + g_pGesture->flick_pressed_point = FLICK_POINT_NONE; + } + else + { + DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_DOWN\n"); + g_pGesture->flick_pressed_point = FLICK_POINT_DOWN; + } + } + else if ( g_pGesture->fingers[idx].px <= g_pGesture->flick_press_area_left) + { + if (!g_pGesture->activate_flick_right) + { + g_pGesture->flick_pressed_point = FLICK_POINT_NONE; + } + else + { + DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_LEFT\n"); + g_pGesture->flick_pressed_point = FLICK_POINT_LEFT; + } + } + + DetailDebugPrint("[GestureRecognize][P] flick_press_point: %d\n", g_pGesture->flick_pressed_point); + + if ((g_pGesture->flick_pressed_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= g_pGesture->flick_pressed_point)) + { + DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_NONE\n"); + g_pGesture->filter_mask |= WFlickFilterMask; + g_pGesture->flick_pressed_point = FLICK_POINT_NONE; + } + else + { + g_pGesture->flick_direction = (g_pGesture->flick_pressed_point - 1) * 2; + if ((g_pGesture->flick_direction == FLICK_WESTWARD) && (g_pGesture->power_pressed != 2)) + { + DetailDebugPrint("[GestureRecognize][P] Flick WesWard is disable when power is not pressed\n"); + g_pGesture->filter_mask |= WFlickFilterMask; + g_pGesture->flick_pressed_point = FLICK_POINT_NONE; + } + if ((g_pGesture->flick_direction < FLICK_NORTHWARD) || (FLICK_NORTHWESTWARD < g_pGesture->flick_direction)) + { + DetailDebugPrint("[GestureRecognize][P] Invalid flick direction\n"); + g_pGesture->filter_mask |= WFlickFilterMask; + g_pGesture->flick_pressed_point = FLICK_POINT_NONE; + } + + DetailDebugPrint("[GestureRecognize][P] flick_direction: %d\n", g_pGesture->flick_direction); + } + } + else + { + DetailDebugPrint("[GestureRecognize][P] Two more fingers come on!\n"); + TimerCancel(single_finger_timer); + single_finger_timer = NULL; + } + break; - mask = (GESTURE_FILTER_MASK_ALL & ~(g_pGesture->grabMask | g_pGesture->eventMask)); + case ET_Motion: + + if (!g_pGesture->fingers[idx].ptime) + { + DetailDebugPrint("[GestureRecognize][M] Start motion. idx=%d\n", idx); + g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]); + return; + } + + g_pGesture->fingers[idx].mx = ev->device_event.root_x; + g_pGesture->fingers[idx].my = ev->device_event.root_y; + g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]); + + if (idx == 0) + { + g_pGesture->event_sum[0] += BTN_MOVING; + } + + g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH; + g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH; + g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT; + g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT; + + if (g_pGesture->inc_num_pressed == 1) + { + pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]); + } + else + { + pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]); + + for (i = 1; i < g_pGesture->inc_num_pressed; i++) + { + pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]); + } + } + + DetailDebugPrint("[GestureRecognize][M] num_pressed=%d, area_size=%d, mx=%d, my=%d\n", + g_pGesture->num_pressed, AREA_SIZE(&g_pGesture->area.extents), g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].my); -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x, mask=0x%x\n", g_pGesture->filter_mask, mask); -#endif//__DETAIL_DEBUG__ + break; - g_pGesture->filter_mask = mask; + case ET_ButtonRelease: + 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; + g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]); -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x\n", g_pGesture->filter_mask); -#endif//__DETAIL_DEBUG__ + g_pGesture->num_pressed--; - return pWin; -} + if (g_pGesture->num_pressed == 0) + { + DetailDebugPrint("[GestureRecognize] All fingers were released !\n"); + } + else if (g_pGesture->num_pressed < 0) + { + DetailDebugPrint("[GestureRecognize] All fingers were released. But, num_pressed is under 0 !\n"); + } -static CARD32 -GestureSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg) -{ - g_pGesture->filter_mask |= WTapFilterMask; - g_pGesture->filter_mask |= WHoldFilterMask; + DetailDebugPrint("[GestureRecognize][R] num_pressed=%d, rx=%d, ry=%d\n", + g_pGesture->num_pressed, g_pGesture->fingers[idx].rx, g_pGesture->fingers[idx].ry); - if( (g_pGesture->event_sum[0] == BTN_PRESSED) && ( (g_pGesture->flick_pressed_point <= FLICK_POINT_NONE) && (FLICK_POINT_MAX <= g_pGesture->flick_pressed_point) ) ) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[SingleFingerTimer] press_point: %d\n", g_pGesture->flick_pressed_point); -#endif//__DETAIL_DEBUG_ - g_pGesture->filter_mask |= WFlickFilterMask; - } + break; + } -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][Single] expired !\n"); -#endif//__DETAIL_DEBUG__ - - if(g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL) - { - if( ERROR_INVALPTR == GestureFlushOrDrop() ) - { - GestureControl(g_pGesture->this_device, DEVICE_OFF); - } - } - - return 0; -} + if (!(g_pGesture->filter_mask & WFlickFilterMask)) + { + DetailDebugPrint("[GestureRecognize] GestureRecognize_groupFlick !\n"); + GestureRecognize_GroupFlick(type, ev, device, idx, g_pGesture->flick_pressed_point, g_pGesture->flick_direction); + } + if (!(g_pGesture->filter_mask & WTapFilterMask)) + { + DetailDebugPrint("[GestureRecognize] GestureRecognize_groupTap !\n"); + GestureRecognize_GroupTap(type, ev, device, idx, 0); + } + if (!(g_pGesture->filter_mask & WHoldFilterMask)) + { + DetailDebugPrint("[GestureRecognize] GestureRecognize_groupHold !\n"); + GestureRecognize_GroupHold(type, ev, device, idx, 0); + } +/* + if (!(g_pGesture->filter_mask & WPalmFlickFilterMask)) + { + DetailDebugPrint("[GestureRecognize] GestureRecognize_palmFlick !\n"); + GestureRecognize_PalmFlick(type, ev, device, idx); + } +*/ + DetailDebugPrint("[GestureRecognize][N] g_pGesture->filter_mask = 0x%x, g_pGesture->GESTURE_WATCH_FILTER_MASK_ALL = 0x%x, g_pGesture->recognized_gesture=0x%x\n", + g_pGesture->filter_mask, GESTURE_WATCH_FILTER_MASK_ALL, g_pGesture->recognized_gesture); -void -GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device) -{ - int i; - static OsTimerPtr single_finger_timer = NULL; - int idx = -1; - - if( PROPAGATE_EVENTS == g_pGesture->ehtype || - device->id < g_pGesture->first_fingerid ) - return; - - for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ ) - { - if( device->id == g_pGesture->mt_devices[i]->id ) - { - idx = i; - break; - } - } - - if( idx < 0 ) - return; - - switch( type ) - { - case ET_ButtonPress: - if( idx == 0 ) - g_pGesture->event_sum[0] = BTN_PRESSED; - g_pGesture->fingers[idx].ptime = ev->any.time; - g_pGesture->fingers[idx].px = ev->device_event.root_x; - g_pGesture->fingers[idx].py = ev->device_event.root_y; - - g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH; - g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH; - g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT; - g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT; - - g_pGesture->num_pressed++; - g_pGesture->inc_num_pressed = g_pGesture->num_pressed; - - if( g_pGesture->inc_num_pressed == 1 ) - { - pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]); -#ifdef __DETAIL_DEBUG__ - ErrorF("[P][g_pGesture->inc_num_pressed=1] AREA_SIZE(area.extents)=%d\n", AREA_SIZE(&g_pGesture->area.extents)); -#endif//__DETAIL_DEBUG__ - } - else - { - pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]); - for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ ) - { - pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]); - } -#ifdef __DETAIL_DEBUG__ - ErrorF("[P][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area.extents)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents)); -#endif//__DETAIL_DEBUG__ - } -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureRecognize][P] g_pGesture->finger_rects\n"); -#endif//__DETAIL_DEBUG__ - if(g_pGesture->num_pressed == 1) - { - single_finger_timer = TimerSet(single_finger_timer, 0, 50, GestureSingleFingerTimerHandler, NULL); - - if( g_pGesture->fingers[idx].py <= g_pGesture->flick_press_area) - { - if((!g_pGesture->activate_flick_down) - || (g_pGesture->fingers[idx].px <= (g_pGesture->flick_press_area_left_right)) - || (g_pGesture->fingers[idx].px >= (g_pGesture->screen_width - g_pGesture->flick_press_area_left_right)) ) - g_pGesture->flick_pressed_point = FLICK_POINT_NONE; - else - g_pGesture->flick_pressed_point = FLICK_POINT_UP; - } - else if(g_pGesture->fingers[idx].py >= (g_pGesture->screen_height - g_pGesture->flick_press_area)) - { - if(!g_pGesture->activate_flick_up) - g_pGesture->flick_pressed_point = FLICK_POINT_NONE; - else - g_pGesture->flick_pressed_point = FLICK_POINT_DOWN; - } - else if( g_pGesture->fingers[idx].px <= g_pGesture->flick_press_area_left) - { - if(!g_pGesture->activate_flick_right) - g_pGesture->flick_pressed_point = FLICK_POINT_NONE; - else - g_pGesture->flick_pressed_point = FLICK_POINT_LEFT; - } -#ifdef __DETAIL_DEBUG__ - ErrorF("[GestureRecognize] flick_press_point: %d\n", g_pGesture->flick_pressed_point); -#endif//__DETAIL_DEBUG__ - - if( (g_pGesture->flick_pressed_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= g_pGesture->flick_pressed_point) ) - { - g_pGesture->filter_mask |= WFlickFilterMask; - g_pGesture->flick_pressed_point = FLICK_POINT_NONE; - } - else - { - g_pGesture->flick_direction = ( g_pGesture->flick_pressed_point - 1 ) * 2; - if( (g_pGesture->flick_direction == FLICK_WESTWARD) && (g_pGesture->power_pressed != 2) ) - { - ErrorF("[GestureRecognize] Flick WesWard is disable when power is not pressed\n"); - g_pGesture->filter_mask |= WFlickFilterMask; - g_pGesture->flick_pressed_point = FLICK_POINT_NONE; - } - if( (g_pGesture->flick_direction < FLICK_NORTHWARD) || (FLICK_NORTHWESTWARD < g_pGesture->flick_direction) ) - { - ErrorF("[GestureRecognize] Invalid flick direction\n"); - g_pGesture->filter_mask |= WFlickFilterMask; - g_pGesture->flick_pressed_point = FLICK_POINT_NONE; - } -#ifdef __DETAIL_DEBUG__ - ErrorF("[GestureRecognize] flick_direction: %d\n", g_pGesture->flick_direction); -#endif//__DETAIL_DEBUG__ - } - } - else - { - TimerCancel(single_finger_timer); - single_finger_timer = NULL; - } - break; - - case ET_Motion: - if( !g_pGesture->fingers[idx].ptime ) - return; - - g_pGesture->fingers[idx].mx = ev->device_event.root_x; - g_pGesture->fingers[idx].my = ev->device_event.root_y; - - if( (g_pGesture->inc_num_pressed < 2) && (idx == 0) && (g_pGesture->event_sum[0] == BTN_PRESSED) ) - { - g_pGesture->event_sum[0] += BTN_MOVING; -#ifdef __DETAIL_DEBUG__ - ErrorF("no seconds finger comming\n"); -#endif//__DETAIL_DEBUG__ - if(g_pGesture->event_sum[0] >= 7) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("Moving Limit\n"); -#endif//__DETAIL_DEBUG__ - g_pGesture->filter_mask |= WTapFilterMask; - g_pGesture->filter_mask |= WHoldFilterMask; - } - if(g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL) - goto flush_or_drop; - } - - g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH; - g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH; - g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT; - g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT; - - if( g_pGesture->inc_num_pressed == 1 ) - { - pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]); -#ifdef __DETAIL_DEBUG__ - ErrorF("[M][g_pGesture->inc_num_pressed=1] AREA_SIZE(area)=%d\n", AREA_SIZE(&g_pGesture->area.extents)); -#endif//__DETAIL_DEBUG__ - } - else - { - pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]); - for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ ) - { - pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]); - } -#ifdef __DETAIL_DEBUG__ - ErrorF("[M][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents)); -#endif//__DETAIL_DEBUG__ - } - break; - - case ET_ButtonRelease: - 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; - - g_pGesture->num_pressed--; - if( g_pGesture->num_pressed <= 0 ) - { -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureRecognize] All fingers were released !\n"); -#endif//__DETAIL_DEBUG__ - } - break; - } - if( g_pGesture->filter_mask != GESTURE_WATCH_FILTER_MASK_ALL ) - { - if( !(g_pGesture->filter_mask & WFlickFilterMask) ) - { - GestureRecognize_GroupFlick(type, ev, device, idx, g_pGesture->flick_pressed_point, g_pGesture->flick_direction); - } - if( !(g_pGesture->filter_mask & WTapFilterMask) ) - { - GestureRecognize_GroupTap(type, ev, device, idx, 0); - } - if( !(g_pGesture->filter_mask & WHoldFilterMask) ) - { - GestureRecognize_GroupHold(type, ev, device, idx, 0); - } - } + if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL) + { + if (!g_pGesture->recognized_gesture) + { + DetailDebugPrint("[GestureRecognize][F] 1 !\n"); + goto flush_or_drop; + } + else if (!g_pGesture->num_pressed) + { + DetailDebugPrint("[GestureRecognize][F] 2 !\n"); + goto flush_or_drop; + } + } -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureRecognize][N] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask); - ErrorF("[X11][GestureRecognize][N] g_pGesture->GESTURE_WATCH_FILTER_MASK_ALL = 0x%x\n", GESTURE_WATCH_FILTER_MASK_ALL); - ErrorF("[X11][GestureRecognize][N] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture); -#endif//__DETAIL_DEBUG__ - - if( g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL ) - { - if( !g_pGesture->recognized_gesture ) - goto flush_or_drop; - else if( !g_pGesture->num_pressed ) - goto flush_or_drop; - } - - if( g_pGesture->recognized_gesture ) - { - if( g_pGesture->ehtype == KEEP_EVENTS ) - GestureEventsDrop(); - g_pGesture->ehtype = IGNORE_EVENTS; - } - return; + if (g_pGesture->recognized_gesture) + { + if (g_pGesture->ehtype == KEEP_EVENTS) + { + DetailDebugPrint("[GestureRecognize] Keep Event !\n"); + GestureEventsDrop(); + } + g_pGesture->ehtype = IGNORE_EVENTS; + } + return; flush_or_drop: -#ifdef __DETAIL_DEBUG__ - ErrorF("[GestureRecognize] GestureFlushOrDrop() !\n"); -#endif//__DETAIL_DEBUG__ - if( ERROR_INVALPTR == GestureFlushOrDrop() ) - { - GestureControl(g_pGesture->this_device, DEVICE_OFF); - } -} + DetailDebugPrint("[GestureRecognize] GestureFlushOrDrop() !\n"); + + if (ERROR_INVALPTR == GestureFlushOrDrop()) + { + GestureControl(g_pGesture->this_device, DEVICE_OFF); + } +} ErrorStatus GestureFlushOrDrop(void) { - ErrorStatus err; + ErrorStatus err; - if( g_pGesture->recognized_gesture ) - { - g_pGesture->ehtype = IGNORE_EVENTS; - GestureEventsDrop(); - } - else - { - g_pGesture->ehtype = PROPAGATE_EVENTS; + if (g_pGesture->recognized_gesture) + { + g_pGesture->ehtype = IGNORE_EVENTS; + GestureEventsDrop(); + DetailDebugPrint("[GestureFlushOrDrop][Drop] IGNORE_EVENTS\n"); + } + else + { + g_pGesture->ehtype = PROPAGATE_EVENTS; - err = GestureEventsFlush(); - if( ERROR_NONE != err ) - return err; + err = GestureEventsFlush(); -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask); - ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->GESTURE_WATCH_FILTER_MASK_ALL = 0x%x\n", GESTURE_WATCH_FILTER_MASK_ALL); - ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture); -#endif//__DETAIL_DEBUG__ - } + if (ERROR_NONE != err) + { + return err; + } - err = GestureRegionsReinit(); - if( ERROR_NONE != err ) - return err; + DetailDebugPrint("[GestureFlushOrDrop][Flush] PROPAGATE_EVENTS\n"); + DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask); + DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->GESTURE_WATCH_FILTER_MASK_ALL = 0x%x\n", GESTURE_WATCH_FILTER_MASK_ALL); + DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture); + } + + err = GestureRegionsReinit(); + + if (ERROR_NONE != err) + { + return err; + } - g_pGesture->pTempWin = NULL; - g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0; - g_pGesture->event_sum[0] = 0; + g_pGesture->pTempWin = NULL; + g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0; + g_pGesture->event_sum[0] = 0; - return ERROR_NONE; + return ERROR_NONE; } void GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) { - int i; + int i; + int idx; #ifdef __DEBUG_EVENT_HANDLER__ - ErrorF("\n[X11][GestureHandleMTSyncEvent] (%d:%d) time:%d cur:%d\n", - ev->any_event.deviceid, ev->any_event.sync, (int)ev->any.time, (int)GetTimeInMillis()); -#endif//__DEBUG_EVENT_HANDLER__ + DetailDebugPrint("[GestureHandleMTSyncEvent] (%d:%d) time:%d cur:%d\n", + ev->any_event.deviceid, ev->any_event.sync, (int)ev->any.time, (int)GetTimeInMillis()); +#endif + + if (!g_pGesture->is_active) + { + g_pGesture->ehtype = PROPAGATE_EVENTS; + DetailDebugPrint("[GestureHandleMTSyncEvent] PROPAGATE_EVENT\n"); + return; + } - if(!g_pGesture->is_active) - { - g_pGesture->ehtype = PROPAGATE_EVENTS; - return; - } - - if( MTOUCH_FRAME_SYNC_BEGIN == ev->any_event.sync ) - { - g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_BEGIN; - g_pGesture->ehtype = KEEP_EVENTS; - g_pGesture->filter_mask = 0; - g_pGesture->recognized_gesture = 0; - g_pGesture->num_pressed = 0; - - for( i=0 ; i < g_pGesture->num_mt_devices ; i++ ) - g_pGesture->fingers[i].ptime = 0; - } - else if( MTOUCH_FRAME_SYNC_END == ev->any_event.sync ) - { - g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_END; - g_pGesture->ehtype = PROPAGATE_EVENTS; - g_pGesture->flick_pressed_point = FLICK_POINT_NONE; - } + if (MTOUCH_FRAME_SYNC_BEGIN == ev->any_event.sync) + { + DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_BEGIN\n"); + g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_BEGIN; + g_pGesture->ehtype = KEEP_EVENTS; + g_pGesture->filter_mask = 0; + g_pGesture->recognized_gesture = 0; + g_pGesture->hold_detector_activate = 1; + g_pGesture->num_pressed = 0; + g_pGesture->has_hold_grabmask = 0; + g_pGesture->mtsync_total_count = 0; + + for (i=0; i < g_pGesture->num_mt_devices; i++) + { + g_pGesture->fingers[i].ptime = 0; + g_pGesture->max_mt_tmajor[i] = 0; + } + } + else if (MTOUCH_FRAME_SYNC_END == ev->any_event.sync) + { + DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_END\n"); + g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_END; + g_pGesture->ehtype = PROPAGATE_EVENTS; + g_pGesture->flick_pressed_point = FLICK_POINT_NONE; + g_pGesture->pTempWin = NULL; + g_pGesture->num_pressed = 0; + g_pGesture->hold_detected = FALSE; + } + else if (MTOUCH_FRAME_SYNC_UPDATE == ev->any_event.sync) + { + g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_UPDATE; + g_pGesture->mtsync_total_count++; + + DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_Update. mt_total_sync=%d\n", g_pGesture->mtsync_total_count); + + if ((g_pGesture->inc_num_pressed < 2) && (g_pGesture->filter_mask != GESTURE_WATCH_FILTER_MASK_ALL)) + { + if (g_pGesture->num_tap_repeated == 1 || g_pGesture->num_tap_repeated == 2) + { + if (g_pGesture->mtsync_total_count >= 6) + { + DetailDebugPrint("[GestureHandleMTSyncEvent] Moving Limit first tap repeated. tap_repeated: %d, mtsync_total_count: %d\n", + g_pGesture->num_tap_repeated, g_pGesture->mtsync_total_count); + g_pGesture->filter_mask |= WTapFilterMask; + g_pGesture->filter_mask |= WHoldFilterMask; + LOGI("[GroupTap][GroupHold] Motions are more than 6 between 1st finger and 2nd finger.\n"); + } + } + + if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL) + { + DetailDebugPrint("[GestureHandleMTSyncEvent] Gesture filter mask all. GestureFlushOrDrop() !\n"); + + if (ERROR_INVALPTR == GestureFlushOrDrop()) + { + GestureControl(g_pGesture->this_device, DEVICE_OFF); + } + } + } + } } + void GestureEmulateHWKey(DeviceIntPtr dev, int keycode) { - if(dev) - { - xf86PostKeyboardEvent(dev, keycode, 1); - xf86PostKeyboardEvent(dev, keycode, 0); - } + if (dev) + { + DetailDebugPrint("[GestureEmulateHWKey] keycode=%d\n", keycode); + xf86PostKeyboardEvent(dev, keycode, 1); + xf86PostKeyboardEvent(dev, keycode, 0); + } } void GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) { #ifdef __DEBUG_EVENT_HANDLER__ - ErrorF("[X11][GestureHandleButtonPEvent] devid=%d time:%d cur:%d (%d, %d)\n", device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y); + DetailDebugPrint("[GestureHandleButtonPressEvent] devid=%d time:%d cur:%d (%d, %d)\n", device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y); #endif//__DEBUG_EVENT_HANDLER__ - switch( g_pGesture->ehtype ) - { - case KEEP_EVENTS: - 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); - break; - - case PROPAGATE_EVENTS: - device->public.processInputProc(ev, device); - break; - - case IGNORE_EVENTS: - GestureRecognize(ET_ButtonPress, ev, device); - break; - - default: - break; - } + + switch (g_pGesture->ehtype) + { + case KEEP_EVENTS: + DetailDebugPrint("[GestureHandleButtonPressEvent] KEEP_EVENT\n"); + + 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); + } + + GestureHoldDetector(ET_ButtonPress, ev, device); + break; + + case PROPAGATE_EVENTS: + DetailDebugPrint("[GestureHandleButtonPressEvent] PROPAGATE_EVENT\n"); + + device->public.processInputProc(ev, device); + GestureHoldDetector(ET_ButtonPress, ev, device); + break; + + case IGNORE_EVENTS: + DetailDebugPrint("[GestureHandleButtonPressEvent] IGNORE_EVENTS\n"); + + GestureRecognize(ET_ButtonPress, ev, device); + break; + + default: + break; + } } void GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) { -#ifdef __DEBUG_EVENT_HANDLER__ - ErrorF("[X11][GestureHandleMotionEvent] devid=%d time:%d cur:%d (%d, %d)\n", device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y); -#endif//__DEBUG_EVENT_HANDLER__ - switch( g_pGesture->ehtype ) - { - case KEEP_EVENTS: - 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); - break; - - case PROPAGATE_EVENTS: - device->public.processInputProc(ev, device); - break; - - case IGNORE_EVENTS: - GestureRecognize(ET_Motion, ev, device); - break; - - default: - break; - } +#ifdef __DEBUG_EVENT_MOTION_HANDLER__ + DetailDebugPrint("[GestureHandleMotionEvent] devid=%d time:%d cur:%d (%d, %d)\n", device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y); +#endif + + switch (g_pGesture->ehtype) + { + case KEEP_EVENTS: + 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); + } + + GestureHoldDetector(ET_Motion, ev, device); + break; + + case PROPAGATE_EVENTS: + device->public.processInputProc(ev, device); + GestureHoldDetector(ET_Motion, ev, device); + break; + + case IGNORE_EVENTS: + GestureRecognize(ET_Motion, ev, device); + break; + + default: + break; + } } @@ -1634,508 +2770,618 @@ void GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) { #ifdef __DEBUG_EVENT_HANDLER__ - ErrorF("[X11][GestureHandleButtonREvent] devid=%d time:%d cur:%d (%d, %d)\n", device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y); -#endif//__DEBUG_EVENT_HANDLER__ - switch( g_pGesture->ehtype ) - { - case KEEP_EVENTS: - 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); - break; - - case PROPAGATE_EVENTS: - device->public.processInputProc(ev, device); + DetailDebugPrint("[GestureHandleButtonReleaseEvent] devid=%d time:%d cur:%d (%d, %d)\n", device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y); +#endif + + switch (g_pGesture->ehtype) + { + case KEEP_EVENTS: + DetailDebugPrint("[GestureHandleButtonPressEvent] KEEP_EVENT\n"); + + 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); + } + + GestureHoldDetector(ET_ButtonRelease, ev, device); + break; + + case PROPAGATE_EVENTS: + DetailDebugPrint("[GestureHandleButtonPressEvent] PROPAGATE_EVENTS\n"); +#ifdef SUPPORT_ANR_WITH_INPUT_EVENT + if( IsMaster(device) && ev->any.type == ET_ButtonRelease ) + { + if( g_pGesture->anr_window == NULL ) + { + g_pGesture->anr_window = _GestureFindANRWindow(device); + } + Time current_time; + + // Send event to the e17 process. + current_time = GetTimeInMillis(); + if( g_pGesture->anr_window != NULL ) + { + // Check anr_window validation. + if( dixLookupWindow(&g_pGesture->anr_window, prop_anr_event_window_xid, serverClient, DixSetPropAccess) != BadWindow ) + { + if( serverClient->devPrivates != NULL ) + dixChangeWindowProperty (serverClient, g_pGesture->anr_window, prop_anr_in_input_event, + XA_CARDINAL, 32, PropModeReplace, 1, ¤t_time, TRUE); + } + else + { + prop_anr_event_window_xid = 0; + g_pGesture->anr_window = NULL; + } + DetailDebugPrint("Release TOUCH!! devid=%d time:%d cur: %d\n", device->id, ev->any.time, GetTimeInMillis()); + } + } +#endif + device->public.processInputProc(ev, device); + GestureHoldDetector(ET_ButtonRelease, ev, device); #if 0 - GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down); - GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up); + GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down); + GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up); #endif - break; + break; - case IGNORE_EVENTS: - GestureRecognize(ET_ButtonRelease, ev, device); - break; + case IGNORE_EVENTS: + DetailDebugPrint("[GestureHandleButtonPressEvent] IGNORE_EVENTS\n"); + GestureRecognize(ET_ButtonRelease, ev, device); + break; - default: - break; - } - } + default: + break; + } +} void GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) { - if( (ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0) ) - { - g_pGesture->power_pressed = 2; -#ifdef __DETAIL_DEBUG__ - ErrorF("[GestureHandleKeyPressEvent] power key pressed devid: %d, hwkey_id: %d\n", device->id, g_pGesture->hwkey_id); - ErrorF("[GestureHandleKeyPressEvent] power_pressed: %d\n", g_pGesture->power_pressed); -#endif//__DETAIL_DEBUG__ - g_pGesture->power_device = device; - } - device->public.processInputProc(ev, device); + if ((ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0)) + { + g_pGesture->power_pressed = 2; + g_pGesture->power_device = device; + + DetailDebugPrint("[GestureHandleKeyPressEvent] power key pressed devid: %d, hwkey_id: %d\n", device->id, g_pGesture->hwkey_id); + DetailDebugPrint("[GestureHandleKeyPressEvent] power_pressed: %d\n", g_pGesture->power_pressed); + } + device->public.processInputProc(ev, device); } void GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) { - if( (ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0) ) - { - g_pGesture->power_pressed = 1; -#ifdef __DETAIL_DEBUG__ - ErrorF("[GestureHandleKeyReleaseEvent] power key released devid: %d, hwkey_id: %d\n", device->id, g_pGesture->hwkey_id); - ErrorF("[GestureHandleKeyReleaseEvent] power_pressed: %d\n", g_pGesture->power_pressed); -#endif//__DETAIL_DEBUG__ - g_pGesture->power_device = device; - } - device->public.processInputProc(ev, device); + if ((ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0)) + { + g_pGesture->power_pressed = 1; + g_pGesture->power_device = device; + + DetailDebugPrint("[GestureHandleKeyReleaseEvent] power key released devid: %d, hwkey_id: %d\n", device->id, g_pGesture->hwkey_id); + DetailDebugPrint("[GestureHandleKeyReleaseEvent] power_pressed: %d\n", g_pGesture->power_pressed); + } + device->public.processInputProc(ev, device); +} + +static void +GestureHandleClientState (CallbackListPtr *list, pointer closure, pointer calldata) +{ + NewClientInfoRec *clientinfo = (NewClientInfoRec*)calldata; + ClientPtr client = clientinfo->client; + + if (client->clientState != ClientStateGone) + { + return; + } + + if (!g_pGesture->factory_cmdname) + { + return; + } + + if (strncmp(client->clientIds->cmdname, g_pGesture->factory_cmdname, strlen(g_pGesture->factory_cmdname))) + { + return; + } + + if (g_pGesture->is_active == 0) + { + int prop_val = 1; + int rc = XIChangeDeviceProperty(g_pGesture->this_device, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &prop_val, FALSE); + + ErrorF("[GestureHandleClientState] %s is exited unintentionally\n", g_pGesture->factory_cmdname); + + if (rc != Success) + { + ErrorF("[GestureHandleClientState] Failed to Gesture Enable\n"); + return; + } + } } static ErrorStatus GestureEnableEventHandler(InputInfoPtr pInfo) - { - Bool res; - GestureDevicePtr pGesture = pInfo->private; +{ + Bool res; + GestureDevicePtr pGesture = pInfo->private; - res = GestureInstallResourceStateHooks(); + res = GestureInstallResourceStateHooks(); - if( !res ) - { - ErrorF("[X11][GestureEnableEventHandler] Failed on GestureInstallResourceStateHooks() !\n"); - return ERROR_ABNORMAL; - } + if (!res) + { + ErrorF("[GestureEnableEventHandler] Failed on GestureInstallResourceStateHooks() !\n"); + return ERROR_ABNORMAL; + } - res = GestureSetMaxNumberOfFingers((int)MAX_MT_DEVICES); + res = GestureSetMaxNumberOfFingers((int)MAX_MT_DEVICES); - if( !res ) - { - ErrorF("[X11][GestureEnableEventHandler] Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)MAX_MT_DEVICES); - goto failed; - } + if (!res) + { + ErrorF("[GestureEnableEventHandler] Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)MAX_MT_DEVICES); + goto failed; + } - res = GestureRegisterCallbacks(GestureCbEventsGrabbed, GestureCbEventsSelected); + res = GestureRegisterCallbacks(GestureCbEventsGrabbed, GestureCbEventsSelected); - if( !res ) - { - ErrorF("[X11][GestureEnableEventHandler] Failed to register callbacks for GestureEventsGrabbed(), GestureEventsSelected() !\n"); - goto failed; - } + if (!res) + { + ErrorF("[GestureEnableEventHandler] Failed to register callbacks for GestureEventsGrabbed(), GestureEventsSelected() !\n"); + goto failed; + } - pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 5000, GestureTimerHandler, pInfo); + pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 5000, GestureTimerHandler, pInfo); - if( !pGesture->device_setting_timer ) - { - ErrorF("[X11][GestureEnableEventHandler] Failed to set time for detecting devices !\n"); - goto failed; - } + if (!pGesture->device_setting_timer) + { + ErrorF("[GestureEnableEventHandler] Failed to set time for detecting devices !\n"); + goto failed; + } - return ERROR_NONE; + return ERROR_NONE; failed: - GestureUninstallResourceStateHooks(); - GestureUnsetMaxNumberOfFingers(); + GestureUninstallResourceStateHooks(); + GestureUnsetMaxNumberOfFingers(); - return ERROR_ABNORMAL; + return ERROR_ABNORMAL; } static ErrorStatus GestureDisableEventHandler(void) { - ErrorStatus err = ERROR_NONE; + ErrorStatus err = ERROR_NONE; - mieqSetHandler(ET_ButtonPress, NULL); - mieqSetHandler(ET_ButtonRelease, NULL); - mieqSetHandler(ET_Motion, NULL); - mieqSetHandler(ET_KeyPress, NULL); - mieqSetHandler(ET_KeyRelease, NULL); - mieqSetHandler(ET_MTSync, NULL); + mieqSetHandler(ET_ButtonPress, NULL); + mieqSetHandler(ET_ButtonRelease, NULL); + mieqSetHandler(ET_Motion, NULL); + mieqSetHandler(ET_KeyPress, NULL); + mieqSetHandler(ET_KeyRelease, NULL); + mieqSetHandler(ET_MTSync, NULL); - err = GestureFiniEQ(); + err = GestureFiniEQ(); - if( ERROR_INVALPTR == err ) - { - ErrorF("[X11][GestureDisableEventHandler] EQ is invalid or was freed already !\n"); - } + if (ERROR_INVALPTR == err) + { + ErrorF("[GestureDisableEventHandler] EQ is invalid or was freed already !\n"); + } - GestureRegisterCallbacks(NULL, NULL); - GestureUninstallResourceStateHooks(); + GestureRegisterCallbacks(NULL, NULL); + GestureUninstallResourceStateHooks(); - return err; + return err; } static CARD32 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg) { - InputInfoPtr pInfo = (InputInfoPtr)arg; - GestureDevicePtr pGesture; - int idx; - DeviceIntPtr dev; - - if(!pInfo) - { - ErrorF("[X11][%s] pInfo is NULL !\n", __FUNCTION__); - goto failed; - } - - pGesture = pInfo->private; - - idx = 0; - for( dev = inputInfo.pointer ; dev; dev = dev->next ) - { - if(IsMaster(dev) && IsPointerDevice(dev)) - { - pGesture->master_pointer = dev; - ErrorF("[X11][GestureTimerHandler][id:%d] Master Pointer=%s\n", dev->id, pGesture->master_pointer->name); - continue; - } - - if(IsXTestDevice(dev, NULL) && IsPointerDevice(dev)) - { - pGesture->xtest_pointer = dev; - ErrorF("[X11][GestureTimerHandler][id:%d] XTest Pointer=%s\n", dev->id, pGesture->xtest_pointer->name); - continue; - } - - if(IsPointerDevice(dev)) - { - 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++; - } - } - - for( dev = inputInfo.keyboard ; dev; dev = dev->next ) - { - if(g_pGesture->hwkey_name && !strncmp(dev->name, g_pGesture->hwkey_name, strlen(dev->name))) - { - g_pGesture->hwkey_id = dev->id; - g_pGesture->hwkey_dev = dev; - - ErrorF("[X11][%s] hwkey_name has been found. hwkey_id=%d (hwkey_dev->name:%s)\n", __FUNCTION__, g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name); - break; - } - else if(!strcasestr(dev->name, "keyboard") && strcasestr(dev->name, "key") && !IsXTestDevice(dev, NULL) && !IsMaster(dev)) - { - g_pGesture->hwkey_id = dev->id; - g_pGesture->hwkey_dev = dev; - - ErrorF("[X11][%s] hwkey has been found. hwkey_id=%d (hwkey_dev->name:%s)\n", __FUNCTION__, g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name); - break; - } - } - - if(!g_pGesture->hwkey_id) - { - g_pGesture->hwkey_id = inputInfo.keyboard->id; - g_pGesture->hwkey_dev = inputInfo.keyboard; - - ErrorF("[X11][%s] No hwkey has been found. Back key will go through VCK. hwkey_id=%d (hwkey_dev->name:%s)\n", - __FUNCTION__, g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name); - } - - if( !pGesture->master_pointer || !pGesture->xtest_pointer ) - { - 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; - - return 0; - } - - TimerCancel(pGesture->device_setting_timer); - pGesture->device_setting_timer = NULL; - pGesture->num_mt_devices = idx; - - if( !pGesture->num_mt_devices ) - { - ErrorF("[X11][GestureTimerHandler] Failed to mt device information !\n"); - TimerCancel(pGesture->device_setting_timer); - pGesture->device_setting_timer = NULL; - pGesture->num_mt_devices = 0; - pGesture->first_fingerid = -1; - return 0; - } - - pGesture->first_fingerid = pGesture->mt_devices[0]->id; - memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices); - g_pGesture->pTempWin = NULL; - g_pGesture->inc_num_pressed = 0; - - if( ERROR_NONE != GestureRegionsInit() || ERROR_NONE != GestureInitEQ() ) - { - goto failed; - } - - mieqSetHandler(ET_ButtonPress, GestureHandleButtonPressEvent); - mieqSetHandler(ET_ButtonRelease, GestureHandleButtonReleaseEvent); - mieqSetHandler(ET_Motion, GestureHandleMotionEvent); - mieqSetHandler(ET_KeyPress, GestureHandleKeyPressEvent); - mieqSetHandler(ET_KeyRelease, GestureHandleKeyReleaseEvent); - - //if( pGesture->is_active ) - mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent); - - return 0; + InputInfoPtr pInfo = (InputInfoPtr)arg; + GestureDevicePtr pGesture; + int idx; + DeviceIntPtr dev; -failed: + if (!pInfo) + { + ErrorF("[GestureTimerHandler][%s] pInfo is NULL !\n"); + goto failed; + } + + pGesture = pInfo->private; + + idx = 0; + for (dev = inputInfo.pointer; dev; dev = dev->next) + { + if (IsMaster(dev) && IsPointerDevice(dev)) + { + pGesture->master_pointer = dev; + ErrorF("[GestureTimerHandler][id:%d] Master Pointer=%s\n", dev->id, pGesture->master_pointer->name); + continue; + } + + if (IsXTestDevice(dev, NULL) && IsPointerDevice(dev)) + { + pGesture->xtest_pointer = dev; + ErrorF("[GestureTimerHandler][id:%d] XTest Pointer=%s\n", dev->id, pGesture->xtest_pointer->name); + continue; + } + + if (IsPointerDevice(dev)) + { + if (idx >= MAX_MT_DEVICES) + { + ErrorF("[GestureTimerHandler] Number of mt device is over MAX_MT_DEVICES(%d) !\n", MAX_MT_DEVICES); + continue; + } + pGesture->mt_devices[idx] = dev; + ErrorF("[GestureTimerHandler][id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name); + GesturePalmGetAbsAxisInfo(dev); + idx++; + } + } + + for (dev = inputInfo.keyboard ; dev; dev = dev->next) + { + if (g_pGesture->hwkey_name && !strncmp(dev->name, g_pGesture->hwkey_name, strlen(dev->name))) + { + g_pGesture->hwkey_id = dev->id; + g_pGesture->hwkey_dev = dev; + + ErrorF("[GestureTimerHandler] hwkey_name has been found. hwkey_id=%d (hwkey_dev->name:%s)\n", g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name); + break; + } + else if (!strcasestr(dev->name, "keyboard") && strcasestr(dev->name, "key") && !IsXTestDevice(dev, NULL) && !IsMaster(dev)) + { + g_pGesture->hwkey_id = dev->id; + g_pGesture->hwkey_dev = dev; + + ErrorF("[GestureTimerHandler] hwkey has been found. hwkey_id=%d (hwkey_dev->name:%s)\n", g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name); + break; + } + } + + if (!g_pGesture->hwkey_id) + { + g_pGesture->hwkey_id = inputInfo.keyboard->id; + g_pGesture->hwkey_dev = inputInfo.keyboard; + + ErrorF("[GestureTimerHandler] No hwkey has been found. Back key will go through VCK. hwkey_id=%d (hwkey_dev->name:%s)\n", + g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name); + } - GestureUninstallResourceStateHooks(); - GestureUnsetMaxNumberOfFingers(); + if (!pGesture->master_pointer || !pGesture->xtest_pointer) + { + ErrorF("[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; + + return 0; + } + + TimerCancel(pGesture->device_setting_timer); + pGesture->device_setting_timer = NULL; + pGesture->num_mt_devices = idx; + + if (!pGesture->num_mt_devices) + { + ErrorF("[GestureTimerHandler] Failed to mt device information !\n"); + TimerCancel(pGesture->device_setting_timer); + pGesture->device_setting_timer = NULL; + pGesture->num_mt_devices = 0; + pGesture->first_fingerid = -1; + return 0; + } + + pGesture->first_fingerid = pGesture->mt_devices[0]->id; + memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices); + pGesture->pRootWin = RootWindow(pGesture->master_pointer); + + if (g_pGesture->palm_misc.enabled) + { + GesturePalmGetScreenInfo(); + } + + g_pGesture->pTempWin = NULL; + g_pGesture->inc_num_pressed = 0; + + if (ERROR_NONE != GestureRegionsInit() || ERROR_NONE != GestureInitEQ()) + { + goto failed; + } + + mieqSetHandler(ET_ButtonPress, GestureHandleButtonPressEvent); + mieqSetHandler(ET_ButtonRelease, GestureHandleButtonReleaseEvent); + mieqSetHandler(ET_Motion, GestureHandleMotionEvent); + mieqSetHandler(ET_KeyPress, GestureHandleKeyPressEvent); + mieqSetHandler(ET_KeyRelease, GestureHandleKeyReleaseEvent); - return 0; + //if ( pGesture->is_active) + mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent); + + return 0; + +failed: + GestureUninstallResourceStateHooks(); + GestureUnsetMaxNumberOfFingers(); + + return 0; } BOOL IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master) { - if (IsMaster(dev)) - return FALSE; + if (IsMaster(dev)) + { + return FALSE; + } - if (master) - return (dev->xtest_master_id == master->id); + if (master) + { + return (dev->xtest_master_id == master->id); + } - return (dev->xtest_master_id != 0); + return (dev->xtest_master_id != 0); } void GestureEnable(int enable, Bool prop, DeviceIntPtr dev) { - if((!enable) && (g_pGesture->is_active)) - { - g_pGesture->ehtype = PROPAGATE_EVENTS; - mieqSetHandler(ET_MTSync, NULL); - g_pGesture->is_active = 0; - ErrorF("[X11][GestureEnable] Disabled !\n"); - } - else if((enable) && (!g_pGesture->is_active)) - { - g_pGesture->ehtype = KEEP_EVENTS; - mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent); - g_pGesture->is_active = 1; - ErrorF("[X11][GestureEnable] Enabled !\n"); - } - - if(!prop) - XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE); + if ((!enable) && (g_pGesture->is_active)) + { + g_pGesture->ehtype = PROPAGATE_EVENTS; + mieqSetHandler(ET_MTSync, NULL); + g_pGesture->is_active = 0; + ErrorF("[GestureEnable] Disabled !\n"); + int res = AddCallback (&ClientStateCallback, GestureHandleClientState, NULL); + + if (!res) + { + ErrorF("[GestureEnable] Failed to add callback for client state\n"); + return; + } + } + + else if ((enable) && (!g_pGesture->is_active)) + { + g_pGesture->ehtype = KEEP_EVENTS; + mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent); + g_pGesture->is_active = 1; + ErrorF("[GestureEnable] Enabled !\n"); + + DeleteCallback (&ClientStateCallback, GestureHandleClientState, NULL); + } + + if (!prop) + { + XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE); + } } ErrorStatus GestureRegionsInit(void) { - int i; + int i; - if( !g_pGesture ) - return ERROR_INVALPTR; + if (!g_pGesture) + { + return ERROR_INVALPTR; + } - pixman_region_init(&g_pGesture->area); + pixman_region_init(&g_pGesture->area); - for( i = 0 ; i < MAX_MT_DEVICES ; i++ ) - { - pixman_region_init_rect (&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T); - } + for (i = 0; i < MAX_MT_DEVICES; i++) + { + pixman_region_init_rect(&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T); + } - return ERROR_NONE; + return ERROR_NONE; } ErrorStatus GestureRegionsReinit(void) { - if( !g_pGesture ) - { - ErrorF("[X11][GestureRegionsReinit] Invalid pointer access !\n"); - return ERROR_INVALPTR; - } + if (!g_pGesture) + { + ErrorF("[GestureRegionsReinit] Invalid pointer access !\n"); + return ERROR_INVALPTR; + } - pixman_region_init(&g_pGesture->area); + pixman_region_init(&g_pGesture->area); - return ERROR_NONE; + return ERROR_NONE; } ErrorStatus GestureInitEQ(void) { - int i; - IEventPtr tmpEQ; - - tmpEQ = (IEventRec *)calloc(GESTURE_EQ_SIZE, sizeof(IEventRec)); - - if( !tmpEQ ) - { - ErrorF("[X11][GestureInitEQ] Failed to allocate memory for EQ !\n"); - return ERROR_ALLOCFAIL; - } - - for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ ) - { - tmpEQ[i].event = (InternalEvent *)malloc(sizeof(InternalEvent)); - if( !tmpEQ[i].event ) - { - ErrorF("[X11][GestureInitEQ] Failed to allocation memory for each event buffer in EQ !\n"); - i--; - while(i >= 0 && tmpEQ[i].event) - { - free(tmpEQ[i].event); - tmpEQ[i].event = NULL; - } - free (tmpEQ); - tmpEQ = NULL; - return ERROR_ALLOCFAIL; - } - } - - g_pGesture->EQ = tmpEQ; - g_pGesture->headEQ = g_pGesture->tailEQ = 0; - - return ERROR_NONE; + int i; + IEventPtr tmpEQ; + + tmpEQ = (IEventRec *)calloc(GESTURE_EQ_SIZE, sizeof(IEventRec)); + + if (!tmpEQ) + { + ErrorF("[GestureInitEQ] Failed to allocate memory for EQ !\n"); + return ERROR_ALLOCFAIL; + } + + for (i = 0; i < GESTURE_EQ_SIZE; i++) + { + tmpEQ[i].event = (InternalEvent *)malloc(sizeof(InternalEvent)); + if (!tmpEQ[i].event) + { + ErrorF("[GestureInitEQ] Failed to allocation memory for each event buffer in EQ !\n"); + i--; + while(i >= 0 && tmpEQ[i].event) + { + free(tmpEQ[i].event); + tmpEQ[i].event = NULL; + } + free (tmpEQ); + tmpEQ = NULL; + return ERROR_ALLOCFAIL; + } + } + + g_pGesture->EQ = tmpEQ; + g_pGesture->headEQ = g_pGesture->tailEQ = 0; + + return ERROR_NONE; } ErrorStatus GestureFiniEQ(void) { - int i; + int i; - if( !g_pGesture || !g_pGesture->EQ ) - return ERROR_INVALPTR; + if (!g_pGesture || !g_pGesture->EQ) + { + return ERROR_INVALPTR; + } - for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ ) - { - if( g_pGesture->EQ[i].event ) - { - free(g_pGesture->EQ[i].event); - g_pGesture->EQ[i].event = NULL; - } - } + for (i = 0; i < GESTURE_EQ_SIZE; i++) + { + if (g_pGesture->EQ[i].event) + { + free(g_pGesture->EQ[i].event); + g_pGesture->EQ[i].event = NULL; + } + } - free(g_pGesture->EQ); - g_pGesture->EQ = NULL; + free(g_pGesture->EQ); + g_pGesture->EQ = NULL; - return ERROR_NONE; + return ERROR_NONE; } ErrorStatus GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) { - int tail; + int tail; + + if (!g_pGesture || !g_pGesture->EQ) + { + ErrorF("[GestureEnqueueEvent] Invalid pointer access !\n"); + return ERROR_INVALPTR; + } + + tail = g_pGesture->tailEQ; - if( !g_pGesture || !g_pGesture->EQ ) - { - ErrorF("[X11][GestureEnqueueEvent] Invalid pointer access !\n"); - return ERROR_INVALPTR; - } + if (tail >= GESTURE_EQ_SIZE) + { + ErrorF("[GestureEnqueueEvent] Gesture EQ is full !\n"); + printk("[GestureEnqueueEvent] Gesture EQ is full...Force Gesture Flush !\n"); + GestureEventsFlush(); + return ERROR_EQFULL; + } - tail = g_pGesture->tailEQ; + switch (ev->any.type) + { + case ET_ButtonPress: + DetailDebugPrint("[GestureEnqueueEvent] ET_ButtonPress (id:%d)\n", device->id); + break; - if( tail >= GESTURE_EQ_SIZE ) - { - ErrorF("[X11][GestureEnqueueEvent] Gesture EQ is full !\n"); - printk("[X11][GestureEnqueueEvent] Gesture EQ is full...Force Gesture Flush !\n"); - GestureEventsFlush(); - return ERROR_EQFULL; - } + case ET_ButtonRelease: + DetailDebugPrint("[GestureEnqueueEvent] ET_ButtonRelease (id:%d)\n", device->id); + break; -#ifdef __DETAIL_DEBUG__ - switch( ev->any.type ) - { - case ET_ButtonPress: - ErrorF("[X11][GestureEnqueueEvent] ET_ButtonPress (id:%d)\n", device->id); - break; - - case ET_ButtonRelease: - ErrorF("[X11][GestureEnqueueEvent] ET_ButtonRelease (id:%d)\n", device->id); - break; - - case ET_Motion: - ErrorF("[X11][GestureEnqueueEvent] ET_Motion (id:%d)\n", device->id); - break; - } -#endif//__DETAIL_DEBUG__ - - g_pGesture->EQ[tail].device = device; - g_pGesture->EQ[tail].screen_num = screen_num; - memcpy(g_pGesture->EQ[tail].event, ev, sizeof(InternalEvent));//need to be optimized - g_pGesture->tailEQ++; - - return ERROR_NONE; + case ET_Motion: + DetailDebugPrint("[GestureEnqueueEvent] ET_Motion (id:%d)\n", device->id); + break; + } + + g_pGesture->EQ[tail].device = device; + g_pGesture->EQ[tail].screen_num = screen_num; + memcpy(g_pGesture->EQ[tail].event, ev, sizeof(InternalEvent));//need to be optimized + g_pGesture->tailEQ++; + + return ERROR_NONE; } ErrorStatus GestureEventsFlush(void) { - int i; - DeviceIntPtr device; + int i; + DeviceIntPtr device; + + if (!g_pGesture->EQ) + { + ErrorF("[GestureEventsFlush] Invalid pointer access !\n"); + return ERROR_INVALPTR; + } - if( !g_pGesture->EQ ) - { - ErrorF("[X11][GestureEventsFlush] Invalid pointer access !\n"); - return ERROR_INVALPTR; - } + DetailDebugPrint("[GestureEventsFlush]\n"); -#ifdef __DETAIL_DEBUG__ - ErrorF("[X11][GestureEventsFlush]\n"); -#endif//__DETAIL_DEBUG__ - for( i = g_pGesture->headEQ ; i < g_pGesture->tailEQ ; i++) - { - device = g_pGesture->EQ[i].device; - device->public.processInputProc(g_pGesture->EQ[i].event, device); - } - for( i = 0 ; i < MAX_MT_DEVICES ; i++ ) - g_pGesture->event_sum[i] = 0; - g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ - - return ERROR_NONE; + for (i = g_pGesture->headEQ; i < g_pGesture->tailEQ; i++) + { + device = g_pGesture->EQ[i].device; + device->public.processInputProc(g_pGesture->EQ[i].event, device); + } + + for (i = 0; i < MAX_MT_DEVICES; i++) + { + g_pGesture->event_sum[i] = 0; + } + + g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ + + return ERROR_NONE; } void GestureEventsDrop(void) { - g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ + DetailDebugPrint("[GestureEventsDrop]\n"); + g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ } #ifdef HAVE_PROPERTIES static void GestureInitProperty(DeviceIntPtr dev) { - int rc; + int rc; + +#ifdef SUPPORT_ANR_WITH_INPUT_EVENT + prop_anr_in_input_event = MakeAtom(CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT, strlen(CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT), TRUE); + prop_anr_event_window = MakeAtom(ANR_EVENT_WINDOW, strlen(ANR_EVENT_WINDOW), TRUE); +#endif - prop_gesture_recognizer_onoff = MakeAtom(GESTURE_RECOGNIZER_ONOFF, strlen(GESTURE_RECOGNIZER_ONOFF), TRUE); - rc = XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE); + prop_gesture_recognizer_onoff = MakeAtom(GESTURE_RECOGNIZER_ONOFF, strlen(GESTURE_RECOGNIZER_ONOFF), TRUE); + rc = XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE); - if (rc != Success) - return; + if (rc != Success) + { + return; + } - XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE); + XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE); } static int GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, - BOOL checkonly) + BOOL checkonly) { - if( prop_gesture_recognizer_onoff == atom ) - { - int data; - if( val->format != 32 || val->type != XA_INTEGER || val->size != 1 ) - return BadMatch; - - if( !checkonly ) - { - data = *((int *)val->data); - GestureEnable(data, TRUE, dev); - } - } - return Success; + if (prop_gesture_recognizer_onoff == atom) + { + int data; + if (val->format != 32 || val->type != XA_INTEGER || val->size != 1) + return BadMatch; + + if (!checkonly) + { + data = *((int *)val->data); + GestureEnable(data, TRUE, dev); + } + } + return Success; } #endif//HAVE_PROPERTIES @@ -2143,24 +3389,24 @@ static int GestureInit(DeviceIntPtr device) { #ifdef HAVE_PROPERTIES - GestureInitProperty(device); - XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL); + GestureInitProperty(device); + XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL); #endif - //GestureEnable(1, FALSE, g_pGesture->this_device); - return Success; + //GestureEnable(1, FALSE, g_pGesture->this_device); + return Success; } static void GestureFini(DeviceIntPtr device) { - XIRegisterPropertyHandler(device, NULL, NULL, NULL); + XIRegisterPropertyHandler(device, NULL, NULL, NULL); } static pointer GesturePlug(pointer module, pointer options, int *errmaj, int *errmin) { - xf86AddInputDriver(&GESTURE, module, 0); - return module; + xf86AddInputDriver(&GESTURE, module, 0); + return module; } static void @@ -2172,22 +3418,25 @@ static int GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) { int rc = BadAlloc; - GestureDevicePtr pGesture; + GestureDevicePtr pGesture; pGesture = calloc(1, sizeof(GestureDeviceRec)); - if (!pGesture) { + if (!pGesture) + { pInfo->private = NULL; //xf86DeleteInput(pInfo, 0); goto error; } g_pGesture = pGesture; + pInfo->private = pGesture; pInfo->flags = 0; pInfo->read_input = GestureReadInput; /* new data avl */ pInfo->switch_mode = NULL; /* toggle absolute/relative mode */ pInfo->device_control = GestureControl; /* enable/disable dev */ + /* process driver specific options */ pGesture->device = xf86SetStrOption(pInfo->options, "Device", "/dev/null"); pGesture->is_active = xf86SetIntOption(pInfo->options, "Activate", 0); @@ -2196,6 +3445,8 @@ GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) pGesture->power_pressed = 1; pGesture->hwkey_id = 0; pGesture->hwkey_dev = NULL; + pGesture->num_tap_repeated = 0; + pGesture->mtsync_total_count = 0; pGesture->hwkey_name = xf86SetStrOption(pInfo->options, "BackHWKeyName", NULL); pGesture->screen_width = xf86SetIntOption(pInfo->options,"ScreenWidth", 0); pGesture->screen_height = xf86SetIntOption(pInfo->options,"ScreenHeight", 0); @@ -2208,30 +3459,40 @@ GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) pGesture->shutdown_keycode = xf86SetIntOption(pInfo->options, "ShutdownKeycode", 0); pGesture->singletap_threshold= xf86SetIntOption(pInfo->options, "SingleTapThresHold", 0); pGesture->doubletap_threshold= xf86SetIntOption(pInfo->options, "DoubleTapThresHold", 0); + pGesture->tripletap_threshold= xf86SetIntOption(pInfo->options, "TripleTapThresHold", 0); pGesture->hold_area_threshold = xf86SetRealOption(pInfo->options, "HoldAreaThresHold", 0); pGesture->hold_move_threshold = xf86SetIntOption(pInfo->options, "HoldMoveThresHold", 0); pGesture->hold_time_threshold = xf86SetIntOption(pInfo->options, "HoldTimeThresHold", 0); + pGesture->palm_flick_time_threshold = xf86SetIntOption(pInfo->options, "PalmFlickTimeThresHold", 0); + pGesture->palm_flick_max_tmajor_threshold = xf86SetIntOption(pInfo->options, "PalmFlickMaxTouchMajorThresHold", 0); + pGesture->palm_flick_min_tmajor_threshold = xf86SetIntOption(pInfo->options, "PalmFlickMinTouchMajorThresHold", 0); pGesture->activate_flick_down = xf86SetIntOption(pInfo->options, "ActivateFlickDown", 0); pGesture->activate_flick_up = xf86SetIntOption(pInfo->options, "ActivateFlickUp", 0); pGesture->activate_flick_right = xf86SetIntOption(pInfo->options, "ActivateFlickRight", 0); + pGesture->factory_cmdname = xf86SetStrOption(pInfo->options, "FactoryCmdName", NULL); - ErrorF("[X11][%s] ###############################################################\n", __FUNCTION__); + ErrorF("[X11][%s] ###############################################################\n", __FUNCTION__); ErrorF("[X11][%s] screen_width=%d, screen_height=%d\n", __FUNCTION__, - pGesture->screen_width, pGesture->screen_height); + pGesture->screen_width, pGesture->screen_height); ErrorF("[X11][%s] FlickDownKeycode=%d, FlickUpKeycode=%d\n", __FUNCTION__, - pGesture->hwkeycode_flick_down, pGesture->hwkeycode_flick_up); + pGesture->hwkeycode_flick_down, pGesture->hwkeycode_flick_up); ErrorF("[X11][%s] flick_press_area=%d, flick_press_area_left: %d, flick_press_area_left_right: %d, flick_minimum_height=%d\n", __FUNCTION__, - pGesture->flick_press_area, pGesture->flick_press_area_left, pGesture->flick_press_area_left_right, pGesture->flick_minimum_height); + pGesture->flick_press_area, pGesture->flick_press_area_left, pGesture->flick_press_area_left_right, pGesture->flick_minimum_height); ErrorF("[X11][%s] ShutdownKeycode=%d\n", __FUNCTION__, pGesture->shutdown_keycode); ErrorF("[X11][%s] singletap_threshold=%d, doubletap_threshold=%d\n", __FUNCTION__, pGesture->singletap_threshold, pGesture->doubletap_threshold); ErrorF("[X11][%s] hold_area_threshold: %f, hold_move_threshold: %d, hold_time_threshold: %d\n", __FUNCTION__, - pGesture->hold_area_threshold, pGesture->hold_move_threshold, pGesture->hold_time_threshold); + pGesture->hold_area_threshold, pGesture->hold_move_threshold, pGesture->hold_time_threshold); + ErrorF("[X11][%s] palm_flick_time_threshold: %d, palm_flick_max_tmajor_threshold: %d, palm_flick_min_tmajor_threshold: %d\n", __FUNCTION__, + pGesture->palm_flick_time_threshold, pGesture->palm_flick_max_tmajor_threshold, pGesture->palm_flick_min_tmajor_threshold); ErrorF("[X11][%s] activate_flick_down=%d, activate_flick_up=%d, activate_flick_right=%d\n", __FUNCTION__, - pGesture->activate_flick_down, pGesture->activate_flick_up, pGesture->activate_flick_right); + pGesture->activate_flick_down, pGesture->activate_flick_up, pGesture->activate_flick_right); + ErrorF("[X11][%s] factory cmd name: %s\n", __FUNCTION__, pGesture->factory_cmdname); ErrorF("[X11][%s] ###############################################################\n", __FUNCTION__); - if(pGesture->hwkey_name) - ErrorF("[X11][%s] hwkey_name=%s\n", __FUNCTION__, pGesture->hwkey_name); + if (pGesture->hwkey_name) + { + ErrorF("[X11][%s] hwkey_name=%s\n", __FUNCTION__, pGesture->hwkey_name); + } pGesture->mtsync_status = MTOUCH_FRAME_SYNC_END; g_pGesture->grabMask = g_pGesture->eventMask = 0; @@ -2255,12 +3516,12 @@ error: static void GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) { - GestureDevicePtr pGesture = pInfo->private; + GestureDevicePtr pGesture = pInfo->private; - g_pGesture = pGesture = NULL; - pInfo->private = NULL; + g_pGesture = pGesture = NULL; + pInfo->private = NULL; - xf86DeleteInput(pInfo, 0); + xf86DeleteInput(pInfo, 0); } static int @@ -2269,32 +3530,32 @@ GestureControl(DeviceIntPtr device, int what) InputInfoPtr pInfo = device->public.devicePrivate; GestureDevicePtr pGesture = pInfo->private; - switch(what) + switch (what) { case DEVICE_INIT: - GestureInit(device); + GestureInit(device); break; - /* Switch device on. Establish socket, start event delivery. */ + /* Switch device on. Establish socket, start event delivery. */ case DEVICE_ON: xf86Msg(X_INFO, "%s: On.\n", pInfo->name); if (device->public.on) - break; + break; device->public.on = TRUE; - pGesture->this_device = device; - pGesture->num_mt_devices = 0; - if( ERROR_ABNORMAL == GestureEnableEventHandler(pInfo) ) - goto device_off; + pGesture->this_device = device; + pGesture->num_mt_devices = 0; + if (ERROR_ABNORMAL == GestureEnableEventHandler(pInfo)) + goto device_off; break; - case DEVICE_OFF: + case DEVICE_OFF: device_off: - GestureDisableEventHandler(); - GestureFini(device); - pGesture->this_device = NULL; - xf86Msg(X_INFO, "%s: Off.\n", pInfo->name); + GestureDisableEventHandler(); + GestureFini(device); + pGesture->this_device = NULL; + xf86Msg(X_INFO, "%s: Off.\n", pInfo->name); if (!device->public.on) break; @@ -2303,7 +3564,7 @@ device_off: device->public.on = FALSE; break; - case DEVICE_CLOSE: + case DEVICE_CLOSE: /* free what we have to free */ break; } @@ -2315,3 +3576,5 @@ GestureReadInput(InputInfoPtr pInfo) { } + + diff --git a/wearable/src/gesture.h b/wearable/src/gesture.h index f61d5a8..e2256db 100755 --- a/wearable/src/gesture.h +++ b/wearable/src/gesture.h @@ -41,12 +41,25 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define HAVE_PROPERTIES 1 #endif +/** + * If there's touch event in pointed window and there's no reponse, we just assume that client looks like deadlock. + * In this case, we will make a popup window and terminate application. + * To support this feature, we use SUPPORT_ANR_WITH_INPUT_EVENT flag. + */ +#define SUPPORT_ANR_WITH_INPUT_EVENT + +#define GESTURE_RECOGNIZER_ONOFF "GESTURE_RECOGNIZER_ONOFF" +#define GESTURE_PALM_REJECTION_MODE "GESTURE_PALM_REJECTION_MODE" +#define CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT "_CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT_" +#define ANR_EVENT_WINDOW "_ANR_EVENT_WINDOW_" + + #define SYSCALL(call) while (((call) == -1) && (errno == EINTR)) #define RootWindow(dev) dev->spriteInfo->sprite->spriteTrace[0] #define CLIENT_BITS(id) ((id) & RESOURCE_CLIENT_MASK) #define CLIENT_ID(id) ((int)(CLIENT_BITS(id) >> CLIENTOFFSET)) -#define MAX_MT_DEVICES 10 +#define MAX_MT_DEVICES 2 #define GESTURE_EQ_SIZE 256 #define GESTURE_RECOGNIZER_ONOFF "GESTURE_RECOGNIZER_ONOFF" @@ -68,6 +81,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SINGLE_TAP_TIMEOUT 100//in msec #define DOUBLE_TAP_TIMEOUT 250//in msec +//palm +#define PALM_HORIZ_ARRAY_COUNT 3 +#define PALM_VERTI_ARRAY_COUNT 4 + typedef int XFixed; typedef double XDouble; #define XDoubleToFixed(f) ((XFixed) ((f) * 65536)) @@ -100,10 +117,10 @@ enum }; #define TAP_AREA_THRESHOLD 10000//= 100pixel * 100pixel -#define TAP_MOVE_THRESHOLD 70//pixel +#define TAP_MOVE_THRESHOLD 35//pixel #define SGL_TAP_TIME_THRESHOLD 300//ms #define DBL_TAP_TIME_THRESHOLD 200//ms -#define MAX_TAP_REPEATS 2 +#define MAX_TAP_REPEATS 3 #define FLICK_AREA_THRESHOLD 22500//=150pixel * 150pixel #define FLICK_AREA_TIMEOUT 700//ms @@ -112,11 +129,20 @@ enum #define FLICK_FALSE_Y_DIFF_COUNT 7 #define FLICK_FALSE_X_DIFF_COUNT 5 +#define PALM_FLICK_DETECT_TIMEOUT 1000//ms +#define PALM_FLICK_MAX_TOUCH_MAJOR 130 + +#define AXIS_LABEL_PROP_ABS_MT_TRACKING_ID "Abs MT Tracking ID" +#define AXIS_LABEL_PROP_ABS_MT_SLOT "Abs MT Slot" +#define AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR "Abs MT Touch Major" +#define AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR "Abs MT Touch Minor" +#define AXIS_LABEL_PROP_ABS_MT_PALM "Abs MT Palm/MT Sumsize" typedef enum _MTSyncType { MTOUCH_FRAME_SYNC_END, - MTOUCH_FRAME_SYNC_BEGIN + MTOUCH_FRAME_SYNC_BEGIN, + MTOUCH_FRAME_SYNC_UPDATE } MTSyncType; typedef enum _EventHandleType @@ -319,8 +345,11 @@ enum #define WFlickFilterMask 0x01//(1 << 0) #define WTapFilterMask 0x02//(1 << 1) #define WHoldFilterMask 0x04//(1 << 2) +#define WPalmFlickFilterMask 0x08//(1 << 3) -#define GESTURE_WATCH_FILTER_MASK_ALL 0x07//(WFlickFilterMask | WTapFilterMask | WHoldFilterMask) +#define GESTURE_WATCH_FILTER_MASK_ALL 0x07//(WFlickFilterMask | WTapFilterMask | WHoldFilterMask ) + +#define PALM_HOLD_TIME_THRESHOLD 150 typedef struct _tagTouchStatus { @@ -338,6 +367,24 @@ typedef struct _tagTouchStatus Time rtime; //current/previous release time } TouchStatus; +typedef struct _tagCurrentTouchStatus +{ + int status;//One of BTN_RELEASED, BTN_PRESSED and BTN_MOVING + int cx; //current x + int cy; //current y +} CurTouchStatus; + +typedef struct _tagPalmDrvStatus +{ + int enabled; + int scrn_width; + int scrn_height; + unsigned int half_scrn_area_size; + int horiz_coord[PALM_HORIZ_ARRAY_COUNT]; + int verti_coord[PALM_VERTI_ARRAY_COUNT]; +} PalmMiscInfo, *PalmMiscInfoPtr; + + typedef struct _GestureDeviceRec { char *device; @@ -361,16 +408,29 @@ typedef struct _GestureDeviceRec int activate_flick_right;//left to right int screen_width; int screen_height; + int singletap_threshold; int doubletap_threshold; + int tripletap_threshold; + + int num_tap_repeated; + double hold_area_threshold; int hold_move_threshold; int hold_time_threshold; + int palm_flick_time_threshold; + int palm_flick_max_tmajor_threshold; + int palm_flick_min_tmajor_threshold; + char *factory_cmdname; + + int max_mt_tmajor[MAX_MT_DEVICES]; + int hwkey_id; char *hwkey_name; DeviceIntPtr hwkey_dev; MTSyncType mtsync_status; + int mtsync_total_count; DeviceIntPtr power_device; @@ -389,6 +449,19 @@ typedef struct _GestureDeviceRec int headEQ; int tailEQ; + int hold_detector_activate; + int has_hold_grabmask; + pixman_region16_t chold_area; + CurTouchStatus cts[MAX_MT_DEVICES]; + Bool hold_detected; + + PalmMiscInfo palm_misc; + int tmajor_idx; + int tminor_idx; + int tpalm_idx; + int mt_px_idx; + int mt_py_idx; + pixman_region16_t area; pixman_region16_t finger_rects[MAX_MT_DEVICES]; @@ -407,6 +480,8 @@ typedef struct _GestureDeviceRec DeviceIntPtr mt_devices[MAX_MT_DEVICES]; DeviceIntPtr master_pointer; DeviceIntPtr xtest_pointer; + + WindowPtr anr_window; } GestureDeviceRec, *GestureDevicePtr ; #endif//_GESTURE_H_ -- 2.7.4