From 9cccf4cf2206a7ab4ebb75bd9ba87ec8a9d33328 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Mon, 24 Mar 2014 21:47:05 +0100 Subject: unifying: mouse compat with Win guests, other mouse fixes Two stupid mistakes slipped in while refactoring the HID report generation in 3615170bd1ed6f09f878a8b538321044efddd8e0 ("unifying: fix mouse report format, DRY"). This makes evtest in Linux report mouse events again and openbox seems happy too. Another mistake went in the calculation of the Y field, the high and low bits of Y were accidentally swapped. As the descriptor for interface 2 (mouse, etc.) includes Report IDs, this ID must be prepended to the HID payload for mice reports. This makes the mouse function for Windows guests. (See section 8.1 of HID 1.11). Signed-off-by: Peter Wu --- hw/usb/dev-unifying.c | 12 +++++++++--- hw/usb/hid-logitech-dj.c | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'hw') diff --git a/hw/usb/dev-unifying.c b/hw/usb/dev-unifying.c index 0eb0ebe5af..f31d0040dd 100644 --- a/hw/usb/dev-unifying.c +++ b/hw/usb/dev-unifying.c @@ -517,12 +517,12 @@ int usb_ltunify_poll_hid(HIDState *hs, uint8_t *buf, size_t bufsz) /* 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]; + lbuf[3] |= (pbuf[2] & 0xf) << 4; /* de -> e0 */ + lbuf[4] = ((int8_t) pbuf[2] & 0xff0) >> 4; /* (ff)de -> fd */ /* wheel, consumer (8 bit each) */ lbuf[5] = pbuf[3]; lbuf[6] = 0; - len = MIN(len, bufsz); + len = MIN(sizeof(lbuf), bufsz); memcpy(buf, lbuf, len); } else if (hs->kind == HID_KEYBOARD) { len = hid_keyboard_poll(hs, buf, bufsz); @@ -545,6 +545,12 @@ static void usb_ltunify_handle_datain_hid(USBDevice *dev, USBPacket *p) return; } + if (hs->kind == HID_MOUSE) { + memmove(buf + 1, buf, MIN(len, sizeof(buf) - 1)); + buf[0] = 2; /* Report ID for Mouse collection */ + len = MIN(len + 1, sizeof(buf)); + } + usb_dump_complete_data(s->usb_dump_state, p, buf, len); usb_packet_copy(p, buf, len); usb_dump_submit(s->usb_dump_state, p); diff --git a/hw/usb/hid-logitech-dj.c b/hw/usb/hid-logitech-dj.c index 5f1bc80f56..bc293a2dc5 100644 --- a/hw/usb/hid-logitech-dj.c +++ b/hw/usb/hid-logitech-dj.c @@ -493,7 +493,7 @@ static void hidpp_handle_hid(USBDevice *dev, USBPacket *p) } if (usb_ltunify_poll_hid(hd->hid, hid_data, sizeof(msg.payload)) <= 0) { - return; + continue; } msg.device_index = i + 1; -- cgit v1.2.1