Initialize Tizen 2.3
[adaptation/xorg/driver/xserver-xorg-input-gesture.git] / wearable / src / gesture.c
1 /**************************************************************************
2
3 xserver-xorg-input-gesture
4
5 Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
6
7 Contact: Sung-Jin Park <sj76.park@samsung.com>
8          Sangjin LEE <lsj119@samsung.com>
9
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
17
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
20 of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 **************************************************************************/
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include <linux/input.h>
37 #include <linux/types.h>
38
39 #include <xf86_OSproc.h>
40
41 #include <unistd.h>
42
43 #include <xf86.h>
44 #include <xf86Xinput.h>
45 #include <exevents.h>
46 #include <xorgVersion.h>
47 #include <xkbsrv.h>
48
49 #ifdef HAVE_PROPERTIES
50 #include <X11/Xatom.h>
51 #include <xserver-properties.h>
52 /* 1.6 has properties, but no labels */
53 #ifdef AXIS_LABEL_PROP
54 #define HAVE_LABELS
55 #else
56 #undef HAVE_LABELS
57 #endif
58
59 #endif
60
61 #include <stdio.h>
62 #include <sys/stat.h>
63 #include <sys/syscall.h>
64 #include <unistd.h>
65 #include <errno.h>
66 #include <sys/types.h>
67 #include <fcntl.h>
68 #include <xorg-server.h>
69 #include <xorgVersion.h>
70 #include <xf86Module.h>
71 #include <X11/Xatom.h>
72 #include "gesture.h"
73 #include <xorg/mi.h>
74
75 char *strcasestr(const char *s, const char *find);
76 static void printk(const char* fmt, ...) __attribute__((format(printf, 1, 0)));
77
78 //Basic functions
79 static int GesturePreInit(InputDriverPtr  drv, InputInfoPtr pInfo, int flags);
80 static void GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
81 static pointer GesturePlug(pointer module, pointer options, int *errmaj, int  *errmin);
82 static void GestureUnplug(pointer p);
83 static int GestureControl(DeviceIntPtr    device,int what);
84 static int GestureInit(DeviceIntPtr device);
85 static void GestureFini(DeviceIntPtr device);
86 static void GestureReadInput(InputInfoPtr pInfo);
87
88 //other initializers
89 ErrorStatus GestureRegionsInit(void);
90
91 //event queue handling functions
92 ErrorStatus GestureInitEQ(void);
93 ErrorStatus GestureFiniEQ(void);
94 ErrorStatus GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
95 ErrorStatus GestureEventsFlush(void);
96 void GestureEventsDrop(void);
97
98 //utility functions
99 ErrorStatus GestureRegionsReinit(void);
100 void GestureEnable(int enable, Bool prop, DeviceIntPtr dev);
101 void GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent);
102 void GestureCbEventsSelected(Window win, Mask *pEventMask);
103 WindowPtr GestureGetEventsWindow(void);
104
105 //Enqueued event handlers and enabler/disabler
106 static ErrorStatus GestureEnableEventHandler(InputInfoPtr pInfo);
107 static ErrorStatus GestureDisableEventHandler(void);
108 static CARD32 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
109 static CARD32 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
110 void GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
111 void GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
112 void GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
113 void GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
114 void GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
115 void GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
116
117 void GestureEmulateHWKey(DeviceIntPtr dev, int keycode);
118
119 //Gesture recognizer helper
120 static Bool PointInBorderSize(WindowPtr pWin, int x, int y);
121 static WindowPtr GestureWindowOnXY(int x, int y);
122 Bool GestureHasFingerEventMask(int eventType, int num_finger);
123
124 //Gesture recognizer and handlers
125 void GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device);
126 void GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
127 void GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int start_point, int direction);
128 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
129 void GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction);
130 void GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy);
131 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds);
132 ErrorStatus GestureFlushOrDrop(void);
133
134 #ifdef HAVE_PROPERTIES
135 //function related property handling
136 static void GestureInitProperty(DeviceIntPtr dev);
137 static int GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkonly);
138 #endif
139
140 static Atom prop_gesture_recognizer_onoff = None;
141
142 GestureDevicePtr g_pGesture = NULL;
143 _X_EXPORT InputDriverRec GESTURE = {
144     1,
145     "gesture",
146     NULL,
147     GesturePreInit,
148     GestureUnInit,
149     NULL,
150     0
151 };
152
153 static XF86ModuleVersionInfo GestureVersionRec =
154 {
155     "gesture",
156     MODULEVENDORSTRING,
157     MODINFOSTRING1,
158     MODINFOSTRING2,
159     XORG_VERSION_CURRENT,
160     PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR,
161     PACKAGE_VERSION_PATCHLEVEL,
162     ABI_CLASS_XINPUT,
163     ABI_XINPUT_VERSION,
164     MOD_CLASS_XINPUT,
165     {0, 0, 0, 0}
166 };
167
168 _X_EXPORT XF86ModuleData gestureModuleData =
169 {
170     &GestureVersionRec,
171     &GesturePlug,
172     &GestureUnplug
173 };
174
175 static void
176 printk(const char* fmt, ...)
177 {
178         static FILE* fp = NULL;
179         static char init = 0;
180         va_list argptr;
181
182         if(!init && !fp)
183         {
184                 fp = fopen("/dev/kmsg", "wt");
185                 init = 1;
186         }
187
188         if(!fp) return;
189
190         va_start(argptr, fmt);
191         vfprintf(fp, fmt, argptr);
192         fflush(fp);
193         va_end(argptr);
194 }
195
196 static Bool
197 PointInBorderSize(WindowPtr pWin, int x, int y)
198 {
199     BoxRec box;
200     if( pixman_region_contains_point (&pWin->borderSize, x, y, &box) )
201         return TRUE;
202
203     return FALSE;
204 }
205
206 static WindowPtr
207 GestureWindowOnXY(int x, int y)
208 {
209     WindowPtr pWin;
210     BoxRec box;
211     SpritePtr pSprite;
212     DeviceIntPtr pDev = g_pGesture->master_pointer;
213
214     pSprite = pDev->spriteInfo->sprite;
215     pSprite->spriteTraceGood = 1;       /* root window still there */
216     pWin = RootWindow(pDev)->firstChild;
217
218     while (pWin)
219     {
220         if ((pWin->mapped) &&
221             (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
222             (x < pWin->drawable.x + (int)pWin->drawable.width +
223              wBorderWidth(pWin)) &&
224             (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
225             (y < pWin->drawable.y + (int)pWin->drawable.height +
226              wBorderWidth (pWin))
227             /* When a window is shaped, a further check
228              * is made to see if the point is inside
229              * borderSize
230              */
231             && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
232             && (!wInputShape(pWin) ||
233                 RegionContainsPoint(wInputShape(pWin),
234                                     x - pWin->drawable.x,
235                                     y - pWin->drawable.y, &box))
236 #ifdef ROOTLESS
237     /* In rootless mode windows may be offscreen, even when
238      * they're in X's stack. (E.g. if the native window system
239      * implements some form of virtual desktop system).
240      */
241                 && !pWin->rootlessUnhittable
242 #endif
243             )
244         {
245             if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
246             {
247                 pSprite->spriteTraceSize += 10;
248                 pSprite->spriteTrace = realloc(pSprite->spriteTrace,
249                                     pSprite->spriteTraceSize*sizeof(WindowPtr));
250             }
251             pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
252             pWin = pWin->firstChild;
253         }
254         else
255             pWin = pWin->nextSib;
256     }
257     return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
258 }
259
260 Bool
261 GestureHasFingerEventMask(int eventType, int num_finger)
262 {
263         Bool ret = FALSE;
264         Mask eventmask = (1L << eventType);
265
266         if( (g_pGesture->grabMask & eventmask) &&
267                 (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[num_finger].window != None) )
268         {
269 #ifdef __DETAIL_DEBUG__
270                 ErrorF("[X11][GestureHasFingerEventMask] TRUE !! Has grabMask\n");
271 #endif//__DETAIL_DEBUG__
272                 return TRUE;
273         }
274
275         if( g_pGesture->eventMask & eventmask )
276         {
277 #ifdef __DETAIL_DEBUG__
278                 ErrorF("[X11][GestureHasFingerEventMask] TRUE !! Has eventMask\n");
279 #endif//__DETAIL_DEBUG__
280                 return TRUE;
281         }
282
283 #ifdef __DETAIL_DEBUG__
284         ErrorF("[X11][GestureHasFingerEventMask] FALSE !! eventType=%d, num_finger=%d\n", eventType, num_finger);
285 #endif//__DETAIL_DEBUG__
286
287         return ret;
288 }
289
290 static CARD32
291 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
292 {
293         int event_type = *(int *)arg;
294
295         switch( event_type )
296         {
297                 case GestureNotifyHold:
298 #ifdef __DETAIL_DEBUG__
299                         ErrorF("[GestureEventTimerHandler] GestureNotifyHold (event_type = %d)\n", event_type);
300 #endif//__DETAIL_DEBUG__
301                         GestureRecognize_GroupHold(event_type, NULL, NULL, 0, 1);
302                         break;
303                 case GestureNotifyTap:
304 #ifdef __DETAIL_DEBUG__
305                         ErrorF("[GestureEventTimerHandler] GestureNotifyTap (event_type = %d)\n", event_type);
306 #endif//__DETAIL_DEBUG__
307                         GestureRecognize_GroupTap(event_type, NULL, NULL, 0, 1);
308                         break;
309                 default:
310 #ifdef __DETAIL_DEBUG__
311                         ErrorF("[GestureEventTimerHandler] unknown event_type (=%d)\n", event_type);
312 #endif//__DETAIL_DEBUG__
313                         if(timer)
314                                 ErrorF("[GestureEventTimerHandler] timer=%x\n", (unsigned int)timer);
315         }
316
317         return 0;
318 }
319
320 void
321 GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy)
322 {
323         Window target_win;
324         WindowPtr target_pWin;
325         xGestureNotifyTapEvent tev;
326
327         //skip non-tap events and single finger tap
328         if( !tap_repeat || num_finger <= 1 )
329                 return;
330
331 #ifdef __DETAIL_DEBUG__
332         ErrorF("[X11][GestureHandleGesture_Tap] num_finger=%d, tap_repeat=%d, cx=%d, cy=%d\n",
333                 num_finger, tap_repeat, cx, cy);
334 #endif//__DETAIL_DEBUG__
335
336         g_pGesture->recognized_gesture |= WTapFilterMask;
337         memset(&tev, 0, sizeof(xGestureNotifyTapEvent));
338         tev.type = GestureNotifyTap;
339         tev.kind = GestureDone;
340         tev.num_finger = num_finger;
341         tev.tap_repeat = tap_repeat;
342         tev.interval = 0;
343         tev.cx = cx;
344         tev.cy = cy;
345
346         target_win = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].window;
347         target_pWin = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].pWin;
348
349         if( g_pGesture->grabMask && (target_win != None) )
350         {
351                 tev.window = target_win;
352         }
353         else
354         {
355                 tev.window = g_pGesture->gestureWin;
356         }
357
358         ErrorF("[X11][GestureHandleGesture_Tap] tev.window=0x%x, g_pGesture->grabMask=0x%x\n", (unsigned int)tev.window, (unsigned int)g_pGesture->grabMask);
359
360         GestureSendEvent(target_pWin, GestureNotifyTap, GestureTapMask, (xGestureCommonEvent *)&tev);
361 }
362
363 void
364 GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction)
365 {
366 #ifdef __DETAIL_DEBUG__
367         ErrorF("[X11][GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n",
368                 num_of_fingers, distance, duration, direction);
369 #endif//__DETAIL_DEBUG__
370         switch(direction)
371         {
372                 case FLICK_NORTHWARD:
373                         ErrorF("[X11][GestureHandleGesture_Flick] Flick Down \n");
374                         GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down);
375                         break;
376
377                 case FLICK_SOUTHWARD:
378                         ErrorF("[X11][GestureHandleGesture_Flick] Flick Up \n");
379                         GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up);
380                         break;
381                 case FLICK_WESTWARD:
382                         if(g_pGesture->power_pressed == 2)
383                         {
384                                 ErrorF("[X11][GestureHandleGesture_Flick] Flick Right & power_pressed\n");
385                                 GestureEmulateHWKey(g_pGesture->hwkey_dev, 122);
386                         }
387                         break;
388                 default:
389                         break;
390         }
391         g_pGesture->recognized_gesture |= WFlickFilterMask;
392 }
393
394 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds)
395 {
396         Window target_win;
397         WindowPtr target_pWin;
398         xGestureNotifyHoldEvent hev;
399
400 #ifdef __DETAIL_DEBUG__
401         ErrorF("[X11][GestureHandleGesture_Hold] num_fingers=%d, cx=%d, cy=%d, holdtime=%d, kinds=%d\n",
402                                 num_fingers, cx, cy, holdtime, kinds);
403 #endif//__DETAIL_DEBUG__
404
405         g_pGesture->recognized_gesture |= WHoldFilterMask;
406         memset(&hev, 0, sizeof(xGestureNotifyHoldEvent));
407         hev.type = GestureNotifyHold;
408         hev.kind = kinds;
409         hev.num_finger = num_fingers;
410         hev.holdtime = holdtime;
411         hev.cx = cx;
412         hev.cy = cy;
413
414         if(g_pGesture->GrabEvents)
415         {
416                 target_win = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].window;
417                 target_pWin = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].pWin;
418         }
419         else
420         {
421                 target_win = None;
422                 target_pWin = None;
423         }
424
425         if( g_pGesture->grabMask && (target_win != None) )
426         {
427                 hev.window = target_win;
428         }
429         else
430         {
431                 hev.window = g_pGesture->gestureWin;
432         }
433
434 #ifdef __DETAIL_DEBUG__
435         ErrorF("[X11][GestureHandleGesture_Hold] hev.window=0x%x, g_pGesture->grabMask=0x%x\n", hev.window, g_pGesture->grabMask);
436 #endif//__DETAIL_DEBUG__
437
438         GestureSendEvent(target_pWin, GestureNotifyHold, GestureHoldMask, (xGestureCommonEvent *)&hev);
439 }
440
441
442 void
443 GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
444 {
445         static int num_pressed = 0;
446         static int base_area_size = 0;
447
448         int cx, cy;
449         int area_size;
450
451         static int state = 0;
452         static int mbits = 0;
453         static int base_cx;
454         static int base_cy;
455         static pixman_box16_t base_box_ext;
456
457         static int tap_repeat = 0;
458         static int prev_num_pressed = 0;
459
460         static OsTimerPtr tap_event_timer = NULL;
461         static int event_type = GestureNotifyTap;
462
463         if( timer_expired )
464         {
465 #ifdef __DETAIL_DEBUG__
466                 ErrorF("[GroupTap][Timer] state=%d\n", state);
467 #endif//__DETAIL_DEBUG__
468
469                 switch( state )
470                 {
471                         case 1://first tap initiation check
472                                 if( num_pressed )
473                                 {
474 #ifdef __DETAIL_DEBUG__
475                                         ErrorF("[GroupTap][Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", tap_repeat, num_pressed, tap_repeat);
476 #endif//__DETAIL_DEBUG__
477                                         state = 0;
478                                         goto cleanup_tap;
479                                 }
480                                 break;
481
482                         case 2:
483                                 if( tap_repeat <= 1 )
484                                 {
485 #ifdef __DETAIL_DEBUG__
486                                         ErrorF("[GroupTap][Timer][state=2] %d finger SINGLE TAP !(ignored)\n", prev_num_pressed);
487 #endif//__DETAIL_DEBUG__
488                                         state = 0;
489                                         goto cleanup_tap;
490                                 }
491
492 #ifdef __DETAIL_DEBUG__
493                                 ErrorF("[GroupTap][Timer][state=2]  tap_repeat=%d, num_pressed=%d\n", tap_repeat, num_pressed);
494 #endif//__DETAIL_DEBUG__
495                                 if( GestureHasFingerEventMask(GestureNotifyTap, prev_num_pressed) )
496                                 {
497                                         GestureHandleGesture_Tap(prev_num_pressed, tap_repeat, base_cx, base_cy);
498                                 }
499                                 goto cleanup_tap;
500                                 break;
501                 }
502
503                 return;
504         }
505
506         switch( type )
507         {
508                 case ET_ButtonPress:
509                         g_pGesture->fingers[idx].flags |= PressFlagTap;
510
511                         if( g_pGesture->num_pressed < 2 )
512                                 return;
513
514                         if( (!base_area_size || g_pGesture->num_pressed > num_pressed) )
515                         {
516                                 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
517                                 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
518                                 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
519                                 base_box_ext.x1 = base_cx-TAP_MOVE_THRESHOLD;
520                                 base_box_ext.y1 = base_cy-TAP_MOVE_THRESHOLD;
521                                 base_box_ext.x2 = base_cx+TAP_MOVE_THRESHOLD;
522                                 base_box_ext.y2 = base_cy+TAP_MOVE_THRESHOLD;
523                                 state = 1;
524                                 TimerCancel(tap_event_timer);
525                                 tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->singletap_threshold, GestureEventTimerHandler, (int *)&event_type);
526                         }
527                         num_pressed = g_pGesture->num_pressed;
528
529 #ifdef __DETAIL_DEBUG__
530                         ErrorF("[GroupTap][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);
531 #endif//__DETAIL_DEBUG__
532                         break;
533
534                 case ET_Motion:
535                         if( !(g_pGesture->fingers[idx].flags & PressFlagTap ) )
536                                 break;
537
538                         if( num_pressed < 2 )
539                                 return;
540
541                         if( num_pressed != g_pGesture->num_pressed )
542                         {
543 #ifdef __DETAIL_DEBUG__
544                                 ErrorF("[GroupTap][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
545 #endif//__DETAIL_DEBUG__
546                                 //goto cleanup_tap;
547                         }
548
549                         mbits |= (1 << idx);
550                         if( mbits == (pow(2, num_pressed)-1) )
551                         {
552                                 area_size = AREA_SIZE(&g_pGesture->area.extents);
553                                 cx = AREA_CENTER_X(&g_pGesture->area.extents);
554                                 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
555 #ifdef __DETAIL_DEBUG__
556                                 ErrorF("[GroupTap][M][num_pressed=%d] area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size));
557                                 ErrorF("[GroupTap][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
558                                 ErrorF("[GroupTap][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
559 #endif//__DETAIL_DEBUG__
560
561                                 if( ABS(base_area_size-area_size) >= TAP_AREA_THRESHOLD )
562                                 {
563 #ifdef __DETAIL_DEBUG__
564                                         ErrorF("[GroupTap][M] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, ABS(base_area_size-area_size));
565 #endif//__DETAIL_DEBUG__
566                                         goto cleanup_tap;
567                                 }
568
569                                 if( !INBOX(&base_box_ext, cx, cy) )
570                                 {
571 #ifdef __DETAIL_DEBUG__
572                                         ErrorF("[GroupTap][M] current center coordinates is not in base coordinates box !\n");
573 #endif//__DETAIL_DEBUG__
574                                         goto cleanup_tap;
575                                 }
576                         }
577                         break;
578
579                 case ET_ButtonRelease:
580                         if( g_pGesture->num_pressed )
581                                 break;
582
583                         if( !tap_repeat )
584                         {
585                                 prev_num_pressed = num_pressed;
586                         }
587
588                         tap_repeat++;
589
590 #ifdef __DETAIL_DEBUG__
591                         ErrorF("[GroupTap][R] tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, num_pressed, prev_num_pressed);
592 #endif//__DETAIL_DEBUG__
593
594                         if(( num_pressed != prev_num_pressed ) || (!GestureHasFingerEventMask(GestureNotifyTap, num_pressed)) )
595                         {
596 #ifdef __DETAIL_DEBUG__
597                                 ErrorF("[GroupTap][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
598                                         num_pressed, prev_num_pressed, num_pressed);
599 #endif//__DETAIL_DEBUG__
600                                 goto cleanup_tap;
601                         }
602
603                         if( tap_repeat < MAX_TAP_REPEATS )
604                         {
605                                 state = 2;
606                                 TimerCancel(tap_event_timer);
607                                 tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->doubletap_threshold, GestureEventTimerHandler, (int *)&event_type);
608                                 base_area_size = num_pressed = 0;
609                                 break;
610                         }
611
612 #ifdef __DETAIL_DEBUG__
613                         ErrorF("[GroupTap][R] %d finger %s\n", num_pressed, (tap_repeat==2) ? "DBL_TAP" : "TRIPLE_TAP");
614 #endif//__DETAIL_DEBUG__
615
616                         if( GestureHasFingerEventMask(GestureNotifyTap, num_pressed) )
617                                 GestureHandleGesture_Tap(num_pressed, tap_repeat, base_cx, base_cy);
618
619                         if( tap_repeat >= MAX_TAP_REPEATS )
620                         {
621                                 goto cleanup_tap;
622                         }
623
624                         prev_num_pressed = num_pressed;
625                         num_pressed = 0;
626                         break;
627         }
628
629         return;
630
631 cleanup_tap:
632
633         if( 0 == state )
634                 g_pGesture->recognized_gesture &= ~WTapFilterMask;
635         g_pGesture->filter_mask |= WTapFilterMask;
636
637         if( g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL )
638         {
639 #ifdef __DETAIL_DEBUG__
640                 ErrorF("[GroupTap][cleanup] GestureFlushOrDrop() !\n");
641 #endif//__DETAIL_DEBUG__
642
643                 if( ERROR_INVALPTR == GestureFlushOrDrop() )
644                 {
645                         GestureControl(g_pGesture->this_device, DEVICE_OFF);
646                 }
647         }
648
649         num_pressed = 0;
650         tap_repeat = 0;
651         prev_num_pressed = 0;
652         mbits = 0;
653         state = 0;
654         TimerCancel(tap_event_timer);
655         return;
656 }
657
658 void
659 GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int start_point, int direction)
660 {
661         static int num_pressed = 0;
662         static Time base_time = 0;
663         Time duration;
664         int distance;
665         static int diff_base_coord = 0;
666         static int diff_base_minor_coord = 0;
667         static int diff_current_coord = 0;
668         static int false_diff_count = 0;
669         static int false_minor_diff_count = 0;
670         static float angle = 0.0f;
671         static int angle_base_x=0, angle_base_y=0;
672
673         if( g_pGesture->num_pressed > 1 )
674                 goto cleanup_flick;
675         if( (start_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= start_point) )
676                 goto cleanup_flick;
677
678         switch( type )
679         {
680                 case ET_ButtonPress:
681                         g_pGesture->fingers[idx].flags = PressFlagFlick;
682                         base_time = GetTimeInMillis();
683                         num_pressed = g_pGesture->num_pressed;
684                         switch(start_point)
685                         {
686                                 case FLICK_POINT_UP:
687                                         if( g_pGesture->fingers[idx].py > g_pGesture->flick_press_area)
688                                         {
689 #ifdef __DETAIL_DEBUG__
690                                                 ErrorF("[FlickDown] press coord is out of bound. (%d, %d)\n", g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
691 #endif//__DETAIL_DEBUG__
692                                                 goto cleanup_flick;
693                                         }
694
695                                         angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
696                                         angle_base_x = g_pGesture->fingers[idx].px;
697                                         break;
698
699                                 case FLICK_POINT_DOWN:
700                                         if( g_pGesture->fingers[idx].py < g_pGesture->screen_height - g_pGesture->flick_press_area)
701                                         {
702 #ifdef __DETAIL_DEBUG__
703                                                 ErrorF("[FlickUp] press coord is out of bound. (%d, %d)\n", g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
704 #endif//__DETAIL_DEBUG__
705                                                 goto cleanup_flick;
706                                         }
707                                         angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
708                                         angle_base_x = g_pGesture->fingers[idx].px;
709                                         break;
710
711                                 case FLICK_POINT_LEFT:
712                                         if( g_pGesture->fingers[idx].px > g_pGesture->flick_press_area)
713                                         {
714 #ifdef __DETAIL_DEBUG__
715                                                 ErrorF("[FlickLeft] press coord is out of bound. (%d, %d)\n", g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
716 #endif//__DETAIL_DEBUG__
717                                                 goto cleanup_flick;
718                                         }
719                                         angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
720                                         angle_base_x = g_pGesture->fingers[idx].px;
721                                         break;
722
723                                 default:
724                                         goto cleanup_flick;
725                                         break;
726                         }
727
728                         break;
729
730                 case ET_Motion:
731                         if( !(g_pGesture->fingers[idx].flags & PressFlagFlick ) )
732                                 break;
733
734                         switch(start_point)
735                         {
736                                 case FLICK_POINT_UP:
737                                         diff_base_coord = diff_current_coord;
738                                         diff_current_coord = g_pGesture->fingers[idx].my;
739
740                                         if( (diff_current_coord - diff_base_coord) < 0 )
741                                                 false_diff_count++;
742                                         if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
743                                         {
744 #ifdef __DETAIL_DEBUG__
745                                                 ErrorF("[FlickDown][M][F] false_diff_count: %d > %d\n", false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
746 #endif//__DETAIL_DEBUG__
747                                                 goto cleanup_flick;
748                                         }
749
750                                         if ((g_pGesture->fingers[idx].my < g_pGesture->flick_press_area) &&
751                                                 (abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) >(int)( g_pGesture->screen_width/2)) )
752                                         {
753 #ifdef __DETAIL_DEBUG__
754                                                 ErrorF("[FlickDown][M][F] move x: %d - %d, y coord: %d\n", g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].my);
755 #endif//__DETAIL_DEBUG__
756                                                 goto cleanup_flick;
757                                         }
758
759                                         if( (g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) > g_pGesture->flick_minimum_height)
760                                         {
761 #ifdef __DETAIL_DEBUG__
762                                                 ErrorF("[FlickDown][M] %d - %d < %d(min_size), angle_base_coord (%d, %d)\n", g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py, g_pGesture->flick_minimum_height, angle_base_x, angle_base_y);
763 #endif//__DETAIL_DEBUG__
764                                                 if(abs(g_pGesture->fingers[idx].mx - angle_base_x) == 0)
765                                                 {
766 #ifdef __DETAIL_DEBUG__
767                                                         ErrorF("[FlickDown][M] abs(%d - %d) = 0\n", g_pGesture->fingers[idx].mx, angle_base_x);
768 #endif//__DETAIL_DEBUG__
769                                                         angle = 1.0f;
770                                                 }
771                                                 else
772                                                 {
773 #ifdef __DETAIL_DEBUG__
774                                                         ErrorF("[FlickDown][M] angle_base_x: %d, angle_base_y: %d\n", angle_base_x, angle_base_y);
775 #endif//__DETAIL_DEBUG__
776
777                                                         int y_diff = abs(g_pGesture->fingers[idx].my - angle_base_y);
778                                                         int x_diff = abs(g_pGesture->fingers[idx].mx - angle_base_x);
779                                                         angle = (float)y_diff / (float)x_diff;
780                                                 }
781
782                                                 if ( angle < 0.27f)
783                                                 {
784 #ifdef __DETAIL_DEBUG__
785                                                         ErrorF("[FlickDown][M][F] %d / %d = %f (angle)\n", abs(g_pGesture->fingers[idx].my - angle_base_y), abs(g_pGesture->fingers[idx].mx - angle_base_x), angle);
786 #endif//__DETAIL_DEBUG__
787                                                         goto cleanup_flick;
788                                                 }
789
790                                                 distance = g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py;
791                                                 duration = GetTimeInMillis() - base_time;
792
793                                                 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
794                                                 goto cleanup_flick_recognized;
795                                         }
796                                         else
797                                         {
798                                                 if( (g_pGesture->fingers[idx].mx - diff_base_minor_coord) < 0 )
799                                                         false_minor_diff_count++;
800                                                 if (false_minor_diff_count> FLICK_FALSE_X_DIFF_COUNT)
801                                                 {
802 #ifdef __DETAIL_DEBUG__
803                                                         ErrorF("[FlickDown][M][F] false_minor_diff_count: %d > %d\n", false_minor_diff_count, FLICK_FALSE_X_DIFF_COUNT);
804 #endif//__DETAIL_DEBUG__
805                                                         goto cleanup_flick;
806                                                 }
807                                         }
808
809                                         if (g_pGesture->fingers[idx].my < g_pGesture->flick_press_area)
810                                         {
811                                                 angle_base_x = g_pGesture->fingers[idx].px;
812                                                 angle_base_y = g_pGesture->fingers[idx].py;
813                                         }
814
815                                         break;
816                                 case FLICK_POINT_DOWN:
817                                         diff_base_coord = diff_current_coord;
818                                         diff_current_coord = g_pGesture->fingers[idx].my;
819
820                                         if( (diff_base_coord - diff_current_coord) < 0 )
821                                                 false_diff_count++;
822                                         if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
823                                         {
824 #ifdef __DETAIL_DEBUG__
825                                                 ErrorF("[FlickUp][M] false_diff_count: %d > %d\n", false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
826 #endif//__DETAIL_DEBUG__
827                                                 goto cleanup_flick;
828                                         }
829
830                                         if( (g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my) > g_pGesture->flick_minimum_height)
831                                         {
832 #ifdef __DETAIL_DEBUG__
833                                                 ErrorF("[FlickUp][R] %d - %d < %d(min_size)\n", g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py, g_pGesture->flick_minimum_height);
834 #endif//__DETAIL_DEBUG__
835                                                 if(abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) == 0)
836                                                 {
837 #ifdef __DETAIL_DEBUG__
838                                                         ErrorF("[FlickUp][R] abs(%d - %d) = 0\n", g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px);
839 #endif//__DETAIL_DEBUG__
840                                                         angle = 1.0f;
841                                                 }
842                                                 else
843                                                 {
844                                                         int y_diff = abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py);
845                                                         int x_diff = abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px);
846                                                         angle = (float)y_diff / (float)x_diff;
847                                                 }
848
849                                                 if ( angle <0.5f)
850                                                 {
851 #ifdef __DETAIL_DEBUG__
852                                                         ErrorF("[FlickUp][R] %d / %d = %f (angle)\n", abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py), abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), angle);
853 #endif//__DETAIL_DEBUG__
854                                                         goto cleanup_flick;
855                                                 }
856
857                                                 distance = g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my;
858                                                 duration = GetTimeInMillis() - base_time;
859
860                                                 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
861                                                 goto cleanup_flick_recognized;
862                                         }
863                                         break;
864                                 case FLICK_POINT_LEFT:
865                                         diff_base_coord = diff_current_coord;
866                                         diff_current_coord = g_pGesture->fingers[idx].mx;
867
868                                         if( (diff_current_coord - diff_base_coord) < 0 )
869                                                 false_diff_count++;
870                                         if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
871                                         {
872 #ifdef __DETAIL_DEBUG__
873                                                 ErrorF("[FlickLeft][M] false_diff_count: %d > %d\n", false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
874 #endif//__DETAIL_DEBUG__
875                                                 goto cleanup_flick;
876                                         }
877
878                                         if( (g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) > g_pGesture->flick_minimum_height)
879                                         {
880 #ifdef __DETAIL_DEBUG__
881                                                 ErrorF("[FlickLeft][M] %d - %d < %d(min_size)\n", g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px, g_pGesture->flick_minimum_height);
882 #endif//__DETAIL_DEBUG__
883                                                 if(abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) == 0)
884                                                 {
885 #ifdef __DETAIL_DEBUG__
886                                                         ErrorF("[FlickLeft][M] abs(%d - %d) = 0\n", g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py);
887 #endif//__DETAIL_DEBUG__
888                                                         angle = 1.0f;
889                                                 }
890                                                 else
891                                                 {
892                                                         int y_diff = abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py);
893                                                         int x_diff = abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px);
894                                                         angle = (float)x_diff / (float)y_diff;
895                                                 }
896
897                                                 if ( angle < 0.5f)
898                                                 {
899 #ifdef __DETAIL_DEBUG__
900                                                         ErrorF("[FlickLeft][M] %d / %d = %f (angle)\n", abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py), angle);
901 #endif//__DETAIL_DEBUG__
902                                                         goto cleanup_flick;
903                                                 }
904
905                                                 distance = g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px;
906                                                 duration = GetTimeInMillis() - base_time;
907
908                                                 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
909                                                 goto cleanup_flick_recognized;
910                                         }
911
912                                         break;
913                                 default:
914                                         goto cleanup_flick;
915                                         break;
916                         }
917                         break;
918
919                 case ET_ButtonRelease:
920                         goto cleanup_flick;
921                         break;
922         }
923
924         return;
925
926 cleanup_flick:
927         ErrorF("[Flick][R] clenup_flick\n");
928         g_pGesture->recognized_gesture &= ~WFlickFilterMask;
929
930 cleanup_flick_recognized:
931         ErrorF("[Flick][R] cleanup_flick_recognized\n");
932         g_pGesture->filter_mask |= WFlickFilterMask;
933         num_pressed = 0;
934         base_time = 0;
935         false_diff_count = 0;
936         diff_base_coord = 0;
937         diff_current_coord = 0;
938         angle = 0.0f;
939         angle_base_x = angle_base_y = 0;
940         return;
941 }
942
943 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
944 {
945         static int num_pressed = 0;
946         static int base_area_size = 0;
947         static Time base_time = 0;
948         static int base_cx;
949         static int base_cy;
950         int cx, cy;
951         static pixman_box16_t base_box_ext;
952         int area_size;
953         static int state = GestureEnd;
954
955         static OsTimerPtr hold_event_timer = NULL;
956         static int event_type = GestureNotifyHold;
957
958         if( timer_expired )
959         {
960                 if( state <= GestureBegin )
961                         state++;
962
963 #ifdef __DETAIL_DEBUG__
964                 switch( state )
965                 {
966                         case GestureBegin:
967                                 ErrorF("[GroupHold] HOLD Begin !\n");
968                                 break;
969
970                         case GestureUpdate:
971                                 ErrorF("[GroupHold] HOLD Update !\n");
972                                 break;
973                 }
974 #endif//__DETAIL_DEBUG__
975
976                 if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) )
977                 {
978                         GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
979                         hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type);
980                 }
981                 return;
982         }
983
984         switch( type )
985         {
986                 case ET_ButtonPress:
987                         g_pGesture->fingers[idx].flags |= PressFlagHold;
988
989                         if( g_pGesture->num_pressed < 2 )
990                                 return;
991
992                         if( !base_area_size || g_pGesture->num_pressed > num_pressed )
993                         {
994                                 if( state != GestureEnd )
995                                 {
996 #ifdef __DETAIL_DEBUG__
997                                         ErrorF("[GroupHold][P][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
998 #endif//__DETAIL_DEBUG__
999                                         goto cleanup_hold;
1000                                 }
1001
1002                                 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1003                                 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1004                                 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1005                                 base_time = GetTimeInMillis();
1006                                 base_box_ext.x1 = base_cx-g_pGesture->hold_move_threshold;
1007                                 base_box_ext.y1 = base_cy-g_pGesture->hold_move_threshold;
1008                                 base_box_ext.x2 = base_cx+g_pGesture->hold_move_threshold;
1009                                 base_box_ext.y2 = base_cy+g_pGesture->hold_move_threshold;
1010                                 event_type = GestureNotifyHold;
1011                                 hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type);
1012                         }
1013                         num_pressed = g_pGesture->num_pressed;
1014
1015 #ifdef __DETAIL_DEBUG__
1016                         ErrorF("[GroupHold][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);
1017 #endif//__DETAIL_DEBUG__
1018                         break;
1019
1020                 case ET_Motion:
1021                         if( !(g_pGesture->fingers[idx].flags & PressFlagHold ) )
1022                                 break;
1023
1024                         if( num_pressed < 2 )
1025                                 return;
1026
1027                         if( num_pressed != g_pGesture->num_pressed )
1028                         {
1029                                 if( state != GestureEnd )
1030                                 {
1031 #ifdef __DETAIL_DEBUG__
1032                                 ErrorF("[GroupHold][M][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1033 #endif//__DETAIL_DEBUG__
1034                                         goto cleanup_hold;
1035                                 }
1036 #ifdef __DETAIL_DEBUG__
1037                                 ErrorF("[GroupHold][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1038 #endif//__DETAIL_DEBUG__
1039                                 //goto cleanup_hold;
1040                         }
1041
1042                         area_size = AREA_SIZE(&g_pGesture->area.extents);
1043                         cx = AREA_CENTER_X(&g_pGesture->area.extents);
1044                         cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1045 #ifdef __DETAIL_DEBUG__
1046                         ErrorF("[GroupHold][M][num_pressed=%d] area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size));
1047                         ErrorF("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1048                         ErrorF("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1049 #endif//__DETAIL_DEBUG__
1050
1051                         if(area_size > 0 && base_area_size > 0)
1052                         {
1053                                 if( ((area_size > base_area_size) ? (double)area_size / (double)base_area_size : (double)base_area_size / (double) area_size) >= g_pGesture->hold_area_threshold)
1054                                 {
1055 #ifdef __DETAIL_DEBUG__
1056                                         ErrorF("[GroupHold][M] No diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%lf)!\n", area_size, base_area_size, ((area_size > base_area_size) ? (double)area_size / (double)base_area_size : (double)base_area_size / (double) area_size));
1057 #endif//__DETAIL_DEBUG__
1058                                         goto cleanup_hold;
1059                                 }
1060                         }
1061
1062                         if( !INBOX(&base_box_ext, cx, cy) )
1063                         {
1064 #ifdef __DETAIL_DEBUG__
1065                                 ErrorF("[GroupHold][M] No current center coordinates is not in base coordinates box !\n");
1066                                 ErrorF("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1067                                 ErrorF("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1068 #endif//__DETAIL_DEBUG__
1069                                 goto cleanup_hold;
1070                         }
1071                         break;
1072
1073                 case ET_ButtonRelease:
1074                         if( state != GestureEnd && num_pressed >= 2)
1075                         {
1076 #ifdef __DETAIL_DEBUG__
1077                                 ErrorF("[GroupHold][R][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1078 #endif//__DETAIL_DEBUG__
1079                                 goto cleanup_hold;
1080                         }
1081
1082                         //ErrorF("[GroupHold][R] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1083                         if( g_pGesture->num_pressed )
1084                                 break;
1085
1086                         goto cleanup_hold;
1087                         break;
1088         }
1089
1090         return;
1091
1092 cleanup_hold:
1093
1094         if( state == GestureBegin || state == GestureUpdate )
1095         {
1096                 state = GestureEnd;
1097                 if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) )
1098                 {
1099                         GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1100                 }
1101         }
1102         else
1103         {
1104                 g_pGesture->recognized_gesture &= ~WHoldFilterMask;
1105         }
1106
1107         g_pGesture->filter_mask |= WHoldFilterMask;
1108         num_pressed = 0;
1109         base_area_size = 0;
1110         base_time = 0;
1111         base_cx = base_cy = 0;
1112         state = GestureEnd;
1113         base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
1114         TimerCancel(hold_event_timer);
1115         return;
1116 }
1117
1118 static inline void
1119 GestureEnableDisable()
1120 {
1121         GestureEnable(1, FALSE, g_pGesture->this_device);
1122 #if 0
1123         if((g_pGesture->grabMask) || (g_pGesture->lastSelectedWin != None))
1124         {
1125                 GestureEnable(1, FALSE, g_pGesture->this_device);
1126         }
1127         else
1128         {
1129                 GestureEnable(0, FALSE, g_pGesture->this_device);
1130         }
1131 #endif
1132 }
1133
1134 void
1135 GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent)
1136 {
1137         g_pGesture->grabMask = *pGrabMask;
1138         g_pGesture->GrabEvents = (GestureGrabEventPtr)pGrabEvent;
1139         GestureEnableDisable();
1140 }
1141
1142 void
1143 GestureCbEventsSelected(Window win, Mask *pEventMask)
1144 {
1145         g_pGesture->lastSelectedWin = win;
1146         g_pGesture->lastSelectedMask = (pEventMask) ? *pEventMask : 0;
1147         GestureEnableDisable();
1148 }
1149
1150 WindowPtr
1151 GestureGetEventsWindow(void)
1152 {
1153         Mask mask;
1154         WindowPtr pWin;
1155
1156         pWin = GestureWindowOnXY(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py);
1157
1158         if( pWin )
1159         {
1160 #ifdef __DETAIL_DEBUG__
1161                 ErrorF("[X11][GestureGetEventsWindow] pWin->drawable.id=0x%x\n", pWin->drawable.id);
1162 #endif//__DETAIL_DEBUG__
1163                 g_pGesture->gestureWin = pWin->drawable.id;
1164         }
1165         else
1166         {
1167 #ifdef __DETAIL_DEBUG__
1168                 ErrorF("[X11][GestureGetEventsWindow] GestureWindowOnXY returns NULL !\n");
1169 #endif//__DETAIL_DEBUG__
1170                 return NULL;
1171         }
1172
1173         if(g_pGesture->gestureWin == g_pGesture->lastSelectedWin)
1174         {
1175                 g_pGesture->eventMask = g_pGesture->lastSelectedMask;
1176                 goto nonempty_eventmask;
1177         }
1178
1179         //check selected event(s)
1180         if( !GestureHasSelectedEvents(pWin, &g_pGesture->eventMask) )
1181         {
1182                 g_pGesture->eventMask = 0;
1183         }
1184         else
1185         {
1186                 g_pGesture->lastSelectedWin = g_pGesture->gestureWin;
1187                 g_pGesture->lastSelectedMask = g_pGesture->eventMask;
1188         }
1189
1190         if( !g_pGesture->eventMask && !g_pGesture->grabMask)
1191         {
1192 #ifdef __DETAIL_DEBUG__
1193                 ErrorF("[X11][GestureGetEventsWindow] No grabbed events or no events were selected for window(0x%x) !\n", pWin->drawable.id);
1194 #endif//__DETAIL_DEBUG__
1195                 return NULL;
1196         }
1197
1198 nonempty_eventmask:
1199
1200 #ifdef __DETAIL_DEBUG__
1201         ErrorF("[X11][GestureGetEventsWindow] g_pGesture->eventMask=0x%x\n", g_pGesture->eventMask);
1202 #endif//__DETAIL_DEBUG__
1203
1204         mask = (GESTURE_FILTER_MASK_ALL & ~(g_pGesture->grabMask | g_pGesture->eventMask));
1205
1206 #ifdef __DETAIL_DEBUG__
1207         ErrorF("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x, mask=0x%x\n", g_pGesture->filter_mask, mask);
1208 #endif//__DETAIL_DEBUG__
1209
1210         g_pGesture->filter_mask = mask;
1211
1212 #ifdef __DETAIL_DEBUG__
1213         ErrorF("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x\n", g_pGesture->filter_mask);
1214 #endif//__DETAIL_DEBUG__
1215
1216         return pWin;
1217 }
1218
1219 static CARD32
1220 GestureSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
1221 {
1222         g_pGesture->filter_mask |= WTapFilterMask;
1223         g_pGesture->filter_mask |= WHoldFilterMask;
1224
1225         if( (g_pGesture->event_sum[0] == BTN_PRESSED) && ( (g_pGesture->flick_pressed_point <= FLICK_POINT_NONE) && (FLICK_POINT_MAX <= g_pGesture->flick_pressed_point) ) )
1226         {
1227 #ifdef __DETAIL_DEBUG__
1228                 ErrorF("[SingleFingerTimer] press_point: %d\n", g_pGesture->flick_pressed_point);
1229 #endif//__DETAIL_DEBUG_
1230                 g_pGesture->filter_mask |= WFlickFilterMask;
1231         }
1232
1233 #ifdef __DETAIL_DEBUG__
1234         ErrorF("[X11][Single] expired !\n");
1235 #endif//__DETAIL_DEBUG__
1236
1237         if(g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
1238         {
1239                 if( ERROR_INVALPTR == GestureFlushOrDrop() )
1240                 {
1241                         GestureControl(g_pGesture->this_device, DEVICE_OFF);
1242                 }
1243         }
1244
1245         return 0;
1246 }
1247
1248 void
1249 GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
1250 {
1251         int i;
1252         static OsTimerPtr single_finger_timer = NULL;
1253         int idx = -1;
1254
1255         if( PROPAGATE_EVENTS == g_pGesture->ehtype ||
1256                 device->id < g_pGesture->first_fingerid )
1257                 return;
1258
1259         for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
1260         {
1261                 if( device->id == g_pGesture->mt_devices[i]->id )
1262                 {
1263                         idx = i;
1264                         break;
1265                 }
1266         }
1267
1268         if( idx < 0 )
1269                 return;
1270
1271         switch( type )
1272         {
1273                 case ET_ButtonPress:
1274                         if( idx == 0 )
1275                                 g_pGesture->event_sum[0] = BTN_PRESSED;
1276                         g_pGesture->fingers[idx].ptime = ev->any.time;
1277                         g_pGesture->fingers[idx].px = ev->device_event.root_x;
1278                         g_pGesture->fingers[idx].py = ev->device_event.root_y;
1279
1280                         g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
1281                         g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
1282                         g_pGesture->finger_rects[idx].extents.y1 =  ev->device_event.root_y - FINGER_HEIGHT;
1283                         g_pGesture->finger_rects[idx].extents.y2 =  ev->device_event.root_y + FINGER_HEIGHT;
1284
1285                         g_pGesture->num_pressed++;
1286                         g_pGesture->inc_num_pressed = g_pGesture->num_pressed;
1287
1288                         if( g_pGesture->inc_num_pressed == 1 )
1289                         {
1290                                 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
1291 #ifdef __DETAIL_DEBUG__
1292                                 ErrorF("[P][g_pGesture->inc_num_pressed=1] AREA_SIZE(area.extents)=%d\n", AREA_SIZE(&g_pGesture->area.extents));
1293 #endif//__DETAIL_DEBUG__
1294                         }
1295                         else
1296                         {
1297                                 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
1298                                 for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ )
1299                                 {
1300                                         pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
1301                                 }
1302 #ifdef __DETAIL_DEBUG__
1303                                 ErrorF("[P][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area.extents)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents));
1304 #endif//__DETAIL_DEBUG__
1305                         }
1306 #ifdef __DETAIL_DEBUG__
1307                         ErrorF("[X11][GestureRecognize][P] g_pGesture->finger_rects\n");
1308 #endif//__DETAIL_DEBUG__
1309                         if(g_pGesture->num_pressed == 1)
1310                         {
1311                                 single_finger_timer = TimerSet(single_finger_timer, 0, 50, GestureSingleFingerTimerHandler, NULL);
1312
1313                                 if( g_pGesture->fingers[idx].py <= g_pGesture->flick_press_area)
1314                                 {
1315                                         if((!g_pGesture->activate_flick_down)
1316                                                 || (g_pGesture->fingers[idx].px <= (g_pGesture->flick_press_area_left_right))
1317                                                 || (g_pGesture->fingers[idx].px >= (g_pGesture->screen_width - g_pGesture->flick_press_area_left_right)) )
1318                                                 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
1319                                         else
1320                                                 g_pGesture->flick_pressed_point = FLICK_POINT_UP;
1321                                 }
1322                                 else if(g_pGesture->fingers[idx].py >= (g_pGesture->screen_height - g_pGesture->flick_press_area))
1323                                 {
1324                                         if(!g_pGesture->activate_flick_up)
1325                                                 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
1326                                         else
1327                                                 g_pGesture->flick_pressed_point = FLICK_POINT_DOWN;
1328                                 }
1329                                 else if( g_pGesture->fingers[idx].px <= g_pGesture->flick_press_area_left)
1330                                 {
1331                                         if(!g_pGesture->activate_flick_right)
1332                                                 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
1333                                         else
1334                                                 g_pGesture->flick_pressed_point = FLICK_POINT_LEFT;
1335                                 }
1336 #ifdef __DETAIL_DEBUG__
1337                                 ErrorF("[GestureRecognize] flick_press_point: %d\n", g_pGesture->flick_pressed_point);
1338 #endif//__DETAIL_DEBUG__
1339
1340                                 if( (g_pGesture->flick_pressed_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= g_pGesture->flick_pressed_point) )
1341                                 {
1342                                         g_pGesture->filter_mask |= WFlickFilterMask;
1343                                         g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
1344                                 }
1345                                 else
1346                                 {
1347                                         g_pGesture->flick_direction = ( g_pGesture->flick_pressed_point - 1 ) * 2;
1348                                         if( (g_pGesture->flick_direction == FLICK_WESTWARD) && (g_pGesture->power_pressed != 2) )
1349                                         {
1350                                                 ErrorF("[GestureRecognize] Flick WesWard is disable when power is not pressed\n");
1351                                                 g_pGesture->filter_mask |= WFlickFilterMask;
1352                                                 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
1353                                         }
1354                                         if( (g_pGesture->flick_direction < FLICK_NORTHWARD) || (FLICK_NORTHWESTWARD < g_pGesture->flick_direction) )
1355                                         {
1356                                                 ErrorF("[GestureRecognize] Invalid flick direction\n");
1357                                                 g_pGesture->filter_mask |= WFlickFilterMask;
1358                                                 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
1359                                         }
1360 #ifdef __DETAIL_DEBUG__
1361                                         ErrorF("[GestureRecognize] flick_direction: %d\n", g_pGesture->flick_direction);
1362 #endif//__DETAIL_DEBUG__
1363                                 }
1364                         }
1365                         else
1366                         {
1367                                 TimerCancel(single_finger_timer);
1368                                 single_finger_timer = NULL;
1369                         }
1370                         break;
1371
1372                 case ET_Motion:
1373                         if( !g_pGesture->fingers[idx].ptime )
1374                                 return;
1375
1376                         g_pGesture->fingers[idx].mx = ev->device_event.root_x;
1377                         g_pGesture->fingers[idx].my = ev->device_event.root_y;
1378
1379                         if( (g_pGesture->inc_num_pressed < 2) && (idx == 0) && (g_pGesture->event_sum[0] == BTN_PRESSED) )
1380                         {
1381                                 g_pGesture->event_sum[0] += BTN_MOVING;
1382 #ifdef __DETAIL_DEBUG__
1383                                 ErrorF("no seconds finger comming\n");
1384 #endif//__DETAIL_DEBUG__
1385                                 if(g_pGesture->event_sum[0] >= 7)
1386                                 {
1387 #ifdef __DETAIL_DEBUG__
1388                                         ErrorF("Moving Limit\n");
1389 #endif//__DETAIL_DEBUG__
1390                                         g_pGesture->filter_mask |= WTapFilterMask;
1391                                         g_pGesture->filter_mask |= WHoldFilterMask;
1392                                 }
1393                                 if(g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
1394                                         goto flush_or_drop;
1395                         }
1396
1397                         g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
1398                         g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
1399                         g_pGesture->finger_rects[idx].extents.y1 =  ev->device_event.root_y - FINGER_HEIGHT;
1400                         g_pGesture->finger_rects[idx].extents.y2 =  ev->device_event.root_y + FINGER_HEIGHT;
1401
1402                         if( g_pGesture->inc_num_pressed == 1 )
1403                         {
1404                                 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
1405 #ifdef __DETAIL_DEBUG__
1406                                 ErrorF("[M][g_pGesture->inc_num_pressed=1] AREA_SIZE(area)=%d\n", AREA_SIZE(&g_pGesture->area.extents));
1407 #endif//__DETAIL_DEBUG__
1408                         }
1409                         else
1410                         {
1411                                 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
1412                                 for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ )
1413                                 {
1414                                         pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
1415                                 }
1416 #ifdef __DETAIL_DEBUG__
1417                                 ErrorF("[M][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents));
1418 #endif//__DETAIL_DEBUG__
1419                         }
1420                         break;
1421
1422                 case ET_ButtonRelease:
1423                         g_pGesture->fingers[idx].rtime = ev->any.time;
1424                         g_pGesture->fingers[idx].rx = ev->device_event.root_x;
1425                         g_pGesture->fingers[idx].ry = ev->device_event.root_y;
1426
1427                         g_pGesture->num_pressed--;
1428                         if( g_pGesture->num_pressed <= 0 )
1429                         {
1430 #ifdef __DETAIL_DEBUG__
1431         ErrorF("[X11][GestureRecognize] All fingers were released !\n");
1432 #endif//__DETAIL_DEBUG__
1433                         }
1434                         break;
1435         }
1436         if( g_pGesture->filter_mask != GESTURE_WATCH_FILTER_MASK_ALL )
1437         {
1438                 if( !(g_pGesture->filter_mask & WFlickFilterMask) )
1439                 {
1440                         GestureRecognize_GroupFlick(type, ev, device, idx, g_pGesture->flick_pressed_point, g_pGesture->flick_direction);
1441                 }
1442                 if( !(g_pGesture->filter_mask & WTapFilterMask) )
1443                 {
1444                         GestureRecognize_GroupTap(type, ev, device, idx, 0);
1445                 }
1446                 if( !(g_pGesture->filter_mask & WHoldFilterMask) )
1447                 {
1448                         GestureRecognize_GroupHold(type, ev, device, idx, 0);
1449                 }
1450         }
1451
1452 #ifdef __DETAIL_DEBUG__
1453         ErrorF("[X11][GestureRecognize][N] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask);
1454         ErrorF("[X11][GestureRecognize][N] g_pGesture->GESTURE_WATCH_FILTER_MASK_ALL = 0x%x\n", GESTURE_WATCH_FILTER_MASK_ALL);
1455         ErrorF("[X11][GestureRecognize][N] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture);
1456 #endif//__DETAIL_DEBUG__
1457
1458         if( g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL )
1459         {
1460                 if( !g_pGesture->recognized_gesture )
1461                         goto flush_or_drop;
1462                 else if( !g_pGesture->num_pressed )
1463                         goto flush_or_drop;
1464         }
1465
1466         if( g_pGesture->recognized_gesture )
1467         {
1468                 if( g_pGesture->ehtype == KEEP_EVENTS )
1469                         GestureEventsDrop();
1470                 g_pGesture->ehtype = IGNORE_EVENTS;
1471         }
1472         return;
1473
1474 flush_or_drop:
1475 #ifdef __DETAIL_DEBUG__
1476         ErrorF("[GestureRecognize] GestureFlushOrDrop() !\n");
1477 #endif//__DETAIL_DEBUG__
1478         if( ERROR_INVALPTR == GestureFlushOrDrop() )
1479         {
1480                 GestureControl(g_pGesture->this_device, DEVICE_OFF);
1481         }
1482 }
1483
1484
1485 ErrorStatus GestureFlushOrDrop(void)
1486 {
1487         ErrorStatus err;
1488
1489         if( g_pGesture->recognized_gesture )
1490         {
1491                 g_pGesture->ehtype = IGNORE_EVENTS;
1492                 GestureEventsDrop();
1493         }
1494         else
1495         {
1496                 g_pGesture->ehtype = PROPAGATE_EVENTS;
1497
1498                 err = GestureEventsFlush();
1499                 if( ERROR_NONE != err )
1500                         return err;
1501
1502 #ifdef __DETAIL_DEBUG__
1503                 ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask);
1504                 ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->GESTURE_WATCH_FILTER_MASK_ALL = 0x%x\n", GESTURE_WATCH_FILTER_MASK_ALL);
1505                 ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture);
1506 #endif//__DETAIL_DEBUG__
1507         }
1508
1509         err = GestureRegionsReinit();
1510         if( ERROR_NONE != err )
1511                 return err;
1512
1513         g_pGesture->pTempWin = NULL;
1514         g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0;
1515         g_pGesture->event_sum[0] = 0;
1516
1517         return ERROR_NONE;
1518 }
1519
1520 void
1521 GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
1522 {
1523         int i;
1524
1525 #ifdef __DEBUG_EVENT_HANDLER__
1526         ErrorF("\n[X11][GestureHandleMTSyncEvent] (%d:%d) time:%d cur:%d\n",
1527                         ev->any_event.deviceid, ev->any_event.sync, (int)ev->any.time, (int)GetTimeInMillis());
1528 #endif//__DEBUG_EVENT_HANDLER__
1529
1530         if(!g_pGesture->is_active)
1531         {
1532                 g_pGesture->ehtype = PROPAGATE_EVENTS;
1533                 return;
1534         }
1535
1536         if( MTOUCH_FRAME_SYNC_BEGIN == ev->any_event.sync )
1537         {
1538                 g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_BEGIN;
1539                 g_pGesture->ehtype = KEEP_EVENTS;
1540                 g_pGesture->filter_mask = 0;
1541                 g_pGesture->recognized_gesture = 0;
1542                 g_pGesture->num_pressed = 0;
1543
1544                 for( i=0 ; i < g_pGesture->num_mt_devices ; i++ )
1545                         g_pGesture->fingers[i].ptime = 0;
1546         }
1547         else if( MTOUCH_FRAME_SYNC_END == ev->any_event.sync )
1548         {
1549                 g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_END;
1550                 g_pGesture->ehtype = PROPAGATE_EVENTS;
1551                 g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
1552         }
1553 }
1554
1555 void GestureEmulateHWKey(DeviceIntPtr dev, int keycode)
1556 {
1557         if(dev)
1558         {
1559                 xf86PostKeyboardEvent(dev, keycode, 1);
1560                 xf86PostKeyboardEvent(dev, keycode, 0);
1561         }
1562 }
1563
1564 void
1565 GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
1566 {
1567 #ifdef __DEBUG_EVENT_HANDLER__
1568         ErrorF("[X11][GestureHandleButtonPEvent] devid=%d time:%d cur:%d (%d, %d)\n", device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y);
1569 #endif//__DEBUG_EVENT_HANDLER__
1570         switch( g_pGesture->ehtype )
1571         {
1572                 case KEEP_EVENTS:
1573                         if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device) )
1574                         {
1575                                 GestureControl(g_pGesture->this_device, DEVICE_OFF);
1576                                 return;
1577                         }
1578
1579                         if( g_pGesture->num_mt_devices )
1580                                 GestureRecognize(ET_ButtonPress, ev, device);
1581                         else
1582                                 device->public.processInputProc(ev, device);
1583                         break;
1584
1585                 case PROPAGATE_EVENTS:
1586                         device->public.processInputProc(ev, device);
1587                         break;
1588
1589                 case IGNORE_EVENTS:
1590                         GestureRecognize(ET_ButtonPress, ev, device);
1591                         break;
1592
1593                 default:
1594                         break;
1595         }
1596 }
1597
1598 void
1599 GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
1600 {
1601 #ifdef __DEBUG_EVENT_HANDLER__
1602         ErrorF("[X11][GestureHandleMotionEvent] devid=%d time:%d cur:%d (%d, %d)\n", device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y);
1603 #endif//__DEBUG_EVENT_HANDLER__
1604         switch( g_pGesture->ehtype )
1605         {
1606                 case KEEP_EVENTS:
1607                         if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device) )
1608                         {
1609                                 GestureControl(g_pGesture->this_device, DEVICE_OFF);
1610                                 return;
1611                         }
1612
1613                         if( g_pGesture->num_mt_devices )
1614                                 GestureRecognize(ET_Motion, ev, device);
1615                         else
1616                                 device->public.processInputProc(ev, device);
1617                         break;
1618
1619                 case PROPAGATE_EVENTS:
1620                         device->public.processInputProc(ev, device);
1621                         break;
1622
1623                 case IGNORE_EVENTS:
1624                         GestureRecognize(ET_Motion, ev, device);
1625                         break;
1626
1627                 default:
1628                         break;
1629         }
1630
1631 }
1632
1633 void
1634 GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
1635 {
1636 #ifdef __DEBUG_EVENT_HANDLER__
1637         ErrorF("[X11][GestureHandleButtonREvent] devid=%d time:%d cur:%d (%d, %d)\n", device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y);
1638 #endif//__DEBUG_EVENT_HANDLER__
1639         switch( g_pGesture->ehtype )
1640         {
1641                 case KEEP_EVENTS:
1642                         if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device) )
1643                         {
1644                                 GestureControl(g_pGesture->this_device, DEVICE_OFF);
1645                                 return;
1646                         }
1647
1648                         if( g_pGesture->num_mt_devices )
1649                                 GestureRecognize(ET_ButtonRelease, ev, device);
1650                         else
1651                                 device->public.processInputProc(ev, device);
1652                         break;
1653
1654                 case PROPAGATE_EVENTS:
1655                         device->public.processInputProc(ev, device);
1656 #if 0
1657                         GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down);
1658                         GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up);
1659 #endif
1660                         break;
1661
1662                 case IGNORE_EVENTS:
1663                         GestureRecognize(ET_ButtonRelease, ev, device);
1664                         break;
1665
1666                 default:
1667                         break;
1668         }
1669  }
1670
1671 void
1672 GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
1673 {
1674         if( (ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0) )
1675         {
1676                 g_pGesture->power_pressed = 2;
1677 #ifdef __DETAIL_DEBUG__
1678                 ErrorF("[GestureHandleKeyPressEvent] power key pressed devid: %d, hwkey_id: %d\n", device->id, g_pGesture->hwkey_id);
1679                 ErrorF("[GestureHandleKeyPressEvent] power_pressed: %d\n", g_pGesture->power_pressed);
1680 #endif//__DETAIL_DEBUG__
1681                 g_pGesture->power_device = device;
1682         }
1683         device->public.processInputProc(ev, device);
1684 }
1685
1686 void
1687 GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
1688 {
1689         if( (ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0) )
1690         {
1691                 g_pGesture->power_pressed = 1;
1692 #ifdef __DETAIL_DEBUG__
1693                 ErrorF("[GestureHandleKeyReleaseEvent] power key released devid: %d, hwkey_id: %d\n", device->id, g_pGesture->hwkey_id);
1694                 ErrorF("[GestureHandleKeyReleaseEvent] power_pressed: %d\n", g_pGesture->power_pressed);
1695 #endif//__DETAIL_DEBUG__
1696                 g_pGesture->power_device = device;
1697         }
1698         device->public.processInputProc(ev, device);
1699 }
1700
1701 static ErrorStatus
1702 GestureEnableEventHandler(InputInfoPtr pInfo)
1703  {
1704         Bool res;
1705         GestureDevicePtr pGesture = pInfo->private;
1706
1707         res = GestureInstallResourceStateHooks();
1708
1709         if( !res )
1710         {
1711                 ErrorF("[X11][GestureEnableEventHandler] Failed on GestureInstallResourceStateHooks() !\n");
1712                 return ERROR_ABNORMAL;
1713         }
1714
1715         res = GestureSetMaxNumberOfFingers((int)MAX_MT_DEVICES);
1716
1717         if( !res )
1718         {
1719                 ErrorF("[X11][GestureEnableEventHandler] Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)MAX_MT_DEVICES);
1720                 goto failed;
1721         }
1722
1723         res = GestureRegisterCallbacks(GestureCbEventsGrabbed, GestureCbEventsSelected);
1724
1725         if( !res )
1726         {
1727                 ErrorF("[X11][GestureEnableEventHandler] Failed to register callbacks for GestureEventsGrabbed(), GestureEventsSelected() !\n");
1728                 goto failed;
1729         }
1730
1731         pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 5000, GestureTimerHandler, pInfo);
1732
1733         if( !pGesture->device_setting_timer )
1734         {
1735                 ErrorF("[X11][GestureEnableEventHandler] Failed to set time for detecting devices !\n");
1736                 goto failed;
1737         }
1738
1739         return ERROR_NONE;
1740
1741 failed:
1742         GestureUninstallResourceStateHooks();
1743         GestureUnsetMaxNumberOfFingers();
1744
1745         return ERROR_ABNORMAL;
1746 }
1747
1748 static ErrorStatus
1749 GestureDisableEventHandler(void)
1750 {
1751         ErrorStatus err = ERROR_NONE;
1752
1753         mieqSetHandler(ET_ButtonPress, NULL);
1754         mieqSetHandler(ET_ButtonRelease, NULL);
1755         mieqSetHandler(ET_Motion, NULL);
1756         mieqSetHandler(ET_KeyPress, NULL);
1757         mieqSetHandler(ET_KeyRelease, NULL);
1758         mieqSetHandler(ET_MTSync, NULL);
1759
1760         err = GestureFiniEQ();
1761
1762         if( ERROR_INVALPTR == err )
1763         {
1764                 ErrorF("[X11][GestureDisableEventHandler] EQ is invalid or was freed already !\n");
1765         }
1766
1767         GestureRegisterCallbacks(NULL, NULL);
1768         GestureUninstallResourceStateHooks();
1769
1770         return err;
1771 }
1772
1773 static CARD32
1774 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
1775 {
1776         InputInfoPtr pInfo = (InputInfoPtr)arg;
1777         GestureDevicePtr pGesture;
1778         int idx;
1779         DeviceIntPtr dev;
1780
1781         if(!pInfo)
1782         {
1783                 ErrorF("[X11][%s] pInfo is NULL !\n", __FUNCTION__);
1784                 goto failed;
1785         }
1786
1787         pGesture = pInfo->private;
1788
1789         idx = 0;
1790         for( dev = inputInfo.pointer ; dev; dev = dev->next )
1791         {
1792                 if(IsMaster(dev) && IsPointerDevice(dev))
1793                 {
1794                         pGesture->master_pointer = dev;
1795                         ErrorF("[X11][GestureTimerHandler][id:%d] Master Pointer=%s\n", dev->id, pGesture->master_pointer->name);
1796                         continue;
1797                 }
1798
1799                 if(IsXTestDevice(dev, NULL) && IsPointerDevice(dev))
1800                 {
1801                         pGesture->xtest_pointer = dev;
1802                         ErrorF("[X11][GestureTimerHandler][id:%d] XTest Pointer=%s\n", dev->id, pGesture->xtest_pointer->name);
1803                         continue;
1804                 }
1805
1806                 if(IsPointerDevice(dev))
1807                 {
1808                         if( idx >= MAX_MT_DEVICES )
1809                         {
1810                                 ErrorF("[X11][GestureTimerHandler] Number of mt device is over MAX_MT_DEVICES(%d) !\n",
1811                                         MAX_MT_DEVICES);
1812                                 continue;
1813                         }
1814                         pGesture->mt_devices[idx] = dev;
1815                         ErrorF("[X11][GestureTimerHandler][id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name);
1816                         idx++;
1817                 }
1818         }
1819
1820         for( dev = inputInfo.keyboard ; dev; dev = dev->next )
1821         {
1822                 if(g_pGesture->hwkey_name && !strncmp(dev->name, g_pGesture->hwkey_name, strlen(dev->name)))
1823                 {
1824                         g_pGesture->hwkey_id = dev->id;
1825                         g_pGesture->hwkey_dev = dev;
1826
1827                         ErrorF("[X11][%s] hwkey_name has been found. hwkey_id=%d (hwkey_dev->name:%s)\n", __FUNCTION__, g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
1828                         break;
1829                 }
1830                 else if(!strcasestr(dev->name, "keyboard") && strcasestr(dev->name, "key") && !IsXTestDevice(dev, NULL) && !IsMaster(dev))
1831                 {
1832                         g_pGesture->hwkey_id = dev->id;
1833                         g_pGesture->hwkey_dev = dev;
1834
1835                         ErrorF("[X11][%s] hwkey has been found. hwkey_id=%d (hwkey_dev->name:%s)\n", __FUNCTION__, g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
1836                         break;
1837                 }
1838         }
1839
1840         if(!g_pGesture->hwkey_id)
1841         {
1842                 g_pGesture->hwkey_id = inputInfo.keyboard->id;
1843                 g_pGesture->hwkey_dev = inputInfo.keyboard;
1844
1845                 ErrorF("[X11][%s] No hwkey has been found. Back key will go through VCK. hwkey_id=%d (hwkey_dev->name:%s)\n",
1846                         __FUNCTION__, g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
1847         }
1848
1849         if( !pGesture->master_pointer || !pGesture->xtest_pointer )
1850         {
1851                 ErrorF("[X11][GestureTimerHandler] Failed to get info of master pointer or XTest pointer !\n");
1852                 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
1853                 pGesture->num_mt_devices = 0;
1854
1855                 return 0;
1856         }
1857
1858         TimerCancel(pGesture->device_setting_timer);
1859         pGesture->device_setting_timer = NULL;
1860         pGesture->num_mt_devices = idx;
1861
1862         if( !pGesture->num_mt_devices )
1863         {
1864                 ErrorF("[X11][GestureTimerHandler] Failed to mt device information !\n");
1865                 TimerCancel(pGesture->device_setting_timer);
1866                 pGesture->device_setting_timer = NULL;
1867                 pGesture->num_mt_devices = 0;
1868                 pGesture->first_fingerid = -1;
1869                 return 0;
1870         }
1871
1872         pGesture->first_fingerid = pGesture->mt_devices[0]->id;
1873         memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices);
1874         g_pGesture->pTempWin = NULL;
1875         g_pGesture->inc_num_pressed = 0;
1876
1877         if( ERROR_NONE != GestureRegionsInit() || ERROR_NONE != GestureInitEQ() )
1878         {
1879                 goto failed;
1880         }
1881
1882         mieqSetHandler(ET_ButtonPress, GestureHandleButtonPressEvent);
1883         mieqSetHandler(ET_ButtonRelease, GestureHandleButtonReleaseEvent);
1884         mieqSetHandler(ET_Motion, GestureHandleMotionEvent);
1885         mieqSetHandler(ET_KeyPress, GestureHandleKeyPressEvent);
1886         mieqSetHandler(ET_KeyRelease, GestureHandleKeyReleaseEvent);
1887
1888         //if( pGesture->is_active )
1889                 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
1890
1891         return 0;
1892
1893 failed:
1894
1895         GestureUninstallResourceStateHooks();
1896         GestureUnsetMaxNumberOfFingers();
1897
1898         return 0;
1899 }
1900
1901 BOOL
1902 IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
1903 {
1904         if (IsMaster(dev))
1905                 return FALSE;
1906
1907         if (master)
1908                 return (dev->xtest_master_id == master->id);
1909
1910         return (dev->xtest_master_id != 0);
1911 }
1912
1913 void
1914 GestureEnable(int enable, Bool prop, DeviceIntPtr dev)
1915 {
1916         if((!enable) && (g_pGesture->is_active))
1917         {
1918                 g_pGesture->ehtype = PROPAGATE_EVENTS;
1919                 mieqSetHandler(ET_MTSync, NULL);
1920                 g_pGesture->is_active = 0;
1921                 ErrorF("[X11][GestureEnable] Disabled !\n");
1922         }
1923         else if((enable) && (!g_pGesture->is_active))
1924         {
1925                 g_pGesture->ehtype = KEEP_EVENTS;
1926                 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
1927                 g_pGesture->is_active = 1;
1928                 ErrorF("[X11][GestureEnable] Enabled !\n");
1929         }
1930
1931         if(!prop)
1932                  XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
1933 }
1934
1935 ErrorStatus
1936 GestureRegionsInit(void)
1937 {
1938         int i;
1939
1940         if( !g_pGesture )
1941                 return ERROR_INVALPTR;
1942
1943         pixman_region_init(&g_pGesture->area);
1944
1945         for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
1946         {
1947                 pixman_region_init_rect (&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
1948         }
1949
1950         return ERROR_NONE;
1951 }
1952
1953 ErrorStatus
1954 GestureRegionsReinit(void)
1955 {
1956         if( !g_pGesture )
1957         {
1958                 ErrorF("[X11][GestureRegionsReinit] Invalid pointer access !\n");
1959                 return ERROR_INVALPTR;
1960         }
1961
1962         pixman_region_init(&g_pGesture->area);
1963
1964         return ERROR_NONE;
1965 }
1966
1967 ErrorStatus
1968 GestureInitEQ(void)
1969 {
1970         int i;
1971         IEventPtr tmpEQ;
1972
1973         tmpEQ = (IEventRec *)calloc(GESTURE_EQ_SIZE, sizeof(IEventRec));
1974
1975         if( !tmpEQ )
1976         {
1977                 ErrorF("[X11][GestureInitEQ] Failed to allocate memory for EQ !\n");
1978                 return ERROR_ALLOCFAIL;
1979         }
1980
1981         for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
1982         {
1983                 tmpEQ[i].event = (InternalEvent *)malloc(sizeof(InternalEvent));
1984                 if( !tmpEQ[i].event )
1985                 {
1986                         ErrorF("[X11][GestureInitEQ] Failed to allocation memory for each event buffer in EQ !\n");
1987                         i--;
1988                         while(i >= 0 && tmpEQ[i].event)
1989                         {
1990                                 free(tmpEQ[i].event);
1991                                 tmpEQ[i].event = NULL;
1992                         }
1993                         free (tmpEQ);
1994                         tmpEQ = NULL;
1995                         return ERROR_ALLOCFAIL;
1996                 }
1997         }
1998
1999         g_pGesture->EQ = tmpEQ;
2000         g_pGesture->headEQ = g_pGesture->tailEQ = 0;
2001
2002         return ERROR_NONE;
2003 }
2004
2005 ErrorStatus
2006 GestureFiniEQ(void)
2007 {
2008         int i;
2009
2010         if( !g_pGesture || !g_pGesture->EQ )
2011                 return ERROR_INVALPTR;
2012
2013         for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
2014         {
2015                 if( g_pGesture->EQ[i].event )
2016                 {
2017                         free(g_pGesture->EQ[i].event);
2018                         g_pGesture->EQ[i].event = NULL;
2019                 }
2020         }
2021
2022         free(g_pGesture->EQ);
2023         g_pGesture->EQ = NULL;
2024
2025         return ERROR_NONE;
2026 }
2027
2028 ErrorStatus
2029 GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2030 {
2031         int tail;
2032
2033         if( !g_pGesture || !g_pGesture->EQ )
2034         {
2035                 ErrorF("[X11][GestureEnqueueEvent] Invalid pointer access !\n");
2036                 return ERROR_INVALPTR;
2037         }
2038
2039         tail = g_pGesture->tailEQ;
2040
2041         if( tail >= GESTURE_EQ_SIZE )
2042         {
2043                 ErrorF("[X11][GestureEnqueueEvent] Gesture EQ is full !\n");
2044                 printk("[X11][GestureEnqueueEvent] Gesture EQ is full...Force Gesture Flush !\n");
2045                 GestureEventsFlush();
2046                 return ERROR_EQFULL;
2047         }
2048
2049 #ifdef __DETAIL_DEBUG__
2050         switch( ev->any.type )
2051         {
2052                 case ET_ButtonPress:
2053                         ErrorF("[X11][GestureEnqueueEvent] ET_ButtonPress (id:%d)\n", device->id);
2054                         break;
2055
2056                 case ET_ButtonRelease:
2057                         ErrorF("[X11][GestureEnqueueEvent] ET_ButtonRelease (id:%d)\n", device->id);
2058                         break;
2059
2060                 case ET_Motion:
2061                         ErrorF("[X11][GestureEnqueueEvent] ET_Motion (id:%d)\n", device->id);
2062                         break;
2063         }
2064 #endif//__DETAIL_DEBUG__
2065
2066         g_pGesture->EQ[tail].device = device;
2067         g_pGesture->EQ[tail].screen_num = screen_num;
2068         memcpy(g_pGesture->EQ[tail].event, ev, sizeof(InternalEvent));//need to be optimized
2069         g_pGesture->tailEQ++;
2070
2071         return ERROR_NONE;
2072 }
2073
2074 ErrorStatus
2075 GestureEventsFlush(void)
2076 {
2077         int i;
2078         DeviceIntPtr device;
2079
2080         if( !g_pGesture->EQ )
2081         {
2082                 ErrorF("[X11][GestureEventsFlush] Invalid pointer access !\n");
2083                 return ERROR_INVALPTR;
2084         }
2085
2086 #ifdef __DETAIL_DEBUG__
2087         ErrorF("[X11][GestureEventsFlush]\n");
2088 #endif//__DETAIL_DEBUG__
2089         for( i = g_pGesture->headEQ ; i < g_pGesture->tailEQ ; i++)
2090         {
2091                 device = g_pGesture->EQ[i].device;
2092                 device->public.processInputProc(g_pGesture->EQ[i].event, device);
2093         }
2094         for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
2095                 g_pGesture->event_sum[i] = 0;
2096         g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
2097
2098         return ERROR_NONE;
2099 }
2100
2101 void
2102 GestureEventsDrop(void)
2103 {
2104         g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
2105 }
2106
2107 #ifdef HAVE_PROPERTIES
2108 static void
2109 GestureInitProperty(DeviceIntPtr dev)
2110 {
2111         int rc;
2112
2113         prop_gesture_recognizer_onoff = MakeAtom(GESTURE_RECOGNIZER_ONOFF, strlen(GESTURE_RECOGNIZER_ONOFF),  TRUE);
2114         rc = XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
2115
2116         if (rc != Success)
2117                 return;
2118
2119         XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE);
2120 }
2121
2122 static int
2123 GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
2124                  BOOL checkonly)
2125 {
2126         if( prop_gesture_recognizer_onoff == atom )
2127         {
2128                 int data;
2129                 if( val->format != 32 || val->type != XA_INTEGER || val->size != 1 )
2130                         return BadMatch;
2131
2132                 if( !checkonly )
2133                 {
2134                         data = *((int *)val->data);
2135                         GestureEnable(data, TRUE, dev);
2136                 }
2137         }
2138         return Success;
2139 }
2140 #endif//HAVE_PROPERTIES
2141
2142 static int
2143 GestureInit(DeviceIntPtr device)
2144 {
2145 #ifdef HAVE_PROPERTIES
2146         GestureInitProperty(device);
2147         XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL);
2148 #endif
2149         //GestureEnable(1, FALSE, g_pGesture->this_device);
2150         return Success;
2151 }
2152
2153 static void
2154 GestureFini(DeviceIntPtr device)
2155 {
2156         XIRegisterPropertyHandler(device, NULL, NULL, NULL);
2157 }
2158
2159 static pointer
2160 GesturePlug(pointer module, pointer options, int *errmaj, int *errmin)
2161 {
2162         xf86AddInputDriver(&GESTURE, module, 0);
2163         return module;
2164 }
2165
2166 static void
2167 GestureUnplug(pointer p)
2168 {
2169 }
2170
2171 static int
2172 GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
2173 {
2174     int rc = BadAlloc;
2175     GestureDevicePtr    pGesture;
2176
2177     pGesture = calloc(1, sizeof(GestureDeviceRec));
2178
2179     if (!pGesture) {
2180         pInfo->private = NULL;
2181         //xf86DeleteInput(pInfo, 0);
2182         goto error;
2183     }
2184
2185     g_pGesture = pGesture;
2186     pInfo->private = pGesture;
2187     pInfo->flags = 0;
2188     pInfo->read_input = GestureReadInput; /* new data avl */
2189     pInfo->switch_mode = NULL; /* toggle absolute/relative mode */
2190     pInfo->device_control = GestureControl; /* enable/disable dev */
2191     /* process driver specific options */
2192     pGesture->device = xf86SetStrOption(pInfo->options, "Device", "/dev/null");
2193     pGesture->is_active = xf86SetIntOption(pInfo->options, "Activate", 0);
2194     pGesture->gestureWin = None;
2195     pGesture->lastSelectedWin = None;
2196     pGesture->power_pressed = 1;
2197     pGesture->hwkey_id = 0;
2198     pGesture->hwkey_dev = NULL;
2199     pGesture->hwkey_name = xf86SetStrOption(pInfo->options, "BackHWKeyName", NULL);
2200     pGesture->screen_width = xf86SetIntOption(pInfo->options,"ScreenWidth", 0);
2201     pGesture->screen_height = xf86SetIntOption(pInfo->options,"ScreenHeight", 0);
2202     pGesture->hwkeycode_flick_down = xf86SetIntOption(pInfo->options, "FlickDownKeycode", 0);
2203     pGesture->hwkeycode_flick_up = xf86SetIntOption(pInfo->options, "FlickUpKeycode", 0);
2204     pGesture->flick_press_area = xf86SetIntOption(pInfo->options, "FlickPressArea", 0);
2205     pGesture->flick_press_area_left = xf86SetIntOption(pInfo->options, "FlickPressArea_LEFT", 0);
2206     pGesture->flick_press_area_left_right = xf86SetIntOption(pInfo->options, "FlickPressArea_LEFT_RIGHT", 0);
2207     pGesture->flick_minimum_height = xf86SetIntOption(pInfo->options, "FlickMinimumHeight", 0);
2208     pGesture->shutdown_keycode = xf86SetIntOption(pInfo->options, "ShutdownKeycode", 0);
2209     pGesture->singletap_threshold= xf86SetIntOption(pInfo->options, "SingleTapThresHold", 0);
2210     pGesture->doubletap_threshold= xf86SetIntOption(pInfo->options, "DoubleTapThresHold", 0);
2211     pGesture->hold_area_threshold = xf86SetRealOption(pInfo->options, "HoldAreaThresHold", 0);
2212     pGesture->hold_move_threshold = xf86SetIntOption(pInfo->options, "HoldMoveThresHold", 0);
2213     pGesture->hold_time_threshold = xf86SetIntOption(pInfo->options, "HoldTimeThresHold", 0);
2214     pGesture->activate_flick_down = xf86SetIntOption(pInfo->options, "ActivateFlickDown", 0);
2215     pGesture->activate_flick_up = xf86SetIntOption(pInfo->options, "ActivateFlickUp", 0);
2216     pGesture->activate_flick_right = xf86SetIntOption(pInfo->options, "ActivateFlickRight", 0);
2217
2218         ErrorF("[X11][%s] ###############################################################\n", __FUNCTION__);
2219     ErrorF("[X11][%s] screen_width=%d, screen_height=%d\n", __FUNCTION__,
2220         pGesture->screen_width, pGesture->screen_height);
2221     ErrorF("[X11][%s] FlickDownKeycode=%d, FlickUpKeycode=%d\n", __FUNCTION__,
2222         pGesture->hwkeycode_flick_down, pGesture->hwkeycode_flick_up);
2223     ErrorF("[X11][%s] flick_press_area=%d, flick_press_area_left: %d, flick_press_area_left_right: %d, flick_minimum_height=%d\n", __FUNCTION__,
2224         pGesture->flick_press_area, pGesture->flick_press_area_left, pGesture->flick_press_area_left_right, pGesture->flick_minimum_height);
2225     ErrorF("[X11][%s] ShutdownKeycode=%d\n", __FUNCTION__, pGesture->shutdown_keycode);
2226     ErrorF("[X11][%s] singletap_threshold=%d, doubletap_threshold=%d\n", __FUNCTION__, pGesture->singletap_threshold, pGesture->doubletap_threshold);
2227     ErrorF("[X11][%s] hold_area_threshold: %f, hold_move_threshold: %d, hold_time_threshold: %d\n", __FUNCTION__,
2228         pGesture->hold_area_threshold, pGesture->hold_move_threshold, pGesture->hold_time_threshold);
2229     ErrorF("[X11][%s] activate_flick_down=%d, activate_flick_up=%d, activate_flick_right=%d\n", __FUNCTION__,
2230                 pGesture->activate_flick_down, pGesture->activate_flick_up, pGesture->activate_flick_right);
2231     ErrorF("[X11][%s] ###############################################################\n", __FUNCTION__);
2232
2233     if(pGesture->hwkey_name)
2234                 ErrorF("[X11][%s] hwkey_name=%s\n", __FUNCTION__, pGesture->hwkey_name);
2235
2236     pGesture->mtsync_status = MTOUCH_FRAME_SYNC_END;
2237     g_pGesture->grabMask = g_pGesture->eventMask = 0;
2238
2239     xf86Msg(X_INFO, "%s: Using device %s.\n", pInfo->name, pGesture->device);
2240
2241     /* process generic options */
2242     xf86CollectInputOptions(pInfo, NULL);
2243     xf86ProcessCommonOptions(pInfo, pInfo->options);
2244
2245     pInfo->fd = -1;
2246
2247     return Success;
2248
2249 error:
2250     if (pInfo->fd >= 0)
2251         close(pInfo->fd);
2252     return rc;
2253 }
2254
2255 static void
2256 GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
2257 {
2258         GestureDevicePtr pGesture = pInfo->private;
2259
2260         g_pGesture = pGesture = NULL;
2261         pInfo->private = NULL;
2262
2263         xf86DeleteInput(pInfo, 0);
2264 }
2265
2266 static int
2267 GestureControl(DeviceIntPtr device, int what)
2268 {
2269     InputInfoPtr  pInfo = device->public.devicePrivate;
2270     GestureDevicePtr pGesture = pInfo->private;
2271
2272     switch(what)
2273     {
2274         case DEVICE_INIT:
2275              GestureInit(device);
2276             break;
2277
2278         /* Switch device on.  Establish socket, start event delivery.  */
2279         case DEVICE_ON:
2280             xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
2281
2282             if (device->public.on)
2283                     break;
2284
2285             device->public.on = TRUE;
2286              pGesture->this_device = device;
2287              pGesture->num_mt_devices = 0;
2288              if( ERROR_ABNORMAL == GestureEnableEventHandler(pInfo) )
2289                 goto device_off;
2290             break;
2291
2292        case DEVICE_OFF:
2293 device_off:
2294              GestureDisableEventHandler();
2295              GestureFini(device);
2296              pGesture->this_device = NULL;
2297              xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
2298
2299             if (!device->public.on)
2300                 break;
2301
2302             pInfo->fd = -1;
2303             device->public.on = FALSE;
2304             break;
2305
2306       case DEVICE_CLOSE:
2307             /* free what we have to free */
2308             break;
2309     }
2310     return Success;
2311 }
2312
2313 static void
2314 GestureReadInput(InputInfoPtr pInfo)
2315 {
2316 }
2317