[PATCH libinput 14/19] touchpad: support single-touch touchpads

Peter Hutterer peter.hutterer at who-t.net
Sun Feb 16 22:48:33 PST 2014


Touchpads without ABS_MT_SLOT create 5 slots by default (for up to QUINTTAP)
and ABS_X/Y is mapped to the 0-slot touchpoint. This commit adds handling for
a single finger, no BTN_TOOL_DOUBLETAP or similar is being processed yet.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-mt-touchpad.c | 57 +++++++++++++++++++++++++++++++++++++++++++------
 src/evdev-mt-touchpad.h |  2 ++
 2 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index c4c4c41..f8edb8c 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -226,6 +226,28 @@ tp_process_absolute(struct tp_dispatch *tp,
 }
 
 static void
+tp_process_absolute_st(struct tp_dispatch *tp,
+		       const struct input_event *e,
+		       uint32_t time)
+{
+	struct tp_touch *t = tp_current_touch(tp);
+
+	switch(e->code) {
+	case ABS_X:
+		t->x = e->value;
+		t->millis = time;
+		t->dirty = true;
+		break;
+	case ABS_Y:
+		t->y = e->value;
+		t->millis = time;
+		t->dirty = true;
+		tp->queued |= TOUCHPAD_EVENT_MOTION;
+		break;
+	}
+}
+
+static void
 tp_process_key(struct tp_dispatch *tp,
 	       const struct input_event *e,
 	       uint32_t time)
@@ -245,6 +267,18 @@ tp_process_key(struct tp_dispatch *tp,
 				tp->queued |= TOUCHPAD_EVENT_BUTTON_RELEASE;
 			}
 			break;
+		case BTN_TOUCH:
+			if (!tp->has_mt) {
+				struct tp_touch *t = tp_current_touch(tp);
+				if (e->value) {
+					tp_begin_touch(tp, t);
+					t->fake = true;
+				} else {
+					tp_end_touch(tp, t);
+				}
+				t->millis = time;
+			}
+			break;
 	}
 }
 
@@ -271,9 +305,10 @@ tp_post_process_state(struct tp_dispatch *tp, uint32_t time)
 		if (!t->dirty)
 			continue;
 
-		if (t->state == TOUCH_END)
+		if (t->state == TOUCH_END) {
 			t->state = TOUCH_NONE;
-		else if (t->state == TOUCH_BEGIN)
+			t->fake = false;
+		} else if (t->state == TOUCH_BEGIN)
 			t->state = TOUCH_UPDATE;
 
 		t->dirty = false;
@@ -443,7 +478,10 @@ tp_process(struct evdev_dispatch *dispatch,
 
 	switch (e->type) {
 	case EV_ABS:
-		tp_process_absolute(tp, e, time);
+		if (tp->has_mt)
+			tp_process_absolute(tp, e, time);
+		else
+			tp_process_absolute_st(tp, e, time);
 		break;
 	case EV_KEY:
 		tp_process_key(tp, e, time);
@@ -479,12 +517,17 @@ tp_init_slots(struct tp_dispatch *tp,
 {
 	struct input_absinfo absinfo = {0};
 
-	ioctl(device->fd, EVIOCGABS(ABS_MT_SLOT), &absinfo);
-
-	tp->ntouches = absinfo.maximum + 1;
+	if (ioctl(device->fd, EVIOCGABS(ABS_MT_SLOT), &absinfo) == -1) {
+		tp->ntouches = 5; /* FIXME: based on DOUBLETAP, etc. */
+		tp->slot = 0;
+		tp->has_mt = false;
+	} else {
+		tp->ntouches = absinfo.maximum + 1;
+		tp->slot = absinfo.value;
+		tp->has_mt = true;
+	}
 	tp->touches = calloc(tp->ntouches,
 			     sizeof(struct tp_touch));
-	tp->slot = absinfo.value;
 
 	return 0;
 }
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 17e9055..1e09497 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -75,6 +75,7 @@ struct tp_motion {
 struct tp_touch {
 	enum touch_state state;
 	bool dirty;
+	bool fake;				/* a fake touch */
 	int32_t x;
 	int32_t y;
 	uint32_t millis;
@@ -96,6 +97,7 @@ struct tp_dispatch {
 	struct evdev_device *device;
 	unsigned int nfingers_down;		/* number of fingers down */
 	unsigned int slot;			/* current slot */
+	bool has_mt;
 
 	unsigned int ntouches;			/* number of slots */
 	struct tp_touch *touches;		/* len == ntouches */
-- 
1.8.4.2



More information about the wayland-devel mailing list