[PATCH libinput 2/3] touchpad: implement configurable button mapping for tapping

Peter Hutterer peter.hutterer at who-t.net
Fri Jul 22 02:46:53 UTC 2016


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

diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c
index 3ca4f95..d9e1e3a 100644
--- a/src/evdev-mt-touchpad-tap.c
+++ b/src/evdev-mt-touchpad-tap.c
@@ -105,14 +105,17 @@ tp_tap_notify(struct tp_dispatch *tp,
 	      enum libinput_button_state state)
 {
 	int32_t button;
+	int32_t button_map[2][3] = {
+		{ BTN_LEFT, BTN_RIGHT, BTN_MIDDLE },
+		{ BTN_LEFT, BTN_MIDDLE, BTN_RIGHT },
+	};
 
-	switch (nfingers) {
-	case 1: button = BTN_LEFT; break;
-	case 2: button = BTN_RIGHT; break;
-	case 3: button = BTN_MIDDLE; break;
-	default:
+	assert(tp->tap.map < ARRAY_LENGTH(button_map));
+
+	if (nfingers > 3)
 		return;
-	}
+
+	button = button_map[tp->tap.map][nfingers - 1];
 
 	if (state == LIBINPUT_BUTTON_STATE_PRESSED)
 		tp->tap.buttons_pressed |= (1 << nfingers);
@@ -827,6 +830,22 @@ tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time)
 	return filter_motion;
 }
 
+static inline void
+tp_tap_update_map(struct tp_dispatch *tp)
+{
+	if (tp->tap.state != TAP_STATE_IDLE)
+		return;
+
+	if (tp->tap.map != tp->tap.want_map)
+		tp->tap.map = tp->tap.want_map;
+}
+
+void
+tp_tap_post_process_state(struct tp_dispatch *tp)
+{
+	tp_tap_update_map(tp);
+}
+
 static void
 tp_tap_handle_timeout(uint64_t time, void *data)
 {
@@ -938,13 +957,26 @@ static enum libinput_config_status
 tp_tap_config_set_map(struct libinput_device *device,
 		      enum libinput_config_tap_button_map map)
 {
-	return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
+	struct evdev_dispatch *dispatch = ((struct evdev_device *) device)->dispatch;
+	struct tp_dispatch *tp = NULL;
+
+	tp = container_of(dispatch, tp, base);
+	tp->tap.want_map = map;
+
+	tp_tap_update_map(tp);
+
+	return LIBINPUT_CONFIG_STATUS_SUCCESS;
 }
 
 static enum libinput_config_tap_button_map
 tp_tap_config_get_map(struct libinput_device *device)
 {
-	return LIBINPUT_CONFIG_TAP_MAP_LRM;
+	struct evdev_dispatch *dispatch = ((struct evdev_device *) device)->dispatch;
+	struct tp_dispatch *tp = NULL;
+
+	tp = container_of(dispatch, tp, base);
+
+	return tp->tap.want_map;
 }
 
 static enum libinput_config_tap_button_map
@@ -1049,6 +1081,8 @@ tp_init_tap(struct tp_dispatch *tp)
 
 	tp->tap.state = TAP_STATE_IDLE;
 	tp->tap.enabled = tp_tap_default(tp->device);
+	tp->tap.map = LIBINPUT_CONFIG_TAP_MAP_LRM;
+	tp->tap.want_map = tp->tap.map;
 	tp->tap.drag_enabled = tp_drag_default(tp->device);
 	tp->tap.drag_lock_enabled = tp_drag_lock_default(tp->device);
 
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index fa398e2..b2605b1 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -1110,6 +1110,8 @@ tp_post_process_state(struct tp_dispatch *tp, uint64_t time)
 	tp->buttons.old_state = tp->buttons.state;
 
 	tp->queued = TOUCHPAD_EVENT_NONE;
+
+	tp_tap_post_process_state(tp);
 }
 
 static void
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 86dd048..c3c876f 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -322,6 +322,9 @@ struct tp_dispatch {
 		uint32_t buttons_pressed;
 		uint64_t first_press_time;
 
+		enum libinput_config_tap_button_map map;
+		enum libinput_config_tap_button_map want_map;
+
 		bool drag_enabled;
 		bool drag_lock_enabled;
 	} tap;
@@ -429,6 +432,9 @@ int
 tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time);
 
 void
+tp_tap_post_process_state(struct tp_dispatch *tp);
+
+void
 tp_init_tap(struct tp_dispatch *tp);
 
 void
-- 
2.7.4



More information about the wayland-devel mailing list