Adjust the USB report descriptors to indicate that the mouse and tablet have horizontal wheels, and then report the delta when polled.
Signed-off-by: Brad Jorsch <ano...@users.sourceforge.net> --- hw/usb-hid.c | 44 ++++++++++++++++++++++++++++++++++++-------- 1 files changed, 36 insertions(+), 8 deletions(-) diff --git a/hw/usb-hid.c b/hw/usb-hid.c index deb4731..15cc2a1 100644 --- a/hw/usb-hid.c +++ b/hw/usb-hid.c @@ -44,7 +44,7 @@ #define USB_KEYBOARD 3 typedef struct USBMouseState { - int dx, dy, dz, buttons_state; + int dx, dy, dz, dw, buttons_state; int x, y; int mouse_grabbed; QEMUPutMouseEntry *eh_entry; @@ -137,14 +137,14 @@ static const uint8_t qemu_mouse_config_descriptor[] = { 0x00, /* u8 country_code */ 0x01, /* u8 num_descriptors */ 0x22, /* u8 type; Report */ - 52, 0, /* u16 len */ + 67, 0, /* u16 len */ /* one endpoint (status change endpoint) */ 0x07, /* u8 ep_bLength; */ 0x05, /* u8 ep_bDescriptorType; Endpoint */ 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */ 0x03, /* u8 ep_bmAttributes; Interrupt */ - 0x04, 0x00, /* u16 ep_wMaxPacketSize; */ + 0x05, 0x00, /* u16 ep_wMaxPacketSize; */ 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */ }; @@ -192,14 +192,14 @@ static const uint8_t qemu_tablet_config_descriptor[] = { 0x00, /* u8 country_code */ 0x01, /* u8 num_descriptors */ 0x22, /* u8 type; Report */ - 74, 0, /* u16 len */ + 93, 0, /* u16 len */ /* one endpoint (status change endpoint) */ 0x07, /* u8 ep_bLength; */ 0x05, /* u8 ep_bDescriptorType; Endpoint */ 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */ 0x03, /* u8 ep_bmAttributes; Interrupt */ - 0x08, 0x00, /* u16 ep_wMaxPacketSize; */ + 0x09, 0x00, /* u16 ep_wMaxPacketSize; */ 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */ }; @@ -284,6 +284,13 @@ static const uint8_t qemu_mouse_hid_report_descriptor[] = { 0x75, 0x08, /* Report Size (8) */ 0x95, 0x03, /* Report Count (3) */ 0x81, 0x06, /* Input (Data, Variable, Relative) */ + 0x05, 0x0c, /* Usage Page (Consumer Devices) */ + 0x0a, 0x38, 0x02, /* Usage (AC Pan) */ + 0x15, 0x81, /* Logical Minimum (-0x7f) */ + 0x25, 0x7f, /* Logical Maximum (0x7f) */ + 0x75, 0x08, /* Report Size (8) */ + 0x95, 0x01, /* Report Count (1) */ + 0x81, 0x06, /* Input (Data, Variable, Relative) */ 0xc0, /* End Collection */ 0xc0, /* End Collection */ }; @@ -324,6 +331,15 @@ static const uint8_t qemu_tablet_hid_report_descriptor[] = { 0x75, 0x08, /* Report Size (8) */ 0x95, 0x01, /* Report Count (1) */ 0x81, 0x06, /* Input (Data, Variable, Relative) */ + 0x05, 0x0c, /* Usage Page (Consumer Devices) */ + 0x0a, 0x38, 0x02, /* Usage (AC Pan) */ + 0x15, 0x81, /* Logical Minimum (-0x7f) */ + 0x25, 0x7f, /* Logical Maximum (0x7f) */ + 0x35, 0x00, /* Physical Minimum (same as logical) */ + 0x45, 0x00, /* Physical Maximum (same as logical) */ + 0x75, 0x08, /* Report Size (8) */ + 0x95, 0x01, /* Report Count (1) */ + 0x81, 0x06, /* Input (Data, Variable, Relative) */ 0xc0, /* End Collection */ 0xc0, /* End Collection */ }; @@ -423,6 +439,7 @@ static void usb_mouse_event(void *opaque, s->dx += dx1; s->dy += dy1; s->dz += dz1; + s->dw += dw1; s->buttons_state = buttons_state; usb_hid_changed(hs); @@ -437,6 +454,7 @@ static void usb_tablet_event(void *opaque, s->x = x; s->y = y; s->dz += dz; + s->dw += dw; s->buttons_state = buttons_state; usb_hid_changed(hs); @@ -508,7 +526,7 @@ static inline int int_clamp(int val, int vmin, int vmax) static int usb_mouse_poll(USBHIDState *hs, uint8_t *buf, int len) { - int dx, dy, dz, b, l; + int dx, dy, dz, dw, b, l; USBMouseState *s = &hs->ptr; if (!s->mouse_grabbed) { @@ -519,10 +537,12 @@ static int usb_mouse_poll(USBHIDState *hs, uint8_t *buf, int len) dx = int_clamp(s->dx, -127, 127); dy = int_clamp(s->dy, -127, 127); dz = int_clamp(s->dz, -127, 127); + dw = int_clamp(s->dw, -127, 127); s->dx -= dx; s->dy -= dy; s->dz -= dz; + s->dw -= dw; /* Appears we have to invert the wheel direction */ dz = 0 - dz; @@ -544,12 +564,15 @@ static int usb_mouse_poll(USBHIDState *hs, uint8_t *buf, int len) buf[l ++] = dy; if (len > l) buf[l ++] = dz; + if (len > l) + buf[l ++] = dw; + return l; } static int usb_tablet_poll(USBHIDState *hs, uint8_t *buf, int len) { - int dz, b, l; + int dz, dw, b, l; USBMouseState *s = &hs->ptr; if (!s->mouse_grabbed) { @@ -560,6 +583,9 @@ static int usb_tablet_poll(USBHIDState *hs, uint8_t *buf, int len) dz = int_clamp(s->dz, -127, 127); s->dz -= dz; + dw = int_clamp(s->dw, -127, 127); + s->dw -= dw; + /* Appears we have to invert the wheel direction */ dz = 0 - dz; b = 0; @@ -576,7 +602,8 @@ static int usb_tablet_poll(USBHIDState *hs, uint8_t *buf, int len) buf[3] = s->y & 0xff; buf[4] = s->y >> 8; buf[5] = dz; - l = 6; + buf[6] = dw; + l = 7; return l; } @@ -624,6 +651,7 @@ static void usb_mouse_handle_reset(USBDevice *dev) s->ptr.dx = 0; s->ptr.dy = 0; s->ptr.dz = 0; + s->ptr.dw = 0; s->ptr.x = 0; s->ptr.y = 0; s->ptr.buttons_state = 0; -- 1.7.1