[PATCH synaptics 17/21] Revise palm check logic

Daniel Kurtz djkurtz at google.com
Tue Jun 14 21:40:07 PDT 2011


On Wed, Jun 15, 2011 at 1:06 AM, Daniel Stone <daniel at fooishbar.org> wrote:
> From: Derek Foreman <derek.foreman at collabora.co.uk>
>
> 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 <derek.foreman at collabora.co.uk>
> Reviewed-by: Daniel Stone <daniel at fooishbar.org>
> Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
>  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 b6cf6e5..37c939e 100644
> --- a/src/synaptics.c
> +++ b/src/synaptics.c
> @@ -1377,12 +1377,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;
>
> @@ -1390,17 +1394,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))

(1) Should these be >= ?
(2) Should the || be && ?

> +        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 */
> @@ -1417,9 +1420,6 @@ SynapticsDetectFinger(SynapticsPrivate *priv, struct SynapticsHwState *hw)
>     }
>     priv->prev_z = hw->z;
>
> -    if (priv->palm)
> -       finger = FS_UNTOUCHED;
> -
>     return finger;
>  }
>
> @@ -1561,12 +1561,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)));
> @@ -1981,7 +1981,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)
> @@ -2104,7 +2104,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;
> @@ -2115,7 +2115,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) ||
> @@ -2153,7 +2153,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)) {
> @@ -2586,7 +2586,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;
> @@ -2640,7 +2640,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 (!from_timer)
> +           finger = SynapticsDetectFinger(priv, hw);
> +       else
> +           finger = priv->finger_state;
>     }
>
>     /* tap and drag detection. Needs to be performed even if the finger is in
> @@ -2652,7 +2655,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 23b854f..7383f97 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
>
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel
>


More information about the xorg-devel mailing list