1 /**************************************************************************
3 xserver-xorg-input-gesture
5 Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
7 Contact: Sung-Jin Park <sj76.park@samsung.com>
8 Sangjin LEE <lsj119@samsung.com>
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:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
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.
30 **************************************************************************/
36 #include <linux/input.h>
37 #include <linux/types.h>
39 #include <xf86_OSproc.h>
44 #include <xf86Xinput.h>
46 #include <xorgVersion.h>
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
63 #include <sys/syscall.h>
66 #include <sys/types.h>
68 #include <xorg-server.h>
69 #include <xorgVersion.h>
70 #include <xf86Module.h>
71 #include <X11/Xatom.h>
76 static InputInfoPtr GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
77 static void GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
78 static pointer GesturePlug(pointer module, pointer options, int *errmaj, int *errmin);
79 static void GestureUnplug(pointer p);
80 static int GestureControl(DeviceIntPtr device,int what);
81 static int GestureInit(DeviceIntPtr device);
82 static void GestureFini(DeviceIntPtr device);
83 static void GestureReadInput(InputInfoPtr pInfo);
86 ErrorStatus GestureRegionsInit(void);
88 //event queue handling functions
89 ErrorStatus GestureInitEQ(void);
90 ErrorStatus GestureFiniEQ(void);
91 ErrorStatus GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
92 ErrorStatus GestureEventsFlush(void);
93 void GestureEventsDrop(void);
96 ErrorStatus GestureRegionsReinit(void);
97 void GestureSetDisable(InputInfoPtr pInfo, int enable);
98 WindowPtr GestureGetEventsWindow(void);
100 //Enqueued event handlers and enabler/disabler
101 static ErrorStatus GestureEnableEventHandler(InputInfoPtr pInfo);
102 static ErrorStatus GestureDisableEventHandler(void);
103 static CARD32 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
104 static CARD32 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
105 void GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
106 void GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
107 void GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
108 void GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
110 //Gesture recognizer helper
111 static Bool PointInBorderSize(WindowPtr pWin, int x, int y);
112 static WindowPtr GestureWindowOnXY(int x, int y);
113 Bool GestureHasFingerEventMask(int eventType, int num_finger);
114 static double get_angle(int x1, int y1, int x2, int y2);
116 //Gesture recognizer and handlers
117 void GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
118 void GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx);
119 void GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
120 void GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
121 void GestureRecognize_GroupTapNHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
122 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
123 void GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction);
124 void GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy);
125 void GestureHandleGesture_PinchRotation(int num_of_fingers, double zoom, double angle, int distance, int cx, int cy, int kinds);
126 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds);
127 void GestureHandleGesture_TapNHold(int num_fingers, int cx, int cy, Time interval, Time holdtime, int kinds);
128 void GestureHandleGesture_Pan(int num_fingers, short int dx, short int dy, int direction, int distance, Time duration, int kinds);
129 void GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device);
130 ErrorStatus GestureFlushOrDrop(void);
132 #ifdef HAVE_PROPERTIES
133 //function related property handling
134 static void GestureInitProperty(DeviceIntPtr dev);
135 static int GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkonly);
138 static Atom prop_gesture_recognizer_onoff = None;
140 GestureDevicePtr g_pGesture = NULL;
141 _X_EXPORT InputDriverRec GESTURE = {
151 static XF86ModuleVersionInfo GestureVersionRec =
157 XORG_VERSION_CURRENT,
158 PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR,
159 PACKAGE_VERSION_PATCHLEVEL,
166 _X_EXPORT XF86ModuleData gestureModuleData =
174 printk(const char* fmt, ...)
176 static FILE* fp = NULL;
177 static char init = 0;
182 fp = fopen("/dev/kmsg", "wt");
188 va_start(argptr, fmt);
189 vfprintf(fp, fmt, argptr);
195 PointInBorderSize(WindowPtr pWin, int x, int y)
198 if( pixman_region_contains_point (&pWin->borderSize, x, y, &box) )
205 GestureWindowOnXY(int x, int y)
210 DeviceIntPtr pDev = g_pGesture->master_pointer;
212 pSprite = pDev->spriteInfo->sprite;
213 pSprite->spriteTraceGood = 1; /* root window still there */
214 pWin = RootWindow(pDev)->firstChild;
218 if ((pWin->mapped) &&
219 (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
220 (x < pWin->drawable.x + (int)pWin->drawable.width +
221 wBorderWidth(pWin)) &&
222 (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
223 (y < pWin->drawable.y + (int)pWin->drawable.height +
225 /* When a window is shaped, a further check
226 * is made to see if the point is inside
229 && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
230 && (!wInputShape(pWin) ||
231 RegionContainsPoint(wInputShape(pWin),
232 x - pWin->drawable.x,
233 y - pWin->drawable.y, &box))
235 /* In rootless mode windows may be offscreen, even when
236 * they're in X's stack. (E.g. if the native window system
237 * implements some form of virtual desktop system).
239 && !pWin->rootlessUnhittable
243 if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
245 pSprite->spriteTraceSize += 10;
246 pSprite->spriteTrace = realloc(pSprite->spriteTrace,
247 pSprite->spriteTraceSize*sizeof(WindowPtr));
249 pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
250 pWin = pWin->firstChild;
253 pWin = pWin->nextSib;
255 return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
259 GestureHasFingerEventMask(int eventType, int num_finger)
262 Mask eventmask = (1L << eventType);
264 if( (g_pGesture->grabMask & eventmask) &&
265 (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[num_finger].window != None) )
267 #ifdef __DETAIL_DEBUG__
268 ErrorF("[X11][GestureHasFingerEventMask] TRUE !! Has grabMask\n");
269 #endif//__DETAIL_DEBUG__
273 if( g_pGesture->eventMask & eventmask )
275 #ifdef __DETAIL_DEBUG__
276 ErrorF("[X11][GestureHasFingerEventMask] TRUE !! Has eventMask\n");
277 #endif//__DETAIL_DEBUG__
281 #ifdef __DETAIL_DEBUG__
282 ErrorF("[X11][GestureHasFingerEventMask] FALSE !! eventType=%d, num_finger=%d\n", eventType, num_finger);
283 #endif//__DETAIL_DEBUG__
289 get_angle(int x1, int y1, int x2, int y2)
295 if (((int) xx) && ((int) yy))
302 return (RAD_360DEG - a);
313 return (RAD_180DEG + a);
317 return (RAD_180DEG - a);
323 { /* Horizontal line */
346 GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction)
349 WindowPtr target_pWin;
350 xGestureNotifyFlickEvent fev;
352 #ifdef __DETAIL_DEBUG__
353 ErrorF("[X11][GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n",
354 num_of_fingers, distance, duration, direction);
355 #endif//__DETAIL_DEBUG__
357 g_pGesture->recognized_gesture |= FlickFilterMask;
358 memset(&fev, 0, sizeof(xGestureNotifyFlickEvent));
359 fev.type = GestureNotifyFlick;
360 fev.kind = GestureDone;
361 fev.num_finger = num_of_fingers;
362 fev.distance = distance;
363 fev.duration = duration;
364 fev.direction = direction;
366 target_win = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].window;
367 target_pWin = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].pWin;
369 if( g_pGesture->grabMask && (target_win != None) )
371 fev.window = target_win;
375 fev.window = g_pGesture->gestureWin;
378 #ifdef __DETAIL_DEBUG__
379 ErrorF("[X11][GestureHandleGesture_Flick] fev.window=0x%x, g_pGesture->grabMask=0x%x\n", fev.window, g_pGesture->grabMask);
380 #endif//__DETAIL_DEBUG__
382 GestureSendEvent(target_pWin, GestureNotifyFlick, GestureFlickMask, (xGestureCommonEvent *)&fev);
386 GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy)
389 WindowPtr target_pWin;
390 xGestureNotifyTapEvent tev;
392 //skip non-tap events and single finger tap
393 if( !tap_repeat || num_finger <= 1 )
396 #ifdef __DETAIL_DEBUG__
397 ErrorF("[X11][GestureHandleGesture_Tap] num_finger=%d, tap_repeat=%d, cx=%d, cy=%d\n",
398 num_finger, tap_repeat, cx, cy);
399 #endif//__DETAIL_DEBUG__
401 g_pGesture->recognized_gesture |= TapFilterMask;
402 memset(&tev, 0, sizeof(xGestureNotifyTapEvent));
403 tev.type = GestureNotifyTap;
404 tev.kind = GestureDone;
405 tev.num_finger = num_finger;
406 tev.tap_repeat = tap_repeat;
411 target_win = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].window;
412 target_pWin = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].pWin;
414 if( g_pGesture->grabMask && (target_win != None) )
416 tev.window = target_win;
420 tev.window = g_pGesture->gestureWin;
423 #ifdef __DETAIL_DEBUG__
424 ErrorF("[X11][GestureHandleGesture_Tap] tev.window=0x%x, g_pGesture->grabMask=0x%x\n", tev.window, g_pGesture->grabMask);
425 #endif//__DETAIL_DEBUG__
427 GestureSendEvent(target_pWin, GestureNotifyTap, GestureTapMask, (xGestureCommonEvent *)&tev);
430 void GestureHandleGesture_PinchRotation(int num_of_fingers, double zoom, double angle, int distance, int cx, int cy, int kinds)
433 WindowPtr target_pWin;
434 xGestureNotifyPinchRotationEvent prev;
436 #ifdef __DETAIL_DEBUG__
437 ErrorF("[X11][GestureHandleGesture_PinchRotation] num_fingers=%d, zoom=%.2f, angle=%.2f(deg=%.2f), distance=%d, cx=%d, cy=%d\n",
438 num_of_fingers, zoom, angle, rad2degree(angle), distance, cx, cy);
439 #endif//__DETAIL_DEBUG__
441 g_pGesture->recognized_gesture |= PinchRotationFilterMask;
442 memset(&prev, 0, sizeof(xGestureNotifyPinchRotationEvent));
443 prev.type = GestureNotifyPinchRotation;
445 prev.num_finger = num_of_fingers;
446 prev.zoom = XDoubleToFixed(zoom);
447 prev.angle = XDoubleToFixed(angle);
448 prev.distance = distance;
452 target_win = g_pGesture->GrabEvents[GestureNotifyPinchRotation].pGestureGrabWinInfo[num_of_fingers].window;
453 target_pWin = g_pGesture->GrabEvents[GestureNotifyPinchRotation].pGestureGrabWinInfo[num_of_fingers].pWin;
455 if( g_pGesture->grabMask && (target_win != None) )
457 prev.window = target_win;
461 prev.window = g_pGesture->gestureWin;
464 #ifdef __DETAIL_DEBUG__
465 ErrorF("[X11][GestureHandleGesture_PinchRotation] prev.window=0x%x, g_pGesture->grabMask=0x%x\n", (unsigned int)prev.window, (unsigned int)g_pGesture->grabMask);
466 #endif//__DETAIL_DEBUG__
468 GestureSendEvent(target_pWin, GestureNotifyPinchRotation, GesturePinchRotationMask, (xGestureCommonEvent *)&prev);
471 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds)
474 WindowPtr target_pWin;
475 xGestureNotifyHoldEvent hev;
477 #ifdef __DETAIL_DEBUG__
478 ErrorF("[X11][GestureHandleGesture_Hold] num_fingers=%d, cx=%d, cy=%d, holdtime=%d, kinds=%d\n",
479 num_fingers, cx, cy, holdtime, kinds);
480 #endif//__DETAIL_DEBUG__
482 g_pGesture->recognized_gesture |= HoldFilterMask;
483 memset(&hev, 0, sizeof(xGestureNotifyHoldEvent));
484 hev.type = GestureNotifyHold;
486 hev.num_finger = num_fingers;
487 hev.holdtime = holdtime;
491 target_win = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].window;
492 target_pWin = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].pWin;
494 if( g_pGesture->grabMask && (target_win != None) )
496 hev.window = target_win;
500 hev.window = g_pGesture->gestureWin;
503 #ifdef __DETAIL_DEBUG__
504 ErrorF("[X11][GestureHandleGesture_Hold] hev.window=0x%x, g_pGesture->grabMask=0x%x\n", hev.window, g_pGesture->grabMask);
505 #endif//__DETAIL_DEBUG__
507 GestureSendEvent(target_pWin, GestureNotifyHold, GestureHoldMask, (xGestureCommonEvent *)&hev);
510 void GestureHandleGesture_TapNHold(int num_fingers, int cx, int cy, Time interval, Time holdtime, int kinds)
513 WindowPtr target_pWin;
514 xGestureNotifyTapNHoldEvent thev;
516 #ifdef __DETAIL_DEBUG__
517 ErrorF("[X11][GestureHandleGesture_TapNHold] num_fingers=%d, cx=%d, cy=%d, interval=%d, holdtime=%d, kinds=%d\n",
518 num_fingers, cx, cy, interval, holdtime, kinds);
519 #endif//__DETAIL_DEBUG__
521 g_pGesture->recognized_gesture |= TapNHoldFilterMask;
522 memset(&thev, 0, sizeof(xGestureNotifyTapNHoldEvent));
523 thev.type = GestureNotifyTapNHold;
525 thev.num_finger = num_fingers;
526 thev.holdtime = holdtime;
529 thev.interval = interval;
531 target_win = g_pGesture->GrabEvents[GestureNotifyTapNHold].pGestureGrabWinInfo[num_fingers].window;
532 target_pWin = g_pGesture->GrabEvents[GestureNotifyTapNHold].pGestureGrabWinInfo[num_fingers].pWin;
534 if( g_pGesture->grabMask && (target_win != None) )
536 thev.window = target_win;
540 thev.window = g_pGesture->gestureWin;
543 #ifdef __DETAIL_DEBUG__
544 ErrorF("[X11][GestureHandleGesture_TapNHold] thev.window=0x%x, g_pGesture->grabMask=0x%x\n", thev.window, g_pGesture->grabMask);
545 #endif//__DETAIL_DEBUG__
547 GestureSendEvent(target_pWin, GestureNotifyTapNHold, GestureTapNHoldMask, (xGestureCommonEvent *)&thev);
550 void GestureHandleGesture_Pan(int num_fingers, short int dx, short int dy, int direction, int distance, Time duration, int kinds)
553 WindowPtr target_pWin;
554 xGestureNotifyPanEvent pev;
556 #ifdef __DETAIL_DEBUG__
557 ErrorF("[X11][GestureHandleGesture_Pan] num_fingers=%d, dx=%d, dy=%d, direction=%d, distance=%d, duration=%d, kinds=%d\n",
558 num_fingers, dx, dy, direction, distance, duration, kinds);
559 #endif//__DETAIL_DEBUG__
561 g_pGesture->recognized_gesture |= PanFilterMask;
562 memset(&pev, 0, sizeof(xGestureNotifyPanEvent));
563 pev.type = GestureNotifyPan;
565 pev.num_finger = num_fingers;
566 pev.direction = direction;
567 pev.distance = distance;
568 pev.duration = duration;
572 target_win = g_pGesture->GrabEvents[GestureNotifyPan].pGestureGrabWinInfo[num_fingers].window;
573 target_pWin = g_pGesture->GrabEvents[GestureNotifyPan].pGestureGrabWinInfo[num_fingers].pWin;
575 if( g_pGesture->grabMask && (target_win != None) )
577 pev.window = target_win;
581 pev.window = g_pGesture->gestureWin;
584 #ifdef __DETAIL_DEBUG__
585 ErrorF("[X11][GestureHandleGesture_Pan] pev.window=0x%x, g_pGesture->grabMask=0x%x\n", pev.window, g_pGesture->grabMask);
586 #endif//__DETAIL_DEBUG__
588 GestureSendEvent(target_pWin, GestureNotifyPan, GesturePanMask, (xGestureCommonEvent *)&pev);
592 GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
596 static int num_pressed = 0;
597 static int state = GestureEnd;
598 static int event_type = GestureNotifyPinchRotation;
599 static OsTimerPtr pinchrotation_event_timer = NULL;
601 static pixman_region16_t base_area;
602 static pixman_region16_t cur_area;
604 static double base_distance = 0.0f;
605 static double base_angle = 0.0f;
607 static double prev_distance = 0.0f;
608 static double prev_angle = 0.0f;
610 static double cur_distance = 0.0f;
611 static double cur_angle = 0.0f;
613 double diff_distance = 0.0f;
614 double diff_angle = 0.0f;
616 static int has_event_mask = 0;
618 static Time base_time = 0;
623 if( state == GestureEnd )
625 current_time = GetTimeInMillis();
626 if( (current_time - base_time) >= PINCHROTATION_TIME_THRESHOLD )
628 #ifdef __DETAIL_DEBUG__
629 ErrorF("[GroupPinchRotation][Timer] You must move farther than dist threshold(=%.2f) or angle threshold(=%2f) within time threshold(=%d) !\n", PINCHROTATION_DIST_THRESHOLD, PINCHROTATION_ANGLE_THRESHOLD, PINCHROTATION_TIME_THRESHOLD);
630 #endif//__DETAIL_DEBUG__
631 goto cleanup_pinchrotation;
641 g_pGesture->fingers[idx].flags |= PressFlagPinchRotation;
643 if( g_pGesture->num_pressed < 2 )
646 if( g_pGesture->num_pressed < num_pressed && state != GestureEnd )
648 #ifdef __DETAIL_DEBUG__
649 ErrorF("[GroupPinchRotation][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
650 #endif//__DETAIL_DEBUG__
651 goto cleanup_pinchrotation;
654 if( base_distance == 0.0f && g_pGesture->num_pressed == 2 )
656 #ifdef __DETAIL_DEBUG__
657 ErrorF("[GroupPinchRotation][First Time !!!] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
658 #endif//__DETAIL_DEBUG__
660 base_time = GetTimeInMillis();
661 pixman_region_init(&base_area);
662 pixman_region_union(&base_area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[1]);
664 prev_distance = base_distance = AREA_DIAG_LEN(&base_area.extents);
666 #ifdef __DETAIL_DEBUG__
667 ErrorF("[GroupPinchRotation][P] x1=%d, x2=%d, y1=%d, y2=%d\n", g_pGesture->fingers[0].px, g_pGesture->fingers[1].px,
668 g_pGesture->fingers[0].py, g_pGesture->fingers[1].py);
669 #endif//__DETAIL_DEBUG__
671 prev_angle = base_angle = get_angle(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py, g_pGesture->fingers[1].px, g_pGesture->fingers[1].py);
672 #ifdef __DETAIL_DEBUG__
673 ErrorF("[GroupPinchRotation][P] base_angle=%.2f(deg=%.2f)\n", base_angle, rad2degree(base_angle));
674 #endif//__DETAIL_DEBUG__
675 event_type = GestureNotifyPinchRotation;
676 pinchrotation_event_timer = TimerSet(pinchrotation_event_timer, 0, PINCHROTATION_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
678 num_pressed = g_pGesture->num_pressed;
680 #ifdef __DETAIL_DEBUG__
681 ErrorF("[GroupPinchRotation][P][num_pressed=%d] AREA_SIZE(base_area.extents)=%d\n", num_pressed, AREA_SIZE(&base_area.extents));
682 ErrorF("[GroupPinchRotation][P][num_pressed=%d] base_distance=%.2f, base_angle=%.2f(deg=%.2f)\n", num_pressed, base_distance, base_angle, rad2degree(base_angle));
683 #endif//__DETAIL_DEBUG__
687 if( !(g_pGesture->fingers[idx].flags & PressFlagPinchRotation) )
690 if( (num_pressed != g_pGesture->num_pressed) && (state != GestureEnd) )
692 #ifdef __DETAIL_DEBUG__
693 ErrorF("[GroupPinchRotation][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
694 #endif//__DETAIL_DEBUG__
695 goto cleanup_pinchrotation;
698 if( num_pressed < 2 )
701 if( g_pGesture->fingers[0].mx && g_pGesture->fingers[0].my && g_pGesture->fingers[1].mx && g_pGesture->fingers[1].my )
703 pixman_region_init(&cur_area);
704 pixman_region_union(&cur_area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[1]);
706 cur_distance = AREA_DIAG_LEN(&cur_area.extents);
708 #ifdef __DETAIL_DEBUG__
709 ErrorF("[GroupPinchRotation][M] x1=%d, x2=%d, y1=%d, y2=%d\n", g_pGesture->fingers[0].mx, g_pGesture->fingers[1].mx,
710 g_pGesture->fingers[0].my, g_pGesture->fingers[1].my);
711 #endif//__DETAIL_DEBUG__
713 cur_angle = get_angle(g_pGesture->fingers[0].mx, g_pGesture->fingers[0].my, g_pGesture->fingers[1].mx, g_pGesture->fingers[1].my);
714 #ifdef __DETAIL_DEBUG__
715 ErrorF("[GroupPinchRotation][M] cur_angle=%.2f(deg=%.2f)\n", cur_angle, rad2degree(cur_angle));
716 #endif//__DETAIL_DEBUG__
718 diff_distance = prev_distance - cur_distance;
719 diff_angle = prev_angle - cur_angle;
721 cx = AREA_CENTER_X(&cur_area.extents);
722 cy = AREA_CENTER_Y(&cur_area.extents);
724 #ifdef __DETAIL_DEBUG__
725 ErrorF("[GroupPinchRotation][M][state=%d] cx=%d, cy=%d\n", state, cx, cy);
726 #endif//__DETAIL_DEBUG__
728 #ifdef __DETAIL_DEBUG__
729 ErrorF("[GroupPinchRotation][M][num_pressed=%d] prev_distance=%.2f, cur_distance=%.2f, diff=%.2f\n", num_pressed, prev_distance, cur_distance, diff_distance);
730 ErrorF("[GroupPinchRotation][M][num_pressed=%d] prev_angle=%.2f(deg=%.2f), cur_angle=%.2f(deg=%.2f), diff=%.2f(deg=%.2f)\n", num_pressed, prev_angle, rad2degree(prev_angle), cur_angle, rad2degree(cur_angle), diff_angle, rad2degree(diff_angle));
731 #endif//__DETAIL_DEBUG__
736 if( (ABS(diff_distance) >= PINCHROTATION_DIST_THRESHOLD) || (ABS(diff_angle) >= PINCHROTATION_ANGLE_THRESHOLD) )
738 #ifdef __DETAIL_DEBUG__
739 if( ABS(diff_distance) >= PINCHROTATION_DIST_THRESHOLD )
740 ErrorF("[GroupPinchRotation][M] zoom changed !\n");
742 if( ABS(diff_angle) >= PINCHROTATION_ANGLE_THRESHOLD )
743 ErrorF("[GroupPinchRotation][M] angle changed !\n");
744 #endif//__DETAIL_DEBUG__
746 TimerCancel(pinchrotation_event_timer);
747 state = GestureBegin;
748 goto gesture_begin_handle;
753 gesture_begin_handle:
754 #ifdef __DETAIL_DEBUG__
755 ErrorF("[GroupPinchRotation] PINCHROTATION Begin !cx=%d, cy=%d, state=%d\n", cx, cy, state);
756 #endif//__DETAIL_DEBUG__
757 if( GestureHasFingerEventMask(GestureNotifyPinchRotation, num_pressed) )
759 GestureHandleGesture_PinchRotation(num_pressed, cur_distance / base_distance, (cur_angle > base_angle) ? (cur_angle-base_angle) : (RAD_360DEG + cur_angle - base_angle), cur_distance, cx, cy, GestureBegin);
760 prev_distance = cur_distance;
761 prev_angle = cur_angle;
762 state = GestureUpdate;
768 goto cleanup_pinchrotation;
773 //if( ABS(diff_distance) < PINCHROTATION_DIST_THRESHOLD && ABS(diff_angle) < PINCHROTATION_ANGLE_THRESHOLD )
776 #ifdef __DETAIL_DEBUG__
777 if( ABS(diff_distance) >= PINCHROTATION_DIST_THRESHOLD )
778 ErrorF("[GroupPinchRotation][M] zoom changed !\n");
780 if( ABS(diff_angle) >= PINCHROTATION_ANGLE_THRESHOLD )
781 ErrorF("[GroupPinchRotation][M] angle changed !\n");
782 #endif//__DETAIL_DEBUG__
784 #ifdef __DETAIL_DEBUG__
785 ErrorF("[GroupPinchRotation] PINCHROTATION Update ! cx=%d, cy=%d, state=%d\n", cx, cy, state);
786 #endif//__DETAIL_DEBUG__
787 GestureHandleGesture_PinchRotation(num_pressed, cur_distance / base_distance, (cur_angle > base_angle) ? (cur_angle-base_angle) : (RAD_360DEG + cur_angle - base_angle), cur_distance, cx, cy, GestureUpdate);
788 prev_distance = cur_distance;
789 prev_angle = cur_angle;
799 case ET_ButtonRelease:
800 if( state != GestureEnd && num_pressed >= 2)
802 #ifdef __DETAIL_DEBUG__
803 ErrorF("[GroupPinchRotation][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
804 #endif//__DETAIL_DEBUG__
805 goto cleanup_pinchrotation;
808 if( g_pGesture->num_pressed )
811 goto cleanup_pinchrotation;
817 cleanup_pinchrotation:
819 if( has_event_mask && (state == GestureBegin || state == GestureUpdate) )
822 #ifdef __DETAIL_DEBUG__
823 ErrorF("[GroupPinchRotation] PINCHROTATION End ! cx=%d, cy=%d, state=%d\n", cx, cy, state);
824 #endif//__DETAIL_DEBUG__
825 GestureHandleGesture_PinchRotation(num_pressed, cur_distance / base_distance, (cur_angle > base_angle) ? (cur_angle-base_angle) : (RAD_360DEG + cur_angle - base_angle), cur_distance, cx, cy, GestureEnd);
829 g_pGesture->recognized_gesture &= ~PinchRotationFilterMask;
832 g_pGesture->filter_mask |= PinchRotationFilterMask;
834 if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
836 #if 1//def __DETAIL_DEBUG__
837 ErrorF("[GroupPinchRotation][cleanup] GestureFlushOrDrop() !\n");
838 #endif//__DETAIL_DEBUG__
840 if( ERROR_INVALPTR == GestureFlushOrDrop() )
842 GestureControl(g_pGesture->this_device, DEVICE_OFF);
846 prev_distance = base_distance = 0.0f;
847 prev_angle = base_angle = 0.0f;
848 has_event_mask = num_pressed = 0;
851 TimerCancel(pinchrotation_event_timer);
856 GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx)
858 static int num_pressed = 0;
859 static int mbits = 0;
860 static int base_area_size = 0;
861 static Time base_time = 0;
862 static int base_x, base_y;
866 int distance, direction;
873 g_pGesture->fingers[idx].flags |= PressFlagFlick;
875 if( g_pGesture->num_pressed < 2 )
878 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
880 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
881 base_x = g_pGesture->area.extents.x1;
882 base_y = g_pGesture->area.extents.y1;
883 base_time = GetTimeInMillis();
885 num_pressed = g_pGesture->num_pressed;
887 #ifdef __DETAIL_DEBUG__
888 ErrorF("[GroupFlick][P]][num_pressed=%d] AREA_SIZE(area.extents)=%d\n", num_pressed, base_area_size);
889 #endif//__DETAIL_DEBUG__
893 if( !(g_pGesture->fingers[idx].flags & PressFlagFlick ) )
896 #ifdef __DETAIL_DEBUG__
897 if( num_pressed > g_pGesture->num_pressed )
899 ErrorF("[GroupFlick][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
900 //goto cleanup_flick;
902 #endif//__DETAIL_DEBUG__
904 if( num_pressed < 2 )
908 if( mbits == (pow(2, num_pressed)-1) )
910 area_size = AREA_SIZE(&g_pGesture->area.extents);
911 #ifdef __DETAIL_DEBUG__
912 ErrorF("[M][num_pressed=%d] AREA_SIZE(area.extents)=%d\n", num_pressed, area_size);
913 #endif//__DETAIL_DEBUG__
914 if( ABS(base_area_size - area_size) >= FLICK_AREA_THRESHOLD )
916 #ifdef __DETAIL_DEBUG__
917 ErrorF("[GroupFlick][M] diff between Area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, FLICK_AREA_THRESHOLD);
918 #endif//__DETAIL_DEBUG__
922 current_time = GetTimeInMillis();
923 if( (current_time - base_time) >= FLICK_AREA_TIMEOUT )
925 #ifdef __DETAIL_DEBUG__
926 ErrorF("[GroupFlick][M] diff between current time(=%d) and base time(=%d) is bigger than threashold(=%d) !\n", current_time, base_time, FLICK_AREA_TIMEOUT);
927 #endif//__DETAIL_DEBUG__
934 case ET_ButtonRelease:
935 if( g_pGesture->num_pressed )
938 duration = GetTimeInMillis() - base_time;
939 distx = g_pGesture->area.extents.x1 - base_x;
940 disty = g_pGesture->area.extents.y1 - base_y;
942 #ifdef __DETAIL_DEBUG__
943 ErrorF("[GroupFlick] duration=%d, distx=%d, disty=%d\n", duration, distx, disty);
944 #endif//__DETAIL_DEBUG__
946 if( duration <= 0 || duration >= FLICK_AREA_TIMEOUT )
949 if( ABS(distx) >= FLICK_MOVE_THRESHOLD )
951 direction = (distx > 0) ? FLICK_EASTWARD : FLICK_WESTWARD;
952 distance = ABS(distx);
955 else if( ABS(disty) >= FLICK_MOVE_THRESHOLD )
957 direction = (disty > 0) ? FLICK_SOUTHWARD : FLICK_NORTHWARD;
958 distance = ABS(disty);
965 if( GestureHasFingerEventMask(GestureNotifyFlick, num_pressed) )
966 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
967 goto cleanup_flick_recognized;
975 g_pGesture->recognized_gesture &= ~FlickFilterMask;
977 cleanup_flick_recognized:
979 g_pGesture->filter_mask |= FlickFilterMask;
988 GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
990 static int num_pressed = 0;
991 static int mbits = 0;
992 static int base_area_size = 0;
993 static Time base_time = 0;
994 static pixman_box16_t base_box_ext;
1002 static Time prev_time = 0;
1003 Time current_time = 0;
1007 static int time_checked = 0;
1008 static int state = GestureEnd;
1010 static OsTimerPtr pan_event_timer = NULL;
1011 static int event_type = GestureNotifyPan;
1017 current_time = GetTimeInMillis();
1018 if( (current_time - base_time) >= PAN_TIME_THRESHOLD )
1020 if( (!cx && !cy) || INBOX(&base_box_ext, cx, cy) )
1022 #ifdef __DETAIL_DEBUG__
1023 ErrorF("[GroupPan][Timer] You must move farther than move threshold(=%d) within time threshold(=%d) !\n", PAN_MOVE_THRESHOLD*2, PAN_TIME_THRESHOLD);
1024 #endif//__DETAIL_DEBUG__
1035 case ET_ButtonPress:
1036 g_pGesture->fingers[idx].flags |= PressFlagPan;
1038 if( g_pGesture->num_pressed < 2 )
1041 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
1043 if( state != GestureEnd )
1045 #ifdef __DETAIL_DEBUG__
1046 ErrorF("[GroupPan][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1047 #endif//__DETAIL_DEBUG__
1050 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1051 prev_cx = base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1052 prev_cy = base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1053 prev_time = base_time = GetTimeInMillis();
1054 base_box_ext.x1 = base_cx-PAN_MOVE_THRESHOLD;
1055 base_box_ext.y1 = base_cy-PAN_MOVE_THRESHOLD;
1056 base_box_ext.x2 = base_cx+PAN_MOVE_THRESHOLD;
1057 base_box_ext.y2 = base_cy+PAN_MOVE_THRESHOLD;
1058 event_type = GestureNotifyPan;
1059 pan_event_timer = TimerSet(pan_event_timer, 0, PAN_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1061 num_pressed = g_pGesture->num_pressed;
1063 #ifdef __DETAIL_DEBUG__
1064 ErrorF("[GroupPan][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);
1065 #endif//__DETAIL_DEBUG__
1069 if( !(g_pGesture->fingers[idx].flags & PressFlagPan ) )
1072 if( num_pressed != g_pGesture->num_pressed )
1074 if( state != GestureEnd )
1076 #ifdef __DETAIL_DEBUG__
1077 ErrorF("[GroupPan][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1078 #endif//__DETAIL_DEBUG__
1083 if( num_pressed < 2 )
1086 mbits |= (1 << idx);
1087 if( mbits == (pow(2, num_pressed)-1) )
1089 area_size = AREA_SIZE(&g_pGesture->area.extents);
1090 #ifdef __DETAIL_DEBUG__
1091 ErrorF("[GroupPan][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));
1092 #endif//__DETAIL_DEBUG__
1094 if( (state != GestureUpdate) && (ABS(base_area_size - area_size) >= PAN_AREA_THRESHOLD) )
1096 #ifdef __DETAIL_DEBUG__
1097 ErrorF("[GroupPan][M] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, PAN_AREA_THRESHOLD);
1098 #endif//__DETAIL_DEBUG__
1102 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1103 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1104 #ifdef __DETAIL_DEBUG__
1105 ErrorF("[GroupPan][M] cx=%d, prev_cx=%d, diff=%d\n", cx, prev_cx, ABS(cx-prev_cx));
1106 ErrorF("[GroupPan][M] cy=%d, prev_cy=%d, diff=%d\n", cy, prev_cy, ABS(cy-prev_cy));
1107 #endif//__DETAIL_DEBUG__
1109 if( state <= GestureBegin )
1111 if( !INBOX(&base_box_ext, cx, cy) )
1113 TimerCancel(pan_event_timer);
1114 pan_event_timer = NULL;
1116 if( GestureHasFingerEventMask(GestureNotifyPan, num_pressed) )
1118 GestureHandleGesture_Pan(num_pressed, prev_cx, prev_cy, direction, distance, current_time-prev_time, GestureBegin);
1119 state = GestureUpdate;
1130 //if( ABS(dx) >= PAN_UPDATE_MOVE_THRESHOLD || ABS(dy) >= PAN_UPDATE_MOVE_THRESHOLD )
1132 #ifdef __DETAIL_DEBUG__
1133 ErrorF("[GroupPan] PAN Update !dx=%d, dy=%d, state=%d\n", dx, dy, state);
1134 #endif//__DETAIL_DEBUG__
1136 GestureHandleGesture_Pan(num_pressed, dx, dy, direction, distance, current_time-prev_time, GestureUpdate);
1146 case ET_ButtonRelease:
1147 if( state != GestureEnd && num_pressed >= 2)
1149 #ifdef __DETAIL_DEBUG__
1150 ErrorF("[GroupPan][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1151 #endif//__DETAIL_DEBUG__
1155 if( g_pGesture->num_pressed )
1166 if( state == GestureBegin || state == GestureUpdate )
1169 if( GestureHasFingerEventMask(GestureNotifyPan, num_pressed) )
1171 GestureHandleGesture_Pan(num_pressed, (short int)(cx-prev_cx), (short int)(cy-prev_cy), direction, distance, GetTimeInMillis()-prev_time, GestureEnd);
1176 g_pGesture->recognized_gesture &= ~PanFilterMask;
1179 g_pGesture->filter_mask |= PanFilterMask;
1188 base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
1189 if( pan_event_timer )
1191 TimerCancel(pan_event_timer);
1192 pan_event_timer = NULL;
1198 GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1200 static int num_pressed = 0;
1201 static int base_area_size = 0;
1203 static Time base_time = 0;
1209 static int state = 0;
1210 static int mbits = 0;
1213 static pixman_box16_t base_box_ext;
1215 static int tap_repeat = 0;
1216 static int prev_tap_repeat = 0;
1217 static int prev_num_pressed = 0;
1219 static OsTimerPtr tap_event_timer = NULL;
1220 static int event_type = GestureNotifyTap;
1224 #ifdef __DETAIL_DEBUG__
1225 ErrorF("[GroupTap][Timer] state=%d\n", state);
1226 #endif//__DETAIL_DEBUG__
1230 case 1://first tap initiation check
1233 #ifdef __DETAIL_DEBUG__
1234 ErrorF("[GroupTap][Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", tap_repeat, num_pressed, tap_repeat);
1235 #endif//__DETAIL_DEBUG__
1242 if( tap_repeat <= 1 )
1244 #ifdef __DETAIL_DEBUG__
1245 ErrorF("[GroupTap][Timer][state=2] %d finger SINGLE TAP !(ignored)\n", prev_num_pressed);
1246 #endif//__DETAIL_DEBUG__
1251 #ifdef __DETAIL_DEBUG__
1252 ErrorF("[GroupTap][Timer][state=2] tap_repeat=%d, prev_tap_repeat=%d, num_pressed=%d\n", tap_repeat, prev_tap_repeat, num_pressed);
1253 #endif//__DETAIL_DEBUG__
1254 if( GestureHasFingerEventMask(GestureNotifyTap, prev_num_pressed) )
1255 GestureHandleGesture_Tap(prev_num_pressed, tap_repeat, base_cx, base_cy);
1265 case ET_ButtonPress:
1266 g_pGesture->fingers[idx].flags |= PressFlagTap;
1268 if( g_pGesture->num_pressed < 2 )
1271 if( !prev_num_pressed && (!base_area_size || g_pGesture->num_pressed > num_pressed) )
1273 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1274 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1275 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1276 base_time = GetTimeInMillis();
1277 base_box_ext.x1 = base_cx-TAP_MOVE_THRESHOLD;
1278 base_box_ext.y1 = base_cy-TAP_MOVE_THRESHOLD;
1279 base_box_ext.x2 = base_cx+TAP_MOVE_THRESHOLD;
1280 base_box_ext.y2 = base_cy+TAP_MOVE_THRESHOLD;
1282 TimerCancel(tap_event_timer);
1283 tap_event_timer = TimerSet(tap_event_timer, 0, SGL_TAP_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1286 num_pressed = g_pGesture->num_pressed;
1288 current_time = GetTimeInMillis();
1290 #ifdef __DETAIL_DEBUG__
1291 ErrorF("[GroupTap][P][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d, base_time=%d, current_time=%d\n", num_pressed, base_area_size, base_cx, base_cy, base_time, current_time);
1292 #endif//__DETAIL_DEBUG__
1296 if( !(g_pGesture->fingers[idx].flags & PressFlagTap ) )
1299 if( num_pressed < 2 )
1302 if( num_pressed != g_pGesture->num_pressed )
1304 #ifdef __DETAIL_DEBUG__
1305 ErrorF("[GroupTap][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1306 #endif//__DETAIL_DEBUG__
1310 mbits |= (1 << idx);
1311 if( mbits == (pow(2, num_pressed)-1) )
1313 area_size = AREA_SIZE(&g_pGesture->area.extents);
1314 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1315 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1316 #ifdef __DETAIL_DEBUG__
1317 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));
1318 ErrorF("[GroupTap][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1319 ErrorF("[GroupTap][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1320 #endif//__DETAIL_DEBUG__
1322 if( ABS(base_area_size-area_size) >= TAP_AREA_THRESHOLD )
1324 #ifdef __DETAIL_DEBUG__
1325 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));
1326 #endif//__DETAIL_DEBUG__
1330 if( !INBOX(&base_box_ext, cx, cy) )
1332 #ifdef __DETAIL_DEBUG__
1333 ErrorF("[GroupTap][M] current center coordinates is not in base coordinates box !\n");
1334 #endif//__DETAIL_DEBUG__
1340 case ET_ButtonRelease:
1341 if( g_pGesture->num_pressed )
1346 prev_num_pressed = num_pressed;
1349 prev_tap_repeat = tap_repeat;
1352 #ifdef __DETAIL_DEBUG__
1353 ErrorF("[GroupTap][R] tap_repeat=%d, prev_tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, prev_tap_repeat, num_pressed, prev_num_pressed);
1354 #endif//__DETAIL_DEBUG__
1356 if( num_pressed != prev_num_pressed || !GestureHasFingerEventMask(GestureNotifyTap, num_pressed) )
1358 #ifdef __DETAIL_DEBUG__
1359 ErrorF("[GroupTap][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
1360 num_pressed, prev_num_pressed, num_pressed);
1361 #endif//__DETAIL_DEBUG__
1365 if( tap_repeat < MAX_TAP_REPEATS )
1368 TimerCancel(tap_event_timer);
1369 tap_event_timer = TimerSet(tap_event_timer, 0, DBL_TAP_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1374 #ifdef __DETAIL_DEBUG__
1375 ErrorF("[GroupTap][R] %d finger %s\n", num_pressed, (tap_repeat==2) ? "DBL_TAP" : "TRIPLE_TAP");
1376 #endif//__DETAIL_DEBUG__
1378 if( GestureHasFingerEventMask(GestureNotifyTap, num_pressed) )
1379 GestureHandleGesture_Tap(num_pressed, tap_repeat, base_cx, base_cy);
1381 if( tap_repeat >= MAX_TAP_REPEATS )
1386 prev_num_pressed = num_pressed;
1396 g_pGesture->recognized_gesture &= ~TapFilterMask;
1397 g_pGesture->filter_mask |= TapFilterMask;
1399 if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
1401 #ifdef __DETAIL_DEBUG__
1402 ErrorF("[GroupTap][cleanup] GestureFlushOrDrop() !\n");
1403 #endif//__DETAIL_DEBUG__
1405 if( ERROR_INVALPTR == GestureFlushOrDrop() )
1407 GestureControl(g_pGesture->this_device, DEVICE_OFF);
1413 prev_num_pressed = 0;
1417 TimerCancel(tap_event_timer);
1422 GestureRecognize_GroupTapNHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1424 static int num_pressed = 0;
1425 static int base_area_size = 0;
1426 static Time base_time = 0;
1430 static pixman_box16_t base_box_ext;
1432 static int mbits = 0;
1434 static int tap_repeat = 0;
1435 static int prev_num_pressed = 0;
1437 static OsTimerPtr tapnhold_event_timer = NULL;
1438 static int event_type = GestureNotifyTapNHold;
1439 static int state = GestureEnd;
1446 if( (state == GestureEnd) && num_pressed )
1448 #ifdef __DETAIL_DEBUG__
1449 ErrorF("[GroupTapNHold][Timer][state=%d] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", GestureEnd, tap_repeat, num_pressed, tap_repeat);
1450 #endif//__DETAIL_DEBUG__
1452 goto cleanup_tapnhold;
1455 if( state == GestureDone )
1457 #ifdef __DETAIL_DEBUG__
1458 ErrorF("[GroupTapNHold][Timer][state=%d] Interval between Tap and Hold is too long !\n");
1459 #endif//__DETAIL_DEBUG__
1460 goto cleanup_tapnhold;
1463 #ifdef __DETAIL_DEBUG__
1467 ErrorF("[GroupTapNHold][Timer] TapNHold Begin !\n");
1471 ErrorF("[GroupTapNHold][Timer] TapNHold Update !\n");
1474 #endif//__DETAIL_DEBUG__
1476 if( GestureHasFingerEventMask(GestureNotifyTapNHold, prev_num_pressed) )
1478 GestureHandleGesture_TapNHold(prev_num_pressed, base_cx, base_cy, interval, holdtime, state);
1479 tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1483 #ifdef __DETAIL_DEBUG__
1484 ErrorF("[GroupTapNHold][Timer] %d finger TapNHold event was not grabbed/selected !\n", prev_num_pressed);
1485 #endif//__DETAIL_DEBUG__
1486 goto cleanup_tapnhold;
1489 if( state <= GestureBegin )
1496 case ET_ButtonPress:
1497 g_pGesture->fingers[idx].flags |= PressFlagTapNHold;
1499 if( g_pGesture->num_pressed < 2 )
1502 //if( !prev_num_pressed && (!base_area_size || g_pGesture->num_pressed > num_pressed) )
1503 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
1506 if( state == GestureUpdate )
1508 #ifdef __DETAIL_DEBUG__
1509 ErrorF("[GroupTapNHold][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1510 #endif//__DETAIL_DEBUG__
1511 goto cleanup_tapnhold;
1514 if( state == GestureDone )
1515 state = GestureBegin;
1517 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1518 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1519 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1520 base_time = GetTimeInMillis();
1521 base_box_ext.x1 = base_cx-TAPNHOLD_MOVE_THRESHOLD;
1522 base_box_ext.y1 = base_cy-TAPNHOLD_MOVE_THRESHOLD;
1523 base_box_ext.x2 = base_cx+TAPNHOLD_MOVE_THRESHOLD;
1524 base_box_ext.y2 = base_cy+TAPNHOLD_MOVE_THRESHOLD;
1525 if( state == GestureEnd )
1526 tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_TAP_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1529 TimerCancel(tapnhold_event_timer);
1530 tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1532 #ifdef __DETAIL_DEBUG__
1533 ErrorF("[GroupTapNHold][P] Create Timer !(state=%d)\n", state);
1534 #endif//__DETAIL_DEBUG__
1537 num_pressed = g_pGesture->num_pressed;
1539 #ifdef __DETAIL_DEBUG__
1540 ErrorF("[GroupTapNHold][P][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d, base_time=%d\n", num_pressed, base_area_size, base_cx, base_cy, base_time);
1541 #endif//__DETAIL_DEBUG__
1545 if( !(g_pGesture->fingers[idx].flags & PressFlagTapNHold ) )
1548 if( num_pressed < 2 )
1551 if( num_pressed != g_pGesture->num_pressed )
1553 if( state != GestureEnd )
1555 #ifdef __DETAIL_DEBUG__
1556 ErrorF("[GroupTapNHold][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1557 #endif//__DETAIL_DEBUG__
1558 goto cleanup_tapnhold;
1560 #ifdef __DETAIL_DEBUG__
1561 ErrorF("[GroupTapNHold][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1562 #endif//__DETAIL_DEBUG__
1563 //goto cleanup_tapnhold;
1566 mbits |= (1 << idx);
1567 if( mbits == (pow(2, num_pressed)-1) )
1569 area_size = AREA_SIZE(&g_pGesture->area.extents);
1570 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1571 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1572 #ifdef __DETAIL_DEBUG__
1573 ErrorF("[GroupTapNHold][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));
1574 ErrorF("[GroupTapNHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1575 ErrorF("[GroupTapNHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1576 #endif//__DETAIL_DEBUG__
1578 if( ABS(base_area_size-area_size) >= TAPNHOLD_AREA_THRESHOLD )
1580 #ifdef __DETAIL_DEBUG__
1581 ErrorF("[GroupTapNHold][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));
1582 #endif//__DETAIL_DEBUG__
1583 goto cleanup_tapnhold;
1586 if( !INBOX(&base_box_ext, cx, cy) )
1588 #ifdef __DETAIL_DEBUG__
1589 ErrorF("[GroupTapNHold][M] current center coordinates is not in base coordinates box !\n");
1590 #endif//__DETAIL_DEBUG__
1591 goto cleanup_tapnhold;
1596 case ET_ButtonRelease:
1597 if( state != GestureEnd && num_pressed >= 2)
1599 #ifdef __DETAIL_DEBUG__
1600 ErrorF("[GroupTapNHold][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1601 #endif//__DETAIL_DEBUG__
1602 goto cleanup_tapnhold;
1605 if( g_pGesture->num_pressed )
1610 prev_num_pressed = num_pressed;
1615 #ifdef __DETAIL_DEBUG__
1616 ErrorF("[GroupTapNHold][R] tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, num_pressed, prev_num_pressed);
1617 #endif//__DETAIL_DEBUG__
1619 if( num_pressed != prev_num_pressed || !GestureHasFingerEventMask(GestureNotifyTapNHold, num_pressed) )
1621 #ifdef __DETAIL_DEBUG__
1622 ErrorF("[GroupTapNHold][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
1623 num_pressed, prev_num_pressed, num_pressed);
1624 #endif//__DETAIL_DEBUG__
1625 goto cleanup_tapnhold;
1628 if( tap_repeat > 1 )
1630 #ifdef __DETAIL_DEBUG__
1631 ErrorF("[GroupTapNHold][R] Tap events(tap_repeat=%d) were put twice or more !(ignored)\n", tap_repeat);
1632 #endif//__DETAIL_DEBUG__
1633 goto cleanup_tapnhold;
1636 prev_num_pressed = num_pressed;
1638 state = GestureDone;
1640 TimerCancel(tapnhold_event_timer);
1641 tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_INTV_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1643 #ifdef __DETAIL_DEBUG__
1644 ErrorF("[GroupTapNHold][R][Last] state=%d, tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", state, tap_repeat, num_pressed, prev_num_pressed);
1645 #endif//__DETAIL_DEBUG__
1653 if( state == GestureUpdate )
1656 if( GestureHasFingerEventMask(GestureNotifyTapNHold, prev_num_pressed) )
1658 GestureHandleGesture_TapNHold(prev_num_pressed, base_cx, base_cy, interval, holdtime, state);
1663 g_pGesture->recognized_gesture &= ~TapNHoldFilterMask;
1666 g_pGesture->filter_mask |= TapNHoldFilterMask;
1667 if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
1669 #ifdef __DETAIL_DEBUG__
1670 ErrorF("[GroupTapNHold][cleanup] GestureFlushOrDrop() !\n");
1671 #endif//__DETAIL_DEBUG__
1673 if( ERROR_INVALPTR == GestureFlushOrDrop() )
1675 GestureControl(g_pGesture->this_device, DEVICE_OFF);
1679 TimerCancel(tapnhold_event_timer);
1682 prev_num_pressed = 0;
1690 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1692 static int num_pressed = 0;
1693 static int base_area_size = 0;
1694 static Time base_time = 0;
1698 static pixman_box16_t base_box_ext;
1700 static int state = GestureEnd;
1702 static OsTimerPtr hold_event_timer = NULL;
1703 static int event_type = GestureNotifyHold;
1707 if( state <= GestureBegin )
1710 #ifdef __DETAIL_DEBUG__
1714 ErrorF("[GroupHold] HOLD Begin !\n");
1718 ErrorF("[GroupHold] HOLD Update !\n");
1721 #endif//__DETAIL_DEBUG__
1723 if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) )
1725 GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1726 hold_event_timer = TimerSet(hold_event_timer, 0, HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1733 case ET_ButtonPress:
1734 g_pGesture->fingers[idx].flags |= PressFlagHold;
1736 if( g_pGesture->num_pressed < 2 )
1739 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
1741 if( state != GestureEnd )
1743 #ifdef __DETAIL_DEBUG__
1744 ErrorF("[GroupHold][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1745 #endif//__DETAIL_DEBUG__
1749 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1750 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1751 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1752 base_time = GetTimeInMillis();
1753 base_box_ext.x1 = base_cx-HOLD_MOVE_THRESHOLD;
1754 base_box_ext.y1 = base_cy-HOLD_MOVE_THRESHOLD;
1755 base_box_ext.x2 = base_cx+HOLD_MOVE_THRESHOLD;
1756 base_box_ext.y2 = base_cy+HOLD_MOVE_THRESHOLD;
1757 event_type = GestureNotifyHold;
1758 hold_event_timer = TimerSet(hold_event_timer, 0, HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1760 num_pressed = g_pGesture->num_pressed;
1762 #ifdef __DETAIL_DEBUG__
1763 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);
1764 #endif//__DETAIL_DEBUG__
1768 if( !(g_pGesture->fingers[idx].flags & PressFlagHold ) )
1771 if( num_pressed < 2 )
1774 if( num_pressed != g_pGesture->num_pressed )
1776 if( state != GestureEnd )
1778 #ifdef __DETAIL_DEBUG__
1779 ErrorF("[GroupHold][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1780 #endif//__DETAIL_DEBUG__
1783 #ifdef __DETAIL_DEBUG__
1784 ErrorF("[GroupHold][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1785 #endif//__DETAIL_DEBUG__
1786 //goto cleanup_hold;
1789 area_size = AREA_SIZE(&g_pGesture->area.extents);
1790 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1791 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1792 #ifdef __DETAIL_DEBUG__
1793 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));
1794 ErrorF("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1795 ErrorF("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1796 #endif//__DETAIL_DEBUG__
1798 if( ABS(base_area_size-area_size) >= HOLD_AREA_THRESHOLD )
1800 #ifdef __DETAIL_DEBUG__
1801 ErrorF("[GroupHold][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));
1802 #endif//__DETAIL_DEBUG__
1806 if( !INBOX(&base_box_ext, cx, cy) )
1808 #ifdef __DETAIL_DEBUG__
1809 ErrorF("[GroupHold][M] current center coordinates is not in base coordinates box !\n");
1810 #endif//__DETAIL_DEBUG__
1815 case ET_ButtonRelease:
1816 if( state != GestureEnd && num_pressed >= 2)
1818 #ifdef __DETAIL_DEBUG__
1819 ErrorF("[GroupHold][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1820 #endif//__DETAIL_DEBUG__
1824 //ErrorF("[GroupHold][R] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1825 if( g_pGesture->num_pressed )
1836 if( state == GestureBegin || state == GestureUpdate )
1839 if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) )
1841 GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1846 g_pGesture->recognized_gesture &= ~HoldFilterMask;
1849 g_pGesture->filter_mask |= HoldFilterMask;
1853 base_cx = base_cy = 0;
1855 base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
1856 TimerCancel(hold_event_timer);
1861 GestureGetEventsWindow(void)
1866 //check grabbed event(s)
1867 if( !GestureHasGrabbedEvents(&g_pGesture->grabMask, &g_pGesture->GrabEvents) )
1868 g_pGesture->grabMask = 0;
1870 pWin = GestureWindowOnXY(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py);
1874 #ifdef __DETAIL_DEBUG__
1875 ErrorF("[X11][GestureGetEventsWindow] pWin->drawable.id=0x%x\n", pWin->drawable.id);
1876 #endif//__DETAIL_DEBUG__
1877 g_pGesture->gestureWin = pWin->drawable.id;
1881 #ifdef __DETAIL_DEBUG__
1882 ErrorF("[X11][GestureGetEventsWindow] GestureWindowOnXY returns NULL !\n");
1883 #endif//__DETAIL_DEBUG__
1887 //check selected event(s)
1888 if( !GestureHasSelectedEvents(pWin, &g_pGesture->eventMask) )
1889 g_pGesture->eventMask = 0;
1891 if( !g_pGesture->grabMask && !g_pGesture->eventMask )
1893 #ifdef __DETAIL_DEBUG__
1894 ErrorF("[X11][GestureGetEventsWindow] No events were grabbed/selected for window(0x%x) !\n", pWin->drawable.id);
1895 #endif//__DETAIL_DEBUG__
1899 #ifdef __DETAIL_DEBUG__
1900 ErrorF("[X11][GestureGetEventsWindow] g_pGesture->grabMask=0x%x, g_pGesture->eventMask=0x%x\n",
1901 g_pGesture->grabMask, g_pGesture->eventMask);
1902 #endif//__DETAIL_DEBUG__
1904 mask = (GESTURE_FILTER_MASK_ALL & ~(g_pGesture->grabMask | g_pGesture->eventMask));
1906 #ifdef __DETAIL_DEBUG__
1907 ErrorF("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x, mask=0x%x\n", g_pGesture->filter_mask, mask);
1908 #endif//__DETAIL_DEBUG__
1910 g_pGesture->filter_mask = mask;
1912 #ifdef __DETAIL_DEBUG__
1913 ErrorF("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x\n", g_pGesture->filter_mask);
1914 #endif//__DETAIL_DEBUG__
1920 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
1922 int event_type = *(int *)arg;
1924 switch( event_type )
1926 case GestureNotifyHold:
1927 #ifdef __DETAIL_DEBUG__
1928 ErrorF("[GestureEventTimerHandler] GestureNotifyHold (event_type = %d)\n", event_type);
1929 #endif//__DETAIL_DEBUG__
1930 GestureRecognize_GroupHold(event_type, NULL, NULL, 0, 1);
1933 case GestureNotifyPan:
1934 #ifdef __DETAIL_DEBUG__
1935 ErrorF("[GestureEventTimerHandler] GestureNotifyPan (event_type = %d)\n", event_type);
1936 #endif//__DETAIL_DEBUG__
1937 GestureRecognize_GroupPan(event_type, NULL, NULL, 0, 1);
1940 case GestureNotifyTap:
1941 #ifdef __DETAIL_DEBUG__
1942 ErrorF("[GestureEventTimerHandler] GestureNotifyTap (event_type = %d)\n", event_type);
1943 #endif//__DETAIL_DEBUG__
1944 GestureRecognize_GroupTap(event_type, NULL, NULL, 0, 1);
1947 case GestureNotifyTapNHold:
1948 #ifdef __DETAIL_DEBUG__
1949 ErrorF("[GestureEventTimerHandler] GestureNotifyTapNHold (event_type = %d)\n", event_type);
1950 #endif//__DETAIL_DEBUG__
1951 GestureRecognize_GroupTapNHold(event_type, NULL, NULL, 0, 1);
1954 case GestureNotifyPinchRotation:
1955 #ifdef __DETAIL_DEBUG__
1956 ErrorF("[GestureEventTimerHandler] GestureNotifyPinchRotation (event_type = %d)\n", event_type);
1957 #endif//__DETAIL_DEBUG__
1958 GestureRecognize_GroupPinchRotation(event_type, NULL, NULL, 0, 1);
1962 #ifdef __DETAIL_DEBUG__
1963 ErrorF("[GestureEventTimerHandler] unknown event_type (=%d)\n", event_type);
1964 #endif//__DETAIL_DEBUG__
1966 ErrorF("[GestureEventTimerHandler] timer=%x\n", (unsigned int)timer);
1973 GestureSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
1975 g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
1976 g_pGesture->recognized_gesture = 0;
1978 if( ERROR_INVALPTR == GestureFlushOrDrop() )
1980 GestureControl(g_pGesture->this_device, DEVICE_OFF);
1983 #ifdef __DETAIL_DEBUG__
1984 ErrorF("[X11][Single] expired !\n");
1985 #endif//__DETAIL_DEBUG__
1991 GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
1994 static OsTimerPtr single_finger_timer = NULL;
1997 if( PROPAGATE_EVENTS == g_pGesture->ehtype ||
1998 device->id < g_pGesture->first_fingerid )
2001 for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
2003 if( device->id == g_pGesture->mt_devices[i]->id )
2015 case ET_ButtonPress:
2017 g_pGesture->event_sum[0] = BTN_PRESSED;
2018 g_pGesture->fingers[idx].ptime = ev->any.time;
2019 g_pGesture->fingers[idx].px = ev->device_event.root_x;
2020 g_pGesture->fingers[idx].py = ev->device_event.root_y;
2022 g_pGesture->num_pressed++;
2023 if( g_pGesture->num_pressed == 1 )
2025 single_finger_timer = TimerSet(single_finger_timer, 0, 50, GestureSingleFingerTimerHandler, NULL);
2029 TimerCancel(single_finger_timer);
2032 if( g_pGesture->num_pressed > g_pGesture->num_mt_devices )
2033 g_pGesture->num_pressed = g_pGesture->num_mt_devices;
2035 if( !g_pGesture->pTempWin || g_pGesture->num_pressed != g_pGesture->inc_num_pressed )
2037 g_pGesture->pTempWin = GestureGetEventsWindow();
2039 if( NULL == g_pGesture->pTempWin )
2041 #ifdef __DETAIL_DEBUG__
2042 ErrorF("[X11][GestureRecognize][g_pGesture->num_pressed=%d] No grabbed events and no event masks !\n", g_pGesture->num_pressed);
2043 #endif//__DETAIL_DEBUG__
2044 g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
2049 g_pGesture->inc_num_pressed = g_pGesture->num_pressed;
2051 g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
2052 g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
2053 g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT;
2054 g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT;
2056 if( g_pGesture->inc_num_pressed == 1 )
2058 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2059 #ifdef __DETAIL_DEBUG__
2060 ErrorF("[P][g_pGesture->inc_num_pressed=1] AREA_SIZE(area.extents)=%d\n", AREA_SIZE(&g_pGesture->area.extents));
2061 #endif//__DETAIL_DEBUG__
2065 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2066 for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ )
2068 pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
2070 #ifdef __DETAIL_DEBUG__
2071 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));
2072 #endif//__DETAIL_DEBUG__
2077 if( !g_pGesture->fingers[idx].ptime )
2080 g_pGesture->fingers[idx].mx = ev->device_event.root_x;
2081 g_pGesture->fingers[idx].my = ev->device_event.root_y;
2083 if( idx == 0 && g_pGesture->event_sum[0] )
2085 g_pGesture->event_sum[0] += BTN_MOVING;
2086 #ifdef __DETAIL_DEBUG__
2087 ErrorF("[X11][GestureRecognize] moving !\n");
2088 #endif//__DETAIL_DEBUG__
2089 if( g_pGesture->event_sum[0] >= 7 )
2091 if( (g_pGesture->event_sum[0] >= 7) && (g_pGesture->inc_num_pressed < 2) )
2093 #ifdef __DETAIL_DEBUG__
2094 ErrorF("[X11][GestureRecognize] moving limit!\n");
2095 #endif//__DETAIL_DEBUG__
2096 g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
2102 g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
2103 g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
2104 g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT;
2105 g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT;
2107 if( g_pGesture->inc_num_pressed == 1 )
2109 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2110 #ifdef __DETAIL_DEBUG__
2111 ErrorF("[M][g_pGesture->inc_num_pressed=1] AREA_SIZE(area)=%d\n", AREA_SIZE(&g_pGesture->area.extents));
2112 #endif//__DETAIL_DEBUG__
2116 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2117 for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ )
2119 pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
2121 #ifdef __DETAIL_DEBUG__
2122 ErrorF("[M][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents));
2123 #endif//__DETAIL_DEBUG__
2127 case ET_ButtonRelease:
2128 g_pGesture->fingers[idx].rtime = ev->any.time;
2129 g_pGesture->fingers[idx].rx = ev->device_event.root_x;
2130 g_pGesture->fingers[idx].ry = ev->device_event.root_y;
2132 g_pGesture->num_pressed--;
2133 if( g_pGesture->num_pressed <= 0 )
2135 #ifdef __DETAIL_DEBUG__
2136 ErrorF("[X11][GestureRecognize] All fingers were released !\n");
2137 #endif//__DETAIL_DEBUG__
2138 if( g_pGesture->inc_num_pressed == 1 )
2144 if( g_pGesture->filter_mask != GESTURE_FILTER_MASK_ALL )
2146 if( !(g_pGesture->filter_mask & FlickFilterMask) )
2148 GestureRecognize_GroupFlick(type, ev, device, idx);
2150 if( !(g_pGesture->filter_mask & PanFilterMask) )
2152 GestureRecognize_GroupPan(type, ev, device, idx, 0);
2154 if( !(g_pGesture->filter_mask & PinchRotationFilterMask) )
2156 GestureRecognize_GroupPinchRotation(type, ev, device, idx, 0);
2158 if( !(g_pGesture->filter_mask & TapFilterMask) )
2160 GestureRecognize_GroupTap(type, ev, device, idx, 0);
2162 if( !(g_pGesture->filter_mask & TapNHoldFilterMask) )
2164 GestureRecognize_GroupTapNHold(type, ev, device, idx, 0);
2166 if( !(g_pGesture->filter_mask & HoldFilterMask) )
2168 GestureRecognize_GroupHold(type, ev, device, idx, 0);
2172 #ifdef __DETAIL_DEBUG__
2173 ErrorF("[X11][GestureRecognize][N] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask);
2174 ErrorF("[X11][GestureRecognize][N] g_pGesture->GESTURE_FILTER_MASK_ALL = 0x%x\n", GESTURE_FILTER_MASK_ALL);
2175 ErrorF("[X11][GestureRecognize][N] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture);
2176 #endif//__DETAIL_DEBUG__
2178 if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
2180 if( !g_pGesture->recognized_gesture )
2182 else if( !g_pGesture->num_pressed )
2186 if( g_pGesture->recognized_gesture )
2188 if( g_pGesture->ehtype == KEEP_EVENTS )
2189 GestureEventsDrop();
2190 g_pGesture->ehtype = IGNORE_EVENTS;
2197 #ifdef __DETAIL_DEBUG__
2198 ErrorF("[GestureRecognize] GestureFlushOrDrop() !\n");
2199 #endif//__DETAIL_DEBUG__
2200 if( ERROR_INVALPTR == GestureFlushOrDrop() )
2202 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2207 ErrorStatus GestureFlushOrDrop(void)
2211 if( g_pGesture->recognized_gesture )
2213 GestureEventsDrop();
2217 g_pGesture->ehtype = PROPAGATE_EVENTS;
2219 err = GestureEventsFlush();
2220 if( ERROR_NONE != err )
2223 #ifdef __DETAIL_DEBUG__
2224 ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask);
2225 ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->GESTURE_FILTER_MASK_ALL = 0x%x\n", GESTURE_FILTER_MASK_ALL);
2226 ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture);
2227 #endif//__DETAIL_DEBUG__
2230 err = GestureRegionsReinit();
2231 if( ERROR_NONE != err )
2234 g_pGesture->pTempWin = NULL;
2235 g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0;
2236 g_pGesture->event_sum[0] = 0;
2242 GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2246 #ifdef __DEBUG_EVENT_HANDLER__
2247 ErrorF("\n[X11][GestureHandleMTSyncEvent] (%d:%d) time:%d cur:%d\n",
2248 ev->any_event.deviceid, ev->any_event.sync, (int)ev->any.time, (int)GetTimeInMillis());
2249 #endif//__DEBUG_EVENT_HANDLER__
2251 if( MTOUCH_FRAME_SYNC_BEGIN == ev->any_event.sync )
2253 g_pGesture->ehtype = KEEP_EVENTS;
2254 g_pGesture->filter_mask = 0;
2255 g_pGesture->recognized_gesture = 0;
2256 g_pGesture->num_pressed = 0;
2258 for( i=0 ; i < g_pGesture->num_mt_devices ; i++ )
2259 g_pGesture->fingers[i].ptime = 0;
2261 else if( MTOUCH_FRAME_SYNC_END == ev->any_event.sync )
2263 g_pGesture->ehtype = PROPAGATE_EVENTS;
2268 GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2270 #ifdef __DEBUG_EVENT_HANDLER__
2271 ErrorF("[X11][GestureHandleButtonPEvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
2272 #endif//__DEBUG_EVENT_HANDLER__
2274 switch( g_pGesture->ehtype )
2277 if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device) )
2279 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2283 if( g_pGesture->num_mt_devices )
2284 GestureRecognize(ET_ButtonPress, ev, device);
2286 device->public.processInputProc(ev, device);
2289 case PROPAGATE_EVENTS:
2290 device->public.processInputProc(ev, device);
2294 GestureRecognize(ET_ButtonPress, ev, device);
2303 GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2305 #ifdef __DEBUG_EVENT_HANDLER__
2306 ErrorF("[X11][GestureHandleMotionEvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
2307 #endif//__DEBUG_EVENT_HANDLER__
2309 switch( g_pGesture->ehtype )
2312 if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device) )
2314 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2318 if( g_pGesture->num_mt_devices )
2319 GestureRecognize(ET_Motion, ev, device);
2321 device->public.processInputProc(ev, device);
2324 case PROPAGATE_EVENTS:
2325 device->public.processInputProc(ev, device);
2329 GestureRecognize(ET_Motion, ev, device);
2339 GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2341 #ifdef __DEBUG_EVENT_HANDLER__
2342 ErrorF("[X11][GestureHandleButtonREvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
2343 #endif//__DEBUG_EVENT_HANDLER__
2345 switch( g_pGesture->ehtype )
2348 if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device) )
2350 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2354 if( g_pGesture->num_mt_devices )
2355 GestureRecognize(ET_ButtonRelease, ev, device);
2357 device->public.processInputProc(ev, device);
2360 case PROPAGATE_EVENTS:
2361 device->public.processInputProc(ev, device);
2365 GestureRecognize(ET_ButtonRelease, ev, device);
2374 GestureEnableEventHandler(InputInfoPtr pInfo)
2377 GestureDevicePtr pGesture = pInfo->private;
2379 res = GestureInstallResourceStateHooks();
2383 ErrorF("[X11][GestureEnableEventHandler] Failed on GestureInstallResourceStateHooks() !\n");
2384 return ERROR_ABNORMAL;
2387 res = GestureSetMaxNumberOfFingers((int)MAX_MT_DEVICES);
2391 ErrorF("[X11][GestureEnableEventHandler] Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)MAX_MT_DEVICES);
2395 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 5000, GestureTimerHandler, pInfo);
2397 if( !pGesture->device_setting_timer )
2399 ErrorF("[X11][GestureEnableEventHandler] Failed to allocate memory for timer !\n");
2406 GestureUninstallResourceStateHooks();
2407 GestureUnsetMaxNumberOfFingers();
2409 return ERROR_ABNORMAL;
2413 GestureDisableEventHandler(void)
2415 ErrorStatus err = ERROR_NONE;
2417 mieqSetHandler(ET_ButtonPress, NULL);
2418 mieqSetHandler(ET_ButtonRelease, NULL);
2419 mieqSetHandler(ET_Motion, NULL);
2420 mieqSetHandler(ET_MTSync, NULL);
2422 err = GestureFiniEQ();
2424 if( ERROR_INVALPTR == err )
2426 ErrorF("[X11][GestureDisableEventHandler] EQ is invalid or was freed already !\n");
2429 GestureUninstallResourceStateHooks();
2435 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2437 InputInfoPtr pInfo = (InputInfoPtr)arg;
2438 GestureDevicePtr pGesture = pInfo->private;
2442 for( dev = inputInfo.pointer ; dev; dev = dev->next )
2444 if(IsMaster(dev) && IsPointerDevice(dev))
2446 pGesture->master_pointer = dev;
2447 ErrorF("[X11][GestureTimerHandler][id:%d] Master Pointer=%s\n", dev->id, pGesture->master_pointer->name);
2451 if(IsXTestDevice(dev, NULL) && IsPointerDevice(dev))
2453 pGesture->xtest_pointer = dev;
2454 ErrorF("[X11][GestureTimerHandler][id:%d] XTest Pointer=%s\n", dev->id, pGesture->xtest_pointer->name);
2458 if(IsPointerDevice(dev))
2460 if( idx >= MAX_MT_DEVICES )
2462 ErrorF("[X11][GestureTimerHandler] Number of mt device is over MAX_MT_DEVICES(%d) !\n",
2466 pGesture->mt_devices[idx] = dev;
2467 ErrorF("[X11][GestureTimerHandler][id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name);
2472 if( !pGesture->master_pointer || !pGesture->xtest_pointer )
2474 ErrorF("[X11][GestureTimerHandler] Failed to get info of master pointer or XTest pointer !\n");
2475 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
2476 pGesture->num_mt_devices = 0;
2481 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
2482 pGesture->num_mt_devices = idx;
2484 if( !pGesture->num_mt_devices )
2486 ErrorF("[X11][GestureTimerHandler] Failed to mt device information !\n");
2487 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
2488 pGesture->num_mt_devices = 0;
2489 pGesture->first_fingerid = -1;
2493 pGesture->first_fingerid = pGesture->mt_devices[0]->id;
2494 memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices);
2495 pGesture->pRootWin = RootWindow(pGesture->master_pointer);
2496 g_pGesture->grabMask = g_pGesture->eventMask = 0;
2497 g_pGesture->pTempWin = NULL;
2498 g_pGesture->inc_num_pressed = 0;
2500 if( ERROR_NONE != GestureRegionsInit() || ERROR_NONE != GestureInitEQ() )
2505 mieqSetHandler(ET_ButtonPress, GestureHandleButtonPressEvent);
2506 mieqSetHandler(ET_ButtonRelease, GestureHandleButtonReleaseEvent);
2507 mieqSetHandler(ET_Motion, GestureHandleMotionEvent);
2509 if( pGesture->is_active )
2510 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
2516 GestureUninstallResourceStateHooks();
2517 GestureUnsetMaxNumberOfFingers();
2523 IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
2529 return (dev->xtest_master_id == master->id);
2531 return (dev->xtest_master_id != 0);
2535 GestureSetDisable(InputInfoPtr pInfo, int enable)
2539 g_pGesture->ehtype = PROPAGATE_EVENTS;
2540 mieqSetHandler(ET_MTSync, NULL);
2541 g_pGesture->is_active = 0;
2542 ErrorF("[X11][GestureSetDisable] Disabled !\n");
2546 g_pGesture->ehtype = KEEP_EVENTS;
2547 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
2548 g_pGesture->is_active = 1;
2549 ErrorF("[X11][GestureSetDisable] Enabled !\n");
2554 GestureRegionsInit(void)
2559 return ERROR_INVALPTR;
2561 pixman_region_init(&g_pGesture->area);
2563 for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
2565 pixman_region_init_rect (&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
2572 GestureRegionsReinit(void)
2576 ErrorF("[X11][GestureRegionsReinit] Invalid pointer access !\n");
2577 return ERROR_INVALPTR;
2580 pixman_region_init(&g_pGesture->area);
2591 tmpEQ = (IEventRec *)calloc(GESTURE_EQ_SIZE, sizeof(IEventRec));
2595 ErrorF("[X11][GestureInitEQ] Failed to allocate memory for EQ !\n");
2596 return ERROR_ALLOCFAIL;
2599 for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
2601 tmpEQ[i].event = (InternalEvent *)malloc(sizeof(InternalEvent));
2602 if( !tmpEQ[i].event )
2604 ErrorF("[X11][GestureInitEQ] Failed to allocation memory for each event buffer in EQ !\n");
2606 while(i >= 0 && tmpEQ[i].event)
2608 free(tmpEQ[i].event);
2609 tmpEQ[i].event = NULL;
2613 return ERROR_ALLOCFAIL;
2617 g_pGesture->EQ = tmpEQ;
2618 g_pGesture->headEQ = g_pGesture->tailEQ = 0;
2628 if( !g_pGesture || !g_pGesture->EQ )
2629 return ERROR_INVALPTR;
2631 for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
2633 if( g_pGesture->EQ[i].event )
2635 free(g_pGesture->EQ[i].event);
2636 g_pGesture->EQ[i].event = NULL;
2640 free(g_pGesture->EQ);
2641 g_pGesture->EQ = NULL;
2647 GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2651 if( !g_pGesture || !g_pGesture->EQ )
2653 ErrorF("[X11][GestureEnqueueEvent] Invalid pointer access !\n");
2654 return ERROR_INVALPTR;
2657 tail = g_pGesture->tailEQ;
2659 if( tail >= GESTURE_EQ_SIZE )
2661 ErrorF("[X11][GestureEnqueueEvent] Gesture EQ is full !\n");
2662 printk("[X11][GestureEnqueueEvent] Gesture EQ is full...Force Gesture Flush !\n");
2663 GestureEventsFlush();
2664 return ERROR_EQFULL;
2667 #ifdef __DETAIL_DEBUG__
2668 switch( ev->any.type )
2670 case ET_ButtonPress:
2671 ErrorF("[X11][GestureEnqueueEvent] ET_ButtonPress (id:%d)\n", device->id);
2674 case ET_ButtonRelease:
2675 ErrorF("[X11][GestureEnqueueEvent] ET_ButtonRelease (id:%d)\n", device->id);
2679 ErrorF("[X11][GestureEnqueueEvent] ET_Motion (id:%d)\n", device->id);
2682 #endif//__DETAIL_DEBUG__
2684 g_pGesture->EQ[tail].device = device;
2685 g_pGesture->EQ[tail].screen_num = screen_num;
2686 memcpy(g_pGesture->EQ[tail].event, ev, sizeof(InternalEvent));//need to be optimized
2687 g_pGesture->tailEQ++;
2693 GestureEventsFlush(void)
2696 DeviceIntPtr device;
2698 if( !g_pGesture->EQ )
2700 ErrorF("[X11][GestureEventsFlush] Invalid pointer access !\n");
2701 return ERROR_INVALPTR;
2704 #ifdef __DETAIL_DEBUG__
2705 ErrorF("[X11][GestureEventsFlush]\n");
2706 #endif//__DETAIL_DEBUG__
2708 for( i = g_pGesture->headEQ ; i < g_pGesture->tailEQ ; i++)
2710 device = g_pGesture->EQ[i].device;
2711 device->public.processInputProc(g_pGesture->EQ[i].event, device);
2714 for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
2715 g_pGesture->event_sum[i] = 0;
2717 g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
2723 GestureEventsDrop(void)
2725 g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
2728 #ifdef HAVE_PROPERTIES
2730 GestureInitProperty(DeviceIntPtr dev)
2734 prop_gesture_recognizer_onoff = MakeAtom(GESTURE_RECOGNIZER_ONOFF, strlen(GESTURE_RECOGNIZER_ONOFF), TRUE);
2735 rc = XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
2740 XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE);
2744 GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
2747 InputInfoPtr pInfo = dev->public.devicePrivate;
2749 if( prop_gesture_recognizer_onoff == atom )
2752 if( val->format != 32 || val->type != XA_INTEGER || val->size != 1 )
2757 data = *((int *)val->data);
2758 GestureSetDisable(pInfo, data);
2764 #endif//HAVE_PROPERTIES
2767 GestureInit(DeviceIntPtr device)
2770 pInfo = device->public.devicePrivate;
2772 #ifdef HAVE_PROPERTIES
2773 GestureInitProperty(device);
2774 XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL);
2781 GestureFini(DeviceIntPtr device)
2783 XIRegisterPropertyHandler(device, NULL, NULL, NULL);
2787 GesturePlug(pointer module, pointer options, int *errmaj, int *errmin)
2789 xf86AddInputDriver(&GESTURE, module, 0);
2794 GestureUnplug(pointer p)
2799 GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
2802 GestureDevicePtr pGesture;
2804 pGesture = calloc(1, sizeof(GestureDeviceRec));
2807 pInfo->private = NULL;
2808 //xf86DeleteInput(pInfo, 0);
2812 g_pGesture = pGesture;
2813 pInfo->private = pGesture;
2815 pInfo->read_input = GestureReadInput; /* new data avl */
2816 pInfo->switch_mode = NULL; /* toggle absolute/relative mode */
2817 pInfo->device_control = GestureControl; /* enable/disable dev */
2818 /* process driver specific options */
2819 pGesture->device = xf86SetStrOption(pInfo->options, "Device", "/dev/null");
2820 pGesture->is_active = xf86SetIntOption(pInfo->options, "Activate", 0);
2821 pGesture->gestureWin = None;
2823 xf86Msg(X_INFO, "%s: Using device %s.\n", pInfo->name, pGesture->device);
2825 /* process generic options */
2826 xf86CollectInputOptions(pInfo, NULL);
2827 xf86ProcessCommonOptions(pInfo, pInfo->options);
2840 GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
2842 GestureDevicePtr pGesture = pInfo->private;
2844 g_pGesture = pGesture = NULL;
2845 pInfo->private = NULL;
2847 xf86DeleteInput(pInfo, 0);
2851 GestureControl(DeviceIntPtr device, int what)
2853 InputInfoPtr pInfo = device->public.devicePrivate;
2854 GestureDevicePtr pGesture = pInfo->private;
2859 GestureInit(device);
2862 /* Switch device on. Establish socket, start event delivery. */
2864 xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
2866 if (device->public.on)
2869 device->public.on = TRUE;
2870 pGesture->this_device = device;
2871 pGesture->num_mt_devices = 0;
2872 if( ERROR_ABNORMAL == GestureEnableEventHandler(pInfo) )
2878 GestureDisableEventHandler();
2879 GestureFini(device);
2880 pGesture->this_device = NULL;
2881 xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
2883 if (!device->public.on)
2887 device->public.on = FALSE;
2891 /* free what we have to free */
2898 GestureReadInput(InputInfoPtr pInfo)