--- v3
+++ v2
@@ -1,43 +1,99 @@
-"4-finger scroll" is a gesture supported by some applications and
-operating systems.
+From: Daniel Kurtz <djkurtz@chromium.org>
-"Resting thumb" is when a clickpad user rests a finger (e.g., a
-thumb), in a "click zone" (typically the bottom of the touchpad) in
-anticipation of click+move=select gestures.
+As long as we know which slots are currently contained in SGM and AGM
+packets, it is possible to track the slot 0 finger when transitioning from
+2->3 fingers. This is the case when fingers are being added one at a
+time, 1->2->3.
-Thus, "4-finger scroll + resting thumb" is a 5-finger gesture.
-To allow userspace to detect this gesture, we send BTN_TOOL_QUINTTAP.
+However, when fingers are removed, we sometimes lose track of which slots
+are contained in SGM and AGM. In particular, when transitioning from 3->2
+and sometimes 3->1. In both of these cases, we can no longer track slot 0
+during 2->3 transitions.
Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
-Acked-by: Chase Douglas <chase.douglas@canonical.com>
---
- drivers/input/input-mt.c | 1 +
- include/linux/input.h | 1 +
- 2 files changed, 2 insertions(+), 0 deletions(-)
+ drivers/input/mouse/synaptics.c | 33 +++++++++++++++++++++++++++------
+ drivers/input/mouse/synaptics.h | 1 +
+ 2 files changed, 28 insertions(+), 6 deletions(-)
-diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
-index c48c81f..9150ee7 100644
---- a/drivers/input/input-mt.c
-+++ b/drivers/input/input-mt.c
-@@ -117,6 +117,7 @@ void input_mt_report_finger_count(struct input_dev *dev, int count)
- input_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, count == 2);
- input_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, count == 3);
- input_event(dev, EV_KEY, BTN_TOOL_QUADTAP, count == 4);
-+ input_event(dev, EV_KEY, BTN_TOOL_QUINTTAP, count == 5);
+diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
+index b626b98..893e567 100644
+--- a/drivers/input/mouse/synaptics.c
++++ b/drivers/input/mouse/synaptics.c
+@@ -659,6 +659,7 @@ static void synaptics_image_sensor_0f(struct synaptics_data *priv,
+ struct synaptics_mt_state *mt_state)
+ {
+ synaptics_mt_state_set(mt_state, 0, -1, -1);
++ priv->mt_state_lost = false;
}
- EXPORT_SYMBOL(input_mt_report_finger_count);
-diff --git a/include/linux/input.h b/include/linux/input.h
-index 068784e..4de4b46 100644
---- a/include/linux/input.h
-+++ b/include/linux/input.h
-@@ -503,6 +503,7 @@ struct input_keymap_entry {
- #define BTN_TOOL_FINGER 0x145
- #define BTN_TOOL_MOUSE 0x146
- #define BTN_TOOL_LENS 0x147
-+#define BTN_TOOL_QUINTTAP 0x148 /* Five fingers on trackpad */
- #define BTN_TOUCH 0x14a
- #define BTN_STYLUS 0x14b
- #define BTN_STYLUS2 0x14c
+ /* Handle case where mt_state->count = 1 */
+@@ -726,6 +727,7 @@ static void synaptics_image_sensor_1f(struct synaptics_data *priv,
+ * So, empty all slots. We will guess slot 0 on subsequent 1->1
+ */
+ synaptics_mt_state_set(mt_state, 0, -1, -1);
++ priv->mt_state_lost = true;
+ break;
+ }
+ }
+@@ -771,6 +773,7 @@ static void synaptics_image_sensor_2f(struct synaptics_data *priv,
+ * subsequent 2->2
+ */
+ synaptics_mt_state_set(mt_state, 0, -1, -1);
++ priv->mt_state_lost = true;
+ break;
+ }
+ }
+@@ -800,14 +803,32 @@ static void synaptics_image_sensor_3f(struct synaptics_data *priv,
+ break;
+ case 2:
+ /*
+- * On 2->3 transitions, we are given no indication which finger
+- * was added.
+- * We don't even know what finger the current AGM packet
+- * contained.
++ * After some 3->1 and all 3->2 transitions, we lose track
++ * of which slot is reported by sgm and agm.
+ *
+- * So, empty all slots. They get filled on a subsequent 3->3
++ * For 2->3 in this state, empty all slots, and we will guess
++ * (0,1) on a subsequent 0->3.
++ *
++ * To userspace, the resulting transition will look like:
++ * 2:[0,1] -> 0:[-1,-1] -> 3:[0,2]
+ */
+- synaptics_mt_state_set(mt_state, 0, -1, -1);
++ if (priv->mt_state_lost) {
++ synaptics_mt_state_set(mt_state, 0, -1, -1);
++ break;
++ }
++
++ /*
++ * If the (SGM,AGM) really previously contained slots (0, 1),
++ * then we cannot know what slot was just reported by the AGM,
++ * because the 2->3 transition can occur either before or after
++ * the AGM packet. Thus, this most recent AGM could contain
++ * either the same old slot 1 or the new slot 2.
++ * Subsequent AGMs will be reporting slot 2.
++ *
++ * To userspace, the resulting transition will look like:
++ * 2:[0,1] -> 1:[0,-1] -> 3:[0,2]
++ */
++ synaptics_mt_state_set(mt_state, 1, 0, -1);
+ break;
+ case 3:
+ /*
+diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
+index 87be1fe..e3edfea 100644
+--- a/drivers/input/mouse/synaptics.h
++++ b/drivers/input/mouse/synaptics.h
+@@ -162,6 +162,7 @@ struct synaptics_data {
+ struct serio *pt_port; /* Pass-through serio port */
+
+ struct synaptics_mt_state mt_state; /* Current mt finger state */
++ bool mt_state_lost; /* mt_state may be incorrect */
+
+ /*
+ * Last received Advanced Gesture Mode (AGM) packet. An AGM packet
--
1.7.3.1