mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-27 12:40:12 +01:00
tablet: disable smoothing for AES devices
Data in https://gitlab.freedesktop.org/libinput/libinput/-/issues/225#note_379034 suggests that AES devices have lower noise than the older EMR devices, so let's try disabling it for those devices. We can't directly get the AES devices in libinput unless we want to add a whole bunch of quirks for the various vid/pid combinations. But we can get that info from libwacom, primarily because we know that libwacom will list all known AES pens for any device. So we can check for one that we know of (0x11) and if it's in the list, the tablet is an AES tablet. Setting the history size to 1 means we never do any actual smoothing. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
cd37dcfa66
commit
a506d092b8
3 changed files with 134 additions and 1 deletions
|
|
@ -89,7 +89,7 @@ tablet_force_button_presses(struct tablet_dispatch *tablet)
|
|||
static inline size_t
|
||||
tablet_history_size(const struct tablet_dispatch *tablet)
|
||||
{
|
||||
return ARRAY_LENGTH(tablet->history.samples);
|
||||
return tablet->history.size;
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
@ -2344,6 +2344,55 @@ tablet_init_left_handed(struct evdev_device *device)
|
|||
tablet_change_to_left_handed);
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_init_smoothing(struct evdev_device *device,
|
||||
struct tablet_dispatch *tablet)
|
||||
{
|
||||
size_t history_size = ARRAY_LENGTH(tablet->history.samples);
|
||||
#if HAVE_LIBWACOM
|
||||
const char *devnode;
|
||||
WacomDeviceDatabase *db;
|
||||
WacomDevice *libwacom_device = NULL;
|
||||
const int *stylus_ids;
|
||||
int nstyli;
|
||||
bool is_aes = false;
|
||||
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)
|
||||
goto out;
|
||||
|
||||
db = tablet_libinput_context(tablet)->libwacom.db;
|
||||
if (!db)
|
||||
goto out;
|
||||
|
||||
devnode = udev_device_get_devnode(device->udev_device);
|
||||
libwacom_device = libwacom_new_from_path(db, devnode, WFALLBACK_NONE, NULL);
|
||||
if (!libwacom_device)
|
||||
goto out;
|
||||
|
||||
stylus_ids = libwacom_get_supported_styli(libwacom_device, &nstyli);
|
||||
for (int i = 0; i < nstyli; i++) {
|
||||
if (stylus_ids[i] == 0x11) {
|
||||
is_aes = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_aes)
|
||||
history_size = 1;
|
||||
|
||||
libwacom_destroy(libwacom_device);
|
||||
out:
|
||||
#endif
|
||||
tablet->history.size = history_size;
|
||||
}
|
||||
|
||||
static bool
|
||||
tablet_reject_device(struct evdev_device *device)
|
||||
{
|
||||
|
|
@ -2408,6 +2457,7 @@ tablet_init(struct tablet_dispatch *tablet,
|
|||
|
||||
evdev_init_sendevents(device, &tablet->base);
|
||||
tablet_init_left_handed(device);
|
||||
tablet_init_smoothing(device, tablet);
|
||||
|
||||
for (axis = LIBINPUT_TABLET_TOOL_AXIS_X;
|
||||
axis <= LIBINPUT_TABLET_TOOL_AXIS_MAX;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ struct tablet_dispatch {
|
|||
unsigned int index;
|
||||
unsigned int count;
|
||||
struct tablet_axes samples[TABLET_HISTORY_LENGTH];
|
||||
size_t size;
|
||||
} history;
|
||||
|
||||
unsigned char axis_caps[NCHARS(LIBINPUT_TABLET_TOOL_AXIS_MAX + 1)];
|
||||
|
|
|
|||
|
|
@ -5988,6 +5988,86 @@ START_TEST(huion_static_btn_tool_pen_disable_quirk_on_prox_out)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(tablet_smoothing)
|
||||
{
|
||||
#if HAVE_LIBWACOM
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
double x, y;
|
||||
struct point {
|
||||
double x, y;
|
||||
} coordinates[100];
|
||||
size_t npoints = 0;
|
||||
size_t idx = 0;
|
||||
struct axis_replacement axes[] = {
|
||||
{ ABS_DISTANCE, 10 },
|
||||
{ ABS_PRESSURE, 0 },
|
||||
{ -1, -1 }
|
||||
};
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
litest_tablet_proximity_in(dev, 10, 10, axes);
|
||||
libinput_dispatch(li);
|
||||
litest_drain_events(li);
|
||||
|
||||
/* Move in a straight line, collect the resulting points */
|
||||
for (x = 11, y = 11; x < 50; x++, y++) {
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_tablet_tool *tev;
|
||||
struct point *p = &coordinates[npoints++];
|
||||
|
||||
litest_assert(npoints <= ARRAY_LENGTH(coordinates));
|
||||
|
||||
litest_tablet_motion(dev, x, y, axes);
|
||||
libinput_dispatch(li);
|
||||
|
||||
event = libinput_get_event(li);
|
||||
tev = litest_is_tablet_event(event,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_AXIS);
|
||||
p->x = libinput_event_tablet_tool_get_x(tev);
|
||||
p->y = libinput_event_tablet_tool_get_y(tev);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
|
||||
litest_tablet_proximity_out(dev);
|
||||
litest_tablet_proximity_in(dev, 10, 10, axes);
|
||||
libinput_dispatch(li);
|
||||
litest_drain_events(li);
|
||||
|
||||
/* Move in a wobbly line, collect every second point */
|
||||
for (x = 11, y = 11; x < 50; x++, y++) {
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_tablet_tool *tev;
|
||||
double ex, ey;
|
||||
struct point *p = &coordinates[idx++];
|
||||
|
||||
litest_assert(idx <= npoints);
|
||||
|
||||
/* point off position */
|
||||
litest_tablet_motion(dev, x - 2, y + 1, axes);
|
||||
libinput_dispatch(li);
|
||||
event = libinput_get_event(li);
|
||||
litest_is_tablet_event(event, LIBINPUT_EVENT_TABLET_TOOL_AXIS);
|
||||
libinput_event_destroy(event);
|
||||
|
||||
/* same position as before */
|
||||
litest_tablet_motion(dev, x, y, axes);
|
||||
libinput_dispatch(li);
|
||||
event = libinput_get_event(li);
|
||||
tev = litest_is_tablet_event(event,
|
||||
LIBINPUT_EVENT_TABLET_TOOL_AXIS);
|
||||
ex = libinput_event_tablet_tool_get_x(tev);
|
||||
ey = libinput_event_tablet_tool_get_y(tev);
|
||||
|
||||
ck_assert_double_eq(ex, p->x);
|
||||
ck_assert_double_eq(ey, p->y);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
END_TEST
|
||||
|
||||
TEST_COLLECTION(tablet)
|
||||
{
|
||||
struct range with_timeout = { 0, 2 };
|
||||
|
|
@ -6112,4 +6192,6 @@ TEST_COLLECTION(tablet)
|
|||
litest_add_for_device("tablet:quirks", huion_static_btn_tool_pen, LITEST_HUION_TABLET);
|
||||
litest_add_for_device("tablet:quirks", huion_static_btn_tool_pen_no_timeout_during_usage, LITEST_HUION_TABLET);
|
||||
litest_add_ranged_for_device("tablet:quirks", huion_static_btn_tool_pen_disable_quirk_on_prox_out, LITEST_HUION_TABLET, &with_timeout);
|
||||
|
||||
litest_add_for_device("tablet:smoothing", tablet_smoothing, LITEST_WACOM_HID4800_PEN);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue