evdev: Continue updating axes internally when tool leaves proximity

Axis changes are now still processed by libinput regardless of whether or not
the tool is in proximity, however we refrain from reporting them unless the tool
is in proximity. This stops bad distance events from being reported without
needing a huge mess of conditional statements in sanitize_axes(). The tool is
now counted as back in proximity when a tool update is received instead of when
an axis update is received.

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-06-19 01:18:06 -04:00 committed by Peter Hutterer
parent 563268fa9f
commit 39b43c7058
2 changed files with 33 additions and 43 deletions

View file

@ -50,9 +50,6 @@ tablet_process_absolute(struct tablet_dispatch *tablet,
case ABS_PRESSURE:
case ABS_TILT_X:
case ABS_TILT_Y:
tablet_unset_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY);
/* Fall through */
case ABS_DISTANCE:
axis = evcode_to_axis(e->code);
if (axis == LIBINPUT_TABLET_AXIS_NONE) {
@ -77,12 +74,15 @@ tablet_update_tool(struct tablet_dispatch *tablet,
{
assert(tool != LIBINPUT_TOOL_NONE);
if (enabled && tool != tablet->current_tool_type) {
tablet->current_tool_type = tool;
tablet_set_status(tablet, TABLET_TOOL_UPDATED);
if (enabled) {
if (tool != tablet->current_tool_type) {
tablet->current_tool_type = tool;
tablet_set_status(tablet, TABLET_TOOL_UPDATED);
}
tablet_unset_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY);
}
else if (!enabled)
tablet_set_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY);
else
tablet_set_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY);
}
static inline double
@ -141,10 +141,14 @@ tablet_check_notify_axes(struct tablet_dispatch *tablet,
axis_update_needed = true;
}
if (axis_update_needed) {
tablet_notify_axis(base, time, tablet->changed_axes, tablet->axes);
memset(tablet->changed_axes, 0, sizeof(tablet->changed_axes));
}
if (axis_update_needed &&
!tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY))
tablet_notify_axis(base,
time,
tablet->changed_axes,
tablet->axes);
memset(tablet->changed_axes, 0, sizeof(tablet->changed_axes));
}
static void
@ -223,6 +227,8 @@ tablet_process_misc(struct tablet_dispatch *tablet,
e->value != -1) {
tablet->current_tool_serial = e->value;
tablet_set_status(tablet, TABLET_TOOL_UPDATED);
tablet_unset_status(tablet,
TABLET_TOOL_OUT_OF_PROXIMITY);
}
break;
default:
@ -334,11 +340,8 @@ sanitize_tablet_axes(struct tablet_dispatch *tablet)
* properly
*/
if (bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_AXIS_DISTANCE) &&
((distance->value > distance->minimum &&
pressure->value > pressure->minimum) ||
(tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY) &&
(distance->value <= distance->minimum ||
distance->value >= distance->maximum)))) {
distance->value > distance->minimum &&
pressure->value > pressure->minimum) {
clear_bit(tablet->changed_axes, LIBINPUT_TABLET_AXIS_DISTANCE);
tablet->axes[LIBINPUT_TABLET_AXIS_DISTANCE] = 0;
} else if (bit_is_set(tablet->changed_axes, LIBINPUT_TABLET_AXIS_PRESSURE) &&
@ -357,28 +360,19 @@ tablet_flush(struct tablet_dispatch *tablet,
struct evdev_device *device,
uint32_t time)
{
if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY)) {
if (tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY)) {
/* Release all stylus buttons */
tablet->button_state.stylus_buttons = 0;
tablet_set_status(tablet, TABLET_BUTTONS_RELEASED);
} else if (tablet_has_status(tablet, TABLET_TOOL_UPDATED)) {
tablet_notify_tool(tablet, device, time);
tablet_unset_status(tablet, TABLET_TOOL_UPDATED);
}
/* FIXME: This behavior is not ideal and this memset should be
* removed */
memset(&tablet->changed_axes, 0, sizeof(tablet->changed_axes));
memset(&tablet->axes, 0, sizeof(tablet->axes));
if (tablet_has_status(tablet, TABLET_AXES_UPDATED)) {
sanitize_tablet_axes(tablet);
tablet_check_notify_axes(tablet, device, time);
tablet_unset_status(tablet, TABLET_AXES_UPDATED);
} else {
if (tablet_has_status(tablet, TABLET_TOOL_UPDATED)) {
tablet_notify_tool(tablet, device, time);
tablet_unset_status(tablet, TABLET_TOOL_UPDATED);
}
if (tablet_has_status(tablet, TABLET_AXES_UPDATED)) {
sanitize_tablet_axes(tablet);
tablet_check_notify_axes(tablet, device, time);
tablet_unset_status(tablet, TABLET_AXES_UPDATED);
}
}
if (tablet_has_status(tablet, TABLET_BUTTONS_RELEASED)) {
@ -393,11 +387,8 @@ tablet_flush(struct tablet_dispatch *tablet,
tablet_unset_status(tablet, TABLET_BUTTONS_PRESSED);
}
if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY)) {
if (tablet_has_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY))
tablet_notify_proximity_out(&device->base, time);
tablet_set_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY);
tablet_unset_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY);
}
/* Update state */
memcpy(&tablet->prev_button_state,

View file

@ -31,11 +31,10 @@ enum tablet_status {
TABLET_NONE = 0,
TABLET_AXES_UPDATED = 1 << 0,
TABLET_TOOL_UPDATED = 1 << 1,
TABLET_TOOL_LEAVING_PROXIMITY = 1 << 2,
TABLET_BUTTONS_PRESSED = 1 << 3,
TABLET_BUTTONS_RELEASED = 1 << 4,
TABLET_STYLUS_IN_CONTACT = 1 << 5,
TABLET_TOOL_OUT_OF_PROXIMITY = 1 << 6
TABLET_BUTTONS_PRESSED = 1 << 2,
TABLET_BUTTONS_RELEASED = 1 << 3,
TABLET_STYLUS_IN_CONTACT = 1 << 4,
TABLET_TOOL_OUT_OF_PROXIMITY = 1 << 5
};
struct button_state {