[PATCH libinput] tablet: change tilt axes to use degrees
Peter Hutterer
peter.hutterer at who-t.net
Tue Feb 9 02:18:24 UTC 2016
On Mon, Feb 08, 2016 at 05:01:11PM -0800, Jason Gerecke wrote:
> 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?
urgh. I have no idea how this happened... You're correct, they're aligned,
I've fixed the two instances and the tests to expect the real thing. Thanks
for the review.
Cheers,
Peter
>
> > }
> >
> > 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