evdev-mt-touchpad.h 13.4 KB
Newer Older
1
/*
Peter Hutterer's avatar
Peter Hutterer committed
2
 * Copyright © 2014-2015 Red Hat, Inc.
3
 *
4 5 6 7 8 9
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
10
 *
11 12 13 14 15 16 17 18 19 20 21
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
22 23 24 25 26 27 28 29 30
 */

#ifndef EVDEV_MT_TOUCHPAD_H
#define EVDEV_MT_TOUCHPAD_H

#include <stdbool.h>

#include "evdev.h"
#include "filter.h"
31
#include "timer.h"
32 33

#define TOUCHPAD_HISTORY_LENGTH 4
34
#define TOUCHPAD_MIN_SAMPLES 4
35

36
/* Convert mm to a distance normalized to DEFAULT_MOUSE_DPI */
37
#define TP_MM_TO_DPI_NORMALIZED(mm) (DEFAULT_MOUSE_DPI/25.4 * mm)
38

39 40 41 42 43
enum touchpad_event {
	TOUCHPAD_EVENT_NONE		= 0,
	TOUCHPAD_EVENT_MOTION		= (1 << 0),
	TOUCHPAD_EVENT_BUTTON_PRESS	= (1 << 1),
	TOUCHPAD_EVENT_BUTTON_RELEASE	= (1 << 2),
44
	TOUCHPAD_EVENT_OTHERAXIS	= (1 << 3),
45 46
};

47 48 49 50 51 52 53 54 55
enum touchpad_model {
	MODEL_UNKNOWN = 0,
	MODEL_SYNAPTICS,
	MODEL_ALPS,
	MODEL_APPLETOUCH,
	MODEL_ELANTECH,
	MODEL_UNIBODY_MACBOOK
};

56 57
enum touch_state {
	TOUCH_NONE = 0,
58
	TOUCH_HOVERING,
59 60 61 62 63
	TOUCH_BEGIN,
	TOUCH_UPDATE,
	TOUCH_END
};

64 65 66
enum touch_palm_state {
	PALM_NONE = 0,
	PALM_EDGE,
67
	PALM_TYPING,
68
	PALM_TRACKPOINT,
69 70
};

71
enum button_event {
72
	BUTTON_EVENT_IN_BOTTOM_R = 30,
73
	BUTTON_EVENT_IN_BOTTOM_M,
74 75 76 77 78 79 80 81 82
	BUTTON_EVENT_IN_BOTTOM_L,
	BUTTON_EVENT_IN_TOP_R,
	BUTTON_EVENT_IN_TOP_M,
	BUTTON_EVENT_IN_TOP_L,
	BUTTON_EVENT_IN_AREA,
	BUTTON_EVENT_UP,
	BUTTON_EVENT_PRESS,
	BUTTON_EVENT_RELEASE,
	BUTTON_EVENT_TIMEOUT,
83 84 85
};

enum button_state {
86 87 88 89 90 91 92
	BUTTON_STATE_NONE,
	BUTTON_STATE_AREA,
	BUTTON_STATE_BOTTOM,
	BUTTON_STATE_TOP,
	BUTTON_STATE_TOP_NEW,
	BUTTON_STATE_TOP_TO_IGNORE,
	BUTTON_STATE_IGNORE,
93 94
};

95 96 97 98 99 100 101
enum tp_tap_state {
	TAP_STATE_IDLE = 4,
	TAP_STATE_TOUCH,
	TAP_STATE_HOLD,
	TAP_STATE_TAPPED,
	TAP_STATE_TOUCH_2,
	TAP_STATE_TOUCH_2_HOLD,
102
	TAP_STATE_TOUCH_2_RELEASE,
103 104 105
	TAP_STATE_TOUCH_3,
	TAP_STATE_TOUCH_3_HOLD,
	TAP_STATE_DRAGGING_OR_DOUBLETAP,
106
	TAP_STATE_DRAGGING_OR_TAP,
107 108 109
	TAP_STATE_DRAGGING,
	TAP_STATE_DRAGGING_WAIT,
	TAP_STATE_DRAGGING_2,
110 111
	TAP_STATE_MULTITAP,
	TAP_STATE_MULTITAP_DOWN,
112 113 114
	TAP_STATE_DEAD, /**< finger count exceeded */
};

115 116 117 118 119 120
enum tp_tap_touch_state {
	TAP_TOUCH_STATE_IDLE = 16,	/**< not in touch */
	TAP_TOUCH_STATE_TOUCH,		/**< touching, may tap */
	TAP_TOUCH_STATE_DEAD,		/**< exceeded motion/timeout */
};

121 122 123 124 125 126 127 128 129 130 131 132 133 134
/* For edge scrolling, so we only care about right and bottom */
enum tp_edge {
	EDGE_NONE = 0,
	EDGE_RIGHT = (1 << 0),
	EDGE_BOTTOM = (1 << 1),
};

