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 GestureEnable(int enable, Bool prop, DeviceIntPtr dev);
98 static inline void GestureEnableDisable();
99 void GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent);
100 void GestureCbEventsSelected(Window win, Mask *pEventMask);
101 WindowPtr GestureGetEventsWindow(void);
103 //Enqueued event handlers and enabler/disabler
104 static ErrorStatus GestureEnableEventHandler(InputInfoPtr pInfo);
105 static ErrorStatus GestureDisableEventHandler(void);
106 static CARD32 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
107 static CARD32 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
108 void GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
109 void GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
110 void GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
111 void GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
113 //Gesture recognizer helper
114 static Bool PointInBorderSize(WindowPtr pWin, int x, int y);
115 static WindowPtr GestureWindowOnXY(int x, int y);
116 Bool GestureHasFingerEventMask(int eventType, int num_finger);
117 static double get_angle(int x1, int y1, int x2, int y2);
119 //Gesture recognizer and handlers
120 void GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
121 void GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx);
122 void GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
123 void GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
124 void GestureRecognize_GroupTapNHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
125 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
126 void GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction);
127 void GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy);
128 void GestureHandleGesture_PinchRotation(int num_of_fingers, double zoom, double angle, int distance, int cx, int cy, int kinds);
129 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds);
130 void GestureHandleGesture_TapNHold(int num_fingers, int cx, int cy, Time interval, Time holdtime, int kinds);
131 void GestureHandleGesture_Pan(int num_fingers, short int dx, short int dy, int direction, int distance, Time duration, int kinds);
132 void GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device);
133 ErrorStatus GestureFlushOrDrop(void);
135 #ifdef HAVE_PROPERTIES
136 //function related property handling
137 static void GestureInitProperty(DeviceIntPtr dev);
138 static int GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkonly);
141 static Atom prop_gesture_recognizer_onoff = None;
143 GestureDevicePtr g_pGesture = NULL;
144 _X_EXPORT InputDriverRec GESTURE = {
154 static XF86ModuleVersionInfo GestureVersionRec =
160 XORG_VERSION_CURRENT,
161 PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR,
162 PACKAGE_VERSION_PATCHLEVEL,
169 _X_EXPORT XF86ModuleData gestureModuleData =
177 printk(const char* fmt, ...)
179 static FILE* fp = NULL;
180 static char init = 0;
185 fp = fopen("/dev/kmsg", "wt");
191 va_start(argptr, fmt);
192 vfprintf(fp, fmt, argptr);
198 PointInBorderSize(WindowPtr pWin, int x, int y)
201 if( pixman_region_contains_point (&pWin->borderSize, x, y, &box) )
208 GestureWindowOnXY(int x, int y)
213 DeviceIntPtr pDev = g_pGesture->master_pointer;
215 pSprite = pDev->spriteInfo->sprite;
216 pSprite->spriteTraceGood = 1; /* root window still there */
217 pWin = RootWindow(pDev)->firstChild;
221 if ((pWin->mapped) &&
222 (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
223 (x < pWin->drawable.x + (int)pWin->drawable.width +
224 wBorderWidth(pWin)) &&
225 (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
226 (y < pWin->drawable.y + (int)pWin->drawable.height +
228 /* When a window is shaped, a further check
229 * is made to see if the point is inside
232 && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
233 && (!wInputShape(pWin) ||
234 RegionContainsPoint(wInputShape(pWin),
235 x - pWin->drawable.x,
236 y - pWin->drawable.y, &box))
238 /* In rootless mode windows may be offscreen, even when
239 * they're in X's stack. (E.g. if the native window system
240 * implements some form of virtual desktop system).
242 && !pWin->rootlessUnhittable
246 if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
248 pSprite->spriteTraceSize += 10;
249 pSprite->spriteTrace = realloc(pSprite->spriteTrace,
250 pSprite->spriteTraceSize*sizeof(WindowPtr));
252 pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
253 pWin = pWin->firstChild;
256 pWin = pWin->nextSib;
258 return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
262 GestureHasFingerEventMask(int eventType, int num_finger)
265 Mask eventmask = (1L << eventType);
267 if( (g_pGesture->grabMask & eventmask) &&
268 (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[num_finger].window != None) )
270 #ifdef __DETAIL_DEBUG__
271 ErrorF("[X11][GestureHasFingerEventMask] TRUE !! Has grabMask\n");
272 #endif//__DETAIL_DEBUG__
276 if( g_pGesture->eventMask & eventmask )
278 #ifdef __DETAIL_DEBUG__
279 ErrorF("[X11][GestureHasFingerEventMask] TRUE !! Has eventMask\n");
280 #endif//__DETAIL_DEBUG__
284 #ifdef __DETAIL_DEBUG__
285 ErrorF("[X11][GestureHasFingerEventMask] FALSE !! eventType=%d, num_finger=%d\n", eventType, num_finger);
286 #endif//__DETAIL_DEBUG__
292 get_angle(int x1, int y1, int x2, int y2)
298 if (((int) xx) && ((int) yy))
305 return (RAD_360DEG - a);
316 return (RAD_180DEG + a);
320 return (RAD_180DEG - a);
326 { /* Horizontal line */
349 GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction)
352 WindowPtr target_pWin;
353 xGestureNotifyFlickEvent fev;
355 #ifdef __DETAIL_DEBUG__
356 ErrorF("[X11][GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n",
357 num_of_fingers, distance, duration, direction);
358 #endif//__DETAIL_DEBUG__
360 g_pGesture->recognized_gesture |= FlickFilterMask;
361 memset(&fev, 0, sizeof(xGestureNotifyFlickEvent));
362 fev.type = GestureNotifyFlick;
363 fev.kind = GestureDone;
364 fev.num_finger = num_of_fingers;
365 fev.distance = distance;
366 fev.duration = duration;
367 fev.direction = direction;
369 target_win = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].window;
370 target_pWin = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].pWin;
372 if( g_pGesture->grabMask && (target_win != None) )
374 fev.window = target_win;
378 fev.window = g_pGesture->gestureWin;
381 #ifdef __DETAIL_DEBUG__
382 ErrorF("[X11][GestureHandleGesture_Flick] fev.window=0x%x, g_pGesture->grabMask=0x%x\n", fev.window, g_pGesture->grabMask);
383 #endif//__DETAIL_DEBUG__
385 GestureSendEvent(target_pWin, GestureNotifyFlick, GestureFlickMask, (xGestureCommonEvent *)&fev);
389 GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy)
392 WindowPtr target_pWin;
393 xGestureNotifyTapEvent tev;
395 //skip non-tap events and single finger tap
396 if( !tap_repeat || num_finger <= 1 )
399 #ifdef __DETAIL_DEBUG__
400 ErrorF("[X11][GestureHandleGesture_Tap] num_finger=%d, tap_repeat=%d, cx=%d, cy=%d\n",
401 num_finger, tap_repeat, cx, cy);
402 #endif//__DETAIL_DEBUG__
404 g_pGesture->recognized_gesture |= TapFilterMask;
405 memset(&tev, 0, sizeof(xGestureNotifyTapEvent));
406 tev.type = GestureNotifyTap;
407 tev.kind = GestureDone;
408 tev.num_finger = num_finger;
409 tev.tap_repeat = tap_repeat;
414 target_win = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].window;
415 target_pWin = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].pWin;
417 if( g_pGesture->grabMask && (target_win != None) )
419 tev.window = target_win;
423 tev.window = g_pGesture->gestureWin;
426 #ifdef __DETAIL_DEBUG__
427 ErrorF("[X11][GestureHandleGesture_Tap] tev.window=0x%x, g_pGesture->grabMask=0x%x\n", tev.window, g_pGesture->grabMask);
428 #endif//__DETAIL_DEBUG__
430 GestureSendEvent(target_pWin, GestureNotifyTap, GestureTapMask, (xGestureCommonEvent *)&tev);
433 void GestureHandleGesture_PinchRotation(int num_of_fingers, double zoom, double angle, int distance, int cx, int cy, int kinds)
436 WindowPtr target_pWin;
437 xGestureNotifyPinchRotationEvent prev;
439 #ifdef __DETAIL_DEBUG__
440 ErrorF("[X11][GestureHandleGesture_PinchRotation] num_fingers=%d, zoom=%.2f, angle=%.2f(deg=%.2f), distance=%d, cx=%d, cy=%d\n",
441 num_of_fingers, zoom, angle, rad2degree(angle), distance, cx, cy);
442 #endif//__DETAIL_DEBUG__
444 g_pGesture->recognized_gesture |= PinchRotationFilterMask;
445 memset(&prev, 0, sizeof(xGestureNotifyPinchRotationEvent));
446 prev.type = GestureNotifyPinchRotation;
448 prev.num_finger = num_of_fingers;
449 prev.zoom = XDoubleToFixed(zoom);
450 prev.angle = XDoubleToFixed(angle);
451 prev.distance = distance;
455 target_win = g_pGesture->GrabEvents[GestureNotifyPinchRotation].pGestureGrabWinInfo[num_of_fingers].window;
456 target_pWin = g_pGesture->GrabEvents[GestureNotifyPinchRotation].pGestureGrabWinInfo[num_of_fingers].pWin;
458 if( g_pGesture->grabMask && (target_win != None) )
460 prev.window = target_win;
464 prev.window = g_pGesture->gestureWin;
467 #ifdef __DETAIL_DEBUG__
468 ErrorF("[X11][GestureHandleGesture_PinchRotation] prev.window=0x%x, g_pGesture->grabMask=0x%x\n", (unsigned int)prev.window, (unsigned int)g_pGesture->grabMask);
469 #endif//__DETAIL_DEBUG__
471 GestureSendEvent(target_pWin, GestureNotifyPinchRotation, GesturePinchRotationMask, (xGestureCommonEvent *)&prev);
474 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds)
477 WindowPtr target_pWin;
478 xGestureNotifyHoldEvent hev;
480 #ifdef __DETAIL_DEBUG__
481 ErrorF("[X11][GestureHandleGesture_Hold] num_fingers=%d, cx=%d, cy=%d, holdtime=%d, kinds=%d\n",
482 num_fingers, cx, cy, holdtime, kinds);
483 #endif//__DETAIL_DEBUG__
485 g_pGesture->recognized_gesture |= HoldFilterMask;
486 memset(&hev, 0, sizeof(xGestureNotifyHoldEvent));
487 hev.type = GestureNotifyHold;
489 hev.num_finger = num_fingers;
490 hev.holdtime = holdtime;
494 target_win = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].window;
495 target_pWin = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].pWin;
497 if( g_pGesture->grabMask && (target_win != None) )
499 hev.window = target_win;
503 hev.window = g_pGesture->gestureWin;
506 #ifdef __DETAIL_DEBUG__
507 ErrorF("[X11][GestureHandleGesture_Hold] hev.window=0x%x, g_pGesture->grabMask=0x%x\n", hev.window, g_pGesture->grabMask);
508 #endif//__DETAIL_DEBUG__
510 GestureSendEvent(target_pWin, GestureNotifyHold, GestureHoldMask, (xGestureCommonEvent *)&hev);
513 void GestureHandleGesture_TapNHold(int num_fingers, int cx, int cy, Time interval, Time holdtime, int kinds)
516 WindowPtr target_pWin;
517 xGestureNotifyTapNHoldEvent thev;
519 #ifdef __DETAIL_DEBUG__
520 ErrorF("[X11][GestureHandleGesture_TapNHold] num_fingers=%d, cx=%d, cy=%d, interval=%d, holdtime=%d, kinds=%d\n",
521 num_fingers, cx, cy, interval, holdtime, kinds);
522 #endif//__DETAIL_DEBUG__
524 g_pGesture->recognized_gesture |= TapNHoldFilterMask;
525 memset(&thev, 0, sizeof(xGestureNotifyTapNHoldEvent));
526 thev.type = GestureNotifyTapNHold;
528 thev.num_finger = num_fingers;
529 thev.holdtime = holdtime;
532 thev.interval = interval;
534 target_win = g_pGesture->GrabEvents[GestureNotifyTapNHold].pGestureGrabWinInfo[num_fingers].window;
535 target_pWin = g_pGesture->GrabEvents[GestureNotifyTapNHold].pGestureGrabWinInfo[num_fingers].pWin;
537 if( g_pGesture->grabMask && (target_win != None) )
539 thev.window = target_win;
543 thev.window = g_pGesture->gestureWin;
546 #ifdef __DETAIL_DEBUG__
547 ErrorF("[X11][GestureHandleGesture_TapNHold] thev.window=0x%x, g_pGesture->grabMask=0x%x\n", thev.window, g_pGesture->grabMask);
548 #endif//__DETAIL_DEBUG__
550 GestureSendEvent(target_pWin, GestureNotifyTapNHold, GestureTapNHoldMask, (xGestureCommonEvent *)&thev);
553 void GestureHandleGesture_Pan(int num_fingers, short int dx, short int dy, int direction, int distance, Time duration, int kinds)
556 WindowPtr target_pWin;
557 xGestureNotifyPanEvent pev;
559 #ifdef __DETAIL_DEBUG__
560 ErrorF("[X11][GestureHandleGesture_Pan] num_fingers=%d, dx=%d, dy=%d, direction=%d, distance=%d, duration=%d, kinds=%d\n",
561 num_fingers, dx, dy, direction, distance, duration, kinds);
562 #endif//__DETAIL_DEBUG__
564 g_pGesture->recognized_gesture |= PanFilterMask;
565 memset(&pev, 0, sizeof(xGestureNotifyPanEvent));
566 pev.type = GestureNotifyPan;
568 pev.num_finger = num_fingers;
569 pev.direction = direction;
570 pev.distance = distance;
571 pev.duration = duration;
575 target_win = g_pGesture->GrabEvents[GestureNotifyPan].pGestureGrabWinInfo[num_fingers].window;
576 target_pWin = g_pGesture->GrabEvents[GestureNotifyPan].pGestureGrabWinInfo[num_fingers].pWin;
578 if( g_pGesture->grabMask && (target_win != None) )
580 pev.window = target_win;
584 pev.window = g_pGesture->gestureWin;
587 #ifdef __DETAIL_DEBUG__
588 ErrorF("[X11][GestureHandleGesture_Pan] pev.window=0x%x, g_pGesture->grabMask=0x%x\n", pev.window, g_pGesture->grabMask);
589 #endif//__DETAIL_DEBUG__
591 GestureSendEvent(target_pWin, GestureNotifyPan, GesturePanMask, (xGestureCommonEvent *)&pev);
595 GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
599 static int num_pressed = 0;
600 static int state = GestureEnd;
601 static int event_type = GestureNotifyPinchRotation;
602 static OsTimerPtr pinchrotation_event_timer = NULL;
604 static pixman_region16_t base_area;
605 static pixman_region16_t cur_area;
607 static double base_distance = 0.0f;
608 static double base_angle = 0.0f;
610 static double prev_distance = 0.0f;
611 static double prev_angle = 0.0f;
613 static double cur_distance = 0.0f;
614 static double cur_angle = 0.0f;
616 double diff_distance = 0.0f;
617 double diff_angle = 0.0f;
619 static int has_event_mask = 0;
621 static Time base_time = 0;
626 if( state == GestureEnd )
628 current_time = GetTimeInMillis();
629 if( (current_time - base_time) >= PINCHROTATION_TIME_THRESHOLD )
631 #ifdef __DETAIL_DEBUG__
632 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);
633 #endif//__DETAIL_DEBUG__
634 goto cleanup_pinchrotation;
644 g_pGesture->fingers[idx].flags |= PressFlagPinchRotation;
646 if( g_pGesture->num_pressed < 2 )
649 if( g_pGesture->num_pressed < num_pressed && state != GestureEnd )
651 #ifdef __DETAIL_DEBUG__
652 ErrorF("[GroupPinchRotation][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
653 #endif//__DETAIL_DEBUG__
654 goto cleanup_pinchrotation;
657 if( base_distance == 0.0f && g_pGesture->num_pressed == 2 )
659 #ifdef __DETAIL_DEBUG__
660 ErrorF("[GroupPinchRotation][First Time !!!] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
661 #endif//__DETAIL_DEBUG__
663 base_time = GetTimeInMillis();
664 pixman_region_init(&base_area);
665 pixman_region_union(&base_area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[1]);
667 prev_distance = base_distance = AREA_DIAG_LEN(&base_area.extents);
669 #ifdef __DETAIL_DEBUG__
670 ErrorF("[GroupPinchRotation][P] x1=%d, x2=%d, y1=%d, y2=%d\n", g_pGesture->fingers[0].px, g_pGesture->fingers[1].px,
671 g_pGesture->fingers[0].py, g_pGesture->fingers[1].py);
672 #endif//__DETAIL_DEBUG__
674 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);
675 #ifdef __DETAIL_DEBUG__
676 ErrorF("[GroupPinchRotation][P] base_angle=%.2f(deg=%.2f)\n", base_angle, rad2degree(base_angle));
677 #endif//__DETAIL_DEBUG__
678 event_type = GestureNotifyPinchRotation;
679 pinchrotation_event_timer = TimerSet(pinchrotation_event_timer, 0, PINCHROTATION_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
681 num_pressed = g_pGesture->num_pressed;
683 #ifdef __DETAIL_DEBUG__
684 ErrorF("[GroupPinchRotation][P][num_pressed=%d] AREA_SIZE(base_area.extents)=%d\n", num_pressed, AREA_SIZE(&base_area.extents));
685 ErrorF("[GroupPinchRotation][P][num_pressed=%d] base_distance=%.2f, base_angle=%.2f(deg=%.2f)\n", num_pressed, base_distance, base_angle, rad2degree(base_angle));
686 #endif//__DETAIL_DEBUG__
690 if( !(g_pGesture->fingers[idx].flags & PressFlagPinchRotation) )
693 if( (num_pressed != g_pGesture->num_pressed) && (state != GestureEnd) )
695 #ifdef __DETAIL_DEBUG__
696 ErrorF("[GroupPinchRotation][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
697 #endif//__DETAIL_DEBUG__
698 goto cleanup_pinchrotation;
701 if( num_pressed < 2 )
704 if( g_pGesture->fingers[0].mx && g_pGesture->fingers[0].my && g_pGesture->fingers[1].mx && g_pGesture->fingers[1].my )
706 pixman_region_init(&cur_area);
707 pixman_region_union(&cur_area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[1]);
709 cur_distance = AREA_DIAG_LEN(&cur_area.extents);
711 #ifdef __DETAIL_DEBUG__
712 ErrorF("[GroupPinchRotation][M] x1=%d, x2=%d, y1=%d, y2=%d\n", g_pGesture->fingers[0].mx, g_pGesture->fingers[1].mx,
713 g_pGesture->fingers[0].my, g_pGesture->fingers[1].my);
714 #endif//__DETAIL_DEBUG__
716 cur_angle = get_angle(g_pGesture->fingers[0].mx, g_pGesture->fingers[0].my, g_pGesture->fingers[1].mx, g_pGesture->fingers[1].my);
717 #ifdef __DETAIL_DEBUG__
718 ErrorF("[GroupPinchRotation][M] cur_angle=%.2f(deg=%.2f)\n", cur_angle, rad2degree(cur_angle));
719 #endif//__DETAIL_DEBUG__
721 diff_distance = prev_distance - cur_distance;
722 diff_angle = prev_angle - cur_angle;
724 cx = AREA_CENTER_X(&cur_area.extents);
725 cy = AREA_CENTER_Y(&cur_area.extents);
727 #ifdef __DETAIL_DEBUG__
728 ErrorF("[GroupPinchRotation][M][state=%d] cx=%d, cy=%d\n", state, cx, cy);
729 #endif//__DETAIL_DEBUG__
731 #ifdef __DETAIL_DEBUG__
732 ErrorF("[GroupPinchRotation][M][num_pressed=%d] prev_distance=%.2f, cur_distance=%.2f, diff=%.2f\n", num_pressed, prev_distance, cur_distance, diff_distance);
733 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));
734 #endif//__DETAIL_DEBUG__
739 if( (ABS(diff_distance) >= PINCHROTATION_DIST_THRESHOLD) || (ABS(diff_angle) >= PINCHROTATION_ANGLE_THRESHOLD) )
741 #ifdef __DETAIL_DEBUG__
742 if( ABS(diff_distance) >= PINCHROTATION_DIST_THRESHOLD )
743 ErrorF("[GroupPinchRotation][M] zoom changed !\n");
745 if( ABS(diff_angle) >= PINCHROTATION_ANGLE_THRESHOLD )
746 ErrorF("[GroupPinchRotation][M] angle changed !\n");
747 #endif//__DETAIL_DEBUG__
749 TimerCancel(pinchrotation_event_timer);
750 state = GestureBegin;
751 goto gesture_begin_handle;
756 gesture_begin_handle:
757 #ifdef __DETAIL_DEBUG__
758 ErrorF("[GroupPinchRotation] PINCHROTATION Begin !cx=%d, cy=%d, state=%d\n", cx, cy, state);
759 #endif//__DETAIL_DEBUG__
760 if( GestureHasFingerEventMask(GestureNotifyPinchRotation, num_pressed) )
762 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);
763 prev_distance = cur_distance;
764 prev_angle = cur_angle;
765 state = GestureUpdate;
771 goto cleanup_pinchrotation;
776 //if( ABS(diff_distance) < PINCHROTATION_DIST_THRESHOLD && ABS(diff_angle) < PINCHROTATION_ANGLE_THRESHOLD )
779 #ifdef __DETAIL_DEBUG__
780 if( ABS(diff_distance) >= PINCHROTATION_DIST_THRESHOLD )
781 ErrorF("[GroupPinchRotation][M] zoom changed !\n");
783 if( ABS(diff_angle) >= PINCHROTATION_ANGLE_THRESHOLD )
784 ErrorF("[GroupPinchRotation][M] angle changed !\n");
785 #endif//__DETAIL_DEBUG__
787 #ifdef __DETAIL_DEBUG__
788 ErrorF("[GroupPinchRotation] PINCHROTATION Update ! cx=%d, cy=%d, state=%d\n", cx, cy, state);
789 #endif//__DETAIL_DEBUG__
790 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);
791 prev_distance = cur_distance;
792 prev_angle = cur_angle;
802 case ET_ButtonRelease:
803 if( state != GestureEnd && num_pressed >= 2)
805 #ifdef __DETAIL_DEBUG__
806 ErrorF("[GroupPinchRotation][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
807 #endif//__DETAIL_DEBUG__
808 goto cleanup_pinchrotation;
811 if( g_pGesture->num_pressed )
814 goto cleanup_pinchrotation;
820 cleanup_pinchrotation:
822 if( has_event_mask && (state == GestureBegin || state == GestureUpdate) )
825 #ifdef __DETAIL_DEBUG__
826 ErrorF("[GroupPinchRotation] PINCHROTATION End ! cx=%d, cy=%d, state=%d\n", cx, cy, state);
827 #endif//__DETAIL_DEBUG__
828 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);
832 g_pGesture->recognized_gesture &= ~PinchRotationFilterMask;
835 g_pGesture->filter_mask |= PinchRotationFilterMask;
837 if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
839 #if 1//def __DETAIL_DEBUG__
840 ErrorF("[GroupPinchRotation][cleanup] GestureFlushOrDrop() !\n");
841 #endif//__DETAIL_DEBUG__
843 if( ERROR_INVALPTR == GestureFlushOrDrop() )
845 GestureControl(g_pGesture->this_device, DEVICE_OFF);
849 prev_distance = base_distance = 0.0f;
850 prev_angle = base_angle = 0.0f;
851 has_event_mask = num_pressed = 0;
854 TimerCancel(pinchrotation_event_timer);
859 GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx)
861 static int num_pressed = 0;
862 static int mbits = 0;
863 static int base_area_size = 0;
864 static Time base_time = 0;
865 static int base_x, base_y;
869 int distance, direction;
876 g_pGesture->fingers[idx].flags |= PressFlagFlick;
878 if( g_pGesture->num_pressed < 2 )
881 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
883 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
884 base_x = g_pGesture->area.extents.x1;
885 base_y = g_pGesture->area.extents.y1;
886 base_time = GetTimeInMillis();
888 num_pressed = g_pGesture->num_pressed;
890 #ifdef __DETAIL_DEBUG__
891 ErrorF("[GroupFlick][P]][num_pressed=%d] AREA_SIZE(area.extents)=%d\n", num_pressed, base_area_size);
892 #endif//__DETAIL_DEBUG__
896 if( !(g_pGesture->fingers[idx].flags & PressFlagFlick ) )
899 #ifdef __DETAIL_DEBUG__
900 if( num_pressed > g_pGesture->num_pressed )
902 ErrorF("[GroupFlick][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
903 //goto cleanup_flick;
905 #endif//__DETAIL_DEBUG__
907 if( num_pressed < 2 )
911 if( mbits == (pow(2, num_pressed)-1) )
913 area_size = AREA_SIZE(&g_pGesture->area.extents);
914 #ifdef __DETAIL_DEBUG__
915 ErrorF("[M][num_pressed=%d] AREA_SIZE(area.extents)=%d\n", num_pressed, area_size);
916 #endif//__DETAIL_DEBUG__
917 if( ABS(base_area_size - area_size) >= FLICK_AREA_THRESHOLD )
919 #ifdef __DETAIL_DEBUG__
920 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);
921 #endif//__DETAIL_DEBUG__
925 current_time = GetTimeInMillis();
926 if( (current_time - base_time) >= FLICK_AREA_TIMEOUT )
928 #ifdef __DETAIL_DEBUG__
929 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);
930 #endif//__DETAIL_DEBUG__
937 case ET_ButtonRelease:
938 if( g_pGesture->num_pressed )
941 duration = GetTimeInMillis() - base_time;
942 distx = g_pGesture->area.extents.x1 - base_x;
943 disty = g_pGesture->area.extents.y1 - base_y;
945 #ifdef __DETAIL_DEBUG__
946 ErrorF("[GroupFlick] duration=%d, distx=%d, disty=%d\n", duration, distx, disty);
947 #endif//__DETAIL_DEBUG__
949 if( duration <= 0 || duration >= FLICK_AREA_TIMEOUT )
952 if( ABS(distx) >= FLICK_MOVE_THRESHOLD )
954 direction = (distx > 0) ? FLICK_EASTWARD : FLICK_WESTWARD;
955 distance = ABS(distx);
958 else if( ABS(disty) >= FLICK_MOVE_THRESHOLD )
960 direction = (disty > 0) ? FLICK_SOUTHWARD : FLICK_NORTHWARD;
961 distance = ABS(disty);
968 if( GestureHasFingerEventMask(GestureNotifyFlick, num_pressed) )
969 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
970 goto cleanup_flick_recognized;
978 g_pGesture->recognized_gesture &= ~FlickFilterMask;
980 cleanup_flick_recognized:
982 g_pGesture->filter_mask |= FlickFilterMask;
991 GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
993 static int num_pressed = 0;
994 static int mbits = 0;
995 static int base_area_size = 0;
996 static Time base_time = 0;
997 static pixman_box16_t base_box_ext;
1005 static Time prev_time = 0;
1006 Time current_time = 0;
1010 static int time_checked = 0;
1011 static int state = GestureEnd;
1013 static OsTimerPtr pan_event_timer = NULL;
1014 static int event_type = GestureNotifyPan;
1020 current_time = GetTimeInMillis();
1021 if( (current_time - base_time) >= PAN_TIME_THRESHOLD )
1023 if( (!cx && !cy) || INBOX(&base_box_ext, cx, cy) )
1025 #ifdef __DETAIL_DEBUG__
1026 ErrorF("[GroupPan][Timer] You must move farther than move threshold(=%d) within time threshold(=%d) !\n", PAN_MOVE_THRESHOLD*2, PAN_TIME_THRESHOLD);
1027 #endif//__DETAIL_DEBUG__
1038 case ET_ButtonPress:
1039 g_pGesture->fingers[idx].flags |= PressFlagPan;
1041 if( g_pGesture->num_pressed < 2 )
1044 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
1046 if( state != GestureEnd )
1048 #ifdef __DETAIL_DEBUG__
1049 ErrorF("[GroupPan][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1050 #endif//__DETAIL_DEBUG__
1053 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1054 prev_cx = base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1055 prev_cy = base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1056 prev_time = base_time = GetTimeInMillis();
1057 base_box_ext.x1 = base_cx-PAN_MOVE_THRESHOLD;
1058 base_box_ext.y1 = base_cy-PAN_MOVE_THRESHOLD;
1059 base_box_ext.x2 = base_cx+PAN_MOVE_THRESHOLD;
1060 base_box_ext.y2 = base_cy+PAN_MOVE_THRESHOLD;
1061 event_type = GestureNotifyPan;
1062 pan_event_timer = TimerSet(pan_event_timer, 0, PAN_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1064 num_pressed = g_pGesture->num_pressed;
1066 #ifdef __DETAIL_DEBUG__
1067 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);
1068 #endif//__DETAIL_DEBUG__
1072 if( !(g_pGesture->fingers[idx].flags & PressFlagPan ) )
1075 if( num_pressed != g_pGesture->num_pressed )
1077 if( state != GestureEnd )
1079 #ifdef __DETAIL_DEBUG__
1080 ErrorF("[GroupPan][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1081 #endif//__DETAIL_DEBUG__
1086 if( num_pressed < 2 )
1089 mbits |= (1 << idx);
1090 if( mbits == (pow(2, num_pressed)-1) )
1092 area_size = AREA_SIZE(&g_pGesture->area.extents);
1093 #ifdef __DETAIL_DEBUG__
1094 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));
1095 #endif//__DETAIL_DEBUG__
1097 if( (state != GestureUpdate) && (ABS(base_area_size - area_size) >= PAN_AREA_THRESHOLD) )
1099 #ifdef __DETAIL_DEBUG__
1100 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);
1101 #endif//__DETAIL_DEBUG__
1105 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1106 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1107 #ifdef __DETAIL_DEBUG__
1108 ErrorF("[GroupPan][M] cx=%d, prev_cx=%d, diff=%d\n", cx, prev_cx, ABS(cx-prev_cx));
1109 ErrorF("[GroupPan][M] cy=%d, prev_cy=%d, diff=%d\n", cy, prev_cy, ABS(cy-prev_cy));
1110 #endif//__DETAIL_DEBUG__
1112 if( state <= GestureBegin )
1114 if( !INBOX(&base_box_ext, cx, cy) )
1116 TimerCancel(pan_event_timer);
1117 pan_event_timer = NULL;
1119 if( GestureHasFingerEventMask(GestureNotifyPan, num_pressed) )
1121 GestureHandleGesture_Pan(num_pressed, prev_cx, prev_cy, direction, distance, current_time-prev_time, GestureBegin);
1122 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);
1149 case ET_ButtonRelease:
1150 if( state != GestureEnd && num_pressed >= 2)
1152 #ifdef __DETAIL_DEBUG__
1153 ErrorF("[GroupPan][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1154 #endif//__DETAIL_DEBUG__
1158 if( g_pGesture->num_pressed )
1169 if( state == GestureBegin || state == GestureUpdate )
1172 if( GestureHasFingerEventMask(GestureNotifyPan, num_pressed) )
1174 GestureHandleGesture_Pan(num_pressed, (short int)(cx-prev_cx), (short int)(cy-prev_cy), direction, distance, GetTimeInMillis()-prev_time, GestureEnd);
1179 g_pGesture->recognized_gesture &= ~PanFilterMask;
1182 g_pGesture->filter_mask |= PanFilterMask;
1191 base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
1192 if( pan_event_timer )
1194 TimerCancel(pan_event_timer);
1195 pan_event_timer = NULL;
1201 GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1203 static int num_pressed = 0;
1204 static int base_area_size = 0;
1206 static Time base_time = 0;
1212 static int state = 0;
1213 static int mbits = 0;
1216 static pixman_box16_t base_box_ext;
1218 static int tap_repeat = 0;
1219 static int prev_tap_repeat = 0;
1220 static int prev_num_pressed = 0;
1222 static OsTimerPtr tap_event_timer = NULL;
1223 static int event_type = GestureNotifyTap;
1227 #ifdef __DETAIL_DEBUG__
1228 ErrorF("[GroupTap][Timer] state=%d\n", state);
1229 #endif//__DETAIL_DEBUG__
1233 case 1://first tap initiation check
1236 #ifdef __DETAIL_DEBUG__
1237 ErrorF("[GroupTap][Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", tap_repeat, num_pressed, tap_repeat);
1238 #endif//__DETAIL_DEBUG__
1245 if( tap_repeat <= 1 )
1247 #ifdef __DETAIL_DEBUG__
1248 ErrorF("[GroupTap][Timer][state=2] %d finger SINGLE TAP !(ignored)\n", prev_num_pressed);
1249 #endif//__DETAIL_DEBUG__
1254 #ifdef __DETAIL_DEBUG__
1255 ErrorF("[GroupTap][Timer][state=2] tap_repeat=%d, prev_tap_repeat=%d, num_pressed=%d\n", tap_repeat, prev_tap_repeat, num_pressed);
1256 #endif//__DETAIL_DEBUG__
1257 if( GestureHasFingerEventMask(GestureNotifyTap, prev_num_pressed) )
1258 GestureHandleGesture_Tap(prev_num_pressed, tap_repeat, base_cx, base_cy);
1268 case ET_ButtonPress:
1269 g_pGesture->fingers[idx].flags |= PressFlagTap;
1271 if( g_pGesture->num_pressed < 2 )
1274 if( !prev_num_pressed && (!base_area_size || g_pGesture->num_pressed > num_pressed) )
1276 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1277 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1278 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1279 base_time = GetTimeInMillis();
1280 base_box_ext.x1 = base_cx-TAP_MOVE_THRESHOLD;
1281 base_box_ext.y1 = base_cy-TAP_MOVE_THRESHOLD;
1282 base_box_ext.x2 = base_cx+TAP_MOVE_THRESHOLD;
1283 base_box_ext.y2 = base_cy+TAP_MOVE_THRESHOLD;
1285 TimerCancel(tap_event_timer);
1286 tap_event_timer = TimerSet(tap_event_timer, 0, SGL_TAP_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1289 num_pressed = g_pGesture->num_pressed;
1291 current_time = GetTimeInMillis();
1293 #ifdef __DETAIL_DEBUG__
1294 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);
1295 #endif//__DETAIL_DEBUG__
1299 if( !(g_pGesture->fingers[idx].flags & PressFlagTap ) )
1302 if( num_pressed < 2 )
1305 if( num_pressed != g_pGesture->num_pressed )
1307 #ifdef __DETAIL_DEBUG__
1308 ErrorF("[GroupTap][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1309 #endif//__DETAIL_DEBUG__
1313 mbits |= (1 << idx);
1314 if( mbits == (pow(2, num_pressed)-1) )
1316 area_size = AREA_SIZE(&g_pGesture->area.extents);
1317 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1318 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1319 #ifdef __DETAIL_DEBUG__
1320 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));
1321 ErrorF("[GroupTap][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1322 ErrorF("[GroupTap][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1323 #endif//__DETAIL_DEBUG__
1325 if( ABS(base_area_size-area_size) >= TAP_AREA_THRESHOLD )
1327 #ifdef __DETAIL_DEBUG__
1328 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));
1329 #endif//__DETAIL_DEBUG__
1333 if( !INBOX(&base_box_ext, cx, cy) )
1335 #ifdef __DETAIL_DEBUG__
1336 ErrorF("[GroupTap][M] current center coordinates is not in base coordinates box !\n");
1337 #endif//__DETAIL_DEBUG__
1343 case ET_ButtonRelease:
1344 if( g_pGesture->num_pressed )
1349 prev_num_pressed = num_pressed;
1352 prev_tap_repeat = tap_repeat;
1355 #ifdef __DETAIL_DEBUG__
1356 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);
1357 #endif//__DETAIL_DEBUG__
1359 if( num_pressed != prev_num_pressed || !GestureHasFingerEventMask(GestureNotifyTap, num_pressed) )
1361 #ifdef __DETAIL_DEBUG__
1362 ErrorF("[GroupTap][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
1363 num_pressed, prev_num_pressed, num_pressed);
1364 #endif//__DETAIL_DEBUG__
1368 if( tap_repeat < MAX_TAP_REPEATS )
1371 TimerCancel(tap_event_timer);
1372 tap_event_timer = TimerSet(tap_event_timer, 0, DBL_TAP_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1377 #ifdef __DETAIL_DEBUG__
1378 ErrorF("[GroupTap][R] %d finger %s\n", num_pressed, (tap_repeat==2) ? "DBL_TAP" : "TRIPLE_TAP");
1379 #endif//__DETAIL_DEBUG__
1381 if( GestureHasFingerEventMask(GestureNotifyTap, num_pressed) )
1382 GestureHandleGesture_Tap(num_pressed, tap_repeat, base_cx, base_cy);
1384 if( tap_repeat >= MAX_TAP_REPEATS )
1389 prev_num_pressed = num_pressed;
1399 g_pGesture->recognized_gesture &= ~TapFilterMask;
1400 g_pGesture->filter_mask |= TapFilterMask;
1402 if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
1404 #ifdef __DETAIL_DEBUG__
1405 ErrorF("[GroupTap][cleanup] GestureFlushOrDrop() !\n");
1406 #endif//__DETAIL_DEBUG__
1408 if( ERROR_INVALPTR == GestureFlushOrDrop() )
1410 GestureControl(g_pGesture->this_device, DEVICE_OFF);
1416 prev_num_pressed = 0;
1420 TimerCancel(tap_event_timer);
1425 GestureRecognize_GroupTapNHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1427 static int num_pressed = 0;
1428 static int base_area_size = 0;
1429 static Time base_time = 0;
1433 static pixman_box16_t base_box_ext;
1435 static int mbits = 0;
1437 static int tap_repeat = 0;
1438 static int prev_num_pressed = 0;
1440 static OsTimerPtr tapnhold_event_timer = NULL;
1441 static int event_type = GestureNotifyTapNHold;
1442 static int state = GestureEnd;
1449 if( (state == GestureEnd) && num_pressed )
1451 #ifdef __DETAIL_DEBUG__
1452 ErrorF("[GroupTapNHold][Timer][state=%d] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", GestureEnd, tap_repeat, num_pressed, tap_repeat);
1453 #endif//__DETAIL_DEBUG__
1455 goto cleanup_tapnhold;
1458 if( state == GestureDone )
1460 #ifdef __DETAIL_DEBUG__
1461 ErrorF("[GroupTapNHold][Timer][state=%d] Interval between Tap and Hold is too long !\n");
1462 #endif//__DETAIL_DEBUG__
1463 goto cleanup_tapnhold;
1466 #ifdef __DETAIL_DEBUG__
1470 ErrorF("[GroupTapNHold][Timer] TapNHold Begin !\n");
1474 ErrorF("[GroupTapNHold][Timer] TapNHold Update !\n");
1477 #endif//__DETAIL_DEBUG__
1479 if( GestureHasFingerEventMask(GestureNotifyTapNHold, prev_num_pressed) )
1481 GestureHandleGesture_TapNHold(prev_num_pressed, base_cx, base_cy, interval, holdtime, state);
1482 tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1486 #ifdef __DETAIL_DEBUG__
1487 ErrorF("[GroupTapNHold][Timer] %d finger TapNHold event was not grabbed/selected !\n", prev_num_pressed);
1488 #endif//__DETAIL_DEBUG__
1489 goto cleanup_tapnhold;
1492 if( state <= GestureBegin )
1499 case ET_ButtonPress:
1500 g_pGesture->fingers[idx].flags |= PressFlagTapNHold;
1502 if( g_pGesture->num_pressed < 2 )
1505 //if( !prev_num_pressed && (!base_area_size || g_pGesture->num_pressed > num_pressed) )
1506 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
1509 if( state == GestureUpdate )
1511 #ifdef __DETAIL_DEBUG__
1512 ErrorF("[GroupTapNHold][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1513 #endif//__DETAIL_DEBUG__
1514 goto cleanup_tapnhold;
1517 if( state == GestureDone )
1518 state = GestureBegin;
1520 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1521 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1522 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1523 base_time = GetTimeInMillis();
1524 base_box_ext.x1 = base_cx-TAPNHOLD_MOVE_THRESHOLD;
1525 base_box_ext.y1 = base_cy-TAPNHOLD_MOVE_THRESHOLD;
1526 base_box_ext.x2 = base_cx+TAPNHOLD_MOVE_THRESHOLD;
1527 base_box_ext.y2 = base_cy+TAPNHOLD_MOVE_THRESHOLD;
1528 if( state == GestureEnd )
1529 tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_TAP_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1532 TimerCancel(tapnhold_event_timer);
1533 tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1535 #ifdef __DETAIL_DEBUG__
1536 ErrorF("[GroupTapNHold][P] Create Timer !(state=%d)\n", state);
1537 #endif//__DETAIL_DEBUG__
1540 num_pressed = g_pGesture->num_pressed;
1542 #ifdef __DETAIL_DEBUG__
1543 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);
1544 #endif//__DETAIL_DEBUG__
1548 if( !(g_pGesture->fingers[idx].flags & PressFlagTapNHold ) )
1551 if( num_pressed < 2 )
1554 if( num_pressed != g_pGesture->num_pressed )
1556 if( state != GestureEnd )
1558 #ifdef __DETAIL_DEBUG__
1559 ErrorF("[GroupTapNHold][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1560 #endif//__DETAIL_DEBUG__
1561 goto cleanup_tapnhold;
1563 #ifdef __DETAIL_DEBUG__
1564 ErrorF("[GroupTapNHold][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1565 #endif//__DETAIL_DEBUG__
1566 //goto cleanup_tapnhold;
1569 mbits |= (1 << idx);
1570 if( mbits == (pow(2, num_pressed)-1) )
1572 area_size = AREA_SIZE(&g_pGesture->area.extents);
1573 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1574 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1575 #ifdef __DETAIL_DEBUG__
1576 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));
1577 ErrorF("[GroupTapNHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1578 ErrorF("[GroupTapNHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1579 #endif//__DETAIL_DEBUG__
1581 if( ABS(base_area_size-area_size) >= TAPNHOLD_AREA_THRESHOLD )
1583 #ifdef __DETAIL_DEBUG__
1584 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));
1585 #endif//__DETAIL_DEBUG__
1586 goto cleanup_tapnhold;
1589 if( !INBOX(&base_box_ext, cx, cy) )
1591 #ifdef __DETAIL_DEBUG__
1592 ErrorF("[GroupTapNHold][M] current center coordinates is not in base coordinates box !\n");
1593 #endif//__DETAIL_DEBUG__
1594 goto cleanup_tapnhold;
1599 case ET_ButtonRelease:
1600 if( state != GestureEnd && num_pressed >= 2)
1602 #ifdef __DETAIL_DEBUG__
1603 ErrorF("[GroupTapNHold][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1604 #endif//__DETAIL_DEBUG__
1605 goto cleanup_tapnhold;
1608 if( g_pGesture->num_pressed )
1613 prev_num_pressed = num_pressed;
1618 #ifdef __DETAIL_DEBUG__
1619 ErrorF("[GroupTapNHold][R] tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, num_pressed, prev_num_pressed);
1620 #endif//__DETAIL_DEBUG__
1622 if( num_pressed != prev_num_pressed || !GestureHasFingerEventMask(GestureNotifyTapNHold, num_pressed) )
1624 #ifdef __DETAIL_DEBUG__
1625 ErrorF("[GroupTapNHold][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
1626 num_pressed, prev_num_pressed, num_pressed);
1627 #endif//__DETAIL_DEBUG__
1628 goto cleanup_tapnhold;
1631 if( tap_repeat > 1 )
1633 #ifdef __DETAIL_DEBUG__
1634 ErrorF("[GroupTapNHold][R] Tap events(tap_repeat=%d) were put twice or more !(ignored)\n", tap_repeat);
1635 #endif//__DETAIL_DEBUG__
1636 goto cleanup_tapnhold;
1639 prev_num_pressed = num_pressed;
1641 state = GestureDone;
1643 TimerCancel(tapnhold_event_timer);
1644 tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_INTV_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1646 #ifdef __DETAIL_DEBUG__
1647 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);
1648 #endif//__DETAIL_DEBUG__
1656 if( state == GestureUpdate )
1659 if( GestureHasFingerEventMask(GestureNotifyTapNHold, prev_num_pressed) )
1661 GestureHandleGesture_TapNHold(prev_num_pressed, base_cx, base_cy, interval, holdtime, state);
1666 g_pGesture->recognized_gesture &= ~TapNHoldFilterMask;
1669 g_pGesture->filter_mask |= TapNHoldFilterMask;
1670 if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
1672 #ifdef __DETAIL_DEBUG__
1673 ErrorF("[GroupTapNHold][cleanup] GestureFlushOrDrop() !\n");
1674 #endif//__DETAIL_DEBUG__
1676 if( ERROR_INVALPTR == GestureFlushOrDrop() )
1678 GestureControl(g_pGesture->this_device, DEVICE_OFF);
1682 TimerCancel(tapnhold_event_timer);
1685 prev_num_pressed = 0;
1693 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1695 static int num_pressed = 0;
1696 static int base_area_size = 0;
1697 static Time base_time = 0;
1701 static pixman_box16_t base_box_ext;
1703 static int state = GestureEnd;
1705 static OsTimerPtr hold_event_timer = NULL;
1706 static int event_type = GestureNotifyHold;
1710 if( state <= GestureBegin )
1713 #ifdef __DETAIL_DEBUG__
1717 ErrorF("[GroupHold] HOLD Begin !\n");
1721 ErrorF("[GroupHold] HOLD Update !\n");
1724 #endif//__DETAIL_DEBUG__
1726 if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) )
1728 GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1729 hold_event_timer = TimerSet(hold_event_timer, 0, HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1736 case ET_ButtonPress:
1737 g_pGesture->fingers[idx].flags |= PressFlagHold;
1739 if( g_pGesture->num_pressed < 2 )
1742 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
1744 if( state != GestureEnd )
1746 #ifdef __DETAIL_DEBUG__
1747 ErrorF("[GroupHold][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1748 #endif//__DETAIL_DEBUG__
1752 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1753 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1754 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1755 base_time = GetTimeInMillis();
1756 base_box_ext.x1 = base_cx-HOLD_MOVE_THRESHOLD;
1757 base_box_ext.y1 = base_cy-HOLD_MOVE_THRESHOLD;
1758 base_box_ext.x2 = base_cx+HOLD_MOVE_THRESHOLD;
1759 base_box_ext.y2 = base_cy+HOLD_MOVE_THRESHOLD;
1760 event_type = GestureNotifyHold;
1761 hold_event_timer = TimerSet(hold_event_timer, 0, HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1763 num_pressed = g_pGesture->num_pressed;
1765 #ifdef __DETAIL_DEBUG__
1766 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);
1767 #endif//__DETAIL_DEBUG__
1771 if( !(g_pGesture->fingers[idx].flags & PressFlagHold ) )
1774 if( num_pressed < 2 )
1777 if( num_pressed != g_pGesture->num_pressed )
1779 if( state != GestureEnd )
1781 #ifdef __DETAIL_DEBUG__
1782 ErrorF("[GroupHold][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1783 #endif//__DETAIL_DEBUG__
1786 #ifdef __DETAIL_DEBUG__
1787 ErrorF("[GroupHold][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1788 #endif//__DETAIL_DEBUG__
1789 //goto cleanup_hold;
1792 area_size = AREA_SIZE(&g_pGesture->area.extents);
1793 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1794 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1795 #ifdef __DETAIL_DEBUG__
1796 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));
1797 ErrorF("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1798 ErrorF("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1799 #endif//__DETAIL_DEBUG__
1801 if( ABS(base_area_size-area_size) >= HOLD_AREA_THRESHOLD )
1803 #ifdef __DETAIL_DEBUG__
1804 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));
1805 #endif//__DETAIL_DEBUG__
1809 if( !INBOX(&base_box_ext, cx, cy) )
1811 #ifdef __DETAIL_DEBUG__
1812 ErrorF("[GroupHold][M] current center coordinates is not in base coordinates box !\n");
1813 #endif//__DETAIL_DEBUG__
1818 case ET_ButtonRelease:
1819 if( state != GestureEnd && num_pressed >= 2)
1821 #ifdef __DETAIL_DEBUG__
1822 ErrorF("[GroupHold][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1823 #endif//__DETAIL_DEBUG__
1827 //ErrorF("[GroupHold][R] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1828 if( g_pGesture->num_pressed )
1839 if( state == GestureBegin || state == GestureUpdate )
1842 if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) )
1844 GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1849 g_pGesture->recognized_gesture &= ~HoldFilterMask;
1852 g_pGesture->filter_mask |= HoldFilterMask;
1856 base_cx = base_cy = 0;
1858 base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
1859 TimerCancel(hold_event_timer);
1864 GestureEnableDisable()
1866 if((g_pGesture->grabMask) || (g_pGesture->lastSelectedWin != None))
1868 GestureEnable(1, FALSE, g_pGesture->this_device);
1872 GestureEnable(0, FALSE, g_pGesture->this_device);
1877 GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent)
1879 g_pGesture->grabMask = *pGrabMask;
1880 g_pGesture->GrabEvents = pGrabEvent;
1881 GestureEnableDisable();
1885 GestureCbEventsSelected(Window win, Mask *pEventMask)
1887 g_pGesture->lastSelectedWin = win;
1888 g_pGesture->lastSelectedMask = (pEventMask) ? *pEventMask : 0;
1889 GestureEnableDisable();
1893 GestureGetEventsWindow(void)
1898 pWin = GestureWindowOnXY(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py);
1902 #ifdef __DETAIL_DEBUG__
1903 ErrorF("[X11][GestureGetEventsWindow] pWin->drawable.id=0x%x\n", pWin->drawable.id);
1904 #endif//__DETAIL_DEBUG__
1905 g_pGesture->gestureWin = pWin->drawable.id;
1909 #ifdef __DETAIL_DEBUG__
1910 ErrorF("[X11][GestureGetEventsWindow] GestureWindowOnXY returns NULL !\n");
1911 #endif//__DETAIL_DEBUG__
1915 if(g_pGesture->gestureWin == g_pGesture->lastSelectedWin)
1917 g_pGesture->eventMask = g_pGesture->lastSelectedMask;
1918 goto nonempty_eventmask;
1921 //check selected event(s)
1922 if( !GestureHasSelectedEvents(pWin, &g_pGesture->eventMask) )
1924 g_pGesture->eventMask = 0;
1928 g_pGesture->lastSelectedWin = g_pGesture->gestureWin;
1929 g_pGesture->lastSelectedMask = g_pGesture->eventMask;
1932 if( !g_pGesture->eventMask && !g_pGesture->grabMask)
1934 #ifdef __DETAIL_DEBUG__
1935 ErrorF("[X11][GestureGetEventsWindow] No grabbed events or no events were selected for window(0x%x) !\n", pWin->drawable.id);
1936 #endif//__DETAIL_DEBUG__
1942 #ifdef __DETAIL_DEBUG__
1943 ErrorF("[X11][GestureGetEventsWindow] g_pGesture->eventMask=0x%x\n", g_pGesture->eventMask);
1944 #endif//__DETAIL_DEBUG__
1946 mask = (GESTURE_FILTER_MASK_ALL & ~(g_pGesture->grabMask | g_pGesture->eventMask));
1948 #ifdef __DETAIL_DEBUG__
1949 ErrorF("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x, mask=0x%x\n", g_pGesture->filter_mask, mask);
1950 #endif//__DETAIL_DEBUG__
1952 g_pGesture->filter_mask = mask;
1954 #ifdef __DETAIL_DEBUG__
1955 ErrorF("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x\n", g_pGesture->filter_mask);
1956 #endif//__DETAIL_DEBUG__
1962 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
1964 int event_type = *(int *)arg;
1966 switch( event_type )
1968 case GestureNotifyHold:
1969 #ifdef __DETAIL_DEBUG__
1970 ErrorF("[GestureEventTimerHandler] GestureNotifyHold (event_type = %d)\n", event_type);
1971 #endif//__DETAIL_DEBUG__
1972 GestureRecognize_GroupHold(event_type, NULL, NULL, 0, 1);
1975 case GestureNotifyPan:
1976 #ifdef __DETAIL_DEBUG__
1977 ErrorF("[GestureEventTimerHandler] GestureNotifyPan (event_type = %d)\n", event_type);
1978 #endif//__DETAIL_DEBUG__
1979 GestureRecognize_GroupPan(event_type, NULL, NULL, 0, 1);
1982 case GestureNotifyTap:
1983 #ifdef __DETAIL_DEBUG__
1984 ErrorF("[GestureEventTimerHandler] GestureNotifyTap (event_type = %d)\n", event_type);
1985 #endif//__DETAIL_DEBUG__
1986 GestureRecognize_GroupTap(event_type, NULL, NULL, 0, 1);
1989 case GestureNotifyTapNHold:
1990 #ifdef __DETAIL_DEBUG__
1991 ErrorF("[GestureEventTimerHandler] GestureNotifyTapNHold (event_type = %d)\n", event_type);
1992 #endif//__DETAIL_DEBUG__
1993 GestureRecognize_GroupTapNHold(event_type, NULL, NULL, 0, 1);
1996 case GestureNotifyPinchRotation:
1997 #ifdef __DETAIL_DEBUG__
1998 ErrorF("[GestureEventTimerHandler] GestureNotifyPinchRotation (event_type = %d)\n", event_type);
1999 #endif//__DETAIL_DEBUG__
2000 GestureRecognize_GroupPinchRotation(event_type, NULL, NULL, 0, 1);
2004 #ifdef __DETAIL_DEBUG__
2005 ErrorF("[GestureEventTimerHandler] unknown event_type (=%d)\n", event_type);
2006 #endif//__DETAIL_DEBUG__
2008 ErrorF("[GestureEventTimerHandler] timer=%x\n", (unsigned int)timer);
2015 GestureSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2017 g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
2018 g_pGesture->recognized_gesture = 0;
2020 if( ERROR_INVALPTR == GestureFlushOrDrop() )
2022 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2025 #ifdef __DETAIL_DEBUG__
2026 ErrorF("[X11][Single] expired !\n");
2027 #endif//__DETAIL_DEBUG__
2033 GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
2036 static OsTimerPtr single_finger_timer = NULL;
2039 if( PROPAGATE_EVENTS == g_pGesture->ehtype ||
2040 device->id < g_pGesture->first_fingerid )
2043 for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
2045 if( device->id == g_pGesture->mt_devices[i]->id )
2057 case ET_ButtonPress:
2059 g_pGesture->event_sum[0] = BTN_PRESSED;
2060 g_pGesture->fingers[idx].ptime = ev->any.time;
2061 g_pGesture->fingers[idx].px = ev->device_event.root_x;
2062 g_pGesture->fingers[idx].py = ev->device_event.root_y;
2064 g_pGesture->num_pressed++;
2065 if( g_pGesture->num_pressed == 1 )
2067 single_finger_timer = TimerSet(single_finger_timer, 0, 50, GestureSingleFingerTimerHandler, NULL);
2071 TimerCancel(single_finger_timer);
2074 if( g_pGesture->num_pressed > g_pGesture->num_mt_devices )
2075 g_pGesture->num_pressed = g_pGesture->num_mt_devices;
2077 if( !g_pGesture->pTempWin || g_pGesture->num_pressed != g_pGesture->inc_num_pressed )
2079 g_pGesture->pTempWin = GestureGetEventsWindow();
2081 if( NULL == g_pGesture->pTempWin )
2083 #ifdef __DETAIL_DEBUG__
2084 ErrorF("[X11][GestureRecognize][g_pGesture->num_pressed=%d] No events were selected !\n", g_pGesture->num_pressed);
2085 #endif//__DETAIL_DEBUG__
2086 g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
2091 g_pGesture->inc_num_pressed = g_pGesture->num_pressed;
2093 g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
2094 g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
2095 g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT;
2096 g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT;
2098 if( g_pGesture->inc_num_pressed == 1 )
2100 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2101 #ifdef __DETAIL_DEBUG__
2102 ErrorF("[P][g_pGesture->inc_num_pressed=1] AREA_SIZE(area.extents)=%d\n", AREA_SIZE(&g_pGesture->area.extents));
2103 #endif//__DETAIL_DEBUG__
2107 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2108 for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ )
2110 pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
2112 #ifdef __DETAIL_DEBUG__
2113 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));
2114 #endif//__DETAIL_DEBUG__
2119 if( !g_pGesture->fingers[idx].ptime )
2122 g_pGesture->fingers[idx].mx = ev->device_event.root_x;
2123 g_pGesture->fingers[idx].my = ev->device_event.root_y;
2125 if( idx == 0 && g_pGesture->event_sum[0] )
2127 g_pGesture->event_sum[0] += BTN_MOVING;
2128 #ifdef __DETAIL_DEBUG__
2129 ErrorF("[X11][GestureRecognize] moving !\n");
2130 #endif//__DETAIL_DEBUG__
2131 if( g_pGesture->event_sum[0] >= 7 )
2133 if( (g_pGesture->event_sum[0] >= 7) && (g_pGesture->inc_num_pressed < 2) )
2135 #ifdef __DETAIL_DEBUG__
2136 ErrorF("[X11][GestureRecognize] moving limit!\n");
2137 #endif//__DETAIL_DEBUG__
2138 g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
2144 g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
2145 g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
2146 g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT;
2147 g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT;
2149 if( g_pGesture->inc_num_pressed == 1 )
2151 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2152 #ifdef __DETAIL_DEBUG__
2153 ErrorF("[M][g_pGesture->inc_num_pressed=1] AREA_SIZE(area)=%d\n", AREA_SIZE(&g_pGesture->area.extents));
2154 #endif//__DETAIL_DEBUG__
2158 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2159 for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ )
2161 pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
2163 #ifdef __DETAIL_DEBUG__
2164 ErrorF("[M][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents));
2165 #endif//__DETAIL_DEBUG__
2169 case ET_ButtonRelease:
2170 g_pGesture->fingers[idx].rtime = ev->any.time;
2171 g_pGesture->fingers[idx].rx = ev->device_event.root_x;
2172 g_pGesture->fingers[idx].ry = ev->device_event.root_y;
2174 g_pGesture->num_pressed--;
2175 if( g_pGesture->num_pressed <= 0 )
2177 #ifdef __DETAIL_DEBUG__
2178 ErrorF("[X11][GestureRecognize] All fingers were released !\n");
2179 #endif//__DETAIL_DEBUG__
2180 if( g_pGesture->inc_num_pressed == 1 )
2186 if( g_pGesture->filter_mask != GESTURE_FILTER_MASK_ALL )
2188 if( !(g_pGesture->filter_mask & FlickFilterMask) )
2190 GestureRecognize_GroupFlick(type, ev, device, idx);
2192 if( !(g_pGesture->filter_mask & PanFilterMask) )
2194 GestureRecognize_GroupPan(type, ev, device, idx, 0);
2196 if( !(g_pGesture->filter_mask & PinchRotationFilterMask) )
2198 GestureRecognize_GroupPinchRotation(type, ev, device, idx, 0);
2200 if( !(g_pGesture->filter_mask & TapFilterMask) )
2202 GestureRecognize_GroupTap(type, ev, device, idx, 0);
2204 if( !(g_pGesture->filter_mask & TapNHoldFilterMask) )
2206 GestureRecognize_GroupTapNHold(type, ev, device, idx, 0);
2208 if( !(g_pGesture->filter_mask & HoldFilterMask) )
2210 GestureRecognize_GroupHold(type, ev, device, idx, 0);
2214 #ifdef __DETAIL_DEBUG__
2215 ErrorF("[X11][GestureRecognize][N] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask);
2216 ErrorF("[X11][GestureRecognize][N] g_pGesture->GESTURE_FILTER_MASK_ALL = 0x%x\n", GESTURE_FILTER_MASK_ALL);
2217 ErrorF("[X11][GestureRecognize][N] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture);
2218 #endif//__DETAIL_DEBUG__
2220 if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
2222 if( !g_pGesture->recognized_gesture )
2224 else if( !g_pGesture->num_pressed )
2228 if( g_pGesture->recognized_gesture )
2230 if( g_pGesture->ehtype == KEEP_EVENTS )
2231 GestureEventsDrop();
2232 g_pGesture->ehtype = IGNORE_EVENTS;
2239 #ifdef __DETAIL_DEBUG__
2240 ErrorF("[GestureRecognize] GestureFlushOrDrop() !\n");
2241 #endif//__DETAIL_DEBUG__
2242 if( ERROR_INVALPTR == GestureFlushOrDrop() )
2244 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2249 ErrorStatus GestureFlushOrDrop(void)
2253 if( g_pGesture->recognized_gesture )
2255 GestureEventsDrop();
2259 g_pGesture->ehtype = PROPAGATE_EVENTS;
2261 err = GestureEventsFlush();
2262 if( ERROR_NONE != err )
2265 #ifdef __DETAIL_DEBUG__
2266 ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask);
2267 ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->GESTURE_FILTER_MASK_ALL = 0x%x\n", GESTURE_FILTER_MASK_ALL);
2268 ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture);
2269 #endif//__DETAIL_DEBUG__
2272 err = GestureRegionsReinit();
2273 if( ERROR_NONE != err )
2276 g_pGesture->pTempWin = NULL;
2277 g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0;
2278 g_pGesture->event_sum[0] = 0;
2284 GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2288 #ifdef __DEBUG_EVENT_HANDLER__
2289 ErrorF("\n[X11][GestureHandleMTSyncEvent] (%d:%d) time:%d cur:%d\n",
2290 ev->any_event.deviceid, ev->any_event.sync, (int)ev->any.time, (int)GetTimeInMillis());
2291 #endif//__DEBUG_EVENT_HANDLER__
2293 if( MTOUCH_FRAME_SYNC_BEGIN == ev->any_event.sync )
2295 g_pGesture->ehtype = KEEP_EVENTS;
2296 g_pGesture->filter_mask = 0;
2297 g_pGesture->recognized_gesture = 0;
2298 g_pGesture->num_pressed = 0;
2300 for( i=0 ; i < g_pGesture->num_mt_devices ; i++ )
2301 g_pGesture->fingers[i].ptime = 0;
2303 else if( MTOUCH_FRAME_SYNC_END == ev->any_event.sync )
2305 g_pGesture->ehtype = PROPAGATE_EVENTS;
2310 GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2312 #ifdef __DEBUG_EVENT_HANDLER__
2313 ErrorF("[X11][GestureHandleButtonPEvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
2314 #endif//__DEBUG_EVENT_HANDLER__
2316 switch( g_pGesture->ehtype )
2319 if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device) )
2321 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2325 if( g_pGesture->num_mt_devices )
2326 GestureRecognize(ET_ButtonPress, ev, device);
2328 device->public.processInputProc(ev, device);
2331 case PROPAGATE_EVENTS:
2332 device->public.processInputProc(ev, device);
2336 GestureRecognize(ET_ButtonPress, ev, device);
2345 GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2347 #ifdef __DEBUG_EVENT_HANDLER__
2348 ErrorF("[X11][GestureHandleMotionEvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
2349 #endif//__DEBUG_EVENT_HANDLER__
2351 switch( g_pGesture->ehtype )
2354 if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device) )
2356 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2360 if( g_pGesture->num_mt_devices )
2361 GestureRecognize(ET_Motion, ev, device);
2363 device->public.processInputProc(ev, device);
2366 case PROPAGATE_EVENTS:
2367 device->public.processInputProc(ev, device);
2371 GestureRecognize(ET_Motion, ev, device);
2381 GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2383 #ifdef __DEBUG_EVENT_HANDLER__
2384 ErrorF("[X11][GestureHandleButtonREvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
2385 #endif//__DEBUG_EVENT_HANDLER__
2387 switch( g_pGesture->ehtype )
2390 if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device) )
2392 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2396 if( g_pGesture->num_mt_devices )
2397 GestureRecognize(ET_ButtonRelease, ev, device);
2399 device->public.processInputProc(ev, device);
2402 case PROPAGATE_EVENTS:
2403 device->public.processInputProc(ev, device);
2407 GestureRecognize(ET_ButtonRelease, ev, device);
2416 GestureEnableEventHandler(InputInfoPtr pInfo)
2419 GestureDevicePtr pGesture = pInfo->private;
2421 res = GestureInstallResourceStateHooks();
2425 ErrorF("[X11][GestureEnableEventHandler] Failed on GestureInstallResourceStateHooks() !\n");
2426 return ERROR_ABNORMAL;
2429 res = GestureSetMaxNumberOfFingers((int)MAX_MT_DEVICES);
2433 ErrorF("[X11][GestureEnableEventHandler] Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)MAX_MT_DEVICES);
2437 res = GestureRegisterCallbacks(GestureCbEventsGrabbed, GestureCbEventsSelected);
2441 ErrorF("[X11][GestureEnableEventHandler] Failed to register callbacks for GestureEventsGrabbed(), GestureEventsSelected() !\n");
2445 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 5000, GestureTimerHandler, pInfo);
2447 if( !pGesture->device_setting_timer )
2449 ErrorF("[X11][GestureEnableEventHandler] Failed to allocate memory for timer !\n");
2456 GestureUninstallResourceStateHooks();
2457 GestureUnsetMaxNumberOfFingers();
2459 return ERROR_ABNORMAL;
2463 GestureDisableEventHandler(void)
2465 ErrorStatus err = ERROR_NONE;
2467 mieqSetHandler(ET_ButtonPress, NULL);
2468 mieqSetHandler(ET_ButtonRelease, NULL);
2469 mieqSetHandler(ET_Motion, NULL);
2470 mieqSetHandler(ET_MTSync, NULL);
2472 err = GestureFiniEQ();
2474 if( ERROR_INVALPTR == err )
2476 ErrorF("[X11][GestureDisableEventHandler] EQ is invalid or was freed already !\n");
2479 GestureRegisterCallbacks(NULL, NULL);
2480 GestureUninstallResourceStateHooks();
2486 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2488 InputInfoPtr pInfo = (InputInfoPtr)arg;
2489 GestureDevicePtr pGesture = pInfo->private;
2493 for( dev = inputInfo.pointer ; dev; dev = dev->next )
2495 if(IsMaster(dev) && IsPointerDevice(dev))
2497 pGesture->master_pointer = dev;
2498 ErrorF("[X11][GestureTimerHandler][id:%d] Master Pointer=%s\n", dev->id, pGesture->master_pointer->name);
2502 if(IsXTestDevice(dev, NULL) && IsPointerDevice(dev))
2504 pGesture->xtest_pointer = dev;
2505 ErrorF("[X11][GestureTimerHandler][id:%d] XTest Pointer=%s\n", dev->id, pGesture->xtest_pointer->name);
2509 if(IsPointerDevice(dev))
2511 if( idx >= MAX_MT_DEVICES )
2513 ErrorF("[X11][GestureTimerHandler] Number of mt device is over MAX_MT_DEVICES(%d) !\n",
2517 pGesture->mt_devices[idx] = dev;
2518 ErrorF("[X11][GestureTimerHandler][id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name);
2523 if( !pGesture->master_pointer || !pGesture->xtest_pointer )
2525 ErrorF("[X11][GestureTimerHandler] Failed to get info of master pointer or XTest pointer !\n");
2526 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
2527 pGesture->num_mt_devices = 0;
2532 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
2533 pGesture->num_mt_devices = idx;
2535 if( !pGesture->num_mt_devices )
2537 ErrorF("[X11][GestureTimerHandler] Failed to mt device information !\n");
2538 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
2539 pGesture->num_mt_devices = 0;
2540 pGesture->first_fingerid = -1;
2544 pGesture->first_fingerid = pGesture->mt_devices[0]->id;
2545 memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices);
2546 pGesture->pRootWin = RootWindow(pGesture->master_pointer);
2547 g_pGesture->pTempWin = NULL;
2548 g_pGesture->inc_num_pressed = 0;
2550 if( ERROR_NONE != GestureRegionsInit() || ERROR_NONE != GestureInitEQ() )
2555 mieqSetHandler(ET_ButtonPress, GestureHandleButtonPressEvent);
2556 mieqSetHandler(ET_ButtonRelease, GestureHandleButtonReleaseEvent);
2557 mieqSetHandler(ET_Motion, GestureHandleMotionEvent);
2559 if( pGesture->is_active )
2560 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
2566 GestureUninstallResourceStateHooks();
2567 GestureUnsetMaxNumberOfFingers();
2573 IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
2579 return (dev->xtest_master_id == master->id);
2581 return (dev->xtest_master_id != 0);
2585 GestureEnable(int enable, Bool prop, DeviceIntPtr dev)
2587 if((!enable) && (g_pGesture->is_active))
2589 g_pGesture->ehtype = PROPAGATE_EVENTS;
2590 mieqSetHandler(ET_MTSync, NULL);
2591 g_pGesture->is_active = 0;
2592 ErrorF("[X11][GestureEnable] Disabled !\n");
2594 else if((enable) && (!g_pGesture->is_active))
2596 g_pGesture->ehtype = KEEP_EVENTS;
2597 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
2598 g_pGesture->is_active = 1;
2599 ErrorF("[X11][GestureEnable] Enabled !\n");
2603 XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
2607 GestureRegionsInit(void)
2612 return ERROR_INVALPTR;
2614 pixman_region_init(&g_pGesture->area);
2616 for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
2618 pixman_region_init_rect (&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
2625 GestureRegionsReinit(void)
2629 ErrorF("[X11][GestureRegionsReinit] Invalid pointer access !\n");
2630 return ERROR_INVALPTR;
2633 pixman_region_init(&g_pGesture->area);
2644 tmpEQ = (IEventRec *)calloc(GESTURE_EQ_SIZE, sizeof(IEventRec));
2648 ErrorF("[X11][GestureInitEQ] Failed to allocate memory for EQ !\n");
2649 return ERROR_ALLOCFAIL;
2652 for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
2654 tmpEQ[i].event = (InternalEvent *)malloc(sizeof(InternalEvent));
2655 if( !tmpEQ[i].event )
2657 ErrorF("[X11][GestureInitEQ] Failed to allocation memory for each event buffer in EQ !\n");
2659 while(i >= 0 && tmpEQ[i].event)
2661 free(tmpEQ[i].event);
2662 tmpEQ[i].event = NULL;
2666 return ERROR_ALLOCFAIL;
2670 g_pGesture->EQ = tmpEQ;
2671 g_pGesture->headEQ = g_pGesture->tailEQ = 0;
2681 if( !g_pGesture || !g_pGesture->EQ )
2682 return ERROR_INVALPTR;
2684 for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
2686 if( g_pGesture->EQ[i].event )
2688 free(g_pGesture->EQ[i].event);
2689 g_pGesture->EQ[i].event = NULL;
2693 free(g_pGesture->EQ);
2694 g_pGesture->EQ = NULL;
2700 GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2704 if( !g_pGesture || !g_pGesture->EQ )
2706 ErrorF("[X11][GestureEnqueueEvent] Invalid pointer access !\n");
2707 return ERROR_INVALPTR;
2710 tail = g_pGesture->tailEQ;
2712 if( tail >= GESTURE_EQ_SIZE )
2714 ErrorF("[X11][GestureEnqueueEvent] Gesture EQ is full !\n");
2715 printk("[X11][GestureEnqueueEvent] Gesture EQ is full...Force Gesture Flush !\n");
2716 GestureEventsFlush();
2717 return ERROR_EQFULL;
2720 #ifdef __DETAIL_DEBUG__
2721 switch( ev->any.type )
2723 case ET_ButtonPress:
2724 ErrorF("[X11][GestureEnqueueEvent] ET_ButtonPress (id:%d)\n", device->id);
2727 case ET_ButtonRelease:
2728 ErrorF("[X11][GestureEnqueueEvent] ET_ButtonRelease (id:%d)\n", device->id);
2732 ErrorF("[X11][GestureEnqueueEvent] ET_Motion (id:%d)\n", device->id);
2735 #endif//__DETAIL_DEBUG__
2737 g_pGesture->EQ[tail].device = device;
2738 g_pGesture->EQ[tail].screen_num = screen_num;
2739 memcpy(g_pGesture->EQ[tail].event, ev, sizeof(InternalEvent));//need to be optimized
2740 g_pGesture->tailEQ++;
2746 GestureEventsFlush(void)
2749 DeviceIntPtr device;
2751 if( !g_pGesture->EQ )
2753 ErrorF("[X11][GestureEventsFlush] Invalid pointer access !\n");
2754 return ERROR_INVALPTR;
2757 #ifdef __DETAIL_DEBUG__
2758 ErrorF("[X11][GestureEventsFlush]\n");
2759 #endif//__DETAIL_DEBUG__
2761 for( i = g_pGesture->headEQ ; i < g_pGesture->tailEQ ; i++)
2763 device = g_pGesture->EQ[i].device;
2764 device->public.processInputProc(g_pGesture->EQ[i].event, device);
2767 for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
2768 g_pGesture->event_sum[i] = 0;
2770 g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
2776 GestureEventsDrop(void)
2778 g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
2781 #ifdef HAVE_PROPERTIES
2783 GestureInitProperty(DeviceIntPtr dev)
2787 prop_gesture_recognizer_onoff = MakeAtom(GESTURE_RECOGNIZER_ONOFF, strlen(GESTURE_RECOGNIZER_ONOFF), TRUE);
2788 rc = XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
2793 XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE);
2797 GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
2800 InputInfoPtr pInfo = dev->public.devicePrivate;
2802 if( prop_gesture_recognizer_onoff == atom )
2805 if( val->format != 32 || val->type != XA_INTEGER || val->size != 1 )
2810 data = *((int *)val->data);
2811 GestureEnable(data, TRUE, dev);
2817 #endif//HAVE_PROPERTIES
2820 GestureInit(DeviceIntPtr device)
2823 pInfo = device->public.devicePrivate;
2825 #ifdef HAVE_PROPERTIES
2826 GestureInitProperty(device);
2827 XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL);
2834 GestureFini(DeviceIntPtr device)
2836 XIRegisterPropertyHandler(device, NULL, NULL, NULL);
2840 GesturePlug(pointer module, pointer options, int *errmaj, int *errmin)
2842 xf86AddInputDriver(&GESTURE, module, 0);
2847 GestureUnplug(pointer p)
2852 GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
2855 GestureDevicePtr pGesture;
2857 pGesture = calloc(1, sizeof(GestureDeviceRec));
2860 pInfo->private = NULL;
2861 //xf86DeleteInput(pInfo, 0);
2865 g_pGesture = pGesture;
2866 pInfo->private = pGesture;
2868 pInfo->read_input = GestureReadInput; /* new data avl */
2869 pInfo->switch_mode = NULL; /* toggle absolute/relative mode */
2870 pInfo->device_control = GestureControl; /* enable/disable dev */
2871 /* process driver specific options */
2872 pGesture->device = xf86SetStrOption(pInfo->options, "Device", "/dev/null");
2873 pGesture->is_active = xf86SetIntOption(pInfo->options, "Activate", 0);
2874 pGesture->gestureWin = None;
2875 pGesture->lastSelectedWin = None;
2876 g_pGesture->grabMask = g_pGesture->eventMask = 0;
2878 xf86Msg(X_INFO, "%s: Using device %s.\n", pInfo->name, pGesture->device);
2880 /* process generic options */
2881 xf86CollectInputOptions(pInfo, NULL);
2882 xf86ProcessCommonOptions(pInfo, pInfo->options);
2895 GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
2897 GestureDevicePtr pGesture = pInfo->private;
2899 g_pGesture = pGesture = NULL;
2900 pInfo->private = NULL;
2902 xf86DeleteInput(pInfo, 0);
2906 GestureControl(DeviceIntPtr device, int what)
2908 InputInfoPtr pInfo = device->public.devicePrivate;
2909 GestureDevicePtr pGesture = pInfo->private;
2914 GestureInit(device);
2917 /* Switch device on. Establish socket, start event delivery. */
2919 xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
2921 if (device->public.on)
2924 device->public.on = TRUE;
2925 pGesture->this_device = device;
2926 pGesture->num_mt_devices = 0;
2927 if( ERROR_ABNORMAL == GestureEnableEventHandler(pInfo) )
2933 GestureDisableEventHandler();
2934 GestureFini(device);
2935 pGesture->this_device = NULL;
2936 xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
2938 if (!device->public.on)
2942 device->public.on = FALSE;
2946 /* free what we have to free */
2953 GestureReadInput(InputInfoPtr pInfo)