[PATCH libinput 3/4] touchpad: re-route trackpoint buttons on the *50 Lenovo series

Peter Hutterer peter.hutterer at who-t.net
Wed Jan 28 20:55:09 PST 2015


The laptops on this series have the physical trackpoint buttons back but
wired them up to the touchpad instead of the trackpoint device and they appear
as BTN_0, BTN_1 and BTN_2 for left, right, middle.

The udev hwdb marks these for us with the TOUCHPAD_HAS_TRACKPOINT_BUTTONS tag
[1]. Use that tag to identify them and re-route the events through the
trackstick device after mangling the event codes to represent the actual
buttons.

[1] http://cgit.freedesktop.org/systemd/systemd/tree/hwdb/70-touchpad.hwdb

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

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 5221be6..ae37ab1 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -350,6 +350,41 @@ tp_process_fake_touch(struct tp_dispatch *tp,
 }
 
 static void
+tp_process_trackpoint_button(struct tp_dispatch *tp,
+			     const struct input_event *e,
+			     uint64_t time)
+{
+	struct evdev_dispatch *dispatch;
+	struct input_event event;
+
+	if (!tp->buttons.trackpoint ||
+	    (tp->device->tags & EVDEV_TAG_TOUCHPAD_TRACKPOINT) == 0)
+		return;
+
+	dispatch = tp->buttons.trackpoint->dispatch;
+
+	event = *e;
+
+	switch (event.code) {
+	case BTN_0:
+		event.code = BTN_LEFT;
+		break;
+	case BTN_1:
+		event.code = BTN_RIGHT;
+		break;
+	case BTN_2:
+		event.code = BTN_MIDDLE;
+		break;
+	default:
+		return;
+	}
+
+	dispatch->interface->process(dispatch,
+				     tp->buttons.trackpoint,
+				     &event, time);
+}
+
+static void
 tp_process_key(struct tp_dispatch *tp,
 	       const struct input_event *e,
 	       uint64_t time)
@@ -367,6 +402,11 @@ tp_process_key(struct tp_dispatch *tp,
 		case BTN_TOOL_QUADTAP:
 			tp_process_fake_touch(tp, e, time);
 			break;
+		case BTN_0:
+		case BTN_1:
+		case BTN_2:
+			tp_process_trackpoint_button(tp, e, time);
+			break;
 	}
 }
 
@@ -1063,6 +1103,10 @@ tp_tag_device(struct evdev_device *device,
 			 device->tags |= EVDEV_TAG_INTERNAL_TOUCHPAD;
 	} else if (bustype != BUS_BLUETOOTH)
 		device->tags |= EVDEV_TAG_INTERNAL_TOUCHPAD;
+
+	if (udev_device_get_property_value(udev_device,
+					   "TOUCHPAD_HAS_TRACKPOINT_BUTTONS"))
+		device->tags |= EVDEV_TAG_TOUCHPAD_TRACKPOINT;
 }
 
 static struct evdev_dispatch_interface tp_interface = {
diff --git a/src/evdev.h b/src/evdev.h
index 0f2c5ac..fc70a28 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -54,6 +54,7 @@ enum evdev_device_tags {
 	EVDEV_TAG_EXTERNAL_MOUSE = (1 << 0),
 	EVDEV_TAG_INTERNAL_TOUCHPAD = (1 << 1),
 	EVDEV_TAG_TRACKPOINT = (1 << 2),
+	EVDEV_TAG_TOUCHPAD_TRACKPOINT = (1 << 3),
 };
 
 struct mt_slot {
-- 
2.1.0



More information about the wayland-devel mailing list