enum tp_edge_scroll_touch_state {
	EDGE_SCROLL_TOUCH_STATE_NONE,
	EDGE_SCROLL_TOUCH_STATE_EDGE_NEW,
	EDGE_SCROLL_TOUCH_STATE_EDGE,
	EDGE_SCROLL_TOUCH_STATE_AREA,
};

135 136 137 138 139
enum tp_gesture_state {
	GESTURE_STATE_NONE,
	GESTURE_STATE_UNKNOWN,
	GESTURE_STATE_SCROLL,
	GESTURE_STATE_PINCH,
140
	GESTURE_STATE_SWIPE,
141 142
};

143 144 145 146 147 148
enum tp_thumb_state {
	THUMB_STATE_NO,
	THUMB_STATE_YES,
	THUMB_STATE_MAYBE,
};

149
struct tp_touch {
150
	struct tp_dispatch *tp;
151
	enum touch_state state;
152
	bool has_ended;				/* TRACKING_ID == -1 */
153
	bool dirty;
154
	struct device_coords point;
155
	uint64_t millis;
156
	int distance;				/* distance == 0 means touch */
157
	int pressure;
158

159 160 161 162 163 164 165 166 167
	struct {
		/* A quirk mostly used on Synaptics touchpads. In a
		   transition to/from fake touches > num_slots, the current
		   event data is likely garbage and the subsequent event
		   is likely too. This marker tells us to reset the motion
		   history again -> this effectively swallows any motion */
		bool reset_motion_history;
	} quirks;

168
	struct {
169
		struct device_coords samples[TOUCHPAD_HISTORY_LENGTH];
170 171 172 173
		unsigned int index;
		unsigned int count;
	} history;

174
	struct device_coords hysteresis_center;
175 176 177 178 179 180 181

	/* A pinned touchpoint is the one that pressed the physical button
	 * on a clickpad. After the release, it won't move until the center
	 * moves more than a threshold away from the original coordinates
	 */
	struct {
		bool is_pinned;
182
		struct device_coords center;
183
	} pinned;
184 185 186 187 188 189

	/* Software-button state and timeout if applicable */
	struct {
		enum button_state state;
		/* We use button_event here so we can use == on events */
		enum button_event curr;
190
		struct libinput_timer timer;
191
	} button;
192 193 194

	struct {
		enum tp_tap_touch_state state;
195
		struct device_coords initial;
196
		bool is_thumb;
197
	} tap;
198

199
	struct {
200
		enum tp_edge_scroll_touch_state edge_state;
201 202 203
		uint32_t edge;
		int direction;
		struct libinput_timer timer;
204
		struct device_coords initial;
205 206
	} scroll;

207
	struct {
208
		enum touch_palm_state state;
209
		struct device_coords first; /* first coordinates if is_palm == true */
210
		uint64_t time; /* first timestamp if is_palm == true */
211
	} palm;
212 213 214 215

	struct {
		struct device_coords initial;
	} gesture;
216 217 218 219

	struct {
		enum tp_thumb_state state;
		uint64_t first_touch_time;
220
		struct device_coords initial;
221
	} thumb;
222 223 224 225 226 227
};

