[PATCH libinput 7/8] tablet: fake a BTN_TOOL_PEN on the first event if needed

Peter Hutterer peter.hutterer at who-t.net
Wed Feb 7 01:45:05 UTC 2018


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 at who-t.net>
---
 src/evdev-tablet.c | 38 ++++++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
index 2480bbfe..c2de8ac8 100644
--- a/src/evdev-tablet.c
+++ b/src/evdev-tablet.c
@@ -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;
 }
-- 
2.14.3



More information about the wayland-devel mailing list