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