struct tp_dispatch {
	struct evdev_dispatch base;
	struct evdev_device *device;
	unsigned int nfingers_down;		/* number of fingers down */
228
	unsigned int old_nfingers_down;		/* previous no fingers down */
229
	unsigned int slot;			/* current slot */
230
	bool has_mt;
231
	bool semi_mt;
232
	bool reports_distance;			/* does the device support true hovering */
233

Peter Hutterer's avatar
Peter Hutterer committed
234 235 236 237
	/* true if we're reading events (i.e. not suspended) but we're
	 * ignoring them */
	bool ignore_events;

238
	unsigned int num_slots;			/* number of slots */
239
	unsigned int ntouches;			/* no slots inc. fakes */
240
	struct tp_touch *touches;		/* len == ntouches */
241 242 243 244 245 246
	/* bit 0: BTN_TOUCH
	 * bit 1: BTN_TOOL_FINGER
	 * bit 2: BTN_TOOL_DOUBLETAP
	 * ...
	 */
	unsigned int fake_touches;
247

248
	struct device_coords hysteresis_margin;
249

250 251 252 253 254
	struct {
		struct device_coords min, max;
		struct ratelimit range_warn_limit;
	} warning_range;

255
	struct {
256 257
		double x_scale_coeff;
		double y_scale_coeff;
258
	} accel;
259

260
	struct {
261
		bool enabled;
262 263 264 265
		bool started;
		unsigned int finger_count;
		unsigned int finger_count_pending;
		struct libinput_timer finger_count_switch_timer;
266
		enum tp_gesture_state state;
267 268 269 270 271 272
		struct tp_touch *touches[2];
		uint64_t initial_time;
		double initial_distance;
		double prev_scale;
		double angle;
		struct device_float_coords center;
273 274
	} gesture;

275
	struct {
276
		bool is_clickpad;		/* true for clickpads */
277
		bool has_topbuttons;
278
		bool use_clickfinger;		/* number of fingers decides button number */
279
		bool click_pending;
280 281
		uint32_t state;
		uint32_t old_state;
282 283 284 285
		struct {
			double x_scale_coeff;
			double y_scale_coeff;
		} motion_dist;			/* for pinned touches */
286
		unsigned int active;		/* currently active button, for release event */
287
		bool active_is_topbutton;	/* is active a top button? */
288

289 290 291
		/* Only used for clickpads. The software button areas are
		 * always 2 horizontal stripes across the touchpad.
		 * The buttons are split according to the edge settings.
292
		 */
293
		struct {
294 295
			int32_t top_edge;	/* in device coordinates */
			int32_t rightbutton_left_edge; /* in device coordinates */
296
			int32_t middlebutton_left_edge; /* in device coordinates */
297
		} bottom_area;
298

299
		struct {
300 301 302
			int32_t bottom_edge;	/* in device coordinates */
			int32_t rightbutton_left_edge; /* in device coordinates */
			int32_t leftbutton_right_edge; /* in device coordinates */
303
		} top_area;
304 305

		struct evdev_device *trackpoint;
306 307 308 309

		enum libinput_config_click_method click_method;
		struct libinput_device_config_click_method config_method;
	} buttons;
310

311
	struct {
312 313
		struct libinput_device_config_scroll_method config_method;
		enum libinput_config_scroll_method method;
314 315
		int32_t right_edge;		/* in device coordinates */
		int32_t bottom_edge;		/* in device coordinates */
316 317
	} scroll;

318
	enum touchpad_event queued;
319 320

	struct {
321
		struct libinput_device_config_tap config;
322
		bool enabled;
323
		bool suspended;
324
		struct libinput_timer timer;
325
		enum tp_tap_state state;
326
		uint32_t buttons_pressed;
327
		uint64_t first_press_time;
328

329 330 331
		enum libinput_config_tap_button_map map;
		enum libinput_config_tap_button_map want_map;

332
		bool drag_enabled;
333
		bool drag_lock_enabled;
334
	} tap;
335 336

	struct {
337 338
		int32_t right_edge;		/* in device coordinates */
		int32_t left_edge;		/* in device coordinates */
339 340 341 342

		bool trackpoint_active;
		struct libinput_event_listener trackpoint_listener;
		struct libinput_timer trackpoint_timer;
343
		uint64_t trackpoint_last_event_time;
344
		uint32_t trackpoint_event_count;
345
		bool monitor_trackpoint;
346
	} palm;
347 348 349 350

	struct {
		struct libinput_device_config_send_events config;
		enum libinput_config_send_events_mode current_mode;
351
	} sendevents;
352

353
	struct {
354 355 356
		struct libinput_device_config_dwt config;
		bool dwt_enabled;

357 358 359 360
		bool keyboard_active;
		struct libinput_event_listener keyboard_listener;
		struct libinput_timer keyboard_timer;
		struct evdev_device *keyboard;
361
		unsigned long key_mask[NLONGS(KEY_CNT)];
362
		unsigned long mod_mask[NLONGS(KEY_CNT)];
363 364

		uint64_t keyboard_last_press_time;
365
	} dwt;
366 367 368 369

	struct {
		bool detect_thumbs;
		int threshold;
370 371
		int upper_thumb_line;
		int lower_thumb_line;
372
	} thumb;
373 374 375 376 377 378 379 380 381 382 383

	struct {
		/* A quirk used on the T450 series Synaptics hardware.
		 * Slowly moving the finger causes multiple events with only
		 * ABS_MT_PRESSURE but no x/y information. When the x/y
		 * event comes, it will be a jump of ~20 units. We use the
		 * below to count non-motion events to discard that first
		 * event with the jump.
		 */
		unsigned int nonmotion_event_count;
	} quirks;
384 385 386 387 388
};

#define tp_for_each_touch(_tp, _t) \
	for (unsigned int _i = 0; _i < (_tp)->ntouches && (_t = &(_tp)->touches[_i]); _i++)

389
static inline struct libinput*
390
tp_libinput_context(const struct tp_dispatch *tp)
391
{
392
	return evdev_libinput_context(tp->device);
393 394
}

