4 * Copyright (c) 2005 Fabrice Bellard
5 * Copyright (c) 2007 OpenMoko, Inc. (andrew@openedhand.com)
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 /* HID interface requests */
30 #define GET_REPORT 0xa101
31 #define GET_IDLE 0xa102
32 #define GET_PROTOCOL 0xa103
33 #define SET_REPORT 0x2109
34 #define SET_IDLE 0x210a
35 #define SET_PROTOCOL 0x210b
37 /* HID descriptor types */
38 #define USB_DT_HID 0x21
39 #define USB_DT_REPORT 0x22
40 #define USB_DT_PHY 0x23
44 #define USB_KEYBOARD 3
46 typedef struct USBMouseState
{
47 int dx
, dy
, dz
, buttons_state
;
50 QEMUPutMouseEntry
*eh_entry
;
53 typedef struct USBKeyboardState
{
60 typedef struct USBHIDState
{
72 /* mostly the same values as the Bochs USB Mouse device */
73 static const uint8_t qemu_mouse_dev_descriptor
[] = {
74 0x12, /* u8 bLength; */
75 0x01, /* u8 bDescriptorType; Device */
76 0x00, 0x01, /* u16 bcdUSB; v1.0 */
78 0x00, /* u8 bDeviceClass; */
79 0x00, /* u8 bDeviceSubClass; */
80 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
81 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
83 0x27, 0x06, /* u16 idVendor; */
84 0x01, 0x00, /* u16 idProduct; */
85 0x00, 0x00, /* u16 bcdDevice */
87 0x03, /* u8 iManufacturer; */
88 0x02, /* u8 iProduct; */
89 0x01, /* u8 iSerialNumber; */
90 0x01 /* u8 bNumConfigurations; */
93 static const uint8_t qemu_mouse_config_descriptor
[] = {
94 /* one configuration */
95 0x09, /* u8 bLength; */
96 0x02, /* u8 bDescriptorType; Configuration */
97 0x22, 0x00, /* u16 wTotalLength; */
98 0x01, /* u8 bNumInterfaces; (1) */
99 0x01, /* u8 bConfigurationValue; */
100 0x04, /* u8 iConfiguration; */
101 0xa0, /* u8 bmAttributes;
106 50, /* u8 MaxPower; */
109 * USB 2.0, single TT organization (mandatory):
110 * one interface, protocol 0
112 * USB 2.0, multiple TT organization (optional):
113 * two interfaces, protocols 1 (like single TT)
114 * and 2 (multiple TT mode) ... config is
120 0x09, /* u8 if_bLength; */
121 0x04, /* u8 if_bDescriptorType; Interface */
122 0x00, /* u8 if_bInterfaceNumber; */
123 0x00, /* u8 if_bAlternateSetting; */
124 0x01, /* u8 if_bNumEndpoints; */
125 0x03, /* u8 if_bInterfaceClass; */
126 0x01, /* u8 if_bInterfaceSubClass; */
127 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
128 0x07, /* u8 if_iInterface; */
131 0x09, /* u8 bLength; */
132 0x21, /* u8 bDescriptorType; */
133 0x01, 0x00, /* u16 HID_class */
134 0x00, /* u8 country_code */
135 0x01, /* u8 num_descriptors */
136 0x22, /* u8 type; Report */
139 /* one endpoint (status change endpoint) */
140 0x07, /* u8 ep_bLength; */
141 0x05, /* u8 ep_bDescriptorType; Endpoint */
142 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
143 0x03, /* u8 ep_bmAttributes; Interrupt */
144 0x03, 0x00, /* u16 ep_wMaxPacketSize; */
145 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
148 static const uint8_t qemu_tablet_config_descriptor
[] = {
149 /* one configuration */
150 0x09, /* u8 bLength; */
151 0x02, /* u8 bDescriptorType; Configuration */
152 0x22, 0x00, /* u16 wTotalLength; */
153 0x01, /* u8 bNumInterfaces; (1) */
154 0x01, /* u8 bConfigurationValue; */
155 0x05, /* u8 iConfiguration; */
156 0xa0, /* u8 bmAttributes;
161 50, /* u8 MaxPower; */
164 * USB 2.0, single TT organization (mandatory):
165 * one interface, protocol 0
167 * USB 2.0, multiple TT organization (optional):
168 * two interfaces, protocols 1 (like single TT)
169 * and 2 (multiple TT mode) ... config is
175 0x09, /* u8 if_bLength; */
176 0x04, /* u8 if_bDescriptorType; Interface */
177 0x00, /* u8 if_bInterfaceNumber; */
178 0x00, /* u8 if_bAlternateSetting; */
179 0x01, /* u8 if_bNumEndpoints; */
180 0x03, /* u8 if_bInterfaceClass; */
181 0x01, /* u8 if_bInterfaceSubClass; */
182 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
183 0x07, /* u8 if_iInterface; */
186 0x09, /* u8 bLength; */
187 0x21, /* u8 bDescriptorType; */
188 0x01, 0x00, /* u16 HID_class */
189 0x00, /* u8 country_code */
190 0x01, /* u8 num_descriptors */
191 0x22, /* u8 type; Report */
194 /* one endpoint (status change endpoint) */
195 0x07, /* u8 ep_bLength; */
196 0x05, /* u8 ep_bDescriptorType; Endpoint */
197 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
198 0x03, /* u8 ep_bmAttributes; Interrupt */
199 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
200 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
203 static const uint8_t qemu_keyboard_config_descriptor
[] = {
204 /* one configuration */
205 0x09, /* u8 bLength; */
206 USB_DT_CONFIG
, /* u8 bDescriptorType; Configuration */
207 0x22, 0x00, /* u16 wTotalLength; */
208 0x01, /* u8 bNumInterfaces; (1) */
209 0x01, /* u8 bConfigurationValue; */
210 0x06, /* u8 iConfiguration; */
211 0xa0, /* u8 bmAttributes;
216 0x32, /* u8 MaxPower; */
219 * USB 2.0, single TT organization (mandatory):
220 * one interface, protocol 0
222 * USB 2.0, multiple TT organization (optional):
223 * two interfaces, protocols 1 (like single TT)
224 * and 2 (multiple TT mode) ... config is
230 0x09, /* u8 if_bLength; */
231 USB_DT_INTERFACE
, /* u8 if_bDescriptorType; Interface */
232 0x00, /* u8 if_bInterfaceNumber; */
233 0x00, /* u8 if_bAlternateSetting; */
234 0x01, /* u8 if_bNumEndpoints; */
235 0x03, /* u8 if_bInterfaceClass; HID */
236 0x01, /* u8 if_bInterfaceSubClass; Boot */
237 0x01, /* u8 if_bInterfaceProtocol; Keyboard */
238 0x07, /* u8 if_iInterface; */
241 0x09, /* u8 bLength; */
242 USB_DT_HID
, /* u8 bDescriptorType; */
243 0x11, 0x01, /* u16 HID_class */
244 0x00, /* u8 country_code */
245 0x01, /* u8 num_descriptors */
246 USB_DT_REPORT
, /* u8 type; Report */
247 0x3f, 0x00, /* u16 len */
249 /* one endpoint (status change endpoint) */
250 0x07, /* u8 ep_bLength; */
251 USB_DT_ENDPOINT
, /* u8 ep_bDescriptorType; Endpoint */
252 USB_DIR_IN
| 0x01, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
253 0x03, /* u8 ep_bmAttributes; Interrupt */
254 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
255 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
258 static const uint8_t qemu_mouse_hid_report_descriptor
[] = {
259 0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01,
260 0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03,
261 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01,
262 0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x01,
263 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81,
264 0x25, 0x7F, 0x75, 0x08, 0x95, 0x02, 0x81, 0x06,
265 0x05, 0x01, 0x09, 0x38, 0x15, 0x81, 0x25, 0x7F,
266 0x35, 0x00, 0x45, 0x00, 0x75, 0x08, 0x95, 0x01,
267 0x81, 0x02, 0xC0, 0xC0,
270 static const uint8_t qemu_tablet_hid_report_descriptor
[] = {
271 0x05, 0x01, /* Usage Page Generic Desktop */
272 0x09, 0x01, /* Usage Mouse */
273 0xA1, 0x01, /* Collection Application */
274 0x09, 0x01, /* Usage Pointer */
275 0xA1, 0x00, /* Collection Physical */
276 0x05, 0x09, /* Usage Page Button */
277 0x19, 0x01, /* Usage Minimum Button 1 */
278 0x29, 0x03, /* Usage Maximum Button 3 */
279 0x15, 0x00, /* Logical Minimum 0 */
280 0x25, 0x01, /* Logical Maximum 1 */
281 0x95, 0x03, /* Report Count 3 */
282 0x75, 0x01, /* Report Size 1 */
283 0x81, 0x02, /* Input (Data, Var, Abs) */
284 0x95, 0x01, /* Report Count 1 */
285 0x75, 0x05, /* Report Size 5 */
286 0x81, 0x01, /* Input (Cnst, Var, Abs) */
287 0x05, 0x01, /* Usage Page Generic Desktop */
288 0x09, 0x30, /* Usage X */
289 0x09, 0x31, /* Usage Y */
290 0x15, 0x00, /* Logical Minimum 0 */
291 0x26, 0xFF, 0x7F, /* Logical Maximum 0x7fff */
292 0x35, 0x00, /* Physical Minimum 0 */
293 0x46, 0xFE, 0x7F, /* Physical Maximum 0x7fff */
294 0x75, 0x10, /* Report Size 16 */
295 0x95, 0x02, /* Report Count 2 */
296 0x81, 0x02, /* Input (Data, Var, Abs) */
297 0x05, 0x01, /* Usage Page Generic Desktop */
298 0x09, 0x38, /* Usage Wheel */
299 0x15, 0x81, /* Logical Minimum -127 */
300 0x25, 0x7F, /* Logical Maximum 127 */
301 0x35, 0x00, /* Physical Minimum 0 (same as logical) */
302 0x45, 0x00, /* Physical Maximum 0 (same as logical) */
303 0x75, 0x08, /* Report Size 8 */
304 0x95, 0x01, /* Report Count 1 */
305 0x81, 0x02, /* Input (Data, Var, Rel) */
306 0xC0, /* End Collection */
307 0xC0, /* End Collection */
310 static const uint8_t qemu_keyboard_hid_report_descriptor
[] = {
311 0x05, 0x01, /* Usage Page (Generic Desktop) */
312 0x09, 0x06, /* Usage (Keyboard) */
313 0xa1, 0x01, /* Collection (Application) */
314 0x75, 0x01, /* Report Size (1) */
315 0x95, 0x08, /* Report Count (8) */
316 0x05, 0x07, /* Usage Page (Key Codes) */
317 0x19, 0xe0, /* Usage Minimum (224) */
318 0x29, 0xe7, /* Usage Maximum (231) */
319 0x15, 0x00, /* Logical Minimum (0) */
320 0x25, 0x01, /* Logical Maximum (1) */
321 0x81, 0x02, /* Input (Data, Variable, Absolute) */
322 0x95, 0x01, /* Report Count (1) */
323 0x75, 0x08, /* Report Size (8) */
324 0x81, 0x01, /* Input (Constant) */
325 0x95, 0x05, /* Report Count (5) */
326 0x75, 0x01, /* Report Size (1) */
327 0x05, 0x08, /* Usage Page (LEDs) */
328 0x19, 0x01, /* Usage Minimum (1) */
329 0x29, 0x05, /* Usage Maximum (5) */
330 0x91, 0x02, /* Output (Data, Variable, Absolute) */
331 0x95, 0x01, /* Report Count (1) */
332 0x75, 0x03, /* Report Size (3) */
333 0x91, 0x01, /* Output (Constant) */
334 0x95, 0x06, /* Report Count (6) */
335 0x75, 0x08, /* Report Size (8) */
336 0x15, 0x00, /* Logical Minimum (0) */
337 0x25, 0xff, /* Logical Maximum (255) */
338 0x05, 0x07, /* Usage Page (Key Codes) */
339 0x19, 0x00, /* Usage Minimum (0) */
340 0x29, 0xff, /* Usage Maximum (255) */
341 0x81, 0x00, /* Input (Data, Array) */
342 0xc0, /* End Collection */
345 #define USB_HID_USAGE_ERROR_ROLLOVER 0x01
346 #define USB_HID_USAGE_POSTFAIL 0x02
347 #define USB_HID_USAGE_ERROR_UNDEFINED 0x03
349 /* Indices are QEMU keycodes, values are from HID Usage Table. Indices
350 * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d. */
351 static const uint8_t usb_hid_usage_keys
[0x100] = {
352 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
353 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
354 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
355 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
356 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
357 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
358 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
359 0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
360 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
361 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
362 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
363 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
364 0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
365 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
366 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
376 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
378 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
379 0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387 static void usb_mouse_event(void *opaque
,
388 int dx1
, int dy1
, int dz1
, int buttons_state
)
390 USBHIDState
*hs
= opaque
;
391 USBMouseState
*s
= &hs
->ptr
;
396 s
->buttons_state
= buttons_state
;
400 static void usb_tablet_event(void *opaque
,
401 int x
, int y
, int dz
, int buttons_state
)
403 USBHIDState
*hs
= opaque
;
404 USBMouseState
*s
= &hs
->ptr
;
409 s
->buttons_state
= buttons_state
;
413 static void usb_keyboard_event(void *opaque
, int keycode
)
415 USBHIDState
*hs
= opaque
;
416 USBKeyboardState
*s
= &hs
->kbd
;
417 uint8_t hid_code
, key
;
420 key
= keycode
& 0x7f;
421 hid_code
= usb_hid_usage_keys
[key
| ((s
->modifiers
>> 1) & (1 << 7))];
422 s
->modifiers
&= ~(1 << 8);
431 if (s
->modifiers
& (1 << 9)) {
432 s
->modifiers
^= 3 << 8;
436 if (keycode
& (1 << 7)) {
437 s
->modifiers
&= ~(1 << (hid_code
& 0x0f));
441 s
->modifiers
|= 1 << (hid_code
& 0x0f);
445 if (keycode
& (1 << 7)) {
446 for (i
= s
->keys
- 1; i
>= 0; i
--)
447 if (s
->key
[i
] == hid_code
) {
448 s
->key
[i
] = s
->key
[-- s
->keys
];
449 s
->key
[s
->keys
] = 0x00;
453 for (i
= s
->keys
- 1; i
>= 0; i
--)
454 if (s
->key
[i
] == hid_code
)
456 if (s
->keys
< sizeof(s
->key
))
457 s
->key
[s
->keys
++] = hid_code
;
461 static inline int int_clamp(int val
, int vmin
, int vmax
)
471 static int usb_mouse_poll(USBHIDState
*hs
, uint8_t *buf
, int len
)
473 int dx
, dy
, dz
, b
, l
;
474 USBMouseState
*s
= &hs
->ptr
;
476 if (!s
->mouse_grabbed
) {
477 s
->eh_entry
= qemu_add_mouse_event_handler(usb_mouse_event
, hs
,
478 0, "QEMU USB Mouse");
479 s
->mouse_grabbed
= 1;
482 dx
= int_clamp(s
->dx
, -128, 127);
483 dy
= int_clamp(s
->dy
, -128, 127);
484 dz
= int_clamp(s
->dz
, -128, 127);
491 if (s
->buttons_state
& MOUSE_EVENT_LBUTTON
)
493 if (s
->buttons_state
& MOUSE_EVENT_RBUTTON
)
495 if (s
->buttons_state
& MOUSE_EVENT_MBUTTON
)
509 static int usb_tablet_poll(USBHIDState
*hs
, uint8_t *buf
, int len
)
512 USBMouseState
*s
= &hs
->ptr
;
514 if (!s
->mouse_grabbed
) {
515 s
->eh_entry
= qemu_add_mouse_event_handler(usb_tablet_event
, hs
,
516 1, "QEMU USB Tablet");
517 s
->mouse_grabbed
= 1;
520 dz
= int_clamp(s
->dz
, -128, 127);
523 /* Appears we have to invert the wheel direction */
526 if (s
->buttons_state
& MOUSE_EVENT_LBUTTON
)
528 if (s
->buttons_state
& MOUSE_EVENT_RBUTTON
)
530 if (s
->buttons_state
& MOUSE_EVENT_MBUTTON
)
534 buf
[1] = s
->x
& 0xff;
536 buf
[3] = s
->y
& 0xff;
544 static int usb_keyboard_poll(USBKeyboardState
*s
, uint8_t *buf
, int len
)
549 buf
[0] = s
->modifiers
& 0xff;
552 memset(buf
+ 2, USB_HID_USAGE_ERROR_ROLLOVER
, MIN(8, len
) - 2);
554 memcpy(buf
+ 2, s
->key
, MIN(8, len
) - 2);
559 static int usb_keyboard_write(USBKeyboardState
*s
, uint8_t *buf
, int len
)
562 /* 0x01: Num Lock LED
563 * 0x02: Caps Lock LED
564 * 0x04: Scroll Lock LED
572 static void usb_mouse_handle_reset(USBDevice
*dev
)
574 USBHIDState
*s
= (USBHIDState
*)dev
;
581 s
->ptr
.buttons_state
= 0;
585 static void usb_keyboard_handle_reset(USBDevice
*dev
)
587 USBHIDState
*s
= (USBHIDState
*)dev
;
589 qemu_add_kbd_event_handler(usb_keyboard_event
, s
);
593 static int usb_hid_handle_control(USBDevice
*dev
, int request
, int value
,
594 int index
, int length
, uint8_t *data
)
596 USBHIDState
*s
= (USBHIDState
*)dev
;
600 case DeviceRequest
| USB_REQ_GET_STATUS
:
601 data
[0] = (1 << USB_DEVICE_SELF_POWERED
) |
602 (dev
->remote_wakeup
<< USB_DEVICE_REMOTE_WAKEUP
);
606 case DeviceOutRequest
| USB_REQ_CLEAR_FEATURE
:
607 if (value
== USB_DEVICE_REMOTE_WAKEUP
) {
608 dev
->remote_wakeup
= 0;
614 case DeviceOutRequest
| USB_REQ_SET_FEATURE
:
615 if (value
== USB_DEVICE_REMOTE_WAKEUP
) {
616 dev
->remote_wakeup
= 1;
622 case DeviceOutRequest
| USB_REQ_SET_ADDRESS
:
626 case DeviceRequest
| USB_REQ_GET_DESCRIPTOR
:
629 memcpy(data
, qemu_mouse_dev_descriptor
,
630 sizeof(qemu_mouse_dev_descriptor
));
631 ret
= sizeof(qemu_mouse_dev_descriptor
);
634 if (s
->kind
== USB_MOUSE
) {
635 memcpy(data
, qemu_mouse_config_descriptor
,
636 sizeof(qemu_mouse_config_descriptor
));
637 ret
= sizeof(qemu_mouse_config_descriptor
);
638 } else if (s
->kind
== USB_TABLET
) {
639 memcpy(data
, qemu_tablet_config_descriptor
,
640 sizeof(qemu_tablet_config_descriptor
));
641 ret
= sizeof(qemu_tablet_config_descriptor
);
642 } else if (s
->kind
== USB_KEYBOARD
) {
643 memcpy(data
, qemu_keyboard_config_descriptor
,
644 sizeof(qemu_keyboard_config_descriptor
));
645 ret
= sizeof(qemu_keyboard_config_descriptor
);
649 switch(value
& 0xff) {
660 ret
= set_usb_string(data
, "1");
663 /* product description */
664 ret
= set_usb_string(data
, s
->dev
.devname
);
667 /* vendor description */
668 ret
= set_usb_string(data
, "QEMU " QEMU_VERSION
);
671 ret
= set_usb_string(data
, "HID Mouse");
674 ret
= set_usb_string(data
, "HID Tablet");
677 ret
= set_usb_string(data
, "HID Keyboard");
680 ret
= set_usb_string(data
, "Endpoint1 Interrupt Pipe");
690 case DeviceRequest
| USB_REQ_GET_CONFIGURATION
:
694 case DeviceOutRequest
| USB_REQ_SET_CONFIGURATION
:
697 case DeviceRequest
| USB_REQ_GET_INTERFACE
:
701 case DeviceOutRequest
| USB_REQ_SET_INTERFACE
:
704 /* hid specific requests */
705 case InterfaceRequest
| USB_REQ_GET_DESCRIPTOR
:
708 if (s
->kind
== USB_MOUSE
) {
709 memcpy(data
, qemu_mouse_hid_report_descriptor
,
710 sizeof(qemu_mouse_hid_report_descriptor
));
711 ret
= sizeof(qemu_mouse_hid_report_descriptor
);
712 } else if (s
->kind
== USB_TABLET
) {
713 memcpy(data
, qemu_tablet_hid_report_descriptor
,
714 sizeof(qemu_tablet_hid_report_descriptor
));
715 ret
= sizeof(qemu_tablet_hid_report_descriptor
);
716 } else if (s
->kind
== USB_KEYBOARD
) {
717 memcpy(data
, qemu_keyboard_hid_report_descriptor
,
718 sizeof(qemu_keyboard_hid_report_descriptor
));
719 ret
= sizeof(qemu_keyboard_hid_report_descriptor
);
727 if (s
->kind
== USB_MOUSE
)
728 ret
= usb_mouse_poll(s
, data
, length
);
729 else if (s
->kind
== USB_TABLET
)
730 ret
= usb_tablet_poll(s
, data
, length
);
731 else if (s
->kind
== USB_KEYBOARD
)
732 ret
= usb_keyboard_poll(&s
->kbd
, data
, length
);
735 if (s
->kind
== USB_KEYBOARD
)
736 ret
= usb_keyboard_write(&s
->kbd
, data
, length
);
741 if (s
->kind
!= USB_KEYBOARD
)
744 data
[0] = s
->protocol
;
747 if (s
->kind
!= USB_KEYBOARD
)
768 static int usb_hid_handle_data(USBDevice
*dev
, USBPacket
*p
)
770 USBHIDState
*s
= (USBHIDState
*)dev
;
776 /* TODO: Implement finite idle delays. */
777 if (!(s
->changed
|| s
->idle
))
780 if (s
->kind
== USB_MOUSE
)
781 ret
= usb_mouse_poll(s
, p
->data
, p
->len
);
782 else if (s
->kind
== USB_TABLET
)
783 ret
= usb_tablet_poll(s
, p
->data
, p
->len
);
784 else if (s
->kind
== USB_KEYBOARD
)
785 ret
= usb_keyboard_poll(&s
->kbd
, p
->data
, p
->len
);
799 static void usb_hid_handle_destroy(USBDevice
*dev
)
801 USBHIDState
*s
= (USBHIDState
*)dev
;
803 if (s
->kind
!= USB_KEYBOARD
)
804 qemu_remove_mouse_event_handler(s
->ptr
.eh_entry
);
809 USBDevice
*usb_tablet_init(void)
813 s
= qemu_mallocz(sizeof(USBHIDState
));
816 s
->dev
.speed
= USB_SPEED_FULL
;
817 s
->dev
.handle_packet
= usb_generic_handle_packet
;
819 s
->dev
.handle_reset
= usb_mouse_handle_reset
;
820 s
->dev
.handle_control
= usb_hid_handle_control
;
821 s
->dev
.handle_data
= usb_hid_handle_data
;
822 s
->dev
.handle_destroy
= usb_hid_handle_destroy
;
823 s
->kind
= USB_TABLET
;
824 /* Force poll routine to be run and grab input the first time. */
827 pstrcpy(s
->dev
.devname
, sizeof(s
->dev
.devname
), "QEMU USB Tablet");
829 return (USBDevice
*)s
;
832 USBDevice
*usb_mouse_init(void)
836 s
= qemu_mallocz(sizeof(USBHIDState
));
839 s
->dev
.speed
= USB_SPEED_FULL
;
840 s
->dev
.handle_packet
= usb_generic_handle_packet
;
842 s
->dev
.handle_reset
= usb_mouse_handle_reset
;
843 s
->dev
.handle_control
= usb_hid_handle_control
;
844 s
->dev
.handle_data
= usb_hid_handle_data
;
845 s
->dev
.handle_destroy
= usb_hid_handle_destroy
;
847 /* Force poll routine to be run and grab input the first time. */
850 pstrcpy(s
->dev
.devname
, sizeof(s
->dev
.devname
), "QEMU USB Mouse");
852 return (USBDevice
*)s
;
855 USBDevice
*usb_keyboard_init(void)
859 s
= qemu_mallocz(sizeof(USBHIDState
));
862 s
->dev
.speed
= USB_SPEED_FULL
;
863 s
->dev
.handle_packet
= usb_generic_handle_packet
;
865 s
->dev
.handle_reset
= usb_keyboard_handle_reset
;
866 s
->dev
.handle_control
= usb_hid_handle_control
;
867 s
->dev
.handle_data
= usb_hid_handle_data
;
868 s
->dev
.handle_destroy
= usb_hid_handle_destroy
;
869 s
->kind
= USB_KEYBOARD
;
871 pstrcpy(s
->dev
.devname
, sizeof(s
->dev
.devname
), "QEMU USB Keyboard");
873 return (USBDevice
*) s
;