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