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