From: Derek Foreman <[email protected]>

Make the palm-check logic more stable and reliable, and make sure that
any palms are blocked for the duration of their presses.

Signed-off-by: Derek Foreman <[email protected]>
Reviewed-by: Daniel Stone <[email protected]>
---
 src/synaptics.c    |   54 +++++++++++++++++++++++++++------------------------
 src/synapticsstr.h |    3 +-
 2 files changed, 30 insertions(+), 27 deletions(-)

diff --git a/src/synaptics.c b/src/synaptics.c
index 4c408d9..7a540ae 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -1353,12 +1353,16 @@ SynapticsDetectFinger(SynapticsPrivate *priv, struct 
SynapticsHwState *hw)
     enum FingerState finger;
 
     /* finger detection thru pressure and threshold */
+    if (hw->z < para->finger_low)
+        return FS_UNTOUCHED;
+
+    if (priv->finger_state == FS_BLOCKED)
+        return FS_BLOCKED;
+
     if (hw->z > para->finger_press && priv->finger_state < FS_PRESSED)
         finger = FS_PRESSED;
-    else if (hw->z > para->finger_high && priv->finger_state < FS_TOUCHED)
+    else if (hw->z > para->finger_high && priv->finger_state == FS_UNTOUCHED)
         finger = FS_TOUCHED;
-    else if (hw->z < para->finger_low &&  priv->finger_state > FS_UNTOUCHED)
-        finger = FS_UNTOUCHED;
     else
        finger = priv->finger_state;
 
@@ -1366,17 +1370,16 @@ SynapticsDetectFinger(SynapticsPrivate *priv, struct 
SynapticsHwState *hw)
        return finger;
 
     /* palm detection */
-    if (finger) {
-       if ((hw->z > para->palm_min_z) && (hw->fingerWidth > 
para->palm_min_width))
-           priv->palm = TRUE;
-    } else {
-       priv->palm = FALSE;
-    }
-    if (hw->x == 0)
+
+    if ((hw->z > para->palm_min_z) || (hw->fingerWidth > para->palm_min_width))
+        return FS_BLOCKED;
+
+    if (hw->x == 0 || priv->finger_state == FS_UNTOUCHED)
        priv->avg_width = 0;
     else
        priv->avg_width += (hw->fingerWidth - priv->avg_width + 1) / 2;
