summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChase Douglas <chase.douglas@canonical.com>2012-02-21 21:42:16 +0100
committerPeter Hutterer <peter.hutterer@who-t.net>2012-02-23 10:59:15 +1000
commit0a2fd560aa965ceac64c8fb047ca90006408a6f4 (patch)
tree05bea37b165ac6f61bb88dbc3b3be18501738e40 /src
parentdfc3a8ed713c2878407c6443c4d3092da3125e0c (diff)
Update touch state when device is off too
If the device is turned off, usually by syndaemon to disable the touchpad while the typing, the touch state will not be updated with the latest hardware state changes. If a touch begins while the device is off and ends while the device is on, then the touch count will be decremented without any previous increment. A similar effect will occur if the device is on when the touch begins, but off when the touch ends. If the touch count goes negative, the index into the touch slot mask array will be out of bounds. This can corrupt memory and cause random crashes. Signed-off-by: Chase Douglas <chase.douglas@canonical.com> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'src')
-rw-r--r--src/synaptics.c74
1 files changed, 41 insertions, 33 deletions
diff --git a/src/synaptics.c b/src/synaptics.c
index 65b48ee..4784157 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -2596,6 +2596,42 @@ repeat_scrollbuttons(const InputInfoPtr pInfo,
return delay;
}
+/* Update the open slots and number of active touches */
+static void
+UpdateTouchState(InputInfoPtr pInfo, struct SynapticsHwState *hw)
+{
+#ifdef HAVE_MULTITOUCH
+ SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
+ int i;
+
+ for (i = 0; i < hw->num_mt_mask; i++)
+ {
+ if (hw->slot_state[i] == SLOTSTATE_OPEN)
+ {
+ priv->open_slots[priv->num_active_touches] = i;
+ priv->num_active_touches++;
+ } else if (hw->slot_state[i] == SLOTSTATE_CLOSE)
+ {
+ Bool found = FALSE;
+ int j;
+
+ for (j = 0; j < priv->num_active_touches - 1; j++)
+ {
+ if (priv->open_slots[j] == i)
+ found = TRUE;
+
+ if (found)
+ priv->open_slots[j] = priv->open_slots[j + 1];
+ }
+
+ priv->num_active_touches--;
+ }
+ }
+
+ SynapticsResetTouchHwState(hw);
+#endif
+}
+
static void
HandleTouches(InputInfoPtr pInfo, struct SynapticsHwState *hw)
{
@@ -2675,40 +2711,9 @@ HandleTouches(InputInfoPtr pInfo, struct SynapticsHwState *hw)
xf86PostTouchEvent(pInfo->dev, slot, XI_TouchEnd, 0,
hw->mt_mask[slot]);
}
-
-out:
- /* Update the open slots and number of active touches */
- for (i = 0; i < hw->num_mt_mask; i++)
- {
- if (hw->slot_state[i] == SLOTSTATE_OPEN)
- {
- priv->open_slots[priv->num_active_touches] = i;
- priv->num_active_touches++;
- } else if (hw->slot_state[i] == SLOTSTATE_CLOSE)
- {
- Bool found = FALSE;
- int j;
- for (j = 0; j < priv->num_active_touches - 1; j++)
- {
- if (priv->open_slots[j] == i)
- found = TRUE;
-
- if (found)
- priv->open_slots[j] = priv->open_slots[j + 1];
- }
-
- priv->num_active_touches--;
- }
- }
-
- /* We calculated the value twice, might as well double check our math */
- if (priv->num_active_touches != new_active_touches)
- xf86IDrvMsg(pInfo, X_WARNING,
- "calculated wrong number of active touches (%d vs %d)\n",
- priv->num_active_touches, new_active_touches);
-
- SynapticsResetTouchHwState(hw);
+out:
+ UpdateTouchState(pInfo, hw);
#endif
}
@@ -2741,7 +2746,10 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
/* If touchpad is switched off, we skip the whole thing and return delay */
if (para->touchpad_off == 1)
+ {
+ UpdateTouchState(pInfo, hw);
return delay;
+ }
/* apply hysteresis before doing anything serious. This cancels
* out a lot of noise which might surface in strange phenomena