tablet: support airbrush wheel as slider

The little wheel isn't a full wheel, it has a ~90 degree rotation angle with a
range of 1024 values. To avoid confusion with "wheel" elsewhere in the API
name it slider.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Stephen Chandler Paul <thatslyude@gmail.com>
This commit is contained in:
Peter Hutterer 2015-02-17 13:04:06 +10:00
parent 8edae426e3
commit 0d87dd8121
7 changed files with 113 additions and 4 deletions

View file

@ -107,6 +107,7 @@ tablet_process_absolute(struct tablet_dispatch *tablet,
case ABS_TILT_X:
case ABS_TILT_Y:
case ABS_DISTANCE:
case ABS_WHEEL:
axis = evcode_to_axis(e->code);
if (axis == LIBINPUT_TABLET_AXIS_NONE) {
log_bug_libinput(device->base.seat->libinput,
@ -189,7 +190,7 @@ tablet_update_tool(struct tablet_dispatch *tablet,
}
static inline double
normalize_pressure_or_dist(const struct input_absinfo *absinfo)
normalize_pressure_dist_slider(const struct input_absinfo *absinfo)
{
double range = absinfo->maximum - absinfo->minimum;
double value = (absinfo->value - absinfo->minimum) / range;
@ -286,7 +287,8 @@ tablet_check_notify_axes(struct tablet_dispatch *tablet,
break;
case LIBINPUT_TABLET_AXIS_DISTANCE:
case LIBINPUT_TABLET_AXIS_PRESSURE:
tablet->axes[a] = normalize_pressure_or_dist(absinfo);
case LIBINPUT_TABLET_AXIS_SLIDER:
tablet->axes[a] = normalize_pressure_dist_slider(absinfo);
break;
case LIBINPUT_TABLET_AXIS_TILT_X:
case LIBINPUT_TABLET_AXIS_TILT_Y:
@ -502,6 +504,8 @@ tool_set_bits_from_libwacom(const struct tablet_dispatch *tablet,
separately. */
switch(type) {
case WSTYLUS_AIRBRUSH:
copy_axis_cap(tablet, tool, LIBINPUT_TABLET_AXIS_SLIDER);
/* fall-through */
case WSTYLUS_MARKER:
case WSTYLUS_GENERAL:
case WSTYLUS_INKING:
@ -551,6 +555,7 @@ tool_set_bits(const struct tablet_dispatch *tablet,
copy_axis_cap(tablet, tool, LIBINPUT_TABLET_AXIS_DISTANCE);
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);
break;
case LIBINPUT_TOOL_MOUSE:
case LIBINPUT_TOOL_LENS:

View file

@ -87,6 +87,9 @@ evcode_to_axis(const uint32_t evcode)
case ABS_TILT_Y:
axis = LIBINPUT_TABLET_AXIS_TILT_Y;
break;
case ABS_WHEEL:
axis = LIBINPUT_TABLET_AXIS_SLIDER;
break;
default:
axis = LIBINPUT_TABLET_AXIS_NONE;
break;
@ -119,6 +122,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_SLIDER:
evcode = ABS_WHEEL;
break;
default:
abort();
}

View file

@ -30,7 +30,7 @@
#include "libinput.h"
#include "libinput-util.h"
#define LIBINPUT_TABLET_AXIS_MAX LIBINPUT_TABLET_AXIS_ROTATION_Z
#define LIBINPUT_TABLET_AXIS_MAX LIBINPUT_TABLET_AXIS_SLIDER
struct libinput_source;

View file

@ -585,6 +585,7 @@ libinput_event_tablet_get_axis_value(struct libinput_event_tablet *event,
case LIBINPUT_TABLET_AXIS_TILT_X:
case LIBINPUT_TABLET_AXIS_TILT_Y:
case LIBINPUT_TABLET_AXIS_ROTATION_Z:
case LIBINPUT_TABLET_AXIS_SLIDER:
return event->axes[axis];
default:
return 0;

View file

@ -143,6 +143,7 @@ enum libinput_tablet_axis {
LIBINPUT_TABLET_AXIS_TILT_X = 5,
LIBINPUT_TABLET_AXIS_TILT_Y = 6,
LIBINPUT_TABLET_AXIS_ROTATION_Z = 7,
LIBINPUT_TABLET_AXIS_SLIDER = 8,
};
/**
@ -1056,6 +1057,8 @@ libinput_event_tablet_axis_has_changed(struct libinput_event_tablet *event,
* @ref LIBINPUT_TOOL_MOUSE and @ref LIBINPUT_TOOL_LENS tools the logical
* neutral position is pointing to the current logical north of the
* tablet.
* - @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.
*
* @note This function may be called for a specific axis even if
* libinput_event_tablet_axis_has_changed() returns 0 for that axis.

View file

@ -1273,6 +1273,92 @@ START_TEST(mouse_rotation)
}
END_TEST
START_TEST(airbrush_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_KEY,
BTN_TOOL_AIRBRUSH))
return;
litest_drain_events(li);
litest_event(dev, EV_KEY, BTN_TOOL_AIRBRUSH, 1);
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_AIRBRUSH);
libinput_event_destroy(event);
}
END_TEST
START_TEST(airbrush_wheel)
{
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 v;
if (!libevdev_has_event_code(dev->evdev,
EV_KEY,
BTN_TOOL_AIRBRUSH))
return;
litest_drain_events(li);
abs = libevdev_get_abs_info(dev->evdev, ABS_WHEEL);
ck_assert_notnull(abs);
litest_event(dev, EV_KEY, BTN_TOOL_AIRBRUSH, 1);
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_WHEEL, 10);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
litest_drain_events(li);
scale = abs->maximum - abs->minimum;
for (v = abs->minimum; v < abs->maximum; v += 8) {
litest_event(dev, EV_ABS, ABS_WHEEL, v);
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_SLIDER));
val = libinput_event_tablet_get_axis_value(tev,
LIBINPUT_TABLET_AXIS_SLIDER);
ck_assert_int_eq(val, (v - abs->minimum)/scale);
libinput_event_destroy(event);
litest_assert_empty_queue(li);
}
}
END_TEST
int
main(int argc, char **argv)
{
@ -1296,6 +1382,8 @@ main(int argc, char **argv)
litest_add("tablet:mouse", mouse_tool, LITEST_TABLET, LITEST_ANY);
litest_add("tablet:mouse", mouse_buttons, LITEST_TABLET, LITEST_ANY);
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);
return litest_run(argc, argv);
}

View file

@ -293,7 +293,7 @@ print_tablet_axis_event(struct libinput_event *ev)
struct libinput_event_tablet *t = libinput_event_get_tablet_event(ev);
double x, y;
double dist, pressure;
double rotation;
double rotation, slider;
print_event_time(libinput_event_tablet_get_time(t));
@ -324,6 +324,12 @@ print_tablet_axis_event(struct libinput_event *ev)
rotation,
tablet_axis_changed_sym(t, LIBINPUT_TABLET_AXIS_ROTATION_Z));
slider = libinput_event_tablet_get_axis_value(t,
LIBINPUT_TABLET_AXIS_SLIDER);
printf(" slider: %.2f%s",
slider,
tablet_axis_changed_sym(t, LIBINPUT_TABLET_AXIS_SLIDER));
printf("\n");
}