[PATCH libinput 2/2 v2] tablet: Add libinput_tool_has_axis() and tests
Peter Hutterer
peter.hutterer at who-t.net
Thu Aug 7 17:38:56 PDT 2014
On Thu, Aug 07, 2014 at 06:54:55PM -0400, Stephen Chandler Paul wrote:
> 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 at gmail.com>
> ---
>
> Changes:
> - Added a description to the patch
> - Fixed all of the memory leaks, passes make check with flying
> colors now
>
> src/evdev-tablet.c | 42 +++++++++++++++++++++++++++++
> src/evdev-tablet.h | 1 +
> src/libinput-private.h | 1 +
> src/libinput.c | 7 +++++
> src/libinput.h | 26 ++++++++++++++++++
> test/tablet.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 6 files changed, 149 insertions(+)
>
> diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
> index 43da67a..5f8a466 100644
> --- a/src/evdev-tablet.c
> +++ b/src/evdev-tablet.c
> @@ -298,6 +298,40 @@ 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_TOOL_AXIS_FLAG_PRESSURE))
> + set_bit(tool->axis_caps,
> + LIBINPUT_TOOL_AXIS_FLAG_PRESSURE);
> + if (bit_is_set(tablet->axis_caps,
> + LIBINPUT_TOOL_AXIS_FLAG_DISTANCE))
> + set_bit(tool->axis_caps,
> + LIBINPUT_TOOL_AXIS_FLAG_DISTANCE);
> + if (bit_is_set(tablet->axis_caps,
> + LIBINPUT_TOOL_AXIS_FLAG_TILT))
> + set_bit(tool->axis_caps,
> + LIBINPUT_TOOL_AXIS_FLAG_TILT);
> + break;
> + default:
> + break;
> + }
> +
> list_insert(tool_list, &tool->link);
> }
>
> @@ -512,6 +546,14 @@ tablet_init(struct tablet_dispatch *tablet,
> tablet->current_tool_type = LIBINPUT_TOOL_NONE;
> list_init(&tablet->tool_list);
>
> + if (libevdev_has_event_code(device->evdev, EV_ABS, ABS_PRESSURE))
> + set_bit(tablet->axis_caps, LIBINPUT_TOOL_AXIS_FLAG_PRESSURE);
> + if (libevdev_has_event_code(device->evdev, EV_ABS, ABS_DISTANCE))
> + set_bit(tablet->axis_caps, LIBINPUT_TOOL_AXIS_FLAG_DISTANCE);
> + if (libevdev_has_event_code(device->evdev, EV_ABS, ABS_TILT_X) &&
> + libevdev_has_event_code(device->evdev, EV_ABS, ABS_TILT_Y))
> + set_bit(tablet->axis_caps, LIBINPUT_TOOL_AXIS_FLAG_TILT);
> +
> tablet_mark_all_axes_changed(tablet, device);
>
> return 0;
> diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h
> index d16aef3..be2d09a 100644
> --- a/src/evdev-tablet.h
> +++ b/src/evdev-tablet.h
> @@ -49,6 +49,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_TOOL_AXIS_FLAG_CNT)];
>
> /* Only used for tablets that don't report serial numbers */
> struct list tool_list;
> diff --git a/src/libinput-private.h b/src/libinput-private.h
> index 8187564..bdef330 100644
> --- a/src/libinput-private.h
> +++ b/src/libinput-private.h
> @@ -108,6 +108,7 @@ struct libinput_tool {
> struct list link;
> uint32_t serial;
> enum libinput_tool_type type;
> + unsigned char axis_caps[NCHARS(LIBINPUT_TOOL_AXIS_FLAG_CNT)];
> int refcount;
> void *user_data;
> };
> diff --git a/src/libinput.c b/src/libinput.c
> index 68187d8..560fedd 100644
> --- a/src/libinput.c
> +++ b/src/libinput.c
> @@ -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_tool_axis_flag axis)
> +{
> + return bit_is_set(tool->axis_caps, axis);
> +}
> +
> LIBINPUT_EXPORT void
> libinput_tool_set_user_data(struct libinput_tool *tool,
> void *user_data)
> diff --git a/src/libinput.h b/src/libinput.h
> index 1d4952b..63c5ad3 100644
> --- a/src/libinput.h
> +++ b/src/libinput.h
> @@ -214,6 +214,19 @@ enum libinput_tool_type {
> };
>
> /**
> + * @ingroup device
> + *
> + * A series of flags for representing which kinds of axes a tablet tool can
> + * support.
> + */
> +enum libinput_tool_axis_flag {
> + LIBINPUT_TOOL_AXIS_FLAG_PRESSURE = 0,
> + LIBINPUT_TOOL_AXIS_FLAG_DISTANCE = 1,
> + LIBINPUT_TOOL_AXIS_FLAG_TILT = 2,
> + LIBINPUT_TOOL_AXIS_FLAG_CNT = 3,
> +};
> +
> +/**
> * @ingroup base
> *
> * Event type for events returned by libinput_get_event().
> @@ -1010,6 +1023,19 @@ 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_tool_axis_flag axis);
looking at that again, I don't think we need the flags here. passing a flag
in here doesn't make esnese unless you define what to return if multiple
flags are set. It's easier to just pass the libinput_tablet_axis enum in
here and check for a single axis at a time. this means you can drop the flag
enum above. sorry, should've picked that up yesterday.
> +
> +/**
> + * @ingroup event_tablet
> + *
> * Decrement the ref count of tool by one. When the ref count of tool reaches 0,
> * the memory allocated for tool will be freed.
> *
> diff --git a/test/tablet.c b/test/tablet.c
> index 2de0989..657251e 100644
> --- a/test/tablet.c
> +++ b/test/tablet.c
> @@ -766,10 +766,82 @@ 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_TOOL_AXIS_FLAG_PRESSURE));
urgh, this indentation just looks awkward, and it aligns it badly. try for
this one instead, so it's more obvious what's an argument to what.
ck_assert(libinput_tool_has_axis(tool,
LIBINPUT_TOOL_AXIS_FLAG_PRESSURE));
despite Jonas' disagreement on the line width, I think this is a case where
going over 80 would make sense too
ck_assert(libinput_tool_has_axis(tool,
LIBINPUT_TOOL_AXIS_FLAG_PRESSURE));
same below.
Cheers,
Peter
> + ck_assert(!libinput_tool_has_axis(
> + tool, LIBINPUT_TOOL_AXIS_FLAG_TILT));
> + ck_assert(libinput_tool_has_axis(
> + tool, LIBINPUT_TOOL_AXIS_FLAG_DISTANCE));
> + }
> +
> + 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_TOOL_AXIS_FLAG_PRESSURE));
> + ck_assert(libinput_tool_has_axis(
> + tool, LIBINPUT_TOOL_AXIS_FLAG_DISTANCE));
> + ck_assert(libinput_tool_has_axis(
> + tool, LIBINPUT_TOOL_AXIS_FLAG_TILT));
> + }
> +
> + 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);
> --
> 1.8.5.5
>
More information about the wayland-devel
mailing list