tizen 2.4 release
[adaptation/xorg/driver/xserver-xorg-input-gesture.git] / wearable / src / gesture.c
1 /**************************************************************************
2
3 xserver-xorg-input-gesture
4
5 Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
6
7 Contact: Sung-Jin Park <sj76.park@samsung.com>
8          Sangjin LEE <lsj119@samsung.com>
9
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:
17
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
20 of the Software.
21
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.
29
30 **************************************************************************/
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include <linux/input.h>
37 #include <linux/types.h>
38
39 #include <xf86_OSproc.h>
40
41 #include <unistd.h>
42
43 #include <xf86.h>
44 #include <xf86Xinput.h>
45 #include <exevents.h>
46 #include <xorgVersion.h>
47 #include <xkbsrv.h>
48
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
54 #define HAVE_LABELS
55 #else
56 #undef HAVE_LABELS
57 #endif
58
59 #endif
60
61 //#define __DETAIL_DEBUG__
62 //#define __DEBUG_EVENT_HANDLER__
63 //#define __PalmFlick_DEBUG__
64 //#define __HOLD_DETECTOR_DEBUG__
65 //#define __DEBUG_EVENT_MOTION_HANDLER__
66
67 #ifdef __PalmFlick_DEBUG__
68 #define PalmFlickDebugPrint ErrorF
69 #else
70 #define PalmFlickDebugPrint(...)
71 #endif
72
73 #ifdef __HOLD_DETECTOR_DEBUG__
74 #define HoldDetectorDebugPrint ErrorF
75 #else
76 #define HoldDetectorDebugPrint(...)
77 #endif
78
79
80 #ifdef __DETAIL_DEBUG__
81 #define DetailDebugPrint ErrorF
82 #else
83 #define DetailDebugPrint(...)
84 #endif
85
86 #include <stdio.h>
87 #include <sys/stat.h>
88 #include <sys/syscall.h>
89 #include <unistd.h>
90 #include <errno.h>
91 #include <sys/types.h>
92 #include <fcntl.h>
93 #include <xorg-server.h>
94 #include <xorgVersion.h>
95 #include <xf86Module.h>
96 #include <X11/Xatom.h>
97 #include "gesture.h"
98 #include <xorg/mi.h>
99
100 #define LOG_TAG "GESTURE"
101 #include "dlog.h"
102
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)));
106
107 //Basic functions
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);
116
117 //other initializers
118 ErrorStatus GestureRegionsInit(void);
119
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);
126
127 //utility functions
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_
141
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);
153
154 void GestureEmulateHWKey(DeviceIntPtr dev, int keycode);
155
156 //Gesture recognizer helper
157 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21
158 static Bool PointInBorderSize(WindowPtr pWin, int x, int y);
159 #endif
160 static WindowPtr GestureWindowOnXY(int x, int y);
161 Bool GestureHasFingerEventMask(int eventType, int num_finger);
162
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);
173
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);
179
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);
184 #endif
185
186 static Atom prop_gesture_recognizer_onoff = None;
187
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;
192 #endif
193
194 GestureDevicePtr g_pGesture = NULL;
195 _X_EXPORT InputDriverRec GESTURE = {
196     1,
197     "gesture",
198     NULL,
199     GesturePreInit,
200     GestureUnInit,
201     NULL,
202     0
203 };
204
205 static XF86ModuleVersionInfo GestureVersionRec =
206 {
207     "gesture",
208     MODULEVENDORSTRING,
209     MODINFOSTRING1,
210     MODINFOSTRING2,
211     XORG_VERSION_CURRENT,
212     PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR,
213     PACKAGE_VERSION_PATCHLEVEL,
214     ABI_CLASS_XINPUT,
215     ABI_XINPUT_VERSION,
216     MOD_CLASS_XINPUT,
217     {0, 0, 0, 0}
218 };
219
220 _X_EXPORT XF86ModuleData gestureModuleData =
221 {
222     &GestureVersionRec,
223     &GesturePlug,
224     &GestureUnplug
225 };
226
227 static void
228 printk(const char* fmt, ...)
229 {
230     static FILE* fp = NULL;
231     static char init = 0;
232     va_list argptr;
233
234     if (!init && !fp)
235     {
236         fp = fopen("/dev/kmsg", "wt");
237         init = 1;
238     }
239
240     if (!fp) return;
241
242     va_start(argptr, fmt);
243     vfprintf(fp, fmt, argptr);
244     fflush(fp);
245     va_end(argptr);
246 }
247
248 #ifdef SUPPORT_ANR_WITH_INPUT_EVENT
249 static WindowPtr
250 _GestureFindANRWindow(DeviceIntPtr device)
251 {
252     WindowPtr root=NULL;
253     WindowPtr anr_window=NULL;
254     Window anr_xid=0;
255     PropertyPtr pProp;
256     int rc=0;
257
258     root = RootWindow(device);
259
260     if( prop_anr_event_window == None )
261         prop_anr_event_window = MakeAtom(ANR_EVENT_WINDOW, strlen(ANR_EVENT_WINDOW), TRUE);
262
263     rc = dixLookupProperty (&pProp, root, prop_anr_event_window, serverClient, DixReadAccess);
264     if (rc == Success && pProp->data){
265         anr_xid = *(int*)pProp->data;
266     }
267
268     if( anr_xid != 0 )
269     {
270         rc = dixLookupWindow(&anr_window, anr_xid, serverClient, DixSetPropAccess);
271         if( rc == BadWindow )
272         {
273             ErrorF("Can't find ANR window !!\n");
274             anr_window = NULL;
275         }
276         prop_anr_event_window_xid = anr_xid;
277     }
278
279     ErrorF("ANR Window is %#x. Ptr is %#x\n", anr_xid, anr_window);
280     return anr_window;
281 }
282 #endif
283
284 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21
285 static Bool
286 PointInBorderSize(WindowPtr pWin, int x, int y)
287 {
288     BoxRec box;
289     if (pixman_region_contains_point (&pWin->borderSize, x, y, &box))
290     {
291         return TRUE;
292     }
293     return FALSE;
294 }
295 #endif
296
297 static WindowPtr
298 GestureWindowOnXY(int x, int y)
299 {
300     WindowPtr pWin;
301     BoxRec box;
302     SpritePtr pSprite;
303     DeviceIntPtr pDev = g_pGesture->master_pointer;
304
305     pSprite = pDev->spriteInfo->sprite;
306     pSprite->spriteTraceGood = 1;       /* root window still there */
307     pWin = RootWindow(pDev)->firstChild;
308
309     while (pWin)
310     {
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 +
317                  wBorderWidth (pWin))
318                 /* When a window is shaped, a further check
319                  * is made to see if the point is inside
320                  * borderSize
321                  */
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))
327 #ifdef ROOTLESS
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).
331                  */
332                     && !pWin->rootlessUnhittable
333 #endif
334                     )
335                     {
336                         if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
337                         {
338                             pSprite->spriteTraceSize += 10;
339                             pSprite->spriteTrace = realloc(pSprite->spriteTrace,
340                                     pSprite->spriteTraceSize*sizeof(WindowPtr));
341                         }
342                         pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
343                         pWin = pWin->firstChild;
344                     }
345         else
346             pWin = pWin->nextSib;
347     }
348     return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
349 }
350
351     Bool
352 GestureHasFingerEventMask(int eventType, int num_finger)
353 {
354     Bool ret = FALSE;
355     Mask eventmask = (1L << eventType);
356
357     if ((g_pGesture->grabMask & eventmask) &&
358             (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[num_finger].window != None))
359     {
360         DetailDebugPrint("[GestureHasFingerEventMask] TRUE !! Has grabMask\n");
361         return TRUE;
362     }
363
364     if (g_pGesture->eventMask & eventmask)
365     {
366         DetailDebugPrint("[GestureHasFingerEventMask] TRUE !! Has eventMask\n");
367         return TRUE;
368     }
369
370     DetailDebugPrint("[GestureHasFingerEventMask] FALSE !! eventType=%d, num_finger=%d\n", eventType, num_finger);
371
372     return ret;
373 }
374
375 static CARD32
376 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
377 {
378     int event_type = *(int *)arg;
379
380     switch (event_type)
381     {
382         case GestureNotifyHold:
383             DetailDebugPrint("[GestureEventTimerHandler] GestureNotifyHold (event_type = %d)\n", event_type);
384             GestureRecognize_GroupHold(event_type, NULL, NULL, 0, 1);
385             break;
386         case GestureNotifyTap:
387             DetailDebugPrint("[GestureEventTimerHandler] GestureNotifyTap (event_type = %d)\n", event_type);
388             GestureRecognize_GroupTap(event_type, NULL, NULL, 0, 1);
389             break;
390         default:
391             DetailDebugPrint("[GestureEventTimerHandler] unknown event_type (=%d)\n", event_type);
392             if (timer)
393             {
394                 DetailDebugPrint("[GestureEventTimerHandler] timer=%x\n", (unsigned int)timer);
395             }
396     }
397
398     return 0;
399 }
400 #ifndef _SUPPORT_EVDEVMULTITOUCH_DRV_
401 int
402 GestureGetTouchIndex(int deviceid, int touchid, int evtype)
403 {
404     int idx=0, i=0;
405
406     for (i=0; i<g_pGesture->num_mt_devices; i++)
407     {
408         if (g_pGesture->fingers[i].touchid == touchid)
409         {
410             return i;
411         }
412     }
413     ErrorF("[GestureGetTouchIndex] Failed to get touch index, devid: %d, touchid: %d, evsystem: %d\n", deviceid, touchid, evtype);
414     return -1;
415 }
416
417 int
418 GestureFindTouchIndex(int deviceid, int touchid, int evtype)
419 {
420     int idx=-1, i=0;
421
422     for (i=0; i<g_pGesture->num_mt_devices; i++)
423     {
424         if (evtype == ET_TouchBegin)
425         {
426             if (g_pGesture->fingers[i].status == BTN_RELEASED)
427             {
428                 g_pGesture->fingers[i].status = BTN_PRESSED;
429                 g_pGesture->fingers[i].touchid = touchid;
430                 return i;
431             }
432         }
433         else if (evtype == ET_TouchUpdate || evtype == ET_TouchEnd)
434         {
435             if (g_pGesture->fingers[i].touchid == touchid)
436             {
437                 g_pGesture->fingers[i].status = (evtype == ET_TouchEnd)?BTN_RELEASED:BTN_MOVING;
438                 return i;
439             }
440         }
441     }
442     ErrorF("[GesutreFindTouchIndex] Failed to find touch index, devid: %d, touchid: %d, evtype: %d\n", deviceid, touchid, evtype);
443     return -1;
444 }
445 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
446
447 void
448 GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy)
449 {
450     Window target_win;
451     WindowPtr target_pWin;
452     xGestureNotifyTapEvent tev;
453
454     //skip non-tap events and single finger tap
455     if (!tap_repeat || num_finger <= 1)
456     {
457         return;
458     }
459
460     DetailDebugPrint("[GestureHandleGesture_Tap] num_finger=%d, tap_repeat=%d, cx=%d, cy=%d\n", num_finger, tap_repeat, cx, cy);
461
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;
468     tev.interval = 0;
469     tev.cx = cx;
470     tev.cy = cy;
471
472     target_win = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].window;
473     target_pWin = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].pWin;
474
475     if (g_pGesture->grabMask && (target_win != None))
476     {
477         tev.window = target_win;
478     }
479     else
480     {
481         tev.window = g_pGesture->gestureWin;
482     }
483
484     DetailDebugPrint("[GestureHandleGesture_Tap] tev.window=0x%x, g_pGesture->grabMask=0x%x\n", (unsigned int)tev.window, (unsigned int)g_pGesture->grabMask);
485
486     GestureSendEvent(target_pWin, GestureNotifyTap, GestureTapMask, (xGestureCommonEvent *)&tev);
487     LOGI("GroupTap Event done. 2 fingers %d tap!", tap_repeat);
488 }
489
490 void
491 GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction)
492 {
493     DeviceIntPtr dev;
494     if (!g_pGesture->hwkey_dev)
495     {
496         for (dev = inputInfo.keyboard ; dev; dev = dev->next)
497         {
498             if (g_pGesture->hwkey_name && !strncmp(dev->name, g_pGesture->hwkey_name, strlen(dev->name)))
499             {
500                 g_pGesture->hwkey_id = dev->id;
501                 g_pGesture->hwkey_dev = dev;
502
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);
504                 break;
505             }
506             else if (!strcasestr(dev->name, "keyboard") && strcasestr(dev->name, "key") && !IsXTestDevice(dev, NULL) && !IsMaster(dev))
507             {
508                 g_pGesture->hwkey_id = dev->id;
509                 g_pGesture->hwkey_dev = dev;
510
511                 ErrorF("[GestureTimerHandler] hwkey has been found. hwkey_id=%d (hwkey_dev->name:%s)\n", g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
512                 break;
513             }
514         }
515
516         if (!g_pGesture->hwkey_id)
517         {
518             g_pGesture->hwkey_id = inputInfo.keyboard->id;
519             g_pGesture->hwkey_dev = inputInfo.keyboard;
520
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);
523         }
524     }
525     if (num_of_fingers == 0)
526     {
527         Window target_win;
528         WindowPtr target_pWin;
529         xGestureNotifyFlickEvent fev;
530
531         DetailDebugPrint("[GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n", num_of_fingers, distance, duration, direction);
532
533         g_pGesture->recognized_gesture |= WPalmFlickFilterMask;
534
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;
542
543         if (g_pGesture->GrabEvents)
544         {
545             target_win = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].window;
546             target_pWin = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].pWin;
547         }
548         else
549         {
550             target_win = None;
551             target_pWin = None;
552         }
553
554         if (g_pGesture->grabMask && (target_win != None))
555         {
556             fev.window = target_win;
557         }
558         else
559         {
560             fev.window = g_pGesture->gestureWin;
561         }
562
563         DetailDebugPrint("[GestureHandleGesture_Flick] fev.window=0x%x, g_pGesture->grabMask=0x%x\n", fev.window, g_pGesture->grabMask);
564
565         GestureSendEvent(target_pWin, GestureNotifyFlick, GestureFlickMask, (xGestureCommonEvent *)&fev);
566     }
567     else
568     {
569         DetailDebugPrint("[GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n", num_of_fingers, distance, duration, direction);
570
571         switch (direction)
572         {
573             case FLICK_NORTHWARD:
574                 DetailDebugPrint("[GestureHandleGesture_Flick] Flick Down \n");
575                 GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down);
576                 break;
577
578             case FLICK_SOUTHWARD:
579                 DetailDebugPrint("[GestureHandleGesture_Flick] Flick Up \n");
580                 GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up);
581                 break;
582             case FLICK_WESTWARD:
583                 if (g_pGesture->power_pressed == 2)
584                 {
585                     DetailDebugPrint("[GestureHandleGesture_Flick] Flick Right & power_pressed\n");
586                     GestureEmulateHWKey(g_pGesture->hwkey_dev, 122);
587                 }
588                 break;
589             default:
590                 break;
591         }
592         g_pGesture->recognized_gesture |= WFlickFilterMask;
593     }
594 }
595
596 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds)
597 {
598     Window target_win;
599     WindowPtr target_pWin;
600     xGestureNotifyHoldEvent hev;
601
602     DetailDebugPrint("[GestureHandleGesture_Hold] num_fingers=%d, cx=%d, cy=%d, holdtime=%d, kinds=%d\n", num_fingers, cx, cy, holdtime, kinds);
603
604     if (num_fingers == 0)
605     {
606         g_pGesture->hold_detected = TRUE;
607         LOGI("[PalmHold] PalmHold success !\n");
608     }
609     else
610     {
611         g_pGesture->recognized_gesture |= WHoldFilterMask;
612     }
613
614     memset(&hev, 0, sizeof(xGestureNotifyHoldEvent));
615     hev.type = GestureNotifyHold;
616     hev.kind = kinds;
617     hev.num_finger = num_fingers;
618     hev.holdtime = holdtime;
619     hev.cx = cx;
620     hev.cy = cy;
621
622     if (g_pGesture->GrabEvents)
623     {
624         target_win = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].window;
625         target_pWin = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].pWin;
626     }
627     else
628     {
629         target_win = None;
630         target_pWin = None;
631     }
632
633     if (g_pGesture->grabMask && (target_win != None))
634     {
635         hev.window = target_win;
636     }
637     else
638     {
639         hev.window = g_pGesture->gestureWin;
640     }
641
642     DetailDebugPrint("[GestureHandleGesture_Hold] hev.window=0x%x, g_pGesture->grabMask=0x%x\n", hev.window, g_pGesture->grabMask);
643
644     GestureSendEvent(target_pWin, GestureNotifyHold, GestureHoldMask, (xGestureCommonEvent *)&hev);
645     LOGI("[GroupHold] GestureHold success !\n");
646 }
647
648
649 void
650 GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
651 {
652     static int num_pressed = 0;
653     static int base_area_size = 0;
654
655     int cx, cy;
656     int area_size;
657
658     static int state = 0;
659     static int mbits = 0;
660     static int base_cx;
661     static int base_cy;
662     static pixman_box16_t base_box_ext;
663
664     static int tap_repeat = 0;
665     static int prev_num_pressed = 0;
666
667     static OsTimerPtr tap_event_timer = NULL;
668     static int event_type = GestureNotifyTap;
669
670     if (timer_expired)
671     {
672         DetailDebugPrint("[GroupTap][Timer] state=%d, num_pressed=%d, tap_repeat=%d\n", state, num_pressed, tap_repeat);
673
674         switch (state)
675         {
676             case 1://first tap initiation check
677                 if (num_pressed)
678                 {
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");
681
682                     state = 0;
683                     goto cleanup_tap;
684                 }
685                 break;
686
687             case 2:
688                 if (tap_repeat <= 1)
689                 {
690                     state = 0;
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");
693                     goto cleanup_tap;
694                 }
695
696                 if (GestureHasFingerEventMask(GestureNotifyTap, prev_num_pressed))
697                 {
698                     DetailDebugPrint("[GroupTap] Success 1!! 2 finger %d tap\n", tap_repeat);
699                     GestureHandleGesture_Tap(prev_num_pressed, tap_repeat, base_cx, base_cy);
700                     goto cleanup_tap;
701                 }
702                 break;
703         }
704         return;
705     }
706
707     switch (type)
708     {
709         case GESTURE_TOUCH_PRESS:
710             g_pGesture->fingers[idx].flags |= PressFlagTap;
711
712             if (g_pGesture->num_pressed < 2)
713             {
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);
715                 return;
716             }
717
718             if ((!base_area_size || g_pGesture->num_pressed > num_pressed))
719             {
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;
727                 state = 1;
728                 TimerCancel(tap_event_timer);
729                 tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->singletap_threshold, GestureEventTimerHandler, (int *)&event_type);
730             }
731             num_pressed = g_pGesture->num_pressed;
732
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);
734             break;
735
736         case GESTURE_TOUCH_MOTION:
737             if (!(g_pGesture->fingers[idx].flags & PressFlagTap))
738             {
739                 break;
740             }
741
742             if (num_pressed < 2)
743             {
744                 DetailDebugPrint("[GroupTap][M] num_pressed=%d, return \n", num_pressed);
745                 return;
746             }
747
748             if (num_pressed != g_pGesture->num_pressed)
749             {
750                 DetailDebugPrint("[GroupTap][M] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
751             }
752
753             mbits |= (1 << idx);
754             if (mbits == (pow(2, num_pressed)-1))
755             {
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);
759
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));
763
764                 if (ABS(base_area_size-area_size) >= TAP_AREA_THRESHOLD)
765                 {
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));
769
770                     goto cleanup_tap;
771                 }
772
773                 if (!INBOX(&base_box_ext, cx, cy))
774                 {
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");
778
779                     goto cleanup_tap;
780                 }
781             }
782             break;
783
784         case GESTURE_TOUCH_RELEASE:
785             if (g_pGesture->num_pressed)
786             {
787                 DetailDebugPrint("[GroupTap][R] Second finger doesn't come up. g_pGesture->num_pressed=%d\n", g_pGesture->num_pressed);
788                 break;
789             }
790
791             if (!tap_repeat)
792             {
793                 prev_num_pressed = num_pressed;
794             }
795
796             tap_repeat++;
797             g_pGesture->num_tap_repeated = tap_repeat;
798
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);
801
802             if ((num_pressed != prev_num_pressed) || (!GestureHasFingerEventMask(GestureNotifyTap, num_pressed)))
803             {
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);
809                 goto cleanup_tap;
810             }
811
812             if (tap_repeat == 1)
813             {
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);
817                 state = 2;
818                 prev_num_pressed = num_pressed;
819                 num_pressed = 0;
820                 break;
821             }
822
823             else if (tap_repeat == 2)
824             {
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);
828                 state = 2;
829                 base_area_size = num_pressed = 0;
830                 break;
831             }
832
833             DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat);
834
835             if (tap_repeat == MAX_TAP_REPEATS)
836             {
837                 if (GestureHasFingerEventMask(GestureNotifyTap, num_pressed))
838                 {
839                     DetailDebugPrint("[GroupTap] Sucess 2!\n");
840                     GestureHandleGesture_Tap(num_pressed, tap_repeat, base_cx, base_cy);
841                 }
842                 goto cleanup_tap;
843             }
844
845             if (tap_repeat >= MAX_TAP_REPEATS)
846             {
847                 LOGI("[GroupTap][F] More than 3 taps. Ignore. \n");
848                 goto cleanup_tap;
849             }
850
851             prev_num_pressed = num_pressed;
852             num_pressed = 0;
853             break;
854     }
855
856     return;
857
858 cleanup_tap:
859
860     DetailDebugPrint("[GroupTap][cleanup_tap]\n");
861
862     if (0 == state)
863     {
864         g_pGesture->recognized_gesture &= ~WTapFilterMask;
865     }
866
867     g_pGesture->filter_mask |= WTapFilterMask;
868
869     if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
870     {
871         DetailDebugPrint("[GroupTap][cleanup] GestureFlushOrDrop() !\n");
872
873         if (ERROR_INVALPTR == GestureFlushOrDrop())
874         {
875             GestureControl(g_pGesture->this_device, DEVICE_OFF);
876         }
877     }
878
879     num_pressed = 0;
880     g_pGesture->num_tap_repeated = tap_repeat = 0;
881     prev_num_pressed = 0;
882     mbits = 0;
883     state = 0;
884     TimerCancel(tap_event_timer);
885     return;
886 }
887
888 void
889 GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int start_point, int direction)
890 {
891     static int num_pressed = 0;
892     static Time base_time = 0;
893     Time duration;
894     int distance;
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;
903
904     if (g_pGesture->num_pressed > 1)
905     {
906         DetailDebugPrint("[GroupFlick][F] 1\n");
907         goto cleanup_flick;
908     }
909
910     if ((start_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= start_point))
911     {
912         DetailDebugPrint("[GroupFlick][F] 2\n");
913         goto cleanup_flick;
914     }
915
916     switch (type)
917     {
918         case GESTURE_TOUCH_PRESS:
919             g_pGesture->fingers[idx].flags = PressFlagFlick;
920             base_time = GetTimeInMillis();
921             num_pressed = g_pGesture->num_pressed;
922             switch (start_point)
923             {
924                 case FLICK_POINT_UP:
925                     if (g_pGesture->fingers[idx].py > g_pGesture->flick_press_area)
926                     {
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);
931                         goto cleanup_flick;
932                     }
933
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);
937                     break;
938
939                 case FLICK_POINT_DOWN:
940                     if (g_pGesture->fingers[idx].py < g_pGesture->screen_height - g_pGesture->flick_press_area)
941                     {
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");
945                         goto cleanup_flick;
946                     }
947                     angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
948                     angle_base_x = g_pGesture->fingers[idx].px;
949                     break;
950
951                 case FLICK_POINT_LEFT:
952                     if (g_pGesture->fingers[idx].px > g_pGesture->flick_press_area)
953                     {
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");
957                         goto cleanup_flick;
958                     }
959                     angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
960                     angle_base_x = g_pGesture->fingers[idx].px;
961                     break;
962
963                 default:
964                     DetailDebugPrint("[GroupFlick][F] 6\n");
965                     goto cleanup_flick;
966                     break;
967             }
968
969             break;
970
971         case GESTURE_TOUCH_MOTION:
972
973             motion_count++;
974
975             if (motion_count > 15)
976             {
977                 DetailDebugPrint("[GroupFlick][F] 6-1 motion_count=%d\n", motion_count);
978                 LOGI("[BackKey][F] More than 15 motion.\n");
979                 goto cleanup_flick;
980             }
981
982             if (!(g_pGesture->fingers[idx].flags & PressFlagFlick))
983             {
984                 break;
985             }
986
987             switch (start_point)
988             {
989                 case FLICK_POINT_UP:
990                     diff_base_coord = diff_current_coord;
991                     diff_current_coord = g_pGesture->fingers[idx].my;
992
993                     if ((diff_current_coord - diff_base_coord) < 0)
994                     {
995                         DetailDebugPrint("[GroupFlick][FlickDown][M] false_diff\n");
996                         false_diff_count++;
997                     }
998
999                     if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
1000                     {
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");
1005                         goto cleanup_flick;
1006                     }
1007
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)))
1010                     {
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");
1015                         goto cleanup_flick;
1016                     }
1017
1018                     if ((g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) > g_pGesture->flick_minimum_height)
1019                     {
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);
1022
1023                         if (abs(g_pGesture->fingers[idx].mx - angle_base_x) == 0)
1024                         {
1025                             DetailDebugPrint("[GroupFlick][FlickDown][M] abs(%d - %d) = 0\n",
1026                                     g_pGesture->fingers[idx].mx, angle_base_x);
1027                             angle = 1.0f;
1028                         }
1029                         else
1030                         {
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;
1036                         }
1037
1038                         if (angle < 0.23f)
1039                         {
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);
1044                             goto cleanup_flick;
1045                         }
1046
1047                         distance = g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py;
1048                         duration = GetTimeInMillis() - base_time;
1049
1050                         GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
1051                         DetailDebugPrint("[GroupFlick][FlickDown][M] FlickDown Done!!\n");
1052                         goto cleanup_flick_recognized;
1053                     }
1054                     else
1055                     {
1056                         if ((g_pGesture->fingers[idx].mx - diff_base_minor_coord) < 0)
1057                         {
1058                             false_minor_diff_count++;
1059                         }
1060
1061                         if (false_minor_diff_count> FLICK_FALSE_X_DIFF_COUNT)
1062                         {
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");
1066                             goto cleanup_flick;
1067                         }
1068                     }
1069
1070                     if (g_pGesture->fingers[idx].my < g_pGesture->flick_press_area)
1071                     {
1072                         angle_base_x = g_pGesture->fingers[idx].px;
1073                         angle_base_y = g_pGesture->fingers[idx].py;
1074                     }
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));
1077
1078                     break;
1079
1080                 case FLICK_POINT_DOWN:
1081                     diff_base_coord = diff_current_coord;
1082                     diff_current_coord = g_pGesture->fingers[idx].my;
1083
1084                     if ((diff_base_coord - diff_current_coord) < 0)
1085                     {
1086                         false_diff_count++;
1087                     }
1088
1089                     if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
1090                     {
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");
1094                         goto cleanup_flick;
1095                     }
1096
1097                     if ((g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my) > g_pGesture->flick_minimum_height)
1098                     {
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)
1102                         {
1103                             DetailDebugPrint("[GroupFlick][FlickUp][R] abs(%d - %d) = 0\n",
1104                                     g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px);
1105                             angle = 1.0f;
1106                         }
1107                         else
1108                         {
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;
1112                         }
1113
1114                         if (angle <0.5f)
1115                         {
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");
1119                             goto cleanup_flick;
1120                         }
1121
1122                         distance = g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my;
1123                         duration = GetTimeInMillis() - base_time;
1124
1125                         GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
1126                         goto cleanup_flick_recognized;
1127                     }
1128                     break;
1129
1130                 case FLICK_POINT_LEFT:
1131                     diff_base_coord = diff_current_coord;
1132                     diff_current_coord = g_pGesture->fingers[idx].mx;
1133
1134                     if ((diff_current_coord - diff_base_coord) < 0)
1135                     {
1136                         false_diff_count++;
1137                     }
1138
1139                     if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
1140                     {
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");
1144                         goto cleanup_flick;
1145                     }
1146
1147                     if ((g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) > g_pGesture->flick_minimum_height)
1148                     {
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);
1151
1152                         if (abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) == 0)
1153                         {
1154                             DetailDebugPrint("[GroupFlick][FlickLeft][M] abs(%d - %d) = 0\n",
1155                                     g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py);
1156                             angle = 1.0f;
1157                         }
1158                         else
1159                         {
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;
1163                         }
1164
1165                         if ( angle < 0.5f)
1166                         {
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");
1170                             goto cleanup_flick;
1171                         }
1172
1173                         distance = g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px;
1174                         duration = GetTimeInMillis() - base_time;
1175
1176                         GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
1177                         goto cleanup_flick_recognized;
1178                     }
1179
1180                     break;
1181                 default:
1182                     DetailDebugPrint("[GroupFlick][F] 15\n");
1183                     goto cleanup_flick;
1184                     break;
1185             }
1186             break;
1187
1188         case GESTURE_TOUCH_RELEASE:
1189             DetailDebugPrint("[GroupFlick][R][F] 16\n");
1190             goto cleanup_flick;
1191             break;
1192     }
1193
1194     return;
1195
1196 cleanup_flick:
1197     DetailDebugPrint("[GroupFlick] cleanup_flick \n");
1198     g_pGesture->recognized_gesture &= ~WFlickFilterMask;
1199     motion_count = 0;
1200
1201 cleanup_flick_recognized:
1202     DetailDebugPrint("[GroupFlick] Flick recognized !\n");
1203     g_pGesture->filter_mask |= WFlickFilterMask;
1204     num_pressed = 0;
1205     base_time = 0;
1206     false_diff_count = 0;
1207     diff_base_coord = 0;
1208     diff_current_coord = 0;
1209     angle = 0.0f;
1210     angle_base_x = angle_base_y = 0;
1211     motion_count = 0;
1212     return;
1213 }
1214
1215 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1216 {
1217     static int num_pressed = 0;
1218     static int base_area_size = 0;
1219     static Time base_time = 0;
1220     static int base_cx;
1221     static int base_cy;
1222     int cx, cy;
1223     static pixman_box16_t base_box_ext;
1224     int area_size;
1225     static int state = GestureEnd;
1226
1227     static OsTimerPtr hold_event_timer = NULL;
1228     static int event_type = GestureNotifyHold;
1229
1230     if (timer_expired)
1231     {
1232         if (state <= GestureBegin)
1233         {
1234             state++;
1235         }
1236
1237         switch (state)
1238         {
1239             case GestureBegin:
1240                 DetailDebugPrint("[GroupHold] HOLD Begin !\n");
1241                 break;
1242
1243             case GestureUpdate:
1244                 DetailDebugPrint("[GroupHold] HOLD Update !\n");
1245                 break;
1246         }
1247
1248         if (GestureHasFingerEventMask(GestureNotifyHold, num_pressed))
1249         {
1250             DetailDebugPrint("[GroupHold] Success 1! \n");
1251             GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1252
1253             // one more time
1254             hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type);
1255         }
1256         return;
1257     }
1258
1259     switch (type)
1260     {
1261         case GESTURE_TOUCH_PRESS:
1262             g_pGesture->fingers[idx].flags |= PressFlagHold;
1263
1264             if (g_pGesture->num_pressed < 2)
1265             {
1266                 DetailDebugPrint("[GroupHold][P] No num_finger changed ! num_pressed=%d\n", num_pressed);
1267                 DetailDebugPrint("[GroupHold][F] 0\n");
1268                 return;
1269             }
1270
1271             if (!base_area_size || g_pGesture->num_pressed > num_pressed)
1272             {
1273                 if (state != GestureEnd)
1274                 {
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");
1277
1278                     goto cleanup_hold;
1279                 }
1280
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();
1285
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;
1290
1291                 event_type = GestureNotifyHold;
1292
1293                 hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type);
1294             }
1295             num_pressed = g_pGesture->num_pressed;
1296
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);
1298
1299             break;
1300
1301         case GESTURE_TOUCH_MOTION:
1302             if (!(g_pGesture->fingers[idx].flags & PressFlagHold))
1303             {
1304                 DetailDebugPrint("[GroupHold][M] No PressFlagHold\n");
1305                 break;
1306             }
1307
1308             if (num_pressed < 2)
1309             {
1310                 DetailDebugPrint("[GroupHold][M] No num_finger changed ! num_pressed=%d\n", num_pressed);
1311                 DetailDebugPrint("[GroupHold][F] 2\n");
1312                 return;
1313             }
1314
1315             if (num_pressed != g_pGesture->num_pressed)
1316             {
1317                 if (state != GestureEnd)
1318                 {
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");
1321                     goto cleanup_hold;
1322                 }
1323
1324                 DetailDebugPrint("[GroupHold][M] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1325             }
1326
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);
1330
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));
1334
1335             if (area_size > 0 && base_area_size > 0)
1336             {
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)
1338                 {
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");
1341                     goto cleanup_hold;
1342                 }
1343             }
1344
1345             if (!INBOX(&base_box_ext, cx, cy))
1346             {
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");
1351                 goto cleanup_hold;
1352             }
1353             break;
1354
1355         case GESTURE_TOUCH_RELEASE:
1356             if (state != GestureEnd && num_pressed >= 2)
1357             {
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");
1360                 goto cleanup_hold;
1361             }
1362
1363             if (g_pGesture->num_pressed)
1364             {
1365                 DetailDebugPrint("[GroupHold][R] num_pressed=%d\n", num_pressed);
1366                 DetailDebugPrint("[GroupHold][F] 7\n");
1367                 break;
1368             }
1369
1370             goto cleanup_hold;
1371             break;
1372     }
1373
1374     return;
1375
1376 cleanup_hold:
1377
1378     DetailDebugPrint("[GroupHold][cleanup_hold] enter!\n");
1379
1380     if (state == GestureBegin || state == GestureUpdate)
1381     {
1382         state = GestureEnd;
1383         if (GestureHasFingerEventMask(GestureNotifyHold, num_pressed))
1384         {
1385             DetailDebugPrint("[GroupHold] Success 2!\n");
1386             GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1387         }
1388     }
1389     else
1390     {
1391         g_pGesture->recognized_gesture &= ~WHoldFilterMask;
1392     }
1393
1394     g_pGesture->filter_mask |= WHoldFilterMask;
1395     num_pressed = 0;
1396     base_area_size = 0;
1397     base_time = 0;
1398     base_cx = base_cy = 0;
1399     state = GestureEnd;
1400     base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
1401     TimerCancel(hold_event_timer);
1402     return;
1403 }
1404
1405 int
1406 GestureGetMaxTmajor(InternalEvent *ev, int max_tmajor)
1407 {
1408     int mt_tmajor_idx = g_pGesture->tmajor_idx;
1409     int mt_tmajor = 0;
1410
1411     DeviceEvent *de = &ev->device_event;
1412
1413     if (!de)
1414     {
1415         DetailDebugPrint("[GestureGetMaxTmajor] de is NULL !\n");
1416         return -1;
1417     }
1418
1419     if (mt_tmajor_idx < 0)
1420     {
1421         DetailDebugPrint("[GestureGetMaxTmajor] One or more of axes are not supported !\n");
1422         return -1;
1423     }
1424
1425     mt_tmajor = de->valuators.data[mt_tmajor_idx];
1426
1427     DetailDebugPrint("[GestureGetMaxTmajor]mt_tmajor_idx=%d, mt_tmajor=%d, max_tmajor=%d\n", mt_tmajor_idx, mt_tmajor, max_tmajor);
1428
1429     return ((mt_tmajor > max_tmajor) ? mt_tmajor : max_tmajor);
1430
1431 }
1432
1433 void
1434 GestureRecognize_PalmFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx)
1435 {
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};
1441
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};
1445
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};
1448
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};
1452
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;
1457
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;
1461
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;
1464
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;
1468
1469     int *mt_sync_count = g_pGesture->palmFlickInfo.mt_sync_count;
1470 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
1471
1472     static Bool is_palm = FALSE;
1473     PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
1474
1475     static Bool is_retry = FALSE;
1476
1477     int distance, direction, duration;
1478
1479     if (g_pGesture->recognized_gesture && !(g_pGesture->recognized_gesture & WPalmFlickFilterMask))
1480     {
1481         PalmFlickDebugPrint("[PalmFlick] recognize other gesture already( g_pGesture->recognized_gesture: %d)\n", g_pGesture->recognized_gesture);
1482         PalmFlickDebugPrint("[PalmFlick][F] 1\n");
1483         goto flick_failed;
1484     }
1485
1486     // only first finger recognize
1487     if (!(idx == 0 || idx == 1))
1488     {
1489         PalmFlickDebugPrint("[PalmFlick] idx=%d, least two fingers come on\n", idx);
1490         return;
1491     }
1492
1493     switch (type)
1494     {
1495         case GESTURE_TOUCH_PRESS:
1496
1497             if (!is_palm)
1498             {
1499                 if (idx == 0)
1500                 {
1501                     base_time = GetTimeInMillis();
1502                 }
1503
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;
1511
1512                 total_max_tmajor = (total_max_tmajor > max_tmajor[idx]) ? total_max_tmajor : max_tmajor[idx];
1513
1514                 // press region
1515                 press_idx[idx] = prev_line_idx[idx] = line_idx[idx] = GesturePalmGetHorizIndexWithX(base_x[idx], idx, type);
1516
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]);
1520
1521                 // invalid region
1522                 if (line_idx[idx] < 0 || line_idx[idx] >= PALM_HORIZ_ARRAY_COUNT)
1523                 {
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");
1526                     goto flick_failed;
1527                 }
1528
1529                 // check press point when there are two fingers
1530                 if (idx == 1)
1531                 {
1532                     if (press_idx[0] != press_idx[1])
1533                     {
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");
1537                         goto flick_failed;
1538                     }
1539                 }
1540             }
1541             else
1542             {
1543                 update_x[idx] = g_pGesture->fingers[idx].px;
1544                 update_y[idx] = g_pGesture->fingers[idx].py;
1545
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]);
1548             }
1549
1550             break;
1551
1552         case GESTURE_TOUCH_MOTION:
1553
1554             if (total_max_tmajor > g_pGesture->palm_flick_max_tmajor_threshold)
1555             {
1556                 mt_sync_count[idx]++;
1557                 is_palm = TRUE;
1558                 DetailDebugPrint("[PalmFlick][M] Sufficient touch enough ! max_tmajor=%d\n", total_max_tmajor);
1559                 break;
1560             }
1561
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]++;
1567
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);
1571
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]);
1574
1575             // exception vezel end line motion
1576             if (current_x[idx] < 5 || current_x[idx] > 355)
1577             {
1578                 if (total_max_tmajor >= g_pGesture->palm_flick_max_tmajor_threshold)
1579                 {
1580                     PalmFlickDebugPrint("[PalmFlick][M][Vezel] Sufficient touch major was came(%d)\n", total_max_tmajor);
1581                     is_palm = TRUE;
1582                 }
1583                 else
1584                 {
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]);
1588                 }
1589                 break;
1590             }
1591
1592             // get current position
1593             line_idx[idx] = GesturePalmGetHorizIndexWithX(current_x[idx], idx, type);
1594
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]);
1597
1598             //error check
1599             if (line_idx[idx] < 0 || line_idx[idx] >= PALM_HORIZ_ARRAY_COUNT)
1600             {
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");
1603                 goto flick_failed;
1604             }
1605
1606             // screen capture motion validation
1607             if (line_idx[idx] != prev_line_idx[idx])
1608             {
1609                 if (base_x[idx] <= pPalmMisc->horiz_coord[0])
1610                 {
1611                     if (line_idx[idx] < prev_line_idx[idx])
1612                     {
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]);
1615
1616                         is_line_invalid[idx] = TRUE;
1617
1618                         if (is_line_invalid[0] && is_line_invalid[1])
1619                         {
1620                             PalmFlickDebugPrint("[PalmFlick][F] 4\n");
1621                             goto flick_failed;
1622                         }
1623                     }
1624                 }
1625                 else if (base_x[idx] >= pPalmMisc->horiz_coord[PALM_HORIZ_ARRAY_COUNT-1])
1626                 {
1627                     if (line_idx[idx] > prev_line_idx[idx])
1628                     {
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]);
1631
1632                         is_line_invalid[idx] = TRUE;
1633
1634                         if (is_line_invalid[0] && is_line_invalid[1])
1635                         {
1636                             PalmFlickDebugPrint("[PalmFlick][F] 5\n");
1637                             goto flick_failed;
1638                         }
1639                     }
1640                 }
1641                 prev_line_idx[idx] = line_idx[idx];
1642             }
1643
1644             if (is_palm == FALSE)
1645             {
1646                 switch (mt_sync_count[idx])
1647                 {
1648                     case 1:
1649                         if (total_max_tmajor <= g_pGesture->palm_flick_min_tmajor_threshold)
1650                         {
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;
1656                         }
1657                         break;
1658                     case 2:
1659                         if (total_max_tmajor <= (g_pGesture->palm_flick_max_tmajor_threshold - 10))
1660                         {
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;
1666                         }
1667                         break;
1668                     case 3:
1669                         if (total_max_tmajor < g_pGesture->palm_flick_max_tmajor_threshold)
1670                         {
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;
1676                         }
1677                         break;
1678                     default:
1679                         PalmFlickDebugPrint("[PalmFlick][M] See more next motion...\n");
1680                         break;
1681                 }
1682             }
1683
1684             if (is_tmajor_invalid[0] && is_tmajor_invalid[1])
1685             {
1686                 PalmFlickDebugPrint("[PalmFlick][M][F] max_tmajor=%d\n", total_max_tmajor);
1687                 goto flick_failed;
1688             }
1689
1690             current_time = GetTimeInMillis();
1691
1692             if (current_time - base_time > g_pGesture->palm_flick_time_threshold)
1693             {
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");
1696                 goto flick_failed;
1697             }
1698
1699             break;
1700
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;
1705
1706             if ((update_x[idx] == current_x[idx]) && (update_y[idx] == current_y[idx]))
1707             {
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");
1711                 break;
1712                 //goto flick_failed;
1713             }
1714
1715             if (!is_palm)
1716             {
1717                 is_tmajor_invalid[idx] = TRUE;
1718
1719                 if (is_tmajor_invalid[0] && is_tmajor_invalid[1])
1720                 {
1721                     PalmFlickDebugPrint("[PalmFlick][R][F] Insufficient touch major was came(%d)\n", total_max_tmajor);
1722                     PalmFlickDebugPrint("[PalmFlick][F] 11\n");
1723                     goto flick_failed;
1724                 }
1725             }
1726
1727             line_idx[idx] = GesturePalmGetHorizIndexWithX(current_x[idx], idx, type);
1728
1729             if (is_palm && line_idx[idx] == 1)
1730             {
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]);
1733                 is_retry = TRUE;
1734                 mt_sync_count[idx] = 0;
1735                 break;
1736             }
1737
1738             if (line_idx[idx] < 0 || line_idx[idx] > PALM_HORIZ_ARRAY_COUNT - 1)
1739             {
1740                 is_line_invalid[idx] = TRUE;
1741
1742                 if (is_line_invalid[0] && is_line_invalid[1])
1743                 {
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");
1746                     goto flick_failed;
1747                 }
1748             }
1749
1750             current_time = GetTimeInMillis();
1751
1752             if (current_time - base_time > g_pGesture->palm_flick_time_threshold)
1753             {
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");
1757                 goto flick_failed;
1758             }
1759
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;
1763
1764             if (!is_retry)
1765             {
1766                 if (GestureHasFingerEventMask(GestureNotifyFlick, 0))
1767                 {
1768                     PalmFlickDebugPrint("[PalmFlick][R] Palm Flick1 !!!, direction=%d, distance=%d\n", direction, distance);
1769                     is_palm = FALSE;
1770                     GestureHandleGesture_Flick(0, distance, duration, direction);
1771                 }
1772             }
1773             else
1774             {
1775                 if (mt_sync_count[idx] < 25)
1776                 {
1777                     PalmFlickDebugPrint("[PalmFlick][R][F] No enough motion=%d\n", mt_sync_count[idx]);
1778                     PalmFlickDebugPrint("[PalmFlick][F] 14\n");
1779                     goto flick_failed;
1780                 }
1781                 else
1782                 {
1783                     if (GestureHasFingerEventMask(GestureNotifyFlick, 0))
1784                     {
1785                         PalmFlickDebugPrint("[PalmFlick][R] Palm Flick2 !!!, direction=%d, distance=%d\n", direction, distance);
1786                         is_palm = FALSE;
1787                         GestureHandleGesture_Flick(0, distance, duration, direction);
1788                     }
1789                 }
1790             }
1791
1792             g_pGesture->recognized_gesture |= WPalmFlickFilterMask;
1793
1794             goto cleanup_flick;
1795             break;
1796     }
1797
1798     return;
1799
1800 flick_failed:
1801
1802     DetailDebugPrint("[PalmFlick][R] flick failed\n");
1803
1804     g_pGesture->recognized_gesture &= ~WPalmFlickFilterMask;
1805     g_pGesture->filter_mask |= WPalmFlickFilterMask;
1806     goto cleanup_flick;
1807
1808 cleanup_flick:
1809
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_
1816     {
1817         base_x[i] = 0;
1818         base_y[i] = 0;
1819         update_x[i] = 0;
1820         update_y[i] = 0;
1821         current_x[i] = 0;
1822         current_y[i] = 0;
1823         line_idx[i] = 0;
1824         press_idx[i] = 0;
1825         prev_line_idx[i] = 0;
1826         max_tmajor[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;
1832     }
1833
1834     total_max_tmajor = 0;
1835     is_palm = FALSE;
1836     is_retry = FALSE;
1837
1838     return;
1839 }
1840
1841 static int
1842 GesturePalmGetHorizIndexWithX(int current_x, int idx, int type)
1843 {
1844     int i;
1845     int ret_idx = -1;
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;
1852
1853     for (i = 0; i < PALM_HORIZ_ARRAY_COUNT; i++)
1854     {
1855         if (current_x <= pPalmMisc->horiz_coord[i])
1856         {
1857             DetailDebugPrint("[GesturePalmGetHorizIndexWithX] index=%d, pPalmMisc->horiz_coord[%d]=%d\n", i, i, pPalmMisc->horiz_coord[i]);
1858
1859             ret_idx = i;
1860             goto index_check;
1861         }
1862     }
1863
1864     DetailDebugPrint("[GesturePalmGetHorizIndexWithX]Error ! Failed to get horiz coordinate index !\n");
1865     return ret_idx;
1866
1867 index_check:
1868
1869     if (type == GESTURE_TOUCH_PRESS)
1870     {
1871         pressed_idx[idx] = ret_idx;
1872
1873         // first press is center
1874         if (pressed_idx[idx] == PALM_HORIZ_ARRAY_COUNT -2)
1875         {
1876             DetailDebugPrint("[GesturePalmGetHorizIndexWithX][P] Invalid press area x=%d, idx=%d, pressed_idx=%d\n", current_x, idx, pressed_idx[idx]);
1877             ret_idx = -1;
1878         }
1879
1880         DetailDebugPrint("[GesturePalmGetHorizIndexWithX][P] pressed_idx=%d\n", pressed_idx[idx]);
1881     }
1882
1883     else if (type == GESTURE_TOUCH_MOTION)
1884     {
1885         DetailDebugPrint("[GesturePalmGetHorizIndexWithX][M] moving x=%d, idx=%d, pressed_idx=%d\n", current_x, idx, pressed_idx[idx]);
1886     }
1887
1888     else if (type == GESTURE_TOUCH_RELEASE)
1889     {
1890         if ((pressed_idx[idx] == 0) && (ret_idx == (PALM_HORIZ_ARRAY_COUNT - 1)))
1891         {
1892             DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] From the left to the right ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
1893         }
1894         else if ((pressed_idx[idx] == (PALM_HORIZ_ARRAY_COUNT - 1)) && (ret_idx == 0))
1895         {
1896             DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] From the right to the left ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
1897         }
1898         else if ((pressed_idx[idx] == ret_idx) && ret_idx != 1)
1899         {
1900             DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] Relased the same region ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
1901             return 1;
1902         }
1903         else
1904         {
1905             DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] Invalid ! pressed_idx=%d, released_idx=%d\n", pressed_idx[idx], ret_idx);
1906             ret_idx = -1;
1907         }
1908
1909         pressed_idx[idx] = -1;
1910     }
1911
1912     return ret_idx;
1913 }
1914
1915 static int
1916 GesturePalmGetAbsAxisInfo(DeviceIntPtr dev)
1917 {
1918     int i, found = 0;
1919     int numAxes;
1920
1921     Atom atom_tpalm;
1922     Atom atom_mt_slot;
1923     Atom atom_tracking_id;
1924     Atom atom_tmajor;
1925     Atom atom_tminor;
1926
1927     g_pGesture->tpalm_idx = -1;
1928     g_pGesture->tmajor_idx = -1;
1929     g_pGesture->tminor_idx = -1;
1930
1931     if (!dev || !dev->valuator)
1932         goto out;
1933
1934     numAxes = dev->valuator->numAxes;
1935
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);
1941
1942     if (!numAxes || !atom_tpalm || !atom_tmajor || !atom_tminor)
1943     {
1944         ErrorF("one or more axes is/are not supported!\n");
1945         goto out;
1946     }
1947
1948     for (i = 0; i < numAxes; i++)
1949     {
1950         AxisInfoPtr axes = &dev->valuator->axes[i];
1951
1952         if (!axes || (axes->mode != Absolute))
1953             continue;
1954
1955         if (axes->label == atom_tpalm)
1956         {
1957             g_pGesture->tpalm_idx = i;
1958             found += 1;
1959         }
1960         else if (axes->label == atom_tmajor)
1961         {
1962             g_pGesture->tmajor_idx = i;
1963             found += 2;
1964         }
1965         else if (axes->label == atom_tminor)
1966         {
1967             g_pGesture->tminor_idx = i;
1968             found += 4;
1969         }
1970     }
1971
1972     if (found != 7)
1973     {
1974         ErrorF("Axes for palm recognization are not supported !\n");
1975         goto out;
1976     }
1977
1978     g_pGesture->palm_misc.enabled = 1;
1979     ErrorF("Axes for palm recognization are supported !\n");
1980     return 1;
1981
1982 out:
1983     g_pGesture->palm_misc.enabled = 0;
1984     ErrorF("Palm recognization is not supported !\n");
1985     return 0;
1986 }
1987
1988 static int
1989 GestureGetPalmValuator(InternalEvent *ev, DeviceIntPtr device)
1990 {
1991     int mt_palm_idx = g_pGesture->tpalm_idx;
1992     int mt_palm = 0;
1993
1994     DeviceEvent *de = &ev->device_event;
1995
1996     if (!de)
1997     {
1998         ErrorF("[GestureGetPalmValuator] de is NULL !\n");
1999         return -1;
2000     }
2001
2002     if (mt_palm_idx < 0)
2003     {
2004         ErrorF("[GestureGetPalmValuator] One or more of axes are not supported !\n");
2005         return -1;
2006     }
2007
2008     mt_palm = de->valuators.data[mt_palm_idx];
2009
2010     HoldDetectorDebugPrint("[GestureGetPalmValuator] mt_palm:%d\n", mt_palm);
2011
2012     return mt_palm;
2013 }
2014
2015 static void GestureHoldDetector(int type, InternalEvent *ev, DeviceIntPtr device)
2016 {
2017     int i;
2018     int idx = -1;
2019     pixman_region16_t tarea1;
2020     static int num_pressed = 0;
2021     unsigned int hold_area_size;
2022     PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
2023     int palm_flag = 0;
2024
2025     if (!g_pGesture->has_hold_grabmask)
2026     {
2027         HoldDetectorDebugPrint("[GestureHoldDetector] g_pGesture->has_hold_grabmask=%d\n", g_pGesture->has_hold_grabmask);
2028
2029         Mask eventmask = (1L << GestureNotifyHold);
2030
2031         if ((g_pGesture->grabMask & eventmask) &&
2032                 (g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[0].window != None))
2033         {
2034             g_pGesture->has_hold_grabmask = 1;
2035
2036             //Initialize a set of variables
2037             num_pressed = 0;
2038             memset(&g_pGesture->cts, 0, sizeof(g_pGesture->cts));
2039             pixman_region_init(&g_pGesture->chold_area);
2040
2041             HoldDetectorDebugPrint("[GestureHoldDetector] Initialize...\n");
2042         }
2043         else
2044         {
2045             //reset local hold_grab_mask variable
2046             g_pGesture->has_hold_grabmask = 0;
2047
2048             g_pGesture->hold_detector_activate = 0;
2049             HoldDetectorDebugPrint("[GestureHoldDetector] has_hold_grabmask=0 and g_pGesture->hold_detector_activate=0\n");
2050             return;
2051         }
2052     }
2053
2054     if (IGNORE_EVENTS == g_pGesture->ehtype ||
2055             device->id < g_pGesture->first_fingerid)
2056     {
2057         HoldDetectorDebugPrint("[GestureHoldDetector] Return (IGNORE_EVENTS or device->id:%d < first_fingerid:%d)\n", device->id, g_pGesture->first_fingerid);
2058         return;
2059     }
2060
2061     palm_flag = GestureGetPalmValuator(ev, device);
2062
2063     if (palm_flag)
2064     {
2065         GestureHandleGesture_Hold(0, 0, 0, PALM_HOLD_TIME_THRESHOLD, GestureBegin);
2066         GestureHandleGesture_Hold(0, 0, 0, PALM_HOLD_TIME_THRESHOLD, GestureEnd);
2067
2068         g_pGesture->hold_detector_activate = 0;
2069         g_pGesture->has_hold_grabmask = 0;
2070         HoldDetectorDebugPrint("[GestureHoldDetector] palm_flag:%d enable\n", palm_flag);
2071         return;
2072     }
2073     else
2074     {
2075         HoldDetectorDebugPrint("[GestureHoldDetector] palm_flag:%d disable\n", palm_flag);
2076         return;
2077     }
2078
2079     HoldDetectorDebugPrint("[GestureHoldDetector] g_pGesture->num_mt_devices:%d\n", g_pGesture->num_mt_devices);
2080
2081 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
2082     for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
2083     {
2084         if( device->id == g_pGesture->mt_devices[i]->id )
2085         {
2086             idx = i;
2087             break;
2088         }
2089     }
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_
2095
2096     switch (type)
2097     {
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;
2102             num_pressed++;
2103             HoldDetectorDebugPrint("[GestureHoldDetector][P] cx:%d, cy:%d, num_pressed:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy, num_pressed);
2104
2105             if (num_pressed < 2)
2106             {
2107                 HoldDetectorDebugPrint("[GestureHoldDetector][P] num_pressed:%d\n", num_pressed);
2108                 break;
2109             }
2110
2111             if (num_pressed > g_pGesture->num_mt_devices)
2112                 num_pressed = g_pGesture->num_mt_devices;
2113
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);
2117
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;
2122
2123             pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1);
2124
2125             for (i = 1; i < num_pressed; i++)
2126             {
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);
2128
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;
2133
2134                 pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1);
2135             }
2136             break;
2137
2138         case GESTURE_TOUCH_MOTION:
2139             if (BTN_RELEASED == g_pGesture->cts[idx].status)
2140                 return;
2141
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;
2145
2146             HoldDetectorDebugPrint("[GestureHoldDetector][M] cx:%d, cy:%d, num_pressed:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy, num_pressed);
2147
2148             if (num_pressed < 2)
2149             {
2150                 HoldDetectorDebugPrint("[GestureHoldDetector][M] num_pressed:%d\n", num_pressed);
2151                 break;
2152             }
2153
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);
2157
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;
2162
2163             pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1);
2164
2165             for (i = 1; i < num_pressed; i++)
2166             {
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);
2168
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;
2173
2174                 pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1);
2175             }
2176             break;
2177
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;
2182
2183             HoldDetectorDebugPrint("[GestureHoldDetector][R] cx:%d, cy:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy);
2184
2185             num_pressed--;
2186             if (num_pressed <3)
2187             {
2188                 pixman_region_init(&g_pGesture->chold_area);
2189             }
2190             break;
2191     }
2192
2193     if (num_pressed >= 2)
2194     {
2195         hold_area_size = AREA_SIZE(&g_pGesture->chold_area.extents);
2196
2197         HoldDetectorDebugPrint("[GestureHoldDetector] hold_area_size=%d, pPalmMisc->half_scrn_area_size=%d\n", hold_area_size, pPalmMisc->half_scrn_area_size);
2198
2199         if (pPalmMisc->half_scrn_area_size <= hold_area_size)
2200         {
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);
2203
2204             g_pGesture->hold_detector_activate = 0;
2205             g_pGesture->has_hold_grabmask = 0;
2206         }
2207     }
2208     else
2209     {
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);
2212     }
2213 }
2214
2215
2216 static int
2217 GesturePalmGetScreenInfo()
2218 {
2219     int i;
2220     pixman_region16_t tarea;
2221     PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
2222     ScreenPtr pScreen = miPointerCurrentScreen();
2223
2224     if (!pScreen)
2225     {
2226         DetailDebugPrint("[X11][GesturePalmGetScreenInfo]Failed to get screen information !\n");
2227
2228         pPalmMisc->scrn_width = pPalmMisc->scrn_height = 0;
2229         return 0;
2230     }
2231
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);
2236
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);
2240
2241     DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->half_scrn_area_size = %d\n", pPalmMisc->half_scrn_area_size);
2242
2243     for (i = 0; i < PALM_HORIZ_ARRAY_COUNT; i++)
2244     {
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);
2247     }
2248     for (i = 0; i < PALM_VERTI_ARRAY_COUNT; i++)
2249     {
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);
2252     }
2253
2254     return 1;
2255 }
2256
2257
2258 static inline void
2259 GestureEnableDisable()
2260 {
2261     GestureEnable(1, FALSE, g_pGesture->this_device);
2262 #if 0
2263     if ((g_pGesture->grabMask) || (g_pGesture->lastSelectedWin != None))
2264     {
2265         GestureEnable(1, FALSE, g_pGesture->this_device);
2266     }
2267     else
2268     {
2269         GestureEnable(0, FALSE, g_pGesture->this_device);
2270     }
2271 #endif
2272 }
2273
2274 void
2275 GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent)
2276 {
2277     g_pGesture->grabMask = *pGrabMask;
2278     g_pGesture->GrabEvents = (GestureGrabEventPtr)pGrabEvent;
2279     GestureEnableDisable();
2280 }
2281
2282 void
2283 GestureCbEventsSelected(Window win, Mask *pEventMask)
2284 {
2285     g_pGesture->lastSelectedWin = win;
2286     g_pGesture->lastSelectedMask = (pEventMask) ? *pEventMask : 0;
2287     GestureEnableDisable();
2288 }
2289
2290 WindowPtr
2291 GestureGetEventsWindow(void)
2292 {
2293     Mask mask;
2294     WindowPtr pWin;
2295
2296     pWin = GestureWindowOnXY(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py);
2297
2298     if (pWin)
2299     {
2300         DetailDebugPrint("[GestureGetEventsWindow] pWin->drawable.id=0x%x\n", pWin->drawable.id);
2301         g_pGesture->gestureWin = pWin->drawable.id;
2302     }
2303     else
2304     {
2305         DetailDebugPrint("[GestureGetEventsWindow] GestureWindowOnXY returns NULL !\n");
2306         return NULL;
2307     }
2308
2309     if (g_pGesture->gestureWin == g_pGesture->lastSelectedWin)
2310     {
2311         g_pGesture->eventMask = g_pGesture->lastSelectedMask;
2312         goto nonempty_eventmask;
2313     }
2314
2315     //check selected event(s)
2316     if (!GestureHasSelectedEvents(pWin, &g_pGesture->eventMask))
2317     {
2318         g_pGesture->eventMask = 0;
2319     }
2320     else
2321     {
2322         g_pGesture->lastSelectedWin = g_pGesture->gestureWin;
2323         g_pGesture->lastSelectedMask = g_pGesture->eventMask;
2324     }
2325
2326     if (!g_pGesture->eventMask && !g_pGesture->grabMask)
2327     {
2328         DetailDebugPrint("[X11][GestureGetEventsWindow] No grabbed events or no events were selected for window(0x%x) !\n", pWin->drawable.id);
2329         return NULL;
2330     }
2331
2332 nonempty_eventmask:
2333
2334     DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->eventMask=0x%x\n", g_pGesture->eventMask);
2335
2336     mask = (GESTURE_FILTER_MASK_ALL & ~(g_pGesture->grabMask | g_pGesture->eventMask));
2337
2338     DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x, mask=0x%x\n", g_pGesture->filter_mask, mask);
2339
2340     g_pGesture->filter_mask = mask;
2341
2342     DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x\n", g_pGesture->filter_mask);
2343
2344     return pWin;
2345 }
2346
2347 static CARD32
2348 GestureSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2349 {
2350     g_pGesture->filter_mask |= WTapFilterMask;
2351     g_pGesture->filter_mask |= WHoldFilterMask;
2352     //LOGI("[GroupTap][GroupHold] 50ms after 1st finger.\n");
2353
2354     DetailDebugPrint("[GestureSingleFingerTimerHandler] TapFilterMask, HoldFilterMask \n");
2355
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)))
2357     {
2358         DetailDebugPrint("[GestureSingleFingerTimerHandler] press_point: %d\n", g_pGesture->flick_pressed_point);
2359         DetailDebugPrint("[GestureSingleFingerTimerHandler] FlickFilterMask\n");
2360         g_pGesture->filter_mask |= WFlickFilterMask;
2361     }
2362
2363     if (g_pGesture->flick_pressed_point == FLICK_POINT_DOWN && abs(g_pGesture->fingers[0].py - g_pGesture->fingers[0].my) < 3)
2364     {
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;
2368     }
2369
2370     DetailDebugPrint("[GestureSingleFingerTimerHandler] expired !\n");
2371
2372     if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
2373     {
2374         if ( ERROR_INVALPTR == GestureFlushOrDrop())
2375         {
2376             DetailDebugPrint("[GestureSingleFingerTimerHandler] AllFilterMask, Flush!\n");
2377             GestureControl(g_pGesture->this_device, DEVICE_OFF);
2378         }
2379     }
2380
2381     return 0;
2382 }
2383
2384 void
2385 GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
2386 {
2387     int i;
2388     static OsTimerPtr single_finger_timer = NULL;
2389     int idx = -1;
2390
2391     if (PROPAGATE_EVENTS == g_pGesture->ehtype || device->id < g_pGesture->first_fingerid)
2392     {
2393         return;
2394     }
2395 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
2396     for (i = 0; i < g_pGesture->num_mt_devices; i++)
2397     {
2398         if (device->id == g_pGesture->mt_devices[i]->id)
2399         {
2400             idx = i;
2401             break;
2402         }
2403     }
2404 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
2405     idx = GestureGetTouchIndex(device->id, ev->device_event.touchid, type);
2406 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
2407
2408     if (idx < 0)
2409         return;
2410
2411     switch (type)
2412     {
2413         case GESTURE_TOUCH_PRESS:
2414             if (idx == 0)
2415             {
2416                 g_pGesture->event_sum[0] = BTN_PRESSED;
2417             }
2418
2419             g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
2420
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;
2424
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;
2429
2430             g_pGesture->num_pressed++;
2431             g_pGesture->inc_num_pressed = g_pGesture->num_pressed;
2432
2433             if (g_pGesture->inc_num_pressed == 1)
2434             {
2435                 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2436             }
2437             else
2438             {
2439                 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2440
2441                 for (i = 1; i < g_pGesture->inc_num_pressed; i++)
2442                 {
2443                     pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
2444                 }
2445             }
2446
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);
2449
2450             if (g_pGesture->num_pressed == 1)
2451             {
2452                 single_finger_timer = TimerSet(single_finger_timer, 0, 50, GestureSingleFingerTimerHandler, NULL);
2453
2454                 if (g_pGesture->fingers[idx].py <= g_pGesture->flick_press_area)
2455                 {
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)))
2459                     {
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");
2464                     }
2465                     else
2466                     {
2467                         DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_UP\n");
2468                         g_pGesture->flick_pressed_point = FLICK_POINT_UP;
2469                     }
2470                 }
2471                 else
2472                 {
2473                     LOGI("[BackKey][F] Press touch outside 40 pixel area from upper vezel. \n");
2474                 }
2475
2476                 if (g_pGesture->fingers[idx].py >= (g_pGesture->screen_height - g_pGesture->flick_press_area))
2477                 {
2478                     if (!g_pGesture->activate_flick_up)
2479                     {
2480                         g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2481                     }
2482                     else
2483                     {
2484                         DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_DOWN\n");
2485                         g_pGesture->flick_pressed_point = FLICK_POINT_DOWN;
2486                     }
2487                 }
2488                 else if ( g_pGesture->fingers[idx].px <= g_pGesture->flick_press_area_left)
2489                 {
2490                     if (!g_pGesture->activate_flick_right)
2491                     {
2492                         g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2493                     }
2494                     else
2495                     {
2496                         DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_LEFT\n");
2497                         g_pGesture->flick_pressed_point = FLICK_POINT_LEFT;
2498                     }
2499                 }
2500
2501                 DetailDebugPrint("[GestureRecognize][P] flick_press_point: %d\n", g_pGesture->flick_pressed_point);
2502
2503                 if ((g_pGesture->flick_pressed_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= g_pGesture->flick_pressed_point))
2504                 {
2505                     DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_NONE\n");
2506                     g_pGesture->filter_mask |= WFlickFilterMask;
2507                     g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2508                 }
2509                 else
2510                 {
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))
2513                     {
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;
2517                     }
2518                     if ((g_pGesture->flick_direction < FLICK_NORTHWARD) || (FLICK_NORTHWESTWARD < g_pGesture->flick_direction))
2519                     {
2520                         DetailDebugPrint("[GestureRecognize][P] Invalid flick direction\n");
2521                         g_pGesture->filter_mask |= WFlickFilterMask;
2522                         g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2523                     }
2524
2525                     DetailDebugPrint("[GestureRecognize][P] flick_direction: %d\n", g_pGesture->flick_direction);
2526                 }
2527             }
2528             else
2529             {
2530                 DetailDebugPrint("[GestureRecognize][P] Two more fingers come on!\n");
2531                 TimerCancel(single_finger_timer);
2532                 single_finger_timer = NULL;
2533             }
2534             break;
2535
2536         case GESTURE_TOUCH_MOTION:
2537
2538             if (!g_pGesture->fingers[idx].ptime)
2539             {
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]);
2542                 return;
2543             }
2544
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]);
2548
2549             if (idx == 0)
2550             {
2551                 g_pGesture->event_sum[0] += BTN_MOVING;
2552             }
2553
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;
2558
2559             if (g_pGesture->inc_num_pressed == 1)
2560             {
2561                 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2562             }
2563             else
2564             {
2565                 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2566
2567                 for (i = 1; i < g_pGesture->inc_num_pressed; i++)
2568                 {
2569                     pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
2570                 }
2571             }
2572
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);
2575
2576             break;
2577
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]);
2583
2584             g_pGesture->num_pressed--;
2585
2586             if (g_pGesture->num_pressed == 0)
2587             {
2588                 DetailDebugPrint("[GestureRecognize] All fingers were released !\n");
2589             }
2590             else if (g_pGesture->num_pressed < 0)
2591             {
2592                 DetailDebugPrint("[GestureRecognize] All fingers were released. But, num_pressed is under 0 !\n");
2593             }
2594
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);
2597
2598             break;
2599     }
2600
2601     if (!(g_pGesture->filter_mask & WFlickFilterMask))
2602     {
2603         DetailDebugPrint("[GestureRecognize] GestureRecognize_groupFlick !\n");
2604         GestureRecognize_GroupFlick(type, ev, device, idx, g_pGesture->flick_pressed_point, g_pGesture->flick_direction);
2605     }
2606     if (!(g_pGesture->filter_mask & WTapFilterMask))
2607     {
2608         DetailDebugPrint("[GestureRecognize] GestureRecognize_groupTap !\n");
2609         GestureRecognize_GroupTap(type, ev, device, idx, 0);
2610     }
2611     if (!(g_pGesture->filter_mask & WHoldFilterMask))
2612     {
2613         DetailDebugPrint("[GestureRecognize] GestureRecognize_groupHold !\n");
2614         GestureRecognize_GroupHold(type, ev, device, idx, 0);
2615     }
2616 /*
2617     if (!(g_pGesture->filter_mask & WPalmFlickFilterMask))
2618     {
2619         DetailDebugPrint("[GestureRecognize] GestureRecognize_palmFlick !\n");
2620         GestureRecognize_PalmFlick(type, ev, device, idx);
2621     }
2622 */
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);
2625
2626     if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
2627     {
2628         if (!g_pGesture->recognized_gesture)
2629         {
2630             DetailDebugPrint("[GestureRecognize][F] 1 !\n");
2631             goto flush_or_drop;
2632         }
2633         else if (!g_pGesture->num_pressed)
2634         {
2635             DetailDebugPrint("[GestureRecognize][F] 2 !\n");
2636             goto flush_or_drop;
2637         }
2638     }
2639
2640     if (g_pGesture->recognized_gesture)
2641     {
2642         if (g_pGesture->ehtype == KEEP_EVENTS)
2643         {
2644             DetailDebugPrint("[GestureRecognize] Keep Event !\n");
2645             GestureEventsDrop();
2646         }
2647         g_pGesture->ehtype = IGNORE_EVENTS;
2648     }
2649     return;
2650
2651 flush_or_drop:
2652
2653     DetailDebugPrint("[GestureRecognize] GestureFlushOrDrop() !\n");
2654
2655     if (ERROR_INVALPTR == GestureFlushOrDrop())
2656     {
2657         GestureControl(g_pGesture->this_device, DEVICE_OFF);
2658     }
2659 }
2660
2661 ErrorStatus GestureFlushOrDrop(void)
2662 {
2663     ErrorStatus err;
2664
2665     if (g_pGesture->recognized_gesture)
2666     {
2667         g_pGesture->ehtype = IGNORE_EVENTS;
2668         GestureEventsDrop();
2669         DetailDebugPrint("[GestureFlushOrDrop][Drop] IGNORE_EVENTS\n");
2670     }
2671     else
2672     {
2673         g_pGesture->ehtype = PROPAGATE_EVENTS;
2674
2675         err = GestureEventsFlush();
2676
2677         if (ERROR_NONE != err)
2678         {
2679             return err;
2680         }
2681
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);
2686     }
2687
2688     err = GestureRegionsReinit();
2689
2690     if (ERROR_NONE != err)
2691     {
2692         return err;
2693     }
2694
2695     g_pGesture->pTempWin = NULL;
2696     g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0;
2697     g_pGesture->event_sum[0] = 0;
2698
2699     return ERROR_NONE;
2700 }
2701
2702 void
2703 GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2704 {
2705     int i;
2706     int idx;
2707
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());
2711 #endif
2712
2713     if (!g_pGesture->is_active)
2714     {
2715         g_pGesture->ehtype = PROPAGATE_EVENTS;
2716         DetailDebugPrint("[GestureHandleMTSyncEvent] PROPAGATE_EVENT\n");
2717         return;
2718     }
2719
2720     switch(ev->any_event.sync)
2721     {
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;
2726         }
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))
2733         {
2734             int zero = 0;
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_
2740         }
2741         g_pGesture->mtsync_flag |= MTSYNC_FLAG_ROTARY;
2742         DetailDebugPrint("[GestureHandleMTSyncEvent] Rotary input starts. Now touch events are dropped!\n");
2743         break;
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");
2747         break;
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;
2758
2759         for (i=0; i < g_pGesture->num_mt_devices; i++)
2760         {
2761             g_pGesture->fingers[i].ptime = 0;
2762             g_pGesture->max_mt_tmajor[i] = 0;
2763         }
2764         break;
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;
2773         break;
2774     case MTOUCH_FRAME_SYNC_UPDATE:
2775         g_pGesture->mtsync_flag |= MTSYNC_FLAG_TOUCH;
2776         g_pGesture->mtsync_total_count++;
2777
2778         DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_Update. mt_total_sync=%d\n", g_pGesture->mtsync_total_count);
2779
2780         if ((g_pGesture->inc_num_pressed < 2) && (g_pGesture->filter_mask != GESTURE_WATCH_FILTER_MASK_ALL))
2781         {
2782             if (g_pGesture->num_tap_repeated == 1 || g_pGesture->num_tap_repeated == 2)
2783             {
2784                 if (g_pGesture->mtsync_total_count >= 6)
2785                 {
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");
2791                 }
2792             }
2793
2794             if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
2795             {
2796                 DetailDebugPrint("[GestureHandleMTSyncEvent] Gesture filter mask all. GestureFlushOrDrop() !\n");
2797
2798                 if (ERROR_INVALPTR == GestureFlushOrDrop())
2799                 {
2800                     GestureControl(g_pGesture->this_device, DEVICE_OFF);
2801                 }
2802             }
2803         }
2804         break;
2805     default:
2806         ErrorF("[GestureHandleMTSyncEvent] Unknown MTSync Event received.\n");
2807         break;
2808     }
2809 }
2810
2811 void GestureEmulateHWKey(DeviceIntPtr dev, int keycode)
2812 {
2813     if (dev)
2814     {
2815         DetailDebugPrint("[GestureEmulateHWKey] keycode=%d\n", keycode);
2816         xf86PostKeyboardEvent(dev, keycode, 1);
2817         xf86PostKeyboardEvent(dev, keycode, 0);
2818     }
2819 }
2820
2821 void
2822 GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2823 {
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_
2829     int idx = 0;
2830
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);
2834         goto out;
2835     }
2836 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
2837
2838     if (g_pGesture->ehtype != KEEP_EVENTS)
2839     {
2840         if(g_pGesture->mtsync_flag & MTSYNC_FLAG_ROTARY)
2841         {
2842             DetailDebugPrint("[GestureHandleButtonPressEvent] Rotary input is coming. Dropping touch events.\n");
2843             return;
2844         }
2845         else if (g_pGesture->mtsync_flag & ~MTSYNC_FLAG_TOUCH)
2846         {
2847             DetailDebugPrint("[GestureHandleButtonPressEvent] Other input is coming. Dropping touch events.\n");
2848             return;
2849         }
2850     }
2851
2852     switch (g_pGesture->ehtype)
2853     {
2854         case KEEP_EVENTS:
2855             DetailDebugPrint("[GestureHandleButtonPressEvent] KEEP_EVENT\n");
2856
2857             if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device))
2858             {
2859                 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2860                 goto out;
2861             }
2862
2863             if (g_pGesture->num_mt_devices)
2864             {
2865                 GestureRecognize(GESTURE_TOUCH_PRESS, ev, device);
2866             }
2867             else
2868             {
2869                 device->public.processInputProc(ev, device);
2870             }
2871
2872             GestureHoldDetector(GESTURE_TOUCH_PRESS, ev, device);
2873             break;
2874
2875         case PROPAGATE_EVENTS:
2876             DetailDebugPrint("[GestureHandleButtonPressEvent] PROPAGATE_EVENT\n");
2877
2878             device->public.processInputProc(ev, device);
2879             GestureHoldDetector(GESTURE_TOUCH_PRESS, ev, device);
2880             break;
2881
2882         case IGNORE_EVENTS:
2883             DetailDebugPrint("[GestureHandleButtonPressEvent] IGNORE_EVENTS\n");
2884
2885             GestureRecognize(GESTURE_TOUCH_PRESS, ev, device);
2886             break;
2887
2888         default:
2889             break;
2890     }
2891 out:
2892     TTRACE_END();
2893     return;
2894 }
2895
2896 void
2897 GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2898 {
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);
2902 #endif
2903 #ifndef _SUPPORT_EVDEVMULTITOUCH_DRV_
2904     int idx = 0;
2905
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);
2909         goto out;
2910     }
2911 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
2912
2913     if (g_pGesture->ehtype != KEEP_EVENTS)
2914     {
2915         if(g_pGesture->mtsync_flag & MTSYNC_FLAG_ROTARY)
2916         {
2917             DetailDebugPrint("[GestureHandleMotionEvent] Rotary input is coming. Dropping touch events.\n");
2918             return;
2919         }
2920         else if (g_pGesture->mtsync_flag & ~MTSYNC_FLAG_TOUCH)
2921         {
2922             DetailDebugPrint("[GestureHandleMotionEvent] Other input is coming. Dropping touch events.\n");
2923             return;
2924         }
2925     }
2926
2927     switch (g_pGesture->ehtype)
2928     {
2929         case KEEP_EVENTS:
2930             if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device))
2931             {
2932                 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2933                 goto out;
2934             }
2935
2936             if (g_pGesture->num_mt_devices)
2937             {
2938                 GestureRecognize(GESTURE_TOUCH_MOTION, ev, device);
2939             }
2940             else
2941             {
2942                 device->public.processInputProc(ev, device);
2943             }
2944
2945             GestureHoldDetector(GESTURE_TOUCH_MOTION, ev, device);
2946             break;
2947
2948         case PROPAGATE_EVENTS:
2949             device->public.processInputProc(ev, device);
2950             GestureHoldDetector(GESTURE_TOUCH_MOTION, ev, device);
2951             break;
2952
2953         case IGNORE_EVENTS:
2954             GestureRecognize(GESTURE_TOUCH_MOTION, ev, device);
2955             break;
2956
2957         default:
2958             break;
2959     }
2960 out:
2961     TTRACE_END();
2962     return;
2963 }
2964
2965 void
2966 GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2967 {
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);
2971 #endif
2972 #ifndef _SUPPORT_EVDEVMULTITOUCH_DRV_
2973     int idx = 0;
2974
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);
2978         goto out;
2979     }
2980 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
2981
2982     if (g_pGesture->ehtype != KEEP_EVENTS)
2983     {
2984         if(!(g_pGesture->mtsync_flag & MTSYNC_FLAG_TOUCH))
2985         {
2986             if(g_pGesture->mtsync_flag & MTSYNC_FLAG_ROTARY)
2987             {
2988                 DetailDebugPrint("[GestureHandleButtonReleaseEvent] Rotary input is coming. Dropping touch events.\n");
2989                 return;
2990             }
2991             else if (g_pGesture->mtsync_flag & ~MTSYNC_FLAG_TOUCH)
2992             {
2993                 DetailDebugPrint("[GestureHandleButtonReleaseEvent] Other input is coming. Dropping touch events.\n");
2994                 return;
2995             }
2996         }
2997     }
2998
2999     switch (g_pGesture->ehtype)
3000     {
3001         case KEEP_EVENTS:
3002             DetailDebugPrint("[GestureHandleButtonPressEvent] KEEP_EVENT\n");
3003
3004             if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device))
3005             {
3006                 GestureControl(g_pGesture->this_device, DEVICE_OFF);
3007                 goto out;
3008             }
3009
3010             if (g_pGesture->num_mt_devices)
3011             {
3012                 GestureRecognize(GESTURE_TOUCH_RELEASE, ev, device);
3013             }
3014             else
3015             {
3016                 device->public.processInputProc(ev, device);
3017             }
3018
3019             GestureHoldDetector(GESTURE_TOUCH_RELEASE, ev, device);
3020             break;
3021
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 )
3026                      {
3027                          if( g_pGesture->anr_window == NULL )
3028                          {
3029                              g_pGesture->anr_window = _GestureFindANRWindow(device);
3030                          }
3031                          Time current_time;
3032
3033                          // Send event to the e17 process.
3034                          current_time = GetTimeInMillis();
3035                          if( g_pGesture->anr_window != NULL )
3036                          {
3037                              // Check anr_window validation.
3038                              if( dixLookupWindow(&g_pGesture->anr_window, prop_anr_event_window_xid, serverClient, DixSetPropAccess) != BadWindow )
3039                              {
3040                                  if( serverClient->devPrivates != NULL )
3041                                      dixChangeWindowProperty (serverClient, g_pGesture->anr_window, prop_anr_in_input_event,
3042                                                                                XA_CARDINAL, 32, PropModeReplace, 1, &current_time, TRUE);
3043                              }
3044                              else
3045                              {
3046                                  prop_anr_event_window_xid = 0;
3047                                  g_pGesture->anr_window = NULL;
3048                              }
3049                              DetailDebugPrint("[GestureHandleButtonReleaseEvent] Release TOUCH!! devid=%d time:%d cur: %d\n", device->id, ev->any.time, GetTimeInMillis());
3050                          }
3051                      }
3052 #endif
3053             device->public.processInputProc(ev, device);
3054             GestureHoldDetector(GESTURE_TOUCH_RELEASE, ev, device);
3055 #if 0
3056             GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down);
3057             GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up);
3058 #endif
3059             break;
3060
3061         case IGNORE_EVENTS:
3062             DetailDebugPrint("[GestureHandleButtonReleaseEvent] IGNORE_EVENTS\n");
3063             GestureRecognize(GESTURE_TOUCH_RELEASE, ev, device);
3064             break;
3065
3066         default:
3067             break;
3068     }
3069 out:
3070     TTRACE_END();
3071     return;
3072 }
3073
3074 void
3075 GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
3076 {
3077     TTRACE_BEGIN("XORG:GESTURE:KEY_PRESS");
3078     if ((ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0))
3079     {
3080         g_pGesture->power_pressed = 2;
3081         g_pGesture->power_device = device;
3082
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);
3085     }
3086     TTRACE_END();
3087     device->public.processInputProc(ev, device);
3088 }
3089
3090 void
3091 GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
3092 {
3093     TTRACE_BEGIN("XORG:GESTURE:KEY_RELEASE");
3094     if ((ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0))
3095     {
3096         g_pGesture->power_pressed = 1;
3097         g_pGesture->power_device = device;
3098
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);
3101     }
3102     TTRACE_END();
3103     device->public.processInputProc(ev, device);
3104 }
3105
3106 static void
3107 GestureHandleClientState (CallbackListPtr *list, pointer closure, pointer calldata)
3108 {
3109     NewClientInfoRec *clientinfo = (NewClientInfoRec*)calldata;
3110     ClientPtr client = clientinfo->client;
3111
3112     if (client->clientState != ClientStateGone)
3113     {
3114         return;
3115     }
3116
3117     if (!g_pGesture->factory_cmdname)
3118     {
3119         return;
3120     }
3121
3122     if (strncmp(client->clientIds->cmdname, g_pGesture->factory_cmdname, strlen(g_pGesture->factory_cmdname)))
3123     {
3124         return;
3125     }
3126
3127     if (g_pGesture->is_active == 0)
3128     {
3129         int prop_val = 1;
3130         int rc = XIChangeDeviceProperty(g_pGesture->this_device, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &prop_val, FALSE);
3131
3132         ErrorF("[GestureHandleClientState] %s is exited unintentionally\n", g_pGesture->factory_cmdname);
3133
3134         if (rc != Success)
3135         {
3136             ErrorF("[GestureHandleClientState] Failed to Gesture Enable\n");
3137             return;
3138         }
3139     }
3140 }
3141
3142 static ErrorStatus
3143 GestureEnableEventHandler(InputInfoPtr pInfo)
3144 {
3145     Bool res;
3146     GestureDevicePtr pGesture = pInfo->private;
3147
3148     TTRACE_BEGIN("XORG:GESTURE:ENABLE_EVENT_HANDLER");
3149
3150     res = GestureInstallResourceStateHooks();
3151
3152     if (!res)
3153     {
3154         ErrorF("[GestureEnableEventHandler] Failed on GestureInstallResourceStateHooks() !\n");
3155         TTRACE_END();
3156         return ERROR_ABNORMAL;
3157     }
3158
3159 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
3160     res = GestureSetMaxNumberOfFingers((int)MAX_MT_DEVICES);
3161     if (!res)
3162     {
3163         ErrorF("[GestureEnableEventHandler] Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)MAX_MT_DEVICES);
3164         goto failed;
3165     }
3166 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
3167
3168     res = GestureRegisterCallbacks(GestureCbEventsGrabbed, GestureCbEventsSelected);
3169
3170     if (!res)
3171     {
3172         ErrorF("[GestureEnableEventHandler] Failed to register callbacks for GestureEventsGrabbed(), GestureEventsSelected() !\n");
3173         goto failed;
3174     }
3175
3176     GestureRegisterDeviceInfo(pInfo->dev);
3177
3178     TTRACE_END();
3179     return ERROR_NONE;
3180
3181 failed:
3182     GestureUninstallResourceStateHooks();
3183     GestureUnsetMaxNumberOfFingers();
3184
3185     TTRACE_END();
3186     return ERROR_ABNORMAL;
3187 }
3188
3189 static ErrorStatus
3190 GestureDisableEventHandler(void)
3191 {
3192     ErrorStatus err = ERROR_NONE;
3193
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);
3200
3201     err = GestureFiniEQ();
3202
3203     if (ERROR_INVALPTR == err)
3204     {
3205         ErrorF("[GestureDisableEventHandler] EQ is invalid or was freed already !\n");
3206     }
3207
3208     GestureRegisterCallbacks(NULL, NULL);
3209     GestureUninstallResourceStateHooks();
3210
3211     return err;
3212 }
3213
3214 static void
3215 GestureRegisterDeviceInfo(DeviceIntPtr device)
3216 {
3217         InputInfoPtr  pInfo = device->public.devicePrivate;
3218         GestureDevicePtr pGesture = pInfo->private;
3219         DeviceIntPtr dev;
3220         ScreenPtr pScreen = miPointerCurrentScreen();
3221         int width = 0, height = 0;
3222         int idx = 0;
3223         int i;
3224
3225         TTRACE_BEGIN("XORG:GESTURE:REGISTER_DEVICE");
3226 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
3227         for (i=0; i<MAX_MT_DEVICES; i++)
3228         {
3229                 pGesture->mt_devices[i] = NULL;
3230         }
3231 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
3232         pGesture->mt_devices = NULL;
3233 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
3234
3235         for( dev = inputInfo.pointer ; dev; dev = dev->next )
3236         {
3237                 if(IsMaster(dev) && IsPointerDevice(dev))
3238                 {
3239                         pGesture->master_pointer = dev;
3240                         ErrorF("[id:%d] Master Pointer=%s\n", dev->id, pGesture->master_pointer->name);
3241                         continue;
3242                 }
3243
3244                 if(IsXTestDevice(dev, NULL) && IsPointerDevice(dev))
3245                 {
3246                         pGesture->xtest_pointer = dev;
3247                         ErrorF("[id:%d] XTest Pointer=%s\n", dev->id, pGesture->xtest_pointer->name);
3248                         continue;
3249                 }
3250
3251                 if(IsPointerDevice(dev))
3252                 {
3253 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
3254                         if( idx >= MAX_MT_DEVICES )
3255                         {
3256                                 ErrorF("Number of mt device is over MAX_MT_DEVICES(%d) !\n", MAX_MT_DEVICES);
3257                                 continue;
3258                         }
3259                         if (strcasestr(dev->name, "Touchscreen"))
3260                         {
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);
3264                                 idx++;
3265                         }
3266 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
3267                         if (strcasestr(dev->name, "Touchscreen"))
3268                         {
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;
3272                                 if (touchInfo)
3273                                 {
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;
3277                                 }
3278                                 else
3279                                 {
3280                                         ErrorF("device(%d) hasn't touch class\n", dev->id);
3281                                 }
3282                         }
3283 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
3284                 }
3285         }
3286
3287         if( !pGesture->master_pointer || !pGesture->xtest_pointer )
3288         {
3289                 ErrorF("Failed to get info of master pointer or XTest pointer !\n");
3290                 pGesture->num_mt_devices = 0;
3291
3292                 TTRACE_END();
3293                 return;
3294         }
3295
3296         pGesture->num_mt_devices = idx;
3297
3298         if( !pGesture->num_mt_devices )
3299         {
3300                 ErrorF("Failed to mt device information !\n");
3301                 pGesture->num_mt_devices = 0;
3302                 pGesture->first_fingerid = -1;
3303
3304                 TTRACE_END();
3305                 return;
3306         }
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_
3315
3316 #ifndef _SUPPORT_EVDEVMULTITOUCH_DRV_
3317         Bool res = GestureSetMaxNumberOfFingers(g_pGesture->num_mt_devices);
3318
3319         if( !res )
3320         {
3321                 ErrorF("Failed on GestureSetMaxNumberOfFingers(%d) !\n", g_pGesture->num_mt_devices);
3322                 goto failed;
3323         }
3324 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
3325
3326         pGesture->pRootWin = RootWindow(pGesture->master_pointer);
3327
3328         if(g_pGesture->palm_misc.enabled)
3329                 GesturePalmGetScreenInfo();
3330
3331         g_pGesture->pTempWin = NULL;
3332         g_pGesture->inc_num_pressed = 0;
3333
3334         if( ERROR_NONE != GestureRegionsInit() || ERROR_NONE != GestureInitEQ() )
3335         {
3336                 goto failed;
3337         }
3338
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);
3345
3346         TTRACE_END();
3347         return;
3348
3349 failed:
3350         GestureUninstallResourceStateHooks();
3351         GestureUnsetMaxNumberOfFingers();
3352         TTRACE_END();
3353 }
3354
3355 #ifndef _SUPPORT_EVDEVMULTITOUCH_DRV_
3356 static void
3357 GestureAlloc(int capability)
3358 {
3359         if (!g_pGesture)
3360         {
3361                 ErrorF("[GestureAlloc] Failed to allocate a gesture drv's structures\n");
3362                 return;
3363         }
3364
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));
3370
3371         /* g_pGesture->palmFlickInfo */
3372         {
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));
3377
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));
3382
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));
3387
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));
3391         }
3392         /* g_pGesture->palmInfo */
3393         {
3394                 g_pGesture->palmInfo.pressed_idx = (int *)calloc(capability, sizeof(int));
3395         }
3396 }
3397
3398 #define GFree(x) \
3399         if(x) { \
3400                 free(x); \
3401                 x=NULL; \
3402         } \
3403
3404 static void
3405 GestureDealloc()
3406 {
3407         if (!g_pGesture)
3408         {
3409                 ErrorF("[GestureDealloc] Failed to free a gesture drv's structures\n");
3410                 return;
3411         }
3412
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)
3418
3419         /* g_pGesture->palmFlickInfo */
3420         {
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)
3425
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)
3430
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)
3435
3436                 GFree(g_pGesture->palmFlickInfo.max_tmajor)
3437                 GFree(g_pGesture->palmFlickInfo.is_tmajor_invalid)
3438                 GFree(g_pGesture->palmFlickInfo.mt_sync_count)
3439         }
3440         /* g_pGesture->palmInfo */
3441         {
3442                 GFree(g_pGesture->palmInfo.pressed_idx)
3443         }
3444 }
3445 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
3446
3447
3448 BOOL
3449 IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
3450 {
3451     if (IsMaster(dev))
3452     {
3453         return FALSE;
3454     }
3455
3456     if (master)
3457     {
3458         return (dev->xtest_master_id == master->id);
3459     }
3460
3461     return (dev->xtest_master_id != 0);
3462 }
3463
3464 void
3465 GestureEnable(int enable, Bool prop, DeviceIntPtr dev)
3466 {
3467     if ((!enable) && (g_pGesture->is_active))
3468     {
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);
3474
3475         if (!res)
3476         {
3477             ErrorF("[GestureEnable] Failed to add callback for client state\n");
3478             return;
3479         }
3480     }
3481
3482     else if ((enable) && (!g_pGesture->is_active))
3483     {
3484         g_pGesture->ehtype = KEEP_EVENTS;
3485         mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
3486         g_pGesture->is_active = 1;
3487         ErrorF("[GestureEnable] Enabled !\n");
3488
3489         DeleteCallback (&ClientStateCallback, GestureHandleClientState, NULL);
3490     }
3491
3492     if (!prop)
3493     {
3494         XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
3495     }
3496 }
3497
3498 ErrorStatus
3499 GestureRegionsInit(void)
3500 {
3501     int i;
3502
3503     if (!g_pGesture)
3504     {
3505         return ERROR_INVALPTR;
3506     }
3507
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_
3514     {
3515         pixman_region_init_rect(&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
3516     }
3517
3518     return ERROR_NONE;
3519 }
3520
3521 ErrorStatus
3522 GestureRegionsReinit(void)
3523 {
3524     if (!g_pGesture)
3525     {
3526         ErrorF("[GestureRegionsReinit] Invalid pointer access !\n");
3527         return ERROR_INVALPTR;
3528     }
3529
3530     pixman_region_init(&g_pGesture->area);
3531
3532     return ERROR_NONE;
3533 }
3534
3535 ErrorStatus
3536 GestureInitEQ(void)
3537 {
3538     int i;
3539     IEventPtr tmpEQ;
3540
3541     tmpEQ = (IEventRec *)calloc(GESTURE_EQ_SIZE, sizeof(IEventRec));
3542
3543     if (!tmpEQ)
3544     {
3545         ErrorF("[GestureInitEQ] Failed to allocate memory for EQ !\n");
3546         return ERROR_ALLOCFAIL;
3547     }
3548
3549     for (i = 0; i < GESTURE_EQ_SIZE; i++)
3550     {
3551         tmpEQ[i].event = (InternalEvent *)malloc(sizeof(InternalEvent));
3552         if (!tmpEQ[i].event)
3553         {
3554             ErrorF("[GestureInitEQ] Failed to allocation memory for each event buffer in EQ !\n");
3555             i--;
3556             while(i >= 0 && tmpEQ[i].event)
3557             {
3558                 free(tmpEQ[i].event);
3559                 tmpEQ[i].event = NULL;
3560             }
3561             free (tmpEQ);
3562             tmpEQ = NULL;
3563             return ERROR_ALLOCFAIL;
3564         }
3565     }
3566
3567     g_pGesture->EQ = tmpEQ;
3568     g_pGesture->headEQ = g_pGesture->tailEQ = 0;
3569
3570     return ERROR_NONE;
3571 }
3572
3573 ErrorStatus
3574 GestureFiniEQ(void)
3575 {
3576     int i;
3577
3578     if (!g_pGesture || !g_pGesture->EQ)
3579     {
3580         return ERROR_INVALPTR;
3581     }
3582
3583     for (i = 0; i < GESTURE_EQ_SIZE; i++)
3584     {
3585         if (g_pGesture->EQ[i].event)
3586         {
3587             free(g_pGesture->EQ[i].event);
3588             g_pGesture->EQ[i].event = NULL;
3589         }
3590     }
3591
3592     free(g_pGesture->EQ);
3593     g_pGesture->EQ = NULL;
3594
3595     return ERROR_NONE;
3596 }
3597
3598 ErrorStatus
3599 GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
3600 {
3601     int tail;
3602
3603     if (!g_pGesture || !g_pGesture->EQ)
3604     {
3605         ErrorF("[GestureEnqueueEvent] Invalid pointer access !\n");
3606         return ERROR_INVALPTR;
3607     }
3608
3609     tail = g_pGesture->tailEQ;
3610
3611     if (tail >= GESTURE_EQ_SIZE)
3612     {
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;
3617     }
3618
3619     if((g_pGesture->mtsync_flag & MTSYNC_FLAG_ROTARY) || (g_pGesture->mtsync_flag & ~MTSYNC_FLAG_TOUCH))
3620     {
3621         DetailDebugPrint("[GestureEnqueueEvent] Rotary or other input are coming. Do not push events to queue.\n");
3622         return ERROR_NONE;
3623     }
3624
3625     switch (ev->any.type)
3626     {
3627         case GESTURE_TOUCH_PRESS:
3628             DetailDebugPrint("[GestureEnqueueEvent] Press (id:%d)\n", device->id);
3629             break;
3630
3631         case GESTURE_TOUCH_RELEASE:
3632             DetailDebugPrint("[GestureEnqueueEvent] Releae (id:%d)\n", device->id);
3633             break;
3634
3635         case GESTURE_TOUCH_MOTION:
3636             DetailDebugPrint("[GestureEnqueueEvent] Motion (id:%d)\n", device->id);
3637             break;
3638     }
3639
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++;
3644
3645     return ERROR_NONE;
3646 }
3647
3648 ErrorStatus
3649 GestureEventsFlush(void)
3650 {
3651     int i;
3652     DeviceIntPtr device;
3653
3654     TTRACE_BEGIN("XORG:GESTURE:FLUSH_EVENT");
3655
3656     if (!g_pGesture->EQ)
3657     {
3658         ErrorF("[GestureEventsFlush] Invalid pointer access !\n");
3659         TTRACE_END();
3660         return ERROR_INVALPTR;
3661     }
3662
3663     DetailDebugPrint("[GestureEventsFlush]\n");
3664
3665     for (i = g_pGesture->headEQ; i < g_pGesture->tailEQ; i++)
3666     {
3667         device = g_pGesture->EQ[i].device;
3668         device->public.processInputProc(g_pGesture->EQ[i].event, device);
3669     }
3670
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_
3676     {
3677         g_pGesture->event_sum[i] = 0;
3678     }
3679
3680     g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
3681
3682     TTRACE_END();
3683     return ERROR_NONE;
3684 }
3685
3686 void
3687 GestureEventsDrop(void)
3688 {
3689     DetailDebugPrint("[GestureEventsDrop]\n");
3690     g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
3691 }
3692
3693 #ifdef HAVE_PROPERTIES
3694 static void
3695 GestureInitProperty(DeviceIntPtr dev)
3696 {
3697     int rc;
3698
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);
3702 #endif
3703
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);
3706
3707     if (rc != Success)
3708     {
3709         return;
3710     }
3711
3712     XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE);
3713 }
3714
3715 static int
3716 GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
3717         BOOL checkonly)
3718 {
3719     if (prop_gesture_recognizer_onoff == atom)
3720     {
3721         int data;
3722         if (val->format != 32 || val->type != XA_INTEGER || val->size != 1)
3723             return BadMatch;
3724
3725         if (!checkonly)
3726         {
3727             data = *((int *)val->data);
3728             GestureEnable(data, TRUE, dev);
3729         }
3730     }
3731     return Success;
3732 }
3733 #endif//HAVE_PROPERTIES
3734
3735 static int
3736 GestureInit(DeviceIntPtr device)
3737 {
3738     TTRACE_BEGIN("XORG:GESTURE:INIT");
3739 #ifdef HAVE_PROPERTIES
3740     GestureInitProperty(device);
3741     XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL);
3742 #endif
3743     //GestureEnable(1, FALSE, g_pGesture->this_device);
3744     TTRACE_END();
3745     return Success;
3746 }
3747
3748 static void
3749 GestureFini(DeviceIntPtr device)
3750 {
3751     XIRegisterPropertyHandler(device, NULL, NULL, NULL);
3752 }
3753
3754 static pointer
3755 GesturePlug(pointer module, pointer options, int *errmaj, int *errmin)
3756 {
3757     xf86AddInputDriver(&GESTURE, module, 0);
3758     return module;
3759 }
3760
3761 static void
3762 GestureUnplug(pointer p)
3763 {
3764 }
3765
3766 static int
3767 GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
3768 {
3769     int rc = BadAlloc;
3770     GestureDevicePtr pGesture;
3771
3772     TTRACE_BEGIN("XORG:GESTURE:PREINIT");
3773
3774     pGesture = calloc(1, sizeof(GestureDeviceRec));
3775
3776     if (!pGesture)
3777     {
3778         pInfo->private = NULL;
3779         //xf86DeleteInput(pInfo, 0);
3780         goto error;
3781     }
3782
3783     g_pGesture = pGesture;
3784
3785     pInfo->private = pGesture;
3786     pInfo->flags = 0;
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 */
3790
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;
3826
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__);
3844
3845     if (pGesture->hwkey_name)
3846     {
3847         ErrorF("[X11][%s] hwkey_name=%s\n", __FUNCTION__, pGesture->hwkey_name);
3848     }
3849
3850     pGesture->mtsync_flag = 0x00;
3851     g_pGesture->grabMask = g_pGesture->eventMask = 0;
3852
3853     xf86Msg(X_INFO, "%s: Using device %s.\n", pInfo->name, pGesture->device);
3854
3855     /* process generic options */
3856     xf86CollectInputOptions(pInfo, NULL);
3857     xf86ProcessCommonOptions(pInfo, pInfo->options);
3858
3859     pInfo->fd = -1;
3860
3861     TTRACE_END();
3862     return Success;
3863
3864 error:
3865     if (pInfo->fd >= 0)
3866         close(pInfo->fd);
3867     TTRACE_END();
3868     return rc;
3869 }
3870
3871 static void
3872 GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
3873 {
3874     GestureDevicePtr pGesture = pInfo->private;
3875
3876     g_pGesture = pGesture = NULL;
3877     pInfo->private = NULL;
3878
3879     xf86DeleteInput(pInfo, 0);
3880 }
3881
3882 static int
3883 GestureControl(DeviceIntPtr device, int what)
3884 {
3885     InputInfoPtr  pInfo = device->public.devicePrivate;
3886     GestureDevicePtr pGesture = pInfo->private;
3887
3888     switch (what)
3889     {
3890         case DEVICE_INIT:
3891             GestureInit(device);
3892             break;
3893
3894             /* Switch device on.  Establish socket, start event delivery.  */
3895         case DEVICE_ON:
3896             xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
3897
3898             if (device->public.on)
3899                 break;
3900
3901             device->public.on = TRUE;
3902             pGesture->this_device = device;
3903             pGesture->num_mt_devices = 0;
3904             if (ERROR_ABNORMAL == GestureEnableEventHandler(pInfo))
3905                 goto device_off;
3906             break;
3907
3908         case DEVICE_OFF:
3909 device_off:
3910             GestureDisableEventHandler();
3911             GestureFini(device);
3912             pGesture->this_device = NULL;
3913             xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
3914
3915             if (!device->public.on)
3916                 break;
3917
3918             pInfo->fd = -1;
3919             device->public.on = FALSE;
3920             break;
3921
3922         case DEVICE_CLOSE:
3923             /* free what we have to free */
3924             break;
3925       case DEVICE_READY:
3926       xf86Msg(X_INFO, "%s: device ready.\n", pInfo->name);
3927             GestureRegisterDeviceInfo(device);
3928             break;
3929     }
3930     return Success;
3931 }
3932
3933 static void
3934 GestureReadInput(InputInfoPtr pInfo)
3935 {
3936 }
3937
3938
3939