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