[PATCH libinput] tablet: make the cursor/lens tool behave like a 1000dpi mouse
Jason Gerecke
killertofu at gmail.com
Mon Jun 27 19:54:55 UTC 2016
On 06/26/2016 09:53 PM, Peter Hutterer wrote:
> The current code tried to emulate the relative motion to be equivalent to the
> absolute motion, except in screen coordinates. This is way too slow for the
> cursor tool that we want to behave like a mouse.
>
> Tablets have high resolution (e.g. an Intuos 4 is a 5080dpi mouse) and that
> motion is way too fast to be usable. Scale it down to match a 1000dpi device
> instead. Since the cursor and lens tool are still high precision devices leave
> them in a flat acceleration profile without actual acceleration.
>
> For the stylus-like devices leave the current accel, pointer acceleration on a
> stylus is hard to handle.
>
> This also adds the missing bits for actually using the speed factor set
> through the config interface.
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
Looks good to me --
Reviewed-by: Jason Gerecke <jason.gerecke at wacom.com>
> ---
> src/evdev-tablet.c | 19 +++++++------
> src/filter.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++--------
> tools/Makefile.am | 2 +-
> 3 files changed, 80 insertions(+), 21 deletions(-)
>
> diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
> index 395e5a0..940a1e0 100644
> --- a/src/evdev-tablet.c
> +++ b/src/evdev-tablet.c
> @@ -386,22 +386,23 @@ tablet_handle_xy(struct tablet_dispatch *tablet,
> }
>
> static inline struct normalized_coords
> -tablet_process_delta(struct tablet_dispatch *tablet,
> - const struct evdev_device *device,
> - const struct device_coords *delta,
> - uint64_t time)
> +tool_process_delta(struct libinput_tablet_tool *tool,
> + const struct evdev_device *device,
> + const struct device_coords *delta,
> + uint64_t time)
> {
> struct normalized_coords accel;
>
> - /* The tablet accel code uses mm as input */
> - accel.x = 1.0 * delta->x/device->abs.absinfo_x->resolution;
> - accel.y = 1.0 * delta->y/device->abs.absinfo_y->resolution;
> + accel.x = 1.0 * delta->x;
> + accel.y = 1.0 * delta->y;
>
> if (normalized_is_zero(accel))
> return accel;
>
> return filter_dispatch(device->pointer.filter,
> - &accel, tablet, time);
> + &accel,
> + tool,
> + time);
> }
>
> static inline double
> @@ -548,7 +549,7 @@ tablet_check_notify_axes(struct tablet_dispatch *tablet,
> axes.distance = tablet_handle_distance(tablet, device);
> axes.slider = tablet_handle_slider(tablet, device);
> axes.tilt = tablet_handle_tilt(tablet, device);
> - axes.delta = tablet_process_delta(tablet, device, &delta, time);
> + axes.delta = tool_process_delta(tool, device, &delta, time);
>
> /* We must check ROTATION_Z after TILT_X/Y so that the tilt axes are
> * already normalized and set if we have the mouse/lens tool */
> diff --git a/src/filter.c b/src/filter.c
> index cf8996d..0bb066c 100644
> --- a/src/filter.c
> +++ b/src/filter.c
> @@ -168,6 +168,8 @@ struct tablet_accelerator_flat {
>
> double factor;
> int xres, yres;
> + double xres_scale, /* 1000dpi : tablet res */
> + yres_scale; /* 1000dpi : tablet res */
> };
>
> static void
> @@ -972,17 +974,39 @@ create_pointer_accelerator_filter_flat(int dpi)
> return &filter->base;
> }
>
> -/* The tablet accel code uses mm as input */
> +static inline struct normalized_coords
> +tablet_accelerator_filter_flat_mouse(struct tablet_accelerator_flat *filter,
> + const struct normalized_coords *units)
> +{
> + struct normalized_coords accelerated;
> +
> + /*
> + The input for and output of accel methods is usually a delta in
> + 1000dpi equivalents. Tablets are high res (Intuos 4 is 5080 dpi)
> + and unmodified deltas are way too high. Slow it down to the
> + equivalent of a 1000dpi mouse. The ratio of that is:
> + ratio = 1000/(resolution_per_mm * 25.4)
> +
> + i.e. on the Intuos4 it's a ratio of ~1/5.
> +
> + */
> +
> + accelerated.x = units->x * filter->xres_scale;
> + accelerated.y = units->y * filter->yres_scale;
> +
> + accelerated.x *= filter->factor;
> + accelerated.y *= filter->factor;
> +
> + return accelerated;
> +}
> +
> static struct normalized_coords
> -tablet_accelerator_filter_flat(struct motion_filter *filter,
> - const struct normalized_coords *mm,
> - void *data, uint64_t time)
> +tablet_accelerator_filter_flat_pen(struct tablet_accelerator_flat *filter,
> + const struct normalized_coords *units)
> {
> - struct tablet_accelerator_flat *accel_filter =
> - (struct tablet_accelerator_flat *)filter;
> struct normalized_coords accelerated;
>
> - /* Tablet input is in mm, output is supposed to be in logical
> + /* Tablet input is in device units, output is supposed to be in logical
> * pixels roughly equivalent to a mouse/touchpad.
> *
> * This is a magical constant found by trial and error. On a 96dpi
> @@ -990,12 +1014,43 @@ tablet_accelerator_filter_flat(struct motion_filter *filter,
> * is almost identical to the tablet mapped to screen in absolute
> * mode. Tested on a Intuos5, other tablets may vary.
> */
> - const double DPI_CONVERSION = 96.0/25.4 * 2.5; /* unitless factor */
> + const double DPI_CONVERSION = 96.0/25.4 * 2.5; /* unitless factor */
> + struct normalized_coords mm;
>
> - accelerated.x = mm->x * accel_filter->factor * DPI_CONVERSION;
> - accelerated.y = mm->y * accel_filter->factor * DPI_CONVERSION;
> + mm.x = 1.0 * units->x/filter->xres;
> + mm.y = 1.0 * units->y/filter->yres;
> + accelerated.x = mm.x * filter->factor * DPI_CONVERSION;
> + accelerated.y = mm.y * filter->factor * DPI_CONVERSION;
>
> - return accelerated;
> + return accelerated;
> +}
> +
> +static struct normalized_coords
> +tablet_accelerator_filter_flat(struct motion_filter *filter,
> + const struct normalized_coords *units,
> + void *data, uint64_t time)
> +{
> + struct tablet_accelerator_flat *accel_filter =
> + (struct tablet_accelerator_flat *)filter;
> + struct libinput_tablet_tool *tool = (struct libinput_tablet_tool*)data;
> + enum libinput_tablet_tool_type type;
> + struct normalized_coords accel;
> +
> + type = libinput_tablet_tool_get_type(tool);
> +
> + switch (type) {
> + case LIBINPUT_TABLET_TOOL_TYPE_MOUSE:
> + case LIBINPUT_TABLET_TOOL_TYPE_LENS:
> + accel = tablet_accelerator_filter_flat_mouse(accel_filter,
> + units);
> + break;
> + default:
> + accel = tablet_accelerator_filter_flat_pen(accel_filter,
> + units);
> + break;
> + }
> +
> + return accel;
> }
>
> static bool
> @@ -1039,8 +1094,11 @@ create_tablet_filter_flat(int xres, int yres)
> if (filter == NULL)
> return NULL;
>
> + filter->factor = 1.0;
> filter->xres = xres;
> filter->yres = yres;
> + filter->xres_scale = DEFAULT_MOUSE_DPI/(25.4 * xres);
> + filter->yres_scale = DEFAULT_MOUSE_DPI/(25.4 * yres);
>
> return filter;
> }
> diff --git a/tools/Makefile.am b/tools/Makefile.am
> index 8f72db9..5fe169c 100644
> --- a/tools/Makefile.am
> +++ b/tools/Makefile.am
> @@ -18,7 +18,7 @@ event_debug_LDFLAGS = -no-install
> event_debug_CFLAGS = $(LIBUDEV_CFLAGS) $(LIBEVDEV_CFLAGS)
>
> ptraccel_debug_SOURCES = ptraccel-debug.c
> -ptraccel_debug_LDADD = ../src/libfilter.la
> +ptraccel_debug_LDADD = ../src/libfilter.la ../src/libinput.la
> ptraccel_debug_LDFLAGS = -no-install
>
> libinput_list_devices_SOURCES = libinput-list-devices.c
>
--
Jason
---
Now instead of four in the eights place /
you’ve got three, ‘Cause you added one /
(That is to say, eight) to the two, /
But you can’t take seven from three, /
So you look at the sixty-fours....
More information about the wayland-devel
mailing list