[PATCH libinput v3] tablet: Add libinput_tool_has_axis() and tests

Peter Hutterer peter.hutterer at who-t.net
Thu Aug 7 20:18:17 PDT 2014


On Thu, Aug 07, 2014 at 10:02:22PM -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>
> ---

merged and pushed, thanks

Cheers,
   Peter


> 
> ===== Changes =====
> * Fixed the line width in test/tablet.c
> * Removed libinput_tool_axis_flag and used the already existing axis enumerators
>   instead
> 
>  src/evdev-tablet.c     | 47 +++++++++++++++++++++++++++++++
>  src/evdev-tablet.h     |  1 +
>  src/libinput-private.h |  1 +
>  src/libinput.c         |  7 +++++
>  src/libinput.h         | 13 +++++++++
>  test/tablet.c          | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  6 files changed, 145 insertions(+)
> 
> diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
> index 15f0663..a63b734 100644
> --- a/src/evdev-tablet.c
> +++ b/src/evdev-tablet.c
> @@ -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;
> diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h
> index adc3aa4..cb37577 100644
> --- a/src/evdev-tablet.h
> +++ b/src/evdev-tablet.h
> @@ -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;
> diff --git a/src/libinput-private.h b/src/libinput-private.h
> index 8187564..369bb8f 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_TABLET_AXIS_CNT)];
>  	int refcount;
>  	void *user_data;
>  };
> diff --git a/src/libinput.c b/src/libinput.c
> index 68187d8..e52527b 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_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)
> diff --git a/src/libinput.h b/src/libinput.h
> index 1d4952b..ed56c0b 100644
> --- a/src/libinput.h
> +++ b/src/libinput.h
> @@ -1010,6 +1010,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_tablet_axis axis);
> +
> +/**
> + * @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..e903d32 100644
> --- a/test/tablet.c
> +++ b/test/tablet.c
> @@ -766,10 +766,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);
> -- 
> 1.8.5.5
> 


More information about the wayland-devel mailing list