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__
65 //#define __DEBUG_EVENT_MOTION_HANDLER__
67 #ifdef __PalmFlick_DEBUG__
68 #define PalmFlickDebugPrint ErrorF
70 #define PalmFlickDebugPrint(...)
73 #ifdef __HOLD_DETECTOR_DEBUG__
74 #define HoldDetectorDebugPrint ErrorF
76 #define HoldDetectorDebugPrint(...)
80 #ifdef __DETAIL_DEBUG__
81 #define DetailDebugPrint ErrorF
83 #define DetailDebugPrint(...)
88 #include <sys/syscall.h>
91 #include <sys/types.h>
93 #include <xorg-server.h>
94 #include <xorgVersion.h>
95 #include <xf86Module.h>
96 #include <X11/Xatom.h>
100 #define LOG_TAG "GESTURE"
103 char *strcasestr(const char *s, const char *find);
104 extern ScreenPtr miPointerCurrentScreen(void);
105 static void printk(const char* fmt, ...) __attribute__((format(printf, 1, 0)));
108 static int GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
109 static void GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
110 static pointer GesturePlug(pointer module, pointer options, int *errmaj, int *errmin);
111 static void GestureUnplug(pointer p);
112 static int GestureControl(DeviceIntPtr device,int what);
113 static int GestureInit(DeviceIntPtr device);
114 static void GestureFini(DeviceIntPtr device);
115 static void GestureReadInput(InputInfoPtr pInfo);
118 ErrorStatus GestureRegionsInit(void);
120 //event queue handling functions
121 ErrorStatus GestureInitEQ(void);
122 ErrorStatus GestureFiniEQ(void);
123 ErrorStatus GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
124 ErrorStatus GestureEventsFlush(void);
125 void GestureEventsDrop(void);
128 ErrorStatus GestureRegionsReinit(void);
129 void GestureEnable(int enable, Bool prop, DeviceIntPtr dev);
130 void GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent);
131 void GestureCbEventsSelected(Window win, Mask *pEventMask);
132 WindowPtr GestureGetEventsWindow(void);
133 #ifndef _SUPPORT_EVDEVMULTITOUCH_DRV_
134 int GestureGetTouchIndex(int deviceid, int touchid, int evtype);
135 int GestureFindTouchIndex(int deviceid, int touchid, int evtype);
136 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
137 #ifndef _SUPPORT_EVDEVMULTITOUCH_DRV_
138 static void GestureAlloc(int capability);
139 static void GestureDeAlloc(void);
140 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
142 //Enqueued event handlers and enabler/disabler
143 static ErrorStatus GestureEnableEventHandler(InputInfoPtr pInfo);
144 static ErrorStatus GestureDisableEventHandler(void);
145 static void GestureRegisterDeviceInfo(DeviceIntPtr device);
146 static CARD32 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
147 void GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
148 void GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
149 void GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
150 void GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
151 void GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
152 void GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
154 void GestureEmulateHWKey(DeviceIntPtr dev, int keycode);
156 //Gesture recognizer helper
157 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21
158 static Bool PointInBorderSize(WindowPtr pWin, int x, int y);
160 static WindowPtr GestureWindowOnXY(int x, int y);
161 Bool GestureHasFingerEventMask(int eventType, int num_finger);
163 //Gesture recognizer and handlers
164 void GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device);
165 void GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
166 void GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int start_point, int direction);
167 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
168 void GestureRecognize_PalmFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx);
169 void GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction);
170 void GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy);
171 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds);
172 ErrorStatus GestureFlushOrDrop(void);
174 static int GestureGetPalmValuator(InternalEvent *ev, DeviceIntPtr device);
175 static int GesturePalmGetAbsAxisInfo(DeviceIntPtr dev);
176 static void GestureHoldDetector(int type, InternalEvent *ev, DeviceIntPtr device);
177 static int GesturePalmGetScreenInfo();
178 static int GesturePalmGetHorizIndexWithX(int current_x, int idx, int type);
180 #ifdef HAVE_PROPERTIES
181 //function related property handling
182 static void GestureInitProperty(DeviceIntPtr dev);
183 static int GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkonly);
186 static Atom prop_gesture_recognizer_onoff = None;
188 #ifdef SUPPORT_ANR_WITH_INPUT_EVENT
189 static Atom prop_anr_in_input_event = None;
190 static Atom prop_anr_event_window = None;
191 static Window prop_anr_event_window_xid = None;
194 GestureDevicePtr g_pGesture = NULL;
195 _X_EXPORT InputDriverRec GESTURE = {
205 static XF86ModuleVersionInfo GestureVersionRec =
211 XORG_VERSION_CURRENT,
212 PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR,
213 PACKAGE_VERSION_PATCHLEVEL,
220 _X_EXPORT XF86ModuleData gestureModuleData =
228 printk(const char* fmt, ...)
230 static FILE* fp = NULL;
231 static char init = 0;
236 fp = fopen("/dev/kmsg", "wt");
242 va_start(argptr, fmt);
243 vfprintf(fp, fmt, argptr);
248 #ifdef SUPPORT_ANR_WITH_INPUT_EVENT
250 _GestureFindANRWindow(DeviceIntPtr device)
253 WindowPtr anr_window=NULL;
258 root = RootWindow(device);
260 if( prop_anr_event_window == None )
261 prop_anr_event_window = MakeAtom(ANR_EVENT_WINDOW, strlen(ANR_EVENT_WINDOW), TRUE);
263 rc = dixLookupProperty (&pProp, root, prop_anr_event_window, serverClient, DixReadAccess);
264 if (rc == Success && pProp->data){
265 anr_xid = *(int*)pProp->data;
270 rc = dixLookupWindow(&anr_window, anr_xid, serverClient, DixSetPropAccess);
271 if( rc == BadWindow )
273 ErrorF("Can't find ANR window !!\n");
276 prop_anr_event_window_xid = anr_xid;
279 ErrorF("ANR Window is %#x. Ptr is %#x\n", anr_xid, anr_window);
284 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21
286 PointInBorderSize(WindowPtr pWin, int x, int y)
289 if (pixman_region_contains_point (&pWin->borderSize, x, y, &box))
298 GestureWindowOnXY(int x, int y)
303 DeviceIntPtr pDev = g_pGesture->master_pointer;
305 pSprite = pDev->spriteInfo->sprite;
306 pSprite->spriteTraceGood = 1; /* root window still there */
307 pWin = RootWindow(pDev)->firstChild;
311 if ((pWin->mapped) &&
312 (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
313 (x < pWin->drawable.x + (int)pWin->drawable.width +
314 wBorderWidth(pWin)) &&
315 (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
316 (y < pWin->drawable.y + (int)pWin->drawable.height +
318 /* When a window is shaped, a further check
319 * is made to see if the point is inside
322 && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
323 && (!wInputShape(pWin) ||
324 RegionContainsPoint(wInputShape(pWin),
325 x - pWin->drawable.x,
326 y - pWin->drawable.y, &box))
328 /* In rootless mode windows may be offscreen, even when
329 * they're in X's stack. (E.g. if the native window system
330 * implements some form of virtual desktop system).
332 && !pWin->rootlessUnhittable
336 if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
338 pSprite->spriteTraceSize += 10;
339 pSprite->spriteTrace = realloc(pSprite->spriteTrace,
340 pSprite->spriteTraceSize*sizeof(WindowPtr));
342 pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
343 pWin = pWin->firstChild;
346 pWin = pWin->nextSib;
348 return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
352 GestureHasFingerEventMask(int eventType, int num_finger)
355 Mask eventmask = (1L << eventType);
357 if ((g_pGesture->grabMask & eventmask) &&
358 (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[num_finger].window != None))
360 DetailDebugPrint("[GestureHasFingerEventMask] TRUE !! Has grabMask\n");
364 if (g_pGesture->eventMask & eventmask)
366 DetailDebugPrint("[GestureHasFingerEventMask] TRUE !! Has eventMask\n");
370 DetailDebugPrint("[GestureHasFingerEventMask] FALSE !! eventType=%d, num_finger=%d\n", eventType, num_finger);
376 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
378 int event_type = *(int *)arg;
382 case GestureNotifyHold:
383 DetailDebugPrint("[GestureEventTimerHandler] GestureNotifyHold (event_type = %d)\n", event_type);
384 GestureRecognize_GroupHold(event_type, NULL, NULL, 0, 1);
386 case GestureNotifyTap:
387 DetailDebugPrint("[GestureEventTimerHandler] GestureNotifyTap (event_type = %d)\n", event_type);
388 GestureRecognize_GroupTap(event_type, NULL, NULL, 0, 1);
391 DetailDebugPrint("[GestureEventTimerHandler] unknown event_type (=%d)\n", event_type);
394 DetailDebugPrint("[GestureEventTimerHandler] timer=%x\n", (unsigned int)timer);
400 #ifndef _SUPPORT_EVDEVMULTITOUCH_DRV_
402 GestureGetTouchIndex(int deviceid, int touchid, int evtype)
406 for (i=0; i<g_pGesture->num_mt_devices; i++)
408 if (g_pGesture->fingers[i].touchid == touchid)
413 ErrorF("[GestureGetTouchIndex] Failed to get touch index, devid: %d, touchid: %d, evsystem: %d\n", deviceid, touchid, evtype);
418 GestureFindTouchIndex(int deviceid, int touchid, int evtype)
422 for (i=0; i<g_pGesture->num_mt_devices; i++)
424 if (evtype == ET_TouchBegin)
426 if (g_pGesture->fingers[i].status == BTN_RELEASED)
428 g_pGesture->fingers[i].status = BTN_PRESSED;
429 g_pGesture->fingers[i].touchid = touchid;
433 else if (evtype == ET_TouchUpdate || evtype == ET_TouchEnd)
435 if (g_pGesture->fingers[i].touchid == touchid)
437 g_pGesture->fingers[i].status = (evtype == ET_TouchEnd)?BTN_RELEASED:BTN_MOVING;
442 ErrorF("[GesutreFindTouchIndex] Failed to find touch index, devid: %d, touchid: %d, evtype: %d\n", deviceid, touchid, evtype);
445 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
448 GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy)
451 WindowPtr target_pWin;
452 xGestureNotifyTapEvent tev;
454 //skip non-tap events and single finger tap
455 if (!tap_repeat || num_finger <= 1)
460 DetailDebugPrint("[GestureHandleGesture_Tap] num_finger=%d, tap_repeat=%d, cx=%d, cy=%d\n", num_finger, tap_repeat, cx, cy);
462 g_pGesture->recognized_gesture |= WTapFilterMask;
463 memset(&tev, 0, sizeof(xGestureNotifyTapEvent));
464 tev.type = GestureNotifyTap;
465 tev.kind = GestureDone;
466 tev.num_finger = num_finger;
467 tev.tap_repeat = tap_repeat;
472 target_win = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].window;
473 target_pWin = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].pWin;
475 if (g_pGesture->grabMask && (target_win != None))
477 tev.window = target_win;
481 tev.window = g_pGesture->gestureWin;
484 DetailDebugPrint("[GestureHandleGesture_Tap] tev.window=0x%x, g_pGesture->grabMask=0x%x\n", (unsigned int)tev.window, (unsigned int)g_pGesture->grabMask);
486 GestureSendEvent(target_pWin, GestureNotifyTap, GestureTapMask, (xGestureCommonEvent *)&tev);
487 LOGI("GroupTap Event done. 2 fingers %d tap!", tap_repeat);
491 GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction)
494 if (!g_pGesture->hwkey_dev)
496 for (dev = inputInfo.keyboard ; dev; dev = dev->next)
498 if (g_pGesture->hwkey_name && !strncmp(dev->name, g_pGesture->hwkey_name, strlen(dev->name)))
500 g_pGesture->hwkey_id = dev->id;
501 g_pGesture->hwkey_dev = dev;
503 ErrorF("[GestureTimerHandler] hwkey_name has been found. hwkey_id=%d (hwkey_dev->name:%s)\n", g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
506 else if (!strcasestr(dev->name, "keyboard") && strcasestr(dev->name, "key") && !IsXTestDevice(dev, NULL) && !IsMaster(dev))
508 g_pGesture->hwkey_id = dev->id;
509 g_pGesture->hwkey_dev = dev;
511 ErrorF("[GestureTimerHandler] hwkey has been found. hwkey_id=%d (hwkey_dev->name:%s)\n", g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
516 if (!g_pGesture->hwkey_id)
518 g_pGesture->hwkey_id = inputInfo.keyboard->id;
519 g_pGesture->hwkey_dev = inputInfo.keyboard;
521 ErrorF("[GestureTimerHandler] No hwkey has been found. Back key will go through VCK. hwkey_id=%d (hwkey_dev->name:%s)\n",
522 g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
525 if (num_of_fingers == 0)
528 WindowPtr target_pWin;
529 xGestureNotifyFlickEvent fev;
531 DetailDebugPrint("[GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n", num_of_fingers, distance, duration, direction);
533 g_pGesture->recognized_gesture |= WPalmFlickFilterMask;
535 memset(&fev, 0, sizeof(xGestureNotifyFlickEvent));
536 fev.type = GestureNotifyFlick;
537 fev.kind = GestureDone;
538 fev.num_finger = num_of_fingers;
539 fev.distance = distance;
540 fev.duration = duration;
541 fev.direction = direction;
543 if (g_pGesture->GrabEvents)
545 target_win = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].window;
546 target_pWin = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].pWin;
554 if (g_pGesture->grabMask && (target_win != None))
556 fev.window = target_win;
560 fev.window = g_pGesture->gestureWin;
563 DetailDebugPrint("[GestureHandleGesture_Flick] fev.window=0x%x, g_pGesture->grabMask=0x%x\n", fev.window, g_pGesture->grabMask);
565 GestureSendEvent(target_pWin, GestureNotifyFlick, GestureFlickMask, (xGestureCommonEvent *)&fev);
569 DetailDebugPrint("[GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n", num_of_fingers, distance, duration, direction);
573 case FLICK_NORTHWARD:
574 DetailDebugPrint("[GestureHandleGesture_Flick] Flick Down \n");
575 GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down);
578 case FLICK_SOUTHWARD:
579 DetailDebugPrint("[GestureHandleGesture_Flick] Flick Up \n");
580 GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up);
583 if (g_pGesture->power_pressed == 2)
585 DetailDebugPrint("[GestureHandleGesture_Flick] Flick Right & power_pressed\n");
586 GestureEmulateHWKey(g_pGesture->hwkey_dev, 122);
592 g_pGesture->recognized_gesture |= WFlickFilterMask;
596 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds)
599 WindowPtr target_pWin;
600 xGestureNotifyHoldEvent hev;
602 DetailDebugPrint("[GestureHandleGesture_Hold] num_fingers=%d, cx=%d, cy=%d, holdtime=%d, kinds=%d\n", num_fingers, cx, cy, holdtime, kinds);
604 if (num_fingers == 0)
606 g_pGesture->hold_detected = TRUE;
607 LOGI("[PalmHold] PalmHold success !\n");
611 g_pGesture->recognized_gesture |= WHoldFilterMask;
614 memset(&hev, 0, sizeof(xGestureNotifyHoldEvent));
615 hev.type = GestureNotifyHold;
617 hev.num_finger = num_fingers;
618 hev.holdtime = holdtime;
622 if (g_pGesture->GrabEvents)
624 target_win = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].window;
625 target_pWin = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].pWin;
633 if (g_pGesture->grabMask && (target_win != None))
635 hev.window = target_win;
639 hev.window = g_pGesture->gestureWin;
642 DetailDebugPrint("[GestureHandleGesture_Hold] hev.window=0x%x, g_pGesture->grabMask=0x%x\n", hev.window, g_pGesture->grabMask);
644 GestureSendEvent(target_pWin, GestureNotifyHold, GestureHoldMask, (xGestureCommonEvent *)&hev);
645 LOGI("[GroupHold] GestureHold success !\n");
650 GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
652 static int num_pressed = 0;
653 static int base_area_size = 0;
658 static int state = 0;
659 static int mbits = 0;
662 static pixman_box16_t base_box_ext;
664 static int tap_repeat = 0;
665 static int prev_num_pressed = 0;
667 static OsTimerPtr tap_event_timer = NULL;
668 static int event_type = GestureNotifyTap;
672 DetailDebugPrint("[GroupTap][Timer] state=%d, num_pressed=%d, tap_repeat=%d\n", state, num_pressed, tap_repeat);
676 case 1://first tap initiation check
679 DetailDebugPrint("[GroupTap][Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", num_pressed, tap_repeat);
680 DetailDebugPrint("[GroupTap][F] 1\n");
691 DetailDebugPrint("[GroupTap][Timer][state=2] 2 finger %d tap\n", tap_repeat);
692 LOGI("[GroupTap][F] Second tap doesn't come up in 400ms after first tap.\n");
696 if (GestureHasFingerEventMask(GestureNotifyTap, prev_num_pressed))
698 DetailDebugPrint("[GroupTap] Success 1!! 2 finger %d tap\n", tap_repeat);
699 GestureHandleGesture_Tap(prev_num_pressed, tap_repeat, base_cx, base_cy);
709 case GESTURE_TOUCH_PRESS:
710 g_pGesture->fingers[idx].flags |= PressFlagTap;
712 if (g_pGesture->num_pressed < 2)
714 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);
718 if ((!base_area_size || g_pGesture->num_pressed > num_pressed))
720 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
721 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
722 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
723 base_box_ext.x1 = base_cx-TAP_MOVE_THRESHOLD;
724 base_box_ext.y1 = base_cy-TAP_MOVE_THRESHOLD;
725 base_box_ext.x2 = base_cx+TAP_MOVE_THRESHOLD;
726 base_box_ext.y2 = base_cy+TAP_MOVE_THRESHOLD;
728 TimerCancel(tap_event_timer);
729 tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->singletap_threshold, GestureEventTimerHandler, (int *)&event_type);
731 num_pressed = g_pGesture->num_pressed;
733 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);
736 case GESTURE_TOUCH_MOTION:
737 if (!(g_pGesture->fingers[idx].flags & PressFlagTap))
744 DetailDebugPrint("[GroupTap][M] num_pressed=%d, return \n", num_pressed);
748 if (num_pressed != g_pGesture->num_pressed)
750 DetailDebugPrint("[GroupTap][M] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
754 if (mbits == (pow(2, num_pressed)-1))
756 area_size = AREA_SIZE(&g_pGesture->area.extents);
757 cx = AREA_CENTER_X(&g_pGesture->area.extents);
758 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
760 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));
761 DetailDebugPrint("[GroupTap][M] cx=%d, base_cx=%d, diff=%d\n", cx, g_pGesture->fingers[idx].mx, ABS(cx-base_cx));
762 DetailDebugPrint("[GroupTap][M] cy=%d, base_cy=%d, diff=%d\n", cy, g_pGesture->fingers[idx].my, ABS(cy-base_cy));
764 if (ABS(base_area_size-area_size) >= TAP_AREA_THRESHOLD)
766 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));
767 DetailDebugPrint("[GroupTap][F] 3\n");
768 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));
773 if (!INBOX(&base_box_ext, cx, cy))
775 DetailDebugPrint("[GroupTap][M] current center coordinates is not in base coordinates box !\n");
776 DetailDebugPrint("[GroupTap][F] 4\n");
777 LOGI("[GroupTap][F] current center coordinates is not in base coordinates box !\n");
784 case GESTURE_TOUCH_RELEASE:
785 if (g_pGesture->num_pressed)
787 DetailDebugPrint("[GroupTap][R] Second finger doesn't come up. g_pGesture->num_pressed=%d\n", g_pGesture->num_pressed);
793 prev_num_pressed = num_pressed;
797 g_pGesture->num_tap_repeated = tap_repeat;
799 DetailDebugPrint("[GroupTap][R] tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, num_pressed, prev_num_pressed);
800 DetailDebugPrint("[GroupTap][R] base_rx=%d, base_ry=%d,\n", g_pGesture->fingers[idx].rx, g_pGesture->fingers[idx].ry);
802 if ((num_pressed != prev_num_pressed) || (!GestureHasFingerEventMask(GestureNotifyTap, num_pressed)))
804 DetailDebugPrint("[GroupTap][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
805 num_pressed, prev_num_pressed, num_pressed);
806 DetailDebugPrint("[GroupTap][F] 5\n");
807 LOGI("[GroupTap][F] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
808 num_pressed, prev_num_pressed, num_pressed);
814 DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat);
815 TimerCancel(tap_event_timer);
816 tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->doubletap_threshold, GestureEventTimerHandler, (int *)&event_type);
818 prev_num_pressed = num_pressed;
823 else if (tap_repeat == 2)
825 DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat);
826 TimerCancel(tap_event_timer);
827 tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->tripletap_threshold, GestureEventTimerHandler, (int *)&event_type);
829 base_area_size = num_pressed = 0;
833 DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat);
835 if (tap_repeat == MAX_TAP_REPEATS)
837 if (GestureHasFingerEventMask(GestureNotifyTap, num_pressed))
839 DetailDebugPrint("[GroupTap] Sucess 2!\n");
840 GestureHandleGesture_Tap(num_pressed, tap_repeat, base_cx, base_cy);
845 if (tap_repeat >= MAX_TAP_REPEATS)
847 LOGI("[GroupTap][F] More than 3 taps. Ignore. \n");
851 prev_num_pressed = num_pressed;
860 DetailDebugPrint("[GroupTap][cleanup_tap]\n");
864 g_pGesture->recognized_gesture &= ~WTapFilterMask;
867 g_pGesture->filter_mask |= WTapFilterMask;
869 if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
871 DetailDebugPrint("[GroupTap][cleanup] GestureFlushOrDrop() !\n");
873 if (ERROR_INVALPTR == GestureFlushOrDrop())
875 GestureControl(g_pGesture->this_device, DEVICE_OFF);
880 g_pGesture->num_tap_repeated = tap_repeat = 0;
881 prev_num_pressed = 0;
884 TimerCancel(tap_event_timer);
889 GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int start_point, int direction)
891 static int num_pressed = 0;
892 static Time base_time = 0;
895 static int diff_base_coord = 0;
896 static int diff_base_minor_coord = 0;
897 static int diff_current_coord = 0;
898 static int false_diff_count = 0;
899 static int false_minor_diff_count = 0;
900 static float angle = 0.0f;
901 static int angle_base_x = 0, angle_base_y = 0;
902 static int motion_count = 0;
904 if (g_pGesture->num_pressed > 1)
906 DetailDebugPrint("[GroupFlick][F] 1\n");
910 if ((start_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= start_point))
912 DetailDebugPrint("[GroupFlick][F] 2\n");
918 case GESTURE_TOUCH_PRESS:
919 g_pGesture->fingers[idx].flags = PressFlagFlick;
920 base_time = GetTimeInMillis();
921 num_pressed = g_pGesture->num_pressed;
925 if (g_pGesture->fingers[idx].py > g_pGesture->flick_press_area)
927 DetailDebugPrint("[GroupFlick][FlickDown][P] press coord is out of bound. (%d, %d)\n",
928 g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
929 DetailDebugPrint("[GroupFlick][F] 3\n");
930 //LOGI("[BackKey][F] press coord is out of bound (40 pixel from upper vezel). press y=%d\n", g_pGesture->fingers[idx].py);
934 angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
935 angle_base_x = g_pGesture->fingers[idx].px;
936 DetailDebugPrint("[GroupFlick][FlickDown][P] px=%d, py=%d\n", g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
939 case FLICK_POINT_DOWN:
940 if (g_pGesture->fingers[idx].py < g_pGesture->screen_height - g_pGesture->flick_press_area)
942 DetailDebugPrint("[GroupFlick][FlickUp][P] press coord is out of bound. (%d, %d)\n",
943 g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
944 DetailDebugPrint("[GroupFlick][F] 4\n");
947 angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
948 angle_base_x = g_pGesture->fingers[idx].px;
951 case FLICK_POINT_LEFT:
952 if (g_pGesture->fingers[idx].px > g_pGesture->flick_press_area)
954 DetailDebugPrint("[GroupFlick][FlickLeft][P] press coord is out of bound. (%d, %d)\n",
955 g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
956 DetailDebugPrint("[GroupFlick][F] 5\n");
959 angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
960 angle_base_x = g_pGesture->fingers[idx].px;
964 DetailDebugPrint("[GroupFlick][F] 6\n");
971 case GESTURE_TOUCH_MOTION:
975 if (motion_count > 15)
977 DetailDebugPrint("[GroupFlick][F] 6-1 motion_count=%d\n", motion_count);
978 LOGI("[BackKey][F] More than 15 motion.\n");
982 if (!(g_pGesture->fingers[idx].flags & PressFlagFlick))
990 diff_base_coord = diff_current_coord;
991 diff_current_coord = g_pGesture->fingers[idx].my;
993 if ((diff_current_coord - diff_base_coord) < 0)
995 DetailDebugPrint("[GroupFlick][FlickDown][M] false_diff\n");
999 if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
1001 DetailDebugPrint("[GroupFlick][FlickDown][M] false_diff_count: %d > %d\n",
1002 false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
1003 DetailDebugPrint("[GroupFlick][F] 7\n");
1004 LOGI("[BackKey][F] Direction is wrong for 7 times.\n");
1008 if ((g_pGesture->fingers[idx].my < g_pGesture->flick_press_area) &&
1009 (abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) >(int)( g_pGesture->screen_width/2)))
1011 DetailDebugPrint("[GroupFlick][FlickDown][M] move x: %d - %d, y coord: %d\n",
1012 g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].my);
1013 DetailDebugPrint("[GroupFlick][F] 8\n");
1014 LOGI("[BackKey][F] From press point, moving x axis is more than half screen size.\n");
1018 if ((g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) > g_pGesture->flick_minimum_height)
1020 DetailDebugPrint("[GroupFlick][FlickDown][M] %d - %d < %d(min_size), angle_base_coord (%d, %d)\n",
1021 g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py, g_pGesture->flick_minimum_height, angle_base_x, angle_base_y);
1023 if (abs(g_pGesture->fingers[idx].mx - angle_base_x) == 0)
1025 DetailDebugPrint("[GroupFlick][FlickDown][M] abs(%d - %d) = 0\n",
1026 g_pGesture->fingers[idx].mx, angle_base_x);
1031 DetailDebugPrint("[GroupFlick][FlickDown][M] angle_base_x: %d, angle_base_y: %d\n",
1032 angle_base_x, angle_base_y);
1033 int y_diff = abs(g_pGesture->fingers[idx].my - angle_base_y);
1034 int x_diff = abs(g_pGesture->fingers[idx].mx - angle_base_x);
1035 angle = (float)y_diff / (float)x_diff;
1040 DetailDebugPrint("[GroupFlick][FlickDown][M][F] %d / %d = %f (angle)\n",
1041 abs(g_pGesture->fingers[idx].my - angle_base_y), abs(g_pGesture->fingers[idx].mx - angle_base_x), angle);
1042 DetailDebugPrint("[GroupFlick][F] 9\n");
1043 LOGI("[BackKey][F] angle is improper. %d < 0.23\n", angle);
1047 distance = g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py;
1048 duration = GetTimeInMillis() - base_time;
1050 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
1051 DetailDebugPrint("[GroupFlick][FlickDown][M] FlickDown Done!!\n");
1052 goto cleanup_flick_recognized;
1056 if ((g_pGesture->fingers[idx].mx - diff_base_minor_coord) < 0)
1058 false_minor_diff_count++;
1061 if (false_minor_diff_count> FLICK_FALSE_X_DIFF_COUNT)
1063 DetailDebugPrint("[GroupFlick][FlickDown][M] false_minor_diff_count: %d > %d\n",
1064 false_minor_diff_count, FLICK_FALSE_X_DIFF_COUNT);
1065 DetailDebugPrint("[GroupFlick][F] 10\n");
1070 if (g_pGesture->fingers[idx].my < g_pGesture->flick_press_area)
1072 angle_base_x = g_pGesture->fingers[idx].px;
1073 angle_base_y = g_pGesture->fingers[idx].py;
1075 DetailDebugPrint("[GroupFlick][FlickDown][M] mx=%d, my=%d, diff_x=%d, diff_y=%d\n",
1076 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));
1080 case FLICK_POINT_DOWN:
1081 diff_base_coord = diff_current_coord;
1082 diff_current_coord = g_pGesture->fingers[idx].my;
1084 if ((diff_base_coord - diff_current_coord) < 0)
1089 if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
1091 DetailDebugPrint("[GroupFlick][FlickUp][M] false_diff_count: %d > %d\n",
1092 false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
1093 DetailDebugPrint("[GroupFlick][F] 11\n");
1097 if ((g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my) > g_pGesture->flick_minimum_height)
1099 DetailDebugPrint("[GroupFlick][FlickUp][R] %d - %d < %d(min_size)\n",
1100 g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py, g_pGesture->flick_minimum_height);
1101 if (abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) == 0)
1103 DetailDebugPrint("[GroupFlick][FlickUp][R] abs(%d - %d) = 0\n",
1104 g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px);
1109 int y_diff = abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py);
1110 int x_diff = abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px);
1111 angle = (float)y_diff / (float)x_diff;
1116 DetailDebugPrint("[GroupFlick][FlickUp][R] %d / %d = %f (angle)\n",
1117 abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py), abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), angle);
1118 DetailDebugPrint("[GroupFlick][F] 12\n");
1122 distance = g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my;
1123 duration = GetTimeInMillis() - base_time;
1125 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
1126 goto cleanup_flick_recognized;
1130 case FLICK_POINT_LEFT:
1131 diff_base_coord = diff_current_coord;
1132 diff_current_coord = g_pGesture->fingers[idx].mx;
1134 if ((diff_current_coord - diff_base_coord) < 0)
1139 if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
1141 DetailDebugPrint("[GroupFlick][FlickLeft][M] false_diff_count: %d > %d\n",
1142 false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
1143 DetailDebugPrint("[GroupFlick][F] 13\n");
1147 if ((g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) > g_pGesture->flick_minimum_height)
1149 DetailDebugPrint("[GroupFlick][FlickLeft][M] %d - %d < %d(min_size)\n",
1150 g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px, g_pGesture->flick_minimum_height);
1152 if (abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) == 0)
1154 DetailDebugPrint("[GroupFlick][FlickLeft][M] abs(%d - %d) = 0\n",
1155 g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py);
1160 int y_diff = abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py);
1161 int x_diff = abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px);
1162 angle = (float)x_diff / (float)y_diff;
1167 DetailDebugPrint("[GroupFlick][FlickLeft][M] %d / %d = %f (angle)\n",
1168 abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py), angle);
1169 DetailDebugPrint("[GroupFlick][F] 14\n");
1173 distance = g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px;
1174 duration = GetTimeInMillis() - base_time;
1176 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
1177 goto cleanup_flick_recognized;
1182 DetailDebugPrint("[GroupFlick][F] 15\n");
1188 case GESTURE_TOUCH_RELEASE:
1189 DetailDebugPrint("[GroupFlick][R][F] 16\n");
1197 DetailDebugPrint("[GroupFlick] cleanup_flick \n");
1198 g_pGesture->recognized_gesture &= ~WFlickFilterMask;
1201 cleanup_flick_recognized:
1202 DetailDebugPrint("[GroupFlick] Flick recognized !\n");
1203 g_pGesture->filter_mask |= WFlickFilterMask;
1206 false_diff_count = 0;
1207 diff_base_coord = 0;
1208 diff_current_coord = 0;
1210 angle_base_x = angle_base_y = 0;
1215 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1217 static int num_pressed = 0;
1218 static int base_area_size = 0;
1219 static Time base_time = 0;
1223 static pixman_box16_t base_box_ext;
1225 static int state = GestureEnd;
1227 static OsTimerPtr hold_event_timer = NULL;
1228 static int event_type = GestureNotifyHold;
1232 if (state <= GestureBegin)
1240 DetailDebugPrint("[GroupHold] HOLD Begin !\n");
1244 DetailDebugPrint("[GroupHold] HOLD Update !\n");
1248 if (GestureHasFingerEventMask(GestureNotifyHold, num_pressed))
1250 DetailDebugPrint("[GroupHold] Success 1! \n");
1251 GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1254 hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type);
1261 case GESTURE_TOUCH_PRESS:
1262 g_pGesture->fingers[idx].flags |= PressFlagHold;
1264 if (g_pGesture->num_pressed < 2)
1266 DetailDebugPrint("[GroupHold][P] No num_finger changed ! num_pressed=%d\n", num_pressed);
1267 DetailDebugPrint("[GroupHold][F] 0\n");
1271 if (!base_area_size || g_pGesture->num_pressed > num_pressed)
1273 if (state != GestureEnd)
1275 DetailDebugPrint("[GroupHold][P][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1276 DetailDebugPrint("[GroupHold][F] 1\n");
1281 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1282 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1283 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1284 base_time = GetTimeInMillis();
1286 base_box_ext.x1 = base_cx-g_pGesture->hold_move_threshold;
1287 base_box_ext.y1 = base_cy-g_pGesture->hold_move_threshold;
1288 base_box_ext.x2 = base_cx+g_pGesture->hold_move_threshold;
1289 base_box_ext.y2 = base_cy+g_pGesture->hold_move_threshold;
1291 event_type = GestureNotifyHold;
1293 hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type);
1295 num_pressed = g_pGesture->num_pressed;
1297 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);
1301 case GESTURE_TOUCH_MOTION:
1302 if (!(g_pGesture->fingers[idx].flags & PressFlagHold))
1304 DetailDebugPrint("[GroupHold][M] No PressFlagHold\n");
1308 if (num_pressed < 2)
1310 DetailDebugPrint("[GroupHold][M] No num_finger changed ! num_pressed=%d\n", num_pressed);
1311 DetailDebugPrint("[GroupHold][F] 2\n");
1315 if (num_pressed != g_pGesture->num_pressed)
1317 if (state != GestureEnd)
1319 DetailDebugPrint("[GroupHold][M][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1320 DetailDebugPrint("[GroupHold][F] 3\n");
1324 DetailDebugPrint("[GroupHold][M] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1327 area_size = AREA_SIZE(&g_pGesture->area.extents);
1328 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1329 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1331 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));
1332 DetailDebugPrint("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1333 DetailDebugPrint("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1335 if (area_size > 0 && base_area_size > 0)
1337 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)
1339 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));
1340 DetailDebugPrint("[GroupHold][F] 4\n");
1345 if (!INBOX(&base_box_ext, cx, cy))
1347 DetailDebugPrint("[GroupHold][M] No current center coordinates is not in base coordinates box !\n");
1348 DetailDebugPrint("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1349 DetailDebugPrint("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1350 DetailDebugPrint("[GroupHold][F] 5\n");
1355 case GESTURE_TOUCH_RELEASE:
1356 if (state != GestureEnd && num_pressed >= 2)
1358 DetailDebugPrint("[GroupHold][R] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1359 DetailDebugPrint("[GroupHold][F] 6\n");
1363 if (g_pGesture->num_pressed)
1365 DetailDebugPrint("[GroupHold][R] num_pressed=%d\n", num_pressed);
1366 DetailDebugPrint("[GroupHold][F] 7\n");
1378 DetailDebugPrint("[GroupHold][cleanup_hold] enter!\n");
1380 if (state == GestureBegin || state == GestureUpdate)
1383 if (GestureHasFingerEventMask(GestureNotifyHold, num_pressed))
1385 DetailDebugPrint("[GroupHold] Success 2!\n");
1386 GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1391 g_pGesture->recognized_gesture &= ~WHoldFilterMask;
1394 g_pGesture->filter_mask |= WHoldFilterMask;
1398 base_cx = base_cy = 0;
1400 base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
1401 TimerCancel(hold_event_timer);
1406 GestureGetMaxTmajor(InternalEvent *ev, int max_tmajor)
1408 int mt_tmajor_idx = g_pGesture->tmajor_idx;
1411 DeviceEvent *de = &ev->device_event;
1415 DetailDebugPrint("[GestureGetMaxTmajor] de is NULL !\n");
1419 if (mt_tmajor_idx < 0)
1421 DetailDebugPrint("[GestureGetMaxTmajor] One or more of axes are not supported !\n");
1425 mt_tmajor = de->valuators.data[mt_tmajor_idx];
1427 DetailDebugPrint("[GestureGetMaxTmajor]mt_tmajor_idx=%d, mt_tmajor=%d, max_tmajor=%d\n", mt_tmajor_idx, mt_tmajor, max_tmajor);
1429 return ((mt_tmajor > max_tmajor) ? mt_tmajor : max_tmajor);
1434 GestureRecognize_PalmFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx)
1436 // static int num_pressed = 0;
1437 static int base_time = 0, current_time = 0;
1438 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
1439 static int base_x[MAX_MT_DEVICES] = {0}, base_y[MAX_MT_DEVICES] = {0};
1440 static int update_x[MAX_MT_DEVICES] = {0}, update_y[MAX_MT_DEVICES] = {0};
1442 static int current_x[MAX_MT_DEVICES] = {0}, current_y[MAX_MT_DEVICES] = {0};
1443 static Bool press_status[MAX_MT_DEVICES] = {FALSE, FALSE};
1444 static Bool release_status[MAX_MT_DEVICES] = {FALSE, FALSE};
1446 static int line_idx[MAX_MT_DEVICES] = {0}, prev_line_idx[MAX_MT_DEVICES] = {0}, press_idx[MAX_MT_DEVICES] = {0};
1447 static Bool is_line_invalid[MAX_MT_DEVICES] = {TRUE, TRUE};
1449 static int max_tmajor[MAX_MT_DEVICES] = {0};
1450 static int total_max_tmajor = 0;
1451 static Bool is_tmajor_invalid[MAX_MT_DEVICES] = {TRUE, TRUE};
1453 static int mt_sync_count[MAX_MT_DEVICES] = {0};
1454 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
1455 int *base_x = g_pGesture->palmFlickInfo.base_x, *base_y = g_pGesture->palmFlickInfo.base_y;
1456 int *update_x = g_pGesture->palmFlickInfo.update_x, *update_y = g_pGesture->palmFlickInfo.update_y;
1458 int *current_x = g_pGesture->palmFlickInfo.current_x, *current_y = g_pGesture->palmFlickInfo.current_y;
1459 Bool *press_status = g_pGesture->palmFlickInfo.press_status;
1460 Bool *release_status = g_pGesture->palmFlickInfo.release_status;
1462 int *line_idx = g_pGesture->palmFlickInfo.line_idx, *prev_line_idx = g_pGesture->palmFlickInfo.prev_line_idx, *press_idx = g_pGesture->palmFlickInfo.press_idx;
1463 Bool *is_line_invalid = g_pGesture->palmFlickInfo.is_line_invalid;
1465 int *max_tmajor = g_pGesture->palmFlickInfo.max_tmajor;
1466 static int total_max_tmajor = 0;
1467 Bool *is_tmajor_invalid = g_pGesture->palmFlickInfo.is_tmajor_invalid;
1469 int *mt_sync_count = g_pGesture->palmFlickInfo.mt_sync_count;
1470 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
1472 static Bool is_palm = FALSE;
1473 PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
1475 static Bool is_retry = FALSE;
1477 int distance, direction, duration;
1479 if (g_pGesture->recognized_gesture && !(g_pGesture->recognized_gesture & WPalmFlickFilterMask))
1481 PalmFlickDebugPrint("[PalmFlick] recognize other gesture already( g_pGesture->recognized_gesture: %d)\n", g_pGesture->recognized_gesture);
1482 PalmFlickDebugPrint("[PalmFlick][F] 1\n");
1486 // only first finger recognize
1487 if (!(idx == 0 || idx == 1))
1489 PalmFlickDebugPrint("[PalmFlick] idx=%d, least two fingers come on\n", idx);
1495 case GESTURE_TOUCH_PRESS:
1501 base_time = GetTimeInMillis();
1504 // press (x,y), touch major
1505 update_x[idx] = base_x[idx] = g_pGesture->fingers[idx].px;
1506 update_y[idx] = base_y[idx] = g_pGesture->fingers[idx].py;
1507 max_tmajor[idx] = g_pGesture->max_mt_tmajor[idx];
1508 press_status[idx] = TRUE;
1509 is_tmajor_invalid[idx] = FALSE;
1510 is_line_invalid[idx] = FALSE;
1512 total_max_tmajor = (total_max_tmajor > max_tmajor[idx]) ? total_max_tmajor : max_tmajor[idx];
1515 press_idx[idx] = prev_line_idx[idx] = line_idx[idx] = GesturePalmGetHorizIndexWithX(base_x[idx], idx, type);
1517 PalmFlickDebugPrint("[PalmFlick][P] idx: %d, num_pressed: %d\n", idx, g_pGesture->num_pressed);
1518 PalmFlickDebugPrint("[PalmFlick][P] base_time: %d, base_x: %d, base_y: %d, line_idx: %d, touch_major=%d\n",
1519 base_time, base_x[idx], base_y[idx], line_idx[idx], max_tmajor[idx]);
1522 if (line_idx[idx] < 0 || line_idx[idx] >= PALM_HORIZ_ARRAY_COUNT)
1524 PalmFlickDebugPrint("[PalmFlick][P][F] No line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x[idx], line_idx[idx]);
1525 PalmFlickDebugPrint("[PalmFlick][F] 2\n");
1529 // check press point when there are two fingers
1532 if (press_idx[0] != press_idx[1])
1534 PalmFlickDebugPrint("[PalmFlick] Press line_idx is the different between two fingers. 1st finger_line_idx=%d, 2nd finger_line_idx=%d\n",
1535 press_idx[0], press_idx[1]);
1536 PalmFlickDebugPrint("[PalmFlick][F] 2-1\n");
1543 update_x[idx] = g_pGesture->fingers[idx].px;
1544 update_y[idx] = g_pGesture->fingers[idx].py;
1546 PalmFlickDebugPrint("[PalmFlick][P] Already palm flick success. base_x=%d, base_y=%d, update_x=%d, update_y=%d\n",
1547 base_x[idx], base_y[idx], update_x[idx], update_y[idx]);
1552 case GESTURE_TOUCH_MOTION:
1554 if (total_max_tmajor > g_pGesture->palm_flick_max_tmajor_threshold)
1556 mt_sync_count[idx]++;
1558 DetailDebugPrint("[PalmFlick][M] Sufficient touch enough ! max_tmajor=%d\n", total_max_tmajor);
1562 // motion information (touch major, x, y)
1563 current_x[idx] = g_pGesture->fingers[idx].mx;
1564 current_y[idx] = g_pGesture->fingers[idx].my;
1565 max_tmajor[idx] = g_pGesture->max_mt_tmajor[idx];
1566 mt_sync_count[idx]++;
1568 //int temp_total_max_tmajor = (idx == 0 ? max_tmajor[0] : max_tmajor[0] + max_tmajor[1]);
1569 int temp_total_max_tmajor = max_tmajor[idx];
1570 total_max_tmajor = (total_max_tmajor > temp_total_max_tmajor ? total_max_tmajor : temp_total_max_tmajor);
1572 PalmFlickDebugPrint("[PalmFlick][M] idx=%d, total_max_tmajor=%d, max_tmajor[0]=%d, max_tmajor[1]=%d, current current=(%d, %d)\n",
1573 idx, total_max_tmajor, max_tmajor[0], max_tmajor[1], current_x[idx], current_y[idx]);
1575 // exception vezel end line motion
1576 if (current_x[idx] < 5 || current_x[idx] > 355)
1578 if (total_max_tmajor >= g_pGesture->palm_flick_max_tmajor_threshold)
1580 PalmFlickDebugPrint("[PalmFlick][M][Vezel] Sufficient touch major was came(%d)\n", total_max_tmajor);
1585 mt_sync_count[idx]--;
1586 PalmFlickDebugPrint("[PalmFlick][M] Except vezel end line condition. x=%d, sync_count=%d \n",
1587 current_x[idx], mt_sync_count[idx]);
1592 // get current position
1593 line_idx[idx] = GesturePalmGetHorizIndexWithX(current_x[idx], idx, type);
1595 PalmFlickDebugPrint("[PalmFlick][M] line_idx: %d, prev_line_idx: %d, sync_count: %d\n",
1596 line_idx[idx], prev_line_idx[idx], mt_sync_count[idx]);
1599 if (line_idx[idx] < 0 || line_idx[idx] >= PALM_HORIZ_ARRAY_COUNT)
1601 PalmFlickDebugPrint("[PalmFlick][M][F] No line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x[idx], line_idx[idx]);
1602 PalmFlickDebugPrint("[PalmFlick][F] 3\n");
1606 // screen capture motion validation
1607 if (line_idx[idx] != prev_line_idx[idx])
1609 if (base_x[idx] <= pPalmMisc->horiz_coord[0])
1611 if (line_idx[idx] < prev_line_idx[idx])
1613 PalmFlickDebugPrint("[PalmFlick][M][F] Invalid line_idx.. line_idx: %d, prev_line_idx: %d, pPalmMisc->horiz_coord[0]: %d\n",
1614 line_idx[idx], prev_line_idx[idx], pPalmMisc->horiz_coord[0]);
1616 is_line_invalid[idx] = TRUE;
1618 if (is_line_invalid[0] && is_line_invalid[1])
1620 PalmFlickDebugPrint("[PalmFlick][F] 4\n");
1625 else if (base_x[idx] >= pPalmMisc->horiz_coord[PALM_HORIZ_ARRAY_COUNT-1])
1627 if (line_idx[idx] > prev_line_idx[idx])
1629 PalmFlickDebugPrint("[PalmFlick][M][F] Invalid line_idx.. line_idx: %d, prev_line_idx: %d, pPalmMisc->horiz_coord[%d]: %d\n",
1630 line_idx[idx], prev_line_idx[idx], PALM_HORIZ_ARRAY_COUNT-1, pPalmMisc->horiz_coord[PALM_HORIZ_ARRAY_COUNT-1]);
1632 is_line_invalid[idx] = TRUE;
1634 if (is_line_invalid[0] && is_line_invalid[1])
1636 PalmFlickDebugPrint("[PalmFlick][F] 5\n");
1641 prev_line_idx[idx] = line_idx[idx];
1644 if (is_palm == FALSE)
1646 switch (mt_sync_count[idx])
1649 if (total_max_tmajor <= g_pGesture->palm_flick_min_tmajor_threshold)
1651 PalmFlickDebugPrint("[PalmFlick][M][F] mtsync_count: %d, max_tmajor: %d(%d) line_idx: %d\n",
1652 mt_sync_count[idx], total_max_tmajor, g_pGesture->palm_flick_min_tmajor_threshold, line_idx[idx]);
1653 PalmFlickDebugPrint("[PalmFlick][F] 6\n");
1654 is_tmajor_invalid[idx] = TRUE;
1655 //goto flick_failed;
1659 if (total_max_tmajor <= (g_pGesture->palm_flick_max_tmajor_threshold - 10))
1661 PalmFlickDebugPrint("[PalmFlick][M][F] mtsync_count: %d, max_tmajor: %d(%d) line_idx: %d\n",
1662 mt_sync_count[idx], total_max_tmajor, g_pGesture->palm_flick_max_tmajor_threshold-10, line_idx[idx]);
1663 PalmFlickDebugPrint("[PalmFlick][F] 7\n");
1664 is_tmajor_invalid[idx] = TRUE;
1665 //goto flick_failed;
1669 if (total_max_tmajor < g_pGesture->palm_flick_max_tmajor_threshold)
1671 PalmFlickDebugPrint("[PalmFlick][M][F] mtsync_count: %d, max_tmajor: %d(%d) line_idx: %d\n",
1672 mt_sync_count[idx], total_max_tmajor, g_pGesture->palm_flick_max_tmajor_threshold, line_idx[idx]);
1673 PalmFlickDebugPrint("[PalmFlick][F] 8\n");
1674 is_tmajor_invalid[idx] = TRUE;
1675 //goto flick_failed;
1679 PalmFlickDebugPrint("[PalmFlick][M] See more next motion...\n");
1684 if (is_tmajor_invalid[0] && is_tmajor_invalid[1])
1686 PalmFlickDebugPrint("[PalmFlick][M][F] max_tmajor=%d\n", total_max_tmajor);
1690 current_time = GetTimeInMillis();
1692 if (current_time - base_time > g_pGesture->palm_flick_time_threshold)
1694 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);
1695 PalmFlickDebugPrint("[PalmFlick][F] 10\n");
1701 case GESTURE_TOUCH_RELEASE:
1702 current_x[idx] = g_pGesture->fingers[idx].mx;
1703 current_y[idx] = g_pGesture->fingers[idx].my;
1704 release_status[idx] = TRUE;
1706 if ((update_x[idx] == current_x[idx]) && (update_y[idx] == current_y[idx]))
1708 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",
1709 update_x[idx], update_y[idx], current_x[idx], current_y[idx]);
1710 PalmFlickDebugPrint("[PalmFlick][F] 10-1\n");
1712 //goto flick_failed;
1717 is_tmajor_invalid[idx] = TRUE;
1719 if (is_tmajor_invalid[0] && is_tmajor_invalid[1])
1721 PalmFlickDebugPrint("[PalmFlick][R][F] Insufficient touch major was came(%d)\n", total_max_tmajor);
1722 PalmFlickDebugPrint("[PalmFlick][F] 11\n");
1727 line_idx[idx] = GesturePalmGetHorizIndexWithX(current_x[idx], idx, type);
1729 if (is_palm && line_idx[idx] == 1)
1731 PalmFlickDebugPrint("[PalmFlick][R] Enough major, but release. base_x=%d, base_y=%d, current_x=%d, current_y=%d\n",
1732 base_x[idx], base_y[idx], current_x[idx], current_y[idx]);
1734 mt_sync_count[idx] = 0;
1738 if (line_idx[idx] < 0 || line_idx[idx] > PALM_HORIZ_ARRAY_COUNT - 1)
1740 is_line_invalid[idx] = TRUE;
1742 if (is_line_invalid[0] && is_line_invalid[1])
1744 PalmFlickDebugPrint("[PalmFlick][R][F] No line_idx is invalid.. base_x: %d, current_x: %d\n", base_x[idx], current_x[idx]);
1745 PalmFlickDebugPrint("[PalmFlick][F] 12\n");
1750 current_time = GetTimeInMillis();
1752 if (current_time - base_time > g_pGesture->palm_flick_time_threshold)
1754 PalmFlickDebugPrint("[PalmFlick][R][F] Release event were came to have long delay (%d - %d > %d)\n",
1755 current_time, base_time, g_pGesture->palm_flick_time_threshold);
1756 PalmFlickDebugPrint("[PalmFlick][F] 13\n");
1760 direction = (line_idx[idx] <= 1) ? FLICK_EASTWARD : FLICK_WESTWARD;
1761 distance = ABS(current_x[idx] - base_x[idx]);
1762 duration = current_time - base_time;
1766 if (GestureHasFingerEventMask(GestureNotifyFlick, 0))
1768 PalmFlickDebugPrint("[PalmFlick][R] Palm Flick1 !!!, direction=%d, distance=%d\n", direction, distance);
1770 GestureHandleGesture_Flick(0, distance, duration, direction);
1775 if (mt_sync_count[idx] < 25)
1777 PalmFlickDebugPrint("[PalmFlick][R][F] No enough motion=%d\n", mt_sync_count[idx]);
1778 PalmFlickDebugPrint("[PalmFlick][F] 14\n");
1783 if (GestureHasFingerEventMask(GestureNotifyFlick, 0))
1785 PalmFlickDebugPrint("[PalmFlick][R] Palm Flick2 !!!, direction=%d, distance=%d\n", direction, distance);
1787 GestureHandleGesture_Flick(0, distance, duration, direction);
1792 g_pGesture->recognized_gesture |= WPalmFlickFilterMask;
1802 DetailDebugPrint("[PalmFlick][R] flick failed\n");
1804 g_pGesture->recognized_gesture &= ~WPalmFlickFilterMask;
1805 g_pGesture->filter_mask |= WPalmFlickFilterMask;
1810 DetailDebugPrint("[PalmFlick][R] cleanup_flick\n");
1811 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
1812 for (int i = 0; i < MAX_MT_DEVICES; i++)
1813 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
1814 for (int i = 0; i < g_pGesture->num_mt_devices; i++)
1815 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
1825 prev_line_idx[i] = 0;
1827 mt_sync_count[i] = 0;
1828 press_status[i] = FALSE;
1829 release_status[i] = FALSE;
1830 is_tmajor_invalid[i] = TRUE;
1831 is_line_invalid[i] = TRUE;
1834 total_max_tmajor = 0;
1842 GesturePalmGetHorizIndexWithX(int current_x, int idx, int type)
1846 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
1847 static int pressed_idx[MAX_MT_DEVICES] = {-1, -1};
1848 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
1849 int *pressed_idx = g_pGesture->palmInfo.pressed_idx;
1850 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
1851 PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
1853 for (i = 0; i < PALM_HORIZ_ARRAY_COUNT; i++)
1855 if (current_x <= pPalmMisc->horiz_coord[i])
1857 DetailDebugPrint("[GesturePalmGetHorizIndexWithX] index=%d, pPalmMisc->horiz_coord[%d]=%d\n", i, i, pPalmMisc->horiz_coord[i]);
1864 DetailDebugPrint("[GesturePalmGetHorizIndexWithX]Error ! Failed to get horiz coordinate index !\n");
1869 if (type == GESTURE_TOUCH_PRESS)
1871 pressed_idx[idx] = ret_idx;
1873 // first press is center
1874 if (pressed_idx[idx] == PALM_HORIZ_ARRAY_COUNT -2)
1876 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][P] Invalid press area x=%d, idx=%d, pressed_idx=%d\n", current_x, idx, pressed_idx[idx]);
1880 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][P] pressed_idx=%d\n", pressed_idx[idx]);
1883 else if (type == GESTURE_TOUCH_MOTION)
1885 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][M] moving x=%d, idx=%d, pressed_idx=%d\n", current_x, idx, pressed_idx[idx]);
1888 else if (type == GESTURE_TOUCH_RELEASE)
1890 if ((pressed_idx[idx] == 0) && (ret_idx == (PALM_HORIZ_ARRAY_COUNT - 1)))
1892 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] From the left to the right ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
1894 else if ((pressed_idx[idx] == (PALM_HORIZ_ARRAY_COUNT - 1)) && (ret_idx == 0))
1896 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] From the right to the left ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
1898 else if ((pressed_idx[idx] == ret_idx) && ret_idx != 1)
1900 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] Relased the same region ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
1905 DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] Invalid ! pressed_idx=%d, released_idx=%d\n", pressed_idx[idx], ret_idx);
1909 pressed_idx[idx] = -1;
1916 GesturePalmGetAbsAxisInfo(DeviceIntPtr dev)
1923 Atom atom_tracking_id;
1927 g_pGesture->tpalm_idx = -1;
1928 g_pGesture->tmajor_idx = -1;
1929 g_pGesture->tminor_idx = -1;
1931 if (!dev || !dev->valuator)
1934 numAxes = dev->valuator->numAxes;
1936 atom_tpalm = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_PALM);
1937 atom_mt_slot = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_SLOT);
1938 atom_tracking_id = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TRACKING_ID);
1939 atom_tmajor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR);
1940 atom_tminor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR);
1942 if (!numAxes || !atom_tpalm || !atom_tmajor || !atom_tminor)
1944 ErrorF("one or more axes is/are not supported!\n");
1948 for (i = 0; i < numAxes; i++)
1950 AxisInfoPtr axes = &dev->valuator->axes[i];
1952 if (!axes || (axes->mode != Absolute))
1955 if (axes->label == atom_tpalm)
1957 g_pGesture->tpalm_idx = i;
1960 else if (axes->label == atom_tmajor)
1962 g_pGesture->tmajor_idx = i;
1965 else if (axes->label == atom_tminor)
1967 g_pGesture->tminor_idx = i;
1974 ErrorF("Axes for palm recognization are not supported !\n");
1978 g_pGesture->palm_misc.enabled = 1;
1979 ErrorF("Axes for palm recognization are supported !\n");
1983 g_pGesture->palm_misc.enabled = 0;
1984 ErrorF("Palm recognization is not supported !\n");
1989 GestureGetPalmValuator(InternalEvent *ev, DeviceIntPtr device)
1991 int mt_palm_idx = g_pGesture->tpalm_idx;
1994 DeviceEvent *de = &ev->device_event;
1998 ErrorF("[GestureGetPalmValuator] de is NULL !\n");
2002 if (mt_palm_idx < 0)
2004 ErrorF("[GestureGetPalmValuator] One or more of axes are not supported !\n");
2008 mt_palm = de->valuators.data[mt_palm_idx];
2010 HoldDetectorDebugPrint("[GestureGetPalmValuator] mt_palm:%d\n", mt_palm);
2015 static void GestureHoldDetector(int type, InternalEvent *ev, DeviceIntPtr device)
2019 pixman_region16_t tarea1;
2020 static int num_pressed = 0;
2021 unsigned int hold_area_size;
2022 PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
2025 if (!g_pGesture->has_hold_grabmask)
2027 HoldDetectorDebugPrint("[GestureHoldDetector] g_pGesture->has_hold_grabmask=%d\n", g_pGesture->has_hold_grabmask);
2029 Mask eventmask = (1L << GestureNotifyHold);
2031 if ((g_pGesture->grabMask & eventmask) &&
2032 (g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[0].window != None))
2034 g_pGesture->has_hold_grabmask = 1;
2036 //Initialize a set of variables
2038 memset(&g_pGesture->cts, 0, sizeof(g_pGesture->cts));
2039 pixman_region_init(&g_pGesture->chold_area);
2041 HoldDetectorDebugPrint("[GestureHoldDetector] Initialize...\n");
2045 //reset local hold_grab_mask variable
2046 g_pGesture->has_hold_grabmask = 0;
2048 g_pGesture->hold_detector_activate = 0;
2049 HoldDetectorDebugPrint("[GestureHoldDetector] has_hold_grabmask=0 and g_pGesture->hold_detector_activate=0\n");
2054 if (IGNORE_EVENTS == g_pGesture->ehtype ||
2055 device->id < g_pGesture->first_fingerid)
2057 HoldDetectorDebugPrint("[GestureHoldDetector] Return (IGNORE_EVENTS or device->id:%d < first_fingerid:%d)\n", device->id, g_pGesture->first_fingerid);
2061 palm_flag = GestureGetPalmValuator(ev, device);
2065 GestureHandleGesture_Hold(0, 0, 0, PALM_HOLD_TIME_THRESHOLD, GestureBegin);
2066 GestureHandleGesture_Hold(0, 0, 0, PALM_HOLD_TIME_THRESHOLD, GestureEnd);
2068 g_pGesture->hold_detector_activate = 0;
2069 g_pGesture->has_hold_grabmask = 0;
2070 HoldDetectorDebugPrint("[GestureHoldDetector] palm_flag:%d enable\n", palm_flag);
2075 HoldDetectorDebugPrint("[GestureHoldDetector] palm_flag:%d disable\n", palm_flag);
2079 HoldDetectorDebugPrint("[GestureHoldDetector] g_pGesture->num_mt_devices:%d\n", g_pGesture->num_mt_devices);
2081 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
2082 for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
2084 if( device->id == g_pGesture->mt_devices[i]->id )
2090 if( (idx < 0) || ((MAX_MT_DEVICES-1) < idx )) return;
2091 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
2092 idx = GestureGetTouchIndex(device->id, ev->device_event.touchid, type);
2093 if( (idx < 0) || ((g_pGesture->num_mt_devices -1) < idx )) return;
2094 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
2098 case GESTURE_TOUCH_PRESS:
2099 g_pGesture->cts[idx].status = BTN_PRESSED;
2100 g_pGesture->cts[idx].cx = ev->device_event.root_x;
2101 g_pGesture->cts[idx].cy = ev->device_event.root_y;
2103 HoldDetectorDebugPrint("[GestureHoldDetector][P] cx:%d, cy:%d, num_pressed:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy, num_pressed);
2105 if (num_pressed < 2)
2107 HoldDetectorDebugPrint("[GestureHoldDetector][P] num_pressed:%d\n", num_pressed);
2111 if (num_pressed > g_pGesture->num_mt_devices)
2112 num_pressed = g_pGesture->num_mt_devices;
2114 pixman_region_init(&tarea1);
2115 pixman_region_init(&g_pGesture->chold_area);
2116 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);
2118 tarea1.extents.x1 = g_pGesture->cts[0].cx;
2119 tarea1.extents.x2 = g_pGesture->cts[0].cx+1;
2120 tarea1.extents.y1 = g_pGesture->cts[0].cy;
2121 tarea1.extents.y2 = g_pGesture->cts[0].cy+1;
2123 pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1);
2125 for (i = 1; i < num_pressed; i++)
2127 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);
2129 tarea1.extents.x1 = g_pGesture->cts[i].cx;
2130 tarea1.extents.x2 = g_pGesture->cts[i].cx + 1;
2131 tarea1.extents.y1 = g_pGesture->cts[i].cy;
2132 tarea1.extents.y2 = g_pGesture->cts[i].cy + 1;
2134 pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1);
2138 case GESTURE_TOUCH_MOTION:
2139 if (BTN_RELEASED == g_pGesture->cts[idx].status)
2142 g_pGesture->cts[idx].status = BTN_MOVING;
2143 g_pGesture->cts[idx].cx = ev->device_event.root_x;
2144 g_pGesture->cts[idx].cy = ev->device_event.root_y;
2146 HoldDetectorDebugPrint("[GestureHoldDetector][M] cx:%d, cy:%d, num_pressed:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy, num_pressed);
2148 if (num_pressed < 2)
2150 HoldDetectorDebugPrint("[GestureHoldDetector][M] num_pressed:%d\n", num_pressed);
2154 pixman_region_init(&tarea1);
2155 pixman_region_init(&g_pGesture->chold_area);
2156 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);
2158 tarea1.extents.x1 = g_pGesture->cts[0].cx;
2159 tarea1.extents.x2 = g_pGesture->cts[0].cx+1;
2160 tarea1.extents.y1 = g_pGesture->cts[0].cy;
2161 tarea1.extents.y2 = g_pGesture->cts[0].cy+1;
2163 pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1);
2165 for (i = 1; i < num_pressed; i++)
2167 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);
2169 tarea1.extents.x1 = g_pGesture->cts[i].cx;
2170 tarea1.extents.x2 = g_pGesture->cts[i].cx + 1;
2171 tarea1.extents.y1 = g_pGesture->cts[i].cy;
2172 tarea1.extents.y2 = g_pGesture->cts[i].cy + 1;
2174 pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1);
2178 case GESTURE_TOUCH_RELEASE:
2179 g_pGesture->cts[idx].status = BTN_RELEASED;
2180 g_pGesture->cts[idx].cx = ev->device_event.root_x;
2181 g_pGesture->cts[idx].cy = ev->device_event.root_y;
2183 HoldDetectorDebugPrint("[GestureHoldDetector][R] cx:%d, cy:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy);
2188 pixman_region_init(&g_pGesture->chold_area);
2193 if (num_pressed >= 2)
2195 hold_area_size = AREA_SIZE(&g_pGesture->chold_area.extents);
2197 HoldDetectorDebugPrint("[GestureHoldDetector] hold_area_size=%d, pPalmMisc->half_scrn_area_size=%d\n", hold_area_size, pPalmMisc->half_scrn_area_size);
2199 if (pPalmMisc->half_scrn_area_size <= hold_area_size)
2201 GestureHandleGesture_Hold(0, AREA_CENTER_X(&g_pGesture->chold_area.extents), AREA_CENTER_Y(&g_pGesture->chold_area.extents), PALM_HOLD_TIME_THRESHOLD, GestureBegin);
2202 GestureHandleGesture_Hold(0, AREA_CENTER_X(&g_pGesture->chold_area.extents), AREA_CENTER_Y(&g_pGesture->chold_area.extents), PALM_HOLD_TIME_THRESHOLD, GestureEnd);
2204 g_pGesture->hold_detector_activate = 0;
2205 g_pGesture->has_hold_grabmask = 0;
2210 hold_area_size = AREA_SIZE(&g_pGesture->chold_area.extents);
2211 HoldDetectorDebugPrint("[GestureHoldDetector] num_pressed is under 2, hold_area_size=%d\n", hold_area_size);
2217 GesturePalmGetScreenInfo()
2220 pixman_region16_t tarea;
2221 PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
2222 ScreenPtr pScreen = miPointerCurrentScreen();
2226 DetailDebugPrint("[X11][GesturePalmGetScreenInfo]Failed to get screen information !\n");
2228 pPalmMisc->scrn_width = pPalmMisc->scrn_height = 0;
2232 pPalmMisc->scrn_width = pScreen->width;
2233 pPalmMisc->scrn_height = pScreen->height;
2234 pixman_region_init(&tarea);
2235 pixman_region_init_rect(&tarea, 0, 0, pPalmMisc->scrn_width, pPalmMisc->scrn_height);
2237 DetailDebugPrint("[X11][GesturePalmGetScreenInfo] x2:%d, x2:%d, y2:%d, y1:%d \n", tarea.extents.x2, tarea.extents.x1, tarea.extents.y2, tarea.extents.y1);
2238 pPalmMisc->half_scrn_area_size = AREA_SIZE(&tarea.extents);
2239 pPalmMisc->half_scrn_area_size = (unsigned int)((double)pPalmMisc->half_scrn_area_size / 4);
2241 DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->half_scrn_area_size = %d\n", pPalmMisc->half_scrn_area_size);
2243 for (i = 0; i < PALM_HORIZ_ARRAY_COUNT; i++)
2245 pPalmMisc->horiz_coord[i] = pPalmMisc->scrn_width * ((i+1)/(double)PALM_HORIZ_ARRAY_COUNT);
2246 DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->horiz_coord[%d]=%d, pPalmMisc->scrn_width=%d\n", i, pPalmMisc->horiz_coord[i], pPalmMisc->scrn_width);
2248 for (i = 0; i < PALM_VERTI_ARRAY_COUNT; i++)
2250 pPalmMisc->verti_coord[i] = pPalmMisc->scrn_height * ((i+1)/(double)PALM_VERTI_ARRAY_COUNT);
2251 DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->verti_coord[%d]=%d, pPalmMisc->scrn_height=%d\n", i, pPalmMisc->verti_coord[i], pPalmMisc->scrn_height);
2259 GestureEnableDisable()
2261 GestureEnable(1, FALSE, g_pGesture->this_device);
2263 if ((g_pGesture->grabMask) || (g_pGesture->lastSelectedWin != None))
2265 GestureEnable(1, FALSE, g_pGesture->this_device);
2269 GestureEnable(0, FALSE, g_pGesture->this_device);
2275 GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent)
2277 g_pGesture->grabMask = *pGrabMask;
2278 g_pGesture->GrabEvents = (GestureGrabEventPtr)pGrabEvent;
2279 GestureEnableDisable();
2283 GestureCbEventsSelected(Window win, Mask *pEventMask)
2285 g_pGesture->lastSelectedWin = win;
2286 g_pGesture->lastSelectedMask = (pEventMask) ? *pEventMask : 0;
2287 GestureEnableDisable();
2291 GestureGetEventsWindow(void)
2296 pWin = GestureWindowOnXY(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py);
2300 DetailDebugPrint("[GestureGetEventsWindow] pWin->drawable.id=0x%x\n", pWin->drawable.id);
2301 g_pGesture->gestureWin = pWin->drawable.id;
2305 DetailDebugPrint("[GestureGetEventsWindow] GestureWindowOnXY returns NULL !\n");
2309 if (g_pGesture->gestureWin == g_pGesture->lastSelectedWin)
2311 g_pGesture->eventMask = g_pGesture->lastSelectedMask;
2312 goto nonempty_eventmask;
2315 //check selected event(s)
2316 if (!GestureHasSelectedEvents(pWin, &g_pGesture->eventMask))
2318 g_pGesture->eventMask = 0;
2322 g_pGesture->lastSelectedWin = g_pGesture->gestureWin;
2323 g_pGesture->lastSelectedMask = g_pGesture->eventMask;
2326 if (!g_pGesture->eventMask && !g_pGesture->grabMask)
2328 DetailDebugPrint("[X11][GestureGetEventsWindow] No grabbed events or no events were selected for window(0x%x) !\n", pWin->drawable.id);
2334 DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->eventMask=0x%x\n", g_pGesture->eventMask);
2336 mask = (GESTURE_FILTER_MASK_ALL & ~(g_pGesture->grabMask | g_pGesture->eventMask));
2338 DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x, mask=0x%x\n", g_pGesture->filter_mask, mask);
2340 g_pGesture->filter_mask = mask;
2342 DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x\n", g_pGesture->filter_mask);
2348 GestureSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2350 g_pGesture->filter_mask |= WTapFilterMask;
2351 g_pGesture->filter_mask |= WHoldFilterMask;
2352 //LOGI("[GroupTap][GroupHold] 50ms after 1st finger.\n");
2354 DetailDebugPrint("[GestureSingleFingerTimerHandler] TapFilterMask, HoldFilterMask \n");
2356 if ((g_pGesture->event_sum[0] == BTN_PRESSED) && ((g_pGesture->flick_pressed_point <= FLICK_POINT_NONE) && (FLICK_POINT_MAX <= g_pGesture->flick_pressed_point)))
2358 DetailDebugPrint("[GestureSingleFingerTimerHandler] press_point: %d\n", g_pGesture->flick_pressed_point);
2359 DetailDebugPrint("[GestureSingleFingerTimerHandler] FlickFilterMask\n");
2360 g_pGesture->filter_mask |= WFlickFilterMask;
2363 if (g_pGesture->flick_pressed_point == FLICK_POINT_DOWN && abs(g_pGesture->fingers[0].py - g_pGesture->fingers[0].my) < 3)
2365 DetailDebugPrint("[GestureSingleFingerTimerHandler] py: %d, my: %d\n", g_pGesture->fingers[0].py, g_pGesture->fingers[0].my);
2366 DetailDebugPrint("[GestureSingleFingerTimerHandler] FlickFilterMask\n");
2367 g_pGesture->filter_mask |= WFlickFilterMask;
2370 DetailDebugPrint("[GestureSingleFingerTimerHandler] expired !\n");
2372 if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
2374 if ( ERROR_INVALPTR == GestureFlushOrDrop())
2376 DetailDebugPrint("[GestureSingleFingerTimerHandler] AllFilterMask, Flush!\n");
2377 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2385 GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
2388 static OsTimerPtr single_finger_timer = NULL;
2391 if (PROPAGATE_EVENTS == g_pGesture->ehtype || device->id < g_pGesture->first_fingerid)
2395 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
2396 for (i = 0; i < g_pGesture->num_mt_devices; i++)
2398 if (device->id == g_pGesture->mt_devices[i]->id)
2404 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
2405 idx = GestureGetTouchIndex(device->id, ev->device_event.touchid, type);
2406 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
2413 case GESTURE_TOUCH_PRESS:
2416 g_pGesture->event_sum[0] = BTN_PRESSED;
2419 g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
2421 g_pGesture->fingers[idx].ptime = ev->any.time;
2422 g_pGesture->fingers[idx].px = ev->device_event.root_x;
2423 g_pGesture->fingers[idx].py = ev->device_event.root_y;
2425 g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
2426 g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
2427 g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT;
2428 g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT;
2430 g_pGesture->num_pressed++;
2431 g_pGesture->inc_num_pressed = g_pGesture->num_pressed;
2433 if (g_pGesture->inc_num_pressed == 1)
2435 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2439 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2441 for (i = 1; i < g_pGesture->inc_num_pressed; i++)
2443 pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
2447 DetailDebugPrint("[GestureRecognize][P] num_pressed=%d, area_size=%d, px=%d, py=%d\n",
2448 g_pGesture->num_pressed, AREA_SIZE(&g_pGesture->area.extents), g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
2450 if (g_pGesture->num_pressed == 1)
2452 single_finger_timer = TimerSet(single_finger_timer, 0, 50, GestureSingleFingerTimerHandler, NULL);
2454 if (g_pGesture->fingers[idx].py <= g_pGesture->flick_press_area)
2456 if ((!g_pGesture->activate_flick_down)
2457 || (g_pGesture->fingers[idx].px <= (g_pGesture->flick_press_area_left_right))
2458 || (g_pGesture->fingers[idx].px >= (g_pGesture->screen_width - g_pGesture->flick_press_area_left_right)))
2460 DetailDebugPrint("[GestureRecognize][P] px=%d, flick_press_area_left_right=%d\n",
2461 g_pGesture->fingers[idx].px, g_pGesture->flick_press_area_left_right);
2462 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2463 LOGI("[BackKey][F] Press touch within 40 pixel area from left or right vezel\n");
2467 DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_UP\n");
2468 g_pGesture->flick_pressed_point = FLICK_POINT_UP;
2473 LOGI("[BackKey][F] Press touch outside 40 pixel area from upper vezel. \n");
2476 if (g_pGesture->fingers[idx].py >= (g_pGesture->screen_height - g_pGesture->flick_press_area))
2478 if (!g_pGesture->activate_flick_up)
2480 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2484 DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_DOWN\n");
2485 g_pGesture->flick_pressed_point = FLICK_POINT_DOWN;
2488 else if ( g_pGesture->fingers[idx].px <= g_pGesture->flick_press_area_left)
2490 if (!g_pGesture->activate_flick_right)
2492 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2496 DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_LEFT\n");
2497 g_pGesture->flick_pressed_point = FLICK_POINT_LEFT;
2501 DetailDebugPrint("[GestureRecognize][P] flick_press_point: %d\n", g_pGesture->flick_pressed_point);
2503 if ((g_pGesture->flick_pressed_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= g_pGesture->flick_pressed_point))
2505 DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_NONE\n");
2506 g_pGesture->filter_mask |= WFlickFilterMask;
2507 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2511 g_pGesture->flick_direction = (g_pGesture->flick_pressed_point - 1) * 2;
2512 if ((g_pGesture->flick_direction == FLICK_WESTWARD) && (g_pGesture->power_pressed != 2))
2514 DetailDebugPrint("[GestureRecognize][P] Flick WesWard is disable when power is not pressed\n");
2515 g_pGesture->filter_mask |= WFlickFilterMask;
2516 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2518 if ((g_pGesture->flick_direction < FLICK_NORTHWARD) || (FLICK_NORTHWESTWARD < g_pGesture->flick_direction))
2520 DetailDebugPrint("[GestureRecognize][P] Invalid flick direction\n");
2521 g_pGesture->filter_mask |= WFlickFilterMask;
2522 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2525 DetailDebugPrint("[GestureRecognize][P] flick_direction: %d\n", g_pGesture->flick_direction);
2530 DetailDebugPrint("[GestureRecognize][P] Two more fingers come on!\n");
2531 TimerCancel(single_finger_timer);
2532 single_finger_timer = NULL;
2536 case GESTURE_TOUCH_MOTION:
2538 if (!g_pGesture->fingers[idx].ptime)
2540 DetailDebugPrint("[GestureRecognize][M] Start motion. idx=%d\n", idx);
2541 g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
2545 g_pGesture->fingers[idx].mx = ev->device_event.root_x;
2546 g_pGesture->fingers[idx].my = ev->device_event.root_y;
2547 g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
2551 g_pGesture->event_sum[0] += BTN_MOVING;
2554 g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
2555 g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
2556 g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT;
2557 g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT;
2559 if (g_pGesture->inc_num_pressed == 1)
2561 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2565 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2567 for (i = 1; i < g_pGesture->inc_num_pressed; i++)
2569 pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
2573 DetailDebugPrint("[GestureRecognize][M] num_pressed=%d, area_size=%d, mx=%d, my=%d\n",
2574 g_pGesture->num_pressed, AREA_SIZE(&g_pGesture->area.extents), g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].my);
2578 case GESTURE_TOUCH_RELEASE:
2579 g_pGesture->fingers[idx].rtime = ev->any.time;
2580 g_pGesture->fingers[idx].rx = ev->device_event.root_x;
2581 g_pGesture->fingers[idx].ry = ev->device_event.root_y;
2582 g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
2584 g_pGesture->num_pressed--;
2586 if (g_pGesture->num_pressed == 0)
2588 DetailDebugPrint("[GestureRecognize] All fingers were released !\n");
2590 else if (g_pGesture->num_pressed < 0)
2592 DetailDebugPrint("[GestureRecognize] All fingers were released. But, num_pressed is under 0 !\n");
2595 DetailDebugPrint("[GestureRecognize][R] num_pressed=%d, rx=%d, ry=%d\n",
2596 g_pGesture->num_pressed, g_pGesture->fingers[idx].rx, g_pGesture->fingers[idx].ry);
2601 if (!(g_pGesture->filter_mask & WFlickFilterMask))
2603 DetailDebugPrint("[GestureRecognize] GestureRecognize_groupFlick !\n");
2604 GestureRecognize_GroupFlick(type, ev, device, idx, g_pGesture->flick_pressed_point, g_pGesture->flick_direction);
2606 if (!(g_pGesture->filter_mask & WTapFilterMask))
2608 DetailDebugPrint("[GestureRecognize] GestureRecognize_groupTap !\n");
2609 GestureRecognize_GroupTap(type, ev, device, idx, 0);
2611 if (!(g_pGesture->filter_mask & WHoldFilterMask))
2613 DetailDebugPrint("[GestureRecognize] GestureRecognize_groupHold !\n");
2614 GestureRecognize_GroupHold(type, ev, device, idx, 0);
2617 if (!(g_pGesture->filter_mask & WPalmFlickFilterMask))
2619 DetailDebugPrint("[GestureRecognize] GestureRecognize_palmFlick !\n");
2620 GestureRecognize_PalmFlick(type, ev, device, idx);
2623 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",
2624 g_pGesture->filter_mask, GESTURE_WATCH_FILTER_MASK_ALL, g_pGesture->recognized_gesture);
2626 if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
2628 if (!g_pGesture->recognized_gesture)
2630 DetailDebugPrint("[GestureRecognize][F] 1 !\n");
2633 else if (!g_pGesture->num_pressed)
2635 DetailDebugPrint("[GestureRecognize][F] 2 !\n");
2640 if (g_pGesture->recognized_gesture)
2642 if (g_pGesture->ehtype == KEEP_EVENTS)
2644 DetailDebugPrint("[GestureRecognize] Keep Event !\n");
2645 GestureEventsDrop();
2647 g_pGesture->ehtype = IGNORE_EVENTS;
2653 DetailDebugPrint("[GestureRecognize] GestureFlushOrDrop() !\n");
2655 if (ERROR_INVALPTR == GestureFlushOrDrop())
2657 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2661 ErrorStatus GestureFlushOrDrop(void)
2665 if (g_pGesture->recognized_gesture)
2667 g_pGesture->ehtype = IGNORE_EVENTS;
2668 GestureEventsDrop();
2669 DetailDebugPrint("[GestureFlushOrDrop][Drop] IGNORE_EVENTS\n");
2673 g_pGesture->ehtype = PROPAGATE_EVENTS;
2675 err = GestureEventsFlush();
2677 if (ERROR_NONE != err)
2682 DetailDebugPrint("[GestureFlushOrDrop][Flush] PROPAGATE_EVENTS\n");
2683 DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask);
2684 DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->GESTURE_WATCH_FILTER_MASK_ALL = 0x%x\n", GESTURE_WATCH_FILTER_MASK_ALL);
2685 DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture);
2688 err = GestureRegionsReinit();
2690 if (ERROR_NONE != err)
2695 g_pGesture->pTempWin = NULL;
2696 g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0;
2697 g_pGesture->event_sum[0] = 0;
2703 GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2708 #ifdef __DEBUG_EVENT_HANDLER__
2709 DetailDebugPrint("[GestureHandleMTSyncEvent] (%d:%d) time:%d cur:%d\n",
2710 ev->any_event.deviceid, ev->any_event.sync, (int)ev->any.time, (int)GetTimeInMillis());
2713 if (!g_pGesture->is_active)
2715 g_pGesture->ehtype = PROPAGATE_EVENTS;
2716 DetailDebugPrint("[GestureHandleMTSyncEvent] PROPAGATE_EVENT\n");
2720 switch(ev->any_event.sync)
2722 case ROTARY_FRAME_SYNC_BEGIN:
2723 if (!g_pGesture->rotary_id) {
2724 g_pGesture->rotary_id = device->id;
2725 g_pGesture->rotary_dev = device;
2727 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
2728 if (g_pGesture->mt_devices[0]
2729 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
2730 if (g_pGesture->mt_devices
2731 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
2732 && (g_pGesture->mtsync_flag & MTSYNC_FLAG_TOUCH))
2735 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
2736 xf86PostButtonEvent(g_pGesture->mt_devices[0], 0, Button1, 0, 0, 2, &zero, &zero);
2737 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
2738 xf86PostButtonEvent(g_pGesture->mt_devices, 0, Button1, 0, 0, 2, &zero, &zero);
2739 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
2741 g_pGesture->mtsync_flag |= MTSYNC_FLAG_ROTARY;
2742 DetailDebugPrint("[GestureHandleMTSyncEvent] Rotary input starts. Now touch events are dropped!\n");
2744 case ROTARY_FRAME_SYNC_END:
2745 g_pGesture->mtsync_flag &= ~MTSYNC_FLAG_ROTARY;
2746 DetailDebugPrint("[GestureHandleMTSyncEvent] Rotary input is finished. Now touch events are not dropped!\n");
2748 case MTOUCH_FRAME_SYNC_BEGIN:
2749 g_pGesture->mtsync_flag |= MTSYNC_FLAG_TOUCH;
2750 DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_BEGIN\n");
2751 g_pGesture->ehtype = KEEP_EVENTS;
2752 g_pGesture->filter_mask = 0;
2753 g_pGesture->recognized_gesture = 0;
2754 g_pGesture->hold_detector_activate = 1;
2755 g_pGesture->num_pressed = 0;
2756 g_pGesture->has_hold_grabmask = 0;
2757 g_pGesture->mtsync_total_count = 0;
2759 for (i=0; i < g_pGesture->num_mt_devices; i++)
2761 g_pGesture->fingers[i].ptime = 0;
2762 g_pGesture->max_mt_tmajor[i] = 0;
2765 case MTOUCH_FRAME_SYNC_END:
2766 g_pGesture->mtsync_flag &= ~MTSYNC_FLAG_TOUCH;
2767 DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_END\n");
2768 g_pGesture->ehtype = PROPAGATE_EVENTS;
2769 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2770 g_pGesture->pTempWin = NULL;
2771 g_pGesture->num_pressed = 0;
2772 g_pGesture->hold_detected = FALSE;
2774 case MTOUCH_FRAME_SYNC_UPDATE:
2775 g_pGesture->mtsync_flag |= MTSYNC_FLAG_TOUCH;
2776 g_pGesture->mtsync_total_count++;
2778 DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_Update. mt_total_sync=%d\n", g_pGesture->mtsync_total_count);
2780 if ((g_pGesture->inc_num_pressed < 2) && (g_pGesture->filter_mask != GESTURE_WATCH_FILTER_MASK_ALL))
2782 if (g_pGesture->num_tap_repeated == 1 || g_pGesture->num_tap_repeated == 2)
2784 if (g_pGesture->mtsync_total_count >= 6)
2786 DetailDebugPrint("[GestureHandleMTSyncEvent] Moving Limit first tap repeated. tap_repeated: %d, mtsync_total_count: %d\n",
2787 g_pGesture->num_tap_repeated, g_pGesture->mtsync_total_count);
2788 g_pGesture->filter_mask |= WTapFilterMask;
2789 g_pGesture->filter_mask |= WHoldFilterMask;
2790 LOGI("[GroupTap][GroupHold] Motions are more than 6 between 1st finger and 2nd finger.\n");
2794 if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
2796 DetailDebugPrint("[GestureHandleMTSyncEvent] Gesture filter mask all. GestureFlushOrDrop() !\n");
2798 if (ERROR_INVALPTR == GestureFlushOrDrop())
2800 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2806 ErrorF("[GestureHandleMTSyncEvent] Unknown MTSync Event received.\n");
2811 void GestureEmulateHWKey(DeviceIntPtr dev, int keycode)
2815 DetailDebugPrint("[GestureEmulateHWKey] keycode=%d\n", keycode);
2816 xf86PostKeyboardEvent(dev, keycode, 1);
2817 xf86PostKeyboardEvent(dev, keycode, 0);
2822 GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2824 TTRACE_BEGIN("XORG:GESTURE:BUTTON_PRESS");
2825 #ifdef __DEBUG_EVENT_HANDLER__
2826 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);
2827 #endif//__DEBUG_EVENT_HANDLER__
2828 #ifndef _SUPPORT_EVDEVMULTITOUCH_DRV_
2831 idx = GestureFindTouchIndex(ev->device_event.deviceid, ev->device_event.touchid, ev->device_event.type);
2832 if (idx < 0 && ev->device_event.deviceid != g_pGesture->master_pointer->id) {
2833 device->public.processInputProc(ev, device);
2836 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
2838 if (g_pGesture->ehtype != KEEP_EVENTS)
2840 if(g_pGesture->mtsync_flag & MTSYNC_FLAG_ROTARY)
2842 DetailDebugPrint("[GestureHandleButtonPressEvent] Rotary input is coming. Dropping touch events.\n");
2845 else if (g_pGesture->mtsync_flag & ~MTSYNC_FLAG_TOUCH)
2847 DetailDebugPrint("[GestureHandleButtonPressEvent] Other input is coming. Dropping touch events.\n");
2852 switch (g_pGesture->ehtype)
2855 DetailDebugPrint("[GestureHandleButtonPressEvent] KEEP_EVENT\n");
2857 if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device))
2859 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2863 if (g_pGesture->num_mt_devices)
2865 GestureRecognize(GESTURE_TOUCH_PRESS, ev, device);
2869 device->public.processInputProc(ev, device);
2872 GestureHoldDetector(GESTURE_TOUCH_PRESS, ev, device);
2875 case PROPAGATE_EVENTS:
2876 DetailDebugPrint("[GestureHandleButtonPressEvent] PROPAGATE_EVENT\n");
2878 device->public.processInputProc(ev, device);
2879 GestureHoldDetector(GESTURE_TOUCH_PRESS, ev, device);
2883 DetailDebugPrint("[GestureHandleButtonPressEvent] IGNORE_EVENTS\n");
2885 GestureRecognize(GESTURE_TOUCH_PRESS, ev, device);
2897 GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2899 TTRACE_BEGIN("XORG:GESTURE:MOTION");
2900 #ifdef __DEBUG_EVENT_MOTION_HANDLER__
2901 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);
2903 #ifndef _SUPPORT_EVDEVMULTITOUCH_DRV_
2906 idx = GestureFindTouchIndex(ev->device_event.deviceid, ev->device_event.touchid, ev->device_event.type);
2907 if (idx < 0 && ev->device_event.deviceid != g_pGesture->master_pointer->id) {
2908 device->public.processInputProc(ev, device);
2911 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
2913 if (g_pGesture->ehtype != KEEP_EVENTS)
2915 if(g_pGesture->mtsync_flag & MTSYNC_FLAG_ROTARY)
2917 DetailDebugPrint("[GestureHandleMotionEvent] Rotary input is coming. Dropping touch events.\n");
2920 else if (g_pGesture->mtsync_flag & ~MTSYNC_FLAG_TOUCH)
2922 DetailDebugPrint("[GestureHandleMotionEvent] Other input is coming. Dropping touch events.\n");
2927 switch (g_pGesture->ehtype)
2930 if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device))
2932 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2936 if (g_pGesture->num_mt_devices)
2938 GestureRecognize(GESTURE_TOUCH_MOTION, ev, device);
2942 device->public.processInputProc(ev, device);
2945 GestureHoldDetector(GESTURE_TOUCH_MOTION, ev, device);
2948 case PROPAGATE_EVENTS:
2949 device->public.processInputProc(ev, device);
2950 GestureHoldDetector(GESTURE_TOUCH_MOTION, ev, device);
2954 GestureRecognize(GESTURE_TOUCH_MOTION, ev, device);
2966 GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2968 TTRACE_BEGIN("XORG:GESTURE:BUTTON_RELEASE");
2969 #ifdef __DEBUG_EVENT_HANDLER__
2970 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);
2972 #ifndef _SUPPORT_EVDEVMULTITOUCH_DRV_
2975 idx = GestureFindTouchIndex(ev->device_event.deviceid, ev->device_event.touchid, ev->device_event.type);
2976 if (idx < 0 && ev->device_event.deviceid != g_pGesture->master_pointer->id) {
2977 device->public.processInputProc(ev, device);
2980 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
2982 if (g_pGesture->ehtype != KEEP_EVENTS)
2984 if(!(g_pGesture->mtsync_flag & MTSYNC_FLAG_TOUCH))
2986 if(g_pGesture->mtsync_flag & MTSYNC_FLAG_ROTARY)
2988 DetailDebugPrint("[GestureHandleButtonReleaseEvent] Rotary input is coming. Dropping touch events.\n");
2991 else if (g_pGesture->mtsync_flag & ~MTSYNC_FLAG_TOUCH)
2993 DetailDebugPrint("[GestureHandleButtonReleaseEvent] Other input is coming. Dropping touch events.\n");
2999 switch (g_pGesture->ehtype)
3002 DetailDebugPrint("[GestureHandleButtonPressEvent] KEEP_EVENT\n");
3004 if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device))
3006 GestureControl(g_pGesture->this_device, DEVICE_OFF);
3010 if (g_pGesture->num_mt_devices)
3012 GestureRecognize(GESTURE_TOUCH_RELEASE, ev, device);
3016 device->public.processInputProc(ev, device);
3019 GestureHoldDetector(GESTURE_TOUCH_RELEASE, ev, device);
3022 case PROPAGATE_EVENTS:
3023 DetailDebugPrint("[GestureHandleButtonPressEvent] PROPAGATE_EVENTS\n");
3024 #ifdef SUPPORT_ANR_WITH_INPUT_EVENT
3025 if( IsMaster(device) && ev->any.type == GESTURE_TOUCH_RELEASE )
3027 if( g_pGesture->anr_window == NULL )
3029 g_pGesture->anr_window = _GestureFindANRWindow(device);
3033 // Send event to the e17 process.
3034 current_time = GetTimeInMillis();
3035 if( g_pGesture->anr_window != NULL )
3037 // Check anr_window validation.
3038 if( dixLookupWindow(&g_pGesture->anr_window, prop_anr_event_window_xid, serverClient, DixSetPropAccess) != BadWindow )
3040 if( serverClient->devPrivates != NULL )
3041 dixChangeWindowProperty (serverClient, g_pGesture->anr_window, prop_anr_in_input_event,
3042 XA_CARDINAL, 32, PropModeReplace, 1, ¤t_time, TRUE);
3046 prop_anr_event_window_xid = 0;
3047 g_pGesture->anr_window = NULL;
3049 DetailDebugPrint("[GestureHandleButtonReleaseEvent] Release TOUCH!! devid=%d time:%d cur: %d\n", device->id, ev->any.time, GetTimeInMillis());
3053 device->public.processInputProc(ev, device);
3054 GestureHoldDetector(GESTURE_TOUCH_RELEASE, ev, device);
3056 GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down);
3057 GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up);
3062 DetailDebugPrint("[GestureHandleButtonReleaseEvent] IGNORE_EVENTS\n");
3063 GestureRecognize(GESTURE_TOUCH_RELEASE, ev, device);
3075 GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
3077 TTRACE_BEGIN("XORG:GESTURE:KEY_PRESS");
3078 if ((ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0))
3080 g_pGesture->power_pressed = 2;
3081 g_pGesture->power_device = device;
3083 DetailDebugPrint("[GestureHandleKeyPressEvent] power key pressed devid: %d, hwkey_id: %d\n", device->id, g_pGesture->hwkey_id);
3084 DetailDebugPrint("[GestureHandleKeyPressEvent] power_pressed: %d\n", g_pGesture->power_pressed);
3087 device->public.processInputProc(ev, device);
3091 GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
3093 TTRACE_BEGIN("XORG:GESTURE:KEY_RELEASE");
3094 if ((ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0))
3096 g_pGesture->power_pressed = 1;
3097 g_pGesture->power_device = device;
3099 DetailDebugPrint("[GestureHandleKeyReleaseEvent] power key released devid: %d, hwkey_id: %d\n", device->id, g_pGesture->hwkey_id);
3100 DetailDebugPrint("[GestureHandleKeyReleaseEvent] power_pressed: %d\n", g_pGesture->power_pressed);
3103 device->public.processInputProc(ev, device);
3107 GestureHandleClientState (CallbackListPtr *list, pointer closure, pointer calldata)
3109 NewClientInfoRec *clientinfo = (NewClientInfoRec*)calldata;
3110 ClientPtr client = clientinfo->client;
3112 if (client->clientState != ClientStateGone)
3117 if (!g_pGesture->factory_cmdname)
3122 if (strncmp(client->clientIds->cmdname, g_pGesture->factory_cmdname, strlen(g_pGesture->factory_cmdname)))
3127 if (g_pGesture->is_active == 0)
3130 int rc = XIChangeDeviceProperty(g_pGesture->this_device, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &prop_val, FALSE);
3132 ErrorF("[GestureHandleClientState] %s is exited unintentionally\n", g_pGesture->factory_cmdname);
3136 ErrorF("[GestureHandleClientState] Failed to Gesture Enable\n");
3143 GestureEnableEventHandler(InputInfoPtr pInfo)
3146 GestureDevicePtr pGesture = pInfo->private;
3148 TTRACE_BEGIN("XORG:GESTURE:ENABLE_EVENT_HANDLER");
3150 res = GestureInstallResourceStateHooks();
3154 ErrorF("[GestureEnableEventHandler] Failed on GestureInstallResourceStateHooks() !\n");
3156 return ERROR_ABNORMAL;
3159 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
3160 res = GestureSetMaxNumberOfFingers((int)MAX_MT_DEVICES);
3163 ErrorF("[GestureEnableEventHandler] Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)MAX_MT_DEVICES);
3166 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
3168 res = GestureRegisterCallbacks(GestureCbEventsGrabbed, GestureCbEventsSelected);
3172 ErrorF("[GestureEnableEventHandler] Failed to register callbacks for GestureEventsGrabbed(), GestureEventsSelected() !\n");
3176 GestureRegisterDeviceInfo(pInfo->dev);
3182 GestureUninstallResourceStateHooks();
3183 GestureUnsetMaxNumberOfFingers();
3186 return ERROR_ABNORMAL;
3190 GestureDisableEventHandler(void)
3192 ErrorStatus err = ERROR_NONE;
3194 mieqSetHandler(GESTURE_TOUCH_PRESS, NULL);
3195 mieqSetHandler(GESTURE_TOUCH_RELEASE, NULL);
3196 mieqSetHandler(GESTURE_TOUCH_MOTION, NULL);
3197 mieqSetHandler(ET_KeyPress, NULL);
3198 mieqSetHandler(ET_KeyRelease, NULL);
3199 mieqSetHandler(ET_MTSync, NULL);
3201 err = GestureFiniEQ();
3203 if (ERROR_INVALPTR == err)
3205 ErrorF("[GestureDisableEventHandler] EQ is invalid or was freed already !\n");
3208 GestureRegisterCallbacks(NULL, NULL);
3209 GestureUninstallResourceStateHooks();
3215 GestureRegisterDeviceInfo(DeviceIntPtr device)
3217 InputInfoPtr pInfo = device->public.devicePrivate;
3218 GestureDevicePtr pGesture = pInfo->private;
3220 ScreenPtr pScreen = miPointerCurrentScreen();
3221 int width = 0, height = 0;
3225 TTRACE_BEGIN("XORG:GESTURE:REGISTER_DEVICE");
3226 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
3227 for (i=0; i<MAX_MT_DEVICES; i++)
3229 pGesture->mt_devices[i] = NULL;
3231 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
3232 pGesture->mt_devices = NULL;
3233 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
3235 for( dev = inputInfo.pointer ; dev; dev = dev->next )
3237 if(IsMaster(dev) && IsPointerDevice(dev))
3239 pGesture->master_pointer = dev;
3240 ErrorF("[id:%d] Master Pointer=%s\n", dev->id, pGesture->master_pointer->name);
3244 if(IsXTestDevice(dev, NULL) && IsPointerDevice(dev))
3246 pGesture->xtest_pointer = dev;
3247 ErrorF("[id:%d] XTest Pointer=%s\n", dev->id, pGesture->xtest_pointer->name);
3251 if(IsPointerDevice(dev))
3253 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
3254 if( idx >= MAX_MT_DEVICES )
3256 ErrorF("Number of mt device is over MAX_MT_DEVICES(%d) !\n", MAX_MT_DEVICES);
3259 if (strcasestr(dev->name, "Touchscreen"))
3261 pGesture->mt_devices[idx] = dev;
3262 ErrorF("[id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name);
3263 GesturePalmGetAbsAxisInfo(dev);
3266 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
3267 if (strcasestr(dev->name, "Touchscreen"))
3269 pGesture->mt_devices = dev;
3270 ErrorF("[id: %d] MT device name=%s\n", dev->id, pGesture->mt_devices->name);
3271 TouchClassPtr touchInfo = dev->touch;
3274 ErrorF("touchInfo state: %d, num_touches: %d, max_touches: %d\n",
3275 touchInfo->state, touchInfo->num_touches, touchInfo->max_touches);
3276 idx = touchInfo->max_touches;
3280 ErrorF("device(%d) hasn't touch class\n", dev->id);
3283 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
3287 if( !pGesture->master_pointer || !pGesture->xtest_pointer )
3289 ErrorF("Failed to get info of master pointer or XTest pointer !\n");
3290 pGesture->num_mt_devices = 0;
3296 pGesture->num_mt_devices = idx;
3298 if( !pGesture->num_mt_devices )
3300 ErrorF("Failed to mt device information !\n");
3301 pGesture->num_mt_devices = 0;
3302 pGesture->first_fingerid = -1;
3307 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
3308 pGesture->first_fingerid = pGesture->mt_devices[0]->id;
3309 memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices);
3310 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
3311 GestureAlloc(pGesture->num_mt_devices);
3312 pGesture->first_fingerid = pGesture->mt_devices->id;
3313 GesturePalmGetAbsAxisInfo(dev);
3314 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
3316 #ifndef _SUPPORT_EVDEVMULTITOUCH_DRV_
3317 Bool res = GestureSetMaxNumberOfFingers(g_pGesture->num_mt_devices);
3321 ErrorF("Failed on GestureSetMaxNumberOfFingers(%d) !\n", g_pGesture->num_mt_devices);
3324 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
3326 pGesture->pRootWin = RootWindow(pGesture->master_pointer);
3328 if(g_pGesture->palm_misc.enabled)
3329 GesturePalmGetScreenInfo();
3331 g_pGesture->pTempWin = NULL;
3332 g_pGesture->inc_num_pressed = 0;
3334 if( ERROR_NONE != GestureRegionsInit() || ERROR_NONE != GestureInitEQ() )
3339 mieqSetHandler(ET_KeyPress, GestureHandleKeyPressEvent);
3340 mieqSetHandler(ET_KeyRelease, GestureHandleKeyReleaseEvent);
3341 mieqSetHandler(GESTURE_TOUCH_PRESS, GestureHandleButtonPressEvent);
3342 mieqSetHandler(GESTURE_TOUCH_RELEASE, GestureHandleButtonReleaseEvent);
3343 mieqSetHandler(GESTURE_TOUCH_MOTION, GestureHandleMotionEvent);
3344 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
3350 GestureUninstallResourceStateHooks();
3351 GestureUnsetMaxNumberOfFingers();
3355 #ifndef _SUPPORT_EVDEVMULTITOUCH_DRV_
3357 GestureAlloc(int capability)
3361 ErrorF("[GestureAlloc] Failed to allocate a gesture drv's structures\n");
3365 g_pGesture->cts = (CurTouchStatus *)calloc(capability, sizeof(CurTouchStatus));
3366 g_pGesture->finger_rects = (pixman_region16_t *)calloc(capability, sizeof(pixman_region16_t));
3367 g_pGesture->fingers = (TouchStatus *)calloc(capability, sizeof(TouchStatus));
3368 g_pGesture->event_sum= (int *)calloc(capability, sizeof(int));
3369 g_pGesture->max_mt_tmajor = (int *)calloc(capability, sizeof(int));
3371 /* g_pGesture->palmFlickInfo */
3373 g_pGesture->palmFlickInfo.base_x = (int *)calloc(capability, sizeof(int));
3374 g_pGesture->palmFlickInfo.base_y = (int *)calloc(capability, sizeof(int));
3375 g_pGesture->palmFlickInfo.update_x = (int *)calloc(capability, sizeof(int));
3376 g_pGesture->palmFlickInfo.update_y = (int *)calloc(capability, sizeof(int));
3378 g_pGesture->palmFlickInfo.current_x = (int *)calloc(capability, sizeof(int));
3379 g_pGesture->palmFlickInfo.current_y = (int *)calloc(capability, sizeof(int));
3380 g_pGesture->palmFlickInfo.press_status = (Bool *)calloc(capability, sizeof(Bool));
3381 g_pGesture->palmFlickInfo.release_status = (Bool *)calloc(capability, sizeof(Bool));
3383 g_pGesture->palmFlickInfo.line_idx = (int *)calloc(capability, sizeof(int));
3384 g_pGesture->palmFlickInfo.prev_line_idx = (int *)calloc(capability, sizeof(int));
3385 g_pGesture->palmFlickInfo.press_idx = (int *)calloc(capability, sizeof(int));
3386 g_pGesture->palmFlickInfo.is_line_invalid = (Bool *)calloc(capability, sizeof(Bool));
3388 g_pGesture->palmFlickInfo.max_tmajor = (int *)calloc(capability, sizeof(int));
3389 g_pGesture->palmFlickInfo.is_tmajor_invalid = (Bool *)calloc(capability, sizeof(Bool));
3390 g_pGesture->palmFlickInfo.mt_sync_count = (int *)calloc(capability, sizeof(int));
3392 /* g_pGesture->palmInfo */
3394 g_pGesture->palmInfo.pressed_idx = (int *)calloc(capability, sizeof(int));
3409 ErrorF("[GestureDealloc] Failed to free a gesture drv's structures\n");
3413 GFree(g_pGesture->cts)
3414 GFree(g_pGesture->finger_rects)
3415 GFree(g_pGesture->fingers)
3416 GFree(g_pGesture->event_sum)
3417 GFree(g_pGesture->max_mt_tmajor)
3419 /* g_pGesture->palmFlickInfo */
3421 GFree(g_pGesture->palmFlickInfo.base_x)
3422 GFree(g_pGesture->palmFlickInfo.base_y)
3423 GFree(g_pGesture->palmFlickInfo.update_x)
3424 GFree(g_pGesture->palmFlickInfo.update_y)
3426 GFree(g_pGesture->palmFlickInfo.current_x)
3427 GFree(g_pGesture->palmFlickInfo.current_y)
3428 GFree(g_pGesture->palmFlickInfo.press_status)
3429 GFree(g_pGesture->palmFlickInfo.release_status)
3431 GFree(g_pGesture->palmFlickInfo.line_idx)
3432 GFree(g_pGesture->palmFlickInfo.prev_line_idx)
3433 GFree(g_pGesture->palmFlickInfo.press_idx)
3434 GFree(g_pGesture->palmFlickInfo.is_line_invalid)
3436 GFree(g_pGesture->palmFlickInfo.max_tmajor)
3437 GFree(g_pGesture->palmFlickInfo.is_tmajor_invalid)
3438 GFree(g_pGesture->palmFlickInfo.mt_sync_count)
3440 /* g_pGesture->palmInfo */
3442 GFree(g_pGesture->palmInfo.pressed_idx)
3445 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
3449 IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
3458 return (dev->xtest_master_id == master->id);
3461 return (dev->xtest_master_id != 0);
3465 GestureEnable(int enable, Bool prop, DeviceIntPtr dev)
3467 if ((!enable) && (g_pGesture->is_active))
3469 g_pGesture->ehtype = PROPAGATE_EVENTS;
3470 mieqSetHandler(ET_MTSync, NULL);
3471 g_pGesture->is_active = 0;
3472 ErrorF("[GestureEnable] Disabled !\n");
3473 int res = AddCallback (&ClientStateCallback, GestureHandleClientState, NULL);
3477 ErrorF("[GestureEnable] Failed to add callback for client state\n");
3482 else if ((enable) && (!g_pGesture->is_active))
3484 g_pGesture->ehtype = KEEP_EVENTS;
3485 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
3486 g_pGesture->is_active = 1;
3487 ErrorF("[GestureEnable] Enabled !\n");
3489 DeleteCallback (&ClientStateCallback, GestureHandleClientState, NULL);
3494 XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
3499 GestureRegionsInit(void)
3505 return ERROR_INVALPTR;
3508 pixman_region_init(&g_pGesture->area);
3509 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
3510 for (i = 0; i < MAX_MT_DEVICES; i++)
3511 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
3512 for (i = 0; i < g_pGesture->num_mt_devices; i++)
3513 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
3515 pixman_region_init_rect(&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
3522 GestureRegionsReinit(void)
3526 ErrorF("[GestureRegionsReinit] Invalid pointer access !\n");
3527 return ERROR_INVALPTR;
3530 pixman_region_init(&g_pGesture->area);
3541 tmpEQ = (IEventRec *)calloc(GESTURE_EQ_SIZE, sizeof(IEventRec));
3545 ErrorF("[GestureInitEQ] Failed to allocate memory for EQ !\n");
3546 return ERROR_ALLOCFAIL;
3549 for (i = 0; i < GESTURE_EQ_SIZE; i++)
3551 tmpEQ[i].event = (InternalEvent *)malloc(sizeof(InternalEvent));
3552 if (!tmpEQ[i].event)
3554 ErrorF("[GestureInitEQ] Failed to allocation memory for each event buffer in EQ !\n");
3556 while(i >= 0 && tmpEQ[i].event)
3558 free(tmpEQ[i].event);
3559 tmpEQ[i].event = NULL;
3563 return ERROR_ALLOCFAIL;
3567 g_pGesture->EQ = tmpEQ;
3568 g_pGesture->headEQ = g_pGesture->tailEQ = 0;
3578 if (!g_pGesture || !g_pGesture->EQ)
3580 return ERROR_INVALPTR;
3583 for (i = 0; i < GESTURE_EQ_SIZE; i++)
3585 if (g_pGesture->EQ[i].event)
3587 free(g_pGesture->EQ[i].event);
3588 g_pGesture->EQ[i].event = NULL;
3592 free(g_pGesture->EQ);
3593 g_pGesture->EQ = NULL;
3599 GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
3603 if (!g_pGesture || !g_pGesture->EQ)
3605 ErrorF("[GestureEnqueueEvent] Invalid pointer access !\n");
3606 return ERROR_INVALPTR;
3609 tail = g_pGesture->tailEQ;
3611 if (tail >= GESTURE_EQ_SIZE)
3613 ErrorF("[GestureEnqueueEvent] Gesture EQ is full !\n");
3614 printk("[GestureEnqueueEvent] Gesture EQ is full...Force Gesture Flush !\n");
3615 GestureEventsFlush();
3616 return ERROR_EQFULL;
3619 if((g_pGesture->mtsync_flag & MTSYNC_FLAG_ROTARY) || (g_pGesture->mtsync_flag & ~MTSYNC_FLAG_TOUCH))
3621 DetailDebugPrint("[GestureEnqueueEvent] Rotary or other input are coming. Do not push events to queue.\n");
3625 switch (ev->any.type)
3627 case GESTURE_TOUCH_PRESS:
3628 DetailDebugPrint("[GestureEnqueueEvent] Press (id:%d)\n", device->id);
3631 case GESTURE_TOUCH_RELEASE:
3632 DetailDebugPrint("[GestureEnqueueEvent] Releae (id:%d)\n", device->id);
3635 case GESTURE_TOUCH_MOTION:
3636 DetailDebugPrint("[GestureEnqueueEvent] Motion (id:%d)\n", device->id);
3640 g_pGesture->EQ[tail].device = device;
3641 g_pGesture->EQ[tail].screen_num = screen_num;
3642 memcpy(g_pGesture->EQ[tail].event, ev, sizeof(InternalEvent));//need to be optimized
3643 g_pGesture->tailEQ++;
3649 GestureEventsFlush(void)
3652 DeviceIntPtr device;
3654 TTRACE_BEGIN("XORG:GESTURE:FLUSH_EVENT");
3656 if (!g_pGesture->EQ)
3658 ErrorF("[GestureEventsFlush] Invalid pointer access !\n");
3660 return ERROR_INVALPTR;
3663 DetailDebugPrint("[GestureEventsFlush]\n");
3665 for (i = g_pGesture->headEQ; i < g_pGesture->tailEQ; i++)
3667 device = g_pGesture->EQ[i].device;
3668 device->public.processInputProc(g_pGesture->EQ[i].event, device);
3671 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
3672 for (i = 0; i < MAX_MT_DEVICES; i++)
3673 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
3674 for (i = 0; i < g_pGesture->num_mt_devices; i++)
3675 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
3677 g_pGesture->event_sum[i] = 0;
3680 g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
3687 GestureEventsDrop(void)
3689 DetailDebugPrint("[GestureEventsDrop]\n");
3690 g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
3693 #ifdef HAVE_PROPERTIES
3695 GestureInitProperty(DeviceIntPtr dev)
3699 #ifdef SUPPORT_ANR_WITH_INPUT_EVENT
3700 prop_anr_in_input_event = MakeAtom(CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT, strlen(CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT), TRUE);
3701 prop_anr_event_window = MakeAtom(ANR_EVENT_WINDOW, strlen(ANR_EVENT_WINDOW), TRUE);
3704 prop_gesture_recognizer_onoff = MakeAtom(GESTURE_RECOGNIZER_ONOFF, strlen(GESTURE_RECOGNIZER_ONOFF), TRUE);
3705 rc = XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
3712 XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE);
3716 GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
3719 if (prop_gesture_recognizer_onoff == atom)
3722 if (val->format != 32 || val->type != XA_INTEGER || val->size != 1)
3727 data = *((int *)val->data);
3728 GestureEnable(data, TRUE, dev);
3733 #endif//HAVE_PROPERTIES
3736 GestureInit(DeviceIntPtr device)
3738 TTRACE_BEGIN("XORG:GESTURE:INIT");
3739 #ifdef HAVE_PROPERTIES
3740 GestureInitProperty(device);
3741 XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL);
3743 //GestureEnable(1, FALSE, g_pGesture->this_device);
3749 GestureFini(DeviceIntPtr device)
3751 XIRegisterPropertyHandler(device, NULL, NULL, NULL);
3755 GesturePlug(pointer module, pointer options, int *errmaj, int *errmin)
3757 xf86AddInputDriver(&GESTURE, module, 0);
3762 GestureUnplug(pointer p)
3767 GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
3770 GestureDevicePtr pGesture;
3772 TTRACE_BEGIN("XORG:GESTURE:PREINIT");
3774 pGesture = calloc(1, sizeof(GestureDeviceRec));
3778 pInfo->private = NULL;
3779 //xf86DeleteInput(pInfo, 0);
3783 g_pGesture = pGesture;
3785 pInfo->private = pGesture;
3787 pInfo->read_input = GestureReadInput; /* new data avl */
3788 pInfo->switch_mode = NULL; /* toggle absolute/relative mode */
3789 pInfo->device_control = GestureControl; /* enable/disable dev */
3791 /* process driver specific options */
3792 pGesture->device = xf86SetStrOption(pInfo->options, "Device", "/dev/null");
3793 pGesture->is_active = xf86SetIntOption(pInfo->options, "Activate", 0);
3794 pGesture->gestureWin = None;
3795 pGesture->lastSelectedWin = None;
3796 pGesture->power_pressed = 1;
3797 pGesture->hwkey_id = 0;
3798 pGesture->hwkey_dev = NULL;
3799 pGesture->num_tap_repeated = 0;
3800 pGesture->mtsync_total_count = 0;
3801 pGesture->hwkey_name = xf86SetStrOption(pInfo->options, "BackHWKeyName", NULL);
3802 pGesture->screen_width = xf86SetIntOption(pInfo->options,"ScreenWidth", 0);
3803 pGesture->screen_height = xf86SetIntOption(pInfo->options,"ScreenHeight", 0);
3804 pGesture->hwkeycode_flick_down = xf86SetIntOption(pInfo->options, "FlickDownKeycode", 0);
3805 pGesture->hwkeycode_flick_up = xf86SetIntOption(pInfo->options, "FlickUpKeycode", 0);
3806 pGesture->flick_press_area = xf86SetIntOption(pInfo->options, "FlickPressArea", 0);
3807 pGesture->flick_press_area_left = xf86SetIntOption(pInfo->options, "FlickPressArea_LEFT", 0);
3808 pGesture->flick_press_area_left_right = xf86SetIntOption(pInfo->options, "FlickPressArea_LEFT_RIGHT", 0);
3809 pGesture->flick_minimum_height = xf86SetIntOption(pInfo->options, "FlickMinimumHeight", 0);
3810 pGesture->shutdown_keycode = xf86SetIntOption(pInfo->options, "ShutdownKeycode", 0);
3811 pGesture->singletap_threshold= xf86SetIntOption(pInfo->options, "SingleTapThresHold", 0);
3812 pGesture->doubletap_threshold= xf86SetIntOption(pInfo->options, "DoubleTapThresHold", 0);
3813 pGesture->tripletap_threshold= xf86SetIntOption(pInfo->options, "TripleTapThresHold", 0);
3814 pGesture->hold_area_threshold = xf86SetRealOption(pInfo->options, "HoldAreaThresHold", 0);
3815 pGesture->hold_move_threshold = xf86SetIntOption(pInfo->options, "HoldMoveThresHold", 0);
3816 pGesture->hold_time_threshold = xf86SetIntOption(pInfo->options, "HoldTimeThresHold", 0);
3817 pGesture->palm_flick_time_threshold = xf86SetIntOption(pInfo->options, "PalmFlickTimeThresHold", 0);
3818 pGesture->palm_flick_max_tmajor_threshold = xf86SetIntOption(pInfo->options, "PalmFlickMaxTouchMajorThresHold", 0);
3819 pGesture->palm_flick_min_tmajor_threshold = xf86SetIntOption(pInfo->options, "PalmFlickMinTouchMajorThresHold", 0);
3820 pGesture->activate_flick_down = xf86SetIntOption(pInfo->options, "ActivateFlickDown", 0);
3821 pGesture->activate_flick_up = xf86SetIntOption(pInfo->options, "ActivateFlickUp", 0);
3822 pGesture->activate_flick_right = xf86SetIntOption(pInfo->options, "ActivateFlickRight", 0);
3823 pGesture->factory_cmdname = xf86SetStrOption(pInfo->options, "FactoryCmdName", NULL);
3824 pGesture->rotary_id = 0;
3825 pGesture->rotary_dev = NULL;
3827 ErrorF("[X11][%s] ###############################################################\n", __FUNCTION__);
3828 ErrorF("[X11][%s] screen_width=%d, screen_height=%d\n", __FUNCTION__,
3829 pGesture->screen_width, pGesture->screen_height);
3830 ErrorF("[X11][%s] FlickDownKeycode=%d, FlickUpKeycode=%d\n", __FUNCTION__,
3831 pGesture->hwkeycode_flick_down, pGesture->hwkeycode_flick_up);
3832 ErrorF("[X11][%s] flick_press_area=%d, flick_press_area_left: %d, flick_press_area_left_right: %d, flick_minimum_height=%d\n", __FUNCTION__,
3833 pGesture->flick_press_area, pGesture->flick_press_area_left, pGesture->flick_press_area_left_right, pGesture->flick_minimum_height);
3834 ErrorF("[X11][%s] ShutdownKeycode=%d\n", __FUNCTION__, pGesture->shutdown_keycode);
3835 ErrorF("[X11][%s] singletap_threshold=%d, doubletap_threshold=%d\n", __FUNCTION__, pGesture->singletap_threshold, pGesture->doubletap_threshold);
3836 ErrorF("[X11][%s] hold_area_threshold: %f, hold_move_threshold: %d, hold_time_threshold: %d\n", __FUNCTION__,
3837 pGesture->hold_area_threshold, pGesture->hold_move_threshold, pGesture->hold_time_threshold);
3838 ErrorF("[X11][%s] palm_flick_time_threshold: %d, palm_flick_max_tmajor_threshold: %d, palm_flick_min_tmajor_threshold: %d\n", __FUNCTION__,
3839 pGesture->palm_flick_time_threshold, pGesture->palm_flick_max_tmajor_threshold, pGesture->palm_flick_min_tmajor_threshold);
3840 ErrorF("[X11][%s] activate_flick_down=%d, activate_flick_up=%d, activate_flick_right=%d\n", __FUNCTION__,
3841 pGesture->activate_flick_down, pGesture->activate_flick_up, pGesture->activate_flick_right);
3842 ErrorF("[X11][%s] factory cmd name: %s\n", __FUNCTION__, pGesture->factory_cmdname);
3843 ErrorF("[X11][%s] ###############################################################\n", __FUNCTION__);
3845 if (pGesture->hwkey_name)
3847 ErrorF("[X11][%s] hwkey_name=%s\n", __FUNCTION__, pGesture->hwkey_name);
3850 pGesture->mtsync_flag = 0x00;
3851 g_pGesture->grabMask = g_pGesture->eventMask = 0;
3853 xf86Msg(X_INFO, "%s: Using device %s.\n", pInfo->name, pGesture->device);
3855 /* process generic options */
3856 xf86CollectInputOptions(pInfo, NULL);
3857 xf86ProcessCommonOptions(pInfo, pInfo->options);
3872 GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
3874 GestureDevicePtr pGesture = pInfo->private;
3876 g_pGesture = pGesture = NULL;
3877 pInfo->private = NULL;
3879 xf86DeleteInput(pInfo, 0);
3883 GestureControl(DeviceIntPtr device, int what)
3885 InputInfoPtr pInfo = device->public.devicePrivate;
3886 GestureDevicePtr pGesture = pInfo->private;
3891 GestureInit(device);
3894 /* Switch device on. Establish socket, start event delivery. */
3896 xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
3898 if (device->public.on)
3901 device->public.on = TRUE;
3902 pGesture->this_device = device;
3903 pGesture->num_mt_devices = 0;
3904 if (ERROR_ABNORMAL == GestureEnableEventHandler(pInfo))
3910 GestureDisableEventHandler();
3911 GestureFini(device);
3912 pGesture->this_device = NULL;
3913 xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
3915 if (!device->public.on)
3919 device->public.on = FALSE;
3923 /* free what we have to free */
3926 xf86Msg(X_INFO, "%s: device ready.\n", pInfo->name);
3927 GestureRegisterDeviceInfo(device);
3934 GestureReadInput(InputInfoPtr pInfo)