tablet: fake a BTN_TOOL_PEN on the first event if needed

Some (?) Aiptek tablets have BTN_TOOL_PEN but aren't inclined to actually send
this on proximity in. This means we don't have a tool assigned and ignore the
events.

This patch piggy-backs on the already-existing proximity-out quirks. On the
first EV_SYN and if the tool is still NONE (i.e. no BTN_TOOL_* was received), we
pretend that we've earlier forced a proximity-out event for this tablet. This
causes the proximity-out quirk code to emulate a proximity in and we're off.
Hooray.

https://bugs.freedesktop.org/show_bug.cgi?id=104911

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2018-02-06 14:22:01 +10:00
parent ee2b58a66f
commit 2191ed6cc0

View file

@ -1696,13 +1696,27 @@ tablet_proximity_out_quirk_timer_func(uint64_t now, void *data)
* We need to remember that we did that, on the first event after the
* timeout we need to inject a BTN_TOOL_PEN event again to force proximity
* in.
*
* Other tools never send the BTN_TOOL_PEN event. For those tools, we
* piggyback along with the proximity out quirks by injecting
* the event during the first event frame.
*/
static inline void
tablet_proximity_out_quirk_update(struct tablet_dispatch *tablet,
struct evdev_device *device,
struct input_event *e,
uint64_t time)
tablet_proximity_quirk_update(struct tablet_dispatch *tablet,
struct evdev_device *device,
struct input_event *e,
uint64_t time)
{
/* LIBINPUT_TOOL_NONE can only happpen on the first event after
* init. By pretending we forced a proximity out, we can inject a
* BTN_TOOL_PEN and move on from there. */
if (e->type == EV_SYN &&
tablet_has_status(tablet, TABLET_AXES_UPDATED) &&
tablet->current_tool_type == LIBINPUT_TOOL_NONE) {
tablet->quirks.proximity_out_forced = true;
tablet->quirks.need_to_force_prox_out = true;
}
if (!tablet->quirks.need_to_force_prox_out)
return;
@ -1751,7 +1765,7 @@ tablet_process(struct evdev_dispatch *dispatch,
struct tablet_dispatch *tablet = tablet_dispatch(dispatch);
/* Warning: this may inject events */
tablet_proximity_out_quirk_update(tablet, device, e, time);
tablet_proximity_quirk_update(tablet, device, e, time);
switch (e->type) {
case EV_ABS:
@ -2065,14 +2079,14 @@ tablet_init(struct tablet_dispatch *tablet,
if (device->model_flags & EVDEV_MODEL_TABLET_NO_PROXIMITY_OUT)
want_proximity_quirk = true;
if (want_proximity_quirk) {
if (want_proximity_quirk)
tablet->quirks.need_to_force_prox_out = true;
libinput_timer_init(&tablet->quirks.prox_out_timer,
tablet_libinput_context(tablet),
"proxout",
tablet_proximity_out_quirk_timer_func,
tablet);
}
libinput_timer_init(&tablet->quirks.prox_out_timer,
tablet_libinput_context(tablet),
"proxout",
tablet_proximity_out_quirk_timer_func,
tablet);
return 0;
}