mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-04-05 12:30:42 +02:00
tablet: enable the calibration matrix for internal tablets
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
20db89f5c9
commit
bd0f43eeb6
5 changed files with 225 additions and 4 deletions
|
|
@ -326,10 +326,47 @@ tablet_check_notify_axes(struct tablet_dispatch *tablet,
|
|||
double deltas[LIBINPUT_TABLET_TOOL_AXIS_MAX + 1] = {0};
|
||||
double deltas_discrete[LIBINPUT_TABLET_TOOL_AXIS_MAX + 1] = {0};
|
||||
double oldval;
|
||||
struct device_coords point, old_point;
|
||||
const struct input_absinfo *absinfo;
|
||||
|
||||
for (a = LIBINPUT_TABLET_TOOL_AXIS_X; a <= LIBINPUT_TABLET_TOOL_AXIS_MAX; a++) {
|
||||
const struct input_absinfo *absinfo;
|
||||
/* x/y are special for left-handed and calibration */
|
||||
a = LIBINPUT_TABLET_TOOL_AXIS_X;
|
||||
old_point.x = tablet->axes[a];
|
||||
if (bit_is_set(tablet->changed_axes, a)) {
|
||||
absinfo = libevdev_get_abs_info(device->evdev,
|
||||
axis_to_evcode(a));
|
||||
|
||||
axis_update_needed = true;
|
||||
if (device->left_handed.enabled)
|
||||
tablet->axes[a] = invert_axis(absinfo);
|
||||
else
|
||||
tablet->axes[a] = absinfo->value;
|
||||
}
|
||||
point.x = tablet->axes[a];
|
||||
|
||||
a = LIBINPUT_TABLET_TOOL_AXIS_Y;
|
||||
old_point.y = tablet->axes[a];
|
||||
if (bit_is_set(tablet->changed_axes, a)) {
|
||||
absinfo = libevdev_get_abs_info(device->evdev,
|
||||
axis_to_evcode(a));
|
||||
axis_update_needed = true;
|
||||
|
||||
if (device->left_handed.enabled)
|
||||
tablet->axes[a] = invert_axis(absinfo);
|
||||
else
|
||||
tablet->axes[a] = absinfo->value;
|
||||
}
|
||||
point.y = tablet->axes[a];
|
||||
|
||||
evdev_transform_absolute(device, &point);
|
||||
evdev_transform_absolute(device, &old_point);
|
||||
|
||||
axes[LIBINPUT_TABLET_TOOL_AXIS_X] = point.x;
|
||||
axes[LIBINPUT_TABLET_TOOL_AXIS_Y] = point.y;
|
||||
deltas[LIBINPUT_TABLET_TOOL_AXIS_X] = point.x - old_point.x;
|
||||
deltas[LIBINPUT_TABLET_TOOL_AXIS_Y] = point.y - old_point.y;
|
||||
|
||||
for (a = LIBINPUT_TABLET_TOOL_AXIS_DISTANCE; a <= LIBINPUT_TABLET_TOOL_AXIS_MAX; a++) {
|
||||
if (!bit_is_set(tablet->changed_axes, a)) {
|
||||
axes[a] = tablet->axes[a];
|
||||
continue;
|
||||
|
|
@ -1088,6 +1125,14 @@ static struct evdev_dispatch_interface tablet_interface = {
|
|||
tablet_check_initial_proximity,
|
||||
};
|
||||
|
||||
static void
|
||||
tablet_init_calibration(struct tablet_dispatch *tablet,
|
||||
struct evdev_device *device)
|
||||
{
|
||||
if (libevdev_has_property(device->evdev, INPUT_PROP_DIRECT))
|
||||
evdev_init_calibration(device, &tablet->base);
|
||||
}
|
||||
|
||||
static int
|
||||
tablet_init(struct tablet_dispatch *tablet,
|
||||
struct evdev_device *device)
|
||||
|
|
@ -1100,6 +1145,8 @@ tablet_init(struct tablet_dispatch *tablet,
|
|||
tablet->current_tool_type = LIBINPUT_TOOL_NONE;
|
||||
list_init(&tablet->tool_list);
|
||||
|
||||
tablet_init_calibration(tablet, device);
|
||||
|
||||
for (axis = LIBINPUT_TABLET_TOOL_AXIS_X;
|
||||
axis <= LIBINPUT_TABLET_TOOL_AXIS_MAX;
|
||||
axis++) {
|
||||
|
|
|
|||
|
|
@ -1178,7 +1178,7 @@ evdev_init_button_scroll(struct evdev_device *device,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
evdev_init_calibration(struct evdev_device *device,
|
||||
struct evdev_dispatch *dispatch)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -290,6 +290,10 @@ void
|
|||
evdev_transform_absolute(struct evdev_device *device,
|
||||
struct device_coords *point);
|
||||
|
||||
void
|
||||
evdev_init_calibration(struct evdev_device *device,
|
||||
struct evdev_dispatch *dispatch);
|
||||
|
||||
int
|
||||
evdev_device_init_pointer_acceleration(struct evdev_device *device,
|
||||
struct motion_filter *filter);
|
||||
|
|
|
|||
|
|
@ -1600,7 +1600,7 @@ litest_setup_tests(void)
|
|||
litest_add("pointer:scroll", pointer_scroll_natural_enable_config, LITEST_WHEEL, LITEST_TABLET);
|
||||
litest_add("pointer:scroll", pointer_scroll_natural_wheel, LITEST_WHEEL, LITEST_TABLET);
|
||||
|
||||
litest_add("pointer:calibration", pointer_no_calibration, LITEST_ANY, LITEST_TOUCH|LITEST_SINGLE_TOUCH|LITEST_ABSOLUTE|LITEST_PROTOCOL_A);
|
||||
litest_add("pointer:calibration", pointer_no_calibration, LITEST_ANY, LITEST_TOUCH|LITEST_SINGLE_TOUCH|LITEST_ABSOLUTE|LITEST_PROTOCOL_A|LITEST_TABLET);
|
||||
|
||||
/* tests touchpads too */
|
||||
litest_add("pointer:left-handed", pointer_left_handed_defaults, LITEST_BUTTON, LITEST_ANY);
|
||||
|
|
|
|||
170
test/tablet.c
170
test/tablet.c
|
|
@ -2364,6 +2364,172 @@ START_TEST(tablet_pressure_distance_exclusive)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tablet_calibration_has_matrix)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput_device *d = dev->libinput_device;
|
||||
enum libinput_config_status status;
|
||||
int rc;
|
||||
float calibration[6] = {1, 0, 0, 0, 1, 0};
|
||||
int has_calibration;
|
||||
|
||||
has_calibration = libevdev_has_property(dev->evdev, INPUT_PROP_DIRECT);
|
||||
|
||||
rc = libinput_device_config_calibration_has_matrix(d);
|
||||
ck_assert_int_eq(rc, has_calibration);
|
||||
rc = libinput_device_config_calibration_get_matrix(d, calibration);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
rc = libinput_device_config_calibration_get_default_matrix(d,
|
||||
calibration);
|
||||
ck_assert_int_eq(rc, 0);
|
||||
|
||||
status = libinput_device_config_calibration_set_matrix(d,
|
||||
calibration);
|
||||
if (has_calibration)
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
else
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tablet_calibration_set_matrix_delta)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_device *d = dev->libinput_device;
|
||||
enum libinput_config_status status;
|
||||
float calibration[6] = {0.5, 0, 0, 0, 0.5, 0};
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_tablet_tool *tablet_event;
|
||||
struct axis_replacement axes[] = {
|
||||
{ ABS_DISTANCE, 10 },
|
||||
{ -1, -1 }
|
||||
};
|
||||
int has_calibration;
|
||||
double dx, dy, mdx, mdy;
|
||||
|
||||
has_calibration = libevdev_has_property(dev->evdev, INPUT_PROP_DIRECT);
|
||||
if (!has_calibration)
|
||||
return;
|
||||
|
||||
litest_tablet_proximity_in(dev, 100, 100, axes);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_tablet_motion(dev, 80, 80, axes);
|
||||
libinput_dispatch(li);
|
||||
|
||||
event = libinput_get_event(li);
|
||||
tablet_event = litest_is_tablet_event(event,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_AXIS);
|
||||
|
||||
dx = libinput_event_tablet_tool_get_axis_delta(tablet_event,
|
||||
LIBINPUT_TABLET_TOOL_AXIS_X);
|
||||
dy = libinput_event_tablet_tool_get_axis_delta(tablet_event,
|
||||
LIBINPUT_TABLET_TOOL_AXIS_Y);
|
||||
libinput_event_destroy(event);
|
||||
litest_tablet_proximity_out(dev);
|
||||
litest_drain_events(li);
|
||||
|
||||
status = libinput_device_config_calibration_set_matrix(d,
|
||||
calibration);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
litest_tablet_proximity_in(dev, 100, 100, axes);
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_tablet_motion(dev, 80, 80, axes);
|
||||
libinput_dispatch(li);
|
||||
|
||||
event = libinput_get_event(li);
|
||||
tablet_event = litest_is_tablet_event(event,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_AXIS);
|
||||
|
||||
mdx = libinput_event_tablet_tool_get_axis_delta(tablet_event,
|
||||
LIBINPUT_TABLET_TOOL_AXIS_X);
|
||||
mdy = libinput_event_tablet_tool_get_axis_delta(tablet_event,
|
||||
LIBINPUT_TABLET_TOOL_AXIS_Y);
|
||||
libinput_event_destroy(event);
|
||||
litest_drain_events(li);
|
||||
|
||||
ck_assert_double_gt(dx, mdx * 2 - 1);
|
||||
ck_assert_double_lt(dx, mdx * 2 + 1);
|
||||
ck_assert_double_gt(dy, mdy * 2 - 1);
|
||||
ck_assert_double_lt(dy, mdy * 2 + 1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tablet_calibration_set_matrix)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_device *d = dev->libinput_device;
|
||||
enum libinput_config_status status;
|
||||
float calibration[6] = {0.5, 0, 0, 0, 1, 0};
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_tablet_tool *tablet_event;
|
||||
struct axis_replacement axes[] = {
|
||||
{ ABS_DISTANCE, 10 },
|
||||
{ -1, -1 }
|
||||
};
|
||||
int has_calibration;
|
||||
double x, y;
|
||||
|
||||
has_calibration = libevdev_has_property(dev->evdev, INPUT_PROP_DIRECT);
|
||||
if (!has_calibration)
|
||||
return;
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
status = libinput_device_config_calibration_set_matrix(d,
|
||||
calibration);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
litest_tablet_proximity_in(dev, 100, 100, axes);
|
||||
libinput_dispatch(li);
|
||||
|
||||
event = libinput_get_event(li);
|
||||
tablet_event = litest_is_tablet_event(event,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
|
||||
x = libinput_event_tablet_tool_get_x_transformed(tablet_event, 100);
|
||||
y = libinput_event_tablet_tool_get_y_transformed(tablet_event, 100);
|
||||
libinput_event_destroy(event);
|
||||
|
||||
ck_assert_double_gt(x, 49.0);
|
||||
ck_assert_double_lt(x, 51.0);
|
||||
ck_assert_double_gt(y, 99.0);
|
||||
ck_assert_double_lt(y, 100.0);
|
||||
|
||||
litest_tablet_proximity_out(dev);
|
||||
libinput_dispatch(li);
|
||||
litest_tablet_proximity_in(dev, 50, 50, axes);
|
||||
litest_tablet_proximity_out(dev);
|
||||
litest_drain_events(li);
|
||||
|
||||
calibration[0] = 1;
|
||||
calibration[4] = 0.5;
|
||||
status = libinput_device_config_calibration_set_matrix(d,
|
||||
calibration);
|
||||
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
||||
litest_tablet_proximity_in(dev, 100, 100, axes);
|
||||
libinput_dispatch(li);
|
||||
|
||||
event = libinput_get_event(li);
|
||||
tablet_event = litest_is_tablet_event(event,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
|
||||
x = libinput_event_tablet_tool_get_x_transformed(tablet_event, 100);
|
||||
y = libinput_event_tablet_tool_get_y_transformed(tablet_event, 100);
|
||||
libinput_event_destroy(event);
|
||||
|
||||
ck_assert_double_gt(x, 99.0);
|
||||
ck_assert_double_lt(x, 100.0);
|
||||
ck_assert_double_gt(y, 49.0);
|
||||
ck_assert_double_lt(y, 51.0);
|
||||
|
||||
litest_tablet_proximity_out(dev);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
void
|
||||
litest_setup_tests(void)
|
||||
{
|
||||
|
|
@ -2408,4 +2574,8 @@ litest_setup_tests(void)
|
|||
|
||||
litest_add("tablet:time", tablet_time_usec, LITEST_TABLET, LITEST_ANY);
|
||||
litest_add("tablet:pressure", tablet_pressure_distance_exclusive, LITEST_TABLET | LITEST_DISTANCE, LITEST_ANY);
|
||||
|
||||
litest_add("tablet:calibration", tablet_calibration_has_matrix, LITEST_TABLET, LITEST_ANY);
|
||||
litest_add("tablet:calibration", tablet_calibration_set_matrix, LITEST_TABLET, LITEST_ANY);
|
||||
litest_add("tablet:calibration", tablet_calibration_set_matrix_delta, LITEST_TABLET, LITEST_ANY);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue