--- sys/dev/usb/input/ums.c.org 2011-06-28 05:59:43.000000000 +0900 +++ sys/dev/usb/input/ums.c 2011-07-26 17:29:33.000000000 +0900 @@ -191,6 +191,9 @@ ums_intr_callback(struct usb_xfer *xfer, int32_t dy = 0; int32_t dz = 0; int32_t dt = 0; + static int32_t buttons_last = 0; + int32_t buttons_repeat = 0; + int32_t buttons_bit; uint8_t i; uint8_t id; int len; @@ -278,8 +281,39 @@ ums_intr_callback(struct usb_xfer *xfer, /* keep old button value(s) for non-detected buttons */ buttons |= sc->sc_status.button & ~buttons_found; + if (0 != dw) { + if (0 < dw) { + buttons_bit = (1 << UMS_BUT(info->sc_buttons + 0)); + if (buttons_bit & sc->sc_status.button) { + buttons_repeat |= buttons_bit; + } + buttons |= buttons_bit; + } else { + buttons_bit = (1 << UMS_BUT(info->sc_buttons + 1)); + if (buttons_bit & sc->sc_status.button) { + buttons_repeat |= buttons_bit; + } + buttons |= buttons_bit; + } + } + if (0 != dt) { + if (0 < dt) { + buttons_bit = (1 << UMS_BUT(info->sc_buttons + ((info->sc_flags & UMS_FLAG_W_AXIS) ? 2 : 0) + 0)); + if (buttons_bit & sc->sc_status.button) { + buttons_repeat |= buttons_bit; + } + buttons |= buttons_bit; + } else { + buttons_bit = (1 << UMS_BUT(info->sc_buttons + ((info->sc_flags & UMS_FLAG_W_AXIS) ? 2 : 0) + 1)); + if (buttons_bit & sc->sc_status.button) { + buttons_repeat |= buttons_bit; + } + buttons |= buttons_bit; + } + } if (dx || dy || dz || dt || dw || + buttons_repeat || (buttons != sc->sc_status.button)) { DPRINTFN(6, "x:%d y:%d z:%d t:%d w:%d buttons:0x%08x\n", @@ -320,7 +354,16 @@ ums_intr_callback(struct usb_xfer *xfer, usb_callout_stop(&sc->sc_callout); + if ( ((( 0x07) & buttons) != (( 0x07) & buttons_last)) + && (((~0x07) & buttons) != ((~0x07) & buttons_last)) + ) { + ums_put_queue(sc, dx, dy, dz, dt, (((~0x07) & buttons) | (( 0x07) & buttons_last))); + } + if (buttons_repeat) { + ums_put_queue(sc, 0, 0, 0, 0, buttons & ~buttons_repeat); + } ums_put_queue(sc, dx, dy, dz, dt, buttons); + buttons_last = buttons; } } case USB_ST_SETUP: