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 #include "qemu-timer.h"
31 /* HID interface requests */
32 #define GET_REPORT 0xa101
33 #define GET_IDLE 0xa102
34 #define GET_PROTOCOL 0xa103
35 #define SET_REPORT 0x2109
36 #define SET_IDLE 0x210a
37 #define SET_PROTOCOL 0x210b
39 /* HID descriptor types */
40 #define USB_DT_HID 0x21
41 #define USB_DT_REPORT 0x22
42 #define USB_DT_PHY 0x23
46 #define HID_KEYBOARD 3
48 typedef struct HIDPointerEvent
{
49 int32_t xdx
, ydy
; /* relative iff it's a mouse, otherwise absolute */
50 int32_t dz
, buttons_state
;
53 #define QUEUE_LENGTH 16 /* should be enough for a triple-click */
54 #define QUEUE_MASK (QUEUE_LENGTH-1u)
55 #define QUEUE_INCR(v) ((v)++, (v) &= QUEUE_MASK)
57 typedef struct HIDState HIDState
;
58 typedef void (*HIDEventFunc
)(HIDState
*s
);
60 typedef struct HIDMouseState
{
61 HIDPointerEvent queue
[QUEUE_LENGTH
];
63 QEMUPutMouseEntry
*eh_entry
;
66 typedef struct HIDKeyboardState
{
67 uint32_t keycodes
[QUEUE_LENGTH
];
79 uint32_t head
; /* index into circular queue */
85 typedef struct USBHIDState
{
90 int64_t next_idle_clock
;
92 void (*datain
)(void *);
106 static const USBDescStrings desc_strings
= {
107 [STR_MANUFACTURER
] = "QEMU " QEMU_VERSION
,
108 [STR_PRODUCT_MOUSE
] = "QEMU USB Mouse",
109 [STR_PRODUCT_TABLET
] = "QEMU USB Tablet",
110 [STR_PRODUCT_KEYBOARD
] = "QEMU USB Keyboard",
111 [STR_SERIALNUMBER
] = "42", /* == remote wakeup works */
112 [STR_CONFIG_MOUSE
] = "HID Mouse",
113 [STR_CONFIG_TABLET
] = "HID Tablet",
114 [STR_CONFIG_KEYBOARD
] = "HID Keyboard",
117 static const USBDescIface desc_iface_mouse
= {
118 .bInterfaceNumber
= 0,
120 .bInterfaceClass
= USB_CLASS_HID
,
121 .bInterfaceSubClass
= 0x01, /* boot */
122 .bInterfaceProtocol
= 0x02,
124 .descs
= (USBDescOther
[]) {
127 .data
= (uint8_t[]) {
128 0x09, /* u8 bLength */
129 USB_DT_HID
, /* u8 bDescriptorType */
130 0x01, 0x00, /* u16 HID_class */
131 0x00, /* u8 country_code */
132 0x01, /* u8 num_descriptors */
133 USB_DT_REPORT
, /* u8 type: Report */
138 .eps
= (USBDescEndpoint
[]) {
140 .bEndpointAddress
= USB_DIR_IN
| 0x01,
141 .bmAttributes
= USB_ENDPOINT_XFER_INT
,
148 static const USBDescIface desc_iface_tablet
= {
149 .bInterfaceNumber
= 0,
151 .bInterfaceClass
= USB_CLASS_HID
,
152 .bInterfaceProtocol
= 0x02,
154 .descs
= (USBDescOther
[]) {
157 .data
= (uint8_t[]) {
158 0x09, /* u8 bLength */
159 USB_DT_HID
, /* u8 bDescriptorType */
160 0x01, 0x00, /* u16 HID_class */
161 0x00, /* u8 country_code */
162 0x01, /* u8 num_descriptors */
163 USB_DT_REPORT
, /* u8 type: Report */
168 .eps
= (USBDescEndpoint
[]) {
170 .bEndpointAddress
= USB_DIR_IN
| 0x01,
171 .bmAttributes
= USB_ENDPOINT_XFER_INT
,
178 static const USBDescIface desc_iface_keyboard
= {
179 .bInterfaceNumber
= 0,
181 .bInterfaceClass
= USB_CLASS_HID
,
182 .bInterfaceSubClass
= 0x01, /* boot */
183 .bInterfaceProtocol
= 0x01, /* keyboard */
185 .descs
= (USBDescOther
[]) {
188 .data
= (uint8_t[]) {
189 0x09, /* u8 bLength */
190 USB_DT_HID
, /* u8 bDescriptorType */
191 0x11, 0x01, /* u16 HID_class */
192 0x00, /* u8 country_code */
193 0x01, /* u8 num_descriptors */
194 USB_DT_REPORT
, /* u8 type: Report */
195 0x3f, 0, /* u16 len */
199 .eps
= (USBDescEndpoint
[]) {
201 .bEndpointAddress
= USB_DIR_IN
| 0x01,
202 .bmAttributes
= USB_ENDPOINT_XFER_INT
,
209 static const USBDescDevice desc_device_mouse
= {
211 .bMaxPacketSize0
= 8,
212 .bNumConfigurations
= 1,
213 .confs
= (USBDescConfig
[]) {
216 .bConfigurationValue
= 1,
217 .iConfiguration
= STR_CONFIG_MOUSE
,
218 .bmAttributes
= 0xa0,
221 .ifs
= &desc_iface_mouse
,
226 static const USBDescDevice desc_device_tablet
= {
228 .bMaxPacketSize0
= 8,
229 .bNumConfigurations
= 1,
230 .confs
= (USBDescConfig
[]) {
233 .bConfigurationValue
= 1,
234 .iConfiguration
= STR_CONFIG_TABLET
,
235 .bmAttributes
= 0xa0,
238 .ifs
= &desc_iface_tablet
,
243 static const USBDescDevice desc_device_keyboard
= {
245 .bMaxPacketSize0
= 8,
246 .bNumConfigurations
= 1,
247 .confs
= (USBDescConfig
[]) {
250 .bConfigurationValue
= 1,
251 .iConfiguration
= STR_CONFIG_KEYBOARD
,
252 .bmAttributes
= 0xa0,
255 .ifs
= &desc_iface_keyboard
,
260 static const USBDesc desc_mouse
= {
265 .iManufacturer
= STR_MANUFACTURER
,
266 .iProduct
= STR_PRODUCT_MOUSE
,
267 .iSerialNumber
= STR_SERIALNUMBER
,
269 .full
= &desc_device_mouse
,
273 static const USBDesc desc_tablet
= {
278 .iManufacturer
= STR_MANUFACTURER
,
279 .iProduct
= STR_PRODUCT_TABLET
,
280 .iSerialNumber
= STR_SERIALNUMBER
,
282 .full
= &desc_device_tablet
,
286 static const USBDesc desc_keyboard
= {
291 .iManufacturer
= STR_MANUFACTURER
,
292 .iProduct
= STR_PRODUCT_KEYBOARD
,
293 .iSerialNumber
= STR_SERIALNUMBER
,
295 .full
= &desc_device_keyboard
,
299 static const uint8_t qemu_mouse_hid_report_descriptor
[] = {
300 0x05, 0x01, /* Usage Page (Generic Desktop) */
301 0x09, 0x02, /* Usage (Mouse) */
302 0xa1, 0x01, /* Collection (Application) */
303 0x09, 0x01, /* Usage (Pointer) */
304 0xa1, 0x00, /* Collection (Physical) */
305 0x05, 0x09, /* Usage Page (Button) */
306 0x19, 0x01, /* Usage Minimum (1) */
307 0x29, 0x03, /* Usage Maximum (3) */
308 0x15, 0x00, /* Logical Minimum (0) */
309 0x25, 0x01, /* Logical Maximum (1) */
310 0x95, 0x03, /* Report Count (3) */
311 0x75, 0x01, /* Report Size (1) */
312 0x81, 0x02, /* Input (Data, Variable, Absolute) */
313 0x95, 0x01, /* Report Count (1) */
314 0x75, 0x05, /* Report Size (5) */
315 0x81, 0x01, /* Input (Constant) */
316 0x05, 0x01, /* Usage Page (Generic Desktop) */
317 0x09, 0x30, /* Usage (X) */
318 0x09, 0x31, /* Usage (Y) */
319 0x09, 0x38, /* Usage (Wheel) */
320 0x15, 0x81, /* Logical Minimum (-0x7f) */
321 0x25, 0x7f, /* Logical Maximum (0x7f) */
322 0x75, 0x08, /* Report Size (8) */
323 0x95, 0x03, /* Report Count (3) */
324 0x81, 0x06, /* Input (Data, Variable, Relative) */
325 0xc0, /* End Collection */
326 0xc0, /* End Collection */
329 static const uint8_t qemu_tablet_hid_report_descriptor
[] = {
330 0x05, 0x01, /* Usage Page (Generic Desktop) */
331 0x09, 0x01, /* Usage (Pointer) */
332 0xa1, 0x01, /* Collection (Application) */
333 0x09, 0x01, /* Usage (Pointer) */
334 0xa1, 0x00, /* Collection (Physical) */
335 0x05, 0x09, /* Usage Page (Button) */
336 0x19, 0x01, /* Usage Minimum (1) */
337 0x29, 0x03, /* Usage Maximum (3) */
338 0x15, 0x00, /* Logical Minimum (0) */
339 0x25, 0x01, /* Logical Maximum (1) */
340 0x95, 0x03, /* Report Count (3) */
341 0x75, 0x01, /* Report Size (1) */
342 0x81, 0x02, /* Input (Data, Variable, Absolute) */
343 0x95, 0x01, /* Report Count (1) */
344 0x75, 0x05, /* Report Size (5) */
345 0x81, 0x01, /* Input (Constant) */
346 0x05, 0x01, /* Usage Page (Generic Desktop) */
347 0x09, 0x30, /* Usage (X) */
348 0x09, 0x31, /* Usage (Y) */
349 0x15, 0x00, /* Logical Minimum (0) */
350 0x26, 0xff, 0x7f, /* Logical Maximum (0x7fff) */
351 0x35, 0x00, /* Physical Minimum (0) */
352 0x46, 0xff, 0x7f, /* Physical Maximum (0x7fff) */
353 0x75, 0x10, /* Report Size (16) */
354 0x95, 0x02, /* Report Count (2) */
355 0x81, 0x02, /* Input (Data, Variable, Absolute) */
356 0x05, 0x01, /* Usage Page (Generic Desktop) */
357 0x09, 0x38, /* Usage (Wheel) */
358 0x15, 0x81, /* Logical Minimum (-0x7f) */
359 0x25, 0x7f, /* Logical Maximum (0x7f) */
360 0x35, 0x00, /* Physical Minimum (same as logical) */
361 0x45, 0x00, /* Physical Maximum (same as logical) */
362 0x75, 0x08, /* Report Size (8) */
363 0x95, 0x01, /* Report Count (1) */
364 0x81, 0x06, /* Input (Data, Variable, Relative) */
365 0xc0, /* End Collection */
366 0xc0, /* End Collection */
369 static const uint8_t qemu_keyboard_hid_report_descriptor
[] = {
370 0x05, 0x01, /* Usage Page (Generic Desktop) */
371 0x09, 0x06, /* Usage (Keyboard) */
372 0xa1, 0x01, /* Collection (Application) */
373 0x75, 0x01, /* Report Size (1) */
374 0x95, 0x08, /* Report Count (8) */
375 0x05, 0x07, /* Usage Page (Key Codes) */
376 0x19, 0xe0, /* Usage Minimum (224) */
377 0x29, 0xe7, /* Usage Maximum (231) */
378 0x15, 0x00, /* Logical Minimum (0) */
379 0x25, 0x01, /* Logical Maximum (1) */
380 0x81, 0x02, /* Input (Data, Variable, Absolute) */
381 0x95, 0x01, /* Report Count (1) */
382 0x75, 0x08, /* Report Size (8) */
383 0x81, 0x01, /* Input (Constant) */
384 0x95, 0x05, /* Report Count (5) */
385 0x75, 0x01, /* Report Size (1) */
386 0x05, 0x08, /* Usage Page (LEDs) */
387 0x19, 0x01, /* Usage Minimum (1) */
388 0x29, 0x05, /* Usage Maximum (5) */
389 0x91, 0x02, /* Output (Data, Variable, Absolute) */
390 0x95, 0x01, /* Report Count (1) */
391 0x75, 0x03, /* Report Size (3) */
392 0x91, 0x01, /* Output (Constant) */
393 0x95, 0x06, /* Report Count (6) */
394 0x75, 0x08, /* Report Size (8) */
395 0x15, 0x00, /* Logical Minimum (0) */
396 0x25, 0xff, /* Logical Maximum (255) */
397 0x05, 0x07, /* Usage Page (Key Codes) */
398 0x19, 0x00, /* Usage Minimum (0) */
399 0x29, 0xff, /* Usage Maximum (255) */
400 0x81, 0x00, /* Input (Data, Array) */
401 0xc0, /* End Collection */
404 #define USB_HID_USAGE_ERROR_ROLLOVER 0x01
405 #define USB_HID_USAGE_POSTFAIL 0x02
406 #define USB_HID_USAGE_ERROR_UNDEFINED 0x03
408 /* Indices are QEMU keycodes, values are from HID Usage Table. Indices
409 * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d. */
410 static const uint8_t usb_hid_usage_keys
[0x100] = {
411 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
412 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
413 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
414 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
415 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
416 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
417 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
418 0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
419 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
420 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
421 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
422 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
423 0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
424 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
425 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
426 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
428 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
431 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
432 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
434 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
435 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
437 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
438 0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
439 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 0x00, 0x00,
440 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
441 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
443 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
446 static bool hid_has_events(HIDState
*hs
)
451 static void usb_hid_changed(HIDState
*hs
)
453 USBHIDState
*us
= container_of(hs
, USBHIDState
, hid
);
456 us
->datain(us
->datain_opaque
);
459 usb_wakeup(&us
->dev
);
462 static void hid_pointer_event_clear(HIDPointerEvent
*e
, int buttons
)
464 e
->xdx
= e
->ydy
= e
->dz
= 0;
465 e
->buttons_state
= buttons
;
468 static void hid_pointer_event_combine(HIDPointerEvent
*e
, int xyrel
,
469 int x1
, int y1
, int z1
) {
476 /* Windows drivers do not like the 0/0 position and ignore such
485 static void hid_pointer_event(void *opaque
,
486 int x1
, int y1
, int z1
, int buttons_state
)
488 HIDState
*hs
= opaque
;
489 unsigned use_slot
= (hs
->head
+ hs
->n
- 1) & QUEUE_MASK
;
490 unsigned previous_slot
= (use_slot
- 1) & QUEUE_MASK
;
492 /* We combine events where feasible to keep the queue small. We shouldn't
493 * combine anything with the first event of a particular button state, as
494 * that would change the location of the button state change. When the
495 * queue is empty, a second event is needed because we don't know if
496 * the first event changed the button state. */
497 if (hs
->n
== QUEUE_LENGTH
) {
498 /* Queue full. Discard old button state, combine motion normally. */
499 hs
->ptr
.queue
[use_slot
].buttons_state
= buttons_state
;
500 } else if (hs
->n
< 2 ||
501 hs
->ptr
.queue
[use_slot
].buttons_state
!= buttons_state
||
502 hs
->ptr
.queue
[previous_slot
].buttons_state
!=
503 hs
->ptr
.queue
[use_slot
].buttons_state
) {
504 /* Cannot or should not combine, so add an empty item to the queue. */
505 QUEUE_INCR(use_slot
);
507 hid_pointer_event_clear(&hs
->ptr
.queue
[use_slot
], buttons_state
);
509 hid_pointer_event_combine(&hs
->ptr
.queue
[use_slot
],
510 hs
->kind
== HID_MOUSE
,
515 static void hid_keyboard_event(void *opaque
, int keycode
)
517 HIDState
*hs
= opaque
;
520 if (hs
->n
== QUEUE_LENGTH
) {
521 fprintf(stderr
, "usb-kbd: warning: key event queue full\n");
524 slot
= (hs
->head
+ hs
->n
) & QUEUE_MASK
; hs
->n
++;
525 hs
->kbd
.keycodes
[slot
] = keycode
;
529 static void hid_keyboard_process_keycode(HIDState
*hs
)
531 uint8_t hid_code
, key
;
532 int i
, keycode
, slot
;
537 slot
= hs
->head
& QUEUE_MASK
; QUEUE_INCR(hs
->head
); hs
->n
--;
538 keycode
= hs
->kbd
.keycodes
[slot
];
540 key
= keycode
& 0x7f;
541 hid_code
= usb_hid_usage_keys
[key
| ((hs
->kbd
.modifiers
>> 1) & (1 << 7))];
542 hs
->kbd
.modifiers
&= ~(1 << 8);
549 if (hs
->kbd
.modifiers
& (1 << 9)) {
550 hs
->kbd
.modifiers
^= 3 << 8;
554 if (keycode
& (1 << 7)) {
555 hs
->kbd
.modifiers
&= ~(1 << (hid_code
& 0x0f));
559 hs
->kbd
.modifiers
|= 1 << (hid_code
& 0x0f);
563 if (keycode
& (1 << 7)) {
564 for (i
= hs
->kbd
.keys
- 1; i
>= 0; i
--) {
565 if (hs
->kbd
.key
[i
] == hid_code
) {
566 hs
->kbd
.key
[i
] = hs
->kbd
.key
[-- hs
->kbd
.keys
];
567 hs
->kbd
.key
[hs
->kbd
.keys
] = 0x00;
575 for (i
= hs
->kbd
.keys
- 1; i
>= 0; i
--) {
576 if (hs
->kbd
.key
[i
] == hid_code
) {
581 if (hs
->kbd
.keys
< sizeof(hs
->kbd
.key
)) {
582 hs
->kbd
.key
[hs
->kbd
.keys
++] = hid_code
;
590 static inline int int_clamp(int val
, int vmin
, int vmax
)
600 static int hid_pointer_poll(HIDState
*hs
, uint8_t *buf
, int len
)
602 int dx
, dy
, dz
, b
, l
;
606 if (!hs
->ptr
.mouse_grabbed
) {
607 qemu_activate_mouse_event_handler(hs
->ptr
.eh_entry
);
608 hs
->ptr
.mouse_grabbed
= 1;
611 /* When the buffer is empty, return the last event. Relative
612 movements will all be zero. */
613 index
= (hs
->n
? hs
->head
: hs
->head
- 1);
614 e
= &hs
->ptr
.queue
[index
& QUEUE_MASK
];
616 if (hs
->kind
== HID_MOUSE
) {
617 dx
= int_clamp(e
->xdx
, -127, 127);
618 dy
= int_clamp(e
->ydy
, -127, 127);
625 dz
= int_clamp(e
->dz
, -127, 127);
629 if (e
->buttons_state
& MOUSE_EVENT_LBUTTON
)
631 if (e
->buttons_state
& MOUSE_EVENT_RBUTTON
)
633 if (e
->buttons_state
& MOUSE_EVENT_MBUTTON
)
638 (hs
->kind
== HID_TABLET
|| (!e
->xdx
&& !e
->ydy
))) {
639 /* that deals with this event */
640 QUEUE_INCR(hs
->head
);
644 /* Appears we have to invert the wheel direction */
663 buf
[l
++] = dx
& 0xff;
667 buf
[l
++] = dy
& 0xff;
681 static int hid_keyboard_poll(HIDState
*hs
, uint8_t *buf
, int len
)
686 hid_keyboard_process_keycode(hs
);
688 buf
[0] = hs
->kbd
.modifiers
& 0xff;
690 if (hs
->kbd
.keys
> 6) {
691 memset(buf
+ 2, USB_HID_USAGE_ERROR_ROLLOVER
, MIN(8, len
) - 2);
693 memcpy(buf
+ 2, hs
->kbd
.key
, MIN(8, len
) - 2);
699 static int hid_keyboard_write(HIDState
*hs
, uint8_t *buf
, int len
)
703 /* 0x01: Num Lock LED
704 * 0x02: Caps Lock LED
705 * 0x04: Scroll Lock LED
708 hs
->kbd
.leds
= buf
[0];
709 if (hs
->kbd
.leds
& 0x04) {
710 ledstate
|= QEMU_SCROLL_LOCK_LED
;
712 if (hs
->kbd
.leds
& 0x01) {
713 ledstate
|= QEMU_NUM_LOCK_LED
;
715 if (hs
->kbd
.leds
& 0x02) {
716 ledstate
|= QEMU_CAPS_LOCK_LED
;
718 kbd_put_ledstate(ledstate
);
723 static void hid_handle_reset(HIDState
*hs
)
727 qemu_add_kbd_event_handler(hid_keyboard_event
, hs
);
728 memset(hs
->kbd
.keycodes
, 0, sizeof(hs
->kbd
.keycodes
));
729 memset(hs
->kbd
.key
, 0, sizeof(hs
->kbd
.key
));
734 memset(hs
->ptr
.queue
, 0, sizeof(hs
->ptr
.queue
));
741 static void usb_hid_handle_reset(USBDevice
*dev
)
743 USBHIDState
*us
= DO_UPCAST(USBHIDState
, dev
, dev
);
745 hid_handle_reset(&us
->hid
);
750 static void usb_hid_set_next_idle(USBHIDState
*s
, int64_t curtime
)
752 s
->next_idle_clock
= curtime
+ (get_ticks_per_sec() * s
->idle
* 4) / 1000;
755 static int usb_hid_handle_control(USBDevice
*dev
, USBPacket
*p
,
756 int request
, int value
, int index
, int length
, uint8_t *data
)
758 USBHIDState
*us
= DO_UPCAST(USBHIDState
, dev
, dev
);
759 HIDState
*hs
= &us
->hid
;
762 ret
= usb_desc_handle_control(dev
, p
, request
, value
, index
, length
, data
);
769 case DeviceRequest
| USB_REQ_GET_INTERFACE
:
773 case DeviceOutRequest
| USB_REQ_SET_INTERFACE
:
776 /* hid specific requests */
777 case InterfaceRequest
| USB_REQ_GET_DESCRIPTOR
:
778 switch (value
>> 8) {
780 if (hs
->kind
== HID_MOUSE
) {
781 memcpy(data
, qemu_mouse_hid_report_descriptor
,
782 sizeof(qemu_mouse_hid_report_descriptor
));
783 ret
= sizeof(qemu_mouse_hid_report_descriptor
);
784 } else if (hs
->kind
== HID_TABLET
) {
785 memcpy(data
, qemu_tablet_hid_report_descriptor
,
786 sizeof(qemu_tablet_hid_report_descriptor
));
787 ret
= sizeof(qemu_tablet_hid_report_descriptor
);
788 } else if (hs
->kind
== HID_KEYBOARD
) {
789 memcpy(data
, qemu_keyboard_hid_report_descriptor
,
790 sizeof(qemu_keyboard_hid_report_descriptor
));
791 ret
= sizeof(qemu_keyboard_hid_report_descriptor
);
799 if (hs
->kind
== HID_MOUSE
|| hs
->kind
== HID_TABLET
) {
800 ret
= hid_pointer_poll(hs
, data
, length
);
801 } else if (hs
->kind
== HID_KEYBOARD
) {
802 ret
= hid_keyboard_poll(hs
, data
, length
);
806 if (hs
->kind
== HID_KEYBOARD
) {
807 ret
= hid_keyboard_write(hs
, data
, length
);
813 if (hs
->kind
!= HID_KEYBOARD
&& hs
->kind
!= HID_MOUSE
) {
817 data
[0] = us
->protocol
;
820 if (hs
->kind
!= HID_KEYBOARD
&& hs
->kind
!= HID_MOUSE
) {
824 us
->protocol
= value
;
831 us
->idle
= (uint8_t) (value
>> 8);
832 usb_hid_set_next_idle(us
, qemu_get_clock_ns(vm_clock
));
843 static int usb_hid_handle_data(USBDevice
*dev
, USBPacket
*p
)
845 USBHIDState
*us
= DO_UPCAST(USBHIDState
, dev
, dev
);
846 HIDState
*hs
= &us
->hid
;
847 uint8_t buf
[p
->iov
.size
];
853 int64_t curtime
= qemu_get_clock_ns(vm_clock
);
854 if (!hid_has_events(hs
) &&
855 (!us
->idle
|| us
->next_idle_clock
- curtime
> 0)) {
858 usb_hid_set_next_idle(us
, curtime
);
859 if (hs
->kind
== HID_MOUSE
|| hs
->kind
== HID_TABLET
) {
860 ret
= hid_pointer_poll(hs
, buf
, p
->iov
.size
);
861 } else if (hs
->kind
== HID_KEYBOARD
) {
862 ret
= hid_keyboard_poll(hs
, buf
, p
->iov
.size
);
864 usb_packet_copy(p
, buf
, ret
);
878 static void hid_free(HIDState
*hs
)
882 qemu_remove_kbd_event_handler();
886 qemu_remove_mouse_event_handler(hs
->ptr
.eh_entry
);
891 static void usb_hid_handle_destroy(USBDevice
*dev
)
893 USBHIDState
*us
= DO_UPCAST(USBHIDState
, dev
, dev
);
898 static void hid_init(HIDState
*hs
, int kind
, HIDEventFunc event
)
903 if (hs
->kind
== HID_MOUSE
) {
904 hs
->ptr
.eh_entry
= qemu_add_mouse_event_handler(hid_pointer_event
, hs
,
905 0, "QEMU HID Mouse");
906 } else if (hs
->kind
== HID_TABLET
) {
907 hs
->ptr
.eh_entry
= qemu_add_mouse_event_handler(hid_pointer_event
, hs
,
908 1, "QEMU HID Tablet");
912 static int usb_hid_initfn(USBDevice
*dev
, int kind
)
914 USBHIDState
*us
= DO_UPCAST(USBHIDState
, dev
, dev
);
917 hid_init(&us
->hid
, kind
, usb_hid_changed
);
921 static int usb_tablet_initfn(USBDevice
*dev
)
923 return usb_hid_initfn(dev
, HID_TABLET
);
926 static int usb_mouse_initfn(USBDevice
*dev
)
928 return usb_hid_initfn(dev
, HID_MOUSE
);
931 static int usb_keyboard_initfn(USBDevice
*dev
)
933 return usb_hid_initfn(dev
, HID_KEYBOARD
);
936 void usb_hid_datain_cb(USBDevice
*dev
, void *opaque
, void (*datain
)(void *))
938 USBHIDState
*s
= (USBHIDState
*)dev
;
940 s
->datain_opaque
= opaque
;
944 static int usb_hid_post_load(void *opaque
, int version_id
)
946 USBHIDState
*s
= opaque
;
949 usb_hid_set_next_idle(s
, qemu_get_clock_ns(vm_clock
));
954 static const VMStateDescription vmstate_usb_ptr_queue
= {
955 .name
= "usb-ptr-queue",
957 .minimum_version_id
= 1,
958 .fields
= (VMStateField
[]) {
959 VMSTATE_INT32(xdx
, HIDPointerEvent
),
960 VMSTATE_INT32(ydy
, HIDPointerEvent
),
961 VMSTATE_INT32(dz
, HIDPointerEvent
),
962 VMSTATE_INT32(buttons_state
, HIDPointerEvent
),
963 VMSTATE_END_OF_LIST()
966 static const VMStateDescription vmstate_usb_ptr
= {
969 .minimum_version_id
= 1,
970 .post_load
= usb_hid_post_load
,
971 .fields
= (VMStateField
[]) {
972 VMSTATE_USB_DEVICE(dev
, USBHIDState
),
973 VMSTATE_STRUCT_ARRAY(hid
.ptr
.queue
, USBHIDState
, QUEUE_LENGTH
, 0,
974 vmstate_usb_ptr_queue
, HIDPointerEvent
),
975 VMSTATE_UINT32(hid
.head
, USBHIDState
),
976 VMSTATE_UINT32(hid
.n
, USBHIDState
),
977 VMSTATE_INT32(protocol
, USBHIDState
),
978 VMSTATE_UINT8(idle
, USBHIDState
),
979 VMSTATE_END_OF_LIST()
983 static const VMStateDescription vmstate_usb_kbd
= {
986 .minimum_version_id
= 1,
987 .post_load
= usb_hid_post_load
,
988 .fields
= (VMStateField
[]) {
989 VMSTATE_USB_DEVICE(dev
, USBHIDState
),
990 VMSTATE_UINT32_ARRAY(hid
.kbd
.keycodes
, USBHIDState
, QUEUE_LENGTH
),
991 VMSTATE_UINT32(hid
.head
, USBHIDState
),
992 VMSTATE_UINT32(hid
.n
, USBHIDState
),
993 VMSTATE_UINT16(hid
.kbd
.modifiers
, USBHIDState
),
994 VMSTATE_UINT8(hid
.kbd
.leds
, USBHIDState
),
995 VMSTATE_UINT8_ARRAY(hid
.kbd
.key
, USBHIDState
, 16),
996 VMSTATE_INT32(hid
.kbd
.keys
, USBHIDState
),
997 VMSTATE_INT32(protocol
, USBHIDState
),
998 VMSTATE_UINT8(idle
, USBHIDState
),
999 VMSTATE_END_OF_LIST()
1003 static struct USBDeviceInfo hid_info
[] = {
1005 .product_desc
= "QEMU USB Tablet",
1006 .qdev
.name
= "usb-tablet",
1007 .usbdevice_name
= "tablet",
1008 .qdev
.size
= sizeof(USBHIDState
),
1009 .qdev
.vmsd
= &vmstate_usb_ptr
,
1010 .usb_desc
= &desc_tablet
,
1011 .init
= usb_tablet_initfn
,
1012 .handle_packet
= usb_generic_handle_packet
,
1013 .handle_reset
= usb_hid_handle_reset
,
1014 .handle_control
= usb_hid_handle_control
,
1015 .handle_data
= usb_hid_handle_data
,
1016 .handle_destroy
= usb_hid_handle_destroy
,
1018 .product_desc
= "QEMU USB Mouse",
1019 .qdev
.name
= "usb-mouse",
1020 .usbdevice_name
= "mouse",
1021 .qdev
.size
= sizeof(USBHIDState
),
1022 .qdev
.vmsd
= &vmstate_usb_ptr
,
1023 .usb_desc
= &desc_mouse
,
1024 .init
= usb_mouse_initfn
,
1025 .handle_packet
= usb_generic_handle_packet
,
1026 .handle_reset
= usb_hid_handle_reset
,
1027 .handle_control
= usb_hid_handle_control
,
1028 .handle_data
= usb_hid_handle_data
,
1029 .handle_destroy
= usb_hid_handle_destroy
,
1031 .product_desc
= "QEMU USB Keyboard",
1032 .qdev
.name
= "usb-kbd",
1033 .usbdevice_name
= "keyboard",
1034 .qdev
.size
= sizeof(USBHIDState
),
1035 .qdev
.vmsd
= &vmstate_usb_kbd
,
1036 .usb_desc
= &desc_keyboard
,
1037 .init
= usb_keyboard_initfn
,
1038 .handle_packet
= usb_generic_handle_packet
,
1039 .handle_reset
= usb_hid_handle_reset
,
1040 .handle_control
= usb_hid_handle_control
,
1041 .handle_data
= usb_hid_handle_data
,
1042 .handle_destroy
= usb_hid_handle_destroy
,
1048 static void usb_hid_register_devices(void)
1050 usb_qdev_register_many(hid_info
);
1052 device_init(usb_hid_register_devices
)