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);
135 //Enqueued event handlers and enabler/disabler
136 static ErrorStatus GestureEnableEventHandler(InputInfoPtr pInfo);
137 static ErrorStatus GestureDisableEventHandler(void);
138 static CARD32 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
139 static CARD32 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
140 void GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
141 void GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
142 void GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
143 void GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
144 void GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
145 void GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
147 void GestureEmulateHWKey(DeviceIntPtr dev, int keycode);
149 //Gesture recognizer helper
150 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21
151 static Bool PointInBorderSize(WindowPtr pWin, int x, int y);
153 static WindowPtr GestureWindowOnXY(int x, int y);
154 Bool GestureHasFingerEventMask(int eventType, int num_finger);
156 //Gesture recognizer and handlers
157 void GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device);
158 void GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
159 void GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int start_point, int direction);
160 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
161 void GestureRecognize_PalmFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx);
162 void GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction);
163 void GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy);
164 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds);
165 ErrorStatus GestureFlushOrDrop(void);
167 static int GestureGetPalmValuator(InternalEvent *ev, DeviceIntPtr device);
168 static int GesturePalmGetAbsAxisInfo(DeviceIntPtr dev);
169 static void GestureHoldDetector(int type, InternalEvent *ev, DeviceIntPtr device);
170 static int GesturePalmGetScreenInfo();
171 static int GesturePalmGetHorizIndexWithX(int current_x, int idx, int type);
173 #ifdef HAVE_PROPERTIES
174 //function related property handling
175 static void GestureInitProperty(DeviceIntPtr dev);
176 static int GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkonly);
179 static Atom prop_gesture_recognizer_onoff = None;
181 #ifdef SUPPORT_ANR_WITH_INPUT_EVENT
182 static Atom prop_anr_in_input_event = None;
183 static Atom prop_anr_event_window = None;
184 static Window prop_anr_event_window_xid = None;
188 GestureDevicePtr g_pGesture = NULL;
189 _X_EXPORT InputDriverRec GESTURE = {
199 static XF86ModuleVersionInfo GestureVersionRec =
205 XORG_VERSION_CURRENT,
206 PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR,
207 PACKAGE_VERSION_PATCHLEVEL,
214 _X_EXPORT XF86ModuleData gestureModuleData =
222 printk(const char* fmt, ...)
224 static FILE* fp = NULL;
225 static char init = 0;
230 fp = fopen("/dev/kmsg", "wt");
236 va_start(argptr, fmt);
237 vfprintf(fp, fmt, argptr);
242 #ifdef SUPPORT_ANR_WITH_INPUT_EVENT
244 _GestureFindANRWindow(DeviceIntPtr device)
247 WindowPtr anr_window=NULL;
252 root = RootWindow(device);
254 if( prop_anr_event_window == None )
255 prop_anr_event_window = MakeAtom(ANR_EVENT_WINDOW, strlen(ANR_EVENT_WINDOW), TRUE);
257 rc = dixLookupProperty (&pProp, root, prop_anr_event_window, serverClient, DixReadAccess);
258 if (rc == Success && pProp->data){
259 anr_xid = *(int*)pProp->data;
264 rc = dixLookupWindow(&anr_window, anr_xid, serverClient, DixSetPropAccess);
265 if( rc == BadWindow )
267 ErrorF("Can't find ANR window !!\n");
270 prop_anr_event_window_xid = anr_xid;
273 ErrorF("ANR Window is %#x. Ptr is %#x\n", anr_xid, anr_window);
278 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21
280 PointInBorderSize(WindowPtr pWin, int x, int y)
283 if (pixman_region_contains_point (&pWin->borderSize, x, y, &box))
292 GestureWindowOnXY(int x, int y)
297 DeviceIntPtr pDev = g_pGesture->master_pointer;
299 pSprite = pDev->spriteInfo->sprite;
300 pSprite->spriteTraceGood = 1; /* root window still there */
301 pWin = RootWindow(pDev)->firstChild;
305 if ((pWin->mapped) &&
306 (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
307 (x < pWin->drawable.x + (int)pWin->drawable.width +
308 wBorderWidth(pWin)) &&
309 (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
310 (y < pWin->drawable.y + (int)pWin->drawable.height +
312 /* When a window is shaped, a further check
313 * is made to see if the point is inside
316 && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
317 && (!wInputShape(pWin) ||
318 RegionContainsPoint(wInputShape(pWin),
319 x - pWin->drawable.x,
320 y - pWin->drawable.y, &box))
322 /* In rootless mode windows may be offscreen, even when
323 * they're in X's stack. (E.g. if the native window system
324 * implements some form of virtual desktop system).
326 && !pWin->rootlessUnhittable
330 if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
332 pSprite->spriteTraceSize += 10;
333 pSprite->spriteTrace = realloc(pSprite->spriteTrace,
334 pSprite->spriteTraceSize*sizeof(WindowPtr));
336 pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
337 pWin = pWin->firstChild;
340 pWin = pWin->nextSib;
342 return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
346 GestureHasFingerEventMask(int eventType, int num_finger)
349 Mask eventmask = (1L << eventType);
351 if ((g_pGesture->grabMask & eventmask) &&
352 (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[num_finger].window != None))
354 DetailDebugPrint("[GestureHasFingerEventMask] TRUE !! Has grabMask\n");
358 if (g_pGesture->eventMask & eventmask)
360 DetailDebugPrint("[GestureHasFingerEventMask] TRUE !! Has eventMask\n");
364 DetailDebugPrint("[GestureHasFingerEventMask] FALSE !! eventType=%d, num_finger=%d\n", eventType, num_finger);
370 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
372 int event_type = *(int *)arg;
376 case GestureNotifyHold:
377 DetailDebugPrint("[GestureEventTimerHandler] GestureNotifyHold (event_type = %d)\n", event_type);
378 GestureRecognize_GroupHold(event_type, NULL, NULL, 0, 1);
380 case GestureNotifyTap:
381 DetailDebugPrint("[GestureEventTimerHandler] GestureNotifyTap (event_type = %d)\n", event_type);
382 GestureRecognize_GroupTap(event_type, NULL, NULL, 0, 1);
385 DetailDebugPrint("[GestureEventTimerHandler] unknown event_type (=%d)\n", event_type);
388 DetailDebugPrint("[GestureEventTimerHandler] timer=%x\n", (unsigned int)timer);
396 GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy)
399 WindowPtr target_pWin;
400 xGestureNotifyTapEvent tev;
402 //skip non-tap events and single finger tap
403 if (!tap_repeat || num_finger <= 1)
408 DetailDebugPrint("[GestureHandleGesture_Tap] num_finger=%d, tap_repeat=%d, cx=%d, cy=%d\n", num_finger, tap_repeat, cx, cy);
410 g_pGesture->recognized_gesture |= WTapFilterMask;
411 memset(&tev, 0, sizeof(xGestureNotifyTapEvent));
412 tev.type = GestureNotifyTap;
413 tev.kind = GestureDone;
414 tev.num_finger = num_finger;
415 tev.tap_repeat = tap_repeat;
420 target_win = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].window;
421 target_pWin = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].pWin;
423 if (g_pGesture->grabMask && (target_win != None))
425 tev.window = target_win;
429 tev.window = g_pGesture->gestureWin;
432 DetailDebugPrint("[GestureHandleGesture_Tap] tev.window=0x%x, g_pGesture->grabMask=0x%x\n", (unsigned int)tev.window, (unsigned int)g_pGesture->grabMask);
434 GestureSendEvent(target_pWin, GestureNotifyTap, GestureTapMask, (xGestureCommonEvent *)&tev);
435 LOGI("GroupTap Event done. 2 fingers %d tap!", tap_repeat);
439 GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction)
441 if (num_of_fingers == 0)
444 WindowPtr target_pWin;
445 xGestureNotifyFlickEvent fev;
447 DetailDebugPrint("[GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n", num_of_fingers, distance, duration, direction);
449 g_pGesture->recognized_gesture |= WPalmFlickFilterMask;
451 memset(&fev, 0, sizeof(xGestureNotifyFlickEvent));
452 fev.type = GestureNotifyFlick;
453 fev.kind = GestureDone;
454 fev.num_finger = num_of_fingers;
455 fev.distance = distance;
456 fev.duration = duration;
457 fev.direction = direction;
459 if (g_pGesture->GrabEvents)
461 target_win = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].window;
462 target_pWin = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].pWin;
470 if (g_pGesture->grabMask && (target_win != None))
472 fev.window = target_win;
476 fev.window = g_pGesture->gestureWin;
479 DetailDebugPrint("[GestureHandleGesture_Flick] fev.window=0x%x, g_pGesture->grabMask=0x%x\n", fev.window, g_pGesture->grabMask);
481 GestureSendEvent(target_pWin, GestureNotifyFlick, GestureFlickMask, (xGestureCommonEvent *)&fev);
485 DetailDebugPrint("[GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n", num_of_fingers, distance, duration, direction);
489 case FLICK_NORTHWARD:
490 DetailDebugPrint("[GestureHandleGesture_Flick] Flick Down \n");
491 GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down);
494 case FLICK_SOUTHWARD:
495 DetailDebugPrint("[GestureHandleGesture_Flick] Flick Up \n");
496 GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up);
499 if (g_pGesture->power_pressed == 2)
501 DetailDebugPrint("[GestureHandleGesture_Flick] Flick Right & power_pressed\n");
502 GestureEmulateHWKey(g_pGesture->hwkey_dev, 122);
508 g_pGesture->recognized_gesture |= WFlickFilterMask;
512 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds)
515 WindowPtr target_pWin;
516 xGestureNotifyHoldEvent hev;
518 DetailDebugPrint("[GestureHandleGesture_Hold] num_fingers=%d, cx=%d, cy=%d, holdtime=%d, kinds=%d\n", num_fingers, cx, cy, holdtime, kinds);
520 if (num_fingers == 0)
522 g_pGesture->hold_detected = TRUE;
523 LOGI("[PalmHold] PalmHold success !\n");
527 g_pGesture->recognized_gesture |= WHoldFilterMask;
530 memset(&hev, 0, sizeof(xGestureNotifyHoldEvent));
531 hev.type = GestureNotifyHold;
533 hev.num_finger = num_fingers;
534 hev.holdtime = holdtime;
538 if (g_pGesture->GrabEvents)
540 target_win = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].window;
541 target_pWin = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].pWin;
549 if (g_pGesture->grabMask && (target_win != None))
551 hev.window = target_win;
555 hev.window = g_pGesture->gestureWin;
558 DetailDebugPrint("[GestureHandleGesture_Hold] hev.window=0x%x, g_pGesture->grabMask=0x%x\n", hev.window, g_pGesture->grabMask);
560 GestureSendEvent(target_pWin, GestureNotifyHold, GestureHoldMask, (xGestureCommonEvent *)&hev);
561 LOGI("[GroupHold] GestureHold success !\n");
566 GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
568 static int num_pressed = 0;
569 static int base_area_size = 0;
574 static int state = 0;
575 static int mbits = 0;
578 static pixman_box16_t base_box_ext;
580 static int tap_repeat = 0;
581 static int prev_num_pressed = 0;
583 static OsTimerPtr tap_event_timer = NULL;
584 static int event_type = GestureNotifyTap;
588 DetailDebugPrint("[GroupTap][Timer] state=%d, num_pressed=%d, tap_repeat=%d\n", state, num_pressed, tap_repeat);
592 case 1://first tap initiation check
595 DetailDebugPrint("[GroupTap][Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", num_pressed, tap_repeat);
596 DetailDebugPrint("[GroupTap][F] 1\n");
607 DetailDebugPrint("[GroupTap][Timer][state=2] 2 finger %d tap\n", tap_repeat);
608 LOGI("[GroupTap][F] Second tap doesn't come up in 400ms after first tap.\n");
612 if (GestureHasFingerEventMask(GestureNotifyTap, prev_num_pressed))
614 DetailDebugPrint("[GroupTap] Success 1!! 2 finger %d tap\n", tap_repeat);
615 GestureHandleGesture_Tap(prev_num_pressed, tap_repeat, base_cx, base_cy);
626 g_pGesture->fingers[idx].flags |= PressFlagTap;
628 if (g_pGesture->num_pressed < 2)
630 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);
634 if ((!base_area_size || g_pGesture->num_pressed > num_pressed))
636 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
637 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
638 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
639 base_box_ext.x1 = base_cx-TAP_MOVE_THRESHOLD;
640 base_box_ext.y1 = base_cy-TAP_MOVE_THRESHOLD;
641 base_box_ext.x2 = base_cx+TAP_MOVE_THRESHOLD;
642 base_box_ext.y2 = base_cy+TAP_MOVE_THRESHOLD;
644 TimerCancel(tap_event_timer);
645 tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->singletap_threshold, GestureEventTimerHandler, (int *)&event_type);
647 num_pressed = g_pGesture->num_pressed;
649 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);
653 if (!(g_pGesture->fingers[idx].flags & PressFlagTap))
660 DetailDebugPrint("[GroupTap][M] num_pressed=%d, return \n", num_pressed);
664 if (num_pressed != g_pGesture->num_pressed)
666 DetailDebugPrint("[GroupTap][M] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
670 if (mbits == (pow(2, num_pressed)-1))
672 area_size = AREA_SIZE(&g_pGesture->area.extents);
673 cx = AREA_CENTER_X(&g_pGesture->area.extents);
674 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
676 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));
677 DetailDebugPrint("[GroupTap][M] cx=%d, base_cx=%d, diff=%d\n", cx, g_pGesture->fingers[idx].mx, ABS(cx-base_cx));
678 DetailDebugPrint("[GroupTap][M] cy=%d, base_cy=%d, diff=%d\n", cy, g_pGesture->fingers[idx].my, ABS(cy-base_cy));
680 if (ABS(base_area_size-area_size) >= TAP_AREA_THRESHOLD)
682 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));
683 DetailDebugPrint("[GroupTap][F] 3\n");
684 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));
689 if (!INBOX(&base_box_ext, cx, cy))
691 DetailDebugPrint("[GroupTap][M] current center coordinates is not in base coordinates box !\n");
692 DetailDebugPrint("[GroupTap][F] 4\n");
693 LOGI("[GroupTap][F] current center coordinates is not in base coordinates box !\n");
700 case ET_ButtonRelease:
701 if (g_pGesture->num_pressed)
703 DetailDebugPrint("[GroupTap][R] Second finger doesn't come up. g_pGesture->num_pressed=%d\n", g_pGesture->num_pressed);
709 prev_num_pressed = num_pressed;
713 g_pGesture->num_tap_repeated = tap_repeat;
715 DetailDebugPrint("[GroupTap][R] tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, num_pressed, prev_num_pressed);
716 DetailDebugPrint("[GroupTap][R] base_rx=%d, base_ry=%d,\n", g_pGesture->fingers[idx].rx, g_pGesture->fingers[idx].ry);
718 if ((num_pressed != prev_num_pressed) || (!GestureHasFingerEventMask(GestureNotifyTap, num_pressed)))
720 DetailDebugPrint("[GroupTap][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
721 num_pressed, prev_num_pressed, num_pressed);
722 DetailDebugPrint("[GroupTap][F] 5\n");
723 LOGI("[GroupTap][F] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
724 num_pressed, prev_num_pressed, num_pressed);
730 DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat);
731 TimerCancel(tap_event_timer);
732 tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->doubletap_threshold, GestureEventTimerHandler, (int *)&event_type);
734 prev_num_pressed = num_pressed;
739 else if (tap_repeat == 2)
741 DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat);
742 TimerCancel(tap_event_timer);
743 tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->tripletap_threshold, GestureEventTimerHandler, (int *)&event_type);
745 base_area_size = num_pressed = 0;
749 DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat);
751 if (tap_repeat == MAX_TAP_REPEATS)
753 if (GestureHasFingerEventMask(GestureNotifyTap, num_pressed))
755 DetailDebugPrint("[GroupTap] Sucess 2!\n");
756 GestureHandleGesture_Tap(num_pressed, tap_repeat, base_cx, base_cy);
761 if (tap_repeat >= MAX_TAP_REPEATS)
763 LOGI("[GroupTap][F] More than 3 taps. Ignore. \n");
767 prev_num_pressed = num_pressed;
776 DetailDebugPrint("[GroupTap][cleanup_tap]\n");
780 g_pGesture->recognized_gesture &= ~WTapFilterMask;
783 g_pGesture->filter_mask |= WTapFilterMask;
785 if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
787 DetailDebugPrint("[GroupTap][cleanup] GestureFlushOrDrop() !\n");
789 if (ERROR_INVALPTR == GestureFlushOrDrop())
791 GestureControl(g_pGesture->this_device, DEVICE_OFF);
796 g_pGesture->num_tap_repeated = tap_repeat = 0;
797 prev_num_pressed = 0;
800 TimerCancel(tap_event_timer);
805 GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int start_point, int direction)
807 static int num_pressed = 0;
808 static Time base_time = 0;
811 static int diff_base_coord = 0;
812 static int diff_base_minor_coord = 0;
813 static int diff_current_coord = 0;
814 static int false_diff_count = 0;
815 static int false_minor_diff_count = 0;
816 static float angle = 0.0f;
817 static int angle_base_x = 0, angle_base_y = 0;
818 static int motion_count = 0;
820 if (g_pGesture->num_pressed > 1)
822 DetailDebugPrint("[GroupFlick][F] 1\n");
826 if ((start_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= start_point))
828 DetailDebugPrint("[GroupFlick][F] 2\n");
835 g_pGesture->fingers[idx].flags = PressFlagFlick;
836 base_time = GetTimeInMillis();
837 num_pressed = g_pGesture->num_pressed;
841 if (g_pGesture->fingers[idx].py > g_pGesture->flick_press_area)
843 DetailDebugPrint("[GroupFlick][FlickDown][P] press coord is out of bound. (%d, %d)\n",
844 g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
845 DetailDebugPrint("[GroupFlick][F] 3\n");
846 LOGI("[BackKey][F] press coord is out of bound (40 pixel from upper vezel). press y=%d\n", g_pGesture->fingers[idx].py);
850 angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
851 angle_base_x = g_pGesture->fingers[idx].px;
852 DetailDebugPrint("[GroupFlick][FlickDown][P] px=%d, py=%d\n", g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
855 case FLICK_POINT_DOWN:
856 if (g_pGesture->fingers[idx].py < g_pGesture->screen_height - g_pGesture->flick_press_area)
858 DetailDebugPrint("[GroupFlick][FlickUp][P] press coord is out of bound. (%d, %d)\n",
859 g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
860 DetailDebugPrint("[GroupFlick][F] 4\n");
863 angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
864 angle_base_x = g_pGesture->fingers[idx].px;
867 case FLICK_POINT_LEFT:
868 if (g_pGesture->fingers[idx].px > g_pGesture->flick_press_area)
870 DetailDebugPrint("[GroupFlick][FlickLeft][P] press coord is out of bound. (%d, %d)\n",
871 g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
872 DetailDebugPrint("[GroupFlick][F] 5\n");
875 angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
876 angle_base_x = g_pGesture->fingers[idx].px;
880 DetailDebugPrint("[GroupFlick][F] 6\n");
891 if (motion_count > 15)
893 DetailDebugPrint("[GroupFlick][F] 6-1 motion_count=%d\n", motion_count);
894 LOGI("[BackKey][F] More than 15 motion.\n");
898 if (!(g_pGesture->fingers[idx].flags & PressFlagFlick))
906 diff_base_coord = diff_current_coord;
907 diff_current_coord = g_pGesture->fingers[idx].my;
909 if ((diff_current_coord - diff_base_coord) < 0)
911 DetailDebugPrint("[GroupFlick][FlickDown][M] false_diff\n");
915 if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
917 DetailDebugPrint("[GroupFlick][FlickDown][M] false_diff_count: %d > %d\n",
918 false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
919 DetailDebugPrint("[GroupFlick][F] 7\n");
920 LOGI("[BackKey][F] Direction is wrong for 7 times.\n");
924 if ((g_pGesture->fingers[idx].my < g_pGesture->flick_press_area) &&
925 (abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) >(int)( g_pGesture->screen_width/2)))
927 DetailDebugPrint("[GroupFlick][FlickDown][M] move x: %d - %d, y coord: %d\n",
928 g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].my);
929 DetailDebugPrint("[GroupFlick][F] 8\n");
930 LOGI("[BackKey][F] From press point, moving x axis is more than half screen size.\n");
934 if ((g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) > g_pGesture->flick_minimum_height)
936 DetailDebugPrint("[GroupFlick][FlickDown][M] %d - %d < %d(min_size), angle_base_coord (%d, %d)\n",
937 g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py, g_pGesture->flick_minimum_height, angle_base_x, angle_base_y);
939 if (abs(g_pGesture->fingers[idx].mx - angle_base_x) == 0)
941 DetailDebugPrint("[GroupFlick][FlickDown][M] abs(%d - %d) = 0\n",
942 g_pGesture->fingers[idx].mx, angle_base_x);
947 DetailDebugPrint("[GroupFlick][FlickDown][M] angle_base_x: %d, angle_base_y: %d\n",
948 angle_base_x, angle_base_y);
949 int y_diff = abs(g_pGesture->fingers[idx].my - angle_base_y);
950 int x_diff = abs(g_pGesture->fingers[idx].mx - angle_base_x);
951 angle = (float)y_diff / (float)x_diff;
956 DetailDebugPrint("[GroupFlick][FlickDown][M][F] %d / %d = %f (angle)\n",
957 abs(g_pGesture->fingers[idx].my - angle_base_y), abs(g_pGesture->fingers[idx].mx - angle_base_x), angle);
958 DetailDebugPrint("[GroupFlick][F] 9\n");
959 LOGI("[BackKey][F] angle is improper. %d < 0.23\n", angle);
963 distance = g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py;
964 duration = GetTimeInMillis() - base_time;
966 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
967 DetailDebugPrint("[GroupFlick][FlickDown][M] FlickDown Done!!\n");
968 goto cleanup_flick_recognized;
972 if ((g_pGesture->fingers[idx].mx - diff_base_minor_coord) < 0)
974 false_minor_diff_count++;
977 if (false_minor_diff_count> FLICK_FALSE_X_DIFF_COUNT)
979 DetailDebugPrint("[GroupFlick][FlickDown][M] false_minor_diff_count: %d > %d\n",
980 false_minor_diff_count, FLICK_FALSE_X_DIFF_COUNT);
981 DetailDebugPrint("[GroupFlick][F] 10\n");
986 if (g_pGesture->fingers[idx].my < g_pGesture->flick_press_area)
988 angle_base_x = g_pGesture->fingers[idx].px;
989 angle_base_y = g_pGesture->fingers[idx].py;
991 DetailDebugPrint("[GroupFlick][FlickDown][M] mx=%d, my=%d, diff_x=%d, diff_y=%d\n",
992 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));
996 case FLICK_POINT_DOWN:
997 diff_base_coord = diff_current_coord;
998 diff_current_coord = g_pGesture->fingers[idx].my;
1000 if ((diff_base_coord - diff_current_coord) < 0)
1005 if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
1007 DetailDebugPrint("[GroupFlick][FlickUp][M] false_diff_count: %d > %d\n",
1008 false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
1009 DetailDebugPrint("[GroupFlick][F] 11\n");
1013 if ((g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my) > g_pGesture->flick_minimum_height)
1015 DetailDebugPrint("[GroupFlick][FlickUp][R] %d - %d < %d(min_size)\n",
1016 g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py, g_pGesture->flick_minimum_height);
1017 if (abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) == 0)
1019 DetailDebugPrint("[GroupFlick][FlickUp][R] abs(%d - %d) = 0\n",
1020 g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px);
1025 int y_diff = abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py);
1026 int x_diff = abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px);
1027 angle = (float)y_diff / (float)x_diff;
1032 DetailDebugPrint("[GroupFlick][FlickUp][R] %d / %d = %f (angle)\n",
1033 abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py), abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), angle);
1034 DetailDebugPrint("[GroupFlick][F] 12\n");
1038 distance = g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my;
1039 duration = GetTimeInMillis() - base_time;
1041 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
1042 goto cleanup_flick_recognized;
1046 case FLICK_POINT_LEFT:
1047 diff_base_coord = diff_current_coord;
1048 diff_current_coord = g_pGesture->fingers[idx].mx;
1050 if ((diff_current_coord - diff_base_coord) < 0)
1055 if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
1057 DetailDebugPrint("[GroupFlick][FlickLeft][M] false_diff_count: %d > %d\n",
1058 false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
1059 DetailDebugPrint("[GroupFlick][F] 13\n");
1063 if ((g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) > g_pGesture->flick_minimum_height)
1065 DetailDebugPrint("[GroupFlick][FlickLeft][M] %d - %d < %d(min_size)\n",
1066 g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px, g_pGesture->flick_minimum_height);
1068 if (abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) == 0)
1070 DetailDebugPrint("[GroupFlick][FlickLeft][M] abs(%d - %d) = 0\n",
1071 g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py);
1076 int y_diff = abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py);
1077 int x_diff = abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px);
1078 angle = (float)x_diff / (float)y_diff;
1083 DetailDebugPrint("[GroupFlick][FlickLeft][M] %d / %d = %f (angle)\n",
1084 abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py), angle);
1085 DetailDebugPrint("[GroupFlick][F] 14\n");
1089 distance = g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px;
1090 duration = GetTimeInMillis() - base_time;
1092 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
1093 goto cleanup_flick_recognized;
1098 DetailDebugPrint("[GroupFlick][F] 15\n");
1104 case ET_ButtonRelease:
1105 DetailDebugPrint("[GroupFlick][R][F] 16\n");
1113 DetailDebugPrint("[GroupFlick] cleanup_flick \n");
1114 g_pGesture->recognized_gesture &= ~WFlickFilterMask;
1117 cleanup_flick_recognized:
1118 DetailDebugPrint("[GroupFlick] Flick recognized !\n");
1119 g_pGesture->filter_mask |= WFlickFilterMask;
1122 false_diff_count = 0;
1123 diff_base_coord = 0;
1124 diff_current_coord = 0;
1126 angle_base_x = angle_base_y = 0;
1131 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1133 static int num_pressed = 0;
1134 static int base_area_size = 0;
1135 static Time base_time = 0;
1139 static pixman_box16_t base_box_ext;
1141 static int state = GestureEnd;
1143 static OsTimerPtr hold_event_timer = NULL;
1144 static int event_type = GestureNotifyHold;
1148 if (state <= GestureBegin)
1156 DetailDebugPrint("[GroupHold] HOLD Begin !\n");
1160 DetailDebugPrint("[GroupHold] HOLD Update !\n");
1164 if (GestureHasFingerEventMask(GestureNotifyHold, num_pressed))
1166 DetailDebugPrint("[GroupHold] Success 1! \n");
1167 GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1170 hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type);
1177 case ET_ButtonPress:
1178 g_pGesture->fingers[idx].flags |= PressFlagHold;
1180 if (g_pGesture->num_pressed < 2)
1182 DetailDebugPrint("[GroupHold][P] No num_finger changed ! num_pressed=%d\n", num_pressed);
1183 DetailDebugPrint("[GroupHold][F] 0\n");
1187 if (!base_area_size || g_pGesture->num_pressed > num_pressed)
1189 if (state != GestureEnd)
1191 DetailDebugPrint("[GroupHold][P][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1192 DetailDebugPrint("[GroupHold][F] 1\n");
1197 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1198 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1199 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1200 base_time = GetTimeInMillis();
1202 base_box_ext.x1 = base_cx-g_pGesture->hold_move_threshold;
1203 base_box_ext.y1 = base_cy-g_pGesture->hold_move_threshold;
1204 base_box_ext.x2 = base_cx+g_pGesture->hold_move_threshold;
1205 base_box_ext.y2 = base_cy+g_pGesture->hold_move_threshold;
1207 event_type = GestureNotifyHold;
1209 hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type);
1211 num_pressed = g_pGesture->num_pressed;
1213 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);
1218 if (!(g_pGesture->fingers[idx].flags & PressFlagHold))
1220 DetailDebugPrint("[GroupHold][M] No PressFlagHold\n");
1224 if (num_pressed < 2)
1226 DetailDebugPrint("[GroupHold][M] No num_finger changed ! num_pressed=%d\n", num_pressed);
1227 DetailDebugPrint("[GroupHold][F] 2\n");
1231 if (num_pressed != g_pGesture->num_pressed)
1233 if (state != GestureEnd)
1235 DetailDebugPrint("[GroupHold][M][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1236 DetailDebugPrint("[GroupHold][F] 3\n");
1240 DetailDebugPrint("[GroupHold][M] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1243 area_size = AREA_SIZE(&g_pGesture->area.extents);
1244 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1245 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1247 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));
1248 DetailDebugPrint("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1249 DetailDebugPrint("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1251 if (area_size > 0 && base_area_size > 0)
1253 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)
1255 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));
1256 DetailDebugPrint("[GroupHold][F] 4\n");
1261 if (!INBOX(&base_box_ext, cx, cy))
1263 DetailDebugPrint("[GroupHold][M] No current center coordinates is not in base coordinates box !\n");
1264 DetailDebugPrint("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1265 DetailDebugPrint("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1266 DetailDebugPrint("[GroupHold][F] 5\n");
1271 case ET_ButtonRelease:
1272 if (state != GestureEnd && num_pressed >= 2)
1274 DetailDebugPrint("[GroupHold][R] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1275 DetailDebugPrint("[GroupHold][F] 6\n");
1279 if (g_pGesture->num_pressed)
1281 DetailDebugPrint("[GroupHold][R] num_pressed=%d\n", num_pressed);
1282 DetailDebugPrint("[GroupHold][F] 7\n");
1294 DetailDebugPrint("[GroupHold][cleanup_hold] enter!\n");
1296 if (state == GestureBegin || state == GestureUpdate)
1299 if (GestureHasFingerEventMask(GestureNotifyHold, num_pressed))
1301 DetailDebugPrint("[GroupHold] Success 2!\n");
1302 GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1307 g_pGesture->recognized_gesture &= ~WHoldFilterMask;
1310 g_pGesture->filter_mask |= WHoldFilterMask;
1314 base_cx = base_cy = 0;
1316 base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
1317 TimerCancel(hold_event_timer);
1322 GestureGetMaxTmajor(InternalEvent *ev, int max_tmajor)
1324 int mt_tmajor_idx = g_pGesture->tmajor_idx;
1327 DeviceEvent *de = &ev->device_event;
1331 DetailDebugPrint("[GestureGetMaxTmajor] de is NULL !\n");
1335 if (mt_tmajor_idx < 0)
1337 DetailDebugPrint("[GestureGetMaxTmajor] One or more of axes are not supported !\n");
1341 mt_tmajor = de->valuators.data[mt_tmajor_idx];
1343 DetailDebugPrint("[GestureGetMaxTmajor]mt_tmajor_idx=%d, mt_tmajor=%d, max_tmajor=%d\n", mt_tmajor_idx, mt_tmajor, max_tmajor);
1345 return ((mt_tmajor > max_tmajor) ? mt_tmajor : max_tmajor);
1350 GestureRecognize_PalmFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx)
1352 // static int num_pressed = 0;
1353 static int base_time = 0, current_time = 0;
1354 static int base_x[MAX_MT_DEVICES] = {0}, base_y[MAX_MT_DEVICES] = {0};
1355 static int update_x[MAX_MT_DEVICES] = {0}, update_y[MAX_MT_DEVICES] = {0};
1358 static int current_x[MAX_MT_DEVICES] = {0}, current_y[MAX_MT_DEVICES] = {0};
1359 static Bool press_status[MAX_MT_DEVICES] = {FALSE, FALSE};
1360 static Bool release_status[MAX_MT_DEVICES] = {FALSE, FALSE};
1362 static int line_idx[MAX_MT_DEVICES] = {0}, prev_line_idx[MAX_MT_DEVICES] = {0}, press_idx[MAX_MT_DEVICES] = {0};
1363 static Bool is_line_invalid[MAX_MT_DEVICES] = {TRUE, TRUE};
1365 static int max_tmajor[MAX_MT_DEVICES] = {0};
1366 static int total_max_tmajor = 0;
1367 static Bool is_tmajor_invalid[MAX_MT_DEVICES] = {TRUE, TRUE};
1369 static int mt_sync_count[MAX_MT_DEVICES] = {0};
1371 static Bool is_palm = FALSE;
1372 PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
1374 static Bool is_retry = FALSE;
1376 int distance, direction, duration;
1378 if (g_pGesture->recognized_gesture && !(g_pGesture->recognized_gesture & WPalmFlickFilterMask))
1380 PalmFlickDebugPrint("[PalmFlick] recognize other gesture already( g_pGesture->recognized_gesture: %d)\n", g_pGesture->recognized_gesture);
1381 PalmFlickDebugPrint("[PalmFlick][F] 1\n");
1385 // only first finger recognize
1386 if (!(idx == 0 || idx == 1))
1388 PalmFlickDebugPrint("[PalmFlick] idx=%d, least two fingers come on\n", idx);
1394 case ET_ButtonPress:
1400 base_time = GetTimeInMillis();
1403 // press (x,y), touch major
1404 update_x[idx] = base_x[idx] = g_pGesture->fingers[idx].px;
1405 update_y[idx] = base_y[idx] = g_pGesture->fingers[idx].py;
1406 max_tmajor[idx] = g_pGesture->max_mt_tmajor[idx];
1407 press_status[idx] = TRUE;
1408 is_tmajor_invalid[idx] = FALSE;
1409 is_line_invalid[idx] = FALSE;
1411 total_max_tmajor = (total_max_tmajor > max_tmajor[idx]) ? total_max_tmajor : max_tmajor[idx];
1414 press_idx[idx] = prev_line_idx[idx] = line_idx[idx] = GesturePalmGetHorizIndexWithX(base_x[idx], idx, type);
1416 PalmFlickDebugPrint("[PalmFlick][P] idx: %d, num_pressed: %d\n", idx, g_pGesture->num_pressed);
1417 PalmFlickDebugPrint("[PalmFlick][P] base_time: %d, base_x: %d, base_y: %d, line_idx: %d, touch_major=%d\n",
1418 base_time, base_x[idx], base_y[idx], line_idx[idx], max_tmajor[idx]);
1421 if (line_idx[idx] < 0 || line_idx[idx] >= PALM_HORIZ_ARRAY_COUNT)
1423 PalmFlickDebugPrint("[PalmFlick][P][F] No line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x[idx], line_idx[idx]);
1424 PalmFlickDebugPrint("[PalmFlick][F] 2\n");
1428 // check press point when there are two fingers
1431 if (press_idx[0] != press_idx[1])
1433 PalmFlickDebugPrint("[PalmFlick] Press line_idx is the different between two fingers. 1st finger_line_idx=%d, 2nd finger_line_idx=%d\n",
1434 press_idx[0], press_idx[1]);
1435 PalmFlickDebugPrint("[PalmFlick][F] 2-1\n");
1442 update_x[idx] = g_pGesture->fingers[idx].px;
1443 update_y[idx] = g_pGesture->fingers[idx].py;
1445 PalmFlickDebugPrint("[PalmFlick][P] Already palm flick success. base_x=%d, base_y=%d, update_x=%d, update_y=%d\n",
1446 base_x[idx], base_y[idx], update_x[idx], update_y[idx]);
1453 if (total_max_tmajor > g_pGesture->palm_flick_max_tmajor_threshold)
1455 mt_sync_count[idx]++;
1457 DetailDebugPrint("[PalmFlick][M] Sufficient touch enough ! max_tmajor=%d\n", total_max_tmajor);
1461 // motion information (touch major, x, y)
1462 current_x[idx] = g_pGesture->fingers[idx].mx;
1463 current_y[idx] = g_pGesture->fingers[idx].my;
1464 max_tmajor[idx] = g_pGesture->max_mt_tmajor[idx];
1465 mt_sync_count[idx]++;
1467 //int temp_total_max_tmajor = (idx == 0 ? max_tmajor[0] : max_tmajor[0] + max_tmajor[1]);
1468 int temp_total_max_tmajor = max_tmajor[idx];
1469 total_max_tmajor = (total_max_tmajor > temp_total_max_tmajor ? total_max_tmajor : temp_total_max_tmajor);
1471 PalmFlickDebugPrint("[PalmFlick][M] idx=%d, total_max_tmajor=%d, max_tmajor[0]=%d, max_tmajor[1]=%d, current current=(%d, %d)\n",
1472 idx, total_max_tmajor, max_tmajor[0], max_tmajor[1], current_x[idx], current_y[idx]);
1474 // exception vezel end line motion
1475 if (current_x[idx] < 5 || current_x[idx] > 355)
1477 if (total_max_tmajor >= g_pGesture->palm_flick_max_tmajor_threshold)
1479 PalmFlickDebugPrint("[PalmFlick][M][Vezel] Sufficient touch major was came(%d)\n", total_max_tmajor);
1484 mt_sync_count[idx]--;
1485 PalmFlickDebugPrint("[PalmFlick][M] Except vezel end line condition. x=%d, sync_count=%d \n",
1486 current_x[idx], mt_sync_count[idx]);
1491 // get current position
1492 line_idx[idx] = GesturePalmGetHorizIndexWithX(current_x[idx], idx, type);
1494 PalmFlickDebugPrint("[PalmFlick][M] line_idx: %d, prev_line_idx: %d, sync_count: %d\n",
1495 line_idx[idx], prev_line_idx[idx], mt_sync_count[idx]);
1498 if (line_idx[idx] < 0 || line_idx[idx] >= PALM_HORIZ_ARRAY_COUNT)
1500 PalmFlickDebugPrint("[PalmFlick][M][F] No line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x[idx], line_idx[idx]);
1501 PalmFlickDebugPrint("[PalmFlick][F] 3\n");
1505 // screen capture motion validation
1506 if (line_idx[idx] != prev_line_idx[idx])
1508 if (base_x[idx] <= pPalmMisc->horiz_coord[0])
1510 if (line_idx[idx] < prev_line_idx[idx])
1512 PalmFlickDebugPrint("[PalmFlick][M][F] Invalid line_idx.. line_idx: %d, prev_line_idx: %d, pPalmMisc->horiz_coord[0]: %d\n",
1513 line_idx[idx], prev_line_idx[idx], pPalmMisc->horiz_coord[0]);
1515 is_line_invalid[idx] = TRUE;
1517 if (is_line_invalid[0] && is_line_invalid[1])
1519 PalmFlickDebugPrint("[PalmFlick][F] 4\n");
1524 else if (base_x[idx] >= pPalmMisc->horiz_coord[PALM_HORIZ_ARRAY_COUNT-1])
1526 if (line_idx[idx] > prev_line_idx[idx])
1528 PalmFlickDebugPrint("[PalmFlick][M][F] Invalid line_idx.. line_idx: %d, prev_line_idx: %d, pPalmMisc->horiz_coord[%d]: %d\n",
1529 line_idx[idx], prev_line_idx[idx], PALM_HORIZ_ARRAY_COUNT-1, pPalmMisc->horiz_coord[PALM_HORIZ_ARRAY_COUNT-1]);
1531 is_line_invalid[idx] = TRUE;
1533 if (is_line_invalid[0] && is_line_invalid[1])
1535 PalmFlickDebugPrint("[PalmFlick][F] 5\n");
1540 prev_line_idx[idx] = line_idx[idx];
1543 if (is_palm == FALSE)
1545 switch (mt_sync_count[idx])
1548 if (total_max_tmajor <= g_pGesture->palm_flick_min_tmajor_threshold)
1550 PalmFlickDebugPrint("[PalmFlick][M][F] mtsync_count: %d, max_tmajor: %d(%d) line_idx: %d\n",
1551 mt_sync_count[idx], total_max_tmajor, g_pGesture->palm_flick_min_tmajor_threshold, line_idx[idx]);
1552 PalmFlickDebugPrint("[PalmFlick][F] 6\n");
1553 is_tmajor_invalid[idx] = TRUE;
1554 //goto flick_failed;
1558 if (total_max_tmajor <= (g_pGesture->palm_flick_max_tmajor_threshold - 10))
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_max_tmajor_threshold-10, line_idx[idx]);
1562 PalmFlickDebugPrint("[PalmFlick][F] 7\n");
1563 is_tmajor_invalid[idx] = TRUE;
1564 //goto flick_failed;
1568 if (total_max_tmajor < g_pGesture->palm_flick_max_tmajor_threshold)
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, line_idx[idx]);
1572 PalmFlickDebugPrint("[PalmFlick][F] 8\n");
1573 is_tmajor_invalid[idx] = TRUE;
1574 //goto flick_failed;
1578 PalmFlickDebugPrint("[PalmFlick][M] See more next motion...\n");
1583 if (is_tmajor_invalid[0] && is_tmajor_invalid[1])
1585 PalmFlickDebugPrint("[PalmFlick][M][F] max_tmajor=%d\n", total_max_tmajor);
1589 current_time = GetTimeInMillis();
1591 if (current_time - base_time > g_pGesture->palm_flick_time_threshold)
1593 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);
1594 PalmFlickDebugPrint("[PalmFlick][F] 10\n");
1600 case ET_ButtonRelease:
1601 current_x[idx] = g_pGesture->fingers[idx].mx;
1602 current_y[idx] = g_pGesture->fingers[idx].my;
1603 release_status[idx] = TRUE;
1605 if ((update_x[idx] == current_x[idx]) && (update_y[idx] == current_y[idx]))
1607 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",
1608 update_x[idx], update_y[idx], current_x[idx], current_y[idx]);
1609 PalmFlickDebugPrint("[PalmFlick][F] 10-1\n");
1611 //goto flick_failed;
1616 is_tmajor_invalid[idx] = TRUE;
1618 if (is_tmajor_invalid[0] && is_tmajor_invalid[1])
1620 PalmFlickDebugPrint("[PalmFlick][R][F] Insufficient touch major was came(%d)\n", total_max_tmajor);
1621 PalmFlickDebugPrint("[PalmFlick][F] 11\n");
1626 line_idx[idx] = GesturePalmGetHorizIndexWithX(current_x[idx], idx, type);
1628 if (is_palm && line_idx[idx] == 1)
1630 PalmFlickDebugPrint("[PalmFlick][R] Enough major, but release. base_x=%d, base_y=%d, current_x=%d, current_y=%d\n",
1631 base_x[idx], base_y[idx], current_x[idx], current_y[idx]);
1633 mt_sync_count[idx] = 0;
1637 if (line_idx[idx] < 0 || line_idx[idx] > PALM_HORIZ_ARRAY_COUNT - 1)
1639 is_line_invalid[idx] = TRUE;
1641 if (is_line_invalid[0] && is_line_invalid[1])
1643 PalmFlickDebugPrint("[PalmFlick][R][F] No line_idx is invalid.. base_x: %d, current_x: %d\n", base_x[idx], current_x[idx]);
1644 PalmFlickDebugPrint("[PalmFlick][F] 12\n");
1649 current_time = GetTimeInMillis();
1651 if (current_time - base_time > g_pGesture->palm_flick_time_threshold)
1653 PalmFlickDebugPrint("[PalmFlick][R][F] Release event were came to have long delay (%d - %d > %d)\n",
1654 current_time, base_time, g_pGesture->palm_flick_time_threshold);
1655 PalmFlickDebugPrint("[PalmFlick][F] 13\n");
1659 direction = (line_idx[idx] <= 1) ? FLICK_EASTWARD : FLICK_WESTWARD;
1660 distance = ABS(current_x[idx] - base_x[idx]);
1661 duration = current_time - base_time;
1665 if (GestureHasFingerEventMask(GestureNotifyFlick, 0))
1667 PalmFlickDebugPrint("[PalmFlick][R] Palm Flick1 !!!, direction=%d, distance=%d\n", direction, distance);
1669 GestureHandleGesture_Flick(0, distance, duration, direction);
1674 if (mt_sync_count[idx] < 25)
1676 PalmFlickDebugPrint("[PalmFlick][R][F] No enough motion=%d\n", mt_sync_count[idx]);
1677 PalmFlickDebugPrint("[PalmFlick][F] 14\n");
1682 if (GestureHasFingerEventMask(GestureNotifyFlick, 0))
1684 PalmFlickDebugPrint("[PalmFlick][R] Palm Flick2 !!!, direction=%d, distance=%d\n", direction, distance);
1686 GestureHandleGesture_Flick(0, distance, duration, direction);
1691 g_pGesture->recognized_gesture |= WPalmFlickFilterMask;
1701 DetailDebugPrint("[PalmFlick][R] flick failed\n");
1703 g_pGesture->recognized_gesture &= ~WPalmFlickFilterMask;
1704 g_pGesture->filter_mask |= WPalmFlickFilterMask;
1709 DetailDebugPrint("[PalmFlick][R] cleanup_flick\n");
1711 for (int i = 0; i < MAX_MT_DEVICES; i++)
1721 prev_line_idx[i] = 0;
1723 mt_sync_count[i] = 0;
1724 press_status[i] = FALSE;
1725 release_status[i] = FALSE;
1726 is_tmajor_invalid[i] = TRUE;
1727 is_line_invalid[i] = TRUE;
1730 total_max_tmajor = 0;
1738 GesturePalmGetHorizIndexWithX(int current_x, int idx, int type)
1742 static int pressed_idx[MAX_MT_DEVICES] = {-1, -1};
1743 PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
1745 for (i = 0; i < PALM_HORIZ_ARRAY_COUNT; i++)
1747 if (current_x <= pPalmMisc->horiz_coord[i])
1749 DetailDebugPrint("[GesturePalmGetHorizIndexWithX] index=%d, pPalmMisc->horiz_coord[%d]=%d\n", i, i, pPalmMisc->horiz_coord[i]);
1756 DetailDebugPrint("[GesturePalmGetHorizIndexWithX]Error ! Failed to get horiz coordinate index !\n");
1761 if (type == ET_ButtonPress)
1763 pressed_idx[idx] = ret_idx;
1765 // first press is center
1766 if (pressed_idx[idx] == PALM_HORIZ_ARRAY_COUNT -2)
1768 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][P] Invalid press area x=%d, idx=%d, pressed_idx=%d\n", current_x, idx, pressed_idx[idx]);
1772 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][P] pressed_idx=%d\n", pressed_idx[idx]);
1775 else if (type == ET_Motion)
1777 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][M] moving x=%d, idx=%d, pressed_idx=%d\n", current_x, idx, pressed_idx[idx]);
1780 else if (type == ET_ButtonRelease)
1782 if ((pressed_idx[idx] == 0) && (ret_idx == (PALM_HORIZ_ARRAY_COUNT - 1)))
1784 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] From the left to the right ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
1786 else if ((pressed_idx[idx] == (PALM_HORIZ_ARRAY_COUNT - 1)) && (ret_idx == 0))
1788 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] From the right to the left ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
1790 else if ((pressed_idx[idx] == ret_idx) && ret_idx != 1)
1792 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] Relased the same region ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
1797 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] Invalid ! pressed_idx=%d, released_idx=%d\n", pressed_idx[idx], ret_idx);
1801 pressed_idx[idx] = -1;
1808 GesturePalmGetAbsAxisInfo(DeviceIntPtr dev)
1815 Atom atom_tracking_id;
1819 g_pGesture->tpalm_idx = -1;
1820 g_pGesture->tmajor_idx = -1;
1821 g_pGesture->tminor_idx = -1;
1823 if (!dev || !dev->valuator)
1826 numAxes = dev->valuator->numAxes;
1828 atom_tpalm = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_PALM);
1829 atom_mt_slot = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_SLOT);
1830 atom_tracking_id = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TRACKING_ID);
1831 atom_tmajor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR);
1832 atom_tminor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR);
1834 if (!numAxes || !atom_tpalm || !atom_tmajor || !atom_tminor)
1836 ErrorF("one or more axes is/are not supported!\n");
1840 for (i = 0; i < numAxes; i++)
1842 AxisInfoPtr axes = &dev->valuator->axes[i];
1844 if (!axes || (axes->mode != Absolute))
1847 if (axes->label == atom_tpalm)
1849 g_pGesture->tpalm_idx = i;
1852 else if (axes->label == atom_tmajor)
1854 g_pGesture->tmajor_idx = i;
1857 else if (axes->label == atom_tminor)
1859 g_pGesture->tminor_idx = i;
1866 ErrorF("Axes for palm recognization are not supported !\n");
1870 g_pGesture->palm_misc.enabled = 1;
1871 ErrorF("Axes for palm recognization are supported !\n");
1875 g_pGesture->palm_misc.enabled = 0;
1876 ErrorF("Palm recognization is not supported !\n");
1881 GestureGetPalmValuator(InternalEvent *ev, DeviceIntPtr device)
1883 int mt_palm_idx = g_pGesture->tpalm_idx;
1886 DeviceEvent *de = &ev->device_event;
1890 ErrorF("[GestureGetPalmValuator] de is NULL !\n");
1894 if (mt_palm_idx < 0)
1896 ErrorF("[GestureGetPalmValuator] One or more of axes are not supported !\n");
1900 mt_palm = de->valuators.data[mt_palm_idx];
1902 HoldDetectorDebugPrint("[GestureGetPalmValuator] mt_palm:%d\n", mt_palm);
1907 static void GestureHoldDetector(int type, InternalEvent *ev, DeviceIntPtr device)
1911 pixman_region16_t tarea1;
1912 static int num_pressed = 0;
1913 unsigned int hold_area_size;
1914 PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
1917 if (!g_pGesture->has_hold_grabmask)
1919 HoldDetectorDebugPrint("[GestureHoldDetector] g_pGesture->has_hold_grabmask=%d\n", g_pGesture->has_hold_grabmask);
1921 Mask eventmask = (1L << GestureNotifyHold);
1923 if ((g_pGesture->grabMask & eventmask) &&
1924 (g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[0].window != None))
1926 g_pGesture->has_hold_grabmask = 1;
1928 //Initialize a set of variables
1930 memset(&g_pGesture->cts, 0, sizeof(g_pGesture->cts));
1931 pixman_region_init(&g_pGesture->chold_area);
1933 HoldDetectorDebugPrint("[GestureHoldDetector] Initialize...\n");
1937 //reset local hold_grab_mask variable
1938 g_pGesture->has_hold_grabmask = 0;
1940 g_pGesture->hold_detector_activate = 0;
1941 HoldDetectorDebugPrint("[GestureHoldDetector] has_hold_grabmask=0 and g_pGesture->hold_detector_activate=0\n");
1946 if (IGNORE_EVENTS == g_pGesture->ehtype ||
1947 device->id < g_pGesture->first_fingerid)
1949 HoldDetectorDebugPrint("[GestureHoldDetector] Return (IGNORE_EVENTS or device->id:%d < first_fingerid:%d)\n", device->id, g_pGesture->first_fingerid);
1953 palm_flag = GestureGetPalmValuator(ev, device);
1957 GestureHandleGesture_Hold(0, 0, 0, PALM_HOLD_TIME_THRESHOLD, GestureBegin);
1958 GestureHandleGesture_Hold(0, 0, 0, PALM_HOLD_TIME_THRESHOLD, GestureEnd);
1960 g_pGesture->hold_detector_activate = 0;
1961 g_pGesture->has_hold_grabmask = 0;
1962 HoldDetectorDebugPrint("[GestureHoldDetector] palm_flag:%d enable\n", palm_flag);
1967 HoldDetectorDebugPrint("[GestureHoldDetector] palm_flag:%d disable\n", palm_flag);
1971 HoldDetectorDebugPrint("[GestureHoldDetector] g_pGesture->num_mt_devices:%d\n", g_pGesture->num_mt_devices);
1973 for (i = 0; i < g_pGesture->num_mt_devices; i++)
1975 if ( device->id == g_pGesture->mt_devices[i]->id)
1978 HoldDetectorDebugPrint("[GestureHoldDetector] idx:%d\n", idx);
1982 if ((idx < 0) || ((MAX_MT_DEVICES-1) < idx)) return;
1986 case ET_ButtonPress:
1987 g_pGesture->cts[idx].status = BTN_PRESSED;
1988 g_pGesture->cts[idx].cx = ev->device_event.root_x;
1989 g_pGesture->cts[idx].cy = ev->device_event.root_y;
1991 HoldDetectorDebugPrint("[GestureHoldDetector][P] cx:%d, cy:%d, num_pressed:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy, num_pressed);
1993 if (num_pressed < 2)
1995 HoldDetectorDebugPrint("[GestureHoldDetector][P] num_pressed:%d\n", num_pressed);
1999 if (num_pressed > g_pGesture->num_mt_devices)
2000 num_pressed = g_pGesture->num_mt_devices;
2002 pixman_region_init(&tarea1);
2003 pixman_region_init(&g_pGesture->chold_area);
2004 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);
2006 tarea1.extents.x1 = g_pGesture->cts[0].cx;
2007 tarea1.extents.x2 = g_pGesture->cts[0].cx+1;
2008 tarea1.extents.y1 = g_pGesture->cts[0].cy;
2009 tarea1.extents.y2 = g_pGesture->cts[0].cy+1;
2011 pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1);
2013 for (i = 1; i < num_pressed; i++)
2015 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);
2017 tarea1.extents.x1 = g_pGesture->cts[i].cx;
2018 tarea1.extents.x2 = g_pGesture->cts[i].cx + 1;
2019 tarea1.extents.y1 = g_pGesture->cts[i].cy;
2020 tarea1.extents.y2 = g_pGesture->cts[i].cy + 1;
2022 pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1);
2027 if (BTN_RELEASED == g_pGesture->cts[idx].status)
2030 g_pGesture->cts[idx].status = BTN_MOVING;
2031 g_pGesture->cts[idx].cx = ev->device_event.root_x;
2032 g_pGesture->cts[idx].cy = ev->device_event.root_y;
2034 HoldDetectorDebugPrint("[GestureHoldDetector][M] cx:%d, cy:%d, num_pressed:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy, num_pressed);
2036 if (num_pressed < 2)
2038 HoldDetectorDebugPrint("[GestureHoldDetector][M] num_pressed:%d\n", num_pressed);
2042 pixman_region_init(&tarea1);
2043 pixman_region_init(&g_pGesture->chold_area);
2044 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);
2046 tarea1.extents.x1 = g_pGesture->cts[0].cx;
2047 tarea1.extents.x2 = g_pGesture->cts[0].cx+1;
2048 tarea1.extents.y1 = g_pGesture->cts[0].cy;
2049 tarea1.extents.y2 = g_pGesture->cts[0].cy+1;
2051 pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1);
2053 for (i = 1; i < num_pressed; i++)
2055 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);
2057 tarea1.extents.x1 = g_pGesture->cts[i].cx;
2058 tarea1.extents.x2 = g_pGesture->cts[i].cx + 1;
2059 tarea1.extents.y1 = g_pGesture->cts[i].cy;
2060 tarea1.extents.y2 = g_pGesture->cts[i].cy + 1;
2062 pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1);
2066 case ET_ButtonRelease:
2067 g_pGesture->cts[idx].status = BTN_RELEASED;
2068 g_pGesture->cts[idx].cx = ev->device_event.root_x;
2069 g_pGesture->cts[idx].cy = ev->device_event.root_y;
2071 HoldDetectorDebugPrint("[GestureHoldDetector][R] cx:%d, cy:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy);
2076 pixman_region_init(&g_pGesture->chold_area);
2081 if (num_pressed >= 2)
2083 hold_area_size = AREA_SIZE(&g_pGesture->chold_area.extents);
2085 HoldDetectorDebugPrint("[GestureHoldDetector] hold_area_size=%d, pPalmMisc->half_scrn_area_size=%d\n", hold_area_size, pPalmMisc->half_scrn_area_size);
2087 if (pPalmMisc->half_scrn_area_size <= hold_area_size)
2089 GestureHandleGesture_Hold(0, AREA_CENTER_X(&g_pGesture->chold_area.extents), AREA_CENTER_Y(&g_pGesture->chold_area.extents), PALM_HOLD_TIME_THRESHOLD, GestureBegin);
2090 GestureHandleGesture_Hold(0, AREA_CENTER_X(&g_pGesture->chold_area.extents), AREA_CENTER_Y(&g_pGesture->chold_area.extents), PALM_HOLD_TIME_THRESHOLD, GestureEnd);
2092 g_pGesture->hold_detector_activate = 0;
2093 g_pGesture->has_hold_grabmask = 0;
2098 hold_area_size = AREA_SIZE(&g_pGesture->chold_area.extents);
2099 HoldDetectorDebugPrint("[GestureHoldDetector] num_pressed is under 2, hold_area_size=%d\n", hold_area_size);
2105 GesturePalmGetScreenInfo()
2108 pixman_region16_t tarea;
2109 PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
2110 ScreenPtr pScreen = miPointerCurrentScreen();
2114 DetailDebugPrint("[X11][GesturePalmGetScreenInfo]Failed to get screen information !\n");
2116 pPalmMisc->scrn_width = pPalmMisc->scrn_height = 0;
2120 pPalmMisc->scrn_width = pScreen->width;
2121 pPalmMisc->scrn_height = pScreen->height;
2122 pixman_region_init(&tarea);
2123 pixman_region_init_rect(&tarea, 0, 0, pPalmMisc->scrn_width, pPalmMisc->scrn_height);
2125 DetailDebugPrint("[X11][GesturePalmGetScreenInfo] x2:%d, x2:%d, y2:%d, y1:%d \n", tarea.extents.x2, tarea.extents.x1, tarea.extents.y2, tarea.extents.y1);
2126 pPalmMisc->half_scrn_area_size = AREA_SIZE(&tarea.extents);
2127 pPalmMisc->half_scrn_area_size = (unsigned int)((double)pPalmMisc->half_scrn_area_size / 4);
2129 DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->half_scrn_area_size = %d\n", pPalmMisc->half_scrn_area_size);
2131 for (i = 0; i < PALM_HORIZ_ARRAY_COUNT; i++)
2133 pPalmMisc->horiz_coord[i] = pPalmMisc->scrn_width * ((i+1)/(double)PALM_HORIZ_ARRAY_COUNT);
2134 DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->horiz_coord[%d]=%d, pPalmMisc->scrn_width=%d\n", i, pPalmMisc->horiz_coord[i], pPalmMisc->scrn_width);
2136 for (i = 0; i < PALM_VERTI_ARRAY_COUNT; i++)
2138 pPalmMisc->verti_coord[i] = pPalmMisc->scrn_height * ((i+1)/(double)PALM_VERTI_ARRAY_COUNT);
2139 DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->verti_coord[%d]=%d, pPalmMisc->scrn_height=%d\n", i, pPalmMisc->verti_coord[i], pPalmMisc->scrn_height);
2147 GestureEnableDisable()
2149 GestureEnable(1, FALSE, g_pGesture->this_device);
2151 if ((g_pGesture->grabMask) || (g_pGesture->lastSelectedWin != None))
2153 GestureEnable(1, FALSE, g_pGesture->this_device);
2157 GestureEnable(0, FALSE, g_pGesture->this_device);
2163 GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent)
2165 g_pGesture->grabMask = *pGrabMask;
2166 g_pGesture->GrabEvents = (GestureGrabEventPtr)pGrabEvent;
2167 GestureEnableDisable();
2171 GestureCbEventsSelected(Window win, Mask *pEventMask)
2173 g_pGesture->lastSelectedWin = win;
2174 g_pGesture->lastSelectedMask = (pEventMask) ? *pEventMask : 0;
2175 GestureEnableDisable();
2179 GestureGetEventsWindow(void)
2184 pWin = GestureWindowOnXY(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py);
2188 DetailDebugPrint("[GestureGetEventsWindow] pWin->drawable.id=0x%x\n", pWin->drawable.id);
2189 g_pGesture->gestureWin = pWin->drawable.id;
2193 DetailDebugPrint("[GestureGetEventsWindow] GestureWindowOnXY returns NULL !\n");
2197 if (g_pGesture->gestureWin == g_pGesture->lastSelectedWin)
2199 g_pGesture->eventMask = g_pGesture->lastSelectedMask;
2200 goto nonempty_eventmask;
2203 //check selected event(s)
2204 if (!GestureHasSelectedEvents(pWin, &g_pGesture->eventMask))
2206 g_pGesture->eventMask = 0;
2210 g_pGesture->lastSelectedWin = g_pGesture->gestureWin;
2211 g_pGesture->lastSelectedMask = g_pGesture->eventMask;
2214 if (!g_pGesture->eventMask && !g_pGesture->grabMask)
2216 DetailDebugPrint("[X11][GestureGetEventsWindow] No grabbed events or no events were selected for window(0x%x) !\n", pWin->drawable.id);
2222 DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->eventMask=0x%x\n", g_pGesture->eventMask);
2224 mask = (GESTURE_FILTER_MASK_ALL & ~(g_pGesture->grabMask | g_pGesture->eventMask));
2226 DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x, mask=0x%x\n", g_pGesture->filter_mask, mask);
2228 g_pGesture->filter_mask = mask;
2230 DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x\n", g_pGesture->filter_mask);
2236 GestureSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2238 g_pGesture->filter_mask |= WTapFilterMask;
2239 g_pGesture->filter_mask |= WHoldFilterMask;
2240 LOGI("[GroupTap][GroupHold] 50ms after 1st finger.\n");
2242 DetailDebugPrint("[GestureSingleFingerTimerHandler] TapFilterMask, HoldFilterMask \n");
2244 if ((g_pGesture->event_sum[0] == BTN_PRESSED) && ((g_pGesture->flick_pressed_point <= FLICK_POINT_NONE) && (FLICK_POINT_MAX <= g_pGesture->flick_pressed_point)))
2246 DetailDebugPrint("[GestureSingleFingerTimerHandler] press_point: %d\n", g_pGesture->flick_pressed_point);
2247 DetailDebugPrint("[GestureSingleFingerTimerHandler] FlickFilterMask\n");
2248 g_pGesture->filter_mask |= WFlickFilterMask;
2251 if (g_pGesture->flick_pressed_point == FLICK_POINT_DOWN && abs(g_pGesture->fingers[0].py - g_pGesture->fingers[0].my) < 3)
2253 DetailDebugPrint("[GestureSingleFingerTimerHandler] py: %d, my: %d\n", g_pGesture->fingers[0].py, g_pGesture->fingers[0].my);
2254 DetailDebugPrint("[GestureSingleFingerTimerHandler] FlickFilterMask\n");
2255 g_pGesture->filter_mask |= WFlickFilterMask;
2258 DetailDebugPrint("[GestureSingleFingerTimerHandler] expired !\n");
2260 if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
2262 if ( ERROR_INVALPTR == GestureFlushOrDrop())
2264 DetailDebugPrint("[GestureSingleFingerTimerHandler] AllFilterMask, Flush!\n");
2265 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2273 GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
2276 static OsTimerPtr single_finger_timer = NULL;
2279 if (PROPAGATE_EVENTS == g_pGesture->ehtype || device->id < g_pGesture->first_fingerid)
2284 for (i = 0; i < g_pGesture->num_mt_devices; i++)
2286 if (device->id == g_pGesture->mt_devices[i]->id)
2298 case ET_ButtonPress:
2301 g_pGesture->event_sum[0] = BTN_PRESSED;
2304 g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
2306 g_pGesture->fingers[idx].ptime = ev->any.time;
2307 g_pGesture->fingers[idx].px = ev->device_event.root_x;
2308 g_pGesture->fingers[idx].py = ev->device_event.root_y;
2310 g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
2311 g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
2312 g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT;
2313 g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT;
2315 g_pGesture->num_pressed++;
2316 g_pGesture->inc_num_pressed = g_pGesture->num_pressed;
2318 if (g_pGesture->inc_num_pressed == 1)
2320 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2324 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2326 for (i = 1; i < g_pGesture->inc_num_pressed; i++)
2328 pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
2332 DetailDebugPrint("[GestureRecognize][P] num_pressed=%d, area_size=%d, px=%d, py=%d\n",
2333 g_pGesture->num_pressed, AREA_SIZE(&g_pGesture->area.extents), g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
2335 if (g_pGesture->num_pressed == 1)
2337 single_finger_timer = TimerSet(single_finger_timer, 0, 50, GestureSingleFingerTimerHandler, NULL);
2339 if (g_pGesture->fingers[idx].py <= g_pGesture->flick_press_area)
2341 if ((!g_pGesture->activate_flick_down)
2342 || (g_pGesture->fingers[idx].px <= (g_pGesture->flick_press_area_left_right))
2343 || (g_pGesture->fingers[idx].px >= (g_pGesture->screen_width - g_pGesture->flick_press_area_left_right)))
2345 DetailDebugPrint("[GestureRecognize][P] px=%d, flick_press_area_left_right=%d\n",
2346 g_pGesture->fingers[idx].px, g_pGesture->flick_press_area_left_right);
2347 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2348 LOGI("[BackKey][F] Press touch within 40 pixel area from left or right vezel\n");
2352 DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_UP\n");
2353 g_pGesture->flick_pressed_point = FLICK_POINT_UP;
2358 LOGI("[BackKey][F] Press touch outside 40 pixel area from upper vezel. \n");
2361 if (g_pGesture->fingers[idx].py >= (g_pGesture->screen_height - g_pGesture->flick_press_area))
2363 if (!g_pGesture->activate_flick_up)
2365 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2369 DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_DOWN\n");
2370 g_pGesture->flick_pressed_point = FLICK_POINT_DOWN;
2373 else if ( g_pGesture->fingers[idx].px <= g_pGesture->flick_press_area_left)
2375 if (!g_pGesture->activate_flick_right)
2377 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2381 DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_LEFT\n");
2382 g_pGesture->flick_pressed_point = FLICK_POINT_LEFT;
2386 DetailDebugPrint("[GestureRecognize][P] flick_press_point: %d\n", g_pGesture->flick_pressed_point);
2388 if ((g_pGesture->flick_pressed_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= g_pGesture->flick_pressed_point))
2390 DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_NONE\n");
2391 g_pGesture->filter_mask |= WFlickFilterMask;
2392 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2396 g_pGesture->flick_direction = (g_pGesture->flick_pressed_point - 1) * 2;
2397 if ((g_pGesture->flick_direction == FLICK_WESTWARD) && (g_pGesture->power_pressed != 2))
2399 DetailDebugPrint("[GestureRecognize][P] Flick WesWard is disable when power is not pressed\n");
2400 g_pGesture->filter_mask |= WFlickFilterMask;
2401 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2403 if ((g_pGesture->flick_direction < FLICK_NORTHWARD) || (FLICK_NORTHWESTWARD < g_pGesture->flick_direction))
2405 DetailDebugPrint("[GestureRecognize][P] Invalid flick direction\n");
2406 g_pGesture->filter_mask |= WFlickFilterMask;
2407 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2410 DetailDebugPrint("[GestureRecognize][P] flick_direction: %d\n", g_pGesture->flick_direction);
2415 DetailDebugPrint("[GestureRecognize][P] Two more fingers come on!\n");
2416 TimerCancel(single_finger_timer);
2417 single_finger_timer = NULL;
2423 if (!g_pGesture->fingers[idx].ptime)
2425 DetailDebugPrint("[GestureRecognize][M] Start motion. idx=%d\n", idx);
2426 g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
2430 g_pGesture->fingers[idx].mx = ev->device_event.root_x;
2431 g_pGesture->fingers[idx].my = ev->device_event.root_y;
2432 g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
2436 g_pGesture->event_sum[0] += BTN_MOVING;
2439 g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
2440 g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
2441 g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT;
2442 g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT;
2444 if (g_pGesture->inc_num_pressed == 1)
2446 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2450 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2452 for (i = 1; i < g_pGesture->inc_num_pressed; i++)
2454 pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
2458 DetailDebugPrint("[GestureRecognize][M] num_pressed=%d, area_size=%d, mx=%d, my=%d\n",
2459 g_pGesture->num_pressed, AREA_SIZE(&g_pGesture->area.extents), g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].my);
2463 case ET_ButtonRelease:
2464 g_pGesture->fingers[idx].rtime = ev->any.time;
2465 g_pGesture->fingers[idx].rx = ev->device_event.root_x;
2466 g_pGesture->fingers[idx].ry = ev->device_event.root_y;
2467 g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
2469 g_pGesture->num_pressed--;
2471 if (g_pGesture->num_pressed == 0)
2473 DetailDebugPrint("[GestureRecognize] All fingers were released !\n");
2475 else if (g_pGesture->num_pressed < 0)
2477 DetailDebugPrint("[GestureRecognize] All fingers were released. But, num_pressed is under 0 !\n");
2480 DetailDebugPrint("[GestureRecognize][R] num_pressed=%d, rx=%d, ry=%d\n",
2481 g_pGesture->num_pressed, g_pGesture->fingers[idx].rx, g_pGesture->fingers[idx].ry);
2486 if (!(g_pGesture->filter_mask & WFlickFilterMask))
2488 DetailDebugPrint("[GestureRecognize] GestureRecognize_groupFlick !\n");
2489 GestureRecognize_GroupFlick(type, ev, device, idx, g_pGesture->flick_pressed_point, g_pGesture->flick_direction);
2491 if (!(g_pGesture->filter_mask & WTapFilterMask))
2493 DetailDebugPrint("[GestureRecognize] GestureRecognize_groupTap !\n");
2494 GestureRecognize_GroupTap(type, ev, device, idx, 0);
2496 if (!(g_pGesture->filter_mask & WHoldFilterMask))
2498 DetailDebugPrint("[GestureRecognize] GestureRecognize_groupHold !\n");
2499 GestureRecognize_GroupHold(type, ev, device, idx, 0);
2502 if (!(g_pGesture->filter_mask & WPalmFlickFilterMask))
2504 DetailDebugPrint("[GestureRecognize] GestureRecognize_palmFlick !\n");
2505 GestureRecognize_PalmFlick(type, ev, device, idx);
2508 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",
2509 g_pGesture->filter_mask, GESTURE_WATCH_FILTER_MASK_ALL, g_pGesture->recognized_gesture);
2511 if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
2513 if (!g_pGesture->recognized_gesture)
2515 DetailDebugPrint("[GestureRecognize][F] 1 !\n");
2518 else if (!g_pGesture->num_pressed)
2520 DetailDebugPrint("[GestureRecognize][F] 2 !\n");
2525 if (g_pGesture->recognized_gesture)
2527 if (g_pGesture->ehtype == KEEP_EVENTS)
2529 DetailDebugPrint("[GestureRecognize] Keep Event !\n");
2530 GestureEventsDrop();
2532 g_pGesture->ehtype = IGNORE_EVENTS;
2538 DetailDebugPrint("[GestureRecognize] GestureFlushOrDrop() !\n");
2540 if (ERROR_INVALPTR == GestureFlushOrDrop())
2542 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2546 ErrorStatus GestureFlushOrDrop(void)
2550 if (g_pGesture->recognized_gesture)
2552 g_pGesture->ehtype = IGNORE_EVENTS;
2553 GestureEventsDrop();
2554 DetailDebugPrint("[GestureFlushOrDrop][Drop] IGNORE_EVENTS\n");
2558 g_pGesture->ehtype = PROPAGATE_EVENTS;
2560 err = GestureEventsFlush();
2562 if (ERROR_NONE != err)
2567 DetailDebugPrint("[GestureFlushOrDrop][Flush] PROPAGATE_EVENTS\n");
2568 DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask);
2569 DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->GESTURE_WATCH_FILTER_MASK_ALL = 0x%x\n", GESTURE_WATCH_FILTER_MASK_ALL);
2570 DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture);
2573 err = GestureRegionsReinit();
2575 if (ERROR_NONE != err)
2580 g_pGesture->pTempWin = NULL;
2581 g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0;
2582 g_pGesture->event_sum[0] = 0;
2588 GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2593 #ifdef __DEBUG_EVENT_HANDLER__
2594 DetailDebugPrint("[GestureHandleMTSyncEvent] (%d:%d) time:%d cur:%d\n",
2595 ev->any_event.deviceid, ev->any_event.sync, (int)ev->any.time, (int)GetTimeInMillis());
2598 if (!g_pGesture->is_active)
2600 g_pGesture->ehtype = PROPAGATE_EVENTS;
2601 DetailDebugPrint("[GestureHandleMTSyncEvent] PROPAGATE_EVENT\n");
2605 if (MTOUCH_FRAME_SYNC_BEGIN == ev->any_event.sync)
2607 DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_BEGIN\n");
2608 g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_BEGIN;
2609 g_pGesture->ehtype = KEEP_EVENTS;
2610 g_pGesture->filter_mask = 0;
2611 g_pGesture->recognized_gesture = 0;
2612 g_pGesture->hold_detector_activate = 1;
2613 g_pGesture->num_pressed = 0;
2614 g_pGesture->has_hold_grabmask = 0;
2615 g_pGesture->mtsync_total_count = 0;
2617 for (i=0; i < g_pGesture->num_mt_devices; i++)
2619 g_pGesture->fingers[i].ptime = 0;
2620 g_pGesture->max_mt_tmajor[i] = 0;
2623 else if (MTOUCH_FRAME_SYNC_END == ev->any_event.sync)
2625 DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_END\n");
2626 g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_END;
2627 g_pGesture->ehtype = PROPAGATE_EVENTS;
2628 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2629 g_pGesture->pTempWin = NULL;
2630 g_pGesture->num_pressed = 0;
2631 g_pGesture->hold_detected = FALSE;
2633 else if (MTOUCH_FRAME_SYNC_UPDATE == ev->any_event.sync)
2635 g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_UPDATE;
2636 g_pGesture->mtsync_total_count++;
2638 DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_Update. mt_total_sync=%d\n", g_pGesture->mtsync_total_count);
2640 if ((g_pGesture->inc_num_pressed < 2) && (g_pGesture->filter_mask != GESTURE_WATCH_FILTER_MASK_ALL))
2642 if (g_pGesture->num_tap_repeated == 1 || g_pGesture->num_tap_repeated == 2)
2644 if (g_pGesture->mtsync_total_count >= 6)
2646 DetailDebugPrint("[GestureHandleMTSyncEvent] Moving Limit first tap repeated. tap_repeated: %d, mtsync_total_count: %d\n",
2647 g_pGesture->num_tap_repeated, g_pGesture->mtsync_total_count);
2648 g_pGesture->filter_mask |= WTapFilterMask;
2649 g_pGesture->filter_mask |= WHoldFilterMask;
2650 LOGI("[GroupTap][GroupHold] Motions are more than 6 between 1st finger and 2nd finger.\n");
2654 if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
2656 DetailDebugPrint("[GestureHandleMTSyncEvent] Gesture filter mask all. GestureFlushOrDrop() !\n");
2658 if (ERROR_INVALPTR == GestureFlushOrDrop())
2660 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2668 void GestureEmulateHWKey(DeviceIntPtr dev, int keycode)
2672 DetailDebugPrint("[GestureEmulateHWKey] keycode=%d\n", keycode);
2673 xf86PostKeyboardEvent(dev, keycode, 1);
2674 xf86PostKeyboardEvent(dev, keycode, 0);
2679 GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2681 #ifdef __DEBUG_EVENT_HANDLER__
2682 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);
2683 #endif//__DEBUG_EVENT_HANDLER__
2685 switch (g_pGesture->ehtype)
2688 DetailDebugPrint("[GestureHandleButtonPressEvent] KEEP_EVENT\n");
2690 if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device))
2692 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2696 if (g_pGesture->num_mt_devices)
2698 GestureRecognize(ET_ButtonPress, ev, device);
2702 device->public.processInputProc(ev, device);
2705 GestureHoldDetector(ET_ButtonPress, ev, device);
2708 case PROPAGATE_EVENTS:
2709 DetailDebugPrint("[GestureHandleButtonPressEvent] PROPAGATE_EVENT\n");
2711 device->public.processInputProc(ev, device);
2712 GestureHoldDetector(ET_ButtonPress, ev, device);
2716 DetailDebugPrint("[GestureHandleButtonPressEvent] IGNORE_EVENTS\n");
2718 GestureRecognize(ET_ButtonPress, ev, device);
2727 GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2729 #ifdef __DEBUG_EVENT_MOTION_HANDLER__
2730 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);
2733 switch (g_pGesture->ehtype)
2736 if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device))
2738 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2742 if (g_pGesture->num_mt_devices)
2744 GestureRecognize(ET_Motion, ev, device);
2748 device->public.processInputProc(ev, device);
2751 GestureHoldDetector(ET_Motion, ev, device);
2754 case PROPAGATE_EVENTS:
2755 device->public.processInputProc(ev, device);
2756 GestureHoldDetector(ET_Motion, ev, device);
2760 GestureRecognize(ET_Motion, ev, device);
2770 GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2772 #ifdef __DEBUG_EVENT_HANDLER__
2773 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);
2776 switch (g_pGesture->ehtype)
2779 DetailDebugPrint("[GestureHandleButtonPressEvent] KEEP_EVENT\n");
2781 if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device))
2783 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2787 if (g_pGesture->num_mt_devices)
2789 GestureRecognize(ET_ButtonRelease, ev, device);
2793 device->public.processInputProc(ev, device);
2796 GestureHoldDetector(ET_ButtonRelease, ev, device);
2799 case PROPAGATE_EVENTS:
2800 DetailDebugPrint("[GestureHandleButtonPressEvent] PROPAGATE_EVENTS\n");
2801 #ifdef SUPPORT_ANR_WITH_INPUT_EVENT
2802 if( IsMaster(device) && ev->any.type == ET_ButtonRelease )
2804 if( g_pGesture->anr_window == NULL )
2806 g_pGesture->anr_window = _GestureFindANRWindow(device);
2810 // Send event to the e17 process.
2811 current_time = GetTimeInMillis();
2812 if( g_pGesture->anr_window != NULL )
2814 // Check anr_window validation.
2815 if( dixLookupWindow(&g_pGesture->anr_window, prop_anr_event_window_xid, serverClient, DixSetPropAccess) != BadWindow )
2817 if( serverClient->devPrivates != NULL )
2818 dixChangeWindowProperty (serverClient, g_pGesture->anr_window, prop_anr_in_input_event,
2819 XA_CARDINAL, 32, PropModeReplace, 1, ¤t_time, TRUE);
2823 prop_anr_event_window_xid = 0;
2824 g_pGesture->anr_window = NULL;
2826 DetailDebugPrint("Release TOUCH!! devid=%d time:%d cur: %d\n", device->id, ev->any.time, GetTimeInMillis());
2830 device->public.processInputProc(ev, device);
2831 GestureHoldDetector(ET_ButtonRelease, ev, device);
2833 GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down);
2834 GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up);
2839 DetailDebugPrint("[GestureHandleButtonPressEvent] IGNORE_EVENTS\n");
2840 GestureRecognize(ET_ButtonRelease, ev, device);
2849 GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2851 if ((ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0))
2853 g_pGesture->power_pressed = 2;
2854 g_pGesture->power_device = device;
2856 DetailDebugPrint("[GestureHandleKeyPressEvent] power key pressed devid: %d, hwkey_id: %d\n", device->id, g_pGesture->hwkey_id);
2857 DetailDebugPrint("[GestureHandleKeyPressEvent] power_pressed: %d\n", g_pGesture->power_pressed);
2859 device->public.processInputProc(ev, device);
2863 GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2865 if ((ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0))
2867 g_pGesture->power_pressed = 1;
2868 g_pGesture->power_device = device;
2870 DetailDebugPrint("[GestureHandleKeyReleaseEvent] power key released devid: %d, hwkey_id: %d\n", device->id, g_pGesture->hwkey_id);
2871 DetailDebugPrint("[GestureHandleKeyReleaseEvent] power_pressed: %d\n", g_pGesture->power_pressed);
2873 device->public.processInputProc(ev, device);
2877 GestureHandleClientState (CallbackListPtr *list, pointer closure, pointer calldata)
2879 NewClientInfoRec *clientinfo = (NewClientInfoRec*)calldata;
2880 ClientPtr client = clientinfo->client;
2882 if (client->clientState != ClientStateGone)
2887 if (!g_pGesture->factory_cmdname)
2892 if (strncmp(client->clientIds->cmdname, g_pGesture->factory_cmdname, strlen(g_pGesture->factory_cmdname)))
2897 if (g_pGesture->is_active == 0)
2900 int rc = XIChangeDeviceProperty(g_pGesture->this_device, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &prop_val, FALSE);
2902 ErrorF("[GestureHandleClientState] %s is exited unintentionally\n", g_pGesture->factory_cmdname);
2906 ErrorF("[GestureHandleClientState] Failed to Gesture Enable\n");
2913 GestureEnableEventHandler(InputInfoPtr pInfo)
2916 GestureDevicePtr pGesture = pInfo->private;
2918 res = GestureInstallResourceStateHooks();
2922 ErrorF("[GestureEnableEventHandler] Failed on GestureInstallResourceStateHooks() !\n");
2923 return ERROR_ABNORMAL;
2926 res = GestureSetMaxNumberOfFingers((int)MAX_MT_DEVICES);
2930 ErrorF("[GestureEnableEventHandler] Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)MAX_MT_DEVICES);
2934 res = GestureRegisterCallbacks(GestureCbEventsGrabbed, GestureCbEventsSelected);
2938 ErrorF("[GestureEnableEventHandler] Failed to register callbacks for GestureEventsGrabbed(), GestureEventsSelected() !\n");
2942 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 5000, GestureTimerHandler, pInfo);
2944 if (!pGesture->device_setting_timer)
2946 ErrorF("[GestureEnableEventHandler] Failed to set time for detecting devices !\n");
2953 GestureUninstallResourceStateHooks();
2954 GestureUnsetMaxNumberOfFingers();
2956 return ERROR_ABNORMAL;
2960 GestureDisableEventHandler(void)
2962 ErrorStatus err = ERROR_NONE;
2964 mieqSetHandler(ET_ButtonPress, NULL);
2965 mieqSetHandler(ET_ButtonRelease, NULL);
2966 mieqSetHandler(ET_Motion, NULL);
2967 mieqSetHandler(ET_KeyPress, NULL);
2968 mieqSetHandler(ET_KeyRelease, NULL);
2969 mieqSetHandler(ET_MTSync, NULL);
2971 err = GestureFiniEQ();
2973 if (ERROR_INVALPTR == err)
2975 ErrorF("[GestureDisableEventHandler] EQ is invalid or was freed already !\n");
2978 GestureRegisterCallbacks(NULL, NULL);
2979 GestureUninstallResourceStateHooks();
2985 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2987 InputInfoPtr pInfo = (InputInfoPtr)arg;
2988 GestureDevicePtr pGesture;
2994 ErrorF("[GestureTimerHandler][%s] pInfo is NULL !\n");
2998 pGesture = pInfo->private;
3001 for (dev = inputInfo.pointer; dev; dev = dev->next)
3003 if (IsMaster(dev) && IsPointerDevice(dev))
3005 pGesture->master_pointer = dev;
3006 ErrorF("[GestureTimerHandler][id:%d] Master Pointer=%s\n", dev->id, pGesture->master_pointer->name);
3010 if (IsXTestDevice(dev, NULL) && IsPointerDevice(dev))
3012 pGesture->xtest_pointer = dev;
3013 ErrorF("[GestureTimerHandler][id:%d] XTest Pointer=%s\n", dev->id, pGesture->xtest_pointer->name);
3017 if (IsPointerDevice(dev))
3019 if (idx >= MAX_MT_DEVICES)
3021 ErrorF("[GestureTimerHandler] Number of mt device is over MAX_MT_DEVICES(%d) !\n", MAX_MT_DEVICES);
3024 pGesture->mt_devices[idx] = dev;
3025 ErrorF("[GestureTimerHandler][id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name);
3026 GesturePalmGetAbsAxisInfo(dev);
3031 for (dev = inputInfo.keyboard ; dev; dev = dev->next)
3033 if (g_pGesture->hwkey_name && !strncmp(dev->name, g_pGesture->hwkey_name, strlen(dev->name)))
3035 g_pGesture->hwkey_id = dev->id;
3036 g_pGesture->hwkey_dev = dev;
3038 ErrorF("[GestureTimerHandler] hwkey_name has been found. hwkey_id=%d (hwkey_dev->name:%s)\n", g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
3041 else if (!strcasestr(dev->name, "keyboard") && strcasestr(dev->name, "key") && !IsXTestDevice(dev, NULL) && !IsMaster(dev))
3043 g_pGesture->hwkey_id = dev->id;
3044 g_pGesture->hwkey_dev = dev;
3046 ErrorF("[GestureTimerHandler] hwkey has been found. hwkey_id=%d (hwkey_dev->name:%s)\n", g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
3051 if (!g_pGesture->hwkey_id)
3053 g_pGesture->hwkey_id = inputInfo.keyboard->id;
3054 g_pGesture->hwkey_dev = inputInfo.keyboard;
3056 ErrorF("[GestureTimerHandler] No hwkey has been found. Back key will go through VCK. hwkey_id=%d (hwkey_dev->name:%s)\n",
3057 g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
3060 if (!pGesture->master_pointer || !pGesture->xtest_pointer)
3062 ErrorF("[GestureTimerHandler] Failed to get info of master pointer or XTest pointer !\n");
3063 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
3064 pGesture->num_mt_devices = 0;
3069 TimerCancel(pGesture->device_setting_timer);
3070 pGesture->device_setting_timer = NULL;
3071 pGesture->num_mt_devices = idx;
3073 if (!pGesture->num_mt_devices)
3075 ErrorF("[GestureTimerHandler] Failed to mt device information !\n");
3076 TimerCancel(pGesture->device_setting_timer);
3077 pGesture->device_setting_timer = NULL;
3078 pGesture->num_mt_devices = 0;
3079 pGesture->first_fingerid = -1;
3083 pGesture->first_fingerid = pGesture->mt_devices[0]->id;
3084 memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices);
3085 pGesture->pRootWin = RootWindow(pGesture->master_pointer);
3087 if (g_pGesture->palm_misc.enabled)
3089 GesturePalmGetScreenInfo();
3092 g_pGesture->pTempWin = NULL;
3093 g_pGesture->inc_num_pressed = 0;
3095 if (ERROR_NONE != GestureRegionsInit() || ERROR_NONE != GestureInitEQ())
3100 mieqSetHandler(ET_ButtonPress, GestureHandleButtonPressEvent);
3101 mieqSetHandler(ET_ButtonRelease, GestureHandleButtonReleaseEvent);
3102 mieqSetHandler(ET_Motion, GestureHandleMotionEvent);
3103 mieqSetHandler(ET_KeyPress, GestureHandleKeyPressEvent);
3104 mieqSetHandler(ET_KeyRelease, GestureHandleKeyReleaseEvent);
3106 //if ( pGesture->is_active)
3107 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
3112 GestureUninstallResourceStateHooks();
3113 GestureUnsetMaxNumberOfFingers();
3119 IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
3128 return (dev->xtest_master_id == master->id);
3131 return (dev->xtest_master_id != 0);
3135 GestureEnable(int enable, Bool prop, DeviceIntPtr dev)
3137 if ((!enable) && (g_pGesture->is_active))
3139 g_pGesture->ehtype = PROPAGATE_EVENTS;
3140 mieqSetHandler(ET_MTSync, NULL);
3141 g_pGesture->is_active = 0;
3142 ErrorF("[GestureEnable] Disabled !\n");
3143 int res = AddCallback (&ClientStateCallback, GestureHandleClientState, NULL);
3147 ErrorF("[GestureEnable] Failed to add callback for client state\n");
3152 else if ((enable) && (!g_pGesture->is_active))
3154 g_pGesture->ehtype = KEEP_EVENTS;
3155 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
3156 g_pGesture->is_active = 1;
3157 ErrorF("[GestureEnable] Enabled !\n");
3159 DeleteCallback (&ClientStateCallback, GestureHandleClientState, NULL);
3164 XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
3169 GestureRegionsInit(void)
3175 return ERROR_INVALPTR;
3178 pixman_region_init(&g_pGesture->area);
3180 for (i = 0; i < MAX_MT_DEVICES; i++)
3182 pixman_region_init_rect(&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
3189 GestureRegionsReinit(void)
3193 ErrorF("[GestureRegionsReinit] Invalid pointer access !\n");
3194 return ERROR_INVALPTR;
3197 pixman_region_init(&g_pGesture->area);
3208 tmpEQ = (IEventRec *)calloc(GESTURE_EQ_SIZE, sizeof(IEventRec));
3212 ErrorF("[GestureInitEQ] Failed to allocate memory for EQ !\n");
3213 return ERROR_ALLOCFAIL;
3216 for (i = 0; i < GESTURE_EQ_SIZE; i++)
3218 tmpEQ[i].event = (InternalEvent *)malloc(sizeof(InternalEvent));
3219 if (!tmpEQ[i].event)
3221 ErrorF("[GestureInitEQ] Failed to allocation memory for each event buffer in EQ !\n");
3223 while(i >= 0 && tmpEQ[i].event)
3225 free(tmpEQ[i].event);
3226 tmpEQ[i].event = NULL;
3230 return ERROR_ALLOCFAIL;
3234 g_pGesture->EQ = tmpEQ;
3235 g_pGesture->headEQ = g_pGesture->tailEQ = 0;
3245 if (!g_pGesture || !g_pGesture->EQ)
3247 return ERROR_INVALPTR;
3250 for (i = 0; i < GESTURE_EQ_SIZE; i++)
3252 if (g_pGesture->EQ[i].event)
3254 free(g_pGesture->EQ[i].event);
3255 g_pGesture->EQ[i].event = NULL;
3259 free(g_pGesture->EQ);
3260 g_pGesture->EQ = NULL;
3266 GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
3270 if (!g_pGesture || !g_pGesture->EQ)
3272 ErrorF("[GestureEnqueueEvent] Invalid pointer access !\n");
3273 return ERROR_INVALPTR;
3276 tail = g_pGesture->tailEQ;
3278 if (tail >= GESTURE_EQ_SIZE)
3280 ErrorF("[GestureEnqueueEvent] Gesture EQ is full !\n");
3281 printk("[GestureEnqueueEvent] Gesture EQ is full...Force Gesture Flush !\n");
3282 GestureEventsFlush();
3283 return ERROR_EQFULL;
3286 switch (ev->any.type)
3288 case ET_ButtonPress:
3289 DetailDebugPrint("[GestureEnqueueEvent] ET_ButtonPress (id:%d)\n", device->id);
3292 case ET_ButtonRelease:
3293 DetailDebugPrint("[GestureEnqueueEvent] ET_ButtonRelease (id:%d)\n", device->id);
3297 DetailDebugPrint("[GestureEnqueueEvent] ET_Motion (id:%d)\n", device->id);
3301 g_pGesture->EQ[tail].device = device;
3302 g_pGesture->EQ[tail].screen_num = screen_num;
3303 memcpy(g_pGesture->EQ[tail].event, ev, sizeof(InternalEvent));//need to be optimized
3304 g_pGesture->tailEQ++;
3310 GestureEventsFlush(void)
3313 DeviceIntPtr device;
3315 if (!g_pGesture->EQ)
3317 ErrorF("[GestureEventsFlush] Invalid pointer access !\n");
3318 return ERROR_INVALPTR;
3321 DetailDebugPrint("[GestureEventsFlush]\n");
3323 for (i = g_pGesture->headEQ; i < g_pGesture->tailEQ; i++)
3325 device = g_pGesture->EQ[i].device;
3326 device->public.processInputProc(g_pGesture->EQ[i].event, device);
3329 for (i = 0; i < MAX_MT_DEVICES; i++)
3331 g_pGesture->event_sum[i] = 0;
3334 g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
3340 GestureEventsDrop(void)
3342 DetailDebugPrint("[GestureEventsDrop]\n");
3343 g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
3346 #ifdef HAVE_PROPERTIES
3348 GestureInitProperty(DeviceIntPtr dev)
3352 #ifdef SUPPORT_ANR_WITH_INPUT_EVENT
3353 prop_anr_in_input_event = MakeAtom(CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT, strlen(CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT), TRUE);
3354 prop_anr_event_window = MakeAtom(ANR_EVENT_WINDOW, strlen(ANR_EVENT_WINDOW), TRUE);
3357 prop_gesture_recognizer_onoff = MakeAtom(GESTURE_RECOGNIZER_ONOFF, strlen(GESTURE_RECOGNIZER_ONOFF), TRUE);
3358 rc = XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
3365 XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE);
3369 GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
3372 if (prop_gesture_recognizer_onoff == atom)
3375 if (val->format != 32 || val->type != XA_INTEGER || val->size != 1)
3380 data = *((int *)val->data);
3381 GestureEnable(data, TRUE, dev);
3386 #endif//HAVE_PROPERTIES
3389 GestureInit(DeviceIntPtr device)
3391 #ifdef HAVE_PROPERTIES
3392 GestureInitProperty(device);
3393 XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL);
3395 //GestureEnable(1, FALSE, g_pGesture->this_device);
3400 GestureFini(DeviceIntPtr device)
3402 XIRegisterPropertyHandler(device, NULL, NULL, NULL);
3406 GesturePlug(pointer module, pointer options, int *errmaj, int *errmin)
3408 xf86AddInputDriver(&GESTURE, module, 0);
3413 GestureUnplug(pointer p)
3418 GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
3421 GestureDevicePtr pGesture;
3423 pGesture = calloc(1, sizeof(GestureDeviceRec));
3427 pInfo->private = NULL;
3428 //xf86DeleteInput(pInfo, 0);
3432 g_pGesture = pGesture;
3434 pInfo->private = pGesture;
3436 pInfo->read_input = GestureReadInput; /* new data avl */
3437 pInfo->switch_mode = NULL; /* toggle absolute/relative mode */
3438 pInfo->device_control = GestureControl; /* enable/disable dev */
3440 /* process driver specific options */
3441 pGesture->device = xf86SetStrOption(pInfo->options, "Device", "/dev/null");
3442 pGesture->is_active = xf86SetIntOption(pInfo->options, "Activate", 0);
3443 pGesture->gestureWin = None;
3444 pGesture->lastSelectedWin = None;
3445 pGesture->power_pressed = 1;
3446 pGesture->hwkey_id = 0;
3447 pGesture->hwkey_dev = NULL;
3448 pGesture->num_tap_repeated = 0;
3449 pGesture->mtsync_total_count = 0;
3450 pGesture->hwkey_name = xf86SetStrOption(pInfo->options, "BackHWKeyName", NULL);
3451 pGesture->screen_width = xf86SetIntOption(pInfo->options,"ScreenWidth", 0);
3452 pGesture->screen_height = xf86SetIntOption(pInfo->options,"ScreenHeight", 0);
3453 pGesture->hwkeycode_flick_down = xf86SetIntOption(pInfo->options, "FlickDownKeycode", 0);
3454 pGesture->hwkeycode_flick_up = xf86SetIntOption(pInfo->options, "FlickUpKeycode", 0);
3455 pGesture->flick_press_area = xf86SetIntOption(pInfo->options, "FlickPressArea", 0);
3456 pGesture->flick_press_area_left = xf86SetIntOption(pInfo->options, "FlickPressArea_LEFT", 0);
3457 pGesture->flick_press_area_left_right = xf86SetIntOption(pInfo->options, "FlickPressArea_LEFT_RIGHT", 0);
3458 pGesture->flick_minimum_height = xf86SetIntOption(pInfo->options, "FlickMinimumHeight", 0);
3459 pGesture->shutdown_keycode = xf86SetIntOption(pInfo->options, "ShutdownKeycode", 0);
3460 pGesture->singletap_threshold= xf86SetIntOption(pInfo->options, "SingleTapThresHold", 0);
3461 pGesture->doubletap_threshold= xf86SetIntOption(pInfo->options, "DoubleTapThresHold", 0);
3462 pGesture->tripletap_threshold= xf86SetIntOption(pInfo->options, "TripleTapThresHold", 0);
3463 pGesture->hold_area_threshold = xf86SetRealOption(pInfo->options, "HoldAreaThresHold", 0);
3464 pGesture->hold_move_threshold = xf86SetIntOption(pInfo->options, "HoldMoveThresHold", 0);
3465 pGesture->hold_time_threshold = xf86SetIntOption(pInfo->options, "HoldTimeThresHold", 0);
3466 pGesture->palm_flick_time_threshold = xf86SetIntOption(pInfo->options, "PalmFlickTimeThresHold", 0);
3467 pGesture->palm_flick_max_tmajor_threshold = xf86SetIntOption(pInfo->options, "PalmFlickMaxTouchMajorThresHold", 0);
3468 pGesture->palm_flick_min_tmajor_threshold = xf86SetIntOption(pInfo->options, "PalmFlickMinTouchMajorThresHold", 0);
3469 pGesture->activate_flick_down = xf86SetIntOption(pInfo->options, "ActivateFlickDown", 0);
3470 pGesture->activate_flick_up = xf86SetIntOption(pInfo->options, "ActivateFlickUp", 0);
3471 pGesture->activate_flick_right = xf86SetIntOption(pInfo->options, "ActivateFlickRight", 0);
3472 pGesture->factory_cmdname = xf86SetStrOption(pInfo->options, "FactoryCmdName", NULL);
3474 ErrorF("[X11][%s] ###############################################################\n", __FUNCTION__);
3475 ErrorF("[X11][%s] screen_width=%d, screen_height=%d\n", __FUNCTION__,
3476 pGesture->screen_width, pGesture->screen_height);
3477 ErrorF("[X11][%s] FlickDownKeycode=%d, FlickUpKeycode=%d\n", __FUNCTION__,
3478 pGesture->hwkeycode_flick_down, pGesture->hwkeycode_flick_up);
3479 ErrorF("[X11][%s] flick_press_area=%d, flick_press_area_left: %d, flick_press_area_left_right: %d, flick_minimum_height=%d\n", __FUNCTION__,
3480 pGesture->flick_press_area, pGesture->flick_press_area_left, pGesture->flick_press_area_left_right, pGesture->flick_minimum_height);
3481 ErrorF("[X11][%s] ShutdownKeycode=%d\n", __FUNCTION__, pGesture->shutdown_keycode);
3482 ErrorF("[X11][%s] singletap_threshold=%d, doubletap_threshold=%d\n", __FUNCTION__, pGesture->singletap_threshold, pGesture->doubletap_threshold);
3483 ErrorF("[X11][%s] hold_area_threshold: %f, hold_move_threshold: %d, hold_time_threshold: %d\n", __FUNCTION__,
3484 pGesture->hold_area_threshold, pGesture->hold_move_threshold, pGesture->hold_time_threshold);
3485 ErrorF("[X11][%s] palm_flick_time_threshold: %d, palm_flick_max_tmajor_threshold: %d, palm_flick_min_tmajor_threshold: %d\n", __FUNCTION__,
3486 pGesture->palm_flick_time_threshold, pGesture->palm_flick_max_tmajor_threshold, pGesture->palm_flick_min_tmajor_threshold);
3487 ErrorF("[X11][%s] activate_flick_down=%d, activate_flick_up=%d, activate_flick_right=%d\n", __FUNCTION__,
3488 pGesture->activate_flick_down, pGesture->activate_flick_up, pGesture->activate_flick_right);
3489 ErrorF("[X11][%s] factory cmd name: %s\n", __FUNCTION__, pGesture->factory_cmdname);
3490 ErrorF("[X11][%s] ###############################################################\n", __FUNCTION__);
3492 if (pGesture->hwkey_name)
3494 ErrorF("[X11][%s] hwkey_name=%s\n", __FUNCTION__, pGesture->hwkey_name);
3497 pGesture->mtsync_status = MTOUCH_FRAME_SYNC_END;
3498 g_pGesture->grabMask = g_pGesture->eventMask = 0;
3500 xf86Msg(X_INFO, "%s: Using device %s.\n", pInfo->name, pGesture->device);
3502 /* process generic options */
3503 xf86CollectInputOptions(pInfo, NULL);
3504 xf86ProcessCommonOptions(pInfo, pInfo->options);
3517 GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
3519 GestureDevicePtr pGesture = pInfo->private;
3521 g_pGesture = pGesture = NULL;
3522 pInfo->private = NULL;
3524 xf86DeleteInput(pInfo, 0);
3528 GestureControl(DeviceIntPtr device, int what)
3530 InputInfoPtr pInfo = device->public.devicePrivate;
3531 GestureDevicePtr pGesture = pInfo->private;
3536 GestureInit(device);
3539 /* Switch device on. Establish socket, start event delivery. */
3541 xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
3543 if (device->public.on)
3546 device->public.on = TRUE;
3547 pGesture->this_device = device;
3548 pGesture->num_mt_devices = 0;
3549 if (ERROR_ABNORMAL == GestureEnableEventHandler(pInfo))
3555 GestureDisableEventHandler();
3556 GestureFini(device);
3557 pGesture->this_device = NULL;
3558 xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
3560 if (!device->public.on)
3564 device->public.on = FALSE;
3568 /* free what we have to free */
3575 GestureReadInput(InputInfoPtr pInfo)