void hidms_input(struct hidms *ms, uint8_t *data, u_int len) { int dx, dy, dz, dw; u_int32_t buttons = 0; int flags; int i, s; DPRINTFN(5,("hidms_input: 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 (ms->sc_flags & HIDMS_LEADINGBYTE) { if (*data++ == 0x02) return; /* len--; */ } else if (ms->sc_flags & HIDMS_SPUR_BUT_UP) { if (*data == 0x14 || *data == 0x15) return; } flags = WSMOUSE_INPUT_DELTA; if (ms->sc_flags & HIDMS_ABSX) flags |= WSMOUSE_INPUT_ABSOLUTE_X; if (ms->sc_flags & HIDMS_ABSY) flags |= WSMOUSE_INPUT_ABSOLUTE_Y; dx = hid_get_data(data, len, &ms->sc_loc_x); dy = -hid_get_data(data, len, &ms->sc_loc_y); dz = hid_get_data(data, len, &ms->sc_loc_z); dw = hid_get_data(data, len, &ms->sc_loc_w); if (ms->sc_flags & HIDMS_ABSY) dy = -dy; if (ms->sc_flags & HIDMS_REVZ) dz = -dz; if (ms->sc_flags & HIDMS_REVW) dw = -dw; if (ms->sc_tsscale.swapxy && !ms->sc_rawmode) { int tmp = dx; dx = dy; dy = tmp; } if (!ms->sc_rawmode && (ms->sc_tsscale.maxx - ms->sc_tsscale.minx) != 0 && (ms->sc_tsscale.maxy - ms->sc_tsscale.miny) != 0) { /* Scale down to the screen resolution. */ dx = ((dx - ms->sc_tsscale.minx) * ms->sc_tsscale.resx) / (ms->sc_tsscale.maxx - ms->sc_tsscale.minx); dy = ((dy - ms->sc_tsscale.miny) * ms->sc_tsscale.resy) / (ms->sc_tsscale.maxy - ms->sc_tsscale.miny); } for (i = 0; i < ms->sc_num_buttons; i++) if (hid_get_data(data, len, &ms->sc_loc_btn[i])) buttons |= (1 << HIDMS_BUT(i)); if (dx != 0 || dy != 0 || dz != 0 || dw != 0 || buttons != ms->sc_buttons) { DPRINTFN(10, ("hidms_input: x:%d y:%d z:%d w:%d buttons:0x%x\n", dx, dy, dz, dw, buttons)); ms->sc_buttons = buttons; if (ms->sc_wsmousedev != NULL) { s = spltty(); wsmouse_input(ms->sc_wsmousedev, buttons, dx, dy, dz, dw, flags); splx(s); } } }