diff options
Diffstat (limited to 'hw/usb/dev-unifying.c')
-rw-r--r-- | hw/usb/dev-unifying.c | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/hw/usb/dev-unifying.c b/hw/usb/dev-unifying.c index 218a654833..36ffdb3f55 100644 --- a/hw/usb/dev-unifying.c +++ b/hw/usb/dev-unifying.c @@ -485,31 +485,60 @@ data_ready: usb_dump_complete(s->usb_dump_state, p); } -static void usb_ltunify_handle_datain_hid(USBDevice *dev, USBPacket *p) +int usb_ltunify_poll_hid(HIDState *hs, uint8_t *buf, size_t bufsz) { - USBLtunifyState *s = (USBLtunifyState *) dev; - uint8_t ifnum = p->ep->nr == 1 ? IFACE_KBD : IFACE_MSE; - HIDState *hs = &s->hid[ifnum]; - uint8_t buf[p->iov.size]; int len = 0; + assert(hs != NULL); if (hs->kind == HID_MOUSE) { /* start accepting pointer events if not already */ hid_pointer_activate(hs); } if (!hid_has_events(hs)) { - p->status = USB_RET_NAK; - return; + return 0; } hid_set_next_idle(hs); assert(hs->kind == HID_MOUSE || hs->kind == HID_KEYBOARD); if (hs->kind == HID_MOUSE) { - len = hid_pointer_poll(hs, buf, p->iov.size); + uint8_t pbuf[4]; /* buttons, x, y, wheel */ + uint8_t lbuf[7]; + + hid_pointer_poll(hs, pbuf, sizeof(pbuf)); + /* buttons (16 bits) */ + lbuf[0] = pbuf[0]; + lbuf[1] = 0; + /* X, Y (12 bits each) */ + lbuf[2] = pbuf[1]; + lbuf[3] = ((int8_t) pbuf[1] & 0xf00) >> 8; /* (ff)fe -> 0f */ + lbuf[3] |= ((int8_t) pbuf[2] & 0xf00) >> 4; /* (ff)fe -> f0 */ + lbuf[4] = pbuf[2]; + /* wheel, consumer (8 bit each) */ + lbuf[5] = pbuf[3]; + lbuf[6] = 0; + len = MIN(len, bufsz); + memcpy(buf, lbuf, len); } else if (hs->kind == HID_KEYBOARD) { - len = hid_keyboard_poll(hs, buf, p->iov.size); + len = hid_keyboard_poll(hs, buf, bufsz); + } + + return len; +} + +static void usb_ltunify_handle_datain_hid(USBDevice *dev, USBPacket *p) +{ + USBLtunifyState *s = (USBLtunifyState *) dev; + uint8_t ifnum = p->ep->nr == 1 ? IFACE_KBD : IFACE_MSE; + HIDState *hs = &s->hid[ifnum]; + uint8_t buf[p->iov.size]; + int len; + + len = usb_ltunify_poll_hid(hs, buf, sizeof(buf)); + if (len <= 0) { + p->status = USB_RET_NAK; + return; } usb_dump_complete_data(s->usb_dump_state, p, buf, len); |