[PATCH libinput 21/26] tablet: support artpen rotation
Peter Hutterer
peter.hutterer at who-t.net
Wed Feb 25 20:32:02 PST 2015
On Wed, Feb 25, 2015 at 05:30:21PM -0800, Jason Gerecke wrote:
>
> On 2/23/2015 10:21 PM, Peter Hutterer wrote:
> >Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> >---
> > src/evdev-tablet.c | 35 +++++++++++++++-----
> > src/evdev-tablet.h | 6 ++++
> > src/libinput.h | 3 +-
> > test/tablet.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > 4 files changed, 130 insertions(+), 9 deletions(-)
> >
> >diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
> >index 143d618..d05b6c2 100644
> >--- a/src/evdev-tablet.c
> >+++ b/src/evdev-tablet.c
> >@@ -103,6 +103,7 @@ tablet_process_absolute(struct tablet_dispatch *tablet,
> > switch (e->code) {
> > case ABS_X:
> > case ABS_Y:
> >+ case ABS_Z:
> > case ABS_PRESSURE:
> > case ABS_TILT_X:
> > case ABS_TILT_Y:
> >@@ -240,6 +241,16 @@ convert_tilt_to_rotation(struct tablet_dispatch *tablet)
> > set_bit(tablet->changed_axes, LIBINPUT_TABLET_AXIS_ROTATION_Z);
> > }
> >+static double
> >+convert_to_degrees(const struct input_absinfo *absinfo, double offset)
> >+{
> >+ /* range is [0, 360[, i.e. range + 1 */
> >+ double range = absinfo->maximum - absinfo->minimum + 1;
> >+ double value = (absinfo->value - absinfo->minimum) / range;
> >+
> >+ return fmod(value * 360.0 + offset, 360.0);
> >+}
> >+
> > static void
> > tablet_check_notify_axes(struct tablet_dispatch *tablet,
> > struct evdev_device *device,
> >@@ -263,14 +274,13 @@ tablet_check_notify_axes(struct tablet_dispatch *tablet,
> > /* ROTATION_Z is higher than TILT_X/Y so we know that the
> > tilt axes are already normalized and set */
> >- if (a == LIBINPUT_TABLET_AXIS_ROTATION_Z) {
> >- if (tablet->current_tool_type == LIBINPUT_TOOL_MOUSE ||
> >- tablet->current_tool_type == LIBINPUT_TOOL_LENS) {
> >- convert_tilt_to_rotation(tablet);
> >- axes[LIBINPUT_TABLET_AXIS_TILT_X] = 0;
> >- axes[LIBINPUT_TABLET_AXIS_TILT_Y] = 0;
> >- axes[a] = tablet->axes[a];
> >- }
> >+ if (a == LIBINPUT_TABLET_AXIS_ROTATION_Z &&
> >+ (tablet->current_tool_type == LIBINPUT_TOOL_MOUSE ||
> >+ tablet->current_tool_type == LIBINPUT_TOOL_LENS)) {
> >+ convert_tilt_to_rotation(tablet);
> >+ axes[LIBINPUT_TABLET_AXIS_TILT_X] = 0;
> >+ axes[LIBINPUT_TABLET_AXIS_TILT_Y] = 0;
> >+ axes[a] = tablet->axes[a];
> Nitpick: Squash into patch 19 ("support z-rotation for the mouse/lens tool")
If you don't mind I'd rather leave it as-is. the logic changes because of
the introduction of the new axis - before we'd 'continue' for any rotation
axis and only process for the mouse, now we changed to only 'continue'
process rotation on the mouse/lens cursor. subtle, but triggered a few
aborts during development which is why i separated it this way.
Cheers,
Peter
> > continue;
> > }
> >@@ -294,6 +304,10 @@ tablet_check_notify_axes(struct tablet_dispatch *tablet,
> > case LIBINPUT_TABLET_AXIS_TILT_Y:
> > tablet->axes[a] = normalize_tilt(absinfo);
> > break;
> >+ case LIBINPUT_TABLET_AXIS_ROTATION_Z:
> >+ /* artpen has 0 with buttons pointing east */
> >+ tablet->axes[a] = convert_to_degrees(absinfo, 90);
> >+ break;
> > default:
> > log_bug_libinput(device->base.seat->libinput,
> > "Invalid axis update: %d\n", a);
> >@@ -506,6 +520,10 @@ tool_set_bits_from_libwacom(const struct tablet_dispatch *tablet,
> > copy_axis_cap(tablet, tool, LIBINPUT_TABLET_AXIS_SLIDER);
> > /* fall-through */
> > case WSTYLUS_MARKER:
> >+ if (type == WSTYLUS_MARKER)
> >+ copy_axis_cap(tablet, tool,
> >+ LIBINPUT_TABLET_AXIS_ROTATION_Z);
> >+ /* fallthrough */
> > case WSTYLUS_GENERAL:
> > case WSTYLUS_INKING:
> > case WSTYLUS_CLASSIC:
> >@@ -555,6 +573,7 @@ tool_set_bits(const struct tablet_dispatch *tablet,
> > copy_axis_cap(tablet, tool, LIBINPUT_TABLET_AXIS_TILT_X);
> > copy_axis_cap(tablet, tool, LIBINPUT_TABLET_AXIS_TILT_Y);
> > copy_axis_cap(tablet, tool, LIBINPUT_TABLET_AXIS_SLIDER);
> >+ copy_axis_cap(tablet, tool, LIBINPUT_TABLET_AXIS_ROTATION_Z);
> > break;
> > case LIBINPUT_TOOL_MOUSE:
> > case LIBINPUT_TOOL_LENS:
> >diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h
> >index d86bf9e..7c472cf 100644
> >--- a/src/evdev-tablet.h
> >+++ b/src/evdev-tablet.h
> >@@ -75,6 +75,9 @@ evcode_to_axis(const uint32_t evcode)
> > case ABS_Y:
> > axis = LIBINPUT_TABLET_AXIS_Y;
> > break;
> >+ case ABS_Z:
> >+ axis = LIBINPUT_TABLET_AXIS_ROTATION_Z;
> >+ break;
> > case ABS_DISTANCE:
> > axis = LIBINPUT_TABLET_AXIS_DISTANCE;
> > break;
> >@@ -122,6 +125,9 @@ axis_to_evcode(const enum libinput_tablet_axis axis)
> > case LIBINPUT_TABLET_AXIS_TILT_Y:
> > evcode = ABS_TILT_Y;
> > break;
> >+ case LIBINPUT_TABLET_AXIS_ROTATION_Z:
> >+ evcode = ABS_Z;
> >+ break;
> > case LIBINPUT_TABLET_AXIS_SLIDER:
> > evcode = ABS_WHEEL;
> > break;
> >diff --git a/src/libinput.h b/src/libinput.h
> >index fb6b803..87d220b 100644
> >--- a/src/libinput.h
> >+++ b/src/libinput.h
> >@@ -1056,7 +1056,8 @@ libinput_event_tablet_axis_has_changed(struct libinput_event_tablet *event,
> > * degrees, clockwise from the tool's logical neutral position. For the
> > * @ref LIBINPUT_TOOL_MOUSE and @ref LIBINPUT_TOOL_LENS tools the logical
> > * neutral position is pointing to the current logical north of the
> >- * tablet.
> >+ * tablet. For the @ref LIBINPUT_TOOL_BRUSH tool, the logical neutral
> >+ * position is with the buttons pointing up.
> > * - @ref LIBINPUT_TABLET_AXIS_SLIDER - A slider on the tool, normalized
> > * from 0 to 1. e.g. the wheel-like tool on the Wacom Airbrush.
> > *
> >diff --git a/test/tablet.c b/test/tablet.c
> >index fef4fc5..afc654e 100644
> >--- a/test/tablet.c
> >+++ b/test/tablet.c
> >@@ -1359,6 +1359,99 @@ START_TEST(airbrush_wheel)
> > }
> > END_TEST
> >+START_TEST(artpen_tool)
> >+{
> >+ struct litest_device *dev = litest_current_device();
> >+ struct libinput *li = dev->libinput;
> >+ struct libinput_event *event;
> >+ struct libinput_event_tablet *tev;
> >+ struct libinput_tool *tool;
> >+
> >+ if (!libevdev_has_event_code(dev->evdev,
> >+ EV_ABS,
> >+ ABS_Z))
> >+ return;
> >+
> >+ litest_drain_events(li);
> >+
> >+ litest_event(dev, EV_KEY, BTN_TOOL_PEN, 1);
> >+ litest_event(dev, EV_ABS, ABS_MISC, 0x804); /* Art Pen */
> >+ litest_event(dev, EV_MSC, MSC_SERIAL, 1000);
> >+ litest_event(dev, EV_SYN, SYN_REPORT, 0);
> >+
> >+ litest_wait_for_event_of_type(li,
> >+ LIBINPUT_EVENT_TABLET_PROXIMITY,
> >+ -1);
> >+ event = libinput_get_event(li);
> >+ tev = libinput_event_get_tablet_event(event);
> >+ tool = libinput_event_tablet_get_tool(tev);
> >+ ck_assert_notnull(tool);
> >+ ck_assert_int_eq(libinput_tool_get_type(tool),
> >+ LIBINPUT_TOOL_PEN);
> >+ ck_assert(libinput_tool_has_axis(tool,
> >+ LIBINPUT_TABLET_AXIS_ROTATION_Z));
> >+
> >+ libinput_event_destroy(event);
> >+}
> >+END_TEST
> >+
> >+START_TEST(artpen_rotation)
> >+{
> >+ struct litest_device *dev = litest_current_device();
> >+ struct libinput *li = dev->libinput;
> >+ struct libinput_event *event;
> >+ struct libinput_event_tablet *tev;
> >+ const struct input_absinfo *abs;
> >+ double val;
> >+ double scale;
> >+ int angle;
> >+
> >+ if (!libevdev_has_event_code(dev->evdev,
> >+ EV_ABS,
> >+ ABS_Z))
> >+ return;
> >+
> >+ litest_drain_events(li);
> >+
> >+ abs = libevdev_get_abs_info(dev->evdev, ABS_Z);
> >+ ck_assert_notnull(abs);
> >+
> >+ litest_event(dev, EV_KEY, BTN_TOOL_BRUSH, 1);
> >+ litest_event(dev, EV_ABS, ABS_MISC, 0x804); /* Art Pen */
> >+ litest_event(dev, EV_MSC, MSC_SERIAL, 1000);
> >+ litest_event(dev, EV_SYN, SYN_REPORT, 0);
> >+
> >+ /* start with non-zero */
> >+ litest_event(dev, EV_ABS, ABS_Z, 10);
> >+ litest_event(dev, EV_SYN, SYN_REPORT, 0);
> >+
> >+ litest_drain_events(li);
> >+
> >+ scale = (abs->maximum - abs->minimum + 1)/360.0;
> >+ for (angle = 0; angle < 360; angle += 8) {
> >+ int a = angle * scale + abs->minimum;
> >+
> >+ litest_event(dev, EV_ABS, ABS_Z, a);
> >+ litest_event(dev, EV_SYN, SYN_REPORT, 0);
> >+
> >+ litest_wait_for_event_of_type(li,
> >+ LIBINPUT_EVENT_TABLET_AXIS,
> >+ -1);
> >+ event = libinput_get_event(li);
> >+ tev = libinput_event_get_tablet_event(event);
> >+ ck_assert(libinput_event_tablet_axis_has_changed(tev,
> >+ LIBINPUT_TABLET_AXIS_ROTATION_Z));
> >+ val = libinput_event_tablet_get_axis_value(tev,
> >+ LIBINPUT_TABLET_AXIS_ROTATION_Z);
> >+
> >+ /* artpen has a 90 deg offset cw */
> >+ ck_assert_int_eq(round(val), (angle + 90) % 360);
> >+ libinput_event_destroy(event);
> >+ litest_assert_empty_queue(li);
> >+ }
> >+}
> >+END_TEST
> >+
> > int
> > main(int argc, char **argv)
> > {
> >@@ -1384,6 +1477,8 @@ main(int argc, char **argv)
> > litest_add("tablet:mouse", mouse_rotation, LITEST_TABLET, LITEST_ANY);
> > litest_add("tablet:airbrush", airbrush_tool, LITEST_TABLET, LITEST_ANY);
> > litest_add("tablet:airbrush", airbrush_wheel, LITEST_TABLET, LITEST_ANY);
> >+ litest_add("tablet:artpen", artpen_tool, LITEST_TABLET, LITEST_ANY);
> >+ litest_add("tablet:artpen", artpen_rotation, LITEST_TABLET, LITEST_ANY);
> > return litest_run(argc, argv);
> > }
>
> --
> 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....
>
More information about the wayland-devel
mailing list