1 /**************************************************************************
3 xserver-xorg-input-gesture
5 Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
7 Contact: Sung-Jin Park <sj76.park@samsung.com>
8 Sangjin LEE <lsj119@samsung.com>
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
36 #include <linux/input.h>
37 #include <linux/types.h>
39 #include <xf86_OSproc.h>
44 #include <xf86Xinput.h>
46 #include <xorgVersion.h>
49 #ifdef HAVE_PROPERTIES
50 #include <X11/Xatom.h>
51 #include <xserver-properties.h>
52 /* 1.6 has properties, but no labels */
53 #ifdef AXIS_LABEL_PROP
61 //#define __DETAIL_DEBUG__
62 //#define __DEBUG_EVENT_HANDLER__
63 //#define __PalmFlick_DEBUG__
64 //#define __HOLD_DETECTOR_DEBUG__
66 #ifdef __PalmFlick_DEBUG__
67 #define PalmFlickDebugPrint ErrorF
69 #define PalmFlickDebugPrint(...)
72 #ifdef __HOLD_DETECTOR_DEBUG__
73 #define HoldDetectorDebugPrint ErrorF
75 #define HoldDetectorDebugPrint(...)
79 #ifdef __DETAIL_DEBUG__
80 #define DetailDebugPrint ErrorF
82 #define DetailDebugPrint(...)
87 #include <sys/syscall.h>
90 #include <sys/types.h>
92 #include <xorg-server.h>
93 #include <xorgVersion.h>
94 #include <xf86Module.h>
95 #include <X11/Xatom.h>
99 #define LOG_TAG "GESTURE"
104 char *strcasestr(const char *s, const char *find);
105 extern ScreenPtr miPointerCurrentScreen(void);
106 static void printk(const char* fmt, ...) __attribute__((format(printf, 1, 0)));
109 static int GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
110 static void GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
111 static pointer GesturePlug(pointer module, pointer options, int *errmaj, int *errmin);
112 static void GestureUnplug(pointer p);
113 static int GestureControl(DeviceIntPtr device,int what);
114 static int GestureInit(DeviceIntPtr device);
115 static void GestureFini(DeviceIntPtr device);
116 static void GestureReadInput(InputInfoPtr pInfo);
119 ErrorStatus GestureRegionsInit(void);
121 //event queue handling functions
122 ErrorStatus GestureInitEQ(void);
123 ErrorStatus GestureFiniEQ(void);
124 ErrorStatus GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
125 ErrorStatus GestureEventsFlush(void);
126 void GestureEventsDrop(void);
129 ErrorStatus GestureRegionsReinit(void);
130 void GestureEnable(int enable, Bool prop, DeviceIntPtr dev);
131 void GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent);
132 void GestureCbEventsSelected(Window win, Mask *pEventMask);
133 WindowPtr GestureGetEventsWindow(void);
134 static int GestureGetFingerIndexFromDevice(DeviceIntPtr device);
136 //Enqueued event handlers and enabler/disabler
137 static ErrorStatus GestureEnableEventHandler(InputInfoPtr pInfo);
138 static ErrorStatus GestureDisableEventHandler(void);
139 static CARD32 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
140 static CARD32 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
141 void GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
142 void GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
143 void GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
144 void GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
145 void GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
146 void GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
148 void GestureEmulateHWKey(DeviceIntPtr dev, int keycode);
150 //Gesture recognizer helper
151 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21
152 static Bool PointInBorderSize(WindowPtr pWin, int x, int y);
154 static WindowPtr GestureWindowOnXY(int x, int y);
155 Bool GestureHasFingerEventMask(int eventType, int num_finger);
157 //Gesture recognizer and handlers
158 void GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device);
159 void GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
160 void GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int start_point, int direction);
161 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
162 void GestureRecognize_PalmFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx);
163 void GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction);
164 void GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy);
165 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds);
166 ErrorStatus GestureFlushOrDrop(void);
168 static int GestureGetPalmValuator(InternalEvent *ev, DeviceIntPtr device);
169 static int GesturePalmGetAbsAxisInfo(DeviceIntPtr dev);
170 static void GestureHoldDetector(int type, InternalEvent *ev, DeviceIntPtr device);
171 static int GesturePalmGetScreenInfo();
172 static int GesturePalmGetHorizIndexWithX(int current_x, int idx, int type);
174 void GestureGenerateTouchCancelEvent(void);
176 static void GestureDPMSCallback(CallbackListPtr *pcbl, void *unused, void *calldata);
178 #ifdef HAVE_PROPERTIES
179 //function related property handling
180 static void GestureInitProperty(DeviceIntPtr dev);
181 static int GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkonly);
184 static Atom prop_gesture_recognizer_onoff = None;
186 #ifdef SUPPORT_ANR_WITH_INPUT_EVENT
187 static Atom prop_anr_in_input_event = None;
188 static Atom prop_anr_event_window = None;
189 static Window prop_anr_event_window_xid = None;
193 GestureDevicePtr g_pGesture = NULL;
194 _X_EXPORT InputDriverRec GESTURE = {
204 static XF86ModuleVersionInfo GestureVersionRec =
210 XORG_VERSION_CURRENT,
211 PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR,
212 PACKAGE_VERSION_PATCHLEVEL,
219 _X_EXPORT XF86ModuleData gestureModuleData =
226 extern CallbackListPtr DPMSCallback;
229 printk(const char* fmt, ...)
231 static FILE* fp = NULL;
232 static char init = 0;
237 fp = fopen("/dev/kmsg", "wt");
243 va_start(argptr, fmt);
244 vfprintf(fp, fmt, argptr);
249 #ifdef SUPPORT_ANR_WITH_INPUT_EVENT
251 _GestureFindANRWindow(DeviceIntPtr device)
254 WindowPtr anr_window=NULL;
259 root = RootWindow(device);
261 if( prop_anr_event_window == None )
262 prop_anr_event_window = MakeAtom(ANR_EVENT_WINDOW, strlen(ANR_EVENT_WINDOW), TRUE);
264 rc = dixLookupProperty (&pProp, root, prop_anr_event_window, serverClient, DixReadAccess);
265 if (rc == Success && pProp->data){
266 anr_xid = *(int*)pProp->data;
271 rc = dixLookupWindow(&anr_window, anr_xid, serverClient, DixSetPropAccess);
272 if( rc == BadWindow )
274 ErrorF("Can't find ANR window !!\n");
277 prop_anr_event_window_xid = anr_xid;
280 ErrorF("ANR Window is %#x. Ptr is %#x\n", anr_xid, anr_window);
285 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21
287 PointInBorderSize(WindowPtr pWin, int x, int y)
290 if (pixman_region_contains_point (&pWin->borderSize, x, y, &box))
299 GestureWindowOnXY(int x, int y)
304 DeviceIntPtr pDev = g_pGesture->master_pointer;
306 pSprite = pDev->spriteInfo->sprite;
307 pSprite->spriteTraceGood = 1; /* root window still there */
308 pWin = RootWindow(pDev)->firstChild;
312 if ((pWin->mapped) &&
313 (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
314 (x < pWin->drawable.x + (int)pWin->drawable.width +
315 wBorderWidth(pWin)) &&
316 (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
317 (y < pWin->drawable.y + (int)pWin->drawable.height +
319 /* When a window is shaped, a further check
320 * is made to see if the point is inside
323 && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
324 && (!wInputShape(pWin) ||
325 RegionContainsPoint(wInputShape(pWin),
326 x - pWin->drawable.x,
327 y - pWin->drawable.y, &box))
329 /* In rootless mode windows may be offscreen, even when
330 * they're in X's stack. (E.g. if the native window system
331 * implements some form of virtual desktop system).
333 && !pWin->rootlessUnhittable
337 if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
339 pSprite->spriteTraceSize += 10;
340 pSprite->spriteTrace = realloc(pSprite->spriteTrace,
341 pSprite->spriteTraceSize*sizeof(WindowPtr));
342 if (!pSprite->spriteTrace) {
346 pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
347 pWin = pWin->firstChild;
350 pWin = pWin->nextSib;
352 return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
356 GestureHasFingerEventMask(int eventType, int num_finger)
359 Mask eventmask = (1L << eventType);
361 if ((g_pGesture->grabMask & eventmask) &&
362 (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[num_finger].window != None))
364 DetailDebugPrint("[GestureHasFingerEventMask] TRUE !! Has grabMask\n");
368 if (g_pGesture->eventMask & eventmask)
370 DetailDebugPrint("[GestureHasFingerEventMask] TRUE !! Has eventMask\n");
374 DetailDebugPrint("[GestureHasFingerEventMask] FALSE !! eventType=%d, num_finger=%d\n", eventType, num_finger);
380 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
382 int event_type = *(int *)arg;
386 case GestureNotifyHold:
387 DetailDebugPrint("[GestureEventTimerHandler] GestureNotifyHold (event_type = %d)\n", event_type);
388 GestureRecognize_GroupHold(event_type, NULL, NULL, 0, 1);
390 case GestureNotifyTap:
391 DetailDebugPrint("[GestureEventTimerHandler] GestureNotifyTap (event_type = %d)\n", event_type);
392 GestureRecognize_GroupTap(event_type, NULL, NULL, 0, 1);
395 DetailDebugPrint("[GestureEventTimerHandler] unknown event_type (=%d)\n", event_type);
398 DetailDebugPrint("[GestureEventTimerHandler] timer=%x\n", (unsigned int)timer);
406 GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy)
409 WindowPtr target_pWin;
410 xGestureNotifyTapEvent tev;
412 //skip non-tap events and single finger tap
413 if (!tap_repeat || num_finger <= 1)
418 DetailDebugPrint("[GestureHandleGesture_Tap] num_finger=%d, tap_repeat=%d, cx=%d, cy=%d\n", num_finger, tap_repeat, cx, cy);
420 g_pGesture->recognized_gesture |= WTapFilterMask;
421 memset(&tev, 0, sizeof(xGestureNotifyTapEvent));
422 tev.type = GestureNotifyTap;
423 tev.kind = GestureDone;
424 tev.num_finger = num_finger;
425 tev.tap_repeat = tap_repeat;
430 target_win = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].window;
431 target_pWin = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].pWin;
433 if (g_pGesture->grabMask && (target_win != None))
435 tev.window = target_win;
439 tev.window = g_pGesture->gestureWin;
442 DetailDebugPrint("[GestureHandleGesture_Tap] tev.window=0x%x, g_pGesture->grabMask=0x%x\n", (unsigned int)tev.window, (unsigned int)g_pGesture->grabMask);
444 GestureSendEvent(target_pWin, GestureNotifyTap, GestureTapMask, (xGestureCommonEvent *)&tev);
445 LOGI("GroupTap Event done. 2 fingers %d tap!", tap_repeat);
449 GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction)
451 if (num_of_fingers == 0)
454 WindowPtr target_pWin;
455 xGestureNotifyFlickEvent fev;
457 DetailDebugPrint("[GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n", num_of_fingers, distance, duration, direction);
459 g_pGesture->recognized_gesture |= WPalmFlickFilterMask;
461 memset(&fev, 0, sizeof(xGestureNotifyFlickEvent));
462 fev.type = GestureNotifyFlick;
463 fev.kind = GestureDone;
464 fev.num_finger = num_of_fingers;
465 fev.distance = distance;
466 fev.duration = duration;
467 fev.direction = direction;
469 if (g_pGesture->GrabEvents)
471 target_win = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].window;
472 target_pWin = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].pWin;
480 if (g_pGesture->grabMask && (target_win != None))
482 fev.window = target_win;
486 fev.window = g_pGesture->gestureWin;
489 DetailDebugPrint("[GestureHandleGesture_Flick] fev.window=0x%x, g_pGesture->grabMask=0x%x\n", fev.window, g_pGesture->grabMask);
491 GestureSendEvent(target_pWin, GestureNotifyFlick, GestureFlickMask, (xGestureCommonEvent *)&fev);
495 DetailDebugPrint("[GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n", num_of_fingers, distance, duration, direction);
499 case FLICK_NORTHWARD:
500 DetailDebugPrint("[GestureHandleGesture_Flick] Flick Down \n");
501 GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down);
504 case FLICK_SOUTHWARD:
505 DetailDebugPrint("[GestureHandleGesture_Flick] Flick Up \n");
506 GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up);
509 if (g_pGesture->power_pressed == 2)
511 DetailDebugPrint("[GestureHandleGesture_Flick] Flick Right & power_pressed\n");
512 GestureEmulateHWKey(g_pGesture->hwkey_dev, 122);
518 g_pGesture->recognized_gesture |= WFlickFilterMask;
522 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds)
525 WindowPtr target_pWin;
526 xGestureNotifyHoldEvent hev;
528 DetailDebugPrint("[GestureHandleGesture_Hold] num_fingers=%d, cx=%d, cy=%d, holdtime=%d, kinds=%d\n", num_fingers, cx, cy, holdtime, kinds);
530 if (num_fingers == 0)
532 g_pGesture->hold_detected = TRUE;
533 LOGI("[PalmHold] PalmHold success !\n");
537 g_pGesture->recognized_gesture |= WHoldFilterMask;
540 memset(&hev, 0, sizeof(xGestureNotifyHoldEvent));
541 hev.type = GestureNotifyHold;
543 hev.num_finger = num_fingers;
544 hev.holdtime = holdtime;
548 if (g_pGesture->GrabEvents)
550 target_win = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].window;
551 target_pWin = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].pWin;
559 if (g_pGesture->grabMask && (target_win != None))
561 hev.window = target_win;
565 hev.window = g_pGesture->gestureWin;
568 DetailDebugPrint("[GestureHandleGesture_Hold] hev.window=0x%x, g_pGesture->grabMask=0x%x\n", hev.window, g_pGesture->grabMask);
570 GestureSendEvent(target_pWin, GestureNotifyHold, GestureHoldMask, (xGestureCommonEvent *)&hev);
571 LOGI("[GroupHold] GestureHold success !\n");
576 GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
578 static int num_pressed = 0;
579 static int base_area_size = 0;
584 static int state = 0;
585 static int mbits = 0;
588 static pixman_box16_t base_box_ext;
590 static int tap_repeat = 0;
591 static int prev_num_pressed = 0;
593 static OsTimerPtr tap_event_timer = NULL;
594 static int event_type = GestureNotifyTap;
598 DetailDebugPrint("[GroupTap][Timer] state=%d, num_pressed=%d, tap_repeat=%d\n", state, num_pressed, tap_repeat);
602 case 1://first tap initiation check
605 DetailDebugPrint("[GroupTap][Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", num_pressed, tap_repeat);
606 DetailDebugPrint("[GroupTap][F] 1\n");
617 DetailDebugPrint("[GroupTap][Timer][state=2] 2 finger %d tap\n", tap_repeat);
618 LOGI("[GroupTap][F] Second tap doesn't come up in 400ms after first tap.\n");
622 if (GestureHasFingerEventMask(GestureNotifyTap, prev_num_pressed))
624 DetailDebugPrint("[GroupTap] Success 1!! 2 finger %d tap\n", tap_repeat);
625 GestureHandleGesture_Tap(prev_num_pressed, tap_repeat, base_cx, base_cy);
636 g_pGesture->fingers[idx].flags |= PressFlagTap;
638 if (g_pGesture->num_pressed < 2)
640 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);
644 if ((!base_area_size || g_pGesture->num_pressed > num_pressed))
646 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
647 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
648 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
649 base_box_ext.x1 = base_cx-TAP_MOVE_THRESHOLD;
650 base_box_ext.y1 = base_cy-TAP_MOVE_THRESHOLD;
651 base_box_ext.x2 = base_cx+TAP_MOVE_THRESHOLD;
652 base_box_ext.y2 = base_cy+TAP_MOVE_THRESHOLD;
654 TimerCancel(tap_event_timer);
655 tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->singletap_threshold, GestureEventTimerHandler, (int *)&event_type);
657 num_pressed = g_pGesture->num_pressed;
659 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);
663 if (!(g_pGesture->fingers[idx].flags & PressFlagTap))
670 DetailDebugPrint("[GroupTap][M] num_pressed=%d, return \n", num_pressed);
674 if (num_pressed != g_pGesture->num_pressed)
676 DetailDebugPrint("[GroupTap][M] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
680 if (mbits == (pow(2, num_pressed)-1))
682 area_size = AREA_SIZE(&g_pGesture->area.extents);
683 cx = AREA_CENTER_X(&g_pGesture->area.extents);
684 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
686 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));
687 DetailDebugPrint("[GroupTap][M] cx=%d, base_cx=%d, diff=%d\n", cx, g_pGesture->fingers[idx].mx, ABS(cx-base_cx));
688 DetailDebugPrint("[GroupTap][M] cy=%d, base_cy=%d, diff=%d\n", cy, g_pGesture->fingers[idx].my, ABS(cy-base_cy));
690 if (ABS(base_area_size-area_size) >= TAP_AREA_THRESHOLD)
692 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));
693 DetailDebugPrint("[GroupTap][F] 3\n");
694 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));
699 if (!INBOX(&base_box_ext, cx, cy))
701 DetailDebugPrint("[GroupTap][M] current center coordinates is not in base coordinates box !\n");
702 DetailDebugPrint("[GroupTap][F] 4\n");
703 LOGI("[GroupTap][F] current center coordinates is not in base coordinates box !\n");
710 case ET_ButtonRelease:
711 if (g_pGesture->num_pressed)
713 DetailDebugPrint("[GroupTap][R] Second finger doesn't come up. g_pGesture->num_pressed=%d\n", g_pGesture->num_pressed);
719 prev_num_pressed = num_pressed;
723 g_pGesture->num_tap_repeated = tap_repeat;
725 DetailDebugPrint("[GroupTap][R] tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, num_pressed, prev_num_pressed);
726 DetailDebugPrint("[GroupTap][R] base_rx=%d, base_ry=%d,\n", g_pGesture->fingers[idx].rx, g_pGesture->fingers[idx].ry);
728 if ((num_pressed != prev_num_pressed) || (!GestureHasFingerEventMask(GestureNotifyTap, num_pressed)))
730 DetailDebugPrint("[GroupTap][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
731 num_pressed, prev_num_pressed, num_pressed);
732 DetailDebugPrint("[GroupTap][F] 5\n");
733 LOGI("[GroupTap][F] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
734 num_pressed, prev_num_pressed, num_pressed);
740 DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat);
741 TimerCancel(tap_event_timer);
742 tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->doubletap_threshold, GestureEventTimerHandler, (int *)&event_type);
744 prev_num_pressed = num_pressed;
749 else if (tap_repeat == 2)
751 DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat);
752 TimerCancel(tap_event_timer);
753 tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->tripletap_threshold, GestureEventTimerHandler, (int *)&event_type);
755 base_area_size = num_pressed = 0;
759 DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat);
761 if (tap_repeat == MAX_TAP_REPEATS)
763 if (GestureHasFingerEventMask(GestureNotifyTap, num_pressed))
765 DetailDebugPrint("[GroupTap] Sucess 2!\n");
766 GestureHandleGesture_Tap(num_pressed, tap_repeat, base_cx, base_cy);
771 if (tap_repeat >= MAX_TAP_REPEATS)
773 LOGI("[GroupTap][F] More than 3 taps. Ignore. \n");
777 prev_num_pressed = num_pressed;
786 DetailDebugPrint("[GroupTap][cleanup_tap]\n");
790 g_pGesture->recognized_gesture &= ~WTapFilterMask;
793 g_pGesture->filter_mask |= WTapFilterMask;
795 if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
797 DetailDebugPrint("[GroupTap][cleanup] GestureFlushOrDrop() !\n");
799 if (ERROR_INVALPTR == GestureFlushOrDrop())
801 GestureControl(g_pGesture->this_device, DEVICE_OFF);
806 g_pGesture->num_tap_repeated = tap_repeat = 0;
807 prev_num_pressed = 0;
810 TimerCancel(tap_event_timer);
815 GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int start_point, int direction)
817 static int num_pressed = 0;
818 static Time base_time = 0;
821 static int diff_base_coord = 0;
822 static int diff_base_minor_coord = 0;
823 static int diff_current_coord = 0;
824 static int false_diff_count = 0;
825 static int false_minor_diff_count = 0;
826 static float angle = 0.0f;
827 static int angle_base_x = 0, angle_base_y = 0;
828 static int motion_count = 0;
830 if (g_pGesture->num_pressed > 1)
832 DetailDebugPrint("[GroupFlick][F] 1\n");
836 if ((start_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= start_point))
838 DetailDebugPrint("[GroupFlick][F] 2\n");
845 g_pGesture->fingers[idx].flags = PressFlagFlick;
846 base_time = GetTimeInMillis();
847 num_pressed = g_pGesture->num_pressed;
851 if (g_pGesture->fingers[idx].py > g_pGesture->flick_press_area)
853 DetailDebugPrint("[GroupFlick][FlickDown][P] press coord is out of bound. (%d, %d)\n",
854 g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
855 DetailDebugPrint("[GroupFlick][F] 3\n");
856 //LOGI("[BackKey][F] press coord is out of bound (40 pixel from upper vezel). press y=%d\n", g_pGesture->fingers[idx].py);
860 angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
861 angle_base_x = g_pGesture->fingers[idx].px;
862 DetailDebugPrint("[GroupFlick][FlickDown][P] px=%d, py=%d\n", g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
865 case FLICK_POINT_DOWN:
866 if (g_pGesture->fingers[idx].py < g_pGesture->screen_height - g_pGesture->flick_press_area)
868 DetailDebugPrint("[GroupFlick][FlickUp][P] press coord is out of bound. (%d, %d)\n",
869 g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
870 DetailDebugPrint("[GroupFlick][F] 4\n");
873 angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
874 angle_base_x = g_pGesture->fingers[idx].px;
877 case FLICK_POINT_LEFT:
878 if (g_pGesture->fingers[idx].px > g_pGesture->flick_press_area)
880 DetailDebugPrint("[GroupFlick][FlickLeft][P] press coord is out of bound. (%d, %d)\n",
881 g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
882 DetailDebugPrint("[GroupFlick][F] 5\n");
885 angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
886 angle_base_x = g_pGesture->fingers[idx].px;
890 DetailDebugPrint("[GroupFlick][F] 6\n");
901 if (motion_count > 15)
903 DetailDebugPrint("[GroupFlick][F] 6-1 motion_count=%d\n", motion_count);
904 LOGI("[BackKey][F] More than 15 motion.\n");
908 if (!(g_pGesture->fingers[idx].flags & PressFlagFlick))
916 diff_base_coord = diff_current_coord;
917 diff_current_coord = g_pGesture->fingers[idx].my;
919 if ((diff_current_coord - diff_base_coord) < 0)
921 DetailDebugPrint("[GroupFlick][FlickDown][M] false_diff\n");
925 if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
927 DetailDebugPrint("[GroupFlick][FlickDown][M] false_diff_count: %d > %d\n",
928 false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
929 DetailDebugPrint("[GroupFlick][F] 7\n");
930 LOGI("[BackKey][F] Direction is wrong for 7 times.\n");
934 if ((g_pGesture->fingers[idx].my < g_pGesture->flick_press_area) &&
935 (abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) >(int)( g_pGesture->screen_width/2)))
937 DetailDebugPrint("[GroupFlick][FlickDown][M] move x: %d - %d, y coord: %d\n",
938 g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].my);
939 DetailDebugPrint("[GroupFlick][F] 8\n");
940 LOGI("[BackKey][F] From press point, moving x axis is more than half screen size.\n");
944 if ((g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) > g_pGesture->flick_minimum_height)
946 DetailDebugPrint("[GroupFlick][FlickDown][M] %d - %d < %d(min_size), angle_base_coord (%d, %d)\n",
947 g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py, g_pGesture->flick_minimum_height, angle_base_x, angle_base_y);
949 if (abs(g_pGesture->fingers[idx].mx - angle_base_x) == 0)
951 DetailDebugPrint("[GroupFlick][FlickDown][M] abs(%d - %d) = 0\n",
952 g_pGesture->fingers[idx].mx, angle_base_x);
957 DetailDebugPrint("[GroupFlick][FlickDown][M] angle_base_x: %d, angle_base_y: %d\n",
958 angle_base_x, angle_base_y);
959 int y_diff = abs(g_pGesture->fingers[idx].my - angle_base_y);
960 int x_diff = abs(g_pGesture->fingers[idx].mx - angle_base_x);
961 angle = (float)y_diff / (float)x_diff;
966 DetailDebugPrint("[GroupFlick][FlickDown][M][F] %d / %d = %f (angle)\n",
967 abs(g_pGesture->fingers[idx].my - angle_base_y), abs(g_pGesture->fingers[idx].mx - angle_base_x), angle);
968 DetailDebugPrint("[GroupFlick][F] 9\n");
969 LOGI("[BackKey][F] angle is improper. %d < 0.23\n", angle);
973 distance = g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py;
974 duration = GetTimeInMillis() - base_time;
976 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
977 DetailDebugPrint("[GroupFlick][FlickDown][M] FlickDown Done!!\n");
978 goto cleanup_flick_recognized;
982 if ((g_pGesture->fingers[idx].mx - diff_base_minor_coord) < 0)
984 false_minor_diff_count++;
987 if (false_minor_diff_count> FLICK_FALSE_X_DIFF_COUNT)
989 DetailDebugPrint("[GroupFlick][FlickDown][M] false_minor_diff_count: %d > %d\n",
990 false_minor_diff_count, FLICK_FALSE_X_DIFF_COUNT);
991 DetailDebugPrint("[GroupFlick][F] 10\n");
996 if (g_pGesture->fingers[idx].my < g_pGesture->flick_press_area)
998 angle_base_x = g_pGesture->fingers[idx].px;
999 angle_base_y = g_pGesture->fingers[idx].py;
1001 DetailDebugPrint("[GroupFlick][FlickDown][M] mx=%d, my=%d, diff_x=%d, diff_y=%d\n",
1002 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));
1006 case FLICK_POINT_DOWN:
1007 diff_base_coord = diff_current_coord;
1008 diff_current_coord = g_pGesture->fingers[idx].my;
1010 if ((diff_base_coord - diff_current_coord) < 0)
1015 if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
1017 DetailDebugPrint("[GroupFlick][FlickUp][M] false_diff_count: %d > %d\n",
1018 false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
1019 DetailDebugPrint("[GroupFlick][F] 11\n");
1023 if ((g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my) > g_pGesture->flick_minimum_height)
1025 DetailDebugPrint("[GroupFlick][FlickUp][R] %d - %d < %d(min_size)\n",
1026 g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py, g_pGesture->flick_minimum_height);
1027 if (abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) == 0)
1029 DetailDebugPrint("[GroupFlick][FlickUp][R] abs(%d - %d) = 0\n",
1030 g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px);
1035 int y_diff = abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py);
1036 int x_diff = abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px);
1037 angle = (float)y_diff / (float)x_diff;
1042 DetailDebugPrint("[GroupFlick][FlickUp][R] %d / %d = %f (angle)\n",
1043 abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py), abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), angle);
1044 DetailDebugPrint("[GroupFlick][F] 12\n");
1048 distance = g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my;
1049 duration = GetTimeInMillis() - base_time;
1051 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
1052 goto cleanup_flick_recognized;
1056 case FLICK_POINT_LEFT:
1057 diff_base_coord = diff_current_coord;
1058 diff_current_coord = g_pGesture->fingers[idx].mx;
1060 if ((diff_current_coord - diff_base_coord) < 0)
1065 if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
1067 DetailDebugPrint("[GroupFlick][FlickLeft][M] false_diff_count: %d > %d\n",
1068 false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
1069 DetailDebugPrint("[GroupFlick][F] 13\n");
1073 if ((g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) > g_pGesture->flick_minimum_height)
1075 DetailDebugPrint("[GroupFlick][FlickLeft][M] %d - %d < %d(min_size)\n",
1076 g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px, g_pGesture->flick_minimum_height);
1078 if (abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) == 0)
1080 DetailDebugPrint("[GroupFlick][FlickLeft][M] abs(%d - %d) = 0\n",
1081 g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py);
1086 int y_diff = abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py);
1087 int x_diff = abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px);
1088 angle = (float)x_diff / (float)y_diff;
1093 DetailDebugPrint("[GroupFlick][FlickLeft][M] %d / %d = %f (angle)\n",
1094 abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py), angle);
1095 DetailDebugPrint("[GroupFlick][F] 14\n");
1099 distance = g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px;
1100 duration = GetTimeInMillis() - base_time;
1102 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
1103 goto cleanup_flick_recognized;
1108 DetailDebugPrint("[GroupFlick][F] 15\n");
1114 case ET_ButtonRelease:
1115 DetailDebugPrint("[GroupFlick][R][F] 16\n");
1123 DetailDebugPrint("[GroupFlick] cleanup_flick \n");
1124 g_pGesture->recognized_gesture &= ~WFlickFilterMask;
1127 cleanup_flick_recognized:
1128 DetailDebugPrint("[GroupFlick] Flick recognized !\n");
1129 g_pGesture->filter_mask |= WFlickFilterMask;
1132 false_diff_count = 0;
1133 diff_base_coord = 0;
1134 diff_current_coord = 0;
1136 angle_base_x = angle_base_y = 0;
1141 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1143 static int num_pressed = 0;
1144 static int base_area_size = 0;
1145 static Time base_time = 0;
1149 static pixman_box16_t base_box_ext;
1151 static int state = GestureEnd;
1153 static OsTimerPtr hold_event_timer = NULL;
1154 static int event_type = GestureNotifyHold;
1158 if (state <= GestureBegin)
1166 DetailDebugPrint("[GroupHold] HOLD Begin !\n");
1170 DetailDebugPrint("[GroupHold] HOLD Update !\n");
1174 if (GestureHasFingerEventMask(GestureNotifyHold, num_pressed))
1176 DetailDebugPrint("[GroupHold] Success 1! \n");
1177 GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1180 hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type);
1187 case ET_ButtonPress:
1188 g_pGesture->fingers[idx].flags |= PressFlagHold;
1190 if (g_pGesture->num_pressed < 2)
1192 DetailDebugPrint("[GroupHold][P] No num_finger changed ! num_pressed=%d\n", num_pressed);
1193 DetailDebugPrint("[GroupHold][F] 0\n");
1197 if (!base_area_size || g_pGesture->num_pressed > num_pressed)
1199 if (state != GestureEnd)
1201 DetailDebugPrint("[GroupHold][P][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1202 DetailDebugPrint("[GroupHold][F] 1\n");
1207 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1208 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1209 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1210 base_time = GetTimeInMillis();
1212 base_box_ext.x1 = base_cx-g_pGesture->hold_move_threshold;
1213 base_box_ext.y1 = base_cy-g_pGesture->hold_move_threshold;
1214 base_box_ext.x2 = base_cx+g_pGesture->hold_move_threshold;
1215 base_box_ext.y2 = base_cy+g_pGesture->hold_move_threshold;
1217 event_type = GestureNotifyHold;
1219 hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type);
1221 num_pressed = g_pGesture->num_pressed;
1223 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);
1228 if (!(g_pGesture->fingers[idx].flags & PressFlagHold))
1230 DetailDebugPrint("[GroupHold][M] No PressFlagHold\n");
1234 if (num_pressed < 2)
1236 DetailDebugPrint("[GroupHold][M] No num_finger changed ! num_pressed=%d\n", num_pressed);
1237 DetailDebugPrint("[GroupHold][F] 2\n");
1241 if (num_pressed != g_pGesture->num_pressed)
1243 if (state != GestureEnd)
1245 DetailDebugPrint("[GroupHold][M][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1246 DetailDebugPrint("[GroupHold][F] 3\n");
1250 DetailDebugPrint("[GroupHold][M] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1253 area_size = AREA_SIZE(&g_pGesture->area.extents);
1254 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1255 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1257 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));
1258 DetailDebugPrint("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1259 DetailDebugPrint("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1261 if (area_size > 0 && base_area_size > 0)
1263 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)
1265 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));
1266 DetailDebugPrint("[GroupHold][F] 4\n");
1271 if (!INBOX(&base_box_ext, cx, cy))
1273 DetailDebugPrint("[GroupHold][M] No current center coordinates is not in base coordinates box !\n");
1274 DetailDebugPrint("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1275 DetailDebugPrint("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1276 DetailDebugPrint("[GroupHold][F] 5\n");
1281 case ET_ButtonRelease:
1282 if (state != GestureEnd && num_pressed >= 2)
1284 DetailDebugPrint("[GroupHold][R] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1285 DetailDebugPrint("[GroupHold][F] 6\n");
1289 if (g_pGesture->num_pressed)
1291 DetailDebugPrint("[GroupHold][R] num_pressed=%d\n", num_pressed);
1292 DetailDebugPrint("[GroupHold][F] 7\n");
1304 DetailDebugPrint("[GroupHold][cleanup_hold] enter!\n");
1306 if (state == GestureBegin || state == GestureUpdate)
1309 if (GestureHasFingerEventMask(GestureNotifyHold, num_pressed))
1311 DetailDebugPrint("[GroupHold] Success 2!\n");
1312 GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1317 g_pGesture->recognized_gesture &= ~WHoldFilterMask;
1320 g_pGesture->filter_mask |= WHoldFilterMask;
1324 base_cx = base_cy = 0;
1326 base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
1327 TimerCancel(hold_event_timer);
1332 GestureGetMaxTmajor(InternalEvent *ev, int max_tmajor)
1334 int mt_tmajor_idx = g_pGesture->tmajor_idx;
1337 DeviceEvent *de = &ev->device_event;
1341 DetailDebugPrint("[GestureGetMaxTmajor] de is NULL !\n");
1345 if (mt_tmajor_idx < 0)
1347 DetailDebugPrint("[GestureGetMaxTmajor] One or more of axes are not supported !\n");
1351 mt_tmajor = de->valuators.data[mt_tmajor_idx];
1353 DetailDebugPrint("[GestureGetMaxTmajor]mt_tmajor_idx=%d, mt_tmajor=%d, max_tmajor=%d\n", mt_tmajor_idx, mt_tmajor, max_tmajor);
1355 return ((mt_tmajor > max_tmajor) ? mt_tmajor : max_tmajor);
1360 GestureRecognize_PalmFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx)
1362 // static int num_pressed = 0;
1363 static int base_time = 0, current_time = 0;
1364 static int base_x[MAX_MT_DEVICES] = {0}, base_y[MAX_MT_DEVICES] = {0};
1365 static int update_x[MAX_MT_DEVICES] = {0}, update_y[MAX_MT_DEVICES] = {0};
1368 static int current_x[MAX_MT_DEVICES] = {0}, current_y[MAX_MT_DEVICES] = {0};
1369 static Bool press_status[MAX_MT_DEVICES] = {FALSE, FALSE};
1370 static Bool release_status[MAX_MT_DEVICES] = {FALSE, FALSE};
1372 static int line_idx[MAX_MT_DEVICES] = {0}, prev_line_idx[MAX_MT_DEVICES] = {0}, press_idx[MAX_MT_DEVICES] = {0};
1373 static Bool is_line_invalid[MAX_MT_DEVICES] = {TRUE, TRUE};
1375 static int max_tmajor[MAX_MT_DEVICES] = {0};
1376 static int total_max_tmajor = 0;
1377 static Bool is_tmajor_invalid[MAX_MT_DEVICES] = {TRUE, TRUE};
1379 static int mt_sync_count[MAX_MT_DEVICES] = {0};
1381 static Bool is_palm = FALSE;
1382 PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
1384 static Bool is_retry = FALSE;
1386 int distance, direction, duration;
1388 if (g_pGesture->recognized_gesture && !(g_pGesture->recognized_gesture & WPalmFlickFilterMask))
1390 PalmFlickDebugPrint("[PalmFlick] recognize other gesture already( g_pGesture->recognized_gesture: %d)\n", g_pGesture->recognized_gesture);
1391 PalmFlickDebugPrint("[PalmFlick][F] 1\n");
1395 // only first finger recognize
1396 if (!(idx == 0 || idx == 1))
1398 PalmFlickDebugPrint("[PalmFlick] idx=%d, least two fingers come on\n", idx);
1404 case ET_ButtonPress:
1410 base_time = GetTimeInMillis();
1413 // press (x,y), touch major
1414 update_x[idx] = base_x[idx] = g_pGesture->fingers[idx].px;
1415 update_y[idx] = base_y[idx] = g_pGesture->fingers[idx].py;
1416 max_tmajor[idx] = g_pGesture->max_mt_tmajor[idx];
1417 press_status[idx] = TRUE;
1418 is_tmajor_invalid[idx] = FALSE;
1419 is_line_invalid[idx] = FALSE;
1421 total_max_tmajor = (total_max_tmajor > max_tmajor[idx]) ? total_max_tmajor : max_tmajor[idx];
1424 press_idx[idx] = prev_line_idx[idx] = line_idx[idx] = GesturePalmGetHorizIndexWithX(base_x[idx], idx, type);
1426 PalmFlickDebugPrint("[PalmFlick][P] idx: %d, num_pressed: %d\n", idx, g_pGesture->num_pressed);
1427 PalmFlickDebugPrint("[PalmFlick][P] base_time: %d, base_x: %d, base_y: %d, line_idx: %d, touch_major=%d\n",
1428 base_time, base_x[idx], base_y[idx], line_idx[idx], max_tmajor[idx]);
1431 if (line_idx[idx] < 0 || line_idx[idx] >= PALM_HORIZ_ARRAY_COUNT)
1433 PalmFlickDebugPrint("[PalmFlick][P][F] No line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x[idx], line_idx[idx]);
1434 PalmFlickDebugPrint("[PalmFlick][F] 2\n");
1438 // check press point when there are two fingers
1441 if (press_idx[0] != press_idx[1])
1443 PalmFlickDebugPrint("[PalmFlick] Press line_idx is the different between two fingers. 1st finger_line_idx=%d, 2nd finger_line_idx=%d\n",
1444 press_idx[0], press_idx[1]);
1445 PalmFlickDebugPrint("[PalmFlick][F] 2-1\n");
1452 update_x[idx] = g_pGesture->fingers[idx].px;
1453 update_y[idx] = g_pGesture->fingers[idx].py;
1455 PalmFlickDebugPrint("[PalmFlick][P] Already palm flick success. base_x=%d, base_y=%d, update_x=%d, update_y=%d\n",
1456 base_x[idx], base_y[idx], update_x[idx], update_y[idx]);
1463 if (total_max_tmajor > g_pGesture->palm_flick_max_tmajor_threshold)
1465 mt_sync_count[idx]++;
1467 DetailDebugPrint("[PalmFlick][M] Sufficient touch enough ! max_tmajor=%d\n", total_max_tmajor);
1471 // motion information (touch major, x, y)
1472 current_x[idx] = g_pGesture->fingers[idx].mx;
1473 current_y[idx] = g_pGesture->fingers[idx].my;
1474 max_tmajor[idx] = g_pGesture->max_mt_tmajor[idx];
1475 mt_sync_count[idx]++;
1477 //int temp_total_max_tmajor = (idx == 0 ? max_tmajor[0] : max_tmajor[0] + max_tmajor[1]);
1478 int temp_total_max_tmajor = max_tmajor[idx];
1479 total_max_tmajor = (total_max_tmajor > temp_total_max_tmajor ? total_max_tmajor : temp_total_max_tmajor);
1481 PalmFlickDebugPrint("[PalmFlick][M] idx=%d, total_max_tmajor=%d, max_tmajor[0]=%d, max_tmajor[1]=%d, current current=(%d, %d)\n",
1482 idx, total_max_tmajor, max_tmajor[0], max_tmajor[1], current_x[idx], current_y[idx]);
1484 // exception vezel end line motion
1485 if (current_x[idx] < 5 || current_x[idx] > 355)
1487 if (total_max_tmajor >= g_pGesture->palm_flick_max_tmajor_threshold)
1489 PalmFlickDebugPrint("[PalmFlick][M][Vezel] Sufficient touch major was came(%d)\n", total_max_tmajor);
1494 mt_sync_count[idx]--;
1495 PalmFlickDebugPrint("[PalmFlick][M] Except vezel end line condition. x=%d, sync_count=%d \n",
1496 current_x[idx], mt_sync_count[idx]);
1501 // get current position
1502 line_idx[idx] = GesturePalmGetHorizIndexWithX(current_x[idx], idx, type);
1504 PalmFlickDebugPrint("[PalmFlick][M] line_idx: %d, prev_line_idx: %d, sync_count: %d\n",
1505 line_idx[idx], prev_line_idx[idx], mt_sync_count[idx]);
1508 if (line_idx[idx] < 0 || line_idx[idx] >= PALM_HORIZ_ARRAY_COUNT)
1510 PalmFlickDebugPrint("[PalmFlick][M][F] No line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x[idx], line_idx[idx]);
1511 PalmFlickDebugPrint("[PalmFlick][F] 3\n");
1515 // screen capture motion validation
1516 if (line_idx[idx] != prev_line_idx[idx])
1518 if (base_x[idx] <= pPalmMisc->horiz_coord[0])
1520 if (line_idx[idx] < prev_line_idx[idx])
1522 PalmFlickDebugPrint("[PalmFlick][M][F] Invalid line_idx.. line_idx: %d, prev_line_idx: %d, pPalmMisc->horiz_coord[0]: %d\n",
1523 line_idx[idx], prev_line_idx[idx], pPalmMisc->horiz_coord[0]);
1525 is_line_invalid[idx] = TRUE;
1527 if (is_line_invalid[0] && is_line_invalid[1])
1529 PalmFlickDebugPrint("[PalmFlick][F] 4\n");
1534 else if (base_x[idx] >= pPalmMisc->horiz_coord[PALM_HORIZ_ARRAY_COUNT-1])
1536 if (line_idx[idx] > prev_line_idx[idx])
1538 PalmFlickDebugPrint("[PalmFlick][M][F] Invalid line_idx.. line_idx: %d, prev_line_idx: %d, pPalmMisc->horiz_coord[%d]: %d\n",
1539 line_idx[idx], prev_line_idx[idx], PALM_HORIZ_ARRAY_COUNT-1, pPalmMisc->horiz_coord[PALM_HORIZ_ARRAY_COUNT-1]);
1541 is_line_invalid[idx] = TRUE;
1543 if (is_line_invalid[0] && is_line_invalid[1])
1545 PalmFlickDebugPrint("[PalmFlick][F] 5\n");
1550 prev_line_idx[idx] = line_idx[idx];
1553 if (is_palm == FALSE)
1555 switch (mt_sync_count[idx])
1558 if (total_max_tmajor <= g_pGesture->palm_flick_min_tmajor_threshold)
1560 PalmFlickDebugPrint("[PalmFlick][M][F] mtsync_count: %d, max_tmajor: %d(%d) line_idx: %d\n",
1561 mt_sync_count[idx], total_max_tmajor, g_pGesture->palm_flick_min_tmajor_threshold, line_idx[idx]);
1562 PalmFlickDebugPrint("[PalmFlick][F] 6\n");
1563 is_tmajor_invalid[idx] = TRUE;
1564 //goto flick_failed;
1568 if (total_max_tmajor <= (g_pGesture->palm_flick_max_tmajor_threshold - 10))
1570 PalmFlickDebugPrint("[PalmFlick][M][F] mtsync_count: %d, max_tmajor: %d(%d) line_idx: %d\n",
1571 mt_sync_count[idx], total_max_tmajor, g_pGesture->palm_flick_max_tmajor_threshold-10, line_idx[idx]);
1572 PalmFlickDebugPrint("[PalmFlick][F] 7\n");
1573 is_tmajor_invalid[idx] = TRUE;
1574 //goto flick_failed;
1578 if (total_max_tmajor < g_pGesture->palm_flick_max_tmajor_threshold)
1580 PalmFlickDebugPrint("[PalmFlick][M][F] mtsync_count: %d, max_tmajor: %d(%d) line_idx: %d\n",
1581 mt_sync_count[idx], total_max_tmajor, g_pGesture->palm_flick_max_tmajor_threshold, line_idx[idx]);
1582 PalmFlickDebugPrint("[PalmFlick][F] 8\n");
1583 is_tmajor_invalid[idx] = TRUE;
1584 //goto flick_failed;
1588 PalmFlickDebugPrint("[PalmFlick][M] See more next motion...\n");
1593 if (is_tmajor_invalid[0] && is_tmajor_invalid[1])
1595 PalmFlickDebugPrint("[PalmFlick][M][F] max_tmajor=%d\n", total_max_tmajor);
1599 current_time = GetTimeInMillis();
1601 if (current_time - base_time > g_pGesture->palm_flick_time_threshold)
1603 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);
1604 PalmFlickDebugPrint("[PalmFlick][F] 10\n");
1610 case ET_ButtonRelease:
1611 current_x[idx] = g_pGesture->fingers[idx].mx;
1612 current_y[idx] = g_pGesture->fingers[idx].my;
1613 release_status[idx] = TRUE;
1615 if ((update_x[idx] == current_x[idx]) && (update_y[idx] == current_y[idx]))
1617 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",
1618 update_x[idx], update_y[idx], current_x[idx], current_y[idx]);
1619 PalmFlickDebugPrint("[PalmFlick][F] 10-1\n");
1621 //goto flick_failed;
1626 is_tmajor_invalid[idx] = TRUE;
1628 if (is_tmajor_invalid[0] && is_tmajor_invalid[1])
1630 PalmFlickDebugPrint("[PalmFlick][R][F] Insufficient touch major was came(%d)\n", total_max_tmajor);
1631 PalmFlickDebugPrint("[PalmFlick][F] 11\n");
1636 line_idx[idx] = GesturePalmGetHorizIndexWithX(current_x[idx], idx, type);
1638 if (is_palm && line_idx[idx] == 1)
1640 PalmFlickDebugPrint("[PalmFlick][R] Enough major, but release. base_x=%d, base_y=%d, current_x=%d, current_y=%d\n",
1641 base_x[idx], base_y[idx], current_x[idx], current_y[idx]);
1643 mt_sync_count[idx] = 0;
1647 if (line_idx[idx] < 0 || line_idx[idx] > PALM_HORIZ_ARRAY_COUNT - 1)
1649 is_line_invalid[idx] = TRUE;
1651 if (is_line_invalid[0] && is_line_invalid[1])
1653 PalmFlickDebugPrint("[PalmFlick][R][F] No line_idx is invalid.. base_x: %d, current_x: %d\n", base_x[idx], current_x[idx]);
1654 PalmFlickDebugPrint("[PalmFlick][F] 12\n");
1659 current_time = GetTimeInMillis();
1661 if (current_time - base_time > g_pGesture->palm_flick_time_threshold)
1663 PalmFlickDebugPrint("[PalmFlick][R][F] Release event were came to have long delay (%d - %d > %d)\n",
1664 current_time, base_time, g_pGesture->palm_flick_time_threshold);
1665 PalmFlickDebugPrint("[PalmFlick][F] 13\n");
1669 direction = (line_idx[idx] <= 1) ? FLICK_EASTWARD : FLICK_WESTWARD;
1670 distance = ABS(current_x[idx] - base_x[idx]);
1671 duration = current_time - base_time;
1675 if (GestureHasFingerEventMask(GestureNotifyFlick, 0))
1677 PalmFlickDebugPrint("[PalmFlick][R] Palm Flick1 !!!, direction=%d, distance=%d\n", direction, distance);
1679 GestureHandleGesture_Flick(0, distance, duration, direction);
1684 if (mt_sync_count[idx] < 25)
1686 PalmFlickDebugPrint("[PalmFlick][R][F] No enough motion=%d\n", mt_sync_count[idx]);
1687 PalmFlickDebugPrint("[PalmFlick][F] 14\n");
1692 if (GestureHasFingerEventMask(GestureNotifyFlick, 0))
1694 PalmFlickDebugPrint("[PalmFlick][R] Palm Flick2 !!!, direction=%d, distance=%d\n", direction, distance);
1696 GestureHandleGesture_Flick(0, distance, duration, direction);
1701 g_pGesture->recognized_gesture |= WPalmFlickFilterMask;
1711 DetailDebugPrint("[PalmFlick][R] flick failed\n");
1713 g_pGesture->recognized_gesture &= ~WPalmFlickFilterMask;
1714 g_pGesture->filter_mask |= WPalmFlickFilterMask;
1719 DetailDebugPrint("[PalmFlick][R] cleanup_flick\n");
1721 for (int i = 0; i < MAX_MT_DEVICES; i++)
1731 prev_line_idx[i] = 0;
1733 mt_sync_count[i] = 0;
1734 press_status[i] = FALSE;
1735 release_status[i] = FALSE;
1736 is_tmajor_invalid[i] = TRUE;
1737 is_line_invalid[i] = TRUE;
1740 total_max_tmajor = 0;
1748 GesturePalmGetHorizIndexWithX(int current_x, int idx, int type)
1752 static int pressed_idx[MAX_MT_DEVICES] = {-1, -1};
1753 PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
1755 for (i = 0; i < PALM_HORIZ_ARRAY_COUNT; i++)
1757 if (current_x <= pPalmMisc->horiz_coord[i])
1759 DetailDebugPrint("[GesturePalmGetHorizIndexWithX] index=%d, pPalmMisc->horiz_coord[%d]=%d\n", i, i, pPalmMisc->horiz_coord[i]);
1766 DetailDebugPrint("[GesturePalmGetHorizIndexWithX]Error ! Failed to get horiz coordinate index !\n");
1771 if (type == ET_ButtonPress)
1773 pressed_idx[idx] = ret_idx;
1775 // first press is center
1776 if (pressed_idx[idx] == PALM_HORIZ_ARRAY_COUNT -2)
1778 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][P] Invalid press area x=%d, idx=%d, pressed_idx=%d\n", current_x, idx, pressed_idx[idx]);
1782 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][P] pressed_idx=%d\n", pressed_idx[idx]);
1785 else if (type == ET_Motion)
1787 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][M] moving x=%d, idx=%d, pressed_idx=%d\n", current_x, idx, pressed_idx[idx]);
1790 else if (type == ET_ButtonRelease)
1792 if ((pressed_idx[idx] == 0) && (ret_idx == (PALM_HORIZ_ARRAY_COUNT - 1)))
1794 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] From the left to the right ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
1796 else if ((pressed_idx[idx] == (PALM_HORIZ_ARRAY_COUNT - 1)) && (ret_idx == 0))
1798 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] From the right to the left ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
1800 else if ((pressed_idx[idx] == ret_idx) && ret_idx != 1)
1802 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] Relased the same region ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
1807 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] Invalid ! pressed_idx=%d, released_idx=%d\n", pressed_idx[idx], ret_idx);
1811 pressed_idx[idx] = -1;
1818 GesturePalmGetAbsAxisInfo(DeviceIntPtr dev)
1825 Atom atom_tracking_id;
1829 g_pGesture->tpalm_idx = -1;
1830 g_pGesture->tmajor_idx = -1;
1831 g_pGesture->tminor_idx = -1;
1833 if (!dev || !dev->valuator)
1836 numAxes = dev->valuator->numAxes;
1838 atom_tpalm = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_PALM);
1839 atom_mt_slot = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_SLOT);
1840 atom_tracking_id = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TRACKING_ID);
1841 atom_tmajor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR);
1842 atom_tminor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR);
1844 if (!numAxes || !atom_tpalm || !atom_tmajor || !atom_tminor)
1846 ErrorF("one or more axes is/are not supported!\n");
1850 for (i = 0; i < numAxes; i++)
1852 AxisInfoPtr axes = &dev->valuator->axes[i];
1854 if (!axes || (axes->mode != Absolute))
1857 if (axes->label == atom_tpalm)
1859 g_pGesture->tpalm_idx = i;
1862 else if (axes->label == atom_tmajor)
1864 g_pGesture->tmajor_idx = i;
1867 else if (axes->label == atom_tminor)
1869 g_pGesture->tminor_idx = i;
1876 ErrorF("Axes for palm recognization are not supported !\n");
1880 g_pGesture->palm_misc.enabled = 1;
1881 ErrorF("Axes for palm recognization are supported !\n");
1885 g_pGesture->palm_misc.enabled = 0;
1886 ErrorF("Palm recognization is not supported !\n");
1891 GestureGetPalmValuator(InternalEvent *ev, DeviceIntPtr device)
1893 int mt_palm_idx = g_pGesture->tpalm_idx;
1896 DeviceEvent *de = &ev->device_event;
1900 ErrorF("[GestureGetPalmValuator] de is NULL !\n");
1904 if (mt_palm_idx < 0)
1906 ErrorF("[GestureGetPalmValuator] One or more of axes are not supported !\n");
1910 mt_palm = de->valuators.data[mt_palm_idx];
1912 HoldDetectorDebugPrint("[GestureGetPalmValuator] mt_palm:%d\n", mt_palm);
1917 static void GestureHoldDetector(int type, InternalEvent *ev, DeviceIntPtr device)
1921 pixman_region16_t tarea1;
1922 static int num_pressed = 0;
1923 unsigned int hold_area_size;
1924 PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
1927 if (!g_pGesture->has_hold_grabmask)
1929 HoldDetectorDebugPrint("[GestureHoldDetector] g_pGesture->has_hold_grabmask=%d\n", g_pGesture->has_hold_grabmask);
1931 Mask eventmask = (1L << GestureNotifyHold);
1933 if ((g_pGesture->grabMask & eventmask) &&
1934 (g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[0].window != None))
1936 g_pGesture->has_hold_grabmask = 1;
1938 //Initialize a set of variables
1940 memset(&g_pGesture->cts, 0, sizeof(g_pGesture->cts));
1941 pixman_region_init(&g_pGesture->chold_area);
1943 HoldDetectorDebugPrint("[GestureHoldDetector] Initialize...\n");
1947 //reset local hold_grab_mask variable
1948 g_pGesture->has_hold_grabmask = 0;
1950 g_pGesture->hold_detector_activate = 0;
1951 HoldDetectorDebugPrint("[GestureHoldDetector] has_hold_grabmask=0 and g_pGesture->hold_detector_activate=0\n");
1956 if (IGNORE_EVENTS == g_pGesture->ehtype ||
1957 device->id < g_pGesture->first_fingerid)
1959 HoldDetectorDebugPrint("[GestureHoldDetector] Return (IGNORE_EVENTS or device->id:%d < first_fingerid:%d)\n", device->id, g_pGesture->first_fingerid);
1963 palm_flag = GestureGetPalmValuator(ev, device);
1967 GestureHandleGesture_Hold(0, 0, 0, PALM_HOLD_TIME_THRESHOLD, GestureBegin);
1968 GestureHandleGesture_Hold(0, 0, 0, PALM_HOLD_TIME_THRESHOLD, GestureEnd);
1970 g_pGesture->hold_detector_activate = 0;
1971 g_pGesture->has_hold_grabmask = 0;
1972 HoldDetectorDebugPrint("[GestureHoldDetector] palm_flag:%d enable\n", palm_flag);
1977 HoldDetectorDebugPrint("[GestureHoldDetector] palm_flag:%d disable\n", palm_flag);
1981 HoldDetectorDebugPrint("[GestureHoldDetector] g_pGesture->num_mt_devices:%d\n", g_pGesture->num_mt_devices);
1983 for (i = 0; i < g_pGesture->num_mt_devices; i++)
1985 if ( device->id == g_pGesture->mt_devices[i]->id)
1988 HoldDetectorDebugPrint("[GestureHoldDetector] idx:%d\n", idx);
1992 if ((idx < 0) || ((MAX_MT_DEVICES-1) < idx)) return;
1996 case ET_ButtonPress:
1997 g_pGesture->cts[idx].status = BTN_PRESSED;
1998 g_pGesture->cts[idx].cx = ev->device_event.root_x;
1999 g_pGesture->cts[idx].cy = ev->device_event.root_y;
2001 HoldDetectorDebugPrint("[GestureHoldDetector][P] cx:%d, cy:%d, num_pressed:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy, num_pressed);
2003 if (num_pressed < 2)
2005 HoldDetectorDebugPrint("[GestureHoldDetector][P] num_pressed:%d\n", num_pressed);
2009 if (num_pressed > g_pGesture->num_mt_devices)
2010 num_pressed = g_pGesture->num_mt_devices;
2012 pixman_region_init(&tarea1);
2013 pixman_region_init(&g_pGesture->chold_area);
2014 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);
2016 tarea1.extents.x1 = g_pGesture->cts[0].cx;
2017 tarea1.extents.x2 = g_pGesture->cts[0].cx+1;
2018 tarea1.extents.y1 = g_pGesture->cts[0].cy;
2019 tarea1.extents.y2 = g_pGesture->cts[0].cy+1;
2021 pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1);
2023 for (i = 1; i < num_pressed; i++)
2025 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);
2027 tarea1.extents.x1 = g_pGesture->cts[i].cx;
2028 tarea1.extents.x2 = g_pGesture->cts[i].cx + 1;
2029 tarea1.extents.y1 = g_pGesture->cts[i].cy;
2030 tarea1.extents.y2 = g_pGesture->cts[i].cy + 1;
2032 pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1);
2037 if (BTN_RELEASED == g_pGesture->cts[idx].status)
2040 g_pGesture->cts[idx].status = BTN_MOVING;
2041 g_pGesture->cts[idx].cx = ev->device_event.root_x;
2042 g_pGesture->cts[idx].cy = ev->device_event.root_y;
2044 HoldDetectorDebugPrint("[GestureHoldDetector][M] cx:%d, cy:%d, num_pressed:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy, num_pressed);
2046 if (num_pressed < 2)
2048 HoldDetectorDebugPrint("[GestureHoldDetector][M] num_pressed:%d\n", num_pressed);
2052 pixman_region_init(&tarea1);
2053 pixman_region_init(&g_pGesture->chold_area);
2054 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);
2056 tarea1.extents.x1 = g_pGesture->cts[0].cx;
2057 tarea1.extents.x2 = g_pGesture->cts[0].cx+1;
2058 tarea1.extents.y1 = g_pGesture->cts[0].cy;
2059 tarea1.extents.y2 = g_pGesture->cts[0].cy+1;
2061 pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1);
2063 for (i = 1; i < num_pressed; i++)
2065 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);
2067 tarea1.extents.x1 = g_pGesture->cts[i].cx;
2068 tarea1.extents.x2 = g_pGesture->cts[i].cx + 1;
2069 tarea1.extents.y1 = g_pGesture->cts[i].cy;
2070 tarea1.extents.y2 = g_pGesture->cts[i].cy + 1;
2072 pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1);
2076 case ET_ButtonRelease:
2077 g_pGesture->cts[idx].status = BTN_RELEASED;
2078 g_pGesture->cts[idx].cx = ev->device_event.root_x;
2079 g_pGesture->cts[idx].cy = ev->device_event.root_y;
2081 HoldDetectorDebugPrint("[GestureHoldDetector][R] cx:%d, cy:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy);
2086 pixman_region_init(&g_pGesture->chold_area);
2091 if (num_pressed >= 2)
2093 hold_area_size = AREA_SIZE(&g_pGesture->chold_area.extents);
2095 HoldDetectorDebugPrint("[GestureHoldDetector] hold_area_size=%d, pPalmMisc->half_scrn_area_size=%d\n", hold_area_size, pPalmMisc->half_scrn_area_size);
2097 if (pPalmMisc->half_scrn_area_size <= hold_area_size)
2099 GestureHandleGesture_Hold(0, AREA_CENTER_X(&g_pGesture->chold_area.extents), AREA_CENTER_Y(&g_pGesture->chold_area.extents), PALM_HOLD_TIME_THRESHOLD, GestureBegin);
2100 GestureHandleGesture_Hold(0, AREA_CENTER_X(&g_pGesture->chold_area.extents), AREA_CENTER_Y(&g_pGesture->chold_area.extents), PALM_HOLD_TIME_THRESHOLD, GestureEnd);
2102 g_pGesture->hold_detector_activate = 0;
2103 g_pGesture->has_hold_grabmask = 0;
2108 hold_area_size = AREA_SIZE(&g_pGesture->chold_area.extents);
2109 HoldDetectorDebugPrint("[GestureHoldDetector] num_pressed is under 2, hold_area_size=%d\n", hold_area_size);
2115 GesturePalmGetScreenInfo()
2118 pixman_region16_t tarea;
2119 PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
2120 ScreenPtr pScreen = miPointerCurrentScreen();
2124 DetailDebugPrint("[X11][GesturePalmGetScreenInfo]Failed to get screen information !\n");
2126 pPalmMisc->scrn_width = pPalmMisc->scrn_height = 0;
2130 pPalmMisc->scrn_width = pScreen->width;
2131 pPalmMisc->scrn_height = pScreen->height;
2132 pixman_region_init(&tarea);
2133 pixman_region_init_rect(&tarea, 0, 0, pPalmMisc->scrn_width, pPalmMisc->scrn_height);
2135 DetailDebugPrint("[X11][GesturePalmGetScreenInfo] x2:%d, x2:%d, y2:%d, y1:%d \n", tarea.extents.x2, tarea.extents.x1, tarea.extents.y2, tarea.extents.y1);
2136 pPalmMisc->half_scrn_area_size = AREA_SIZE(&tarea.extents);
2137 pPalmMisc->half_scrn_area_size = (unsigned int)((double)pPalmMisc->half_scrn_area_size / 4);
2139 DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->half_scrn_area_size = %d\n", pPalmMisc->half_scrn_area_size);
2141 for (i = 0; i < PALM_HORIZ_ARRAY_COUNT; i++)
2143 pPalmMisc->horiz_coord[i] = pPalmMisc->scrn_width * ((i+1)/(double)PALM_HORIZ_ARRAY_COUNT);
2144 DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->horiz_coord[%d]=%d, pPalmMisc->scrn_width=%d\n", i, pPalmMisc->horiz_coord[i], pPalmMisc->scrn_width);
2146 for (i = 0; i < PALM_VERTI_ARRAY_COUNT; i++)
2148 pPalmMisc->verti_coord[i] = pPalmMisc->scrn_height * ((i+1)/(double)PALM_VERTI_ARRAY_COUNT);
2149 DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->verti_coord[%d]=%d, pPalmMisc->scrn_height=%d\n", i, pPalmMisc->verti_coord[i], pPalmMisc->scrn_height);
2157 GestureEnableDisable()
2159 GestureEnable(1, FALSE, g_pGesture->this_device);
2161 if ((g_pGesture->grabMask) || (g_pGesture->lastSelectedWin != None))
2163 GestureEnable(1, FALSE, g_pGesture->this_device);
2167 GestureEnable(0, FALSE, g_pGesture->this_device);
2173 GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent)
2175 g_pGesture->grabMask = *pGrabMask;
2176 g_pGesture->GrabEvents = (GestureGrabEventPtr)pGrabEvent;
2177 GestureEnableDisable();
2181 GestureCbEventsSelected(Window win, Mask *pEventMask)
2183 g_pGesture->lastSelectedWin = win;
2184 g_pGesture->lastSelectedMask = (pEventMask) ? *pEventMask : 0;
2185 GestureEnableDisable();
2189 GestureGetEventsWindow(void)
2194 pWin = GestureWindowOnXY(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py);
2198 DetailDebugPrint("[GestureGetEventsWindow] pWin->drawable.id=0x%x\n", pWin->drawable.id);
2199 g_pGesture->gestureWin = pWin->drawable.id;
2203 DetailDebugPrint("[GestureGetEventsWindow] GestureWindowOnXY returns NULL !\n");
2207 if (g_pGesture->gestureWin == g_pGesture->lastSelectedWin)
2209 g_pGesture->eventMask = g_pGesture->lastSelectedMask;
2210 goto nonempty_eventmask;
2213 //check selected event(s)
2214 if (!GestureHasSelectedEvents(pWin, &g_pGesture->eventMask))
2216 g_pGesture->eventMask = 0;
2220 g_pGesture->lastSelectedWin = g_pGesture->gestureWin;
2221 g_pGesture->lastSelectedMask = g_pGesture->eventMask;
2224 if (!g_pGesture->eventMask && !g_pGesture->grabMask)
2226 DetailDebugPrint("[X11][GestureGetEventsWindow] No grabbed events or no events were selected for window(0x%x) !\n", pWin->drawable.id);
2232 DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->eventMask=0x%x\n", g_pGesture->eventMask);
2234 mask = (GESTURE_FILTER_MASK_ALL & ~(g_pGesture->grabMask | g_pGesture->eventMask));
2236 DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x, mask=0x%x\n", g_pGesture->filter_mask, mask);
2238 g_pGesture->filter_mask = mask;
2240 DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x\n", g_pGesture->filter_mask);
2246 GestureSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2248 g_pGesture->filter_mask |= WTapFilterMask;
2249 g_pGesture->filter_mask |= WHoldFilterMask;
2250 //LOGI("[GroupTap][GroupHold] 50ms after 1st finger.\n");
2252 DetailDebugPrint("[GestureSingleFingerTimerHandler] TapFilterMask, HoldFilterMask \n");
2254 if ((g_pGesture->event_sum[0] == BTN_PRESSED) && ((g_pGesture->flick_pressed_point <= FLICK_POINT_NONE) && (FLICK_POINT_MAX <= g_pGesture->flick_pressed_point)))
2256 DetailDebugPrint("[GestureSingleFingerTimerHandler] press_point: %d\n", g_pGesture->flick_pressed_point);
2257 DetailDebugPrint("[GestureSingleFingerTimerHandler] FlickFilterMask\n");
2258 g_pGesture->filter_mask |= WFlickFilterMask;
2261 if (g_pGesture->flick_pressed_point == FLICK_POINT_DOWN && abs(g_pGesture->fingers[0].py - g_pGesture->fingers[0].my) < 3)
2263 DetailDebugPrint("[GestureSingleFingerTimerHandler] py: %d, my: %d\n", g_pGesture->fingers[0].py, g_pGesture->fingers[0].my);
2264 DetailDebugPrint("[GestureSingleFingerTimerHandler] FlickFilterMask\n");
2265 g_pGesture->filter_mask |= WFlickFilterMask;
2268 DetailDebugPrint("[GestureSingleFingerTimerHandler] expired !\n");
2270 if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
2272 if ( ERROR_INVALPTR == GestureFlushOrDrop())
2274 DetailDebugPrint("[GestureSingleFingerTimerHandler] AllFilterMask, Flush!\n");
2275 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2283 GestureGetFingerIndexFromDevice(DeviceIntPtr device)
2287 for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
2289 if( device->id == g_pGesture->mt_devices[i]->id )
2299 GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
2302 static OsTimerPtr single_finger_timer = NULL;
2305 if (PROPAGATE_EVENTS == g_pGesture->ehtype || device->id < g_pGesture->first_fingerid)
2310 idx = GestureGetFingerIndexFromDevice(device);
2317 case ET_ButtonPress:
2320 g_pGesture->event_sum[0] = BTN_PRESSED;
2323 g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
2325 g_pGesture->fingers[idx].ptime = ev->any.time;
2326 g_pGesture->fingers[idx].px = ev->device_event.root_x;
2327 g_pGesture->fingers[idx].py = ev->device_event.root_y;
2329 g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
2330 g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
2331 g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT;
2332 g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT;
2334 g_pGesture->num_pressed++;
2335 g_pGesture->inc_num_pressed = g_pGesture->num_pressed;
2337 if (g_pGesture->inc_num_pressed == 1)
2339 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2343 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2345 for (i = 1; i < g_pGesture->inc_num_pressed; i++)
2347 pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
2351 DetailDebugPrint("[GestureRecognize][P] num_pressed=%d, area_size=%d, px=%d, py=%d\n",
2352 g_pGesture->num_pressed, AREA_SIZE(&g_pGesture->area.extents), g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
2354 if (g_pGesture->num_pressed == 1)
2356 single_finger_timer = TimerSet(single_finger_timer, 0, 50, GestureSingleFingerTimerHandler, NULL);
2358 if (g_pGesture->fingers[idx].py <= g_pGesture->flick_press_area)
2360 if ((!g_pGesture->activate_flick_down)
2361 || (g_pGesture->fingers[idx].px <= (g_pGesture->flick_press_area_left_right))
2362 || (g_pGesture->fingers[idx].px >= (g_pGesture->screen_width - g_pGesture->flick_press_area_left_right)))
2364 DetailDebugPrint("[GestureRecognize][P] px=%d, flick_press_area_left_right=%d\n",
2365 g_pGesture->fingers[idx].px, g_pGesture->flick_press_area_left_right);
2366 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2367 LOGI("[BackKey][F] Press touch within 40 pixel area from left or right vezel\n");
2371 DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_UP\n");
2372 g_pGesture->flick_pressed_point = FLICK_POINT_UP;
2377 LOGI("[BackKey][F] Press touch outside 40 pixel area from upper vezel. \n");
2380 if (g_pGesture->fingers[idx].py >= (g_pGesture->screen_height - g_pGesture->flick_press_area))
2382 if (!g_pGesture->activate_flick_up)
2384 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2388 DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_DOWN\n");
2389 g_pGesture->flick_pressed_point = FLICK_POINT_DOWN;
2392 else if ( g_pGesture->fingers[idx].px <= g_pGesture->flick_press_area_left)
2394 if (!g_pGesture->activate_flick_right)
2396 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2400 DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_LEFT\n");
2401 g_pGesture->flick_pressed_point = FLICK_POINT_LEFT;
2405 DetailDebugPrint("[GestureRecognize][P] flick_press_point: %d\n", g_pGesture->flick_pressed_point);
2407 if ((g_pGesture->flick_pressed_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= g_pGesture->flick_pressed_point))
2409 DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_NONE\n");
2410 g_pGesture->filter_mask |= WFlickFilterMask;
2411 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2415 g_pGesture->flick_direction = (g_pGesture->flick_pressed_point - 1) * 2;
2416 if ((g_pGesture->flick_direction == FLICK_WESTWARD) && (g_pGesture->power_pressed != 2))
2418 DetailDebugPrint("[GestureRecognize][P] Flick WesWard is disable when power is not pressed\n");
2419 g_pGesture->filter_mask |= WFlickFilterMask;
2420 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2422 if ((g_pGesture->flick_direction < FLICK_NORTHWARD) || (FLICK_NORTHWESTWARD < g_pGesture->flick_direction))
2424 DetailDebugPrint("[GestureRecognize][P] Invalid flick direction\n");
2425 g_pGesture->filter_mask |= WFlickFilterMask;
2426 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2429 DetailDebugPrint("[GestureRecognize][P] flick_direction: %d\n", g_pGesture->flick_direction);
2434 DetailDebugPrint("[GestureRecognize][P] Two more fingers come on!\n");
2435 TimerCancel(single_finger_timer);
2436 single_finger_timer = NULL;
2442 if (!g_pGesture->fingers[idx].ptime)
2444 DetailDebugPrint("[GestureRecognize][M] Start motion. idx=%d\n", idx);
2445 g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
2449 g_pGesture->fingers[idx].mx = ev->device_event.root_x;
2450 g_pGesture->fingers[idx].my = ev->device_event.root_y;
2451 g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
2455 g_pGesture->event_sum[0] += BTN_MOVING;
2458 g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
2459 g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
2460 g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT;
2461 g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT;
2463 if (g_pGesture->inc_num_pressed == 1)
2465 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2469 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2471 for (i = 1; i < g_pGesture->inc_num_pressed; i++)
2473 pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
2477 DetailDebugPrint("[GestureRecognize][M] num_pressed=%d, area_size=%d, mx=%d, my=%d\n",
2478 g_pGesture->num_pressed, AREA_SIZE(&g_pGesture->area.extents), g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].my);
2482 case ET_ButtonRelease:
2483 g_pGesture->fingers[idx].rtime = ev->any.time;
2484 g_pGesture->fingers[idx].rx = ev->device_event.root_x;
2485 g_pGesture->fingers[idx].ry = ev->device_event.root_y;
2486 g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
2488 g_pGesture->num_pressed--;
2490 if (g_pGesture->num_pressed == 0)
2492 DetailDebugPrint("[GestureRecognize] All fingers were released !\n");
2494 else if (g_pGesture->num_pressed < 0)
2496 DetailDebugPrint("[GestureRecognize] All fingers were released. But, num_pressed is under 0 !\n");
2499 DetailDebugPrint("[GestureRecognize][R] num_pressed=%d, rx=%d, ry=%d\n",
2500 g_pGesture->num_pressed, g_pGesture->fingers[idx].rx, g_pGesture->fingers[idx].ry);
2505 if (!(g_pGesture->filter_mask & WFlickFilterMask))
2507 DetailDebugPrint("[GestureRecognize] GestureRecognize_groupFlick !\n");
2508 GestureRecognize_GroupFlick(type, ev, device, idx, g_pGesture->flick_pressed_point, g_pGesture->flick_direction);
2510 if (!(g_pGesture->filter_mask & WTapFilterMask))
2512 DetailDebugPrint("[GestureRecognize] GestureRecognize_groupTap !\n");
2513 GestureRecognize_GroupTap(type, ev, device, idx, 0);
2515 if (!(g_pGesture->filter_mask & WHoldFilterMask))
2517 DetailDebugPrint("[GestureRecognize] GestureRecognize_groupHold !\n");
2518 GestureRecognize_GroupHold(type, ev, device, idx, 0);
2521 if (!(g_pGesture->filter_mask & WPalmFlickFilterMask))
2523 DetailDebugPrint("[GestureRecognize] GestureRecognize_palmFlick !\n");
2524 GestureRecognize_PalmFlick(type, ev, device, idx);
2527 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",
2528 g_pGesture->filter_mask, GESTURE_WATCH_FILTER_MASK_ALL, g_pGesture->recognized_gesture);
2530 if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
2532 if (!g_pGesture->recognized_gesture)
2534 DetailDebugPrint("[GestureRecognize][F] 1 !\n");
2537 else if (!g_pGesture->num_pressed)
2539 DetailDebugPrint("[GestureRecognize][F] 2 !\n");
2544 if (g_pGesture->recognized_gesture)
2546 if (g_pGesture->ehtype == KEEP_EVENTS)
2548 DetailDebugPrint("[GestureRecognize] Keep Event !\n");
2549 GestureEventsDrop();
2551 g_pGesture->ehtype = IGNORE_EVENTS;
2557 DetailDebugPrint("[GestureRecognize] GestureFlushOrDrop() !\n");
2559 if (ERROR_INVALPTR == GestureFlushOrDrop())
2561 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2565 ErrorStatus GestureFlushOrDrop(void)
2569 if (g_pGesture->recognized_gesture)
2571 g_pGesture->ehtype = IGNORE_EVENTS;
2572 GestureEventsDrop();
2573 DetailDebugPrint("[GestureFlushOrDrop][Drop] IGNORE_EVENTS\n");
2577 g_pGesture->ehtype = PROPAGATE_EVENTS;
2579 err = GestureEventsFlush();
2581 if (ERROR_NONE != err)
2586 DetailDebugPrint("[GestureFlushOrDrop][Flush] PROPAGATE_EVENTS\n");
2587 DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask);
2588 DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->GESTURE_WATCH_FILTER_MASK_ALL = 0x%x\n", GESTURE_WATCH_FILTER_MASK_ALL);
2589 DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture);
2592 err = GestureRegionsReinit();
2594 if (ERROR_NONE != err)
2599 g_pGesture->pTempWin = NULL;
2600 g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0;
2601 g_pGesture->event_sum[0] = 0;
2607 GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2612 #ifdef __DEBUG_EVENT_HANDLER__
2613 DetailDebugPrint("[GestureHandleMTSyncEvent] (%d:%d) time:%d cur:%d\n",
2614 ev->any_event.deviceid, ev->any_event.sync, (int)ev->any.time, (int)GetTimeInMillis());
2617 if (!g_pGesture->is_active)
2619 g_pGesture->ehtype = PROPAGATE_EVENTS;
2620 DetailDebugPrint("[GestureHandleMTSyncEvent] PROPAGATE_EVENT\n");
2624 switch(ev->any_event.sync)
2626 case ROTARY_FRAME_SYNC_BEGIN:
2627 if (g_pGesture->mt_devices[0] && (g_pGesture->mtsync_flag & MTSYNC_FLAG_TOUCH))
2630 xf86PostButtonEvent(g_pGesture->mt_devices[0], 0, Button1, 0, 0, 2, &zero, &zero);
2632 g_pGesture->mtsync_flag |= MTSYNC_FLAG_ROTARY;
2633 DetailDebugPrint("[GestureHandleMTSyncEvent] Rotary input starts. Now touch events are dropped!\n");
2635 case ROTARY_FRAME_SYNC_END:
2636 g_pGesture->mtsync_flag &= ~MTSYNC_FLAG_ROTARY;
2637 DetailDebugPrint("[GestureHandleMTSyncEvent] Rotary input is finished. Now touch events are not dropped!\n");
2639 case MTOUCH_FRAME_SYNC_BEGIN:
2640 g_pGesture->mtsync_flag |= MTSYNC_FLAG_TOUCH;
2641 DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_BEGIN\n");
2642 g_pGesture->ehtype = KEEP_EVENTS;
2643 g_pGesture->filter_mask = 0;
2644 g_pGesture->recognized_gesture = 0;
2645 g_pGesture->hold_detector_activate = 1;
2646 g_pGesture->num_pressed = 0;
2647 g_pGesture->has_hold_grabmask = 0;
2648 g_pGesture->mtsync_total_count = 0;
2649 memset(&g_pGesture->last_touches, 0, sizeof(g_pGesture->last_touches));
2650 for (i=0; i < g_pGesture->num_mt_devices; i++)
2652 g_pGesture->fingers[i].ptime = 0;
2653 g_pGesture->max_mt_tmajor[i] = 0;
2656 case MTOUCH_FRAME_SYNC_END:
2657 g_pGesture->mtsync_flag &= ~MTSYNC_FLAG_TOUCH;
2658 DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_END\n");
2659 g_pGesture->ehtype = PROPAGATE_EVENTS;
2660 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2661 g_pGesture->pTempWin = NULL;
2662 g_pGesture->num_pressed = 0;
2663 g_pGesture->hold_detected = FALSE;
2665 case MTOUCH_FRAME_SYNC_UPDATE:
2666 g_pGesture->mtsync_flag |= MTSYNC_FLAG_TOUCH;
2667 g_pGesture->mtsync_total_count++;
2669 DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_Update. mt_total_sync=%d\n", g_pGesture->mtsync_total_count);
2671 if ((g_pGesture->inc_num_pressed < 2) && (g_pGesture->filter_mask != GESTURE_WATCH_FILTER_MASK_ALL))
2673 if (g_pGesture->num_tap_repeated == 1 || g_pGesture->num_tap_repeated == 2)
2675 if (g_pGesture->mtsync_total_count >= 6)
2677 DetailDebugPrint("[GestureHandleMTSyncEvent] Moving Limit first tap repeated. tap_repeated: %d, mtsync_total_count: %d\n",
2678 g_pGesture->num_tap_repeated, g_pGesture->mtsync_total_count);
2679 g_pGesture->filter_mask |= WTapFilterMask;
2680 g_pGesture->filter_mask |= WHoldFilterMask;
2681 LOGI("[GroupTap][GroupHold] Motions are more than 6 between 1st finger and 2nd finger.\n");
2685 if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
2687 DetailDebugPrint("[GestureHandleMTSyncEvent] Gesture filter mask all. GestureFlushOrDrop() !\n");
2689 if (ERROR_INVALPTR == GestureFlushOrDrop())
2691 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2697 ErrorF("[GestureHandleMTSyncEvent] Unknown MTSync Event received.\n");
2702 void GestureEmulateHWKey(DeviceIntPtr dev, int keycode)
2706 DetailDebugPrint("[GestureEmulateHWKey] keycode=%d\n", keycode);
2707 xf86PostKeyboardEvent(dev, keycode, 1);
2708 xf86PostKeyboardEvent(dev, keycode, 0);
2713 GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2715 #ifdef __DEBUG_EVENT_HANDLER__
2716 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);
2717 #endif//__DEBUG_EVENT_HANDLER__
2719 if (g_pGesture->touch_cancel_status == TRUE)
2721 DetailDebugPrint("[GestureHandleButtonPressEvent] Ignore Button Press event after touch cancel generated. \n");
2725 idx = GestureGetFingerIndexFromDevice(device);
2728 g_pGesture->last_touches[idx].status = BTN_PRESSED;
2729 g_pGesture->last_touches[idx].cx = ev->device_event.root_x;
2730 g_pGesture->last_touches[idx].cy = ev->device_event.root_y;
2733 if (g_pGesture->ehtype != KEEP_EVENTS)
2735 if(g_pGesture->mtsync_flag & MTSYNC_FLAG_ROTARY)
2737 DetailDebugPrint("[GestureHandleButtonPressEvent] Rotary input is coming. Dropping touch events.\n");
2740 else if (g_pGesture->mtsync_flag & ~MTSYNC_FLAG_TOUCH)
2742 DetailDebugPrint("[GestureHandleButtonPressEvent] Other input is coming. Dropping touch events.\n");
2747 switch (g_pGesture->ehtype)
2750 DetailDebugPrint("[GestureHandleButtonPressEvent] KEEP_EVENT\n");
2752 if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device))
2754 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2758 if (g_pGesture->num_mt_devices)
2760 GestureRecognize(ET_ButtonPress, ev, device);
2764 device->public.processInputProc(ev, device);
2767 GestureHoldDetector(ET_ButtonPress, ev, device);
2770 case PROPAGATE_EVENTS:
2771 DetailDebugPrint("[GestureHandleButtonPressEvent] PROPAGATE_EVENT\n");
2773 device->public.processInputProc(ev, device);
2774 GestureHoldDetector(ET_ButtonPress, ev, device);
2778 DetailDebugPrint("[GestureHandleButtonPressEvent] IGNORE_EVENTS\n");
2780 GestureRecognize(ET_ButtonPress, ev, device);
2789 GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2791 #ifdef __DEBUG_EVENT_MOTION_HANDLER__
2792 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);
2795 if (g_pGesture->touch_cancel_status == TRUE)
2797 DetailDebugPrint("[GestureHandleButtonPressEvent] Ignore Button Press event after touch cancel generated. \n");
2801 idx = GestureGetFingerIndexFromDevice(device);
2804 g_pGesture->last_touches[idx].status = BTN_MOVING;
2805 g_pGesture->last_touches[idx].cx = ev->device_event.root_x;
2806 g_pGesture->last_touches[idx].cy = ev->device_event.root_y;
2809 if (g_pGesture->ehtype != KEEP_EVENTS)
2811 if(g_pGesture->mtsync_flag & MTSYNC_FLAG_ROTARY)
2813 DetailDebugPrint("[GestureHandleMotionEvent] Rotary input is coming. Dropping touch events.\n");
2816 else if (g_pGesture->mtsync_flag & ~MTSYNC_FLAG_TOUCH)
2818 DetailDebugPrint("[GestureHandleMotionEvent] Other input is coming. Dropping touch events.\n");
2823 switch (g_pGesture->ehtype)
2826 if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device))
2828 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2832 if (g_pGesture->num_mt_devices)
2834 GestureRecognize(ET_Motion, ev, device);
2838 device->public.processInputProc(ev, device);
2841 GestureHoldDetector(ET_Motion, ev, device);
2844 case PROPAGATE_EVENTS:
2845 device->public.processInputProc(ev, device);
2846 GestureHoldDetector(ET_Motion, ev, device);
2850 GestureRecognize(ET_Motion, ev, device);
2860 GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2862 #ifdef __DEBUG_EVENT_HANDLER__
2863 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);
2866 if (g_pGesture->touch_cancel_status == TRUE)
2868 DetailDebugPrint("[GestureHandleButtonPressEvent] Ignore Button Press event after touch cancel generated. \n");
2872 idx = GestureGetFingerIndexFromDevice(device);
2875 g_pGesture->last_touches[idx].status = BTN_RELEASED;
2876 g_pGesture->last_touches[idx].cx = ev->device_event.root_x;
2877 g_pGesture->last_touches[idx].cy = ev->device_event.root_y;
2880 if (g_pGesture->ehtype != KEEP_EVENTS)
2882 if(!(g_pGesture->mtsync_flag & MTSYNC_FLAG_TOUCH))
2884 if(g_pGesture->mtsync_flag & MTSYNC_FLAG_ROTARY)
2886 DetailDebugPrint("[GestureHandleButtonReleaseEvent] Rotary input is coming. Dropping touch events.\n");
2889 else if (g_pGesture->mtsync_flag & ~MTSYNC_FLAG_TOUCH)
2891 DetailDebugPrint("[GestureHandleButtonReleaseEvent] Other input is coming. Dropping touch events.\n");
2897 switch (g_pGesture->ehtype)
2900 DetailDebugPrint("[GestureHandleButtonReleaseEvent] KEEP_EVENT\n");
2902 if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device))
2904 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2908 if (g_pGesture->num_mt_devices)
2910 GestureRecognize(ET_ButtonRelease, ev, device);
2914 device->public.processInputProc(ev, device);
2917 GestureHoldDetector(ET_ButtonRelease, ev, device);
2920 case PROPAGATE_EVENTS:
2921 DetailDebugPrint("[GestureHandleButtonReleaseEvent] PROPAGATE_EVENTS\n");
2922 #ifdef SUPPORT_ANR_WITH_INPUT_EVENT
2923 if( IsMaster(device) && ev->any.type == ET_ButtonRelease )
2925 if( g_pGesture->anr_window == NULL )
2927 g_pGesture->anr_window = _GestureFindANRWindow(device);
2931 // Send event to the e17 process.
2932 current_time = GetTimeInMillis();
2933 if( g_pGesture->anr_window != NULL )
2935 // Check anr_window validation.
2936 if( dixLookupWindow(&g_pGesture->anr_window, prop_anr_event_window_xid, serverClient, DixSetPropAccess) != BadWindow )
2938 if( serverClient->devPrivates != NULL )
2939 dixChangeWindowProperty (serverClient, g_pGesture->anr_window, prop_anr_in_input_event,
2940 XA_CARDINAL, 32, PropModeReplace, 1, ¤t_time, TRUE);
2944 prop_anr_event_window_xid = 0;
2945 g_pGesture->anr_window = NULL;
2947 DetailDebugPrint("[GestureHandleButtonReleaseEvent] Release TOUCH!! devid=%d time:%d cur: %d\n", device->id, ev->any.time, GetTimeInMillis());
2951 device->public.processInputProc(ev, device);
2952 GestureHoldDetector(ET_ButtonRelease, ev, device);
2954 GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down);
2955 GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up);
2960 DetailDebugPrint("[GestureHandleButtonReleaseEvent] IGNORE_EVENTS\n");
2961 GestureRecognize(ET_ButtonRelease, ev, device);
2970 GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2972 if ((ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0))
2974 g_pGesture->power_pressed = 2;
2975 g_pGesture->power_device = device;
2977 DetailDebugPrint("[GestureHandleKeyPressEvent] power key pressed devid: %d, hwkey_id: %d\n", device->id, g_pGesture->hwkey_id);
2978 DetailDebugPrint("[GestureHandleKeyPressEvent] power_pressed: %d\n", g_pGesture->power_pressed);
2980 device->public.processInputProc(ev, device);
2984 GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2986 if ((ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0))
2988 g_pGesture->power_pressed = 1;
2989 g_pGesture->power_device = device;
2991 DetailDebugPrint("[GestureHandleKeyReleaseEvent] power key released devid: %d, hwkey_id: %d\n", device->id, g_pGesture->hwkey_id);
2992 DetailDebugPrint("[GestureHandleKeyReleaseEvent] power_pressed: %d\n", g_pGesture->power_pressed);
2994 device->public.processInputProc(ev, device);
2998 GestureHandleClientState (CallbackListPtr *list, pointer closure, pointer calldata)
3000 NewClientInfoRec *clientinfo = (NewClientInfoRec*)calldata;
3001 ClientPtr client = clientinfo->client;
3003 if (client->clientState != ClientStateGone)
3008 if (!g_pGesture->factory_cmdname)
3013 if (strncmp(client->clientIds->cmdname, g_pGesture->factory_cmdname, strlen(g_pGesture->factory_cmdname)))
3018 if (g_pGesture->is_active == 0)
3021 int rc = XIChangeDeviceProperty(g_pGesture->this_device, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &prop_val, FALSE);
3023 ErrorF("[GestureHandleClientState] %s is exited unintentionally\n", g_pGesture->factory_cmdname);
3027 ErrorF("[GestureHandleClientState] Failed to Gesture Enable\n");
3034 GestureEnableEventHandler(InputInfoPtr pInfo)
3037 GestureDevicePtr pGesture = pInfo->private;
3039 res = GestureInstallResourceStateHooks();
3043 ErrorF("[GestureEnableEventHandler] Failed on GestureInstallResourceStateHooks() !\n");
3044 return ERROR_ABNORMAL;
3047 res = GestureSetMaxNumberOfFingers((int)MAX_MT_DEVICES);
3051 ErrorF("[GestureEnableEventHandler] Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)MAX_MT_DEVICES);
3055 res = GestureRegisterCallbacks(GestureCbEventsGrabbed, GestureCbEventsSelected);
3059 ErrorF("[GestureEnableEventHandler] Failed to register callbacks for GestureEventsGrabbed(), GestureEventsSelected() !\n");
3063 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 5000, GestureTimerHandler, pInfo);
3065 if (!pGesture->device_setting_timer)
3067 ErrorF("[GestureEnableEventHandler] Failed to set time for detecting devices !\n");
3074 GestureUninstallResourceStateHooks();
3075 GestureUnsetMaxNumberOfFingers();
3077 return ERROR_ABNORMAL;
3081 GestureDisableEventHandler(void)
3083 ErrorStatus err = ERROR_NONE;
3085 mieqSetHandler(ET_ButtonPress, NULL);
3086 mieqSetHandler(ET_ButtonRelease, NULL);
3087 mieqSetHandler(ET_Motion, NULL);
3088 mieqSetHandler(ET_KeyPress, NULL);
3089 mieqSetHandler(ET_KeyRelease, NULL);
3090 mieqSetHandler(ET_MTSync, NULL);
3092 err = GestureFiniEQ();
3094 if (ERROR_INVALPTR == err)
3096 ErrorF("[GestureDisableEventHandler] EQ is invalid or was freed already !\n");
3099 GestureRegisterCallbacks(NULL, NULL);
3100 GestureUninstallResourceStateHooks();
3106 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
3108 InputInfoPtr pInfo = (InputInfoPtr)arg;
3109 GestureDevicePtr pGesture;
3115 ErrorF("[GestureTimerHandler][%s] pInfo is NULL !\n");
3119 pGesture = pInfo->private;
3122 for (dev = inputInfo.pointer; dev; dev = dev->next)
3124 if (IsMaster(dev) && IsPointerDevice(dev))
3126 pGesture->master_pointer = dev;
3127 ErrorF("[GestureTimerHandler][id:%d] Master Pointer=%s\n", dev->id, pGesture->master_pointer->name);
3131 if (IsXTestDevice(dev, NULL) && IsPointerDevice(dev))
3133 pGesture->xtest_pointer = dev;
3134 ErrorF("[GestureTimerHandler][id:%d] XTest Pointer=%s\n", dev->id, pGesture->xtest_pointer->name);
3138 if (IsPointerDevice(dev))
3140 if (idx >= MAX_MT_DEVICES)
3142 ErrorF("[GestureTimerHandler] Number of mt device is over MAX_MT_DEVICES(%d) !\n", MAX_MT_DEVICES);
3145 pGesture->mt_devices[idx] = dev;
3146 ErrorF("[GestureTimerHandler][id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name);
3147 GesturePalmGetAbsAxisInfo(dev);
3152 for (dev = inputInfo.keyboard ; dev; dev = dev->next)
3154 if (g_pGesture->hwkey_name && !strncmp(dev->name, g_pGesture->hwkey_name, strlen(dev->name)))
3156 g_pGesture->hwkey_id = dev->id;
3157 g_pGesture->hwkey_dev = dev;
3159 ErrorF("[GestureTimerHandler] hwkey_name has been found. hwkey_id=%d (hwkey_dev->name:%s)\n", g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
3162 else if (!strncmp(dev->name, "tizen_rotary", strlen(dev->name)))
3164 g_pGesture->rotary_id = dev->id;
3165 g_pGesture->rotary_dev = dev;
3167 ErrorF("[GestureTimerHandler] rotary_name has been found. rotary_id=%d (rotary_dev->name:%s)\n", g_pGesture->rotary_id, g_pGesture->rotary_dev->name);
3170 else if (!strcasestr(dev->name, "keyboard") && strcasestr(dev->name, "key") && !IsXTestDevice(dev, NULL) && !IsMaster(dev))
3172 g_pGesture->hwkey_id = dev->id;
3173 g_pGesture->hwkey_dev = dev;
3175 ErrorF("[GestureTimerHandler] hwkey has been found. hwkey_id=%d (hwkey_dev->name:%s)\n", g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
3180 if (!g_pGesture->hwkey_id)
3182 g_pGesture->hwkey_id = inputInfo.keyboard->id;
3183 g_pGesture->hwkey_dev = inputInfo.keyboard;
3185 ErrorF("[GestureTimerHandler] No hwkey has been found. Back key will go through VCK. hwkey_id=%d (hwkey_dev->name:%s)\n",
3186 g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
3189 if (!pGesture->master_pointer || !pGesture->xtest_pointer)
3191 ErrorF("[GestureTimerHandler] Failed to get info of master pointer or XTest pointer !\n");
3192 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
3193 pGesture->num_mt_devices = 0;
3198 TimerCancel(pGesture->device_setting_timer);
3199 pGesture->device_setting_timer = NULL;
3200 pGesture->num_mt_devices = idx;
3202 if (!pGesture->num_mt_devices)
3204 ErrorF("[GestureTimerHandler] Failed to mt device information !\n");
3205 TimerCancel(pGesture->device_setting_timer);
3206 pGesture->device_setting_timer = NULL;
3207 pGesture->num_mt_devices = 0;
3208 pGesture->first_fingerid = -1;
3212 pGesture->first_fingerid = pGesture->mt_devices[0]->id;
3213 memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices);
3214 pGesture->pRootWin = RootWindow(pGesture->master_pointer);
3216 if (g_pGesture->palm_misc.enabled)
3218 GesturePalmGetScreenInfo();
3221 g_pGesture->pTempWin = NULL;
3222 g_pGesture->inc_num_pressed = 0;
3224 if (ERROR_NONE != GestureRegionsInit() || ERROR_NONE != GestureInitEQ())
3229 mieqSetHandler(ET_ButtonPress, GestureHandleButtonPressEvent);
3230 mieqSetHandler(ET_ButtonRelease, GestureHandleButtonReleaseEvent);
3231 mieqSetHandler(ET_Motion, GestureHandleMotionEvent);
3232 mieqSetHandler(ET_KeyPress, GestureHandleKeyPressEvent);
3233 mieqSetHandler(ET_KeyRelease, GestureHandleKeyReleaseEvent);
3235 //if ( pGesture->is_active)
3236 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
3241 GestureUninstallResourceStateHooks();
3242 GestureUnsetMaxNumberOfFingers();
3248 IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
3257 return (dev->xtest_master_id == master->id);
3260 return (dev->xtest_master_id != 0);
3264 GestureGenerateTouchCancelEvent(void)
3267 Bool canceled_touch_index[MAX_MT_DEVICES] = {FALSE, };
3269 if (g_pGesture->mtsync_flag & MTSYNC_FLAG_TOUCH)
3271 ErrorF("no Touch(%d)\n", g_pGesture->mtsync_flag);
3275 for (i=0; i<MAX_MT_DEVICES; i++)
3277 if (!(g_pGesture->mt_devices[i]->button->buttonsDown)) continue;
3278 InternalEvent cancel_event;
3280 cancel_event.touch_cancel_event.header = ET_Internal;
3281 cancel_event.touch_cancel_event.type = ET_TouchCancel;
3282 cancel_event.touch_cancel_event.length = sizeof(TouchCancelEvent);
3283 cancel_event.touch_cancel_event.time = CurrentTime;
3284 cancel_event.touch_cancel_event.deviceid = g_pGesture->mt_devices[i]?g_pGesture->mt_devices[i]->id:0;
3286 cancel_event.touch_cancel_event.sourceid = g_pGesture->mt_devices[i]?g_pGesture->mt_devices[i]->id:0;
3287 cancel_event.touch_cancel_event.resource = 0;
3288 cancel_event.touch_cancel_event.flags = 0;
3290 g_pGesture->mt_devices[i]->public.processInputProc(&cancel_event, g_pGesture->mt_devices[i]);
3291 canceled_touch_index[i] = TRUE;
3292 g_pGesture->touch_cancel_status = TRUE;
3295 for (i=0; i<MAX_MT_DEVICES; i++)
3297 if (canceled_touch_index[i] == FALSE) continue;
3298 InternalEvent release_event;
3299 InternalEvent release_event_master;
3301 memset(&release_event, 0, sizeof(InternalEvent));
3303 release_event.device_event.header = ET_Internal;
3304 release_event.device_event.type = ET_ButtonRelease;
3305 release_event.device_event.length = sizeof(DeviceEvent);
3306 release_event.device_event.time = CurrentTime;
3307 release_event.device_event.deviceid = g_pGesture->mt_devices[i]->id;
3308 release_event.device_event.sourceid = g_pGesture->mt_devices[i]->button->sourceid;
3309 release_event.device_event.detail.button = 1;
3310 release_event.device_event.root_x = g_pGesture->last_touches[i].cx;
3311 release_event.device_event.root_y = g_pGesture->last_touches[i].cy;
3312 if (g_pGesture->mt_devices[i]->id == g_pGesture->first_fingerid)
3314 memcpy(&release_event_master, &release_event, sizeof(InternalEvent));
3315 release_event_master.device_event.deviceid = g_pGesture->master_pointer->id;
3318 g_pGesture->mt_devices[i]->public.processInputProc(&release_event, g_pGesture->mt_devices[i]);
3319 if (g_pGesture->mt_devices[i]->id == g_pGesture->first_fingerid)
3321 g_pGesture->master_pointer->public.processInputProc(&release_event_master, g_pGesture->master_pointer);
3323 g_pGesture->touch_cancel_status = TRUE;
3328 GestureDPMSCallback(CallbackListPtr *pcbl, void *unused, void *calldata)
3330 int dpmsLevel = *(int *)calldata;
3332 if ((DPMSModeOff == dpmsLevel) && (MTSYNC_FLAG_TOUCH & g_pGesture->mtsync_flag)) {
3333 ErrorF("TouchCancel dpmslevel: %d, g_pGesture->mtsync_flag: %d\n", dpmsLevel, g_pGesture->mtsync_flag);
3334 GestureGenerateTouchCancelEvent();
3339 GestureEnable(int enable, Bool prop, DeviceIntPtr dev)
3341 if ((!enable) && (g_pGesture->is_active))
3343 g_pGesture->ehtype = PROPAGATE_EVENTS;
3344 mieqSetHandler(ET_MTSync, NULL);
3345 g_pGesture->is_active = 0;
3346 ErrorF("[GestureEnable] Disabled !\n");
3347 int res = AddCallback (&ClientStateCallback, GestureHandleClientState, NULL);
3351 ErrorF("[GestureEnable] Failed to add callback for client state\n");
3356 else if ((enable) && (!g_pGesture->is_active))
3358 g_pGesture->ehtype = KEEP_EVENTS;
3359 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
3360 g_pGesture->is_active = 1;
3361 ErrorF("[GestureEnable] Enabled !\n");
3363 DeleteCallback (&ClientStateCallback, GestureHandleClientState, NULL);
3368 XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
3373 GestureRegionsInit(void)
3379 return ERROR_INVALPTR;
3382 pixman_region_init(&g_pGesture->area);
3384 for (i = 0; i < MAX_MT_DEVICES; i++)
3386 pixman_region_init_rect(&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
3393 GestureRegionsReinit(void)
3397 ErrorF("[GestureRegionsReinit] Invalid pointer access !\n");
3398 return ERROR_INVALPTR;
3401 pixman_region_init(&g_pGesture->area);
3412 tmpEQ = (IEventRec *)calloc(GESTURE_EQ_SIZE, sizeof(IEventRec));
3416 ErrorF("[GestureInitEQ] Failed to allocate memory for EQ !\n");
3417 return ERROR_ALLOCFAIL;
3420 for (i = 0; i < GESTURE_EQ_SIZE; i++)
3422 tmpEQ[i].event = (InternalEvent *)malloc(sizeof(InternalEvent));
3423 if (!tmpEQ[i].event)
3425 ErrorF("[GestureInitEQ] Failed to allocation memory for each event buffer in EQ !\n");
3427 while(i >= 0 && tmpEQ[i].event)
3429 free(tmpEQ[i].event);
3430 tmpEQ[i].event = NULL;
3434 return ERROR_ALLOCFAIL;
3438 g_pGesture->EQ = tmpEQ;
3439 g_pGesture->headEQ = g_pGesture->tailEQ = 0;
3449 if (!g_pGesture || !g_pGesture->EQ)
3451 return ERROR_INVALPTR;
3454 for (i = 0; i < GESTURE_EQ_SIZE; i++)
3456 if (g_pGesture->EQ[i].event)
3458 free(g_pGesture->EQ[i].event);
3459 g_pGesture->EQ[i].event = NULL;
3463 free(g_pGesture->EQ);
3464 g_pGesture->EQ = NULL;
3470 GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
3474 if (!g_pGesture || !g_pGesture->EQ)
3476 ErrorF("[GestureEnqueueEvent] Invalid pointer access !\n");
3477 return ERROR_INVALPTR;
3480 tail = g_pGesture->tailEQ;
3482 if (tail >= GESTURE_EQ_SIZE)
3484 ErrorF("[GestureEnqueueEvent] Gesture EQ is full !\n");
3485 printk("[GestureEnqueueEvent] Gesture EQ is full...Force Gesture Flush !\n");
3486 GestureEventsFlush();
3487 return ERROR_EQFULL;
3490 if((g_pGesture->mtsync_flag & MTSYNC_FLAG_ROTARY) || (g_pGesture->mtsync_flag & ~MTSYNC_FLAG_TOUCH))
3492 DetailDebugPrint("[GestureEnqueueEvent] Rotary or other input are coming. Do not push events to queue.\n");
3496 switch (ev->any.type)
3498 case ET_ButtonPress:
3499 DetailDebugPrint("[GestureEnqueueEvent] ET_ButtonPress (id:%d)\n", device->id);
3502 case ET_ButtonRelease:
3503 DetailDebugPrint("[GestureEnqueueEvent] ET_ButtonRelease (id:%d)\n", device->id);
3507 DetailDebugPrint("[GestureEnqueueEvent] ET_Motion (id:%d)\n", device->id);
3511 g_pGesture->EQ[tail].device = device;
3512 g_pGesture->EQ[tail].screen_num = screen_num;
3513 memcpy(g_pGesture->EQ[tail].event, ev, sizeof(InternalEvent));//need to be optimized
3514 g_pGesture->tailEQ++;
3520 GestureEventsFlush(void)
3523 DeviceIntPtr device;
3525 if (!g_pGesture->EQ)
3527 ErrorF("[GestureEventsFlush] Invalid pointer access !\n");
3528 return ERROR_INVALPTR;
3531 DetailDebugPrint("[GestureEventsFlush]\n");
3533 for (i = g_pGesture->headEQ; i < g_pGesture->tailEQ; i++)
3535 device = g_pGesture->EQ[i].device;
3536 device->public.processInputProc(g_pGesture->EQ[i].event, device);
3539 for (i = 0; i < MAX_MT_DEVICES; i++)
3541 g_pGesture->event_sum[i] = 0;
3544 g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
3550 GestureEventsDrop(void)
3552 DetailDebugPrint("[GestureEventsDrop]\n");
3553 g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
3556 #ifdef HAVE_PROPERTIES
3558 GestureInitProperty(DeviceIntPtr dev)
3562 #ifdef SUPPORT_ANR_WITH_INPUT_EVENT
3563 prop_anr_in_input_event = MakeAtom(CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT, strlen(CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT), TRUE);
3564 prop_anr_event_window = MakeAtom(ANR_EVENT_WINDOW, strlen(ANR_EVENT_WINDOW), TRUE);
3567 prop_gesture_recognizer_onoff = MakeAtom(GESTURE_RECOGNIZER_ONOFF, strlen(GESTURE_RECOGNIZER_ONOFF), TRUE);
3568 rc = XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
3575 XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE);
3579 GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
3582 if (prop_gesture_recognizer_onoff == atom)
3585 if (val->format != 32 || val->type != XA_INTEGER || val->size != 1)
3590 data = *((int *)val->data);
3591 GestureEnable(data, TRUE, dev);
3596 #endif//HAVE_PROPERTIES
3599 GestureInit(DeviceIntPtr device)
3601 #ifdef HAVE_PROPERTIES
3602 GestureInitProperty(device);
3603 XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL);
3605 //GestureEnable(1, FALSE, g_pGesture->this_device);
3610 GestureFini(DeviceIntPtr device)
3612 XIRegisterPropertyHandler(device, NULL, NULL, NULL);
3616 GesturePlug(pointer module, pointer options, int *errmaj, int *errmin)
3618 xf86AddInputDriver(&GESTURE, module, 0);
3623 GestureUnplug(pointer p)
3628 GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
3631 GestureDevicePtr pGesture;
3633 pGesture = calloc(1, sizeof(GestureDeviceRec));
3637 pInfo->private = NULL;
3638 //xf86DeleteInput(pInfo, 0);
3642 g_pGesture = pGesture;
3644 pInfo->private = pGesture;
3646 pInfo->read_input = GestureReadInput; /* new data avl */
3647 pInfo->switch_mode = NULL; /* toggle absolute/relative mode */
3648 pInfo->device_control = GestureControl; /* enable/disable dev */
3650 /* process driver specific options */
3651 pGesture->device = xf86SetStrOption(pInfo->options, "Device", "/dev/null");
3652 pGesture->is_active = xf86SetIntOption(pInfo->options, "Activate", 0);
3653 pGesture->gestureWin = None;
3654 pGesture->lastSelectedWin = None;
3655 pGesture->power_pressed = 1;
3656 pGesture->hwkey_id = 0;
3657 pGesture->hwkey_dev = NULL;
3658 pGesture->num_tap_repeated = 0;
3659 pGesture->mtsync_total_count = 0;
3660 pGesture->hwkey_name = xf86SetStrOption(pInfo->options, "BackHWKeyName", NULL);
3661 pGesture->screen_width = xf86SetIntOption(pInfo->options,"ScreenWidth", 0);
3662 pGesture->screen_height = xf86SetIntOption(pInfo->options,"ScreenHeight", 0);
3663 pGesture->hwkeycode_flick_down = xf86SetIntOption(pInfo->options, "FlickDownKeycode", 0);
3664 pGesture->hwkeycode_flick_up = xf86SetIntOption(pInfo->options, "FlickUpKeycode", 0);
3665 pGesture->flick_press_area = xf86SetIntOption(pInfo->options, "FlickPressArea", 0);
3666 pGesture->flick_press_area_left = xf86SetIntOption(pInfo->options, "FlickPressArea_LEFT", 0);
3667 pGesture->flick_press_area_left_right = xf86SetIntOption(pInfo->options, "FlickPressArea_LEFT_RIGHT", 0);
3668 pGesture->flick_minimum_height = xf86SetIntOption(pInfo->options, "FlickMinimumHeight", 0);
3669 pGesture->shutdown_keycode = xf86SetIntOption(pInfo->options, "ShutdownKeycode", 0);
3670 pGesture->singletap_threshold= xf86SetIntOption(pInfo->options, "SingleTapThresHold", 0);
3671 pGesture->doubletap_threshold= xf86SetIntOption(pInfo->options, "DoubleTapThresHold", 0);
3672 pGesture->tripletap_threshold= xf86SetIntOption(pInfo->options, "TripleTapThresHold", 0);
3673 pGesture->hold_area_threshold = xf86SetRealOption(pInfo->options, "HoldAreaThresHold", 0);
3674 pGesture->hold_move_threshold = xf86SetIntOption(pInfo->options, "HoldMoveThresHold", 0);
3675 pGesture->hold_time_threshold = xf86SetIntOption(pInfo->options, "HoldTimeThresHold", 0);
3676 pGesture->palm_flick_time_threshold = xf86SetIntOption(pInfo->options, "PalmFlickTimeThresHold", 0);
3677 pGesture->palm_flick_max_tmajor_threshold = xf86SetIntOption(pInfo->options, "PalmFlickMaxTouchMajorThresHold", 0);
3678 pGesture->palm_flick_min_tmajor_threshold = xf86SetIntOption(pInfo->options, "PalmFlickMinTouchMajorThresHold", 0);
3679 pGesture->activate_flick_down = xf86SetIntOption(pInfo->options, "ActivateFlickDown", 0);
3680 pGesture->activate_flick_up = xf86SetIntOption(pInfo->options, "ActivateFlickUp", 0);
3681 pGesture->activate_flick_right = xf86SetIntOption(pInfo->options, "ActivateFlickRight", 0);
3682 pGesture->factory_cmdname = xf86SetStrOption(pInfo->options, "FactoryCmdName", NULL);
3684 ErrorF("[X11][%s] ###############################################################\n", __FUNCTION__);
3685 ErrorF("[X11][%s] screen_width=%d, screen_height=%d\n", __FUNCTION__,
3686 pGesture->screen_width, pGesture->screen_height);
3687 ErrorF("[X11][%s] FlickDownKeycode=%d, FlickUpKeycode=%d\n", __FUNCTION__,
3688 pGesture->hwkeycode_flick_down, pGesture->hwkeycode_flick_up);
3689 ErrorF("[X11][%s] flick_press_area=%d, flick_press_area_left: %d, flick_press_area_left_right: %d, flick_minimum_height=%d\n", __FUNCTION__,
3690 pGesture->flick_press_area, pGesture->flick_press_area_left, pGesture->flick_press_area_left_right, pGesture->flick_minimum_height);
3691 ErrorF("[X11][%s] ShutdownKeycode=%d\n", __FUNCTION__, pGesture->shutdown_keycode);
3692 ErrorF("[X11][%s] singletap_threshold=%d, doubletap_threshold=%d\n", __FUNCTION__, pGesture->singletap_threshold, pGesture->doubletap_threshold);
3693 ErrorF("[X11][%s] hold_area_threshold: %f, hold_move_threshold: %d, hold_time_threshold: %d\n", __FUNCTION__,
3694 pGesture->hold_area_threshold, pGesture->hold_move_threshold, pGesture->hold_time_threshold);
3695 ErrorF("[X11][%s] palm_flick_time_threshold: %d, palm_flick_max_tmajor_threshold: %d, palm_flick_min_tmajor_threshold: %d\n", __FUNCTION__,
3696 pGesture->palm_flick_time_threshold, pGesture->palm_flick_max_tmajor_threshold, pGesture->palm_flick_min_tmajor_threshold);
3697 ErrorF("[X11][%s] activate_flick_down=%d, activate_flick_up=%d, activate_flick_right=%d\n", __FUNCTION__,
3698 pGesture->activate_flick_down, pGesture->activate_flick_up, pGesture->activate_flick_right);
3699 ErrorF("[X11][%s] factory cmd name: %s\n", __FUNCTION__, pGesture->factory_cmdname);
3700 ErrorF("[X11][%s] ###############################################################\n", __FUNCTION__);
3702 if (pGesture->hwkey_name)
3704 ErrorF("[X11][%s] hwkey_name=%s\n", __FUNCTION__, pGesture->hwkey_name);
3707 pGesture->mtsync_flag = 0x00;
3708 g_pGesture->grabMask = g_pGesture->eventMask = 0;
3710 xf86Msg(X_INFO, "%s: Using device %s.\n", pInfo->name, pGesture->device);
3712 /* process generic options */
3713 xf86CollectInputOptions(pInfo, NULL);
3714 xf86ProcessCommonOptions(pInfo, pInfo->options);
3718 g_pGesture->touch_cancel_status = FALSE;
3729 GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
3731 GestureDevicePtr pGesture = pInfo->private;
3733 g_pGesture = pGesture = NULL;
3734 pInfo->private = NULL;
3736 xf86DeleteInput(pInfo, 0);
3740 GestureControl(DeviceIntPtr device, int what)
3742 InputInfoPtr pInfo = device->public.devicePrivate;
3743 GestureDevicePtr pGesture = pInfo->private;
3748 GestureInit(device);
3751 /* Switch device on. Establish socket, start event delivery. */
3753 xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
3755 if (device->public.on)
3758 device->public.on = TRUE;
3759 pGesture->this_device = device;
3760 pGesture->num_mt_devices = 0;
3761 if (ERROR_ABNORMAL == GestureEnableEventHandler(pInfo))
3763 if (!AddCallback(&DPMSCallback, GestureDPMSCallback, NULL))
3764 ErrorF("[Gesture]Failed to Add DPMS CallBack\n");
3769 GestureDisableEventHandler();
3770 DeleteCallback(&DPMSCallback, GestureDPMSCallback, NULL);
3771 GestureFini(device);
3772 pGesture->this_device = NULL;
3773 xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
3775 if (!device->public.on)
3779 device->public.on = FALSE;
3783 /* free what we have to free */
3790 GestureReadInput(InputInfoPtr pInfo)