tablet: support the rel wheel on the mouse device

Providing a relative axis in the axis_get_value() is inconsistent with the
other axes, this will be fixed in a follow-up commit.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Reviewed-by: Stephen Chandler Paul <thatslyude@gmail.com>
This commit is contained in:
Peter Hutterer 2015-02-20 11:41:06 +10:00
parent ec8b703c9c
commit 71c2cd26cc
6 changed files with 90 additions and 2 deletions

View file

@ -82,6 +82,10 @@ tablet_device_has_axis(struct tablet_dispatch *tablet,
libevdev_has_event_code(evdev,
EV_ABS,
ABS_TILT_Y));
} else if (axis == LIBINPUT_TABLET_AXIS_REL_WHEEL) {
has_axis = libevdev_has_event_code(evdev,
EV_REL,
REL_WHEEL);
} else {
code = axis_to_evcode(axis);
has_axis = libevdev_has_event_code(evdev,
@ -251,6 +255,15 @@ convert_to_degrees(const struct input_absinfo *absinfo, double offset)
return fmod(value * 360.0 + offset, 360.0);
}
static inline double
normalize_wheel(struct tablet_dispatch *tablet,
int value)
{
struct evdev_device *device = tablet->device;
return value * device->scroll.wheel_click_angle;
}
static void
tablet_check_notify_axes(struct tablet_dispatch *tablet,
struct evdev_device *device,
@ -282,6 +295,11 @@ tablet_check_notify_axes(struct tablet_dispatch *tablet,
axes[LIBINPUT_TABLET_AXIS_TILT_Y] = 0;
axes[a] = tablet->axes[a];
continue;
} else if (a == LIBINPUT_TABLET_AXIS_REL_WHEEL) {
tablet->axes[a] = normalize_wheel(tablet,
tablet->deltas[a]);
axes[a] = tablet->axes[a];
continue;
}
absinfo = libevdev_get_abs_info(device->evdev,
@ -441,6 +459,35 @@ tablet_process_key(struct tablet_dispatch *tablet,
}
}
static void
tablet_process_relative(struct tablet_dispatch *tablet,
struct evdev_device *device,
struct input_event *e,
uint32_t time)
{
enum libinput_tablet_axis axis;
switch (e->code) {
case REL_WHEEL:
axis = rel_evcode_to_axis(e->code);
if (axis == LIBINPUT_TABLET_AXIS_NONE) {
log_bug_libinput(device->base.seat->libinput,
"Invalid ABS event code %#x\n",
e->code);
break;
}
set_bit(tablet->changed_axes, axis);
tablet->deltas[axis] = -1 * e->value;
tablet_set_status(tablet, TABLET_AXES_UPDATED);
break;
default:
log_info(tablet->device->base.seat->libinput,
"Unhandled relative axis %s (%#x)\n",
libevdev_event_code_get_name(EV_REL, e->code),
e->code);
return;
}
}
static void
tablet_process_misc(struct tablet_dispatch *tablet,
struct evdev_device *device,
@ -536,6 +583,11 @@ tool_set_bits_from_libwacom(const struct tablet_dispatch *tablet,
break;
case WSTYLUS_PUCK:
copy_axis_cap(tablet, tool, LIBINPUT_TABLET_AXIS_ROTATION_Z);
/* lens cursors don't have a wheel */
if (!libwacom_stylus_has_lens(s))
copy_axis_cap(tablet,
tool,
LIBINPUT_TABLET_AXIS_REL_WHEEL);
break;
default:
break;
@ -579,6 +631,7 @@ tool_set_bits(const struct tablet_dispatch *tablet,
case LIBINPUT_TOOL_MOUSE:
case LIBINPUT_TOOL_LENS:
copy_axis_cap(tablet, tool, LIBINPUT_TABLET_AXIS_ROTATION_Z);
copy_axis_cap(tablet, tool, LIBINPUT_TABLET_AXIS_REL_WHEEL);
break;
default:
break;
@ -826,6 +879,9 @@ tablet_process(struct evdev_dispatch *dispatch,
case EV_ABS:
tablet_process_absolute(tablet, device, e, time);
break;
case EV_REL:
tablet_process_relative(tablet, device, e, time);
break;
case EV_KEY:
tablet_process_key(tablet, device, e, time);
break;

View file

@ -50,6 +50,7 @@ struct tablet_dispatch {
unsigned char status;
unsigned char changed_axes[NCHARS(LIBINPUT_TABLET_AXIS_MAX + 1)];
double axes[LIBINPUT_TABLET_AXIS_MAX + 1];
double deltas[LIBINPUT_TABLET_AXIS_MAX + 1];
unsigned char axis_caps[NCHARS(LIBINPUT_TABLET_AXIS_MAX + 1)];
/* Only used for tablets that don't report serial numbers */
@ -101,6 +102,23 @@ evcode_to_axis(const uint32_t evcode)
return axis;
}
static inline enum libinput_tablet_axis
rel_evcode_to_axis(const uint32_t evcode)
{
enum libinput_tablet_axis axis;
switch (evcode) {
case REL_WHEEL:
axis = LIBINPUT_TABLET_AXIS_REL_WHEEL;
break;
default:
axis = LIBINPUT_TABLET_AXIS_NONE;
break;
}
return axis;
}
static inline uint32_t
axis_to_evcode(const enum libinput_tablet_axis axis)
{

View file

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

View file

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

View file

@ -144,6 +144,7 @@ enum libinput_tablet_axis {
LIBINPUT_TABLET_AXIS_TILT_Y = 6,
LIBINPUT_TABLET_AXIS_ROTATION_Z = 7,
LIBINPUT_TABLET_AXIS_SLIDER = 8,
LIBINPUT_TABLET_AXIS_REL_WHEEL = 9,
};
/**
@ -1060,6 +1061,9 @@ libinput_event_tablet_axis_has_changed(struct libinput_event_tablet *event,
* 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.
* - @ref LIBINPUT_TABLET_AXIS_REL_WHEEL - A relative wheel on the tool,
* similar or equivalent to a mouse wheel. The value is a delta from the
* device's previous position, in degrees.
*
* @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

@ -293,7 +293,7 @@ print_tablet_axes(struct libinput_event_tablet *t)
struct libinput_tool *tool = libinput_event_tablet_get_tool(t);
double x, y;
double dist, pressure;
double rotation, slider;
double rotation, slider, wheel;
x = libinput_event_tablet_get_axis_value(t, LIBINPUT_TABLET_AXIS_X);
y = libinput_event_tablet_get_axis_value(t, LIBINPUT_TABLET_AXIS_Y);
@ -350,6 +350,15 @@ print_tablet_axes(struct libinput_event_tablet *t)
tablet_axis_changed_sym(t,
LIBINPUT_TABLET_AXIS_SLIDER));
}
if (libinput_tool_has_axis(tool, LIBINPUT_TABLET_AXIS_REL_WHEEL)) {
wheel = libinput_event_tablet_get_axis_value(t,
LIBINPUT_TABLET_AXIS_REL_WHEEL);
printf("\twheel: %.2f%s",
wheel,
tablet_axis_changed_sym(t,
LIBINPUT_TABLET_AXIS_REL_WHEEL));
}
}
static void