]> git.proxmox.com Git - qemu.git/blob - hw/usb-hid.c
870cc6627236b79d1f490a32633fd96711dbe496
[qemu.git] / hw / usb-hid.c
1 /*
2 * QEMU USB HID devices
3 *
4 * Copyright (c) 2005 Fabrice Bellard
5 * Copyright (c) 2007 OpenMoko, Inc. (andrew@openedhand.com)
6 *
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:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
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
23 * THE SOFTWARE.
24 */
25 #include "hw.h"
26 #include "console.h"
27 #include "usb.h"
28 #include "usb-desc.h"
29 #include "qemu-timer.h"
30
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
38
39 /* HID descriptor types */
40 #define USB_DT_HID 0x21
41 #define USB_DT_REPORT 0x22
42 #define USB_DT_PHY 0x23
43
44 #define HID_MOUSE 1
45 #define HID_TABLET 2
46 #define HID_KEYBOARD 3
47
48 typedef struct HIDPointerEvent {
49 int32_t xdx, ydy; /* relative iff it's a mouse, otherwise absolute */
50 int32_t dz, buttons_state;
51 } HIDPointerEvent;
52
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)
56
57 typedef struct HIDState HIDState;
58 typedef void (*HIDEventFunc)(HIDState *s);
59
60 typedef struct HIDMouseState {
61 HIDPointerEvent queue[QUEUE_LENGTH];
62 int mouse_grabbed;
63 QEMUPutMouseEntry *eh_entry;
64 } HIDMouseState;
65
66 typedef struct HIDKeyboardState {
67 uint32_t keycodes[QUEUE_LENGTH];
68 uint16_t modifiers;
69 uint8_t leds;
70 uint8_t key[16];
71 int32_t keys;
72 } HIDKeyboardState;
73
74 struct HIDState {
75 union {
76 HIDMouseState ptr;
77 HIDKeyboardState kbd;
78 };
79 uint32_t head; /* index into circular queue */
80 uint32_t n;
81 int kind;
82 HIDEventFunc event;
83 };
84
85 typedef struct USBHIDState {
86 USBDevice dev;
87 HIDState hid;
88 int32_t protocol;
89 uint8_t idle;
90 int64_t next_idle_clock;
91 int changed;
92 void *datain_opaque;
93 void (*datain)(void *);
94 } USBHIDState;
95
96 enum {
97 STR_MANUFACTURER = 1,
98 STR_PRODUCT_MOUSE,
99 STR_PRODUCT_TABLET,
100 STR_PRODUCT_KEYBOARD,
101 STR_SERIALNUMBER,
102 STR_CONFIG_MOUSE,
103 STR_CONFIG_TABLET,
104 STR_CONFIG_KEYBOARD,
105 };
106
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",
116 };
117
118 static const USBDescIface desc_iface_mouse = {
119 .bInterfaceNumber = 0,
120 .bNumEndpoints = 1,
121 .bInterfaceClass = USB_CLASS_HID,
122 .bInterfaceSubClass = 0x01, /* boot */
123 .bInterfaceProtocol = 0x02,
124 .ndesc = 1,
125 .descs = (USBDescOther[]) {
126 {
127 /* HID descriptor */
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 */
135 52, 0, /* u16 len */
136 },
137 },
138 },
139 .eps = (USBDescEndpoint[]) {
140 {
141 .bEndpointAddress = USB_DIR_IN | 0x01,
142 .bmAttributes = USB_ENDPOINT_XFER_INT,
143 .wMaxPacketSize = 4,
144 .bInterval = 0x0a,
145 },
146 },
147 };
148
149 static const USBDescIface desc_iface_tablet = {
150 .bInterfaceNumber = 0,
151 .bNumEndpoints = 1,
152 .bInterfaceClass = USB_CLASS_HID,
153 .bInterfaceProtocol = 0x02,
154 .ndesc = 1,
155 .descs = (USBDescOther[]) {
156 {
157 /* HID descriptor */
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 */
165 74, 0, /* u16 len */
166 },
167 },
168 },
169 .eps = (USBDescEndpoint[]) {
170 {
171 .bEndpointAddress = USB_DIR_IN | 0x01,
172 .bmAttributes = USB_ENDPOINT_XFER_INT,
173 .wMaxPacketSize = 8,
174 .bInterval = 0x0a,
175 },
176 },
177 };
178
179 static const USBDescIface desc_iface_keyboard = {
180 .bInterfaceNumber = 0,
181 .bNumEndpoints = 1,
182 .bInterfaceClass = USB_CLASS_HID,
183 .bInterfaceSubClass = 0x01, /* boot */
184 .bInterfaceProtocol = 0x01, /* keyboard */
185 .ndesc = 1,
186 .descs = (USBDescOther[]) {
187 {
188 /* HID descriptor */
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 */
197 },
198 },
199 },
200 .eps = (USBDescEndpoint[]) {
201 {
202 .bEndpointAddress = USB_DIR_IN | 0x01,
203 .bmAttributes = USB_ENDPOINT_XFER_INT,
204 .wMaxPacketSize = 8,
205 .bInterval = 0x0a,
206 },
207 },
208 };
209
210 static const USBDescDevice desc_device_mouse = {
211 .bcdUSB = 0x0100,
212 .bMaxPacketSize0 = 8,
213 .bNumConfigurations = 1,
214 .confs = (USBDescConfig[]) {
215 {
216 .bNumInterfaces = 1,
217 .bConfigurationValue = 1,
218 .iConfiguration = STR_CONFIG_MOUSE,
219 .bmAttributes = 0xa0,
220 .bMaxPower = 50,
221 .nif = 1,
222 .ifs = &desc_iface_mouse,
223 },
224 },
225 };
226
227 static const USBDescDevice desc_device_tablet = {
228 .bcdUSB = 0x0100,
229 .bMaxPacketSize0 = 8,
230 .bNumConfigurations = 1,
231 .confs = (USBDescConfig[]) {
232 {
233 .bNumInterfaces = 1,
234 .bConfigurationValue = 1,
235 .iConfiguration = STR_CONFIG_TABLET,
236 .bmAttributes = 0xa0,
237 .bMaxPower = 50,
238 .nif = 1,
239 .ifs = &desc_iface_tablet,
240 },
241 },
242 };
243
244 static const USBDescDevice desc_device_keyboard = {
245 .bcdUSB = 0x0100,
246 .bMaxPacketSize0 = 8,
247 .bNumConfigurations = 1,
248 .confs = (USBDescConfig[]) {
249 {
250 .bNumInterfaces = 1,
251 .bConfigurationValue = 1,
252 .iConfiguration = STR_CONFIG_KEYBOARD,
253 .bmAttributes = 0xa0,
254 .bMaxPower = 50,
255 .nif = 1,
256 .ifs = &desc_iface_keyboard,
257 },
258 },
259 };
260
261 static const USBDesc desc_mouse = {
262 .id = {
263 .idVendor = 0x0627,
264 .idProduct = 0x0001,
265 .bcdDevice = 0,
266 .iManufacturer = STR_MANUFACTURER,
267 .iProduct = STR_PRODUCT_MOUSE,
268 .iSerialNumber = STR_SERIALNUMBER,
269 },
270 .full = &desc_device_mouse,
271 .str = desc_strings,
272 };
273
274 static const USBDesc desc_tablet = {
275 .id = {
276 .idVendor = 0x0627,
277 .idProduct = 0x0001,
278 .bcdDevice = 0,
279 .iManufacturer = STR_MANUFACTURER,
280 .iProduct = STR_PRODUCT_TABLET,
281 .iSerialNumber = STR_SERIALNUMBER,
282 },
283 .full = &desc_device_tablet,
284 .str = desc_strings,
285 };
286
287 static const USBDesc desc_keyboard = {
288 .id = {
289 .idVendor = 0x0627,
290 .idProduct = 0x0001,
291 .bcdDevice = 0,
292 .iManufacturer = STR_MANUFACTURER,
293 .iProduct = STR_PRODUCT_KEYBOARD,
294 .iSerialNumber = STR_SERIALNUMBER,
295 },
296 .full = &desc_device_keyboard,
297 .str = desc_strings,
298 };
299
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 */
328 };
329
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 */
368 };
369
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 */
403 };
404
405 #define USB_HID_USAGE_ERROR_ROLLOVER 0x01
406 #define USB_HID_USAGE_POSTFAIL 0x02
407 #define USB_HID_USAGE_ERROR_UNDEFINED 0x03
408
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,
428
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,
445 };
446
447 static void usb_hid_changed(HIDState *hs)
448 {
449 USBHIDState *us = container_of(hs, USBHIDState, hid);
450
451 us->changed = 1;
452
453 if (us->datain) {
454 us->datain(us->datain_opaque);
455 }
456
457 usb_wakeup(&us->dev);
458 }
459
460 static void hid_pointer_event_clear(HIDPointerEvent *e, int buttons)
461 {
462 e->xdx = e->ydy = e->dz = 0;
463 e->buttons_state = buttons;
464 }
465
466 static void hid_pointer_event_combine(HIDPointerEvent *e, int xyrel,
467 int x1, int y1, int z1) {
468 if (xyrel) {
469 e->xdx += x1;
470 e->ydy += y1;
471 } else {
472 e->xdx = x1;
473 e->ydy = y1;
474 /* Windows drivers do not like the 0/0 position and ignore such
475 * events. */
476 if (!(x1 | y1)) {
477 x1 = 1;
478 }
479 }
480 e->dz += z1;
481 }
482
483 static void hid_pointer_event(void *opaque,
484 int x1, int y1, int z1, int buttons_state)
485 {
486 HIDState *hs = opaque;
487 unsigned use_slot = (hs->head + hs->n - 1) & QUEUE_MASK;
488 unsigned previous_slot = (use_slot - 1) & QUEUE_MASK;
489
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);
504 hs->n++;
505 hid_pointer_event_clear(&hs->ptr.queue[use_slot], buttons_state);
506 }
507 hid_pointer_event_combine(&hs->ptr.queue[use_slot],
508 hs->kind == HID_MOUSE,
509 x1, y1, z1);
510 hs->event(hs);
511 }
512
513 static void hid_keyboard_event(void *opaque, int keycode)
514 {
515 HIDState *hs = opaque;
516 int slot;
517
518 if (hs->n == QUEUE_LENGTH) {
519 fprintf(stderr, "usb-kbd: warning: key event queue full\n");
520 return;
521 }
522 slot = (hs->head + hs->n) & QUEUE_MASK; hs->n++;
523 hs->kbd.keycodes[slot] = keycode;
524 hs->event(hs);
525 }
526
527 static void hid_keyboard_process_keycode(HIDState *hs)
528 {
529 uint8_t hid_code, key;
530 int i, keycode, slot;
531
532 if (hs->n == 0) {
533 return;
534 }
535 slot = hs->head & QUEUE_MASK; QUEUE_INCR(hs->head); hs->n--;
536 keycode = hs->kbd.keycodes[slot];
537
538 key = keycode & 0x7f;
539 hid_code = usb_hid_usage_keys[key | ((hs->kbd.modifiers >> 1) & (1 << 7))];
540 hs->kbd.modifiers &= ~(1 << 8);
541
542 switch (hid_code) {
543 case 0x00:
544 return;
545
546 case 0xe0:
547 if (hs->kbd.modifiers & (1 << 9)) {
548 hs->kbd.modifiers ^= 3 << 8;
549 return;
550 }
551 case 0xe1 ... 0xe7:
552 if (keycode & (1 << 7)) {
553 hs->kbd.modifiers &= ~(1 << (hid_code & 0x0f));
554 return;
555 }
556 case 0xe8 ... 0xef:
557 hs->kbd.modifiers |= 1 << (hid_code & 0x0f);
558 return;
559 }
560
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;
566 break;
567 }
568 }
569 if (i < 0) {
570 return;
571 }
572 } else {
573 for (i = hs->kbd.keys - 1; i >= 0; i--) {
574 if (hs->kbd.key[i] == hid_code) {
575 break;
576 }
577 }
578 if (i < 0) {
579 if (hs->kbd.keys < sizeof(hs->kbd.key)) {
580 hs->kbd.key[hs->kbd.keys++] = hid_code;
581 }
582 } else {
583 return;
584 }
585 }
586 }
587
588 static inline int int_clamp(int val, int vmin, int vmax)
589 {
590 if (val < vmin)
591 return vmin;
592 else if (val > vmax)
593 return vmax;
594 else
595 return val;
596 }
597
598 static int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
599 {
600 int dx, dy, dz, b, l;
601 int index;
602 HIDPointerEvent *e;
603
604 if (!hs->ptr.mouse_grabbed) {
605 qemu_activate_mouse_event_handler(hs->ptr.eh_entry);
606 hs->ptr.mouse_grabbed = 1;
607 }
608
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];
613
614 if (hs->kind == HID_MOUSE) {
615 dx = int_clamp(e->xdx, -127, 127);
616 dy = int_clamp(e->ydy, -127, 127);
617 e->xdx -= dx;
618 e->ydy -= dy;
619 } else {
620 dx = e->xdx;
621 dy = e->ydy;
622 }
623 dz = int_clamp(e->dz, -127, 127);
624 e->dz -= dz;
625
626 b = 0;
627 if (e->buttons_state & MOUSE_EVENT_LBUTTON)
628 b |= 0x01;
629 if (e->buttons_state & MOUSE_EVENT_RBUTTON)
630 b |= 0x02;
631 if (e->buttons_state & MOUSE_EVENT_MBUTTON)
632 b |= 0x04;
633
634 if (hs->n &&
635 !e->dz &&
636 (hs->kind == HID_TABLET || (!e->xdx && !e->ydy))) {
637 /* that deals with this event */
638 QUEUE_INCR(hs->head);
639 hs->n--;
640 }
641
642 /* Appears we have to invert the wheel direction */
643 dz = 0 - dz;
644 l = 0;
645 switch (hs->kind) {
646 case HID_MOUSE:
647 if (len > l)
648 buf[l++] = b;
649 if (len > l)
650 buf[l++] = dx;
651 if (len > l)
652 buf[l++] = dy;
653 if (len > l)
654 buf[l++] = dz;
655 break;
656
657 case HID_TABLET:
658 if (len > l)
659 buf[l++] = b;
660 if (len > l)
661 buf[l++] = dx & 0xff;
662 if (len > l)
663 buf[l++] = dx >> 8;
664 if (len > l)
665 buf[l++] = dy & 0xff;
666 if (len > l)
667 buf[l++] = dy >> 8;
668 if (len > l)
669 buf[l++] = dz;
670 break;
671
672 default:
673 abort();
674 }
675
676 return l;
677 }
678
679 static int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len)
680 {
681 if (len < 2)
682 return 0;
683
684 hid_keyboard_process_keycode(hs);
685
686 buf[0] = hs->kbd.modifiers & 0xff;
687 buf[1] = 0;
688 if (hs->kbd.keys > 6) {
689 memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
690 } else {
691 memcpy(buf + 2, hs->kbd.key, MIN(8, len) - 2);
692 }
693
694 return MIN(8, len);
695 }
696
697 static int hid_keyboard_write(HIDState *hs, uint8_t *buf, int len)
698 {
699 if (len > 0) {
700 int ledstate = 0;
701 /* 0x01: Num Lock LED
702 * 0x02: Caps Lock LED
703 * 0x04: Scroll Lock LED
704 * 0x08: Compose LED
705 * 0x10: Kana LED */
706 hs->kbd.leds = buf[0];
707 if (hs->kbd.leds & 0x04) {
708 ledstate |= QEMU_SCROLL_LOCK_LED;
709 }
710 if (hs->kbd.leds & 0x01) {
711 ledstate |= QEMU_NUM_LOCK_LED;
712 }
713 if (hs->kbd.leds & 0x02) {
714 ledstate |= QEMU_CAPS_LOCK_LED;
715 }
716 kbd_put_ledstate(ledstate);
717 }
718 return 0;
719 }
720
721 static void hid_handle_reset(HIDState *hs)
722 {
723 switch (hs->kind) {
724 case HID_KEYBOARD:
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));
728 hs->kbd.keys = 0;
729 break;
730 case HID_MOUSE:
731 case HID_TABLET:
732 memset(hs->ptr.queue, 0, sizeof(hs->ptr.queue));
733 break;
734 }
735 hs->head = 0;
736 hs->n = 0;
737 }
738
739 static void usb_hid_handle_reset(USBDevice *dev)
740 {
741 USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev);
742
743 hid_handle_reset(&us->hid);
744 us->protocol = 1;
745 }
746
747 static void usb_hid_set_next_idle(USBHIDState *s, int64_t curtime)
748 {
749 s->next_idle_clock = curtime + (get_ticks_per_sec() * s->idle * 4) / 1000;
750 }
751
752 static int usb_hid_handle_control(USBDevice *dev, USBPacket *p,
753 int request, int value, int index, int length, uint8_t *data)
754 {
755 USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev);
756 HIDState *hs = &us->hid;
757 int ret;
758
759 ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
760 if (ret >= 0) {
761 return ret;
762 }
763
764 ret = 0;
765 switch (request) {
766 case DeviceRequest | USB_REQ_GET_INTERFACE:
767 data[0] = 0;
768 ret = 1;
769 break;
770 case DeviceOutRequest | USB_REQ_SET_INTERFACE:
771 ret = 0;
772 break;
773 /* hid specific requests */
774 case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
775 switch (value >> 8) {
776 case 0x22:
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);
789 }
790 break;
791 default:
792 goto fail;
793 }
794 break;
795 case GET_REPORT:
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);
800 }
801 us->changed = hs->n > 0;
802 break;
803 case SET_REPORT:
804 if (hs->kind == HID_KEYBOARD) {
805 ret = hid_keyboard_write(hs, data, length);
806 } else {
807 goto fail;
808 }
809 break;
810 case GET_PROTOCOL:
811 if (hs->kind != HID_KEYBOARD && hs->kind != HID_MOUSE) {
812 goto fail;
813 }
814 ret = 1;
815 data[0] = us->protocol;
816 break;
817 case SET_PROTOCOL:
818 if (hs->kind != HID_KEYBOARD && hs->kind != HID_MOUSE) {
819 goto fail;
820 }
821 ret = 0;
822 us->protocol = value;
823 break;
824 case GET_IDLE:
825 ret = 1;
826 data[0] = us->idle;
827 break;
828 case SET_IDLE:
829 us->idle = (uint8_t) (value >> 8);
830 usb_hid_set_next_idle(us, qemu_get_clock_ns(vm_clock));
831 ret = 0;
832 break;
833 default:
834 fail:
835 ret = USB_RET_STALL;
836 break;
837 }
838 return ret;
839 }
840
841 static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
842 {
843 USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev);
844 HIDState *hs = &us->hid;
845 uint8_t buf[p->iov.size];
846 int ret = 0;
847
848 switch (p->pid) {
849 case USB_TOKEN_IN:
850 if (p->devep == 1) {
851 int64_t curtime = qemu_get_clock_ns(vm_clock);
852 if (!us->changed &&
853 (!us->idle || us->next_idle_clock - curtime > 0)) {
854 return USB_RET_NAK;
855 }
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);
861 }
862 usb_packet_copy(p, buf, ret);
863 us->changed = hs->n > 0;
864 } else {
865 goto fail;
866 }
867 break;
868 case USB_TOKEN_OUT:
869 default:
870 fail:
871 ret = USB_RET_STALL;
872 break;
873 }
874 return ret;
875 }
876
877 static void hid_free(HIDState *hs)
878 {
879 switch (hs->kind) {
880 case HID_KEYBOARD:
881 qemu_remove_kbd_event_handler();
882 break;
883 case HID_MOUSE:
884 case HID_TABLET:
885 qemu_remove_mouse_event_handler(hs->ptr.eh_entry);
886 break;
887 }
888 }
889
890 static void usb_hid_handle_destroy(USBDevice *dev)
891 {
892 USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev);
893
894 hid_free(&us->hid);
895 }
896
897 static void hid_init(HIDState *hs, int kind, HIDEventFunc event)
898 {
899 hs->kind = kind;
900 hs->event = event;
901
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");
908 }
909 }
910
911 static int usb_hid_initfn(USBDevice *dev, int kind)
912 {
913 USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev);
914
915 usb_desc_init(dev);
916 hid_init(&us->hid, kind, usb_hid_changed);
917
918 /* Force poll routine to be run and grab input the first time. */
919 us->changed = 1;
920 return 0;
921 }
922
923 static int usb_tablet_initfn(USBDevice *dev)
924 {
925 return usb_hid_initfn(dev, HID_TABLET);
926 }
927
928 static int usb_mouse_initfn(USBDevice *dev)
929 {
930 return usb_hid_initfn(dev, HID_MOUSE);
931 }
932
933 static int usb_keyboard_initfn(USBDevice *dev)
934 {
935 return usb_hid_initfn(dev, HID_KEYBOARD);
936 }
937
938 void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *))
939 {
940 USBHIDState *s = (USBHIDState *)dev;
941
942 s->datain_opaque = opaque;
943 s->datain = datain;
944 }
945
946 static int usb_hid_post_load(void *opaque, int version_id)
947 {
948 USBHIDState *s = opaque;
949
950 if (s->idle) {
951 usb_hid_set_next_idle(s, qemu_get_clock_ns(vm_clock));
952 }
953 return 0;
954 }
955
956 static const VMStateDescription vmstate_usb_ptr_queue = {
957 .name = "usb-ptr-queue",
958 .version_id = 1,
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()
966 }
967 };
968 static const VMStateDescription vmstate_usb_ptr = {
969 .name = "usb-ptr",
970 .version_id = 1,
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()
982 }
983 };
984
985 static const VMStateDescription vmstate_usb_kbd = {
986 .name = "usb-kbd",
987 .version_id = 1,
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()
1002 }
1003 };
1004
1005 static struct USBDeviceInfo hid_info[] = {
1006 {
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,
1019 },{
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,
1032 },{
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,
1045 },{
1046 /* end of list */
1047 }
1048 };
1049
1050 static void usb_hid_register_devices(void)
1051 {
1052 usb_qdev_register_many(hid_info);
1053 }
1054 device_init(usb_hid_register_devices)