diff options
author | Peter Wu <peter@lekensteyn.nl> | 2014-03-24 17:16:24 +0100 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2014-03-24 17:16:24 +0100 |
commit | 3615170bd1ed6f09f878a8b538321044efddd8e0 (patch) | |
tree | 67f457ba2eb226a302c309845662e4e2d6276d8d /hw/usb/dev-unifying.c | |
parent | d26faef5d3e70ab8072f6387dd97b2527b8f0e39 (diff) | |
download | qemu-3615170bd1ed6f09f878a8b538321044efddd8e0.tar.gz |
unifying: fix mouse report format, DRY
Introduce new function to retrieve HID data for a given HIDState (if
any) and fix the incompatibility between the HID format for mice as
used by QEMU and the format described by the report (it contains an
extra field for buttons).
Signed-off-by: Peter Wu <peter@lekensteyn.nl>
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); |