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 **************************************************************************/
35 #include <xorg/events.h>
36 #include <xorg/gestureext.h>
37 #include <X11/extensions/gestureconst.h>
43 #define TTRACE_BEGIN(NAME) traceBegin(TTRACE_TAG_INPUT, NAME)
44 #define TTRACE_END() traceEnd(TTRACE_TAG_INPUT)
46 #define TTRACE_BEGIN(NAME)
48 #endif //ENABLE_TTRACE
50 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
51 #define HAVE_PROPERTIES 1
55 * If there's touch event in pointed window and there's no reponse, we just assume that client looks like deadlock.
56 * In this case, we will make a popup window and terminate application.
57 * To support this feature, we use SUPPORT_ANR_WITH_INPUT_EVENT flag.
59 #define SUPPORT_ANR_WITH_INPUT_EVENT
61 #define GESTURE_RECOGNIZER_ONOFF "GESTURE_RECOGNIZER_ONOFF"
62 #define GESTURE_PALM_REJECTION_MODE "GESTURE_PALM_REJECTION_MODE"
63 #define CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT "_CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT_"
64 #define ANR_EVENT_WINDOW "_ANR_EVENT_WINDOW_"
67 #define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
68 #define RootWindow(dev) dev->spriteInfo->sprite->spriteTrace[0]
69 #define CLIENT_BITS(id) ((id) & RESOURCE_CLIENT_MASK)
70 #define CLIENT_ID(id) ((int)(CLIENT_BITS(id) >> CLIENTOFFSET))
72 #define MAX_MT_DEVICES 2
73 #define GESTURE_EQ_SIZE 256
75 #define GESTURE_RECOGNIZER_ONOFF "GESTURE_RECOGNIZER_ONOFF"
77 #define FINGER_WIDTH 10
78 #define FINGER_HEIGHT 10
79 #define FINGER_WIDTH_2T 20
80 #define FINGER_HEIGHT_2T 20
81 #define AREA_CENTER_X(extents) ((extents)->x1 + (((extents)->x2-(extents)->x1)/2))
82 #define AREA_CENTER_Y(extents) ((extents)->y1 + (((extents)->y2-(extents)->y1)/2))
83 #define AREA_SIZE(extents) (ABS((extents)->x2-(extents)->x1)*ABS((extents)->y2-(extents)->y1))
84 #define INBOX(r,x,y) ( ((r)->x2 > x) && ((r)->x1 <= x) && ((r)->y2 > y) && ((r)->y1 <= y) )
85 #define AREA_HEIGHT(extents) (((extents)->y2)-((extents)->y1))
86 #define AREA_WIDTH(extents) (((extents)->x2)-((extents)->x1))
87 #define AREA_DIAG_LEN(extents) sqrt((AREA_WIDTH(extents)*AREA_WIDTH(extents))+(AREA_HEIGHT(extents)*AREA_HEIGHT(extents)))
90 #define TAP_THRESHOLD 100//in pixel
91 #define SINGLE_TAP_TIMEOUT 100//in msec
92 #define DOUBLE_TAP_TIMEOUT 250//in msec
95 #define PALM_HORIZ_ARRAY_COUNT 3
96 #define PALM_VERTI_ARRAY_COUNT 4
99 typedef double XDouble;
100 #define XDoubleToFixed(f) ((XFixed) ((f) * 65536))
101 #define XFixedToDouble(f) (((XDouble) (f)) / 65536)
103 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
104 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
105 #define ABS(x) (((x) < 0) ? -(x) : (x))
121 FLICK_POINT_NONE = 0,
129 /* Gesture query devices infomation and register handlers
130 * if a device_control function is called using DEVICE_READY */
131 #define DEVICE_READY 11
133 #define TAP_AREA_THRESHOLD 10000//= 100pixel * 100pixel
134 #define TAP_MOVE_THRESHOLD 35//pixel
135 #define SGL_TAP_TIME_THRESHOLD 300//ms
136 #define DBL_TAP_TIME_THRESHOLD 200//ms
137 #define MAX_TAP_REPEATS 3
139 #define FLICK_AREA_THRESHOLD 22500//=150pixel * 150pixel
140 #define FLICK_AREA_TIMEOUT 700//ms
141 #define FLICK_MOVE_THRESHOLD 100//pixel
142 #define FLICK_MOVE_TIMEOUT 1000//ms
143 #define FLICK_FALSE_Y_DIFF_COUNT 7
144 #define FLICK_FALSE_X_DIFF_COUNT 5
146 #define PALM_FLICK_DETECT_TIMEOUT 1000//ms
147 #define PALM_FLICK_MAX_TOUCH_MAJOR 130
149 #define AXIS_LABEL_PROP_ABS_MT_TRACKING_ID "Abs MT Tracking ID"
150 #define AXIS_LABEL_PROP_ABS_MT_SLOT "Abs MT Slot"
151 #define AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR "Abs MT Touch Major"
152 #define AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR "Abs MT Touch Minor"
153 #define AXIS_LABEL_PROP_ABS_MT_PALM "Abs MT Palm/MT Sumsize"
155 #ifndef _SUPPORT_EVDEVMULTITOUCH_DRV_
156 #define GESTURE_TOUCH_PRESS ET_TouchBegin
157 #define GESTURE_TOUCH_MOTION ET_TouchUpdate
158 #define GESTURE_TOUCH_RELEASE ET_TouchEnd
159 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
160 #define GESTURE_TOUCH_PRESS ET_ButtonPress
161 #define GESTURE_TOUCH_MOTION ET_Motion
162 #define GESTURE_TOUCH_RELEASE ET_ButtonRelease
163 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
165 typedef enum _MTSyncType
167 MTOUCH_FRAME_SYNC_END,
168 MTOUCH_FRAME_SYNC_BEGIN,
169 MTOUCH_FRAME_SYNC_UPDATE,
170 ROTARY_FRAME_SYNC_END,
171 ROTARY_FRAME_SYNC_BEGIN
174 typedef enum _EventHandleType
181 typedef enum _ErrorStatus
194 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
198 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
203 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
208 ET_Internal = 0xFF /* First byte */
211 struct _DeviceEvent {
212 unsigned char header; /**< Always ET_Internal */
213 enum EventType type; /**< One of EventType */
214 int length; /**< Length in bytes */
215 Time time; /**< Time in ms */
216 int deviceid; /**< Device to post this event for */
217 int sourceid; /**< The physical source device */
219 uint32_t button; /**< Button number (also used in pointer emulating
221 uint32_t key; /**< Key code */
223 uint32_t touchid; /**< Touch ID (client_id) */
224 int16_t root_x; /**< Pos relative to root window in integral data */
225 float root_x_frac; /**< Pos relative to root window in frac part */
226 int16_t root_y; /**< Pos relative to root window in integral part */
227 float root_y_frac; /**< Pos relative to root window in frac part */
228 uint8_t buttons[(MAX_BUTTONS + 7) / 8]; /**< Button mask */
230 uint8_t mask[(MAX_VALUATORS + 7) / 8];/**< Valuator mask */
231 uint8_t mode[(MAX_VALUATORS + 7) / 8];/**< Valuator mode (Abs or Rel)*/
232 double data[MAX_VALUATORS]; /**< Valuator data */
235 uint32_t base; /**< XKB base modifiers */
236 uint32_t latched; /**< XKB latched modifiers */
237 uint32_t locked; /**< XKB locked modifiers */
238 uint32_t effective;/**< XKB effective modifiers */
241 uint8_t base; /**< XKB base group */
242 uint8_t latched; /**< XKB latched group */
243 uint8_t locked; /**< XKB locked group */
244 uint8_t effective;/**< XKB effective group */
246 Window root; /**< Root window of the event */
247 int corestate; /**< Core key/button state BEFORE the event */
248 int key_repeat; /**< Internally-generated key repeat event */
249 uint32_t flags; /**< Flags to be copied into the generated event */
250 uint32_t resource; /**< Touch event resource, only for TOUCH_REPLAYING */
253 typedef struct _AnyEvent AnyEvent;
256 unsigned char header; /**< Always ET_Internal */
257 enum EventType type; /**< One of EventType */
258 int length; /**< Length in bytes */
259 Time time; /**< Time in ms */
266 union _InternalEvent {
268 unsigned char header; /**< Always ET_Internal */
269 enum EventType type; /**< One of ET_* */
270 int length; /**< Length in bytes */
271 Time time; /**< Time in ms. */
274 DeviceEvent device_event;
277 #define wUseDefault(w,field,def) ((w)->optional ? (w)->optional->field : def)
278 #define wBoundingShape(w) wUseDefault(w, boundingShape, NULL)
279 #define wInputShape(w) wUseDefault(w, inputShape, NULL)
280 #define wBorderWidth(w) ((int) (w)->borderWidth)
282 /* used as NULL-terminated list */
283 typedef struct _DevCursorNode {
286 struct _DevCursorNode* next;
287 } DevCursNodeRec, *DevCursNodePtr, *DevCursorList;
289 typedef struct _WindowOpt {
290 CursorPtr cursor; /* default: window.cursorNone */
291 VisualID visual; /* default: same as parent */
292 Colormap colormap; /* default: same as parent */
293 Mask dontPropagateMask; /* default: window.dontPropagate */
294 Mask otherEventMasks; /* default: 0 */
295 struct _OtherClients *otherClients; /* default: NULL */
296 struct _GrabRec *passiveGrabs; /* default: NULL */
297 PropertyPtr userProps; /* default: NULL */
298 CARD32 backingBitPlanes; /* default: ~0L */
299 CARD32 backingPixel; /* default: 0 */
300 RegionPtr boundingShape; /* default: NULL */
301 RegionPtr clipShape; /* default: NULL */
302 RegionPtr inputShape; /* default: NULL */
303 struct _OtherInputMasks *inputMasks; /* default: NULL */
304 DevCursorList deviceCursors; /* default: NULL */
305 } WindowOptRec, *WindowOptPtr;
307 typedef struct _Window {
308 DrawableRec drawable;
309 PrivateRec *devPrivates;
310 WindowPtr parent; /* ancestor chain */
311 WindowPtr nextSib; /* next lower sibling */
312 WindowPtr prevSib; /* next higher sibling */
313 WindowPtr firstChild; /* top-most child */
314 WindowPtr lastChild; /* bottom-most child */
315 RegionRec clipList; /* clipping rectangle for output */
316 RegionRec borderClip; /* NotClippedByChildren + border */
317 union _Validate *valdata;
319 RegionRec borderSize;
320 DDXPointRec origin; /* position relative to parent */
321 unsigned short borderWidth;
322 unsigned short deliverableEvents; /* all masks from all clients */
323 Mask eventMask; /* mask from the creating client */
326 pointer backStorage; /* null when BS disabled */
327 WindowOptPtr optional;
328 unsigned backgroundState:2; /* None, Relative, Pixel, Pixmap */
329 unsigned borderIsPixel:1;
330 unsigned cursorIsNone:1; /* else real cursor (might inherit) */
331 unsigned backingStore:2;
332 unsigned saveUnder:1;
333 unsigned DIXsaveUnder:1;
334 unsigned bitGravity:4;
335 unsigned winGravity:4;
336 unsigned overrideRedirect:1;
337 unsigned visibility:2;
339 unsigned realized:1; /* ancestors are all mapped */
340 unsigned viewable:1; /* realized && InputOutput */
341 unsigned dontPropagate:3;/* index into DontPropagateMasks */
342 unsigned forcedBS:1; /* system-supplied backingStore */
343 unsigned redirectDraw:2; /* COMPOSITE rendering redirect */
344 unsigned forcedBG:1; /* must have an opaque background */
346 unsigned rootlessUnhittable:1; /* doesn't hit-test */
351 unsigned damagedDescendants:1; /* some descendants are damaged */
352 unsigned inhibitBGPaint:1; /* paint the background? */
356 typedef struct _IEvent {
357 InternalEvent *event;
360 } IEventRec, *IEventPtr;
369 #define PressFlagFlick 0x01//(1 << 0)
370 #define PressFlagPan 0x02//(1 << 1)
371 #define PressFlagPinchRotation 0x04//(1 << 2)
372 #define PressFlagTap 0x08//(1 << 3)
373 #define PressFlagTapNHold 0x10//(1 << 4)
374 #define PressFlagHold 0x20//(1 << 5)
376 #define FlickFilterMask 0x01//(1 << 0)
377 #define PanFilterMask 0x02//(1 << 1)
378 #define PinchRotationFilterMask 0x04//(1 << 2)
379 #define TapFilterMask 0x08//(1 << 3)
380 #define TapNHoldFilterMask 0x10//(1 << 4)
381 #define HoldFilterMask 0x20//(1 << 5)
383 #define GESTURE_FILTER_MASK_ALL 0x3f//(FlickFilterMask | PanFilterMask | PinchRotationFilterMask | TapFilterMask |TapNHoldFilterMask | HoldFilterMask)
385 #define WFlickFilterMask 0x01//(1 << 0)
386 #define WTapFilterMask 0x02//(1 << 1)
387 #define WHoldFilterMask 0x04//(1 << 2)
388 #define WPalmFlickFilterMask 0x08//(1 << 3)
390 #define GESTURE_WATCH_FILTER_MASK_ALL 0x07//(WFlickFilterMask | WTapFilterMask | WHoldFilterMask )
392 #define MTSYNC_FLAG_TOUCH 0x01//(1 << 0)
393 #define MTSYNC_FLAG_ROTARY 0x02//(1 << 1)
395 #define PALM_HOLD_TIME_THRESHOLD 150
397 typedef struct _tagTouchStatus
399 int status;//One of BTN_RELEASED, BTN_PRESSED and BTN_MOVING
400 #ifndef _SUPPORT_EVDEVMULTITOUCH_DRV_
402 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
411 Time ptime; //press time
412 Time mtime; //motion time
413 Time rtime; //current/previous release time
416 typedef struct _tagCurrentTouchStatus
418 int status;//One of BTN_RELEASED, BTN_PRESSED and BTN_MOVING
423 typedef struct _tagPalmDrvStatus
428 unsigned int half_scrn_area_size;
429 int horiz_coord[PALM_HORIZ_ARRAY_COUNT];
430 int verti_coord[PALM_VERTI_ARRAY_COUNT];
431 } PalmMiscInfo, *PalmMiscInfoPtr;
433 #ifndef _SUPPORT_EVDEVMULTITOUCH_DRV_
434 typedef struct _tagPalmInfo
437 }PalmInfo, *PalmInfoPtr;
439 typedef struct _tagPalmFlickInfo
449 Bool *release_status;
454 Bool *is_line_invalid;
457 Bool *is_tmajor_invalid;
459 } PalmFlickInfo, *PalmFlickInfoPtr;
460 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
462 typedef struct _GestureDeviceRec
465 int version; /* Driver version */
466 OsTimerPtr device_setting_timer;
470 int flick_pressed_point;
473 int hwkeycode_flick_down;
474 int hwkeycode_flick_up;
475 int shutdown_keycode;
476 int flick_press_area;
477 int flick_press_area_left;
478 int flick_press_area_left_right;
479 int flick_minimum_height;
480 int activate_flick_down;//up to down
481 int activate_flick_up;//down to up
482 int activate_flick_right;//left to right
486 int singletap_threshold;
487 int doubletap_threshold;
488 int tripletap_threshold;
490 int num_tap_repeated;
492 double hold_area_threshold;
493 int hold_move_threshold;
494 int hold_time_threshold;
496 int palm_flick_time_threshold;
497 int palm_flick_max_tmajor_threshold;
498 int palm_flick_min_tmajor_threshold;
499 char *factory_cmdname;
501 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
502 int max_mt_tmajor[MAX_MT_DEVICES];
503 #else //_SUPPORT_EVDEVMULTITOUCH_DRV
505 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV
509 DeviceIntPtr hwkey_dev;
511 DeviceIntPtr rotary_dev;
512 unsigned char mtsync_flag;
513 int mtsync_total_count;
515 DeviceIntPtr power_device;
523 GestureGrabEventPtr GrabEvents;
524 Mask lastSelectedMask;
525 Window lastSelectedWin;
527 EventHandleType ehtype;
532 int hold_detector_activate;
533 int has_hold_grabmask;
534 pixman_region16_t chold_area;
535 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
536 CurTouchStatus cts[MAX_MT_DEVICES];
537 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
539 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
542 PalmMiscInfo palm_misc;
549 pixman_region16_t area;
550 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
551 pixman_region16_t finger_rects[MAX_MT_DEVICES];
552 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
553 pixman_region16_t *finger_rects;
554 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
561 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
562 TouchStatus fingers[MAX_MT_DEVICES];
563 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
564 TouchStatus *fingers;
565 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
567 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
568 int event_sum[MAX_MT_DEVICES];
569 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
571 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
572 uint32_t recognized_gesture;
573 uint32_t filter_mask;
575 DeviceIntPtr this_device;
576 #ifdef _SUPPORT_EVDEVMULTITOUCH_DRV_
577 DeviceIntPtr mt_devices[MAX_MT_DEVICES];
578 #else //_SUPPORT_EVDEVMULTITOUCH_DRV_
579 DeviceIntPtr mt_devices;
580 PalmFlickInfo palmFlickInfo;
582 #endif //_SUPPORT_EVDEVMULTITOUCH_DRV_
583 DeviceIntPtr master_pointer;
584 DeviceIntPtr xtest_pointer;
586 WindowPtr anr_window;
587 } GestureDeviceRec, *GestureDevicePtr ;