diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c index 395e5a0f..940a1e06 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 cf8996dd..0bb066c9 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 struct normalized_coords -tablet_accelerator_filter_flat(struct motion_filter *filter, - const struct normalized_coords *mm, - void *data, uint64_t time) +static inline struct normalized_coords +tablet_accelerator_filter_flat_mouse(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 + /* + 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_pen(struct tablet_accelerator_flat *filter, + const struct normalized_coords *units) +{ + struct normalized_coords accelerated; + + /* 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 8f72db99..5fe169cd 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