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