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