[PATCH libinput 1/6] touchpad: factor out fake finger handling

Peter Hutterer peter.hutterer at who-t.net
Mon Dec 15 19:14:46 PST 2014


We need this for determining hovering touches on some semi-mt touchpads.

This makes the fake_touches mask use bit 1 for BTN_TOUCH, and the other bits
for BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP, etc. BTN_TOUCH is independent of the
rest, the others are mutually exclusive in the kernel.

Since the mask isn't a straightforward bitmask anymore, abstract it all
through helper functions.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-mt-touchpad.c | 72 ++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 53 insertions(+), 19 deletions(-)

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 32d6eac..42c163b 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -135,6 +135,57 @@ tp_get_touch(struct tp_dispatch *tp, unsigned int slot)
 	return &tp->touches[slot];
 }
 
+static inline int
+tp_fake_finger_count(struct tp_dispatch *tp)
+{
+	unsigned int fake_touches, nfake_touches;
+
+	/* don't count BTN_TOUCH */
+	fake_touches = tp->fake_touches >> 1;
+	nfake_touches = 0;
+	while (fake_touches) {
+		nfake_touches++;
+		fake_touches >>= 1;
+	}
+
+	return nfake_touches;
+}
+
+static inline bool
+tp_fake_finger_is_touching(struct tp_dispatch *tp)
+{
+	return tp->fake_touches & 0x1;
+}
+
+static inline void
+tp_fake_finger_set(struct tp_dispatch *tp,
+		   unsigned int code,
+		   bool is_press)
+{
+	unsigned int shift;
+
+	switch (code) {
+	case BTN_TOUCH:
+		shift = 0;
+		break;
+	case BTN_TOOL_FINGER:
+		shift = 1;
+		break;
+	case BTN_TOOL_DOUBLETAP:
+	case BTN_TOOL_TRIPLETAP:
+	case BTN_TOOL_QUADTAP:
+		shift = code - BTN_TOOL_DOUBLETAP + 2;
+		break;
+	default:
+		return;
+	}
+
+	if (is_press)
+		tp->fake_touches |= 1 << shift;
+	else
+		tp->fake_touches &= ~(0x1 << shift);
+}
+
 static inline void
 tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
 {
@@ -253,30 +304,13 @@ tp_process_fake_touch(struct tp_dispatch *tp,
 		      uint64_t time)
 {
 	struct tp_touch *t;
-	unsigned int fake_touches;
 	unsigned int nfake_touches;
 	unsigned int i, start;
-	unsigned int shift;
 
-	if (e->code != BTN_TOUCH &&
-	    (e->code < BTN_TOOL_DOUBLETAP || e->code > BTN_TOOL_QUADTAP))
-		return;
+	tp_fake_finger_set(tp, e->code, e->value != 0);
 
-	shift = e->code == BTN_TOUCH ? 0 : (e->code - BTN_TOOL_DOUBLETAP + 1);
+	nfake_touches = tp_fake_finger_count(tp);
 
-	if (e->value)
-		tp->fake_touches |= 1 << shift;
-	else
-		tp->fake_touches &= ~(0x1 << shift);
-
-	fake_touches = tp->fake_touches;
-	nfake_touches = 0;
-	while (fake_touches) {
-		nfake_touches++;
-		fake_touches >>= 1;
-	}
-
-	/* For single touch tps we use BTN_TOUCH for begin / end of touch 0 */
 	start = tp->has_mt ? tp->real_touches : 0;
 	for (i = start; i < tp->ntouches; i++) {
 		t = tp_get_touch(tp, i);
-- 
2.1.0



More information about the wayland-devel mailing list