[PATCH libinput 12/23] Sanitize distance and pressure axes before reporting their values

Peter Hutterer peter.hutterer at who-t.net
Sun Jun 15 22:49:02 PDT 2014


On Thu, Jun 12, 2014 at 11:28:33PM -0400, Stephen Chandler Paul wrote:
> This commit changes two things with the way distance and pressure axes are
> reported:
> 1. Distance and pressure are made mutually exclusive. When there is a distance
>    event and a pressure event and the tool is in contact with the tablet, only
>    the pressure change will be reported. When the tool is not in contact and
>    both a distance and pressure change are received, only the distance update
>    will be received.
> 2. Bad distance events are not reported to the caller. There is a certain
>    distance a tool can be from the tablet where the tablet recongnizes that a
>    tool appeared, but the tool doesn't send any useful information to the
>    tablet. When this happens, the distance will update to it's minimum or
>    maximum value, and no other axis updates will be sent. Since this can give
>    a caller the impression that the tool is within a useful proximity of the
>    tablet, we filter out any distance events with a value of maximum or minimum
>    when the tool is not within useful proximity of the tablet.
> 
> Signed-off-by: Stephen Chandler Paul <thatslyude at gmail.com>
> ---
>  src/evdev-tablet.c | 34 ++++++++++++++++++++++++++++++++++
>  src/evdev-tablet.h |  3 ++-
>  2 files changed, 36 insertions(+), 1 deletion(-)
> 
> diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
> index 8cb7d64..f42caab 100644
> --- a/src/evdev-tablet.c
> +++ b/src/evdev-tablet.c
> @@ -56,6 +56,9 @@ tablet_process_absolute(struct tablet_dispatch *tablet,
>  	case ABS_PRESSURE:
>  	case ABS_TILT_X:
>  	case ABS_TILT_Y:
> +		tablet_unset_status(tablet, TABLET_TOOL_LEFT_PROXIMITY);

Only one request: please rename this to TABLET_TOOL_OUT_OF_PROXIMITY. My
brain keeps wondering how proximity can be on the left even though I know
what it should in this context.

otherwise
Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

Cheers,
   Peter

> +
> +		/* Fall through */
>  	case ABS_DISTANCE:
>  		axis = evcode_to_axis(e->code);
>  		if (axis == LIBINPUT_TABLET_AXIS_NONE) {
> @@ -314,6 +317,35 @@ tablet_notify_buttons(struct tablet_dispatch *tablet,
>  }
>  
>  static void
> +sanitize_tablet_axes(struct tablet_dispatch *tablet)
> +{
> +	const struct input_absinfo *distance,
> +	                           *pressure;
> +
> +	distance = tablet->absinfo[LIBINPUT_TABLET_AXIS_DISTANCE];
> +	pressure = tablet->absinfo[LIBINPUT_TABLET_AXIS_PRESSURE];
> +
> +	/* Keep distance and pressure mutually exclusive. In addition, filter
> +	 * out invalid distance events that can occur when the tablet tool is
> +	 * close enough for the tablet to detect that's something's there, but
> +	 * not close enough for it to actually receive data from the tool
> +	 * properly
> +	 */
> +	if (bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_AXIS_DISTANCE) &&
> +	    ((bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_AXIS_PRESSURE) &&
> +	      distance->value > distance->minimum &&
> +	      pressure->value > pressure->minimum) ||
> +	     (tablet_has_status(tablet, TABLET_TOOL_LEFT_PROXIMITY) &&
> +	      (distance->value <= distance->minimum ||
> +	       distance->value >= distance->maximum)))) {
> +		clear_bit(tablet->changed_axes, LIBINPUT_TABLET_AXIS_DISTANCE);
> +	} else if (bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_AXIS_PRESSURE) &&
> +		   !tablet_has_status(tablet, TABLET_STYLUS_IN_CONTACT)) {
> +		clear_bit(tablet->changed_axes, LIBINPUT_TABLET_AXIS_PRESSURE);
> +	}
> +}
> +
> +static void
>  tablet_flush(struct tablet_dispatch *tablet,
>  	     struct evdev_device *device,
>  	     uint32_t time)
> @@ -334,6 +366,7 @@ tablet_flush(struct tablet_dispatch *tablet,
>  		}
>  
>  		if (tablet_has_status(tablet, TABLET_AXES_UPDATED)) {
> +			sanitize_tablet_axes(tablet);
>  			tablet_notify_axes(tablet, device, time);
>  			tablet_unset_status(tablet, TABLET_AXES_UPDATED);
>  		}
> @@ -354,6 +387,7 @@ tablet_flush(struct tablet_dispatch *tablet,
>  	/* We want button releases to be sent before the proximity out event */
>  	if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY)) {
>  		tablet_notify_proximity_out(&device->base, time);
> +		tablet_set_status(tablet, TABLET_TOOL_LEFT_PROXIMITY);
>  		tablet_unset_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY);
>  	}
>  
> diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h
> index ffcf33c..5a27c8d 100644
> --- a/src/evdev-tablet.h
> +++ b/src/evdev-tablet.h
> @@ -34,7 +34,8 @@ enum tablet_status {
>  	TABLET_TOOL_LEAVING_PROXIMITY = 1 << 2,
>  	TABLET_BUTTONS_PRESSED = 1 << 3,
>  	TABLET_BUTTONS_RELEASED = 1 << 4,
> -	TABLET_STYLUS_IN_CONTACT = 1 << 5
> +	TABLET_STYLUS_IN_CONTACT = 1 << 5,
> +	TABLET_TOOL_LEFT_PROXIMITY = 1 << 6
>  };
>  
>  struct button_state {
> -- 
> 1.8.5.5
> 


More information about the wayland-devel mailing list