tablet: allow calibration if libwacom says our tablet is a display tablet

Not all display tablets have INPUT_PROP_DIRECT SET (looking at you,
Huion Kamvas 12) so our calibration went nowhere. Let libwacom override
whatever the kernel says.

This also makes testing without matching hardware a bit easier now since
we only need to override the libwacom file, not the whole device.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1019>
This commit is contained in:
Peter Hutterer 2024-06-19 11:50:52 +10:00
parent 41a4b128e9
commit 978676be1e
2 changed files with 49 additions and 21 deletions

View file

@ -2496,9 +2496,10 @@ static struct evdev_dispatch_interface tablet_interface = {
static void
tablet_init_calibration(struct tablet_dispatch *tablet,
struct evdev_device *device)
struct evdev_device *device,
bool is_display_tablet)
{
if (libevdev_has_property(device->evdev, INPUT_PROP_DIRECT))
if (is_display_tablet || libevdev_has_property(device->evdev, INPUT_PROP_DIRECT))
evdev_init_calibration(device, &tablet->calibration);
}
@ -2588,7 +2589,8 @@ tablet_init_left_handed(struct evdev_device *device)
static void
tablet_lookup_libwacom(struct evdev_device *device,
struct tablet_dispatch *tablet,
bool *is_aes)
bool *is_aes,
bool *is_display_tablet)
{
#if HAVE_LIBWACOM
const char *devnode;
@ -2598,15 +2600,6 @@ tablet_lookup_libwacom(struct evdev_device *device,
int nstyli;
int vid = evdev_device_get_id_vendor(device);
/* Wacom-specific check for whether smoothing is required:
* libwacom keeps all the AES pens in a single group, so any device
* that supports AES pens will list all AES pens. 0x11 is one of the
* lenovo pens so we use that as the flag of whether the tablet
* is an AES tablet
*/
if (vid != VENDOR_ID_WACOM)
return;
db = tablet_libinput_context(tablet)->libwacom.db;
if (!db)
return;
@ -2616,6 +2609,18 @@ tablet_lookup_libwacom(struct evdev_device *device,
if (!libwacom_device)
return;
*is_display_tablet = !!(libwacom_get_integration_flags(libwacom_device)
& (WACOM_DEVICE_INTEGRATED_SYSTEM|WACOM_DEVICE_INTEGRATED_DISPLAY));
/* Wacom-specific check for whether smoothing is required:
* libwacom keeps all the AES pens in a single group, so any device
* that supports AES pens will list all AES pens. 0x11 is one of the
* lenovo pens so we use that as the flag of whether the tablet
* is an AES tablet
*/
if (vid != VENDOR_ID_WACOM)
return;
stylus_ids = libwacom_get_supported_styli(libwacom_device, &nstyli);
for (int i = 0; i < nstyli; i++) {
if (stylus_ids[i] == 0x11) {
@ -2751,7 +2756,8 @@ tablet_init(struct tablet_dispatch *tablet,
return -1;
bool is_aes = false;
tablet_lookup_libwacom(device, tablet, &is_aes);
bool is_display_tablet = false;
tablet_lookup_libwacom(device, tablet, &is_aes, &is_display_tablet);
if (!libevdev_has_event_code(evdev, EV_KEY, BTN_TOOL_PEN)) {
libevdev_enable_event_code(evdev, EV_KEY, BTN_TOOL_PEN, NULL);
@ -2766,7 +2772,7 @@ tablet_init(struct tablet_dispatch *tablet,
}
tablet_fix_tilt(tablet, device);
tablet_init_calibration(tablet, device);
tablet_init_calibration(tablet, device, is_display_tablet);
tablet_init_proximity_threshold(tablet, device);
rc = tablet_init_accel(tablet, device);
if (rc != 0)

View file

@ -32,6 +32,10 @@
#include <stdbool.h>
#include <stdarg.h>
#if HAVE_LIBWACOM
#include <libwacom/libwacom.h>
#endif
#include "libinput-util.h"
#include "evdev-tablet.h"
#include "litest.h"
@ -3677,6 +3681,28 @@ START_TEST(tablet_pressure_distance_exclusive)
}
END_TEST
static bool
device_has_calibration(struct litest_device *dev)
{
bool has_calibration = libevdev_has_property(dev->evdev, INPUT_PROP_DIRECT);
if (has_calibration)
return true;
#if HAVE_LIBWACOM
WacomDeviceDatabase *db = libwacom_database_new();
if (db) {
WacomDevice *d = libwacom_new_from_path(db, libevdev_uinput_get_devnode(dev->uinput), WFALLBACK_NONE, NULL);
if (d) {
has_calibration = !!(libwacom_get_integration_flags(d) & (WACOM_DEVICE_INTEGRATED_SYSTEM|WACOM_DEVICE_INTEGRATED_DISPLAY));
libwacom_destroy(d);
}
libwacom_database_destroy(db);
}
#endif
return has_calibration;
}
START_TEST(tablet_calibration_has_matrix)
{
struct litest_device *dev = litest_current_device();
@ -3686,7 +3712,7 @@ START_TEST(tablet_calibration_has_matrix)
float calibration[6] = {1, 0, 0, 0, 1, 0};
int has_calibration;
has_calibration = libevdev_has_property(dev->evdev, INPUT_PROP_DIRECT);
has_calibration = device_has_calibration(dev);
rc = libinput_device_config_calibration_has_matrix(d);
ck_assert_int_eq(rc, has_calibration);
@ -3719,11 +3745,9 @@ START_TEST(tablet_calibration_set_matrix_delta)
{ ABS_PRESSURE, 10 },
{ -1, -1 }
};
int has_calibration;
double x, y, dx, dy, mdx, mdy;
has_calibration = libevdev_has_property(dev->evdev, INPUT_PROP_DIRECT);
if (!has_calibration)
if (!device_has_calibration(dev))
return;
litest_drain_events(li);
@ -3804,11 +3828,9 @@ START_TEST(tablet_calibration_set_matrix)
{ ABS_PRESSURE, 0 },
{ -1, -1 }
};
int has_calibration;
double x, y;
has_calibration = libevdev_has_property(dev->evdev, INPUT_PROP_DIRECT);
if (!has_calibration)
if (!device_has_calibration(dev))
return;
litest_drain_events(li);