tizen 2.3 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
66 #ifdef __PalmFlick_DEBUG__
67 #define PalmFlickDebugPrint ErrorF
68 #else
69 #define PalmFlickDebugPrint(...)
70 #endif
71
72 #ifdef __HOLD_DETECTOR_DEBUG__
73 #define HoldDetectorDebugPrint ErrorF
74 #else
75 #define HoldDetectorDebugPrint(...)
76 #endif
77
78
79 #ifdef __DETAIL_DEBUG__
80 #define DetailDebugPrint ErrorF
81 #else
82 #define DetailDebugPrint(...)
83 #endif
84
85 #include <stdio.h>
86 #include <sys/stat.h>
87 #include <sys/syscall.h>
88 #include <unistd.h>
89 #include <errno.h>
90 #include <sys/types.h>
91 #include <fcntl.h>
92 #include <xorg-server.h>
93 #include <xorgVersion.h>
94 #include <xf86Module.h>
95 #include <X11/Xatom.h>
96 #include "gesture.h"
97 #include <xorg/mi.h>
98
99 #define LOG_TAG "GESTURE"
100 #include "dlog.h"
101
102
103
104 char *strcasestr(const char *s, const char *find);
105 extern ScreenPtr miPointerCurrentScreen(void);
106 static void printk(const char* fmt, ...) __attribute__((format(printf, 1, 0)));
107
108 //Basic functions
109 static int GesturePreInit(InputDriverPtr  drv, InputInfoPtr pInfo, int flags);
110 static void GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
111 static pointer GesturePlug(pointer module, pointer options, int *errmaj, int  *errmin);
112 static void GestureUnplug(pointer p);
113 static int GestureControl(DeviceIntPtr    device,int what);
114 static int GestureInit(DeviceIntPtr device);
115 static void GestureFini(DeviceIntPtr device);
116 static void GestureReadInput(InputInfoPtr pInfo);
117
118 //other initializers
119 ErrorStatus GestureRegionsInit(void);
120
121 //event queue handling functions
122 ErrorStatus GestureInitEQ(void);
123 ErrorStatus GestureFiniEQ(void);
124 ErrorStatus GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
125 ErrorStatus GestureEventsFlush(void);
126 void GestureEventsDrop(void);
127
128 //utility functions
129 ErrorStatus GestureRegionsReinit(void);
130 void GestureEnable(int enable, Bool prop, DeviceIntPtr dev);
131 void GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent);
132 void GestureCbEventsSelected(Window win, Mask *pEventMask);
133 WindowPtr GestureGetEventsWindow(void);
134
135 //Enqueued event handlers and enabler/disabler
136 static ErrorStatus GestureEnableEventHandler(InputInfoPtr pInfo);
137 static ErrorStatus GestureDisableEventHandler(void);
138 static CARD32 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
139 static CARD32 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
140 void GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
141 void GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
142 void GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
143 void GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
144 void GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
145 void GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
146
147 void GestureEmulateHWKey(DeviceIntPtr dev, int keycode);
148
149 //Gesture recognizer helper
150 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21
151 static Bool PointInBorderSize(WindowPtr pWin, int x, int y);
152 #endif
153 static WindowPtr GestureWindowOnXY(int x, int y);
154 Bool GestureHasFingerEventMask(int eventType, int num_finger);
155
156 //Gesture recognizer and handlers
157 void GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device);
158 void GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
159 void GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int start_point, int direction);
160 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
161 void GestureRecognize_PalmFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx);
162 void GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction);
163 void GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy);
164 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds);
165 ErrorStatus GestureFlushOrDrop(void);
166
167 static int GestureGetPalmValuator(InternalEvent *ev, DeviceIntPtr device);
168 static int GesturePalmGetAbsAxisInfo(DeviceIntPtr dev);
169 static void GestureHoldDetector(int type, InternalEvent *ev, DeviceIntPtr device);
170 static int GesturePalmGetScreenInfo();
171 static int GesturePalmGetHorizIndexWithX(int current_x, int idx, int type);
172
173 #ifdef HAVE_PROPERTIES
174 //function related property handling
175 static void GestureInitProperty(DeviceIntPtr dev);
176 static int GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkonly);
177 #endif
178
179 static Atom prop_gesture_recognizer_onoff = None;
180
181 #ifdef SUPPORT_ANR_WITH_INPUT_EVENT
182 static Atom prop_anr_in_input_event = None;
183 static Atom prop_anr_event_window = None;
184 static Window prop_anr_event_window_xid = None;
185 #endif
186
187
188 GestureDevicePtr g_pGesture = NULL;
189 _X_EXPORT InputDriverRec GESTURE = {
190     1,
191     "gesture",
192     NULL,
193     GesturePreInit,
194     GestureUnInit,
195     NULL,
196     0
197 };
198
199 static XF86ModuleVersionInfo GestureVersionRec =
200 {
201     "gesture",
202     MODULEVENDORSTRING,
203     MODINFOSTRING1,
204     MODINFOSTRING2,
205     XORG_VERSION_CURRENT,
206     PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR,
207     PACKAGE_VERSION_PATCHLEVEL,
208     ABI_CLASS_XINPUT,
209     ABI_XINPUT_VERSION,
210     MOD_CLASS_XINPUT,
211     {0, 0, 0, 0}
212 };
213
214 _X_EXPORT XF86ModuleData gestureModuleData =
215 {
216     &GestureVersionRec,
217     &GesturePlug,
218     &GestureUnplug
219 };
220
221 static void
222 printk(const char* fmt, ...)
223 {
224     static FILE* fp = NULL;
225     static char init = 0;
226     va_list argptr;
227
228     if (!init && !fp)
229     {
230         fp = fopen("/dev/kmsg", "wt");
231         init = 1;
232     }
233
234     if (!fp) return;
235
236     va_start(argptr, fmt);
237     vfprintf(fp, fmt, argptr);
238     fflush(fp);
239     va_end(argptr);
240 }
241
242 #ifdef SUPPORT_ANR_WITH_INPUT_EVENT
243 static WindowPtr
244 _GestureFindANRWindow(DeviceIntPtr device)
245 {
246     WindowPtr root=NULL;
247     WindowPtr anr_window=NULL;
248     Window anr_xid=0;
249     PropertyPtr pProp;
250     int rc=0;
251
252     root = RootWindow(device);
253
254     if( prop_anr_event_window == None )
255         prop_anr_event_window = MakeAtom(ANR_EVENT_WINDOW, strlen(ANR_EVENT_WINDOW), TRUE);
256
257     rc = dixLookupProperty (&pProp, root, prop_anr_event_window, serverClient, DixReadAccess);
258     if (rc == Success && pProp->data){
259         anr_xid = *(int*)pProp->data;
260     }
261
262     if( anr_xid != 0 )
263     {
264         rc = dixLookupWindow(&anr_window, anr_xid, serverClient, DixSetPropAccess);
265         if( rc == BadWindow )
266         {
267             ErrorF("Can't find ANR window !!\n");
268             anr_window = NULL;
269         }
270         prop_anr_event_window_xid = anr_xid;
271     }
272
273     ErrorF("ANR Window is %#x. Ptr is %#x\n", anr_xid, anr_window);
274     return anr_window;
275 }
276 #endif
277
278 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21
279 static Bool
280 PointInBorderSize(WindowPtr pWin, int x, int y)
281 {
282     BoxRec box;
283     if (pixman_region_contains_point (&pWin->borderSize, x, y, &box))
284     {
285         return TRUE;
286     }
287     return FALSE;
288 }
289 #endif
290
291 static WindowPtr
292 GestureWindowOnXY(int x, int y)
293 {
294     WindowPtr pWin;
295     BoxRec box;
296     SpritePtr pSprite;
297     DeviceIntPtr pDev = g_pGesture->master_pointer;
298
299     pSprite = pDev->spriteInfo->sprite;
300     pSprite->spriteTraceGood = 1;       /* root window still there */
301     pWin = RootWindow(pDev)->firstChild;
302
303     while (pWin)
304     {
305         if ((pWin->mapped) &&
306                 (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
307                 (x < pWin->drawable.x + (int)pWin->drawable.width +
308                  wBorderWidth(pWin)) &&
309                 (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
310                 (y < pWin->drawable.y + (int)pWin->drawable.height +
311                  wBorderWidth (pWin))
312                 /* When a window is shaped, a further check
313                  * is made to see if the point is inside
314                  * borderSize
315                  */
316                 && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
317                 && (!wInputShape(pWin) ||
318                     RegionContainsPoint(wInputShape(pWin),
319                         x - pWin->drawable.x,
320                         y - pWin->drawable.y, &box))
321 #ifdef ROOTLESS
322                 /* In rootless mode windows may be offscreen, even when
323                  * they're in X's stack. (E.g. if the native window system
324                  * implements some form of virtual desktop system).
325                  */
326                     && !pWin->rootlessUnhittable
327 #endif
328                     )
329                     {
330                         if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
331                         {
332                             pSprite->spriteTraceSize += 10;
333                             pSprite->spriteTrace = realloc(pSprite->spriteTrace,
334                                     pSprite->spriteTraceSize*sizeof(WindowPtr));
335                         }
336                         pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
337                         pWin = pWin->firstChild;
338                     }
339         else
340             pWin = pWin->nextSib;
341     }
342     return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
343 }
344
345     Bool
346 GestureHasFingerEventMask(int eventType, int num_finger)
347 {
348     Bool ret = FALSE;
349     Mask eventmask = (1L << eventType);
350
351     if ((g_pGesture->grabMask & eventmask) &&
352             (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[num_finger].window != None))
353     {
354         DetailDebugPrint("[GestureHasFingerEventMask] TRUE !! Has grabMask\n");
355         return TRUE;
356     }
357
358     if (g_pGesture->eventMask & eventmask)
359     {
360         DetailDebugPrint("[GestureHasFingerEventMask] TRUE !! Has eventMask\n");
361         return TRUE;
362     }
363
364     DetailDebugPrint("[GestureHasFingerEventMask] FALSE !! eventType=%d, num_finger=%d\n", eventType, num_finger);
365
366     return ret;
367 }
368
369 static CARD32
370 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
371 {
372     int event_type = *(int *)arg;
373
374     switch (event_type)
375     {
376         case GestureNotifyHold:
377             DetailDebugPrint("[GestureEventTimerHandler] GestureNotifyHold (event_type = %d)\n", event_type);
378             GestureRecognize_GroupHold(event_type, NULL, NULL, 0, 1);
379             break;
380         case GestureNotifyTap:
381             DetailDebugPrint("[GestureEventTimerHandler] GestureNotifyTap (event_type = %d)\n", event_type);
382             GestureRecognize_GroupTap(event_type, NULL, NULL, 0, 1);
383             break;
384         default:
385             DetailDebugPrint("[GestureEventTimerHandler] unknown event_type (=%d)\n", event_type);
386             if (timer)
387             {
388                 DetailDebugPrint("[GestureEventTimerHandler] timer=%x\n", (unsigned int)timer);
389             }
390     }
391
392     return 0;
393 }
394
395 void
396 GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy)
397 {
398     Window target_win;
399     WindowPtr target_pWin;
400     xGestureNotifyTapEvent tev;
401
402     //skip non-tap events and single finger tap
403     if (!tap_repeat || num_finger <= 1)
404     {
405         return;
406     }
407
408     DetailDebugPrint("[GestureHandleGesture_Tap] num_finger=%d, tap_repeat=%d, cx=%d, cy=%d\n", num_finger, tap_repeat, cx, cy);
409
410     g_pGesture->recognized_gesture |= WTapFilterMask;
411     memset(&tev, 0, sizeof(xGestureNotifyTapEvent));
412     tev.type = GestureNotifyTap;
413     tev.kind = GestureDone;
414     tev.num_finger = num_finger;
415     tev.tap_repeat = tap_repeat;
416     tev.interval = 0;
417     tev.cx = cx;
418     tev.cy = cy;
419
420     target_win = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].window;
421     target_pWin = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].pWin;
422
423     if (g_pGesture->grabMask && (target_win != None))
424     {
425         tev.window = target_win;
426     }
427     else
428     {
429         tev.window = g_pGesture->gestureWin;
430     }
431
432     DetailDebugPrint("[GestureHandleGesture_Tap] tev.window=0x%x, g_pGesture->grabMask=0x%x\n", (unsigned int)tev.window, (unsigned int)g_pGesture->grabMask);
433
434     GestureSendEvent(target_pWin, GestureNotifyTap, GestureTapMask, (xGestureCommonEvent *)&tev);
435     LOGI("GroupTap Event done. 2 fingers %d tap!", tap_repeat);
436 }
437
438 void
439 GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction)
440 {
441     if (num_of_fingers == 0)
442     {
443         Window target_win;
444         WindowPtr target_pWin;
445         xGestureNotifyFlickEvent fev;
446
447         DetailDebugPrint("[GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n", num_of_fingers, distance, duration, direction);
448
449         g_pGesture->recognized_gesture |= WPalmFlickFilterMask;
450
451         memset(&fev, 0, sizeof(xGestureNotifyFlickEvent));
452         fev.type = GestureNotifyFlick;
453         fev.kind = GestureDone;
454         fev.num_finger = num_of_fingers;
455         fev.distance = distance;
456         fev.duration = duration;
457         fev.direction = direction;
458
459         if (g_pGesture->GrabEvents)
460         {
461             target_win = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].window;
462             target_pWin = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].pWin;
463         }
464         else
465         {
466             target_win = None;
467             target_pWin = None;
468         }
469
470         if (g_pGesture->grabMask && (target_win != None))
471         {
472             fev.window = target_win;
473         }
474         else
475         {
476             fev.window = g_pGesture->gestureWin;
477         }
478
479         DetailDebugPrint("[GestureHandleGesture_Flick] fev.window=0x%x, g_pGesture->grabMask=0x%x\n", fev.window, g_pGesture->grabMask);
480
481         GestureSendEvent(target_pWin, GestureNotifyFlick, GestureFlickMask, (xGestureCommonEvent *)&fev);
482     }
483     else
484     {
485         DetailDebugPrint("[GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n", num_of_fingers, distance, duration, direction);
486
487         switch (direction)
488         {
489             case FLICK_NORTHWARD:
490                 DetailDebugPrint("[GestureHandleGesture_Flick] Flick Down \n");
491                 GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down);
492                 break;
493
494             case FLICK_SOUTHWARD:
495                 DetailDebugPrint("[GestureHandleGesture_Flick] Flick Up \n");
496                 GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up);
497                 break;
498             case FLICK_WESTWARD:
499                 if (g_pGesture->power_pressed == 2)
500                 {
501                     DetailDebugPrint("[GestureHandleGesture_Flick] Flick Right & power_pressed\n");
502                     GestureEmulateHWKey(g_pGesture->hwkey_dev, 122);
503                 }
504                 break;
505             default:
506                 break;
507         }
508         g_pGesture->recognized_gesture |= WFlickFilterMask;
509     }
510 }
511
512 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds)
513 {
514     Window target_win;
515     WindowPtr target_pWin;
516     xGestureNotifyHoldEvent hev;
517
518     DetailDebugPrint("[GestureHandleGesture_Hold] num_fingers=%d, cx=%d, cy=%d, holdtime=%d, kinds=%d\n", num_fingers, cx, cy, holdtime, kinds);
519
520     if (num_fingers == 0)
521     {
522         g_pGesture->hold_detected = TRUE;
523         LOGI("[PalmHold] PalmHold success !\n");
524     }
525     else
526     {
527         g_pGesture->recognized_gesture |= WHoldFilterMask;
528     }
529
530     memset(&hev, 0, sizeof(xGestureNotifyHoldEvent));
531     hev.type = GestureNotifyHold;
532     hev.kind = kinds;
533     hev.num_finger = num_fingers;
534     hev.holdtime = holdtime;
535     hev.cx = cx;
536     hev.cy = cy;
537
538     if (g_pGesture->GrabEvents)
539     {
540         target_win = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].window;
541         target_pWin = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].pWin;
542     }
543     else
544     {
545         target_win = None;
546         target_pWin = None;
547     }
548
549     if (g_pGesture->grabMask && (target_win != None))
550     {
551         hev.window = target_win;
552     }
553     else
554     {
555         hev.window = g_pGesture->gestureWin;
556     }
557
558     DetailDebugPrint("[GestureHandleGesture_Hold] hev.window=0x%x, g_pGesture->grabMask=0x%x\n", hev.window, g_pGesture->grabMask);
559
560     GestureSendEvent(target_pWin, GestureNotifyHold, GestureHoldMask, (xGestureCommonEvent *)&hev);
561     LOGI("[GroupHold] GestureHold success !\n");
562 }
563
564
565 void
566 GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
567 {
568     static int num_pressed = 0;
569     static int base_area_size = 0;
570
571     int cx, cy;
572     int area_size;
573
574     static int state = 0;
575     static int mbits = 0;
576     static int base_cx;
577     static int base_cy;
578     static pixman_box16_t base_box_ext;
579
580     static int tap_repeat = 0;
581     static int prev_num_pressed = 0;
582
583     static OsTimerPtr tap_event_timer = NULL;
584     static int event_type = GestureNotifyTap;
585
586     if (timer_expired)
587     {
588         DetailDebugPrint("[GroupTap][Timer] state=%d, num_pressed=%d, tap_repeat=%d\n", state, num_pressed, tap_repeat);
589
590         switch (state)
591         {
592             case 1://first tap initiation check
593                 if (num_pressed)
594                 {
595                     DetailDebugPrint("[GroupTap][Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", num_pressed, tap_repeat);
596                     DetailDebugPrint("[GroupTap][F] 1\n");
597
598                     state = 0;
599                     goto cleanup_tap;
600                 }
601                 break;
602
603             case 2:
604                 if (tap_repeat <= 1)
605                 {
606                     state = 0;
607                     DetailDebugPrint("[GroupTap][Timer][state=2] 2 finger %d tap\n", tap_repeat);
608                     LOGI("[GroupTap][F] Second tap doesn't come up in 400ms after first tap.\n");
609                     goto cleanup_tap;
610                 }
611
612                 if (GestureHasFingerEventMask(GestureNotifyTap, prev_num_pressed))
613                 {
614                     DetailDebugPrint("[GroupTap] Success 1!! 2 finger %d tap\n", tap_repeat);
615                     GestureHandleGesture_Tap(prev_num_pressed, tap_repeat, base_cx, base_cy);
616                     goto cleanup_tap;
617                 }
618                 break;
619         }
620         return;
621     }
622
623     switch (type)
624     {
625         case ET_ButtonPress:
626             g_pGesture->fingers[idx].flags |= PressFlagTap;
627
628             if (g_pGesture->num_pressed < 2)
629             {
630                 DetailDebugPrint("[GroupTap][P] num_pressed=%d, base_px=%d, base_py=%d. return \n", g_pGesture->num_pressed, g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
631                 return;
632             }
633
634             if ((!base_area_size || g_pGesture->num_pressed > num_pressed))
635             {
636                 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
637                 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
638                 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
639                 base_box_ext.x1 = base_cx-TAP_MOVE_THRESHOLD;
640                 base_box_ext.y1 = base_cy-TAP_MOVE_THRESHOLD;
641                 base_box_ext.x2 = base_cx+TAP_MOVE_THRESHOLD;
642                 base_box_ext.y2 = base_cy+TAP_MOVE_THRESHOLD;
643                 state = 1;
644                 TimerCancel(tap_event_timer);
645                 tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->singletap_threshold, GestureEventTimerHandler, (int *)&event_type);
646             }
647             num_pressed = g_pGesture->num_pressed;
648
649             DetailDebugPrint("[GroupTap][P] num_pressed=%d, area_size=%d, base_mx=%d, base_my=%d\n", num_pressed, base_area_size, g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
650             break;
651
652         case ET_Motion:
653             if (!(g_pGesture->fingers[idx].flags & PressFlagTap))
654             {
655                 break;
656             }
657
658             if (num_pressed < 2)
659             {
660                 DetailDebugPrint("[GroupTap][M] num_pressed=%d, return \n", num_pressed);
661                 return;
662             }
663
664             if (num_pressed != g_pGesture->num_pressed)
665             {
666                 DetailDebugPrint("[GroupTap][M] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
667             }
668
669             mbits |= (1 << idx);
670             if (mbits == (pow(2, num_pressed)-1))
671             {
672                 area_size = AREA_SIZE(&g_pGesture->area.extents);
673                 cx = AREA_CENTER_X(&g_pGesture->area.extents);
674                 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
675
676                 DetailDebugPrint("[GroupTap][M][num_pressed=%d] area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size));
677                 DetailDebugPrint("[GroupTap][M] cx=%d, base_cx=%d, diff=%d\n", cx, g_pGesture->fingers[idx].mx, ABS(cx-base_cx));
678                 DetailDebugPrint("[GroupTap][M] cy=%d, base_cy=%d, diff=%d\n", cy, g_pGesture->fingers[idx].my, ABS(cy-base_cy));
679
680                 if (ABS(base_area_size-area_size) >= TAP_AREA_THRESHOLD)
681                 {
682                     DetailDebugPrint("[GroupTap][M] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, ABS(base_area_size-area_size));
683                     DetailDebugPrint("[GroupTap][F] 3\n");
684                     LOGI("[GroupTap][F] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, ABS(base_area_size-area_size));
685
686                     goto cleanup_tap;
687                 }
688
689                 if (!INBOX(&base_box_ext, cx, cy))
690                 {
691                     DetailDebugPrint("[GroupTap][M] current center coordinates is not in base coordinates box !\n");
692                     DetailDebugPrint("[GroupTap][F] 4\n");
693                     LOGI("[GroupTap][F] current center coordinates is not in base coordinates box !\n");
694
695                     goto cleanup_tap;
696                 }
697             }
698             break;
699
700         case ET_ButtonRelease:
701             if (g_pGesture->num_pressed)
702             {
703                 DetailDebugPrint("[GroupTap][R] Second finger doesn't come up. g_pGesture->num_pressed=%d\n", g_pGesture->num_pressed);
704                 break;
705             }
706
707             if (!tap_repeat)
708             {
709                 prev_num_pressed = num_pressed;
710             }
711
712             tap_repeat++;
713             g_pGesture->num_tap_repeated = tap_repeat;
714
715             DetailDebugPrint("[GroupTap][R] tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, num_pressed, prev_num_pressed);
716             DetailDebugPrint("[GroupTap][R] base_rx=%d, base_ry=%d,\n", g_pGesture->fingers[idx].rx, g_pGesture->fingers[idx].ry);
717
718             if ((num_pressed != prev_num_pressed) || (!GestureHasFingerEventMask(GestureNotifyTap, num_pressed)))
719             {
720                 DetailDebugPrint("[GroupTap][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
721                         num_pressed, prev_num_pressed, num_pressed);
722                 DetailDebugPrint("[GroupTap][F] 5\n");
723                 LOGI("[GroupTap][F] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
724                         num_pressed, prev_num_pressed, num_pressed);
725                 goto cleanup_tap;
726             }
727
728             if (tap_repeat == 1)
729             {
730                 DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat);
731                 TimerCancel(tap_event_timer);
732                 tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->doubletap_threshold, GestureEventTimerHandler, (int *)&event_type);
733                 state = 2;
734                 prev_num_pressed = num_pressed;
735                 num_pressed = 0;
736                 break;
737             }
738
739             else if (tap_repeat == 2)
740             {
741                 DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat);
742                 TimerCancel(tap_event_timer);
743                 tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->tripletap_threshold, GestureEventTimerHandler, (int *)&event_type);
744                 state = 2;
745                 base_area_size = num_pressed = 0;
746                 break;
747             }
748
749             DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat);
750
751             if (tap_repeat == MAX_TAP_REPEATS)
752             {
753                 if (GestureHasFingerEventMask(GestureNotifyTap, num_pressed))
754                 {
755                     DetailDebugPrint("[GroupTap] Sucess 2!\n");
756                     GestureHandleGesture_Tap(num_pressed, tap_repeat, base_cx, base_cy);
757                 }
758                 goto cleanup_tap;
759             }
760
761             if (tap_repeat >= MAX_TAP_REPEATS)
762             {
763                 LOGI("[GroupTap][F] More than 3 taps. Ignore. \n");
764                 goto cleanup_tap;
765             }
766
767             prev_num_pressed = num_pressed;
768             num_pressed = 0;
769             break;
770     }
771
772     return;
773
774 cleanup_tap:
775
776     DetailDebugPrint("[GroupTap][cleanup_tap]\n");
777
778     if (0 == state)
779     {
780         g_pGesture->recognized_gesture &= ~WTapFilterMask;
781     }
782
783     g_pGesture->filter_mask |= WTapFilterMask;
784
785     if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
786     {
787         DetailDebugPrint("[GroupTap][cleanup] GestureFlushOrDrop() !\n");
788
789         if (ERROR_INVALPTR == GestureFlushOrDrop())
790         {
791             GestureControl(g_pGesture->this_device, DEVICE_OFF);
792         }
793     }
794
795     num_pressed = 0;
796     g_pGesture->num_tap_repeated = tap_repeat = 0;
797     prev_num_pressed = 0;
798     mbits = 0;
799     state = 0;
800     TimerCancel(tap_event_timer);
801     return;
802 }
803
804 void
805 GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int start_point, int direction)
806 {
807     static int num_pressed = 0;
808     static Time base_time = 0;
809     Time duration;
810     int distance;
811     static int diff_base_coord = 0;
812     static int diff_base_minor_coord = 0;
813     static int diff_current_coord = 0;
814     static int false_diff_count = 0;
815     static int false_minor_diff_count = 0;
816     static float angle = 0.0f;
817     static int angle_base_x = 0, angle_base_y = 0;
818     static int motion_count = 0;
819
820     if (g_pGesture->num_pressed > 1)
821     {
822         DetailDebugPrint("[GroupFlick][F] 1\n");
823         goto cleanup_flick;
824     }
825
826     if ((start_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= start_point))
827     {
828         DetailDebugPrint("[GroupFlick][F] 2\n");
829         goto cleanup_flick;
830     }
831
832     switch (type)
833     {
834         case ET_ButtonPress:
835             g_pGesture->fingers[idx].flags = PressFlagFlick;
836             base_time = GetTimeInMillis();
837             num_pressed = g_pGesture->num_pressed;
838             switch (start_point)
839             {
840                 case FLICK_POINT_UP:
841                     if (g_pGesture->fingers[idx].py > g_pGesture->flick_press_area)
842                     {
843                         DetailDebugPrint("[GroupFlick][FlickDown][P] press coord is out of bound. (%d, %d)\n",
844                                 g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
845                         DetailDebugPrint("[GroupFlick][F] 3\n");
846                         LOGI("[BackKey][F] press coord is out of bound (40 pixel from upper vezel). press y=%d\n", g_pGesture->fingers[idx].py);
847                         goto cleanup_flick;
848                     }
849
850                     angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
851                     angle_base_x = g_pGesture->fingers[idx].px;
852                     DetailDebugPrint("[GroupFlick][FlickDown][P] px=%d, py=%d\n", g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
853                     break;
854
855                 case FLICK_POINT_DOWN:
856                     if (g_pGesture->fingers[idx].py < g_pGesture->screen_height - g_pGesture->flick_press_area)
857                     {
858                         DetailDebugPrint("[GroupFlick][FlickUp][P] press coord is out of bound. (%d, %d)\n",
859                                 g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
860                         DetailDebugPrint("[GroupFlick][F] 4\n");
861                         goto cleanup_flick;
862                     }
863                     angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
864                     angle_base_x = g_pGesture->fingers[idx].px;
865                     break;
866
867                 case FLICK_POINT_LEFT:
868                     if (g_pGesture->fingers[idx].px > g_pGesture->flick_press_area)
869                     {
870                         DetailDebugPrint("[GroupFlick][FlickLeft][P] press coord is out of bound. (%d, %d)\n",
871                                 g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
872                         DetailDebugPrint("[GroupFlick][F] 5\n");
873                         goto cleanup_flick;
874                     }
875                     angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
876                     angle_base_x = g_pGesture->fingers[idx].px;
877                     break;
878
879                 default:
880                     DetailDebugPrint("[GroupFlick][F] 6\n");
881                     goto cleanup_flick;
882                     break;
883             }
884
885             break;
886
887         case ET_Motion:
888
889             motion_count++;
890
891             if (motion_count > 15)
892             {
893                 DetailDebugPrint("[GroupFlick][F] 6-1 motion_count=%d\n", motion_count);
894                 LOGI("[BackKey][F] More than 15 motion.\n");
895                 goto cleanup_flick;
896             }
897
898             if (!(g_pGesture->fingers[idx].flags & PressFlagFlick))
899             {
900                 break;
901             }
902
903             switch (start_point)
904             {
905                 case FLICK_POINT_UP:
906                     diff_base_coord = diff_current_coord;
907                     diff_current_coord = g_pGesture->fingers[idx].my;
908
909                     if ((diff_current_coord - diff_base_coord) < 0)
910                     {
911                         DetailDebugPrint("[GroupFlick][FlickDown][M] false_diff\n");
912                         false_diff_count++;
913                     }
914
915                     if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
916                     {
917                         DetailDebugPrint("[GroupFlick][FlickDown][M] false_diff_count: %d > %d\n",
918                                 false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
919                         DetailDebugPrint("[GroupFlick][F] 7\n");
920                         LOGI("[BackKey][F] Direction is wrong for 7 times.\n");
921                         goto cleanup_flick;
922                     }
923
924                     if ((g_pGesture->fingers[idx].my < g_pGesture->flick_press_area) &&
925                             (abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) >(int)( g_pGesture->screen_width/2)))
926                     {
927                         DetailDebugPrint("[GroupFlick][FlickDown][M] move x: %d - %d, y coord: %d\n",
928                                 g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].my);
929                         DetailDebugPrint("[GroupFlick][F] 8\n");
930                         LOGI("[BackKey][F] From press point, moving x axis is more than half screen size.\n");
931                         goto cleanup_flick;
932                     }
933
934                     if ((g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) > g_pGesture->flick_minimum_height)
935                     {
936                         DetailDebugPrint("[GroupFlick][FlickDown][M] %d - %d < %d(min_size), angle_base_coord (%d, %d)\n",
937                                 g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py, g_pGesture->flick_minimum_height, angle_base_x, angle_base_y);
938
939                         if (abs(g_pGesture->fingers[idx].mx - angle_base_x) == 0)
940                         {
941                             DetailDebugPrint("[GroupFlick][FlickDown][M] abs(%d - %d) = 0\n",
942                                     g_pGesture->fingers[idx].mx, angle_base_x);
943                             angle = 1.0f;
944                         }
945                         else
946                         {
947                             DetailDebugPrint("[GroupFlick][FlickDown][M] angle_base_x: %d, angle_base_y: %d\n",
948                                     angle_base_x, angle_base_y);
949                             int y_diff = abs(g_pGesture->fingers[idx].my - angle_base_y);
950                             int x_diff = abs(g_pGesture->fingers[idx].mx - angle_base_x);
951                             angle = (float)y_diff / (float)x_diff;
952                         }
953
954                         if (angle < 0.23f)
955                         {
956                             DetailDebugPrint("[GroupFlick][FlickDown][M][F] %d / %d = %f (angle)\n",
957                                     abs(g_pGesture->fingers[idx].my - angle_base_y), abs(g_pGesture->fingers[idx].mx - angle_base_x), angle);
958                             DetailDebugPrint("[GroupFlick][F] 9\n");
959                             LOGI("[BackKey][F] angle is improper. %d < 0.23\n", angle);
960                             goto cleanup_flick;
961                         }
962
963                         distance = g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py;
964                         duration = GetTimeInMillis() - base_time;
965
966                         GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
967                         DetailDebugPrint("[GroupFlick][FlickDown][M] FlickDown Done!!\n");
968                         goto cleanup_flick_recognized;
969                     }
970                     else
971                     {
972                         if ((g_pGesture->fingers[idx].mx - diff_base_minor_coord) < 0)
973                         {
974                             false_minor_diff_count++;
975                         }
976
977                         if (false_minor_diff_count> FLICK_FALSE_X_DIFF_COUNT)
978                         {
979                             DetailDebugPrint("[GroupFlick][FlickDown][M] false_minor_diff_count: %d > %d\n",
980                                     false_minor_diff_count, FLICK_FALSE_X_DIFF_COUNT);
981                             DetailDebugPrint("[GroupFlick][F] 10\n");
982                             goto cleanup_flick;
983                         }
984                     }
985
986                     if (g_pGesture->fingers[idx].my < g_pGesture->flick_press_area)
987                     {
988                         angle_base_x = g_pGesture->fingers[idx].px;
989                         angle_base_y = g_pGesture->fingers[idx].py;
990                     }
991                     DetailDebugPrint("[GroupFlick][FlickDown][M] mx=%d, my=%d, diff_x=%d, diff_y=%d\n",
992                             g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].my, abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py));
993
994                     break;
995
996                 case FLICK_POINT_DOWN:
997                     diff_base_coord = diff_current_coord;
998                     diff_current_coord = g_pGesture->fingers[idx].my;
999
1000                     if ((diff_base_coord - diff_current_coord) < 0)
1001                     {
1002                         false_diff_count++;
1003                     }
1004
1005                     if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
1006                     {
1007                         DetailDebugPrint("[GroupFlick][FlickUp][M] false_diff_count: %d > %d\n",
1008                                 false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
1009                         DetailDebugPrint("[GroupFlick][F] 11\n");
1010                         goto cleanup_flick;
1011                     }
1012
1013                     if ((g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my) > g_pGesture->flick_minimum_height)
1014                     {
1015                         DetailDebugPrint("[GroupFlick][FlickUp][R] %d - %d < %d(min_size)\n",
1016                                 g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py, g_pGesture->flick_minimum_height);
1017                         if (abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) == 0)
1018                         {
1019                             DetailDebugPrint("[GroupFlick][FlickUp][R] abs(%d - %d) = 0\n",
1020                                     g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px);
1021                             angle = 1.0f;
1022                         }
1023                         else
1024                         {
1025                             int y_diff = abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py);
1026                             int x_diff = abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px);
1027                             angle = (float)y_diff / (float)x_diff;
1028                         }
1029
1030                         if (angle <0.5f)
1031                         {
1032                             DetailDebugPrint("[GroupFlick][FlickUp][R] %d / %d = %f (angle)\n",
1033                                     abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py), abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), angle);
1034                             DetailDebugPrint("[GroupFlick][F] 12\n");
1035                             goto cleanup_flick;
1036                         }
1037
1038                         distance = g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my;
1039                         duration = GetTimeInMillis() - base_time;
1040
1041                         GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
1042                         goto cleanup_flick_recognized;
1043                     }
1044                     break;
1045
1046                 case FLICK_POINT_LEFT:
1047                     diff_base_coord = diff_current_coord;
1048                     diff_current_coord = g_pGesture->fingers[idx].mx;
1049
1050                     if ((diff_current_coord - diff_base_coord) < 0)
1051                     {
1052                         false_diff_count++;
1053                     }
1054
1055                     if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
1056                     {
1057                         DetailDebugPrint("[GroupFlick][FlickLeft][M] false_diff_count: %d > %d\n",
1058                                 false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
1059                         DetailDebugPrint("[GroupFlick][F] 13\n");
1060                         goto cleanup_flick;
1061                     }
1062
1063                     if ((g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) > g_pGesture->flick_minimum_height)
1064                     {
1065                         DetailDebugPrint("[GroupFlick][FlickLeft][M] %d - %d < %d(min_size)\n",
1066                                 g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px, g_pGesture->flick_minimum_height);
1067
1068                         if (abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) == 0)
1069                         {
1070                             DetailDebugPrint("[GroupFlick][FlickLeft][M] abs(%d - %d) = 0\n",
1071                                     g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py);
1072                             angle = 1.0f;
1073                         }
1074                         else
1075                         {
1076                             int y_diff = abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py);
1077                             int x_diff = abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px);
1078                             angle = (float)x_diff / (float)y_diff;
1079                         }
1080
1081                         if ( angle < 0.5f)
1082                         {
1083                             DetailDebugPrint("[GroupFlick][FlickLeft][M] %d / %d = %f (angle)\n",
1084                                     abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py), angle);
1085                             DetailDebugPrint("[GroupFlick][F] 14\n");
1086                             goto cleanup_flick;
1087                         }
1088
1089                         distance = g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px;
1090                         duration = GetTimeInMillis() - base_time;
1091
1092                         GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
1093                         goto cleanup_flick_recognized;
1094                     }
1095
1096                     break;
1097                 default:
1098                     DetailDebugPrint("[GroupFlick][F] 15\n");
1099                     goto cleanup_flick;
1100                     break;
1101             }
1102             break;
1103
1104         case ET_ButtonRelease:
1105             DetailDebugPrint("[GroupFlick][R][F] 16\n");
1106             goto cleanup_flick;
1107             break;
1108     }
1109
1110     return;
1111
1112 cleanup_flick:
1113     DetailDebugPrint("[GroupFlick] cleanup_flick \n");
1114     g_pGesture->recognized_gesture &= ~WFlickFilterMask;
1115     motion_count = 0;
1116
1117 cleanup_flick_recognized:
1118     DetailDebugPrint("[GroupFlick] Flick recognized !\n");
1119     g_pGesture->filter_mask |= WFlickFilterMask;
1120     num_pressed = 0;
1121     base_time = 0;
1122     false_diff_count = 0;
1123     diff_base_coord = 0;
1124     diff_current_coord = 0;
1125     angle = 0.0f;
1126     angle_base_x = angle_base_y = 0;
1127     motion_count = 0;
1128     return;
1129 }
1130
1131 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1132 {
1133     static int num_pressed = 0;
1134     static int base_area_size = 0;
1135     static Time base_time = 0;
1136     static int base_cx;
1137     static int base_cy;
1138     int cx, cy;
1139     static pixman_box16_t base_box_ext;
1140     int area_size;
1141     static int state = GestureEnd;
1142
1143     static OsTimerPtr hold_event_timer = NULL;
1144     static int event_type = GestureNotifyHold;
1145
1146     if (timer_expired)
1147     {
1148         if (state <= GestureBegin)
1149         {
1150             state++;
1151         }
1152
1153         switch (state)
1154         {
1155             case GestureBegin:
1156                 DetailDebugPrint("[GroupHold] HOLD Begin !\n");
1157                 break;
1158
1159             case GestureUpdate:
1160                 DetailDebugPrint("[GroupHold] HOLD Update !\n");
1161                 break;
1162         }
1163
1164         if (GestureHasFingerEventMask(GestureNotifyHold, num_pressed))
1165         {
1166             DetailDebugPrint("[GroupHold] Success 1! \n");
1167             GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1168
1169             // one more time
1170             hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type);
1171         }
1172         return;
1173     }
1174
1175     switch (type)
1176     {
1177         case ET_ButtonPress:
1178             g_pGesture->fingers[idx].flags |= PressFlagHold;
1179
1180             if (g_pGesture->num_pressed < 2)
1181             {
1182                 DetailDebugPrint("[GroupHold][P] No num_finger changed ! num_pressed=%d\n", num_pressed);
1183                 DetailDebugPrint("[GroupHold][F] 0\n");
1184                 return;
1185             }
1186
1187             if (!base_area_size || g_pGesture->num_pressed > num_pressed)
1188             {
1189                 if (state != GestureEnd)
1190                 {
1191                     DetailDebugPrint("[GroupHold][P][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1192                     DetailDebugPrint("[GroupHold][F] 1\n");
1193
1194                     goto cleanup_hold;
1195                 }
1196
1197                 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1198                 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1199                 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1200                 base_time = GetTimeInMillis();
1201
1202                 base_box_ext.x1 = base_cx-g_pGesture->hold_move_threshold;
1203                 base_box_ext.y1 = base_cy-g_pGesture->hold_move_threshold;
1204                 base_box_ext.x2 = base_cx+g_pGesture->hold_move_threshold;
1205                 base_box_ext.y2 = base_cy+g_pGesture->hold_move_threshold;
1206
1207                 event_type = GestureNotifyHold;
1208
1209                 hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type);
1210             }
1211             num_pressed = g_pGesture->num_pressed;
1212
1213             DetailDebugPrint("[GroupHold][P] num_pressed=%d area_size=%d, base_cx=%d, base_cy=%d\n", num_pressed, base_area_size, base_cx, base_cy);
1214
1215             break;
1216
1217         case ET_Motion:
1218             if (!(g_pGesture->fingers[idx].flags & PressFlagHold))
1219             {
1220                 DetailDebugPrint("[GroupHold][M] No PressFlagHold\n");
1221                 break;
1222             }
1223
1224             if (num_pressed < 2)
1225             {
1226                 DetailDebugPrint("[GroupHold][M] No num_finger changed ! num_pressed=%d\n", num_pressed);
1227                 DetailDebugPrint("[GroupHold][F] 2\n");
1228                 return;
1229             }
1230
1231             if (num_pressed != g_pGesture->num_pressed)
1232             {
1233                 if (state != GestureEnd)
1234                 {
1235                     DetailDebugPrint("[GroupHold][M][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1236                     DetailDebugPrint("[GroupHold][F] 3\n");
1237                     goto cleanup_hold;
1238                 }
1239
1240                 DetailDebugPrint("[GroupHold][M] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1241             }
1242
1243             area_size = AREA_SIZE(&g_pGesture->area.extents);
1244             cx = AREA_CENTER_X(&g_pGesture->area.extents);
1245             cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1246
1247             DetailDebugPrint("[GroupHold][M] num_pressed=%d area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size));
1248             DetailDebugPrint("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1249             DetailDebugPrint("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1250
1251             if (area_size > 0 && base_area_size > 0)
1252             {
1253                 if (((area_size > base_area_size) ? (double)area_size / (double)base_area_size : (double)base_area_size / (double) area_size) >= g_pGesture->hold_area_threshold)
1254                 {
1255                     DetailDebugPrint("[GroupHold][M] No diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%lf)!\n", area_size, base_area_size, ((area_size > base_area_size) ? (double)area_size / (double)base_area_size : (double)base_area_size / (double) area_size));
1256                     DetailDebugPrint("[GroupHold][F] 4\n");
1257                     goto cleanup_hold;
1258                 }
1259             }
1260
1261             if (!INBOX(&base_box_ext, cx, cy))
1262             {
1263                 DetailDebugPrint("[GroupHold][M] No current center coordinates is not in base coordinates box !\n");
1264                 DetailDebugPrint("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1265                 DetailDebugPrint("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1266                 DetailDebugPrint("[GroupHold][F] 5\n");
1267                 goto cleanup_hold;
1268             }
1269             break;
1270
1271         case ET_ButtonRelease:
1272             if (state != GestureEnd && num_pressed >= 2)
1273             {
1274                 DetailDebugPrint("[GroupHold][R] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1275                 DetailDebugPrint("[GroupHold][F] 6\n");
1276                 goto cleanup_hold;
1277             }
1278
1279             if (g_pGesture->num_pressed)
1280             {
1281                 DetailDebugPrint("[GroupHold][R] num_pressed=%d\n", num_pressed);
1282                 DetailDebugPrint("[GroupHold][F] 7\n");
1283                 break;
1284             }
1285
1286             goto cleanup_hold;
1287             break;
1288     }
1289
1290     return;
1291
1292 cleanup_hold:
1293
1294     DetailDebugPrint("[GroupHold][cleanup_hold] enter!\n");
1295
1296     if (state == GestureBegin || state == GestureUpdate)
1297     {
1298         state = GestureEnd;
1299         if (GestureHasFingerEventMask(GestureNotifyHold, num_pressed))
1300         {
1301             DetailDebugPrint("[GroupHold] Success 2!\n");
1302             GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1303         }
1304     }
1305     else
1306     {
1307         g_pGesture->recognized_gesture &= ~WHoldFilterMask;
1308     }
1309
1310     g_pGesture->filter_mask |= WHoldFilterMask;
1311     num_pressed = 0;
1312     base_area_size = 0;
1313     base_time = 0;
1314     base_cx = base_cy = 0;
1315     state = GestureEnd;
1316     base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
1317     TimerCancel(hold_event_timer);
1318     return;
1319 }
1320
1321 int
1322 GestureGetMaxTmajor(InternalEvent *ev, int max_tmajor)
1323 {
1324     int mt_tmajor_idx = g_pGesture->tmajor_idx;
1325     int mt_tmajor = 0;
1326
1327     DeviceEvent *de = &ev->device_event;
1328
1329     if (!de)
1330     {
1331         DetailDebugPrint("[GestureGetMaxTmajor] de is NULL !\n");
1332         return -1;
1333     }
1334
1335     if (mt_tmajor_idx < 0)
1336     {
1337         DetailDebugPrint("[GestureGetMaxTmajor] One or more of axes are not supported !\n");
1338         return -1;
1339     }
1340
1341     mt_tmajor = de->valuators.data[mt_tmajor_idx];
1342
1343     DetailDebugPrint("[GestureGetMaxTmajor]mt_tmajor_idx=%d, mt_tmajor=%d, max_tmajor=%d\n", mt_tmajor_idx, mt_tmajor, max_tmajor);
1344
1345     return ((mt_tmajor > max_tmajor) ? mt_tmajor : max_tmajor);
1346
1347 }
1348
1349 void
1350 GestureRecognize_PalmFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx)
1351 {
1352     //  static int num_pressed = 0;
1353     static int base_time = 0, current_time = 0;
1354     static int base_x[MAX_MT_DEVICES] = {0}, base_y[MAX_MT_DEVICES] = {0};
1355     static int update_x[MAX_MT_DEVICES] = {0}, update_y[MAX_MT_DEVICES] = {0};
1356
1357
1358     static int current_x[MAX_MT_DEVICES] = {0}, current_y[MAX_MT_DEVICES] = {0};
1359     static Bool press_status[MAX_MT_DEVICES] = {FALSE, FALSE};
1360     static Bool release_status[MAX_MT_DEVICES] = {FALSE, FALSE};
1361
1362     static int line_idx[MAX_MT_DEVICES] = {0}, prev_line_idx[MAX_MT_DEVICES] = {0}, press_idx[MAX_MT_DEVICES] = {0};
1363     static Bool is_line_invalid[MAX_MT_DEVICES] = {TRUE, TRUE};
1364
1365     static int max_tmajor[MAX_MT_DEVICES] = {0};
1366     static int total_max_tmajor = 0;
1367     static Bool is_tmajor_invalid[MAX_MT_DEVICES] = {TRUE, TRUE};
1368
1369     static int mt_sync_count[MAX_MT_DEVICES] = {0};
1370
1371     static Bool is_palm = FALSE;
1372     PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
1373
1374     static Bool is_retry = FALSE;
1375
1376     int distance, direction, duration;
1377
1378     if (g_pGesture->recognized_gesture && !(g_pGesture->recognized_gesture & WPalmFlickFilterMask))
1379     {
1380         PalmFlickDebugPrint("[PalmFlick] recognize other gesture already( g_pGesture->recognized_gesture: %d)\n", g_pGesture->recognized_gesture);
1381         PalmFlickDebugPrint("[PalmFlick][F] 1\n");
1382         goto flick_failed;
1383     }
1384
1385     // only first finger recognize
1386     if (!(idx == 0 || idx == 1))
1387     {
1388         PalmFlickDebugPrint("[PalmFlick] idx=%d, least two fingers come on\n", idx);
1389         return;
1390     }
1391
1392     switch (type)
1393     {
1394         case ET_ButtonPress:
1395
1396             if (!is_palm)
1397             {
1398                 if (idx == 0)
1399                 {
1400                     base_time = GetTimeInMillis();
1401                 }
1402
1403                 // press (x,y), touch major
1404                 update_x[idx] = base_x[idx] = g_pGesture->fingers[idx].px;
1405                 update_y[idx] = base_y[idx] = g_pGesture->fingers[idx].py;
1406                 max_tmajor[idx] = g_pGesture->max_mt_tmajor[idx];
1407                 press_status[idx] = TRUE;
1408                 is_tmajor_invalid[idx] = FALSE;
1409                 is_line_invalid[idx] = FALSE;
1410
1411                 total_max_tmajor = (total_max_tmajor > max_tmajor[idx]) ? total_max_tmajor : max_tmajor[idx];
1412
1413                 // press region
1414                 press_idx[idx] = prev_line_idx[idx] = line_idx[idx] = GesturePalmGetHorizIndexWithX(base_x[idx], idx, type);
1415
1416                 PalmFlickDebugPrint("[PalmFlick][P] idx: %d, num_pressed: %d\n", idx, g_pGesture->num_pressed);
1417                 PalmFlickDebugPrint("[PalmFlick][P] base_time: %d, base_x: %d, base_y: %d, line_idx: %d, touch_major=%d\n",
1418                         base_time, base_x[idx], base_y[idx], line_idx[idx], max_tmajor[idx]);
1419
1420                 // invalid region
1421                 if (line_idx[idx] < 0 || line_idx[idx] >= PALM_HORIZ_ARRAY_COUNT)
1422                 {
1423                     PalmFlickDebugPrint("[PalmFlick][P][F] No line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x[idx], line_idx[idx]);
1424                     PalmFlickDebugPrint("[PalmFlick][F] 2\n");
1425                     goto flick_failed;
1426                 }
1427
1428                 // check press point when there are two fingers
1429                 if (idx == 1)
1430                 {
1431                     if (press_idx[0] != press_idx[1])
1432                     {
1433                         PalmFlickDebugPrint("[PalmFlick] Press line_idx is the different between two fingers. 1st finger_line_idx=%d, 2nd finger_line_idx=%d\n",
1434                                 press_idx[0], press_idx[1]);
1435                         PalmFlickDebugPrint("[PalmFlick][F] 2-1\n");
1436                         goto flick_failed;
1437                     }
1438                 }
1439             }
1440             else
1441             {
1442                 update_x[idx] = g_pGesture->fingers[idx].px;
1443                 update_y[idx] = g_pGesture->fingers[idx].py;
1444
1445                 PalmFlickDebugPrint("[PalmFlick][P] Already palm flick success. base_x=%d, base_y=%d, update_x=%d, update_y=%d\n",
1446                         base_x[idx], base_y[idx], update_x[idx], update_y[idx]);
1447             }
1448
1449             break;
1450
1451         case ET_Motion:
1452
1453             if (total_max_tmajor > g_pGesture->palm_flick_max_tmajor_threshold)
1454             {
1455                 mt_sync_count[idx]++;
1456                 is_palm = TRUE;
1457                 DetailDebugPrint("[PalmFlick][M] Sufficient touch enough ! max_tmajor=%d\n", total_max_tmajor);
1458                 break;
1459             }
1460
1461             // motion information (touch major, x, y)
1462             current_x[idx] = g_pGesture->fingers[idx].mx;
1463             current_y[idx] = g_pGesture->fingers[idx].my;
1464             max_tmajor[idx] = g_pGesture->max_mt_tmajor[idx];
1465             mt_sync_count[idx]++;
1466
1467             //int temp_total_max_tmajor = (idx == 0 ? max_tmajor[0] : max_tmajor[0] + max_tmajor[1]);
1468             int temp_total_max_tmajor = max_tmajor[idx];
1469             total_max_tmajor = (total_max_tmajor > temp_total_max_tmajor ? total_max_tmajor : temp_total_max_tmajor);
1470
1471             PalmFlickDebugPrint("[PalmFlick][M] idx=%d, total_max_tmajor=%d, max_tmajor[0]=%d, max_tmajor[1]=%d, current current=(%d, %d)\n",
1472                     idx, total_max_tmajor, max_tmajor[0], max_tmajor[1], current_x[idx], current_y[idx]);
1473
1474             // exception vezel end line motion
1475             if (current_x[idx] < 5 || current_x[idx] > 355)
1476             {
1477                 if (total_max_tmajor >= g_pGesture->palm_flick_max_tmajor_threshold)
1478                 {
1479                     PalmFlickDebugPrint("[PalmFlick][M][Vezel] Sufficient touch major was came(%d)\n", total_max_tmajor);
1480                     is_palm = TRUE;
1481                 }
1482                 else
1483                 {
1484                     mt_sync_count[idx]--;
1485                     PalmFlickDebugPrint("[PalmFlick][M] Except vezel end line condition. x=%d, sync_count=%d \n",
1486                             current_x[idx], mt_sync_count[idx]);
1487                 }
1488                 break;
1489             }
1490
1491             // get current position
1492             line_idx[idx] = GesturePalmGetHorizIndexWithX(current_x[idx], idx, type);
1493
1494             PalmFlickDebugPrint("[PalmFlick][M] line_idx: %d, prev_line_idx: %d, sync_count: %d\n",
1495                     line_idx[idx], prev_line_idx[idx], mt_sync_count[idx]);
1496
1497             //error check
1498             if (line_idx[idx] < 0 || line_idx[idx] >= PALM_HORIZ_ARRAY_COUNT)
1499             {
1500                 PalmFlickDebugPrint("[PalmFlick][M][F] No line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x[idx], line_idx[idx]);
1501                 PalmFlickDebugPrint("[PalmFlick][F] 3\n");
1502                 goto flick_failed;
1503             }
1504
1505             // screen capture motion validation
1506             if (line_idx[idx] != prev_line_idx[idx])
1507             {
1508                 if (base_x[idx] <= pPalmMisc->horiz_coord[0])
1509                 {
1510                     if (line_idx[idx] < prev_line_idx[idx])
1511                     {
1512                         PalmFlickDebugPrint("[PalmFlick][M][F] Invalid line_idx.. line_idx: %d, prev_line_idx: %d, pPalmMisc->horiz_coord[0]: %d\n",
1513                                 line_idx[idx], prev_line_idx[idx], pPalmMisc->horiz_coord[0]);
1514
1515                         is_line_invalid[idx] = TRUE;
1516
1517                         if (is_line_invalid[0] && is_line_invalid[1])
1518                         {
1519                             PalmFlickDebugPrint("[PalmFlick][F] 4\n");
1520                             goto flick_failed;
1521                         }
1522                     }
1523                 }
1524                 else if (base_x[idx] >= pPalmMisc->horiz_coord[PALM_HORIZ_ARRAY_COUNT-1])
1525                 {
1526                     if (line_idx[idx] > prev_line_idx[idx])
1527                     {
1528                         PalmFlickDebugPrint("[PalmFlick][M][F] Invalid line_idx.. line_idx: %d, prev_line_idx: %d, pPalmMisc->horiz_coord[%d]: %d\n",
1529                                 line_idx[idx], prev_line_idx[idx], PALM_HORIZ_ARRAY_COUNT-1, pPalmMisc->horiz_coord[PALM_HORIZ_ARRAY_COUNT-1]);
1530
1531                         is_line_invalid[idx] = TRUE;
1532
1533                         if (is_line_invalid[0] && is_line_invalid[1])
1534                         {
1535                             PalmFlickDebugPrint("[PalmFlick][F] 5\n");
1536                             goto flick_failed;
1537                         }
1538                     }
1539                 }
1540                 prev_line_idx[idx] = line_idx[idx];
1541             }
1542
1543             if (is_palm == FALSE)
1544             {
1545                 switch (mt_sync_count[idx])
1546                 {
1547                     case 1:
1548                         if (total_max_tmajor <= g_pGesture->palm_flick_min_tmajor_threshold)
1549                         {
1550                             PalmFlickDebugPrint("[PalmFlick][M][F] mtsync_count: %d, max_tmajor: %d(%d) line_idx: %d\n",
1551                                     mt_sync_count[idx], total_max_tmajor, g_pGesture->palm_flick_min_tmajor_threshold, line_idx[idx]);
1552                             PalmFlickDebugPrint("[PalmFlick][F] 6\n");
1553                             is_tmajor_invalid[idx] = TRUE;
1554                             //goto flick_failed;
1555                         }
1556                         break;
1557                     case 2:
1558                         if (total_max_tmajor <= (g_pGesture->palm_flick_max_tmajor_threshold - 10))
1559                         {
1560                             PalmFlickDebugPrint("[PalmFlick][M][F] mtsync_count: %d, max_tmajor: %d(%d) line_idx: %d\n",
1561                                     mt_sync_count[idx], total_max_tmajor, g_pGesture->palm_flick_max_tmajor_threshold-10, line_idx[idx]);
1562                             PalmFlickDebugPrint("[PalmFlick][F] 7\n");
1563                             is_tmajor_invalid[idx] = TRUE;
1564                             //goto flick_failed;
1565                         }
1566                         break;
1567                     case 3:
1568                         if (total_max_tmajor < g_pGesture->palm_flick_max_tmajor_threshold)
1569                         {
1570                             PalmFlickDebugPrint("[PalmFlick][M][F] mtsync_count: %d, max_tmajor: %d(%d) line_idx: %d\n",
1571                                     mt_sync_count[idx], total_max_tmajor, g_pGesture->palm_flick_max_tmajor_threshold, line_idx[idx]);
1572                             PalmFlickDebugPrint("[PalmFlick][F] 8\n");
1573                             is_tmajor_invalid[idx] = TRUE;
1574                             //goto flick_failed;
1575                         }
1576                         break;
1577                     default:
1578                         PalmFlickDebugPrint("[PalmFlick][M] See more next motion...\n");
1579                         break;
1580                 }
1581             }
1582
1583             if (is_tmajor_invalid[0] && is_tmajor_invalid[1])
1584             {
1585                 PalmFlickDebugPrint("[PalmFlick][M][F] max_tmajor=%d\n", total_max_tmajor);
1586                 goto flick_failed;
1587             }
1588
1589             current_time = GetTimeInMillis();
1590
1591             if (current_time - base_time > g_pGesture->palm_flick_time_threshold)
1592             {
1593                 PalmFlickDebugPrint("[PalmFlick][M][F] Release event were not came too long time (%d - %d > %d)\n", current_time, base_time, g_pGesture->palm_flick_time_threshold);
1594                 PalmFlickDebugPrint("[PalmFlick][F] 10\n");
1595                 goto flick_failed;
1596             }
1597
1598             break;
1599
1600         case ET_ButtonRelease:
1601             current_x[idx] = g_pGesture->fingers[idx].mx;
1602             current_y[idx] = g_pGesture->fingers[idx].my;
1603             release_status[idx] = TRUE;
1604
1605             if ((update_x[idx] == current_x[idx]) && (update_y[idx] == current_y[idx]))
1606             {
1607                 PalmFlickDebugPrint("[PalmFlick][R][F] Press point and release point are the same. base_x=%d, base_y=%d, current_x=%d, current_y=%d\n",
1608                         update_x[idx], update_y[idx], current_x[idx], current_y[idx]);
1609                 PalmFlickDebugPrint("[PalmFlick][F] 10-1\n");
1610                 break;
1611                 //goto flick_failed;
1612             }
1613
1614             if (!is_palm)
1615             {
1616                 is_tmajor_invalid[idx] = TRUE;
1617
1618                 if (is_tmajor_invalid[0] && is_tmajor_invalid[1])
1619                 {
1620                     PalmFlickDebugPrint("[PalmFlick][R][F] Insufficient touch major was came(%d)\n", total_max_tmajor);
1621                     PalmFlickDebugPrint("[PalmFlick][F] 11\n");
1622                     goto flick_failed;
1623                 }
1624             }
1625
1626             line_idx[idx] = GesturePalmGetHorizIndexWithX(current_x[idx], idx, type);
1627
1628             if (is_palm && line_idx[idx] == 1)
1629             {
1630                 PalmFlickDebugPrint("[PalmFlick][R] Enough major, but release. base_x=%d, base_y=%d, current_x=%d, current_y=%d\n",
1631                         base_x[idx], base_y[idx], current_x[idx], current_y[idx]);
1632                 is_retry = TRUE;
1633                 mt_sync_count[idx] = 0;
1634                 break;
1635             }
1636
1637             if (line_idx[idx] < 0 || line_idx[idx] > PALM_HORIZ_ARRAY_COUNT - 1)
1638             {
1639                 is_line_invalid[idx] = TRUE;
1640
1641                 if (is_line_invalid[0] && is_line_invalid[1])
1642                 {
1643                     PalmFlickDebugPrint("[PalmFlick][R][F] No line_idx is invalid.. base_x: %d, current_x: %d\n", base_x[idx], current_x[idx]);
1644                     PalmFlickDebugPrint("[PalmFlick][F] 12\n");
1645                     goto flick_failed;
1646                 }
1647             }
1648
1649             current_time = GetTimeInMillis();
1650
1651             if (current_time - base_time > g_pGesture->palm_flick_time_threshold)
1652             {
1653                 PalmFlickDebugPrint("[PalmFlick][R][F] Release event were came to have long delay (%d - %d > %d)\n",
1654                         current_time, base_time, g_pGesture->palm_flick_time_threshold);
1655                 PalmFlickDebugPrint("[PalmFlick][F] 13\n");
1656                 goto flick_failed;
1657             }
1658
1659             direction = (line_idx[idx] <= 1) ? FLICK_EASTWARD : FLICK_WESTWARD;
1660             distance = ABS(current_x[idx] - base_x[idx]);
1661             duration = current_time - base_time;
1662
1663             if (!is_retry)
1664             {
1665                 if (GestureHasFingerEventMask(GestureNotifyFlick, 0))
1666                 {
1667                     PalmFlickDebugPrint("[PalmFlick][R] Palm Flick1 !!!, direction=%d, distance=%d\n", direction, distance);
1668                     is_palm = FALSE;
1669                     GestureHandleGesture_Flick(0, distance, duration, direction);
1670                 }
1671             }
1672             else
1673             {
1674                 if (mt_sync_count[idx] < 25)
1675                 {
1676                     PalmFlickDebugPrint("[PalmFlick][R][F] No enough motion=%d\n", mt_sync_count[idx]);
1677                     PalmFlickDebugPrint("[PalmFlick][F] 14\n");
1678                     goto flick_failed;
1679                 }
1680                 else
1681                 {
1682                     if (GestureHasFingerEventMask(GestureNotifyFlick, 0))
1683                     {
1684                         PalmFlickDebugPrint("[PalmFlick][R] Palm Flick2 !!!, direction=%d, distance=%d\n", direction, distance);
1685                         is_palm = FALSE;
1686                         GestureHandleGesture_Flick(0, distance, duration, direction);
1687                     }
1688                 }
1689             }
1690
1691             g_pGesture->recognized_gesture |= WPalmFlickFilterMask;
1692
1693             goto cleanup_flick;
1694             break;
1695     }
1696
1697     return;
1698
1699 flick_failed:
1700
1701     DetailDebugPrint("[PalmFlick][R] flick failed\n");
1702
1703     g_pGesture->recognized_gesture &= ~WPalmFlickFilterMask;
1704     g_pGesture->filter_mask |= WPalmFlickFilterMask;
1705     goto cleanup_flick;
1706
1707 cleanup_flick:
1708
1709     DetailDebugPrint("[PalmFlick][R] cleanup_flick\n");
1710
1711     for (int i = 0; i < MAX_MT_DEVICES; i++)
1712     {
1713         base_x[i] = 0;
1714         base_y[i] = 0;
1715         update_x[i] = 0;
1716         update_y[i] = 0;
1717         current_x[i] = 0;
1718         current_y[i] = 0;
1719         line_idx[i] = 0;
1720         press_idx[i] = 0;
1721         prev_line_idx[i] = 0;
1722         max_tmajor[i] = 0;
1723         mt_sync_count[i] = 0;
1724         press_status[i] = FALSE;
1725         release_status[i] = FALSE;
1726         is_tmajor_invalid[i] = TRUE;
1727         is_line_invalid[i] = TRUE;
1728     }
1729
1730     total_max_tmajor = 0;
1731     is_palm = FALSE;
1732     is_retry = FALSE;
1733
1734     return;
1735 }
1736
1737 static int
1738 GesturePalmGetHorizIndexWithX(int current_x, int idx, int type)
1739 {
1740     int i;
1741     int ret_idx = -1;
1742     static int pressed_idx[MAX_MT_DEVICES] = {-1, -1};
1743     PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
1744
1745     for (i = 0; i < PALM_HORIZ_ARRAY_COUNT; i++)
1746     {
1747         if (current_x <= pPalmMisc->horiz_coord[i])
1748         {
1749             DetailDebugPrint("[GesturePalmGetHorizIndexWithX] index=%d, pPalmMisc->horiz_coord[%d]=%d\n", i, i, pPalmMisc->horiz_coord[i]);
1750
1751             ret_idx = i;
1752             goto index_check;
1753         }
1754     }
1755
1756     DetailDebugPrint("[GesturePalmGetHorizIndexWithX]Error ! Failed to get horiz coordinate index !\n");
1757     return ret_idx;
1758
1759 index_check:
1760
1761     if (type == ET_ButtonPress)
1762     {
1763         pressed_idx[idx] = ret_idx;
1764
1765         // first press is center
1766         if (pressed_idx[idx] == PALM_HORIZ_ARRAY_COUNT -2)
1767         {
1768             DetailDebugPrint("[GesturePalmGetHorizIndexWithX][P] Invalid press area x=%d, idx=%d, pressed_idx=%d\n", current_x, idx, pressed_idx[idx]);
1769             ret_idx = -1;
1770         }
1771
1772         DetailDebugPrint("[GesturePalmGetHorizIndexWithX][P] pressed_idx=%d\n", pressed_idx[idx]);
1773     }
1774
1775     else if (type == ET_Motion)
1776     {
1777         DetailDebugPrint("[GesturePalmGetHorizIndexWithX][M] moving x=%d, idx=%d, pressed_idx=%d\n", current_x, idx, pressed_idx[idx]);
1778     }
1779
1780     else if (type == ET_ButtonRelease)
1781     {
1782         if ((pressed_idx[idx] == 0) && (ret_idx == (PALM_HORIZ_ARRAY_COUNT - 1)))
1783         {
1784             DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] From the left to the right ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
1785         }
1786         else if ((pressed_idx[idx] == (PALM_HORIZ_ARRAY_COUNT - 1)) && (ret_idx == 0))
1787         {
1788             DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] From the right to the left ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
1789         }
1790         else if ((pressed_idx[idx] == ret_idx) && ret_idx != 1)
1791         {
1792             DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] Relased the same region ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
1793             return 1;
1794         }
1795         else
1796         {
1797             DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] Invalid ! pressed_idx=%d, released_idx=%d\n", pressed_idx[idx], ret_idx);
1798             ret_idx = -1;
1799         }
1800
1801         pressed_idx[idx] = -1;
1802     }
1803
1804     return ret_idx;
1805 }
1806
1807 static int
1808 GesturePalmGetAbsAxisInfo(DeviceIntPtr dev)
1809 {
1810     int i, found = 0;
1811     int numAxes;
1812
1813     Atom atom_tpalm;
1814     Atom atom_mt_slot;
1815     Atom atom_tracking_id;
1816     Atom atom_tmajor;
1817     Atom atom_tminor;
1818
1819     g_pGesture->tpalm_idx = -1;
1820     g_pGesture->tmajor_idx = -1;
1821     g_pGesture->tminor_idx = -1;
1822
1823     if (!dev || !dev->valuator)
1824         goto out;
1825
1826     numAxes = dev->valuator->numAxes;
1827
1828     atom_tpalm = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_PALM);
1829     atom_mt_slot = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_SLOT);
1830     atom_tracking_id = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TRACKING_ID);
1831     atom_tmajor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR);
1832     atom_tminor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR);
1833
1834     if (!numAxes || !atom_tpalm || !atom_tmajor || !atom_tminor)
1835     {
1836         ErrorF("one or more axes is/are not supported!\n");
1837         goto out;
1838     }
1839
1840     for (i = 0; i < numAxes; i++)
1841     {
1842         AxisInfoPtr axes = &dev->valuator->axes[i];
1843
1844         if (!axes || (axes->mode != Absolute))
1845             continue;
1846
1847         if (axes->label == atom_tpalm)
1848         {
1849             g_pGesture->tpalm_idx = i;
1850             found += 1;
1851         }
1852         else if (axes->label == atom_tmajor)
1853         {
1854             g_pGesture->tmajor_idx = i;
1855             found += 2;
1856         }
1857         else if (axes->label == atom_tminor)
1858         {
1859             g_pGesture->tminor_idx = i;
1860             found += 4;
1861         }
1862     }
1863
1864     if (found != 7)
1865     {
1866         ErrorF("Axes for palm recognization are not supported !\n");
1867         goto out;
1868     }
1869
1870     g_pGesture->palm_misc.enabled = 1;
1871     ErrorF("Axes for palm recognization are supported !\n");
1872     return 1;
1873
1874 out:
1875     g_pGesture->palm_misc.enabled = 0;
1876     ErrorF("Palm recognization is not supported !\n");
1877     return 0;
1878 }
1879
1880 static int
1881 GestureGetPalmValuator(InternalEvent *ev, DeviceIntPtr device)
1882 {
1883     int mt_palm_idx = g_pGesture->tpalm_idx;
1884     int mt_palm = 0;
1885
1886     DeviceEvent *de = &ev->device_event;
1887
1888     if (!de)
1889     {
1890         ErrorF("[GestureGetPalmValuator] de is NULL !\n");
1891         return -1;
1892     }
1893
1894     if (mt_palm_idx < 0)
1895     {
1896         ErrorF("[GestureGetPalmValuator] One or more of axes are not supported !\n");
1897         return -1;
1898     }
1899
1900     mt_palm = de->valuators.data[mt_palm_idx];
1901
1902     HoldDetectorDebugPrint("[GestureGetPalmValuator] mt_palm:%d\n", mt_palm);
1903
1904     return mt_palm;
1905 }
1906
1907 static void GestureHoldDetector(int type, InternalEvent *ev, DeviceIntPtr device)
1908 {
1909     int i;
1910     int idx = -1;
1911     pixman_region16_t tarea1;
1912     static int num_pressed = 0;
1913     unsigned int hold_area_size;
1914     PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
1915     int palm_flag = 0;
1916
1917     if (!g_pGesture->has_hold_grabmask)
1918     {
1919         HoldDetectorDebugPrint("[GestureHoldDetector] g_pGesture->has_hold_grabmask=%d\n", g_pGesture->has_hold_grabmask);
1920
1921         Mask eventmask = (1L << GestureNotifyHold);
1922
1923         if ((g_pGesture->grabMask & eventmask) &&
1924                 (g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[0].window != None))
1925         {
1926             g_pGesture->has_hold_grabmask = 1;
1927
1928             //Initialize a set of variables
1929             num_pressed = 0;
1930             memset(&g_pGesture->cts, 0, sizeof(g_pGesture->cts));
1931             pixman_region_init(&g_pGesture->chold_area);
1932
1933             HoldDetectorDebugPrint("[GestureHoldDetector] Initialize...\n");
1934         }
1935         else
1936         {
1937             //reset local hold_grab_mask variable
1938             g_pGesture->has_hold_grabmask = 0;
1939
1940             g_pGesture->hold_detector_activate = 0;
1941             HoldDetectorDebugPrint("[GestureHoldDetector] has_hold_grabmask=0 and g_pGesture->hold_detector_activate=0\n");
1942             return;
1943         }
1944     }
1945
1946     if (IGNORE_EVENTS == g_pGesture->ehtype ||
1947             device->id < g_pGesture->first_fingerid)
1948     {
1949         HoldDetectorDebugPrint("[GestureHoldDetector] Return (IGNORE_EVENTS or device->id:%d < first_fingerid:%d)\n", device->id, g_pGesture->first_fingerid);
1950         return;
1951     }
1952
1953     palm_flag = GestureGetPalmValuator(ev, device);
1954
1955     if (palm_flag)
1956     {
1957         GestureHandleGesture_Hold(0, 0, 0, PALM_HOLD_TIME_THRESHOLD, GestureBegin);
1958         GestureHandleGesture_Hold(0, 0, 0, PALM_HOLD_TIME_THRESHOLD, GestureEnd);
1959
1960         g_pGesture->hold_detector_activate = 0;
1961         g_pGesture->has_hold_grabmask = 0;
1962         HoldDetectorDebugPrint("[GestureHoldDetector] palm_flag:%d enable\n", palm_flag);
1963         return;
1964     }
1965     else
1966     {
1967         HoldDetectorDebugPrint("[GestureHoldDetector] palm_flag:%d disable\n", palm_flag);
1968         return;
1969     }
1970
1971     HoldDetectorDebugPrint("[GestureHoldDetector] g_pGesture->num_mt_devices:%d\n", g_pGesture->num_mt_devices);
1972
1973     for (i = 0; i < g_pGesture->num_mt_devices; i++)
1974     {
1975         if ( device->id == g_pGesture->mt_devices[i]->id)
1976         {
1977             idx = i;
1978             HoldDetectorDebugPrint("[GestureHoldDetector] idx:%d\n", idx);
1979             break;
1980         }
1981     }
1982     if ((idx < 0) || ((MAX_MT_DEVICES-1) < idx)) return;
1983
1984     switch (type)
1985     {
1986         case ET_ButtonPress:
1987             g_pGesture->cts[idx].status = BTN_PRESSED;
1988             g_pGesture->cts[idx].cx = ev->device_event.root_x;
1989             g_pGesture->cts[idx].cy = ev->device_event.root_y;
1990             num_pressed++;
1991             HoldDetectorDebugPrint("[GestureHoldDetector][P] cx:%d, cy:%d, num_pressed:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy, num_pressed);
1992
1993             if (num_pressed < 2)
1994             {
1995                 HoldDetectorDebugPrint("[GestureHoldDetector][P] num_pressed:%d\n", num_pressed);
1996                 break;
1997             }
1998
1999             if (num_pressed > g_pGesture->num_mt_devices)
2000                 num_pressed = g_pGesture->num_mt_devices;
2001
2002             pixman_region_init(&tarea1);
2003             pixman_region_init(&g_pGesture->chold_area);
2004             pixman_region_init_rect(&tarea1, g_pGesture->cts[0].cx, g_pGesture->cts[0].cy, g_pGesture->cts[0].cx+1, g_pGesture->cts[0].cy+1);
2005
2006             tarea1.extents.x1 = g_pGesture->cts[0].cx;
2007             tarea1.extents.x2 = g_pGesture->cts[0].cx+1;
2008             tarea1.extents.y1 = g_pGesture->cts[0].cy;
2009             tarea1.extents.y2 = g_pGesture->cts[0].cy+1;
2010
2011             pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1);
2012
2013             for (i = 1; i < num_pressed; i++)
2014             {
2015                 pixman_region_init_rect(&tarea1, g_pGesture->cts[i].cx, g_pGesture->cts[i].cy, g_pGesture->cts[i].cx + 1, g_pGesture->cts[i].cy + 1);
2016
2017                 tarea1.extents.x1 = g_pGesture->cts[i].cx;
2018                 tarea1.extents.x2 = g_pGesture->cts[i].cx + 1;
2019                 tarea1.extents.y1 = g_pGesture->cts[i].cy;
2020                 tarea1.extents.y2 = g_pGesture->cts[i].cy + 1;
2021
2022                 pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1);
2023             }
2024             break;
2025
2026         case ET_Motion:
2027             if (BTN_RELEASED == g_pGesture->cts[idx].status)
2028                 return;
2029
2030             g_pGesture->cts[idx].status = BTN_MOVING;
2031             g_pGesture->cts[idx].cx = ev->device_event.root_x;
2032             g_pGesture->cts[idx].cy = ev->device_event.root_y;
2033
2034             HoldDetectorDebugPrint("[GestureHoldDetector][M] cx:%d, cy:%d, num_pressed:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy, num_pressed);
2035
2036             if (num_pressed < 2)
2037             {
2038                 HoldDetectorDebugPrint("[GestureHoldDetector][M] num_pressed:%d\n", num_pressed);
2039                 break;
2040             }
2041
2042             pixman_region_init(&tarea1);
2043             pixman_region_init(&g_pGesture->chold_area);
2044             pixman_region_init_rect(&tarea1, g_pGesture->cts[0].cx, g_pGesture->cts[0].cy, g_pGesture->cts[0].cx+1, g_pGesture->cts[0].cy+1);
2045
2046             tarea1.extents.x1 = g_pGesture->cts[0].cx;
2047             tarea1.extents.x2 = g_pGesture->cts[0].cx+1;
2048             tarea1.extents.y1 = g_pGesture->cts[0].cy;
2049             tarea1.extents.y2 = g_pGesture->cts[0].cy+1;
2050
2051             pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1);
2052
2053             for (i = 1; i < num_pressed; i++)
2054             {
2055                 pixman_region_init_rect(&tarea1, g_pGesture->cts[i].cx, g_pGesture->cts[i].cy, g_pGesture->cts[i].cx + 1, g_pGesture->cts[i].cy + 1);
2056
2057                 tarea1.extents.x1 = g_pGesture->cts[i].cx;
2058                 tarea1.extents.x2 = g_pGesture->cts[i].cx + 1;
2059                 tarea1.extents.y1 = g_pGesture->cts[i].cy;
2060                 tarea1.extents.y2 = g_pGesture->cts[i].cy + 1;
2061
2062                 pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1);
2063             }
2064             break;
2065
2066         case ET_ButtonRelease:
2067             g_pGesture->cts[idx].status = BTN_RELEASED;
2068             g_pGesture->cts[idx].cx = ev->device_event.root_x;
2069             g_pGesture->cts[idx].cy = ev->device_event.root_y;
2070
2071             HoldDetectorDebugPrint("[GestureHoldDetector][R] cx:%d, cy:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy);
2072
2073             num_pressed--;
2074             if (num_pressed <3)
2075             {
2076                 pixman_region_init(&g_pGesture->chold_area);
2077             }
2078             break;
2079     }
2080
2081     if (num_pressed >= 2)
2082     {
2083         hold_area_size = AREA_SIZE(&g_pGesture->chold_area.extents);
2084
2085         HoldDetectorDebugPrint("[GestureHoldDetector] hold_area_size=%d, pPalmMisc->half_scrn_area_size=%d\n", hold_area_size, pPalmMisc->half_scrn_area_size);
2086
2087         if (pPalmMisc->half_scrn_area_size <= hold_area_size)
2088         {
2089             GestureHandleGesture_Hold(0, AREA_CENTER_X(&g_pGesture->chold_area.extents), AREA_CENTER_Y(&g_pGesture->chold_area.extents), PALM_HOLD_TIME_THRESHOLD, GestureBegin);
2090             GestureHandleGesture_Hold(0, AREA_CENTER_X(&g_pGesture->chold_area.extents), AREA_CENTER_Y(&g_pGesture->chold_area.extents), PALM_HOLD_TIME_THRESHOLD, GestureEnd);
2091
2092             g_pGesture->hold_detector_activate = 0;
2093             g_pGesture->has_hold_grabmask = 0;
2094         }
2095     }
2096     else
2097     {
2098         hold_area_size = AREA_SIZE(&g_pGesture->chold_area.extents);
2099         HoldDetectorDebugPrint("[GestureHoldDetector] num_pressed is under 2, hold_area_size=%d\n", hold_area_size);
2100     }
2101 }
2102
2103
2104 static int
2105 GesturePalmGetScreenInfo()
2106 {
2107     int i;
2108     pixman_region16_t tarea;
2109     PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
2110     ScreenPtr pScreen = miPointerCurrentScreen();
2111
2112     if (!pScreen)
2113     {
2114         DetailDebugPrint("[X11][GesturePalmGetScreenInfo]Failed to get screen information !\n");
2115
2116         pPalmMisc->scrn_width = pPalmMisc->scrn_height = 0;
2117         return 0;
2118     }
2119
2120     pPalmMisc->scrn_width = pScreen->width;
2121     pPalmMisc->scrn_height = pScreen->height;
2122     pixman_region_init(&tarea);
2123     pixman_region_init_rect(&tarea, 0, 0, pPalmMisc->scrn_width, pPalmMisc->scrn_height);
2124
2125     DetailDebugPrint("[X11][GesturePalmGetScreenInfo] x2:%d, x2:%d, y2:%d, y1:%d \n", tarea.extents.x2, tarea.extents.x1, tarea.extents.y2, tarea.extents.y1);
2126     pPalmMisc->half_scrn_area_size = AREA_SIZE(&tarea.extents);
2127     pPalmMisc->half_scrn_area_size = (unsigned int)((double)pPalmMisc->half_scrn_area_size / 4);
2128
2129     DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->half_scrn_area_size = %d\n", pPalmMisc->half_scrn_area_size);
2130
2131     for (i = 0; i < PALM_HORIZ_ARRAY_COUNT; i++)
2132     {
2133         pPalmMisc->horiz_coord[i] = pPalmMisc->scrn_width * ((i+1)/(double)PALM_HORIZ_ARRAY_COUNT);
2134         DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->horiz_coord[%d]=%d, pPalmMisc->scrn_width=%d\n", i, pPalmMisc->horiz_coord[i], pPalmMisc->scrn_width);
2135     }
2136     for (i = 0; i < PALM_VERTI_ARRAY_COUNT; i++)
2137     {
2138         pPalmMisc->verti_coord[i] = pPalmMisc->scrn_height * ((i+1)/(double)PALM_VERTI_ARRAY_COUNT);
2139         DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->verti_coord[%d]=%d, pPalmMisc->scrn_height=%d\n", i, pPalmMisc->verti_coord[i], pPalmMisc->scrn_height);
2140     }
2141
2142     return 1;
2143 }
2144
2145
2146 static inline void
2147 GestureEnableDisable()
2148 {
2149     GestureEnable(1, FALSE, g_pGesture->this_device);
2150 #if 0
2151     if ((g_pGesture->grabMask) || (g_pGesture->lastSelectedWin != None))
2152     {
2153         GestureEnable(1, FALSE, g_pGesture->this_device);
2154     }
2155     else
2156     {
2157         GestureEnable(0, FALSE, g_pGesture->this_device);
2158     }
2159 #endif
2160 }
2161
2162 void
2163 GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent)
2164 {
2165     g_pGesture->grabMask = *pGrabMask;
2166     g_pGesture->GrabEvents = (GestureGrabEventPtr)pGrabEvent;
2167     GestureEnableDisable();
2168 }
2169
2170 void
2171 GestureCbEventsSelected(Window win, Mask *pEventMask)
2172 {
2173     g_pGesture->lastSelectedWin = win;
2174     g_pGesture->lastSelectedMask = (pEventMask) ? *pEventMask : 0;
2175     GestureEnableDisable();
2176 }
2177
2178 WindowPtr
2179 GestureGetEventsWindow(void)
2180 {
2181     Mask mask;
2182     WindowPtr pWin;
2183
2184     pWin = GestureWindowOnXY(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py);
2185
2186     if (pWin)
2187     {
2188         DetailDebugPrint("[GestureGetEventsWindow] pWin->drawable.id=0x%x\n", pWin->drawable.id);
2189         g_pGesture->gestureWin = pWin->drawable.id;
2190     }
2191     else
2192     {
2193         DetailDebugPrint("[GestureGetEventsWindow] GestureWindowOnXY returns NULL !\n");
2194         return NULL;
2195     }
2196
2197     if (g_pGesture->gestureWin == g_pGesture->lastSelectedWin)
2198     {
2199         g_pGesture->eventMask = g_pGesture->lastSelectedMask;
2200         goto nonempty_eventmask;
2201     }
2202
2203     //check selected event(s)
2204     if (!GestureHasSelectedEvents(pWin, &g_pGesture->eventMask))
2205     {
2206         g_pGesture->eventMask = 0;
2207     }
2208     else
2209     {
2210         g_pGesture->lastSelectedWin = g_pGesture->gestureWin;
2211         g_pGesture->lastSelectedMask = g_pGesture->eventMask;
2212     }
2213
2214     if (!g_pGesture->eventMask && !g_pGesture->grabMask)
2215     {
2216         DetailDebugPrint("[X11][GestureGetEventsWindow] No grabbed events or no events were selected for window(0x%x) !\n", pWin->drawable.id);
2217         return NULL;
2218     }
2219
2220 nonempty_eventmask:
2221
2222     DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->eventMask=0x%x\n", g_pGesture->eventMask);
2223
2224     mask = (GESTURE_FILTER_MASK_ALL & ~(g_pGesture->grabMask | g_pGesture->eventMask));
2225
2226     DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x, mask=0x%x\n", g_pGesture->filter_mask, mask);
2227
2228     g_pGesture->filter_mask = mask;
2229
2230     DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x\n", g_pGesture->filter_mask);
2231
2232     return pWin;
2233 }
2234
2235 static CARD32
2236 GestureSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2237 {
2238     g_pGesture->filter_mask |= WTapFilterMask;
2239     g_pGesture->filter_mask |= WHoldFilterMask;
2240     LOGI("[GroupTap][GroupHold] 50ms after 1st finger.\n");
2241
2242     DetailDebugPrint("[GestureSingleFingerTimerHandler] TapFilterMask, HoldFilterMask \n");
2243
2244     if ((g_pGesture->event_sum[0] == BTN_PRESSED) && ((g_pGesture->flick_pressed_point <= FLICK_POINT_NONE) && (FLICK_POINT_MAX <= g_pGesture->flick_pressed_point)))
2245     {
2246         DetailDebugPrint("[GestureSingleFingerTimerHandler] press_point: %d\n", g_pGesture->flick_pressed_point);
2247         DetailDebugPrint("[GestureSingleFingerTimerHandler] FlickFilterMask\n");
2248         g_pGesture->filter_mask |= WFlickFilterMask;
2249     }
2250
2251     if (g_pGesture->flick_pressed_point == FLICK_POINT_DOWN && abs(g_pGesture->fingers[0].py - g_pGesture->fingers[0].my) < 3)
2252     {
2253         DetailDebugPrint("[GestureSingleFingerTimerHandler] py: %d, my: %d\n", g_pGesture->fingers[0].py, g_pGesture->fingers[0].my);
2254         DetailDebugPrint("[GestureSingleFingerTimerHandler] FlickFilterMask\n");
2255         g_pGesture->filter_mask |= WFlickFilterMask;
2256     }
2257
2258     DetailDebugPrint("[GestureSingleFingerTimerHandler] expired !\n");
2259
2260     if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
2261     {
2262         if ( ERROR_INVALPTR == GestureFlushOrDrop())
2263         {
2264             DetailDebugPrint("[GestureSingleFingerTimerHandler] AllFilterMask, Flush!\n");
2265             GestureControl(g_pGesture->this_device, DEVICE_OFF);
2266         }
2267     }
2268
2269     return 0;
2270 }
2271
2272 void
2273 GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
2274 {
2275     int i;
2276     static OsTimerPtr single_finger_timer = NULL;
2277     int idx = -1;
2278
2279     if (PROPAGATE_EVENTS == g_pGesture->ehtype || device->id < g_pGesture->first_fingerid)
2280     {
2281         return;
2282     }
2283
2284     for (i = 0; i < g_pGesture->num_mt_devices; i++)
2285     {
2286         if (device->id == g_pGesture->mt_devices[i]->id)
2287         {
2288             idx = i;
2289             break;
2290         }
2291     }
2292
2293     if (idx < 0)
2294         return;
2295
2296     switch (type)
2297     {
2298         case ET_ButtonPress:
2299             if (idx == 0)
2300             {
2301                 g_pGesture->event_sum[0] = BTN_PRESSED;
2302             }
2303
2304             g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
2305
2306             g_pGesture->fingers[idx].ptime = ev->any.time;
2307             g_pGesture->fingers[idx].px = ev->device_event.root_x;
2308             g_pGesture->fingers[idx].py = ev->device_event.root_y;
2309
2310             g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
2311             g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
2312             g_pGesture->finger_rects[idx].extents.y1 =  ev->device_event.root_y - FINGER_HEIGHT;
2313             g_pGesture->finger_rects[idx].extents.y2 =  ev->device_event.root_y + FINGER_HEIGHT;
2314
2315             g_pGesture->num_pressed++;
2316             g_pGesture->inc_num_pressed = g_pGesture->num_pressed;
2317
2318             if (g_pGesture->inc_num_pressed == 1)
2319             {
2320                 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2321             }
2322             else
2323             {
2324                 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2325
2326                 for (i = 1; i < g_pGesture->inc_num_pressed; i++)
2327                 {
2328                     pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
2329                 }
2330             }
2331
2332             DetailDebugPrint("[GestureRecognize][P] num_pressed=%d, area_size=%d, px=%d, py=%d\n",
2333                     g_pGesture->num_pressed, AREA_SIZE(&g_pGesture->area.extents), g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
2334
2335             if (g_pGesture->num_pressed == 1)
2336             {
2337                 single_finger_timer = TimerSet(single_finger_timer, 0, 50, GestureSingleFingerTimerHandler, NULL);
2338
2339                 if (g_pGesture->fingers[idx].py <= g_pGesture->flick_press_area)
2340                 {
2341                     if ((!g_pGesture->activate_flick_down)
2342                             || (g_pGesture->fingers[idx].px <= (g_pGesture->flick_press_area_left_right))
2343                             || (g_pGesture->fingers[idx].px >= (g_pGesture->screen_width - g_pGesture->flick_press_area_left_right)))
2344                     {
2345                         DetailDebugPrint("[GestureRecognize][P] px=%d, flick_press_area_left_right=%d\n",
2346                             g_pGesture->fingers[idx].px, g_pGesture->flick_press_area_left_right);
2347                         g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2348                         LOGI("[BackKey][F] Press touch within 40 pixel area from left or right vezel\n");
2349                     }
2350                     else
2351                     {
2352                         DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_UP\n");
2353                         g_pGesture->flick_pressed_point = FLICK_POINT_UP;
2354                     }
2355                 }
2356                 else
2357                 {
2358                     LOGI("[BackKey][F] Press touch outside 40 pixel area from upper vezel. \n");
2359                 }
2360
2361                 if (g_pGesture->fingers[idx].py >= (g_pGesture->screen_height - g_pGesture->flick_press_area))
2362                 {
2363                     if (!g_pGesture->activate_flick_up)
2364                     {
2365                         g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2366                     }
2367                     else
2368                     {
2369                         DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_DOWN\n");
2370                         g_pGesture->flick_pressed_point = FLICK_POINT_DOWN;
2371                     }
2372                 }
2373                 else if ( g_pGesture->fingers[idx].px <= g_pGesture->flick_press_area_left)
2374                 {
2375                     if (!g_pGesture->activate_flick_right)
2376                     {
2377                         g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2378                     }
2379                     else
2380                     {
2381                         DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_LEFT\n");
2382                         g_pGesture->flick_pressed_point = FLICK_POINT_LEFT;
2383                     }
2384                 }
2385
2386                 DetailDebugPrint("[GestureRecognize][P] flick_press_point: %d\n", g_pGesture->flick_pressed_point);
2387
2388                 if ((g_pGesture->flick_pressed_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= g_pGesture->flick_pressed_point))
2389                 {
2390                     DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_NONE\n");
2391                     g_pGesture->filter_mask |= WFlickFilterMask;
2392                     g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2393                 }
2394                 else
2395                 {
2396                     g_pGesture->flick_direction = (g_pGesture->flick_pressed_point - 1) * 2;
2397                     if ((g_pGesture->flick_direction == FLICK_WESTWARD) && (g_pGesture->power_pressed != 2))
2398                     {
2399                         DetailDebugPrint("[GestureRecognize][P] Flick WesWard is disable when power is not pressed\n");
2400                         g_pGesture->filter_mask |= WFlickFilterMask;
2401                         g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2402                     }
2403                     if ((g_pGesture->flick_direction < FLICK_NORTHWARD) || (FLICK_NORTHWESTWARD < g_pGesture->flick_direction))
2404                     {
2405                         DetailDebugPrint("[GestureRecognize][P] Invalid flick direction\n");
2406                         g_pGesture->filter_mask |= WFlickFilterMask;
2407                         g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2408                     }
2409
2410                     DetailDebugPrint("[GestureRecognize][P] flick_direction: %d\n", g_pGesture->flick_direction);
2411                 }
2412             }
2413             else
2414             {
2415                 DetailDebugPrint("[GestureRecognize][P] Two more fingers come on!\n");
2416                 TimerCancel(single_finger_timer);
2417                 single_finger_timer = NULL;
2418             }
2419             break;
2420
2421         case ET_Motion:
2422
2423             if (!g_pGesture->fingers[idx].ptime)
2424             {
2425                 DetailDebugPrint("[GestureRecognize][M] Start motion. idx=%d\n", idx);
2426                 g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
2427                 return;
2428             }
2429
2430             g_pGesture->fingers[idx].mx = ev->device_event.root_x;
2431             g_pGesture->fingers[idx].my = ev->device_event.root_y;
2432             g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
2433
2434             if (idx == 0)
2435             {
2436                 g_pGesture->event_sum[0] += BTN_MOVING;
2437             }
2438
2439             g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
2440             g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
2441             g_pGesture->finger_rects[idx].extents.y1 =  ev->device_event.root_y - FINGER_HEIGHT;
2442             g_pGesture->finger_rects[idx].extents.y2 =  ev->device_event.root_y + FINGER_HEIGHT;
2443
2444             if (g_pGesture->inc_num_pressed == 1)
2445             {
2446                 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2447             }
2448             else
2449             {
2450                 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2451
2452                 for (i = 1; i < g_pGesture->inc_num_pressed; i++)
2453                 {
2454                     pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
2455                 }
2456             }
2457
2458             DetailDebugPrint("[GestureRecognize][M] num_pressed=%d, area_size=%d, mx=%d, my=%d\n",
2459                     g_pGesture->num_pressed, AREA_SIZE(&g_pGesture->area.extents), g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].my);
2460
2461             break;
2462
2463         case ET_ButtonRelease:
2464             g_pGesture->fingers[idx].rtime = ev->any.time;
2465             g_pGesture->fingers[idx].rx = ev->device_event.root_x;
2466             g_pGesture->fingers[idx].ry = ev->device_event.root_y;
2467             g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
2468
2469             g_pGesture->num_pressed--;
2470
2471             if (g_pGesture->num_pressed == 0)
2472             {
2473                 DetailDebugPrint("[GestureRecognize] All fingers were released !\n");
2474             }
2475             else if (g_pGesture->num_pressed < 0)
2476             {
2477                 DetailDebugPrint("[GestureRecognize] All fingers were released. But, num_pressed is under 0 !\n");
2478             }
2479
2480             DetailDebugPrint("[GestureRecognize][R] num_pressed=%d, rx=%d, ry=%d\n",
2481                     g_pGesture->num_pressed, g_pGesture->fingers[idx].rx, g_pGesture->fingers[idx].ry);
2482
2483             break;
2484     }
2485
2486     if (!(g_pGesture->filter_mask & WFlickFilterMask))
2487     {
2488         DetailDebugPrint("[GestureRecognize] GestureRecognize_groupFlick !\n");
2489         GestureRecognize_GroupFlick(type, ev, device, idx, g_pGesture->flick_pressed_point, g_pGesture->flick_direction);
2490     }
2491     if (!(g_pGesture->filter_mask & WTapFilterMask))
2492     {
2493         DetailDebugPrint("[GestureRecognize] GestureRecognize_groupTap !\n");
2494         GestureRecognize_GroupTap(type, ev, device, idx, 0);
2495     }
2496     if (!(g_pGesture->filter_mask & WHoldFilterMask))
2497     {
2498         DetailDebugPrint("[GestureRecognize] GestureRecognize_groupHold !\n");
2499         GestureRecognize_GroupHold(type, ev, device, idx, 0);
2500     }
2501 /*
2502     if (!(g_pGesture->filter_mask & WPalmFlickFilterMask))
2503     {
2504         DetailDebugPrint("[GestureRecognize] GestureRecognize_palmFlick !\n");
2505         GestureRecognize_PalmFlick(type, ev, device, idx);
2506     }
2507 */
2508     DetailDebugPrint("[GestureRecognize][N] g_pGesture->filter_mask = 0x%x, g_pGesture->GESTURE_WATCH_FILTER_MASK_ALL = 0x%x, g_pGesture->recognized_gesture=0x%x\n",
2509             g_pGesture->filter_mask, GESTURE_WATCH_FILTER_MASK_ALL, g_pGesture->recognized_gesture);
2510
2511     if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
2512     {
2513         if (!g_pGesture->recognized_gesture)
2514         {
2515             DetailDebugPrint("[GestureRecognize][F] 1 !\n");
2516             goto flush_or_drop;
2517         }
2518         else if (!g_pGesture->num_pressed)
2519         {
2520             DetailDebugPrint("[GestureRecognize][F] 2 !\n");
2521             goto flush_or_drop;
2522         }
2523     }
2524
2525     if (g_pGesture->recognized_gesture)
2526     {
2527         if (g_pGesture->ehtype == KEEP_EVENTS)
2528         {
2529             DetailDebugPrint("[GestureRecognize] Keep Event !\n");
2530             GestureEventsDrop();
2531         }
2532         g_pGesture->ehtype = IGNORE_EVENTS;
2533     }
2534     return;
2535
2536 flush_or_drop:
2537
2538     DetailDebugPrint("[GestureRecognize] GestureFlushOrDrop() !\n");
2539
2540     if (ERROR_INVALPTR == GestureFlushOrDrop())
2541     {
2542         GestureControl(g_pGesture->this_device, DEVICE_OFF);
2543     }
2544 }
2545
2546 ErrorStatus GestureFlushOrDrop(void)
2547 {
2548     ErrorStatus err;
2549
2550     if (g_pGesture->recognized_gesture)
2551     {
2552         g_pGesture->ehtype = IGNORE_EVENTS;
2553         GestureEventsDrop();
2554         DetailDebugPrint("[GestureFlushOrDrop][Drop] IGNORE_EVENTS\n");
2555     }
2556     else
2557     {
2558         g_pGesture->ehtype = PROPAGATE_EVENTS;
2559
2560         err = GestureEventsFlush();
2561
2562         if (ERROR_NONE != err)
2563         {
2564             return err;
2565         }
2566
2567         DetailDebugPrint("[GestureFlushOrDrop][Flush] PROPAGATE_EVENTS\n");
2568         DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask);
2569         DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->GESTURE_WATCH_FILTER_MASK_ALL = 0x%x\n", GESTURE_WATCH_FILTER_MASK_ALL);
2570         DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture);
2571     }
2572
2573     err = GestureRegionsReinit();
2574
2575     if (ERROR_NONE != err)
2576     {
2577         return err;
2578     }
2579
2580     g_pGesture->pTempWin = NULL;
2581     g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0;
2582     g_pGesture->event_sum[0] = 0;
2583
2584     return ERROR_NONE;
2585 }
2586
2587 void
2588 GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2589 {
2590     int i;
2591     int idx;
2592
2593 #ifdef __DEBUG_EVENT_HANDLER__
2594     DetailDebugPrint("[GestureHandleMTSyncEvent] (%d:%d) time:%d cur:%d\n",
2595             ev->any_event.deviceid, ev->any_event.sync, (int)ev->any.time, (int)GetTimeInMillis());
2596 #endif
2597
2598     if (!g_pGesture->is_active)
2599     {
2600         g_pGesture->ehtype = PROPAGATE_EVENTS;
2601         DetailDebugPrint("[GestureHandleMTSyncEvent] PROPAGATE_EVENT\n");
2602         return;
2603     }
2604
2605     if (MTOUCH_FRAME_SYNC_BEGIN == ev->any_event.sync)
2606     {
2607         DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_BEGIN\n");
2608         g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_BEGIN;
2609         g_pGesture->ehtype = KEEP_EVENTS;
2610         g_pGesture->filter_mask = 0;
2611         g_pGesture->recognized_gesture = 0;
2612         g_pGesture->hold_detector_activate = 1;
2613         g_pGesture->num_pressed = 0;
2614         g_pGesture->has_hold_grabmask = 0;
2615         g_pGesture->mtsync_total_count = 0;
2616
2617         for (i=0; i < g_pGesture->num_mt_devices; i++)
2618         {
2619             g_pGesture->fingers[i].ptime = 0;
2620             g_pGesture->max_mt_tmajor[i] = 0;
2621         }
2622     }
2623     else if (MTOUCH_FRAME_SYNC_END == ev->any_event.sync)
2624     {
2625         DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_END\n");
2626         g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_END;
2627         g_pGesture->ehtype = PROPAGATE_EVENTS;
2628         g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
2629         g_pGesture->pTempWin = NULL;
2630         g_pGesture->num_pressed = 0;
2631         g_pGesture->hold_detected = FALSE;
2632     }
2633     else if (MTOUCH_FRAME_SYNC_UPDATE == ev->any_event.sync)
2634     {
2635         g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_UPDATE;
2636         g_pGesture->mtsync_total_count++;
2637
2638         DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_Update. mt_total_sync=%d\n", g_pGesture->mtsync_total_count);
2639
2640         if ((g_pGesture->inc_num_pressed < 2) && (g_pGesture->filter_mask != GESTURE_WATCH_FILTER_MASK_ALL))
2641         {
2642             if (g_pGesture->num_tap_repeated == 1 || g_pGesture->num_tap_repeated == 2)
2643             {
2644                 if (g_pGesture->mtsync_total_count >= 6)
2645                 {
2646                     DetailDebugPrint("[GestureHandleMTSyncEvent] Moving Limit first tap repeated. tap_repeated: %d, mtsync_total_count: %d\n",
2647                             g_pGesture->num_tap_repeated, g_pGesture->mtsync_total_count);
2648                     g_pGesture->filter_mask |= WTapFilterMask;
2649                     g_pGesture->filter_mask |= WHoldFilterMask;
2650                                         LOGI("[GroupTap][GroupHold] Motions are more than 6 between 1st finger and 2nd finger.\n");
2651                 }
2652             }
2653
2654             if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
2655             {
2656                 DetailDebugPrint("[GestureHandleMTSyncEvent] Gesture filter mask all. GestureFlushOrDrop() !\n");
2657
2658                 if (ERROR_INVALPTR == GestureFlushOrDrop())
2659                 {
2660                     GestureControl(g_pGesture->this_device, DEVICE_OFF);
2661                 }
2662             }
2663         }
2664     }
2665 }
2666
2667
2668 void GestureEmulateHWKey(DeviceIntPtr dev, int keycode)
2669 {
2670     if (dev)
2671     {
2672         DetailDebugPrint("[GestureEmulateHWKey] keycode=%d\n", keycode);
2673         xf86PostKeyboardEvent(dev, keycode, 1);
2674         xf86PostKeyboardEvent(dev, keycode, 0);
2675     }
2676 }
2677
2678 void
2679 GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2680 {
2681 #ifdef __DEBUG_EVENT_HANDLER__
2682     DetailDebugPrint("[GestureHandleButtonPressEvent] devid=%d time:%d cur:%d (%d, %d)\n", device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y);
2683 #endif//__DEBUG_EVENT_HANDLER__
2684
2685     switch (g_pGesture->ehtype)
2686     {
2687         case KEEP_EVENTS:
2688             DetailDebugPrint("[GestureHandleButtonPressEvent] KEEP_EVENT\n");
2689
2690             if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device))
2691             {
2692                 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2693                 return;
2694             }
2695
2696             if (g_pGesture->num_mt_devices)
2697             {
2698                 GestureRecognize(ET_ButtonPress, ev, device);
2699             }
2700             else
2701             {
2702                 device->public.processInputProc(ev, device);
2703             }
2704
2705             GestureHoldDetector(ET_ButtonPress, ev, device);
2706             break;
2707
2708         case PROPAGATE_EVENTS:
2709             DetailDebugPrint("[GestureHandleButtonPressEvent] PROPAGATE_EVENT\n");
2710
2711             device->public.processInputProc(ev, device);
2712             GestureHoldDetector(ET_ButtonPress, ev, device);
2713             break;
2714
2715         case IGNORE_EVENTS:
2716             DetailDebugPrint("[GestureHandleButtonPressEvent] IGNORE_EVENTS\n");
2717
2718             GestureRecognize(ET_ButtonPress, ev, device);
2719             break;
2720
2721         default:
2722             break;
2723     }
2724 }
2725
2726 void
2727 GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2728 {
2729 #ifdef __DEBUG_EVENT_MOTION_HANDLER__
2730     DetailDebugPrint("[GestureHandleMotionEvent] devid=%d time:%d cur:%d (%d, %d)\n", device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y);
2731 #endif
2732
2733     switch (g_pGesture->ehtype)
2734     {
2735         case KEEP_EVENTS:
2736             if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device))
2737             {
2738                 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2739                 return;
2740             }
2741
2742             if (g_pGesture->num_mt_devices)
2743             {
2744                 GestureRecognize(ET_Motion, ev, device);
2745             }
2746             else
2747             {
2748                 device->public.processInputProc(ev, device);
2749             }
2750
2751             GestureHoldDetector(ET_Motion, ev, device);
2752             break;
2753
2754         case PROPAGATE_EVENTS:
2755             device->public.processInputProc(ev, device);
2756             GestureHoldDetector(ET_Motion, ev, device);
2757             break;
2758
2759         case IGNORE_EVENTS:
2760             GestureRecognize(ET_Motion, ev, device);
2761             break;
2762
2763         default:
2764             break;
2765     }
2766
2767 }
2768
2769 void
2770 GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2771 {
2772 #ifdef __DEBUG_EVENT_HANDLER__
2773     DetailDebugPrint("[GestureHandleButtonReleaseEvent] devid=%d time:%d cur:%d (%d, %d)\n", device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y);
2774 #endif
2775
2776     switch (g_pGesture->ehtype)
2777     {
2778         case KEEP_EVENTS:
2779             DetailDebugPrint("[GestureHandleButtonPressEvent] KEEP_EVENT\n");
2780
2781             if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device))
2782             {
2783                 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2784                 return;
2785             }
2786
2787             if (g_pGesture->num_mt_devices)
2788             {
2789                 GestureRecognize(ET_ButtonRelease, ev, device);
2790             }
2791             else
2792             {
2793                 device->public.processInputProc(ev, device);
2794             }
2795
2796             GestureHoldDetector(ET_ButtonRelease, ev, device);
2797             break;
2798
2799         case PROPAGATE_EVENTS:
2800             DetailDebugPrint("[GestureHandleButtonPressEvent] PROPAGATE_EVENTS\n");
2801 #ifdef SUPPORT_ANR_WITH_INPUT_EVENT
2802                      if( IsMaster(device) && ev->any.type == ET_ButtonRelease )
2803                      {
2804                          if( g_pGesture->anr_window == NULL )
2805                          {
2806                              g_pGesture->anr_window = _GestureFindANRWindow(device);
2807                          }
2808                          Time current_time;
2809
2810                          // Send event to the e17 process.
2811                          current_time = GetTimeInMillis();
2812                          if( g_pGesture->anr_window != NULL )
2813                          {
2814                              // Check anr_window validation.
2815                              if( dixLookupWindow(&g_pGesture->anr_window, prop_anr_event_window_xid, serverClient, DixSetPropAccess) != BadWindow )
2816                              {
2817                                  if( serverClient->devPrivates != NULL )
2818                                      dixChangeWindowProperty (serverClient, g_pGesture->anr_window, prop_anr_in_input_event,
2819                                                                                XA_CARDINAL, 32, PropModeReplace, 1, &current_time, TRUE);
2820                              }
2821                              else
2822                              {
2823                                  prop_anr_event_window_xid = 0;
2824                                  g_pGesture->anr_window = NULL;
2825                              }
2826                              DetailDebugPrint("Release TOUCH!! devid=%d time:%d cur: %d\n", device->id, ev->any.time, GetTimeInMillis());
2827                          }
2828                      }
2829 #endif
2830             device->public.processInputProc(ev, device);
2831             GestureHoldDetector(ET_ButtonRelease, ev, device);
2832 #if 0
2833             GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down);
2834             GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up);
2835 #endif
2836             break;
2837
2838         case IGNORE_EVENTS:
2839             DetailDebugPrint("[GestureHandleButtonPressEvent] IGNORE_EVENTS\n");
2840             GestureRecognize(ET_ButtonRelease, ev, device);
2841             break;
2842
2843         default:
2844             break;
2845     }
2846 }
2847
2848 void
2849 GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2850 {
2851     if ((ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0))
2852     {
2853         g_pGesture->power_pressed = 2;
2854         g_pGesture->power_device = device;
2855
2856         DetailDebugPrint("[GestureHandleKeyPressEvent] power key pressed devid: %d, hwkey_id: %d\n", device->id, g_pGesture->hwkey_id);
2857         DetailDebugPrint("[GestureHandleKeyPressEvent] power_pressed: %d\n", g_pGesture->power_pressed);
2858     }
2859     device->public.processInputProc(ev, device);
2860 }
2861
2862 void
2863 GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2864 {
2865     if ((ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0))
2866     {
2867         g_pGesture->power_pressed = 1;
2868         g_pGesture->power_device = device;
2869
2870         DetailDebugPrint("[GestureHandleKeyReleaseEvent] power key released devid: %d, hwkey_id: %d\n", device->id, g_pGesture->hwkey_id);
2871         DetailDebugPrint("[GestureHandleKeyReleaseEvent] power_pressed: %d\n", g_pGesture->power_pressed);
2872     }
2873     device->public.processInputProc(ev, device);
2874 }
2875
2876 static void
2877 GestureHandleClientState (CallbackListPtr *list, pointer closure, pointer calldata)
2878 {
2879     NewClientInfoRec *clientinfo = (NewClientInfoRec*)calldata;
2880     ClientPtr client = clientinfo->client;
2881
2882     if (client->clientState != ClientStateGone)
2883     {
2884         return;
2885     }
2886
2887     if (!g_pGesture->factory_cmdname)
2888     {
2889         return;
2890     }
2891
2892     if (strncmp(client->clientIds->cmdname, g_pGesture->factory_cmdname, strlen(g_pGesture->factory_cmdname)))
2893     {
2894         return;
2895     }
2896
2897     if (g_pGesture->is_active == 0)
2898     {
2899         int prop_val = 1;
2900         int rc = XIChangeDeviceProperty(g_pGesture->this_device, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &prop_val, FALSE);
2901
2902         ErrorF("[GestureHandleClientState] %s is exited unintentionally\n", g_pGesture->factory_cmdname);
2903
2904         if (rc != Success)
2905         {
2906             ErrorF("[GestureHandleClientState] Failed to Gesture Enable\n");
2907             return;
2908         }
2909     }
2910 }
2911
2912 static ErrorStatus
2913 GestureEnableEventHandler(InputInfoPtr pInfo)
2914 {
2915     Bool res;
2916     GestureDevicePtr pGesture = pInfo->private;
2917
2918     res = GestureInstallResourceStateHooks();
2919
2920     if (!res)
2921     {
2922         ErrorF("[GestureEnableEventHandler] Failed on GestureInstallResourceStateHooks() !\n");
2923         return ERROR_ABNORMAL;
2924     }
2925
2926     res = GestureSetMaxNumberOfFingers((int)MAX_MT_DEVICES);
2927
2928     if (!res)
2929     {
2930         ErrorF("[GestureEnableEventHandler] Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)MAX_MT_DEVICES);
2931         goto failed;
2932     }
2933
2934     res = GestureRegisterCallbacks(GestureCbEventsGrabbed, GestureCbEventsSelected);
2935
2936     if (!res)
2937     {
2938         ErrorF("[GestureEnableEventHandler] Failed to register callbacks for GestureEventsGrabbed(), GestureEventsSelected() !\n");
2939         goto failed;
2940     }
2941
2942     pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 5000, GestureTimerHandler, pInfo);
2943
2944     if (!pGesture->device_setting_timer)
2945     {
2946         ErrorF("[GestureEnableEventHandler] Failed to set time for detecting devices !\n");
2947         goto failed;
2948     }
2949
2950     return ERROR_NONE;
2951
2952 failed:
2953     GestureUninstallResourceStateHooks();
2954     GestureUnsetMaxNumberOfFingers();
2955
2956     return ERROR_ABNORMAL;
2957 }
2958
2959 static ErrorStatus
2960 GestureDisableEventHandler(void)
2961 {
2962     ErrorStatus err = ERROR_NONE;
2963
2964     mieqSetHandler(ET_ButtonPress, NULL);
2965     mieqSetHandler(ET_ButtonRelease, NULL);
2966     mieqSetHandler(ET_Motion, NULL);
2967     mieqSetHandler(ET_KeyPress, NULL);
2968     mieqSetHandler(ET_KeyRelease, NULL);
2969     mieqSetHandler(ET_MTSync, NULL);
2970
2971     err = GestureFiniEQ();
2972
2973     if (ERROR_INVALPTR == err)
2974     {
2975         ErrorF("[GestureDisableEventHandler] EQ is invalid or was freed already !\n");
2976     }
2977
2978     GestureRegisterCallbacks(NULL, NULL);
2979     GestureUninstallResourceStateHooks();
2980
2981     return err;
2982 }
2983
2984 static CARD32
2985 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2986 {
2987     InputInfoPtr pInfo = (InputInfoPtr)arg;
2988     GestureDevicePtr pGesture;
2989     int idx;
2990     DeviceIntPtr dev;
2991
2992     if (!pInfo)
2993     {
2994         ErrorF("[GestureTimerHandler][%s] pInfo is NULL !\n");
2995         goto failed;
2996     }
2997
2998     pGesture = pInfo->private;
2999
3000     idx = 0;
3001     for (dev = inputInfo.pointer; dev; dev = dev->next)
3002     {
3003         if (IsMaster(dev) && IsPointerDevice(dev))
3004         {
3005             pGesture->master_pointer = dev;
3006             ErrorF("[GestureTimerHandler][id:%d] Master Pointer=%s\n", dev->id, pGesture->master_pointer->name);
3007             continue;
3008         }
3009
3010         if (IsXTestDevice(dev, NULL) && IsPointerDevice(dev))
3011         {
3012             pGesture->xtest_pointer = dev;
3013             ErrorF("[GestureTimerHandler][id:%d] XTest Pointer=%s\n", dev->id, pGesture->xtest_pointer->name);
3014             continue;
3015         }
3016
3017         if (IsPointerDevice(dev))
3018         {
3019             if (idx >= MAX_MT_DEVICES)
3020             {
3021                 ErrorF("[GestureTimerHandler] Number of mt device is over MAX_MT_DEVICES(%d) !\n", MAX_MT_DEVICES);
3022                 continue;
3023             }
3024             pGesture->mt_devices[idx] = dev;
3025             ErrorF("[GestureTimerHandler][id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name);
3026             GesturePalmGetAbsAxisInfo(dev);
3027             idx++;
3028         }
3029     }
3030
3031     for (dev = inputInfo.keyboard ; dev; dev = dev->next)
3032     {
3033         if (g_pGesture->hwkey_name && !strncmp(dev->name, g_pGesture->hwkey_name, strlen(dev->name)))
3034         {
3035             g_pGesture->hwkey_id = dev->id;
3036             g_pGesture->hwkey_dev = dev;
3037
3038             ErrorF("[GestureTimerHandler] hwkey_name has been found. hwkey_id=%d (hwkey_dev->name:%s)\n", g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
3039             break;
3040         }
3041         else if (!strcasestr(dev->name, "keyboard") && strcasestr(dev->name, "key") && !IsXTestDevice(dev, NULL) && !IsMaster(dev))
3042         {
3043             g_pGesture->hwkey_id = dev->id;
3044             g_pGesture->hwkey_dev = dev;
3045
3046             ErrorF("[GestureTimerHandler] hwkey has been found. hwkey_id=%d (hwkey_dev->name:%s)\n", g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
3047             break;
3048         }
3049     }
3050
3051     if (!g_pGesture->hwkey_id)
3052     {
3053         g_pGesture->hwkey_id = inputInfo.keyboard->id;
3054         g_pGesture->hwkey_dev = inputInfo.keyboard;
3055
3056         ErrorF("[GestureTimerHandler] No hwkey has been found. Back key will go through VCK. hwkey_id=%d (hwkey_dev->name:%s)\n",
3057                 g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
3058     }
3059
3060     if (!pGesture->master_pointer || !pGesture->xtest_pointer)
3061     {
3062         ErrorF("[GestureTimerHandler] Failed to get info of master pointer or XTest pointer !\n");
3063         pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
3064         pGesture->num_mt_devices = 0;
3065
3066         return 0;
3067     }
3068
3069     TimerCancel(pGesture->device_setting_timer);
3070     pGesture->device_setting_timer = NULL;
3071     pGesture->num_mt_devices = idx;
3072
3073     if (!pGesture->num_mt_devices)
3074     {
3075         ErrorF("[GestureTimerHandler] Failed to mt device information !\n");
3076         TimerCancel(pGesture->device_setting_timer);
3077         pGesture->device_setting_timer = NULL;
3078         pGesture->num_mt_devices = 0;
3079         pGesture->first_fingerid = -1;
3080         return 0;
3081     }
3082
3083     pGesture->first_fingerid = pGesture->mt_devices[0]->id;
3084     memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices);
3085     pGesture->pRootWin = RootWindow(pGesture->master_pointer);
3086
3087     if (g_pGesture->palm_misc.enabled)
3088     {
3089         GesturePalmGetScreenInfo();
3090     }
3091
3092     g_pGesture->pTempWin = NULL;
3093     g_pGesture->inc_num_pressed = 0;
3094
3095     if (ERROR_NONE != GestureRegionsInit() || ERROR_NONE != GestureInitEQ())
3096     {
3097         goto failed;
3098     }
3099
3100     mieqSetHandler(ET_ButtonPress, GestureHandleButtonPressEvent);
3101     mieqSetHandler(ET_ButtonRelease, GestureHandleButtonReleaseEvent);
3102     mieqSetHandler(ET_Motion, GestureHandleMotionEvent);
3103     mieqSetHandler(ET_KeyPress, GestureHandleKeyPressEvent);
3104     mieqSetHandler(ET_KeyRelease, GestureHandleKeyReleaseEvent);
3105
3106     //if ( pGesture->is_active)
3107     mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
3108
3109     return 0;
3110
3111 failed:
3112     GestureUninstallResourceStateHooks();
3113     GestureUnsetMaxNumberOfFingers();
3114
3115     return 0;
3116 }
3117
3118 BOOL
3119 IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
3120 {
3121     if (IsMaster(dev))
3122     {
3123         return FALSE;
3124     }
3125
3126     if (master)
3127     {
3128         return (dev->xtest_master_id == master->id);
3129     }
3130
3131     return (dev->xtest_master_id != 0);
3132 }
3133
3134 void
3135 GestureEnable(int enable, Bool prop, DeviceIntPtr dev)
3136 {
3137     if ((!enable) && (g_pGesture->is_active))
3138     {
3139         g_pGesture->ehtype = PROPAGATE_EVENTS;
3140         mieqSetHandler(ET_MTSync, NULL);
3141         g_pGesture->is_active = 0;
3142         ErrorF("[GestureEnable] Disabled !\n");
3143         int res = AddCallback (&ClientStateCallback, GestureHandleClientState, NULL);
3144
3145         if (!res)
3146         {
3147             ErrorF("[GestureEnable] Failed to add callback for client state\n");
3148             return;
3149         }
3150     }
3151
3152     else if ((enable) && (!g_pGesture->is_active))
3153     {
3154         g_pGesture->ehtype = KEEP_EVENTS;
3155         mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
3156         g_pGesture->is_active = 1;
3157         ErrorF("[GestureEnable] Enabled !\n");
3158
3159         DeleteCallback (&ClientStateCallback, GestureHandleClientState, NULL);
3160     }
3161
3162     if (!prop)
3163     {
3164         XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
3165     }
3166 }
3167
3168 ErrorStatus
3169 GestureRegionsInit(void)
3170 {
3171     int i;
3172
3173     if (!g_pGesture)
3174     {
3175         return ERROR_INVALPTR;
3176     }
3177
3178     pixman_region_init(&g_pGesture->area);
3179
3180     for (i = 0; i < MAX_MT_DEVICES; i++)
3181     {
3182         pixman_region_init_rect(&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
3183     }
3184
3185     return ERROR_NONE;
3186 }
3187
3188 ErrorStatus
3189 GestureRegionsReinit(void)
3190 {
3191     if (!g_pGesture)
3192     {
3193         ErrorF("[GestureRegionsReinit] Invalid pointer access !\n");
3194         return ERROR_INVALPTR;
3195     }
3196
3197     pixman_region_init(&g_pGesture->area);
3198
3199     return ERROR_NONE;
3200 }
3201
3202 ErrorStatus
3203 GestureInitEQ(void)
3204 {
3205     int i;
3206     IEventPtr tmpEQ;
3207
3208     tmpEQ = (IEventRec *)calloc(GESTURE_EQ_SIZE, sizeof(IEventRec));
3209
3210     if (!tmpEQ)
3211     {
3212         ErrorF("[GestureInitEQ] Failed to allocate memory for EQ !\n");
3213         return ERROR_ALLOCFAIL;
3214     }
3215
3216     for (i = 0; i < GESTURE_EQ_SIZE; i++)
3217     {
3218         tmpEQ[i].event = (InternalEvent *)malloc(sizeof(InternalEvent));
3219         if (!tmpEQ[i].event)
3220         {
3221             ErrorF("[GestureInitEQ] Failed to allocation memory for each event buffer in EQ !\n");
3222             i--;
3223             while(i >= 0 && tmpEQ[i].event)
3224             {
3225                 free(tmpEQ[i].event);
3226                 tmpEQ[i].event = NULL;
3227             }
3228             free (tmpEQ);
3229             tmpEQ = NULL;
3230             return ERROR_ALLOCFAIL;
3231         }
3232     }
3233
3234     g_pGesture->EQ = tmpEQ;
3235     g_pGesture->headEQ = g_pGesture->tailEQ = 0;
3236
3237     return ERROR_NONE;
3238 }
3239
3240 ErrorStatus
3241 GestureFiniEQ(void)
3242 {
3243     int i;
3244
3245     if (!g_pGesture || !g_pGesture->EQ)
3246     {
3247         return ERROR_INVALPTR;
3248     }
3249
3250     for (i = 0; i < GESTURE_EQ_SIZE; i++)
3251     {
3252         if (g_pGesture->EQ[i].event)
3253         {
3254             free(g_pGesture->EQ[i].event);
3255             g_pGesture->EQ[i].event = NULL;
3256         }
3257     }
3258
3259     free(g_pGesture->EQ);
3260     g_pGesture->EQ = NULL;
3261
3262     return ERROR_NONE;
3263 }
3264
3265 ErrorStatus
3266 GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
3267 {
3268     int tail;
3269
3270     if (!g_pGesture || !g_pGesture->EQ)
3271     {
3272         ErrorF("[GestureEnqueueEvent] Invalid pointer access !\n");
3273         return ERROR_INVALPTR;
3274     }
3275
3276     tail = g_pGesture->tailEQ;
3277
3278     if (tail >= GESTURE_EQ_SIZE)
3279     {
3280         ErrorF("[GestureEnqueueEvent] Gesture EQ is full !\n");
3281         printk("[GestureEnqueueEvent] Gesture EQ is full...Force Gesture Flush !\n");
3282         GestureEventsFlush();
3283         return ERROR_EQFULL;
3284     }
3285
3286     switch (ev->any.type)
3287     {
3288         case ET_ButtonPress:
3289             DetailDebugPrint("[GestureEnqueueEvent] ET_ButtonPress (id:%d)\n", device->id);
3290             break;
3291
3292         case ET_ButtonRelease:
3293             DetailDebugPrint("[GestureEnqueueEvent] ET_ButtonRelease (id:%d)\n", device->id);
3294             break;
3295
3296         case ET_Motion:
3297             DetailDebugPrint("[GestureEnqueueEvent] ET_Motion (id:%d)\n", device->id);
3298             break;
3299     }
3300
3301     g_pGesture->EQ[tail].device = device;
3302     g_pGesture->EQ[tail].screen_num = screen_num;
3303     memcpy(g_pGesture->EQ[tail].event, ev, sizeof(InternalEvent));//need to be optimized
3304     g_pGesture->tailEQ++;
3305
3306     return ERROR_NONE;
3307 }
3308
3309 ErrorStatus
3310 GestureEventsFlush(void)
3311 {
3312     int i;
3313     DeviceIntPtr device;
3314
3315     if (!g_pGesture->EQ)
3316     {
3317         ErrorF("[GestureEventsFlush] Invalid pointer access !\n");
3318         return ERROR_INVALPTR;
3319     }
3320
3321     DetailDebugPrint("[GestureEventsFlush]\n");
3322
3323     for (i = g_pGesture->headEQ; i < g_pGesture->tailEQ; i++)
3324     {
3325         device = g_pGesture->EQ[i].device;
3326         device->public.processInputProc(g_pGesture->EQ[i].event, device);
3327     }
3328
3329     for (i = 0; i < MAX_MT_DEVICES; i++)
3330     {
3331         g_pGesture->event_sum[i] = 0;
3332     }
3333
3334     g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
3335
3336     return ERROR_NONE;
3337 }
3338
3339 void
3340 GestureEventsDrop(void)
3341 {
3342     DetailDebugPrint("[GestureEventsDrop]\n");
3343     g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
3344 }
3345
3346 #ifdef HAVE_PROPERTIES
3347 static void
3348 GestureInitProperty(DeviceIntPtr dev)
3349 {
3350     int rc;
3351
3352 #ifdef SUPPORT_ANR_WITH_INPUT_EVENT
3353     prop_anr_in_input_event = MakeAtom(CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT, strlen(CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT),  TRUE);
3354     prop_anr_event_window = MakeAtom(ANR_EVENT_WINDOW, strlen(ANR_EVENT_WINDOW), TRUE);
3355 #endif
3356
3357     prop_gesture_recognizer_onoff = MakeAtom(GESTURE_RECOGNIZER_ONOFF, strlen(GESTURE_RECOGNIZER_ONOFF),  TRUE);
3358     rc = XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
3359
3360     if (rc != Success)
3361     {
3362         return;
3363     }
3364
3365     XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE);
3366 }
3367
3368 static int
3369 GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
3370         BOOL checkonly)
3371 {
3372     if (prop_gesture_recognizer_onoff == atom)
3373     {
3374         int data;
3375         if (val->format != 32 || val->type != XA_INTEGER || val->size != 1)
3376             return BadMatch;
3377
3378         if (!checkonly)
3379         {
3380             data = *((int *)val->data);
3381             GestureEnable(data, TRUE, dev);
3382         }
3383     }
3384     return Success;
3385 }
3386 #endif//HAVE_PROPERTIES
3387
3388 static int
3389 GestureInit(DeviceIntPtr device)
3390 {
3391 #ifdef HAVE_PROPERTIES
3392     GestureInitProperty(device);
3393     XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL);
3394 #endif
3395     //GestureEnable(1, FALSE, g_pGesture->this_device);
3396     return Success;
3397 }
3398
3399 static void
3400 GestureFini(DeviceIntPtr device)
3401 {
3402     XIRegisterPropertyHandler(device, NULL, NULL, NULL);
3403 }
3404
3405 static pointer
3406 GesturePlug(pointer module, pointer options, int *errmaj, int *errmin)
3407 {
3408     xf86AddInputDriver(&GESTURE, module, 0);
3409     return module;
3410 }
3411
3412 static void
3413 GestureUnplug(pointer p)
3414 {
3415 }
3416
3417 static int
3418 GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
3419 {
3420     int rc = BadAlloc;
3421     GestureDevicePtr pGesture;
3422
3423     pGesture = calloc(1, sizeof(GestureDeviceRec));
3424
3425     if (!pGesture)
3426     {
3427         pInfo->private = NULL;
3428         //xf86DeleteInput(pInfo, 0);
3429         goto error;
3430     }
3431
3432     g_pGesture = pGesture;
3433
3434     pInfo->private = pGesture;
3435     pInfo->flags = 0;
3436     pInfo->read_input = GestureReadInput; /* new data avl */
3437     pInfo->switch_mode = NULL; /* toggle absolute/relative mode */
3438     pInfo->device_control = GestureControl; /* enable/disable dev */
3439
3440     /* process driver specific options */
3441     pGesture->device = xf86SetStrOption(pInfo->options, "Device", "/dev/null");
3442     pGesture->is_active = xf86SetIntOption(pInfo->options, "Activate", 0);
3443     pGesture->gestureWin = None;
3444     pGesture->lastSelectedWin = None;
3445     pGesture->power_pressed = 1;
3446     pGesture->hwkey_id = 0;
3447     pGesture->hwkey_dev = NULL;
3448     pGesture->num_tap_repeated = 0;
3449     pGesture->mtsync_total_count = 0;
3450     pGesture->hwkey_name = xf86SetStrOption(pInfo->options, "BackHWKeyName", NULL);
3451     pGesture->screen_width = xf86SetIntOption(pInfo->options,"ScreenWidth", 0);
3452     pGesture->screen_height = xf86SetIntOption(pInfo->options,"ScreenHeight", 0);
3453     pGesture->hwkeycode_flick_down = xf86SetIntOption(pInfo->options, "FlickDownKeycode", 0);
3454     pGesture->hwkeycode_flick_up = xf86SetIntOption(pInfo->options, "FlickUpKeycode", 0);
3455     pGesture->flick_press_area = xf86SetIntOption(pInfo->options, "FlickPressArea", 0);
3456     pGesture->flick_press_area_left = xf86SetIntOption(pInfo->options, "FlickPressArea_LEFT", 0);
3457     pGesture->flick_press_area_left_right = xf86SetIntOption(pInfo->options, "FlickPressArea_LEFT_RIGHT", 0);
3458     pGesture->flick_minimum_height = xf86SetIntOption(pInfo->options, "FlickMinimumHeight", 0);
3459     pGesture->shutdown_keycode = xf86SetIntOption(pInfo->options, "ShutdownKeycode", 0);
3460     pGesture->singletap_threshold= xf86SetIntOption(pInfo->options, "SingleTapThresHold", 0);
3461     pGesture->doubletap_threshold= xf86SetIntOption(pInfo->options, "DoubleTapThresHold", 0);
3462     pGesture->tripletap_threshold= xf86SetIntOption(pInfo->options, "TripleTapThresHold", 0);
3463     pGesture->hold_area_threshold = xf86SetRealOption(pInfo->options, "HoldAreaThresHold", 0);
3464     pGesture->hold_move_threshold = xf86SetIntOption(pInfo->options, "HoldMoveThresHold", 0);
3465     pGesture->hold_time_threshold = xf86SetIntOption(pInfo->options, "HoldTimeThresHold", 0);
3466     pGesture->palm_flick_time_threshold = xf86SetIntOption(pInfo->options, "PalmFlickTimeThresHold", 0);
3467     pGesture->palm_flick_max_tmajor_threshold = xf86SetIntOption(pInfo->options, "PalmFlickMaxTouchMajorThresHold", 0);
3468     pGesture->palm_flick_min_tmajor_threshold = xf86SetIntOption(pInfo->options, "PalmFlickMinTouchMajorThresHold", 0);
3469     pGesture->activate_flick_down = xf86SetIntOption(pInfo->options, "ActivateFlickDown", 0);
3470     pGesture->activate_flick_up = xf86SetIntOption(pInfo->options, "ActivateFlickUp", 0);
3471     pGesture->activate_flick_right = xf86SetIntOption(pInfo->options, "ActivateFlickRight", 0);
3472     pGesture->factory_cmdname = xf86SetStrOption(pInfo->options, "FactoryCmdName", NULL);
3473
3474     ErrorF("[X11][%s] ###############################################################\n", __FUNCTION__);
3475     ErrorF("[X11][%s] screen_width=%d, screen_height=%d\n", __FUNCTION__,
3476             pGesture->screen_width, pGesture->screen_height);
3477     ErrorF("[X11][%s] FlickDownKeycode=%d, FlickUpKeycode=%d\n", __FUNCTION__,
3478             pGesture->hwkeycode_flick_down, pGesture->hwkeycode_flick_up);
3479     ErrorF("[X11][%s] flick_press_area=%d, flick_press_area_left: %d, flick_press_area_left_right: %d, flick_minimum_height=%d\n", __FUNCTION__,
3480             pGesture->flick_press_area, pGesture->flick_press_area_left, pGesture->flick_press_area_left_right, pGesture->flick_minimum_height);
3481     ErrorF("[X11][%s] ShutdownKeycode=%d\n", __FUNCTION__, pGesture->shutdown_keycode);
3482     ErrorF("[X11][%s] singletap_threshold=%d, doubletap_threshold=%d\n", __FUNCTION__, pGesture->singletap_threshold, pGesture->doubletap_threshold);
3483     ErrorF("[X11][%s] hold_area_threshold: %f, hold_move_threshold: %d, hold_time_threshold: %d\n", __FUNCTION__,
3484             pGesture->hold_area_threshold, pGesture->hold_move_threshold, pGesture->hold_time_threshold);
3485     ErrorF("[X11][%s] palm_flick_time_threshold: %d, palm_flick_max_tmajor_threshold: %d, palm_flick_min_tmajor_threshold: %d\n", __FUNCTION__,
3486             pGesture->palm_flick_time_threshold, pGesture->palm_flick_max_tmajor_threshold, pGesture->palm_flick_min_tmajor_threshold);
3487     ErrorF("[X11][%s] activate_flick_down=%d, activate_flick_up=%d, activate_flick_right=%d\n", __FUNCTION__,
3488             pGesture->activate_flick_down, pGesture->activate_flick_up, pGesture->activate_flick_right);
3489     ErrorF("[X11][%s] factory cmd name: %s\n", __FUNCTION__, pGesture->factory_cmdname);
3490     ErrorF("[X11][%s] ###############################################################\n", __FUNCTION__);
3491
3492     if (pGesture->hwkey_name)
3493     {
3494         ErrorF("[X11][%s] hwkey_name=%s\n", __FUNCTION__, pGesture->hwkey_name);
3495     }
3496
3497     pGesture->mtsync_status = MTOUCH_FRAME_SYNC_END;
3498     g_pGesture->grabMask = g_pGesture->eventMask = 0;
3499
3500     xf86Msg(X_INFO, "%s: Using device %s.\n", pInfo->name, pGesture->device);
3501
3502     /* process generic options */
3503     xf86CollectInputOptions(pInfo, NULL);
3504     xf86ProcessCommonOptions(pInfo, pInfo->options);
3505
3506     pInfo->fd = -1;
3507
3508     return Success;
3509
3510 error:
3511     if (pInfo->fd >= 0)
3512         close(pInfo->fd);
3513     return rc;
3514 }
3515
3516 static void
3517 GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
3518 {
3519     GestureDevicePtr pGesture = pInfo->private;
3520
3521     g_pGesture = pGesture = NULL;
3522     pInfo->private = NULL;
3523
3524     xf86DeleteInput(pInfo, 0);
3525 }
3526
3527 static int
3528 GestureControl(DeviceIntPtr device, int what)
3529 {
3530     InputInfoPtr  pInfo = device->public.devicePrivate;
3531     GestureDevicePtr pGesture = pInfo->private;
3532
3533     switch (what)
3534     {
3535         case DEVICE_INIT:
3536             GestureInit(device);
3537             break;
3538
3539             /* Switch device on.  Establish socket, start event delivery.  */
3540         case DEVICE_ON:
3541             xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
3542
3543             if (device->public.on)
3544                 break;
3545
3546             device->public.on = TRUE;
3547             pGesture->this_device = device;
3548             pGesture->num_mt_devices = 0;
3549             if (ERROR_ABNORMAL == GestureEnableEventHandler(pInfo))
3550                 goto device_off;
3551             break;
3552
3553         case DEVICE_OFF:
3554 device_off:
3555             GestureDisableEventHandler();
3556             GestureFini(device);
3557             pGesture->this_device = NULL;
3558             xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
3559
3560             if (!device->public.on)
3561                 break;
3562
3563             pInfo->fd = -1;
3564             device->public.on = FALSE;
3565             break;
3566
3567         case DEVICE_CLOSE:
3568             /* free what we have to free */
3569             break;
3570     }
3571     return Success;
3572 }
3573
3574 static void
3575 GestureReadInput(InputInfoPtr pInfo)
3576 {
3577 }
3578
3579
3580