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 PointInBorderSize(WindowPtr pWin, int x, int y)
177 if( pixman_region_contains_point (&pWin->borderSize, x, y, &box) )
184 GestureWindowOnXY(int x, int y)
189 DeviceIntPtr pDev = g_pGesture->master_pointer;
191 pSprite = pDev->spriteInfo->sprite;
192 pSprite->spriteTraceGood = 1; /* root window still there */
193 pWin = RootWindow(pDev)->firstChild;
197 if ((pWin->mapped) &&
198 (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
199 (x < pWin->drawable.x + (int)pWin->drawable.width +
200 wBorderWidth(pWin)) &&
201 (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
202 (y < pWin->drawable.y + (int)pWin->drawable.height +
204 /* When a window is shaped, a further check
205 * is made to see if the point is inside
208 && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
209 && (!wInputShape(pWin) ||
210 RegionContainsPoint(wInputShape(pWin),
211 x - pWin->drawable.x,
212 y - pWin->drawable.y, &box))
214 /* In rootless mode windows may be offscreen, even when
215 * they're in X's stack. (E.g. if the native window system
216 * implements some form of virtual desktop system).
218 && !pWin->rootlessUnhittable
222 if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
224 pSprite->spriteTraceSize += 10;
225 pSprite->spriteTrace = realloc(pSprite->spriteTrace,
226 pSprite->spriteTraceSize*sizeof(WindowPtr));
228 pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
229 pWin = pWin->firstChild;
232 pWin = pWin->nextSib;
234 return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
238 GestureHasFingerEventMask(int eventType, int num_finger)
241 Mask eventmask = (1L << eventType);
243 if( (g_pGesture->grabMask & eventmask) &&
244 (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[num_finger].window != None) )
246 #ifdef __DETAIL_DEBUG__
247 ErrorF("[X11][GestureHasFingerEventMask] TRUE !! Has grabMask\n");
248 #endif//__DETAIL_DEBUG__
252 if( g_pGesture->eventMask & eventmask )
254 #ifdef __DETAIL_DEBUG__
255 ErrorF("[X11][GestureHasFingerEventMask] TRUE !! Has eventMask\n");
256 #endif//__DETAIL_DEBUG__
260 #ifdef __DETAIL_DEBUG__
261 ErrorF("[X11][GestureHasFingerEventMask] FALSE !! eventType=%d, num_finger=%d\n", eventType, num_finger);
262 #endif//__DETAIL_DEBUG__
268 get_angle(int x1, int y1, int x2, int y2)
274 if (((int) xx) && ((int) yy))
281 return (RAD_360DEG - a);
292 return (RAD_180DEG + a);
296 return (RAD_180DEG - a);
302 { /* Horizontal line */
325 GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction)
328 WindowPtr target_pWin;
329 xGestureNotifyFlickEvent fev;
331 #ifdef __DETAIL_DEBUG__
332 ErrorF("[X11][GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n",
333 num_of_fingers, distance, duration, direction);
334 #endif//__DETAIL_DEBUG__
336 g_pGesture->recognized_gesture |= FlickFilterMask;
337 memset(&fev, 0, sizeof(xGestureNotifyFlickEvent));
338 fev.type = GestureNotifyFlick;
339 fev.kind = GestureDone;
340 fev.num_finger = num_of_fingers;
341 fev.distance = distance;
342 fev.duration = duration;
343 fev.direction = direction;
345 target_win = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].window;
346 target_pWin = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].pWin;
348 if( g_pGesture->grabMask && (target_win != None) )
350 fev.window = target_win;
354 fev.window = g_pGesture->gestureWin;
357 #ifdef __DETAIL_DEBUG__
358 ErrorF("[X11][GestureHandleGesture_Flick] fev.window=0x%x, g_pGesture->grabMask=0x%x\n", fev.window, g_pGesture->grabMask);
359 #endif//__DETAIL_DEBUG__
361 GestureSendEvent(target_pWin, GestureNotifyFlick, GestureFlickMask, (xGestureCommonEvent *)&fev);
365 GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy)
368 WindowPtr target_pWin;
369 xGestureNotifyTapEvent tev;
371 //skip non-tap events and single finger tap
372 if( !tap_repeat || num_finger <= 1 )
375 #ifdef __DETAIL_DEBUG__
376 ErrorF("[X11][GestureHandleGesture_Tap] num_finger=%d, tap_repeat=%d, cx=%d, cy=%d\n",
377 num_finger, tap_repeat, cx, cy);
378 #endif//__DETAIL_DEBUG__
380 g_pGesture->recognized_gesture |= TapFilterMask;
381 memset(&tev, 0, sizeof(xGestureNotifyTapEvent));
382 tev.type = GestureNotifyTap;
383 tev.kind = GestureDone;
384 tev.num_finger = num_finger;
385 tev.tap_repeat = tap_repeat;
390 target_win = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].window;
391 target_pWin = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].pWin;
393 if( g_pGesture->grabMask && (target_win != None) )
395 tev.window = target_win;
399 tev.window = g_pGesture->gestureWin;
402 #ifdef __DETAIL_DEBUG__
403 ErrorF("[X11][GestureHandleGesture_Tap] tev.window=0x%x, g_pGesture->grabMask=0x%x\n", tev.window, g_pGesture->grabMask);
404 #endif//__DETAIL_DEBUG__
406 GestureSendEvent(target_pWin, GestureNotifyTap, GestureTapMask, (xGestureCommonEvent *)&tev);
409 void GestureHandleGesture_PinchRotation(int num_of_fingers, double zoom, double angle, int distance, int cx, int cy, int kinds)
412 WindowPtr target_pWin;
413 xGestureNotifyPinchRotationEvent prev;
415 #ifdef __DETAIL_DEBUG__
416 ErrorF("[X11][GestureHandleGesture_PinchRotation] num_fingers=%d, zoom=%.2f, angle=%.2f(deg=%.2f), distance=%d, cx=%d, cy=%d\n",
417 num_of_fingers, zoom, angle, rad2degree(angle), distance, cx, cy);
418 #endif//__DETAIL_DEBUG__
420 g_pGesture->recognized_gesture |= PinchRotationFilterMask;
421 memset(&prev, 0, sizeof(xGestureNotifyPinchRotationEvent));
422 prev.type = GestureNotifyPinchRotation;
424 prev.num_finger = num_of_fingers;
425 prev.zoom = XDoubleToFixed(zoom);
426 prev.angle = XDoubleToFixed(angle);
427 prev.distance = distance;
431 target_win = g_pGesture->GrabEvents[GestureNotifyPinchRotation].pGestureGrabWinInfo[num_of_fingers].window;
432 target_pWin = g_pGesture->GrabEvents[GestureNotifyPinchRotation].pGestureGrabWinInfo[num_of_fingers].pWin;
434 if( g_pGesture->grabMask && (target_win != None) )
436 prev.window = target_win;
440 prev.window = g_pGesture->gestureWin;
443 #ifdef __DETAIL_DEBUG__
444 ErrorF("[X11][GestureHandleGesture_PinchRotation] prev.window=0x%x, g_pGesture->grabMask=0x%x\n", (unsigned int)prev.window, (unsigned int)g_pGesture->grabMask);
445 #endif//__DETAIL_DEBUG__
447 GestureSendEvent(target_pWin, GestureNotifyPinchRotation, GesturePinchRotationMask, (xGestureCommonEvent *)&prev);
450 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds)
453 WindowPtr target_pWin;
454 xGestureNotifyHoldEvent hev;
456 #ifdef __DETAIL_DEBUG__
457 ErrorF("[X11][GestureHandleGesture_Hold] num_fingers=%d, cx=%d, cy=%d, holdtime=%d, kinds=%d\n",
458 num_fingers, cx, cy, holdtime, kinds);
459 #endif//__DETAIL_DEBUG__
461 g_pGesture->recognized_gesture |= HoldFilterMask;
462 memset(&hev, 0, sizeof(xGestureNotifyHoldEvent));
463 hev.type = GestureNotifyHold;
465 hev.num_finger = num_fingers;
466 hev.holdtime = holdtime;
470 target_win = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].window;
471 target_pWin = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].pWin;
473 if( g_pGesture->grabMask && (target_win != None) )
475 hev.window = target_win;
479 hev.window = g_pGesture->gestureWin;
482 #ifdef __DETAIL_DEBUG__
483 ErrorF("[X11][GestureHandleGesture_Hold] hev.window=0x%x, g_pGesture->grabMask=0x%x\n", hev.window, g_pGesture->grabMask);
484 #endif//__DETAIL_DEBUG__
486 GestureSendEvent(target_pWin, GestureNotifyHold, GestureHoldMask, (xGestureCommonEvent *)&hev);
489 void GestureHandleGesture_TapNHold(int num_fingers, int cx, int cy, Time interval, Time holdtime, int kinds)
492 WindowPtr target_pWin;
493 xGestureNotifyTapNHoldEvent thev;
495 #ifdef __DETAIL_DEBUG__
496 ErrorF("[X11][GestureHandleGesture_TapNHold] num_fingers=%d, cx=%d, cy=%d, interval=%d, holdtime=%d, kinds=%d\n",
497 num_fingers, cx, cy, interval, holdtime, kinds);
498 #endif//__DETAIL_DEBUG__
500 g_pGesture->recognized_gesture |= TapNHoldFilterMask;
501 memset(&thev, 0, sizeof(xGestureNotifyTapNHoldEvent));
502 thev.type = GestureNotifyTapNHold;
504 thev.num_finger = num_fingers;
505 thev.holdtime = holdtime;
508 thev.interval = interval;
510 target_win = g_pGesture->GrabEvents[GestureNotifyTapNHold].pGestureGrabWinInfo[num_fingers].window;
511 target_pWin = g_pGesture->GrabEvents[GestureNotifyTapNHold].pGestureGrabWinInfo[num_fingers].pWin;
513 if( g_pGesture->grabMask && (target_win != None) )
515 thev.window = target_win;
519 thev.window = g_pGesture->gestureWin;
522 #ifdef __DETAIL_DEBUG__
523 ErrorF("[X11][GestureHandleGesture_TapNHold] thev.window=0x%x, g_pGesture->grabMask=0x%x\n", thev.window, g_pGesture->grabMask);
524 #endif//__DETAIL_DEBUG__
526 GestureSendEvent(target_pWin, GestureNotifyTapNHold, GestureTapNHoldMask, (xGestureCommonEvent *)&thev);
529 void GestureHandleGesture_Pan(int num_fingers, short int dx, short int dy, int direction, int distance, Time duration, int kinds)
532 WindowPtr target_pWin;
533 xGestureNotifyPanEvent pev;
535 #ifdef __DETAIL_DEBUG__
536 ErrorF("[X11][GestureHandleGesture_Pan] num_fingers=%d, dx=%d, dy=%d, direction=%d, distance=%d, duration=%d, kinds=%d\n",
537 num_fingers, dx, dy, direction, distance, duration, kinds);
538 #endif//__DETAIL_DEBUG__
540 g_pGesture->recognized_gesture |= PanFilterMask;
541 memset(&pev, 0, sizeof(xGestureNotifyPanEvent));
542 pev.type = GestureNotifyPan;
544 pev.num_finger = num_fingers;
545 pev.direction = direction;
546 pev.distance = distance;
547 pev.duration = duration;
551 target_win = g_pGesture->GrabEvents[GestureNotifyPan].pGestureGrabWinInfo[num_fingers].window;
552 target_pWin = g_pGesture->GrabEvents[GestureNotifyPan].pGestureGrabWinInfo[num_fingers].pWin;
554 if( g_pGesture->grabMask && (target_win != None) )
556 pev.window = target_win;
560 pev.window = g_pGesture->gestureWin;
563 #ifdef __DETAIL_DEBUG__
564 ErrorF("[X11][GestureHandleGesture_Pan] pev.window=0x%x, g_pGesture->grabMask=0x%x\n", pev.window, g_pGesture->grabMask);
565 #endif//__DETAIL_DEBUG__
567 GestureSendEvent(target_pWin, GestureNotifyPan, GesturePanMask, (xGestureCommonEvent *)&pev);
571 GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
575 static int num_pressed = 0;
576 static int state = GestureEnd;
577 static int event_type = GestureNotifyPinchRotation;
578 static OsTimerPtr pinchrotation_event_timer = NULL;
580 static pixman_region16_t base_area;
581 static pixman_region16_t cur_area;
583 static double base_distance = 0.0f;
584 static double base_angle = 0.0f;
586 static double prev_distance = 0.0f;
587 static double prev_angle = 0.0f;
589 static double cur_distance = 0.0f;
590 static double cur_angle = 0.0f;
592 double diff_distance = 0.0f;
593 double diff_angle = 0.0f;
595 static int has_event_mask = 0;
597 static Time base_time = 0;
602 if( state == GestureEnd )
604 current_time = GetTimeInMillis();
605 if( (current_time - base_time) >= PINCHROTATION_TIME_THRESHOLD )
607 #ifdef __DETAIL_DEBUG__
608 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);
609 #endif//__DETAIL_DEBUG__
610 goto cleanup_pinchrotation;
620 g_pGesture->fingers[idx].flags |= PressFlagPinchRotation;
622 if( g_pGesture->num_pressed < 2 )
625 if( g_pGesture->num_pressed < num_pressed && state != GestureEnd )
627 #ifdef __DETAIL_DEBUG__
628 ErrorF("[GroupPinchRotation][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
629 #endif//__DETAIL_DEBUG__
630 goto cleanup_pinchrotation;
633 if( base_distance == 0.0f && g_pGesture->num_pressed == 2 )
635 #ifdef __DETAIL_DEBUG__
636 ErrorF("[GroupPinchRotation][First Time !!!] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
637 #endif//__DETAIL_DEBUG__
639 base_time = GetTimeInMillis();
640 pixman_region_init(&base_area);
641 pixman_region_union(&base_area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[1]);
643 prev_distance = base_distance = AREA_DIAG_LEN(&base_area.extents);
645 #ifdef __DETAIL_DEBUG__
646 ErrorF("[GroupPinchRotation][P] x1=%d, x2=%d, y1=%d, y2=%d\n", g_pGesture->fingers[0].px, g_pGesture->fingers[1].px,
647 g_pGesture->fingers[0].py, g_pGesture->fingers[1].py);
648 #endif//__DETAIL_DEBUG__
650 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);
651 #ifdef __DETAIL_DEBUG__
652 ErrorF("[GroupPinchRotation][P] base_angle=%.2f(deg=%.2f)\n", base_angle, rad2degree(base_angle));
653 #endif//__DETAIL_DEBUG__
654 event_type = GestureNotifyPinchRotation;
655 pinchrotation_event_timer = TimerSet(pinchrotation_event_timer, 0, PINCHROTATION_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
657 num_pressed = g_pGesture->num_pressed;
659 #ifdef __DETAIL_DEBUG__
660 ErrorF("[GroupPinchRotation][P][num_pressed=%d] AREA_SIZE(base_area.extents)=%d\n", num_pressed, AREA_SIZE(&base_area.extents));
661 ErrorF("[GroupPinchRotation][P][num_pressed=%d] base_distance=%.2f, base_angle=%.2f(deg=%.2f)\n", num_pressed, base_distance, base_angle, rad2degree(base_angle));
662 #endif//__DETAIL_DEBUG__
666 if( !(g_pGesture->fingers[idx].flags & PressFlagPinchRotation) )
669 if( (num_pressed != g_pGesture->num_pressed) && (state != GestureEnd) )
671 #ifdef __DETAIL_DEBUG__
672 ErrorF("[GroupPinchRotation][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
673 #endif//__DETAIL_DEBUG__
674 goto cleanup_pinchrotation;
677 if( num_pressed < 2 )
680 if( g_pGesture->fingers[0].mx && g_pGesture->fingers[0].my && g_pGesture->fingers[1].mx && g_pGesture->fingers[1].my )
682 pixman_region_init(&cur_area);
683 pixman_region_union(&cur_area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[1]);
685 cur_distance = AREA_DIAG_LEN(&cur_area.extents);
687 #ifdef __DETAIL_DEBUG__
688 ErrorF("[GroupPinchRotation][M] x1=%d, x2=%d, y1=%d, y2=%d\n", g_pGesture->fingers[0].mx, g_pGesture->fingers[1].mx,
689 g_pGesture->fingers[0].my, g_pGesture->fingers[1].my);
690 #endif//__DETAIL_DEBUG__
692 cur_angle = get_angle(g_pGesture->fingers[0].mx, g_pGesture->fingers[0].my, g_pGesture->fingers[1].mx, g_pGesture->fingers[1].my);
693 #ifdef __DETAIL_DEBUG__
694 ErrorF("[GroupPinchRotation][M] cur_angle=%.2f(deg=%.2f)\n", cur_angle, rad2degree(cur_angle));
695 #endif//__DETAIL_DEBUG__
697 diff_distance = prev_distance - cur_distance;
698 diff_angle = prev_angle - cur_angle;
700 cx = AREA_CENTER_X(&cur_area.extents);
701 cy = AREA_CENTER_Y(&cur_area.extents);
703 #ifdef __DETAIL_DEBUG__
704 ErrorF("[GroupPinchRotation][M][state=%d] cx=%d, cy=%d\n", state, cx, cy);
705 #endif//__DETAIL_DEBUG__
707 #ifdef __DETAIL_DEBUG__
708 ErrorF("[GroupPinchRotation][M][num_pressed=%d] prev_distance=%.2f, cur_distance=%.2f, diff=%.2f\n", num_pressed, prev_distance, cur_distance, diff_distance);
709 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));
710 #endif//__DETAIL_DEBUG__
715 if( (ABS(diff_distance) >= PINCHROTATION_DIST_THRESHOLD) || (ABS(diff_angle) >= PINCHROTATION_ANGLE_THRESHOLD) )
717 #ifdef __DETAIL_DEBUG__
718 if( ABS(diff_distance) >= PINCHROTATION_DIST_THRESHOLD )
719 ErrorF("[GroupPinchRotation][M] zoom changed !\n");
721 if( ABS(diff_angle) >= PINCHROTATION_ANGLE_THRESHOLD )
722 ErrorF("[GroupPinchRotation][M] angle changed !\n");
723 #endif//__DETAIL_DEBUG__
725 TimerCancel(pinchrotation_event_timer);
726 state = GestureBegin;
727 goto gesture_begin_handle;
732 gesture_begin_handle:
733 #ifdef __DETAIL_DEBUG__
734 ErrorF("[GroupPinchRotation] PINCHROTATION Begin !cx=%d, cy=%d, state=%d\n", cx, cy, state);
735 #endif//__DETAIL_DEBUG__
736 if( GestureHasFingerEventMask(GestureNotifyPinchRotation, num_pressed) )
738 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);
739 prev_distance = cur_distance;
740 prev_angle = cur_angle;
741 state = GestureUpdate;
747 goto cleanup_pinchrotation;
752 //if( ABS(diff_distance) < PINCHROTATION_DIST_THRESHOLD && ABS(diff_angle) < PINCHROTATION_ANGLE_THRESHOLD )
755 #ifdef __DETAIL_DEBUG__
756 if( ABS(diff_distance) >= PINCHROTATION_DIST_THRESHOLD )
757 ErrorF("[GroupPinchRotation][M] zoom changed !\n");
759 if( ABS(diff_angle) >= PINCHROTATION_ANGLE_THRESHOLD )
760 ErrorF("[GroupPinchRotation][M] angle changed !\n");
761 #endif//__DETAIL_DEBUG__
763 #ifdef __DETAIL_DEBUG__
764 ErrorF("[GroupPinchRotation] PINCHROTATION Update ! cx=%d, cy=%d, state=%d\n", cx, cy, state);
765 #endif//__DETAIL_DEBUG__
766 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);
767 prev_distance = cur_distance;
768 prev_angle = cur_angle;
778 case ET_ButtonRelease:
779 if( state != GestureEnd && num_pressed >= 2)
781 #ifdef __DETAIL_DEBUG__
782 ErrorF("[GroupPinchRotation][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
783 #endif//__DETAIL_DEBUG__
784 goto cleanup_pinchrotation;
787 if( g_pGesture->num_pressed )
790 goto cleanup_pinchrotation;
796 cleanup_pinchrotation:
798 if( has_event_mask && (state == GestureBegin || state == GestureUpdate) )
801 #ifdef __DETAIL_DEBUG__
802 ErrorF("[GroupPinchRotation] PINCHROTATION End ! cx=%d, cy=%d, state=%d\n", cx, cy, state);
803 #endif//__DETAIL_DEBUG__
804 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);
808 g_pGesture->recognized_gesture &= ~PinchRotationFilterMask;
811 g_pGesture->filter_mask |= PinchRotationFilterMask;
813 if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
815 #if 1//def __DETAIL_DEBUG__
816 ErrorF("[GroupPinchRotation][cleanup] GestureFlushOrDrop() !\n");
817 #endif//__DETAIL_DEBUG__
819 if( ERROR_INVALPTR == GestureFlushOrDrop() )
821 GestureControl(g_pGesture->this_device, DEVICE_OFF);
825 prev_distance = base_distance = 0.0f;
826 prev_angle = base_angle = 0.0f;
827 has_event_mask = num_pressed = 0;
830 TimerCancel(pinchrotation_event_timer);
835 GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx)
837 static int num_pressed = 0;
838 static int mbits = 0;
839 static int base_area_size = 0;
840 static Time base_time = 0;
841 static int base_x, base_y;
845 int distance, direction;
852 g_pGesture->fingers[idx].flags |= PressFlagFlick;
854 if( g_pGesture->num_pressed < 2 )
857 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
859 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
860 base_x = g_pGesture->area.extents.x1;
861 base_y = g_pGesture->area.extents.y1;
862 base_time = GetTimeInMillis();
864 num_pressed = g_pGesture->num_pressed;
866 #ifdef __DETAIL_DEBUG__
867 ErrorF("[GroupFlick][P]][num_pressed=%d] AREA_SIZE(area.extents)=%d\n", num_pressed, base_area_size);
868 #endif//__DETAIL_DEBUG__
872 if( !(g_pGesture->fingers[idx].flags & PressFlagFlick ) )
875 #ifdef __DETAIL_DEBUG__
876 if( num_pressed > g_pGesture->num_pressed )
878 ErrorF("[GroupFlick][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
879 //goto cleanup_flick;
881 #endif//__DETAIL_DEBUG__
883 if( num_pressed < 2 )
887 if( mbits == (pow(2, num_pressed)-1) )
889 area_size = AREA_SIZE(&g_pGesture->area.extents);
890 #ifdef __DETAIL_DEBUG__
891 ErrorF("[M][num_pressed=%d] AREA_SIZE(area.extents)=%d\n", num_pressed, area_size);
892 #endif//__DETAIL_DEBUG__
893 if( ABS(base_area_size - area_size) >= FLICK_AREA_THRESHOLD )
895 #ifdef __DETAIL_DEBUG__
896 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);
897 #endif//__DETAIL_DEBUG__
901 current_time = GetTimeInMillis();
902 if( (current_time - base_time) >= FLICK_AREA_TIMEOUT )
904 #ifdef __DETAIL_DEBUG__
905 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);
906 #endif//__DETAIL_DEBUG__
913 case ET_ButtonRelease:
914 if( g_pGesture->num_pressed )
917 duration = GetTimeInMillis() - base_time;
918 distx = g_pGesture->area.extents.x1 - base_x;
919 disty = g_pGesture->area.extents.y1 - base_y;
921 #ifdef __DETAIL_DEBUG__
922 ErrorF("[GroupFlick] duration=%d, distx=%d, disty=%d\n", duration, distx, disty);
923 #endif//__DETAIL_DEBUG__
925 if( duration <= 0 || duration >= FLICK_AREA_TIMEOUT )
928 if( ABS(distx) >= FLICK_MOVE_THRESHOLD )
930 direction = (distx > 0) ? FLICK_EASTWARD : FLICK_WESTWARD;
931 distance = ABS(distx);
934 else if( ABS(disty) >= FLICK_MOVE_THRESHOLD )
936 direction = (disty > 0) ? FLICK_SOUTHWARD : FLICK_NORTHWARD;
937 distance = ABS(disty);
944 if( GestureHasFingerEventMask(GestureNotifyFlick, num_pressed) )
945 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
946 goto cleanup_flick_recognized;
954 g_pGesture->recognized_gesture &= ~FlickFilterMask;
956 cleanup_flick_recognized:
958 g_pGesture->filter_mask |= FlickFilterMask;
967 GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
969 static int num_pressed = 0;
970 static int mbits = 0;
971 static int base_area_size = 0;
972 static Time base_time = 0;
973 static pixman_box16_t base_box_ext;
981 static Time prev_time = 0;
982 Time current_time = 0;
986 static int time_checked = 0;
987 static int state = GestureEnd;
989 static OsTimerPtr pan_event_timer = NULL;
990 static int event_type = GestureNotifyPan;
996 current_time = GetTimeInMillis();
997 if( (current_time - base_time) >= PAN_TIME_THRESHOLD )
999 if( (!cx && !cy) || INBOX(&base_box_ext, cx, cy) )
1001 #ifdef __DETAIL_DEBUG__
1002 ErrorF("[GroupPan][Timer] You must move farther than move threshold(=%d) within time threshold(=%d) !\n", PAN_MOVE_THRESHOLD*2, PAN_TIME_THRESHOLD);
1003 #endif//__DETAIL_DEBUG__
1014 case ET_ButtonPress:
1015 g_pGesture->fingers[idx].flags |= PressFlagPan;
1017 if( g_pGesture->num_pressed < 2 )
1020 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
1022 if( state != GestureEnd )
1024 #ifdef __DETAIL_DEBUG__
1025 ErrorF("[GroupPan][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1026 #endif//__DETAIL_DEBUG__
1029 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1030 prev_cx = base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1031 prev_cy = base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1032 prev_time = base_time = GetTimeInMillis();
1033 base_box_ext.x1 = base_cx-PAN_MOVE_THRESHOLD;
1034 base_box_ext.y1 = base_cy-PAN_MOVE_THRESHOLD;
1035 base_box_ext.x2 = base_cx+PAN_MOVE_THRESHOLD;
1036 base_box_ext.y2 = base_cy+PAN_MOVE_THRESHOLD;
1037 event_type = GestureNotifyPan;
1038 pan_event_timer = TimerSet(pan_event_timer, 0, PAN_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1040 num_pressed = g_pGesture->num_pressed;
1042 #ifdef __DETAIL_DEBUG__
1043 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);
1044 #endif//__DETAIL_DEBUG__
1048 if( !(g_pGesture->fingers[idx].flags & PressFlagPan ) )
1051 if( num_pressed != g_pGesture->num_pressed )
1053 if( state != GestureEnd )
1055 #ifdef __DETAIL_DEBUG__
1056 ErrorF("[GroupPan][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1057 #endif//__DETAIL_DEBUG__
1062 if( num_pressed < 2 )
1065 mbits |= (1 << idx);
1066 if( mbits == (pow(2, num_pressed)-1) )
1068 area_size = AREA_SIZE(&g_pGesture->area.extents);
1069 #ifdef __DETAIL_DEBUG__
1070 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));
1071 #endif//__DETAIL_DEBUG__
1073 if( (state != GestureUpdate) && (ABS(base_area_size - area_size) >= PAN_AREA_THRESHOLD) )
1075 #ifdef __DETAIL_DEBUG__
1076 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);
1077 #endif//__DETAIL_DEBUG__
1081 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1082 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1084 #ifdef __DETAIL_DEBUG__
1085 ErrorF("[GroupPan][M] cx=%d, prev_cx=%d, diff=%d\n", cx, prev_cx, ABS(cx-prev_cx));
1086 ErrorF("[GroupPan][M] cy=%d, prev_cy=%d, diff=%d\n", cy, prev_cy, ABS(cy-prev_cy));
1087 #endif//__DETAIL_DEBUG__
1091 current_time = GetTimeInMillis();
1092 if( (current_time - base_time) >= PAN_TIME_THRESHOLD )
1094 if( INBOX(&base_box_ext, cx, cy) )
1096 #ifdef __DETAIL_DEBUG__
1097 ErrorF("[GroupPan][M] You must move farther than move threshold(=%d) within time threshold(=%d) !\n", PAN_MOVE_THRESHOLD*2, PAN_TIME_THRESHOLD);
1098 #endif//__DETAIL_DEBUG__
1107 if( state <= GestureBegin )
1109 base_box_ext.x1 = prev_cx-PAN_MOVE_THRESHOLD;
1110 base_box_ext.y1 = prev_cy-PAN_MOVE_THRESHOLD;
1111 base_box_ext.x2 = prev_cx+PAN_MOVE_THRESHOLD;
1112 base_box_ext.y2 = prev_cy+PAN_MOVE_THRESHOLD;
1114 if( !INBOX(&base_box_ext, cx, cy) )
1116 current_time = GetTimeInMillis();
1117 #ifdef __DETAIL_DEBUG__
1118 ErrorF("[GroupPan] PAN Begin !dx=%d, dy=%d, state=%d\n", prev_cx, prev_cy, state);
1119 #endif//__DETAIL_DEBUG__
1120 if( GestureHasFingerEventMask(GestureNotifyPan, num_pressed) )
1122 GestureHandleGesture_Pan(num_pressed, prev_cx, prev_cy, direction, distance, current_time-prev_time, GestureBegin);
1123 state = GestureUpdate;
1133 //if( ABS(dx) >= PAN_UPDATE_MOVE_THRESHOLD || ABS(dy) >= PAN_UPDATE_MOVE_THRESHOLD )
1135 #ifdef __DETAIL_DEBUG__
1136 ErrorF("[GroupPan] PAN Update !dx=%d, dy=%d, state=%d\n", dx, dy, state);
1137 #endif//__DETAIL_DEBUG__
1139 GestureHandleGesture_Pan(num_pressed, dx, dy, direction, distance, current_time-prev_time, GestureUpdate);
1144 prev_time = current_time;
1150 case ET_ButtonRelease:
1151 if( state != GestureEnd && num_pressed >= 2)
1153 #ifdef __DETAIL_DEBUG__
1154 ErrorF("[GroupPan][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1155 #endif//__DETAIL_DEBUG__
1159 if( g_pGesture->num_pressed )
1170 if( state == GestureBegin || state == GestureUpdate )
1173 if( GestureHasFingerEventMask(GestureNotifyPan, num_pressed) )
1175 GestureHandleGesture_Pan(num_pressed, (short int)(cx-prev_cx), (short int)(cy-prev_cy), direction, distance, GetTimeInMillis()-prev_time, GestureEnd);
1180 g_pGesture->recognized_gesture &= ~PanFilterMask;
1183 g_pGesture->filter_mask |= PanFilterMask;
1192 base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
1193 TimerCancel(pan_event_timer);
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, 500, GestureTimerHandler, pInfo);
2397 if( !pGesture->device_setting_timer )
2399 ErrorF("[X11][GestureEnableEventHandler] Failed to allocate memory for timer !\n");
2403 if( ERROR_NONE != GestureRegionsInit() || ERROR_NONE != GestureInitEQ() )
2408 mieqSetHandler(ET_ButtonPress, GestureHandleButtonPressEvent);
2409 mieqSetHandler(ET_ButtonRelease, GestureHandleButtonReleaseEvent);
2410 mieqSetHandler(ET_Motion, GestureHandleMotionEvent);
2411 if( pGesture->is_active )
2412 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
2417 GestureUninstallResourceStateHooks();
2418 GestureUnsetMaxNumberOfFingers();
2420 return ERROR_ABNORMAL;
2424 GestureDisableEventHandler(void)
2426 ErrorStatus err = ERROR_NONE;
2428 mieqSetHandler(ET_ButtonPress, NULL);
2429 mieqSetHandler(ET_ButtonRelease, NULL);
2430 mieqSetHandler(ET_Motion, NULL);
2431 mieqSetHandler(ET_MTSync, NULL);
2433 err = GestureFiniEQ();
2435 if( ERROR_INVALPTR == err )
2437 ErrorF("[X11][GestureDisableEventHandler] EQ is invalid or was freed already !\n");
2440 GestureUninstallResourceStateHooks();
2441 GestureUnsetMaxNumberOfFingers();
2447 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2449 InputInfoPtr pInfo = (InputInfoPtr)arg;
2450 GestureDevicePtr pGesture = pInfo->private;
2454 for( dev = inputInfo.pointer ; dev; dev = dev->next )
2456 if(IsMaster(dev) && IsPointerDevice(dev))
2458 pGesture->master_pointer = dev;
2459 ErrorF("[X11][GestureTimerHandler][id:%d] Master Pointer=%s\n", dev->id, pGesture->master_pointer->name);
2463 if(IsXTestDevice(dev, NULL) && IsPointerDevice(dev))
2465 pGesture->xtest_pointer = dev;
2466 ErrorF("[X11][GestureTimerHandler][id:%d] XTest Pointer=%s\n", dev->id, pGesture->xtest_pointer->name);
2470 if(IsPointerDevice(dev))
2472 if( idx >= MAX_MT_DEVICES )
2474 ErrorF("[X11][GestureTimerHandler] Number of mt device is over MAX_MT_DEVICES(%d) !\n",
2478 pGesture->mt_devices[idx] = dev;
2479 ErrorF("[X11][GestureTimerHandler][id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name);
2484 if( !pGesture->master_pointer || !pGesture->xtest_pointer )
2486 ErrorF("[X11][GestureTimerHandler] Failed to get info of master pointer or XTest pointer !\n");
2487 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
2488 pGesture->num_mt_devices = 0;
2493 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
2494 pGesture->first_fingerid = pGesture->mt_devices[0]->id;
2495 pGesture->num_mt_devices = idx;
2497 if( !pGesture->num_mt_devices )
2499 ErrorF("[X11][GestureTimerHandler] Failed to mt device information !\n");
2500 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
2501 pGesture->num_mt_devices = 0;
2506 memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices);
2507 pGesture->pRootWin = RootWindow(pGesture->master_pointer);
2508 g_pGesture->grabMask = g_pGesture->eventMask = 0;
2509 g_pGesture->pTempWin = NULL;
2510 g_pGesture->inc_num_pressed = 0;
2516 IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
2522 return (dev->xtest_master_id == master->id);
2524 return (dev->xtest_master_id != 0);
2528 GestureSetDisable(InputInfoPtr pInfo, int enable)
2532 g_pGesture->ehtype = PROPAGATE_EVENTS;
2533 mieqSetHandler(ET_MTSync, NULL);
2534 g_pGesture->is_active = 0;
2535 ErrorF("[X11][GestureSetDisable] Disabled !\n");
2539 g_pGesture->ehtype = KEEP_EVENTS;
2540 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
2541 g_pGesture->is_active = 1;
2542 ErrorF("[X11][GestureSetDisable] Enabled !\n");
2547 GestureRegionsInit(void)
2552 return ERROR_INVALPTR;
2554 pixman_region_init(&g_pGesture->area);
2556 for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
2558 pixman_region_init_rect (&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
2565 GestureRegionsReinit(void)
2569 ErrorF("[X11][GestureRegionsReinit] Invalid pointer access !\n");
2570 return ERROR_INVALPTR;
2573 pixman_region_init(&g_pGesture->area);
2584 tmpEQ = (IEventRec *)calloc(GESTURE_EQ_SIZE, sizeof(IEventRec));
2588 ErrorF("[X11][GestureInitEQ] Failed to allocate memory for EQ !\n");
2589 return ERROR_ALLOCFAIL;
2592 for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
2594 tmpEQ[i].event = (InternalEvent *)malloc(sizeof(InternalEvent));
2595 if( !tmpEQ[i].event )
2597 ErrorF("[X11][GestureInitEQ] Failed to allocation memory for each event buffer in EQ !\n");
2598 return ERROR_ALLOCFAIL;
2602 g_pGesture->EQ = tmpEQ;
2603 g_pGesture->headEQ = g_pGesture->tailEQ = 0;
2613 if( !g_pGesture || !g_pGesture->EQ )
2614 return ERROR_INVALPTR;
2616 for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
2618 if( g_pGesture->EQ[i].event )
2620 free(g_pGesture->EQ[i].event);
2621 g_pGesture->EQ[i].event = NULL;
2625 free(g_pGesture->EQ);
2626 g_pGesture->EQ = NULL;
2632 GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2636 if( !g_pGesture || !g_pGesture->EQ )
2638 ErrorF("[X11][GestureEnqueueEvent] Invalid pointer access !\n");
2639 return ERROR_INVALPTR;
2642 tail = g_pGesture->tailEQ;
2644 if( tail >= GESTURE_EQ_SIZE )
2646 ErrorF("[X11][GestureEnqueueEvent] Gesture EQ is full !\n");
2647 return ERROR_EQFULL;
2650 #ifdef __DETAIL_DEBUG__
2651 switch( ev->any.type )
2653 case ET_ButtonPress:
2654 ErrorF("[X11][GestureEnqueueEvent] ET_ButtonPress (id:%d)\n", device->id);
2657 case ET_ButtonRelease:
2658 ErrorF("[X11][GestureEnqueueEvent] ET_ButtonRelease (id:%d)\n", device->id);
2662 ErrorF("[X11][GestureEnqueueEvent] ET_Motion (id:%d)\n", device->id);
2665 #endif//__DETAIL_DEBUG__
2667 g_pGesture->EQ[tail].device = device;
2668 g_pGesture->EQ[tail].screen_num = screen_num;
2669 memcpy(g_pGesture->EQ[tail].event, ev, sizeof(InternalEvent));//need to be optimized
2670 g_pGesture->tailEQ++;
2676 GestureEventsFlush(void)
2679 DeviceIntPtr device;
2681 if( !g_pGesture->EQ )
2683 ErrorF("[X11][GestureEventsFlush] Invalid pointer access !\n");
2684 return ERROR_INVALPTR;
2687 #ifdef __DETAIL_DEBUG__
2688 ErrorF("[X11][GestureEventsFlush]\n");
2689 #endif//__DETAIL_DEBUG__
2691 for( i = g_pGesture->headEQ ; i < g_pGesture->tailEQ ; i++)
2693 device = g_pGesture->EQ[i].device;
2694 device->public.processInputProc(g_pGesture->EQ[i].event, device);
2697 for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
2698 g_pGesture->event_sum[i] = 0;
2700 g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
2706 GestureEventsDrop(void)
2708 g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
2711 #ifdef HAVE_PROPERTIES
2713 GestureInitProperty(DeviceIntPtr dev)
2717 prop_gesture_recognizer_onoff = MakeAtom(GESTURE_RECOGNIZER_ONOFF, strlen(GESTURE_RECOGNIZER_ONOFF), TRUE);
2718 rc = XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
2723 XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE);
2727 GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
2730 InputInfoPtr pInfo = dev->public.devicePrivate;
2732 if( prop_gesture_recognizer_onoff == atom )
2735 if( val->format != 32 || val->type != XA_INTEGER || val->size != 1 )
2740 data = *((int *)val->data);
2741 GestureSetDisable(pInfo, data);
2747 #endif//HAVE_PROPERTIES
2750 GestureInit(DeviceIntPtr device)
2753 pInfo = device->public.devicePrivate;
2755 #ifdef HAVE_PROPERTIES
2756 GestureInitProperty(device);
2757 XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL);
2764 GestureFini(DeviceIntPtr device)
2766 XIRegisterPropertyHandler(device, NULL, NULL, NULL);
2770 GesturePlug(pointer module, pointer options, int *errmaj, int *errmin)
2772 xf86AddInputDriver(&GESTURE, module, 0);
2777 GestureUnplug(pointer p)
2782 GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
2785 GestureDevicePtr pGesture;
2787 pGesture = calloc(1, sizeof(GestureDeviceRec));
2790 pInfo->private = NULL;
2791 //xf86DeleteInput(pInfo, 0);
2795 g_pGesture = pGesture;
2796 pInfo->private = pGesture;
2798 pInfo->read_input = GestureReadInput; /* new data avl */
2799 pInfo->switch_mode = NULL; /* toggle absolute/relative mode */
2800 pInfo->device_control = GestureControl; /* enable/disable dev */
2801 /* process driver specific options */
2802 pGesture->device = xf86SetStrOption(pInfo->options, "Device", "/dev/null");
2803 pGesture->is_active = xf86SetIntOption(pInfo->options, "Activate", 0);
2804 pGesture->gestureWin = None;
2806 xf86Msg(X_INFO, "%s: Using device %s.\n", pInfo->name, pGesture->device);
2808 /* process generic options */
2809 xf86CollectInputOptions(pInfo, NULL);
2810 xf86ProcessCommonOptions(pInfo, pInfo->options);
2822 GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
2824 GestureDevicePtr pGesture = pInfo->private;
2826 g_pGesture = pGesture = NULL;
2827 pInfo->private = NULL;
2829 xf86DeleteInput(pInfo, 0);
2833 GestureControl(DeviceIntPtr device, int what)
2835 InputInfoPtr pInfo = device->public.devicePrivate;
2836 GestureDevicePtr pGesture = pInfo->private;
2841 GestureInit(device);
2844 /* Switch device on. Establish socket, start event delivery. */
2846 xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
2848 if (device->public.on)
2851 device->public.on = TRUE;
2852 pGesture->this_device = device;
2853 pGesture->num_mt_devices = 0;
2854 if( ERROR_ABNORMAL == GestureEnableEventHandler(pInfo) )
2860 GestureDisableEventHandler();
2861 GestureFini(device);
2862 pGesture->this_device = NULL;
2863 xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
2865 if (!device->public.on)
2869 device->public.on = FALSE;
2873 /* free what we have to free */
2880 GestureReadInput(InputInfoPtr pInfo)