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
;
93 void (*datain
)(void *);
100 STR_PRODUCT_KEYBOARD
,
107 static const USBDescStrings desc_strings
= {
108 [STR_MANUFACTURER
] = "QEMU " QEMU_VERSION
,
109 [STR_PRODUCT_MOUSE
] = "QEMU USB Mouse",
110 [STR_PRODUCT_TABLET
] = "QEMU USB Tablet",
111 [STR_PRODUCT_KEYBOARD
] = "QEMU USB Keyboard",
112 [STR_SERIALNUMBER
] = "42", /* == remote wakeup works */
113 [STR_CONFIG_MOUSE
] = "HID Mouse",
114 [STR_CONFIG_TABLET
] = "HID Tablet",
115 [STR_CONFIG_KEYBOARD
] = "HID Keyboard",
118 static const USBDescIface desc_iface_mouse
= {
119 .bInterfaceNumber
= 0,
121 .bInterfaceClass
= USB_CLASS_HID
,
122 .bInterfaceSubClass
= 0x01, /* boot */
123 .bInterfaceProtocol
= 0x02,
125 .descs
= (USBDescOther
[]) {
128 .data
= (uint8_t[]) {
129 0x09, /* u8 bLength */
130 USB_DT_HID
, /* u8 bDescriptorType */
131 0x01, 0x00, /* u16 HID_class */
132 0x00, /* u8 country_code */
133 0x01, /* u8 num_descriptors */
134 USB_DT_REPORT
, /* u8 type: Report */
139 .eps
= (USBDescEndpoint
[]) {
141 .bEndpointAddress
= USB_DIR_IN
| 0x01,
142 .bmAttributes
= USB_ENDPOINT_XFER_INT
,
149 static const USBDescIface desc_iface_tablet
= {
150 .bInterfaceNumber
= 0,
152 .bInterfaceClass
= USB_CLASS_HID
,
153 .bInterfaceProtocol
= 0x02,
155 .descs
= (USBDescOther
[]) {
158 .data
= (uint8_t[]) {
159 0x09, /* u8 bLength */
160 USB_DT_HID
, /* u8 bDescriptorType */
161 0x01, 0x00, /* u16 HID_class */
162 0x00, /* u8 country_code */
163 0x01, /* u8 num_descriptors */
164 USB_DT_REPORT
, /* u8 type: Report */
169 .eps
= (USBDescEndpoint
[]) {
171 .bEndpointAddress
= USB_DIR_IN
| 0x01,
172 .bmAttributes
= USB_ENDPOINT_XFER_INT
,
179 static const USBDescIface desc_iface_keyboard
= {
180 .bInterfaceNumber
= 0,
182 .bInterfaceClass
= USB_CLASS_HID
,
183 .bInterfaceSubClass
= 0x01, /* boot */
184 .bInterfaceProtocol
= 0x01, /* keyboard */
186 .descs
= (USBDescOther
[]) {
189 .data
= (uint8_t[]) {
190 0x09, /* u8 bLength */
191 USB_DT_HID
, /* u8 bDescriptorType */
192 0x11, 0x01, /* u16 HID_class */
193 0x00, /* u8 country_code */
194 0x01, /* u8 num_descriptors */
195 USB_DT_REPORT
, /* u8 type: Report */
196 0x3f, 0, /* u16 len */
200 .eps
= (USBDescEndpoint
[]) {
202 .bEndpointAddress
= USB_DIR_IN
| 0x01,
203 .bmAttributes
= USB_ENDPOINT_XFER_INT
,
210 static const USBDescDevice desc_device_mouse
= {
212 .bMaxPacketSize0
= 8,
213 .bNumConfigurations
= 1,
214 .confs
= (USBDescConfig
[]) {
217 .bConfigurationValue
= 1,
218 .iConfiguration
= STR_CONFIG_MOUSE
,
219 .bmAttributes
= 0xa0,
222 .ifs
= &desc_iface_mouse
,
227 static const USBDescDevice desc_device_tablet
= {
229 .bMaxPacketSize0
= 8,
230 .bNumConfigurations
= 1,
231 .confs
= (USBDescConfig
[]) {
234 .bConfigurationValue
= 1,
235 .iConfiguration
= STR_CONFIG_TABLET
,
236 .bmAttributes
= 0xa0,
239 .ifs
= &desc_iface_tablet
,
244 static const USBDescDevice desc_device_keyboard
= {
246 .bMaxPacketSize0
= 8,
247 .bNumConfigurations
= 1,
248 .confs
= (USBDescConfig
[]) {
251 .bConfigurationValue
= 1,
252 .iConfiguration
= STR_CONFIG_KEYBOARD
,
253 .bmAttributes
= 0xa0,
256 .ifs
= &desc_iface_keyboard
,
261 static const USBDesc desc_mouse
= {
266 .iManufacturer
= STR_MANUFACTURER
,
267 .iProduct
= STR_PRODUCT_MOUSE
,
268 .iSerialNumber
= STR_SERIALNUMBER
,
270 .full
= &desc_device_mouse
,
274 static const USBDesc desc_tablet
= {
279 .iManufacturer
= STR_MANUFACTURER
,
280 .iProduct
= STR_PRODUCT_TABLET
,
281 .iSerialNumber
= STR_SERIALNUMBER
,
283 .full
= &desc_device_tablet
,
287 static const USBDesc desc_keyboard
= {
292 .iManufacturer
= STR_MANUFACTURER
,
293 .iProduct
= STR_PRODUCT_KEYBOARD
,
294 .iSerialNumber
= STR_SERIALNUMBER
,
296 .full
= &desc_device_keyboard
,
300 static const uint8_t qemu_mouse_hid_report_descriptor
[] = {
301 0x05, 0x01, /* Usage Page (Generic Desktop) */
302 0x09, 0x02, /* Usage (Mouse) */
303 0xa1, 0x01, /* Collection (Application) */
304 0x09, 0x01, /* Usage (Pointer) */
305 0xa1, 0x00, /* Collection (Physical) */
306 0x05, 0x09, /* Usage Page (Button) */
307 0x19, 0x01, /* Usage Minimum (1) */
308 0x29, 0x03, /* Usage Maximum (3) */
309 0x15, 0x00, /* Logical Minimum (0) */
310 0x25, 0x01, /* Logical Maximum (1) */
311 0x95, 0x03, /* Report Count (3) */
312 0x75, 0x01, /* Report Size (1) */
313 0x81, 0x02, /* Input (Data, Variable, Absolute) */
314 0x95, 0x01, /* Report Count (1) */
315 0x75, 0x05, /* Report Size (5) */
316 0x81, 0x01, /* Input (Constant) */
317 0x05, 0x01, /* Usage Page (Generic Desktop) */
318 0x09, 0x30, /* Usage (X) */
319 0x09, 0x31, /* Usage (Y) */
320 0x09, 0x38, /* Usage (Wheel) */
321 0x15, 0x81, /* Logical Minimum (-0x7f) */
322 0x25, 0x7f, /* Logical Maximum (0x7f) */
323 0x75, 0x08, /* Report Size (8) */
324 0x95, 0x03, /* Report Count (3) */
325 0x81, 0x06, /* Input (Data, Variable, Relative) */
326 0xc0, /* End Collection */
327 0xc0, /* End Collection */
330 static const uint8_t qemu_tablet_hid_report_descriptor
[] = {
331 0x05, 0x01, /* Usage Page (Generic Desktop) */
332 0x09, 0x01, /* Usage (Pointer) */
333 0xa1, 0x01, /* Collection (Application) */
334 0x09, 0x01, /* Usage (Pointer) */
335 0xa1, 0x00, /* Collection (Physical) */
336 0x05, 0x09, /* Usage Page (Button) */
337 0x19, 0x01, /* Usage Minimum (1) */
338 0x29, 0x03, /* Usage Maximum (3) */
339 0x15, 0x00, /* Logical Minimum (0) */
340 0x25, 0x01, /* Logical Maximum (1) */
341 0x95, 0x03, /* Report Count (3) */
342 0x75, 0x01, /* Report Size (1) */
343 0x81, 0x02, /* Input (Data, Variable, Absolute) */
344 0x95, 0x01, /* Report Count (1) */
345 0x75, 0x05, /* Report Size (5) */
346 0x81, 0x01, /* Input (Constant) */
347 0x05, 0x01, /* Usage Page (Generic Desktop) */
348 0x09, 0x30, /* Usage (X) */
349 0x09, 0x31, /* Usage (Y) */
350 0x15, 0x00, /* Logical Minimum (0) */
351 0x26, 0xff, 0x7f, /* Logical Maximum (0x7fff) */
352 0x35, 0x00, /* Physical Minimum (0) */
353 0x46, 0xff, 0x7f, /* Physical Maximum (0x7fff) */
354 0x75, 0x10, /* Report Size (16) */
355 0x95, 0x02, /* Report Count (2) */
356 0x81, 0x02, /* Input (Data, Variable, Absolute) */
357 0x05, 0x01, /* Usage Page (Generic Desktop) */
358 0x09, 0x38, /* Usage (Wheel) */
359 0x15, 0x81, /* Logical Minimum (-0x7f) */
360 0x25, 0x7f, /* Logical Maximum (0x7f) */
361 0x35, 0x00, /* Physical Minimum (same as logical) */
362 0x45, 0x00, /* Physical Maximum (same as logical) */
363 0x75, 0x08, /* Report Size (8) */
364 0x95, 0x01, /* Report Count (1) */
365 0x81, 0x06, /* Input (Data, Variable, Relative) */
366 0xc0, /* End Collection */
367 0xc0, /* End Collection */
370 static const uint8_t qemu_keyboard_hid_report_descriptor
[] = {
371 0x05, 0x01, /* Usage Page (Generic Desktop) */
372 0x09, 0x06, /* Usage (Keyboard) */
373 0xa1, 0x01, /* Collection (Application) */
374 0x75, 0x01, /* Report Size (1) */
375 0x95, 0x08, /* Report Count (8) */
376 0x05, 0x07, /* Usage Page (Key Codes) */
377 0x19, 0xe0, /* Usage Minimum (224) */
378 0x29, 0xe7, /* Usage Maximum (231) */
379 0x15, 0x00, /* Logical Minimum (0) */
380 0x25, 0x01, /* Logical Maximum (1) */
381 0x81, 0x02, /* Input (Data, Variable, Absolute) */
382 0x95, 0x01, /* Report Count (1) */
383 0x75, 0x08, /* Report Size (8) */
384 0x81, 0x01, /* Input (Constant) */
385 0x95, 0x05, /* Report Count (5) */
386 0x75, 0x01, /* Report Size (1) */
387 0x05, 0x08, /* Usage Page (LEDs) */
388 0x19, 0x01, /* Usage Minimum (1) */
389 0x29, 0x05, /* Usage Maximum (5) */
390 0x91, 0x02, /* Output (Data, Variable, Absolute) */
391 0x95, 0x01, /* Report Count (1) */
392 0x75, 0x03, /* Report Size (3) */
393 0x91, 0x01, /* Output (Constant) */
394 0x95, 0x06, /* Report Count (6) */
395 0x75, 0x08, /* Report Size (8) */
396 0x15, 0x00, /* Logical Minimum (0) */
397 0x25, 0xff, /* Logical Maximum (255) */
398 0x05, 0x07, /* Usage Page (Key Codes) */
399 0x19, 0x00, /* Usage Minimum (0) */
400 0x29, 0xff, /* Usage Maximum (255) */
401 0x81, 0x00, /* Input (Data, Array) */
402 0xc0, /* End Collection */
405 #define USB_HID_USAGE_ERROR_ROLLOVER 0x01
406 #define USB_HID_USAGE_POSTFAIL 0x02
407 #define USB_HID_USAGE_ERROR_UNDEFINED 0x03
409 /* Indices are QEMU keycodes, values are from HID Usage Table. Indices
410 * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d. */
411 static const uint8_t usb_hid_usage_keys
[0x100] = {
412 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
413 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
414 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
415 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
416 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
417 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
418 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
419 0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
420 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
421 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
422 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
423 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
424 0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
425 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
426 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
427 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
431 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
432 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
434 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
435 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
436 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
437 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
438 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
439 0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
440 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 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,
444 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
447 static void usb_hid_changed(HIDState
*hs
)
449 USBHIDState
*us
= container_of(hs
, USBHIDState
, hid
);
454 us
->datain(us
->datain_opaque
);
457 usb_wakeup(&us
->dev
);
460 static void hid_pointer_event_clear(HIDPointerEvent
*e
, int buttons
)
462 e
->xdx
= e
->ydy
= e
->dz
= 0;
463 e
->buttons_state
= buttons
;
466 static void hid_pointer_event_combine(HIDPointerEvent
*e
, int xyrel
,
467 int x1
, int y1
, int z1
) {
474 /* Windows drivers do not like the 0/0 position and ignore such
483 static void hid_pointer_event(void *opaque
,
484 int x1
, int y1
, int z1
, int buttons_state
)
486 HIDState
*hs
= opaque
;
487 unsigned use_slot
= (hs
->head
+ hs
->n
- 1) & QUEUE_MASK
;
488 unsigned previous_slot
= (use_slot
- 1) & QUEUE_MASK
;
490 /* We combine events where feasible to keep the queue small. We shouldn't
491 * combine anything with the first event of a particular button state, as
492 * that would change the location of the button state change. When the
493 * queue is empty, a second event is needed because we don't know if
494 * the first event changed the button state. */
495 if (hs
->n
== QUEUE_LENGTH
) {
496 /* Queue full. Discard old button state, combine motion normally. */
497 hs
->ptr
.queue
[use_slot
].buttons_state
= buttons_state
;
498 } else if (hs
->n
< 2 ||
499 hs
->ptr
.queue
[use_slot
].buttons_state
!= buttons_state
||
500 hs
->ptr
.queue
[previous_slot
].buttons_state
!=
501 hs
->ptr
.queue
[use_slot
].buttons_state
) {
502 /* Cannot or should not combine, so add an empty item to the queue. */
503 QUEUE_INCR(use_slot
);
505 hid_pointer_event_clear(&hs
->ptr
.queue
[use_slot
], buttons_state
);
507 hid_pointer_event_combine(&hs
->ptr
.queue
[use_slot
],
508 hs
->kind
== HID_MOUSE
,
513 static void hid_keyboard_event(void *opaque
, int keycode
)
515 HIDState
*hs
= opaque
;
518 if (hs
->n
== QUEUE_LENGTH
) {
519 fprintf(stderr
, "usb-kbd: warning: key event queue full\n");
522 slot
= (hs
->head
+ hs
->n
) & QUEUE_MASK
; hs
->n
++;
523 hs
->kbd
.keycodes
[slot
] = keycode
;
527 static void hid_keyboard_process_keycode(HIDState
*hs
)
529 uint8_t hid_code
, key
;
530 int i
, keycode
, slot
;
535 slot
= hs
->head
& QUEUE_MASK
; QUEUE_INCR(hs
->head
); hs
->n
--;
536 keycode
= hs
->kbd
.keycodes
[slot
];
538 key
= keycode
& 0x7f;
539 hid_code
= usb_hid_usage_keys
[key
| ((hs
->kbd
.modifiers
>> 1) & (1 << 7))];
540 hs
->kbd
.modifiers
&= ~(1 << 8);
547 if (hs
->kbd
.modifiers
& (1 << 9)) {
548 hs
->kbd
.modifiers
^= 3 << 8;
552 if (keycode
& (1 << 7)) {
553 hs
->kbd
.modifiers
&= ~(1 << (hid_code
& 0x0f));
557 hs
->kbd
.modifiers
|= 1 << (hid_code
& 0x0f);
561 if (keycode
& (1 << 7)) {
562 for (i
= hs
->kbd
.keys
- 1; i
>= 0; i
--) {
563 if (hs
->kbd
.key
[i
] == hid_code
) {
564 hs
->kbd
.key
[i
] = hs
->kbd
.key
[-- hs
->kbd
.keys
];
565 hs
->kbd
.key
[hs
->kbd
.keys
] = 0x00;
573 for (i
= hs
->kbd
.keys
- 1; i
>= 0; i
--) {
574 if (hs
->kbd
.key
[i
] == hid_code
) {
579 if (hs
->kbd
.keys
< sizeof(hs
->kbd
.key
)) {
580 hs
->kbd
.key
[hs
->kbd
.keys
++] = hid_code
;
588 static inline int int_clamp(int val
, int vmin
, int vmax
)
598 static int hid_pointer_poll(HIDState
*hs
, uint8_t *buf
, int len
)
600 int dx
, dy
, dz
, b
, l
;
604 if (!hs
->ptr
.mouse_grabbed
) {
605 qemu_activate_mouse_event_handler(hs
->ptr
.eh_entry
);
606 hs
->ptr
.mouse_grabbed
= 1;
609 /* When the buffer is empty, return the last event. Relative
610 movements will all be zero. */
611 index
= (hs
->n
? hs
->head
: hs
->head
- 1);
612 e
= &hs
->ptr
.queue
[index
& QUEUE_MASK
];
614 if (hs
->kind
== HID_MOUSE
) {
615 dx
= int_clamp(e
->xdx
, -127, 127);
616 dy
= int_clamp(e
->ydy
, -127, 127);
623 dz
= int_clamp(e
->dz
, -127, 127);
627 if (e
->buttons_state
& MOUSE_EVENT_LBUTTON
)
629 if (e
->buttons_state
& MOUSE_EVENT_RBUTTON
)
631 if (e
->buttons_state
& MOUSE_EVENT_MBUTTON
)
636 (hs
->kind
== HID_TABLET
|| (!e
->xdx
&& !e
->ydy
))) {
637 /* that deals with this event */
638 QUEUE_INCR(hs
->head
);
642 /* Appears we have to invert the wheel direction */
661 buf
[l
++] = dx
& 0xff;
665 buf
[l
++] = dy
& 0xff;
679 static int hid_keyboard_poll(HIDState
*hs
, uint8_t *buf
, int len
)
684 hid_keyboard_process_keycode(hs
);
686 buf
[0] = hs
->kbd
.modifiers
& 0xff;
688 if (hs
->kbd
.keys
> 6) {
689 memset(buf
+ 2, USB_HID_USAGE_ERROR_ROLLOVER
, MIN(8, len
) - 2);
691 memcpy(buf
+ 2, hs
->kbd
.key
, MIN(8, len
) - 2);
697 static int hid_keyboard_write(HIDState
*hs
, uint8_t *buf
, int len
)
701 /* 0x01: Num Lock LED
702 * 0x02: Caps Lock LED
703 * 0x04: Scroll Lock LED
706 hs
->kbd
.leds
= buf
[0];
707 if (hs
->kbd
.leds
& 0x04) {
708 ledstate
|= QEMU_SCROLL_LOCK_LED
;
710 if (hs
->kbd
.leds
& 0x01) {
711 ledstate
|= QEMU_NUM_LOCK_LED
;
713 if (hs
->kbd
.leds
& 0x02) {
714 ledstate
|= QEMU_CAPS_LOCK_LED
;
716 kbd_put_ledstate(ledstate
);
721 static void hid_handle_reset(HIDState
*hs
)
725 qemu_add_kbd_event_handler(hid_keyboard_event
, hs
);
726 memset(hs
->kbd
.keycodes
, 0, sizeof(hs
->kbd
.keycodes
));
727 memset(hs
->kbd
.key
, 0, sizeof(hs
->kbd
.key
));
732 memset(hs
->ptr
.queue
, 0, sizeof(hs
->ptr
.queue
));
739 static void usb_hid_handle_reset(USBDevice
*dev
)
741 USBHIDState
*us
= DO_UPCAST(USBHIDState
, dev
, dev
);
743 hid_handle_reset(&us
->hid
);
747 static void usb_hid_set_next_idle(USBHIDState
*s
, int64_t curtime
)
749 s
->next_idle_clock
= curtime
+ (get_ticks_per_sec() * s
->idle
* 4) / 1000;
752 static int usb_hid_handle_control(USBDevice
*dev
, USBPacket
*p
,
753 int request
, int value
, int index
, int length
, uint8_t *data
)
755 USBHIDState
*us
= DO_UPCAST(USBHIDState
, dev
, dev
);
756 HIDState
*hs
= &us
->hid
;
759 ret
= usb_desc_handle_control(dev
, p
, request
, value
, index
, length
, data
);
766 case DeviceRequest
| USB_REQ_GET_INTERFACE
:
770 case DeviceOutRequest
| USB_REQ_SET_INTERFACE
:
773 /* hid specific requests */
774 case InterfaceRequest
| USB_REQ_GET_DESCRIPTOR
:
775 switch (value
>> 8) {
777 if (hs
->kind
== HID_MOUSE
) {
778 memcpy(data
, qemu_mouse_hid_report_descriptor
,
779 sizeof(qemu_mouse_hid_report_descriptor
));
780 ret
= sizeof(qemu_mouse_hid_report_descriptor
);
781 } else if (hs
->kind
== HID_TABLET
) {
782 memcpy(data
, qemu_tablet_hid_report_descriptor
,
783 sizeof(qemu_tablet_hid_report_descriptor
));
784 ret
= sizeof(qemu_tablet_hid_report_descriptor
);
785 } else if (hs
->kind
== HID_KEYBOARD
) {
786 memcpy(data
, qemu_keyboard_hid_report_descriptor
,
787 sizeof(qemu_keyboard_hid_report_descriptor
));
788 ret
= sizeof(qemu_keyboard_hid_report_descriptor
);
796 if (hs
->kind
== HID_MOUSE
|| hs
->kind
== HID_TABLET
) {
797 ret
= hid_pointer_poll(hs
, data
, length
);
798 } else if (hs
->kind
== HID_KEYBOARD
) {
799 ret
= hid_keyboard_poll(hs
, data
, length
);
801 us
->changed
= hs
->n
> 0;
804 if (hs
->kind
== HID_KEYBOARD
) {
805 ret
= hid_keyboard_write(hs
, data
, length
);
811 if (hs
->kind
!= HID_KEYBOARD
&& hs
->kind
!= HID_MOUSE
) {
815 data
[0] = us
->protocol
;
818 if (hs
->kind
!= HID_KEYBOARD
&& hs
->kind
!= HID_MOUSE
) {
822 us
->protocol
= value
;
829 us
->idle
= (uint8_t) (value
>> 8);
830 usb_hid_set_next_idle(us
, qemu_get_clock_ns(vm_clock
));
841 static int usb_hid_handle_data(USBDevice
*dev
, USBPacket
*p
)
843 USBHIDState
*us
= DO_UPCAST(USBHIDState
, dev
, dev
);
844 HIDState
*hs
= &us
->hid
;
845 uint8_t buf
[p
->iov
.size
];
851 int64_t curtime
= qemu_get_clock_ns(vm_clock
);
853 (!us
->idle
|| us
->next_idle_clock
- curtime
> 0)) {
856 usb_hid_set_next_idle(us
, curtime
);
857 if (hs
->kind
== HID_MOUSE
|| hs
->kind
== HID_TABLET
) {
858 ret
= hid_pointer_poll(hs
, buf
, p
->iov
.size
);
859 } else if (hs
->kind
== HID_KEYBOARD
) {
860 ret
= hid_keyboard_poll(hs
, buf
, p
->iov
.size
);
862 usb_packet_copy(p
, buf
, ret
);
863 us
->changed
= hs
->n
> 0;
877 static void hid_free(HIDState
*hs
)
881 qemu_remove_kbd_event_handler();
885 qemu_remove_mouse_event_handler(hs
->ptr
.eh_entry
);
890 static void usb_hid_handle_destroy(USBDevice
*dev
)
892 USBHIDState
*us
= DO_UPCAST(USBHIDState
, dev
, dev
);
897 static void hid_init(HIDState
*hs
, int kind
, HIDEventFunc event
)
902 if (hs
->kind
== HID_MOUSE
) {
903 hs
->ptr
.eh_entry
= qemu_add_mouse_event_handler(hid_pointer_event
, hs
,
904 0, "QEMU HID Mouse");
905 } else if (hs
->kind
== HID_TABLET
) {
906 hs
->ptr
.eh_entry
= qemu_add_mouse_event_handler(hid_pointer_event
, hs
,
907 1, "QEMU HID Tablet");
911 static int usb_hid_initfn(USBDevice
*dev
, int kind
)
913 USBHIDState
*us
= DO_UPCAST(USBHIDState
, dev
, dev
);
916 hid_init(&us
->hid
, kind
, usb_hid_changed
);
918 /* Force poll routine to be run and grab input the first time. */
923 static int usb_tablet_initfn(USBDevice
*dev
)
925 return usb_hid_initfn(dev
, HID_TABLET
);
928 static int usb_mouse_initfn(USBDevice
*dev
)
930 return usb_hid_initfn(dev
, HID_MOUSE
);
933 static int usb_keyboard_initfn(USBDevice
*dev
)
935 return usb_hid_initfn(dev
, HID_KEYBOARD
);
938 void usb_hid_datain_cb(USBDevice
*dev
, void *opaque
, void (*datain
)(void *))
940 USBHIDState
*s
= (USBHIDState
*)dev
;
942 s
->datain_opaque
= opaque
;
946 static int usb_hid_post_load(void *opaque
, int version_id
)
948 USBHIDState
*s
= opaque
;
951 usb_hid_set_next_idle(s
, qemu_get_clock_ns(vm_clock
));
956 static const VMStateDescription vmstate_usb_ptr_queue
= {
957 .name
= "usb-ptr-queue",
959 .minimum_version_id
= 1,
960 .fields
= (VMStateField
[]) {
961 VMSTATE_INT32(xdx
, HIDPointerEvent
),
962 VMSTATE_INT32(ydy
, HIDPointerEvent
),
963 VMSTATE_INT32(dz
, HIDPointerEvent
),
964 VMSTATE_INT32(buttons_state
, HIDPointerEvent
),
965 VMSTATE_END_OF_LIST()
968 static const VMStateDescription vmstate_usb_ptr
= {
971 .minimum_version_id
= 1,
972 .post_load
= usb_hid_post_load
,
973 .fields
= (VMStateField
[]) {
974 VMSTATE_USB_DEVICE(dev
, USBHIDState
),
975 VMSTATE_STRUCT_ARRAY(hid
.ptr
.queue
, USBHIDState
, QUEUE_LENGTH
, 0,
976 vmstate_usb_ptr_queue
, HIDPointerEvent
),
977 VMSTATE_UINT32(hid
.head
, USBHIDState
),
978 VMSTATE_UINT32(hid
.n
, USBHIDState
),
979 VMSTATE_INT32(protocol
, USBHIDState
),
980 VMSTATE_UINT8(idle
, USBHIDState
),
981 VMSTATE_END_OF_LIST()
985 static const VMStateDescription vmstate_usb_kbd
= {
988 .minimum_version_id
= 1,
989 .post_load
= usb_hid_post_load
,
990 .fields
= (VMStateField
[]) {
991 VMSTATE_USB_DEVICE(dev
, USBHIDState
),
992 VMSTATE_UINT32_ARRAY(hid
.kbd
.keycodes
, USBHIDState
, QUEUE_LENGTH
),
993 VMSTATE_UINT32(hid
.head
, USBHIDState
),
994 VMSTATE_UINT32(hid
.n
, USBHIDState
),
995 VMSTATE_UINT16(hid
.kbd
.modifiers
, USBHIDState
),
996 VMSTATE_UINT8(hid
.kbd
.leds
, USBHIDState
),
997 VMSTATE_UINT8_ARRAY(hid
.kbd
.key
, USBHIDState
, 16),
998 VMSTATE_INT32(hid
.kbd
.keys
, USBHIDState
),
999 VMSTATE_INT32(protocol
, USBHIDState
),
1000 VMSTATE_UINT8(idle
, USBHIDState
),
1001 VMSTATE_END_OF_LIST()
1005 static struct USBDeviceInfo hid_info
[] = {
1007 .product_desc
= "QEMU USB Tablet",
1008 .qdev
.name
= "usb-tablet",
1009 .usbdevice_name
= "tablet",
1010 .qdev
.size
= sizeof(USBHIDState
),
1011 .qdev
.vmsd
= &vmstate_usb_ptr
,
1012 .usb_desc
= &desc_tablet
,
1013 .init
= usb_tablet_initfn
,
1014 .handle_packet
= usb_generic_handle_packet
,
1015 .handle_reset
= usb_hid_handle_reset
,
1016 .handle_control
= usb_hid_handle_control
,
1017 .handle_data
= usb_hid_handle_data
,
1018 .handle_destroy
= usb_hid_handle_destroy
,
1020 .product_desc
= "QEMU USB Mouse",
1021 .qdev
.name
= "usb-mouse",
1022 .usbdevice_name
= "mouse",
1023 .qdev
.size
= sizeof(USBHIDState
),
1024 .qdev
.vmsd
= &vmstate_usb_ptr
,
1025 .usb_desc
= &desc_mouse
,
1026 .init
= usb_mouse_initfn
,
1027 .handle_packet
= usb_generic_handle_packet
,
1028 .handle_reset
= usb_hid_handle_reset
,
1029 .handle_control
= usb_hid_handle_control
,
1030 .handle_data
= usb_hid_handle_data
,
1031 .handle_destroy
= usb_hid_handle_destroy
,
1033 .product_desc
= "QEMU USB Keyboard",
1034 .qdev
.name
= "usb-kbd",
1035 .usbdevice_name
= "keyboard",
1036 .qdev
.size
= sizeof(USBHIDState
),
1037 .qdev
.vmsd
= &vmstate_usb_kbd
,
1038 .usb_desc
= &desc_keyboard
,
1039 .init
= usb_keyboard_initfn
,
1040 .handle_packet
= usb_generic_handle_packet
,
1041 .handle_reset
= usb_hid_handle_reset
,
1042 .handle_control
= usb_hid_handle_control
,
1043 .handle_data
= usb_hid_handle_data
,
1044 .handle_destroy
= usb_hid_handle_destroy
,
1050 static void usb_hid_register_devices(void)
1052 usb_qdev_register_many(hid_info
);
1054 device_init(usb_hid_register_devices
)