void ums_intr(struct uhidev *addr, void *buf, u_int len) { struct ums_softc *sc = (struct ums_softc *)addr; u_char *ibuf = (u_char *)buf; int dx, dy, dz, dw; u_int32_t buttons = 0; int i; int s; DPRINTFN(5,("ums_intr: len=%d\n", len)); /* * The Microsoft Wireless Intellimouse 2.0 sends one extra leading * byte of data compared to most USB mice. This byte frequently * switches from 0x01 (usual state) to 0x02. It may be used to * report non-standard events (such as battery life). However, * at the same time, it generates a left click event on the * button byte, where there shouldn't be any. We simply discard * the packet in this case. * * This problem affects the MS Wireless Notebook Optical Mouse, too. * However, the leading byte for this mouse is normally 0x11, and * the phantom mouse click occurs when it's 0x14. */ if (sc->flags & UMS_LEADINGBYTE) { if (*ibuf++ == 0x02) return; /* len--; */ } else if (sc->flags & UMS_SPUR_BUT_UP) { if (*ibuf == 0x14 || *ibuf == 0x15) return; } dx = hid_get_data(ibuf, &sc->sc_loc_x); dy = -hid_get_data(ibuf, &sc->sc_loc_y); dz = hid_get_data(ibuf, &sc->sc_loc_z); dw = hid_get_data(ibuf, &sc->sc_loc_w); if (sc->flags & UMS_REVZ) dz = -dz; if (sc->flags & UMS_REVW) dw = -dw; for (i = 0; i < sc->nbuttons; i++) if (hid_get_data(ibuf, &sc->sc_loc_btn[i])) buttons |= (1 << UMS_BUT(i)); if (dx != 0 || dy != 0 || dz != 0 || dw != 0 || buttons != sc->sc_buttons) { DPRINTFN(10, ("ums_intr: x:%d y:%d z:%d w:%d buttons:0x%x\n", dx, dy, dz, dw, buttons)); sc->sc_buttons = buttons; if (sc->sc_wsmousedev != NULL) { s = spltty(); wsmouse_input(sc->sc_wsmousedev, buttons, dx, dy, dz, dw, WSMOUSE_INPUT_DELTA); splx(s); } } }
void ums_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) { struct ums_softc *sc = addr; u_char *ibuf; int dx, dy, dz; u_int32_t buttons = 0; int i; int s; DPRINTFN(5, ("ums_intr: sc=%p status=%d\n", sc, status)); DPRINTFN(5, ("ums_intr: data = %02x %02x %02x\n", sc->sc_ibuf[0], sc->sc_ibuf[1], sc->sc_ibuf[2])); if (status == USBD_CANCELLED) return; if (status) { DPRINTF(("ums_intr: status=%d\n", status)); usbd_clear_endpoint_stall_async(sc->sc_intrpipe); return; } ibuf = sc->sc_ibuf; if (sc->sc_iid != 0) { if (*ibuf++ != sc->sc_iid) return; } dx = hid_get_data(ibuf, &sc->sc_loc_x); dy = -hid_get_data(ibuf, &sc->sc_loc_y); dz = hid_get_data(ibuf, &sc->sc_loc_z); if (sc->flags & UMS_REVZ) dz = -dz; for (i = 0; i < sc->nbuttons; i++) if (hid_get_data(ibuf, &sc->sc_loc_btn[i])) buttons |= (1 << UMS_BUT(i)); if (dx != 0 || dy != 0 || dz != 0 || buttons != sc->sc_buttons) { DPRINTFN(10, ("ums_intr: x:%d y:%d z:%d buttons:0x%x\n", dx, dy, dz, buttons)); sc->sc_buttons = buttons; if (sc->sc_wsmousedev != NULL) { s = spltty(); wsmouse_input(sc->sc_wsmousedev, buttons, dx, dy, dz, WSMOUSE_INPUT_DELTA); splx(s); } } }
void ums_intr(struct uhidev *addr, void *ibuf, u_int len) { struct ums_softc *sc = (struct ums_softc *)addr; int dx, dy, dz, dw; uint32_t buttons = 0; int i, flags, s; DPRINTFN(5,("ums_intr: len=%d\n", len)); flags = WSMOUSE_INPUT_DELTA; /* equals 0 */ dx = hid_get_data(ibuf, &sc->sc_loc_x); if (sc->flags & UMS_ABS) { flags |= (WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y); dy = hid_get_data(ibuf, &sc->sc_loc_y); } else dy = -hid_get_data(ibuf, &sc->sc_loc_y); dz = hid_get_data(ibuf, &sc->sc_loc_z); dw = hid_get_data(ibuf, &sc->sc_loc_w); if (sc->flags & UMS_REVZ) dz = -dz; for (i = 0; i < sc->nbuttons; i++) if (hid_get_data(ibuf, &sc->sc_loc_btn[i])) buttons |= (1 << UMS_BUT(i)); if (dx != 0 || dy != 0 || dz != 0 || dw != 0 || buttons != sc->sc_buttons) { DPRINTFN(10, ("ums_intr: x:%d y:%d z:%d w:%d buttons:0x%x\n", dx, dy, dz, dw, buttons)); sc->sc_buttons = buttons; if (sc->sc_wsmousedev != NULL) { s = spltty(); wsmouse_input(sc->sc_wsmousedev, buttons, dx, dy, dz, dw, flags); splx(s); } } }