> I find the mouse emulation code for synaptics touch pads in your patch 
> really weird. I've tried to understand what it does, and why it
> behaves badly for me on the first tap (move the pointer in the upper
> right direction every time), but I fail to understand the logic.

your change makes the problem worse on 2 laptops (samsung series 9
and thinkpad x220), where the cursor now jumps to the lower left
after every movement.  these seem to be due to events that come
through after removing all the fingers from the touchpad that need
to be ignored.  i checked linux and they also ignore these events:

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=4f56ce929cab45a3a6e1a81700da52bb9bdbfc0f

this also adds support for "clickpads" where there is only one
physical button and it's the entire trackpad that moves down, which
both of those laptops have.  without this change, the click gets
ignored.


--- pms.c.new   Mon Jun 13 16:26:39 2011
+++ pms.c       Mon Jun 13 20:06:59 2011
@@ -799,7 +799,9 @@
                syn->wsmode = WSMOUSE_COMPAT;
                syn->count = 0;
 
-               printf("%s: Synaptics touchpad, firmware %d.%d\n", DEVNAME(sc),
+               printf("%s: Synaptics %s, firmware %d.%d\n", DEVNAME(sc),
+                   (syn->capabilities & SYNAPTICS_EXT_CAP_CLICKPAD ?
+                       "clickpad" : "touchpad"),
                    SYNAPTICS_ID_MAJOR(syn->identify),
                    SYNAPTICS_ID_MINOR(syn->identify));
        }
@@ -882,8 +884,11 @@
        buttons |= ((sc->packet[0] & 0x02) & (sc->packet[3] & 0x02)) ?
            WSMOUSE_BUTTON(3) : 0;
 
-       if (syn->capabilities & SYNAPTICS_CAP_MIDDLE_BUTTON) {
+       if (syn->ext_capabilities & SYNAPTICS_EXT_CAP_CLICKPAD) {
                buttons |= ((sc->packet[0] & 0x01) ^ (sc->packet[3] & 0x01)) ?
+                   WSMOUSE_BUTTON(1) : 0;
+       } else if (syn->capabilities & SYNAPTICS_CAP_MIDDLE_BUTTON) {
+               buttons |= ((sc->packet[0] & 0x01) ^ (sc->packet[3] & 0x01)) ?
                    WSMOUSE_BUTTON(2) : 0;
        }
 
@@ -906,6 +911,14 @@
                y &= ~0x0f;
        }
 
+       /* ignore final events that happen when removing all fingers */
+       if (x <= 1 && !z) {
+               x = syn->old_x;
+               y = syn->old_y;
+               w = 0;
+               buttons = 0;
+       }
+
        if (syn->wsmode == WSMOUSE_NATIVE) {
                wsmouse_input(sc->sc_wsmousedev, buttons, x, y, z, w,
                    WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y |
@@ -925,10 +938,11 @@
                if (dx || dy || buttons != syn->old_buttons) 
                        wsmouse_input(sc->sc_wsmousedev, buttons, dx, dy, 0, 0,
                            WSMOUSE_INPUT_DELTA);
-               syn->old_x = x;
-               syn->old_y = y;
                syn->old_buttons = buttons;
        }
+
+       syn->old_x = x;
+       syn->old_y = y;
 }
 
 void

Reply via email to