xref: /third_party/libinput/src/evdev-tablet.c (revision a46c0ec8)
1/*
2 * Copyright © 2014 Red Hat, Inc.
3 * Copyright © 2014 Lyude Paul
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24#include "config.h"
25#include "evdev-tablet.h"
26#include "util-input-event.h"
27
28#include <assert.h>
29#include <stdbool.h>
30#include <string.h>
31
32#if HAVE_LIBWACOM
33#include <libwacom/libwacom.h>
34#endif
35
36enum notify {
37	DONT_NOTIFY,
38	DO_NOTIFY,
39};
40
41/* The tablet sends events every ~2ms , 50ms should be plenty enough to
42   detect out-of-range.
43   This value is higher during test suite runs */
44static int FORCED_PROXOUT_TIMEOUT = 50 * 1000; /* µs */
45
46#define tablet_set_status(tablet_,s_) (tablet_)->status |= (s_)
47#define tablet_unset_status(tablet_,s_) (tablet_)->status &= ~(s_)
48#define tablet_has_status(tablet_,s_) (!!((tablet_)->status & (s_)))
49
50static inline void
51tablet_get_pressed_buttons(struct tablet_dispatch *tablet,
52			   struct button_state *buttons)
53{
54	size_t i;
55	const struct button_state *state = &tablet->button_state,
56			          *prev_state = &tablet->prev_button_state;
57
58	for (i = 0; i < sizeof(buttons->bits); i++)
59		buttons->bits[i] = state->bits[i] & ~(prev_state->bits[i]);
60}
61
62static inline void
63tablet_get_released_buttons(struct tablet_dispatch *tablet,
64			    struct button_state *buttons)
65{
66	size_t i;
67	const struct button_state *state = &tablet->button_state,
68			          *prev_state = &tablet->prev_button_state;
69
70	for (i = 0; i < sizeof(buttons->bits); i++)
71		buttons->bits[i] = prev_state->bits[i] &
72					~(state->bits[i]);
73}
74
75/* Merge the previous state with the current one so all buttons look like
76 * they just got pressed in this frame */
77static inline void
78tablet_force_button_presses(struct tablet_dispatch *tablet)
79{
80	struct button_state *state = &tablet->button_state,
81			    *prev_state = &tablet->prev_button_state;
82	size_t i;
83
84	for (i = 0; i < sizeof(state->bits); i++) {
85		state->bits[i] = state->bits[i] | prev_state->bits[i];
86		prev_state->bits[i] = 0;
87	}
88}
89
90static inline size_t
91tablet_history_size(const struct tablet_dispatch *tablet)
92{
93	return tablet->history.size;
94}
95
96static inline void
97tablet_history_reset(struct tablet_dispatch *tablet)
98{
99	tablet->history.count = 0;
100}
101
102static inline void
103tablet_history_push(struct tablet_dispatch *tablet,
104		    const struct tablet_axes *axes)
105{
106	unsigned int index = (tablet->history.index + 1) %
107				tablet_history_size(tablet);
108
109	tablet->history.samples[index] = *axes;
110	tablet->history.index = index;
111	tablet->history.count = min(tablet->history.count + 1,
112				    tablet_history_size(tablet));
113
114	if (tablet->history.count < tablet_history_size(tablet))
115		tablet_history_push(tablet, axes);
116}
117
118/**
119 * Return a previous axis state, where index of 0 means "most recent", 1 is
120 * "one before most recent", etc.
121 */
122static inline const struct tablet_axes*
123tablet_history_get(const struct tablet_dispatch *tablet, unsigned int index)
124{
125	size_t sz = tablet_history_size(tablet);
126
127	assert(index < sz);
128	assert(index < tablet->history.count);
129
130	index = (tablet->history.index + sz - index) % sz;
131	return &tablet->history.samples[index];
132}
133
134static inline void
135tablet_reset_changed_axes(struct tablet_dispatch *tablet)
136{
137	memset(tablet->changed_axes, 0, sizeof(tablet->changed_axes));
138}
139
140static bool
141tablet_device_has_axis(struct tablet_dispatch *tablet,
142		       enum libinput_tablet_tool_axis axis)
143{
144	struct libevdev *evdev = tablet->device->evdev;
145	bool has_axis = false;
146	unsigned int code;
147
148	if (axis == LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z) {
149		has_axis = (libevdev_has_event_code(evdev,
150						    EV_KEY,
151						    BTN_TOOL_MOUSE) &&
152			    libevdev_has_event_code(evdev,
153						    EV_ABS,
154						    ABS_TILT_X) &&
155			    libevdev_has_event_code(evdev,
156						    EV_ABS,
157						    ABS_TILT_Y));
158		code = axis_to_evcode(axis);
159		has_axis |= libevdev_has_event_code(evdev,
160						    EV_ABS,
161						    code);
162	} else if (axis == LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL) {
163		has_axis = libevdev_has_event_code(evdev,
164						   EV_REL,
165						   REL_WHEEL);
166	} else {
167		code = axis_to_evcode(axis);
168		has_axis = libevdev_has_event_code(evdev,
169						   EV_ABS,
170						   code);
171	}
172
173	return has_axis;
174}
175
176static inline bool
177tablet_filter_axis_fuzz(const struct tablet_dispatch *tablet,
178			const struct evdev_device *device,
179			const struct input_event *e,
180			enum libinput_tablet_tool_axis axis)
181{
182	int delta, fuzz;
183	int current, previous;
184
185	previous = tablet->prev_value[axis];
186	current = e->value;
187	delta = previous - current;
188
189	fuzz = libevdev_get_abs_fuzz(device->evdev, e->code);
190
191	/* ABS_DISTANCE doesn't have have fuzz set and causes continuous
192	 * updates for the cursor/lens tools. Add a minimum fuzz of 2, same
193	 * as the xf86-input-wacom driver
194	 */
195	switch (e->code) {
196	case ABS_DISTANCE:
197		fuzz = max(2, fuzz);
198		break;
199	default:
200		break;
201	}
202
203	return abs(delta) <= fuzz;
204}
205
206static void
207tablet_process_absolute(struct tablet_dispatch *tablet,
208			struct evdev_device *device,
209			struct input_event *e,
210			uint64_t time)
211{
212	enum libinput_tablet_tool_axis axis;
213
214	switch (e->code) {
215	case ABS_X:
216	case ABS_Y:
217	case ABS_Z:
218	case ABS_PRESSURE:
219	case ABS_TILT_X:
220	case ABS_TILT_Y:
221	case ABS_DISTANCE:
222	case ABS_WHEEL:
223		axis = evcode_to_axis(e->code);
224		if (axis == LIBINPUT_TABLET_TOOL_AXIS_NONE) {
225			evdev_log_bug_libinput(device,
226					       "Invalid ABS event code %#x\n",
227					       e->code);
228			break;
229		}
230
231		tablet->prev_value[axis] = tablet->current_value[axis];
232		if (tablet_filter_axis_fuzz(tablet, device, e, axis))
233			break;
234
235		tablet->current_value[axis] = e->value;
236		set_bit(tablet->changed_axes, axis);
237		tablet_set_status(tablet, TABLET_AXES_UPDATED);
238		break;
239	/* tool_id is the identifier for the tool we can use in libwacom
240	 * to identify it (if we have one anyway) */
241	case ABS_MISC:
242		tablet->current_tool.id = e->value;
243		break;
244	/* Intuos 3 strip data. Should only happen on the Pad device, not on
245	   the Pen device. */
246	case ABS_RX:
247	case ABS_RY:
248	/* Only on the 4D mouse (Intuos2), obsolete */
249	case ABS_RZ:
250	/* Only on the 4D mouse (Intuos2), obsolete.
251	   The 24HD sends ABS_THROTTLE on the Pad device for the second
252	   wheel but we shouldn't get here on kernel >= 3.17.
253	   */
254	case ABS_THROTTLE:
255	default:
256		evdev_log_info(device,
257			       "Unhandled ABS event code %#x\n",
258			       e->code);
259		break;
260	}
261}
262
263static void
264tablet_apply_rotation(struct evdev_device *device)
265{
266	struct tablet_dispatch *tablet = tablet_dispatch(device->dispatch);
267
268	if (tablet->rotation.rotate == tablet->rotation.want_rotate)
269		return;
270
271	if (!tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY))
272		return;
273
274	tablet->rotation.rotate = tablet->rotation.want_rotate;
275
276	evdev_log_debug(device,
277			"tablet-rotation: rotation is %s\n",
278			tablet->rotation.rotate ? "on" : "off");
279}
280
281static void
282tablet_change_rotation(struct evdev_device *device, enum notify notify)
283{
284	struct tablet_dispatch *tablet = tablet_dispatch(device->dispatch);
285	struct evdev_device *touch_device = tablet->touch_device;
286	struct evdev_dispatch *dispatch;
287	bool tablet_is_left, touchpad_is_left;
288
289	tablet_is_left = tablet->device->left_handed.enabled;
290	touchpad_is_left = tablet->rotation.touch_device_left_handed_state;
291
292	tablet->rotation.want_rotate = tablet_is_left || touchpad_is_left;
293	tablet_apply_rotation(device);
294
295	if (notify == DO_NOTIFY && touch_device) {
296		bool enable = device->left_handed.want_enabled;
297
298		dispatch = touch_device->dispatch;
299		if (dispatch->interface->left_handed_toggle)
300			dispatch->interface->left_handed_toggle(dispatch,
301								touch_device,
302								enable);
303	}
304}
305
306static void
307tablet_change_to_left_handed(struct evdev_device *device)
308{
309	if (device->left_handed.enabled == device->left_handed.want_enabled)
310		return;
311
312	device->left_handed.enabled = device->left_handed.want_enabled;
313
314	tablet_change_rotation(device, DO_NOTIFY);
315}
316
317static void
318tablet_update_tool(struct tablet_dispatch *tablet,
319		   struct evdev_device *device,
320		   enum libinput_tablet_tool_type tool,
321		   bool enabled)
322{
323	assert(tool != LIBINPUT_TOOL_NONE);
324
325	if (enabled) {
326		tablet->current_tool.type = tool;
327		tablet_set_status(tablet, TABLET_TOOL_ENTERING_PROXIMITY);
328		tablet_unset_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY);
329	}
330	else if (!tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY)) {
331		tablet_set_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY);
332	}
333}
334
335static inline double
336normalize_slider(const struct input_absinfo *absinfo)
337{
338	double value = (absinfo->value - absinfo->minimum) / absinfo_range(absinfo);
339
340	return value * 2 - 1;
341}
342
343static inline double
344normalize_distance(const struct input_absinfo *absinfo)
345{
346	double value = (absinfo->value - absinfo->minimum) / absinfo_range(absinfo);
347
348	return value;
349}
350
351static inline double
352normalize_pressure(const struct input_absinfo *absinfo,
353		   struct libinput_tablet_tool *tool)
354{
355	/**
356	 * Note: the upper threshold takes the offset into account so that
357	 *            |- 4% -|
358	 * min |------X------X-------------------------| max
359	 *            |      |
360	 *            |      + upper threshold / tip trigger
361	 *            +- offset and lower threshold
362	 *
363	 * The axis is scaled into the range [lower, max] so that the lower
364	 * threshold is 0 pressure.
365	 */
366	int base = tool->pressure.threshold.lower;
367	double range = absinfo->maximum - base + 1;
368	double value = (absinfo->value - base) / range;
369
370	return max(0.0, value);
371}
372
373static inline double
374adjust_tilt(const struct input_absinfo *absinfo)
375{
376	double value = (absinfo->value - absinfo->minimum) / absinfo_range(absinfo);
377	const int WACOM_MAX_DEGREES = 64;
378
379	/* If resolution is nonzero, it's in units/radian. But require
380	 * a min/max less/greater than zero so we can assume 0 is the
381	 * center */
382	if (absinfo->resolution != 0 &&
383	    absinfo->maximum > 0 &&
384	    absinfo->minimum < 0) {
385		value = 180.0/M_PI * absinfo->value/absinfo->resolution;
386	} else {
387		/* Wacom supports physical [-64, 64] degrees, so map to that by
388		 * default. If other tablets have a different physical range or
389		 * nonzero physical offsets, they need extra treatment
390		 * here.
391		 */
392		/* Map to the (-1, 1) range */
393		value = (value * 2) - 1;
394		value *= WACOM_MAX_DEGREES;
395	}
396
397	return value;
398}
399
400static inline int32_t
401invert_axis(const struct input_absinfo *absinfo)
402{
403	return absinfo->maximum - (absinfo->value - absinfo->minimum);
404}
405
406static void
407convert_tilt_to_rotation(struct tablet_dispatch *tablet)
408{
409	const int offset = 5;
410	double x, y;
411	double angle = 0.0;
412
413	/* Wacom Intuos 4, 5, Pro mouse calculates rotation from the x/y tilt
414	   values. The device has a 175 degree CCW hardware offset but since we use
415	   atan2 the effective offset is just 5 degrees.
416	   */
417	x = tablet->axes.tilt.x;
418	y = tablet->axes.tilt.y;
419
420	/* atan2 is CCW, we want CW -> negate x */
421	if (x || y)
422		angle = ((180.0 * atan2(-x, y)) / M_PI);
423
424	angle = fmod(360 + angle - offset, 360);
425
426	tablet->axes.rotation = angle;
427	set_bit(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z);
428}
429
430static double
431convert_to_degrees(const struct input_absinfo *absinfo, double offset)
432{
433	/* range is [0, 360[, i.e. range + 1 */
434	double value = (absinfo->value - absinfo->minimum) / absinfo_range(absinfo);
435
436	return fmod(value * 360.0 + offset, 360.0);
437}
438
439static inline double
440normalize_wheel(struct tablet_dispatch *tablet,
441		int value)
442{
443	struct evdev_device *device = tablet->device;
444
445	return value * device->scroll.wheel_click_angle.x;
446}
447
448static inline void
449tablet_update_xy(struct tablet_dispatch *tablet,
450		 struct evdev_device *device)
451{
452	const struct input_absinfo *absinfo;
453	int value;
454
455	if (!libevdev_has_event_code(device->evdev, EV_ABS, ABS_X) ||
456	    !libevdev_has_event_code(device->evdev, EV_ABS, ABS_Y))
457		return;
458
459	if (bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_X) ||
460	    bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_Y)) {
461		absinfo = libevdev_get_abs_info(device->evdev, ABS_X);
462
463		if (tablet->rotation.rotate)
464			value = invert_axis(absinfo);
465		else
466			value = absinfo->value;
467
468		tablet->axes.point.x = value;
469
470		absinfo = libevdev_get_abs_info(device->evdev, ABS_Y);
471
472		if (tablet->rotation.rotate)
473			value = invert_axis(absinfo);
474		else
475			value = absinfo->value;
476
477		tablet->axes.point.y = value;
478
479		evdev_transform_absolute(device, &tablet->axes.point);
480	}
481}
482
483static inline struct normalized_coords
484tablet_tool_process_delta(struct tablet_dispatch *tablet,
485			  struct libinput_tablet_tool *tool,
486			  const struct evdev_device *device,
487			  struct tablet_axes *axes,
488			  uint64_t time)
489{
490	const struct normalized_coords zero = { 0.0, 0.0 };
491	struct device_coords delta = { 0, 0 };
492	struct device_float_coords accel;
493
494	/* When tool contact changes, we probably got a cursor jump. Don't
495	   try to calculate a delta for that event */
496	if (!tablet_has_status(tablet,
497			       TABLET_TOOL_ENTERING_PROXIMITY) &&
498	    !tablet_has_status(tablet, TABLET_TOOL_ENTERING_CONTACT) &&
499	    !tablet_has_status(tablet, TABLET_TOOL_LEAVING_CONTACT) &&
500	    (bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_X) ||
501	     bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_Y))) {
502		delta.x = axes->point.x - tablet->last_smooth_point.x;
503		delta.y = axes->point.y - tablet->last_smooth_point.y;
504	}
505
506	if (axes->point.x != tablet->last_smooth_point.x)
507		set_bit(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_X);
508	if (axes->point.y != tablet->last_smooth_point.y)
509		set_bit(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_Y);
510
511	tablet->last_smooth_point = axes->point;
512
513	accel.x = 1.0 * delta.x;
514	accel.y = 1.0 * delta.y;
515
516	if (device_float_is_zero(accel))
517		return zero;
518
519	return filter_dispatch(device->pointer.filter,
520			       &accel,
521			       tool,
522			       time);
523}
524
525static inline void
526tablet_update_pressure(struct tablet_dispatch *tablet,
527		       struct evdev_device *device,
528		       struct libinput_tablet_tool *tool)
529{
530	const struct input_absinfo *absinfo;
531
532	if (!libevdev_has_event_code(device->evdev, EV_ABS, ABS_PRESSURE))
533		return;
534
535	if (bit_is_set(tablet->changed_axes,
536		       LIBINPUT_TABLET_TOOL_AXIS_PRESSURE)) {
537		absinfo = libevdev_get_abs_info(device->evdev, ABS_PRESSURE);
538		tablet->axes.pressure = normalize_pressure(absinfo, tool);
539	}
540}
541
542static inline void
543tablet_update_distance(struct tablet_dispatch *tablet,
544		       struct evdev_device *device)
545{
546	const struct input_absinfo *absinfo;
547
548	if (!libevdev_has_event_code(device->evdev, EV_ABS, ABS_DISTANCE))
549		return;
550
551	if (bit_is_set(tablet->changed_axes,
552		       LIBINPUT_TABLET_TOOL_AXIS_DISTANCE)) {
553		absinfo = libevdev_get_abs_info(device->evdev, ABS_DISTANCE);
554		tablet->axes.distance = normalize_distance(absinfo);
555	}
556}
557
558static inline void
559tablet_update_slider(struct tablet_dispatch *tablet,
560		     struct evdev_device *device)
561{
562	const struct input_absinfo *absinfo;
563
564	if (!libevdev_has_event_code(device->evdev, EV_ABS, ABS_WHEEL))
565		return;
566
567	if (bit_is_set(tablet->changed_axes,
568		       LIBINPUT_TABLET_TOOL_AXIS_SLIDER)) {
569		absinfo = libevdev_get_abs_info(device->evdev, ABS_WHEEL);
570		tablet->axes.slider = normalize_slider(absinfo);
571	}
572}
573
574static inline void
575tablet_update_tilt(struct tablet_dispatch *tablet,
576		   struct evdev_device *device)
577{
578	const struct input_absinfo *absinfo;
579
580	if (!libevdev_has_event_code(device->evdev, EV_ABS, ABS_TILT_X) ||
581	    !libevdev_has_event_code(device->evdev, EV_ABS, ABS_TILT_Y))
582		return;
583
584	/* mouse rotation resets tilt to 0 so always fetch both axes if
585	 * either has changed */
586	if (bit_is_set(tablet->changed_axes,
587		       LIBINPUT_TABLET_TOOL_AXIS_TILT_X) ||
588	    bit_is_set(tablet->changed_axes,
589		       LIBINPUT_TABLET_TOOL_AXIS_TILT_Y)) {
590
591		absinfo = libevdev_get_abs_info(device->evdev, ABS_TILT_X);
592		tablet->axes.tilt.x = adjust_tilt(absinfo);
593
594		absinfo = libevdev_get_abs_info(device->evdev, ABS_TILT_Y);
595		tablet->axes.tilt.y = adjust_tilt(absinfo);
596
597		if (device->left_handed.enabled) {
598			tablet->axes.tilt.x *= -1;
599			tablet->axes.tilt.y *= -1;
600		}
601	}
602}
603
604static inline void
605tablet_update_artpen_rotation(struct tablet_dispatch *tablet,
606			      struct evdev_device *device)
607{
608	const struct input_absinfo *absinfo;
609
610	if (!libevdev_has_event_code(device->evdev, EV_ABS, ABS_Z))
611		return;
612
613	if (bit_is_set(tablet->changed_axes,
614		       LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z)) {
615		absinfo = libevdev_get_abs_info(device->evdev,
616						ABS_Z);
617		/* artpen has 0 with buttons pointing east */
618		tablet->axes.rotation = convert_to_degrees(absinfo, 90);
619	}
620}
621
622static inline void
623tablet_update_mouse_rotation(struct tablet_dispatch *tablet,
624			     struct evdev_device *device)
625{
626	if (bit_is_set(tablet->changed_axes,
627		       LIBINPUT_TABLET_TOOL_AXIS_TILT_X) ||
628	    bit_is_set(tablet->changed_axes,
629		       LIBINPUT_TABLET_TOOL_AXIS_TILT_Y)) {
630		convert_tilt_to_rotation(tablet);
631	}
632}
633
634static inline void
635tablet_update_rotation(struct tablet_dispatch *tablet,
636		       struct evdev_device *device)
637{
638	/* We must check ROTATION_Z after TILT_X/Y so that the tilt axes are
639	 * already normalized and set if we have the mouse/lens tool */
640	if (tablet->current_tool.type == LIBINPUT_TABLET_TOOL_TYPE_MOUSE ||
641	    tablet->current_tool.type == LIBINPUT_TABLET_TOOL_TYPE_LENS) {
642		tablet_update_mouse_rotation(tablet, device);
643		clear_bit(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_TILT_X);
644		clear_bit(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_TILT_Y);
645		tablet->axes.tilt.x = 0;
646		tablet->axes.tilt.y = 0;
647
648		/* tilt is already converted to left-handed, so mouse
649		 * rotation is converted to left-handed automatically */
650	} else {
651
652		tablet_update_artpen_rotation(tablet, device);
653
654		if (device->left_handed.enabled) {
655			double r = tablet->axes.rotation;
656			tablet->axes.rotation = fmod(180 + r, 360);
657		}
658	}
659}
660
661static inline void
662tablet_update_wheel(struct tablet_dispatch *tablet,
663		    struct evdev_device *device)
664{
665	int a;
666
667	a = LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL;
668	if (bit_is_set(tablet->changed_axes, a)) {
669		/* tablet->axes.wheel_discrete is already set */
670		tablet->axes.wheel = normalize_wheel(tablet,
671						     tablet->axes.wheel_discrete);
672	} else {
673		tablet->axes.wheel = 0;
674		tablet->axes.wheel_discrete = 0;
675	}
676}
677
678static void
679tablet_smoothen_axes(const struct tablet_dispatch *tablet,
680		     struct tablet_axes *axes)
681{
682	size_t i;
683	size_t count = tablet_history_size(tablet);
684	struct tablet_axes smooth = { 0 };
685
686	for (i = 0; i < count; i++) {
687		const struct tablet_axes *a = tablet_history_get(tablet, i);
688
689		smooth.point.x += a->point.x;
690		smooth.point.y += a->point.y;
691
692		smooth.tilt.x += a->tilt.x;
693		smooth.tilt.y += a->tilt.y;
694	}
695
696	axes->point.x = smooth.point.x/count;
697	axes->point.y = smooth.point.y/count;
698
699	axes->tilt.x = smooth.tilt.x/count;
700	axes->tilt.y = smooth.tilt.y/count;
701}
702
703static bool
704tablet_check_notify_axes(struct tablet_dispatch *tablet,
705			 struct evdev_device *device,
706			 struct libinput_tablet_tool *tool,
707			 struct tablet_axes *axes_out,
708			 uint64_t time)
709{
710	struct tablet_axes axes = {0};
711	const char tmp[sizeof(tablet->changed_axes)] = {0};
712	bool rc = false;
713
714	if (memcmp(tmp, tablet->changed_axes, sizeof(tmp)) == 0) {
715		axes = tablet->axes;
716		goto out;
717	}
718
719	tablet_update_xy(tablet, device);
720	tablet_update_pressure(tablet, device, tool);
721	tablet_update_distance(tablet, device);
722	tablet_update_slider(tablet, device);
723	tablet_update_tilt(tablet, device);
724	tablet_update_wheel(tablet, device);
725	/* We must check ROTATION_Z after TILT_X/Y so that the tilt axes are
726	 * already normalized and set if we have the mouse/lens tool */
727	tablet_update_rotation(tablet, device);
728
729	axes.point = tablet->axes.point;
730	axes.pressure = tablet->axes.pressure;
731	axes.distance = tablet->axes.distance;
732	axes.slider = tablet->axes.slider;
733	axes.tilt = tablet->axes.tilt;
734	axes.wheel = tablet->axes.wheel;
735	axes.wheel_discrete = tablet->axes.wheel_discrete;
736	axes.rotation = tablet->axes.rotation;
737
738	rc = true;
739
740out:
741	/* The tool position often jumps to a different spot when contact changes.
742	 * If tool contact changes, clear the history to prevent axis smoothing
743	 * from trying to average over the spatial discontinuity. */
744	if (tablet_has_status(tablet, TABLET_TOOL_ENTERING_CONTACT) ||
745	    tablet_has_status(tablet, TABLET_TOOL_LEAVING_CONTACT)) {
746		tablet_history_reset(tablet);
747	}
748
749	tablet_history_push(tablet, &tablet->axes);
750	tablet_smoothen_axes(tablet, &axes);
751
752	/* The delta relies on the last *smooth* point, so we do it last */
753	axes.delta = tablet_tool_process_delta(tablet, tool, device, &axes, time);
754
755	*axes_out = axes;
756
757	return rc;
758}
759
760static void
761tablet_update_button(struct tablet_dispatch *tablet,
762		     uint32_t evcode,
763		     uint32_t enable)
764{
765	switch (evcode) {
766	case BTN_LEFT:
767	case BTN_RIGHT:
768	case BTN_MIDDLE:
769	case BTN_SIDE:
770	case BTN_EXTRA:
771	case BTN_FORWARD:
772	case BTN_BACK:
773	case BTN_TASK:
774	case BTN_STYLUS:
775	case BTN_STYLUS2:
776		break;
777	default:
778		evdev_log_info(tablet->device,
779			       "Unhandled button %s (%#x)\n",
780			       libevdev_event_code_get_name(EV_KEY, evcode),
781			       evcode);
782		return;
783	}
784
785	if (enable) {
786		set_bit(tablet->button_state.bits, evcode);
787		tablet_set_status(tablet, TABLET_BUTTONS_PRESSED);
788	} else {
789		clear_bit(tablet->button_state.bits, evcode);
790		tablet_set_status(tablet, TABLET_BUTTONS_RELEASED);
791	}
792}
793
794static inline enum libinput_tablet_tool_type
795tablet_evcode_to_tool(int code)
796{
797	enum libinput_tablet_tool_type type;
798
799	switch (code) {
800	case BTN_TOOL_PEN:	type = LIBINPUT_TABLET_TOOL_TYPE_PEN;		break;
801	case BTN_TOOL_RUBBER:	type = LIBINPUT_TABLET_TOOL_TYPE_ERASER;	break;
802	case BTN_TOOL_BRUSH:	type = LIBINPUT_TABLET_TOOL_TYPE_BRUSH;		break;
803	case BTN_TOOL_PENCIL:	type = LIBINPUT_TABLET_TOOL_TYPE_PENCIL;	break;
804	case BTN_TOOL_AIRBRUSH:	type = LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH;	break;
805	case BTN_TOOL_MOUSE:	type = LIBINPUT_TABLET_TOOL_TYPE_MOUSE;		break;
806	case BTN_TOOL_LENS:	type = LIBINPUT_TABLET_TOOL_TYPE_LENS;		break;
807	default:
808		abort();
809	}
810
811	return type;
812}
813
814static void
815tablet_process_key(struct tablet_dispatch *tablet,
816		   struct evdev_device *device,
817		   struct input_event *e,
818		   uint64_t time)
819{
820	enum libinput_tablet_tool_type type;
821
822	/* ignore kernel key repeat */
823	if (e->value == 2)
824		return;
825
826	switch (e->code) {
827	case BTN_TOOL_FINGER:
828		evdev_log_bug_libinput(device,
829			       "Invalid tool 'finger' on tablet interface\n");
830		break;
831	case BTN_TOOL_PEN:
832	case BTN_TOOL_RUBBER:
833	case BTN_TOOL_BRUSH:
834	case BTN_TOOL_PENCIL:
835	case BTN_TOOL_AIRBRUSH:
836	case BTN_TOOL_MOUSE:
837	case BTN_TOOL_LENS:
838		type = tablet_evcode_to_tool(e->code);
839		tablet_set_status(tablet, TABLET_TOOL_UPDATED);
840		if (e->value)
841			tablet->tool_state |= bit(type);
842		else
843			tablet->tool_state &= ~bit(type);
844		break;
845	case BTN_TOUCH:
846		if (!bit_is_set(tablet->axis_caps,
847				LIBINPUT_TABLET_TOOL_AXIS_PRESSURE)) {
848			if (e->value)
849				tablet_set_status(tablet,
850						  TABLET_TOOL_ENTERING_CONTACT);
851			else
852				tablet_set_status(tablet,
853						  TABLET_TOOL_LEAVING_CONTACT);
854		}
855		break;
856	default:
857		tablet_update_button(tablet, e->code, e->value);
858		break;
859	}
860}
861
862static void
863tablet_process_relative(struct tablet_dispatch *tablet,
864			struct evdev_device *device,
865			struct input_event *e,
866			uint64_t time)
867{
868	enum libinput_tablet_tool_axis axis;
869
870	switch (e->code) {
871	case REL_WHEEL:
872		axis = rel_evcode_to_axis(e->code);
873		if (axis == LIBINPUT_TABLET_TOOL_AXIS_NONE) {
874			evdev_log_bug_libinput(device,
875					       "Invalid ABS event code %#x\n",
876					       e->code);
877			break;
878		}
879		set_bit(tablet->changed_axes, axis);
880		tablet->axes.wheel_discrete = -1 * e->value;
881		tablet_set_status(tablet, TABLET_AXES_UPDATED);
882		break;
883	default:
884		evdev_log_info(device,
885			       "Unhandled relative axis %s (%#x)\n",
886			       libevdev_event_code_get_name(EV_REL, e->code),
887			       e->code);
888		return;
889	}
890}
891
892static void
893tablet_process_misc(struct tablet_dispatch *tablet,
894		    struct evdev_device *device,
895		    struct input_event *e,
896		    uint64_t time)
897{
898	switch (e->code) {
899	case MSC_SERIAL:
900		if (e->value != -1)
901			tablet->current_tool.serial = e->value;
902
903		break;
904	case MSC_SCAN:
905		break;
906	default:
907		evdev_log_info(device,
908			       "Unhandled MSC event code %s (%#x)\n",
909			       libevdev_event_code_get_name(EV_MSC, e->code),
910			       e->code);
911		break;
912	}
913}
914
915static inline void
916copy_axis_cap(const struct tablet_dispatch *tablet,
917	      struct libinput_tablet_tool *tool,
918	      enum libinput_tablet_tool_axis axis)
919{
920	if (bit_is_set(tablet->axis_caps, axis))
921		set_bit(tool->axis_caps, axis);
922}
923
924static inline void
925copy_button_cap(const struct tablet_dispatch *tablet,
926		struct libinput_tablet_tool *tool,
927		uint32_t button)
928{
929	struct libevdev *evdev = tablet->device->evdev;
930	if (libevdev_has_event_code(evdev, EV_KEY, button))
931		set_bit(tool->buttons, button);
932}
933
934#if HAVE_LIBWACOM
935static inline int
936tool_set_bits_from_libwacom(const struct tablet_dispatch *tablet,
937			    struct libinput_tablet_tool *tool)
938{
939	int rc = 1;
940	WacomDeviceDatabase *db;
941	const WacomStylus *s = NULL;
942	int code;
943	WacomStylusType type;
944	WacomAxisTypeFlags axes;
945
946	db = tablet_libinput_context(tablet)->libwacom.db;
947	if (!db)
948		return rc;
949
950	s = libwacom_stylus_get_for_id(db, tool->tool_id);
951	if (!s)
952		return rc;
953
954	type = libwacom_stylus_get_type(s);
955	if (type == WSTYLUS_PUCK) {
956		for (code = BTN_LEFT;
957		     code < BTN_LEFT + libwacom_stylus_get_num_buttons(s);
958		     code++)
959			copy_button_cap(tablet, tool, code);
960	} else {
961		if (libwacom_stylus_get_num_buttons(s) >= 2)
962			copy_button_cap(tablet, tool, BTN_STYLUS2);
963		if (libwacom_stylus_get_num_buttons(s) >= 1)
964			copy_button_cap(tablet, tool, BTN_STYLUS);
965	}
966
967	if (libwacom_stylus_has_wheel(s))
968		copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL);
969
970	axes = libwacom_stylus_get_axes(s);
971
972	if (axes & WACOM_AXIS_TYPE_TILT) {
973		/* tilt on the puck is converted to rotation */
974		if (type == WSTYLUS_PUCK) {
975			set_bit(tool->axis_caps,
976				LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z);
977		} else {
978			copy_axis_cap(tablet,
979				      tool,
980				      LIBINPUT_TABLET_TOOL_AXIS_TILT_X);
981			copy_axis_cap(tablet,
982				      tool,
983				      LIBINPUT_TABLET_TOOL_AXIS_TILT_Y);
984		}
985	}
986	if (axes & WACOM_AXIS_TYPE_ROTATION_Z)
987		copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z);
988	if (axes & WACOM_AXIS_TYPE_DISTANCE)
989		copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_DISTANCE);
990	if (axes & WACOM_AXIS_TYPE_SLIDER)
991		copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_SLIDER);
992	if (axes & WACOM_AXIS_TYPE_PRESSURE)
993		copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);
994
995	rc = 0;
996
997	return rc;
998}
999#endif
1000
1001static void
1002tool_set_bits(const struct tablet_dispatch *tablet,
1003	      struct libinput_tablet_tool *tool)
1004{
1005	enum libinput_tablet_tool_type type = tool->type;
1006
1007	copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_X);
1008	copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_Y);
1009
1010#if HAVE_LIBWACOM
1011	if (tool_set_bits_from_libwacom(tablet, tool) == 0)
1012		return;
1013#endif
1014	/* If we don't have libwacom, we simply copy any axis we have on the
1015	   tablet onto the tool. Except we know that mice only have rotation
1016	   anyway.
1017	 */
1018	switch (type) {
1019	case LIBINPUT_TABLET_TOOL_TYPE_PEN:
1020	case LIBINPUT_TABLET_TOOL_TYPE_ERASER:
1021	case LIBINPUT_TABLET_TOOL_TYPE_PENCIL:
1022	case LIBINPUT_TABLET_TOOL_TYPE_BRUSH:
1023	case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH:
1024		copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);
1025		copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_DISTANCE);
1026		copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_TILT_X);
1027		copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_TILT_Y);
1028		copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_SLIDER);
1029
1030		/* Rotation is special, it can be either ABS_Z or
1031		 * BTN_TOOL_MOUSE+ABS_TILT_X/Y. Aiptek tablets have
1032		 * mouse+tilt (and thus rotation), but they do not have
1033		 * ABS_Z. So let's not copy the axis bit if we don't have
1034		 * ABS_Z, otherwise we try to get the value from it later on
1035		 * proximity in and go boom because the absinfo isn't there.
1036		 */
1037		if (libevdev_has_event_code(tablet->device->evdev, EV_ABS,
1038					    ABS_Z))
1039			copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z);
1040		break;
1041	case LIBINPUT_TABLET_TOOL_TYPE_MOUSE:
1042	case LIBINPUT_TABLET_TOOL_TYPE_LENS:
1043		copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z);
1044		copy_axis_cap(tablet, tool, LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL);
1045		break;
1046	default:
1047		break;
1048	}
1049
1050	/* If we don't have libwacom, copy all pen-related buttons from the
1051	   tablet vs all mouse-related buttons */
1052	switch (type) {
1053	case LIBINPUT_TABLET_TOOL_TYPE_PEN:
1054	case LIBINPUT_TABLET_TOOL_TYPE_BRUSH:
1055	case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH:
1056	case LIBINPUT_TABLET_TOOL_TYPE_PENCIL:
1057	case LIBINPUT_TABLET_TOOL_TYPE_ERASER:
1058		copy_button_cap(tablet, tool, BTN_STYLUS);
1059		copy_button_cap(tablet, tool, BTN_STYLUS2);
1060		break;
1061	case LIBINPUT_TABLET_TOOL_TYPE_MOUSE:
1062	case LIBINPUT_TABLET_TOOL_TYPE_LENS:
1063		copy_button_cap(tablet, tool, BTN_LEFT);
1064		copy_button_cap(tablet, tool, BTN_MIDDLE);
1065		copy_button_cap(tablet, tool, BTN_RIGHT);
1066		copy_button_cap(tablet, tool, BTN_SIDE);
1067		copy_button_cap(tablet, tool, BTN_EXTRA);
1068		break;
1069	default:
1070		break;
1071	}
1072}
1073
1074static inline int
1075axis_range_percentage(const struct input_absinfo *a, double percent)
1076{
1077	return absinfo_range(a) * percent/100.0 + a->minimum;
1078}
1079
1080static inline void
1081tool_set_pressure_thresholds(struct tablet_dispatch *tablet,
1082			     struct libinput_tablet_tool *tool)
1083{
1084	struct evdev_device *device = tablet->device;
1085	const struct input_absinfo *pressure, *distance;
1086	struct quirks_context *quirks = NULL;
1087	struct quirks *q = NULL;
1088	struct quirk_range r;
1089	int lo = 0, hi = 1;
1090
1091	tool->pressure.offset = 0;
1092	tool->pressure.has_offset = false;
1093
1094	pressure = libevdev_get_abs_info(device->evdev, ABS_PRESSURE);
1095	if (!pressure)
1096		goto out;
1097
1098	quirks = evdev_libinput_context(device)->quirks;
1099	q = quirks_fetch_for_device(quirks, device->udev_device);
1100
1101	distance = libevdev_get_abs_info(device->evdev, ABS_DISTANCE);
1102	if (distance) {
1103		tool->pressure.offset = pressure->minimum;
1104		tool->pressure.heuristic_state = PRESSURE_HEURISTIC_STATE_DONE;
1105	} else {
1106		tool->pressure.offset = pressure->maximum;
1107		tool->pressure.heuristic_state = PRESSURE_HEURISTIC_STATE_PROXIN1;
1108	}
1109
1110	/* 5 and 1% of the pressure range */
1111	hi = axis_range_percentage(pressure, 5);
1112	lo = axis_range_percentage(pressure, 1);
1113
1114	if (q && quirks_get_range(q, QUIRK_ATTR_PRESSURE_RANGE, &r)) {
1115		if (r.lower >= r.upper) {
1116			evdev_log_info(device,
1117				       "Invalid pressure range, using defaults\n");
1118		} else {
1119			hi = r.upper;
1120			lo = r.lower;
1121		}
1122	}
1123out:
1124	tool->pressure.threshold.upper = hi;
1125	tool->pressure.threshold.lower = lo;
1126
1127	quirks_unref(q);
1128}
1129
1130static struct libinput_tablet_tool *
1131tablet_get_tool(struct tablet_dispatch *tablet,
1132		enum libinput_tablet_tool_type type,
1133		uint32_t tool_id,
1134		uint32_t serial)
1135{
1136	struct libinput *libinput = tablet_libinput_context(tablet);
1137	struct libinput_tablet_tool *tool = NULL, *t;
1138	struct list *tool_list;
1139
1140	if (serial) {
1141		tool_list = &libinput->tool_list;
1142		/* Check if we already have the tool in our list of tools */
1143		list_for_each(t, tool_list, link) {
1144			if (type == t->type && serial == t->serial) {
1145				tool = t;
1146				break;
1147			}
1148		}
1149	}
1150
1151	/* If we get a tool with a delayed serial number, we already created
1152	 * a 0-serial number tool for it earlier. Re-use that, even though
1153	 * it means we can't distinguish this tool from others.
1154	 * https://bugs.freedesktop.org/show_bug.cgi?id=97526
1155	 */
1156	if (!tool) {
1157		tool_list = &tablet->tool_list;
1158		/* We can't guarantee that tools without serial numbers are
1159		 * unique, so we keep them local to the tablet that they come
1160		 * into proximity of instead of storing them in the global tool
1161		 * list
1162		 * Same as above, but don't bother checking the serial number
1163		 */
1164		list_for_each(t, tool_list, link) {
1165			if (type == t->type) {
1166				tool = t;
1167				break;
1168			}
1169		}
1170
1171		/* Didn't find the tool but we have a serial. Switch
1172		 * tool_list back so we create in the correct list */
1173		if (!tool && serial)
1174			tool_list = &libinput->tool_list;
1175	}
1176
1177	/* If we didn't already have the new_tool in our list of tools,
1178	 * add it */
1179	if (!tool) {
1180		tool = zalloc(sizeof *tool);
1181
1182		*tool = (struct libinput_tablet_tool) {
1183			.type = type,
1184			.serial = serial,
1185			.tool_id = tool_id,
1186			.refcount = 1,
1187		};
1188
1189		tool_set_pressure_thresholds(tablet, tool);
1190		tool_set_bits(tablet, tool);
1191
1192		list_insert(tool_list, &tool->link);
1193	}
1194
1195	return tool;
1196}
1197
1198static void
1199tablet_notify_button_mask(struct tablet_dispatch *tablet,
1200			  struct evdev_device *device,
1201			  uint64_t time,
1202			  struct libinput_tablet_tool *tool,
1203			  const struct button_state *buttons,
1204			  enum libinput_button_state state)
1205{
1206	struct libinput_device *base = &device->base;
1207	size_t i;
1208	size_t nbits = 8 * sizeof(buttons->bits);
1209	enum libinput_tablet_tool_tip_state tip_state;
1210
1211	if (tablet_has_status(tablet, TABLET_TOOL_IN_CONTACT))
1212		tip_state = LIBINPUT_TABLET_TOOL_TIP_DOWN;
1213	else
1214		tip_state = LIBINPUT_TABLET_TOOL_TIP_UP;
1215
1216	for (i = 0; i < nbits; i++) {
1217		if (!bit_is_set(buttons->bits, i))
1218			continue;
1219
1220		tablet_notify_button(base,
1221				     time,
1222				     tool,
1223				     tip_state,
1224				     &tablet->axes,
1225				     i,
1226				     state);
1227	}
1228}
1229
1230static void
1231tablet_notify_buttons(struct tablet_dispatch *tablet,
1232		      struct evdev_device *device,
1233		      uint64_t time,
1234		      struct libinput_tablet_tool *tool,
1235		      enum libinput_button_state state)
1236{
1237	struct button_state buttons;
1238
1239	if (state == LIBINPUT_BUTTON_STATE_PRESSED)
1240		tablet_get_pressed_buttons(tablet, &buttons);
1241	else
1242		tablet_get_released_buttons(tablet, &buttons);
1243
1244	tablet_notify_button_mask(tablet,
1245				  device,
1246				  time,
1247				  tool,
1248				  &buttons,
1249				  state);
1250}
1251
1252static void
1253sanitize_pressure_distance(struct tablet_dispatch *tablet,
1254			   struct libinput_tablet_tool *tool)
1255{
1256	bool tool_in_contact;
1257	const struct input_absinfo *distance,
1258	                           *pressure;
1259
1260	distance = libevdev_get_abs_info(tablet->device->evdev, ABS_DISTANCE);
1261	pressure = libevdev_get_abs_info(tablet->device->evdev, ABS_PRESSURE);
1262
1263	if (!pressure || !distance)
1264		return;
1265
1266	bool pressure_changed = bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);
1267	bool distance_changed = bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_DISTANCE);
1268
1269	if (!pressure_changed && !distance_changed)
1270		return;
1271
1272	/* Note: this is an arbitrary "in contact" decision rather than "tip
1273	 * down". We use the lower threshold as minimum pressure value,
1274	 * anything less than that gets filtered away */
1275	tool_in_contact = (pressure->value > tool->pressure.threshold.lower);
1276
1277	/* Keep distance and pressure mutually exclusive */
1278	if (distance &&
1279	    distance->value > distance->minimum &&
1280	    pressure->value > pressure->minimum) {
1281		if (tool_in_contact) {
1282			clear_bit(tablet->changed_axes,
1283				  LIBINPUT_TABLET_TOOL_AXIS_DISTANCE);
1284			tablet->axes.distance = 0;
1285		} else {
1286			clear_bit(tablet->changed_axes,
1287				  LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);
1288			tablet->axes.pressure = 0;
1289		}
1290	} else if (pressure_changed && !tool_in_contact) {
1291		/* Make sure that the last axis value sent to the caller is a 0 */
1292		if (tablet->axes.pressure == 0)
1293			clear_bit(tablet->changed_axes,
1294				  LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);
1295		else
1296			tablet->axes.pressure = 0;
1297	}
1298}
1299
1300static inline void
1301sanitize_mouse_lens_rotation(struct tablet_dispatch *tablet)
1302{
1303	/* If we have a mouse/lens cursor and the tilt changed, the rotation
1304	   changed. Mark this, calculate the angle later */
1305	if ((tablet->current_tool.type == LIBINPUT_TABLET_TOOL_TYPE_MOUSE ||
1306	    tablet->current_tool.type == LIBINPUT_TABLET_TOOL_TYPE_LENS) &&
1307	    (bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_TILT_X) ||
1308	     bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_TILT_Y)))
1309		set_bit(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z);
1310}
1311
1312static void
1313sanitize_tablet_axes(struct tablet_dispatch *tablet,
1314		     struct libinput_tablet_tool *tool)
1315{
1316	sanitize_pressure_distance(tablet, tool);
1317	sanitize_mouse_lens_rotation(tablet);
1318}
1319
1320static void
1321set_pressure_offset(struct libinput_tablet_tool *tool, int offset)
1322{
1323	tool->pressure.offset = offset;
1324	tool->pressure.has_offset = true;
1325
1326	/* Adjust the tresholds accordingly - we use the same gap (4% in
1327	 * device coordinates) between upper and lower as before which isn't
1328	 * technically correct (our range shrunk) but it's easy to calculate.
1329	 */
1330	int gap = tool->pressure.threshold.upper - tool->pressure.threshold.lower;
1331	tool->pressure.threshold.lower = offset;
1332	tool->pressure.threshold.upper = offset + gap;
1333}
1334
1335static void
1336update_pressure_offset(struct tablet_dispatch *tablet,
1337		       struct evdev_device *device,
1338		       struct libinput_tablet_tool *tool)
1339{
1340	const struct input_absinfo *pressure =
1341		libevdev_get_abs_info(device->evdev, ABS_PRESSURE);
1342
1343	if (!pressure ||
1344	    !bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_PRESSURE))
1345		return;
1346
1347	/* If we have an event that falls below the current offset, adjust
1348	 * the offset downwards. A fast contact can start with a
1349	 * higher-than-needed pressure offset and then we'd be tied into a
1350	 * high pressure offset for the rest of the session.
1351	 *
1352	 * If we are still pending the offset decision, only update the observed
1353	 * offset value, don't actually set it to have an offset.
1354	 */
1355	int offset = pressure->value;
1356	if (tool->pressure.has_offset) {
1357		if (offset < tool->pressure.offset)
1358			set_pressure_offset(tool, offset);
1359	} else if (tool->pressure.heuristic_state != PRESSURE_HEURISTIC_STATE_DONE) {
1360		tool->pressure.offset = min(offset, tool->pressure.offset);
1361	}
1362}
1363
1364static void
1365detect_pressure_offset(struct tablet_dispatch *tablet,
1366		       struct evdev_device *device,
1367		       struct libinput_tablet_tool *tool)
1368{
1369	const struct input_absinfo *pressure, *distance;
1370	int offset;
1371
1372	if (tool->pressure.has_offset ||
1373	    !bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_PRESSURE))
1374		return;
1375
1376	pressure = libevdev_get_abs_info(device->evdev, ABS_PRESSURE);
1377	distance = libevdev_get_abs_info(device->evdev, ABS_DISTANCE);
1378
1379	if (!pressure)
1380		return;
1381
1382	offset = pressure->value;
1383	if (offset <= pressure->minimum)
1384		return;
1385
1386	if (distance) {
1387		/* If we're closer than 50% of the distance axis, skip pressure
1388		 * offset detection, too likely to be wrong */
1389		if (distance->value < axis_range_percentage(distance, 50))
1390			return;
1391	} else {
1392                /* A device without distance will always have some pressure on
1393                 * contact. Offset detection is delayed for a few proximity ins
1394                 * in the hope we'll find the minimum value until then. That
1395                 * offset is updated during motion events so by the time the
1396                 * deciding prox-in arrives we should know the minimum offset.
1397                 */
1398                if (offset > pressure->minimum)
1399			tool->pressure.offset = min(offset, tool->pressure.offset);
1400
1401		switch (tool->pressure.heuristic_state) {
1402		case PRESSURE_HEURISTIC_STATE_PROXIN1:
1403		case PRESSURE_HEURISTIC_STATE_PROXIN2:
1404			tool->pressure.heuristic_state++;
1405			return;
1406		case PRESSURE_HEURISTIC_STATE_DECIDE:
1407			tool->pressure.heuristic_state++;
1408			offset = tool->pressure.offset;
1409			break;
1410		case PRESSURE_HEURISTIC_STATE_DONE:
1411			return;
1412		}
1413	}
1414
1415	if (offset <= pressure->minimum)
1416		return;
1417
1418	if (offset > axis_range_percentage(pressure, 50)) {
1419		evdev_log_error(device,
1420			 "Ignoring pressure offset greater than 50%% detected on tool %s (serial %#x). "
1421			 "See %s/tablet-support.html\n",
1422			 tablet_tool_type_to_string(tool->type),
1423			 tool->serial,
1424			 HTTP_DOC_LINK);
1425		return;
1426	}
1427
1428	evdev_log_info(device,
1429		 "Pressure offset detected on tool %s (serial %#x).  "
1430		 "See %s/tablet-support.html\n",
1431		 tablet_tool_type_to_string(tool->type),
1432		 tool->serial,
1433		 HTTP_DOC_LINK);
1434
1435	set_pressure_offset(tool, offset);
1436}
1437
1438static void
1439detect_tool_contact(struct tablet_dispatch *tablet,
1440		    struct evdev_device *device,
1441		    struct libinput_tablet_tool *tool)
1442{
1443	const struct input_absinfo *p;
1444	int pressure;
1445
1446	if (!bit_is_set(tool->axis_caps, LIBINPUT_TABLET_TOOL_AXIS_PRESSURE))
1447		return;
1448
1449	/* if we have pressure, always use that for contact, not BTN_TOUCH */
1450	if (tablet_has_status(tablet, TABLET_TOOL_ENTERING_CONTACT))
1451		evdev_log_bug_libinput(device,
1452				       "Invalid status: entering contact\n");
1453	if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_CONTACT) &&
1454	    !tablet_has_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY))
1455		evdev_log_bug_libinput(device,
1456				       "Invalid status: leaving contact\n");
1457
1458	p = libevdev_get_abs_info(tablet->device->evdev, ABS_PRESSURE);
1459	if (!p) {
1460		evdev_log_bug_libinput(device,
1461				       "Missing pressure axis\n");
1462		return;
1463	}
1464	pressure = p->value;
1465
1466	if (pressure <= tool->pressure.threshold.lower &&
1467	    tablet_has_status(tablet, TABLET_TOOL_IN_CONTACT)) {
1468		tablet_set_status(tablet, TABLET_TOOL_LEAVING_CONTACT);
1469	} else if (pressure >= tool->pressure.threshold.upper &&
1470		   !tablet_has_status(tablet, TABLET_TOOL_IN_CONTACT)) {
1471		tablet_set_status(tablet, TABLET_TOOL_ENTERING_CONTACT);
1472	}
1473}
1474
1475static void
1476tablet_mark_all_axes_changed(struct tablet_dispatch *tablet,
1477			     struct libinput_tablet_tool *tool)
1478{
1479	static_assert(sizeof(tablet->changed_axes) ==
1480			      sizeof(tool->axis_caps),
1481		      "Mismatching array sizes");
1482
1483	memcpy(tablet->changed_axes,
1484	       tool->axis_caps,
1485	       sizeof(tablet->changed_axes));
1486}
1487
1488static void
1489tablet_update_proximity_state(struct tablet_dispatch *tablet,
1490			      struct evdev_device *device,
1491			      struct libinput_tablet_tool *tool)
1492{
1493	const struct input_absinfo *distance;
1494	int dist_max = tablet->cursor_proximity_threshold;
1495	int dist;
1496
1497	distance = libevdev_get_abs_info(tablet->device->evdev, ABS_DISTANCE);
1498	if (!distance)
1499		return;
1500
1501	dist = distance->value;
1502	if (dist == 0)
1503		return;
1504
1505	/* Tool got into permitted range */
1506	if (dist < dist_max &&
1507	    (tablet_has_status(tablet, TABLET_TOOL_OUT_OF_RANGE) ||
1508	     tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY))) {
1509		tablet_unset_status(tablet,
1510				    TABLET_TOOL_OUT_OF_RANGE);
1511		tablet_unset_status(tablet,
1512				    TABLET_TOOL_OUT_OF_PROXIMITY);
1513		tablet_set_status(tablet, TABLET_TOOL_ENTERING_PROXIMITY);
1514		tablet_mark_all_axes_changed(tablet, tool);
1515
1516		tablet_set_status(tablet, TABLET_BUTTONS_PRESSED);
1517		tablet_force_button_presses(tablet);
1518		return;
1519	}
1520
1521	if (dist < dist_max)
1522		return;
1523
1524	/* Still out of range/proximity */
1525	if (tablet_has_status(tablet, TABLET_TOOL_OUT_OF_RANGE) ||
1526	    tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY))
1527	    return;
1528
1529	/* Tool entered prox but is outside of permitted range */
1530	if (tablet_has_status(tablet,
1531			      TABLET_TOOL_ENTERING_PROXIMITY)) {
1532		tablet_set_status(tablet,
1533				  TABLET_TOOL_OUT_OF_RANGE);
1534		tablet_unset_status(tablet,
1535				    TABLET_TOOL_ENTERING_PROXIMITY);
1536		return;
1537	}
1538
1539	/* Tool was in prox and is now outside of range. Set leaving
1540	 * proximity, on the next event it will be OUT_OF_PROXIMITY and thus
1541	 * caught by the above conditions */
1542	tablet_set_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY);
1543}
1544
1545static struct phys_rect
1546tablet_calculate_arbitration_rect(struct tablet_dispatch *tablet)
1547{
1548	struct evdev_device *device = tablet->device;
1549	struct phys_rect r = {0};
1550	struct phys_coords mm;
1551
1552	mm = evdev_device_units_to_mm(device, &tablet->axes.point);
1553
1554	/* The rect we disable is 20mm left of the tip, 100mm north of the
1555	 * tip, and 200x250mm large.
1556	 * If the stylus is tilted left (tip further right than the eraser
1557	 * end) assume left-handed mode.
1558	 *
1559	 * Obviously if we'd run out of the boundaries, we clip the rect
1560	 * accordingly.
1561	 */
1562	if (tablet->axes.tilt.x > 0) {
1563		r.x = mm.x - 20;
1564		r.w = 200;
1565	} else {
1566		r.x = mm.x + 20;
1567		r.w = 200;
1568		r.x -= r.w;
1569	}
1570
1571	if (r.x < 0) {
1572		r.w += r.x;
1573		r.x = 0;
1574	}
1575
1576	r.y = mm.y - 100;
1577	r.h = 250;
1578	if (r.y < 0) {
1579		r.h += r.y;
1580		r.y = 0;
1581	}
1582
1583	return r;
1584}
1585
1586static inline void
1587tablet_update_touch_device_rect(struct tablet_dispatch *tablet,
1588				const struct tablet_axes *axes,
1589				uint64_t time)
1590{
1591	struct evdev_dispatch *dispatch;
1592	struct phys_rect rect = {0};
1593
1594	if (tablet->touch_device == NULL ||
1595	    tablet->arbitration != ARBITRATION_IGNORE_RECT)
1596		return;
1597
1598	rect = tablet_calculate_arbitration_rect(tablet);
1599
1600	dispatch = tablet->touch_device->dispatch;
1601	if (dispatch->interface->touch_arbitration_update_rect)
1602		dispatch->interface->touch_arbitration_update_rect(dispatch,
1603								   tablet->touch_device,
1604								   &rect,
1605								   time);
1606}
1607
1608static inline bool
1609tablet_send_proximity_in(struct tablet_dispatch *tablet,
1610			 struct libinput_tablet_tool *tool,
1611			 struct evdev_device *device,
1612			 struct tablet_axes *axes,
1613			 uint64_t time)
1614{
1615	if (!tablet_has_status(tablet, TABLET_TOOL_ENTERING_PROXIMITY))
1616		return false;
1617
1618	tablet_notify_proximity(&device->base,
1619				time,
1620				tool,
1621				LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN,
1622				tablet->changed_axes,
1623				axes);
1624	tablet_unset_status(tablet, TABLET_TOOL_ENTERING_PROXIMITY);
1625	tablet_unset_status(tablet, TABLET_AXES_UPDATED);
1626
1627	tablet_reset_changed_axes(tablet);
1628	axes->delta.x = 0;
1629	axes->delta.y = 0;
1630
1631	return true;
1632}
1633
1634static inline bool
1635tablet_send_proximity_out(struct tablet_dispatch *tablet,
1636			 struct libinput_tablet_tool *tool,
1637			 struct evdev_device *device,
1638			 struct tablet_axes *axes,
1639			 uint64_t time)
1640{
1641	if (!tablet_has_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY))
1642		return false;
1643
1644	tablet_notify_proximity(&device->base,
1645				time,
1646				tool,
1647				LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT,
1648				tablet->changed_axes,
1649				axes);
1650
1651	tablet_set_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY);
1652	tablet_unset_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY);
1653
1654	tablet_reset_changed_axes(tablet);
1655	axes->delta.x = 0;
1656	axes->delta.y = 0;
1657
1658	return true;
1659}
1660
1661static inline bool
1662tablet_send_tip(struct tablet_dispatch *tablet,
1663		struct libinput_tablet_tool *tool,
1664		struct evdev_device *device,
1665		struct tablet_axes *axes,
1666		uint64_t time)
1667{
1668	if (tablet_has_status(tablet, TABLET_TOOL_ENTERING_CONTACT)) {
1669		tablet_notify_tip(&device->base,
1670				  time,
1671				  tool,
1672				  LIBINPUT_TABLET_TOOL_TIP_DOWN,
1673				  tablet->changed_axes,
1674				  axes);
1675		tablet_unset_status(tablet, TABLET_AXES_UPDATED);
1676		tablet_unset_status(tablet, TABLET_TOOL_ENTERING_CONTACT);
1677		tablet_set_status(tablet, TABLET_TOOL_IN_CONTACT);
1678
1679		tablet_reset_changed_axes(tablet);
1680		axes->delta.x = 0;
1681		axes->delta.y = 0;
1682
1683		return true;
1684	}
1685
1686	if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_CONTACT)) {
1687		tablet_notify_tip(&device->base,
1688				  time,
1689				  tool,
1690				  LIBINPUT_TABLET_TOOL_TIP_UP,
1691				  tablet->changed_axes,
1692				  axes);
1693		tablet_unset_status(tablet, TABLET_AXES_UPDATED);
1694		tablet_unset_status(tablet, TABLET_TOOL_LEAVING_CONTACT);
1695		tablet_unset_status(tablet, TABLET_TOOL_IN_CONTACT);
1696
1697		tablet_reset_changed_axes(tablet);
1698		axes->delta.x = 0;
1699		axes->delta.y = 0;
1700
1701		return true;
1702	}
1703
1704	return false;
1705}
1706
1707static inline void
1708tablet_send_axes(struct tablet_dispatch *tablet,
1709		 struct libinput_tablet_tool *tool,
1710		 struct evdev_device *device,
1711		 struct tablet_axes *axes,
1712		 uint64_t time)
1713{
1714	enum libinput_tablet_tool_tip_state tip_state;
1715
1716	if (!tablet_has_status(tablet, TABLET_AXES_UPDATED))
1717		return;
1718
1719	if (tablet_has_status(tablet,
1720			      TABLET_TOOL_IN_CONTACT))
1721		tip_state = LIBINPUT_TABLET_TOOL_TIP_DOWN;
1722	else
1723		tip_state = LIBINPUT_TABLET_TOOL_TIP_UP;
1724
1725	tablet_notify_axis(&device->base,
1726			   time,
1727			   tool,
1728			   tip_state,
1729			   tablet->changed_axes,
1730			   axes);
1731	tablet_unset_status(tablet, TABLET_AXES_UPDATED);
1732	tablet_reset_changed_axes(tablet);
1733	axes->delta.x = 0;
1734	axes->delta.y = 0;
1735}
1736
1737static inline void
1738tablet_send_buttons(struct tablet_dispatch *tablet,
1739		    struct libinput_tablet_tool *tool,
1740		    struct evdev_device *device,
1741		    uint64_t time)
1742{
1743	if (tablet_has_status(tablet, TABLET_BUTTONS_RELEASED)) {
1744		tablet_notify_buttons(tablet,
1745				      device,
1746				      time,
1747				      tool,
1748				      LIBINPUT_BUTTON_STATE_RELEASED);
1749		tablet_unset_status(tablet, TABLET_BUTTONS_RELEASED);
1750	}
1751
1752	if (tablet_has_status(tablet, TABLET_BUTTONS_PRESSED)) {
1753		tablet_notify_buttons(tablet,
1754				      device,
1755				      time,
1756				      tool,
1757				      LIBINPUT_BUTTON_STATE_PRESSED);
1758		tablet_unset_status(tablet, TABLET_BUTTONS_PRESSED);
1759	}
1760}
1761
1762static void
1763tablet_send_events(struct tablet_dispatch *tablet,
1764		   struct libinput_tablet_tool *tool,
1765		   struct evdev_device *device,
1766		   uint64_t time)
1767{
1768	struct tablet_axes axes = {0};
1769
1770	if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY)) {
1771		/* Tool is leaving proximity, we can't rely on the last axis
1772		 * information (it'll be mostly 0), so we just get the
1773		 * current state and skip over updating the axes.
1774		 */
1775		axes = tablet->axes;
1776
1777		/* Don't send an axis event, but we may have a tip event
1778		 * update */
1779		tablet_unset_status(tablet, TABLET_AXES_UPDATED);
1780	} else {
1781		if (tablet_check_notify_axes(tablet, device, tool, &axes, time))
1782			tablet_update_touch_device_rect(tablet, &axes, time);
1783	}
1784
1785	assert(tablet->axes.delta.x == 0);
1786	assert(tablet->axes.delta.y == 0);
1787
1788	tablet_send_proximity_in(tablet, tool, device, &axes, time);
1789	if (!tablet_send_tip(tablet, tool, device, &axes, time))
1790		tablet_send_axes(tablet, tool, device, &axes, time);
1791
1792	tablet_unset_status(tablet, TABLET_TOOL_ENTERING_CONTACT);
1793	tablet_reset_changed_axes(tablet);
1794
1795	tablet_send_buttons(tablet, tool, device, time);
1796
1797	if (tablet_send_proximity_out(tablet, tool, device, &axes, time)) {
1798		tablet_change_to_left_handed(device);
1799		tablet_apply_rotation(device);
1800		tablet_history_reset(tablet);
1801	}
1802}
1803
1804/**
1805 * Handling for the proximity out workaround. Some tablets only send
1806 * BTN_TOOL_PEN on the very first event, then leave it set even when the pen
1807 * leaves the detectable range. To libinput this looks like we always have
1808 * the pen in proximity.
1809 *
1810 * To avoid this, we set a timer on BTN_TOOL_PEN in. We expect the tablet to
1811 * continuously send events, and while it's doing so we keep updating the
1812 * timer. Once we go Xms without an event we assume proximity out and inject
1813 * a BTN_TOOL_PEN event into the sequence through the timer func.
1814 *
1815 * We need to remember that we did that, on the first event after the
1816 * timeout we need to emulate a BTN_TOOL_PEN event again to force proximity
1817 * in.
1818 *
1819 * Other tools never send the BTN_TOOL_PEN event. For those tools, we
1820 * piggyback along with the proximity out quirks by injecting
1821 * the event during the first event frame.
1822 */
1823static inline void
1824tablet_proximity_out_quirk_set_timer(struct tablet_dispatch *tablet,
1825				     uint64_t time)
1826{
1827	if (tablet->quirks.need_to_force_prox_out)
1828		libinput_timer_set(&tablet->quirks.prox_out_timer,
1829				   time + FORCED_PROXOUT_TIMEOUT);
1830}
1831
1832static bool
1833tablet_update_tool_state(struct tablet_dispatch *tablet,
1834			 struct evdev_device *device,
1835			 uint64_t time)
1836{
1837	enum libinput_tablet_tool_type type;
1838	uint32_t changed;
1839	int state;
1840	uint32_t doubled_up_new_tool_bit = 0;
1841
1842	/* we were already out of proximity but now got a tool update but
1843	 * our tool state is zero - i.e. we got a valid prox out from the
1844	 * device.
1845	 */
1846	if (tablet->quirks.proximity_out_forced &&
1847	    tablet_has_status(tablet, TABLET_TOOL_UPDATED) &&
1848	    !tablet->tool_state) {
1849		tablet->quirks.need_to_force_prox_out = false;
1850		tablet->quirks.proximity_out_forced = false;
1851	}
1852	/* We need to emulate a BTN_TOOL_PEN if we get an axis event (i.e.
1853	 * stylus is def. in proximity) and:
1854	 * - we forced a proximity out before, or
1855	 * - on the very first event after init, because if we didn't get a
1856	 *   BTN_TOOL_PEN and the state for the tool was 0, this device will
1857	 *   never send the event.
1858	 * We don't do this for pure button events because we discard those.
1859	 *
1860	 * But: on some devices the proximity out is delayed by the kernel,
1861	 * so we get it after our forced prox-out has triggered. In that
1862	 * case we need to just ignore the change.
1863	 */
1864	if (tablet_has_status(tablet, TABLET_AXES_UPDATED)) {
1865		if (tablet->quirks.proximity_out_forced) {
1866			if (!tablet_has_status(tablet, TABLET_TOOL_UPDATED)  &&
1867			    !tablet->tool_state)
1868				tablet->tool_state = bit(LIBINPUT_TABLET_TOOL_TYPE_PEN);
1869			tablet->quirks.proximity_out_forced = false;
1870		} else if (tablet->tool_state == 0 &&
1871			    tablet->current_tool.type == LIBINPUT_TOOL_NONE) {
1872			tablet->tool_state = bit(LIBINPUT_TABLET_TOOL_TYPE_PEN);
1873			tablet->quirks.proximity_out_forced = false;
1874		}
1875	}
1876
1877	if (tablet->tool_state == tablet->prev_tool_state)
1878		return false;
1879
1880	/* Kernel tools are supposed to be mutually exclusive, but we may have
1881	 * two bits set due to firmware/kernel bugs.
1882	 * Two cases that have been seen in the wild:
1883	 * - BTN_TOOL_PEN on proximity in, followed by
1884	 *   BTN_TOOL_RUBBER later, see #259
1885	 *   -> We force a prox-out of the pen, trigger prox-in for eraser
1886	 * - BTN_TOOL_RUBBER on proximity in, but BTN_TOOL_PEN when
1887	 *   the tip is down, see #702.
1888	 *   -> We ignore BTN_TOOL_PEN
1889	 * In both cases the eraser is what we want, so we bias
1890	 * towards that.
1891	 */
1892	if (tablet->tool_state & (tablet->tool_state - 1)) {
1893		doubled_up_new_tool_bit = tablet->tool_state ^ tablet->prev_tool_state;
1894
1895		/* The new tool is the pen. Ignore it */
1896		if (doubled_up_new_tool_bit == bit(LIBINPUT_TABLET_TOOL_TYPE_PEN)) {
1897			tablet->tool_state &= ~bit(LIBINPUT_TABLET_TOOL_TYPE_PEN);
1898			return false;
1899		}
1900
1901		/* The new tool is some tool other than pen (usually eraser).
1902		 * We set the current tool state to zero, thus setting
1903		 * everything up for a prox out on the tool. Once that is set
1904		 * up, we change the tool state to be the new one we just got.
1905		 * When we re-process this function we now get the new tool
1906		 * as prox in. Importantly, we basically rely on nothing else
1907		 * happening in the meantime.
1908		 */
1909		tablet->tool_state = 0;
1910	}
1911
1912	changed = tablet->tool_state ^ tablet->prev_tool_state;
1913	type = ffs(changed) - 1;
1914	state = !!(tablet->tool_state & bit(type));
1915
1916	tablet_update_tool(tablet, device, type, state);
1917
1918	/* The proximity timeout is only needed for BTN_TOOL_PEN, devices
1919	 * that require it don't do erasers */
1920	if (type == LIBINPUT_TABLET_TOOL_TYPE_PEN) {
1921		if (state) {
1922			tablet_proximity_out_quirk_set_timer(tablet, time);
1923		} else {
1924			/* If we get a BTN_TOOL_PEN 0 when *not* injecting
1925			 * events it means the tablet will give us the right
1926			 * events after all and we can disable our
1927			 * timer-based proximity out.
1928			 */
1929			if (!tablet->quirks.proximity_out_in_progress)
1930				tablet->quirks.need_to_force_prox_out = false;
1931
1932			libinput_timer_cancel(&tablet->quirks.prox_out_timer);
1933		}
1934	}
1935
1936	tablet->prev_tool_state = tablet->tool_state;
1937
1938	if (doubled_up_new_tool_bit) {
1939		tablet->tool_state = doubled_up_new_tool_bit;
1940		return true; /* need to re-process */
1941	}
1942	return false;
1943}
1944
1945static struct libinput_tablet_tool *
1946tablet_get_current_tool(struct tablet_dispatch *tablet)
1947{
1948	if (tablet->current_tool.type == LIBINPUT_TOOL_NONE)
1949		return NULL;
1950
1951	return tablet_get_tool(tablet,
1952			       tablet->current_tool.type,
1953			       tablet->current_tool.id,
1954			       tablet->current_tool.serial);
1955}
1956
1957static void
1958tablet_flush(struct tablet_dispatch *tablet,
1959	     struct evdev_device *device,
1960	     uint64_t time)
1961{
1962	struct libinput_tablet_tool *tool;
1963	bool process_tool_twice;
1964
1965reprocess:
1966	process_tool_twice = tablet_update_tool_state(tablet, device, time);
1967
1968	tool = tablet_get_current_tool(tablet);
1969	if (!tool)
1970		return; /* OOM */
1971
1972	if (tool->type == LIBINPUT_TABLET_TOOL_TYPE_MOUSE ||
1973	    tool->type == LIBINPUT_TABLET_TOOL_TYPE_LENS)
1974		tablet_update_proximity_state(tablet, device, tool);
1975
1976	if (tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY) ||
1977	    tablet_has_status(tablet, TABLET_TOOL_OUT_OF_RANGE))
1978		return;
1979
1980	if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY)) {
1981		/* Release all stylus buttons */
1982		memset(tablet->button_state.bits,
1983		       0,
1984		       sizeof(tablet->button_state.bits));
1985		tablet_set_status(tablet, TABLET_BUTTONS_RELEASED);
1986		if (tablet_has_status(tablet, TABLET_TOOL_IN_CONTACT))
1987			tablet_set_status(tablet, TABLET_TOOL_LEAVING_CONTACT);
1988	} else if (tablet_has_status(tablet, TABLET_TOOL_ENTERING_PROXIMITY)) {
1989		tablet_mark_all_axes_changed(tablet, tool);
1990		update_pressure_offset(tablet, device, tool);
1991		detect_pressure_offset(tablet, device, tool);
1992		detect_tool_contact(tablet, device, tool);
1993		sanitize_tablet_axes(tablet, tool);
1994	} else if (tablet_has_status(tablet, TABLET_AXES_UPDATED)) {
1995		update_pressure_offset(tablet, device, tool);
1996		detect_tool_contact(tablet, device, tool);
1997		sanitize_tablet_axes(tablet, tool);
1998	}
1999
2000	tablet_send_events(tablet, tool, device, time);
2001
2002	if (process_tool_twice)
2003		goto reprocess;
2004}
2005
2006static inline void
2007tablet_set_touch_device_enabled(struct tablet_dispatch *tablet,
2008				enum evdev_arbitration_state which,
2009				const struct phys_rect *rect,
2010				uint64_t time)
2011{
2012	struct evdev_device *touch_device = tablet->touch_device;
2013	struct evdev_dispatch *dispatch;
2014
2015	if (touch_device == NULL)
2016		return;
2017
2018	tablet->arbitration = which;
2019
2020	dispatch = touch_device->dispatch;
2021	if (dispatch->interface->touch_arbitration_toggle)
2022		dispatch->interface->touch_arbitration_toggle(dispatch,
2023							      touch_device,
2024							      which,
2025							      rect,
2026							      time);
2027}
2028
2029static inline void
2030tablet_toggle_touch_device(struct tablet_dispatch *tablet,
2031			   struct evdev_device *tablet_device,
2032			   uint64_t time)
2033{
2034	enum evdev_arbitration_state which;
2035	struct phys_rect r = {0};
2036	struct phys_rect *rect = NULL;
2037
2038	if (tablet_has_status(tablet,
2039			      TABLET_TOOL_OUT_OF_RANGE) ||
2040	    tablet_has_status(tablet, TABLET_NONE) ||
2041	    tablet_has_status(tablet,
2042			      TABLET_TOOL_LEAVING_PROXIMITY) ||
2043	    tablet_has_status(tablet,
2044			      TABLET_TOOL_OUT_OF_PROXIMITY)) {
2045		which = ARBITRATION_NOT_ACTIVE;
2046	} else if (tablet->axes.tilt.x == 0) {
2047		which = ARBITRATION_IGNORE_ALL;
2048	} else if (tablet->arbitration != ARBITRATION_IGNORE_RECT) {
2049		/* This enables rect-based arbitration, updates are sent
2050		 * elsewhere */
2051		r = tablet_calculate_arbitration_rect(tablet);
2052		rect = &r;
2053		which = ARBITRATION_IGNORE_RECT;
2054	} else {
2055		return;
2056	}
2057
2058	tablet_set_touch_device_enabled(tablet,
2059					which,
2060					rect,
2061					time);
2062}
2063
2064static inline void
2065tablet_reset_state(struct tablet_dispatch *tablet)
2066{
2067	struct button_state zero = {0};
2068
2069	/* Update state */
2070	memcpy(&tablet->prev_button_state,
2071	       &tablet->button_state,
2072	       sizeof(tablet->button_state));
2073	tablet_unset_status(tablet, TABLET_TOOL_UPDATED);
2074
2075	if (memcmp(&tablet->button_state, &zero, sizeof(zero)) == 0)
2076		tablet_unset_status(tablet, TABLET_BUTTONS_DOWN);
2077	else
2078		tablet_set_status(tablet, TABLET_BUTTONS_DOWN);
2079}
2080
2081static void
2082tablet_proximity_out_quirk_timer_func(uint64_t now, void *data)
2083{
2084	struct tablet_dispatch *tablet = data;
2085	struct timeval tv = us2tv(now);
2086	struct input_event events[2] = {
2087		{ .input_event_sec = tv.tv_sec,
2088		  .input_event_usec = tv.tv_usec,
2089		  .type = EV_KEY,
2090		  .code = BTN_TOOL_PEN,
2091		  .value = 0 },
2092		{ .input_event_sec = tv.tv_sec,
2093		  .input_event_usec = tv.tv_usec,
2094		  .type = EV_SYN,
2095		  .code = SYN_REPORT,
2096		  .value = 0 },
2097	};
2098
2099	if (tablet_has_status(tablet, TABLET_TOOL_IN_CONTACT) ||
2100	    tablet_has_status(tablet, TABLET_BUTTONS_DOWN)) {
2101		tablet_proximity_out_quirk_set_timer(tablet, now);
2102		return;
2103	}
2104
2105	if (tablet->quirks.last_event_time > now - FORCED_PROXOUT_TIMEOUT) {
2106		tablet_proximity_out_quirk_set_timer(tablet,
2107						     tablet->quirks.last_event_time);
2108		return;
2109	}
2110
2111	evdev_log_debug(tablet->device, "tablet: forcing proximity after timeout\n");
2112
2113	tablet->quirks.proximity_out_in_progress = true;
2114	ARRAY_FOR_EACH(events, e) {
2115		tablet->base.interface->process(&tablet->base,
2116						 tablet->device,
2117						 e,
2118						 now);
2119	}
2120	tablet->quirks.proximity_out_in_progress = false;
2121
2122	tablet->quirks.proximity_out_forced = true;
2123}
2124
2125static void
2126tablet_process(struct evdev_dispatch *dispatch,
2127	       struct evdev_device *device,
2128	       struct input_event *e,
2129	       uint64_t time)
2130{
2131	struct tablet_dispatch *tablet = tablet_dispatch(dispatch);
2132
2133	switch (e->type) {
2134	case EV_ABS:
2135		tablet_process_absolute(tablet, device, e, time);
2136		break;
2137	case EV_REL:
2138		tablet_process_relative(tablet, device, e, time);
2139		break;
2140	case EV_KEY:
2141		tablet_process_key(tablet, device, e, time);
2142		break;
2143	case EV_MSC:
2144		tablet_process_misc(tablet, device, e, time);
2145		break;
2146	case EV_SYN:
2147		tablet_flush(tablet, device, time);
2148		tablet_toggle_touch_device(tablet, device, time);
2149		tablet_reset_state(tablet);
2150		tablet->quirks.last_event_time = time;
2151		break;
2152	default:
2153		evdev_log_error(device,
2154				"Unexpected event type %s (%#x)\n",
2155				libevdev_event_type_get_name(e->type),
2156				e->type);
2157		break;
2158	}
2159}
2160
2161static void
2162tablet_suspend(struct evdev_dispatch *dispatch,
2163	       struct evdev_device *device)
2164{
2165	struct tablet_dispatch *tablet = tablet_dispatch(dispatch);
2166	struct libinput *li = tablet_libinput_context(tablet);
2167	uint64_t now = libinput_now(li);
2168
2169	tablet_set_touch_device_enabled(tablet,
2170					ARBITRATION_NOT_ACTIVE,
2171					NULL,
2172					now);
2173
2174	if (!tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY)) {
2175		tablet_set_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY);
2176		tablet_flush(tablet, device, libinput_now(li));
2177	}
2178}
2179
2180static void
2181tablet_destroy(struct evdev_dispatch *dispatch)
2182{
2183	struct tablet_dispatch *tablet = tablet_dispatch(dispatch);
2184	struct libinput_tablet_tool *tool;
2185	struct libinput *li = tablet_libinput_context(tablet);
2186
2187	libinput_timer_cancel(&tablet->quirks.prox_out_timer);
2188	libinput_timer_destroy(&tablet->quirks.prox_out_timer);
2189
2190	list_for_each_safe(tool, &tablet->tool_list, link) {
2191		libinput_tablet_tool_unref(tool);
2192	}
2193
2194	libinput_libwacom_unref(li);
2195
2196	free(tablet);
2197}
2198
2199static void
2200tablet_setup_touch_arbitration(struct evdev_device *device,
2201			       struct evdev_device *new_device)
2202{
2203	struct tablet_dispatch *tablet = tablet_dispatch(device->dispatch);
2204
2205        /* We enable touch arbitration with the first touch screen/external
2206         * touchpad we see. This may be wrong in some cases, so we have some
2207         * heuristics in case we find a "better" device.
2208         */
2209        if (tablet->touch_device != NULL) {
2210		struct libinput_device_group *group1 = libinput_device_get_device_group(&device->base);
2211		struct libinput_device_group *group2 = libinput_device_get_device_group(&new_device->base);
2212
2213		/* same phsical device? -> better, otherwise keep the one we have */
2214		if (group1 != group2)
2215			return;
2216
2217		/* We found a better device, let's swap it out */
2218		struct libinput *li = tablet_libinput_context(tablet);
2219		tablet_set_touch_device_enabled(tablet,
2220						ARBITRATION_NOT_ACTIVE,
2221						NULL,
2222						libinput_now(li));
2223		evdev_log_debug(device,
2224				"touch-arbitration: removing pairing for %s<->%s\n",
2225				device->devname,
2226				tablet->touch_device->devname);
2227	}
2228
2229	evdev_log_debug(device,
2230			"touch-arbitration: activated for %s<->%s\n",
2231			device->devname,
2232			new_device->devname);
2233	tablet->touch_device = new_device;
2234}
2235
2236static void
2237tablet_setup_rotation(struct evdev_device *device,
2238		      struct evdev_device *new_device)
2239{
2240	struct tablet_dispatch *tablet = tablet_dispatch(device->dispatch);
2241	struct libinput_device_group *group1 = libinput_device_get_device_group(&device->base);
2242	struct libinput_device_group *group2 = libinput_device_get_device_group(&new_device->base);
2243
2244	if (tablet->rotation.touch_device == NULL && (group1 == group2)) {
2245		evdev_log_debug(device,
2246				"tablet-rotation: %s will rotate %s\n",
2247				device->devname,
2248				new_device->devname);
2249		tablet->rotation.touch_device = new_device;
2250
2251		if (libinput_device_config_left_handed_get(&new_device->base)) {
2252			tablet->rotation.touch_device_left_handed_state = true;
2253			tablet_change_rotation(device, DO_NOTIFY);
2254		}
2255	}
2256}
2257
2258static void
2259tablet_device_added(struct evdev_device *device,
2260		    struct evdev_device *added_device)
2261{
2262	bool is_touchscreen, is_ext_touchpad;
2263
2264	is_touchscreen = evdev_device_has_capability(added_device,
2265						     LIBINPUT_DEVICE_CAP_TOUCH);
2266	is_ext_touchpad = evdev_device_has_capability(added_device,
2267						      LIBINPUT_DEVICE_CAP_POINTER) &&
2268			  (added_device->tags & EVDEV_TAG_EXTERNAL_TOUCHPAD);
2269
2270	if (is_touchscreen || is_ext_touchpad)
2271		tablet_setup_touch_arbitration(device, added_device);
2272
2273	if (is_ext_touchpad)
2274		tablet_setup_rotation(device, added_device);
2275}
2276
2277static void
2278tablet_device_removed(struct evdev_device *device,
2279		      struct evdev_device *removed_device)
2280{
2281	struct tablet_dispatch *tablet = tablet_dispatch(device->dispatch);
2282
2283	if (tablet->touch_device == removed_device)
2284		tablet->touch_device = NULL;
2285
2286	if (tablet->rotation.touch_device == removed_device) {
2287		tablet->rotation.touch_device = NULL;
2288		tablet->rotation.touch_device_left_handed_state = false;
2289		tablet_change_rotation(device, DO_NOTIFY);
2290	}
2291}
2292
2293static void
2294tablet_check_initial_proximity(struct evdev_device *device,
2295			       struct evdev_dispatch *dispatch)
2296{
2297	struct tablet_dispatch *tablet = tablet_dispatch(dispatch);
2298	struct libinput *li = tablet_libinput_context(tablet);
2299	int code, state;
2300	enum libinput_tablet_tool_type tool;
2301
2302	for (tool = LIBINPUT_TABLET_TOOL_TYPE_PEN;
2303	     tool <= LIBINPUT_TABLET_TOOL_TYPE_MAX;
2304	     tool++) {
2305		code = tablet_tool_to_evcode(tool);
2306
2307		/* we only expect one tool to be in proximity at a time */
2308		if (libevdev_fetch_event_value(device->evdev,
2309						EV_KEY,
2310						code,
2311						&state) && state) {
2312			tablet->tool_state = bit(tool);
2313			tablet->prev_tool_state = bit(tool);
2314			break;
2315		}
2316	}
2317
2318	if (!tablet->tool_state)
2319		return;
2320
2321	tablet_update_tool(tablet, device, tool, state);
2322	if (tablet->quirks.need_to_force_prox_out)
2323		tablet_proximity_out_quirk_set_timer(tablet, libinput_now(li));
2324
2325	tablet->current_tool.id =
2326		libevdev_get_event_value(device->evdev,
2327					 EV_ABS,
2328					 ABS_MISC);
2329
2330	/* we can't fetch MSC_SERIAL from the kernel, so we set the serial
2331	 * to 0 for now. On the first real event from the device we get the
2332	 * serial (if any) and that event will be converted into a proximity
2333	 * event */
2334	tablet->current_tool.serial = 0;
2335}
2336
2337/* Called when the touchpad toggles to left-handed */
2338static void
2339tablet_left_handed_toggled(struct evdev_dispatch *dispatch,
2340			   struct evdev_device *device,
2341			   bool left_handed_enabled)
2342{
2343	struct tablet_dispatch *tablet = tablet_dispatch(dispatch);
2344
2345	if (!tablet->rotation.touch_device)
2346		return;
2347
2348	evdev_log_debug(device,
2349			"tablet-rotation: touchpad is %s\n",
2350			left_handed_enabled ? "left-handed" : "right-handed");
2351
2352	/* Our left-handed config is independent even though rotation is
2353	 * locked. So we rotate when either device is left-handed. But it
2354	 * can only be actually changed when the device is in a neutral
2355	 * state, hence the want_rotate.
2356	 */
2357	tablet->rotation.touch_device_left_handed_state = left_handed_enabled;
2358	tablet_change_rotation(device, DONT_NOTIFY);
2359}
2360
2361static struct evdev_dispatch_interface tablet_interface = {
2362	.process = tablet_process,
2363	.suspend = tablet_suspend,
2364	.remove = NULL,
2365	.destroy = tablet_destroy,
2366	.device_added = tablet_device_added,
2367	.device_removed = tablet_device_removed,
2368	.device_suspended = NULL,
2369	.device_resumed = NULL,
2370	.post_added = tablet_check_initial_proximity,
2371	.touch_arbitration_toggle = NULL,
2372	.touch_arbitration_update_rect = NULL,
2373	.get_switch_state = NULL,
2374	.left_handed_toggle = tablet_left_handed_toggled,
2375};
2376
2377static void
2378tablet_init_calibration(struct tablet_dispatch *tablet,
2379			struct evdev_device *device)
2380{
2381	if (libevdev_has_property(device->evdev, INPUT_PROP_DIRECT))
2382		evdev_init_calibration(device, &tablet->calibration);
2383}
2384
2385static void
2386tablet_init_proximity_threshold(struct tablet_dispatch *tablet,
2387				struct evdev_device *device)
2388{
2389	/* This rules out most of the bamboos and other devices, we're
2390	 * pretty much down to
2391	 */
2392	if (!libevdev_has_event_code(device->evdev, EV_KEY, BTN_TOOL_MOUSE) &&
2393	    !libevdev_has_event_code(device->evdev, EV_KEY, BTN_TOOL_LENS))
2394		return;
2395
2396	/* 42 is the default proximity threshold the xf86-input-wacom driver
2397	 * uses for Intuos/Cintiq models. Graphire models have a threshold
2398	 * of 10 but since they haven't been manufactured in ages and the
2399	 * intersection of users having a graphire, running libinput and
2400	 * wanting to use the mouse/lens cursor tool is small enough to not
2401	 * worry about it for now. If we need to, we can introduce a udev
2402	 * property later.
2403	 *
2404	 * Value is in device coordinates.
2405	 */
2406	tablet->cursor_proximity_threshold = 42;
2407}
2408
2409static uint32_t
2410tablet_accel_config_get_profiles(struct libinput_device *libinput_device)
2411{
2412	return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
2413}
2414
2415static enum libinput_config_status
2416tablet_accel_config_set_profile(struct libinput_device *libinput_device,
2417			    enum libinput_config_accel_profile profile)
2418{
2419	return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
2420}
2421
2422static enum libinput_config_accel_profile
2423tablet_accel_config_get_profile(struct libinput_device *libinput_device)
2424{
2425	return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
2426}
2427
2428static enum libinput_config_accel_profile
2429tablet_accel_config_get_default_profile(struct libinput_device *libinput_device)
2430{
2431	return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
2432}
2433
2434static int
2435tablet_init_accel(struct tablet_dispatch *tablet, struct evdev_device *device)
2436{
2437	const struct input_absinfo *x, *y;
2438	struct motion_filter *filter;
2439
2440	x = device->abs.absinfo_x;
2441	y = device->abs.absinfo_y;
2442
2443	filter = create_pointer_accelerator_filter_tablet(x->resolution,
2444							  y->resolution);
2445	if (!filter)
2446		return -1;
2447
2448	evdev_device_init_pointer_acceleration(device, filter);
2449
2450	/* we override the profile hooks for accel configuration with hooks
2451	 * that don't allow selection of profiles */
2452	device->pointer.config.get_profiles = tablet_accel_config_get_profiles;
2453	device->pointer.config.set_profile = tablet_accel_config_set_profile;
2454	device->pointer.config.get_profile = tablet_accel_config_get_profile;
2455	device->pointer.config.get_default_profile = tablet_accel_config_get_default_profile;
2456
2457	return 0;
2458}
2459
2460static void
2461tablet_init_left_handed(struct evdev_device *device)
2462{
2463	if (evdev_tablet_has_left_handed(device))
2464		evdev_init_left_handed(device,
2465				       tablet_change_to_left_handed);
2466}
2467
2468static bool
2469tablet_is_aes(struct evdev_device *device,
2470	      struct tablet_dispatch *tablet)
2471{
2472	bool is_aes = false;
2473#if HAVE_LIBWACOM
2474	const char *devnode;
2475	WacomDeviceDatabase *db;
2476	WacomDevice *libwacom_device = NULL;
2477	const int *stylus_ids;
2478	int nstyli;
2479	int vid = evdev_device_get_id_vendor(device);
2480
2481	/* Wacom-specific check for whether smoothing is required:
2482	 * libwacom keeps all the AES pens in a single group, so any device
2483	 * that supports AES pens will list all AES pens. 0x11 is one of the
2484	 * lenovo pens so we use that as the flag of whether the tablet
2485	 * is an AES tablet
2486	 */
2487	if (vid != VENDOR_ID_WACOM)
2488		goto out;
2489
2490	db = tablet_libinput_context(tablet)->libwacom.db;
2491	if (!db)
2492		goto out;
2493
2494	devnode = udev_device_get_devnode(device->udev_device);
2495	libwacom_device = libwacom_new_from_path(db, devnode, WFALLBACK_NONE, NULL);
2496	if (!libwacom_device)
2497		goto out;
2498
2499	stylus_ids = libwacom_get_supported_styli(libwacom_device, &nstyli);
2500	for (int i = 0; i < nstyli; i++) {
2501		if (stylus_ids[i] == 0x11) {
2502			is_aes = true;
2503			break;
2504		}
2505	}
2506
2507	libwacom_destroy(libwacom_device);
2508
2509out:
2510#endif
2511	return is_aes;
2512}
2513
2514static void
2515tablet_init_smoothing(struct evdev_device *device,
2516		      struct tablet_dispatch *tablet)
2517{
2518	size_t history_size = ARRAY_LENGTH(tablet->history.samples);
2519	struct quirks_context *quirks = NULL;
2520	struct quirks *q = NULL;
2521	bool use_smoothing = true;
2522
2523	quirks = evdev_libinput_context(device)->quirks;
2524	q = quirks_fetch_for_device(quirks, device->udev_device);
2525
2526	/* By default, always enable smoothing except on AES devices.
2527	 * AttrTabletSmoothing can override this, if necessary.
2528	 */
2529	if (!q || !quirks_get_bool(q, QUIRK_ATTR_TABLET_SMOOTHING, &use_smoothing))
2530		use_smoothing = !tablet_is_aes(device, tablet);
2531
2532	/* Setting the history size to 1 means we never do any actual smoothing. */
2533	if (!use_smoothing)
2534		history_size = 1;
2535
2536	quirks_unref(q);
2537	tablet->history.size = history_size;
2538}
2539
2540static bool
2541tablet_reject_device(struct evdev_device *device)
2542{
2543	struct libevdev *evdev = device->evdev;
2544	double w, h;
2545	bool has_xy, has_pen, has_btn_stylus, has_size;
2546
2547	has_xy = libevdev_has_event_code(evdev, EV_ABS, ABS_X) &&
2548	         libevdev_has_event_code(evdev, EV_ABS, ABS_Y);
2549	has_pen = libevdev_has_event_code(evdev, EV_KEY, BTN_TOOL_PEN);
2550	has_btn_stylus = libevdev_has_event_code(evdev, EV_KEY, BTN_STYLUS);
2551	has_size = evdev_device_get_size(device, &w, &h) == 0;
2552
2553	if (has_xy && (has_pen || has_btn_stylus) && has_size)
2554		return false;
2555
2556	evdev_log_bug_libinput(device,
2557			       "missing tablet capabilities:%s%s%s%s. "
2558			       "Ignoring this device.\n",
2559			       has_xy ? "" : " xy",
2560			       has_pen ? "" : " pen",
2561			       has_btn_stylus ? "" : " btn-stylus",
2562			       has_size ? "" : " resolution");
2563	return true;
2564}
2565
2566static int
2567tablet_init(struct tablet_dispatch *tablet,
2568	    struct evdev_device *device)
2569{
2570	struct libevdev *evdev = device->evdev;
2571	enum libinput_tablet_tool_axis axis;
2572	int rc;
2573
2574	tablet->base.dispatch_type = DISPATCH_TABLET;
2575	tablet->base.interface = &tablet_interface;
2576	tablet->device = device;
2577	tablet->status = TABLET_NONE;
2578	tablet->current_tool.type = LIBINPUT_TOOL_NONE;
2579	list_init(&tablet->tool_list);
2580
2581	if (tablet_reject_device(device))
2582		return -1;
2583
2584	if (!libevdev_has_event_code(evdev, EV_KEY, BTN_TOOL_PEN)) {
2585		libevdev_enable_event_code(evdev, EV_KEY, BTN_TOOL_PEN, NULL);
2586		tablet->quirks.proximity_out_forced = true;
2587	}
2588
2589	/* Our rotation code only works with Wacoms, let's wait until
2590	 * someone shouts */
2591	if (evdev_device_get_id_vendor(device) != VENDOR_ID_WACOM) {
2592		libevdev_disable_event_code(evdev, EV_KEY, BTN_TOOL_MOUSE);
2593		libevdev_disable_event_code(evdev, EV_KEY, BTN_TOOL_LENS);
2594	}
2595
2596	tablet_init_calibration(tablet, device);
2597	tablet_init_proximity_threshold(tablet, device);
2598	rc = tablet_init_accel(tablet, device);
2599	if (rc != 0)
2600		return rc;
2601
2602	evdev_init_sendevents(device, &tablet->base);
2603	tablet_init_left_handed(device);
2604	tablet_init_smoothing(device, tablet);
2605
2606	for (axis = LIBINPUT_TABLET_TOOL_AXIS_X;
2607	     axis <= LIBINPUT_TABLET_TOOL_AXIS_MAX;
2608	     axis++) {
2609		if (tablet_device_has_axis(tablet, axis))
2610			set_bit(tablet->axis_caps, axis);
2611	}
2612
2613	tablet_set_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY);
2614
2615	/* We always enable the proximity out quirk, but disable it once a
2616	   device gives us the right event sequence */
2617	tablet->quirks.need_to_force_prox_out = true;
2618
2619	libinput_timer_init(&tablet->quirks.prox_out_timer,
2620			    tablet_libinput_context(tablet),
2621			    "proxout",
2622			    tablet_proximity_out_quirk_timer_func,
2623			    tablet);
2624
2625	return 0;
2626}
2627
2628struct evdev_dispatch *
2629evdev_tablet_create(struct evdev_device *device)
2630{
2631	struct tablet_dispatch *tablet;
2632	struct libinput *li = evdev_libinput_context(device);
2633
2634	libinput_libwacom_ref(li);
2635
2636	/* Stop false positives caused by the forced proximity code */
2637	if (getenv("LIBINPUT_RUNNING_TEST_SUITE"))
2638		FORCED_PROXOUT_TIMEOUT = 150 * 1000; /* µs */
2639
2640	tablet = zalloc(sizeof *tablet);
2641
2642	if (tablet_init(tablet, device) != 0) {
2643		tablet_destroy(&tablet->base);
2644		return NULL;
2645	}
2646
2647	return &tablet->base;
2648}
2649