-    if (finger && !priv->finger_state) {
+
+    if (finger != FS_UNTOUCHED && priv->finger_state == FS_UNTOUCHED) {
        int safe_width = MAX(hw->fingerWidth, priv->avg_width);
 
        if (hw->numFingers > 1 ||       /* more than one finger -> not a palm */
@@ -1393,9 +1396,6 @@ SynapticsDetectFinger(SynapticsPrivate *priv, struct 
SynapticsHwState *hw)
     }
     priv->prev_z = hw->z;
 
-    if (priv->palm)
-       finger = FS_UNTOUCHED;
-
     return finger;
 }
 
@@ -1537,12 +1537,12 @@ HandleTapProcessing(SynapticsPrivate *priv, struct 
SynapticsHwState *hw,
     edge_type edge;
     int delay = 1000000000;
 
-    if (priv->palm)
+    if (priv->finger_state == FS_BLOCKED)
        return delay;
 
-    touch = finger && !priv->finger_state;
-    release = !finger && priv->finger_state;
-    move = (finger &&
+    touch = finger >= FS_TOUCHED && priv->finger_state == FS_UNTOUCHED;
+    release = finger == FS_UNTOUCHED && priv->finger_state >= FS_TOUCHED;
+    move = (finger >= FS_TOUCHED &&
             (priv->tap_max_fingers <= ((priv->horiz_scroll_twofinger_on || 
priv->vert_scroll_twofinger_on)? 2 : 1)) &&
             ((abs(hw->x - priv->touch_on.x) >= para->tap_move) ||
             (abs(hw->y - priv->touch_on.y) >= para->tap_move)));
@@ -1939,7 +1939,7 @@ ComputeDeltas(SynapticsPrivate *priv, const struct 
SynapticsHwState *hw,
        }
     }
 
-    if (!inside_area || !moving_state || priv->palm ||
+    if (!inside_area || !moving_state || priv->finger_state == FS_BLOCKED ||
        priv->vert_scroll_edge_on || priv->horiz_scroll_edge_on ||
        priv->vert_scroll_twofinger_on || priv->horiz_scroll_twofinger_on ||
        priv->circ_scroll_on || priv->prevFingers != hw->numFingers)
@@ -2063,7 +2063,7 @@ HandleScrolling(SynapticsPrivate *priv, struct 
SynapticsHwState *hw,
 
     sd->left = sd->right = sd->up = sd->down = 0;
 
-    if (priv->synpara.touchpad_off == 2) {
+    if ((priv->synpara.touchpad_off == 2) || (priv->finger_state == 
FS_BLOCKED)) {
        stop_coasting(priv);
        priv->circ_scroll_on = FALSE;
        priv->vert_scroll_edge_on = FALSE;
@@ -2074,7 +2074,7 @@ HandleScrolling(SynapticsPrivate *priv, struct 
SynapticsHwState *hw,
     }
 
     /* scroll detection */
-    if (finger && !priv->finger_state) {
+    if (finger && priv->finger_state == FS_UNTOUCHED) {
        stop_coasting(priv);
        if (para->circular_scrolling) {
            if ((para->circular_trigger == 0 && edge) ||
@@ -2112,7 +2112,7 @@ HandleScrolling(SynapticsPrivate *priv, struct 
SynapticsHwState *hw,
                }
            }
        }
-       if (finger && !priv->finger_state) {
+       if (finger && priv->finger_state == FS_UNTOUCHED) {
            if (!priv->vert_scroll_twofinger_on && 
!priv->horiz_scroll_twofinger_on) {
                if ((para->scroll_edge_vert) && (para->scroll_dist_vert != 0) &&
                    (edge & RIGHT_EDGE)) {
@@ -2541,7 +2541,7 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState 
*hw, CARD32 now,
 {
     SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
     SynapticsParameters *para = &priv->synpara;
-    int finger;
+    enum FingerState finger;
     int dx, dy, buttons, id;
     edge_type edge = NO_EDGE;
     int change;
@@ -2595,7 +2595,10 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState 
*hw, CARD32 now,
     /* no edge or finger detection outside of area */
     if (inside_active_area) {
        edge = edge_detection(priv, hw->x, hw->y);
-       finger = SynapticsDetectFinger(priv, hw);
+       if (actual)
+           finger = SynapticsDetectFinger(priv, hw);
+       else
+           finger = priv->finger_state;
     }
 
     /* tap and drag detection. Needs to be performed even if the finger is in
@@ -2607,7 +2610,8 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState 
*hw, CARD32 now,
     if (inside_active_area)
     {
        /* Don't bother about scrolling in the dead area of the touchpad. */
-       timeleft = HandleScrolling(priv, hw, edge, finger, &scroll);
+       timeleft = HandleScrolling(priv, hw, edge, (finger >= FS_TOUCHED),
+                                  &scroll);
        if (timeleft > 0)
            delay = MIN(delay, timeleft);
 
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index 73893cf..7c20756 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -52,6 +52,7 @@ typedef struct _SynapticsMoveHist
 } SynapticsMoveHistRec;
 
 enum FingerState {              /* Note! The order matters. Compared with < 
operator. */
+    FS_BLOCKED = -1,
     FS_UNTOUCHED = 0, /* this is 0 so it's the initialized value. */
     FS_TOUCHED = 1,
     FS_PRESSED = 2,
@@ -234,8 +235,6 @@ typedef struct _SynapticsPrivateRec
     int repeatButtons;                 /* buttons for repeat */
     int nextRepeat;                    /* Time when to trigger next auto 
repeat event */
     int lastButtons;                   /* last state of the buttons */
-    int palm;                          /* Set to true when palm detected, 
reset to false when
-                                          palm/finger contact disappears */
     int prev_z;                                /* previous z value, for palm 
detection */
     int prevFingers;                   /* previous numFingers, for transition 
detection */
     int avg_width;                     /* weighted average of previous 
fingerWidth values */
-- 
1.7.5.3

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to