Initialize Tizen 2.3
[adaptation/xorg/driver/xserver-xorg-input-gesture.git] / mobile / 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 #include <stdio.h>
62 #include <sys/stat.h>
63 #include <sys/syscall.h>
64 #include <unistd.h>
65 #include <errno.h>
66 #include <sys/types.h>
67 #include <fcntl.h>
68 #include <xorg-server.h>
69 #include <xorgVersion.h>
70 #include <xf86Module.h>
71 #include <X11/Xatom.h>
72 #include "gesture.h"
73 #include <xorg/mi.h>
74 #include <xdbg.h>
75
76 #define MGEST   XDBG_M('G','E','S','T')
77
78 static void printk(const char* fmt, ...) __attribute__((format(printf, 1, 0)));
79 extern char *strcasestr(const char *s, const char *find);
80 extern ScreenPtr miPointerCurrentScreen(void);
81
82 //Basic functions
83 static int GesturePreInit(InputDriverPtr  drv, InputInfoPtr pInfo, int flags);
84 static void GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
85 static pointer GesturePlug(pointer module, pointer options, int *errmaj, int  *errmin);
86 static void GestureUnplug(pointer p);
87 static int GestureControl(DeviceIntPtr    device,int what);
88 static int GestureInit(DeviceIntPtr device);
89 static void GestureFini(DeviceIntPtr device);
90 static void GestureReadInput(InputInfoPtr pInfo);
91
92 //other initializers
93 ErrorStatus GestureRegionsInit(void);
94
95 //event queue handling functions
96 ErrorStatus GestureInitEQ(void);
97 ErrorStatus GestureFiniEQ(void);
98 ErrorStatus GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
99 ErrorStatus GestureEventsFlush(void);
100 void GestureEventsDrop(void);
101
102 //utility functions
103 ErrorStatus GestureRegionsReinit(void);
104 void GestureEnable(int enable, Bool prop, DeviceIntPtr dev);
105 static inline void GestureEnableDisable();
106 void GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent);
107 void GestureCbEventsSelected(Window win, Mask *pEventMask);
108 WindowPtr GestureGetEventsWindow(void);
109 static Bool GestureHasFingersEvents(int eventType);
110
111 //Enqueued event handlers and enabler/disabler
112 static ErrorStatus GestureEnableEventHandler(InputInfoPtr pInfo);
113 static ErrorStatus GestureDisableEventHandler(void);
114 static CARD32 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
115 static CARD32 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
116 static CARD32 GesturePalmEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
117 void GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
118 void GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
119 void GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
120 void GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
121 void GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
122
123 //Gesture recognizer helper
124 static Bool PointInBorderSize(WindowPtr pWin, int x, int y);
125 static WindowPtr GestureWindowOnXY(int x, int y);
126 Bool GestureHasFingerEventMask(int eventType, int num_finger);
127 #ifdef _F_SUPPORT_BEZEL_FLICK_
128 static int get_distance(int x1, int y1, int x2, int y2);
129 #endif
130 static double get_angle(int x1, int y1, int x2, int y2);
131
132 //Gesture recognizer and handlers
133 void GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
134 void GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx);
135 void GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
136 void GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
137 void GestureRecognize_GroupTapNHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
138 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
139 #ifdef _F_SUPPORT_BEZEL_FLICK_
140 int GestureBezelAngleRecognize(int type, int distance, double angle);
141 #endif
142 void GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction);
143 void GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy);
144 void GestureHandleGesture_PinchRotation(int num_of_fingers, double zoom, double angle, int distance, int cx, int cy, int kinds);
145 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds);
146 void GestureHandleGesture_TapNHold(int num_fingers, int cx, int cy, Time interval, Time holdtime, int kinds);
147 void GestureHandleGesture_Pan(int num_fingers, short int dx, short int dy, int direction, int distance, Time duration, int kinds);
148 static void GestureHoldDetector(int type, InternalEvent *ev, DeviceIntPtr device);
149 void GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device);
150 ErrorStatus GestureFlushOrDrop(void);
151
152 static int GesturePalmGetHorizIndexWithX(int x, int type);
153 static int GesturePalmGetVertiIndexWithY(int y, int type);
154 static void GesturePalmRecognize_Hold(int type, int idx, int timer_expired);
155 static void GesturePalmRecognize_FlickHorizen(int type, int idx);
156 static void GesturePalmRecognize_FlickVertical(int type,int idx);
157 static int GesturePalmGetScreenInfo();
158 static int GesturePalmGetAbsAxisInfo(DeviceIntPtr dev);
159 static void GesturePalmDataUpdate(int idx, int type, InternalEvent *ev, DeviceIntPtr device);
160 static void GesturePalmUpdateAreaInfo(int type, int idx);
161 void GesturePalmRecognize(int type, InternalEvent *ev, DeviceIntPtr device);
162
163 //#define __PALM_GESTURE_LOG__
164 //#define __PALM_DETAIL_LOG__
165 //#define __DETAIL_DEBUG__
166 //#define __BEZEL_DEBUG__
167 //#define __DEBUG_EVENT_HANDLER__
168
169 #ifdef HAVE_PROPERTIES
170 //function related property handling
171 static void GestureInitProperty(DeviceIntPtr dev);
172 static int GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkonly);
173 #endif
174
175 static Atom prop_gesture_recognizer_onoff = None;
176
177 GestureDevicePtr g_pGesture = NULL;
178 _X_EXPORT InputDriverRec GESTURE = {
179     1,
180     "gesture",
181     NULL,
182     GesturePreInit,
183     GestureUnInit,
184     NULL,
185     0
186 };
187
188 static XF86ModuleVersionInfo GestureVersionRec =
189 {
190     "gesture",
191     MODULEVENDORSTRING,
192     MODINFOSTRING1,
193     MODINFOSTRING2,
194     XORG_VERSION_CURRENT,
195     PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR,
196     PACKAGE_VERSION_PATCHLEVEL,
197     ABI_CLASS_XINPUT,
198     ABI_XINPUT_VERSION,
199     MOD_CLASS_XINPUT,
200     {0, 0, 0, 0}
201 };
202
203 _X_EXPORT XF86ModuleData gestureModuleData =
204 {
205     &GestureVersionRec,
206     &GesturePlug,
207     &GestureUnplug
208 };
209
210 static void
211 printk(const char* fmt, ...)
212 {
213         static FILE* fp = NULL;
214         static char init = 0;
215         va_list argptr;
216
217         if(!init && !fp)
218         {
219                 fp = fopen("/dev/kmsg", "wt");
220                 init = 1;
221         }
222
223         if(!fp) return;
224
225         va_start(argptr, fmt);
226         vfprintf(fp, fmt, argptr);
227         fflush(fp);
228         va_end(argptr);
229 }
230
231 static Bool
232 PointInBorderSize(WindowPtr pWin, int x, int y)
233 {
234     BoxRec box;
235     if( pixman_region_contains_point (&pWin->borderSize, x, y, &box) )
236         return TRUE;
237
238     return FALSE;
239 }
240
241 static WindowPtr
242 GestureWindowOnXY(int x, int y)
243 {
244     WindowPtr pWin;
245     BoxRec box;
246     SpritePtr pSprite;
247     DeviceIntPtr pDev = g_pGesture->master_pointer;
248
249     pSprite = pDev->spriteInfo->sprite;
250     pSprite->spriteTraceGood = 1;       /* root window still there */
251     pWin = RootWindow(pDev)->firstChild;
252     while (pWin)
253     {
254         if ((pWin->mapped) &&
255             (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
256             (x < pWin->drawable.x + (int)pWin->drawable.width +
257              wBorderWidth(pWin)) &&
258             (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
259             (y < pWin->drawable.y + (int)pWin->drawable.height +
260              wBorderWidth (pWin))
261             /* When a window is shaped, a further check
262              * is made to see if the point is inside
263              * borderSize
264              */
265             && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
266             && (!wInputShape(pWin) ||
267                 RegionContainsPoint(wInputShape(pWin),
268                                     x - pWin->drawable.x,
269                                     y - pWin->drawable.y, &box))
270 #ifdef ROOTLESS
271     /* In rootless mode windows may be offscreen, even when
272      * they're in X's stack. (E.g. if the native window system
273      * implements some form of virtual desktop system).
274      */
275                 && !pWin->rootlessUnhittable
276 #endif
277             )
278         {
279             if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
280             {
281                 pSprite->spriteTraceSize += 10;
282                 pSprite->spriteTrace = realloc(pSprite->spriteTrace,
283                                     pSprite->spriteTraceSize*sizeof(WindowPtr));
284             }
285             pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
286             pWin = pWin->firstChild;
287         }
288         else
289             pWin = pWin->nextSib;
290     }
291     return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
292 }
293
294 Bool
295 GestureHasFingerEventMask(int eventType, int num_finger)
296 {
297         Bool ret = FALSE;
298         Mask eventmask = (1L << eventType);
299
300         if( (g_pGesture->grabMask & eventmask) &&
301                 (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[num_finger].window != None) )
302         {
303 #ifdef __DETAIL_DEBUG__
304                 XDBG_DEBUG(MGEST, "TRUE !! Has grabMask\n");
305 #endif//__DETAIL_DEBUG__
306                 return TRUE;
307         }
308
309         if( g_pGesture->eventMask & eventmask )
310         {
311 #ifdef __DETAIL_DEBUG__
312                 XDBG_DEBUG(MGEST, "TRUE !! Has eventMask\n");
313 #endif//__DETAIL_DEBUG__
314                 return TRUE;
315         }
316
317 #ifdef __DETAIL_DEBUG__
318         XDBG_DEBUG(MGEST, "FALSE !! eventType=%d, num_finger=%d\n", eventType, num_finger);
319 #endif//__DETAIL_DEBUG__
320
321         return ret;
322 }
323
324 #ifdef _F_SUPPORT_BEZEL_FLICK_
325 static int
326 get_distance(int _x1, int _y1, int _x2, int _y2)
327 {
328         int xx, yy;
329         xx = ABS(_x2 - _x1);
330         yy = ABS(_y2 - _y1);
331
332         if(xx && yy)
333         {
334                 return (int)sqrt(pow(xx, 2) + pow(yy, 2));
335         }
336         else if(xx)
337         {
338                 return yy;
339         }
340         else if(yy)
341         {
342                 return xx;
343         }
344         else
345         {
346                 return 0;
347         }
348 }
349 #endif//_F_SUPPORT_BEZEL_FLICK_
350
351 static double
352 get_angle(int _x1, int _y1, int _x2, int _y2)
353 {
354    double a, xx, yy;
355    xx = fabs(_x2 - _x1);
356    yy = fabs(_y2 - _y1);
357
358    if (((int) xx) && ((int) yy))
359      {
360         a = atan(yy / xx);
361         if (_x1 < _x2)
362           {
363              if (_y1 < _y2)
364                {
365                   return (RAD_360DEG - a);
366                }
367              else
368                {
369                   return (a);
370                }
371           }
372         else
373           {
374              if (_y1 < _y2)
375                {
376                   return (RAD_180DEG + a);
377                }
378              else
379                {
380                   return (RAD_180DEG - a);
381                }
382           }
383      }
384
385    if (((int) xx))
386      {  /* Horizontal line */
387         if (_x2 < _x1)
388           {
389              return (RAD_180DEG);
390           }
391         else
392           {
393              return (0.0);
394           }
395      }
396
397    /* Vertical line */
398    if (_y2 < _y1)
399      {
400         return (RAD_90DEG);
401      }
402    else
403      {
404         return (RAD_270DEG);
405      }
406 }
407
408 void
409 GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction)
410 {
411         Window target_win;
412         WindowPtr target_pWin;
413         xGestureNotifyFlickEvent fev;
414
415 #ifdef __DETAIL_DEBUG__
416         XDBG_DEBUG(MGEST, "num_fingers=%d, distance=%d, duration=%d, direction=%d\n",
417                 num_of_fingers, distance, duration, direction);
418 #endif//__DETAIL_DEBUG__
419
420         if(num_of_fingers == 0)
421         {
422                 if(direction == FLICK_EASTWARD || direction == FLICK_WESTWARD)
423                         g_pGesture->recognized_palm |= PalmFlickHorizFilterMask;
424                 if(direction == FLICK_NORTHWARD || direction == FLICK_SOUTHWARD)
425                         g_pGesture->recognized_palm |= PalmFlickVertiFilterMask;
426         }
427
428 #ifdef _F_SUPPORT_BEZEL_FLICK_
429         else if(num_of_fingers == 1)
430         {
431                 g_pGesture->bezel_recognized_mask |= BezelFlickFilterMask;
432         }
433         else
434 #endif
435                 g_pGesture->recognized_gesture |= FlickFilterMask;
436
437         memset(&fev, 0, sizeof(xGestureNotifyFlickEvent));
438         fev.type = GestureNotifyFlick;
439         fev.kind = GestureDone;
440         fev.num_finger = num_of_fingers;
441         fev.distance = distance;
442         fev.duration = duration;
443         fev.direction = direction;
444
445         if(g_pGesture->GrabEvents)
446         {
447                 target_win = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].window;
448                 target_pWin = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].pWin;
449         }
450         else
451         {
452                 target_win = None;
453                 target_pWin = None;
454         }
455
456         if( g_pGesture->grabMask && (target_win != None) )
457         {
458                 fev.window = target_win;
459         }
460         else
461         {
462                 fev.window = g_pGesture->gestureWin;
463         }
464
465 #ifdef __DETAIL_DEBUG__
466         XDBG_DEBUG(MGEST, "fev.window=0x%x, g_pGesture->grabMask=0x%x\n", fev.window, g_pGesture->grabMask);
467 #endif//__DETAIL_DEBUG__
468
469         GestureSendEvent(target_pWin, GestureNotifyFlick, GestureFlickMask, (xGestureCommonEvent *)&fev);
470 }
471
472 void
473 GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy)
474 {
475         Window target_win;
476         WindowPtr target_pWin;
477         xGestureNotifyTapEvent tev;
478
479         //skip non-tap events and single finger tap
480         if( !tap_repeat || num_finger <= 1 )
481                 return;
482
483 #ifdef __DETAIL_DEBUG__
484         XDBG_DEBUG(MGEST, "num_finger=%d, tap_repeat=%d, cx=%d, cy=%d\n",
485                 num_finger, tap_repeat, cx, cy);
486 #endif//__DETAIL_DEBUG__
487
488         g_pGesture->recognized_gesture |= TapFilterMask;
489         memset(&tev, 0, sizeof(xGestureNotifyTapEvent));
490         tev.type = GestureNotifyTap;
491         tev.kind = GestureDone;
492         tev.num_finger = num_finger;
493         tev.tap_repeat = tap_repeat;
494         tev.interval = 0;
495         tev.cx = cx;
496         tev.cy = cy;
497
498         if(g_pGesture->GrabEvents)
499         {
500                 target_win = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].window;
501                 target_pWin = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].pWin;
502         }
503         else
504         {
505                 target_win = None;
506                 target_pWin = None;
507         }
508
509         if( g_pGesture->grabMask && (target_win != None) )
510         {
511                 tev.window = target_win;
512         }
513         else
514         {
515                 tev.window = g_pGesture->gestureWin;
516         }
517
518 #ifdef __DETAIL_DEBUG__
519         XDBG_DEBUG(MGEST, "tev.window=0x%x, g_pGesture->grabMask=0x%x\n", tev.window, g_pGesture->grabMask);
520 #endif//__DETAIL_DEBUG__
521
522         GestureSendEvent(target_pWin, GestureNotifyTap, GestureTapMask, (xGestureCommonEvent *)&tev);
523 }
524
525 void GestureHandleGesture_PinchRotation(int num_of_fingers, double zoom, double angle, int distance, int cx, int cy, int kinds)
526 {
527         Window target_win;
528         WindowPtr target_pWin;
529         xGestureNotifyPinchRotationEvent prev;
530
531 #ifdef __DETAIL_DEBUG__
532         XDBG_DEBUG(MGEST, "num_fingers=%d, zoom=%.2f, angle=%.2f(deg=%.2f), distance=%d, cx=%d, cy=%d\n",
533                                 num_of_fingers, zoom, angle, rad2degree(angle), distance, cx, cy);
534 #endif//__DETAIL_DEBUG__
535
536         g_pGesture->recognized_gesture |= PinchRotationFilterMask;
537         memset(&prev, 0, sizeof(xGestureNotifyPinchRotationEvent));
538         prev.type = GestureNotifyPinchRotation;
539         prev.kind = kinds;
540         prev.num_finger = num_of_fingers;
541         prev.zoom = XDoubleToFixed(zoom);
542         prev.angle = XDoubleToFixed(angle);
543         prev.distance = distance;
544         prev.cx = cx;
545         prev.cy = cy;
546
547         if(g_pGesture->GrabEvents)
548         {
549                 target_win = g_pGesture->GrabEvents[GestureNotifyPinchRotation].pGestureGrabWinInfo[num_of_fingers].window;
550                 target_pWin = g_pGesture->GrabEvents[GestureNotifyPinchRotation].pGestureGrabWinInfo[num_of_fingers].pWin;
551         }
552         else
553         {
554                 target_win = None;
555                 target_pWin = None;
556         }
557
558         if( g_pGesture->grabMask && (target_win != None) )
559         {
560                 prev.window = target_win;
561         }
562         else
563         {
564                 prev.window = g_pGesture->gestureWin;
565         }
566
567 #ifdef __DETAIL_DEBUG__
568         XDBG_DEBUG(MGEST, "prev.window=0x%x, g_pGesture->grabMask=0x%x\n", (unsigned int)prev.window, (unsigned int)g_pGesture->grabMask);
569 #endif//__DETAIL_DEBUG__
570
571         GestureSendEvent(target_pWin, GestureNotifyPinchRotation, GesturePinchRotationMask, (xGestureCommonEvent *)&prev);
572 }
573
574 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds)
575 {
576         Window target_win;
577         WindowPtr target_pWin;
578         xGestureNotifyHoldEvent hev;
579
580 #ifdef __DETAIL_DEBUG__
581         XDBG_DEBUG(MGEST, "num_fingers=%d, cx=%d, cy=%d, holdtime=%d, kinds=%d\n",
582                                 num_fingers, cx, cy, holdtime, kinds);
583 #endif//__DETAIL_DEBUG__
584
585         if(num_fingers == 0)
586                 g_pGesture->recognized_palm |= PalmHoldFilterMask;
587         else
588                 g_pGesture->recognized_gesture |= HoldFilterMask;
589         memset(&hev, 0, sizeof(xGestureNotifyHoldEvent));
590         hev.type = GestureNotifyHold;
591         hev.kind = kinds;
592         hev.num_finger = num_fingers;
593         hev.holdtime = holdtime;
594         hev.cx = cx;
595         hev.cy = cy;
596
597         if(g_pGesture->GrabEvents)
598         {
599                 target_win = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].window;
600                 target_pWin = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].pWin;
601         }
602         else
603         {
604                 target_win = None;
605                 target_pWin = None;
606         }
607
608         if( g_pGesture->grabMask && (target_win != None) )
609         {
610                 hev.window = target_win;
611         }
612         else
613         {
614                 hev.window = g_pGesture->gestureWin;
615         }
616
617 #ifdef __DETAIL_DEBUG__
618         XDBG_DEBUG(MGEST, "hev.window=0x%x, g_pGesture->grabMask=0x%x\n", hev.window, g_pGesture->grabMask);
619 #endif//__DETAIL_DEBUG__
620
621         GestureSendEvent(target_pWin, GestureNotifyHold, GestureHoldMask, (xGestureCommonEvent *)&hev);
622 }
623
624 void GestureHandleGesture_TapNHold(int num_fingers, int cx, int cy, Time interval, Time holdtime, int kinds)
625 {
626         Window target_win;
627         WindowPtr target_pWin;
628         xGestureNotifyTapNHoldEvent thev;
629
630 #ifdef __DETAIL_DEBUG__
631         XDBG_DEBUG(MGEST, "num_fingers=%d, cx=%d, cy=%d, interval=%d, holdtime=%d, kinds=%d\n",
632                                 num_fingers, cx, cy, interval, holdtime, kinds);
633 #endif//__DETAIL_DEBUG__
634
635         g_pGesture->recognized_gesture |= TapNHoldFilterMask;
636         memset(&thev, 0, sizeof(xGestureNotifyTapNHoldEvent));
637         thev.type = GestureNotifyTapNHold;
638         thev.kind = kinds;
639         thev.num_finger = num_fingers;
640         thev.holdtime = holdtime;
641         thev.cx = cx;
642         thev.cy = cy;
643         thev.interval = interval;
644
645         if(g_pGesture->GrabEvents)
646         {
647                 target_win = g_pGesture->GrabEvents[GestureNotifyTapNHold].pGestureGrabWinInfo[num_fingers].window;
648                 target_pWin = g_pGesture->GrabEvents[GestureNotifyTapNHold].pGestureGrabWinInfo[num_fingers].pWin;
649         }
650         else
651         {
652                 target_win = None;
653                 target_pWin = None;
654         }
655
656         if( g_pGesture->grabMask && (target_win != None) )
657         {
658                 thev.window = target_win;
659         }
660         else
661         {
662                 thev.window = g_pGesture->gestureWin;
663         }
664
665 #ifdef __DETAIL_DEBUG__
666         XDBG_DEBUG(MGEST, "thev.window=0x%x, g_pGesture->grabMask=0x%x\n", thev.window, g_pGesture->grabMask);
667 #endif//__DETAIL_DEBUG__
668
669         GestureSendEvent(target_pWin, GestureNotifyTapNHold, GestureTapNHoldMask, (xGestureCommonEvent *)&thev);
670 }
671
672 void GestureHandleGesture_Pan(int num_fingers, short int dx, short int dy, int direction, int distance, Time duration, int kinds)
673 {
674         Window target_win;
675         WindowPtr target_pWin;
676         xGestureNotifyPanEvent pev;
677
678 #ifdef __DETAIL_DEBUG__
679         XDBG_DEBUG(MGEST, "num_fingers=%d, dx=%d, dy=%d, direction=%d, distance=%d, duration=%d, kinds=%d\n",
680                                 num_fingers, dx, dy, direction, distance, duration, kinds);
681 #endif//__DETAIL_DEBUG__
682
683         g_pGesture->recognized_gesture |= PanFilterMask;
684         memset(&pev, 0, sizeof(xGestureNotifyPanEvent));
685         pev.type = GestureNotifyPan;
686         pev.kind = kinds;
687         pev.num_finger = num_fingers;
688         pev.direction = direction;
689         pev.distance = distance;
690         pev.duration = duration;
691         pev.dx = dx;
692         pev.dy = dy;
693
694         if(g_pGesture->GrabEvents)
695         {
696                 target_win = g_pGesture->GrabEvents[GestureNotifyPan].pGestureGrabWinInfo[num_fingers].window;
697                 target_pWin = g_pGesture->GrabEvents[GestureNotifyPan].pGestureGrabWinInfo[num_fingers].pWin;
698         }
699         else
700         {
701                 target_win = None;
702                 target_pWin = None;
703         }
704
705         if( g_pGesture->grabMask && (target_win != None) )
706         {
707                 pev.window = target_win;
708         }
709         else
710         {
711                 pev.window = g_pGesture->gestureWin;
712         }
713
714 #ifdef __DETAIL_DEBUG__
715         XDBG_DEBUG(MGEST, "pev.window=0x%x, g_pGesture->grabMask=0x%x\n", pev.window, g_pGesture->grabMask);
716 #endif//__DETAIL_DEBUG__
717
718         GestureSendEvent(target_pWin, GestureNotifyPan, GesturePanMask, (xGestureCommonEvent *)&pev);
719 }
720
721 static void GestureHoldDetector(int type, InternalEvent *ev, DeviceIntPtr device)
722 {
723         int i;
724         int idx = -1;
725         pixman_region16_t tarea1;
726         static int num_pressed = 0;
727         unsigned int hold_area_size;
728         PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
729
730         if(!g_pGesture->hold_detector_activate)
731         {
732 #ifdef __HOLD_DETECTOR_DEBUG__
733                 XDBG_DEBUG(MGEST, "g_pGesture->hold_detector_activate=0\n");
734 #endif//__HOLD_DETECTOR_DEBUG__
735                 return;
736         }
737
738         if(!g_pGesture->has_hold_grabmask)
739         {
740                 Mask eventmask = (1L << GestureNotifyHold);
741
742                 if( (g_pGesture->grabMask & eventmask) &&
743                 (g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[0].window != None) )
744                 {
745                         g_pGesture->has_hold_grabmask = 1;
746
747                         //Initialize a set of variables
748                         num_pressed = 0;
749                         memset(&g_pGesture->cts, 0, sizeof(g_pGesture->cts));
750                         pixman_region_init(&g_pGesture->chold_area);
751 #ifdef __HOLD_DETECTOR_DEBUG__
752                         XDBG_DEBUG(MGEST, "[%d] Initialize...\n", __LINE__);
753 #endif//__HOLD_DETECTOR_DEBUG__
754                 }
755                 else
756                 {
757                         //reset local hold_grab_mask variable
758                         g_pGesture->has_hold_grabmask = 0;
759
760                         g_pGesture->hold_detector_activate = 0;
761 #ifdef __HOLD_DETECTOR_DEBUG__
762                         XDBG_DEBUG(MGEST, "has_hold_grabmask=0 and g_pGesture->hold_detector_activate=0\n");
763 #endif//__HOLD_DETECTOR_DEBUG__
764                         return;
765                 }               
766         }
767
768         if( IGNORE_EVENTS == g_pGesture->ehtype ||
769                 device->id < g_pGesture->first_fingerid )
770         {
771 #ifdef __HOLD_DETECTOR_DEBUG__
772                 XDBG_DEBUG(MGEST, "Return (IGNORE_EVENTS or device->id:%d < first_fingerid:%d)\n", device->id, g_pGesture->first_fingerid);
773 #endif//__HOLD_DETECTOR_DEBUG__
774                 return;
775         }
776
777         for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
778         {
779                 if( device->id == g_pGesture->mt_devices[i]->id )
780                 {
781                         idx = i;
782                         break;
783                 }
784         }
785         if( (idx < 0) || ((MAX_MT_DEVICES-1) < idx )) return;
786
787         switch( type )
788         {
789                 case ET_ButtonPress:
790                         g_pGesture->cts[idx].status = BTN_PRESSED;
791                         g_pGesture->cts[idx].cx = ev->device_event.root_x;
792                         g_pGesture->cts[idx].cy = ev->device_event.root_y;
793
794                         num_pressed++;
795                         if(num_pressed < 3) break;
796
797                         if( num_pressed > g_pGesture->num_mt_devices )
798                                 num_pressed = g_pGesture->num_mt_devices;
799
800                         pixman_region_init(&tarea1);
801                         pixman_region_init(&g_pGesture->chold_area);
802                         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);
803
804                         tarea1.extents.x1 = g_pGesture->cts[0].cx;
805                         tarea1.extents.x2 = g_pGesture->cts[0].cx+1;
806                         tarea1.extents.y1 = g_pGesture->cts[0].cy;
807                         tarea1.extents.y2 = g_pGesture->cts[0].cy+1;
808
809                         pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1);
810
811                         for( i = 1 ; i < num_pressed ; i++ )
812                         {
813                                         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);
814
815                                         tarea1.extents.x1 = g_pGesture->cts[i].cx;
816                                         tarea1.extents.x2 = g_pGesture->cts[i].cx + 1;
817                                         tarea1.extents.y1 = g_pGesture->cts[i].cy;
818                                         tarea1.extents.y2 = g_pGesture->cts[i].cy + 1;
819
820                                         pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1);
821                         }
822                         break;
823
824                 case ET_Motion:
825                         if(BTN_RELEASED == g_pGesture->cts[idx].status)
826                                 return;
827
828                         g_pGesture->cts[idx].status = BTN_MOVING;
829                         g_pGesture->cts[idx].cx = ev->device_event.root_x;
830                         g_pGesture->cts[idx].cy = ev->device_event.root_y;
831
832                         if(num_pressed < 3) break;
833
834                         pixman_region_init(&tarea1);
835                         pixman_region_init(&g_pGesture->chold_area);
836                         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);
837
838                         tarea1.extents.x1 = g_pGesture->cts[0].cx;
839                         tarea1.extents.x2 = g_pGesture->cts[0].cx+1;
840                         tarea1.extents.y1 = g_pGesture->cts[0].cy;
841                         tarea1.extents.y2 = g_pGesture->cts[0].cy+1;
842
843                         pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1);
844
845                         for( i = 1 ; i < num_pressed ; i++ )
846                         {
847                                         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);
848
849                                         tarea1.extents.x1 = g_pGesture->cts[i].cx;
850                                         tarea1.extents.x2 = g_pGesture->cts[i].cx + 1;
851                                         tarea1.extents.y1 = g_pGesture->cts[i].cy;
852                                         tarea1.extents.y2 = g_pGesture->cts[i].cy + 1;
853
854                                         pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1);
855                         }
856                         break;
857
858                 case ET_ButtonRelease:
859                         g_pGesture->cts[idx].status = BTN_RELEASED;
860                         g_pGesture->cts[idx].cx = ev->device_event.root_x;
861                         g_pGesture->cts[idx].cy = ev->device_event.root_y;
862
863                         num_pressed--;
864                         if(num_pressed <3)
865                         {
866                                 pixman_region_init(&g_pGesture->chold_area);
867                         }
868                         break;
869         }
870
871         if(num_pressed >= 3)
872         {
873                 hold_area_size = AREA_SIZE(&g_pGesture->chold_area.extents);
874
875 #ifdef __HOLD_DETECTOR_DEBUG__
876                 XDBG_DEBUG(MGEST, "hold_area_size=%d, pPalmMisc->half_scrn_area_size=%d\n", hold_area_size, pPalmMisc->half_scrn_area_size);
877 #endif//__HOLD_DETECTOR_DEBUG__
878
879                 if(pPalmMisc->half_scrn_area_size <= hold_area_size)
880                 {
881                         GestureHandleGesture_Hold(0, AREA_CENTER_X(&g_pGesture->chold_area.extents), AREA_CENTER_Y(&g_pGesture->chold_area.extents), PALM_HOLD_TIME_THRESHOLD, GestureBegin);
882                         GestureHandleGesture_Hold(0, AREA_CENTER_X(&g_pGesture->chold_area.extents), AREA_CENTER_Y(&g_pGesture->chold_area.extents), PALM_HOLD_TIME_THRESHOLD, GestureEnd);
883
884                         g_pGesture->hold_detector_activate = 0;
885                         g_pGesture->has_hold_grabmask = 0;
886                 }
887         }
888 }
889
890 void
891 GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
892 {
893         static int cx, cy;
894
895         static int num_pressed = 0;
896         static int state = GestureEnd;
897         static int event_type = GestureNotifyPinchRotation;
898         static OsTimerPtr pinchrotation_event_timer = NULL;
899
900         static pixman_region16_t base_area;
901         static pixman_region16_t cur_area;
902
903         static double base_distance = 0.0f;
904         static double base_angle = 0.0f;
905
906         static double prev_distance = 0.0f;
907         static double prev_angle = 0.0f;
908
909         static double cur_distance = 0.0f;
910         static double cur_angle = 0.0f;
911
912         double diff_distance = 0.0f;
913         double diff_angle = 0.0f;
914
915         static int has_event_mask = 0;
916
917         static Time base_time = 0;
918         Time current_time;
919
920         if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1
921 #ifdef _F_SUPPORT_BEZEL_FLICK_
922                         || g_pGesture->bezel_recognized_mask)
923 #else
924                         )
925 #endif
926                 goto cleanup_pinchrotation;
927
928         if( timer_expired )
929         {
930                 if( state == GestureEnd )
931                 {
932                         current_time = GetTimeInMillis();
933                         if( (current_time - base_time) >= g_pGesture->pinchrotation_time_threshold )
934                         {
935 #ifdef __DETAIL_DEBUG__
936                                 XDBG_DEBUG(MGEST, "[Timer] You must move farther than dist threshold(=%.2f) or angle threshold(=%2f) within time threshold(=%d) !\n", g_pGesture->pinchrotation_dist_threshold, g_pGesture->pinchrotation_angle_threshold, g_pGesture->pinchrotation_time_threshold);
937 #endif//__DETAIL_DEBUG__
938                                 goto cleanup_pinchrotation;
939                         }
940                 }
941
942                 return;
943         }
944
945         switch( type )
946         {
947                 case ET_ButtonPress:
948                         g_pGesture->fingers[idx].flags |= PressFlagPinchRotation;
949
950                         if( g_pGesture->num_pressed < 2 )
951                                 return;
952
953                         if( g_pGesture->num_pressed < num_pressed && state != GestureEnd )
954                         {
955 #ifdef __DETAIL_DEBUG__
956                                 XDBG_DEBUG(MGEST, "[P][cleanup] num_finger changed !(state: %d)  num_pressed=%d, g_pGesture->num_pressed=%d\n", state, num_pressed, g_pGesture->num_pressed);
957 #endif//__DETAIL_DEBUG__
958                                 goto cleanup_pinchrotation;
959                         }
960
961                         if( base_distance == 0.0f && g_pGesture->num_pressed == 2 )
962                         {
963 #ifdef __DETAIL_DEBUG__
964                                 XDBG_DEBUG(MGEST, "[First Time !!!] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
965 #endif//__DETAIL_DEBUG__
966
967                                 base_time = GetTimeInMillis();
968                                 pixman_region_init(&base_area);
969                                 pixman_region_union(&base_area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[1]);
970
971                                 prev_distance = base_distance = AREA_DIAG_LEN(&base_area.extents);
972
973 #ifdef __DETAIL_DEBUG__
974                                 XDBG_DEBUG(MGEST, "[P] x1=%d, x2=%d, y1=%d, y2=%d\n", g_pGesture->fingers[0].px, g_pGesture->fingers[1].px,
975                                 g_pGesture->fingers[0].py, g_pGesture->fingers[1].py);
976 #endif//__DETAIL_DEBUG__
977
978                                 prev_angle = base_angle = get_angle(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py, g_pGesture->fingers[1].px, g_pGesture->fingers[1].py);
979 #ifdef __DETAIL_DEBUG__
980                                 XDBG_DEBUG(MGEST, "[P] base_angle=%.2f(deg=%.2f)\n", base_angle, rad2degree(base_angle));
981 #endif//__DETAIL_DEBUG__
982                                 event_type = GestureNotifyPinchRotation;
983                                 pinchrotation_event_timer = TimerSet(pinchrotation_event_timer, 0, g_pGesture->pinchrotation_time_threshold, GestureEventTimerHandler, (int *)&event_type);
984                         }
985                         num_pressed = g_pGesture->num_pressed;
986
987 #ifdef __DETAIL_DEBUG__
988                         XDBG_DEBUG(MGEST, "[P][num_pressed=%d] AREA_SIZE(base_area.extents)=%d\n", num_pressed, AREA_SIZE(&base_area.extents));
989                         XDBG_DEBUG(MGEST, "[P][num_pressed=%d] base_distance=%.2f, base_angle=%.2f(deg=%.2f)\n", num_pressed, base_distance, base_angle, rad2degree(base_angle));
990 #endif//__DETAIL_DEBUG__
991                         break;
992
993                 case ET_Motion:
994                         if( !(g_pGesture->fingers[idx].flags & PressFlagPinchRotation) )
995                                 break;
996
997                         if( (num_pressed != g_pGesture->num_pressed) && (state != GestureEnd) )
998                         {
999 #ifdef __DETAIL_DEBUG__
1000                                 XDBG_DEBUG(MGEST, "[M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1001 #endif//__DETAIL_DEBUG__
1002                                 goto cleanup_pinchrotation;
1003                         }
1004
1005                         if( num_pressed < 2 )
1006                                 return;
1007
1008                         if( g_pGesture->fingers[0].mx && g_pGesture->fingers[0].my && g_pGesture->fingers[1].mx && g_pGesture->fingers[1].my )
1009                         {
1010                                 pixman_region_init(&cur_area);
1011                                 pixman_region_union(&cur_area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[1]);
1012
1013                                 cur_distance = AREA_DIAG_LEN(&cur_area.extents);
1014
1015 #ifdef __DETAIL_DEBUG__
1016                                 XDBG_DEBUG(MGEST, "[M] x1=%d, x2=%d, y1=%d, y2=%d\n", g_pGesture->fingers[0].mx, g_pGesture->fingers[1].mx,
1017                                 g_pGesture->fingers[0].my, g_pGesture->fingers[1].my);
1018 #endif//__DETAIL_DEBUG__
1019
1020                                 cur_angle = get_angle(g_pGesture->fingers[0].mx, g_pGesture->fingers[0].my, g_pGesture->fingers[1].mx, g_pGesture->fingers[1].my);
1021 #ifdef __DETAIL_DEBUG__
1022                                 XDBG_DEBUG(MGEST, "[M] cur_angle=%.2f(deg=%.2f)\n", cur_angle, rad2degree(cur_angle));
1023 #endif//__DETAIL_DEBUG__
1024
1025                                 diff_distance = prev_distance - cur_distance;
1026                                 diff_angle = prev_angle - cur_angle;
1027
1028                                 cx = AREA_CENTER_X(&cur_area.extents);
1029                                 cy = AREA_CENTER_Y(&cur_area.extents);
1030
1031 #ifdef __DETAIL_DEBUG__
1032                                 XDBG_DEBUG(MGEST, "[M][state=%d] cx=%d, cy=%d\n", state, cx, cy);
1033 #endif//__DETAIL_DEBUG__
1034
1035 #ifdef __DETAIL_DEBUG__
1036                                 XDBG_DEBUG(MGEST, "[M][num_pressed=%d] prev_distance=%.2f, cur_distance=%.2f, diff=%.2f\n", num_pressed, prev_distance, cur_distance, diff_distance);
1037                                 XDBG_DEBUG(MGEST, "[M][num_pressed=%d] prev_angle=%.2f(deg=%.2f), cur_angle=%.2f(deg=%.2f), diff=%.2f(deg=%.2f)\n", num_pressed, prev_angle, rad2degree(prev_angle), cur_angle, rad2degree(cur_angle), diff_angle, rad2degree(diff_angle));
1038 #endif//__DETAIL_DEBUG__
1039
1040                                 switch( state )
1041                                 {
1042                                         case GestureEnd:
1043                                                 if( (ABS(diff_distance) >= g_pGesture->pinchrotation_dist_threshold) || (ABS(diff_angle) >= g_pGesture->pinchrotation_angle_threshold) )
1044                                                 {
1045 #ifdef __DETAIL_DEBUG__
1046                                                         if( ABS(diff_distance) >= g_pGesture->pinchrotation_dist_threshold )
1047                                                                 XDBG_DEBUG(MGEST, "[M] zoom changed !\n");
1048
1049                                                         if( ABS(diff_angle) >= g_pGesture->pinchrotation_angle_threshold )
1050                                                                 XDBG_DEBUG(MGEST, "[M] angle changed !\n");
1051 #endif//__DETAIL_DEBUG__
1052
1053                                                         TimerCancel(pinchrotation_event_timer);
1054                                                         state = GestureBegin;
1055                                                         goto gesture_begin_handle;
1056                                                 }
1057                                                 break;
1058
1059                                         case GestureBegin:
1060 gesture_begin_handle:
1061 #ifdef __DETAIL_DEBUG__
1062                                                 XDBG_DEBUG(MGEST, "PINCHROTATION Begin !cx=%d, cy=%d, state=%d\n", cx, cy, state);
1063 #endif//__DETAIL_DEBUG__
1064                                                 if( GestureHasFingerEventMask(GestureNotifyPinchRotation, num_pressed) )
1065                                                 {
1066                                                         GestureHandleGesture_PinchRotation(num_pressed, cur_distance / base_distance, (cur_angle > base_angle) ? (cur_angle-base_angle) : (RAD_360DEG + cur_angle - base_angle), cur_distance, cx, cy, GestureBegin);
1067                                                         prev_distance = cur_distance;
1068                                                         prev_angle = cur_angle;
1069                                                         state = GestureUpdate;
1070                                                         has_event_mask = 1;
1071                                                 }
1072                                                 else
1073                                                 {
1074                                                         has_event_mask = 0;
1075                                                         goto cleanup_pinchrotation;
1076                                                 }
1077                                                 break;
1078
1079                                         case GestureUpdate:
1080                                                 //if( ABS(diff_distance) < g_pGesture->pinchrotation_dist_threshold && ABS(diff_angle) < g_pGesture->pinchrotation_angle_threshold )
1081                                                 //      break;
1082
1083 #ifdef __DETAIL_DEBUG__
1084                                                 if( ABS(diff_distance) >= g_pGesture->pinchrotation_dist_threshold )
1085                                                         XDBG_DEBUG(MGEST, "[M] zoom changed !\n");
1086
1087                                                 if( ABS(diff_angle) >= g_pGesture->pinchrotation_angle_threshold )
1088                                                         XDBG_DEBUG(MGEST, "[M] angle changed !\n");
1089 #endif//__DETAIL_DEBUG__
1090
1091 #ifdef __DETAIL_DEBUG__
1092                                                 XDBG_DEBUG(MGEST, "PINCHROTATION Update ! cx=%d, cy=%d, state=%d\n", cx, cy, state);
1093 #endif//__DETAIL_DEBUG__
1094                                                 GestureHandleGesture_PinchRotation(num_pressed, cur_distance / base_distance, (cur_angle > base_angle) ? (cur_angle-base_angle) : (RAD_360DEG + cur_angle - base_angle), cur_distance, cx, cy, GestureUpdate);
1095                                                 prev_distance = cur_distance;
1096                                                 prev_angle = cur_angle;
1097                                                 break;
1098
1099                                         case GestureDone:
1100                                         default:
1101                                                 break;
1102                                 }
1103                         }
1104                         break;
1105
1106                 case ET_ButtonRelease:
1107                         if( state != GestureEnd && num_pressed >= 2)
1108                         {
1109 #ifdef __DETAIL_DEBUG__
1110                                 XDBG_DEBUG(MGEST, "[R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1111 #endif//__DETAIL_DEBUG__
1112                                 goto cleanup_pinchrotation;
1113                         }
1114
1115                         if( g_pGesture->num_pressed )
1116                                 break;
1117
1118                         goto cleanup_pinchrotation;
1119                         break;
1120         }
1121
1122         return;
1123
1124 cleanup_pinchrotation:
1125         g_pGesture->filter_mask |= PinchRotationFilterMask;
1126         if(  has_event_mask  && (state == GestureBegin || state == GestureUpdate) )
1127         {
1128                 state = GestureEnd;
1129 #ifdef __DETAIL_DEBUG__
1130                 XDBG_DEBUG(MGEST, "PINCHROTATION End ! cx=%d, cy=%d, state=%d\n", cx, cy, state);
1131 #endif//__DETAIL_DEBUG__
1132                 GestureHandleGesture_PinchRotation(num_pressed, cur_distance / base_distance, (cur_angle > base_angle) ? (cur_angle-base_angle) : (RAD_360DEG + cur_angle - base_angle), cur_distance, cx, cy, GestureEnd);
1133         }
1134         else if(g_pGesture->num_pressed > 1)
1135         {
1136                 if(!(g_pGesture->filter_mask & PanFilterMask))
1137                 {
1138                         pixman_region_init(&base_area);
1139                         pixman_region_union(&base_area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[1]);
1140
1141                         prev_distance = base_distance = AREA_DIAG_LEN(&base_area.extents);
1142                         prev_angle = base_angle = get_angle(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py, g_pGesture->fingers[1].px, g_pGesture->fingers[1].py);
1143
1144                         g_pGesture->filter_mask &= ~PinchRotationFilterMask;
1145
1146                         return;
1147                 }
1148                 g_pGesture->recognized_gesture &= ~PinchRotationFilterMask;
1149         }
1150
1151         if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
1152         {
1153 #ifdef __DETAIL_DEBUG__
1154                 XDBG_DEBUG(MGEST, "[cleanup] GestureFlushOrDrop() !\n");
1155 #endif//__DETAIL_DEBUG__
1156
1157                 if( ERROR_INVALPTR == GestureFlushOrDrop() )
1158                 {
1159                         GestureControl(g_pGesture->this_device, DEVICE_OFF);
1160                 }
1161         }
1162
1163         prev_distance = base_distance = 0.0f;
1164         prev_angle = base_angle = 0.0f;
1165         has_event_mask = num_pressed = 0;
1166         state = GestureEnd;
1167         cx = cy = 0;
1168         TimerCancel(pinchrotation_event_timer);
1169         return;
1170 }
1171
1172 void
1173 GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx)
1174 {
1175         static int num_pressed = 0;
1176         static int mbits = 0;
1177         static int base_area_size = 0;
1178         static Time base_time = 0;
1179         static int base_x, base_y;
1180         Time current_time;
1181         Time duration;
1182         int distx, disty;
1183         int distance, direction;
1184         int area_size;
1185         int flicked = 0;
1186
1187         if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1
1188 #ifdef _F_SUPPORT_BEZEL_FLICK_
1189                 || g_pGesture->bezel_recognized_mask)
1190 #else
1191                 )
1192 #endif
1193                 goto cleanup_flick;
1194
1195         switch( type )
1196         {
1197                 case ET_ButtonPress:
1198                         g_pGesture->fingers[idx].flags |= PressFlagFlick;
1199                         if( g_pGesture->num_pressed < 2 )
1200                                 return;
1201
1202                         if( !base_area_size || g_pGesture->num_pressed > num_pressed )
1203                         {
1204                                 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1205                                 base_x = g_pGesture->area.extents.x1;
1206                                 base_y = g_pGesture->area.extents.y1;
1207                                 base_time = GetTimeInMillis();
1208                         }
1209                         num_pressed = g_pGesture->num_pressed;
1210
1211 #ifdef __DETAIL_DEBUG__
1212                         XDBG_DEBUG(MGEST, "[P]][num_pressed=%d] AREA_SIZE(area.extents)=%d\n", num_pressed, base_area_size);
1213 #endif//__DETAIL_DEBUG__
1214                         break;
1215
1216                 case ET_Motion:
1217                         if( !(g_pGesture->fingers[idx].flags & PressFlagFlick ) )
1218                                 break;
1219
1220 #ifdef __DETAIL_DEBUG__
1221                         if( num_pressed > g_pGesture->num_pressed )
1222                         {
1223                                 XDBG_DEBUG(MGEST, "[M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1224                                 //goto cleanup_flick;
1225                         }
1226 #endif//__DETAIL_DEBUG__
1227
1228                         if( num_pressed < 2 )
1229                                 return;
1230
1231                         mbits |= (1 << idx);
1232                         if( mbits == (pow(2, num_pressed)-1) )
1233                         {
1234                                 area_size = AREA_SIZE(&g_pGesture->area.extents);
1235 #ifdef __DETAIL_DEBUG__
1236                                 XDBG_DEBUG(MGEST, "[M][num_pressed=%d] AREA_SIZE(area.extents)=%d\n", num_pressed, area_size);
1237 #endif//__DETAIL_DEBUG__
1238                                 if( ABS(base_area_size - area_size) >= FLICK_AREA_THRESHOLD )
1239                                 {
1240 #ifdef __DETAIL_DEBUG__
1241                                         XDBG_DEBUG(MGEST, "[M] diff between Area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, FLICK_AREA_THRESHOLD);
1242 #endif//__DETAIL_DEBUG__
1243                                         goto cleanup_flick;
1244                                 }
1245
1246                                 current_time = GetTimeInMillis();
1247                                 if( (current_time - base_time) >= FLICK_AREA_TIMEOUT )
1248                                 {
1249 #ifdef __DETAIL_DEBUG__
1250                                         XDBG_DEBUG(MGEST, "[M] diff between current time(=%d) and base time(=%d) is bigger than threashold(=%d) !\n", current_time, base_time, FLICK_AREA_TIMEOUT);
1251 #endif//__DETAIL_DEBUG__
1252                                         goto cleanup_flick;
1253                                 }
1254                                 mbits = 0;
1255                         }
1256                         break;
1257
1258                 case ET_ButtonRelease:
1259                         if( g_pGesture->num_pressed )
1260                                 break;
1261
1262                         duration = GetTimeInMillis() - base_time;
1263                         distx = g_pGesture->area.extents.x1 - base_x;
1264                         disty = g_pGesture->area.extents.y1 - base_y;
1265
1266 #ifdef __DETAIL_DEBUG__
1267                         XDBG_DEBUG(MGEST, "duration=%d, distx=%d, disty=%d\n", duration, distx, disty);
1268 #endif//__DETAIL_DEBUG__
1269
1270                         if( duration <= 0 || duration >= FLICK_AREA_TIMEOUT )
1271                                 goto cleanup_flick;
1272
1273                         if( ABS(distx) >= FLICK_MOVE_THRESHOLD )
1274                         {
1275                                 direction = (distx > 0) ? FLICK_EASTWARD : FLICK_WESTWARD;
1276                                 distance = ABS(distx);
1277                                 flicked++;
1278                         }
1279                         else if( ABS(disty) >= FLICK_MOVE_THRESHOLD )
1280                         {
1281                                 direction = (disty > 0) ? FLICK_SOUTHWARD : FLICK_NORTHWARD;
1282                                 distance = ABS(disty);
1283                                 flicked++;
1284                         }
1285
1286                         if( !flicked )
1287                                 goto cleanup_flick;
1288
1289                         if( GestureHasFingerEventMask(GestureNotifyFlick, num_pressed) )
1290                                 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
1291                         goto cleanup_flick_recognized;
1292                         break;
1293         }
1294
1295         return;
1296
1297 cleanup_flick:
1298
1299         g_pGesture->recognized_gesture &= ~FlickFilterMask;
1300
1301 cleanup_flick_recognized:
1302
1303         g_pGesture->filter_mask |= FlickFilterMask;
1304         num_pressed = 0;
1305         base_area_size = 0;
1306         base_time = 0;
1307         mbits = 0;
1308         return;
1309 }
1310
1311 void
1312 GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1313 {
1314         static int num_pressed = 0;
1315         static int mbits = 0;
1316         static int base_area_size = 0;
1317         static Time base_time = 0;
1318         static pixman_box16_t base_box_ext;
1319         static int base_cx;
1320         static int base_cy;
1321         static int prev_cx;
1322         static int prev_cy;
1323         static int cx = 0;
1324         static int cy = 0;
1325         int dx, dy;
1326         static Time prev_time = 0;
1327         Time current_time = 0;
1328         int distance = 0;
1329         int direction = 0;
1330         int area_size;
1331         static int time_checked = 0;
1332         static int state = GestureEnd;
1333
1334         static OsTimerPtr pan_event_timer = NULL;
1335         static int event_type = GestureNotifyPan;
1336
1337         if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1
1338 #ifdef _F_SUPPORT_BEZEL_FLICK_
1339                 || g_pGesture->bezel_recognized_mask)
1340 #else
1341                 )
1342 #endif
1343                 goto cleanup_pan;
1344
1345         if( timer_expired )
1346         {
1347                 if( !time_checked )
1348                 {
1349                         current_time = GetTimeInMillis();
1350                         if( (current_time - base_time) >= PAN_TIME_THRESHOLD )
1351                         {
1352                                 if( (!cx && !cy) || INBOX(&base_box_ext, cx, cy) )
1353                                 {
1354 #ifdef __DETAIL_DEBUG__
1355                                         XDBG_DEBUG(MGEST, "[Timer] You must move farther than move threshold(=%d) within time threshold(=%d) !\n", PAN_MOVE_THRESHOLD*2, PAN_TIME_THRESHOLD);
1356 #endif//__DETAIL_DEBUG__
1357                                         goto cleanup_pan;
1358                                 }
1359                                 time_checked = 1;
1360                         }
1361                 }
1362                 return;
1363         }
1364
1365         switch( type )
1366         {
1367                 case ET_ButtonPress:
1368                         g_pGesture->fingers[idx].flags |= PressFlagPan;
1369
1370                         if( g_pGesture->num_pressed < 2 )
1371                                 return;
1372
1373                         if( !base_area_size || g_pGesture->num_pressed > num_pressed )
1374                         {
1375                                 if( state != GestureEnd )
1376                                 {
1377 #ifdef __DETAIL_DEBUG__
1378                                         XDBG_DEBUG(MGEST, "[P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1379 #endif//__DETAIL_DEBUG__
1380                                         goto cleanup_pan;
1381                                 }
1382                                 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1383                                 prev_cx = base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1384                                 prev_cy = base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1385                                 prev_time = base_time = GetTimeInMillis();
1386                                 base_box_ext.x1 = base_cx-PAN_MOVE_THRESHOLD;
1387                                 base_box_ext.y1 = base_cy-PAN_MOVE_THRESHOLD;
1388                                 base_box_ext.x2 = base_cx+PAN_MOVE_THRESHOLD;
1389                                 base_box_ext.y2 = base_cy+PAN_MOVE_THRESHOLD;
1390                                 event_type = GestureNotifyPan;
1391                                 pan_event_timer = TimerSet(pan_event_timer, 0, PAN_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1392                         }
1393                         num_pressed = g_pGesture->num_pressed;
1394
1395 #ifdef __DETAIL_DEBUG__
1396                         XDBG_DEBUG(MGEST, "[P][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d\n", num_pressed, base_area_size, base_cx, base_cy);
1397 #endif//__DETAIL_DEBUG__
1398                         break;
1399
1400                 case ET_Motion:
1401                         if( !(g_pGesture->fingers[idx].flags & PressFlagPan ) )
1402                                 break;
1403
1404                         if( num_pressed != g_pGesture->num_pressed )
1405                         {
1406                                 if( state != GestureEnd )
1407                                 {
1408 #ifdef __DETAIL_DEBUG__
1409                                 XDBG_DEBUG(MGEST, "[M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1410 #endif//__DETAIL_DEBUG__
1411                                         goto cleanup_pan;
1412                                 }
1413                         }
1414
1415                         if( num_pressed < 2 )
1416                                 return;
1417
1418                         mbits |= (1 << idx);
1419                         if( mbits == (pow(2, num_pressed)-1) )
1420                         {
1421                                 area_size = AREA_SIZE(&g_pGesture->area.extents);
1422 #ifdef __DETAIL_DEBUG__
1423                                 XDBG_DEBUG(MGEST, "[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));
1424 #endif//__DETAIL_DEBUG__
1425
1426                                 if( (state != GestureUpdate) && (ABS(base_area_size - area_size) >= PAN_AREA_THRESHOLD) )
1427                                 {
1428 #ifdef __DETAIL_DEBUG__
1429                                         XDBG_DEBUG(MGEST, "[M] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, PAN_AREA_THRESHOLD);
1430 #endif//__DETAIL_DEBUG__
1431                                         goto cleanup_pan;
1432                                 }
1433
1434                                 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1435                                 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1436 #ifdef __DETAIL_DEBUG__
1437                                 XDBG_DEBUG(MGEST, "[M] cx=%d, prev_cx=%d, diff=%d\n", cx, prev_cx, ABS(cx-prev_cx));
1438                                 XDBG_DEBUG(MGEST, "[M] cy=%d, prev_cy=%d, diff=%d\n", cy, prev_cy, ABS(cy-prev_cy));
1439 #endif//__DETAIL_DEBUG__
1440
1441                                 if( state <= GestureBegin )
1442                                 {
1443                                         if( !INBOX(&base_box_ext, cx, cy) )
1444                                         {
1445                                                 TimerCancel(pan_event_timer);
1446                                                 pan_event_timer = NULL;
1447                                                 
1448                                                 if( GestureHasFingerEventMask(GestureNotifyPan, num_pressed) )
1449                                                 {
1450                                                         GestureHandleGesture_Pan(num_pressed, prev_cx, prev_cy, direction, distance, current_time-prev_time, GestureBegin);
1451                                                         state = GestureUpdate;
1452                                                 }
1453                                                 else
1454                                                         goto cleanup_pan;
1455                                         }
1456                                 }
1457                                 else
1458                                 {
1459                                         dx = cx-prev_cx;
1460                                         dy = cy-prev_cy;
1461
1462                                         //if( ABS(dx) >= PAN_UPDATE_MOVE_THRESHOLD || ABS(dy) >= PAN_UPDATE_MOVE_THRESHOLD )
1463                                         {
1464 #ifdef __DETAIL_DEBUG__
1465                                                 XDBG_DEBUG(MGEST, "PAN Update !dx=%d, dy=%d, state=%d\n", dx, dy, state);
1466 #endif//__DETAIL_DEBUG__
1467
1468                                                 GestureHandleGesture_Pan(num_pressed, dx, dy, direction, distance, current_time-prev_time, GestureUpdate);
1469                                         }
1470                                 }
1471
1472                                 prev_cx = cx;
1473                                 prev_cy = cy;
1474                                 mbits = 0;
1475                         }
1476                         break;
1477
1478                 case ET_ButtonRelease:
1479                         if( state != GestureEnd && num_pressed >= 2)
1480                         {
1481 #ifdef __DETAIL_DEBUG__
1482                                 XDBG_DEBUG(MGEST, "[R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1483 #endif//__DETAIL_DEBUG__
1484                                 goto cleanup_pan;
1485                         }
1486
1487                         if( g_pGesture->num_pressed )
1488                                 break;
1489
1490                         goto cleanup_pan;
1491                         break;
1492         }
1493
1494         return;
1495
1496 cleanup_pan:
1497         g_pGesture->filter_mask |= PanFilterMask;
1498         if( state == GestureBegin || state == GestureUpdate )
1499         {
1500                 state = GestureEnd;
1501                 if( GestureHasFingerEventMask(GestureNotifyPan, num_pressed) )
1502                 {
1503                         GestureHandleGesture_Pan(num_pressed, (short int)(cx-prev_cx), (short int)(cy-prev_cy), direction, distance, GetTimeInMillis()-prev_time, GestureEnd);
1504                 }
1505         }
1506         else if(g_pGesture->num_pressed > 1)
1507         {
1508                 if(!(g_pGesture->filter_mask & PinchRotationFilterMask))
1509                 {
1510                         base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1511                         prev_cx = base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1512                         prev_cy = base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1513                         prev_time = base_time = GetTimeInMillis();
1514                         base_box_ext.x1 = base_cx-PAN_MOVE_THRESHOLD;
1515                         base_box_ext.y1 = base_cy-PAN_MOVE_THRESHOLD;
1516                         base_box_ext.x2 = base_cx+PAN_MOVE_THRESHOLD;
1517                         base_box_ext.y2 = base_cy+PAN_MOVE_THRESHOLD;
1518                         g_pGesture->filter_mask &= ~PanFilterMask;
1519                         return;
1520                 }
1521                 g_pGesture->recognized_gesture &= ~PanFilterMask;
1522         }
1523
1524         num_pressed = 0;
1525         base_area_size = 0;
1526         base_time = 0;
1527         mbits = 0;
1528         time_checked = 0;
1529         state = GestureEnd;
1530         cx = cy = 0;
1531         prev_time = 0;
1532         base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
1533         if( pan_event_timer )
1534         {
1535                 TimerCancel(pan_event_timer);
1536                 pan_event_timer = NULL;
1537         }
1538         return;
1539 }
1540
1541 void
1542 GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1543 {
1544         static int num_pressed = 0;
1545         static int base_area_size = 0;
1546
1547         static Time base_time = 0;
1548         Time current_time;
1549
1550         int cx, cy;
1551         int area_size;
1552
1553         static int state = GestureEnd;
1554         static int mbits = 0;
1555         static int base_cx;
1556         static int base_cy;
1557         static pixman_box16_t base_box_ext;
1558
1559         static int tap_repeat = 0;
1560         static int prev_tap_repeat = 0;
1561         static int prev_num_pressed = 0;
1562
1563         static OsTimerPtr tap_event_timer = NULL;
1564         static int event_type = GestureNotifyTap;
1565
1566         if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1
1567 #ifdef _F_SUPPORT_BEZEL_FLICK_
1568                 || g_pGesture->bezel_recognized_mask)
1569 #else
1570                 )
1571 #endif
1572                 goto cleanup_tap;
1573
1574         if( timer_expired )
1575         {
1576 #ifdef __DETAIL_DEBUG__
1577                 XDBG_DEBUG(MGEST, "[Timer] state=%d\n", state);
1578 #endif//__DETAIL_DEBUG__
1579
1580                 switch( state )
1581                 {
1582                         case GestureBegin://first tap initiation check
1583                                 if( num_pressed )
1584                                 {
1585 #ifdef __DETAIL_DEBUG__
1586                                         XDBG_DEBUG(MGEST, "[Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", tap_repeat, num_pressed, tap_repeat);
1587 #endif//__DETAIL_DEBUG__
1588                                         state = GestureEnd;
1589                                         goto cleanup_tap;
1590                                 }
1591                                 break;
1592
1593                         case GestureUpdate:
1594                                 if( tap_repeat <= 1 )
1595                                 {
1596 #ifdef __DETAIL_DEBUG__
1597                                         XDBG_DEBUG(MGEST, "[Timer][state=2] %d finger SINGLE TAP !(ignored)\n", prev_num_pressed);
1598 #endif//__DETAIL_DEBUG__
1599                                         state = GestureEnd;
1600                                         goto cleanup_tap;
1601                                 }
1602
1603 #ifdef __DETAIL_DEBUG__
1604                                 XDBG_DEBUG(MGEST, "[Timer][state=2]  tap_repeat=%d, prev_tap_repeat=%d, num_pressed=%d\n", tap_repeat, prev_tap_repeat, num_pressed);
1605 #endif//__DETAIL_DEBUG__
1606                                 if( GestureHasFingerEventMask(GestureNotifyTap, prev_num_pressed) )
1607                                 {
1608                                         if(prev_num_pressed == 2 && tap_repeat == 2)
1609                                         {
1610                                                 g_pGesture->zoom_enabled = (g_pGesture->zoom_enabled + 1)%2;
1611                                                 if(g_pGesture->zoom_enabled == 1)
1612                                                 {
1613                                                         g_pGesture->recognized_gesture |= TapFilterMask;
1614                                                 }
1615                                         }
1616                                         GestureHandleGesture_Tap(prev_num_pressed, tap_repeat, base_cx, base_cy);
1617                                 }
1618                                 goto cleanup_tap;
1619                                 break;
1620                 }
1621
1622                 return;
1623         }
1624
1625         switch( type )
1626         {
1627                 case ET_ButtonPress:
1628                         g_pGesture->fingers[idx].flags |= PressFlagTap;
1629
1630                         if( g_pGesture->num_pressed < 2 )
1631                                 return;
1632
1633                         if( !prev_num_pressed && (!base_area_size || g_pGesture->num_pressed > num_pressed) )
1634                         {
1635                                 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1636                                 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1637                                 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1638                                 base_time = GetTimeInMillis();
1639                                 base_box_ext.x1 = base_cx-TAP_MOVE_THRESHOLD;
1640                                 base_box_ext.y1 = base_cy-TAP_MOVE_THRESHOLD;
1641                                 base_box_ext.x2 = base_cx+TAP_MOVE_THRESHOLD;
1642                                 base_box_ext.y2 = base_cy+TAP_MOVE_THRESHOLD;
1643                                 state = GestureBegin;
1644                                 TimerCancel(tap_event_timer);
1645                                 tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->singletap_threshold, GestureEventTimerHandler, (int *)&event_type);
1646                         }
1647
1648                         num_pressed = g_pGesture->num_pressed;
1649
1650                         current_time = GetTimeInMillis();
1651
1652 #ifdef __DETAIL_DEBUG__
1653                         XDBG_DEBUG(MGEST, "[P][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d, base_time=%d, current_time=%d\n", num_pressed, base_area_size, base_cx, base_cy, base_time, current_time);
1654 #endif//__DETAIL_DEBUG__
1655                         break;
1656
1657                 case ET_Motion:
1658                         if( !(g_pGesture->fingers[idx].flags & PressFlagTap ) )
1659                                 break;
1660
1661                         if( num_pressed < 2 )
1662                                 return;
1663
1664 #ifdef __DETAIL_DEBUG__
1665                         XDBG_DEBUG(MGEST, "[M][num_pressed=%d] g_pGesture->num_pressed: %d\n", num_pressed, g_pGesture->num_pressed);
1666 #endif//__DETAIL_DEBUG__
1667
1668                         if( num_pressed != g_pGesture->num_pressed )
1669                         {
1670 #ifdef __DETAIL_DEBUG__
1671                                 XDBG_DEBUG(MGEST, "[M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1672 #endif//__DETAIL_DEBUG__
1673                                 //goto cleanup_tap;
1674                                 break;
1675                         }
1676
1677                         mbits |= (1 << idx);
1678                         if( mbits == (pow(2, num_pressed)-1) )
1679                         {
1680                                 area_size = AREA_SIZE(&g_pGesture->area.extents);
1681                                 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1682                                 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1683 #ifdef __DETAIL_DEBUG__
1684                                 XDBG_DEBUG(MGEST, "[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));
1685                                 XDBG_DEBUG(MGEST, "[M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1686                                 XDBG_DEBUG(MGEST, "[M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1687 #endif//__DETAIL_DEBUG__
1688
1689                                 if( ABS(base_area_size-area_size) >= TAP_AREA_THRESHOLD )
1690                                 {
1691 #ifdef __DETAIL_DEBUG__
1692                                         XDBG_DEBUG(MGEST, "[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));
1693 #endif//__DETAIL_DEBUG__
1694                                         goto cleanup_tap;
1695                                 }
1696
1697                                 if( !INBOX(&base_box_ext, cx, cy) )
1698                                 {
1699 #ifdef __DETAIL_DEBUG__
1700                                         XDBG_DEBUG(MGEST, "[M] current center coordinates is not in base coordinates box !\n");
1701 #endif//__DETAIL_DEBUG__
1702                                         goto cleanup_tap;
1703                                 }
1704                         }
1705                         break;
1706
1707                 case ET_ButtonRelease:
1708                         if( g_pGesture->num_pressed )
1709                         {
1710                                 break;
1711                         }
1712
1713                         if( !tap_repeat )
1714                         {
1715                                 prev_num_pressed = num_pressed;
1716                         }
1717
1718                         prev_tap_repeat = tap_repeat;
1719                         tap_repeat++;
1720                         g_pGesture->tap_repeated = tap_repeat;
1721
1722 #ifdef __DETAIL_DEBUG__
1723                         XDBG_DEBUG(MGEST, "[R] tap_repeat=%d, prev_tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, prev_tap_repeat, num_pressed, prev_num_pressed);
1724 #endif//__DETAIL_DEBUG__
1725
1726                         if( num_pressed != prev_num_pressed || !GestureHasFingerEventMask(GestureNotifyTap, num_pressed) )
1727                         {
1728 #ifdef __DETAIL_DEBUG__
1729                                 XDBG_DEBUG(MGEST, "[R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
1730                                         num_pressed, prev_num_pressed, num_pressed);
1731 #endif//__DETAIL_DEBUG__
1732                                 goto cleanup_tap;
1733                         }
1734
1735                         if( tap_repeat < MAX_TAP_REPEATS )
1736                         {
1737                                 state = GestureUpdate;
1738                                 TimerCancel(tap_event_timer);
1739                                 tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->doubletap_threshold, GestureEventTimerHandler, (int *)&event_type);
1740                                 num_pressed = 0;
1741                                 break;
1742                         }
1743
1744 #ifdef __DETAIL_DEBUG__
1745                         XDBG_DEBUG(MGEST, "[R] %d finger %s\n", num_pressed, (tap_repeat==2) ? "DBL_TAP" : "TRIPLE_TAP");
1746 #endif//__DETAIL_DEBUG__
1747
1748                         if( GestureHasFingerEventMask(GestureNotifyTap, num_pressed) )
1749                                 GestureHandleGesture_Tap(num_pressed, tap_repeat, base_cx, base_cy);
1750
1751                         if( tap_repeat >= MAX_TAP_REPEATS )
1752                         {
1753                                 goto cleanup_tap;
1754                         }
1755
1756                         prev_num_pressed = num_pressed;
1757                         num_pressed = 0;
1758                         break;
1759         }
1760
1761         return;
1762
1763 cleanup_tap:
1764
1765         if( GestureEnd == state )
1766                 g_pGesture->recognized_gesture &= ~TapFilterMask;
1767         g_pGesture->filter_mask |= TapFilterMask;
1768
1769         if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
1770         {
1771 #ifdef __DETAIL_DEBUG__
1772                 XDBG_DEBUG(MGEST, "[cleanup] GestureFlushOrDrop() !\n");
1773 #endif//__DETAIL_DEBUG__
1774
1775                 if( ERROR_INVALPTR == GestureFlushOrDrop() )
1776                 {
1777                         GestureControl(g_pGesture->this_device, DEVICE_OFF);
1778                 }
1779         }
1780
1781         num_pressed = 0;
1782         tap_repeat = 0;
1783         g_pGesture->tap_repeated = 0;
1784         prev_num_pressed = 0;
1785         mbits = 0;
1786         base_time = 0;
1787         state = GestureEnd;
1788         TimerCancel(tap_event_timer);
1789         return;
1790 }
1791
1792 void
1793 GestureRecognize_GroupTapNHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1794 {
1795         static int num_pressed = 0;
1796         static int base_area_size = 0;
1797         static Time base_time = 0;
1798         static int base_cx;
1799         static int base_cy;
1800         int cx, cy;
1801         static pixman_box16_t base_box_ext;
1802         int area_size;
1803         static int mbits = 0;
1804
1805         static int tap_repeat = 0;
1806         static int prev_num_pressed = 0;
1807
1808         static OsTimerPtr tapnhold_event_timer = NULL;
1809         static int event_type = GestureNotifyTapNHold;
1810         static int state = GestureEnd;
1811
1812         Time interval = 0;
1813         Time holdtime = 0;
1814
1815         if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1
1816 #ifdef _F_SUPPORT_BEZEL_FLICK_
1817                 || g_pGesture->bezel_recognized_mask)
1818 #else
1819                 )
1820 #endif
1821                 goto cleanup_tapnhold;
1822
1823         if( timer_expired )
1824         {
1825                 if( (state == GestureEnd) && num_pressed )
1826                 {
1827 #ifdef __DETAIL_DEBUG__
1828                         XDBG_DEBUG(MGEST, "[Timer][state=%d] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", GestureEnd, tap_repeat, num_pressed, tap_repeat);
1829 #endif//__DETAIL_DEBUG__
1830                         state = 0;
1831                         goto cleanup_tapnhold;
1832                 }
1833
1834                 if( state == GestureDone )
1835                 {
1836 #ifdef __DETAIL_DEBUG__
1837                         XDBG_DEBUG(MGEST, "[Timer][state=%d] Interval between Tap and Hold is too long !\n");
1838 #endif//__DETAIL_DEBUG__
1839                         goto cleanup_tapnhold;
1840                 }
1841
1842 #ifdef __DETAIL_DEBUG__
1843                 switch( state )
1844                 {
1845                         case GestureBegin:
1846                                 XDBG_DEBUG(MGEST, "[Timer] TapNHold Begin !\n");
1847                                 break;
1848
1849                         case GestureUpdate:
1850                                 XDBG_DEBUG(MGEST, "[Timer] TapNHold Update !\n");
1851                                 break;
1852                 }
1853 #endif//__DETAIL_DEBUG__
1854
1855                 if( GestureHasFingerEventMask(GestureNotifyTapNHold, prev_num_pressed) )
1856                 {
1857                         GestureHandleGesture_TapNHold(prev_num_pressed, base_cx, base_cy, interval, holdtime, state);
1858                         tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1859                 }
1860                 else
1861                 {
1862 #ifdef __DETAIL_DEBUG__
1863                         XDBG_DEBUG(MGEST, "[Timer] %d finger TapNHold event was not grabbed/selected !\n", prev_num_pressed);
1864 #endif//__DETAIL_DEBUG__
1865                         goto cleanup_tapnhold;
1866                 }
1867
1868                 if( state <= GestureBegin )
1869                         state++;
1870                 return;
1871         }
1872
1873         switch( type )
1874         {
1875                 case ET_ButtonPress:
1876                         g_pGesture->fingers[idx].flags |= PressFlagTapNHold;
1877
1878                         if( g_pGesture->num_pressed < 2 )
1879                                 return;
1880
1881                         //if( !prev_num_pressed && (!base_area_size || g_pGesture->num_pressed > num_pressed) )
1882                         if( !base_area_size || g_pGesture->num_pressed > num_pressed )
1883                         {
1884
1885                                 if( state == GestureUpdate )
1886                                 {
1887 #ifdef __DETAIL_DEBUG__
1888                                         XDBG_DEBUG(MGEST, "[P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1889 #endif//__DETAIL_DEBUG__
1890                                         goto cleanup_tapnhold;
1891                                 }
1892
1893                                 if( state == GestureDone )
1894                                         state = GestureBegin;
1895
1896                                 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1897                                 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1898                                 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1899                                 base_time = GetTimeInMillis();
1900                                 base_box_ext.x1 = base_cx-TAPNHOLD_MOVE_THRESHOLD;
1901                                 base_box_ext.y1 = base_cy-TAPNHOLD_MOVE_THRESHOLD;
1902                                 base_box_ext.x2 = base_cx+TAPNHOLD_MOVE_THRESHOLD;
1903                                 base_box_ext.y2 = base_cy+TAPNHOLD_MOVE_THRESHOLD;
1904                                 if( state == GestureEnd )
1905                                         tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_TAP_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1906                                 else
1907                                 {
1908                                         TimerCancel(tapnhold_event_timer);
1909                                         tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1910                                 }
1911 #ifdef __DETAIL_DEBUG__
1912                                 XDBG_DEBUG(MGEST, "[P] Create Timer !(state=%d)\n", state);
1913 #endif//__DETAIL_DEBUG__
1914                         }
1915
1916                         num_pressed = g_pGesture->num_pressed;
1917
1918 #ifdef __DETAIL_DEBUG__
1919                         XDBG_DEBUG(MGEST, "[P][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d, base_time=%d\n", num_pressed, base_area_size, base_cx, base_cy, base_time);
1920 #endif//__DETAIL_DEBUG__
1921                         break;
1922
1923                 case ET_Motion:
1924                         if( !(g_pGesture->fingers[idx].flags & PressFlagTapNHold ) )
1925                                 break;
1926
1927                         if( num_pressed < 2 )
1928                                 return;
1929
1930                         if( num_pressed != g_pGesture->num_pressed )
1931                         {
1932                                 if( state != GestureEnd )
1933                                 {
1934 #ifdef __DETAIL_DEBUG__
1935                                 XDBG_DEBUG(MGEST, "[M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1936 #endif//__DETAIL_DEBUG__
1937                                         goto cleanup_tapnhold;
1938                                 }
1939 #ifdef __DETAIL_DEBUG__
1940                                 XDBG_DEBUG(MGEST, "[M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1941 #endif//__DETAIL_DEBUG__
1942                                 //goto cleanup_tapnhold;
1943                         }
1944
1945                         mbits |= (1 << idx);
1946                         if( mbits == (pow(2, num_pressed)-1) )
1947                         {
1948                                 area_size = AREA_SIZE(&g_pGesture->area.extents);
1949                                 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1950                                 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1951 #ifdef __DETAIL_DEBUG__
1952                                 XDBG_DEBUG(MGEST, "[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));
1953                                 XDBG_DEBUG(MGEST, "[M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1954                                 XDBG_DEBUG(MGEST, "[M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1955 #endif//__DETAIL_DEBUG__
1956
1957                                 if( ABS(base_area_size-area_size) >= TAPNHOLD_AREA_THRESHOLD )
1958                                 {
1959 #ifdef __DETAIL_DEBUG__
1960                                         XDBG_DEBUG(MGEST, "[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));
1961 #endif//__DETAIL_DEBUG__
1962                                         goto cleanup_tapnhold;
1963                                 }
1964
1965                                 if( !INBOX(&base_box_ext, cx, cy) )
1966                                 {
1967 #ifdef __DETAIL_DEBUG__
1968                                         XDBG_DEBUG(MGEST, "[M] current center coordinates is not in base coordinates box !\n");
1969 #endif//__DETAIL_DEBUG__
1970                                         goto cleanup_tapnhold;
1971                                 }
1972                         }
1973                         break;
1974
1975                 case ET_ButtonRelease:
1976                         if( state != GestureEnd && num_pressed >= 2)
1977                         {
1978 #ifdef __DETAIL_DEBUG__
1979                                 XDBG_DEBUG(MGEST, "[R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1980 #endif//__DETAIL_DEBUG__
1981                                 goto cleanup_tapnhold;
1982                         }
1983
1984                         if( g_pGesture->num_pressed )
1985                                 break;
1986
1987                         if( !tap_repeat )
1988                         {
1989                                 prev_num_pressed = num_pressed;
1990                         }
1991
1992                         tap_repeat++;
1993
1994 #ifdef __DETAIL_DEBUG__
1995                         XDBG_DEBUG(MGEST, "[R] tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, num_pressed, prev_num_pressed);
1996 #endif//__DETAIL_DEBUG__
1997
1998                         if( num_pressed != prev_num_pressed || !GestureHasFingerEventMask(GestureNotifyTapNHold, num_pressed) )
1999                         {
2000 #ifdef __DETAIL_DEBUG__
2001                                 XDBG_DEBUG(MGEST, "[R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
2002                                         num_pressed, prev_num_pressed, num_pressed);
2003 #endif//__DETAIL_DEBUG__
2004                                 goto cleanup_tapnhold;
2005                         }
2006
2007                         if( tap_repeat > 1 )
2008                         {
2009 #ifdef __DETAIL_DEBUG__
2010                                 XDBG_DEBUG(MGEST, "[R] Tap events(tap_repeat=%d) were put twice or more !(ignored)\n", tap_repeat);
2011 #endif//__DETAIL_DEBUG__
2012                                 goto cleanup_tapnhold;
2013                         }
2014
2015                         prev_num_pressed = num_pressed;
2016                         num_pressed = 0;
2017                         state = GestureDone;
2018
2019                         TimerCancel(tapnhold_event_timer);
2020                         tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_INTV_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
2021
2022 #ifdef __DETAIL_DEBUG__
2023                         XDBG_DEBUG(MGEST, "[R][Last] state=%d, tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", state,  tap_repeat, num_pressed, prev_num_pressed);
2024 #endif//__DETAIL_DEBUG__
2025                         break;
2026         }
2027
2028         return;
2029
2030 cleanup_tapnhold:
2031
2032         if( state == GestureUpdate )
2033         {
2034                 state = GestureEnd;
2035                 if( GestureHasFingerEventMask(GestureNotifyTapNHold, prev_num_pressed) )
2036                 {
2037                         GestureHandleGesture_TapNHold(prev_num_pressed, base_cx, base_cy, interval, holdtime, state);
2038                 }
2039         }
2040         else
2041         {
2042                 g_pGesture->recognized_gesture &= ~TapNHoldFilterMask;
2043         }
2044
2045         g_pGesture->filter_mask |= TapNHoldFilterMask;
2046         if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
2047         {
2048 #ifdef __DETAIL_DEBUG__
2049                 XDBG_DEBUG(MGEST, "[cleanup] GestureFlushOrDrop() !\n");
2050 #endif//__DETAIL_DEBUG__
2051
2052                 if( ERROR_INVALPTR == GestureFlushOrDrop() )
2053                 {
2054                         GestureControl(g_pGesture->this_device, DEVICE_OFF);
2055                 }
2056         }
2057
2058         TimerCancel(tapnhold_event_timer);
2059         num_pressed = 0;
2060         tap_repeat = 0;
2061         prev_num_pressed = 0;
2062         mbits = 0;
2063         base_time = 0;
2064         state = 0;
2065
2066         return;
2067 }
2068
2069 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
2070 {
2071         static int num_pressed = 0;
2072         static int base_area_size = 0;
2073         static Time base_time = 0;
2074         static int base_cx;
2075         static int base_cy;
2076         int cx, cy;
2077         static pixman_box16_t base_box_ext;
2078         int area_size;
2079         static int state = GestureEnd;
2080
2081         static OsTimerPtr hold_event_timer = NULL;
2082         static int event_type = GestureNotifyHold;
2083
2084         if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1
2085 #ifdef _F_SUPPORT_BEZEL_FLICK_
2086                 || g_pGesture->bezel_recognized_mask)
2087 #else
2088                 )
2089 #endif
2090                 goto cleanup_hold;
2091
2092         if( timer_expired )
2093         {
2094                 if( state <= GestureBegin )
2095                         state++;
2096
2097 #ifdef __DETAIL_DEBUG__
2098                 switch( state )
2099                 {
2100                         case GestureBegin:
2101                                 XDBG_DEBUG(MGEST, "HOLD Begin !\n");
2102                                 break;
2103
2104                         case GestureUpdate:
2105                                 XDBG_DEBUG(MGEST, "HOLD Update !\n");
2106                                 break;
2107                 }
2108 #endif//__DETAIL_DEBUG__
2109
2110                 if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) )
2111                 {
2112                         GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
2113                         hold_event_timer = TimerSet(hold_event_timer, 0, HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
2114                 }
2115                 return;
2116         }
2117
2118         switch( type )
2119         {
2120                 case ET_ButtonPress:
2121                         g_pGesture->fingers[idx].flags |= PressFlagHold;
2122
2123                         if( g_pGesture->num_pressed < 2 )
2124                                 return;
2125
2126                         if( !base_area_size || g_pGesture->num_pressed > num_pressed )
2127                         {
2128                                 if( state != GestureEnd )
2129                                 {
2130 #ifdef __DETAIL_DEBUG__
2131                                         XDBG_DEBUG(MGEST, "[P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
2132 #endif//__DETAIL_DEBUG__
2133                                         goto cleanup_hold;
2134                                 }
2135
2136                                 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
2137                                 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
2138                                 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
2139                                 base_time = GetTimeInMillis();
2140                                 base_box_ext.x1 = base_cx-HOLD_MOVE_THRESHOLD;
2141                                 base_box_ext.y1 = base_cy-HOLD_MOVE_THRESHOLD;
2142                                 base_box_ext.x2 = base_cx+HOLD_MOVE_THRESHOLD;
2143                                 base_box_ext.y2 = base_cy+HOLD_MOVE_THRESHOLD;
2144                                 event_type = GestureNotifyHold;
2145                                 hold_event_timer = TimerSet(hold_event_timer, 0, HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
2146                         }
2147                         num_pressed = g_pGesture->num_pressed;
2148
2149 #ifdef __DETAIL_DEBUG__
2150                         XDBG_DEBUG(MGEST, "[P]][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d\n", num_pressed, base_area_size, base_cx, base_cy);
2151 #endif//__DETAIL_DEBUG__
2152                         break;
2153
2154                 case ET_Motion:
2155                         if( !(g_pGesture->fingers[idx].flags & PressFlagHold ) )
2156                                 break;
2157
2158                         if( num_pressed < 2 )
2159                                 return;
2160
2161                         if( num_pressed != g_pGesture->num_pressed )
2162                         {
2163                                 if( state != GestureEnd )
2164                                 {
2165 #ifdef __DETAIL_DEBUG__
2166                                 XDBG_DEBUG(MGEST, "[M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
2167 #endif//__DETAIL_DEBUG__
2168                                         goto cleanup_hold;
2169                                 }
2170 #ifdef __DETAIL_DEBUG__
2171                                 XDBG_DEBUG(MGEST, "[M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
2172 #endif//__DETAIL_DEBUG__
2173                                 //goto cleanup_hold;
2174                         }
2175
2176                         area_size = AREA_SIZE(&g_pGesture->area.extents);
2177                         cx = AREA_CENTER_X(&g_pGesture->area.extents);
2178                         cy = AREA_CENTER_Y(&g_pGesture->area.extents);
2179 #ifdef __DETAIL_DEBUG__
2180                         XDBG_DEBUG(MGEST, "[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));
2181                         XDBG_DEBUG(MGEST, "[M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
2182                         XDBG_DEBUG(MGEST, "[M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
2183 #endif//__DETAIL_DEBUG__
2184
2185                         if( ABS(base_area_size-area_size) >= HOLD_AREA_THRESHOLD )
2186                         {
2187 #ifdef __DETAIL_DEBUG__
2188                                 XDBG_DEBUG(MGEST, "[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));
2189 #endif//__DETAIL_DEBUG__
2190                                 goto cleanup_hold;
2191                         }
2192
2193                         if( !INBOX(&base_box_ext, cx, cy) )
2194                         {
2195 #ifdef __DETAIL_DEBUG__
2196                                 XDBG_DEBUG(MGEST, "[M] current center coordinates is not in base coordinates box !\n");
2197 #endif//__DETAIL_DEBUG__
2198                                 goto cleanup_hold;
2199                         }
2200                         break;
2201
2202                 case ET_ButtonRelease:
2203                         if( state != GestureEnd && num_pressed >= 2)
2204                         {
2205 #ifdef __DETAIL_DEBUG__
2206                                 XDBG_DEBUG(MGEST, "[R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
2207 #endif//__DETAIL_DEBUG__
2208                                 goto cleanup_hold;
2209                         }
2210
2211                         //XDBG_DEBUG(MGEST, "[R] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
2212                         if( g_pGesture->num_pressed )
2213                                 break;
2214
2215                         goto cleanup_hold;
2216                         break;
2217         }
2218
2219         return;
2220
2221 cleanup_hold:
2222
2223         if( state == GestureBegin || state == GestureUpdate )
2224         {
2225                 state = GestureEnd;
2226                 if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) )
2227                 {
2228                         GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
2229                 }
2230         }
2231         else
2232         {
2233                 g_pGesture->recognized_gesture &= ~HoldFilterMask;
2234         }
2235
2236         g_pGesture->filter_mask |= HoldFilterMask;
2237         num_pressed = 0;
2238         base_area_size = 0;
2239         base_time = 0;
2240         base_cx = base_cy = 0;
2241         state = GestureEnd;
2242         base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
2243         TimerCancel(hold_event_timer);
2244         return;
2245 }
2246
2247 #ifdef _F_SUPPORT_BEZEL_FLICK_
2248 int
2249 GestureBezelAngleRecognize(int type, int distance, double angle)
2250 {
2251         if (distance < g_pGesture->bezel.flick_distance)
2252         {
2253 #ifdef __BEZEL_DEBUG__
2254                 XDBG_DEBUG(MGEST, "distance(%d) < flick_distance(%d)\n", distance, g_pGesture->bezel.flick_distance);
2255 #endif//__BEZEL_DEBUG__
2256                 return 0;
2257         }
2258         switch(type)
2259         {
2260                 case BEZEL_TOP_LEFT:
2261                         break;
2262                 case BEZEL_TOP_RIGHT:
2263                         break;
2264                 case BEZEL_BOTTOM_LEFT:
2265                         if( (g_pGesture->bezel.min_rad< angle) && (angle < g_pGesture->bezel.max_rad) )
2266                         {
2267 #ifdef __BEZEL_DEBUG__
2268                                 XDBG_DEBUG(MGEST, "bottom_left bezel success....\n");
2269 #endif//__BEZEL_DEBUG__
2270                                 return 1;
2271                         }
2272                         else
2273                         {
2274 #ifdef __BEZEL_DEBUG__
2275                                 XDBG_DEBUG(MGEST, "bottom_left bezel failed....\n");
2276 #endif//__BEZEL_DEBUG__
2277                                 return 0;
2278                         }
2279                 case BEZEL_BOTTOM_RIGHT:
2280                         if( (g_pGesture->bezel.min_180_rad< angle) && (angle < g_pGesture->bezel.max_180_rad))
2281                         {
2282 #ifdef __BEZEL_DEBUG__
2283                                 XDBG_DEBUG(MGEST, "bottom_right bezel success...\n");
2284 #endif//__BEZEL_DEBUG__
2285                                 return 1;
2286                         }
2287                         else
2288                         {
2289 #ifdef __BEZEL_DEBUG__
2290                                 XDBG_DEBUG(MGEST, "bottom_right bezel failed....\n");
2291 #endif//__BEZEL_DEBUG__
2292                                 return 0;
2293                         }
2294                 default:
2295                         return 0;
2296         }
2297         return 0;
2298 }
2299 #endif
2300
2301 static inline void
2302 GestureEnableDisable()
2303 {
2304         if((g_pGesture->grabMask) || (g_pGesture->lastSelectedWin != None))
2305         {
2306                 GestureEnable(1, FALSE, g_pGesture->this_device);
2307         }
2308         else
2309         {
2310                 GestureEnable(0, FALSE, g_pGesture->this_device);
2311         }
2312 }
2313
2314 void
2315 GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent)
2316 {
2317         g_pGesture->grabMask = *pGrabMask;
2318         g_pGesture->GrabEvents = (GestureGrabEventPtr)pGrabEvent;
2319         GestureEnableDisable();
2320 }
2321
2322 void
2323 GestureCbEventsSelected(Window win, Mask *pEventMask)
2324 {
2325         g_pGesture->lastSelectedWin = win;
2326         g_pGesture->lastSelectedMask = (pEventMask) ? *pEventMask : 0;
2327         GestureEnableDisable();
2328 }
2329
2330 WindowPtr
2331 GestureGetEventsWindow(void)
2332 {
2333         Mask mask;
2334         WindowPtr pWin;
2335
2336         pWin = GestureWindowOnXY(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py);
2337
2338         if( pWin )
2339         {
2340 #ifdef __DETAIL_DEBUG__
2341                 XDBG_DEBUG(MGEST, "pWin->drawable.id=0x%x\n", pWin->drawable.id);
2342 #endif//__DETAIL_DEBUG__
2343                 g_pGesture->gestureWin = pWin->drawable.id;
2344         }
2345         else
2346         {
2347 #ifdef __DETAIL_DEBUG__
2348                 XDBG_DEBUG(MGEST, "GestureWindowOnXY returns NULL !\n");
2349 #endif//__DETAIL_DEBUG__
2350                 return NULL;
2351         }
2352         if(g_pGesture->gestureWin == g_pGesture->lastSelectedWin)
2353         {
2354                 g_pGesture->eventMask = g_pGesture->lastSelectedMask;
2355                 goto nonempty_eventmask;
2356         }
2357
2358         //check selected event(s)
2359         if( !GestureHasSelectedEvents(pWin, &g_pGesture->eventMask) )
2360         {
2361                 g_pGesture->eventMask = 0;
2362         }
2363         else
2364         {
2365                 g_pGesture->lastSelectedWin = g_pGesture->gestureWin;
2366                 g_pGesture->lastSelectedMask = g_pGesture->eventMask;
2367         }
2368
2369         if( !g_pGesture->eventMask && !g_pGesture->grabMask)
2370         {
2371 #ifdef __DETAIL_DEBUG__
2372                 XDBG_DEBUG(MGEST, "No grabbed events or no events were selected for window(0x%x) !\n", pWin->drawable.id);
2373 #endif//__DETAIL_DEBUG__
2374                 return NULL;
2375         }
2376
2377 nonempty_eventmask:
2378
2379 #ifdef __DETAIL_DEBUG__
2380         XDBG_DEBUG(MGEST, "g_pGesture->eventMask=0x%x\n", g_pGesture->eventMask);
2381 #endif//__DETAIL_DEBUG__
2382
2383         mask = (GESTURE_FILTER_MASK_ALL & ~(g_pGesture->grabMask | g_pGesture->eventMask));
2384
2385 #ifdef __DETAIL_DEBUG__
2386 #ifdef _F_SUPPORT_BEZEL_FLICK_
2387         XDBG_DEBUG(MGEST, "g_pGesture->filter_mask=0x%x, mask=0x%x, palm_filter_mask=0x%x bezel_filter_mask=0x%x\n", g_pGesture->filter_mask, mask, g_pGesture->palm_filter_mask, g_pGesture->bezel_filter_mask);
2388 #else
2389         XDBG_DEBUG(MGEST, "g_pGesture->filter_mask=0x%x, mask=0x%x, palm_filter_mask=0x%x\n", g_pGesture->filter_mask, mask, g_pGesture->palm_filter_mask);
2390 #endif
2391 #endif//__DETAIL_DEBUG__
2392         g_pGesture->palm_filter_mask = 0;
2393         if(mask & HoldFilterMask)
2394                 g_pGesture->palm_filter_mask |= PalmHoldFilterMask;
2395         if(mask & FlickFilterMask)
2396         {
2397                 g_pGesture->palm_filter_mask |= PalmFlickHorizFilterMask;
2398                 g_pGesture->palm_filter_mask |= PalmFlickVertiFilterMask;
2399 #ifdef _F_SUPPORT_BEZEL_FLICK_
2400                 g_pGesture->bezel_filter_mask |= BezelFlickFilterMask;
2401 #endif
2402         }
2403         if(!(mask & FlickFilterMask))
2404         {
2405 #ifdef _F_SUPPORT_BEZEL_FLICK_
2406                 if(!(g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[1].window))
2407                 {
2408                         g_pGesture->bezel_filter_mask |= BezelFlickFilterMask;
2409                 }
2410                 else
2411 #endif
2412                 if(!(g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[0].window))
2413                 {
2414                         g_pGesture->palm_filter_mask |= PalmFlickHorizFilterMask;
2415                         g_pGesture->palm_filter_mask |= PalmFlickVertiFilterMask;
2416                 }
2417         }
2418         if(!g_pGesture->palm.palmflag)
2419         {
2420                 if(!GestureHasFingersEvents(HoldFilterMask))
2421                         mask |= HoldFilterMask;
2422                 if(!GestureHasFingersEvents(FlickFilterMask))
2423                         mask |= FlickFilterMask;
2424                 g_pGesture->filter_mask = mask;
2425         }
2426 #ifdef __DETAIL_DEBUG__
2427 #ifdef _F_SUPPORT_BEZEL_FLICK_
2428         XDBG_DEBUG(MGEST, "g_pGesture->filter_mask=0x%x, palm_filter_mask: 0x%x, bezel_filter_mask=0x%x\n", g_pGesture->filter_mask, g_pGesture->palm_filter_mask, g_pGesture->bezel_filter_mask);
2429 #else
2430         XDBG_DEBUG(MGEST, "g_pGesture->filter_mask=0x%x, palm_filter_mask: 0x%x\n", g_pGesture->filter_mask, g_pGesture->palm_filter_mask);
2431 #endif
2432 #endif//__DETAIL_DEBUG__
2433
2434         return pWin;
2435 }
2436
2437 static Bool
2438 GestureHasFingersEvents(int eventType)
2439 {
2440         int i=0;
2441         Mask eventmask = (1L << eventType);
2442         for(i=2; i<MAX_MT_DEVICES; i++)
2443         {
2444                 if( (g_pGesture->grabMask & eventmask) &&
2445                 (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[i].window != None) )
2446                 {
2447 #ifdef __DETAIL_DEBUG__
2448                         XDBG_DEBUG(MGEST, "TRUE !! Has grabMask\n");
2449 #endif//__DETAIL_DEBUG__
2450                         return TRUE;
2451                 }
2452         }
2453         return FALSE;
2454 }
2455
2456 static CARD32
2457 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2458 {
2459         int event_type = *(int *)arg;
2460
2461         switch( event_type )
2462         {
2463                 case GestureNotifyHold:
2464 #ifdef __DETAIL_DEBUG__
2465                         XDBG_DEBUG(MGEST, "GestureNotifyHold (event_type = %d)\n", event_type);
2466 #endif//__DETAIL_DEBUG__
2467                         GestureRecognize_GroupHold(event_type, NULL, NULL, 0, 1);
2468                         break;
2469
2470                 case GestureNotifyPan:
2471 #ifdef __DETAIL_DEBUG__
2472                         XDBG_DEBUG(MGEST, "GestureNotifyPan (event_type = %d)\n", event_type);
2473 #endif//__DETAIL_DEBUG__
2474                         GestureRecognize_GroupPan(event_type, NULL, NULL, 0, 1);
2475                         break;
2476
2477                 case GestureNotifyTap:
2478 #ifdef __DETAIL_DEBUG__
2479                         XDBG_DEBUG(MGEST, "GestureNotifyTap (event_type = %d)\n", event_type);
2480 #endif//__DETAIL_DEBUG__
2481                         GestureRecognize_GroupTap(event_type, NULL, NULL, 0, 1);
2482                         break;
2483
2484                 case GestureNotifyTapNHold:
2485 #ifdef __DETAIL_DEBUG__
2486                         XDBG_DEBUG(MGEST, "GestureNotifyTapNHold (event_type = %d)\n", event_type);
2487 #endif//__DETAIL_DEBUG__
2488                         GestureRecognize_GroupTapNHold(event_type, NULL, NULL, 0, 1);
2489                         break;
2490
2491                 case GestureNotifyPinchRotation:
2492 #ifdef __DETAIL_DEBUG__
2493                         XDBG_DEBUG(MGEST, "GestureNotifyPinchRotation (event_type = %d)\n", event_type);
2494 #endif//__DETAIL_DEBUG__
2495                         GestureRecognize_GroupPinchRotation(event_type, NULL, NULL, 0, 1);
2496                         break;
2497
2498                 default:
2499 #ifdef __DETAIL_DEBUG__
2500                         XDBG_DEBUG(MGEST, "unknown event_type (=%d)\n", event_type);
2501 #endif//__DETAIL_DEBUG__
2502                         if(timer)
2503                                 XDBG_INFO(MGEST, "timer=%x\n", (unsigned int)timer);
2504         }
2505
2506         return 0;
2507 }
2508
2509 static CARD32
2510 GesturePalmEventTimerHandler(OsTimerPtr timer,CARD32 time,pointer arg)
2511 {
2512         int event_type = *(int *)arg;
2513
2514         switch( event_type )
2515         {
2516                 case GestureNotifyHold:
2517 #ifdef __PALM_DETAIL_LOG__
2518                         XDBG_DEBUG(MGEST, "GestureNotifyHold (event_type = %d)\n", event_type);
2519 #endif//__PALM_DETAIL_LOG__
2520                         GesturePalmRecognize_Hold(event_type, 0, 1);
2521                         break;
2522
2523                 default:
2524 #ifdef __PALM_DETAIL_LOG__
2525                         XDBG_DEBUG(MGEST, "unknown event_type (=%d)\n", event_type);
2526 #endif//__PALM_DETAIL_LOG__
2527                         break;
2528         }
2529
2530         return 0;
2531 }
2532
2533 #ifdef _F_SUPPORT_BEZEL_FLICK_
2534 static CARD32
2535 GestureBezelSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2536 {
2537         BezelFlickStatusPtr pBezel = &g_pGesture->bezel;
2538
2539         if( pBezel->is_active != BEZEL_NONE )
2540         {
2541                 pBezel->is_active = BEZEL_END;
2542 #ifdef __BEZEL_DEBUG__
2543                 XDBG_DEBUG(MGEST, "end\n");
2544 #endif//__BEZEL_DEBUG__
2545         }
2546         return 0;
2547 }
2548 #endif
2549
2550 static CARD32
2551 GestureSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2552 {
2553         g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
2554         g_pGesture->recognized_gesture = 0;
2555
2556         if( ERROR_INVALPTR == GestureFlushOrDrop() )
2557         {
2558                 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2559         }
2560
2561 #ifdef __DETAIL_DEBUG__
2562         XDBG_DEBUG(MGEST, "expired !\n");
2563 #endif//__DETAIL_DEBUG__
2564
2565         return 0;
2566 }
2567
2568 static CARD32
2569 GesturePalmSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2570 {
2571         PalmStatusPtr pPalm = &g_pGesture->palm;
2572         if(pPalm->palmflag || (pPalm->biggest_tmajor >= PALM_FLICK_FINGER_MIN_TOUCH_MAJOR))
2573         {
2574                 pPalm->single_timer_expired = 0;
2575                 return 0;
2576         }
2577
2578         pPalm->single_timer_expired = 1;
2579 #ifdef __PALM_DETAIL_LOG__
2580         XDBG_DEBUG(MGEST, "palm expired !\n");
2581 #endif//__DETAIL_DEBUG__
2582
2583         return 0;
2584 }
2585
2586 static CARD32
2587 GesturePalmHoldRapidHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2588 {
2589 #ifdef __PALM_DETAIL_LOG__
2590         XDBG_DEBUG(MGEST, "[%d] rapid timer in.....\n", __LINE__);
2591 #endif
2592         GesturePalmRecognize_Hold(0, 0, 0);
2593         return 0;
2594 }
2595
2596
2597 static int
2598 GesturePalmGetHorizIndexWithX(int x, int type)
2599 {
2600         int i;
2601         int ret_idx = -1;
2602         static int pressed_idx = -1;
2603         PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
2604
2605         for(i = 0 ; i < PALM_HORIZ_ARRAY_COUNT ; i++)
2606         {
2607 #ifdef __PALM_DETAIL_LOG__
2608                 XDBG_DEBUG(MGEST, "pPalmMisc->horiz_coord[%d]=%d, x=%d\n", i, pPalmMisc->horiz_coord[i], x);
2609 #endif//__PALM_DETAIL_LOG__
2610                 if(x <= pPalmMisc->horiz_coord[i])
2611                 {
2612 #ifdef __PALM_DETAIL_LOG__
2613                         XDBG_DEBUG(MGEST, "index=%d\n", i);
2614 #endif//__PALM_DETAIL_LOG__
2615                         ret_idx = i;
2616                         goto index_check;
2617                 }
2618         }
2619 #ifdef __PALM_DETAIL_LOG__
2620         XDBG_DEBUG(MGEST, "Error ! Failed to get horiz coordinate index !\n");
2621 #endif//__PALM_DETAIL_LOG__
2622         return ret_idx;
2623
2624 index_check:
2625
2626         if(type == ET_ButtonPress)
2627         {
2628                 pressed_idx = ret_idx;
2629         }
2630         else if(type == ET_ButtonRelease)
2631         {
2632                 if((pressed_idx <= 1) && (ret_idx >= (PALM_HORIZ_ARRAY_COUNT-2)))
2633                 {
2634 #ifdef __PALM_DETAIL_LOG__
2635                         XDBG_DEBUG(MGEST, "[R] Valid !\n");
2636 #else
2637                         ;
2638 #endif//__PALM_DETAIL_LOG__
2639                 }
2640                 else if((pressed_idx >= (PALM_HORIZ_ARRAY_COUNT-2)) && (ret_idx <= 1))
2641                 {
2642 #ifdef __PALM_DETAIL_LOG__
2643                         XDBG_DEBUG(MGEST, "[R] Valid !\n");
2644 #else
2645                         ;
2646 #endif//__PALM_DETAIL_LOG__
2647                 }
2648                 else
2649                 {
2650 #ifdef __PALM_DETAIL_LOG__
2651                         XDBG_DEBUG(MGEST, "[R] Invalid !(pressed_idx=%d, released_idx=%d\n", pressed_idx, ret_idx);
2652 #endif//__PALM_DETAIL_LOG__
2653                         ret_idx = -1;
2654                 }
2655         }
2656
2657         return ret_idx;
2658 }
2659
2660 static int
2661 GesturePalmGetVertiIndexWithY(int y, int type)
2662 {
2663         int i;
2664         int ret_idx = -1;
2665         static int pressed_idx = -1;
2666         PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
2667
2668         for(i = 0 ; i < PALM_VERTI_ARRAY_COUNT ; i++)
2669         {
2670 #ifdef __PALM_DETAIL_LOG__
2671                 XDBG_DEBUG(MGEST, "pPalmMisc->horiz_coord[%d]=%d, x=%d\n", i, pPalmMisc->horiz_coord[i], y);
2672 #endif//__PALM_DETAIL_LOG__
2673                 if(y <= pPalmMisc->verti_coord[i])
2674                 {
2675 #ifdef __PALM_DETAIL_LOG__
2676                         XDBG_DEBUG(MGEST, "index=%d\n", i);
2677 #endif//__PALM_DETAIL_LOG__
2678                         ret_idx = i;
2679                         goto index_check;
2680                 }
2681         }
2682 #ifdef __PALM_DETAIL_LOG__
2683         XDBG_DEBUG(MGEST, "Error ! Failed to get verti coordinate index !\n");
2684 #endif//__PALM_DETAIL_LOG__
2685         return ret_idx;
2686
2687 index_check:
2688
2689         if(type == ET_ButtonPress)
2690         {
2691                 if((ret_idx <= 1) || (ret_idx >=(PALM_VERTI_ARRAY_COUNT-2)))
2692                 {
2693 #ifdef __PALM_DETAIL_LOG__
2694                         XDBG_DEBUG(MGEST, "[P] Valid !\n");
2695 #endif//__PALM_DETAIL_LOG__
2696                         pressed_idx = ret_idx;
2697                 }
2698                 else
2699                 {
2700 #ifdef __PALM_DETAIL_LOG__
2701                         XDBG_DEBUG(MGEST, "[P] Invalid !(pressed_idx(=%d) must be between 0 and 1 or between 3 and 4\n", pressed_idx);
2702 #endif//__PALM_DETAIL_LOG__
2703                         ret_idx = -1;
2704                 }
2705
2706         }
2707         else if(type == ET_ButtonRelease)
2708         {
2709                 if((pressed_idx <= 1) && (ret_idx >= (PALM_VERTI_ARRAY_COUNT-2)))
2710                 {
2711 #ifdef __PALM_DETAIL_LOG__
2712                         XDBG_DEBUG(MGEST, "[R] Valid !\n");
2713 #else
2714                         ;
2715 #endif//__PALM_DETAIL_LOG__
2716                 }
2717                 else if((pressed_idx >= (PALM_VERTI_ARRAY_COUNT-2)) && (ret_idx <= 1))
2718                 {
2719 #ifdef __PALM_DETAIL_LOG__
2720                         XDBG_DEBUG(MGEST, "[R] Valid !\n");
2721 #else
2722                         ;
2723 #endif//__PALM_DETAIL_LOG__
2724                 }
2725                 else
2726                 {
2727 #ifdef __PALM_DETAIL_LOG__
2728                         XDBG_DEBUG(MGEST, "[R] Invalid !(pressed_idx=%d, released_idx=%d\n", pressed_idx, ret_idx);
2729 #endif//__PALM_DETAIL_LOG__
2730                         ret_idx = -1;
2731                 }
2732         }
2733
2734         return ret_idx;
2735 }
2736
2737 static void
2738 GesturePalmRecognize_Hold(int type, int idx, int timer_expired)
2739 {
2740         static int is_holding = 1;
2741         static int num_pressed = 0;
2742         static Time base_time = 0;
2743         static int cx, cy;
2744         static int base_width_size = 0;
2745
2746         static int state = GestureEnd;
2747         static int false_base_width_size_count = 0;
2748         static int max_num_finger = 0;
2749
2750         static OsTimerPtr palm_hold_event_timer = NULL;
2751         static int event_type = GestureNotifyHold;
2752         PalmStatusPtr pPalm = &g_pGesture->palm;
2753         static int hold_occured = 0;
2754         static int rapid_hold = 0;
2755         static OsTimerPtr palm_hold_rapid_timer = NULL;
2756
2757 #ifdef __PALM_GESTURE_LOG__
2758         XDBG_DEBUG(MGEST, "recognized_palm= 0x%x, palm_filter_mask= 0x%x\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask);
2759         XDBG_DEBUG(MGEST, "num_pressed: %d, cur_touched: %d, palm_flag: %d, is_holding: %d hold_occured %.f\n", num_pressed, pPalm->cur_touched, pPalm->palmflag, is_holding, hold_occured);
2760         XDBG_DEBUG(MGEST, "pPalm->biggest_wmajor: %.f, pPalm->bigger_wmajor: %.f, pPalm->biggest_tmajor: %.f\n", pPalm->biggest_wmajor, pPalm->bigger_wmajor, pPalm->biggest_tmajor);
2761 #endif
2762         if(g_pGesture->enqueue_fulled == 1)
2763         {
2764 #ifdef __PALM_GESTURE_LOG__
2765                 XDBG_DEBUG(MGEST, "EQ Event is full.... palm recognize drop..\n");
2766 #endif
2767                 goto hold_failed;
2768         }
2769         if(rapid_hold && type==0 && idx==0 && timer_expired == 0)
2770         {
2771 #ifdef __PALM_GESTURE_LOG__
2772                 XDBG_DEBUG(MGEST, "rapid timer is released .....\n");
2773 #endif
2774                 rapid_hold = 0;
2775                 goto release_hold;
2776         }
2777         if(pPalm->single_timer_expired && (pPalm->biggest_tmajor < PALM_HOLD_FINGER_MIN_TOUCH_MAJOR) && (max_num_finger < (PALM_HOLD_MIN_FINGER - 1)))
2778         {
2779 #ifdef __PALM_GESTURE_LOG__
2780                 XDBG_DEBUG(MGEST, "No Hold single finger...expired, biggest_tmajor: %.f\n", pPalm->biggest_tmajor);
2781 #endif
2782                 goto hold_failed;
2783         }
2784
2785         if(g_pGesture->recognized_gesture || (g_pGesture->recognized_palm && !(g_pGesture->recognized_palm & PalmHoldFilterMask)) || (g_pGesture->palm_filter_mask & PalmHoldFilterMask)
2786 #ifdef _F_SUPPORT_BEZEL_FLICK_
2787                 || g_pGesture->bezel_recognized_mask)
2788 #else
2789                 )
2790 #endif
2791         {
2792 #ifdef __PALM_GESTURE_LOG__
2793                 XDBG_DEBUG(MGEST, "zoom_enabled: %d\n", g_pGesture->zoom_enabled);
2794                 XDBG_DEBUG(MGEST, "type(%d) recognized_palm= 0x%x, palm_filter_mask= 0x%x\n", type, g_pGesture->recognized_palm, g_pGesture->palm_filter_mask);
2795                 XDBG_DEBUG(MGEST, "type(%d) recognized_gesture= 0x%x, filter_mask= 0x%x\n", type, g_pGesture->recognized_gesture, g_pGesture->filter_mask);
2796 #endif
2797                 goto hold_failed;
2798         }
2799         if( timer_expired && !pPalm->palmflag)
2800         {
2801 #ifdef __PALM_GESTURE_LOG__
2802                 XDBG_DEBUG(MGEST, "No Palm is comming \n");
2803 #endif
2804                 if( (pPalm->biggest_wmajor > PALM_HOLD_FINGER_MIN_WIDTH_MAJOR) && (max_num_finger >= PALM_HOLD_MIN_FINGER) )
2805                 {
2806 #ifdef __PALM_GESTURE_LOG__
2807                         XDBG_DEBUG(MGEST, "It seemed palm hold (biggest_wmajor: %.f max_num_finger: %d) \n", pPalm->biggest_wmajor, max_num_finger);
2808 #endif
2809                         pPalm->palmflag = 1;
2810                 }
2811                 else
2812                 {
2813 #ifdef __PALM_GESTURE_LOG__
2814                         XDBG_DEBUG(MGEST, "No Palm and No Hold \n");
2815 #endif
2816                         goto hold_failed;
2817                 }
2818         }
2819
2820         if( timer_expired && pPalm->palmflag)
2821         {
2822 #ifdef __PALM_GESTURE_LOG__
2823                 XDBG_DEBUG(MGEST, "state: %d\n", state);
2824 #endif
2825                 if(max_num_finger < PALM_HOLD_MIN_FINGER)
2826                 {
2827 #ifdef __PALM_GESTURE_LOG__
2828                         XDBG_DEBUG(MGEST, "palm hold false : max_num_finger(%d) < %d\n", max_num_finger, PALM_HOLD_MIN_FINGER);
2829 #endif
2830                         goto hold_failed;
2831                 }
2832                 if( state <= GestureBegin )
2833                         state++;
2834
2835                 switch( state )
2836                 {
2837                         case GestureBegin:
2838 #ifdef __PALM_GESTURE_LOG__
2839                                 XDBG_DEBUG(MGEST, "HOLD Begin !(state=%d)\n", state);
2840 #endif
2841                                 break;
2842
2843                         case GestureUpdate:
2844 #ifdef __PALM_GESTURE_LOG__
2845                                 XDBG_DEBUG(MGEST, "HOLD Update !(state=%d)\n", state);
2846 #endif
2847                                 break;
2848                 }
2849
2850                 if(base_width_size < PALM_HOLD_MIN_BASE_WIDTH)
2851                 {
2852 #ifdef __PALM_GESTURE_LOG__
2853                         XDBG_DEBUG(MGEST, "[P] No Hold base_width_size: %d < %d\n", base_width_size, PALM_HOLD_MIN_BASE_WIDTH);
2854 #endif
2855                         goto hold_failed;
2856                 }
2857
2858                 if( GestureHasFingerEventMask(GestureNotifyHold, 0) )
2859                 {
2860                         if(state == GestureBegin)
2861                         {
2862                                 hold_occured = 1;
2863                         }
2864                         GestureHandleGesture_Hold(0, cx, cy, GetTimeInMillis()-base_time, state);
2865 #ifdef __PALM_GESTURE_LOG__
2866                         XDBG_DEBUG(MGEST, "[T] create hold timer @ timer expired\n");
2867 #endif
2868                         palm_hold_event_timer = TimerSet(palm_hold_event_timer, 0, PALM_HOLD_UPDATE_THRESHOLD, GesturePalmEventTimerHandler, (int *)&event_type);
2869                 }
2870                 return;
2871         }
2872
2873         switch( type )
2874         {
2875                 case ET_ButtonPress:
2876                         if(!is_holding)
2877                                 break;
2878                         if(!base_time)
2879                         {
2880                                 if(!base_time)
2881                                         base_time = GetTimeInMillis();
2882                                 event_type = GestureNotifyHold;
2883                                 TimerCancel(palm_hold_event_timer);
2884 #ifdef __PALM_GESTURE_LOG__
2885                                 XDBG_DEBUG(MGEST, "[P] create hold timer @ initial time\n");
2886 #endif
2887                                 max_num_finger=0;
2888                                 palm_hold_event_timer = TimerSet(palm_hold_event_timer, 0, PALM_HOLD_TIME_THRESHOLD, GesturePalmEventTimerHandler, (int *)&event_type);
2889                         }
2890                         base_width_size = AREA_WIDTH(&pPalm->area.extents);
2891 #ifdef __PALM_GESTURE_LOG__
2892                         XDBG_DEBUG(MGEST, "[P] Hold base_width_size: %d\n", base_width_size);
2893 #endif
2894                         false_base_width_size_count = 0;
2895                         num_pressed++;
2896                         if(max_num_finger < num_pressed)
2897                                 max_num_finger = num_pressed;
2898                         break;
2899
2900                 case ET_Motion:
2901                         if(!num_pressed || !is_holding)
2902                                 return;
2903
2904                         if(state < GestureBegin)
2905                         {
2906                                 if( !(pPalm->palmflag) && pPalm->max_palm >= PALM_FLICK_MIN_PALM)
2907                                         pPalm->palmflag = 1;
2908                                 if(base_width_size < PALM_HOLD_MIN_BASE_WIDTH)
2909                                 {
2910                                         false_base_width_size_count++;
2911 #ifdef __PALM_GESTURE_LOG__
2912                                         XDBG_DEBUG(MGEST, "[M] increase false_base_width_size_count: %d!, width: %.f\n", false_base_width_size_count, base_width_size);
2913 #endif
2914                                         if(false_base_width_size_count > PALM_HOLD_FALSE_WIDTH)
2915                                         {
2916 #ifdef __PALM_GESTURE_LOG__
2917                                                 XDBG_DEBUG(MGEST, "[M] No hold width!\n");
2918 #endif
2919                                                 goto hold_failed;
2920                                         }
2921                                 }
2922                         }
2923
2924                         cx = AREA_CENTER_X(&pPalm->area.extents);
2925                         cy = AREA_CENTER_Y(&pPalm->area.extents);
2926                         break;
2927
2928                 case ET_ButtonRelease:
2929                         if(--num_pressed < 0)
2930                                 num_pressed = 0;
2931
2932                         if(pPalm->cur_touched || num_pressed)
2933                                 break;
2934 #ifdef __PALM_GESTURE_LOG__
2935                         XDBG_DEBUG(MGEST, "[R] All fingers were released ! state=%d, is_holding=%d, cur_touched=%d, num_pressed=%d\n",
2936                                 state, is_holding, pPalm->cur_touched, num_pressed);
2937 #endif
2938                         if(!is_holding)
2939                                 goto cleanup_hold;
2940
2941                         if (hold_occured == 0 && state == GestureEnd)
2942                         {
2943 #ifdef __PALM_GESTURE_LOG__
2944                                 XDBG_DEBUG(MGEST, "[R] Fast Release..\n");
2945 #endif
2946                                 if( (pPalm->palmflag) && (base_width_size > PALM_HOLD_MIN_BASE_WIDTH))
2947                                 {
2948 #ifdef __PALM_GESTURE_LOG__
2949                                         XDBG_DEBUG(MGEST, "[R] seemed hold palm is came, base_width_size: %d..\n", base_width_size);
2950 #endif
2951                                         if( GestureHasFingerEventMask(GestureNotifyHold, 0) )
2952                                         {
2953                                                 hold_occured = 1;
2954                                                 state = GestureBegin;
2955                                                 GestureHandleGesture_Hold(0, cx, cy, GetTimeInMillis()-base_time, state);
2956                                                 rapid_hold = 1;
2957                                                 palm_hold_rapid_timer = TimerSet(palm_hold_rapid_timer, 0, PALM_HOLD_TIME_THRESHOLD, GesturePalmHoldRapidHandler,  NULL);
2958 #ifdef __PALM_GESTURE_LOG__
2959                                                 XDBG_DEBUG(MGEST, "[R] rapid hold begin !!\n");
2960 #endif
2961                                                 goto hold_failed;
2962                                         }
2963                                 }
2964                                 else if( (pPalm->biggest_wmajor > PALM_HOLD_FINGER_MIN_WIDTH_MAJOR) && (max_num_finger >= PALM_HOLD_MIN_FINGER) )
2965                                 {
2966 #ifdef __PALM_GESTURE_LOG__
2967                                         XDBG_DEBUG(MGEST, "[R] seemed hold.. biggest_wmajor: %.f, max_num_finger: %d", pPalm->biggest_wmajor, max_num_finger);
2968 #endif
2969                                         if( GestureHasFingerEventMask(GestureNotifyHold, 0) )
2970                                         {
2971                                                 hold_occured = 1;
2972                                                 state = GestureBegin;
2973                                                 GestureHandleGesture_Hold(0, cx, cy, GetTimeInMillis()-base_time, state);
2974                                                 rapid_hold = 1;
2975                                                 palm_hold_rapid_timer = TimerSet(palm_hold_rapid_timer, 0, PALM_HOLD_TIME_THRESHOLD, GesturePalmHoldRapidHandler,  NULL);
2976 #ifdef __PALM_GESTURE_LOG__
2977                                                 XDBG_DEBUG(MGEST, "[R] rapid hold begin !!\n");
2978 #endif
2979                                                 goto hold_failed;
2980                                         }
2981                                 }
2982                         }
2983 release_hold:
2984                         if(hold_occured == 0 && num_pressed == 0)
2985                         {
2986 #ifdef __PALM_GESTURE_LOG__
2987                                 XDBG_DEBUG(MGEST, "[R] release all finger and No hold base_width_size: %d, biggest_wmajor: %.f, max_num_finger: %d\n", base_width_size, pPalm->biggest_wmajor, max_num_finger);
2988 #endif
2989                                 goto hold_failed;
2990                         }
2991
2992                         if( state == GestureBegin || state == GestureUpdate )
2993                         {
2994                                 state = GestureEnd;
2995 #ifdef __PALM_GESTURE_LOG__
2996                                 XDBG_DEBUG(MGEST, "[R] HOLD End !(state=%d)\n", state);
2997 #endif
2998                                 hold_occured = 0;
2999                                 //g_pGesture->recognized_palm = GESTURE_PALM_FILTER_MASK_ALL;
3000                                 if( GestureHasFingerEventMask(GestureNotifyHold, 0) )
3001                                 {
3002                                         GestureHandleGesture_Hold(0, cx, cy, GetTimeInMillis()-base_time, state);
3003                                 }
3004                                 //else
3005                                         //XDBG_DEBUG(MGEST, "[END] \n");
3006                         }
3007                         else
3008                         {
3009 #ifdef __PALM_GESTURE_LOG__
3010                                 XDBG_DEBUG(MGEST, "[R] Gesture Hold End is already occured\n");
3011 #endif
3012                                 goto hold_failed;
3013                         }
3014                         goto cleanup_hold;
3015         }
3016         return;
3017
3018 hold_failed:
3019         is_holding = 0;
3020         TimerCancel(palm_hold_event_timer);
3021         g_pGesture->palm_filter_mask |= PalmHoldFilterMask;
3022         if( g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL )
3023         {
3024                 if( ERROR_INVALPTR == GestureFlushOrDrop() )
3025                 {
3026                         GestureControl(g_pGesture->this_device, DEVICE_OFF);
3027                 }
3028         }
3029 #ifdef __PALM_GESTURE_LOG__
3030         XDBG_DEBUG(MGEST, "[F] recognized_palm= 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask);
3031 #endif
3032         goto cleanup_hold;
3033         return;
3034
3035 cleanup_hold:
3036 #ifdef __PALM_GESTURE_LOG__
3037         XDBG_DEBUG(MGEST, "[F] HOLD Cleanup (state: %d)\n", state);
3038 #endif
3039         TimerCancel(palm_hold_event_timer);
3040         if(state == GestureBegin || state == GestureUpdate)
3041         {
3042                 if( GestureHasFingerEventMask(GestureNotifyHold, 0) )
3043                 {
3044                         GestureHandleGesture_Hold(0, cx, cy, GetTimeInMillis()-base_time, GestureEnd);
3045                 }
3046         }
3047         is_holding = 1;
3048         num_pressed = 0;
3049         false_base_width_size_count = 0;
3050         base_time = 0;
3051         cx = cy = 0;
3052         max_num_finger = 0;
3053         state = GestureEnd;
3054         base_width_size = 0;
3055         hold_occured = 0;
3056         rapid_hold = 0;
3057         return;
3058 }
3059
3060 static void
3061 GesturePalmRecognize_FlickHorizen(int type, int idx)
3062 {
3063         static int curTouched = 0;
3064         static int num_pressed = 0;
3065         static int base_width_size = 0;
3066         static Time base_time = 0;
3067         static int base_x;
3068         static pixman_box16_t base_box_ext;
3069 #ifdef __PALM_GESTURE_LOG__
3070         int i;
3071 #endif
3072
3073         int line_idx;
3074         static int press_idx;
3075         static int prev_line_idx;
3076         static int horiz_line[PALM_HORIZ_ARRAY_COUNT];
3077
3078         Time duration;
3079         int distx=0, disty=0;
3080         int distance, direction;
3081
3082         int width_size;
3083         static int is_flicking = 1;
3084         //static int is_surface = 0;
3085         static int pass_count = 0;
3086         static int base_cx=0, base_cy=0;
3087         static int release_flag = 0;
3088
3089         PalmStatusPtr pPalm = &g_pGesture->palm;
3090 #ifdef __PALM_GESTURE_LOG__
3091         XDBG_DEBUG(MGEST, "recognized_palm= 0x%x, palm_filter_mask= 0x%x\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask);
3092         XDBG_DEBUG(MGEST, "num_pressed: %d, cur_touched: %d palmflag: %d\n", num_pressed, pPalm->cur_touched, pPalm->palmflag);
3093         XDBG_DEBUG(MGEST, "idx: %d, cx: %d, cy: %d\n", idx, pPalm->cx, pPalm->cy);
3094 #endif
3095
3096         if(g_pGesture->enqueue_fulled == 1)
3097         {
3098 #ifdef __PALM_GESTURE_LOG__
3099                         XDBG_DEBUG(MGEST, "EQ Event is full.... palm recognize drop..\n");
3100 #endif
3101                         goto flick_failed;
3102         }
3103
3104         if(pPalm->single_timer_expired)
3105         {
3106 #ifdef __PALM_GESTURE_LOG__
3107                 XDBG_DEBUG(MGEST, "No flick single finger...expired\n");
3108 #endif
3109                 goto flick_failed;
3110         }
3111
3112         if(g_pGesture->recognized_gesture || (g_pGesture->recognized_palm && !(g_pGesture->recognized_palm & PalmFlickHorizFilterMask)) || (g_pGesture->palm_filter_mask & PalmFlickHorizFilterMask)
3113 #ifdef _F_SUPPORT_BEZEL_FLICK_
3114                 || g_pGesture->bezel_recognized_mask)
3115 #else
3116                 )
3117 #endif
3118         {
3119 #ifdef __PALM_GESTURE_LOG__
3120                 XDBG_DEBUG(MGEST, "zoom_enabled: %d\n", g_pGesture->zoom_enabled);
3121                 XDBG_DEBUG(MGEST, "type(%d) recognized_palm= 0x%x, palm_filter_mask= 0x%x\n", type, g_pGesture->recognized_palm, g_pGesture->palm_filter_mask);
3122                 XDBG_DEBUG(MGEST, "type(%d) recognized_gesture= 0x%x, filter_mask= 0x%x\n", type, g_pGesture->recognized_gesture, g_pGesture->filter_mask);
3123 #endif
3124                 goto flick_failed;
3125         }
3126         switch( type )
3127         {
3128                 case ET_ButtonPress:
3129                         if(!is_flicking)
3130                                 break;
3131                         if(!base_width_size || pPalm->cur_touched > curTouched)
3132                         {
3133                                 if(!base_time)
3134                                 {
3135                                         base_time = GetTimeInMillis();
3136                                         base_x = AREA_CENTER_X(&pPalm->area.extents);
3137                                         line_idx = GesturePalmGetHorizIndexWithX(base_x, type);
3138 #ifdef __PALM_GESTURE_LOG__
3139                                         XDBG_DEBUG(MGEST, "[P] cx: %d, cy: %d, x1: %d, x2: %d, y1: %d, y2: %d, line_idx: %d\n", pPalm->cx, pPalm->cy, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2, line_idx);
3140 #endif
3141                                         if(line_idx < 0)
3142                                         {
3143 #ifdef __PALM_GESTURE_LOG__
3144                                                 XDBG_DEBUG(MGEST, "[P] line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x, line_idx);
3145 #endif
3146                                                 goto flick_failed;
3147                                         }
3148
3149                                         horiz_line[line_idx]++;
3150                                         pass_count++;
3151                                         press_idx = prev_line_idx = line_idx;
3152                                         release_flag = 0;
3153 #ifdef __PALM_GESTURE_LOG__
3154                                         XDBG_DEBUG(MGEST, "[P] Base_width=%d, base_x=%d, line_idx=%d\n", base_width_size, base_x, line_idx);
3155 #endif
3156                                 }
3157
3158                                 base_width_size = AREA_WIDTH(&pPalm->area.extents);
3159                                 if(base_width_size > PALM_FLICK_HORIZ_MAX_BASE_WIDTH)
3160                                 {
3161 #ifdef __PALM_GESTURE_LOG__
3162                                         XDBG_DEBUG(MGEST, "[P] No flickBase_width=%d > MAX_WIDTH\n", base_width_size, PALM_FLICK_HORIZ_MAX_BASE_WIDTH);
3163 #endif
3164                                         goto flick_failed;
3165                                 }
3166 #ifdef __PALM_GESTURE_LOG__
3167                                 XDBG_DEBUG(MGEST, "[P] Base_width=%d, cur_touched=%d\n", base_width_size, pPalm->cur_touched);
3168 #endif
3169                                 if(pPalm->max_touched == 1)
3170                                 {
3171                                         base_cx = AREA_CENTER_X(&pPalm->area.extents);
3172                                         base_cy = AREA_CENTER_Y(&pPalm->area.extents);
3173                                         base_box_ext.x1 = base_cx-HOLD_MOVE_THRESHOLD;
3174                                         base_box_ext.y1 = base_cy-HOLD_MOVE_THRESHOLD;
3175                                         base_box_ext.x2 = base_cx+HOLD_MOVE_THRESHOLD;
3176                                         base_box_ext.y2 = base_cy+HOLD_MOVE_THRESHOLD;
3177                                 }
3178                         }
3179                         curTouched = pPalm->cur_touched;
3180                         num_pressed++;
3181                         break;
3182
3183                 case ET_Motion:
3184                         if(!num_pressed || !is_flicking)
3185                         {
3186 #ifdef __PALM_GESTURE_LOG__
3187                                 XDBG_DEBUG(MGEST, "[M] num_pressed: %d, is_flicking: %d\n", num_pressed, is_flicking);
3188 #endif
3189                                 break;
3190                         }
3191
3192                         distx = AREA_CENTER_X(&pPalm->area.extents);
3193                         disty = AREA_CENTER_Y(&pPalm->area.extents);
3194                         line_idx = GesturePalmGetHorizIndexWithX(distx, type);
3195 #ifdef __PALM_GESTURE_LOG__
3196                         for(i=0; i<PALM_HORIZ_ARRAY_COUNT; i++)
3197                         {
3198                                 XDBG_DEBUG(MGEST, "M] %d: %d\n", i, horiz_line[i]);
3199                         }
3200                         XDBG_DEBUG(MGEST, "[M] distx: %d, line_idx: %d, prev_line_idx: %d! pass_count: %d\n", distx, line_idx, prev_line_idx, pass_count);
3201 #endif
3202
3203                         if(line_idx < 0)
3204                         {
3205 #ifdef __PALM_GESTURE_LOG__
3206                                 XDBG_DEBUG(MGEST, "[M] line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x, line_idx);
3207 #endif
3208                                 goto flick_failed;
3209                         }
3210
3211                         if(pPalm->max_touched == 1)
3212                         {
3213                                 if(ABS(disty - base_cy) > PALM_FLICK_HORIZ_MAX_MOVE_Y)
3214                                 {
3215 #ifdef __PALM_GESTURE_LOG__
3216                                         XDBG_DEBUG(MGEST, "[M] No flick ! (move too long toward y coordination %d(%d - %d) > %d\n", ABS(disty - base_cy), disty, base_cy, PALM_FLICK_HORIZ_MAX_MOVE_Y);
3217 #endif
3218                                         goto flick_failed;
3219                                 }
3220                         }
3221
3222                         if(prev_line_idx != line_idx)
3223                         {
3224                                 horiz_line[line_idx]++;
3225                                 if(horiz_line[line_idx] > 2)
3226                                         goto flick_failed;
3227                                 pass_count++;
3228                         }
3229                         if(pass_count > 6)
3230                         {
3231 #ifdef __PALM_GESTURE_LOG__
3232                                 XDBG_DEBUG(MGEST, "[M] No flick !(visit same place twice !)\n");
3233 #endif
3234                                 goto flick_failed;
3235                         }
3236 #if 0
3237                         if((prev_line_idx != line_idx) && horiz_line[line_idx] && !release_flag)
3238                         {
3239 #ifdef __PALM_GESTURE_LOG__
3240                                 XDBG_DEBUG(MGEST, "[M] No flick !(visit same place twice !)\n");
3241 #endif
3242                                 goto flick_failed;
3243                         }
3244 #endif
3245                         prev_line_idx = line_idx;
3246
3247                         width_size = AREA_WIDTH(&pPalm->area.extents);
3248 #ifdef __PALM_GESTURE_LOG__
3249                         XDBG_DEBUG(MGEST, "[M] Base_width=%d, Current_width=%d, diff=%d\n", base_width_size, width_size, ABS(width_size - base_width_size));
3250 #endif
3251                         duration = GetTimeInMillis() - base_time;
3252 #ifdef __PALM_GESTURE_LOG__
3253                         XDBG_DEBUG(MGEST, "[M] duration =%d !\n", duration);
3254 #endif
3255                         if(!pPalm->palmflag && (duration >= PALM_FLICK_INITIAL_TIMEOUT))
3256                         {
3257 #ifdef __PALM_GESTURE_LOG__
3258                                 XDBG_DEBUG(MGEST, "[M] No flick !(initial flick timeout : duration=%d)\n", duration);
3259 #endif
3260                                 goto flick_failed;
3261                         }
3262                         if( (duration >= PALM_FLICK_INITIAL_TIMEOUT) && (INBOX(&base_box_ext, distx, disty)) )
3263                         {
3264 #ifdef __PALM_GESTURE_LOG__
3265                                 XDBG_DEBUG(MGEST, "[M] No flick !(move too short !in duration: %d)\n", duration);
3266 #endif
3267                                 goto flick_failed;
3268                         }
3269                         if( (duration >= PALM_FLICK_FALSE_TIMEOUT) && (pPalm->biggest_tmajor < PALM_FLICK_TOUCH_MAJOR) )
3270                         {
3271 #ifdef __PALM_GESTURE_LOG__
3272                                 XDBG_DEBUG(MGEST, "[M] No flick !(press touch major(%.f < %.f) is little in duration(%d))\n", pPalm->biggest_tmajor, PALM_FLICK_TOUCH_MAJOR, duration);
3273 #endif
3274                                 goto flick_failed;
3275                         }
3276
3277                         if(duration >= PALM_FLICK_DETECT_TIMEOUT)
3278                         {
3279 #ifdef __PALM_GESTURE_LOG__
3280                                 XDBG_DEBUG(MGEST, "[M] No flick !(flick detection timeout : duration=%d)\n", duration);
3281 #endif
3282                                 goto flick_failed;
3283                         }
3284                         break;
3285
3286                 case ET_ButtonRelease:
3287                         release_flag = 1;
3288                         if(--num_pressed < 0)
3289                                 num_pressed = 0;
3290                         base_width_size = AREA_WIDTH(&pPalm->area.extents);
3291                         if(num_pressed)
3292                                 break;
3293                         if(!pPalm->palmflag)
3294                         {
3295 #ifdef __PALM_GESTURE_LOG__
3296                                 XDBG_DEBUG(MGEST, "[R] No flick (No palm comming and all finger release))\n");
3297 #endif
3298                                 goto flick_failed;
3299                         }
3300
3301                         if(!is_flicking)
3302                                 goto cleanup_flick;
3303
3304                         duration = GetTimeInMillis() - base_time;
3305                         distx = AREA_CENTER_X(&pPalm->area.extents);
3306                         line_idx = GesturePalmGetHorizIndexWithX(distx, type);
3307
3308                         if(line_idx < 0)
3309                         {
3310 #ifdef __PALM_GESTURE_LOG__
3311                                 XDBG_DEBUG(MGEST, "[R] No flick (distx: %d, line_idx: %d))\n", distx, line_idx);
3312 #endif
3313                                 goto flick_failed;
3314                         }
3315 #ifdef __PALM_GESTURE_LOG__
3316                         XDBG_DEBUG(MGEST, "[R] duration=%d, distx=%d\n", duration, distx);
3317 #endif
3318                         if(duration >= PALM_FLICK_DETECT_TIMEOUT)
3319                         {
3320 #ifdef __PALM_GESTURE_LOG__
3321                                 XDBG_DEBUG(MGEST, "[R] No flick !(flick detection timeout : duration=%d)\n", duration);
3322 #endif
3323                                 goto flick_failed;
3324                         }
3325                         if(pass_count < PALM_HORIZ_ARRAY_COUNT - 1)
3326                         {
3327 #ifdef __PALM_GESTURE_LOG__
3328                                 XDBG_DEBUG(MGEST, "[R] No flick !(flick distance is short!\n");
3329 #endif
3330                                 goto flick_failed;
3331                         }
3332                         if(pPalm->biggest_tmajor < PALM_FLICK_TOUCH_MAJOR)
3333                         {
3334 #ifdef __PALM_GESTURE_LOG__
3335                                 XDBG_DEBUG(MGEST, "[R] No flick !(touch major(%.f < %d) is small...)\n", pPalm->biggest_tmajor, PALM_FLICK_TOUCH_MAJOR);
3336 #endif
3337                                 goto flick_failed;
3338                         }
3339
3340                         direction = (line_idx <= 1) ? FLICK_EASTWARD : FLICK_WESTWARD;
3341                         distance = ABS(distx - base_x);
3342 #ifdef __PALM_GESTURE_LOG__
3343                         XDBG_DEBUG(MGEST, "[R] Palm Flick !!!, direction=%d, distance=%d\n", direction, distance);
3344 #endif
3345                         if( GestureHasFingerEventMask(GestureNotifyFlick, 0) )
3346                                 GestureHandleGesture_Flick(0, distance, duration, direction);
3347                         goto cleanup_flick;
3348                         break;
3349         }
3350
3351         return;
3352
3353 flick_failed:
3354         is_flicking = 0;
3355         g_pGesture->recognized_palm &= ~PalmFlickHorizFilterMask;
3356         g_pGesture->palm_filter_mask |= PalmFlickHorizFilterMask;
3357 #ifdef __PALM_GESTURE_LOG__
3358         XDBG_DEBUG(MGEST, "[Failed] recognized_palm= 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask);
3359 #endif
3360         goto cleanup_flick;
3361         return;
3362
3363 cleanup_flick:
3364         num_pressed = 0;
3365         is_flicking = 1;
3366         base_width_size = 0;
3367         //is_surface = 0;
3368         base_time = 0;
3369         curTouched = 0;
3370         pass_count = 0;
3371         prev_line_idx = 0;
3372         release_flag = 0;
3373         base_cx = base_cy = 0;
3374         base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
3375         memset(&horiz_line, 0L, PALM_HORIZ_ARRAY_COUNT * sizeof(int));
3376 #ifdef __PALM_GESTURE_LOG__
3377         XDBG_DEBUG(MGEST, "[cleanup_flick] base_width_size=%d, curTouched=%d\n", base_width_size, curTouched);
3378 #endif
3379         return;
3380 }
3381
3382 static void
3383 GesturePalmRecognize_FlickVertical(int type,int idx)
3384 {
3385         static int curTouched = 0;
3386         static int num_pressed = 0;
3387         static int base_height_size = 0;
3388         static Time base_time = 0;
3389         static int base_y;
3390         static int base_cx, base_cy;
3391         static int pass_count = 0;
3392         static int release_flag = 0;
3393         static pixman_box16_t base_box_ext;
3394
3395         int line_idx;
3396         static int press_idx;
3397         static int prev_line_idx;
3398         static int verti_line[PALM_VERTI_ARRAY_COUNT];
3399
3400         Time duration;
3401         int disty;
3402         int distx;
3403         int distance, direction;
3404
3405         int height_size;
3406         static int is_flicking = 1;
3407         static int false_base_height_size = 0;
3408
3409         PalmStatusPtr pPalm = &g_pGesture->palm;
3410 #ifdef __PALM_GESTURE_LOG__
3411         XDBG_DEBUG(MGEST, "recognized_palm= 0x%x, palm_filter_mask= 0x%x\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask);
3412         XDBG_DEBUG(MGEST, "num_pressed: %d, cur_touched: %d, palm_flag: %d, single_timer_expired: %d\n", num_pressed, pPalm->cur_touched, pPalm->palmflag, pPalm->single_timer_expired);
3413 #endif
3414         if(g_pGesture->enqueue_fulled == 1)
3415         {
3416 #ifdef __PALM_GESTURE_LOG__
3417                 XDBG_DEBUG(MGEST, "EQ Event is full.... palm recognize drop..\n");
3418 #endif
3419                 goto flick_failed;
3420         }
3421
3422
3423         if(g_pGesture->recognized_gesture || (g_pGesture->recognized_palm && !(g_pGesture->recognized_palm & PalmFlickVertiFilterMask)) || (g_pGesture->palm_filter_mask & PalmFlickVertiFilterMask)
3424 #ifdef _F_SUPPORT_BEZEL_FLICK_
3425                 || g_pGesture->bezel_recognized_mask)
3426 #else
3427                 )
3428 #endif
3429         {
3430 #ifdef __PALM_GESTURE_LOG__
3431                 XDBG_DEBUG(MGEST, "zoom_enabled: %d\n", g_pGesture->zoom_enabled);
3432                 XDBG_DEBUG(MGEST, "type(%d) recognized_palm= 0x%x, palm_filter_mask= 0x%x\n", type, g_pGesture->recognized_palm, g_pGesture->palm_filter_mask);
3433                 XDBG_DEBUG(MGEST, "type(%d) recognized_gesture= 0x%x, filter_mask= 0x%x\n", type, g_pGesture->recognized_gesture, g_pGesture->filter_mask);
3434 #endif
3435                 goto flick_failed;
3436         }
3437
3438         if(pPalm->single_timer_expired)
3439         {
3440 #ifdef __PALM_GESTURE_LOG__
3441                 XDBG_DEBUG(MGEST, "No flick single finger...expired\n");
3442 #endif
3443                 goto flick_failed;
3444         }
3445
3446         switch( type )
3447         {
3448                 case ET_ButtonPress:
3449                         if(!is_flicking)
3450                                 break;
3451                         if(!base_height_size || pPalm->cur_touched > curTouched)
3452                         {
3453                                 if(!base_time)
3454                                 {
3455                                         base_time = GetTimeInMillis();
3456                                         base_y = AREA_CENTER_Y(&pPalm->area.extents);
3457                                         line_idx = GesturePalmGetVertiIndexWithY(base_y, type);
3458
3459 #ifdef __PALM_GESTURE_LOG__
3460                                         XDBG_DEBUG(MGEST, "[P] Base_height=%d, base_y=%d, line_idx=%d\n", base_height_size, base_y, line_idx);
3461 #endif
3462                                         if(line_idx < 0)
3463                                                 goto flick_failed;
3464
3465                                         verti_line[line_idx] = 1;
3466                                         pass_count++;
3467                                         press_idx = prev_line_idx = line_idx;
3468                                         release_flag = 0;
3469 #ifdef __PALM_GESTURE_LOG__
3470                                         XDBG_DEBUG(MGEST, "[P] Base_height=%d, base_y=%d, line_idx=%d\n", base_height_size, base_y, line_idx);
3471 #endif
3472                                 }
3473
3474                                 base_height_size = AREA_HEIGHT(&pPalm->area.extents);
3475 #ifdef __PALM_GESTURE_LOG__
3476                                 XDBG_DEBUG(MGEST, "[P] Base_height=%d, cur_touched=%d\n", base_height_size, pPalm->cur_touched);
3477 #endif
3478                                 if(base_height_size > PALM_FLICK_VERTI_MAX_BASE_WIDTH)
3479                                 {
3480 #ifdef __PALM_GESTURE_LOG__
3481                                         XDBG_DEBUG(MGEST, "[P] No flickBase_width=%d > MAX_WIDTH\n", base_height_size, PALM_FLICK_VERTI_MAX_BASE_WIDTH);
3482 #endif
3483                                         goto flick_failed;
3484                                 }
3485                                 false_base_height_size = 0;
3486                                 if(pPalm->max_touched == 1)
3487                                 {
3488                                         base_cx = AREA_CENTER_X(&pPalm->area.extents);
3489                                         base_cy = AREA_CENTER_Y(&pPalm->area.extents);
3490                                         base_box_ext.x1 = base_cx-HOLD_MOVE_THRESHOLD;
3491                                         base_box_ext.y1 = base_cy-HOLD_MOVE_THRESHOLD;
3492                                         base_box_ext.x2 = base_cx+HOLD_MOVE_THRESHOLD;
3493                                         base_box_ext.y2 = base_cy+HOLD_MOVE_THRESHOLD;
3494                                 }
3495                         }
3496
3497                         curTouched = pPalm->cur_touched;
3498                         num_pressed++;
3499                         break;
3500
3501                 case ET_Motion:
3502                         if(!num_pressed|| !is_flicking)
3503                                 break;
3504
3505                         distx = AREA_CENTER_X(&pPalm->area.extents);
3506                         disty = AREA_CENTER_Y(&pPalm->area.extents);
3507                         line_idx = GesturePalmGetVertiIndexWithY(disty, type);
3508 #ifdef __PALM_GESTURE_LOG__
3509                         XDBG_DEBUG(MGEST, "[M] line_idx: %d\n", line_idx);
3510 #endif
3511
3512                         if(line_idx < 0)
3513                                 goto flick_failed;
3514                         if((prev_line_idx != line_idx) && verti_line[line_idx] && !release_flag)
3515                         {
3516 #ifdef __PALM_GESTURE_LOG__
3517                                 XDBG_DEBUG(MGEST, "[M] No flick !(visit same place twice !)\n");
3518 #endif
3519                                 goto flick_failed;
3520                         }
3521
3522                         if(pPalm->max_touched == 1)
3523                         {
3524                                 if(ABS(AREA_CENTER_X(&pPalm->area.extents) - base_cx) > PALM_FLICK_VERTI_MAX_MOVE_X)
3525                                 {
3526 #ifdef __PALM_GESTURE_LOG__
3527                                         XDBG_DEBUG(MGEST, "[M] No flick ! (move too long toward x coordination %d(%d - %d) > PALM_FLICK_VERTI_MAX_MOVE_X\n", ABS(AREA_CENTER_X(&pPalm->area.extents) - base_cx), AREA_CENTER_X(&pPalm->area.extents) , base_cx, PALM_FLICK_VERTI_MAX_MOVE_X);
3528 #endif
3529                                         goto flick_failed;
3530                                 }
3531                         }
3532
3533                         verti_line[line_idx] = 1;
3534                         if(prev_line_idx != line_idx)
3535                                 pass_count++;
3536                         prev_line_idx = line_idx;
3537
3538                         height_size = AREA_HEIGHT(&pPalm->area.extents);
3539 #ifdef __PALM_GESTURE_LOG__
3540                         XDBG_DEBUG(MGEST, "[M] Base_height=%d, Current_height=%d, diff=%d\n", base_height_size, height_size, ABS(height_size - base_height_size));
3541 #endif
3542
3543                         duration = GetTimeInMillis() - base_time;
3544 #ifdef __PALM_GESTURE_LOG__
3545                         XDBG_DEBUG(MGEST, "[M] duration =%d !\n", duration);
3546 #endif
3547
3548                         if(!pPalm->palmflag && (duration >= PALM_FLICK_INITIAL_TIMEOUT))
3549                         {
3550 #ifdef __PALM_GESTURE_LOG__
3551                                 XDBG_DEBUG(MGEST, "[M] No flick !(initial flick timeout : duration=%d)\n", duration);
3552 #endif
3553                                 goto flick_failed;
3554                         }
3555                         if( (duration >= PALM_FLICK_INITIAL_TIMEOUT) && (INBOX(&base_box_ext, distx, disty)) )
3556                         {
3557 #ifdef __PALM_GESTURE_LOG__
3558                                 XDBG_DEBUG(MGEST, "[M] No flick !(move too short !in duration: %d)\n", duration);
3559 #endif
3560                                 goto flick_failed;
3561                         }
3562
3563                         if(duration >= PALM_FLICK_DETECT_TIMEOUT)
3564                         {
3565 #ifdef __PALM_GESTURE_LOG__
3566                                 XDBG_DEBUG(MGEST, "[M] No flick !(flick detection timeout : duration=%d)\n", duration);
3567 #endif
3568                                 goto flick_failed;
3569                         }
3570                         break;
3571
3572                 case ET_ButtonRelease:
3573                         release_flag = 1;
3574                         if(pPalm->cur_touched)
3575                                 break;
3576
3577                         if(--num_pressed < 0)
3578                                 num_pressed = 0;
3579                         if(num_pressed)
3580                                 break;
3581                         if(!pPalm->palmflag)
3582                         {
3583 #ifdef __PALM_GESTURE_LOG__
3584                                 XDBG_DEBUG(MGEST, "[R] num_pressed is 0\n");
3585 #endif
3586                                 goto flick_failed;
3587                         }
3588
3589                         if(!is_flicking)
3590                                 goto cleanup_flick;
3591
3592                         duration = GetTimeInMillis() - base_time;
3593                         disty = AREA_CENTER_Y(&pPalm->area.extents);
3594                         line_idx = GesturePalmGetVertiIndexWithY(disty, type);
3595 #ifdef __PALM_GESTURE_LOG__
3596                         XDBG_DEBUG(MGEST, "[R] line_idx: %d\n", line_idx);
3597 #endif
3598
3599                         if(line_idx < 0)
3600                                 goto flick_failed;
3601 #ifdef __PALM_GESTURE_LOG__
3602                         XDBG_DEBUG(MGEST, "[R] duration=%d, disty=%d\n", duration, disty);
3603 #endif
3604
3605                         if(duration >= PALM_FLICK_DETECT_TIMEOUT)
3606                         {
3607 #ifdef __PALM_GESTURE_LOG__
3608                                 XDBG_DEBUG(MGEST, "[R] No flick !(flick detection timeout : duration=%d)\n", duration);
3609 #endif
3610                                 goto flick_failed;
3611                         }
3612                         if(pass_count < PALM_VERTI_ARRAY_COUNT -1)
3613                         {
3614 #ifdef __PALM_GESTURE_LOG__
3615                                 XDBG_DEBUG(MGEST, "[R] No flick !(flick distance is short!)\n");
3616 #endif
3617                                 goto flick_failed;
3618                         }
3619                         if(pPalm->biggest_tmajor < PALM_FLICK_TOUCH_MAJOR)
3620                         {
3621 #ifdef __PALM_GESTURE_LOG__
3622                                 XDBG_DEBUG(MGEST, "[R] No flick !(flick touch major(%.f < %d) is small!)\n", pPalm->biggest_tmajor, PALM_FLICK_TOUCH_MAJOR);
3623 #endif
3624                                 goto flick_failed;
3625                         }
3626                         direction = (line_idx <= 1) ? FLICK_SOUTHWARD : FLICK_NORTHWARD;
3627                         distance = ABS(disty - base_y);
3628
3629 #ifdef __PALM_GESTURE_LOG__
3630                         XDBG_DEBUG(MGEST, "[R] Palm Flick !!!, direction=%d, distance=%d\n", direction, distance);
3631 #endif
3632
3633                         if( GestureHasFingerEventMask(GestureNotifyFlick, 0) )
3634                                 GestureHandleGesture_Flick(0, distance, duration, direction);
3635                         goto cleanup_flick;
3636                         break;
3637         }
3638
3639         return;
3640
3641 flick_failed:
3642         is_flicking = 0;
3643         g_pGesture->recognized_palm &= ~PalmFlickVertiFilterMask;
3644         g_pGesture->palm_filter_mask |= PalmFlickVertiFilterMask;
3645 #ifdef __PALM_GESTURE_LOG__
3646         XDBG_DEBUG(MGEST, "[Fail] recognized_palm= 0x%x, palm_filter_mask= 0x%x\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask);
3647 #endif
3648         goto cleanup_flick;
3649         return;
3650
3651 cleanup_flick:
3652         num_pressed = 0;
3653         is_flicking = 1;
3654         base_height_size = 0;
3655         base_time = 0;
3656         curTouched = 0;
3657         pass_count = 0;
3658         false_base_height_size = 0;
3659         prev_line_idx = 0;
3660         release_flag = 0;
3661         base_cx = base_cy = 0;
3662         base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
3663         memset(&verti_line, 0L, PALM_VERTI_ARRAY_COUNT * sizeof(int));
3664 #ifdef __PALM_GESTURE_LOG__
3665         XDBG_DEBUG(MGEST, "[cleanup_flick] base_height_size=%d, curTouched=%d\n", base_height_size, curTouched);
3666 #endif
3667
3668         return;
3669 }
3670
3671
3672 static int
3673 GesturePalmGetScreenInfo()
3674 {
3675         int i;
3676         pixman_region16_t tarea;
3677         PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
3678         ScreenPtr pScreen = miPointerCurrentScreen();
3679
3680         if(!pScreen)
3681         {
3682 #ifdef __PALM_DETAIL_LOG__
3683                 XDBG_DEBUG(MGEST, "Failed to get screen information !\n");
3684 #endif
3685                 pPalmMisc->scrn_width = pPalmMisc->scrn_height = 0;
3686                 return 0;
3687         }
3688
3689         pPalmMisc->scrn_width = pScreen->width;
3690         pPalmMisc->scrn_height = pScreen->height;
3691         pixman_region_init(&tarea);
3692         pixman_region_init_rect(&tarea, 0, 0, pPalmMisc->scrn_width, pPalmMisc->scrn_height);
3693         pPalmMisc->half_scrn_area_size = AREA_SIZE(&tarea.extents);
3694         pPalmMisc->half_scrn_area_size = (unsigned int)((double)pPalmMisc->half_scrn_area_size / 2);
3695 #ifdef __HOLD_DETECTOR_DEBUG__
3696         XDBG_DEBUG(MGEST, "pPalmMisc->half_scrn_area_size = %d\n", pPalmMisc->half_scrn_area_size);
3697 #endif//__HOLD_DETECTOR_DEBUG__
3698
3699         for(i = 0 ; i < PALM_HORIZ_ARRAY_COUNT ; i++)
3700         {
3701                 pPalmMisc->horiz_coord[i] = pPalmMisc->scrn_width * ((i+1)/(double)PALM_HORIZ_ARRAY_COUNT);
3702 #ifdef __PALM_DETAIL_LOG__
3703                 XDBG_DEBUG(MGEST, "pPalmMisc->horiz_coord[%d]=%d, pPalmMisc->scrn_width=%d\n", i, pPalmMisc->horiz_coord[i], pPalmMisc->scrn_width);
3704 #endif
3705         }
3706         for(i = 0 ; i < PALM_VERTI_ARRAY_COUNT ; i++)
3707         {
3708                 pPalmMisc->verti_coord[i] = pPalmMisc->scrn_height * ((i+1)/(double)PALM_VERTI_ARRAY_COUNT);
3709 #ifdef __PALM_DETAIL_LOG__
3710                 XDBG_DEBUG(MGEST, "pPalmMisc->verti_coord[%d]=%d, pPalmMisc->scrn_height=%d\n", i, pPalmMisc->verti_coord[i], pPalmMisc->scrn_height);
3711 #endif
3712         }
3713
3714         return 1;
3715 }
3716
3717 static int
3718 GesturePalmGetAbsAxisInfo(DeviceIntPtr dev)
3719 {
3720         int i, found = 0;
3721         int numAxes;
3722         PalmStatusPtr pPalm;
3723
3724         Atom atom_wmajor;
3725         Atom atom_tmajor;
3726         Atom atom_tminor;
3727         Atom atom_tangle;
3728         Atom atom_tpalm;
3729         Atom atom_mt_px;
3730         Atom atom_mt_py;
3731
3732         Atom atom_px;
3733         Atom atom_py;
3734         Atom atom_mt_slot;
3735         Atom atom_tracking_id;
3736         Atom atom_distance;
3737
3738         g_pGesture->wmajor_idx = -1;
3739         g_pGesture->tmajor_idx = -1;
3740         g_pGesture->tminor_idx = -1;
3741         g_pGesture->tangle_idx = -1;
3742         g_pGesture->tpalm_idx = -1;
3743         g_pGesture->mt_px_idx = -1;
3744         g_pGesture->mt_py_idx = -1;
3745
3746         memset(&g_pGesture->palm, 0, sizeof(PalmStatus));
3747
3748         if (!dev || !dev->valuator)
3749                 goto out;
3750
3751         numAxes = dev->valuator->numAxes;
3752         atom_mt_px = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_X);
3753         atom_mt_py = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_Y);
3754         atom_wmajor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_WIDTH_MAJOR);
3755         atom_tmajor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR);
3756         atom_tminor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR);
3757         atom_tangle = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_ANGLE);
3758         atom_tpalm = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_PALM);
3759
3760         atom_px = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
3761         atom_py = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
3762         atom_mt_slot = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_SLOT);
3763         atom_tracking_id = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TRACKING_ID);
3764         atom_distance = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_DISTANCE);
3765
3766         if (!numAxes || !atom_mt_px || !atom_mt_py || !atom_tmajor || !atom_tminor  || !atom_tangle || !atom_tpalm)
3767         {
3768                 XDBG_WARNING(MGEST, "one or more axes is/are not supported!\n");
3769                 goto out;
3770         }
3771
3772         for( i = 0 ; i < numAxes ; i++ )
3773         {
3774                 AxisInfoPtr axes = &dev->valuator->axes[i];
3775
3776                 if (!axes || (axes->mode != Absolute))
3777                         continue;
3778
3779                 if ( axes->label == atom_mt_px )
3780                 {
3781                         g_pGesture->mt_px_idx = i;
3782                         found += 1;
3783                 }
3784                 else if ( axes->label == atom_mt_py )
3785                 {
3786                         g_pGesture->mt_py_idx = i;
3787                         found += 2;
3788                 }
3789                 else if ( axes->label == atom_wmajor )
3790                 {
3791                         g_pGesture->wmajor_idx = i;
3792                         found += 3;
3793                 }
3794                 else if ( axes->label == atom_tmajor )
3795                 {
3796                         g_pGesture->tmajor_idx = i;
3797                         found += 4;
3798                 }
3799                 else if ( axes->label == atom_tminor )
3800                 {
3801                         g_pGesture->tminor_idx = i;
3802                         found += 5;
3803                 }
3804                 else if ( axes->label == atom_tangle )
3805                 {
3806                         g_pGesture->tangle_idx = i;
3807                         found += 6;
3808                 }
3809                 else if ( axes->label == atom_tpalm )
3810                 {
3811                         g_pGesture->tpalm_idx = i;
3812                         found += 7;
3813                 }
3814         }
3815
3816         if (found != 28)
3817         {
3818                 XDBG_WARNING(MGEST, "Axes for palm recognization are not supported !\n");
3819                 goto out;
3820         }
3821
3822         pPalm = &g_pGesture->palm;
3823         pixman_region_init(&pPalm->area);
3824
3825         for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
3826         {
3827                 pixman_region_init_rect (&pPalm->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
3828         }
3829
3830         g_pGesture->palm_misc.enabled = 1;
3831         XDBG_INFO(MGEST, "Axes for palm recognization are supported !\n");
3832         return 1;
3833
3834 out:
3835         g_pGesture->palm_misc.enabled = 0;
3836         XDBG_INFO(MGEST, "Palm recognization is not supported !\n");
3837         return 0;
3838 }
3839
3840 static void
3841 GesturePalmDataUpdate(int idx, int type, InternalEvent *ev, DeviceIntPtr device)
3842 {
3843         int wmajor_idx = g_pGesture->wmajor_idx;
3844         int tmajor_idx = g_pGesture->tmajor_idx;
3845         int tminor_idx = g_pGesture->tminor_idx;
3846         int tangle_idx = g_pGesture->tangle_idx;
3847         int tpalm_idx = g_pGesture->tpalm_idx;
3848         int px_idx = g_pGesture->mt_px_idx;
3849         int py_idx= g_pGesture->mt_py_idx;
3850
3851         double width_major = 0.0f;
3852         double touch_major = 0.0f;
3853         double touch_minor = 0.0f;
3854         double touch_angle = 0.0f;
3855         double touch_palm = 0.0f;
3856         double max_width = -1.0f;
3857
3858         int i;
3859         int count;
3860         double meanX = 0.0f;
3861         double meanY = 0.0f;
3862         double tmpXp = 0.0f;
3863         double tmpYp = 0.0f;
3864
3865         PalmStatusPtr pPalm = &g_pGesture->palm;
3866         DeviceEvent *de = &ev->device_event;
3867         pPalm->cx = 0;
3868         pPalm->cy = 0;
3869
3870         if (!de || !de->valuators.data)
3871         {
3872                 XDBG_WARNING(MGEST, "de or de->valuators.data are NULL !\n");
3873                 return;
3874         }
3875
3876         if ((wmajor_idx < 0) || (tmajor_idx < 0) || (tminor_idx < 0) || (tangle_idx < 0) || (tpalm_idx < 0) || (px_idx < 0) || (py_idx < 0))
3877         {
3878                 XDBG_WARNING(MGEST, "One or more of axes are not supported !\n");
3879                 return;
3880         }
3881
3882         width_major = de->valuators.data[wmajor_idx];
3883         touch_major = de->valuators.data[tmajor_idx];
3884         touch_minor = de->valuators.data[tminor_idx];
3885         touch_angle = de->valuators.data[tangle_idx];
3886         touch_palm = de->valuators.data[tpalm_idx];
3887         if( !(g_pGesture->palm.palmflag) && pPalm->max_palm >= PALM_FLICK_MIN_PALM)
3888         {
3889                 g_pGesture->palm.palmflag = 1;
3890                 g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
3891         }
3892
3893 #ifdef __PALM_DETAIL_LOG__
3894         XDBG_DEBUG(MGEST, "[idx:%d, devid:%d, type:%d] width_major=%.f, touch_major=%.f, touch_minor=%.f, touch_palm=%.f \n", idx, de->deviceid, type, width_major, touch_major, touch_minor, touch_palm);
3895         XDBG_DEBUG(MGEST, "[%d]: touch_status: %d, x: %d, y: %d  (cur_touched: %d);\n", idx, pPalm->pti[idx].touch_status, pPalm->pti[idx].x, pPalm->pti[idx].y, pPalm->cur_touched);
3896 #endif
3897
3898         switch(type)
3899         {
3900                 case ET_ButtonPress:
3901                         if (!pPalm->pti[idx].touch_status)
3902                         {
3903                                 pPalm->cur_touched++;
3904                                 pPalm->pti[idx].touch_status = 1;
3905                         }
3906
3907                         pPalm->pti[idx].x = de->root_x;
3908                         pPalm->pti[idx].y = de->root_y;
3909 #ifdef __PALM_DETAIL_LOG__
3910                         XDBG_DEBUG(MGEST, "[idx:%d(devid:%d)][PRESS] x=%d, y=%d, wmajor=%.f, tmajor=%.f, tminor=%.f, tangle=%.f, tpalm=%.f\n", idx, device->id, pPalm->pti[idx].x, pPalm->pti[idx].y, pPalm->pti[idx].wmajor, pPalm->pti[idx].tmajor, pPalm->pti[idx].tminor, pPalm->pti[idx].tangle, pPalm->pti[idx].tpalm);
3911 #endif
3912                         break;
3913
3914                 case ET_ButtonRelease:
3915                         if (pPalm->pti[idx].touch_status)
3916                         {
3917                                 --pPalm->cur_touched;
3918                                 if (pPalm->cur_touched < 0)
3919                                         pPalm->cur_touched = 0;
3920                         }
3921
3922                         pPalm->pti[idx].touch_status = 2;
3923
3924                         pPalm->pti[idx].x = de->root_x;
3925                         pPalm->pti[idx].y = de->root_y;
3926
3927                         pPalm->pti[idx].tangle = 0.0f;
3928                         pPalm->pti[idx].wmajor = 0.0f;
3929                         pPalm->pti[idx].tmajor = 0.0f;
3930                         pPalm->pti[idx].tminor = 0.0f;
3931                         pPalm->pti[idx].tpalm = 0.0f;
3932 #ifdef __PALM_DETAIL_LOG__
3933                         XDBG_DEBUG(MGEST, "[idx:%d(devid:%d)][RELEASE] x=%d, y=%d, wmajor=%.f, tmajor=%.f, tminor=%.f, tangle=%.f, tpalm=%.f\n", idx, device->id, pPalm->pti[idx].x, pPalm->pti[idx].y, pPalm->pti[idx].wmajor, pPalm->pti[idx].tmajor, pPalm->pti[idx].tminor, pPalm->pti[idx].tangle, pPalm->pti[idx].tpalm);
3934 #endif
3935                         break;
3936
3937                 case ET_Motion:
3938                         pPalm->pti[idx].x = de->root_x;
3939                         pPalm->pti[idx].y = de->root_y;
3940
3941                         pPalm->pti[idx].tmajor = touch_major;
3942                         pPalm->pti[idx].tangle = touch_angle;
3943                         pPalm->pti[idx].wmajor = width_major;
3944                         pPalm->pti[idx].tminor = touch_minor;
3945                         pPalm->pti[idx].tpalm = touch_palm;
3946
3947                         if (!pPalm->pti[idx].touch_status || (pPalm->pti[idx].tmajor == 0))
3948                                 return;
3949 #ifdef __PALM_DETAIL_LOG__
3950                         XDBG_DEBUG(MGEST, "[idx:%d(devid:%d)][MOVE] x=%d, y=%d, wmajor=%.f, tmajor=%.f, tminor=%.f, tangle=%.f, tpalm=%.f\n", idx, device->id, pPalm->pti[idx].x, pPalm->pti[idx].y, pPalm->pti[idx].wmajor, pPalm->pti[idx].tmajor, pPalm->pti[idx].tminor, pPalm->pti[idx].tangle, pPalm->pti[idx].tpalm);
3951 #endif
3952                         break;
3953         }
3954
3955         pPalm->sum_size = 0.0f;
3956         pPalm->max_wmajor = -1.0f;
3957         pPalm->max_tmajor = -1.0f;
3958         pPalm->max_tminor = -1.0f;
3959         pPalm->max_size_idx = -1;
3960         pPalm->max_palm = -1.0f;
3961         max_width = -1.0f;
3962
3963         for( count = 0, i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
3964         {
3965                 if (!pPalm->pti[i].touch_status)
3966                         continue;
3967                 if(pPalm->pti[i].touch_status == 2)
3968                         pPalm->pti[i].touch_status =0;
3969                 count++;
3970                 meanX += pPalm->pti[i].x;
3971                 meanY += pPalm->pti[i].y;
3972                 pPalm->sum_size += pPalm->pti[i].wmajor;
3973                 if(max_width < pPalm->pti[i].wmajor)
3974                 {
3975                         pPalm->max_size_idx = i;
3976                 }
3977                 if (pPalm->max_wmajor < pPalm->pti[i].wmajor)
3978                 {
3979                         pPalm->max_wmajor = pPalm->pti[i].wmajor;
3980                 }
3981                 if(pPalm->max_tmajor < pPalm->pti[i].tmajor)
3982                         pPalm->max_tmajor = pPalm->pti[i].tmajor;
3983                 if(pPalm->max_tminor < pPalm->pti[i].tminor)
3984                         pPalm->max_tminor = pPalm->pti[i].tminor;
3985                 if(pPalm->max_palm < pPalm->pti[i].tpalm)
3986                 {
3987                         pPalm->max_palm = (int)pPalm->pti[i].tpalm;
3988 #ifdef __PALM_DETAIL_LOG__
3989                         XDBG_DEBUG(MGEST, "max_palm=%d pPalm->pti[%d].tpalm: %.f\n", pPalm->max_palm, i, pPalm->pti[i].tpalm);
3990 #endif
3991                 }
3992         }
3993
3994         if (pPalm->max_size_idx < 0)
3995         {
3996 #ifdef __PALM_DETAIL_LOG__
3997                 XDBG_DEBUG(MGEST, "Failed to get sum_size !\n");
3998 #endif
3999                 //meanX = 0;
4000                 //meanY = 0;
4001                 pPalm->dispersionX = 0.0f;
4002                 pPalm->deviationX = 0.0f;
4003                 pPalm->dispersionY= 0.0f;
4004                 pPalm->deviationY = 0.0f;
4005                 pPalm->max_eccen = 0.0f;
4006                 pPalm->max_angle = 0.0f;
4007         }
4008         else
4009         {
4010                 meanX /= count;
4011                 meanY /= count;
4012                 pPalm->cx = meanX;
4013                 pPalm->cy = meanY;
4014
4015                 for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
4016                 {
4017                         if (!pPalm->pti[i].touch_status)
4018                                 continue;
4019
4020                         tmpXp += (pPalm->pti[i].x - meanX)*(pPalm->pti[i].x - meanX);
4021                         tmpYp += (pPalm->pti[i].y - meanY)*(pPalm->pti[i].y - meanY);
4022                 }
4023
4024                 pPalm->dispersionX = tmpXp / count;
4025                 pPalm->deviationX = sqrt(pPalm->dispersionX);
4026                 pPalm->dispersionY = tmpYp / count;
4027                 pPalm->deviationY = sqrt(pPalm->dispersionY);
4028 #ifdef __PALM_DETAIL_LOG__
4029                 XDBG_DEBUG(MGEST, "meanX=%.f, meanY=%.f, count=%d, tmpXp=%.f, tmpYp=%.f\n", meanX, meanY, count, tmpXp, tmpYp);
4030 #endif
4031
4032                 pPalm->max_eccen = pPalm->max_tmajor/ pPalm->max_tminor;
4033                 pPalm->max_angle = pPalm->pti[pPalm->max_size_idx].tangle;
4034         }
4035         if(pPalm->palmflag)
4036         {
4037                 TimerCancel(pPalm->palm_single_finger_timer);
4038                 pPalm->single_timer_expired = 0;
4039         }
4040         if(pPalm->biggest_tmajor < pPalm->max_tmajor)
4041                 pPalm->biggest_tmajor = pPalm->max_tmajor;
4042         if(pPalm->biggest_wmajor < pPalm->max_wmajor)
4043                 pPalm->biggest_wmajor = pPalm->max_wmajor;
4044         if(pPalm->bigger_wmajor < pPalm->max_wmajor)
4045                 pPalm->bigger_wmajor = pPalm->max_wmajor;
4046 #ifdef __PALM_DETAIL_LOG__
4047         XDBG_DEBUG(MGEST, "[maxidx:%d] cur_touched=%d, palmflag=%d, sum_size=%.f, max_wmajor=%.f, max_eccen=%.1f, max_angle=%.f\n",     pPalm->max_size_idx, pPalm->cur_touched, pPalm->palmflag, pPalm->sum_size, pPalm->max_wmajor, pPalm->max_eccen, pPalm->max_angle);
4048         XDBG_DEBUG(MGEST, "sum_size=%.f, max_tmajor=%.f, dispersionX=%.f, deviationX=%.f, dispersionY=%.f, deviationY=%.f\n", pPalm->sum_size, pPalm->max_tmajor, pPalm->dispersionX, pPalm->deviationX, pPalm->dispersionY, pPalm->deviationY);
4049         XDBG_DEBUG(MGEST, "max_palm=%d\n", pPalm->max_palm);
4050 #endif
4051 }
4052
4053 static void
4054 GesturePalmUpdateAreaInfo(int type, int idx)
4055 {
4056         int i;
4057         PalmStatusPtr pPalm = &g_pGesture->palm;
4058
4059         switch(type)
4060         {
4061                 case ET_ButtonPress:
4062                         pPalm->finger_rects[idx].extents.x1 = pPalm->pti[idx].x - FINGER_WIDTH;
4063                         pPalm->finger_rects[idx].extents.x2 = pPalm->pti[idx].x + FINGER_WIDTH;
4064                         pPalm->finger_rects[idx].extents.y1 = pPalm->pti[idx].y - FINGER_HEIGHT;
4065                         pPalm->finger_rects[idx].extents.y2 = pPalm->pti[idx].y + FINGER_HEIGHT;
4066 #ifdef __PALM_DETAIL_LOG__
4067                         XDBG_DEBUG(MGEST, "[P] [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", idx, pPalm->finger_rects[idx].extents.x1, pPalm->finger_rects[idx].extents.x2, pPalm->finger_rects[idx].extents.y1, pPalm->finger_rects[idx].extents.y2);
4068                         XDBG_DEBUG(MGEST, "[P] area [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", idx, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2);
4069 #endif// __PALM_DETAIL_LOG__
4070
4071                 if(pPalm->cur_touched == 1)
4072                         {
4073                                 pixman_region_union(&pPalm->area, &pPalm->finger_rects[idx], &pPalm->finger_rects[idx]);
4074 #ifdef __PALM_DETAIL_LOG__
4075                                 XDBG_DEBUG(MGEST, "[P] cur:1 [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", idx, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2);
4076 #endif//__PALM_DETAIL_LOG__
4077                         }
4078                         else
4079                         {
4080                                 pixman_region_union(&pPalm->area, &pPalm->finger_rects[idx], &pPalm->finger_rects[idx]);
4081                                 for(i = 0 ; i < g_pGesture->num_mt_devices ; i++)
4082                                 {
4083                                         if(!pPalm->pti[i].touch_status)
4084                                                 continue;
4085
4086                                         pixman_region_union(&pPalm->area, &pPalm->area, &pPalm->finger_rects[i]);
4087 #ifdef __PALM_DETAIL_LOG__
4088                                         XDBG_DEBUG(MGEST, "[P] cur:else [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", i, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2);
4089 #endif//__PALM_DETAIL_LOG__
4090                                 }
4091                         }
4092                         break;
4093
4094                 case ET_ButtonRelease:
4095                         break;
4096
4097                 case ET_Motion:
4098                         if (!pPalm->pti[idx].touch_status || (pPalm->pti[idx].tmajor == 0))
4099                                 return;
4100                         pPalm->finger_rects[idx].extents.x1 = pPalm->pti[idx].x - FINGER_WIDTH;
4101                         pPalm->finger_rects[idx].extents.x2 = pPalm->pti[idx].x + FINGER_WIDTH;
4102                         pPalm->finger_rects[idx].extents.y1 = pPalm->pti[idx].y - FINGER_HEIGHT;
4103                         pPalm->finger_rects[idx].extents.y2 = pPalm->pti[idx].y + FINGER_HEIGHT;
4104 #ifdef __PALM_DETAIL_LOG__
4105                         XDBG_DEBUG(MGEST, "[M] [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", idx, pPalm->finger_rects[idx].extents.x1, pPalm->finger_rects[idx].extents.x2, pPalm->finger_rects[idx].extents.y1, pPalm->finger_rects[idx].extents.y2);
4106                         XDBG_DEBUG(MGEST, "[M] area [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", idx, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2);
4107 #endif//__PALM_DETAIL_LOG__
4108                         if(pPalm->cur_touched == 1)
4109                 {
4110                                 pixman_region_union(&pPalm->area, &pPalm->finger_rects[idx], &pPalm->finger_rects[idx]);
4111 #ifdef __PALM_DETAIL_LOG__
4112                                 XDBG_DEBUG(MGEST, "[M] cur:1 [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", idx, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2);
4113 #endif//__PALM_DETAIL_LOG__
4114                         }
4115                         else
4116                         {
4117                         pixman_region_union(&pPalm->area, &pPalm->finger_rects[idx], &pPalm->finger_rects[idx]);
4118 #ifdef __PALM_DETAIL_LOG__
4119                         XDBG_DEBUG(MGEST, "[M] cur:else:first [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", idx, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2);
4120 #endif//__PALM_DETAIL_LOG__
4121
4122                                 for(i = 0 ; i < g_pGesture->num_mt_devices ; i++)
4123                                 {
4124                                         if(!pPalm->pti[i].touch_status)
4125                                                 continue;
4126                                         pixman_region_union(&pPalm->area, &pPalm->area, &pPalm->finger_rects[i]);
4127 #ifdef __PALM_DETAIL_LOG__
4128                                         XDBG_DEBUG(MGEST, "[M] cur:else [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", i, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2);
4129 #endif//__PALM_DETAIL_LOG__
4130                                 }
4131                         }
4132                         break;
4133         }
4134 }
4135
4136 void
4137 GesturePalmRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
4138 {
4139         int i;
4140         int idx = -1;
4141         PalmStatusPtr pPalm = &g_pGesture->palm;
4142         static int calc_touched = 0;
4143
4144         if( device->id < g_pGesture->first_fingerid )
4145                 return;
4146
4147         for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
4148         {
4149                 if( device->id == g_pGesture->mt_devices[i]->id )
4150                 {
4151                         idx = i;
4152                         break;
4153                 }
4154         }
4155         if( idx < 0 )
4156                 return;
4157
4158 #ifdef __DETAIL_DEBUG__
4159         XDBG_DEBUG(MGEST, "[g_pGesture->num_pressed=%d]\n", g_pGesture->num_pressed);
4160 #endif//__DETAIL_DEBUG__
4161         if(!g_pGesture->pTempPalmWin)
4162         {
4163                 g_pGesture->pTempPalmWin = GestureGetEventsWindow();
4164                 if(!g_pGesture->pTempPalmWin)
4165                 {
4166 #ifdef __PALM_DETAIL_LOG__
4167                         XDBG_DEBUG(MGEST, "No events are grabbed/selected !\n");
4168 #endif//__PALM_DETAIL_LOG__
4169                         g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL;
4170                         goto flush_or_drop;
4171                 }
4172         }
4173         GesturePalmDataUpdate(idx, type, ev, device);
4174         GesturePalmUpdateAreaInfo(type, idx);
4175
4176         switch(type)
4177         {
4178                 case ET_ButtonPress:
4179                         pPalm->max_touched++;
4180                         if( g_pGesture->num_pressed == 1 )
4181                         {
4182                                 pPalm->palm_single_finger_timer = TimerSet(pPalm->palm_single_finger_timer, 0, 50, GesturePalmSingleFingerTimerHandler, NULL);
4183                         }
4184                         else if(g_pGesture->num_pressed > 1)
4185                         {
4186                                 TimerCancel(pPalm->palm_single_finger_timer);
4187                         }
4188                         break;
4189                 case ET_Motion:
4190                         if(pPalm->cur_touched == 0)
4191                         {
4192                                 break;
4193                         }
4194                         calc_touched++;
4195                         if(calc_touched == pPalm->cur_touched)
4196                         {
4197                                 calc_touched = 0;
4198                         }
4199                         break;
4200                 case ET_ButtonRelease:
4201                         if(calc_touched)
4202                         {
4203                                 calc_touched--;
4204                         }
4205                         break;
4206         }
4207
4208         if( GestureHasFingerEventMask(GestureNotifyFlick, 0) )
4209         {
4210                 if(!(g_pGesture->palm_filter_mask & PalmFlickHorizFilterMask))
4211                 {
4212                         GesturePalmRecognize_FlickHorizen(type, idx);
4213                 }
4214                 if(!(g_pGesture->palm_filter_mask & PalmFlickVertiFilterMask))
4215                 {
4216                         GesturePalmRecognize_FlickVertical(type, idx);
4217                 }
4218         }
4219         if( GestureHasFingerEventMask(GestureNotifyHold, 0) )
4220         {
4221                 if(!(g_pGesture->palm_filter_mask & PalmHoldFilterMask))
4222                 {
4223                         GesturePalmRecognize_Hold(type, idx, 0);
4224                 }
4225         }
4226
4227         if(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL)
4228         {
4229                 pixman_region_init(&pPalm->area);
4230
4231                 for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
4232                 {
4233                         pixman_region_init_rect (&pPalm->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
4234                 }
4235                 pPalm->palmflag = 0;
4236         }
4237
4238         switch(type)
4239         {
4240                 case ET_ButtonPress:
4241                         break;
4242
4243                 case ET_ButtonRelease:
4244                         if(( g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL ) && ( pPalm->cur_touched == 0))
4245                                 goto flush_or_drop;
4246                         break;
4247
4248                 case ET_Motion:
4249                         break;
4250         }
4251 #ifdef __PALM_DETAIL_LOG__
4252         XDBG_DEBUG(MGEST, "recognized_palm: 0x%x, palm_filter_mask: 0x%x, ehtype: %d\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask, g_pGesture->ehtype);
4253 #endif//__PALM_DETAIL_LOG__
4254         if( g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL )
4255         {
4256                 if( !g_pGesture->recognized_palm )
4257                         goto flush_or_drop;
4258         }
4259
4260         if( g_pGesture->recognized_palm )
4261         {
4262                 if( g_pGesture->ehtype == KEEP_EVENTS )
4263                         GestureEventsDrop();
4264                 g_pGesture->ehtype = IGNORE_EVENTS;
4265         }
4266
4267         return;
4268
4269 flush_or_drop:
4270         calc_touched = 0;
4271 #ifdef __PALM_DETAIL_LOG__
4272                 XDBG_DEBUG(MGEST, "GestureFlushOrDrop() !\n");
4273 #endif//__PALM_DETAIL_LOG__
4274                 if( ERROR_INVALPTR == GestureFlushOrDrop() )
4275                 {
4276                         GestureControl(g_pGesture->this_device, DEVICE_OFF);
4277                 }
4278
4279 }
4280
4281 #ifdef _F_SUPPORT_BEZEL_FLICK_
4282 void
4283 GestureBezelRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
4284 {
4285         static OsTimerPtr bezel_finger_timer = NULL;
4286
4287         BezelFlickStatusPtr pBezel = &g_pGesture->bezel;
4288         int direction = 0;
4289         int distance;
4290         double angle;
4291         static Time base_time = 0;
4292         int idx = -1;
4293         int i;
4294         static int px=-1, py=-1;
4295         static int mx=-1, my=-1;
4296         static int rx=-1, ry=-1;
4297         static int event_count=0;
4298
4299         if(g_pGesture->enqueue_fulled == 1)
4300         {
4301 #ifdef __BEZEL_DEBUG__
4302                 XDBG_DEBUG(MGEST, "EQ Event is full.... palm recognize drop..\n");
4303 #endif//__BEZEL_DEBUG__
4304                 goto bezel_failed;
4305         }
4306
4307         if( (PROPAGATE_EVENTS == g_pGesture->ehtype) || (device->id != g_pGesture->first_fingerid) )
4308                 return;
4309
4310         for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
4311         {
4312                 if( device->id == g_pGesture->mt_devices[i]->id )
4313                 {
4314                         idx = i;
4315                         break;
4316                 }
4317         }
4318 #ifdef __BEZEL_DEBUG__
4319         XDBG_DEBUG(MGEST, "[type: %d][g_pGesture->num_pressed=%d, x,y(%d, %d) ]\n", type, g_pGesture->num_pressed, ev->device_event.root_x, ev->device_event.root_x);
4320         XDBG_DEBUG(MGEST, "[filter_mask: 0x%x, bezel_filter_mask: 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->filter_mask, g_pGesture->bezel_filter_mask, g_pGesture->palm_filter_mask);
4321 #endif//__BEZEL_DEBUG__
4322
4323         if (idx < 0)
4324                 return;
4325         if(g_pGesture->recognized_gesture || g_pGesture->recognized_palm)
4326                 goto bezel_failed;
4327         if(g_pGesture->num_pressed > 1)
4328         {
4329 #ifdef __BEZEL_DEBUG__
4330                 XDBG_DEBUG(MGEST, "Not single finger g_pGesture->num_pressed: %d\n", g_pGesture->num_pressed);
4331 #endif//__BEZEL_DEBUG__
4332                 goto bezel_failed;
4333         }
4334         if(pBezel->is_active == BEZEL_END)
4335         {
4336 #ifdef __BEZEL_DEBUG__
4337                 XDBG_DEBUG(MGEST, "Bezel state is END pBezel->is_active: %d\n", pBezel->is_active);
4338                 XDBG_DEBUG(MGEST, "[filter_mask: 0x%x, bezel_filter_mask: 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->filter_mask, g_pGesture->bezel_filter_mask, g_pGesture->palm_filter_mask);
4339 #endif//__BEZEL_DEBUG__
4340                 goto bezel_failed;
4341         }
4342
4343         switch(type)
4344         {
4345                 case ET_ButtonPress:
4346                         base_time = GetTimeInMillis();
4347                         px = ev->device_event.root_x;
4348                         py = ev->device_event.root_y;
4349 #ifdef __BEZEL_DEBUG__
4350                         XDBG_DEBUG(MGEST, "[P] pBezel->is_active: %d, g_pGesture->num_pressed: %d, idx: %d\n", pBezel->is_active, g_pGesture->num_pressed, idx);
4351                         XDBG_DEBUG(MGEST, "[P] g_pGesture->fingers[%d].p: (%d, %d)\n", idx, px,py);
4352 #endif//__BEZEL_DEBUG__
4353                         if( (pBezel->is_active == BEZEL_ON) && ((g_pGesture->num_pressed == 1) && (idx == 0)) )
4354                         {
4355                                 if( ( px < pBezel->top_left.width) && ( py < pBezel->top_left.height) )
4356                                 {
4357 #ifdef __BEZEL_DEBUG__
4358                                         XDBG_DEBUG(MGEST, "[P] top_left\n");
4359 #endif//__BEZEL_DEBUG__
4360                                         pBezel->is_active = BEZEL_START;
4361                                         pBezel->bezelStatus = BEZEL_TOP_LEFT;
4362                                 }
4363                                 else if( (px > (720 - pBezel->top_right.width)) && ( py < pBezel->top_right.height) )
4364                                 {
4365 #ifdef __BEZEL_DEBUG__
4366                                         XDBG_DEBUG(MGEST, "[P] top_right\n");
4367 #endif//__BEZEL_DEBUG__
4368                                         pBezel->is_active = BEZEL_START;
4369                                         pBezel->bezelStatus = BEZEL_TOP_RIGHT;
4370                                 }
4371                                 else if( (px < pBezel->bottom_left.width) && ( py > (1280 - pBezel->bottom_left.height)) )
4372                                 {
4373 #ifdef __BEZEL_DEBUG__
4374                                         XDBG_DEBUG(MGEST, "[P] bottom_left\n");
4375 #endif//__BEZEL_DEBUG__
4376                                         pBezel->is_active = BEZEL_START;
4377                                         pBezel->bezelStatus = BEZEL_BOTTOM_LEFT;
4378                                 }
4379                                 else if( (px > (720 - pBezel->bottom_right.width)) && ( py > (1280 - pBezel->bottom_right.height)) )
4380                                 {
4381 #ifdef __BEZEL_DEBUG__
4382                                         XDBG_DEBUG(MGEST, "[P] bottom_right\n");
4383 #endif//__BEZEL_DEBUG__
4384                                         pBezel->is_active = BEZEL_START;
4385                                         pBezel->bezelStatus = BEZEL_BOTTOM_RIGHT;
4386                                 }
4387                                 else
4388                                 {
4389 #ifdef __BEZEL_DEBUG__
4390                                         XDBG_DEBUG(MGEST, "[P] None\n");
4391 #endif//__BEZEL_DEBUG__
4392                                         pBezel->bezelStatus = NO_BEZEL;
4393                                         goto bezel_failed;
4394                                 }
4395                         }
4396                         if(pBezel->is_active == BEZEL_START)
4397                         {
4398                                 bezel_finger_timer = TimerSet(bezel_finger_timer, 0, 500, GestureBezelSingleFingerTimerHandler, NULL);
4399                         }
4400                         else
4401                         {
4402                                 TimerCancel(bezel_finger_timer);
4403                         }
4404                         break;
4405                 case ET_Motion:
4406                         if(px <0 || py < 0)
4407                                 return;
4408                         mx = ev->device_event.root_x;
4409                         my = ev->device_event.root_y;
4410                         event_count++;
4411                         if( (g_pGesture->bezel.bezel_angle_moving_check) && (event_count >= 10))
4412                         {
4413                                 angle = get_angle(px, py, mx, my);
4414                                 event_count = 0;
4415                                 if(!GestureBezelAngleRecognize(pBezel->bezelStatus, pBezel->flick_distance, angle))
4416                                 {
4417 #ifdef __BEZEL_DEBUG__
4418                                         XDBG_DEBUG(MGEST, "[M] moving limit!\n");
4419 #endif//__BEZEL_DEBUG__
4420                                         TimerCancel(bezel_finger_timer);
4421                                         goto bezel_failed;
4422                                 }
4423                         }
4424                         break;
4425                 case ET_ButtonRelease:
4426                         rx = ev->device_event.root_x;
4427                         ry = ev->device_event.root_y;
4428                         if( (g_pGesture->num_pressed == 0) && (g_pGesture->inc_num_pressed == 1) && (pBezel->is_active == BEZEL_START) )
4429                         {
4430                                 angle = get_angle(px, py, rx, ry);
4431                                 distance = get_distance(px, py, rx, ry);
4432                                 Time duration = GetTimeInMillis() - base_time;
4433 #ifdef __BEZEL_DEBUG__
4434                                 XDBG_DEBUG(MGEST, "[R] bezelStatus: %d, distance: %d, angle: %lf\n", pBezel->bezelStatus, distance, angle);
4435 #endif//__BEZEL_DEBUG__
4436                                 int res = GestureBezelAngleRecognize(pBezel->bezelStatus, distance, angle);
4437                                 if(res)
4438                                 {
4439 #ifdef __BEZEL_DEBUG__
4440                                         XDBG_DEBUG(MGEST, "[R] Bezel Success\n");
4441 #endif//__BEZEL_DEBUG__
4442                                         pBezel->is_active = BEZEL_DONE;
4443                                         g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
4444                                         g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL;
4445                                         TimerCancel(bezel_finger_timer);
4446
4447                                         if( (0.0 < angle) && (angle < RAD_90DEG))
4448                                                 direction = FLICK_NORTHEASTWARD;
4449                                         else if(angle < RAD_180DEG)
4450                                                 direction = FLICK_NORTHWESTWARD;
4451
4452                                         if( GestureHasFingerEventMask(GestureNotifyFlick, 1) )
4453                                                 GestureHandleGesture_Flick(1, distance, duration, direction);
4454                                         goto bezel_cleanup;
4455                                 }
4456 #ifdef __BEZEL_DEBUG__
4457                                 XDBG_DEBUG(MGEST, "[R] Bezel failed\n");
4458 #endif//__BEZEL_DEBUG__
4459                                 goto bezel_failed;
4460                         }
4461                         break;
4462         }
4463         return;
4464 bezel_failed:
4465 #ifdef __BEZEL_DEBUG__
4466         XDBG_DEBUG(MGEST, "[F] Bezel failed\n");
4467 #endif//__BEZEL_DEBUG__
4468         pBezel->is_active = BEZEL_END;
4469         g_pGesture->bezel_filter_mask |= BezelFlickFilterMask;
4470         goto bezel_cleanup;
4471         return;
4472 bezel_cleanup:
4473 #ifdef __BEZEL_DEBUG__
4474         XDBG_DEBUG(MGEST, "[F] Bezel cleanup\n");
4475 #endif//__BEZEL_DEBUG__
4476         TimerCancel(bezel_finger_timer);
4477         if( ERROR_INVALPTR == GestureFlushOrDrop() )
4478         {
4479                 GestureControl(g_pGesture->this_device, DEVICE_OFF);
4480         }
4481         bezel_finger_timer = NULL;
4482         base_time = 0;
4483         px=py=mx=my=rx=ry=-1;
4484         event_count = 0;
4485 }
4486 #endif
4487
4488 void
4489 GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
4490 {
4491         int i;
4492         static OsTimerPtr single_finger_timer = NULL;
4493         int idx = -1;
4494
4495         if( PROPAGATE_EVENTS == g_pGesture->ehtype ||
4496                 device->id < g_pGesture->first_fingerid )
4497                 return;
4498
4499         for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
4500         {
4501                 if( device->id == g_pGesture->mt_devices[i]->id )
4502                 {
4503                         idx = i;
4504                         break;
4505                 }
4506         }
4507
4508         if( idx < 0 )
4509                 return;
4510 #ifdef __DETAIL_DEBUG__
4511         XDBG_DEBUG(MGEST, "[type: %d][g_pGesture->num_pressed=%d, x,y(%d, %d) ]\n", type, g_pGesture->num_pressed, ev->device_event.root_x, ev->device_event.root_x);
4512         XDBG_DEBUG(MGEST, "[inc_num_pressed: %d]\n", g_pGesture->inc_num_pressed);
4513 #ifdef _F_SUPPORT_BEZEL_FLICK_
4514         XDBG_DEBUG(MGEST, "[filter_mask: 0x%x, bezel_filter_mask: 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->filter_mask, g_pGesture->bezel_filter_mask, g_pGesture->palm_filter_mask);
4515         XDBG_DEBUG(MGEST, "[recognized_gesture: 0x%x, bezel_recognize_mask: 0x%x, recognized_palm: 0x%x\n", g_pGesture->recognized_gesture, g_pGesture->bezel_recognized_mask, g_pGesture->recognized_palm);
4516 #else
4517         XDBG_DEBUG(MGEST, "[filter_mask: 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->filter_mask, g_pGesture->palm_filter_mask);
4518         XDBG_DEBUG(MGEST, "[recognized_gesture: 0x%x, recognized_palm: 0x%x\n", g_pGesture->recognized_gesture, g_pGesture->recognized_palm);
4519 #endif
4520 #endif//__DETAIL_DEBUG__
4521
4522
4523         switch( type )
4524         {
4525                 case ET_ButtonPress:
4526                         if( idx == 0 )
4527                                 g_pGesture->event_sum[0] = BTN_PRESSED;
4528                         g_pGesture->fingers[idx].ptime = ev->any.time;
4529                         g_pGesture->fingers[idx].px = ev->device_event.root_x;
4530                         g_pGesture->fingers[idx].py = ev->device_event.root_y;
4531
4532                         if( g_pGesture->num_pressed == 1 )
4533                         {
4534                                 single_finger_timer = TimerSet(single_finger_timer, 0, g_pGesture->singlefinger_threshold, GestureSingleFingerTimerHandler, NULL);
4535                         }
4536                         else
4537                         {
4538                                 TimerCancel(single_finger_timer);
4539                         }
4540
4541                         if( g_pGesture->num_pressed > g_pGesture->num_mt_devices )
4542                                 g_pGesture->num_pressed = g_pGesture->num_mt_devices;
4543
4544                         if( !g_pGesture->pTempWin || g_pGesture->num_pressed != g_pGesture->inc_num_pressed )
4545                         {
4546                                 g_pGesture->pTempWin = GestureGetEventsWindow();
4547
4548                                 if( NULL == g_pGesture->pTempWin )
4549                                 {
4550 #ifdef __DETAIL_DEBUG__
4551                                         XDBG_DEBUG(MGEST, "[g_pGesture->num_pressed=%d] No events were selected !\n", g_pGesture->num_pressed);
4552 #endif//__DETAIL_DEBUG__
4553                                         g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
4554                                         goto flush_or_drop;
4555                                 }
4556                         }
4557
4558                         g_pGesture->inc_num_pressed = g_pGesture->num_pressed;
4559
4560                         g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
4561                         g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
4562                         g_pGesture->finger_rects[idx].extents.y1 =  ev->device_event.root_y - FINGER_HEIGHT;
4563                         g_pGesture->finger_rects[idx].extents.y2 =  ev->device_event.root_y + FINGER_HEIGHT;
4564
4565                         if( g_pGesture->inc_num_pressed == 1 )
4566                         {
4567                                 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
4568 #ifdef __DETAIL_DEBUG__
4569                                 XDBG_DEBUG(MGEST, "[P][g_pGesture->inc_num_pressed=1] AREA_SIZE(area.extents)=%d\n", AREA_SIZE(&g_pGesture->area.extents));
4570 #endif//__DETAIL_DEBUG__
4571                         }
4572                         else
4573                         {
4574                                 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
4575                                 for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ )
4576                                 {
4577                                         pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
4578                                 }
4579 #ifdef __DETAIL_DEBUG__
4580                                 XDBG_DEBUG(MGEST, "[P][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area.extents)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents));
4581 #endif//__DETAIL_DEBUG__
4582                         }
4583
4584                         break;
4585
4586                 case ET_Motion:
4587                         if( !g_pGesture->fingers[idx].ptime )
4588                                 return;
4589                         if( (g_pGesture->inc_num_pressed < 2) && (idx == 0))
4590                         {
4591                                 g_pGesture->event_sum[0] += BTN_MOVING;
4592 #ifdef __DETAIL_DEBUG__
4593                                 XDBG_DEBUG(MGEST, "no seconds finger comming\n");
4594 #endif//__DETAIL_DEBUG__
4595
4596                                 // tolerate false motion events only when second double-finger press is applied
4597                                 if(!g_pGesture->tap_repeated)
4598                                 {
4599 #ifdef __DETAIL_DEBUG__
4600                                         XDBG_DEBUG(MGEST, "single finger!\n");
4601 #endif//__DETAIL_DEBUG__
4602                                         g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
4603                                         goto flush_or_drop;
4604                                 }
4605                                 else if(g_pGesture->event_sum[0] >= 7)
4606                                 {
4607 #ifdef __DETAIL_DEBUG__
4608                                         XDBG_DEBUG(MGEST, "tap repeat Moving Limit Exceeded.\n");
4609 #endif//__DETAIL_DEBUG__
4610                                         g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
4611                                         goto flush_or_drop;
4612                                 }
4613                         }
4614
4615                         g_pGesture->fingers[idx].mx = ev->device_event.root_x;
4616                         g_pGesture->fingers[idx].my = ev->device_event.root_y;
4617
4618                         g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
4619                         g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
4620                         g_pGesture->finger_rects[idx].extents.y1 =  ev->device_event.root_y - FINGER_HEIGHT;
4621                         g_pGesture->finger_rects[idx].extents.y2 =  ev->device_event.root_y + FINGER_HEIGHT;
4622
4623                         if( g_pGesture->inc_num_pressed == 1 )
4624                         {
4625                                 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
4626 #ifdef __DETAIL_DEBUG__
4627                                 XDBG_DEBUG(MGEST, "[M][g_pGesture->inc_num_pressed=1] AREA_SIZE(area)=%d\n", AREA_SIZE(&g_pGesture->area.extents));
4628 #endif//__DETAIL_DEBUG__
4629                         }
4630                         else
4631                         {
4632                                 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
4633                                 for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ )
4634                                 {
4635                                         pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
4636                                 }
4637 #ifdef __DETAIL_DEBUG__
4638                                 XDBG_DEBUG(MGEST, "[M][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents));
4639 #endif//__DETAIL_DEBUG__
4640                         }
4641                         break;
4642
4643                 case ET_ButtonRelease:
4644                         g_pGesture->fingers[idx].rtime = ev->any.time;
4645                         g_pGesture->fingers[idx].rx = ev->device_event.root_x;
4646                         g_pGesture->fingers[idx].ry = ev->device_event.root_y;
4647
4648                         if( g_pGesture->num_pressed <= 0 )
4649                         {
4650 #ifdef __DETAIL_DEBUG__
4651         XDBG_DEBUG(MGEST, "All fingers were released !\n");
4652 #endif//__DETAIL_DEBUG__
4653                                 if( g_pGesture->inc_num_pressed == 1 )
4654                                         goto flush_or_drop;
4655                         }
4656                         break;
4657         }
4658
4659         if( g_pGesture->filter_mask != GESTURE_FILTER_MASK_ALL )
4660         {
4661                 if( !(g_pGesture->filter_mask & FlickFilterMask) )
4662                 {
4663                         GestureRecognize_GroupFlick(type, ev, device, idx);
4664                 }
4665                 if( !(g_pGesture->filter_mask & PanFilterMask) )
4666                 {
4667                         GestureRecognize_GroupPan(type, ev, device, idx, 0);
4668                 }
4669                 if( !(g_pGesture->filter_mask & PinchRotationFilterMask) )
4670                 {
4671                         GestureRecognize_GroupPinchRotation(type, ev, device, idx, 0);
4672                 }
4673                 if( !(g_pGesture->filter_mask & TapFilterMask) )
4674                 {
4675                         GestureRecognize_GroupTap(type, ev, device, idx, 0);
4676                 }
4677                 if( !(g_pGesture->filter_mask & TapNHoldFilterMask) )
4678                 {
4679                         GestureRecognize_GroupTapNHold(type, ev, device, idx, 0);
4680                 }
4681                 if( !(g_pGesture->filter_mask & HoldFilterMask) )
4682                 {
4683                         GestureRecognize_GroupHold(type, ev, device, idx, 0);
4684                 }
4685         }
4686
4687 #ifdef __DETAIL_DEBUG__
4688 #ifdef _F_SUPPORT_BEZEL_FLICK_
4689         XDBG_DEBUG(MGEST, "[filter_mask: 0x%x, bezel_filter_mask: 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->filter_mask, g_pGesture->bezel_filter_mask, g_pGesture->palm_filter_mask);
4690         XDBG_DEBUG(MGEST, "[recognized_gesture: 0x%x, bezel_recognize_mask: 0x%x, recognized_palm: 0x%x\n", g_pGesture->recognized_gesture, g_pGesture->bezel_recognized_mask, g_pGesture->recognized_palm);
4691 #else
4692         XDBG_DEBUG(MGEST, "[filter_mask: 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->filter_mask, g_pGesture->palm_filter_mask);
4693         XDBG_DEBUG(MGEST, "[recognized_gesture: 0x%x, recognized_palm: 0x%x\n", g_pGesture->recognized_gesture, g_pGesture->recognized_palm);
4694 #endif
4695 #endif//__DETAIL_DEBUG__
4696
4697         if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
4698         {
4699                 if( !g_pGesture->recognized_gesture )
4700                         goto flush_or_drop;
4701                 else if( !g_pGesture->num_pressed )
4702                         goto flush_or_drop;
4703         }
4704
4705         if( g_pGesture->recognized_gesture )
4706         {
4707                 if( g_pGesture->ehtype == KEEP_EVENTS )
4708                         GestureEventsDrop();
4709                 g_pGesture->ehtype = IGNORE_EVENTS;
4710         }
4711
4712         return;
4713
4714 flush_or_drop:
4715
4716 #ifdef __DETAIL_DEBUG__
4717         XDBG_DEBUG(MGEST, "GestureFlushOrDrop() !\n");
4718 #endif//__DETAIL_DEBUG__
4719         if( ERROR_INVALPTR == GestureFlushOrDrop() )
4720         {
4721                 GestureControl(g_pGesture->this_device, DEVICE_OFF);
4722         }
4723 }
4724
4725
4726 ErrorStatus GestureFlushOrDrop(void)
4727 {
4728         ErrorStatus err = ERROR_NONE;
4729         PalmStatusPtr pPalm = &g_pGesture->palm;
4730         int i;
4731 #ifdef __DETAIL_DEBUG__
4732         XDBG_DEBUG(MGEST, "recognized_gesture: 0x%x, filter_mask: 0x%x\n", g_pGesture->recognized_gesture, g_pGesture->filter_mask);
4733         XDBG_DEBUG(MGEST, "recognized_palm: 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask);
4734 #ifdef _F_SUPPORT_BEZEL_FLICK_
4735         XDBG_DEBUG(MGEST, "bezel_recognized_mask: 0x%x, bezel_filter_mask: 0x%x\n", g_pGesture->bezel_recognized_mask, g_pGesture->bezel_filter_mask);
4736 #endif
4737 #endif//__DETAIL_DEBUG__
4738
4739         if(g_pGesture->recognized_gesture || g_pGesture->recognized_palm
4740 #ifdef _F_SUPPORT_BEZEL_FLICK_
4741                  || g_pGesture->bezel_recognized_mask)
4742 #else
4743                 )
4744 #endif
4745         {
4746                 g_pGesture->ehtype = IGNORE_EVENTS;
4747                 GestureEventsDrop();
4748                 if(g_pGesture->recognized_palm)
4749                         err = GestureRegionsReinit();
4750         //memset(pPalm->pti, 0, sizeof(pPalm->pti[MAX_MT_DEVICES]));
4751                 for(i=0; i<MAX_MT_DEVICES; i++)
4752                 {
4753                         pPalm->pti[i].touch_status = 0;
4754                         pPalm->pti[i].tangle = 0.0f;
4755                         pPalm->pti[i].wmajor = 0.0f;
4756                         pPalm->pti[i].tmajor = 0.0f;
4757                         pPalm->pti[i].tminor = 0.0f;
4758                         pPalm->pti[i].tpalm = 0.0f;
4759                 }
4760                 if( ERROR_NONE != err )
4761                         return err;
4762         }
4763         else if((g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL) && (g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL)
4764 #ifdef _F_SUPPORT_BEZEL_FLICK_
4765                 && (g_pGesture->bezel_filter_mask == BezelFlickFilterMask))
4766 #else
4767                 )
4768 #endif
4769         {
4770                 g_pGesture->ehtype = PROPAGATE_EVENTS;
4771                 err = GestureEventsFlush();
4772                 if( ERROR_NONE != err )
4773                         return err;
4774
4775                 err = GestureRegionsReinit();
4776                 for(i=0; i<MAX_MT_DEVICES; i++)
4777                 {
4778                         pPalm->pti[i].touch_status = 0;
4779                         pPalm->pti[i].tangle = 0.0f;
4780                         pPalm->pti[i].wmajor = 0.0f;
4781                         pPalm->pti[i].tmajor = 0.0f;
4782                         pPalm->pti[i].tminor = 0.0f;
4783                         pPalm->pti[i].tpalm = 0.0f;
4784                 }
4785                 if( ERROR_NONE != err )
4786                         return err;
4787
4788                 g_pGesture->pTempWin = NULL;
4789                 g_pGesture->inc_num_pressed = 0;
4790                 g_pGesture->event_sum[0] = 0;
4791         }
4792
4793         return ERROR_NONE;
4794 }
4795
4796 void
4797 GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
4798 {
4799         int i;
4800         PalmStatusPtr pPalm = &g_pGesture->palm;
4801 #ifdef _F_SUPPORT_BEZEL_FLICK_
4802         BezelFlickStatusPtr pBezel = &g_pGesture->bezel;
4803 #endif
4804 #ifdef __DEBUG_EVENT_HANDLER__
4805         XDBG_DEBUG(MGEST, "(%d:%d) time:%d cur:%d\n",
4806                         ev->any_event.deviceid, ev->any_event.sync, (int)ev->any.time, (int)GetTimeInMillis());
4807 #endif//__DEBUG_EVENT_HANDLER__
4808
4809         if( MTOUCH_FRAME_SYNC_BEGIN == ev->any_event.sync )
4810         {
4811 #ifdef __DEBUG_EVENT_HANDLER__
4812                 XDBG_DEBUG(MGEST, "SYNC_BEGIN\n");
4813 #endif//__DEBUG_EVENT_HANDLER
4814                 g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_BEGIN;
4815
4816                 if(g_pGesture->is_active)
4817                 {
4818                         g_pGesture->ehtype = KEEP_EVENTS;
4819                         g_pGesture->filter_mask = 0;
4820                         g_pGesture->recognized_gesture = 0;
4821                         g_pGesture->num_pressed = 0;
4822                         g_pGesture->palm_filter_mask = 0;
4823                         g_pGesture->recognized_palm= 0;
4824                         g_pGesture->hold_detector_activate = 1;
4825                         g_pGesture->has_hold_grabmask = 0;
4826                         pPalm->palmflag = 0;
4827                         pPalm->single_timer_expired = 0;
4828                         pPalm->biggest_tmajor = 0;
4829                         pPalm->biggest_wmajor = 0;
4830                         pPalm->bigger_wmajor = 0;
4831                         g_pGesture->enqueue_fulled = 0;
4832 #ifdef _F_SUPPORT_BEZEL_FLICK_
4833                         pBezel->is_active = BEZEL_ON;
4834                         g_pGesture->bezel_filter_mask = 0;
4835                         g_pGesture->bezel_recognized_mask = 0;
4836 #endif
4837                         for( i=0 ; i < g_pGesture->num_mt_devices ; i++ )
4838                                 g_pGesture->fingers[i].ptime = 0;
4839                 }
4840         }
4841         else if( MTOUCH_FRAME_SYNC_END == ev->any_event.sync )
4842         {
4843 #ifdef __DEBUG_EVENT_HANDLER__
4844                 XDBG_DEBUG(MGEST, "SYNC_END\n");
4845 #endif//__DEBUG_EVENT_HANDLER
4846                 g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_END;
4847
4848                 if(g_pGesture->is_active)
4849                 {
4850                         g_pGesture->ehtype = PROPAGATE_EVENTS;
4851                         g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL;
4852                         pPalm->cur_touched = 0;
4853                         pPalm->palmflag = 0;
4854                         pPalm->max_palm = 0;
4855                         g_pGesture->pTempPalmWin = NULL;
4856                         if(pPalm->palm_single_finger_timer)
4857                                 TimerCancel(pPalm->palm_single_finger_timer);
4858                         g_pGesture->pTempWin = NULL;
4859                         g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0;
4860                         g_pGesture->event_sum[0] = 0;
4861                         pPalm->max_touched = 0;
4862 #ifdef _F_SUPPORT_BEZEL_FLICK_
4863                         pBezel->is_active = BEZEL_END;
4864                         g_pGesture->bezel_filter_mask = BezelFlickFilterMask;
4865 #endif
4866                 }
4867         }
4868 }
4869
4870 void
4871 GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
4872 {
4873 #ifdef __DEBUG_EVENT_HANDLER__
4874         XDBG_DEBUG(MGEST, "mode: %d devid=%d time:%d cur: %d\n", g_pGesture->ehtype, device->id, ev->any.time, GetTimeInMillis());
4875 #endif//__DEBUG_EVENT_HANDLER__
4876         switch( g_pGesture->ehtype )
4877         {
4878                 case KEEP_EVENTS:
4879                         if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device) )
4880                         {
4881                                 GestureControl(g_pGesture->this_device, DEVICE_OFF);
4882                                 return;
4883                         }
4884                         if( g_pGesture->num_mt_devices )
4885                         {
4886                                 if(!(device->id < g_pGesture->first_fingerid))
4887                                         g_pGesture->num_pressed++;
4888 #ifdef _F_SUPPORT_BEZEL_FLICK_
4889                                 if(!(g_pGesture->bezel_filter_mask == BezelFlickFilterMask))
4890                                         GestureBezelRecognize(ET_ButtonPress, ev, device);
4891 #endif
4892                                 if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL))
4893                                         GestureRecognize(ET_ButtonPress, ev, device);
4894                                 if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL))
4895                                         GesturePalmRecognize(ET_ButtonPress, ev, device);
4896                         }
4897                         else
4898                                 device->public.processInputProc(ev, device);
4899                         GestureHoldDetector(ET_ButtonPress, ev, device);
4900                         break;
4901
4902                 case PROPAGATE_EVENTS:
4903                         if(!(device->id < g_pGesture->first_fingerid))
4904                                 g_pGesture->num_pressed++;
4905                         device->public.processInputProc(ev, device);
4906                         GestureHoldDetector(ET_ButtonPress, ev, device);
4907                         break;
4908
4909                 case IGNORE_EVENTS:
4910                         if(!(device->id < g_pGesture->first_fingerid))
4911                                 g_pGesture->num_pressed++;
4912 #ifdef _F_SUPPORT_BEZEL_FLICK_
4913                         if(!(g_pGesture->bezel_filter_mask == BezelFlickFilterMask))
4914                                 GestureBezelRecognize(ET_ButtonPress, ev, device);
4915 #endif
4916                         if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL))
4917                                 GestureRecognize(ET_ButtonPress, ev, device);
4918                         if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL))
4919                                 GesturePalmRecognize(ET_ButtonPress, ev, device);
4920                         break;
4921
4922                 default:
4923                         break;
4924         }
4925 }
4926
4927 void
4928 GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
4929 {
4930 #ifdef __DEBUG_EVENT_HANDLER__
4931         XDBG_DEBUG(MGEST, "devid=%d time:%d cur: %d\n", device->id, ev->any.time, GetTimeInMillis());
4932 #endif//__DEBUG_EVENT_HANDLER__
4933
4934         switch( g_pGesture->ehtype )
4935         {
4936                 case KEEP_EVENTS:
4937                         if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device) )
4938                         {
4939                                 GestureControl(g_pGesture->this_device, DEVICE_OFF);
4940                                 return;
4941                         }
4942                         if( g_pGesture->num_mt_devices )
4943                         {
4944 #ifdef _F_SUPPORT_BEZEL_FLICK_
4945                                 if(!(g_pGesture->bezel_filter_mask == BezelFlickFilterMask))
4946                                         GestureBezelRecognize(ET_Motion, ev, device);
4947 #endif
4948                                 if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL))
4949                                         GestureRecognize(ET_Motion, ev, device);
4950                                 if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL))
4951                                         GesturePalmRecognize(ET_Motion, ev, device);
4952                         }
4953                         else
4954                                 device->public.processInputProc(ev, device);
4955                         GestureHoldDetector(ET_Motion, ev, device);
4956                         break;
4957
4958                 case PROPAGATE_EVENTS:
4959                         device->public.processInputProc(ev, device);
4960                         GestureHoldDetector(ET_Motion, ev, device);
4961                         break;
4962
4963                 case IGNORE_EVENTS:
4964 #ifdef _F_SUPPORT_BEZEL_FLICK_
4965                         if(!(g_pGesture->bezel_filter_mask == BezelFlickFilterMask))
4966                                 GestureBezelRecognize(ET_Motion, ev, device);
4967 #endif
4968                         if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL))
4969                                 GestureRecognize(ET_Motion, ev, device);
4970                         if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL))
4971                                 GesturePalmRecognize(ET_Motion, ev, device);
4972                         break;
4973
4974                 default:
4975                         break;
4976         }
4977
4978 }
4979
4980 void
4981 GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
4982 {
4983 #ifdef __DEBUG_EVENT_HANDLER__
4984         XDBG_DEBUG(MGEST, "devid=%d time:%d cur: %d\n", device->id, ev->any.time, GetTimeInMillis());
4985 #endif//__DEBUG_EVENT_HANDLER__
4986         switch( g_pGesture->ehtype )
4987         {
4988                 case KEEP_EVENTS:
4989                         if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device) )
4990                         {
4991                                 GestureControl(g_pGesture->this_device, DEVICE_OFF);
4992                                 return;
4993                         }
4994                         if( g_pGesture->num_mt_devices )
4995                         {
4996                                 if(!(device->id < g_pGesture->first_fingerid))
4997                                         g_pGesture->num_pressed--;
4998 #ifdef _F_SUPPORT_BEZEL_FLICK_
4999                                 if(!(g_pGesture->bezel_filter_mask == BezelFlickFilterMask))
5000                                         GestureBezelRecognize(ET_ButtonRelease, ev, device);
5001 #endif
5002                                 if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL))
5003                                         GestureRecognize(ET_ButtonRelease, ev, device);
5004                                 if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL))
5005                                         GesturePalmRecognize(ET_ButtonRelease, ev, device);
5006                         }
5007                         else
5008                                 device->public.processInputProc(ev, device);
5009                         GestureHoldDetector(ET_ButtonRelease, ev, device);
5010                         break;
5011
5012                 case PROPAGATE_EVENTS:
5013                         if(!(device->id < g_pGesture->first_fingerid))
5014                                 g_pGesture->num_pressed--;
5015                         device->public.processInputProc(ev, device);
5016                         GestureHoldDetector(ET_ButtonRelease, ev, device);
5017                         break;
5018
5019                 case IGNORE_EVENTS:
5020                         if(!(device->id < g_pGesture->first_fingerid))
5021                                 g_pGesture->num_pressed--;
5022 #ifdef _F_SUPPORT_BEZEL_FLICK_
5023                         if(!(g_pGesture->bezel_filter_mask == BezelFlickFilterMask))
5024                                 GestureBezelRecognize(ET_ButtonRelease, ev, device);
5025 #endif
5026                         if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL))
5027                                 GestureRecognize(ET_ButtonRelease, ev, device);
5028                         if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL))
5029                                 GesturePalmRecognize(ET_ButtonRelease, ev, device);
5030                         break;
5031
5032                 default:
5033                         break;
5034         }
5035 }
5036
5037 void
5038 GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
5039 {
5040 #ifdef __DEBUG_EVENT_HANDLER__
5041         XDBG_DEBUG(MGEST, "devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
5042 #endif//__DEBUG_EVENT_HANDLER__
5043
5044         if(DPMSPowerLevel == DPMSModeOff)
5045         {
5046                 XDBG_INFO(MGEST, "LCD status : Off\n");
5047
5048                 {
5049                         int i;
5050                         for(i = 0 ; i < NUM_PASSKEYS ; i++)
5051                         {
5052                                 if(0 == g_pGesture->pass_keycodes[i])
5053                                         break;
5054
5055                                 if(g_pGesture->pass_keycodes[i] == ev->device_event.detail.key)
5056                                 {
5057                                         XDBG_SECURE(MGEST, "Pass KeyPress (devid:%d, keycode:%d) during LCD Off!\n", device->id, ev->device_event.detail.key);
5058                                         goto handle_keypress;
5059                                 }
5060                         }
5061
5062                         XDBG_SECURE(MGEST, "Ignore KeyPress (devid:%d, keycode:%d) during LCD Off!\n", device->id, ev->device_event.detail.key);
5063                         return;
5064                 }
5065         }
5066
5067 handle_keypress:
5068
5069         if((g_pGesture->mtsync_status != MTOUCH_FRAME_SYNC_END) && (device->id == g_pGesture->touchkey_id))
5070         {
5071                 XDBG_SECURE(MGEST, "Ignore TouchKey KeyPress (devid:%d, keycode:%d)\n", device->id, ev->device_event.detail.key);
5072                 return;
5073         }
5074
5075         device->public.processInputProc(ev, device);
5076 }
5077
5078 static ErrorStatus
5079 GestureEnableEventHandler(InputInfoPtr pInfo)
5080  {
5081         Bool res;
5082         GestureDevicePtr pGesture = pInfo->private;
5083
5084         res = GestureInstallResourceStateHooks();
5085
5086         if( !res )
5087         {
5088                 XDBG_ERROR(MGEST, "Failed on GestureInstallResourceStateHooks() !\n");
5089                 return ERROR_ABNORMAL;
5090         }
5091
5092         res = GestureSetMaxNumberOfFingers((int)MAX_MT_DEVICES);
5093
5094         if( !res )
5095         {
5096                 XDBG_ERROR(MGEST, "Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)MAX_MT_DEVICES);
5097                 goto failed;
5098         }
5099
5100         res = GestureRegisterCallbacks(GestureCbEventsGrabbed, GestureCbEventsSelected);
5101
5102         if( !res )
5103         {
5104                 XDBG_ERROR(MGEST, "Failed to register callbacks for GestureEventsGrabbed(), GestureEventsSelected() !\n");
5105                 goto failed;
5106         }
5107
5108         pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 5000, GestureTimerHandler, pInfo);
5109
5110         if( !pGesture->device_setting_timer )
5111         {
5112                 XDBG_ERROR(MGEST, "Failed to allocate memory for timer !\n");
5113                 goto failed;
5114         }
5115
5116         return ERROR_NONE;
5117
5118 failed:
5119         GestureUninstallResourceStateHooks();
5120         GestureUnsetMaxNumberOfFingers();
5121
5122         return ERROR_ABNORMAL;
5123 }
5124
5125 static ErrorStatus
5126 GestureDisableEventHandler(void)
5127 {
5128         ErrorStatus err = ERROR_NONE;
5129
5130         mieqSetHandler(ET_KeyPress, NULL);
5131         mieqSetHandler(ET_ButtonPress, NULL);
5132         mieqSetHandler(ET_ButtonRelease, NULL);
5133         mieqSetHandler(ET_Motion, NULL);
5134         mieqSetHandler(ET_MTSync, NULL);
5135
5136         err = GestureFiniEQ();
5137
5138         if( ERROR_INVALPTR == err )
5139         {
5140                 XDBG_ERROR(MGEST, "EQ is invalid or was freed already !\n");
5141         }
5142
5143         GestureRegisterCallbacks(NULL, NULL);
5144         GestureUninstallResourceStateHooks();
5145
5146         return err;
5147 }
5148
5149 static CARD32
5150 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
5151 {
5152         InputInfoPtr pInfo = (InputInfoPtr)arg;
5153         GestureDevicePtr pGesture = pInfo->private;
5154
5155         int idx = 0;
5156         DeviceIntPtr dev;
5157         for( dev = inputInfo.pointer ; dev; dev = dev->next )
5158         {
5159                 if(IsMaster(dev) && IsPointerDevice(dev))
5160                 {
5161                         pGesture->master_pointer = dev;
5162                         XDBG_INFO(MGEST, "[id:%d] Master Pointer=%s\n", dev->id, pGesture->master_pointer->name);
5163                         continue;
5164                 }
5165
5166                 if(IsXTestDevice(dev, NULL) && IsPointerDevice(dev))
5167                 {
5168                         pGesture->xtest_pointer = dev;
5169                         XDBG_INFO(MGEST, "[id:%d] XTest Pointer=%s\n", dev->id, pGesture->xtest_pointer->name);
5170                         continue;
5171                 }
5172
5173                 if(IsPointerDevice(dev))
5174                 {
5175                         if( idx >= MAX_MT_DEVICES )
5176                         {
5177                                 XDBG_WARNING(MGEST, "Number of mt device is over MAX_MT_DEVICES(%d) !\n",
5178                                         MAX_MT_DEVICES);
5179                                 continue;
5180                         }
5181                         pGesture->mt_devices[idx] = dev;
5182                         XDBG_INFO(MGEST, "[id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name);
5183                         GesturePalmGetAbsAxisInfo(dev);
5184                         idx++;
5185                 }
5186         }
5187
5188         for( dev = inputInfo.keyboard ; dev; dev = dev->next )
5189         {
5190                 if(strcasestr(dev->name, "touchkey"))
5191                 {
5192                         g_pGesture->touchkey_id = dev->id;
5193                         break;
5194                 }
5195         }
5196
5197         if( !pGesture->master_pointer || !pGesture->xtest_pointer )
5198         {
5199                 XDBG_ERROR(MGEST, "Failed to get info of master pointer or XTest pointer !\n");
5200                 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
5201                 pGesture->num_mt_devices = 0;
5202
5203                 return 0;
5204         }
5205
5206         pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
5207         pGesture->num_mt_devices = idx;
5208
5209         if( !pGesture->num_mt_devices )
5210         {
5211                 XDBG_ERROR(MGEST, "Failed to mt device information !\n");
5212                 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
5213                 pGesture->num_mt_devices = 0;
5214         pGesture->first_fingerid = -1;
5215                 return 0;
5216         }
5217
5218         pGesture->first_fingerid = pGesture->mt_devices[0]->id;
5219         memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices);
5220         pGesture->pRootWin = RootWindow(pGesture->master_pointer);
5221
5222         if(g_pGesture->palm_misc.enabled)
5223                 GesturePalmGetScreenInfo();
5224
5225         g_pGesture->pTempWin = NULL;
5226         g_pGesture->pTempPalmWin = NULL;
5227         g_pGesture->inc_num_pressed = 0;
5228
5229         if( ERROR_NONE != GestureRegionsInit() || ERROR_NONE != GestureInitEQ() )
5230         {
5231                 goto failed;
5232         }
5233
5234         mieqSetHandler(ET_KeyPress, GestureHandleKeyPressEvent);
5235         mieqSetHandler(ET_ButtonPress, GestureHandleButtonPressEvent);
5236         mieqSetHandler(ET_ButtonRelease, GestureHandleButtonReleaseEvent);
5237         mieqSetHandler(ET_Motion, GestureHandleMotionEvent);
5238         mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
5239
5240         return 0;
5241
5242 failed:
5243
5244         GestureUninstallResourceStateHooks();
5245         GestureUnsetMaxNumberOfFingers();
5246
5247         return 0;
5248 }
5249
5250 BOOL
5251 IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
5252 {
5253         if (IsMaster(dev))
5254                 return FALSE;
5255
5256         if (master)
5257                 return (dev->xtest_master_id == master->id);
5258
5259         return (dev->xtest_master_id != 0);
5260 }
5261
5262 void
5263 GestureEnable(int enable, Bool prop, DeviceIntPtr dev)
5264 {
5265         if((!enable) && (g_pGesture->is_active))
5266         {
5267                 g_pGesture->is_active = 0;
5268                 XDBG_INFO(MGEST, "Disabled !\n");
5269         }
5270         else if((enable) && (!g_pGesture->is_active))
5271         {
5272                 g_pGesture->is_active = 1;
5273                 XDBG_INFO(MGEST, "Enabled !\n");
5274         }
5275
5276         if(!prop)
5277                  XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
5278 }
5279
5280 ErrorStatus
5281 GestureRegionsInit(void)
5282 {
5283         int i;
5284         PalmStatusPtr pPalm = &g_pGesture->palm;
5285
5286         if( !g_pGesture )
5287                 return ERROR_INVALPTR;
5288
5289         pixman_region_init(&g_pGesture->area);
5290         pixman_region_init(&pPalm->area);
5291
5292         for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
5293         {
5294                 pixman_region_init_rect (&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
5295                 pixman_region_init_rect (&pPalm->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
5296         }
5297
5298         return ERROR_NONE;
5299 }
5300
5301 ErrorStatus
5302 GestureRegionsReinit(void)
5303 {
5304         PalmStatusPtr pPalm = &g_pGesture->palm;
5305         int i;
5306         if( !g_pGesture )
5307         {
5308                 XDBG_ERROR(MGEST, "Invalid pointer access !\n");
5309                 return ERROR_INVALPTR;
5310         }
5311
5312         pixman_region_init(&g_pGesture->area);
5313         pixman_region_init(&pPalm->area);
5314
5315         for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
5316         {
5317                 pixman_region_init_rect (&pPalm->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
5318         }
5319
5320         return ERROR_NONE;
5321 }
5322
5323 ErrorStatus
5324 GestureInitEQ(void)
5325 {
5326         int i;
5327         IEventPtr tmpEQ;
5328
5329         tmpEQ = (IEventRec *)calloc(GESTURE_EQ_SIZE, sizeof(IEventRec));
5330
5331         if( !tmpEQ )
5332         {
5333                 XDBG_ERROR(MGEST, "Failed to allocate memory for EQ !\n");
5334                 return ERROR_ALLOCFAIL;
5335         }
5336
5337         for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
5338         {
5339                 tmpEQ[i].event = (InternalEvent *)malloc(sizeof(InternalEvent));
5340                 if( !tmpEQ[i].event )
5341                 {
5342                         XDBG_ERROR(MGEST, "Failed to allocation memory for each event buffer in EQ !\n");
5343                         i--;
5344                         while(i >= 0 && tmpEQ[i].event)
5345                         {
5346                                 free(tmpEQ[i].event);
5347                                 tmpEQ[i].event = NULL;
5348                         }
5349                         free (tmpEQ);
5350                         tmpEQ = NULL;
5351                         return ERROR_ALLOCFAIL;
5352                 }
5353         }
5354
5355         g_pGesture->EQ = tmpEQ;
5356         g_pGesture->headEQ = g_pGesture->tailEQ = 0;
5357
5358         return ERROR_NONE;
5359 }
5360
5361 ErrorStatus
5362 GestureFiniEQ(void)
5363 {
5364         int i;
5365
5366         if( !g_pGesture || !g_pGesture->EQ )
5367                 return ERROR_INVALPTR;
5368
5369         for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
5370         {
5371                 if( g_pGesture->EQ[i].event )
5372                 {
5373                         free(g_pGesture->EQ[i].event);
5374                         g_pGesture->EQ[i].event = NULL;
5375                 }
5376         }
5377
5378         free(g_pGesture->EQ);
5379         g_pGesture->EQ = NULL;
5380
5381         return ERROR_NONE;
5382 }
5383
5384 ErrorStatus
5385 GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
5386 {
5387         int tail;
5388
5389         if( !g_pGesture || !g_pGesture->EQ )
5390         {
5391                 XDBG_ERROR(MGEST, "Invalid pointer access !\n");
5392                 return ERROR_INVALPTR;
5393         }
5394
5395         tail = g_pGesture->tailEQ;
5396
5397         if( tail >= GESTURE_EQ_SIZE )
5398         {
5399                 XDBG_WARNING(MGEST, "Gesture EQ is full !\n");
5400                 printk("[X11][GestureEnqueueEvent] Gesture EQ is full...Force Gesture Flush !\n");
5401                 g_pGesture->enqueue_fulled = 1;
5402                 if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL))
5403                 {
5404                         if( !(g_pGesture->filter_mask & FlickFilterMask) )
5405                         {
5406                                 GestureRecognize_GroupFlick(ev->any.type, ev, device, 0);
5407                         }
5408                         if( !(g_pGesture->filter_mask & PanFilterMask) )
5409                         {
5410                                 GestureRecognize_GroupPan(ev->any.type, ev, device, 0, 0);
5411                         }
5412                         if( !(g_pGesture->filter_mask & PinchRotationFilterMask) )
5413                         {
5414                                 GestureRecognize_GroupPinchRotation(ev->any.type, ev, device, 0, 0);
5415                         }
5416                         if( !(g_pGesture->filter_mask & TapFilterMask) )
5417                         {
5418                                 GestureRecognize_GroupTap(ev->any.type, ev, device, 0, 0);
5419                         }
5420                         if( !(g_pGesture->filter_mask & TapNHoldFilterMask) )
5421                         {
5422                                 GestureRecognize_GroupTapNHold(ev->any.type, ev, device, 0, 0);
5423                         }
5424                         if( !(g_pGesture->filter_mask & HoldFilterMask) )
5425                         {
5426                                 GestureRecognize_GroupHold(ev->any.type, ev, device, 0, 0);
5427                         }
5428                 }
5429                 if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL))
5430                 {
5431                         if(!(g_pGesture->palm_filter_mask & PalmHoldFilterMask))
5432                         {
5433                                 GesturePalmRecognize_Hold(ev->any.type, 0, 0);
5434                         }
5435                         if(!(g_pGesture->palm_filter_mask & PalmFlickHorizFilterMask))
5436                         {
5437                                 GesturePalmRecognize_FlickHorizen(ev->any.type, 0);
5438                         }
5439                         if(!(g_pGesture->palm_filter_mask & PalmFlickHorizFilterMask))
5440                         {
5441                                 GesturePalmRecognize_FlickVertical(ev->any.type, 0);
5442                         }
5443                 }
5444 #ifdef _F_SUPPORT_BEZEL_FLICK_
5445                 if(!(g_pGesture->bezel_filter_mask == BezelFlickFilterMask))
5446                 {
5447                         GestureBezelRecognize(ev->any.type, ev, device);
5448                 }
5449 #endif
5450                 g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
5451                 g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL;
5452 #ifdef _F_SUPPORT_BEZEL_FLICK_
5453                 g_pGesture->bezel_filter_mask = BezelFlickFilterMask;
5454                 g_pGesture->bezel_recognized_mask = 0;
5455 #endif
5456                 g_pGesture->recognized_gesture = 0;
5457                 g_pGesture->recognized_palm = 0;
5458                 if( ERROR_INVALPTR == GestureFlushOrDrop() )
5459                 {
5460                         GestureControl(g_pGesture->this_device, DEVICE_OFF);
5461                 }
5462                 return ERROR_EQFULL;
5463         }
5464
5465 #ifdef __DETAIL_DEBUG__
5466         switch( ev->any.type )
5467         {
5468                 case ET_ButtonPress:
5469                         XDBG_DEBUG(MGEST, "ET_ButtonPress (id:%d)\n", device->id);
5470                         break;
5471
5472                 case ET_ButtonRelease:
5473                         XDBG_DEBUG(MGEST, "ET_ButtonRelease (id:%d)\n", device->id);
5474                         break;
5475
5476                 case ET_Motion:
5477                         XDBG_DEBUG(MGEST, "ET_Motion (id:%d)\n", device->id);
5478                         break;
5479         }
5480 #endif//__DETAIL_DEBUG__
5481
5482         g_pGesture->EQ[tail].device = device;
5483         g_pGesture->EQ[tail].screen_num = screen_num;
5484         memcpy(g_pGesture->EQ[tail].event, ev, sizeof(InternalEvent));//need to be optimized
5485         g_pGesture->tailEQ++;
5486
5487         return ERROR_NONE;
5488 }
5489
5490 ErrorStatus
5491 GestureEventsFlush(void)
5492 {
5493         int i, j;
5494         DeviceIntPtr device;
5495
5496         if( !g_pGesture->EQ )
5497         {
5498                 XDBG_ERROR(MGEST, "Invalid pointer access !\n");
5499                 return ERROR_INVALPTR;
5500         }
5501
5502 #ifdef __DETAIL_DEBUG__
5503         XDBG_DEBUG(MGEST, "\n");
5504 #endif//__DETAIL_DEBUG__
5505
5506         for( i = g_pGesture->headEQ ; i < g_pGesture->tailEQ ; i++)
5507         {
5508                 device = g_pGesture->EQ[i].device;
5509 #ifdef __DETAIL_DEBUG__
5510                 if(g_pGesture->EQ[i].event->any.type != ET_Motion)
5511                         XDBG_DEBUG(MGEST, "[%d] type: %d\n", device->id, g_pGesture->EQ[i].event->any.type);
5512 #endif//__DETAIL_DEBUG__
5513                 for(j = 0 ; j < MAX_MT_DEVICES+1 ; j++)
5514                 {
5515                         if(g_pGesture->palm.qti[j].devid == device->id)
5516                         {
5517 #ifdef __DETAIL_DEBUG__
5518                                 if(g_pGesture->EQ[i].event->any.type != ET_Motion)
5519                                         XDBG_DEBUG(MGEST, "[%d] type: %d(pressed: %d) time: %d\n", device->id, g_pGesture->EQ[i].event->any.type, g_pGesture->palm.qti[j].pressed, GetTimeInMillis());
5520 #endif//__DETAIL_DEBUG__
5521                                 if( (g_pGesture->palm.qti[j].pressed == 0) && (g_pGesture->EQ[i].event->any.type == ET_ButtonRelease) )
5522                                 {
5523                                         XDBG_WARNING(MGEST, "Enqueued event..ButtonRelease with no ButtonPress !(devid: %d)\n", device->id);
5524                                         g_pGesture->EQ[i].event->any.type = ET_ButtonPress;
5525                                         device->public.processInputProc(g_pGesture->EQ[i].event, device);
5526                                         g_pGesture->EQ[i].event->any.type = ET_ButtonRelease;
5527                                         g_pGesture->palm.qti[j].pressed = 0;
5528                                 }
5529                                 else if(g_pGesture->EQ[i].event->any.type == ET_ButtonPress)
5530                                 {
5531                                         g_pGesture->palm.qti[j].pressed = 1;
5532                                 }
5533                                 else if( (g_pGesture->palm.qti[j].pressed == 1) && (g_pGesture->EQ[i].event->any.type == ET_ButtonRelease))
5534                                 {
5535                                         g_pGesture->palm.qti[j].pressed = 0;
5536                                 }
5537                                 break;
5538                         }
5539                         else if(g_pGesture->palm.qti[j].devid == 0)
5540                         {
5541                                 g_pGesture->palm.qti[j].devid = device->id;
5542                                 j--;
5543                         }
5544                 }
5545 #ifdef __DETAIL_DEBUG__
5546                 if(g_pGesture->EQ[i].event->any.type != ET_Motion)
5547                         XDBG_DEBUG(MGEST, "!!! [%d] type: %d\n", device->id, g_pGesture->EQ[i].event->any.type);
5548 #endif
5549                 device->public.processInputProc(g_pGesture->EQ[i].event, device);
5550         }
5551         memset(g_pGesture->palm.qti, 0, sizeof(g_pGesture->palm.qti[MAX_MT_DEVICES+1]));
5552
5553         for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
5554                 g_pGesture->event_sum[i] = 0;
5555
5556         g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
5557
5558         return ERROR_NONE;
5559 }
5560
5561
5562 void
5563 GestureEventsDrop(void)
5564 {
5565 #ifdef __DETAIL_DEBUG__
5566         XDBG_DEBUG(MGEST, "\n");
5567 #endif//__DETAIL_DEBUG__
5568
5569         g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
5570 }
5571
5572 #ifdef HAVE_PROPERTIES
5573 static void
5574 GestureInitProperty(DeviceIntPtr dev)
5575 {
5576         int rc;
5577
5578         prop_gesture_recognizer_onoff = MakeAtom(GESTURE_RECOGNIZER_ONOFF, strlen(GESTURE_RECOGNIZER_ONOFF),  TRUE);
5579         rc = XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
5580
5581         if (rc != Success)
5582                 return;
5583
5584         XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE);
5585 }
5586
5587 static int
5588 GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
5589                  BOOL checkonly)
5590 {
5591         if( prop_gesture_recognizer_onoff == atom )
5592         {
5593                 int data;
5594                 if( val->format != 32 || val->type != XA_INTEGER || val->size != 1 )
5595                         return BadMatch;
5596
5597                 if( !checkonly )
5598                 {
5599                         data = *((int *)val->data);
5600                         GestureEnable(data, TRUE, dev);
5601                 }
5602         }
5603
5604         return Success;
5605 }
5606 #endif//HAVE_PROPERTIES
5607
5608 static int
5609 GestureInit(DeviceIntPtr device)
5610 {
5611         InputInfoPtr pInfo;
5612         pInfo = device->public.devicePrivate;
5613
5614 #ifdef HAVE_PROPERTIES
5615         GestureInitProperty(device);
5616         XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL);
5617 #endif
5618
5619         return Success;
5620 }
5621
5622 static void
5623 GestureFini(DeviceIntPtr device)
5624 {
5625         XIRegisterPropertyHandler(device, NULL, NULL, NULL);
5626 }
5627
5628 static pointer
5629 GesturePlug(pointer module, pointer options, int *errmaj, int *errmin)
5630 {
5631         xf86AddInputDriver(&GESTURE, module, 0);
5632         return module;
5633 }
5634
5635 static void
5636 GestureUnplug(pointer p)
5637 {
5638 }
5639
5640 static int
5641 GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
5642 {
5643     int rc = BadAlloc;
5644     GestureDevicePtr    pGesture;
5645 #ifdef _F_SUPPORT_BEZEL_FLICK_
5646     BezelFlickStatusPtr pBezel;
5647 #endif
5648
5649     pGesture = calloc(1, sizeof(GestureDeviceRec));
5650
5651     if (!pGesture) {
5652         pInfo->private = NULL;
5653         //xf86DeleteInput(pInfo, 0);
5654         goto error;
5655     }
5656
5657     g_pGesture = pGesture;
5658     pInfo->private = pGesture;
5659     pInfo->flags = 0;
5660     pInfo->read_input = GestureReadInput; /* new data avl */
5661     pInfo->switch_mode = NULL; /* toggle absolute/relative mode */
5662     pInfo->device_control = GestureControl; /* enable/disable dev */
5663     /* process driver specific options */
5664     pGesture->device = xf86SetStrOption(pInfo->options, "Device", "/dev/null");
5665     pGesture->is_active = xf86SetIntOption(pInfo->options, "Activate", 0);
5666
5667     {
5668         int i;
5669         char tmp[10];
5670
5671         memset(&pGesture->pass_keycodes, 0, sizeof(pGesture->pass_keycodes));
5672
5673         for(i = 0 ; i < NUM_PASSKEYS ; i++)
5674         {
5675                 snprintf(tmp, sizeof(tmp), "PassKey%d", i+1);
5676                 pGesture->pass_keycodes[i] = xf86SetIntOption(pInfo->options, tmp, 0);
5677                 XDBG_SECURE(MGEST, "pass_keycode[%d]=%d\n", i, pGesture->pass_keycodes[i]);
5678         }
5679     }
5680
5681     pGesture->gestureWin = None;
5682 #ifdef _F_SUPPORT_BEZEL_FLICK_
5683     pBezel = &pGesture->bezel;
5684     pBezel->is_active = xf86SetIntOption(pInfo->options, "Bezel_Activate", 0);
5685     pBezel->top_left.width = xf86SetIntOption(pInfo->options, "Bezel_Top_Left_Width", 0);
5686     pBezel->top_left.height = xf86SetIntOption(pInfo->options, "Bezel_Top_Left_Height", 0);
5687     pBezel->top_right.width = xf86SetIntOption(pInfo->options, "Bezel_Top_Right_Width", 0);
5688     pBezel->top_right.height = xf86SetIntOption(pInfo->options, "Bezel_Top_Right_Height", 0);
5689     pBezel->bottom_left.width = xf86SetIntOption(pInfo->options, "Bezel_Bottom_Left_Width", 0);
5690     pBezel->bottom_left.height = xf86SetIntOption(pInfo->options, "Bezel_Bottom_Left_Height", 0);
5691     pBezel->bottom_right.width = xf86SetIntOption(pInfo->options, "Bezel_Bottom_Right_Width", 0);
5692     pBezel->bottom_right.height = xf86SetIntOption(pInfo->options, "Bezel_Bottom_Right_Height", 0);
5693     pBezel->flick_distance = xf86SetIntOption(pInfo->options, "Bezel_Flick_Distance", 0);
5694     pBezel->bezel_angle_ratio = xf86SetIntOption(pInfo->options, "Bezel_Flick_Angle_Ratio", 0);
5695     pBezel->bezel_angle_moving_check = xf86SetIntOption(pInfo->options, "Bezel_Flick_Angle_Moving_Check", 0);
5696 #ifdef __BEZEL_DEBUG__
5697         XDBG_DEBUG(MGEST, "[BEZEL] top_left.width: %d, top_left.height: %d\n", pBezel->top_left.width, pBezel->top_left.height);
5698         XDBG_DEBUG(MGEST, "[BEZEL] top_right.width: %d, top_right.height: %d\n", pBezel->top_right.width, pBezel->top_right.height);
5699         XDBG_DEBUG(MGEST, "[BEZEL] bottom_left.width: %d, bottom_left.height: %d\n", pBezel->bottom_left.width, pBezel->bottom_left.height);
5700         XDBG_DEBUG(MGEST, "[BEZEL] bottom_right.width: %d, bottom_right.height: %d\n", pBezel->bottom_right.width, pBezel->bottom_right.height);
5701         XDBG_DEBUG(MGEST, "[BEZEL] flick_distance: %d, bezel_angle_ratio: %d, bezel_angle_moving_check: %d\n", pBezel->flick_distance, pBezel->bezel_angle_ratio, pBezel->bezel_angle_moving_check);
5702 #endif//__BEZEL_DEBUG__
5703 #endif
5704
5705         pGesture->pinchrotation_time_threshold = xf86SetIntOption(pInfo->options, "PinchRotationTimeThresHold", PINCHROTATION_TIME_THRESHOLD);
5706         pGesture->pinchrotation_dist_threshold = xf86SetRealOption(pInfo->options, "PinchRotationDistThresHold", PINCHROTATION_DIST_THRESHOLD);
5707         pGesture->pinchrotation_angle_threshold = xf86SetRealOption(pInfo->options, "PinchRotationAngleThresHold", PINCHROTATION_ANGLE_THRESHOLD);
5708         pGesture->singlefinger_threshold = xf86SetIntOption(pInfo->options, "SingleFingerThresHold", SGL_FINGER_TIME_THRESHOLD);
5709         pGesture->singletap_threshold = xf86SetIntOption(pInfo->options, "SingleTapThresHold", SGL_TAP_TIME_THRESHOLD);
5710         pGesture->doubletap_threshold = xf86SetIntOption(pInfo->options, "DoubleTapThresHold", DBL_TAP_TIME_THRESHOLD);
5711
5712         if (pGesture->is_active)
5713                 pGesture->ehtype = KEEP_EVENTS;
5714         else
5715                 pGesture->ehtype = PROPAGATE_EVENTS;
5716 #ifdef _F_SUPPORT_BEZEL_FLICK_
5717         if(pBezel->bezel_angle_ratio > 0)
5718         {
5719                 pBezel->min_rad = (RAD_90DEG / pBezel->bezel_angle_ratio);
5720                 pBezel->max_rad = ((RAD_90DEG / pBezel->bezel_angle_ratio) * (pBezel->bezel_angle_ratio-1));
5721                 pBezel->min_180_rad = (RAD_90DEG + pBezel->min_rad);
5722                 pBezel->max_180_rad = (RAD_90DEG + pBezel->max_rad);
5723         }
5724         else
5725         {
5726                 pBezel->min_rad = MIN_RAD;
5727                 pBezel->max_rad = MAX_RAD;
5728                 pBezel->min_180_rad = RAD_180DEG_MIN;
5729                 pBezel->max_180_rad = RAD_180DEG_MAX;
5730         }
5731 #endif
5732     pGesture->lastSelectedWin = None;
5733     pGesture->touchkey_id = 0;
5734     pGesture->mtsync_status = MTOUCH_FRAME_SYNC_END;
5735     g_pGesture->grabMask = g_pGesture->eventMask = 0;
5736
5737     xf86Msg(X_INFO, "%s: Using device %s.\n", pInfo->name, pGesture->device);
5738
5739     /* process generic options */
5740     xf86CollectInputOptions(pInfo, NULL);
5741     xf86ProcessCommonOptions(pInfo, pInfo->options);
5742
5743     pInfo->fd = -1;
5744
5745         g_pGesture->tap_repeated = 0;
5746
5747         g_pGesture->palm.palmflag = 0;
5748         g_pGesture->palm.palm_single_finger_timer = NULL;
5749         g_pGesture->enqueue_fulled = 0;
5750         g_pGesture->zoom_enabled = 0;
5751         memset(g_pGesture->palm.qti, 0, sizeof(g_pGesture->palm.qti[MAX_MT_DEVICES+1]));
5752
5753     return Success;
5754
5755 error:
5756     if (pInfo->fd >= 0)
5757         close(pInfo->fd);
5758     return rc;
5759 }
5760
5761 static void
5762 GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
5763 {
5764         GestureDevicePtr pGesture = pInfo->private;
5765
5766         g_pGesture = pGesture = NULL;
5767         pInfo->private = NULL;
5768
5769         xf86DeleteInput(pInfo, 0);
5770 }
5771
5772 static int
5773 GestureControl(DeviceIntPtr device, int what)
5774 {
5775     InputInfoPtr  pInfo = device->public.devicePrivate;
5776     GestureDevicePtr pGesture = pInfo->private;
5777
5778     switch(what)
5779     {
5780         case DEVICE_INIT:
5781              GestureInit(device);
5782             break;
5783
5784         /* Switch device on.  Establish socket, start event delivery.  */
5785         case DEVICE_ON:
5786             xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
5787
5788             if (device->public.on)
5789                     break;
5790
5791             device->public.on = TRUE;
5792              pGesture->this_device = device;
5793              pGesture->num_mt_devices = 0;
5794              if( ERROR_ABNORMAL == GestureEnableEventHandler(pInfo) )
5795                 goto device_off;
5796             break;
5797
5798        case DEVICE_OFF:
5799 device_off:
5800              GestureDisableEventHandler();
5801              GestureFini(device);
5802              pGesture->this_device = NULL;
5803              xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
5804
5805             if (!device->public.on)
5806                 break;
5807
5808             pInfo->fd = -1;
5809             device->public.on = FALSE;
5810             break;
5811
5812       case DEVICE_CLOSE:
5813             /* free what we have to free */
5814             break;
5815     }
5816     return Success;
5817 }
5818
5819 static void
5820 GestureReadInput(InputInfoPtr pInfo)
5821 {
5822 }
5823