[PATCH libinput] touchpad: mark ALPS touchpads for middle button emulation

Peter Hutterer peter.hutterer at who-t.net
Mon Jun 15 20:19:48 PDT 2015


Alps devices don't know if there is a physical middle button on the touchpad,
so they always report one.
Since a large number of touchpads only have two buttons, enable middle button
emulation by default. Those that really don't want it can play with
configuration options, everyone else has it working by default.

The hwdb entry uses "*Alps ..*" as name to also trigger the "litest Alps..."
devices.

https://bugzilla.redhat.com/show_bug.cgi?id=1227992

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-mt-touchpad-buttons.c    | 33 ++++++++++++++++++++++++++++++---
 src/evdev.c                        |  1 +
 src/evdev.h                        |  1 +
 test/pointer.c                     | 24 ++++++++++++++++++++++++
 udev/90-libinput-model-quirks.hwdb |  7 +++++++
 5 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
index eb0ddcb..6689db3 100644
--- a/src/evdev-mt-touchpad-buttons.c
+++ b/src/evdev-mt-touchpad-buttons.c
@@ -677,6 +677,35 @@ tp_button_config_click_get_default_method(struct libinput_device *device)
 	return tp_click_get_default_method(tp);
 }
 
+static inline void
+tp_init_middlebutton_emulation(struct tp_dispatch *tp,
+			       struct evdev_device *device)
+{
+	bool enable_by_default,
+	     want_config_option;
+
+	if (tp->buttons.is_clickpad)
+		return;
+
+	/* init middle button emulation on non-clickpads, but only if we
+	 * don't have a middle button. Exception: ALPS touchpads don't know
+	 * if they have a middle button, so we always want the option there
+	 * and enabled by default.
+	 */
+	if (!libevdev_has_event_code(device->evdev, EV_KEY, BTN_MIDDLE)) {
+		enable_by_default = true;
+		want_config_option = false;
+	} else if (device->model == EVDEV_MODEL_ALPS_TOUCHPAD) {
+		enable_by_default = true;
+		want_config_option = true;
+	} else
+		return;
+
+	evdev_init_middlebutton(tp->device,
+				enable_by_default,
+				want_config_option);
+}
+
 int
 tp_init_buttons(struct tp_dispatch *tp,
 		struct evdev_device *device)
@@ -733,9 +762,7 @@ tp_init_buttons(struct tp_dispatch *tp,
 
 	tp_init_top_softbuttons(tp, device, 1.0);
 
-	if (!tp->buttons.is_clickpad &&
-	    !libevdev_has_event_code(device->evdev, EV_KEY, BTN_MIDDLE))
-		evdev_init_middlebutton(tp->device, true, false);
+	tp_init_middlebutton_emulation(tp, device);
 
 	tp_for_each_touch(tp, t) {
 		t->button.state = BUTTON_STATE_NONE;
diff --git a/src/evdev.c b/src/evdev.c
index b8f798e..294630f 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1515,6 +1515,7 @@ evdev_read_model(struct evdev_device *device)
 		{ "LIBINPUT_MODEL_CLEVO_W740SU", EVDEV_MODEL_CLEVO_W740SU },
 		{ "LIBINPUT_MODEL_APPLE_TOUCHPAD", EVDEV_MODEL_APPLE_TOUCHPAD },
 		{ "LIBINPUT_MODEL_WACOM_TOUCHPAD", EVDEV_MODEL_WACOM_TOUCHPAD },
+		{ "LIBINPUT_MODEL_ALPS_TOUCHPAD", EVDEV_MODEL_ALPS_TOUCHPAD },
 		{ NULL, EVDEV_MODEL_DEFAULT },
 	};
 	const struct model_map *m = model_map;
diff --git a/src/evdev.h b/src/evdev.h
index f074ad7..7dd239a 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -105,6 +105,7 @@ enum evdev_device_model {
 	EVDEV_MODEL_CLEVO_W740SU,
 	EVDEV_MODEL_APPLE_TOUCHPAD,
 	EVDEV_MODEL_WACOM_TOUCHPAD,
+	EVDEV_MODEL_ALPS_TOUCHPAD,
 };
 
 struct mt_slot {
diff --git a/test/pointer.c b/test/pointer.c
index 2918754..bc480c3 100644
--- a/test/pointer.c
+++ b/test/pointer.c
@@ -1279,6 +1279,10 @@ START_TEST(middlebutton_default_touchpad)
 	enum libinput_config_middle_emulation_state state;
 	int available;
 
+	if (streq(libinput_device_get_name(dev->libinput_device),
+					   "litest AlpsPS/2 ALPS GlidePoint"))
+	    return;
+
 	available = libinput_device_config_middle_emulation_is_available(device);
 	ck_assert(!available);
 
@@ -1294,6 +1298,25 @@ START_TEST(middlebutton_default_touchpad)
 }
 END_TEST
 
+START_TEST(middlebutton_default_alps)
+{
+	struct litest_device *dev = litest_current_device();
+	struct libinput_device *device = dev->libinput_device;
+	enum libinput_config_middle_emulation_state state;
+	int available;
+
+	available = libinput_device_config_middle_emulation_is_available(device);
+	ck_assert(available);
+
+	state = libinput_device_config_middle_emulation_get_enabled(
+					    device);
+	ck_assert_int_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
+	state = libinput_device_config_middle_emulation_get_default_enabled(
+					    device);
+	ck_assert_int_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
+}
+END_TEST
+
 START_TEST(middlebutton_default_disabled)
 {
 	struct litest_device *dev = litest_current_device();
@@ -1359,6 +1382,7 @@ litest_setup_tests(void)
 	litest_add("pointer:middlebutton", middlebutton_default_clickpad, LITEST_CLICKPAD, LITEST_ANY);
 	litest_add("pointer:middlebutton", middlebutton_default_touchpad, LITEST_TOUCHPAD, LITEST_CLICKPAD);
 	litest_add("pointer:middlebutton", middlebutton_default_disabled, LITEST_ANY, LITEST_BUTTON);
+	litest_add_for_device("pointer:middlebutton", middlebutton_default_alps, LITEST_ALPS_SEMI_MT);
 
 	litest_add_ranged("pointer:state", pointer_absolute_initial_state, LITEST_ABSOLUTE, LITEST_ANY, &axis_range);
 }
diff --git a/udev/90-libinput-model-quirks.hwdb b/udev/90-libinput-model-quirks.hwdb
index 7442f82..cf57e9c 100644
--- a/udev/90-libinput-model-quirks.hwdb
+++ b/udev/90-libinput-model-quirks.hwdb
@@ -16,6 +16,13 @@
 # Sort by brand, model
 
 ##########################################
+# ALPS
+##########################################
+libinput:name:*AlpsPS/2 ALPS DualPoint TouchPad:dmi:*
+libinput:name:*AlpsPS/2 ALPS GlidePoint:dmi:*
+ LIBINPUT_MODEL_ALPS_TOUCHPAD=1
+
+##########################################
 # Apple
 ##########################################
 libinput:touchpad:input:b0003v05ACp*
-- 
2.4.3



More information about the wayland-devel mailing list