Emit LIBINPUT_EVENT_TABLET_PROXIMITY_OUT when tool leaves proximity

This event is just used to notify the caller when the tool's no longer in
proximity. When an event like this occurs, everything from evdev up until the
next EV_SYN event is discarded along with any events that occured since the last
EV_SYN event. This also silences any tool update events where the tool type is
changed to LIBINPUT_TOOL_NONE, so we don't end up filling the tool list with a
bunch of tools that aren't actually tools.

Signed-off-by: Stephen Chandler Paul <thatslyude@gmail.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
Stephen Chandler Paul 2014-06-06 16:35:33 -04:00
parent 535c2cab2c
commit 5fa892a88e
5 changed files with 65 additions and 8 deletions

View file

@ -69,6 +69,8 @@ tablet_update_tool(struct tablet_dispatch *tablet,
tablet->current_tool_type = tool;
tablet_set_status(tablet, TABLET_TOOL_UPDATED);
}
else if (!enabled)
tablet_set_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY);
}
static void
@ -189,12 +191,28 @@ tablet_flush(struct tablet_dispatch *tablet,
struct evdev_device *device,
uint32_t time)
{
if (tablet_has_status(tablet, TABLET_TOOL_UPDATED))
tablet_notify_tool(tablet, device, time);
if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY)) {
/* 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)) {
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)) {
tablet_check_notify_axes(tablet, device, time);
tablet_unset_status(tablet, TABLET_AXES_UPDATED);
}
}
if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY)) {
tablet_notify_proximity_out(&device->base, time);
tablet_unset_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY);
}
}

View file

@ -30,7 +30,8 @@
enum tablet_status {
TABLET_NONE = 0,
TABLET_AXES_UPDATED = 1 << 0,
TABLET_TOOL_UPDATED = 1 << 1
TABLET_TOOL_UPDATED = 1 << 1,
TABLET_TOOL_LEAVING_PROXIMITY = 1 << 2
};
struct tablet_dispatch {

View file

@ -214,6 +214,10 @@ tablet_notify_tool_update(struct libinput_device *device,
uint32_t time,
struct libinput_tool *tool);
void
tablet_notify_proximity_out(struct libinput_device *device,
uint32_t time);
void
touch_notify_frame(struct libinput_device *device,
uint32_t time);

View file

@ -201,6 +201,7 @@ libinput_event_get_pointer_event(struct libinput_event *event)
case LIBINPUT_EVENT_TOUCH_FRAME:
case LIBINPUT_EVENT_TABLET_AXIS:
case LIBINPUT_EVENT_TABLET_TOOL_UPDATE:
case LIBINPUT_EVENT_TABLET_PROXIMITY_OUT:
break;
}
@ -229,6 +230,7 @@ libinput_event_get_keyboard_event(struct libinput_event *event)
case LIBINPUT_EVENT_TOUCH_FRAME:
case LIBINPUT_EVENT_TABLET_AXIS:
case LIBINPUT_EVENT_TABLET_TOOL_UPDATE:
case LIBINPUT_EVENT_TABLET_PROXIMITY_OUT:
break;
}
@ -257,6 +259,7 @@ libinput_event_get_touch_event(struct libinput_event *event)
return (struct libinput_event_touch *) event;
case LIBINPUT_EVENT_TABLET_AXIS:
case LIBINPUT_EVENT_TABLET_TOOL_UPDATE:
case LIBINPUT_EVENT_TABLET_PROXIMITY_OUT:
break;
}
@ -284,6 +287,7 @@ libinput_event_get_tablet_event(struct libinput_event *event)
break;
case LIBINPUT_EVENT_TABLET_AXIS:
case LIBINPUT_EVENT_TABLET_TOOL_UPDATE:
case LIBINPUT_EVENT_TABLET_PROXIMITY_OUT:
return (struct libinput_event_tablet *) event;
}
@ -311,6 +315,7 @@ libinput_event_get_device_notify_event(struct libinput_event *event)
case LIBINPUT_EVENT_TOUCH_FRAME:
case LIBINPUT_EVENT_TABLET_AXIS:
case LIBINPUT_EVENT_TABLET_TOOL_UPDATE:
case LIBINPUT_EVENT_TABLET_PROXIMITY_OUT:
break;
}
@ -1199,6 +1204,25 @@ tablet_notify_tool_update(struct libinput_device *device,
&tool_update_event->base);
}
void
tablet_notify_proximity_out(struct libinput_device *device,
uint32_t time)
{
struct libinput_event_tablet *proximity_out_update_event;
proximity_out_update_event = zalloc(sizeof *proximity_out_update_event);
if (!proximity_out_update_event)
return;
*proximity_out_update_event = (struct libinput_event_tablet) {
.time = time
};
post_device_event(device,
LIBINPUT_EVENT_TABLET_PROXIMITY_OUT,
&proximity_out_update_event->base);
}
static void
libinput_post_event(struct libinput *libinput,
struct libinput_event *event)

View file

@ -259,7 +259,17 @@ enum libinput_event_type {
* Signals that a device with the @ref LIBINPUT_DEVICE_CAP_TABLET
* capability has changed its tool.
*/
LIBINPUT_EVENT_TABLET_TOOL_UPDATE
LIBINPUT_EVENT_TABLET_TOOL_UPDATE,
/**
* Signals that a device with the @ref LIBINPUT_DEVICE_CAP_TABLET
* capability has detected that there is no longer a tool in use. When
* this happens, the value of every axis should be assumed to have a
* value of 0 and any buttons that are currently held down on the stylus
* are marked as released. Button release events for each button that
* was held down on the stylus are sent before the initial proximity out
* event.
*/
LIBINPUT_EVENT_TABLET_PROXIMITY_OUT
};
struct libinput;
@ -288,8 +298,8 @@ struct libinput_event_touch;
* @struct libinput_event_tablet
*
* Tablet event representing an axis update, button press, or tool update. Valid
* event types for this event are @ref LIBINPUT_EVENT_TABLET_AXIS, and
* @ref LIBINPUT_EVENT_TABLET_TOOL_UPDATE.
* event types for this event are @ref LIBINPUT_EVENT_TABLET_AXIS, @ref
* LIBINPUT_EVENT_TABLET_TOOL_UPDATE and @ref LIBINPUT_EVENT_TABLET_TOOL_UPDATE.
*/
struct libinput_event_tablet;