summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2015-01-28 15:38:00 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2015-01-29 14:43:57 +1000
commit428614bb242a85a0b46f1a60bc822dbb47327b31 (patch)
tree97d928da6ea6b18a90eadddbcc55b823be3051ca
parent82bb5841a2303b9bef2d6d390323aec5eb5dea45 (diff)
touchpad: re-route trackpoint buttons on the *50 Lenovo series
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@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
-rw-r--r--src/evdev-mt-touchpad.c44
-rw-r--r--src/evdev.h1
2 files changed, 45 insertions, 0 deletions
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 5221be60..ae37ab17 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 0f2c5acc..fc70a287 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 {