On Sat, Aug 15, 2015 at 4:32 AM, Ulf Brosziewski <
[email protected]> wrote:

>
> The tap-and-drag gesture doesn't work reliably with the ALPS touchpads
> supported by pms. To make it work, it is necessary to start dragging
> immediately with the second touch, which doesn't always succeed.
> Increasing the tap timeout helps, but doesn't change the principle. The
> patch below solves that problem. Tests and comments would be welcome.
>
> In case someone is interested in the background: I have observed the
> same problem with a Linux installation on a machine with an ALPS
> touchpad; however, increasing the tap timeout to a sufficiently high
> value (>= 260ms) makes it work normally. The somewhat special behaviour
> of those ALPS models is described in this LKML posting:
>     https://lkml.org/lkml/2004/7/28/210
> The approach put forward there - which is partially reproduced in the
> current version of pms - is improved by the patch as follows: When the
> hardware signals a tap, the handler does nothing. The missing events
> will be emulated when the next packet arrives, which either signals the
> end of the gesture, or the start of a drag action. No timeout will occur
> even if the hardware introduces a long delay between the first and the
> second packet (which just happens when the finger is resting after the
> second contact).
>
>
>
Now is a good time to commit it :-)
ok shadchin@


> Index: dev/pckbc/pms.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pckbc/pms.c,v
> retrieving revision 1.64
> diff -u -p -r1.64 pms.c
> --- dev/pckbc/pms.c     20 Jul 2015 00:55:06 -0000      1.64
> +++ dev/pckbc/pms.c     14 Aug 2015 18:27:57 -0000
> @@ -120,7 +120,8 @@ struct alps_softc {
>
>         int min_x, min_y;
>         int max_x, max_y;
> -       int old_fin;
> +
> +       u_int gesture;
>
>         u_int sec_buttons;      /* trackpoint */
>
> @@ -1521,8 +1522,7 @@ pms_proc_alps(struct pms_softc *sc)
>  {
>         struct alps_softc *alps = sc->alps;
>         int x, y, z, w, dx, dy;
> -       u_int buttons;
> -       int fin, ges;
> +       u_int buttons, gesture;
>
>         if ((alps->model & ALPS_DUALPOINT) && alps_sec_proc(sc))
>                 return;
> @@ -1557,28 +1557,44 @@ pms_proc_alps(struct pms_softc *sc)
>         y = ALPS_YMAX_BEZEL - y + ALPS_YMIN_BEZEL;
>
>         if (alps->wsmode == WSMOUSE_NATIVE) {
> -               ges = sc->packet[2] & 0x01;
> -               fin = sc->packet[2] & 0x02;
> +               if (alps->gesture == ALPS_TAP) {
> +                       /* Report a touch with the tap coordinates. */
> +                       wsmouse_input(sc->sc_wsmousedev, buttons,
> +                           alps->old_x, alps->old_y, ALPS_PRESSURE, 4,
> +                           WSMOUSE_INPUT_ABSOLUTE_X
> +                           | WSMOUSE_INPUT_ABSOLUTE_Y
> +                           | WSMOUSE_INPUT_ABSOLUTE_Z
> +                           | WSMOUSE_INPUT_ABSOLUTE_W);
> +                       if (z > 0) {
> +                               /*
> +                                * The hardware doesn't send a null
> pressure
> +                                * event when dragging starts.
> +                                */
> +                               wsmouse_input(sc->sc_wsmousedev, buttons,
> +                                   alps->old_x, alps->old_y, 0, 0,
> +                                   WSMOUSE_INPUT_ABSOLUTE_X
> +                                   | WSMOUSE_INPUT_ABSOLUTE_Y
> +                                   | WSMOUSE_INPUT_ABSOLUTE_Z
> +                                   | WSMOUSE_INPUT_ABSOLUTE_W);
> +                       }
> +               }
>
> -               /* Simulate click (tap) */
> -               if (ges && !fin)
> -                       z = 35;
> -
> -               /* Generate a null pressure event (needed for tap & drag)
> */
> -               if (ges && fin && !alps->old_fin)
> -                       z = 0;
> -
> -               /* Generate a width value corresponding to one finger */
> -               if (z > 0)
> -                       w = 4;
> -               else
> -                       w = 0;
> +               gesture = sc->packet[2] & 0x03;
> +               if (gesture != ALPS_TAP) {
> +                       w = z ? 4 : 0;
> +                       wsmouse_input(sc->sc_wsmousedev, buttons, x, y, z,
> w,
> +                           WSMOUSE_INPUT_ABSOLUTE_X
> +                           | WSMOUSE_INPUT_ABSOLUTE_Y
> +                           | WSMOUSE_INPUT_ABSOLUTE_Z
> +                           | WSMOUSE_INPUT_ABSOLUTE_W);
> +               }
>
> -               wsmouse_input(sc->sc_wsmousedev, buttons, x, y, z, w,
> -                   WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y |
> -                   WSMOUSE_INPUT_ABSOLUTE_Z | WSMOUSE_INPUT_ABSOLUTE_W);
> +               if (alps->gesture != ALPS_DRAG || gesture != ALPS_TAP)
> +                       alps->gesture = gesture;
> +
> +               alps->old_x = x;
> +               alps->old_y = y;
>
> -               alps->old_fin = fin;
>         } else {
>                 dx = dy = 0;
>                 if (z > ALPS_PRESSURE) {
> Index: dev/pckbc/pmsreg.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pckbc/pmsreg.h,v
> retrieving revision 1.11
> diff -u -p -r1.11 pmsreg.h
> --- dev/pckbc/pmsreg.h  26 Mar 2015 01:30:22 -0000      1.11
> +++ dev/pckbc/pmsreg.h  14 Aug 2015 18:27:57 -0000
> @@ -164,6 +164,10 @@
>
>  #define ALPS_Z_MAGIC                           127
>
> +/* ALPS "gesture" and "finger" bits */
> +#define ALPS_TAP                               0x01
> +#define ALPS_DRAG                              0x03
> +
>  /* Elantech queries */
>  #define ELANTECH_QUE_FW_ID                     0
>  #define ELANTECH_QUE_FW_VER                    1
>
>


-- 
Alexandr Shadchin

Reply via email to