A previous version of this last year broke on some devices because 
it tried to pass in pressure data.  This version only fixes the 
padding data of type4 devices.

Tested on the 2015 MacBook Pro.  Tests on other Apple devices would 
be appreciated.


Index: sys/dev/usb/ubcmtp.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ubcmtp.c,v
retrieving revision 1.19
diff -u -p -u -p -r1.19 ubcmtp.c
--- sys/dev/usb/ubcmtp.c        13 Jan 2019 14:30:16 -0000      1.19
+++ sys/dev/usb/ubcmtp.c        25 May 2019 15:17:00 -0000
@@ -118,6 +118,7 @@ struct ubcmtp_finger {
 #define UBCMTP_TYPE4_TPLEN     UBCMTP_TYPE4_TPOFF + UBCMTP_ALL_FINGER_SIZE
 #define UBCMTP_TYPE4_TPIFACE   2
 #define UBCMTP_TYPE4_BTOFF     31
+#define UBCMTP_TYPE4_FINGERPAD (1 * sizeof(uint16_t))
 
 #define UBCMTP_FINGER_ORIENT   16384
 #define UBCMTP_SN_PRESSURE     45
@@ -336,6 +337,7 @@ struct ubcmtp_softc {
        int                     sc_tp_epaddr;   /* endpoint addr */
        int                     tp_maxlen;      /* max size of tp data */
        int                     tp_offset;      /* finger offset into data */
+       int                     tp_fingerpad;   /* padding between finger data 
*/
        uint8_t                 *tp_pkt;
 
        struct usbd_interface   *sc_bt_iface;   /* button interface */
@@ -429,6 +431,7 @@ ubcmtp_attach(struct device *parent, str
 
        sc->sc_udev = uaa->device;
        sc->sc_status = 0;
+       sc->tp_fingerpad = 0;
 
        if ((udd = usbd_get_device_descriptor(dev)) == NULL) {
                printf("ubcmtp: failed getting device descriptor\n");
@@ -486,6 +489,7 @@ ubcmtp_attach(struct device *parent, str
                sc->tp_maxlen = UBCMTP_TYPE4_TPLEN;
                sc->tp_offset = UBCMTP_TYPE4_TPOFF;
                sc->sc_tp_iface = uaa->ifaces[UBCMTP_TYPE4_TPIFACE];
+               sc->tp_fingerpad = UBCMTP_TYPE4_FINGERPAD;
                usbd_claim_iface(sc->sc_udev, UBCMTP_TYPE4_TPIFACE);
                break;
        }
@@ -790,9 +794,9 @@ void
 ubcmtp_tp_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
 {
        struct ubcmtp_softc *sc = priv;
-       struct ubcmtp_finger *pkt;
+       struct ubcmtp_finger *finger;
        u_int32_t pktlen;
-       int i, s, btn, contacts, fingers;
+       int off, s, btn, contacts = 0;
 
        if (usbd_is_dying(sc->sc_udev) || !(sc->sc_status & UBCMTP_ENABLED))
                return;
@@ -813,15 +817,16 @@ ubcmtp_tp_intr(struct usbd_xfer *xfer, v
        if (sc->tp_pkt == NULL || pktlen < sc->tp_offset)
                return;
 
-       pkt = (struct ubcmtp_finger *)(sc->tp_pkt + sc->tp_offset);
-       fingers = (pktlen - sc->tp_offset) / sizeof(struct ubcmtp_finger);
-
        contacts = 0;
-       for (i = 0; i < fingers; i++) {
-               if ((int16_t)letoh16(pkt[i].touch_major) == 0)
+       for (off = sc->tp_offset; off < pktlen;
+           off += (sizeof(struct ubcmtp_finger) + sc->tp_fingerpad)) {
+               finger = (struct ubcmtp_finger *)(sc->tp_pkt + off);
+
+               if ((int16_t)letoh16(finger->touch_major) == 0)
                        continue; /* finger lifted */
-               sc->frame[contacts].x = (int16_t)letoh16(pkt[i].abs_x);
-               sc->frame[contacts].y = (int16_t)letoh16(pkt[i].abs_y);
+
+               sc->frame[contacts].x = (int16_t)letoh16(finger->abs_x);
+               sc->frame[contacts].y = (int16_t)letoh16(finger->abs_y);
                sc->frame[contacts].pressure = DEFAULT_PRESSURE;
                contacts++;
        }

Reply via email to