tablet: Add libinput_tool_has_axis() and tests

Because the axes that tool reports can change depending on the tool in use, we
want to be able to provide functionality to determine which axes each tool can
support.

Signed-off-by: Stephen Chandler Paul <thatslyude@gmail.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Stephen Chandler Paul 2014-08-07 22:02:22 -04:00 committed by Peter Hutterer
parent 142cc66880
commit a0c9f1224e
6 changed files with 145 additions and 0 deletions

View file

@ -302,6 +302,44 @@ tablet_get_tool(struct tablet_dispatch *tablet,
.refcount = 1,
};
/* Determine the axis capabilities of the tool. Here's a break
* down of the heuristics used here:
* - The Wacom art pen supports all of the extra axes, along
* with rotation
* - All of normal pens and the airbrush support all of the
* extra axes if the tablet can report them
* - All of the mouse like devices don't really report any of
* the extra axes except for rotation.
* (as of writing this comment, rotation isn't supported, so you
* won't see the mouse or art pen here)
*/
switch (type) {
case LIBINPUT_TOOL_PEN:
case LIBINPUT_TOOL_ERASER:
case LIBINPUT_TOOL_PENCIL:
case LIBINPUT_TOOL_BRUSH:
case LIBINPUT_TOOL_AIRBRUSH:
if (bit_is_set(tablet->axis_caps,
LIBINPUT_TABLET_AXIS_PRESSURE))
set_bit(tool->axis_caps,
LIBINPUT_TABLET_AXIS_PRESSURE);
if (bit_is_set(tablet->axis_caps,
LIBINPUT_TABLET_AXIS_DISTANCE))
set_bit(tool->axis_caps,
LIBINPUT_TABLET_AXIS_DISTANCE);
if (bit_is_set(tablet->axis_caps,
LIBINPUT_TABLET_AXIS_TILT_X))
set_bit(tool->axis_caps,
LIBINPUT_TABLET_AXIS_TILT_X);
if (bit_is_set(tablet->axis_caps,
LIBINPUT_TABLET_AXIS_TILT_Y))
set_bit(tool->axis_caps,
LIBINPUT_TABLET_AXIS_TILT_Y);
break;
default:
break;
}
list_insert(tool_list, &tool->link);
}
@ -510,12 +548,21 @@ static int
tablet_init(struct tablet_dispatch *tablet,
struct evdev_device *device)
{
enum libinput_tablet_axis axis;
tablet->base.interface = &tablet_interface;
tablet->device = device;
tablet->status = TABLET_NONE;
tablet->current_tool_type = LIBINPUT_TOOL_NONE;
list_init(&tablet->tool_list);
for (axis = 0; axis < LIBINPUT_TABLET_AXIS_CNT; axis++) {
if (libevdev_has_event_code(device->evdev,
EV_ABS,
axis_to_evcode(axis)))
set_bit(tablet->axis_caps, axis);
}
tablet_mark_all_axes_changed(tablet, device);
return 0;

View file

@ -48,6 +48,7 @@ struct tablet_dispatch {
unsigned char status;
unsigned char changed_axes[NCHARS(LIBINPUT_TABLET_AXIS_CNT)];
double axes[LIBINPUT_TABLET_AXIS_CNT];
unsigned char axis_caps[NCHARS(LIBINPUT_TABLET_AXIS_CNT)];
/* Only used for tablets that don't report serial numbers */
struct list tool_list;

View file

@ -108,6 +108,7 @@ struct libinput_tool {
struct list link;
uint32_t serial;
enum libinput_tool_type type;
unsigned char axis_caps[NCHARS(LIBINPUT_TABLET_AXIS_CNT)];
int refcount;
void *user_data;
};

View file

@ -599,6 +599,13 @@ libinput_tool_get_serial(struct libinput_tool *tool)
return tool->serial;
}
LIBINPUT_EXPORT int
libinput_tool_has_axis(struct libinput_tool *tool,
enum libinput_tablet_axis axis)
{
return bit_is_set(tool->axis_caps, axis);
}
LIBINPUT_EXPORT void
libinput_tool_set_user_data(struct libinput_tool *tool,
void *user_data)

View file

@ -1007,6 +1007,19 @@ libinput_tool_get_type(struct libinput_tool *tool);
struct libinput_tool *
libinput_tool_ref(struct libinput_tool *tool);
/**
* @ingroup event_tablet
*
* Return whether or not a tablet tool supports the specified axis
*
* @param tool The tool to check the axis capabilities of
* @param axis The axis to check for support
* @return Whether or not the axis is supported
*/
int
libinput_tool_has_axis(struct libinput_tool *tool,
enum libinput_tablet_axis axis);
/**
* @ingroup event_tablet
*

View file

@ -770,10 +770,86 @@ START_TEST(tools_without_serials)
}
END_TEST
START_TEST(tool_capabilities)
{
struct libinput *li = litest_create_context();
struct litest_device *intuos;
struct litest_device *bamboo;
struct libinput_event *event;
/* The axis capabilities of a tool can differ depending on the type of
* tablet the tool is being used with */
bamboo = litest_create_device_with_overrides(LITEST_WACOM_BAMBOO,
NULL,
NULL,
NULL,
NULL);
intuos = litest_create_device_with_overrides(LITEST_WACOM_INTUOS,
NULL,
NULL,
NULL,
NULL);
litest_event(bamboo, EV_KEY, BTN_TOOL_PEN, 1);
litest_event(bamboo, EV_SYN, SYN_REPORT, 0);
libinput_dispatch(li);
while ((event = libinput_get_event(li))) {
if (libinput_event_get_type(event) ==
LIBINPUT_EVENT_TABLET_PROXIMITY_IN) {
struct libinput_event_tablet *t =
libinput_event_get_tablet_event(event);
struct libinput_tool *tool =
libinput_event_tablet_get_tool(t);
ck_assert(libinput_tool_has_axis(tool,
LIBINPUT_TABLET_AXIS_PRESSURE));
ck_assert(libinput_tool_has_axis(tool,
LIBINPUT_TABLET_AXIS_DISTANCE));
ck_assert(!libinput_tool_has_axis(tool,
LIBINPUT_TABLET_AXIS_TILT_X));
ck_assert(!libinput_tool_has_axis(tool,
LIBINPUT_TABLET_AXIS_TILT_Y));
}
libinput_event_destroy(event);
}
litest_event(intuos, EV_KEY, BTN_TOOL_PEN, 1);
litest_event(intuos, EV_SYN, SYN_REPORT, 0);
while ((event = libinput_get_event(li))) {
if (libinput_event_get_type(event) ==
LIBINPUT_EVENT_TABLET_PROXIMITY_IN) {
struct libinput_event_tablet *t =
libinput_event_get_tablet_event(event);
struct libinput_tool *tool =
libinput_event_tablet_get_tool(t);
ck_assert(libinput_tool_has_axis(tool,
LIBINPUT_TABLET_AXIS_PRESSURE));
ck_assert(libinput_tool_has_axis(tool,
LIBINPUT_TABLET_AXIS_DISTANCE));
ck_assert(libinput_tool_has_axis(tool,
LIBINPUT_TABLET_AXIS_TILT_X));
ck_assert(libinput_tool_has_axis(tool,
LIBINPUT_TABLET_AXIS_TILT_Y));
}
libinput_event_destroy(event);
}
litest_delete_device(bamboo);
litest_delete_device(intuos);
libinput_unref(li);
}
END_TEST
int
main(int argc, char **argv)
{
litest_add("tablet:tool", tool_ref, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
litest_add_no_device("tablet:tool", tool_capabilities);
litest_add("tablet:tool_serial", tool_serial, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
litest_add("tablet:tool_serial", serial_changes_tool, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);
litest_add("tablet:tool_serial", invalid_serials, LITEST_TABLET | LITEST_TOOL_SERIAL, LITEST_ANY);