• Home
  • Raw
  • Download

Lines Matching +full:libinput +full:- +full:test +full:- +full:suite +full:- +full:touchpad

25 #include "evdev-tablet.h"
26 #include "util-input-event.h"
42 detect out-of-range.
43 This value is higher during test suite runs */
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_)))
55 const struct button_state *state = &tablet->button_state, in tablet_get_pressed_buttons()
56 *prev_state = &tablet->prev_button_state; in tablet_get_pressed_buttons()
58 for (i = 0; i < sizeof(buttons->bits); i++) in tablet_get_pressed_buttons()
59 buttons->bits[i] = state->bits[i] & ~(prev_state->bits[i]); in tablet_get_pressed_buttons()
67 const struct button_state *state = &tablet->button_state, in tablet_get_released_buttons()
68 *prev_state = &tablet->prev_button_state; in tablet_get_released_buttons()
70 for (i = 0; i < sizeof(buttons->bits); i++) in tablet_get_released_buttons()
71 buttons->bits[i] = prev_state->bits[i] & in tablet_get_released_buttons()
72 ~(state->bits[i]); in tablet_get_released_buttons()
80 struct button_state *state = &tablet->button_state, in tablet_force_button_presses()
81 *prev_state = &tablet->prev_button_state; in tablet_force_button_presses()
84 for (i = 0; i < sizeof(state->bits); i++) { in tablet_force_button_presses()
85 state->bits[i] = state->bits[i] | prev_state->bits[i]; in tablet_force_button_presses()
86 prev_state->bits[i] = 0; in tablet_force_button_presses()
93 return tablet->history.size; in tablet_history_size()
99 tablet->history.count = 0; in tablet_history_reset()
106 unsigned int index = (tablet->history.index + 1) % in tablet_history_push()
109 tablet->history.samples[index] = *axes; in tablet_history_push()
110 tablet->history.index = index; in tablet_history_push()
111 tablet->history.count = min(tablet->history.count + 1, in tablet_history_push()
114 if (tablet->history.count < tablet_history_size(tablet)) in tablet_history_push()
128 assert(index < tablet->history.count); in tablet_history_get()
130 index = (tablet->history.index + sz - index) % sz; in tablet_history_get()
131 return &tablet->history.samples[index]; in tablet_history_get()
137 memset(tablet->changed_axes, 0, sizeof(tablet->changed_axes)); in tablet_reset_changed_axes()
144 struct libevdev *evdev = tablet->device->evdev; in tablet_device_has_axis()
185 previous = tablet->prev_value[axis]; in tablet_filter_axis_fuzz()
186 current = e->value; in tablet_filter_axis_fuzz()
187 delta = previous - current; in tablet_filter_axis_fuzz()
189 fuzz = libevdev_get_abs_fuzz(device->evdev, e->code); in tablet_filter_axis_fuzz()
193 * as the xf86-input-wacom driver in tablet_filter_axis_fuzz()
195 switch (e->code) { in tablet_filter_axis_fuzz()
214 switch (e->code) { in tablet_process_absolute()
223 axis = evcode_to_axis(e->code); in tablet_process_absolute()
227 e->code); in tablet_process_absolute()
231 tablet->prev_value[axis] = tablet->current_value[axis]; in tablet_process_absolute()
235 tablet->current_value[axis] = e->value; in tablet_process_absolute()
236 set_bit(tablet->changed_axes, axis); in tablet_process_absolute()
242 tablet->current_tool.id = e->value; in tablet_process_absolute()
258 e->code); in tablet_process_absolute()
266 struct tablet_dispatch *tablet = tablet_dispatch(device->dispatch); in tablet_apply_rotation()
268 if (tablet->rotation.rotate == tablet->rotation.want_rotate) in tablet_apply_rotation()
274 tablet->rotation.rotate = tablet->rotation.want_rotate; in tablet_apply_rotation()
277 "tablet-rotation: rotation is %s\n", in tablet_apply_rotation()
278 tablet->rotation.rotate ? "on" : "off"); in tablet_apply_rotation()
284 struct tablet_dispatch *tablet = tablet_dispatch(device->dispatch); in tablet_change_rotation()
285 struct evdev_device *touch_device = tablet->touch_device; in tablet_change_rotation()
289 tablet_is_left = tablet->device->left_handed.enabled; in tablet_change_rotation()
290 touchpad_is_left = tablet->rotation.touch_device_left_handed_state; in tablet_change_rotation()
292 tablet->rotation.want_rotate = tablet_is_left || touchpad_is_left; in tablet_change_rotation()
296 bool enable = device->left_handed.want_enabled; in tablet_change_rotation()
298 dispatch = touch_device->dispatch; in tablet_change_rotation()
299 if (dispatch->interface->left_handed_toggle) in tablet_change_rotation()
300 dispatch->interface->left_handed_toggle(dispatch, in tablet_change_rotation()
309 if (device->left_handed.enabled == device->left_handed.want_enabled) in tablet_change_to_left_handed()
312 device->left_handed.enabled = device->left_handed.want_enabled; in tablet_change_to_left_handed()
326 tablet->current_tool.type = tool; in tablet_update_tool()
338 double value = (absinfo->value - absinfo->minimum) / absinfo_range(absinfo); in normalize_slider()
340 return value * 2 - 1; in normalize_slider()
346 double value = (absinfo->value - absinfo->minimum) / absinfo_range(absinfo); in normalize_distance()
357 * |- 4% -| in normalize_pressure()
358 * min |------X------X-------------------------| max in normalize_pressure()
361 * +- offset and lower threshold in normalize_pressure()
366 int base = tool->pressure.threshold.lower; in normalize_pressure()
367 double range = absinfo->maximum - base + 1; in normalize_pressure()
368 double value = (absinfo->value - base) / range; in normalize_pressure()
376 double value = (absinfo->value - absinfo->minimum) / absinfo_range(absinfo); in adjust_tilt()
382 if (absinfo->resolution != 0 && in adjust_tilt()
383 absinfo->maximum > 0 && in adjust_tilt()
384 absinfo->minimum < 0) { in adjust_tilt()
385 value = 180.0/M_PI * absinfo->value/absinfo->resolution; in adjust_tilt()
387 /* Wacom supports physical [-64, 64] degrees, so map to that by in adjust_tilt()
392 /* Map to the (-1, 1) range */ in adjust_tilt()
393 value = (value * 2) - 1; in adjust_tilt()
403 return absinfo->maximum - (absinfo->value - absinfo->minimum); in invert_axis()
417 x = tablet->axes.tilt.x; in convert_tilt_to_rotation()
418 y = tablet->axes.tilt.y; in convert_tilt_to_rotation()
420 /* atan2 is CCW, we want CW -> negate x */ in convert_tilt_to_rotation()
422 angle = ((180.0 * atan2(-x, y)) / M_PI); in convert_tilt_to_rotation()
424 angle = fmod(360 + angle - offset, 360); in convert_tilt_to_rotation()
426 tablet->axes.rotation = angle; in convert_tilt_to_rotation()
427 set_bit(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z); in convert_tilt_to_rotation()
434 double value = (absinfo->value - absinfo->minimum) / absinfo_range(absinfo); in convert_to_degrees()
443 struct evdev_device *device = tablet->device; in normalize_wheel()
445 return value * device->scroll.wheel_click_angle.x; in normalize_wheel()
455 if (!libevdev_has_event_code(device->evdev, EV_ABS, ABS_X) || in tablet_update_xy()
456 !libevdev_has_event_code(device->evdev, EV_ABS, ABS_Y)) in tablet_update_xy()
459 if (bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_X) || in tablet_update_xy()
460 bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_Y)) { in tablet_update_xy()
461 absinfo = libevdev_get_abs_info(device->evdev, ABS_X); in tablet_update_xy()
463 if (tablet->rotation.rotate) in tablet_update_xy()
466 value = absinfo->value; in tablet_update_xy()
468 tablet->axes.point.x = value; in tablet_update_xy()
470 absinfo = libevdev_get_abs_info(device->evdev, ABS_Y); in tablet_update_xy()
472 if (tablet->rotation.rotate) in tablet_update_xy()
475 value = absinfo->value; in tablet_update_xy()
477 tablet->axes.point.y = value; in tablet_update_xy()
479 evdev_transform_absolute(device, &tablet->axes.point); in tablet_update_xy()
500 (bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_X) || in tablet_tool_process_delta()
501 bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_Y))) { in tablet_tool_process_delta()
502 delta.x = axes->point.x - tablet->last_smooth_point.x; in tablet_tool_process_delta()
503 delta.y = axes->point.y - tablet->last_smooth_point.y; in tablet_tool_process_delta()
506 if (axes->point.x != tablet->last_smooth_point.x) in tablet_tool_process_delta()
507 set_bit(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_X); in tablet_tool_process_delta()
508 if (axes->point.y != tablet->last_smooth_point.y) in tablet_tool_process_delta()
509 set_bit(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_Y); in tablet_tool_process_delta()
511 tablet->last_smooth_point = axes->point; in tablet_tool_process_delta()
519 return filter_dispatch(device->pointer.filter, in tablet_tool_process_delta()
532 if (!libevdev_has_event_code(device->evdev, EV_ABS, ABS_PRESSURE)) in tablet_update_pressure()
535 if (bit_is_set(tablet->changed_axes, in tablet_update_pressure()
537 absinfo = libevdev_get_abs_info(device->evdev, ABS_PRESSURE); in tablet_update_pressure()
538 tablet->axes.pressure = normalize_pressure(absinfo, tool); in tablet_update_pressure()
548 if (!libevdev_has_event_code(device->evdev, EV_ABS, ABS_DISTANCE)) in tablet_update_distance()
551 if (bit_is_set(tablet->changed_axes, in tablet_update_distance()
553 absinfo = libevdev_get_abs_info(device->evdev, ABS_DISTANCE); in tablet_update_distance()
554 tablet->axes.distance = normalize_distance(absinfo); in tablet_update_distance()
564 if (!libevdev_has_event_code(device->evdev, EV_ABS, ABS_WHEEL)) in tablet_update_slider()
567 if (bit_is_set(tablet->changed_axes, in tablet_update_slider()
569 absinfo = libevdev_get_abs_info(device->evdev, ABS_WHEEL); in tablet_update_slider()
570 tablet->axes.slider = normalize_slider(absinfo); in tablet_update_slider()
580 if (!libevdev_has_event_code(device->evdev, EV_ABS, ABS_TILT_X) || in tablet_update_tilt()
581 !libevdev_has_event_code(device->evdev, EV_ABS, ABS_TILT_Y)) in tablet_update_tilt()
586 if (bit_is_set(tablet->changed_axes, in tablet_update_tilt()
588 bit_is_set(tablet->changed_axes, in tablet_update_tilt()
591 absinfo = libevdev_get_abs_info(device->evdev, ABS_TILT_X); in tablet_update_tilt()
592 tablet->axes.tilt.x = adjust_tilt(absinfo); in tablet_update_tilt()
594 absinfo = libevdev_get_abs_info(device->evdev, ABS_TILT_Y); in tablet_update_tilt()
595 tablet->axes.tilt.y = adjust_tilt(absinfo); in tablet_update_tilt()
597 if (device->left_handed.enabled) { in tablet_update_tilt()
598 tablet->axes.tilt.x *= -1; in tablet_update_tilt()
599 tablet->axes.tilt.y *= -1; in tablet_update_tilt()
610 if (!libevdev_has_event_code(device->evdev, EV_ABS, ABS_Z)) in tablet_update_artpen_rotation()
613 if (bit_is_set(tablet->changed_axes, in tablet_update_artpen_rotation()
615 absinfo = libevdev_get_abs_info(device->evdev, in tablet_update_artpen_rotation()
618 tablet->axes.rotation = convert_to_degrees(absinfo, 90); in tablet_update_artpen_rotation()
626 if (bit_is_set(tablet->changed_axes, in tablet_update_mouse_rotation()
628 bit_is_set(tablet->changed_axes, in tablet_update_mouse_rotation()
640 if (tablet->current_tool.type == LIBINPUT_TABLET_TOOL_TYPE_MOUSE || in tablet_update_rotation()
641 tablet->current_tool.type == LIBINPUT_TABLET_TOOL_TYPE_LENS) { in tablet_update_rotation()
643 clear_bit(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_TILT_X); in tablet_update_rotation()
644 clear_bit(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_TILT_Y); in tablet_update_rotation()
645 tablet->axes.tilt.x = 0; in tablet_update_rotation()
646 tablet->axes.tilt.y = 0; in tablet_update_rotation()
648 /* tilt is already converted to left-handed, so mouse in tablet_update_rotation()
649 * rotation is converted to left-handed automatically */ in tablet_update_rotation()
654 if (device->left_handed.enabled) { in tablet_update_rotation()
655 double r = tablet->axes.rotation; in tablet_update_rotation()
656 tablet->axes.rotation = fmod(180 + r, 360); in tablet_update_rotation()
668 if (bit_is_set(tablet->changed_axes, a)) { in tablet_update_wheel()
669 /* tablet->axes.wheel_discrete is already set */ in tablet_update_wheel()
670 tablet->axes.wheel = normalize_wheel(tablet, in tablet_update_wheel()
671 tablet->axes.wheel_discrete); in tablet_update_wheel()
673 tablet->axes.wheel = 0; in tablet_update_wheel()
674 tablet->axes.wheel_discrete = 0; in tablet_update_wheel()
689 smooth.point.x += a->point.x; in tablet_smoothen_axes()
690 smooth.point.y += a->point.y; in tablet_smoothen_axes()
692 smooth.tilt.x += a->tilt.x; in tablet_smoothen_axes()
693 smooth.tilt.y += a->tilt.y; in tablet_smoothen_axes()
696 axes->point.x = smooth.point.x/count; in tablet_smoothen_axes()
697 axes->point.y = smooth.point.y/count; in tablet_smoothen_axes()
699 axes->tilt.x = smooth.tilt.x/count; in tablet_smoothen_axes()
700 axes->tilt.y = smooth.tilt.y/count; in tablet_smoothen_axes()
711 const char tmp[sizeof(tablet->changed_axes)] = {0}; in tablet_check_notify_axes()
714 if (memcmp(tmp, tablet->changed_axes, sizeof(tmp)) == 0) { in tablet_check_notify_axes()
715 axes = tablet->axes; in tablet_check_notify_axes()
729 axes.point = tablet->axes.point; in tablet_check_notify_axes()
730 axes.pressure = tablet->axes.pressure; in tablet_check_notify_axes()
731 axes.distance = tablet->axes.distance; in tablet_check_notify_axes()
732 axes.slider = tablet->axes.slider; in tablet_check_notify_axes()
733 axes.tilt = tablet->axes.tilt; in tablet_check_notify_axes()
734 axes.wheel = tablet->axes.wheel; in tablet_check_notify_axes()
735 axes.wheel_discrete = tablet->axes.wheel_discrete; in tablet_check_notify_axes()
736 axes.rotation = tablet->axes.rotation; in tablet_check_notify_axes()
749 tablet_history_push(tablet, &tablet->axes); in tablet_check_notify_axes()
778 evdev_log_info(tablet->device, in tablet_update_button()
786 set_bit(tablet->button_state.bits, evcode); in tablet_update_button()
789 clear_bit(tablet->button_state.bits, evcode); in tablet_update_button()
823 if (e->value == 2) in tablet_process_key()
826 switch (e->code) { in tablet_process_key()
838 type = tablet_evcode_to_tool(e->code); in tablet_process_key()
840 if (e->value) in tablet_process_key()
841 tablet->tool_state |= bit(type); in tablet_process_key()
843 tablet->tool_state &= ~bit(type); in tablet_process_key()
846 if (!bit_is_set(tablet->axis_caps, in tablet_process_key()
848 if (e->value) in tablet_process_key()
857 tablet_update_button(tablet, e->code, e->value); in tablet_process_key()
870 switch (e->code) { in tablet_process_relative()
872 axis = rel_evcode_to_axis(e->code); in tablet_process_relative()
876 e->code); in tablet_process_relative()
879 set_bit(tablet->changed_axes, axis); in tablet_process_relative()
880 tablet->axes.wheel_discrete = -1 * e->value; in tablet_process_relative()
886 libevdev_event_code_get_name(EV_REL, e->code), in tablet_process_relative()
887 e->code); in tablet_process_relative()
898 switch (e->code) { in tablet_process_misc()
900 if (e->value != -1) in tablet_process_misc()
901 tablet->current_tool.serial = e->value; in tablet_process_misc()
909 libevdev_event_code_get_name(EV_MSC, e->code), in tablet_process_misc()
910 e->code); in tablet_process_misc()
920 if (bit_is_set(tablet->axis_caps, axis)) in copy_axis_cap()
921 set_bit(tool->axis_caps, axis); in copy_axis_cap()
929 struct libevdev *evdev = tablet->device->evdev; in copy_button_cap()
931 set_bit(tool->buttons, button); in copy_button_cap()
946 db = tablet_libinput_context(tablet)->libwacom.db; in tool_set_bits_from_libwacom()
950 s = libwacom_stylus_get_for_id(db, tool->tool_id); in tool_set_bits_from_libwacom()
975 set_bit(tool->axis_caps, in tool_set_bits_from_libwacom()
1005 enum libinput_tablet_tool_type type = tool->type; in tool_set_bits()
1037 if (libevdev_has_event_code(tablet->device->evdev, EV_ABS, in tool_set_bits()
1050 /* If we don't have libwacom, copy all pen-related buttons from the in tool_set_bits()
1051 tablet vs all mouse-related buttons */ in tool_set_bits()
1077 return absinfo_range(a) * percent/100.0 + a->minimum; in axis_range_percentage()
1084 struct evdev_device *device = tablet->device; in tool_set_pressure_thresholds()
1091 tool->pressure.offset = 0; in tool_set_pressure_thresholds()
1092 tool->pressure.has_offset = false; in tool_set_pressure_thresholds()
1094 pressure = libevdev_get_abs_info(device->evdev, ABS_PRESSURE); in tool_set_pressure_thresholds()
1098 quirks = evdev_libinput_context(device)->quirks; in tool_set_pressure_thresholds()
1099 q = quirks_fetch_for_device(quirks, device->udev_device); in tool_set_pressure_thresholds()
1101 distance = libevdev_get_abs_info(device->evdev, ABS_DISTANCE); in tool_set_pressure_thresholds()
1103 tool->pressure.offset = pressure->minimum; in tool_set_pressure_thresholds()
1104 tool->pressure.heuristic_state = PRESSURE_HEURISTIC_STATE_DONE; in tool_set_pressure_thresholds()
1106 tool->pressure.offset = pressure->maximum; in tool_set_pressure_thresholds()
1107 tool->pressure.heuristic_state = PRESSURE_HEURISTIC_STATE_PROXIN1; in tool_set_pressure_thresholds()
1124 tool->pressure.threshold.upper = hi; in tool_set_pressure_thresholds()
1125 tool->pressure.threshold.lower = lo; in tool_set_pressure_thresholds()
1136 struct libinput *libinput = tablet_libinput_context(tablet); in tablet_get_tool() local
1141 tool_list = &libinput->tool_list; in tablet_get_tool()
1144 if (type == t->type && serial == t->serial) { in tablet_get_tool()
1152 * a 0-serial number tool for it earlier. Re-use that, even though in tablet_get_tool()
1157 tool_list = &tablet->tool_list; in tablet_get_tool()
1165 if (type == t->type) { in tablet_get_tool()
1174 tool_list = &libinput->tool_list; in tablet_get_tool()
1192 list_insert(tool_list, &tool->link); in tablet_get_tool()
1206 struct libinput_device *base = &device->base; in tablet_notify_button_mask()
1208 size_t nbits = 8 * sizeof(buttons->bits); in tablet_notify_button_mask()
1217 if (!bit_is_set(buttons->bits, i)) in tablet_notify_button_mask()
1224 &tablet->axes, in tablet_notify_button_mask()
1260 distance = libevdev_get_abs_info(tablet->device->evdev, ABS_DISTANCE); in sanitize_pressure_distance()
1261 pressure = libevdev_get_abs_info(tablet->device->evdev, ABS_PRESSURE); in sanitize_pressure_distance()
1266 bool pressure_changed = bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_PRESSURE); in sanitize_pressure_distance()
1267 bool distance_changed = bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_DISTANCE); in sanitize_pressure_distance()
1275 tool_in_contact = (pressure->value > tool->pressure.threshold.lower); in sanitize_pressure_distance()
1279 distance->value > distance->minimum && in sanitize_pressure_distance()
1280 pressure->value > pressure->minimum) { in sanitize_pressure_distance()
1282 clear_bit(tablet->changed_axes, in sanitize_pressure_distance()
1284 tablet->axes.distance = 0; in sanitize_pressure_distance()
1286 clear_bit(tablet->changed_axes, in sanitize_pressure_distance()
1288 tablet->axes.pressure = 0; in sanitize_pressure_distance()
1292 if (tablet->axes.pressure == 0) in sanitize_pressure_distance()
1293 clear_bit(tablet->changed_axes, in sanitize_pressure_distance()
1296 tablet->axes.pressure = 0; in sanitize_pressure_distance()
1305 if ((tablet->current_tool.type == LIBINPUT_TABLET_TOOL_TYPE_MOUSE || in sanitize_mouse_lens_rotation()
1306 tablet->current_tool.type == LIBINPUT_TABLET_TOOL_TYPE_LENS) && in sanitize_mouse_lens_rotation()
1307 (bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_TILT_X) || in sanitize_mouse_lens_rotation()
1308 bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_TILT_Y))) in sanitize_mouse_lens_rotation()
1309 set_bit(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z); in sanitize_mouse_lens_rotation()
1323 tool->pressure.offset = offset; in set_pressure_offset()
1324 tool->pressure.has_offset = true; in set_pressure_offset()
1326 /* Adjust the tresholds accordingly - we use the same gap (4% in in set_pressure_offset()
1330 int gap = tool->pressure.threshold.upper - tool->pressure.threshold.lower; in set_pressure_offset()
1331 tool->pressure.threshold.lower = offset; in set_pressure_offset()
1332 tool->pressure.threshold.upper = offset + gap; in set_pressure_offset()
1341 libevdev_get_abs_info(device->evdev, ABS_PRESSURE); in update_pressure_offset()
1344 !bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_PRESSURE)) in update_pressure_offset()
1349 * higher-than-needed pressure offset and then we'd be tied into a in update_pressure_offset()
1355 int offset = pressure->value; in update_pressure_offset()
1356 if (tool->pressure.has_offset) { in update_pressure_offset()
1357 if (offset < tool->pressure.offset) in update_pressure_offset()
1359 } else if (tool->pressure.heuristic_state != PRESSURE_HEURISTIC_STATE_DONE) { in update_pressure_offset()
1360 tool->pressure.offset = min(offset, tool->pressure.offset); in update_pressure_offset()
1372 if (tool->pressure.has_offset || in detect_pressure_offset()
1373 !bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_PRESSURE)) in detect_pressure_offset()
1376 pressure = libevdev_get_abs_info(device->evdev, ABS_PRESSURE); in detect_pressure_offset()
1377 distance = libevdev_get_abs_info(device->evdev, ABS_DISTANCE); in detect_pressure_offset()
1382 offset = pressure->value; in detect_pressure_offset()
1383 if (offset <= pressure->minimum) in detect_pressure_offset()
1389 if (distance->value < axis_range_percentage(distance, 50)) in detect_pressure_offset()
1396 * deciding prox-in arrives we should know the minimum offset. in detect_pressure_offset()
1398 if (offset > pressure->minimum) in detect_pressure_offset()
1399 tool->pressure.offset = min(offset, tool->pressure.offset); in detect_pressure_offset()
1401 switch (tool->pressure.heuristic_state) { in detect_pressure_offset()
1404 tool->pressure.heuristic_state++; in detect_pressure_offset()
1407 tool->pressure.heuristic_state++; in detect_pressure_offset()
1408 offset = tool->pressure.offset; in detect_pressure_offset()
1415 if (offset <= pressure->minimum) in detect_pressure_offset()
1421 "See %s/tablet-support.html\n", in detect_pressure_offset()
1422 tablet_tool_type_to_string(tool->type), in detect_pressure_offset()
1423 tool->serial, in detect_pressure_offset()
1430 "See %s/tablet-support.html\n", in detect_pressure_offset()
1431 tablet_tool_type_to_string(tool->type), in detect_pressure_offset()
1432 tool->serial, in detect_pressure_offset()
1446 if (!bit_is_set(tool->axis_caps, LIBINPUT_TABLET_TOOL_AXIS_PRESSURE)) in detect_tool_contact()
1458 p = libevdev_get_abs_info(tablet->device->evdev, ABS_PRESSURE); in detect_tool_contact()
1464 pressure = p->value; in detect_tool_contact()
1466 if (pressure <= tool->pressure.threshold.lower && in detect_tool_contact()
1469 } else if (pressure >= tool->pressure.threshold.upper && in detect_tool_contact()
1479 static_assert(sizeof(tablet->changed_axes) == in tablet_mark_all_axes_changed()
1480 sizeof(tool->axis_caps), in tablet_mark_all_axes_changed()
1483 memcpy(tablet->changed_axes, in tablet_mark_all_axes_changed()
1484 tool->axis_caps, in tablet_mark_all_axes_changed()
1485 sizeof(tablet->changed_axes)); in tablet_mark_all_axes_changed()
1494 int dist_max = tablet->cursor_proximity_threshold; in tablet_update_proximity_state()
1497 distance = libevdev_get_abs_info(tablet->device->evdev, ABS_DISTANCE); in tablet_update_proximity_state()
1501 dist = distance->value; in tablet_update_proximity_state()
1548 struct evdev_device *device = tablet->device; in tablet_calculate_arbitration_rect()
1552 mm = evdev_device_units_to_mm(device, &tablet->axes.point); in tablet_calculate_arbitration_rect()
1557 * end) assume left-handed mode. in tablet_calculate_arbitration_rect()
1562 if (tablet->axes.tilt.x > 0) { in tablet_calculate_arbitration_rect()
1563 r.x = mm.x - 20; in tablet_calculate_arbitration_rect()
1568 r.x -= r.w; in tablet_calculate_arbitration_rect()
1576 r.y = mm.y - 100; in tablet_calculate_arbitration_rect()
1594 if (tablet->touch_device == NULL || in tablet_update_touch_device_rect()
1595 tablet->arbitration != ARBITRATION_IGNORE_RECT) in tablet_update_touch_device_rect()
1600 dispatch = tablet->touch_device->dispatch; in tablet_update_touch_device_rect()
1601 if (dispatch->interface->touch_arbitration_update_rect) in tablet_update_touch_device_rect()
1602 dispatch->interface->touch_arbitration_update_rect(dispatch, in tablet_update_touch_device_rect()
1603 tablet->touch_device, in tablet_update_touch_device_rect()
1618 tablet_notify_proximity(&device->base, in tablet_send_proximity_in()
1622 tablet->changed_axes, in tablet_send_proximity_in()
1628 axes->delta.x = 0; in tablet_send_proximity_in()
1629 axes->delta.y = 0; in tablet_send_proximity_in()
1644 tablet_notify_proximity(&device->base, in tablet_send_proximity_out()
1648 tablet->changed_axes, in tablet_send_proximity_out()
1655 axes->delta.x = 0; in tablet_send_proximity_out()
1656 axes->delta.y = 0; in tablet_send_proximity_out()
1669 tablet_notify_tip(&device->base, in tablet_send_tip()
1673 tablet->changed_axes, in tablet_send_tip()
1680 axes->delta.x = 0; in tablet_send_tip()
1681 axes->delta.y = 0; in tablet_send_tip()
1687 tablet_notify_tip(&device->base, in tablet_send_tip()
1691 tablet->changed_axes, in tablet_send_tip()
1698 axes->delta.x = 0; in tablet_send_tip()
1699 axes->delta.y = 0; in tablet_send_tip()
1725 tablet_notify_axis(&device->base, in tablet_send_axes()
1729 tablet->changed_axes, in tablet_send_axes()
1733 axes->delta.x = 0; in tablet_send_axes()
1734 axes->delta.y = 0; in tablet_send_axes()
1775 axes = tablet->axes; in tablet_send_events()
1785 assert(tablet->axes.delta.x == 0); in tablet_send_events()
1786 assert(tablet->axes.delta.y == 0); in tablet_send_events()
1807 * leaves the detectable range. To libinput this looks like we always have
1827 if (tablet->quirks.need_to_force_prox_out) in tablet_proximity_out_quirk_set_timer()
1828 libinput_timer_set(&tablet->quirks.prox_out_timer, in tablet_proximity_out_quirk_set_timer()
1843 * our tool state is zero - i.e. we got a valid prox out from the in tablet_update_tool_state()
1846 if (tablet->quirks.proximity_out_forced && in tablet_update_tool_state()
1848 !tablet->tool_state) { in tablet_update_tool_state()
1849 tablet->quirks.need_to_force_prox_out = false; in tablet_update_tool_state()
1850 tablet->quirks.proximity_out_forced = false; in tablet_update_tool_state()
1854 * - we forced a proximity out before, or in tablet_update_tool_state()
1855 * - on the very first event after init, because if we didn't get a in tablet_update_tool_state()
1861 * so we get it after our forced prox-out has triggered. In that in tablet_update_tool_state()
1865 if (tablet->quirks.proximity_out_forced) { in tablet_update_tool_state()
1867 !tablet->tool_state) in tablet_update_tool_state()
1868 tablet->tool_state = bit(LIBINPUT_TABLET_TOOL_TYPE_PEN); in tablet_update_tool_state()
1869 tablet->quirks.proximity_out_forced = false; in tablet_update_tool_state()
1870 } else if (tablet->tool_state == 0 && in tablet_update_tool_state()
1871 tablet->current_tool.type == LIBINPUT_TOOL_NONE) { in tablet_update_tool_state()
1872 tablet->tool_state = bit(LIBINPUT_TABLET_TOOL_TYPE_PEN); in tablet_update_tool_state()
1873 tablet->quirks.proximity_out_forced = false; in tablet_update_tool_state()
1877 if (tablet->tool_state == tablet->prev_tool_state) in tablet_update_tool_state()
1883 * - BTN_TOOL_PEN on proximity in, followed by in tablet_update_tool_state()
1885 * -> We force a prox-out of the pen, trigger prox-in for eraser in tablet_update_tool_state()
1886 * - BTN_TOOL_RUBBER on proximity in, but BTN_TOOL_PEN when in tablet_update_tool_state()
1888 * -> We ignore BTN_TOOL_PEN in tablet_update_tool_state()
1892 if (tablet->tool_state & (tablet->tool_state - 1)) { in tablet_update_tool_state()
1893 doubled_up_new_tool_bit = tablet->tool_state ^ tablet->prev_tool_state; in tablet_update_tool_state()
1897 tablet->tool_state &= ~bit(LIBINPUT_TABLET_TOOL_TYPE_PEN); in tablet_update_tool_state()
1905 * When we re-process this function we now get the new tool in tablet_update_tool_state()
1909 tablet->tool_state = 0; in tablet_update_tool_state()
1912 changed = tablet->tool_state ^ tablet->prev_tool_state; in tablet_update_tool_state()
1913 type = ffs(changed) - 1; in tablet_update_tool_state()
1914 state = !!(tablet->tool_state & bit(type)); in tablet_update_tool_state()
1927 * timer-based proximity out. in tablet_update_tool_state()
1929 if (!tablet->quirks.proximity_out_in_progress) in tablet_update_tool_state()
1930 tablet->quirks.need_to_force_prox_out = false; in tablet_update_tool_state()
1932 libinput_timer_cancel(&tablet->quirks.prox_out_timer); in tablet_update_tool_state()
1936 tablet->prev_tool_state = tablet->tool_state; in tablet_update_tool_state()
1939 tablet->tool_state = doubled_up_new_tool_bit; in tablet_update_tool_state()
1940 return true; /* need to re-process */ in tablet_update_tool_state()
1948 if (tablet->current_tool.type == LIBINPUT_TOOL_NONE) in tablet_get_current_tool()
1952 tablet->current_tool.type, in tablet_get_current_tool()
1953 tablet->current_tool.id, in tablet_get_current_tool()
1954 tablet->current_tool.serial); in tablet_get_current_tool()
1972 if (tool->type == LIBINPUT_TABLET_TOOL_TYPE_MOUSE || in tablet_flush()
1973 tool->type == LIBINPUT_TABLET_TOOL_TYPE_LENS) in tablet_flush()
1982 memset(tablet->button_state.bits, in tablet_flush()
1984 sizeof(tablet->button_state.bits)); in tablet_flush()
2012 struct evdev_device *touch_device = tablet->touch_device; in tablet_set_touch_device_enabled()
2018 tablet->arbitration = which; in tablet_set_touch_device_enabled()
2020 dispatch = touch_device->dispatch; in tablet_set_touch_device_enabled()
2021 if (dispatch->interface->touch_arbitration_toggle) in tablet_set_touch_device_enabled()
2022 dispatch->interface->touch_arbitration_toggle(dispatch, in tablet_set_touch_device_enabled()
2046 } else if (tablet->axes.tilt.x == 0) { in tablet_toggle_touch_device()
2048 } else if (tablet->arbitration != ARBITRATION_IGNORE_RECT) { in tablet_toggle_touch_device()
2049 /* This enables rect-based arbitration, updates are sent in tablet_toggle_touch_device()
2070 memcpy(&tablet->prev_button_state, in tablet_reset_state()
2071 &tablet->button_state, in tablet_reset_state()
2072 sizeof(tablet->button_state)); in tablet_reset_state()
2075 if (memcmp(&tablet->button_state, &zero, sizeof(zero)) == 0) in tablet_reset_state()
2105 if (tablet->quirks.last_event_time > now - FORCED_PROXOUT_TIMEOUT) { in tablet_proximity_out_quirk_timer_func()
2107 tablet->quirks.last_event_time); in tablet_proximity_out_quirk_timer_func()
2111 evdev_log_debug(tablet->device, "tablet: forcing proximity after timeout\n"); in tablet_proximity_out_quirk_timer_func()
2113 tablet->quirks.proximity_out_in_progress = true; in tablet_proximity_out_quirk_timer_func()
2115 tablet->base.interface->process(&tablet->base, in tablet_proximity_out_quirk_timer_func()
2116 tablet->device, in tablet_proximity_out_quirk_timer_func()
2120 tablet->quirks.proximity_out_in_progress = false; in tablet_proximity_out_quirk_timer_func()
2122 tablet->quirks.proximity_out_forced = true; in tablet_proximity_out_quirk_timer_func()
2133 switch (e->type) { in tablet_process()
2150 tablet->quirks.last_event_time = time; in tablet_process()
2155 libevdev_event_type_get_name(e->type), in tablet_process()
2156 e->type); in tablet_process()
2166 struct libinput *li = tablet_libinput_context(tablet); in tablet_suspend()
2185 struct libinput *li = tablet_libinput_context(tablet); in tablet_destroy()
2187 libinput_timer_cancel(&tablet->quirks.prox_out_timer); in tablet_destroy()
2188 libinput_timer_destroy(&tablet->quirks.prox_out_timer); in tablet_destroy()
2190 list_for_each_safe(tool, &tablet->tool_list, link) { in tablet_destroy()
2203 struct tablet_dispatch *tablet = tablet_dispatch(device->dispatch); in tablet_setup_touch_arbitration()
2206 * touchpad we see. This may be wrong in some cases, so we have some in tablet_setup_touch_arbitration()
2209 if (tablet->touch_device != NULL) { in tablet_setup_touch_arbitration()
2210 struct libinput_device_group *group1 = libinput_device_get_device_group(&device->base); in tablet_setup_touch_arbitration()
2211 struct libinput_device_group *group2 = libinput_device_get_device_group(&new_device->base); in tablet_setup_touch_arbitration()
2213 /* same phsical device? -> better, otherwise keep the one we have */ in tablet_setup_touch_arbitration()
2218 struct libinput *li = tablet_libinput_context(tablet); in tablet_setup_touch_arbitration()
2224 "touch-arbitration: removing pairing for %s<->%s\n", in tablet_setup_touch_arbitration()
2225 device->devname, in tablet_setup_touch_arbitration()
2226 tablet->touch_device->devname); in tablet_setup_touch_arbitration()
2230 "touch-arbitration: activated for %s<->%s\n", in tablet_setup_touch_arbitration()
2231 device->devname, in tablet_setup_touch_arbitration()
2232 new_device->devname); in tablet_setup_touch_arbitration()
2233 tablet->touch_device = new_device; in tablet_setup_touch_arbitration()
2240 struct tablet_dispatch *tablet = tablet_dispatch(device->dispatch); in tablet_setup_rotation()
2241 struct libinput_device_group *group1 = libinput_device_get_device_group(&device->base); in tablet_setup_rotation()
2242 struct libinput_device_group *group2 = libinput_device_get_device_group(&new_device->base); in tablet_setup_rotation()
2244 if (tablet->rotation.touch_device == NULL && (group1 == group2)) { in tablet_setup_rotation()
2246 "tablet-rotation: %s will rotate %s\n", in tablet_setup_rotation()
2247 device->devname, in tablet_setup_rotation()
2248 new_device->devname); in tablet_setup_rotation()
2249 tablet->rotation.touch_device = new_device; in tablet_setup_rotation()
2251 if (libinput_device_config_left_handed_get(&new_device->base)) { in tablet_setup_rotation()
2252 tablet->rotation.touch_device_left_handed_state = true; in tablet_setup_rotation()
2268 (added_device->tags & EVDEV_TAG_EXTERNAL_TOUCHPAD); in tablet_device_added()
2281 struct tablet_dispatch *tablet = tablet_dispatch(device->dispatch); in tablet_device_removed()
2283 if (tablet->touch_device == removed_device) in tablet_device_removed()
2284 tablet->touch_device = NULL; in tablet_device_removed()
2286 if (tablet->rotation.touch_device == removed_device) { in tablet_device_removed()
2287 tablet->rotation.touch_device = NULL; in tablet_device_removed()
2288 tablet->rotation.touch_device_left_handed_state = false; in tablet_device_removed()
2298 struct libinput *li = tablet_libinput_context(tablet); in tablet_check_initial_proximity()
2308 if (libevdev_fetch_event_value(device->evdev, in tablet_check_initial_proximity()
2312 tablet->tool_state = bit(tool); in tablet_check_initial_proximity()
2313 tablet->prev_tool_state = bit(tool); in tablet_check_initial_proximity()
2318 if (!tablet->tool_state) in tablet_check_initial_proximity()
2322 if (tablet->quirks.need_to_force_prox_out) in tablet_check_initial_proximity()
2325 tablet->current_tool.id = in tablet_check_initial_proximity()
2326 libevdev_get_event_value(device->evdev, in tablet_check_initial_proximity()
2334 tablet->current_tool.serial = 0; in tablet_check_initial_proximity()
2337 /* Called when the touchpad toggles to left-handed */
2345 if (!tablet->rotation.touch_device) in tablet_left_handed_toggled()
2349 "tablet-rotation: touchpad is %s\n", in tablet_left_handed_toggled()
2350 left_handed_enabled ? "left-handed" : "right-handed"); in tablet_left_handed_toggled()
2352 /* Our left-handed config is independent even though rotation is in tablet_left_handed_toggled()
2353 * locked. So we rotate when either device is left-handed. But it in tablet_left_handed_toggled()
2357 tablet->rotation.touch_device_left_handed_state = left_handed_enabled; in tablet_left_handed_toggled()
2381 if (libevdev_has_property(device->evdev, INPUT_PROP_DIRECT)) in tablet_init_calibration()
2382 evdev_init_calibration(device, &tablet->calibration); in tablet_init_calibration()
2392 if (!libevdev_has_event_code(device->evdev, EV_KEY, BTN_TOOL_MOUSE) && in tablet_init_proximity_threshold()
2393 !libevdev_has_event_code(device->evdev, EV_KEY, BTN_TOOL_LENS)) in tablet_init_proximity_threshold()
2396 /* 42 is the default proximity threshold the xf86-input-wacom driver in tablet_init_proximity_threshold()
2399 * intersection of users having a graphire, running libinput and in tablet_init_proximity_threshold()
2406 tablet->cursor_proximity_threshold = 42; in tablet_init_proximity_threshold()
2440 x = device->abs.absinfo_x; in tablet_init_accel()
2441 y = device->abs.absinfo_y; in tablet_init_accel()
2443 filter = create_pointer_accelerator_filter_tablet(x->resolution, in tablet_init_accel()
2444 y->resolution); in tablet_init_accel()
2446 return -1; in tablet_init_accel()
2452 device->pointer.config.get_profiles = tablet_accel_config_get_profiles; in tablet_init_accel()
2453 device->pointer.config.set_profile = tablet_accel_config_set_profile; in tablet_init_accel()
2454 device->pointer.config.get_profile = tablet_accel_config_get_profile; in tablet_init_accel()
2455 device->pointer.config.get_default_profile = tablet_accel_config_get_default_profile; in tablet_init_accel()
2481 /* Wacom-specific check for whether smoothing is required: in tablet_is_aes()
2490 db = tablet_libinput_context(tablet)->libwacom.db; in tablet_is_aes()
2494 devnode = udev_device_get_devnode(device->udev_device); in tablet_is_aes()
2518 size_t history_size = ARRAY_LENGTH(tablet->history.samples); in tablet_init_smoothing()
2523 quirks = evdev_libinput_context(device)->quirks; in tablet_init_smoothing()
2524 q = quirks_fetch_for_device(quirks, device->udev_device); in tablet_init_smoothing()
2537 tablet->history.size = history_size; in tablet_init_smoothing()
2543 struct libevdev *evdev = device->evdev; in tablet_reject_device()
2561 has_btn_stylus ? "" : " btn-stylus", in tablet_reject_device()
2570 struct libevdev *evdev = device->evdev; in tablet_init()
2574 tablet->base.dispatch_type = DISPATCH_TABLET; in tablet_init()
2575 tablet->base.interface = &tablet_interface; in tablet_init()
2576 tablet->device = device; in tablet_init()
2577 tablet->status = TABLET_NONE; in tablet_init()
2578 tablet->current_tool.type = LIBINPUT_TOOL_NONE; in tablet_init()
2579 list_init(&tablet->tool_list); in tablet_init()
2582 return -1; in tablet_init()
2586 tablet->quirks.proximity_out_forced = true; in tablet_init()
2602 evdev_init_sendevents(device, &tablet->base); in tablet_init()
2610 set_bit(tablet->axis_caps, axis); in tablet_init()
2617 tablet->quirks.need_to_force_prox_out = true; in tablet_init()
2619 libinput_timer_init(&tablet->quirks.prox_out_timer, in tablet_init()
2632 struct libinput *li = evdev_libinput_context(device); in evdev_tablet_create()
2643 tablet_destroy(&tablet->base); in evdev_tablet_create()
2647 return &tablet->base; in evdev_tablet_create()