[PATCH xf86-input-synaptics v3 1/3] Don't emit touch sequences if only one touch is active

Peter Hutterer peter.hutterer at who-t.net
Mon Feb 6 12:17:00 PST 2012


On Mon, Feb 06, 2012 at 08:40:45AM -0800, Chase Douglas wrote:
> When a second touch begins, emit a touch begin for the first touch with
> the current valuator values. When a touch ends and we are going from two
> touches down to one touch, end both touches. This ensures we don't send
> a touch sequence at the same time we are moving the pointer.

Series pulled from your fixes branch, pushed 
3822705..141d912  master -> master

thanks!

Cheers,
  Peter

> 
> Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
> ---
> Changes since v2:
> * Rebased onto master
> 
>  src/eventcomm.c |   89 ++++++++++++++++++++++++++++++++++++++++++++++++++----
>  1 files changed, 82 insertions(+), 7 deletions(-)
> 
> diff --git a/src/eventcomm.c b/src/eventcomm.c
> index c323f8f..6a55df0 100644
> --- a/src/eventcomm.c
> +++ b/src/eventcomm.c
> @@ -78,6 +78,8 @@ struct eventcomm_proto_data
>      } slot_state;
>      ValuatorMask *mt_mask;
>      ValuatorMask **last_mt_vals;
> +    unsigned int num_touches;
> +    int *open_slots;
>  #endif
>  };
>  
> @@ -109,6 +111,9 @@ UninitializeTouch(InputInfoPtr pInfo)
>      if (!proto_data->mtdev)
>          return;
>  
> +    free(proto_data->open_slots);
> +    proto_data->open_slots = NULL;
> +
>      valuator_mask_free(&proto_data->mt_mask);
>      if (proto_data->last_mt_vals)
>      {
> @@ -183,6 +188,8 @@ InitializeTouch(InputInfoPtr pInfo)
>          for (j = 4; j < priv->num_mt_axes; j++)
>              valuator_mask_set(proto_data->last_mt_vals[i], j, 0);
>      }
> +
> +    proto_data->open_slots = malloc(num_slots(proto_data) * sizeof(int));
>  }
>  #endif
>  
> @@ -511,13 +518,82 @@ SynapticsReadEvent(InputInfoPtr pInfo, struct input_event *ev)
>      return rc;
>  }
>  
> +#ifdef HAVE_MTDEV
> +static void
> +EventBeginTouches(InputInfoPtr pInfo)
> +{
> +    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
> +    struct eventcomm_proto_data *proto_data = priv->proto_data;
> +    int first_slot;
> +
> +    proto_data->num_touches++;
> +    proto_data->open_slots[proto_data->num_touches - 1] = proto_data->cur_slot;
> +
> +    /* Don't start a touch if it's the only one. */
> +    if (proto_data->num_touches < 2)
> +        return;
> +
> +    xf86PostTouchEvent(pInfo->dev, proto_data->cur_slot, XI_TouchBegin, 0,
> +                       proto_data->mt_mask);
> +
> +    /* If this is the third or more touch, we've already begun the first touch.
> +     */
> +    if (proto_data->num_touches > 2)
> +        return;
> +
> +    /* If this is the second touch, begin the first touch at this time. */
> +    first_slot = proto_data->open_slots[0];
> +    xf86PostTouchEvent(pInfo->dev, first_slot, XI_TouchBegin, 0,
> +                       proto_data->last_mt_vals[first_slot]);
> +}
> +
> +static void
> +EventEndTouches(InputInfoPtr pInfo)
> +{
> +    SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
> +    struct eventcomm_proto_data *proto_data = priv->proto_data;
> +    int first_slot;
> +    int i;
> +    Bool found;
> +
> +    found = FALSE;
> +    for (i = 0; i < proto_data->num_touches - 1; i++)
> +    {
> +        if (proto_data->open_slots[i] == proto_data->cur_slot)
> +            found = TRUE;
> +
> +        if (found)
> +            proto_data->open_slots[i] = proto_data->open_slots[i + 1];
> +    }
> +
> +    proto_data->num_touches--;
> +
> +    /* If this was the only touch left on the device, don't send a touch end
> +     * event because we are inhibiting its touch sequence. */
> +    if (proto_data->num_touches == 0)
> +        return;
> +
> +    xf86PostTouchEvent(pInfo->dev, proto_data->cur_slot, XI_TouchEnd, 0,
> +                       proto_data->mt_mask);
> +
> +    /* If there is at least two other touches on the device, we don't need to
> +     * end any more touches. */
> +    if (proto_data->num_touches >= 2)
> +        return;
> +
> +    /* We've gone down to one touch, so we must end the touch as well. */
> +    first_slot = proto_data->open_slots[0];
> +    xf86PostTouchEvent(pInfo->dev, first_slot, XI_TouchEnd, 0,
> +                       proto_data->last_mt_vals[first_slot]);
> +}
> +#endif
> +
>  static void
>  EventProcessTouch(InputInfoPtr pInfo)
>  {
>  #ifdef HAVE_MTDEV
>      SynapticsPrivate *priv = (SynapticsPrivate *)pInfo->private;
>      struct eventcomm_proto_data *proto_data = priv->proto_data;
> -    int type;
>  
>      if (proto_data->cur_slot < 0 || !priv->has_touch)
>          return;
> @@ -529,19 +605,18 @@ EventProcessTouch(InputInfoPtr pInfo)
>      switch (proto_data->slot_state)
>      {
>          case SLOTSTATE_CLOSE:
> -            type = XI_TouchEnd;
> +            EventEndTouches(pInfo);
>              break;
>          case SLOTSTATE_OPEN:
> -            type = XI_TouchBegin;
> +            EventBeginTouches(pInfo);
>              break;
>          default:
> -            type = XI_TouchUpdate;
> +            if (proto_data->num_touches >= 2)
> +                xf86PostTouchEvent(pInfo->dev, proto_data->cur_slot,
> +                                   XI_TouchUpdate, 0, proto_data->mt_mask);
>              break;
>      }
>  
> -    xf86PostTouchEvent(pInfo->dev, proto_data->cur_slot, type, 0,
> -                       proto_data->mt_mask);
> -
>      proto_data->slot_state = SLOTSTATE_EMPTY;
>      valuator_mask_zero(proto_data->mt_mask);
>  #endif
> -- 
> 1.7.8.3
> 


More information about the xorg-devel mailing list