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
62 //#define __DETAIL_DEBUG__
63 //#define __DEBUG_EVENT_HANDLER__
67 #include <sys/syscall.h>
70 #include <sys/types.h>
72 #include <xorg-server.h>
73 #include <xorgVersion.h>
74 #include <xf86Module.h>
75 #include <X11/Xatom.h>
80 static InputInfoPtr GesturePreInit(InputDriverPtr drv, IDevPtr dev, int flags);
81 static void GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
82 static pointer GesturePlug(pointer module, pointer options, int *errmaj, int *errmin);
83 static void GestureUnplug(pointer p);
84 static int GestureControl(DeviceIntPtr device,int what);
85 static int GestureInit(DeviceIntPtr device);
86 static void GestureFini(DeviceIntPtr device);
87 static void GestureReadInput(InputInfoPtr pInfo);
90 ErrorStatus GestureRegionsInit(void);
92 //event queue handling functions
93 ErrorStatus GestureInitEQ(void);
94 ErrorStatus GestureFiniEQ(void);
95 ErrorStatus GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
96 ErrorStatus GestureEventsFlush(void);
97 void GestureEventsDrop(void);
100 ErrorStatus GestureRegionsReinit(void);
101 void GestureSetDisable(InputInfoPtr pInfo, int enable);
102 WindowPtr GestureGetEventsWindow(void);
104 //Enqueued event handlers and enabler/disabler
105 static ErrorStatus GestureEnableEventHandler(InputInfoPtr pInfo);
106 static ErrorStatus GestureDisableEventHandler(void);
107 static CARD32 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
108 static CARD32 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
109 void GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
110 void GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
111 void GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
112 void GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
114 //Gesture recognizer helper
115 static Bool PointInBorderSize(WindowPtr pWin, int x, int y);
116 static WindowPtr GestureWindowOnXY(int x, int y);
117 Bool GestureHasFingerEventMask(int eventType, int num_finger);
119 //Gesture recognizer and handlers
120 void GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr device, int idx);
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);
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 PointInBorderSize(WindowPtr pWin, int x, int y)
180 if( pixman_region_contains_point (&pWin->borderSize, x, y, &box) )
187 GestureWindowOnXY(int x, int y)
192 DeviceIntPtr pDev = g_pGesture->master_pointer;
194 pSprite = pDev->spriteInfo->sprite;
195 pSprite->spriteTraceGood = 1; /* root window still there */
196 pWin = RootWindow(pDev)->firstChild;
200 if ((pWin->mapped) &&
201 (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
202 (x < pWin->drawable.x + (int)pWin->drawable.width +
203 wBorderWidth(pWin)) &&
204 (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
205 (y < pWin->drawable.y + (int)pWin->drawable.height +
207 /* When a window is shaped, a further check
208 * is made to see if the point is inside
211 && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
212 && (!wInputShape(pWin) ||
213 RegionContainsPoint(wInputShape(pWin),
214 x - pWin->drawable.x,
215 y - pWin->drawable.y, &box))
217 /* In rootless mode windows may be offscreen, even when
218 * they're in X's stack. (E.g. if the native window system
219 * implements some form of virtual desktop system).
221 && !pWin->rootlessUnhittable
225 if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
227 pSprite->spriteTraceSize += 10;
228 pSprite->spriteTrace = realloc(pSprite->spriteTrace,
229 pSprite->spriteTraceSize*sizeof(WindowPtr));
231 pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
232 pWin = pWin->firstChild;
235 pWin = pWin->nextSib;
237 return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
241 GestureHasFingerEventMask(int eventType, int num_finger)
244 Mask eventmask = (1L << eventType);
246 if( (g_pGesture->grabMask & eventmask) &&
247 (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[num_finger].window != None) )
249 #ifdef __DETAIL_DEBUG__
250 ErrorF("[X11][GestureHasFingerEventMask] TRUE !! Has grabMask\n");
251 #endif//__DETAIL_DEBUG__
255 if( g_pGesture->eventMask & eventmask )
257 #ifdef __DETAIL_DEBUG__
258 ErrorF("[X11][GestureHasFingerEventMask] TRUE !! Has eventMask\n");
259 #endif//__DETAIL_DEBUG__
263 #ifdef __DETAIL_DEBUG__
264 ErrorF("[X11][GestureHasFingerEventMask] FALSE !! eventType=%d, num_finger=%d\n", eventType, num_finger);
265 #endif//__DETAIL_DEBUG__
271 GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction)
274 WindowPtr target_pWin;
275 xGestureNotifyFlickEvent fev;
277 #ifdef __DETAIL_DEBUG__
278 ErrorF("[X11][GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n",
279 num_of_fingers, distance, duration, direction);
280 #endif//__DETAIL_DEBUG__
282 g_pGesture->recognized_gesture |= FlickFilterMask;
283 memset(&fev, 0, sizeof(xGestureNotifyFlickEvent));
284 fev.type = GestureNotifyFlick;
285 fev.kind = GestureDone;
286 fev.num_finger = num_of_fingers;
287 fev.distance = distance;
288 fev.duration = duration;
289 fev.direction = direction;
291 target_win = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].window;
292 target_pWin = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].pWin;
294 if( g_pGesture->grabMask && (target_win != None) )
296 fev.window = target_win;
300 fev.window = g_pGesture->gestureWin;
303 #ifdef __DETAIL_DEBUG__
304 ErrorF("[X11][GestureHandleGesture_Flick] fev.window=0x%x, g_pGesture->grabMask=0x%x\n", fev.window, g_pGesture->grabMask);
305 #endif//__DETAIL_DEBUG__
307 GestureSendEvent(target_pWin, GestureNotifyFlick, GestureFlickMask, (xGestureCommonEvent *)&fev);
311 GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy)
314 WindowPtr target_pWin;
315 xGestureNotifyTapEvent tev;
317 //skip non-tap events and single finger tap
318 if( !tap_repeat || num_finger <= 1 )
321 #ifdef __DETAIL_DEBUG__
322 ErrorF("[X11][GestureHandleGesture_Tap] num_finger=%d, tap_repeat=%d, cx=%d, cy=%d\n",
323 num_finger, tap_repeat, cx, cy);
324 #endif//__DETAIL_DEBUG__
326 g_pGesture->recognized_gesture |= TapFilterMask;
327 memset(&tev, 0, sizeof(xGestureNotifyTapEvent));
328 tev.type = GestureNotifyTap;
329 tev.kind = GestureDone;
330 tev.num_finger = num_finger;
331 tev.tap_repeat = tap_repeat;
336 target_win = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].window;
337 target_pWin = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].pWin;
339 if( g_pGesture->grabMask && (target_win != None) )
341 tev.window = target_win;
345 tev.window = g_pGesture->gestureWin;
348 #ifdef __DETAIL_DEBUG__
349 ErrorF("[X11][GestureHandleGesture_Tap] tev.window=0x%x, g_pGesture->grabMask=0x%x\n", tev.window, g_pGesture->grabMask);
350 #endif//__DETAIL_DEBUG__
352 GestureSendEvent(target_pWin, GestureNotifyTap, GestureTapMask, (xGestureCommonEvent *)&tev);
355 void GestureHandleGesture_PinchRotation(int num_of_fingers, double zoom, double angle, int distance, int cx, int cy)
358 WindowPtr target_pWin;
359 xGestureNotifyPinchRotationEvent prev;
361 #ifdef __DETAIL_DEBUG__
362 ErrorF("[X11][GestureHandleGesture_PinchRotation] num_fingers=%d, zoom=%.2f, angle=%.2f, distance=%d\n",
363 num_of_fingers, zoom, angle, distance, cx, cy);
364 #endif//__DETAIL_DEBUG__
366 g_pGesture->recognized_gesture |= PinchRotationFilterMask;
367 memset(&prev, 0, sizeof(xGestureNotifyPinchRotationEvent));
368 prev.type = GestureNotifyPinchRotation;
369 prev.kind = GestureDone;
370 prev.num_finger = num_of_fingers;
371 prev.zoom = XDoubleToFixed(zoom);
372 prev.angle = XDoubleToFixed(angle);
373 prev.distance = distance;
377 target_win = g_pGesture->GrabEvents[GestureNotifyPinchRotation].pGestureGrabWinInfo[num_of_fingers].window;
378 target_pWin = g_pGesture->GrabEvents[GestureNotifyPinchRotation].pGestureGrabWinInfo[num_of_fingers].pWin;
380 if( g_pGesture->grabMask && (target_win != None) )
382 prev.window = target_win;
386 prev.window = g_pGesture->gestureWin;
389 #ifdef __DETAIL_DEBUG__
390 ErrorF("[X11][GestureHandleGesture_PinchRotation] prev.window=0x%x, g_pGesture->grabMask=0x%x\n", prev.window, g_pGesture->grabMask);
391 #endif//__DETAIL_DEBUG__
393 GestureSendEvent(target_pWin, GestureNotifyPinchRotation, GesturePinchRotationMask, (xGestureCommonEvent *)&prev);
396 void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds)
399 WindowPtr target_pWin;
400 xGestureNotifyHoldEvent hev;
402 #ifdef __DETAIL_DEBUG__
403 ErrorF("[X11][GestureHandleGesture_Hold] num_fingers=%d, cx=%d, cy=%d, holdtime=%d, kinds=%d\n",
404 num_fingers, cx, cy, holdtime, kinds);
405 #endif//__DETAIL_DEBUG__
407 g_pGesture->recognized_gesture |= HoldFilterMask;
408 memset(&hev, 0, sizeof(xGestureNotifyHoldEvent));
409 hev.type = GestureNotifyHold;
411 hev.num_finger = num_fingers;
412 hev.holdtime = holdtime;
416 target_win = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].window;
417 target_pWin = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].pWin;
419 if( g_pGesture->grabMask && (target_win != None) )
421 hev.window = target_win;
425 hev.window = g_pGesture->gestureWin;
428 #ifdef __DETAIL_DEBUG__
429 ErrorF("[X11][GestureHandleGesture_Hold] hev.window=0x%x, g_pGesture->grabMask=0x%x\n", hev.window, g_pGesture->grabMask);
430 #endif//__DETAIL_DEBUG__
432 GestureSendEvent(target_pWin, GestureNotifyHold, GestureHoldMask, (xGestureCommonEvent *)&hev);
435 void GestureHandleGesture_TapNHold(int num_fingers, int cx, int cy, Time interval, Time holdtime, int kinds)
438 WindowPtr target_pWin;
439 xGestureNotifyTapNHoldEvent thev;
441 #ifdef __DETAIL_DEBUG__
442 ErrorF("[X11][GestureHandleGesture_TapNHold] num_fingers=%d, cx=%d, cy=%d, interval=%d, holdtime=%d, kinds=%d\n",
443 num_fingers, cx, cy, interval, holdtime, kinds);
444 #endif//__DETAIL_DEBUG__
446 g_pGesture->recognized_gesture |= TapNHoldFilterMask;
447 memset(&thev, 0, sizeof(xGestureNotifyTapNHoldEvent));
448 thev.type = GestureNotifyTapNHold;
450 thev.num_finger = num_fingers;
451 thev.holdtime = holdtime;
454 thev.interval = interval;
456 target_win = g_pGesture->GrabEvents[GestureNotifyTapNHold].pGestureGrabWinInfo[num_fingers].window;
457 target_pWin = g_pGesture->GrabEvents[GestureNotifyTapNHold].pGestureGrabWinInfo[num_fingers].pWin;
459 if( g_pGesture->grabMask && (target_win != None) )
461 thev.window = target_win;
465 thev.window = g_pGesture->gestureWin;
468 #ifdef __DETAIL_DEBUG__
469 ErrorF("[X11][GestureHandleGesture_TapNHold] thev.window=0x%x, g_pGesture->grabMask=0x%x\n", thev.window, g_pGesture->grabMask);
470 #endif//__DETAIL_DEBUG__
472 GestureSendEvent(target_pWin, GestureNotifyTapNHold, GestureTapNHoldMask, (xGestureCommonEvent *)&thev);
475 void GestureHandleGesture_Pan(int num_fingers, short int dx, short int dy, int direction, int distance, Time duration, int kinds)
478 WindowPtr target_pWin;
479 xGestureNotifyPanEvent pev;
481 #ifdef __DETAIL_DEBUG__
482 ErrorF("[X11][GestureHandleGesture_Pan] num_fingers=%d, dx=%d, dy=%d, direction=%d, distance=%d, duration=%d, kinds=%d\n",
483 num_fingers, dx, dy, direction, distance, duration, kinds);
484 #endif//__DETAIL_DEBUG__
486 g_pGesture->recognized_gesture |= PanFilterMask;
487 memset(&pev, 0, sizeof(xGestureNotifyPanEvent));
488 pev.type = GestureNotifyPan;
490 pev.num_finger = num_fingers;
491 pev.direction = direction;
492 pev.distance = distance;
493 pev.duration = duration;
497 target_win = g_pGesture->GrabEvents[GestureNotifyPan].pGestureGrabWinInfo[num_fingers].window;
498 target_pWin = g_pGesture->GrabEvents[GestureNotifyPan].pGestureGrabWinInfo[num_fingers].pWin;
500 if( g_pGesture->grabMask && (target_win != None) )
502 pev.window = target_win;
506 pev.window = g_pGesture->gestureWin;
509 #ifdef __DETAIL_DEBUG__
510 ErrorF("[X11][GestureHandleGesture_Pan] pev.window=0x%x, g_pGesture->grabMask=0x%x\n", pev.window, g_pGesture->grabMask);
511 #endif//__DETAIL_DEBUG__
513 GestureSendEvent(target_pWin, GestureNotifyPan, GesturePanMask, (xGestureCommonEvent *)&pev);
517 GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr device, int idx)
520 g_pGesture->recognized_gesture &= ~PinchRotationFilterMask;
521 g_pGesture->filter_mask |= PinchRotationFilterMask;
526 GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx)
528 static int num_pressed = 0;
529 static int mbits = 0;
530 static int base_area_size = 0;
531 static Time base_time = 0;
532 static int base_x, base_y;
536 int distance, direction;
543 g_pGesture->fingers[idx].flags |= PressFlagFlick;
545 if( g_pGesture->num_pressed < 2 )
548 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
550 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
551 base_x = g_pGesture->area.extents.x1;
552 base_y = g_pGesture->area.extents.y1;
553 base_time = GetTimeInMillis();
555 num_pressed = g_pGesture->num_pressed;
557 #ifdef __DETAIL_DEBUG__
558 ErrorF("[GroupFlick][P]][num_pressed=%d] AREA_SIZE(area.extents)=%d\n", num_pressed, base_area_size);
559 #endif//__DETAIL_DEBUG__
563 if( !(g_pGesture->fingers[idx].flags & PressFlagFlick ) )
566 #ifdef __DETAIL_DEBUG__
567 if( num_pressed > g_pGesture->num_pressed )
569 ErrorF("[GroupFlick][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
570 //goto cleanup_flick;
572 #endif//__DETAIL_DEBUG__
574 if( num_pressed < 2 )
578 if( mbits == (pow(2, num_pressed)-1) )
580 area_size = AREA_SIZE(&g_pGesture->area.extents);
581 #ifdef __DETAIL_DEBUG__
582 ErrorF("[M][num_pressed=%d] AREA_SIZE(area.extents)=%d\n", num_pressed, area_size);
583 #endif//__DETAIL_DEBUG__
584 if( ABS(base_area_size - area_size) >= FLICK_AREA_THRESHOLD )
586 #ifdef __DETAIL_DEBUG__
587 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);
588 #endif//__DETAIL_DEBUG__
592 current_time = GetTimeInMillis();
593 if( (current_time - base_time) >= FLICK_AREA_TIMEOUT )
595 #ifdef __DETAIL_DEBUG__
596 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);
597 #endif//__DETAIL_DEBUG__
604 case ET_ButtonRelease:
605 if( g_pGesture->num_pressed )
608 duration = GetTimeInMillis() - base_time;
609 distx = g_pGesture->area.extents.x1 - base_x;
610 disty = g_pGesture->area.extents.y1 - base_y;
612 #ifdef __DETAIL_DEBUG__
613 ErrorF("[GroupFlick] duration=%d, distx=%d, disty=%d\n", duration, distx, disty);
614 #endif//__DETAIL_DEBUG__
616 if( duration <= 0 || duration >= FLICK_AREA_TIMEOUT )
619 if( ABS(distx) >= FLICK_MOVE_THRESHOLD )
621 direction = (distx > 0) ? FLICK_EASTWARD : FLICK_WESTWARD;
622 distance = ABS(distx);
625 else if( ABS(disty) >= FLICK_MOVE_THRESHOLD )
627 direction = (disty > 0) ? FLICK_SOUTHWARD : FLICK_NORTHWARD;
628 distance = ABS(disty);
635 if( GestureHasFingerEventMask(GestureNotifyFlick, num_pressed) )
636 GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
637 goto cleanup_flick_recognized;
645 g_pGesture->recognized_gesture &= ~FlickFilterMask;
647 cleanup_flick_recognized:
649 g_pGesture->filter_mask |= FlickFilterMask;
658 GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
660 static int num_pressed = 0;
661 static int mbits = 0;
662 static int base_area_size = 0;
663 static Time base_time = 0;
664 static pixman_box16_t base_box_ext;
672 static Time prev_time = 0;
673 Time current_time = 0;
677 static int time_checked = 0;
678 static int state = GestureEnd;
680 static OsTimerPtr pan_event_timer = NULL;
681 static int event_type = GestureNotifyPan;
687 current_time = GetTimeInMillis();
688 if( (current_time - base_time) >= PAN_TIME_THRESHOLD )
690 if( (!cx && !cy) || INBOX(&base_box_ext, cx, cy) )
692 #ifdef __DETAIL_DEBUG__
693 ErrorF("[GroupPan][Timer] You must move farther than move threshold(=%d) within time threshold(=%d) !\n", PAN_MOVE_THRESHOLD*2, PAN_TIME_THRESHOLD);
694 #endif//__DETAIL_DEBUG__
706 g_pGesture->fingers[idx].flags |= PressFlagPan;
708 if( g_pGesture->num_pressed < 2 )
711 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
713 if( state != GestureEnd )
715 #ifdef __DETAIL_DEBUG__
716 ErrorF("[GroupPan][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
717 #endif//__DETAIL_DEBUG__
720 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
721 prev_cx = base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
722 prev_cy = base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
723 prev_time = base_time = GetTimeInMillis();
724 base_box_ext.x1 = base_cx-PAN_MOVE_THRESHOLD;
725 base_box_ext.y1 = base_cy-PAN_MOVE_THRESHOLD;
726 base_box_ext.x2 = base_cx+PAN_MOVE_THRESHOLD;
727 base_box_ext.y2 = base_cy+PAN_MOVE_THRESHOLD;
728 event_type = GestureNotifyPan;
729 pan_event_timer = TimerSet(pan_event_timer, 0, PAN_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
731 num_pressed = g_pGesture->num_pressed;
733 #ifdef __DETAIL_DEBUG__
734 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);
735 #endif//__DETAIL_DEBUG__
739 if( !(g_pGesture->fingers[idx].flags & PressFlagPan ) )
742 if( num_pressed != g_pGesture->num_pressed )
744 if( state != GestureEnd )
746 #ifdef __DETAIL_DEBUG__
747 ErrorF("[GroupPan][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
748 #endif//__DETAIL_DEBUG__
753 if( num_pressed < 2 )
757 if( mbits == (pow(2, num_pressed)-1) )
759 area_size = AREA_SIZE(&g_pGesture->area.extents);
760 #ifdef __DETAIL_DEBUG__
761 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));
762 #endif//__DETAIL_DEBUG__
764 if( (state != GestureUpdate) && (ABS(base_area_size - area_size) >= PAN_AREA_THRESHOLD) )
766 #ifdef __DETAIL_DEBUG__
767 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);
768 #endif//__DETAIL_DEBUG__
772 cx = AREA_CENTER_X(&g_pGesture->area.extents);
773 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
775 #ifdef __DETAIL_DEBUG__
776 ErrorF("[GroupPan][M] cx=%d, prev_cx=%d, diff=%d\n", cx, prev_cx, ABS(cx-prev_cx));
777 ErrorF("[GroupPan][M] cy=%d, prev_cy=%d, diff=%d\n", cy, prev_cy, ABS(cy-prev_cy));
778 #endif//__DETAIL_DEBUG__
782 current_time = GetTimeInMillis();
783 if( (current_time - base_time) >= PAN_TIME_THRESHOLD )
785 if( INBOX(&base_box_ext, cx, cy) )
787 #ifdef __DETAIL_DEBUG__
788 ErrorF("[GroupPan][M] You must move farther than move threshold(=%d) within time threshold(=%d) !\n", PAN_MOVE_THRESHOLD*2, PAN_TIME_THRESHOLD);
789 #endif//__DETAIL_DEBUG__
798 if( state <= GestureBegin )
800 base_box_ext.x1 = prev_cx-PAN_MOVE_THRESHOLD;
801 base_box_ext.y1 = prev_cy-PAN_MOVE_THRESHOLD;
802 base_box_ext.x2 = prev_cx+PAN_MOVE_THRESHOLD;
803 base_box_ext.y2 = prev_cy+PAN_MOVE_THRESHOLD;
805 if( !INBOX(&base_box_ext, cx, cy) )
807 current_time = GetTimeInMillis();
808 #ifdef __DETAIL_DEBUG__
809 ErrorF("[GroupPan] PAN Begin !dx=%d, dy=%d, state=%d\n", prev_cx, prev_cy, state);
810 #endif//__DETAIL_DEBUG__
811 if( GestureHasFingerEventMask(GestureNotifyPan, num_pressed) )
813 GestureHandleGesture_Pan(num_pressed, prev_cx, prev_cy, direction, distance, current_time-prev_time, GestureBegin);
814 state = GestureUpdate;
824 //if( ABS(dx) >= PAN_UPDATE_MOVE_THRESHOLD || ABS(dy) >= PAN_UPDATE_MOVE_THRESHOLD )
826 #ifdef __DETAIL_DEBUG__
827 ErrorF("[GroupPan] PAN Update !dx=%d, dy=%d, state=%d\n", dx, dy, state);
828 #endif//__DETAIL_DEBUG__
830 GestureHandleGesture_Pan(num_pressed, dx, dy, direction, distance, current_time-prev_time, GestureUpdate);
835 prev_time = current_time;
841 case ET_ButtonRelease:
842 if( state != GestureEnd && num_pressed >= 2)
844 #ifdef __DETAIL_DEBUG__
845 ErrorF("[GroupPan][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
846 #endif//__DETAIL_DEBUG__
850 if( g_pGesture->num_pressed )
861 if( state == GestureBegin || state == GestureUpdate )
864 if( GestureHasFingerEventMask(GestureNotifyPan, num_pressed) )
866 GestureHandleGesture_Pan(num_pressed, (short int)(cx-prev_cx), (short int)(cy-prev_cy), direction, distance, GetTimeInMillis()-prev_time, GestureEnd);
871 g_pGesture->recognized_gesture &= ~PanFilterMask;
874 g_pGesture->filter_mask |= PanFilterMask;
883 base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
884 TimerCancel(pan_event_timer);
889 GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
891 static int num_pressed = 0;
892 static int base_area_size = 0;
894 static Time base_time = 0;
900 static int state = 0;
901 static int mbits = 0;
904 static pixman_box16_t base_box_ext;
906 static int tap_repeat = 0;
907 static int prev_tap_repeat = 0;
908 static int prev_num_pressed = 0;
910 static OsTimerPtr tap_event_timer = NULL;
911 static int event_type = GestureNotifyTap;
915 #ifdef __DETAIL_DEBUG__
916 ErrorF("[GroupTap][Timer] state=%d\n", state);
917 #endif//__DETAIL_DEBUG__
921 case 1://first tap initiation check
924 #ifdef __DETAIL_DEBUG__
925 ErrorF("[GroupTap][Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", tap_repeat, num_pressed, tap_repeat);
926 #endif//__DETAIL_DEBUG__
933 if( tap_repeat <= 1 )
935 #ifdef __DETAIL_DEBUG__
936 ErrorF("[GroupTap][Timer][state=2] %d finger SINGLE TAP !(ignored)\n", prev_num_pressed);
937 #endif//__DETAIL_DEBUG__
942 #ifdef __DETAIL_DEBUG__
943 ErrorF("[GroupTap][Timer][state=2] tap_repeat=%d, prev_tap_repeat=%d, num_pressed=%d\n", tap_repeat, prev_tap_repeat, num_pressed);
944 #endif//__DETAIL_DEBUG__
945 if( GestureHasFingerEventMask(GestureNotifyTap, prev_num_pressed) )
946 GestureHandleGesture_Tap(prev_num_pressed, tap_repeat, base_cx, base_cy);
957 g_pGesture->fingers[idx].flags |= PressFlagTap;
959 if( g_pGesture->num_pressed < 2 )
962 if( !prev_num_pressed && (!base_area_size || g_pGesture->num_pressed > num_pressed) )
964 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
965 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
966 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
967 base_time = GetTimeInMillis();
968 base_box_ext.x1 = base_cx-TAP_MOVE_THRESHOLD;
969 base_box_ext.y1 = base_cy-TAP_MOVE_THRESHOLD;
970 base_box_ext.x2 = base_cx+TAP_MOVE_THRESHOLD;
971 base_box_ext.y2 = base_cy+TAP_MOVE_THRESHOLD;
973 TimerCancel(tap_event_timer);
974 tap_event_timer = TimerSet(tap_event_timer, 0, SGL_TAP_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
977 num_pressed = g_pGesture->num_pressed;
979 current_time = GetTimeInMillis();
981 #ifdef __DETAIL_DEBUG__
982 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);
983 #endif//__DETAIL_DEBUG__
987 if( !(g_pGesture->fingers[idx].flags & PressFlagTap ) )
990 if( num_pressed < 2 )
993 if( num_pressed != g_pGesture->num_pressed )
995 #ifdef __DETAIL_DEBUG__
996 ErrorF("[GroupTap][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
997 #endif//__DETAIL_DEBUG__
1001 mbits |= (1 << idx);
1002 if( mbits == (pow(2, num_pressed)-1) )
1004 area_size = AREA_SIZE(&g_pGesture->area.extents);
1005 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1006 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1007 #ifdef __DETAIL_DEBUG__
1008 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));
1009 ErrorF("[GroupTap][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1010 ErrorF("[GroupTap][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1011 #endif//__DETAIL_DEBUG__
1013 if( ABS(base_area_size-area_size) >= TAP_AREA_THRESHOLD )
1015 #ifdef __DETAIL_DEBUG__
1016 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));
1017 #endif//__DETAIL_DEBUG__
1021 if( !INBOX(&base_box_ext, cx, cy) )
1023 #ifdef __DETAIL_DEBUG__
1024 ErrorF("[GroupTap][M] current center coordinates is not in base coordinates box !\n");
1025 #endif//__DETAIL_DEBUG__
1031 case ET_ButtonRelease:
1032 if( g_pGesture->num_pressed )
1037 prev_num_pressed = num_pressed;
1040 prev_tap_repeat = tap_repeat;
1043 #ifdef __DETAIL_DEBUG__
1044 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);
1045 #endif//__DETAIL_DEBUG__
1047 if( num_pressed != prev_num_pressed || !GestureHasFingerEventMask(GestureNotifyTap, num_pressed) )
1049 #ifdef __DETAIL_DEBUG__
1050 ErrorF("[GroupTap][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
1051 num_pressed, prev_num_pressed, num_pressed);
1052 #endif//__DETAIL_DEBUG__
1056 if( tap_repeat < MAX_TAP_REPEATS )
1059 TimerCancel(tap_event_timer);
1060 tap_event_timer = TimerSet(tap_event_timer, 0, DBL_TAP_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1065 #ifdef __DETAIL_DEBUG__
1066 ErrorF("[GroupTap][R] %d finger %s\n", num_pressed, (tap_repeat==2) ? "DBL_TAP" : "TRIPLE_TAP");
1067 #endif//__DETAIL_DEBUG__
1069 if( GestureHasFingerEventMask(GestureNotifyTap, num_pressed) )
1070 GestureHandleGesture_Tap(num_pressed, tap_repeat, base_cx, base_cy);
1072 if( tap_repeat >= MAX_TAP_REPEATS )
1077 prev_num_pressed = num_pressed;
1087 g_pGesture->recognized_gesture &= ~TapFilterMask;
1088 g_pGesture->filter_mask |= TapFilterMask;
1090 if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
1092 #ifdef __DETAIL_DEBUG__
1093 ErrorF("[GroupTap][cleanup] GestureFlushOrDrop() !\n");
1094 #endif//__DETAIL_DEBUG__
1096 if( ERROR_INVALPTR == GestureFlushOrDrop() )
1098 GestureControl(g_pGesture->this_device, DEVICE_OFF);
1104 prev_num_pressed = 0;
1108 TimerCancel(tap_event_timer);
1113 GestureRecognize_GroupTapNHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1115 static int num_pressed = 0;
1116 static int base_area_size = 0;
1117 static Time base_time = 0;
1121 static pixman_box16_t base_box_ext;
1123 static int mbits = 0;
1125 static int tap_repeat = 0;
1126 static int prev_num_pressed = 0;
1128 static OsTimerPtr tapnhold_event_timer = NULL;
1129 static int event_type = GestureNotifyTapNHold;
1130 static int state = GestureEnd;
1137 if( (state == GestureEnd) && num_pressed )
1139 #ifdef __DETAIL_DEBUG__
1140 ErrorF("[GroupTapNHold][Timer][state=%d] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", GestureEnd, tap_repeat, num_pressed, tap_repeat);
1141 #endif//__DETAIL_DEBUG__
1143 goto cleanup_tapnhold;
1146 if( state == GestureDone )
1148 #ifdef __DETAIL_DEBUG__
1149 ErrorF("[GroupTapNHold][Timer][state=%d] Interval between Tap and Hold is too long !\n");
1150 #endif//__DETAIL_DEBUG__
1151 goto cleanup_tapnhold;
1154 #ifdef __DETAIL_DEBUG__
1158 ErrorF("[GroupTapNHold][Timer] TapNHold Begin !\n");
1162 ErrorF("[GroupTapNHold][Timer] TapNHold Update !\n");
1165 #endif//__DETAIL_DEBUG__
1167 if( GestureHasFingerEventMask(GestureNotifyTapNHold, prev_num_pressed) )
1169 GestureHandleGesture_TapNHold(prev_num_pressed, base_cx, base_cy, interval, holdtime, state);
1170 tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1174 #ifdef __DETAIL_DEBUG__
1175 ErrorF("[GroupTapNHold][Timer] %d finger TapNHold event was not grabbed/selected !\n", prev_num_pressed);
1176 #endif//__DETAIL_DEBUG__
1177 goto cleanup_tapnhold;
1180 if( state <= GestureBegin )
1187 case ET_ButtonPress:
1188 g_pGesture->fingers[idx].flags |= PressFlagTapNHold;
1190 if( g_pGesture->num_pressed < 2 )
1193 //if( !prev_num_pressed && (!base_area_size || g_pGesture->num_pressed > num_pressed) )
1194 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
1197 if( state == GestureUpdate )
1199 #ifdef __DETAIL_DEBUG__
1200 ErrorF("[GroupTapNHold][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1201 #endif//__DETAIL_DEBUG__
1202 goto cleanup_tapnhold;
1205 if( state == GestureDone )
1206 state = GestureBegin;
1208 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1209 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1210 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1211 base_time = GetTimeInMillis();
1212 base_box_ext.x1 = base_cx-TAPNHOLD_MOVE_THRESHOLD;
1213 base_box_ext.y1 = base_cy-TAPNHOLD_MOVE_THRESHOLD;
1214 base_box_ext.x2 = base_cx+TAPNHOLD_MOVE_THRESHOLD;
1215 base_box_ext.y2 = base_cy+TAPNHOLD_MOVE_THRESHOLD;
1216 if( state == GestureEnd )
1217 tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_TAP_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1220 TimerCancel(tapnhold_event_timer);
1221 tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1223 #ifdef __DETAIL_DEBUG__
1224 ErrorF("[GroupTapNHold][P] Create Timer !(state=%d)\n", state);
1225 #endif//__DETAIL_DEBUG__
1228 num_pressed = g_pGesture->num_pressed;
1230 #ifdef __DETAIL_DEBUG__
1231 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);
1232 #endif//__DETAIL_DEBUG__
1236 if( !(g_pGesture->fingers[idx].flags & PressFlagTapNHold ) )
1239 if( num_pressed < 2 )
1242 if( num_pressed != g_pGesture->num_pressed )
1244 if( state != GestureEnd )
1246 #ifdef __DETAIL_DEBUG__
1247 ErrorF("[GroupTapNHold][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1248 #endif//__DETAIL_DEBUG__
1249 goto cleanup_tapnhold;
1251 #ifdef __DETAIL_DEBUG__
1252 ErrorF("[GroupTapNHold][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1253 #endif//__DETAIL_DEBUG__
1254 //goto cleanup_tapnhold;
1257 mbits |= (1 << idx);
1258 if( mbits == (pow(2, num_pressed)-1) )
1260 area_size = AREA_SIZE(&g_pGesture->area.extents);
1261 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1262 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1263 #ifdef __DETAIL_DEBUG__
1264 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));
1265 ErrorF("[GroupTapNHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1266 ErrorF("[GroupTapNHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1267 #endif//__DETAIL_DEBUG__
1269 if( ABS(base_area_size-area_size) >= TAPNHOLD_AREA_THRESHOLD )
1271 #ifdef __DETAIL_DEBUG__
1272 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));
1273 #endif//__DETAIL_DEBUG__
1274 goto cleanup_tapnhold;
1277 if( !INBOX(&base_box_ext, cx, cy) )
1279 #ifdef __DETAIL_DEBUG__
1280 ErrorF("[GroupTapNHold][M] current center coordinates is not in base coordinates box !\n");
1281 #endif//__DETAIL_DEBUG__
1282 goto cleanup_tapnhold;
1287 case ET_ButtonRelease:
1288 if( state != GestureEnd && num_pressed >= 2)
1290 #ifdef __DETAIL_DEBUG__
1291 ErrorF("[GroupTapNHold][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1292 #endif//__DETAIL_DEBUG__
1293 goto cleanup_tapnhold;
1296 if( g_pGesture->num_pressed )
1301 prev_num_pressed = num_pressed;
1306 #ifdef __DETAIL_DEBUG__
1307 ErrorF("[GroupTapNHold][R] tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, num_pressed, prev_num_pressed);
1308 #endif//__DETAIL_DEBUG__
1310 if( num_pressed != prev_num_pressed || !GestureHasFingerEventMask(GestureNotifyTapNHold, num_pressed) )
1312 #ifdef __DETAIL_DEBUG__
1313 ErrorF("[GroupTapNHold][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
1314 num_pressed, prev_num_pressed, num_pressed);
1315 #endif//__DETAIL_DEBUG__
1316 goto cleanup_tapnhold;
1319 if( tap_repeat > 1 )
1321 #ifdef __DETAIL_DEBUG__
1322 ErrorF("[GroupTapNHold][R] Tap events(tap_repeat=%d) were put twice or more !(ignored)\n", tap_repeat);
1323 #endif//__DETAIL_DEBUG__
1324 goto cleanup_tapnhold;
1327 prev_num_pressed = num_pressed;
1329 state = GestureDone;
1331 TimerCancel(tapnhold_event_timer);
1332 tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_INTV_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1334 #ifdef __DETAIL_DEBUG__
1335 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);
1336 #endif//__DETAIL_DEBUG__
1344 if( state == GestureUpdate )
1347 if( GestureHasFingerEventMask(GestureNotifyTapNHold, prev_num_pressed) )
1349 GestureHandleGesture_TapNHold(prev_num_pressed, base_cx, base_cy, interval, holdtime, state);
1354 g_pGesture->recognized_gesture &= ~TapNHoldFilterMask;
1357 g_pGesture->filter_mask |= TapNHoldFilterMask;
1358 if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
1360 #ifdef __DETAIL_DEBUG__
1361 ErrorF("[GroupTapNHold][cleanup] GestureFlushOrDrop() !\n");
1362 #endif//__DETAIL_DEBUG__
1364 if( ERROR_INVALPTR == GestureFlushOrDrop() )
1366 GestureControl(g_pGesture->this_device, DEVICE_OFF);
1370 TimerCancel(tapnhold_event_timer);
1373 prev_num_pressed = 0;
1381 void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
1383 static int num_pressed = 0;
1384 static int base_area_size = 0;
1385 static Time base_time = 0;
1389 static pixman_box16_t base_box_ext;
1391 static int state = GestureEnd;
1393 static OsTimerPtr hold_event_timer = NULL;
1394 static int event_type = GestureNotifyHold;
1398 if( state <= GestureBegin )
1401 #ifdef __DETAIL_DEBUG__
1405 ErrorF("[GroupHold] HOLD Begin !\n");
1409 ErrorF("[GroupHold] HOLD Update !\n");
1412 #endif//__DETAIL_DEBUG__
1414 if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) )
1416 GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1417 hold_event_timer = TimerSet(hold_event_timer, 0, HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1424 case ET_ButtonPress:
1425 g_pGesture->fingers[idx].flags |= PressFlagHold;
1427 if( g_pGesture->num_pressed < 2 )
1430 if( !base_area_size || g_pGesture->num_pressed > num_pressed )
1432 if( state != GestureEnd )
1434 #ifdef __DETAIL_DEBUG__
1435 ErrorF("[GroupHold][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1436 #endif//__DETAIL_DEBUG__
1440 base_area_size = AREA_SIZE(&g_pGesture->area.extents);
1441 base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
1442 base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1443 base_time = GetTimeInMillis();
1444 base_box_ext.x1 = base_cx-HOLD_MOVE_THRESHOLD;
1445 base_box_ext.y1 = base_cy-HOLD_MOVE_THRESHOLD;
1446 base_box_ext.x2 = base_cx+HOLD_MOVE_THRESHOLD;
1447 base_box_ext.y2 = base_cy+HOLD_MOVE_THRESHOLD;
1448 event_type = GestureNotifyHold;
1449 hold_event_timer = TimerSet(hold_event_timer, 0, HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
1451 num_pressed = g_pGesture->num_pressed;
1453 #ifdef __DETAIL_DEBUG__
1454 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);
1455 #endif//__DETAIL_DEBUG__
1459 if( !(g_pGesture->fingers[idx].flags & PressFlagHold ) )
1462 if( num_pressed < 2 )
1465 if( num_pressed != g_pGesture->num_pressed )
1467 if( state != GestureEnd )
1469 #ifdef __DETAIL_DEBUG__
1470 ErrorF("[GroupHold][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1471 #endif//__DETAIL_DEBUG__
1474 #ifdef __DETAIL_DEBUG__
1475 ErrorF("[GroupHold][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1476 #endif//__DETAIL_DEBUG__
1477 //goto cleanup_hold;
1480 area_size = AREA_SIZE(&g_pGesture->area.extents);
1481 cx = AREA_CENTER_X(&g_pGesture->area.extents);
1482 cy = AREA_CENTER_Y(&g_pGesture->area.extents);
1483 #ifdef __DETAIL_DEBUG__
1484 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));
1485 ErrorF("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
1486 ErrorF("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
1487 #endif//__DETAIL_DEBUG__
1489 if( ABS(base_area_size-area_size) >= HOLD_AREA_THRESHOLD )
1491 #ifdef __DETAIL_DEBUG__
1492 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));
1493 #endif//__DETAIL_DEBUG__
1497 if( !INBOX(&base_box_ext, cx, cy) )
1499 #ifdef __DETAIL_DEBUG__
1500 ErrorF("[GroupHold][M] current center coordinates is not in base coordinates box !\n");
1501 #endif//__DETAIL_DEBUG__
1506 case ET_ButtonRelease:
1507 if( state != GestureEnd && num_pressed >= 2)
1509 #ifdef __DETAIL_DEBUG__
1510 ErrorF("[GroupHold][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1511 #endif//__DETAIL_DEBUG__
1515 //ErrorF("[GroupHold][R] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
1516 if( g_pGesture->num_pressed )
1527 if( state == GestureBegin || state == GestureUpdate )
1530 if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) )
1532 GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
1537 g_pGesture->recognized_gesture &= ~HoldFilterMask;
1540 g_pGesture->filter_mask |= HoldFilterMask;
1544 base_cx = base_cy = 0;
1546 base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
1547 TimerCancel(hold_event_timer);
1552 GestureGetEventsWindow(void)
1557 //check grabbed event(s)
1558 if( !GestureHasGrabbedEvents(&g_pGesture->grabMask, &g_pGesture->GrabEvents) )
1559 g_pGesture->grabMask = 0;
1561 pWin = GestureWindowOnXY(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py);
1565 #ifdef __DETAIL_DEBUG__
1566 ErrorF("[X11][GestureGetEventsWindow] pWin->drawable.id=0x%x\n", pWin->drawable.id);
1567 #endif//__DETAIL_DEBUG__
1568 g_pGesture->gestureWin = pWin->drawable.id;
1572 #ifdef __DETAIL_DEBUG__
1573 ErrorF("[X11][GestureGetEventsWindow] GestureWindowOnXY returns NULL !\n");
1574 #endif//__DETAIL_DEBUG__
1578 //check selected event(s)
1579 if( !GestureHasSelectedEvents(pWin, &g_pGesture->eventMask) )
1580 g_pGesture->eventMask = 0;
1582 if( !g_pGesture->grabMask && !g_pGesture->eventMask )
1584 #ifdef __DETAIL_DEBUG__
1585 ErrorF("[X11][GestureGetEventsWindow] No events were grabbed/selected for window(0x%x) !\n", pWin->drawable.id);
1586 #endif//__DETAIL_DEBUG__
1590 #ifdef __DETAIL_DEBUG__
1591 ErrorF("[X11][GestureGetEventsWindow] g_pGesture->grabMask=0x%x, g_pGesture->eventMask=0x%x\n",
1592 g_pGesture->grabMask, g_pGesture->eventMask);
1593 #endif//__DETAIL_DEBUG__
1595 mask = (GESTURE_FILTER_MASK_ALL & ~(g_pGesture->grabMask | g_pGesture->eventMask));
1597 #ifdef __DETAIL_DEBUG__
1598 ErrorF("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x, mask=0x%x\n", g_pGesture->filter_mask, mask);
1599 #endif//__DETAIL_DEBUG__
1601 g_pGesture->filter_mask = mask;
1603 #ifdef __DETAIL_DEBUG__
1604 ErrorF("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x\n", g_pGesture->filter_mask);
1605 #endif//__DETAIL_DEBUG__
1611 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
1613 int event_type = *(int *)arg;
1615 switch( event_type )
1617 case GestureNotifyHold:
1618 #ifdef __DETAIL_DEBUG__
1619 ErrorF("[GestureEventTimerHandler] GestureNotifyHold (event_type = %d)\n", event_type);
1620 #endif//__DETAIL_DEBUG__
1621 GestureRecognize_GroupHold(event_type, NULL, NULL, 0, 1);
1624 case GestureNotifyPan:
1625 #ifdef __DETAIL_DEBUG__
1626 ErrorF("[GestureEventTimerHandler] GestureNotifyPan (event_type = %d)\n", event_type);
1627 #endif//__DETAIL_DEBUG__
1628 GestureRecognize_GroupPan(event_type, NULL, NULL, 0, 1);
1631 case GestureNotifyTap:
1632 #ifdef __DETAIL_DEBUG__
1633 ErrorF("[GestureEventTimerHandler] GestureNotifyTap (event_type = %d)\n", event_type);
1634 #endif//__DETAIL_DEBUG__
1635 GestureRecognize_GroupTap(event_type, NULL, NULL, 0, 1);
1638 case GestureNotifyTapNHold:
1639 #ifdef __DETAIL_DEBUG__
1640 ErrorF("[GestureEventTimerHandler] GestureNotifyTapNHold (event_type = %d)\n", event_type);
1641 #endif//__DETAIL_DEBUG__
1642 GestureRecognize_GroupTapNHold(event_type, NULL, NULL, 0, 1);
1646 #ifdef __DETAIL_DEBUG__
1647 ErrorF("[GestureEventTimerHandler] unknown event_type (=%d)\n", event_type);
1648 #endif//__DETAIL_DEBUG__
1650 ErrorF("[GestureEventTimerHandler] timer=%x\n", (unsigned int)timer);
1657 GestureSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
1659 g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
1660 g_pGesture->recognized_gesture = 0;
1662 if( ERROR_INVALPTR == GestureFlushOrDrop() )
1664 GestureControl(g_pGesture->this_device, DEVICE_OFF);
1667 #ifdef __DETAIL_DEBUG__
1668 ErrorF("[X11][Single] expired !\n");
1669 #endif//__DETAIL_DEBUG__
1675 GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
1678 int idx = device->id - g_pGesture->first_fingerid;
1679 static OsTimerPtr single_finger_timer = NULL;
1681 if( PROPAGATE_EVENTS == g_pGesture->ehtype )
1684 if( device->id < g_pGesture->first_fingerid )//filtering device id : 2
1689 case ET_ButtonPress:
1691 g_pGesture->event_sum[0] = BTN_PRESSED;
1692 g_pGesture->fingers[idx].ptime = ev->any.time;
1693 g_pGesture->fingers[idx].px = ev->device_event.root_x;
1694 g_pGesture->fingers[idx].py = ev->device_event.root_y;
1696 g_pGesture->num_pressed++;
1697 if( g_pGesture->num_pressed == 1 )
1699 single_finger_timer = TimerSet(single_finger_timer, 0, 50, GestureSingleFingerTimerHandler, NULL);
1703 TimerCancel(single_finger_timer);
1706 if( g_pGesture->num_pressed > g_pGesture->num_mt_devices )
1707 g_pGesture->num_pressed = g_pGesture->num_mt_devices;
1709 if( !g_pGesture->pTempWin || g_pGesture->num_pressed != g_pGesture->inc_num_pressed )
1711 g_pGesture->pTempWin = GestureGetEventsWindow();
1713 if( NULL == g_pGesture->pTempWin )
1715 #ifdef __DETAIL_DEBUG__
1716 ErrorF("[X11][GestureRecognize][g_pGesture->num_pressed=%d] No grabbed events and no event masks !\n", g_pGesture->num_pressed);
1717 #endif//__DETAIL_DEBUG__
1718 g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
1723 g_pGesture->inc_num_pressed = g_pGesture->num_pressed;
1725 g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
1726 g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
1727 g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT;
1728 g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT;
1730 if( g_pGesture->inc_num_pressed == 1 )
1732 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
1733 #ifdef __DETAIL_DEBUG__
1734 ErrorF("[P][g_pGesture->inc_num_pressed=1] AREA_SIZE(area.extents)=%d\n", AREA_SIZE(&g_pGesture->area.extents));
1735 #endif//__DETAIL_DEBUG__
1739 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
1740 for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ )
1742 pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
1744 #ifdef __DETAIL_DEBUG__
1745 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));
1746 #endif//__DETAIL_DEBUG__
1751 if( !g_pGesture->fingers[idx].ptime )
1754 g_pGesture->fingers[idx].mx = ev->device_event.root_x;
1755 g_pGesture->fingers[idx].my = ev->device_event.root_y;
1757 if( idx == 0 && g_pGesture->event_sum[0] )
1759 g_pGesture->event_sum[0] += BTN_MOVING;
1760 #ifdef __DETAIL_DEBUG__
1761 ErrorF("[X11][GestureRecognize] moving !\n");
1762 #endif//__DETAIL_DEBUG__
1763 if( g_pGesture->event_sum[0] >= 7 )
1765 if( (g_pGesture->event_sum[0] >= 7) && (g_pGesture->inc_num_pressed < 2) )
1767 #ifdef __DETAIL_DEBUG__
1768 ErrorF("[X11][GestureRecognize] moving limit!\n");
1769 #endif//__DETAIL_DEBUG__
1770 g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
1776 g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
1777 g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
1778 g_pGesture->finger_rects[idx].extents.y1 = ev->device_event.root_y - FINGER_HEIGHT;
1779 g_pGesture->finger_rects[idx].extents.y2 = ev->device_event.root_y + FINGER_HEIGHT;
1781 if( g_pGesture->inc_num_pressed == 1 )
1783 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
1784 #ifdef __DETAIL_DEBUG__
1785 ErrorF("[M][g_pGesture->inc_num_pressed=1] AREA_SIZE(area)=%d\n", AREA_SIZE(&g_pGesture->area.extents));
1786 #endif//__DETAIL_DEBUG__
1790 pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
1791 for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ )
1793 pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
1795 #ifdef __DETAIL_DEBUG__
1796 ErrorF("[M][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents));
1797 #endif//__DETAIL_DEBUG__
1801 case ET_ButtonRelease:
1802 g_pGesture->fingers[idx].rtime = ev->any.time;
1803 g_pGesture->fingers[idx].rx = ev->device_event.root_x;
1804 g_pGesture->fingers[idx].ry = ev->device_event.root_y;
1806 g_pGesture->num_pressed--;
1807 if( g_pGesture->num_pressed <= 0 )
1809 #ifdef __DETAIL_DEBUG__
1810 ErrorF("[X11][GestureRecognize] All fingers were released !\n");
1811 #endif//__DETAIL_DEBUG__
1812 if( g_pGesture->inc_num_pressed == 1 )
1818 if( g_pGesture->filter_mask != GESTURE_FILTER_MASK_ALL )
1820 if( !(g_pGesture->filter_mask & FlickFilterMask) )
1822 GestureRecognize_GroupFlick(type, ev, device, idx);
1824 if( !(g_pGesture->filter_mask & PanFilterMask) )
1826 GestureRecognize_GroupPan(type, ev, device, idx, 0);
1828 if( !(g_pGesture->filter_mask & PinchRotationFilterMask) )
1830 GestureRecognize_GroupPinchRotation(type, ev, device, idx);
1832 if( !(g_pGesture->filter_mask & TapFilterMask) )
1834 GestureRecognize_GroupTap(type, ev, device, idx, 0);
1836 if( !(g_pGesture->filter_mask & TapNHoldFilterMask) )
1838 GestureRecognize_GroupTapNHold(type, ev, device, idx, 0);
1840 if( !(g_pGesture->filter_mask & HoldFilterMask) )
1842 GestureRecognize_GroupHold(type, ev, device, idx, 0);
1846 #ifdef __DETAIL_DEBUG__
1847 ErrorF("[X11][GestureRecognize][N] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask);
1848 ErrorF("[X11][GestureRecognize][N] g_pGesture->GESTURE_FILTER_MASK_ALL = 0x%x\n", GESTURE_FILTER_MASK_ALL);
1849 ErrorF("[X11][GestureRecognize][N] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture);
1850 #endif//__DETAIL_DEBUG__
1852 if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
1854 if( !g_pGesture->recognized_gesture )
1856 else if( !g_pGesture->num_pressed )
1860 if( g_pGesture->recognized_gesture )
1862 if( g_pGesture->ehtype == KEEP_EVENTS )
1863 GestureEventsDrop();
1864 g_pGesture->ehtype = IGNORE_EVENTS;
1871 #ifdef __DETAIL_DEBUG__
1872 ErrorF("[GestureRecognize] GestureFlushOrDrop() !\n");
1873 #endif//__DETAIL_DEBUG__
1874 if( ERROR_INVALPTR == GestureFlushOrDrop() )
1876 GestureControl(g_pGesture->this_device, DEVICE_OFF);
1881 ErrorStatus GestureFlushOrDrop(void)
1885 if( g_pGesture->recognized_gesture )
1887 GestureEventsDrop();
1891 g_pGesture->ehtype = PROPAGATE_EVENTS;
1893 err = GestureEventsFlush();
1894 if( ERROR_NONE != err )
1897 #ifdef __DETAIL_DEBUG__
1898 ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask);
1899 ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->GESTURE_FILTER_MASK_ALL = 0x%x\n", GESTURE_FILTER_MASK_ALL);
1900 ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture);
1901 #endif//__DETAIL_DEBUG__
1904 err = GestureRegionsReinit();
1905 if( ERROR_NONE != err )
1908 g_pGesture->pTempWin = NULL;
1909 g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0;
1910 g_pGesture->event_sum[0] = 0;
1916 GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
1920 #ifdef __DEBUG_EVENT_HANDLER__
1921 ErrorF("\n[X11][GestureHandleMTSyncEvent] (%d:%d) time:%d cur:%d\n",
1922 ev->any_event.deviceid, ev->any_event.sync, (int)ev->any.time, (int)GetTimeInMillis());
1923 #endif//__DEBUG_EVENT_HANDLER__
1925 if( MTOUCH_FRAME_SYNC_BEGIN == ev->any_event.sync )
1927 g_pGesture->ehtype = KEEP_EVENTS;
1928 g_pGesture->filter_mask = 0;
1929 g_pGesture->recognized_gesture = 0;
1930 g_pGesture->num_pressed = 0;
1932 for( i=0 ; i < g_pGesture->num_mt_devices ; i++ )
1933 g_pGesture->fingers[i].ptime = 0;
1935 else if( MTOUCH_FRAME_SYNC_END == ev->any_event.sync )
1937 g_pGesture->ehtype = PROPAGATE_EVENTS;
1942 GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
1944 #ifdef __DEBUG_EVENT_HANDLER__
1945 ErrorF("[X11][GestureHandleButtonPEvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
1946 #endif//__DEBUG_EVENT_HANDLER__
1948 switch( g_pGesture->ehtype )
1951 if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device) )
1953 GestureControl(g_pGesture->this_device, DEVICE_OFF);
1957 if( g_pGesture->num_mt_devices )
1958 GestureRecognize(ET_ButtonPress, ev, device);
1960 device->public.processInputProc(ev, device);
1963 case PROPAGATE_EVENTS:
1964 device->public.processInputProc(ev, device);
1968 GestureRecognize(ET_ButtonPress, ev, device);
1977 GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
1979 #ifdef __DEBUG_EVENT_HANDLER__
1980 ErrorF("[X11][GestureHandleMotionEvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
1981 #endif//__DEBUG_EVENT_HANDLER__
1983 switch( g_pGesture->ehtype )
1986 if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device) )
1988 GestureControl(g_pGesture->this_device, DEVICE_OFF);
1992 if( g_pGesture->num_mt_devices )
1993 GestureRecognize(ET_Motion, ev, device);
1995 device->public.processInputProc(ev, device);
1998 case PROPAGATE_EVENTS:
1999 device->public.processInputProc(ev, device);
2003 GestureRecognize(ET_Motion, ev, device);
2013 GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2015 #ifdef __DEBUG_EVENT_HANDLER__
2016 ErrorF("[X11][GestureHandleButtonREvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
2017 #endif//__DEBUG_EVENT_HANDLER__
2019 switch( g_pGesture->ehtype )
2022 if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device) )
2024 GestureControl(g_pGesture->this_device, DEVICE_OFF);
2028 if( g_pGesture->num_mt_devices )
2029 GestureRecognize(ET_ButtonRelease, ev, device);
2031 device->public.processInputProc(ev, device);
2034 case PROPAGATE_EVENTS:
2035 device->public.processInputProc(ev, device);
2039 GestureRecognize(ET_ButtonRelease, ev, device);
2048 GestureEnableEventHandler(InputInfoPtr pInfo)
2051 GestureDevicePtr pGesture = pInfo->private;
2053 res = GestureInstallResourceStateHooks();
2057 ErrorF("[X11][GestureEnableEventHandler] Failed on GestureInstallResourceStateHooks() !\n");
2058 return ERROR_ABNORMAL;
2061 res = GestureSetMaxNumberOfFingers((int)MAX_MT_DEVICES);
2065 ErrorF("[X11][GestureEnableEventHandler] Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)MAX_MT_DEVICES);
2069 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 500, GestureTimerHandler, pInfo);
2071 if( !pGesture->device_setting_timer )
2073 ErrorF("[X11][GestureEnableEventHandler] Failed to allocate memory for timer !\n");
2077 if( ERROR_NONE != GestureRegionsInit() || ERROR_NONE != GestureInitEQ() )
2082 mieqSetHandler(ET_ButtonPress, GestureHandleButtonPressEvent);
2083 mieqSetHandler(ET_ButtonRelease, GestureHandleButtonReleaseEvent);
2084 mieqSetHandler(ET_Motion, GestureHandleMotionEvent);
2085 if( pGesture->is_active )
2086 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
2091 GestureUninstallResourceStateHooks();
2092 GestureUnsetMaxNumberOfFingers();
2094 return ERROR_ABNORMAL;
2098 GestureDisableEventHandler(void)
2100 ErrorStatus err = ERROR_NONE;
2102 mieqSetHandler(ET_ButtonPress, NULL);
2103 mieqSetHandler(ET_ButtonRelease, NULL);
2104 mieqSetHandler(ET_Motion, NULL);
2105 mieqSetHandler(ET_MTSync, NULL);
2107 err = GestureFiniEQ();
2109 if( ERROR_INVALPTR == err )
2111 ErrorF("[X11][GestureDisableEventHandler] EQ is invalid or was freed already !\n");
2114 GestureUninstallResourceStateHooks();
2115 GestureUnsetMaxNumberOfFingers();
2121 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
2123 InputInfoPtr pInfo = (InputInfoPtr)arg;
2124 GestureDevicePtr pGesture = pInfo->private;
2128 for( dev = inputInfo.pointer ; dev; dev = dev->next )
2130 if(IsMaster(dev) && IsPointerDevice(dev))
2132 pGesture->master_pointer = dev;
2133 ErrorF("[X11][GestureTimerHandler][id:%d] Master Pointer=%s\n", dev->id, pGesture->master_pointer->name);
2137 if(IsXTestDevice(dev, NULL) && IsPointerDevice(dev))
2139 pGesture->xtest_pointer = dev;
2140 ErrorF("[X11][GestureTimerHandler][id:%d] XTest Pointer=%s\n", dev->id, pGesture->xtest_pointer->name);
2144 if(IsPointerDevice(dev))
2146 if( idx >= MAX_MT_DEVICES )
2148 ErrorF("[X11][GestureTimerHandler] Number of mt device is over MAX_MT_DEVICES(%d) !\n",
2152 pGesture->mt_devices[idx] = dev;
2153 ErrorF("[X11][GestureTimerHandler][id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name);
2158 if( !pGesture->master_pointer || !pGesture->xtest_pointer )
2160 ErrorF("[X11][GestureTimerHandler] Failed to get info of master pointer or XTest pointer !\n");
2161 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
2162 pGesture->num_mt_devices = 0;
2167 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
2168 pGesture->first_fingerid = pGesture->mt_devices[0]->id;
2169 pGesture->num_mt_devices = idx;
2171 if( !pGesture->num_mt_devices )
2173 ErrorF("[X11][GestureTimerHandler] Failed to mt device information !\n");
2174 pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
2175 pGesture->num_mt_devices = 0;
2180 memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices);
2181 pGesture->pRootWin = RootWindow(pGesture->master_pointer);
2182 g_pGesture->grabMask = g_pGesture->eventMask = 0;
2183 g_pGesture->pTempWin = NULL;
2184 g_pGesture->inc_num_pressed = 0;
2190 IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
2196 return (dev->xtest_master_id == master->id);
2198 return (dev->xtest_master_id != 0);
2202 GestureSetDisable(InputInfoPtr pInfo, int enable)
2206 g_pGesture->ehtype = PROPAGATE_EVENTS;
2207 mieqSetHandler(ET_MTSync, NULL);
2208 g_pGesture->is_active = 0;
2209 ErrorF("[X11][GestureSetDisable] Disabled !\n");
2213 g_pGesture->ehtype = KEEP_EVENTS;
2214 mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
2215 g_pGesture->is_active = 1;
2216 ErrorF("[X11][GestureSetDisable] Enabled !\n");
2221 GestureRegionsInit(void)
2226 return ERROR_INVALPTR;
2228 pixman_region_init(&g_pGesture->area);
2230 for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
2232 pixman_region_init_rect (&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
2239 GestureRegionsReinit(void)
2243 ErrorF("[X11][GestureRegionsReinit] Invalid pointer access !\n");
2244 return ERROR_INVALPTR;
2247 pixman_region_init(&g_pGesture->area);
2258 tmpEQ = (IEventRec *)calloc(GESTURE_EQ_SIZE, sizeof(IEventRec));
2262 ErrorF("[X11][GestureInitEQ] Failed to allocate memory for EQ !\n");
2263 return ERROR_ALLOCFAIL;
2266 for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
2268 tmpEQ[i].event = (InternalEvent *)malloc(sizeof(InternalEvent));
2269 if( !tmpEQ[i].event )
2271 ErrorF("[X11][GestureInitEQ] Failed to allocation memory for each event buffer in EQ !\n");
2272 return ERROR_ALLOCFAIL;
2276 g_pGesture->EQ = tmpEQ;
2277 g_pGesture->headEQ = g_pGesture->tailEQ = 0;
2287 if( !g_pGesture || !g_pGesture->EQ )
2288 return ERROR_INVALPTR;
2290 for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
2292 if( g_pGesture->EQ[i].event )
2294 free(g_pGesture->EQ[i].event);
2295 g_pGesture->EQ[i].event = NULL;
2299 free(g_pGesture->EQ);
2300 g_pGesture->EQ = NULL;
2306 GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
2310 if( !g_pGesture || !g_pGesture->EQ )
2312 ErrorF("[X11][GestureEnqueueEvent] Invalid pointer access !\n");
2313 return ERROR_INVALPTR;
2316 tail = g_pGesture->tailEQ;
2318 if( tail >= GESTURE_EQ_SIZE )
2320 ErrorF("[X11][GestureEnqueueEvent] Gesture EQ is full !\n");
2321 return ERROR_EQFULL;
2324 #ifdef __DETAIL_DEBUG__
2325 switch( ev->any.type )
2327 case ET_ButtonPress:
2328 ErrorF("[X11][GestureEnqueueEvent] ET_ButtonPress (id:%d)\n", device->id);
2331 case ET_ButtonRelease:
2332 ErrorF("[X11][GestureEnqueueEvent] ET_ButtonRelease (id:%d)\n", device->id);
2336 ErrorF("[X11][GestureEnqueueEvent] ET_Motion (id:%d)\n", device->id);
2339 #endif//__DETAIL_DEBUG__
2341 g_pGesture->EQ[tail].device = device;
2342 g_pGesture->EQ[tail].screen_num = screen_num;
2343 memcpy(g_pGesture->EQ[tail].event, ev, sizeof(InternalEvent));//need to be optimized
2344 g_pGesture->tailEQ++;
2350 GestureEventsFlush(void)
2353 DeviceIntPtr device;
2355 if( !g_pGesture->EQ )
2357 ErrorF("[X11][GestureEventsFlush] Invalid pointer access !\n");
2358 return ERROR_INVALPTR;
2361 #ifdef __DETAIL_DEBUG__
2362 ErrorF("[X11][GestureEventsFlush]\n");
2363 #endif//__DETAIL_DEBUG__
2365 for( i = g_pGesture->headEQ ; i < g_pGesture->tailEQ ; i++)
2367 device = g_pGesture->EQ[i].device;
2368 device->public.processInputProc(g_pGesture->EQ[i].event, device);
2371 for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
2372 g_pGesture->event_sum[i] = 0;
2374 g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
2380 GestureEventsDrop(void)
2382 g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
2385 #ifdef HAVE_PROPERTIES
2387 GestureInitProperty(DeviceIntPtr dev)
2391 prop_gesture_recognizer_onoff = MakeAtom(GESTURE_RECOGNIZER_ONOFF, strlen(GESTURE_RECOGNIZER_ONOFF), TRUE);
2392 rc = XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
2397 XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE);
2401 GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
2404 InputInfoPtr pInfo = dev->public.devicePrivate;
2406 if( prop_gesture_recognizer_onoff == atom )
2409 if( val->format != 32 || val->type != XA_INTEGER || val->size != 1 )
2414 data = *((int *)val->data);
2415 GestureSetDisable(pInfo, data);
2421 #endif//HAVE_PROPERTIES
2424 GestureInit(DeviceIntPtr device)
2427 pInfo = device->public.devicePrivate;
2429 #ifdef HAVE_PROPERTIES
2430 GestureInitProperty(device);
2431 XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL);
2438 GestureFini(DeviceIntPtr device)
2440 XIRegisterPropertyHandler(device, NULL, NULL, NULL);
2444 GesturePlug(pointer module, pointer options, int *errmaj, int *errmin)
2446 xf86AddInputDriver(&GESTURE, module, 0);
2451 GestureUnplug(pointer p)
2456 GesturePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
2459 GestureDevicePtr pGesture;
2461 if (!(pInfo = xf86AllocateInput(drv, 0)))
2464 pGesture = calloc(1, sizeof(GestureDeviceRec));
2466 pInfo->private = NULL;
2467 xf86DeleteInput(pInfo, 0);
2471 g_pGesture = pGesture;
2472 pInfo->private = pGesture;
2473 pInfo->name = xstrdup(dev->identifier);
2475 pInfo->type_name = XI_MOUSE; /* see XI.h */
2476 pInfo->conf_idev = dev;
2477 pInfo->read_input = GestureReadInput; /* new data avl */
2478 pInfo->switch_mode = NULL; /* toggle absolute/relative mode */
2479 pInfo->device_control = GestureControl; /* enable/disable dev */
2480 /* process driver specific options */
2481 pGesture->device = xf86SetStrOption(dev->commonOptions, "Device", "/dev/null");
2482 pGesture->is_active = xf86SetIntOption(dev->commonOptions, "Activate", 0);
2483 pGesture->gestureWin = None;
2485 xf86Msg(X_INFO, "%s: Using device %s.\n", pInfo->name, pGesture->device);
2487 /* process generic options */
2488 xf86CollectInputOptions(pInfo, NULL, NULL);
2489 xf86ProcessCommonOptions(pInfo, pInfo->options);
2492 pInfo->flags |= XI86_POINTER_CAPABLE;
2493 pInfo->flags |= XI86_OPEN_ON_INIT;
2494 pInfo->flags |= XI86_CONFIGURED;
2499 GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
2501 GestureDevicePtr pGesture = pInfo->private;
2503 g_pGesture = pGesture = NULL;
2504 pInfo->private = NULL;
2506 xf86DeleteInput(pInfo, 0);
2510 GestureControl(DeviceIntPtr device, int what)
2512 InputInfoPtr pInfo = device->public.devicePrivate;
2513 GestureDevicePtr pGesture = pInfo->private;
2518 GestureInit(device);
2521 /* Switch device on. Establish socket, start event delivery. */
2523 xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
2525 if (device->public.on)
2528 device->public.on = TRUE;
2529 pGesture->this_device = device;
2530 pGesture->num_mt_devices = 0;
2531 if( ERROR_ABNORMAL == GestureEnableEventHandler(pInfo) )
2537 GestureDisableEventHandler();
2538 GestureFini(device);
2539 pGesture->this_device = NULL;
2540 xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
2542 if (!device->public.on)
2546 device->public.on = FALSE;
2550 /* free what we have to free */
2557 GestureReadInput(InputInfoPtr pInfo)