[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