4 * Copyright (c) 2005 Fabrice Bellard
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 /* HID interface requests */
27 #define GET_REPORT 0xa101
28 #define GET_IDLE 0xa102
29 #define GET_PROTOCOL 0xa103
30 #define SET_IDLE 0x210a
31 #define SET_PROTOCOL 0x210b
33 typedef struct USBMouseState {
35 int dx, dy, dz, buttons_state;
38 /* mostly the same values as the Bochs USB Mouse device */
39 static const uint8_t qemu_mouse_dev_descriptor[] = {
40 0x12, /* u8 bLength; */
41 0x01, /* u8 bDescriptorType; Device */
42 0x10, 0x00, /* u16 bcdUSB; v1.0 */
44 0x00, /* u8 bDeviceClass; */
45 0x00, /* u8 bDeviceSubClass; */
46 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
47 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
49 0x27, 0x06, /* u16 idVendor; */
50 0x01, 0x00, /* u16 idProduct; */
51 0x00, 0x00, /* u16 bcdDevice */
53 0x03, /* u8 iManufacturer; */
54 0x02, /* u8 iProduct; */
55 0x01, /* u8 iSerialNumber; */
56 0x01 /* u8 bNumConfigurations; */
59 static const uint8_t qemu_mouse_config_descriptor[] = {
60 /* one configuration */
61 0x09, /* u8 bLength; */
62 0x02, /* u8 bDescriptorType; Configuration */
63 0x22, 0x00, /* u16 wTotalLength; */
64 0x01, /* u8 bNumInterfaces; (1) */
65 0x01, /* u8 bConfigurationValue; */
66 0x04, /* u8 iConfiguration; */
67 0xa0, /* u8 bmAttributes;
72 50, /* u8 MaxPower; */
75 * USB 2.0, single TT organization (mandatory):
76 * one interface, protocol 0
78 * USB 2.0, multiple TT organization (optional):
79 * two interfaces, protocols 1 (like single TT)
80 * and 2 (multiple TT mode) ... config is
86 0x09, /* u8 if_bLength; */
87 0x04, /* u8 if_bDescriptorType; Interface */
88 0x00, /* u8 if_bInterfaceNumber; */
89 0x00, /* u8 if_bAlternateSetting; */
90 0x01, /* u8 if_bNumEndpoints; */
91 0x03, /* u8 if_bInterfaceClass; */
92 0x01, /* u8 if_bInterfaceSubClass; */
93 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
94 0x05, /* u8 if_iInterface; */
96 /* one endpoint (status change endpoint) */
97 0x07, /* u8 ep_bLength; */
98 0x05, /* u8 ep_bDescriptorType; Endpoint */
99 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
100 0x03, /* u8 ep_bmAttributes; Interrupt */
101 0x03, 0x00, /* u16 ep_wMaxPacketSize; */
102 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
105 0x09, /* u8 bLength; */
106 0x21, /* u8 bDescriptorType; */
107 0x01, 0x00, /* u16 HID_class */
108 0x00, /* u8 country_code */
109 0x01, /* u8 num_descriptors */
110 0x22, /* u8 type; Report */
114 static const uint8_t qemu_mouse_hid_report_descriptor[] = {
115 0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01,
116 0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03,
117 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01,
118 0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x01,
119 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81,
120 0x25, 0x7F, 0x75, 0x08, 0x95, 0x02, 0x81, 0x06,
124 static void usb_mouse_event(void *opaque,
125 int dx1, int dy1, int dz1, int buttons_state)
127 USBMouseState *s = opaque;
132 s->buttons_state = buttons_state;
135 static inline int int_clamp(int val, int vmin, int vmax)
145 static int usb_mouse_poll(USBMouseState *s, uint8_t *buf, int len)
147 int dx, dy, dz, b, l;
149 dx = int_clamp(s->dx, -128, 127);
150 dy = int_clamp(s->dy, -128, 127);
151 dz = int_clamp(s->dz, -128, 127);
158 if (s->buttons_state & MOUSE_EVENT_LBUTTON)
160 if (s->buttons_state & MOUSE_EVENT_RBUTTON)
162 if (s->buttons_state & MOUSE_EVENT_MBUTTON)
176 static void usb_mouse_handle_reset(USBDevice *dev)
178 USBMouseState *s = (USBMouseState *)dev;
183 s->buttons_state = 0;
186 static int usb_mouse_handle_control(USBDevice *dev, int request, int value,
187 int index, int length, uint8_t *data)
189 USBMouseState *s = (USBMouseState *)dev;
193 case DeviceRequest | USB_REQ_GET_STATUS:
194 data[0] = (1 << USB_DEVICE_SELF_POWERED) |
195 (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
199 case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
200 if (value == USB_DEVICE_REMOTE_WAKEUP) {
201 dev->remote_wakeup = 0;
207 case DeviceOutRequest | USB_REQ_SET_FEATURE:
208 if (value == USB_DEVICE_REMOTE_WAKEUP) {
209 dev->remote_wakeup = 1;
215 case DeviceOutRequest | USB_REQ_SET_ADDRESS:
219 case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
222 memcpy(data, qemu_mouse_dev_descriptor,
223 sizeof(qemu_mouse_dev_descriptor));
224 ret = sizeof(qemu_mouse_dev_descriptor);
227 memcpy(data, qemu_mouse_config_descriptor,
228 sizeof(qemu_mouse_config_descriptor));
229 ret = sizeof(qemu_mouse_config_descriptor);
232 switch(value & 0xff) {
243 ret = set_usb_string(data, "1");
246 /* product description */
247 ret = set_usb_string(data, "QEMU USB Mouse");
250 /* vendor description */
251 ret = set_usb_string(data, "QEMU " QEMU_VERSION);
254 ret = set_usb_string(data, "HID Mouse");
257 ret = set_usb_string(data, "Endpoint1 Interrupt Pipe");
267 case DeviceRequest | USB_REQ_GET_CONFIGURATION:
271 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
274 case DeviceRequest | USB_REQ_GET_INTERFACE:
278 case DeviceOutRequest | USB_REQ_SET_INTERFACE:
281 /* hid specific requests */
282 case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
285 memcpy(data, qemu_mouse_hid_report_descriptor,
286 sizeof(qemu_mouse_hid_report_descriptor));
287 ret = sizeof(qemu_mouse_hid_report_descriptor);
294 ret = usb_mouse_poll(s, data, length);
307 static int usb_mouse_handle_data(USBDevice *dev, int pid,
308 uint8_t devep, uint8_t *data, int len)
310 USBMouseState *s = (USBMouseState *)dev;
316 ret = usb_mouse_poll(s, data, len);
330 USBDevice *usb_mouse_init(void)
334 s = qemu_mallocz(sizeof(USBMouseState));
337 s->dev.speed = USB_SPEED_FULL;
338 s->dev.handle_packet = usb_generic_handle_packet;
340 s->dev.handle_reset = usb_mouse_handle_reset;
341 s->dev.handle_control = usb_mouse_handle_control;
342 s->dev.handle_data = usb_mouse_handle_data;
344 qemu_add_mouse_event_handler(usb_mouse_event, s);
346 return (USBDevice *)s;