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 WindowPtr GestureWindowOnXY(int x, int y);
115 Bool GestureHasFingerEventMask(int eventType, int num_finger);
116 static double get_angle(int x1, int y1, int x2, int y2);
118 //Gesture recognizer and handlers
119 void GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
120 void GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx);
121 void GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
122 void GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
123 void GestureRecognize_GroupTapNHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
124 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
125 void GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction);
126 void GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy);
127 void GestureHandleGesture_PinchRotation(int num_of_fingers, double zoom, double angle, int distance, int cx, int cy, int kinds);
128 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds);
129 void GestureHandleGesture_TapNHold(int num_fingers, int cx, int cy, Time interval, Time holdtime, int kinds);
130 void GestureHandleGesture_Pan(int num_fingers, short int dx, short int dy, int direction, int distance, Time duration, int kinds);
131 void GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device);
132 ErrorStatus GestureFlushOrDrop(void);
134 #ifdef HAVE_PROPERTIES
135 //function related property handling
136 static void GestureInitProperty(DeviceIntPtr dev);
137 static int GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkonly);
140 static Atom prop_gesture_recognizer_onoff = None;
142 GestureDevicePtr g_pGesture = NULL;
143 _X_EXPORT InputDriverRec GESTURE = {
153 static XF86ModuleVersionInfo GestureVersionRec =
159 XORG_VERSION_CURRENT,
160 PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR,
161 PACKAGE_VERSION_PATCHLEVEL,
168 _X_EXPORT XF86ModuleData gestureModuleData =
176 printk(const char* fmt, ...)
178 static FILE* fp = NULL;
179 static char init = 0;
184 fp = fopen("/dev/kmsg", "wt");
190 va_start(argptr, fmt);
191 vfprintf(fp, fmt, argptr);
197 GestureWindowOnXY(int x, int y)
202 DeviceIntPtr pDev = g_pGesture->master_pointer;
204 pSprite = pDev->spriteInfo->sprite;
205 pSprite->spriteTraceGood = 1; /* root window still there */
206 pWin = RootWindow(pDev)->firstChild;
210 if ((pWin->mapped) &&
211 (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
212 (x < pWin->drawable.x + (int)pWin->drawable.width +
213 wBorderWidth(pWin)) &&
214 (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
215 (y < pWin->drawable.y + (int)pWin->drawable.height +
217 /* When a window is shaped, a further check
218 * is made to see if the point is inside
221 && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
222 && (!wInputShape(pWin) ||
223 RegionContainsPoint(wInputShape(pWin),
224 x - pWin->drawable.x,
225 y - pWin->drawable.y, &box))
227 /* In rootless mode windows may be offscreen, even when
228 * they're in X's stack. (E.g. if the native window system
229 * implements some form of virtual desktop system).
231 && !pWin->rootlessUnhittable
235 if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
237 pSprite->spriteTraceSize += 10;
238 pSprite->spriteTrace = realloc(pSprite->spriteTrace,
239 pSprite->spriteTraceSize*sizeof(WindowPtr));
241 pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
242 pWin = pWin->firstChild;
245 pWin = pWin->nextSib;
247 return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
251 GestureHasFingerEventMask(int eventType, int num_finger)
254 Mask eventmask = (1L << eventType);
256 if( (g_pGesture->grabMask & eventmask) &&
257 (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[num_finger].window != None) )
259 #ifdef __DETAIL_DEBUG__
260 ErrorF("[X11][GestureHasFingerEventMask] TRUE !! Has grabMask\n");
261 #endif//__DETAIL_DEBUG__
265 if( g_pGesture->eventMask & eventmask )
267 #ifdef __DETAIL_DEBUG__
268 ErrorF("[X11][GestureHasFingerEventMask] TRUE !! Has eventMask\n");
269 #endif//__DETAIL_DEBUG__
273 #ifdef __DETAIL_DEBUG__
274 ErrorF("[X11][GestureHasFingerEventMask] FALSE !! eventType=%d, num_finger=%d\n", eventType, num_finger);
275 #endif//__DETAIL_DEBUG__
281 get_angle(int x1, int y1, int x2, int y2)
287 if (((int) xx) && ((int) yy))
294 return (RAD_360DEG - a);
305 return (RAD_180DEG + a);
309 return (RAD_180DEG - a);
315 { /* Horizontal line */
338 GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction)
341 WindowPtr target_pWin;
342 xGestureNotifyFlickEvent fev;
344 #ifdef __DETAIL_DEBUG__
345 ErrorF("[X11][GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n",
346 num_of_fingers, distance, duration, direction);
347 #endif//__DETAIL_DEBUG__
349 g_pGesture->recognized_gesture |= FlickFilterMask;
350 memset(&fev, 0, sizeof(xGestureNotifyFlickEvent));
351 fev.type = GestureNotifyFlick;
352 fev.kind = GestureDone;
353 fev.num_finger = num_of_fingers;
354 fev.distance = distance;
355 fev.duration = duration;
356 fev.direction = direction;
358 target_win = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].window;
359 target_pWin = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].pWin;
361 if( g_pGesture->grabMask && (target_win != None) )
363 fev.window = target_win;
367 fev.window = g_pGesture->gestureWin;
370 #ifdef __DETAIL_DEBUG__
371 ErrorF("[X11][GestureHandleGesture_Flick] fev.window=0x%x, g_pGesture->grabMask=0x%x\n", fev.window, g_pGesture->grabMask);
372 #endif//__DETAIL_DEBUG__
374 GestureSendEvent(target_pWin, GestureNotifyFlick, GestureFlickMask, (xGestureCommonEvent *)&fev);
378 GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy)
381 WindowPtr target_pWin;
382 xGestureNotifyTapEvent tev;
384 //skip non-tap events and single finger tap
385 if( !tap_repeat || num_finger <= 1 )
388 #ifdef __DETAIL_DEBUG__
389 ErrorF("[X11][GestureHandleGesture_Tap] num_finger=%d, tap_repeat=%d, cx=%d, cy=%d\n",
390 num_finger, tap_repeat, cx, cy);
391 #endif//__DETAIL_DEBUG__
393 g_pGesture->recognized_gesture |= TapFilterMask;
394 memset(&tev, 0, sizeof(xGestureNotifyTapEvent));
395 tev.type = GestureNotifyTap;
396 tev.kind = GestureDone;
397 tev.num_finger = num_finger;
398 tev.tap_repeat = tap_repeat;
403 target_win = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].window;
404 target_pWin = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].pWin;
406 if( g_pGesture->grabMask && (target_win != None) )
408 tev.window = target_win;
412 tev.window = g_pGesture->gestureWin;
415 #ifdef __DETAIL_DEBUG__
416 ErrorF("[X11][GestureHandleGesture_Tap] tev.window=0x%x, g_pGesture->grabMask=0x%x\n", tev.window, g_pGesture->grabMask);
417 #endif//__DETAIL_DEBUG__
419 GestureSendEvent(target_pWin, GestureNotifyTap, GestureTapMask, (xGestureCommonEvent *)&tev);
422 void GestureHandleGesture_PinchRotation(int num_of_fingers, double zoom, double angle, int distance, int cx, int cy, int kinds)
425 WindowPtr target_pWin;
426 xGestureNotifyPinchRotationEvent prev;
428 #ifdef __DETAIL_DEBUG__
429 ErrorF("[X11][GestureHandleGesture_PinchRotation] num_fingers=%d, zoom=%.2f, angle=%.2f(deg=%.2f), distance=%d, cx=%d, cy=%d\n",
430 num_of_fingers, zoom, angle, rad2degree(angle), distance, cx, cy);
431 #endif//__DETAIL_DEBUG__
433 g_pGesture->recognized_gesture |= PinchRotationFilterMask;
434 memset(&prev, 0, sizeof(xGestureNotifyPinchRotationEvent));
435 prev.type = GestureNotifyPinchRotation;
437 prev.num_finger = num_of_fingers;
438 prev.zoom = XDoubleToFixed(zoom);
439 prev.angle = XDoubleToFixed(angle);
440 prev.distance = distance;
444 target_win = g_pGesture->GrabEvents[GestureNotifyPinchRotation].pGestureGrabWinInfo[num_of_fingers].window;
445 target_pWin = g_pGesture->GrabEvents[GestureNotifyPinchRotation].pGestureGrabWinInfo[num_of_fingers].pWin;
447 if( g_pGesture->grabMask && (target_win != None) )
449 prev.window = target_win;
453 prev.window = g_pGesture->gestureWin;
456 #ifdef __DETAIL_DEBUG__
457 ErrorF("[X11][GestureHandleGesture_PinchRotation] prev.window=0x%x, g_pGesture->grabMask=0x%x\n", (unsigned int)prev.window, (unsigned int)g_pGesture->grabMask);
458 #endif//__DETAIL_DEBUG__
460 GestureSendEvent(target_pWin, GestureNotifyPinchRotation, GesturePinchRotationMask, (xGestureCommonEvent *)&prev);
463 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds)
466 WindowPtr target_pWin;
467 xGestureNotifyHoldEvent hev;
469 #ifdef __DETAIL_DEBUG__
470 ErrorF("[X11][GestureHandleGesture_Hold] num_fingers=%d, cx=%d, cy=%d, holdtime=%d, kinds=%d\n",
471 num_fingers, cx, cy, holdtime, kinds);
472 #endif//__DETAIL_DEBUG__
474 g_pGesture->recognized_gesture |= HoldFilterMask;
475 memset(&hev, 0, sizeof(xGestureNotifyHoldEvent));
476 hev.type = GestureNotifyHold;
478 hev.num_finger = num_fingers;
479 hev.holdtime = holdtime;
483 target_win = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].window;
484 target_pWin = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].pWin;
486 if( g_pGesture->grabMask && (target_win != None) )
488 hev.window = target_win;
492 hev.window = g_pGesture->gestureWin;
495 #ifdef __DETAIL_DEBUG__
496 ErrorF("[X11][GestureHandleGesture_Hold] hev.window=0x%x, g_pGesture->grabMask=0x%x\n", hev.window, g_pGesture->grabMask);
497 #endif//__DETAIL_DEBUG__
499 GestureSendEvent(target_pWin, GestureNotifyHold, GestureHoldMask, (xGestureCommonEvent *)&hev);
502 void GestureHandleGesture_TapNHold(int num_fingers, int cx, int cy, Time interval, Time holdtime, int kinds)
505 WindowPtr target_pWin;
506 xGestureNotifyTapNHoldEvent thev;
508 #ifdef __DETAIL_DEBUG__
509 ErrorF("[X11][GestureHandleGesture_TapNHold] num_fingers=%d, cx=%d, cy=%d, interval=%d, holdtime=%d, kinds=%d\n",
510 num_fingers, cx, cy, interval, holdtime, kinds);
511 #endif//__DETAIL_DEBUG__
513 g_pGesture->recognized_gesture |= TapNHoldFilterMask;
514 memset(&thev, 0, sizeof(xGestureNotifyTapNHoldEvent));
515 thev.type = GestureNotifyTapNHold;
517 thev.num_finger = num_fingers;
518 thev.holdtime = holdtime;
521 thev.interval = interval;
523 target_win = g_pGesture->GrabEvents[GestureNotifyTapNHold].pGestureGrabWinInfo[num_fingers].window;
524 target_pWin = g_pGesture->GrabEvents[GestureNotifyTapNHold].pGestureGrabWinInfo[num_fingers].pWin;
526 if( g_pGesture->grabMask && (target_win != None) )
528 thev.window = target_win;
532 thev.window = g_pGesture->gestureWin;
535 #ifdef __DETAIL_DEBUG__
536 ErrorF("[X11][GestureHandleGesture_TapNHold] thev.window=0x%x, g_pGesture->grabMask=0x%x\n", thev.window, g_pGesture->grabMask);
537 #endif//__DETAIL_DEBUG__
539 GestureSendEvent(target_pWin, GestureNotifyTapNHold, GestureTapNHoldMask, (xGestureCommonEvent *)&thev);
542 void GestureHandleGesture_Pan(int num_fingers, short int dx, short int dy, int direction, int distance, Time duration, int kinds)
545 WindowPtr target_pWin;
546 xGestureNotifyPanEvent pev;
548 #ifdef __DETAIL_DEBUG__
549 ErrorF("[X11][GestureHandleGesture_Pan] num_fingers=%d, dx=%d, dy=%d, direction=%d, distance=%d, duration=%d, kinds=%d\n",
550 num_fingers, dx, dy, direction, distance, duration, kinds);
551 #endif//__DETAIL_DEBUG__
553 g_pGesture->recognized_gesture |= PanFilterMask;
554 memset(&pev, 0, sizeof(xGestureNotifyPanEvent));
555 pev.type = GestureNotifyPan;
557 pev.num_finger = num_fingers;
558 pev.direction = direction;
559 pev.distance = distance;
560 pev.duration = duration;
564 target_win = g_pGesture->GrabEvents[GestureNotifyPan].pGestureGrabWinInfo[num_fingers].window;
565 target_pWin = g_pGesture->GrabEvents[GestureNotifyPan].pGestureGrabWinInfo[num_fingers].pWin;
567 if( g_pGesture->grabMask && (target_win != None) )
569 pev.window = target_win;
573 pev.window = g_pGesture->gestureWin;
576 #ifdef __DETAIL_DEBUG__
577 ErrorF("[X11][GestureHandleGesture_Pan] pev.window=0x%x, g_pGesture->grabMask=0x%x\n", pev.window, g_pGesture->grabMask);
578 #endif//__DETAIL_DEBUG__
580 GestureSendEvent(target_pWin, GestureNotifyPan, GesturePanMask, (xGestureCommonEvent *)&pev);
584 GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
588 static int num_pressed = 0;
589 static int state = GestureEnd;
590 static int event_type = GestureNotifyPinchRotation;
591 static OsTimerPtr pinchrotation_event_timer = NULL;
593 static pixman_region16_t base_area;
594 static pixman_region16_t cur_area;
596 static double base_distance = 0.0f;
597 static double base_angle = 0.0f;
599 static double prev_distance = 0.0f;
600 static double prev_angle = 0.0f;
602 static double cur_distance = 0.0f;
603 static double cur_angle = 0.0f;
605 double diff_distance = 0.0f;
606 double diff_angle = 0.0f;
608 static int has_event_mask = 0;
610 static Time base_time = 0;
615 if( state == GestureEnd )
617 current_time = GetTimeInMillis();
618 if( (current_time - base_time) >= PINCHROTATION_TIME_THRESHOLD )
620 #ifdef __DETAIL_DEBUG__
621 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);
622 #endif//__DETAIL_DEBUG__
623 goto cleanup_pinchrotation;
633 g_pGesture->fingers[idx].flags |= PressFlagPinchRotation;
635 if( g_pGesture->num_pressed < 2 )
638 if( g_pGesture->num_pressed < num_pressed && state != GestureEnd )
640 #ifdef __DETAIL_DEBUG__
641 ErrorF("[GroupPinchRotation][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
642 #endif//__DETAIL_DEBUG__
643 goto cleanup_pinchrotation;
646 if( base_distance == 0.0f && g_pGesture->num_pressed == 2 )
648 #ifdef __DETAIL_DEBUG__
649 ErrorF("[GroupPinchRotation][First Time !!!] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
650 #endif//__DETAIL_DEBUG__
652 base_time = GetTimeInMillis();
653 pixman_region_init(&base_area);
654 pixman_region_union(&base_area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[1]);
656 prev_distance = base_distance = AREA_DIAG_LEN(&base_area.extents);
658 #ifdef __DETAIL_DEBUG__
659 ErrorF("[GroupPinchRotation][P] x1=%d, x2=%d, y1=%d, y2=%d\n", g_pGesture->fingers[0].px, g_pGesture->fingers[1].px,
660 g_pGesture->fingers[0].py, g_pGesture->fingers[1].py);
661 #endif//__DETAIL_DEBUG__
663 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);
664 #ifdef __DETAIL_DEBUG__
665 ErrorF("[GroupPinchRotation][P] base_angle=%.2f(deg=%.2f)\n", base_angle, rad2degree(base_angle));
666 #endif//__DETAIL_DEBUG__
667 event_type = GestureNotifyPinchRotation;
668 pinchrotation_event_timer = TimerSet(pinchrotation_event_timer, 0, PINCHROTATION_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
670 num_pressed = g_pGesture->num_pressed;
672 #ifdef __DETAIL_DEBUG__
673 ErrorF("[GroupPinchRotation][P][num_pressed=%d] AREA_SIZE(base_area.extents)=%d\n", num_pressed, AREA_SIZE(&base_area.extents));
674 ErrorF("[GroupPinchRotation][P][num_pressed=%d] base_distance=%.2f, base_angle=%.2f(deg=%.2f)\n", num_pressed, base_distance, base_angle, rad2degree(base_angle));
675 #endif//__DETAIL_DEBUG__
679 if( !(g_pGesture->fingers[idx].flags & PressFlagPinchRotation) )
682 if( (num_pressed != g_pGesture->num_pressed) && (state != GestureEnd) )
684 #ifdef __DETAIL_DEBUG__
685 ErrorF("[GroupPinchRotation][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
686 #endif//__DETAIL_DEBUG__
687 goto cleanup_pinchrotation;
690 if( num_pressed < 2 )
693 if( g_pGesture->fingers[0].mx && g_pGesture->fingers[0].my && g_pGesture->fingers[1].mx && g_pGesture->fingers[1].my )
695 pixman_region_init(&cur_area);
696 pixman_region_union(&cur_area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[1]);
698 cur_distance = AREA_DIAG_LEN(&cur_area.extents);
700 #ifdef __DETAIL_DEBUG__
701 ErrorF("[GroupPinchRotation][M] x1=%d, x2=%d, y1=%d, y2=%d\n", g_pGesture->fingers[0].mx, g_pGesture->fingers[1].mx,
702 g_pGesture->fingers[0].my, g_pGesture->fingers[1].my);
703 #endif//__DETAIL_DEBUG__
705 cur_angle = get_angle(g_pGesture->fingers[0].mx, g_pGesture->fingers[0].my, g_pGesture->fingers[1].mx, g_pGesture->fingers[1].my);
706 #ifdef __DETAIL_DEBUG__
707 ErrorF("[GroupPinchRotation][M] cur_angle=%.2f(deg=%.2f)\n", cur_angle, rad2degree(cur_angle));
708 #endif//__DETAIL_DEBUG__
710 diff_distance = prev_distance - cur_distance;
711 diff_angle = prev_angle - cur_angle;
713 cx = AREA_CENTER_X(&cur_area.extents);
714 cy = AREA_CENTER_Y(&cur_area.extents);
716 #ifdef __DETAIL_DEBUG__
717 ErrorF("[GroupPinchRotation][M][state=%d] cx=%d, cy=%d\n", state, cx, cy);
718 #endif//__DETAIL_DEBUG__
720 #ifdef __DETAIL_DEBUG__
721 ErrorF("[GroupPinchRotation][M][num_pressed=%d] prev_distance=%.2f, cur_distance=%.2f, diff=%.2f\n", num_pressed, prev_distance, cur_distance, diff_distance);
722 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));
723 #endif//__DETAIL_DEBUG__
728 if( (ABS(diff_distance) >= PINCHROTATION_DIST_THRESHOLD) || (ABS(diff_angle) >= PINCHROTATION_ANGLE_THRESHOLD) )
730 #ifdef __DETAIL_DEBUG__
731 if( ABS(diff_distance) >= PINCHROTATION_DIST_THRESHOLD )
732 ErrorF("[GroupPinchRotation][M] zoom changed !\n");
734 if( ABS(diff_angle) >= PINCHROTATION_ANGLE_THRESHOLD )
735 ErrorF("[GroupPinchRotation][M] angle changed !\n");
736 #endif//__DETAIL_DEBUG__
738 TimerCancel(pinchrotation_event_timer);
739 state = GestureBegin;
740 goto gesture_begin_handle;
745 gesture_begin_handle:
746 #ifdef __DETAIL_DEBUG__
747 ErrorF("[GroupPinchRotation] PINCHROTATION Begin !cx=%d, cy=%d, state=%d\n", cx, cy, state);
748 #endif//__DETAIL_DEBUG__
749 if( GestureHasFingerEventMask(GestureNotifyPinchRotation, num_pressed) )
751 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);
752 prev_distance = cur_distance;
753 prev_angle = cur_angle;
754 state = GestureUpdate;
760 goto cleanup_pinchrotation;
765 //if( ABS(diff_distance) < PINCHROTATION_DIST_THRESHOLD && ABS(diff_angle) < PINCHROTATION_ANGLE_THRESHOLD )
768 #ifdef __DETAIL_DEBUG__
769 if( ABS(diff_distance) >= PINCHROTATION_DIST_THRESHOLD )
770 ErrorF("[GroupPinchRotation][M] zoom changed !\n");
772 if( ABS(diff_angle) >= PINCHROTATION_ANGLE_THRESHOLD )
773 ErrorF("[GroupPinchRotation][M] angle changed !\n");
774 #endif//__DETAIL_DEBUG__
776 #ifdef __DETAIL_DEBUG__
777 ErrorF("[GroupPinchRotation] PINCHROTATION Update ! cx=%d, cy=%d, state=%d\n", cx, cy, state);
778 #endif//__DETAIL_DEBUG__
779 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);
780 prev_distance = cur_distance;
781 prev_angle = cur_angle;
791 case ET_ButtonRelease:
792 if( state != GestureEnd && num_pressed >= 2)
794 #ifdef __DETAIL_DEBUG__
795 ErrorF("[GroupPinchRotation][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
796 #endif//__DETAIL_DEBUG__
797 goto cleanup_pinchrotation;
800 if( g_pGesture->num_pressed )
803 goto cleanup_pinchrotation;
809 cleanup_pinchrotation:
811 if( has_event_mask && (state == GestureBegin || state == GestureUpdate) )
814 #ifdef __DETAIL_DEBUG__
815 ErrorF("[GroupPinchRotation] PINCHROTATION End ! cx=%d, cy=%d, state=%d\n", cx, cy, state);
816 #endif//__DETAIL_DEBUG__
817 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);
821 g_pGesture->recognized_gesture &= ~PinchRotationFilterMask;
824 g_pGesture->filter_mask |= PinchRotationFilterMask;
826 if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
828 #if 1//def __DETAIL_DEBUG__
829 ErrorF("[GroupPinchRotation][cleanup] GestureFlushOrDrop() !\n");
830 #endif//__DETAIL_DEBUG__
832 if( ERROR_INVALPTR == GestureFlushOrDrop() )
834 GestureControl(g_pGesture->this_device, DEVICE_OFF);
838 prev_distance = base_distance = 0.0f;
839 prev_angle = base_angle = 0.0f;
840 has_event_mask = num_pressed = 0;
843 TimerCancel(pinchrotation_event_timer);
848 GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx)
850 static int num_pressed = 0;
851 static int mbits = 0;
852 static int base_area_size = 0;
853 static Time base_time = 0;
854 static int base_x, base_y;
858 int distance, direction;
865 g_pGesture->fingers[idx].flags |= PressFlagFlick;
867 if( g_pGesture->num_pressed < 2 )
870 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
872 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
873 base_x = g_pGesture->area.extents.x1;
874 base_y = g_pGesture->area.extents.y1;
875 base_time = GetTimeInMillis();
877 num_pressed = g_pGesture->num_pressed;
879 #ifdef __DETAIL_DEBUG__
880 ErrorF("[GroupFlick][P]][num_pressed=%d] AREA_SIZE(area.extents)=%d\n", num_pressed, base_area_size);
881 #endif//__DETAIL_DEBUG__
885 if( !(g_pGesture->fingers[idx].flags & PressFlagFlick ) )
888 #ifdef __DETAIL_DEBUG__
889 if( num_pressed > g_pGesture->num_pressed )
891 ErrorF("[GroupFlick][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
892 //goto cleanup_flick;
894 #endif//__DETAIL_DEBUG__
896 if( num_pressed < 2 )
900 if( mbits == (pow(2, num_pressed)-1) )
902 area_size = AREA_SIZE(&g_pGesture->area.extents);
903 #ifdef __DETAIL_DEBUG__
904 ErrorF("[M][num_pressed=%d] AREA_SIZE(area.extents)=%d\n", num_pressed, area_size);
905 #endif//__DETAIL_DEBUG__
906 if( ABS(base_area_size - area_size) >= FLICK_AREA_THRESHOLD )
908 #ifdef __DETAIL_DEBUG__
909 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);
910 #endif//__DETAIL_DEBUG__
914 current_time = GetTimeInMillis();
915 if( (current_time - base_time) >= FLICK_AREA_TIMEOUT )
917 #ifdef __DETAIL_DEBUG__
918 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);
919 #endif//__DETAIL_DEBUG__
926 case ET_ButtonRelease:
927 if( g_pGesture->num_pressed )
930 duration = GetTimeInMillis() - base_time;
931 distx = g_pGesture->area.extents.x1 - base_x;
932 disty = g_pGesture->area.extents.y1 - base_y;
934 #ifdef __DETAIL_DEBUG__
935 ErrorF("[GroupFlick] duration=%d, distx=%d, disty=%d\n", duration, distx, disty);
936 #endif//__DETAIL_DEBUG__
938 if( duration <= 0 || duration >= FLICK_AREA_TIMEOUT )
941 if( ABS(distx) >= FLICK_MOVE_THRESHOLD )
943 direction = (distx > 0) ? FLICK_EASTWARD : FLICK_WESTWARD;
944 distance = ABS(distx);
947 else if( ABS(disty) >= FLICK_MOVE_THRESHOLD )
949 direction = (disty > 0) ? FLICK_SOUTHWARD : FLICK_NORTHWARD;
950 distance = ABS(disty);
957 if( GestureHasFingerEventMask(GestureNotifyFlick, num_pressed) )
958 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
959 goto cleanup_flick_recognized;
967 g_pGesture->recognized_gesture &= ~FlickFilterMask;
969 cleanup_flick_recognized:
971 g_pGesture->filter_mask |= FlickFilterMask;
980 GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
982 static int num_pressed = 0;
983 static int mbits = 0;
984 static int base_area_size = 0;
985 static Time base_time = 0;
986 static pixman_box16_t base_box_ext;
994 static Time prev_time = 0;
995 Time current_time = 0;
999 static int time_checked = 0;
1000 static int state = GestureEnd;
1002 static OsTimerPtr pan_event_timer = NULL;
1003 static int event_type = GestureNotifyPan;
1009 current_time = GetTimeInMillis();
1010 if( (current_time - base_time) >= PAN_TIME_THRESHOLD )
1012 if( (!cx && !cy) || INBOX(&base_box_ext, cx, cy) )
1014 #ifdef __DETAIL_DEBUG__
1015 ErrorF("[GroupPan][Timer] You must move farther than move threshold(=%d) within time threshold(=%d) !\n", PAN_MOVE_THRESHOLD*2, PAN_TIME_THRESHOLD);
1016 #endif//__DETAIL_DEBUG__
1027 case ET_ButtonPress:
1028 g_pGesture->fingers[idx].flags |= PressFlagPan;
1030 if( g_pGesture->num_pressed < 2 )
1033 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
1035 if( state != GestureEnd )
1037 #ifdef __DETAIL_DEBUG__
1038 ErrorF("[GroupPan][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1039 #endif//__DETAIL_DEBUG__
1042 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1043 prev_cx = base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1044 prev_cy = base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1045 prev_time = base_time = GetTimeInMillis();
1046 base_box_ext.x1 = base_cx-PAN_MOVE_THRESHOLD;
1047 base_box_ext.y1 = base_cy-PAN_MOVE_THRESHOLD;
1048 base_box_ext.x2 = base_cx+PAN_MOVE_THRESHOLD;
1049 base_box_ext.y2 = base_cy+PAN_MOVE_THRESHOLD;
1050 event_type = GestureNotifyPan;
1051 pan_event_timer = TimerSet(pan_event_timer, 0, PAN_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1053 num_pressed = g_pGesture->num_pressed;
1055 #ifdef __DETAIL_DEBUG__
1056 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);
1057 #endif//__DETAIL_DEBUG__
1061 if( !(g_pGesture->fingers[idx].flags & PressFlagPan ) )
1064 if( num_pressed != g_pGesture->num_pressed )
1066 if( state != GestureEnd )
1068 #ifdef __DETAIL_DEBUG__
1069 ErrorF("[GroupPan][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1070 #endif//__DETAIL_DEBUG__
1075 if( num_pressed < 2 )
1078 mbits |= (1 << idx);
1079 if( mbits == (pow(2, num_pressed)-1) )
1081 area_size = AREA_SIZE(&g_pGesture->area.extents);
1082 #ifdef __DETAIL_DEBUG__
1083 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));
1084 #endif//__DETAIL_DEBUG__
1086 if( (state != GestureUpdate) && (ABS(base_area_size - area_size) >= PAN_AREA_THRESHOLD) )
1088 #ifdef __DETAIL_DEBUG__
1089 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);
1090 #endif//__DETAIL_DEBUG__
1094 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1095 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1096 #ifdef __DETAIL_DEBUG__
1097 ErrorF("[GroupPan][M] cx=%d, prev_cx=%d, diff=%d\n", cx, prev_cx, ABS(cx-prev_cx));
1098 ErrorF("[GroupPan][M] cy=%d, prev_cy=%d, diff=%d\n", cy, prev_cy, ABS(cy-prev_cy));
1099 #endif//__DETAIL_DEBUG__
1101 if( state <= GestureBegin )
1103 if( !INBOX(&base_box_ext, cx, cy) )
1105 TimerCancel(pan_event_timer);
1106 pan_event_timer = NULL;
1108 if( GestureHasFingerEventMask(GestureNotifyPan, num_pressed) )
1110 GestureHandleGesture_Pan(num_pressed, prev_cx, prev_cy, direction, distance, current_time-prev_time, GestureBegin);
1111 state = GestureUpdate;
1122 //if( ABS(dx) >= PAN_UPDATE_MOVE_THRESHOLD || ABS(dy) >= PAN_UPDATE_MOVE_THRESHOLD )
1124 #ifdef __DETAIL_DEBUG__
1125 ErrorF("[GroupPan] PAN Update !dx=%d, dy=%d, state=%d\n", dx, dy, state);
1126 #endif//__DETAIL_DEBUG__
1128 GestureHandleGesture_Pan(num_pressed, dx, dy, direction, distance, current_time-prev_time, GestureUpdate);
1138 case ET_ButtonRelease:
1139 if( state != GestureEnd && num_pressed >= 2)
1141 #ifdef __DETAIL_DEBUG__
1142 ErrorF("[GroupPan][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1143 #endif//__DETAIL_DEBUG__
1147 if( g_pGesture->num_pressed )
1158 if( state == GestureBegin || state == GestureUpdate )
1161 if( GestureHasFingerEventMask(GestureNotifyPan, num_pressed) )
1163 GestureHandleGesture_Pan(num_pressed, (short int)(cx-prev_cx), (short int)(cy-prev_cy), direction, distance, GetTimeInMillis()-prev_time, GestureEnd);
1168 g_pGesture->recognized_gesture &= ~PanFilterMask;
1171 g_pGesture->filter_mask |= PanFilterMask;
1180 base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
1181 if( pan_event_timer )
1183 TimerCancel(pan_event_timer);
1184 pan_event_timer = NULL;
1190 GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1192 static int num_pressed = 0;
1193 static int base_area_size = 0;
1195 static Time base_time = 0;
1201 static int state = 0;
1202 static int mbits = 0;
1205 static pixman_box16_t base_box_ext;
1207 static int tap_repeat = 0;
1208 static int prev_tap_repeat = 0;
1209 static int prev_num_pressed = 0;
1211 static OsTimerPtr tap_event_timer = NULL;
1212 static int event_type = GestureNotifyTap;
1216 #ifdef __DETAIL_DEBUG__
1217 ErrorF("[GroupTap][Timer] state=%d\n", state);
1218 #endif//__DETAIL_DEBUG__
1222 case 1://first tap initiation check
1225 #ifdef __DETAIL_DEBUG__
1226 ErrorF("[GroupTap][Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", tap_repeat, num_pressed, tap_repeat);
1227 #endif//__DETAIL_DEBUG__
1234 if( tap_repeat <= 1 )
1236 #ifdef __DETAIL_DEBUG__
1237 ErrorF("[GroupTap][Timer][state=2] %d finger SINGLE TAP !(ignored)\n", prev_num_pressed);
1238 #endif//__DETAIL_DEBUG__
1243 #ifdef __DETAIL_DEBUG__
1244 ErrorF("[GroupTap][Timer][state=2] tap_repeat=%d, prev_tap_repeat=%d, num_pressed=%d\n", tap_repeat, prev_tap_repeat, num_pressed);
1245 #endif//__DETAIL_DEBUG__
1246 if( GestureHasFingerEventMask(GestureNotifyTap, prev_num_pressed) )
1247 GestureHandleGesture_Tap(prev_num_pressed, tap_repeat, base_cx, base_cy);
1257 case ET_ButtonPress:
1258 g_pGesture->fingers[idx].flags |= PressFlagTap;
1260 if( g_pGesture->num_pressed < 2 )
1263 if( !prev_num_pressed && (!base_area_size || g_pGesture->num_pressed > num_pressed) )
1265 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1266 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1267 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1268 base_time = GetTimeInMillis();
1269 base_box_ext.x1 = base_cx-TAP_MOVE_THRESHOLD;
1270 base_box_ext.y1 = base_cy-TAP_MOVE_THRESHOLD;
1271 base_box_ext.x2 = base_cx+TAP_MOVE_THRESHOLD;
1272 base_box_ext.y2 = base_cy+TAP_MOVE_THRESHOLD;
1274 TimerCancel(tap_event_timer);
1275 tap_event_timer = TimerSet(tap_event_timer, 0, SGL_TAP_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1278 num_pressed = g_pGesture->num_pressed;
1280 current_time = GetTimeInMillis();
1282 #ifdef __DETAIL_DEBUG__
1283 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);
1284 #endif//__DETAIL_DEBUG__
1288 if( !(g_pGesture->fingers[idx].flags & PressFlagTap ) )
1291 if( num_pressed < 2 )
1294 if( num_pressed != g_pGesture->num_pressed )
1296 #ifdef __DETAIL_DEBUG__
1297 ErrorF("[GroupTap][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1298 #endif//__DETAIL_DEBUG__
1302 mbits |= (1 << idx);
1303 if( mbits == (pow(2, num_pressed)-1) )
1305 area_size = AREA_SIZE(&g_pGesture->area.extents);
1306 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1307 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1308 #ifdef __DETAIL_DEBUG__
1309 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));
1310 ErrorF("[GroupTap][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1311 ErrorF("[GroupTap][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1312 #endif//__DETAIL_DEBUG__
1314 if( ABS(base_area_size-area_size) >= TAP_AREA_THRESHOLD )
1316 #ifdef __DETAIL_DEBUG__
1317 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));
1318 #endif//__DETAIL_DEBUG__
1322 if( !INBOX(&base_box_ext, cx, cy) )
1324 #ifdef __DETAIL_DEBUG__
1325 ErrorF("[GroupTap][M] current center coordinates is not in base coordinates box !\n");
1326 #endif//__DETAIL_DEBUG__
1332 case ET_ButtonRelease:
1333 if( g_pGesture->num_pressed )
1338 prev_num_pressed = num_pressed;
1341 prev_tap_repeat = tap_repeat;
1344 #ifdef __DETAIL_DEBUG__
1345 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);
1346 #endif//__DETAIL_DEBUG__
1348 if( num_pressed != prev_num_pressed || !GestureHasFingerEventMask(GestureNotifyTap, num_pressed) )
1350 #ifdef __DETAIL_DEBUG__
1351 ErrorF("[GroupTap][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
1352 num_pressed, prev_num_pressed, num_pressed);
1353 #endif//__DETAIL_DEBUG__
1357 if( tap_repeat < MAX_TAP_REPEATS )
1360 TimerCancel(tap_event_timer);
1361 tap_event_timer = TimerSet(tap_event_timer, 0, DBL_TAP_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1366 #ifdef __DETAIL_DEBUG__
1367 ErrorF("[GroupTap][R] %d finger %s\n", num_pressed, (tap_repeat==2) ? "DBL_TAP" : "TRIPLE_TAP");
1368 #endif//__DETAIL_DEBUG__
1370 if( GestureHasFingerEventMask(GestureNotifyTap, num_pressed) )
1371 GestureHandleGesture_Tap(num_pressed, tap_repeat, base_cx, base_cy);
1373 if( tap_repeat >= MAX_TAP_REPEATS )
1378 prev_num_pressed = num_pressed;
1388 g_pGesture->recognized_gesture &= ~TapFilterMask;
1389 g_pGesture->filter_mask |= TapFilterMask;
1391 if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
1393 #ifdef __DETAIL_DEBUG__
1394 ErrorF("[GroupTap][cleanup] GestureFlushOrDrop() !\n");
1395 #endif//__DETAIL_DEBUG__
1397 if( ERROR_INVALPTR == GestureFlushOrDrop() )
1399 GestureControl(g_pGesture->this_device, DEVICE_OFF);
1405 prev_num_pressed = 0;
1409 TimerCancel(tap_event_timer);
1414 GestureRecognize_GroupTapNHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1416 static int num_pressed = 0;
1417 static int base_area_size = 0;
1418 static Time base_time = 0;
1422 static pixman_box16_t base_box_ext;
1424 static int mbits = 0;
1426 static int tap_repeat = 0;
1427 static int prev_num_pressed = 0;
1429 static OsTimerPtr tapnhold_event_timer = NULL;
1430 static int event_type = GestureNotifyTapNHold;
1431 static int state = GestureEnd;
1438 if( (state == GestureEnd) && num_pressed )
1440 #ifdef __DETAIL_DEBUG__
1441 ErrorF("[GroupTapNHold][Timer][state=%d] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", GestureEnd, tap_repeat, num_pressed, tap_repeat);
1442 #endif//__DETAIL_DEBUG__
1444 goto cleanup_tapnhold;
1447 if( state == GestureDone )
1449 #ifdef __DETAIL_DEBUG__
1450 ErrorF("[GroupTapNHold][Timer][state=%d] Interval between Tap and Hold is too long !\n");
1451 #endif//__DETAIL_DEBUG__
1452 goto cleanup_tapnhold;
1455 #ifdef __DETAIL_DEBUG__
1459 ErrorF("[GroupTapNHold][Timer] TapNHold Begin !\n");
1463 ErrorF("[GroupTapNHold][Timer] TapNHold Update !\n");
1466 #endif//__DETAIL_DEBUG__
1468 if( GestureHasFingerEventMask(GestureNotifyTapNHold, prev_num_pressed) )
1470 GestureHandleGesture_TapNHold(prev_num_pressed, base_cx, base_cy, interval, holdtime, state);
1471 tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1475 #ifdef __DETAIL_DEBUG__
1476 ErrorF("[GroupTapNHold][Timer] %d finger TapNHold event was not grabbed/selected !\n", prev_num_pressed);
1477 #endif//__DETAIL_DEBUG__
1478 goto cleanup_tapnhold;
1481 if( state <= GestureBegin )
1488 case ET_ButtonPress:
1489 g_pGesture->fingers[idx].flags |= PressFlagTapNHold;
1491 if( g_pGesture->num_pressed < 2 )
1494 //if( !prev_num_pressed && (!base_area_size || g_pGesture->num_pressed > num_pressed) )
1495 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
1498 if( state == GestureUpdate )
1500 #ifdef __DETAIL_DEBUG__
1501 ErrorF("[GroupTapNHold][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1502 #endif//__DETAIL_DEBUG__
1503 goto cleanup_tapnhold;
1506 if( state == GestureDone )
1507 state = GestureBegin;
1509 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1510 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1511 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1512 base_time = GetTimeInMillis();
1513 base_box_ext.x1 = base_cx-TAPNHOLD_MOVE_THRESHOLD;
1514 base_box_ext.y1 = base_cy-TAPNHOLD_MOVE_THRESHOLD;
1515 base_box_ext.x2 = base_cx+TAPNHOLD_MOVE_THRESHOLD;
1516 base_box_ext.y2 = base_cy+TAPNHOLD_MOVE_THRESHOLD;
1517 if( state == GestureEnd )
1518 tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_TAP_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1521 TimerCancel(tapnhold_event_timer);
1522 tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1524 #ifdef __DETAIL_DEBUG__
1525 ErrorF("[GroupTapNHold][P] Create Timer !(state=%d)\n", state);
1526 #endif//__DETAIL_DEBUG__
1529 num_pressed = g_pGesture->num_pressed;
1531 #ifdef __DETAIL_DEBUG__
1532 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);
1533 #endif//__DETAIL_DEBUG__
1537 if( !(g_pGesture->fingers[idx].flags & PressFlagTapNHold ) )
1540 if( num_pressed < 2 )
1543 if( num_pressed != g_pGesture->num_pressed )
1545 if( state != GestureEnd )
1547 #ifdef __DETAIL_DEBUG__
1548 ErrorF("[GroupTapNHold][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1549 #endif//__DETAIL_DEBUG__
1550 goto cleanup_tapnhold;
1552 #ifdef __DETAIL_DEBUG__
1553 ErrorF("[GroupTapNHold][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1554 #endif//__DETAIL_DEBUG__
1555 //goto cleanup_tapnhold;
1558 mbits |= (1 << idx);
1559 if( mbits == (pow(2, num_pressed)-1) )
1561 area_size = AREA_SIZE(&g_pGesture->area.extents);
1562 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1563 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1564 #ifdef __DETAIL_DEBUG__
1565 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));
1566 ErrorF("[GroupTapNHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1567 ErrorF("[GroupTapNHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1568 #endif//__DETAIL_DEBUG__
1570 if( ABS(base_area_size-area_size) >= TAPNHOLD_AREA_THRESHOLD )
1572 #ifdef __DETAIL_DEBUG__
1573 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));
1574 #endif//__DETAIL_DEBUG__
1575 goto cleanup_tapnhold;
1578 if( !INBOX(&base_box_ext, cx, cy) )
1580 #ifdef __DETAIL_DEBUG__
1581 ErrorF("[GroupTapNHold][M] current center coordinates is not in base coordinates box !\n");
1582 #endif//__DETAIL_DEBUG__
1583 goto cleanup_tapnhold;
1588 case ET_ButtonRelease:
1589 if( state != GestureEnd && num_pressed >= 2)
1591 #ifdef __DETAIL_DEBUG__
1592 ErrorF("[GroupTapNHold][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1593 #endif//__DETAIL_DEBUG__
1594 goto cleanup_tapnhold;
1597 if( g_pGesture->num_pressed )
1602 prev_num_pressed = num_pressed;
1607 #ifdef __DETAIL_DEBUG__
1608 ErrorF("[GroupTapNHold][R] tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, num_pressed, prev_num_pressed);
1609 #endif//__DETAIL_DEBUG__
1611 if( num_pressed != prev_num_pressed || !GestureHasFingerEventMask(GestureNotifyTapNHold, num_pressed) )
1613 #ifdef __DETAIL_DEBUG__
1614 ErrorF("[GroupTapNHold][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
1615 num_pressed, prev_num_pressed, num_pressed);
1616 #endif//__DETAIL_DEBUG__
1617 goto cleanup_tapnhold;
1620 if( tap_repeat > 1 )
1622 #ifdef __DETAIL_DEBUG__
1623 ErrorF("[GroupTapNHold][R] Tap events(tap_repeat=%d) were put twice or more !(ignored)\n", tap_repeat);
1624 #endif//__DETAIL_DEBUG__
1625 goto cleanup_tapnhold;
1628 prev_num_pressed = num_pressed;
1630 state = GestureDone;
1632 TimerCancel(tapnhold_event_timer);
1633 tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_INTV_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1635 #ifdef __DETAIL_DEBUG__
1636 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);
1637 #endif//__DETAIL_DEBUG__
1645 if( state == GestureUpdate )
1648 if( GestureHasFingerEventMask(GestureNotifyTapNHold, prev_num_pressed) )
1650 GestureHandleGesture_TapNHold(prev_num_pressed, base_cx, base_cy, interval, holdtime, state);
1655 g_pGesture->recognized_gesture &= ~TapNHoldFilterMask;
1658 g_pGesture->filter_mask |= TapNHoldFilterMask;
1659 if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
1661 #ifdef __DETAIL_DEBUG__
1662 ErrorF("[GroupTapNHold][cleanup] GestureFlushOrDrop() !\n");
1663 #endif//__DETAIL_DEBUG__
1665 if( ERROR_INVALPTR == GestureFlushOrDrop() )
1667 GestureControl(g_pGesture->this_device, DEVICE_OFF);
1671 TimerCancel(tapnhold_event_timer);
1674 prev_num_pressed = 0;
1682 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1684 static int num_pressed = 0;
1685 static int base_area_size = 0;
1686 static Time base_time = 0;
1690 static pixman_box16_t base_box_ext;
1692 static int state = GestureEnd;
1694 static OsTimerPtr hold_event_timer = NULL;
1695 static int event_type = GestureNotifyHold;
1699 if( state <= GestureBegin )
1702 #ifdef __DETAIL_DEBUG__
1706 ErrorF("[GroupHold] HOLD Begin !\n");
1710 ErrorF("[GroupHold] HOLD Update !\n");
1713 #endif//__DETAIL_DEBUG__
1715 if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) )
1717 GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1718 hold_event_timer = TimerSet(hold_event_timer, 0, HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1725 case ET_ButtonPress:
1726 g_pGesture->fingers[idx].flags |= PressFlagHold;
1728 if( g_pGesture->num_pressed < 2 )
1731 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
1733 if( state != GestureEnd )
1735 #ifdef __DETAIL_DEBUG__
1736 ErrorF("[GroupHold][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1737 #endif//__DETAIL_DEBUG__
1741 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1742 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1743 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1744 base_time = GetTimeInMillis();
1745 base_box_ext.x1 = base_cx-HOLD_MOVE_THRESHOLD;
1746 base_box_ext.y1 = base_cy-HOLD_MOVE_THRESHOLD;
1747 base_box_ext.x2 = base_cx+HOLD_MOVE_THRESHOLD;
1748 base_box_ext.y2 = base_cy+HOLD_MOVE_THRESHOLD;
1749 event_type = GestureNotifyHold;
1750 hold_event_timer = TimerSet(hold_event_timer, 0, HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1752 num_pressed = g_pGesture->num_pressed;
1754 #ifdef __DETAIL_DEBUG__
1755 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);
1756 #endif//__DETAIL_DEBUG__
1760 if( !(g_pGesture->fingers[idx].flags & PressFlagHold ) )
1763 if( num_pressed < 2 )
1766 if( num_pressed != g_pGesture->num_pressed )
1768 if( state != GestureEnd )
1770 #ifdef __DETAIL_DEBUG__
1771 ErrorF("[GroupHold][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1772 #endif//__DETAIL_DEBUG__
1775 #ifdef __DETAIL_DEBUG__
1776 ErrorF("[GroupHold][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1777 #endif//__DETAIL_DEBUG__
1778 //goto cleanup_hold;
1781 area_size = AREA_SIZE(&g_pGesture->area.extents);
1782 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1783 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1784 #ifdef __DETAIL_DEBUG__
1785 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));
1786 ErrorF("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1787 ErrorF("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1788 #endif//__DETAIL_DEBUG__
1790 if( ABS(base_area_size-area_size) >= HOLD_AREA_THRESHOLD )
1792 #ifdef __DETAIL_DEBUG__
1793 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));
1794 #endif//__DETAIL_DEBUG__
1798 if( !INBOX(&base_box_ext, cx, cy) )
1800 #ifdef __DETAIL_DEBUG__
1801 ErrorF("[GroupHold][M] current center coordinates is not in base coordinates box !\n");
1802 #endif//__DETAIL_DEBUG__
1807 case ET_ButtonRelease:
1808 if( state != GestureEnd && num_pressed >= 2)
1810 #ifdef __DETAIL_DEBUG__
1811 ErrorF("[GroupHold][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1812 #endif//__DETAIL_DEBUG__
1816 //ErrorF("[GroupHold][R] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1817 if( g_pGesture->num_pressed )
1828 if( state == GestureBegin || state == GestureUpdate )
1831 if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) )
1833 GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1838 g_pGesture->recognized_gesture &= ~HoldFilterMask;
1841 g_pGesture->filter_mask |= HoldFilterMask;
1845 base_cx = base_cy = 0;
1847 base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
1848 TimerCancel(hold_event_timer);
1853 GestureEnableDisable()
1855 if((g_pGesture->grabMask) || (g_pGesture->lastSelectedWin != None))
1857 GestureEnable(1, FALSE, g_pGesture->this_device);
1861 GestureEnable(0, FALSE, g_pGesture->this_device);
1866 GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent)
1868 g_pGesture->grabMask = *pGrabMask;
1869 g_pGesture->GrabEvents = pGrabEvent;
1870 GestureEnableDisable();
1874 GestureCbEventsSelected(Window win, Mask *pEventMask)
1876 g_pGesture->lastSelectedWin = win;
1877 g_pGesture->lastSelectedMask = (pEventMask) ? *pEventMask : 0;
1878 GestureEnableDisable();
1882 GestureGetEventsWindow(void)
1887 pWin = GestureWindowOnXY(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py);
1891 #ifdef __DETAIL_DEBUG__
1892 ErrorF("[X11][GestureGetEventsWindow] pWin->drawable.id=0x%x\n", pWin->drawable.id);
1893 #endif//__DETAIL_DEBUG__
1894 g_pGesture->gestureWin = pWin->drawable.id;
1898 #ifdef __DETAIL_DEBUG__
1899 ErrorF("[X11][GestureGetEventsWindow] GestureWindowOnXY returns NULL !\n");
1900 #endif//__DETAIL_DEBUG__
1904 if(g_pGesture->gestureWin == g_pGesture->lastSelectedWin)
1906 g_pGesture->eventMask = g_pGesture->lastSelectedMask;
1907 goto nonempty_eventmask;
1910 //check selected event(s)
1911 if( !GestureHasSelectedEvents(pWin, &g_pGesture->eventMask) )
1913 g_pGesture->eventMask = 0;
1917 g_pGesture->lastSelectedWin = g_pGesture->gestureWin;
1918 g_pGesture->lastSelectedMask = g_pGesture->eventMask;
1921 if( !g_pGesture->eventMask && !g_pGesture->grabMask)
1923 #ifdef __DETAIL_DEBUG__
1924 ErrorF("[X11][GestureGetEventsWindow] No grabbed events or no events were selected for window(0x%x) !\n", pWin->drawable.id);
1925 #endif//__DETAIL_DEBUG__
1931 #ifdef __DETAIL_DEBUG__
1932 ErrorF("[X11][GestureGetEventsWindow] g_pGesture->eventMask=0x%x\n", g_pGesture->eventMask);
1933 #endif//__DETAIL_DEBUG__
1935 mask = (GESTURE_FILTER_MASK_ALL & ~(g_pGesture->grabMask | g_pGesture->eventMask));
1937 #ifdef __DETAIL_DEBUG__
1938 ErrorF("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x, mask=0x%x\n", g_pGesture->filter_mask, mask);
1939 #endif//__DETAIL_DEBUG__
1941 g_pGesture->filter_mask = mask;
1943 #ifdef __DETAIL_DEBUG__
1944 ErrorF("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x\n", g_pGesture->filter_mask);
1945 #endif//__DETAIL_DEBUG__
1951 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
1953 int event_type = *(int *)arg;
1955 switch( event_type )
1957 case GestureNotifyHold:
1958 #ifdef __DETAIL_DEBUG__
1959 ErrorF("[GestureEventTimerHandler] GestureNotifyHold (event_type = %d)\n", event_type);
1960 #endif//__DETAIL_DEBUG__
1961 GestureRecognize_GroupHold(event_type, NULL, NULL, 0, 1);
1964 case GestureNotifyPan:
1965 #ifdef __DETAIL_DEBUG__
1966 ErrorF("[GestureEventTimerHandler] GestureNotifyPan (event_type = %d)\n", event_type);
1967 #endif//__DETAIL_DEBUG__
1968 GestureRecognize_GroupPan(event_type, NULL, NULL, 0, 1);
1971 case GestureNotifyTap:
1972 #ifdef __DETAIL_DEBUG__
1973 ErrorF("[GestureEventTimerHandler] GestureNotifyTap (event_type = %d)\n", event_type);
1974 #endif//__DETAIL_DEBUG__
1975 GestureRecognize_GroupTap(event_type, NULL, NULL, 0, 1);
1978 case GestureNotifyTapNHold:
1979 #ifdef __DETAIL_DEBUG__
1980 ErrorF("[GestureEventTimerHandler] GestureNotifyTapNHold (event_type = %d)\n", event_type);
1981 #endif//__DETAIL_DEBUG__
1982 GestureRecognize_GroupTapNHold(event_type, NULL, NULL, 0, 1);
1985 case GestureNotifyPinchRotation:
1986 #ifdef __DETAIL_DEBUG__
1987 ErrorF("[GestureEventTimerHandler] GestureNotifyPinchRotation (event_type = %d)\n", event_type);
1988 #endif//__DETAIL_DEBUG__
1989 GestureRecognize_GroupPinchRotation(event_type, NULL, NULL, 0, 1);
1993 #ifdef __DETAIL_DEBUG__
1994 ErrorF("[GestureEventTimerHandler] unknown event_type (=%d)\n", event_type);
1995 #endif//__DETAIL_DEBUG__
1997 ErrorF("[GestureEventTimerHandler] timer=%x\n", (unsigned int)timer);
2004 GestureSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2006 g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
2007 g_pGesture->recognized_gesture = 0;
2009 if( ERROR_INVALPTR == GestureFlushOrDrop() )
2011 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2014 #ifdef __DETAIL_DEBUG__
2015 ErrorF("[X11][Single] expired !\n");
2016 #endif//__DETAIL_DEBUG__
2022 GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
2025 static OsTimerPtr single_finger_timer = NULL;
2028 if( PROPAGATE_EVENTS == g_pGesture->ehtype ||
2029 device->id < g_pGesture->first_fingerid )
2032 for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
2034 if( device->id == g_pGesture->mt_devices[i]->id )
2046 case ET_ButtonPress:
2048 g_pGesture->event_sum[0] = BTN_PRESSED;
2049 g_pGesture->fingers[idx].ptime = ev->any.time;
2050 g_pGesture->fingers[idx].px = ev->device_event.root_x;
2051 g_pGesture->fingers[idx].py = ev->device_event.root_y;
2053 g_pGesture->num_pressed++;
2054 if( g_pGesture->num_pressed == 1 )
2056 single_finger_timer = TimerSet(single_finger_timer, 0, 50, GestureSingleFingerTimerHandler, NULL);
2060 TimerCancel(single_finger_timer);
2063 if( g_pGesture->num_pressed > g_pGesture->num_mt_devices )
2064 g_pGesture->num_pressed = g_pGesture->num_mt_devices;
2066 if( !g_pGesture->pTempWin || g_pGesture->num_pressed != g_pGesture->inc_num_pressed )
2068 g_pGesture->pTempWin = GestureGetEventsWindow();
2070 if( NULL == g_pGesture->pTempWin )
2072 #ifdef __DETAIL_DEBUG__
2073 ErrorF("[X11][GestureRecognize][g_pGesture->num_pressed=%d] No events were selected !\n", g_pGesture->num_pressed);
2074 #endif//__DETAIL_DEBUG__
2075 g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
2080 g_pGesture->inc_num_pressed = g_pGesture->num_pressed;
2082 g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
2083 g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
2084 g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT;
2085 g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT;
2087 if( g_pGesture->inc_num_pressed == 1 )
2089 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2090 #ifdef __DETAIL_DEBUG__
2091 ErrorF("[P][g_pGesture->inc_num_pressed=1] AREA_SIZE(area.extents)=%d\n", AREA_SIZE(&g_pGesture->area.extents));
2092 #endif//__DETAIL_DEBUG__
2096 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2097 for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ )
2099 pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
2101 #ifdef __DETAIL_DEBUG__
2102 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));
2103 #endif//__DETAIL_DEBUG__
2108 if( !g_pGesture->fingers[idx].ptime )
2111 g_pGesture->fingers[idx].mx = ev->device_event.root_x;
2112 g_pGesture->fingers[idx].my = ev->device_event.root_y;
2114 if( idx == 0 && g_pGesture->event_sum[0] )
2116 g_pGesture->event_sum[0] += BTN_MOVING;
2117 #ifdef __DETAIL_DEBUG__
2118 ErrorF("[X11][GestureRecognize] moving !\n");
2119 #endif//__DETAIL_DEBUG__
2120 if( g_pGesture->event_sum[0] >= 7 )
2122 if( (g_pGesture->event_sum[0] >= 7) && (g_pGesture->inc_num_pressed < 2) )
2124 #ifdef __DETAIL_DEBUG__
2125 ErrorF("[X11][GestureRecognize] moving limit!\n");
2126 #endif//__DETAIL_DEBUG__
2127 g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
2133 g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
2134 g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
2135 g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT;
2136 g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT;
2138 if( g_pGesture->inc_num_pressed == 1 )
2140 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2141 #ifdef __DETAIL_DEBUG__
2142 ErrorF("[M][g_pGesture->inc_num_pressed=1] AREA_SIZE(area)=%d\n", AREA_SIZE(&g_pGesture->area.extents));
2143 #endif//__DETAIL_DEBUG__
2147 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
2148 for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ )
2150 pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
2152 #ifdef __DETAIL_DEBUG__
2153 ErrorF("[M][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents));
2154 #endif//__DETAIL_DEBUG__
2158 case ET_ButtonRelease:
2159 g_pGesture->fingers[idx].rtime = ev->any.time;
2160 g_pGesture->fingers[idx].rx = ev->device_event.root_x;
2161 g_pGesture->fingers[idx].ry = ev->device_event.root_y;
2163 g_pGesture->num_pressed--;
2164 if( g_pGesture->num_pressed <= 0 )
2166 #ifdef __DETAIL_DEBUG__
2167 ErrorF("[X11][GestureRecognize] All fingers were released !\n");
2168 #endif//__DETAIL_DEBUG__
2169 if( g_pGesture->inc_num_pressed == 1 )
2175 if( g_pGesture->filter_mask != GESTURE_FILTER_MASK_ALL )
2177 if( !(g_pGesture->filter_mask & FlickFilterMask) )
2179 GestureRecognize_GroupFlick(type, ev, device, idx);
2181 if( !(g_pGesture->filter_mask & PanFilterMask) )
2183 GestureRecognize_GroupPan(type, ev, device, idx, 0);
2185 if( !(g_pGesture->filter_mask & PinchRotationFilterMask) )
2187 GestureRecognize_GroupPinchRotation(type, ev, device, idx, 0);
2189 if( !(g_pGesture->filter_mask & TapFilterMask) )
2191 GestureRecognize_GroupTap(type, ev, device, idx, 0);
2193 if( !(g_pGesture->filter_mask & TapNHoldFilterMask) )
2195 GestureRecognize_GroupTapNHold(type, ev, device, idx, 0);
2197 if( !(g_pGesture->filter_mask & HoldFilterMask) )
2199 GestureRecognize_GroupHold(type, ev, device, idx, 0);
2203 #ifdef __DETAIL_DEBUG__
2204 ErrorF("[X11][GestureRecognize][N] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask);
2205 ErrorF("[X11][GestureRecognize][N] g_pGesture->GESTURE_FILTER_MASK_ALL = 0x%x\n", GESTURE_FILTER_MASK_ALL);
2206 ErrorF("[X11][GestureRecognize][N] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture);
2207 #endif//__DETAIL_DEBUG__
2209 if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
2211 if( !g_pGesture->recognized_gesture )
2213 else if( !g_pGesture->num_pressed )
2217 if( g_pGesture->recognized_gesture )
2219 if( g_pGesture->ehtype == KEEP_EVENTS )
2220 GestureEventsDrop();
2221 g_pGesture->ehtype = IGNORE_EVENTS;
2228 #ifdef __DETAIL_DEBUG__
2229 ErrorF("[GestureRecognize] GestureFlushOrDrop() !\n");
2230 #endif//__DETAIL_DEBUG__
2231 if( ERROR_INVALPTR == GestureFlushOrDrop() )
2233 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2238 ErrorStatus GestureFlushOrDrop(void)
2242 if( g_pGesture->recognized_gesture )
2244 GestureEventsDrop();
2248 g_pGesture->ehtype = PROPAGATE_EVENTS;
2250 err = GestureEventsFlush();
2251 if( ERROR_NONE != err )
2254 #ifdef __DETAIL_DEBUG__
2255 ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask);
2256 ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->GESTURE_FILTER_MASK_ALL = 0x%x\n", GESTURE_FILTER_MASK_ALL);
2257 ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture);
2258 #endif//__DETAIL_DEBUG__
2261 err = GestureRegionsReinit();
2262 if( ERROR_NONE != err )
2265 g_pGesture->pTempWin = NULL;
2266 g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0;
2267 g_pGesture->event_sum[0] = 0;
2273 GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2277 #ifdef __DEBUG_EVENT_HANDLER__
2278 ErrorF("\n[X11][GestureHandleMTSyncEvent] (%d:%d) time:%d cur:%d\n",
2279 ev->any_event.deviceid, ev->any_event.sync, (int)ev->any.time, (int)GetTimeInMillis());
2280 #endif//__DEBUG_EVENT_HANDLER__
2282 if( MTOUCH_FRAME_SYNC_BEGIN == ev->any_event.sync )
2284 g_pGesture->ehtype = KEEP_EVENTS;
2285 g_pGesture->filter_mask = 0;
2286 g_pGesture->recognized_gesture = 0;
2287 g_pGesture->num_pressed = 0;
2289 for( i=0 ; i < g_pGesture->num_mt_devices ; i++ )
2290 g_pGesture->fingers[i].ptime = 0;
2292 else if( MTOUCH_FRAME_SYNC_END == ev->any_event.sync )
2294 g_pGesture->ehtype = PROPAGATE_EVENTS;
2299 GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2301 #ifdef __DEBUG_EVENT_HANDLER__
2302 ErrorF("[X11][GestureHandleButtonPEvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
2303 #endif//__DEBUG_EVENT_HANDLER__
2305 switch( g_pGesture->ehtype )
2308 if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device) )
2310 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2314 if( g_pGesture->num_mt_devices )
2315 GestureRecognize(ET_ButtonPress, ev, device);
2317 device->public.processInputProc(ev, device);
2320 case PROPAGATE_EVENTS:
2321 device->public.processInputProc(ev, device);
2325 GestureRecognize(ET_ButtonPress, ev, device);
2334 GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2336 #ifdef __DEBUG_EVENT_HANDLER__
2337 ErrorF("[X11][GestureHandleMotionEvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
2338 #endif//__DEBUG_EVENT_HANDLER__
2340 switch( g_pGesture->ehtype )
2343 if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device) )
2345 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2349 if( g_pGesture->num_mt_devices )
2350 GestureRecognize(ET_Motion, ev, device);
2352 device->public.processInputProc(ev, device);
2355 case PROPAGATE_EVENTS:
2356 device->public.processInputProc(ev, device);
2360 GestureRecognize(ET_Motion, ev, device);
2370 GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2372 #ifdef __DEBUG_EVENT_HANDLER__
2373 ErrorF("[X11][GestureHandleButtonREvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
2374 #endif//__DEBUG_EVENT_HANDLER__
2376 switch( g_pGesture->ehtype )
2379 if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device) )
2381 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2385 if( g_pGesture->num_mt_devices )
2386 GestureRecognize(ET_ButtonRelease, ev, device);
2388 device->public.processInputProc(ev, device);
2391 case PROPAGATE_EVENTS:
2392 device->public.processInputProc(ev, device);
2396 GestureRecognize(ET_ButtonRelease, ev, device);
2405 GestureEnableEventHandler(InputInfoPtr pInfo)
2408 GestureDevicePtr pGesture = pInfo->private;
2410 res = GestureInstallResourceStateHooks();
2414 ErrorF("[X11][GestureEnableEventHandler] Failed on GestureInstallResourceStateHooks() !\n");
2415 return ERROR_ABNORMAL;
2418 res = GestureSetMaxNumberOfFingers((int)MAX_MT_DEVICES);
2422 ErrorF("[X11][GestureEnableEventHandler] Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)MAX_MT_DEVICES);
2426 res = GestureRegisterCallbacks(GestureCbEventsGrabbed, GestureCbEventsSelected);
2430 ErrorF("[X11][GestureEnableEventHandler] Failed to register callbacks for GestureEventsGrabbed(), GestureEventsSelected() !\n");
2434 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 5000, GestureTimerHandler, pInfo);
2436 if( !pGesture->device_setting_timer )
2438 ErrorF("[X11][GestureEnableEventHandler] Failed to allocate memory for timer !\n");
2445 GestureUninstallResourceStateHooks();
2446 GestureUnsetMaxNumberOfFingers();
2448 return ERROR_ABNORMAL;
2452 GestureDisableEventHandler(void)
2454 ErrorStatus err = ERROR_NONE;
2456 mieqSetHandler(ET_ButtonPress, NULL);
2457 mieqSetHandler(ET_ButtonRelease, NULL);
2458 mieqSetHandler(ET_Motion, NULL);
2459 mieqSetHandler(ET_MTSync, NULL);
2461 err = GestureFiniEQ();
2463 if( ERROR_INVALPTR == err )
2465 ErrorF("[X11][GestureDisableEventHandler] EQ is invalid or was freed already !\n");
2468 GestureRegisterCallbacks(NULL, NULL);
2469 GestureUninstallResourceStateHooks();
2475 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2477 InputInfoPtr pInfo = (InputInfoPtr)arg;
2478 GestureDevicePtr pGesture = pInfo->private;
2482 for( dev = inputInfo.pointer ; dev; dev = dev->next )
2484 if(IsMaster(dev) && IsPointerDevice(dev))
2486 pGesture->master_pointer = dev;
2487 ErrorF("[X11][GestureTimerHandler][id:%d] Master Pointer=%s\n", dev->id, pGesture->master_pointer->name);
2491 if(IsXTestDevice(dev, NULL) && IsPointerDevice(dev))
2493 pGesture->xtest_pointer = dev;
2494 ErrorF("[X11][GestureTimerHandler][id:%d] XTest Pointer=%s\n", dev->id, pGesture->xtest_pointer->name);
2498 if(IsPointerDevice(dev))
2500 if( idx >= MAX_MT_DEVICES )
2502 ErrorF("[X11][GestureTimerHandler] Number of mt device is over MAX_MT_DEVICES(%d) !\n",
2506 pGesture->mt_devices[idx] = dev;
2507 ErrorF("[X11][GestureTimerHandler][id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name);
2512 if( !pGesture->master_pointer || !pGesture->xtest_pointer )
2514 ErrorF("[X11][GestureTimerHandler] Failed to get info of master pointer or XTest pointer !\n");
2515 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
2516 pGesture->num_mt_devices = 0;
2521 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
2522 pGesture->num_mt_devices = idx;
2524 if( !pGesture->num_mt_devices )
2526 ErrorF("[X11][GestureTimerHandler] Failed to mt device information !\n");
2527 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
2528 pGesture->num_mt_devices = 0;
2529 pGesture->first_fingerid = -1;
2533 pGesture->first_fingerid = pGesture->mt_devices[0]->id;
2534 memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices);
2535 pGesture->pRootWin = RootWindow(pGesture->master_pointer);
2536 g_pGesture->pTempWin = NULL;
2537 g_pGesture->inc_num_pressed = 0;
2539 if( ERROR_NONE != GestureRegionsInit() || ERROR_NONE != GestureInitEQ() )
2544 mieqSetHandler(ET_ButtonPress, GestureHandleButtonPressEvent);
2545 mieqSetHandler(ET_ButtonRelease, GestureHandleButtonReleaseEvent);
2546 mieqSetHandler(ET_Motion, GestureHandleMotionEvent);
2548 if( pGesture->is_active )
2549 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
2555 GestureUninstallResourceStateHooks();
2556 GestureUnsetMaxNumberOfFingers();
2562 IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
2568 return (dev->xtest_master_id == master->id);
2570 return (dev->xtest_master_id != 0);
2574 GestureEnable(int enable, Bool prop, DeviceIntPtr dev)
2576 if((!enable) && (g_pGesture->is_active))
2578 g_pGesture->ehtype = PROPAGATE_EVENTS;
2579 mieqSetHandler(ET_MTSync, NULL);
2580 g_pGesture->is_active = 0;
2581 ErrorF("[X11][GestureEnable] Disabled !\n");
2583 else if((enable) && (!g_pGesture->is_active))
2585 g_pGesture->ehtype = KEEP_EVENTS;
2586 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
2587 g_pGesture->is_active = 1;
2588 ErrorF("[X11][GestureEnable] Enabled !\n");
2592 XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
2596 GestureRegionsInit(void)
2601 return ERROR_INVALPTR;
2603 pixman_region_init(&g_pGesture->area);
2605 for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
2607 pixman_region_init_rect (&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
2614 GestureRegionsReinit(void)
2618 ErrorF("[X11][GestureRegionsReinit] Invalid pointer access !\n");
2619 return ERROR_INVALPTR;
2622 pixman_region_init(&g_pGesture->area);
2633 tmpEQ = (IEventRec *)calloc(GESTURE_EQ_SIZE, sizeof(IEventRec));
2637 ErrorF("[X11][GestureInitEQ] Failed to allocate memory for EQ !\n");
2638 return ERROR_ALLOCFAIL;
2641 for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
2643 tmpEQ[i].event = (InternalEvent *)malloc(sizeof(InternalEvent));
2644 if( !tmpEQ[i].event )
2646 ErrorF("[X11][GestureInitEQ] Failed to allocation memory for each event buffer in EQ !\n");
2648 while(i >= 0 && tmpEQ[i].event)
2650 free(tmpEQ[i].event);
2651 tmpEQ[i].event = NULL;
2655 return ERROR_ALLOCFAIL;
2659 g_pGesture->EQ = tmpEQ;
2660 g_pGesture->headEQ = g_pGesture->tailEQ = 0;
2670 if( !g_pGesture || !g_pGesture->EQ )
2671 return ERROR_INVALPTR;
2673 for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
2675 if( g_pGesture->EQ[i].event )
2677 free(g_pGesture->EQ[i].event);
2678 g_pGesture->EQ[i].event = NULL;
2682 free(g_pGesture->EQ);
2683 g_pGesture->EQ = NULL;
2689 GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2693 if( !g_pGesture || !g_pGesture->EQ )
2695 ErrorF("[X11][GestureEnqueueEvent] Invalid pointer access !\n");
2696 return ERROR_INVALPTR;
2699 tail = g_pGesture->tailEQ;
2701 if( tail >= GESTURE_EQ_SIZE )
2703 ErrorF("[X11][GestureEnqueueEvent] Gesture EQ is full !\n");
2704 printk("[X11][GestureEnqueueEvent] Gesture EQ is full...Force Gesture Flush !\n");
2705 GestureEventsFlush();
2706 return ERROR_EQFULL;
2709 #ifdef __DETAIL_DEBUG__
2710 switch( ev->any.type )
2712 case ET_ButtonPress:
2713 ErrorF("[X11][GestureEnqueueEvent] ET_ButtonPress (id:%d)\n", device->id);
2716 case ET_ButtonRelease:
2717 ErrorF("[X11][GestureEnqueueEvent] ET_ButtonRelease (id:%d)\n", device->id);
2721 ErrorF("[X11][GestureEnqueueEvent] ET_Motion (id:%d)\n", device->id);
2724 #endif//__DETAIL_DEBUG__
2726 g_pGesture->EQ[tail].device = device;
2727 g_pGesture->EQ[tail].screen_num = screen_num;
2728 memcpy(g_pGesture->EQ[tail].event, ev, sizeof(InternalEvent));//need to be optimized
2729 g_pGesture->tailEQ++;
2735 GestureEventsFlush(void)
2738 DeviceIntPtr device;
2740 if( !g_pGesture->EQ )
2742 ErrorF("[X11][GestureEventsFlush] Invalid pointer access !\n");
2743 return ERROR_INVALPTR;
2746 #ifdef __DETAIL_DEBUG__
2747 ErrorF("[X11][GestureEventsFlush]\n");
2748 #endif//__DETAIL_DEBUG__
2750 for( i = g_pGesture->headEQ ; i < g_pGesture->tailEQ ; i++)
2752 device = g_pGesture->EQ[i].device;
2753 device->public.processInputProc(g_pGesture->EQ[i].event, device);
2756 for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
2757 g_pGesture->event_sum[i] = 0;
2759 g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
2765 GestureEventsDrop(void)
2767 g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
2770 #ifdef HAVE_PROPERTIES
2772 GestureInitProperty(DeviceIntPtr dev)
2776 prop_gesture_recognizer_onoff = MakeAtom(GESTURE_RECOGNIZER_ONOFF, strlen(GESTURE_RECOGNIZER_ONOFF), TRUE);
2777 rc = XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
2782 XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE);
2786 GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
2789 InputInfoPtr pInfo = dev->public.devicePrivate;
2791 if( prop_gesture_recognizer_onoff == atom )
2794 if( val->format != 32 || val->type != XA_INTEGER || val->size != 1 )
2799 data = *((int *)val->data);
2800 GestureEnable(data, TRUE, dev);
2806 #endif//HAVE_PROPERTIES
2809 GestureInit(DeviceIntPtr device)
2812 pInfo = device->public.devicePrivate;
2814 #ifdef HAVE_PROPERTIES
2815 GestureInitProperty(device);
2816 XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL);
2823 GestureFini(DeviceIntPtr device)
2825 XIRegisterPropertyHandler(device, NULL, NULL, NULL);
2829 GesturePlug(pointer module, pointer options, int *errmaj, int *errmin)
2831 xf86AddInputDriver(&GESTURE, module, 0);
2836 GestureUnplug(pointer p)
2841 GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
2844 GestureDevicePtr pGesture;
2846 pGesture = calloc(1, sizeof(GestureDeviceRec));
2849 pInfo->private = NULL;
2850 //xf86DeleteInput(pInfo, 0);
2854 g_pGesture = pGesture;
2855 pInfo->private = pGesture;
2857 pInfo->read_input = GestureReadInput; /* new data avl */
2858 pInfo->switch_mode = NULL; /* toggle absolute/relative mode */
2859 pInfo->device_control = GestureControl; /* enable/disable dev */
2860 /* process driver specific options */
2861 pGesture->device = xf86SetStrOption(pInfo->options, "Device", "/dev/null");
2862 pGesture->is_active = xf86SetIntOption(pInfo->options, "Activate", 0);
2863 pGesture->gestureWin = None;
2864 pGesture->lastSelectedWin = None;
2865 g_pGesture->grabMask = g_pGesture->eventMask = 0;
2867 xf86Msg(X_INFO, "%s: Using device %s.\n", pInfo->name, pGesture->device);
2869 /* process generic options */
2870 xf86CollectInputOptions(pInfo, NULL);
2871 xf86ProcessCommonOptions(pInfo, pInfo->options);
2884 GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
2886 GestureDevicePtr pGesture = pInfo->private;
2888 g_pGesture = pGesture = NULL;
2889 pInfo->private = NULL;
2891 xf86DeleteInput(pInfo, 0);
2895 GestureControl(DeviceIntPtr device, int what)
2897 InputInfoPtr pInfo = device->public.devicePrivate;
2898 GestureDevicePtr pGesture = pInfo->private;
2903 GestureInit(device);
2906 /* Switch device on. Establish socket, start event delivery. */
2908 xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
2910 if (device->public.on)
2913 device->public.on = TRUE;
2914 pGesture->this_device = device;
2915 pGesture->num_mt_devices = 0;
2916 if( ERROR_ABNORMAL == GestureEnableEventHandler(pInfo) )
2922 GestureDisableEventHandler();
2923 GestureFini(device);
2924 pGesture->this_device = NULL;
2925 xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
2927 if (!device->public.on)
2931 device->public.on = FALSE;
2935 /* free what we have to free */
2942 GestureReadInput(InputInfoPtr pInfo)