diff options
| author | Daniel Kurtz <djkurtz@chromium.org> | 2013-02-13 16:53:07 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-02-13 23:21:12 -0500 |
| commit | 48064bdcd6d1c27ad0a35103eb8cee2d087940d9 (patch) | |
| tree | 0c567d4046c03be803fcdeadec5426ce412ae617 /drivers/input/mouse | |
| parent | d722260d233949ec531c684248a88cb163608851 (diff) | |
Input: synaptics - fix 1->3 contact transition reporting
Investigating the following gesture highlighted two slight implementation
errors with choosing which slots to report in which slot when multiple
contacts are present:
Action SGM AGM (MTB slot:Contact)
1. Touch contact 0 (0:0)
2. Touch contact 1 (0:0, 1:1)
3. Lift contact 0 (1:1)
4. Touch contacts 2,3 (0:2, 1:3)
In step 4, slot 1 was not being cleared first, which means the same
tracking ID was being used for reporting both the old contact 1 and the
new contact 3. This could result in "drumroll", where the old contact 1
would appear to suddenly jump to new finger 3 position.
Similarly, if contacts 2 & 3 are not detected at the same sample, step 4
is split into two:
Action SGM AGM (MTB slot:contact)
1. Touch contact 0 (0:0)
2. Touch contact 1 (0:0, 1:1)
3. Lift contact 0 (1:1)
4. Touch contact 2 (0:2, 1:1)
5. Touch contact 3 (0:2, 1:3)
In this case, there was also a bug. In step 4, when contact 1 moves from
SGM to AGM and contact 2 is first reported in SGM, slot 0 was actually
empty. So slot 0 can be used to report the new SGM (contact 0),
immediately. Since it was empty, contact 2 in slot 0 will get a new
tracking ID.
Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/mouse')
| -rw-r--r-- | drivers/input/mouse/synaptics.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 12d12ca3fee0..c3d1c86ac591 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
| @@ -722,11 +722,13 @@ static void synaptics_report_mt_data(struct psmouse *psmouse, | |||
| 722 | default: | 722 | default: |
| 723 | /* | 723 | /* |
| 724 | * If the finger slot contained in SGM is valid, and either | 724 | * If the finger slot contained in SGM is valid, and either |
| 725 | * hasn't changed, or is new, then report SGM in MTB slot 0. | 725 | * hasn't changed, or is new, or the old SGM has now moved to |
| 726 | * AGM, then report SGM in MTB slot 0. | ||
| 726 | * Otherwise, empty MTB slot 0. | 727 | * Otherwise, empty MTB slot 0. |
| 727 | */ | 728 | */ |
| 728 | if (mt_state->sgm != -1 && | 729 | if (mt_state->sgm != -1 && |
| 729 | (mt_state->sgm == old->sgm || old->sgm == -1)) | 730 | (mt_state->sgm == old->sgm || |
| 731 | old->sgm == -1 || mt_state->agm == old->sgm)) | ||
| 730 | synaptics_report_slot(dev, 0, sgm); | 732 | synaptics_report_slot(dev, 0, sgm); |
| 731 | else | 733 | else |
| 732 | synaptics_report_slot(dev, 0, NULL); | 734 | synaptics_report_slot(dev, 0, NULL); |
| @@ -735,9 +737,31 @@ static void synaptics_report_mt_data(struct psmouse *psmouse, | |||
| 735 | * If the finger slot contained in AGM is valid, and either | 737 | * If the finger slot contained in AGM is valid, and either |
| 736 | * hasn't changed, or is new, then report AGM in MTB slot 1. | 738 | * hasn't changed, or is new, then report AGM in MTB slot 1. |
| 737 | * Otherwise, empty MTB slot 1. | 739 | * Otherwise, empty MTB slot 1. |
| 740 | * | ||
| 741 | * However, in the case where the AGM is new, make sure that | ||
| 742 | * that it is either the same as the old SGM, or there was no | ||
| 743 | * SGM. | ||
| 744 | * | ||
| 745 | * Otherwise, if the SGM was just 1, and the new AGM is 2, then | ||
| 746 | * the new AGM will keep the old SGM's tracking ID, which can | ||
| 747 | * cause apparent drumroll. This happens if in the following | ||
| 748 | * valid finger sequence: | ||
| 749 | * | ||
| 750 | * Action SGM AGM (MTB slot:Contact) | ||
| 751 | * 1. Touch contact 0 (0:0) | ||
| 752 | * 2. Touch contact 1 (0:0, 1:1) | ||
| 753 | * 3. Lift contact 0 (1:1) | ||
| 754 | * 4. Touch contacts 2,3 (0:2, 1:3) | ||
| 755 | * | ||
| 756 | * In step 4, contact 3, in AGM must not be given the same | ||
| 757 | * tracking ID as contact 1 had in step 3. To avoid this, | ||
| 758 | * the first agm with contact 3 is dropped and slot 1 is | ||
| 759 | * invalidated (tracking ID = -1). | ||
| 738 | */ | 760 | */ |
| 739 | if (mt_state->agm != -1 && | 761 | if (mt_state->agm != -1 && |
| 740 | (mt_state->agm == old->agm || old->agm == -1)) | 762 | (mt_state->agm == old->agm || |
| 763 | (old->agm == -1 && | ||
| 764 | (old->sgm == -1 || mt_state->agm == old->sgm)))) | ||
| 741 | synaptics_report_slot(dev, 1, agm); | 765 | synaptics_report_slot(dev, 1, agm); |
| 742 | else | 766 | else |
| 743 | synaptics_report_slot(dev, 1, NULL); | 767 | synaptics_report_slot(dev, 1, NULL); |
