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
30 /* HID interface requests */
31 #define GET_REPORT 0xa101
32 #define GET_IDLE 0xa102
33 #define GET_PROTOCOL 0xa103
34 #define SET_REPORT 0x2109
35 #define SET_IDLE 0x210a
36 #define SET_PROTOCOL 0x210b
38 /* HID descriptor types */
39 #define USB_DT_HID 0x21
40 #define USB_DT_REPORT 0x22
41 #define USB_DT_PHY 0x23
45 #define USB_KEYBOARD 3
47 typedef struct USBMouseState
{
48 int dx
, dy
, dz
, buttons_state
;
51 QEMUPutMouseEntry
*eh_entry
;
54 typedef struct USBKeyboardState
{
61 typedef struct USBHIDState
{
70 int64_t next_idle_clock
;
73 void (*datain
)(void *);
76 /* mostly the same values as the Bochs USB Mouse device */
77 static const uint8_t qemu_mouse_dev_descriptor
[] = {
78 0x12, /* u8 bLength; */
79 0x01, /* u8 bDescriptorType; Device */
80 0x00, 0x01, /* u16 bcdUSB; v1.0 */
82 0x00, /* u8 bDeviceClass; */
83 0x00, /* u8 bDeviceSubClass; */
84 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
85 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
87 0x27, 0x06, /* u16 idVendor; */
88 0x01, 0x00, /* u16 idProduct; */
89 0x00, 0x00, /* u16 bcdDevice */
91 0x03, /* u8 iManufacturer; */
92 0x02, /* u8 iProduct; */
93 0x01, /* u8 iSerialNumber; */
94 0x01 /* u8 bNumConfigurations; */
97 static const uint8_t qemu_mouse_config_descriptor
[] = {
98 /* one configuration */
99 0x09, /* u8 bLength; */
100 0x02, /* u8 bDescriptorType; Configuration */
101 0x22, 0x00, /* u16 wTotalLength; */
102 0x01, /* u8 bNumInterfaces; (1) */
103 0x01, /* u8 bConfigurationValue; */
104 0x04, /* u8 iConfiguration; */
105 0xe0, /* u8 bmAttributes;
110 50, /* u8 MaxPower; */
113 * USB 2.0, single TT organization (mandatory):
114 * one interface, protocol 0
116 * USB 2.0, multiple TT organization (optional):
117 * two interfaces, protocols 1 (like single TT)
118 * and 2 (multiple TT mode) ... config is
124 0x09, /* u8 if_bLength; */
125 0x04, /* u8 if_bDescriptorType; Interface */
126 0x00, /* u8 if_bInterfaceNumber; */
127 0x00, /* u8 if_bAlternateSetting; */
128 0x01, /* u8 if_bNumEndpoints; */
129 0x03, /* u8 if_bInterfaceClass; */
130 0x01, /* u8 if_bInterfaceSubClass; */
131 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
132 0x07, /* u8 if_iInterface; */
135 0x09, /* u8 bLength; */
136 0x21, /* u8 bDescriptorType; */
137 0x01, 0x00, /* u16 HID_class */
138 0x00, /* u8 country_code */
139 0x01, /* u8 num_descriptors */
140 0x22, /* u8 type; Report */
143 /* one endpoint (status change endpoint) */
144 0x07, /* u8 ep_bLength; */
145 0x05, /* u8 ep_bDescriptorType; Endpoint */
146 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
147 0x03, /* u8 ep_bmAttributes; Interrupt */
148 0x04, 0x00, /* u16 ep_wMaxPacketSize; */
149 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
152 static const uint8_t qemu_tablet_config_descriptor
[] = {
153 /* one configuration */
154 0x09, /* u8 bLength; */
155 0x02, /* u8 bDescriptorType; Configuration */
156 0x22, 0x00, /* u16 wTotalLength; */
157 0x01, /* u8 bNumInterfaces; (1) */
158 0x01, /* u8 bConfigurationValue; */
159 0x05, /* u8 iConfiguration; */
160 0xa0, /* u8 bmAttributes;
165 50, /* u8 MaxPower; */
168 * USB 2.0, single TT organization (mandatory):
169 * one interface, protocol 0
171 * USB 2.0, multiple TT organization (optional):
172 * two interfaces, protocols 1 (like single TT)
173 * and 2 (multiple TT mode) ... config is
179 0x09, /* u8 if_bLength; */
180 0x04, /* u8 if_bDescriptorType; Interface */
181 0x00, /* u8 if_bInterfaceNumber; */
182 0x00, /* u8 if_bAlternateSetting; */
183 0x01, /* u8 if_bNumEndpoints; */
184 0x03, /* u8 if_bInterfaceClass; */
185 0x01, /* u8 if_bInterfaceSubClass; */
186 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
187 0x07, /* u8 if_iInterface; */
190 0x09, /* u8 bLength; */
191 0x21, /* u8 bDescriptorType; */
192 0x01, 0x00, /* u16 HID_class */
193 0x00, /* u8 country_code */
194 0x01, /* u8 num_descriptors */
195 0x22, /* u8 type; Report */
198 /* one endpoint (status change endpoint) */
199 0x07, /* u8 ep_bLength; */
200 0x05, /* u8 ep_bDescriptorType; Endpoint */
201 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
202 0x03, /* u8 ep_bmAttributes; Interrupt */
203 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
204 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
207 static const uint8_t qemu_keyboard_config_descriptor
[] = {
208 /* one configuration */
209 0x09, /* u8 bLength; */
210 USB_DT_CONFIG
, /* u8 bDescriptorType; Configuration */
211 0x22, 0x00, /* u16 wTotalLength; */
212 0x01, /* u8 bNumInterfaces; (1) */
213 0x01, /* u8 bConfigurationValue; */
214 0x06, /* u8 iConfiguration; */
215 0xa0, /* u8 bmAttributes;
220 0x32, /* u8 MaxPower; */
223 * USB 2.0, single TT organization (mandatory):
224 * one interface, protocol 0
226 * USB 2.0, multiple TT organization (optional):
227 * two interfaces, protocols 1 (like single TT)
228 * and 2 (multiple TT mode) ... config is
234 0x09, /* u8 if_bLength; */
235 USB_DT_INTERFACE
, /* u8 if_bDescriptorType; Interface */
236 0x00, /* u8 if_bInterfaceNumber; */
237 0x00, /* u8 if_bAlternateSetting; */
238 0x01, /* u8 if_bNumEndpoints; */
239 0x03, /* u8 if_bInterfaceClass; HID */
240 0x01, /* u8 if_bInterfaceSubClass; Boot */
241 0x01, /* u8 if_bInterfaceProtocol; Keyboard */
242 0x07, /* u8 if_iInterface; */
245 0x09, /* u8 bLength; */
246 USB_DT_HID
, /* u8 bDescriptorType; */
247 0x11, 0x01, /* u16 HID_class */
248 0x00, /* u8 country_code */
249 0x01, /* u8 num_descriptors */
250 USB_DT_REPORT
, /* u8 type; Report */
251 0x3f, 0x00, /* u16 len */
253 /* one endpoint (status change endpoint) */
254 0x07, /* u8 ep_bLength; */
255 USB_DT_ENDPOINT
, /* u8 ep_bDescriptorType; Endpoint */
256 USB_DIR_IN
| 0x01, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
257 0x03, /* u8 ep_bmAttributes; Interrupt */
258 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
259 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
262 static const uint8_t qemu_mouse_hid_report_descriptor
[] = {
263 0x05, 0x01, /* Usage Page (Generic Desktop) */
264 0x09, 0x02, /* Usage (Mouse) */
265 0xa1, 0x01, /* Collection (Application) */
266 0x09, 0x01, /* Usage (Pointer) */
267 0xa1, 0x00, /* Collection (Physical) */
268 0x05, 0x09, /* Usage Page (Button) */
269 0x19, 0x01, /* Usage Minimum (1) */
270 0x29, 0x03, /* Usage Maximum (3) */
271 0x15, 0x00, /* Logical Minimum (0) */
272 0x25, 0x01, /* Logical Maximum (1) */
273 0x95, 0x03, /* Report Count (3) */
274 0x75, 0x01, /* Report Size (1) */
275 0x81, 0x02, /* Input (Data, Variable, Absolute) */
276 0x95, 0x01, /* Report Count (1) */
277 0x75, 0x05, /* Report Size (5) */
278 0x81, 0x01, /* Input (Constant) */
279 0x05, 0x01, /* Usage Page (Generic Desktop) */
280 0x09, 0x30, /* Usage (X) */
281 0x09, 0x31, /* Usage (Y) */
282 0x09, 0x38, /* Usage (Wheel) */
283 0x15, 0x81, /* Logical Minimum (-0x7f) */
284 0x25, 0x7f, /* Logical Maximum (0x7f) */
285 0x75, 0x08, /* Report Size (8) */
286 0x95, 0x03, /* Report Count (3) */
287 0x81, 0x06, /* Input (Data, Variable, Relative) */
288 0xc0, /* End Collection */
289 0xc0, /* End Collection */
292 static const uint8_t qemu_tablet_hid_report_descriptor
[] = {
293 0x05, 0x01, /* Usage Page (Generic Desktop) */
294 0x09, 0x01, /* Usage (Pointer) */
295 0xa1, 0x01, /* Collection (Application) */
296 0x09, 0x01, /* Usage (Pointer) */
297 0xa1, 0x00, /* Collection (Physical) */
298 0x05, 0x09, /* Usage Page (Button) */
299 0x19, 0x01, /* Usage Minimum (1) */
300 0x29, 0x03, /* Usage Maximum (3) */
301 0x15, 0x00, /* Logical Minimum (0) */
302 0x25, 0x01, /* Logical Maximum (1) */
303 0x95, 0x03, /* Report Count (3) */
304 0x75, 0x01, /* Report Size (1) */
305 0x81, 0x02, /* Input (Data, Variable, Absolute) */
306 0x95, 0x01, /* Report Count (1) */
307 0x75, 0x05, /* Report Size (5) */
308 0x81, 0x01, /* Input (Constant) */
309 0x05, 0x01, /* Usage Page (Generic Desktop) */
310 0x09, 0x30, /* Usage (X) */
311 0x09, 0x31, /* Usage (Y) */
312 0x15, 0x00, /* Logical Minimum (0) */
313 0x26, 0xff, 0x7f, /* Logical Maximum (0x7fff) */
314 0x35, 0x00, /* Physical Minimum (0) */
315 0x46, 0xff, 0x7f, /* Physical Maximum (0x7fff) */
316 0x75, 0x10, /* Report Size (16) */
317 0x95, 0x02, /* Report Count (2) */
318 0x81, 0x02, /* Input (Data, Variable, Absolute) */
319 0x05, 0x01, /* Usage Page (Generic Desktop) */
320 0x09, 0x38, /* Usage (Wheel) */
321 0x15, 0x81, /* Logical Minimum (-0x7f) */
322 0x25, 0x7f, /* Logical Maximum (0x7f) */
323 0x35, 0x00, /* Physical Minimum (same as logical) */
324 0x45, 0x00, /* Physical Maximum (same as logical) */
325 0x75, 0x08, /* Report Size (8) */
326 0x95, 0x01, /* Report Count (1) */
327 0x81, 0x06, /* Input (Data, Variable, Relative) */
328 0xc0, /* End Collection */
329 0xc0, /* End Collection */
332 static const uint8_t qemu_keyboard_hid_report_descriptor
[] = {
333 0x05, 0x01, /* Usage Page (Generic Desktop) */
334 0x09, 0x06, /* Usage (Keyboard) */
335 0xa1, 0x01, /* Collection (Application) */
336 0x75, 0x01, /* Report Size (1) */
337 0x95, 0x08, /* Report Count (8) */
338 0x05, 0x07, /* Usage Page (Key Codes) */
339 0x19, 0xe0, /* Usage Minimum (224) */
340 0x29, 0xe7, /* Usage Maximum (231) */
341 0x15, 0x00, /* Logical Minimum (0) */
342 0x25, 0x01, /* Logical Maximum (1) */
343 0x81, 0x02, /* Input (Data, Variable, Absolute) */
344 0x95, 0x01, /* Report Count (1) */
345 0x75, 0x08, /* Report Size (8) */
346 0x81, 0x01, /* Input (Constant) */
347 0x95, 0x05, /* Report Count (5) */
348 0x75, 0x01, /* Report Size (1) */
349 0x05, 0x08, /* Usage Page (LEDs) */
350 0x19, 0x01, /* Usage Minimum (1) */
351 0x29, 0x05, /* Usage Maximum (5) */
352 0x91, 0x02, /* Output (Data, Variable, Absolute) */
353 0x95, 0x01, /* Report Count (1) */
354 0x75, 0x03, /* Report Size (3) */
355 0x91, 0x01, /* Output (Constant) */
356 0x95, 0x06, /* Report Count (6) */
357 0x75, 0x08, /* Report Size (8) */
358 0x15, 0x00, /* Logical Minimum (0) */
359 0x25, 0xff, /* Logical Maximum (255) */
360 0x05, 0x07, /* Usage Page (Key Codes) */
361 0x19, 0x00, /* Usage Minimum (0) */
362 0x29, 0xff, /* Usage Maximum (255) */
363 0x81, 0x00, /* Input (Data, Array) */
364 0xc0, /* End Collection */
367 #define USB_HID_USAGE_ERROR_ROLLOVER 0x01
368 #define USB_HID_USAGE_POSTFAIL 0x02
369 #define USB_HID_USAGE_ERROR_UNDEFINED 0x03
371 /* Indices are QEMU keycodes, values are from HID Usage Table. Indices
372 * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d. */
373 static const uint8_t usb_hid_usage_keys
[0x100] = {
374 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
375 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
376 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
377 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
378 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
379 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
380 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
381 0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
382 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
383 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
384 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
385 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
386 0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
395 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
398 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
400 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
401 0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
402 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409 static void usb_hid_changed(USBHIDState
*hs
)
414 hs
->datain(hs
->datain_opaque
);
417 static void usb_mouse_event(void *opaque
,
418 int dx1
, int dy1
, int dz1
, int buttons_state
)
420 USBHIDState
*hs
= opaque
;
421 USBMouseState
*s
= &hs
->ptr
;
426 s
->buttons_state
= buttons_state
;
431 static void usb_tablet_event(void *opaque
,
432 int x
, int y
, int dz
, int buttons_state
)
434 USBHIDState
*hs
= opaque
;
435 USBMouseState
*s
= &hs
->ptr
;
440 s
->buttons_state
= buttons_state
;
445 static void usb_keyboard_event(void *opaque
, int keycode
)
447 USBHIDState
*hs
= opaque
;
448 USBKeyboardState
*s
= &hs
->kbd
;
449 uint8_t hid_code
, key
;
452 key
= keycode
& 0x7f;
453 hid_code
= usb_hid_usage_keys
[key
| ((s
->modifiers
>> 1) & (1 << 7))];
454 s
->modifiers
&= ~(1 << 8);
461 if (s
->modifiers
& (1 << 9)) {
462 s
->modifiers
^= 3 << 8;
466 if (keycode
& (1 << 7)) {
467 s
->modifiers
&= ~(1 << (hid_code
& 0x0f));
471 s
->modifiers
|= 1 << (hid_code
& 0x0f);
475 if (keycode
& (1 << 7)) {
476 for (i
= s
->keys
- 1; i
>= 0; i
--)
477 if (s
->key
[i
] == hid_code
) {
478 s
->key
[i
] = s
->key
[-- s
->keys
];
479 s
->key
[s
->keys
] = 0x00;
486 for (i
= s
->keys
- 1; i
>= 0; i
--)
487 if (s
->key
[i
] == hid_code
)
490 if (s
->keys
< sizeof(s
->key
))
491 s
->key
[s
->keys
++] = hid_code
;
499 static inline int int_clamp(int val
, int vmin
, int vmax
)
509 static int usb_mouse_poll(USBHIDState
*hs
, uint8_t *buf
, int len
)
511 int dx
, dy
, dz
, b
, l
;
512 USBMouseState
*s
= &hs
->ptr
;
514 if (!s
->mouse_grabbed
) {
515 qemu_activate_mouse_event_handler(s
->eh_entry
);
516 s
->mouse_grabbed
= 1;
519 dx
= int_clamp(s
->dx
, -127, 127);
520 dy
= int_clamp(s
->dy
, -127, 127);
521 dz
= int_clamp(s
->dz
, -127, 127);
527 /* Appears we have to invert the wheel direction */
531 if (s
->buttons_state
& MOUSE_EVENT_LBUTTON
)
533 if (s
->buttons_state
& MOUSE_EVENT_RBUTTON
)
535 if (s
->buttons_state
& MOUSE_EVENT_MBUTTON
)
550 static int usb_tablet_poll(USBHIDState
*hs
, uint8_t *buf
, int len
)
553 USBMouseState
*s
= &hs
->ptr
;
555 if (!s
->mouse_grabbed
) {
556 qemu_activate_mouse_event_handler(s
->eh_entry
);
557 s
->mouse_grabbed
= 1;
560 dz
= int_clamp(s
->dz
, -127, 127);
563 /* Appears we have to invert the wheel direction */
566 if (s
->buttons_state
& MOUSE_EVENT_LBUTTON
)
568 if (s
->buttons_state
& MOUSE_EVENT_RBUTTON
)
570 if (s
->buttons_state
& MOUSE_EVENT_MBUTTON
)
574 buf
[1] = s
->x
& 0xff;
576 buf
[3] = s
->y
& 0xff;
584 static int usb_keyboard_poll(USBKeyboardState
*s
, uint8_t *buf
, int len
)
589 buf
[0] = s
->modifiers
& 0xff;
592 memset(buf
+ 2, USB_HID_USAGE_ERROR_ROLLOVER
, MIN(8, len
) - 2);
594 memcpy(buf
+ 2, s
->key
, MIN(8, len
) - 2);
599 static int usb_keyboard_write(USBKeyboardState
*s
, uint8_t *buf
, int len
)
603 /* 0x01: Num Lock LED
604 * 0x02: Caps Lock LED
605 * 0x04: Scroll Lock LED
610 ledstate
|= QEMU_SCROLL_LOCK_LED
;
612 ledstate
|= QEMU_NUM_LOCK_LED
;
614 ledstate
|= QEMU_CAPS_LOCK_LED
;
615 kbd_put_ledstate(ledstate
);
620 static void usb_mouse_handle_reset(USBDevice
*dev
)
622 USBHIDState
*s
= (USBHIDState
*)dev
;
629 s
->ptr
.buttons_state
= 0;
633 static void usb_keyboard_handle_reset(USBDevice
*dev
)
635 USBHIDState
*s
= (USBHIDState
*)dev
;
637 qemu_add_kbd_event_handler(usb_keyboard_event
, s
);
641 static void usb_hid_set_next_idle(USBHIDState
*s
, int64_t curtime
)
643 s
->next_idle_clock
= curtime
+ (get_ticks_per_sec() * s
->idle
* 4) / 1000;
646 static int usb_hid_handle_control(USBDevice
*dev
, int request
, int value
,
647 int index
, int length
, uint8_t *data
)
649 USBHIDState
*s
= (USBHIDState
*)dev
;
653 case DeviceRequest
| USB_REQ_GET_STATUS
:
654 data
[0] = (1 << USB_DEVICE_SELF_POWERED
) |
655 (dev
->remote_wakeup
<< USB_DEVICE_REMOTE_WAKEUP
);
659 case DeviceOutRequest
| USB_REQ_CLEAR_FEATURE
:
660 if (value
== USB_DEVICE_REMOTE_WAKEUP
) {
661 dev
->remote_wakeup
= 0;
667 case DeviceOutRequest
| USB_REQ_SET_FEATURE
:
668 if (value
== USB_DEVICE_REMOTE_WAKEUP
) {
669 dev
->remote_wakeup
= 1;
675 case DeviceOutRequest
| USB_REQ_SET_ADDRESS
:
679 case DeviceRequest
| USB_REQ_GET_DESCRIPTOR
:
682 memcpy(data
, qemu_mouse_dev_descriptor
,
683 sizeof(qemu_mouse_dev_descriptor
));
684 ret
= sizeof(qemu_mouse_dev_descriptor
);
687 if (s
->kind
== USB_MOUSE
) {
688 memcpy(data
, qemu_mouse_config_descriptor
,
689 sizeof(qemu_mouse_config_descriptor
));
690 ret
= sizeof(qemu_mouse_config_descriptor
);
691 } else if (s
->kind
== USB_TABLET
) {
692 memcpy(data
, qemu_tablet_config_descriptor
,
693 sizeof(qemu_tablet_config_descriptor
));
694 ret
= sizeof(qemu_tablet_config_descriptor
);
695 } else if (s
->kind
== USB_KEYBOARD
) {
696 memcpy(data
, qemu_keyboard_config_descriptor
,
697 sizeof(qemu_keyboard_config_descriptor
));
698 ret
= sizeof(qemu_keyboard_config_descriptor
);
702 switch(value
& 0xff) {
713 ret
= set_usb_string(data
, "1");
716 /* product description */
717 ret
= set_usb_string(data
, s
->dev
.product_desc
);
720 /* vendor description */
721 ret
= set_usb_string(data
, "QEMU " QEMU_VERSION
);
724 ret
= set_usb_string(data
, "HID Mouse");
727 ret
= set_usb_string(data
, "HID Tablet");
730 ret
= set_usb_string(data
, "HID Keyboard");
733 ret
= set_usb_string(data
, "Endpoint1 Interrupt Pipe");
743 case DeviceRequest
| USB_REQ_GET_CONFIGURATION
:
747 case DeviceOutRequest
| USB_REQ_SET_CONFIGURATION
:
750 case DeviceRequest
| USB_REQ_GET_INTERFACE
:
754 case DeviceOutRequest
| USB_REQ_SET_INTERFACE
:
757 /* hid specific requests */
758 case InterfaceRequest
| USB_REQ_GET_DESCRIPTOR
:
761 if (s
->kind
== USB_MOUSE
) {
762 memcpy(data
, qemu_mouse_hid_report_descriptor
,
763 sizeof(qemu_mouse_hid_report_descriptor
));
764 ret
= sizeof(qemu_mouse_hid_report_descriptor
);
765 } else if (s
->kind
== USB_TABLET
) {
766 memcpy(data
, qemu_tablet_hid_report_descriptor
,
767 sizeof(qemu_tablet_hid_report_descriptor
));
768 ret
= sizeof(qemu_tablet_hid_report_descriptor
);
769 } else if (s
->kind
== USB_KEYBOARD
) {
770 memcpy(data
, qemu_keyboard_hid_report_descriptor
,
771 sizeof(qemu_keyboard_hid_report_descriptor
));
772 ret
= sizeof(qemu_keyboard_hid_report_descriptor
);
780 if (s
->kind
== USB_MOUSE
)
781 ret
= usb_mouse_poll(s
, data
, length
);
782 else if (s
->kind
== USB_TABLET
)
783 ret
= usb_tablet_poll(s
, data
, length
);
784 else if (s
->kind
== USB_KEYBOARD
)
785 ret
= usb_keyboard_poll(&s
->kbd
, data
, length
);
788 if (s
->kind
== USB_KEYBOARD
)
789 ret
= usb_keyboard_write(&s
->kbd
, data
, length
);
794 if (s
->kind
!= USB_KEYBOARD
)
797 data
[0] = s
->protocol
;
800 if (s
->kind
!= USB_KEYBOARD
)
810 s
->idle
= (uint8_t) (value
>> 8);
811 usb_hid_set_next_idle(s
, qemu_get_clock(vm_clock
));
822 static int usb_hid_handle_data(USBDevice
*dev
, USBPacket
*p
)
824 USBHIDState
*s
= (USBHIDState
*)dev
;
830 int64_t curtime
= qemu_get_clock(vm_clock
);
831 if (!s
->changed
&& (!s
->idle
|| s
->next_idle_clock
- curtime
> 0))
833 usb_hid_set_next_idle(s
, curtime
);
835 if (s
->kind
== USB_MOUSE
)
836 ret
= usb_mouse_poll(s
, p
->data
, p
->len
);
837 else if (s
->kind
== USB_TABLET
)
838 ret
= usb_tablet_poll(s
, p
->data
, p
->len
);
839 else if (s
->kind
== USB_KEYBOARD
)
840 ret
= usb_keyboard_poll(&s
->kbd
, p
->data
, p
->len
);
854 static void usb_hid_handle_destroy(USBDevice
*dev
)
856 USBHIDState
*s
= (USBHIDState
*)dev
;
860 qemu_remove_kbd_event_handler();
863 qemu_remove_mouse_event_handler(s
->ptr
.eh_entry
);
867 static int usb_hid_initfn(USBDevice
*dev
, int kind
)
869 USBHIDState
*s
= DO_UPCAST(USBHIDState
, dev
, dev
);
870 s
->dev
.speed
= USB_SPEED_FULL
;
873 if (s
->kind
== USB_MOUSE
) {
874 s
->ptr
.eh_entry
= qemu_add_mouse_event_handler(usb_mouse_event
, s
,
875 0, "QEMU USB Mouse");
876 } else if (s
->kind
== USB_TABLET
) {
877 s
->ptr
.eh_entry
= qemu_add_mouse_event_handler(usb_tablet_event
, s
,
878 1, "QEMU USB Tablet");
881 /* Force poll routine to be run and grab input the first time. */
886 static int usb_tablet_initfn(USBDevice
*dev
)
888 return usb_hid_initfn(dev
, USB_TABLET
);
891 static int usb_mouse_initfn(USBDevice
*dev
)
893 return usb_hid_initfn(dev
, USB_MOUSE
);
896 static int usb_keyboard_initfn(USBDevice
*dev
)
898 return usb_hid_initfn(dev
, USB_KEYBOARD
);
901 void usb_hid_datain_cb(USBDevice
*dev
, void *opaque
, void (*datain
)(void *))
903 USBHIDState
*s
= (USBHIDState
*)dev
;
905 s
->datain_opaque
= opaque
;
909 static struct USBDeviceInfo hid_info
[] = {
911 .product_desc
= "QEMU USB Tablet",
912 .qdev
.name
= "usb-tablet",
913 .usbdevice_name
= "tablet",
914 .qdev
.size
= sizeof(USBHIDState
),
915 .init
= usb_tablet_initfn
,
916 .handle_packet
= usb_generic_handle_packet
,
917 .handle_reset
= usb_mouse_handle_reset
,
918 .handle_control
= usb_hid_handle_control
,
919 .handle_data
= usb_hid_handle_data
,
920 .handle_destroy
= usb_hid_handle_destroy
,
922 .product_desc
= "QEMU USB Mouse",
923 .qdev
.name
= "usb-mouse",
924 .usbdevice_name
= "mouse",
925 .qdev
.size
= sizeof(USBHIDState
),
926 .init
= usb_mouse_initfn
,
927 .handle_packet
= usb_generic_handle_packet
,
928 .handle_reset
= usb_mouse_handle_reset
,
929 .handle_control
= usb_hid_handle_control
,
930 .handle_data
= usb_hid_handle_data
,
931 .handle_destroy
= usb_hid_handle_destroy
,
933 .product_desc
= "QEMU USB Keyboard",
934 .qdev
.name
= "usb-kbd",
935 .usbdevice_name
= "keyboard",
936 .qdev
.size
= sizeof(USBHIDState
),
937 .init
= usb_keyboard_initfn
,
938 .handle_packet
= usb_generic_handle_packet
,
939 .handle_reset
= usb_keyboard_handle_reset
,
940 .handle_control
= usb_hid_handle_control
,
941 .handle_data
= usb_hid_handle_data
,
942 .handle_destroy
= usb_hid_handle_destroy
,
948 static void usb_hid_register_devices(void)
950 usb_qdev_register_many(hid_info
);
952 device_init(usb_hid_register_devices
)