[PATCH libinput] tablet: change tilt axes to use degrees
Jason Gerecke
killertofu at gmail.com
Tue Feb 9 01:01:11 UTC 2016
On Tue, Feb 2, 2016 at 2:59 PM, Peter Hutterer <peter.hutterer at who-t.net> wrote:
> The Wacom tilt range is 64 degrees so we map everything into that until we
> know otherwise.
>
> This commit also switches the tilt axes around to align the angles with the
> x/y orientation, i.e. tilting the top of the stylus towards the positive x
> axis now generates a positive x tilt.
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
> doc/tablet-support.dox | 12 ++++++++----
> src/evdev-tablet.c | 28 +++++++++++++++++++--------
> src/libinput-private.h | 7 ++++++-
> src/libinput.h | 16 ++++++++++++----
> test/tablet.c | 52 +++++++++++++++++++++++++-------------------------
> 5 files changed, 72 insertions(+), 43 deletions(-)
>
> diff --git a/doc/tablet-support.dox b/doc/tablet-support.dox
> index cc5d409..ff4e460 100644
> --- a/doc/tablet-support.dox
> +++ b/doc/tablet-support.dox
> @@ -83,15 +83,19 @@ additionally provide tilt information along the x and y axis.
>
> @image html tablet-axes.svg "Illustration of the distance, pressure and tilt axes"
>
> -The granularity and precision of these axes varies between tablet devices
> -and cannot usually be mapped into a physical unit.
> -libinput normalizes distance and pressure into the [0, 1] range and the tilt
> -axes into the [-1, 1] range with 0 as the neutral point.
> +The granularity and precision of the distance and pressure axes varies
> +between tablet devices and cannot usually be mapped into a physical unit.
> +libinput normalizes distance and pressure into the [0, 1] range.
>
> While the normalization range is identical for these axes, a caller should
> not interpret identical values as identical across axes, i.e. a value v1 on
> the distance axis has no relation to the same value v1 on the pressure axis.
>
> +The tilt axes provide the angle in degrees between a vertical line out of
> +the tablet and the top of the stylus. The angle is measured along the x and
> +y axis, respectively, a positive tilt angle thus means that the stylus' top
> +is tilted towards the logical right and/or bottom of the tablet.
> +
> @section tablet-fake-proximity Handling of proximity events
>
> libinput's @ref LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY events notify a caller
> diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
> index e684055..2157dfc 100644
> --- a/src/evdev-tablet.c
> +++ b/src/evdev-tablet.c
> @@ -225,13 +225,25 @@ normalize_pressure(const struct input_absinfo *absinfo,
> }
>
> static inline double
> -normalize_tilt(const struct input_absinfo *absinfo)
> +adjust_tilt(const struct input_absinfo *absinfo)
> {
> double range = absinfo->maximum - absinfo->minimum;
> double value = (absinfo->value - absinfo->minimum) / range;
> + const int WACOM_MAX_DEGREES = 64;
>
> /* Map to the (-1, 1) range */
> - return (value * 2) - 1;
> + value = (value * 2) - 1;
> +
> + /* Wacom supports physical [-64, 64] degrees, so map to that by
> + * default. If other tablets have a different physical range or
> + * nonzero physical offsets, they need extra treatment
> + * here.
> + *
> + * And invert because we flip the axes to align with the x/y
> + * positive direction.
> + */
> +
> + return value * WACOM_MAX_DEGREES * -1;
The axes should already be aligned to positive X/Y, so I'm not sure
what this is about. Watching the output from evemu-record, tilt values
are positive for right/down and negative for left/up. Am I missing
something?
> }
>
> static inline int32_t
> @@ -251,8 +263,8 @@ convert_tilt_to_rotation(struct tablet_dispatch *tablet)
> values. The device has a 175 degree CCW hardware offset but since we use
> atan2 the effective offset is just 5 degrees.
> */
> - x = tablet->axes.tilt.x;
> - y = tablet->axes.tilt.y;
> + x = -tablet->axes.tilt.x;
> + y = -tablet->axes.tilt.y;
Ditto.
Otherwise,
Reviewed-by: Jason Gerecke <jason.gerecke at wacom.com>
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....
> clear_bit(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_TILT_X);
> clear_bit(tablet->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_TILT_Y);
>
> @@ -398,17 +410,17 @@ tablet_handle_slider(struct tablet_dispatch *tablet,
> return tablet->axes.slider;
> }
>
> -static inline struct normalized_range_coords
> +static inline struct tilt_degrees
> tablet_handle_tilt(struct tablet_dispatch *tablet,
> struct evdev_device *device)
> {
> - struct normalized_range_coords tilt;
> + struct tilt_degrees tilt;
> const struct input_absinfo *absinfo;
>
> if (bit_is_set(tablet->changed_axes,
> LIBINPUT_TABLET_TOOL_AXIS_TILT_X)) {
> absinfo = libevdev_get_abs_info(device->evdev, ABS_TILT_X);
> - tablet->axes.tilt.x = normalize_tilt(absinfo);
> + tablet->axes.tilt.x = adjust_tilt(absinfo);
> if (device->left_handed.enabled)
> tablet->axes.tilt.x *= -1;
> }
> @@ -417,7 +429,7 @@ tablet_handle_tilt(struct tablet_dispatch *tablet,
> if (bit_is_set(tablet->changed_axes,
> LIBINPUT_TABLET_TOOL_AXIS_TILT_Y)) {
> absinfo = libevdev_get_abs_info(device->evdev, ABS_TILT_Y);
> - tablet->axes.tilt.y = normalize_tilt(absinfo);
> + tablet->axes.tilt.y = adjust_tilt(absinfo);
> if (device->left_handed.enabled)
> tablet->axes.tilt.y *= -1;
> }
> diff --git a/src/libinput-private.h b/src/libinput-private.h
> index bc7000d..8d2492a 100644
> --- a/src/libinput-private.h
> +++ b/src/libinput-private.h
> @@ -63,6 +63,11 @@ struct normalized_range_coords {
> double x, y;
> };
>
> +/* A pair of angles in degrees */
> +struct tilt_degrees {
> + double x, y;
> +};
> +
> /* A threshold with an upper and lower limit */
> struct threshold {
> int upper;
> @@ -74,7 +79,7 @@ struct tablet_axes {
> struct normalized_coords delta;
> double distance;
> double pressure;
> - struct normalized_range_coords tilt;
> + struct tilt_degrees tilt;
> double rotation;
> double slider;
> double wheel;
> diff --git a/src/libinput.h b/src/libinput.h
> index 8ed5632..0b6fbc4 100644
> --- a/src/libinput.h
> +++ b/src/libinput.h
> @@ -1646,12 +1646,16 @@ libinput_event_tablet_tool_get_distance(struct libinput_event_tablet_tool *event
> * @ingroup event_tablet
> *
> * Returns the current tilt along the X axis of the tablet's current logical
> - * orientation, normalized to the range [-1, 1].
> + * orientation, in degrees off the tablet's z axis. That is, if the tool is
> + * perfectly orthogonal to the tablet, the tilt angle is 0. When the top
> + * tilts towards the logical top/left of the tablet, the x/y tilt angles are
> + * negative, if the top tilts towards the logical bottom/right of the
> + * tablet, the x/y tilt angles are positive.
> *
> * If this axis does not exist on the current tool, this function returns 0.
> *
> * @param event The libinput tablet event
> - * @return The current value of the the axis
> + * @return The current value of the the axis in degrees
> */
> double
> libinput_event_tablet_tool_get_tilt_x(struct libinput_event_tablet_tool *event);
> @@ -1660,12 +1664,16 @@ libinput_event_tablet_tool_get_tilt_x(struct libinput_event_tablet_tool *event);
> * @ingroup event_tablet
> *
> * Returns the current tilt along the Y axis of the tablet's current logical
> - * orientation, normalized to the range [-1, 1].
> + * orientation, in degrees off the tablet's z axis. That is, if the tool is
> + * perfectly orthogonal to the tablet, the tilt angle is 0. When the top
> + * tilts towards the logical top/left of the tablet, the x/y tilt angles are
> + * negative, if the top tilts towards the logical bottom/right of the
> + * tablet, the x/y tilt angles are positive.
> *
> * If this axis does not exist on the current tool, this function returns 0.
> *
> * @param event The libinput tablet event
> - * @return The current value of the the axis
> + * @return The current value of the the axis in degrees
> */
> double
> libinput_event_tablet_tool_get_tilt_y(struct libinput_event_tablet_tool *event);
> diff --git a/test/tablet.c b/test/tablet.c
> index 8936d57..a09deb2 100644
> --- a/test/tablet.c
> +++ b/test/tablet.c
> @@ -1415,8 +1415,8 @@ START_TEST(left_handed_tilt)
> tx = libinput_event_tablet_tool_get_tilt_x(tev);
> ty = libinput_event_tablet_tool_get_tilt_y(tev);
>
> - ck_assert_double_lt(tx, 0);
> - ck_assert_double_gt(ty, 0);
> + ck_assert_double_gt(tx, 0);
> + ck_assert_double_lt(ty, 0);
>
> libinput_event_destroy(event);
> #endif
> @@ -3097,19 +3097,18 @@ START_TEST(tilt_x)
> tev = litest_is_tablet_event(event,
> LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
>
> - /* 90% of the actual axis but mapped into a [-1, 1] range, so we
> - * expect a pos. value of 80. Rounding errors in the scaling though,
> - * we'll get something between 0.79 and 0.80 */
> + /* 90% of the actual axis but mapped into a [-64, 64] tilt range, so
> + * we expect 50 degrees ą rounding errors */
> tx = libinput_event_tablet_tool_get_tilt_x(tev);
> - ck_assert_double_gt(tx, 0.79);
> - ck_assert_double_le(tx, 0.80);
> + ck_assert_double_le(tx, -50);
> + ck_assert_double_ge(tx, -51);
>
> ty = libinput_event_tablet_tool_get_tilt_y(tev);
> - ck_assert_double_eq(ty, -1);
> + ck_assert_double_eq(ty, 64);
>
> libinput_event_destroy(event);
>
> - expected_tx = -1.0;
> + expected_tx = 64.0;
>
> litest_axis_set_value(axes, ABS_DISTANCE, 0);
> litest_axis_set_value(axes, ABS_PRESSURE, 1);
> @@ -3123,19 +3122,20 @@ START_TEST(tilt_x)
> LIBINPUT_EVENT_TABLET_TOOL_AXIS);
>
> tx = libinput_event_tablet_tool_get_tilt_x(tev);
> - ck_assert_double_gt(tx, expected_tx - 0.1);
> - ck_assert_double_lt(tx, expected_tx + 0.1);
> + ck_assert_double_ge(tx, expected_tx - 1);
> + ck_assert_double_le(tx, expected_tx + 1);
>
> ty = libinput_event_tablet_tool_get_tilt_y(tev);
> - ck_assert_double_eq(ty, -1);
> + ck_assert_double_eq(ty, 64);
>
> libinput_event_destroy(event);
>
> - expected_tx += 0.1;
> + expected_tx = tx - 6;
> }
>
> /* the last event must reach the max */
> - ck_assert_double_eq(tx, 1.0);
> + ck_assert_double_le(tx, -63.0);
> + ck_assert_double_ge(tx, -64.0);
> }
> END_TEST
>
> @@ -3164,19 +3164,18 @@ START_TEST(tilt_y)
> tev = litest_is_tablet_event(event,
> LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
>
> - /* 90% of the actual axis but mapped into a [-1, 1] range, so we
> - * expect a pos. value of 80. Rounding errors in the scaling though,
> - * we'll get something between 0.79 and 0.80 */
> + /* 90% of the actual axis but mapped into a [-64, 64] tilt range, so
> + * we expect 50 degrees ą rounding errors */
> ty = libinput_event_tablet_tool_get_tilt_y(tev);
> - ck_assert_double_gt(ty, 0.79);
> - ck_assert_double_le(ty, 0.80);
> + ck_assert_double_le(ty, -50);
> + ck_assert_double_ge(ty, -51);
>
> tx = libinput_event_tablet_tool_get_tilt_x(tev);
> - ck_assert_double_eq(tx, -1);
> + ck_assert_double_eq(tx, 64);
>
> libinput_event_destroy(event);
>
> - expected_ty = -1.0;
> + expected_ty = 64;
>
> litest_axis_set_value(axes, ABS_DISTANCE, 0);
> litest_axis_set_value(axes, ABS_PRESSURE, 1);
> @@ -3190,19 +3189,20 @@ START_TEST(tilt_y)
> LIBINPUT_EVENT_TABLET_TOOL_AXIS);
>
> ty = libinput_event_tablet_tool_get_tilt_y(tev);
> - ck_assert_double_gt(ty, expected_ty - 0.1);
> - ck_assert_double_lt(ty, expected_ty + 0.1);
> + ck_assert_double_ge(ty, expected_ty - 1);
> + ck_assert_double_le(ty, expected_ty + 1);
>
> tx = libinput_event_tablet_tool_get_tilt_x(tev);
> - ck_assert_double_eq(tx, -1);
> + ck_assert_double_eq(tx, 64);
>
> libinput_event_destroy(event);
>
> - expected_ty += 0.1;
> + expected_ty = ty - 6;
> }
>
> /* the last event must reach the max */
> - ck_assert_double_eq(ty, 1.0);
> + ck_assert_double_le(ty, -63.0);
> + ck_assert_double_ge(tx, -64.0);
> }
> END_TEST
>
> --
> 2.5.0
>
More information about the wayland-devel
mailing list