summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2016-06-21 15:20:08 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2016-06-28 11:28:49 +1000
commit0926f570c448b4d321e23e075f0ad3032c56b92a (patch)
tree9f3551e528795ca3da1c04fd4262c8890ed7c356 /src
parent97cec18d2755b287d1f65cae88138b19cc5fff4e (diff)
tablet: make the cursor/lens tool behave like a 1000dpi mouse
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@who-t.net> Reviewed-by: Jason Gerecke <jason.gerecke@wacom.com> Reviewed-by: Carlos Garnacho <carlosg@gnome.org>
Diffstat (limited to 'src')
-rw-r--r--src/evdev-tablet.c19
-rw-r--r--src/filter.c80
2 files changed, 79 insertions, 20 deletions
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 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;
}