Patchwork [4/5] Add a horizontal wheel to the USB mouse and tablet

login
register
mail settings
Submitter Brad Jorsch
Date May 4, 2010, 4:56 p.m.
Message ID <1272992201-26911-5-git-send-email-anomie@users.sourceforge.net>
Download mbox | patch
Permalink /patch/51657/
State New
Headers show

Comments

Brad Jorsch - May 4, 2010, 4:56 p.m.
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 <anomie@users.sourceforge.net>
---
 hw/usb-hid.c |   44 ++++++++++++++++++++++++++++++++++++--------
 1 files changed, 36 insertions(+), 8 deletions(-)

Patch

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;