395
static inline struct normalized_coords
396
tp_normalize_delta(struct tp_dispatch *tp, struct device_float_coords delta)
397
{
398 399
	struct normalized_coords normalized;

400 401
	normalized.x = delta.x * tp->accel.x_scale_coeff;
	normalized.y = delta.y * tp->accel.y_scale_coeff;
402 403

	return normalized;
404 405
}

406 407 408 409 410 411 412 413 414 415 416 417 418 419 420
/**
 * Takes a dpi-normalized set of coordinates, returns a set of coordinates
 * in the x-axis' coordinate space.
 */
static inline struct device_float_coords
tp_unnormalize_for_xaxis(struct tp_dispatch *tp, struct normalized_coords delta)
{
	struct device_float_coords raw;

	raw.x = delta.x / tp->accel.x_scale_coeff;
	raw.y = delta.y / tp->accel.x_scale_coeff; /* <--- not a typo */

	return raw;
}

421 422
struct normalized_coords
tp_get_delta(struct tp_touch *t);
423

424
struct normalized_coords
425
tp_filter_motion(struct tp_dispatch *tp,
426
		 const struct normalized_coords *unaccelerated,
427
		 uint64_t time);
Peter Hutterer's avatar
Peter Hutterer committed
428

429 430 431 432
struct normalized_coords
tp_filter_motion_unaccelerated(struct tp_dispatch *tp,
			       const struct normalized_coords *unaccelerated,
			       uint64_t time);
433

434
bool
435
tp_touch_active(const struct tp_dispatch *tp, const struct tp_touch *t);
436

437
int
438
tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time);
439

440 441 442
void
tp_tap_post_process_state(struct tp_dispatch *tp);

443
void
444 445
tp_init_tap(struct tp_dispatch *tp);

446
void
447
tp_remove_tap(struct tp_dispatch *tp);
448

449
void
450 451
tp_init_buttons(struct tp_dispatch *tp, struct evdev_device *device);

452
void
453 454 455
tp_init_top_softbuttons(struct tp_dispatch *tp,
			struct evdev_device *device,
			double topbutton_size_mult);
456

457
void
458
tp_remove_buttons(struct tp_dispatch *tp);
459

460
void
461 462
tp_process_button(struct tp_dispatch *tp,
		  const struct input_event *e,
463
		  uint64_t time);
464

465 466 467 468
void
tp_release_all_buttons(struct tp_dispatch *tp,
		       uint64_t time);

469
int
470
tp_post_button_events(struct tp_dispatch *tp, uint64_t time);
471

472
void
473
tp_button_handle_state(struct tp_dispatch *tp, uint64_t time);
474

475
bool
476 477
tp_button_touch_active(const struct tp_dispatch *tp,
		       const struct tp_touch *t);
478

479
bool
480 481
tp_button_is_inside_softbutton_area(const struct tp_dispatch *tp,
				    const struct tp_touch *t);
482

483 484 485 486
void
tp_release_all_taps(struct tp_dispatch *tp,
		    uint64_t time);

487 488 489 490 491 492
void
tp_tap_suspend(struct tp_dispatch *tp, uint64_t time);

void
tp_tap_resume(struct tp_dispatch *tp, uint64_t time);

493
bool
494
tp_tap_dragging(const struct tp_dispatch *tp);
495

496
void
497 498 499
tp_edge_scroll_init(struct tp_dispatch *tp, struct evdev_device *device);

void
500
tp_remove_edge_scroll(struct tp_dispatch *tp);
501 502 503 504 505 506 507 508 509 510 511

void
tp_edge_scroll_handle_state(struct tp_dispatch *tp, uint64_t time);

int
tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time);

void
tp_edge_scroll_stop_events(struct tp_dispatch *tp, uint64_t time);

int
512 513
tp_edge_scroll_touch_active(const struct tp_dispatch *tp,
			    const struct tp_touch *t);
514

515
uint32_t
516
tp_touch_get_edge(const struct tp_dispatch *tp, const struct tp_touch *t);
517

518
void
519 520 521 522 523 524
tp_init_gesture(struct tp_dispatch *tp);

void
tp_remove_gesture(struct tp_dispatch *tp);

void
525 526 527 528
tp_gesture_stop(struct tp_dispatch *tp, uint64_t time);

void
tp_gesture_cancel(struct tp_dispatch *tp, uint64_t time);
529 530 531 532 533 534 535 536 537 538

void
tp_gesture_handle_state(struct tp_dispatch *tp, uint64_t time);

void
tp_gesture_post_events(struct tp_dispatch *tp, uint64_t time);

void
tp_gesture_stop_twofinger_scroll(struct tp_dispatch *tp, uint64_t time);

539
bool
540
tp_palm_tap_is_palm(const struct tp_dispatch *tp, const struct tp_touch *t);
541

542 543 544
void
tp_clickpad_middlebutton_apply_config(struct evdev_device *device);

545
#endif