summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/tablet-support.dox12
-rw-r--r--src/evdev-tablet.c21
-rw-r--r--src/libinput-private.h7
-rw-r--r--src/libinput.h16
-rw-r--r--test/tablet.c52
5 files changed, 67 insertions, 41 deletions
diff --git a/doc/tablet-support.dox b/doc/tablet-support.dox
index cc5d4091..ff4e4607 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 e684055b..9fd98403 100644
--- a/src/evdev-tablet.c
+++ b/src/evdev-tablet.c
@@ -225,13 +225,22 @@ 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.
+ */
+
+ return value * WACOM_MAX_DEGREES;
}
static inline int32_t
@@ -398,17 +407,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 +426,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 bc7000d7..8d2492aa 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 d808c162..b14c2811 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -1648,12 +1648,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 tool 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);
@@ -1662,12 +1666,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 tool 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 8936d577..bd4172dd 100644
--- a/test/tablet.c
+++ b/test/tablet.c
@@ -3081,7 +3081,7 @@ START_TEST(tilt_x)
struct axis_replacement axes[] = {
{ ABS_DISTANCE, 10 },
{ ABS_PRESSURE, 0 },
- { ABS_TILT_X, 90 },
+ { ABS_TILT_X, 10 },
{ ABS_TILT_Y, 0 },
{ -1, -1 }
};
@@ -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 51 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, -52);
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 - 2);
+ ck_assert_double_le(tx, expected_tx + 2);
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.04;
}
/* the last event must reach the max */
- ck_assert_double_eq(tx, 1.0);
+ ck_assert_double_ge(tx, 63.0);
+ ck_assert_double_le(tx, 64.0);
}
END_TEST
@@ -3149,7 +3149,7 @@ START_TEST(tilt_y)
{ ABS_DISTANCE, 10 },
{ ABS_PRESSURE, 0 },
{ ABS_TILT_X, 0 },
- { ABS_TILT_Y, 90 },
+ { ABS_TILT_Y, 10 },
{ -1, -1 }
};
double tx, ty;
@@ -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, -52);
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 - 2);
+ ck_assert_double_le(ty, expected_ty + 2);
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_ge(ty, 63.0);
+ ck_assert_double_le(tx, 64.0);
}
END_TEST