]> git.proxmox.com Git - qemu.git/blob - hw/usb-hid.c
usb hid: add migration support
[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 "sysemu.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 USB_MOUSE 1
45 #define USB_TABLET 2
46 #define USB_KEYBOARD 3
47
48 typedef struct USBPointerEvent {
49 int32_t xdx, ydy; /* relative iff it's a mouse, otherwise absolute */
50 int32_t dz, buttons_state;
51 } USBPointerEvent;
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 USBMouseState {
58 USBPointerEvent queue[QUEUE_LENGTH];
59 int mouse_grabbed;
60 QEMUPutMouseEntry *eh_entry;
61 } USBMouseState;
62
63 typedef struct USBKeyboardState {
64 uint32_t keycodes[QUEUE_LENGTH];
65 uint16_t modifiers;
66 uint8_t leds;
67 uint8_t key[16];
68 int32_t keys;
69 } USBKeyboardState;
70
71 typedef struct USBHIDState {
72 USBDevice dev;
73 union {
74 USBMouseState ptr;
75 USBKeyboardState kbd;
76 };
77 uint32_t head; /* index into circular queue */
78 uint32_t n;
79 int kind;
80 int32_t protocol;
81 uint8_t idle;
82 int64_t next_idle_clock;
83 int changed;
84 void *datain_opaque;
85 void (*datain)(void *);
86 } USBHIDState;
87
88 enum {
89 STR_MANUFACTURER = 1,
90 STR_PRODUCT_MOUSE,
91 STR_PRODUCT_TABLET,
92 STR_PRODUCT_KEYBOARD,
93 STR_SERIALNUMBER,
94 STR_CONFIG_MOUSE,
95 STR_CONFIG_TABLET,
96 STR_CONFIG_KEYBOARD,
97 };
98
99 static const USBDescStrings desc_strings = {
100 [STR_MANUFACTURER] = "QEMU " QEMU_VERSION,
101 [STR_PRODUCT_MOUSE] = "QEMU USB Mouse",
102 [STR_PRODUCT_TABLET] = "QEMU USB Tablet",
103 [STR_PRODUCT_KEYBOARD] = "QEMU USB Keyboard",
104 [STR_SERIALNUMBER] = "42", /* == remote wakeup works */
105 [STR_CONFIG_MOUSE] = "HID Mouse",
106 [STR_CONFIG_TABLET] = "HID Tablet",
107 [STR_CONFIG_KEYBOARD] = "HID Keyboard",
108 };
109
110 static const USBDescIface desc_iface_mouse = {
111 .bInterfaceNumber = 0,
112 .bNumEndpoints = 1,
113 .bInterfaceClass = USB_CLASS_HID,
114 .bInterfaceSubClass = 0x01, /* boot */
115 .bInterfaceProtocol = 0x02,
116 .ndesc = 1,
117 .descs = (USBDescOther[]) {
118 {
119 /* HID descriptor */
120 .data = (uint8_t[]) {
121 0x09, /* u8 bLength */
122 USB_DT_HID, /* u8 bDescriptorType */
123 0x01, 0x00, /* u16 HID_class */
124 0x00, /* u8 country_code */
125 0x01, /* u8 num_descriptors */
126 USB_DT_REPORT, /* u8 type: Report */
127 52, 0, /* u16 len */
128 },
129 },
130 },
131 .eps = (USBDescEndpoint[]) {
132 {
133 .bEndpointAddress = USB_DIR_IN | 0x01,
134 .bmAttributes = USB_ENDPOINT_XFER_INT,
135 .wMaxPacketSize = 4,
136 .bInterval = 0x0a,
137 },
138 },
139 };
140
141 static const USBDescIface desc_iface_tablet = {
142 .bInterfaceNumber = 0,
143 .bNumEndpoints = 1,
144 .bInterfaceClass = USB_CLASS_HID,
145 .bInterfaceSubClass = 0x01, /* boot */
146 .bInterfaceProtocol = 0x02,
147 .ndesc = 1,
148 .descs = (USBDescOther[]) {
149 {
150 /* HID descriptor */
151 .data = (uint8_t[]) {
152 0x09, /* u8 bLength */
153 USB_DT_HID, /* u8 bDescriptorType */
154 0x01, 0x00, /* u16 HID_class */
155 0x00, /* u8 country_code */
156 0x01, /* u8 num_descriptors */
157 USB_DT_REPORT, /* u8 type: Report */
158 74, 0, /* u16 len */
159 },
160 },
161 },
162 .eps = (USBDescEndpoint[]) {
163 {
164 .bEndpointAddress = USB_DIR_IN | 0x01,
165 .bmAttributes = USB_ENDPOINT_XFER_INT,
166 .wMaxPacketSize = 8,
167 .bInterval = 0x0a,
168 },
169 },
170 };
171
172 static const USBDescIface desc_iface_keyboard = {
173 .bInterfaceNumber = 0,
174 .bNumEndpoints = 1,
175 .bInterfaceClass = USB_CLASS_HID,
176 .bInterfaceSubClass = 0x01, /* boot */
177 .bInterfaceProtocol = 0x01, /* keyboard */
178 .ndesc = 1,
179 .descs = (USBDescOther[]) {
180 {
181 /* HID descriptor */
182 .data = (uint8_t[]) {
183 0x09, /* u8 bLength */
184 USB_DT_HID, /* u8 bDescriptorType */
185 0x11, 0x01, /* u16 HID_class */
186 0x00, /* u8 country_code */
187 0x01, /* u8 num_descriptors */
188 USB_DT_REPORT, /* u8 type: Report */
189 0x3f, 0, /* u16 len */
190 },
191 },
192 },
193 .eps = (USBDescEndpoint[]) {
194 {
195 .bEndpointAddress = USB_DIR_IN | 0x01,
196 .bmAttributes = USB_ENDPOINT_XFER_INT,
197 .wMaxPacketSize = 8,
198 .bInterval = 0x0a,
199 },
200 },
201 };
202
203 static const USBDescDevice desc_device_mouse = {
204 .bcdUSB = 0x0100,
205 .bMaxPacketSize0 = 8,
206 .bNumConfigurations = 1,
207 .confs = (USBDescConfig[]) {
208 {
209 .bNumInterfaces = 1,
210 .bConfigurationValue = 1,
211 .iConfiguration = STR_CONFIG_MOUSE,
212 .bmAttributes = 0xa0,
213 .bMaxPower = 50,
214 .ifs = &desc_iface_mouse,
215 },
216 },
217 };
218
219 static const USBDescDevice desc_device_tablet = {
220 .bcdUSB = 0x0100,
221 .bMaxPacketSize0 = 8,
222 .bNumConfigurations = 1,
223 .confs = (USBDescConfig[]) {
224 {
225 .bNumInterfaces = 1,
226 .bConfigurationValue = 1,
227 .iConfiguration = STR_CONFIG_TABLET,
228 .bmAttributes = 0xa0,
229 .bMaxPower = 50,
230 .ifs = &desc_iface_tablet,
231 },
232 },
233 };
234
235 static const USBDescDevice desc_device_keyboard = {
236 .bcdUSB = 0x0100,
237 .bMaxPacketSize0 = 8,
238 .bNumConfigurations = 1,
239 .confs = (USBDescConfig[]) {
240 {
241 .bNumInterfaces = 1,
242 .bConfigurationValue = 1,
243 .iConfiguration = STR_CONFIG_KEYBOARD,
244 .bmAttributes = 0xa0,
245 .bMaxPower = 50,
246 .ifs = &desc_iface_keyboard,
247 },
248 },
249 };
250
251 static const USBDesc desc_mouse = {
252 .id = {
253 .idVendor = 0x0627,
254 .idProduct = 0x0001,
255 .bcdDevice = 0,
256 .iManufacturer = STR_MANUFACTURER,
257 .iProduct = STR_PRODUCT_MOUSE,
258 .iSerialNumber = STR_SERIALNUMBER,
259 },
260 .full = &desc_device_mouse,
261 .str = desc_strings,
262 };
263
264 static const USBDesc desc_tablet = {
265 .id = {
266 .idVendor = 0x0627,
267 .idProduct = 0x0001,
268 .bcdDevice = 0,
269 .iManufacturer = STR_MANUFACTURER,
270 .iProduct = STR_PRODUCT_TABLET,
271 .iSerialNumber = STR_SERIALNUMBER,
272 },
273 .full = &desc_device_tablet,
274 .str = desc_strings,
275 };
276
277 static const USBDesc desc_keyboard = {
278 .id = {
279 .idVendor = 0x0627,
280 .idProduct = 0x0001,
281 .bcdDevice = 0,
282 .iManufacturer = STR_MANUFACTURER,
283 .iProduct = STR_PRODUCT_KEYBOARD,
284 .iSerialNumber = STR_SERIALNUMBER,
285 },
286 .full = &desc_device_keyboard,
287 .str = desc_strings,
288 };
289
290 static const uint8_t qemu_mouse_hid_report_descriptor[] = {
291 0x05, 0x01, /* Usage Page (Generic Desktop) */
292 0x09, 0x02, /* Usage (Mouse) */
293 0xa1, 0x01, /* Collection (Application) */
294 0x09, 0x01, /* Usage (Pointer) */
295 0xa1, 0x00, /* Collection (Physical) */
296 0x05, 0x09, /* Usage Page (Button) */
297 0x19, 0x01, /* Usage Minimum (1) */
298 0x29, 0x03, /* Usage Maximum (3) */
299 0x15, 0x00, /* Logical Minimum (0) */
300 0x25, 0x01, /* Logical Maximum (1) */
301 0x95, 0x03, /* Report Count (3) */
302 0x75, 0x01, /* Report Size (1) */
303 0x81, 0x02, /* Input (Data, Variable, Absolute) */
304 0x95, 0x01, /* Report Count (1) */
305 0x75, 0x05, /* Report Size (5) */
306 0x81, 0x01, /* Input (Constant) */
307 0x05, 0x01, /* Usage Page (Generic Desktop) */
308 0x09, 0x30, /* Usage (X) */
309 0x09, 0x31, /* Usage (Y) */
310 0x09, 0x38, /* Usage (Wheel) */
311 0x15, 0x81, /* Logical Minimum (-0x7f) */
312 0x25, 0x7f, /* Logical Maximum (0x7f) */
313 0x75, 0x08, /* Report Size (8) */
314 0x95, 0x03, /* Report Count (3) */
315 0x81, 0x06, /* Input (Data, Variable, Relative) */
316 0xc0, /* End Collection */
317 0xc0, /* End Collection */
318 };
319
320 static const uint8_t qemu_tablet_hid_report_descriptor[] = {
321 0x05, 0x01, /* Usage Page (Generic Desktop) */
322 0x09, 0x01, /* Usage (Pointer) */
323 0xa1, 0x01, /* Collection (Application) */
324 0x09, 0x01, /* Usage (Pointer) */
325 0xa1, 0x00, /* Collection (Physical) */
326 0x05, 0x09, /* Usage Page (Button) */
327 0x19, 0x01, /* Usage Minimum (1) */
328 0x29, 0x03, /* Usage Maximum (3) */
329 0x15, 0x00, /* Logical Minimum (0) */
330 0x25, 0x01, /* Logical Maximum (1) */
331 0x95, 0x03, /* Report Count (3) */
332 0x75, 0x01, /* Report Size (1) */
333 0x81, 0x02, /* Input (Data, Variable, Absolute) */
334 0x95, 0x01, /* Report Count (1) */
335 0x75, 0x05, /* Report Size (5) */
336 0x81, 0x01, /* Input (Constant) */
337 0x05, 0x01, /* Usage Page (Generic Desktop) */
338 0x09, 0x30, /* Usage (X) */
339 0x09, 0x31, /* Usage (Y) */
340 0x15, 0x00, /* Logical Minimum (0) */
341 0x26, 0xff, 0x7f, /* Logical Maximum (0x7fff) */
342 0x35, 0x00, /* Physical Minimum (0) */
343 0x46, 0xff, 0x7f, /* Physical Maximum (0x7fff) */
344 0x75, 0x10, /* Report Size (16) */
345 0x95, 0x02, /* Report Count (2) */
346 0x81, 0x02, /* Input (Data, Variable, Absolute) */
347 0x05, 0x01, /* Usage Page (Generic Desktop) */
348 0x09, 0x38, /* Usage (Wheel) */
349 0x15, 0x81, /* Logical Minimum (-0x7f) */
350 0x25, 0x7f, /* Logical Maximum (0x7f) */
351 0x35, 0x00, /* Physical Minimum (same as logical) */
352 0x45, 0x00, /* Physical Maximum (same as logical) */
353 0x75, 0x08, /* Report Size (8) */
354 0x95, 0x01, /* Report Count (1) */
355 0x81, 0x06, /* Input (Data, Variable, Relative) */
356 0xc0, /* End Collection */
357 0xc0, /* End Collection */
358 };
359
360 static const uint8_t qemu_keyboard_hid_report_descriptor[] = {
361 0x05, 0x01, /* Usage Page (Generic Desktop) */
362 0x09, 0x06, /* Usage (Keyboard) */
363 0xa1, 0x01, /* Collection (Application) */
364 0x75, 0x01, /* Report Size (1) */
365 0x95, 0x08, /* Report Count (8) */
366 0x05, 0x07, /* Usage Page (Key Codes) */
367 0x19, 0xe0, /* Usage Minimum (224) */
368 0x29, 0xe7, /* Usage Maximum (231) */
369 0x15, 0x00, /* Logical Minimum (0) */
370 0x25, 0x01, /* Logical Maximum (1) */
371 0x81, 0x02, /* Input (Data, Variable, Absolute) */
372 0x95, 0x01, /* Report Count (1) */
373 0x75, 0x08, /* Report Size (8) */
374 0x81, 0x01, /* Input (Constant) */
375 0x95, 0x05, /* Report Count (5) */
376 0x75, 0x01, /* Report Size (1) */
377 0x05, 0x08, /* Usage Page (LEDs) */
378 0x19, 0x01, /* Usage Minimum (1) */
379 0x29, 0x05, /* Usage Maximum (5) */
380 0x91, 0x02, /* Output (Data, Variable, Absolute) */
381 0x95, 0x01, /* Report Count (1) */
382 0x75, 0x03, /* Report Size (3) */
383 0x91, 0x01, /* Output (Constant) */
384 0x95, 0x06, /* Report Count (6) */
385 0x75, 0x08, /* Report Size (8) */
386 0x15, 0x00, /* Logical Minimum (0) */
387 0x25, 0xff, /* Logical Maximum (255) */
388 0x05, 0x07, /* Usage Page (Key Codes) */
389 0x19, 0x00, /* Usage Minimum (0) */
390 0x29, 0xff, /* Usage Maximum (255) */
391 0x81, 0x00, /* Input (Data, Array) */
392 0xc0, /* End Collection */
393 };
394
395 #define USB_HID_USAGE_ERROR_ROLLOVER 0x01
396 #define USB_HID_USAGE_POSTFAIL 0x02
397 #define USB_HID_USAGE_ERROR_UNDEFINED 0x03
398
399 /* Indices are QEMU keycodes, values are from HID Usage Table. Indices
400 * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d. */
401 static const uint8_t usb_hid_usage_keys[0x100] = {
402 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
403 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
404 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
405 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
406 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
407 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
408 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
409 0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
410 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
411 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
412 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
413 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
414 0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
415 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
416 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
417 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
418
419 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
421 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
425 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
426 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
427 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
428 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
429 0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
430 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 0x00, 0x00,
431 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00,
435 };
436
437 static void usb_hid_changed(USBHIDState *hs)
438 {
439 hs->changed = 1;
440
441 if (hs->datain)
442 hs->datain(hs->datain_opaque);
443
444 usb_wakeup(&hs->dev);
445 }
446
447 static void usb_pointer_event_clear(USBPointerEvent *e, int buttons) {
448 e->xdx = e->ydy = e->dz = 0;
449 e->buttons_state = buttons;
450 }
451
452 static void usb_pointer_event_combine(USBPointerEvent *e, int xyrel,
453 int x1, int y1, int z1) {
454 if (xyrel) {
455 e->xdx += x1;
456 e->ydy += y1;
457 } else {
458 e->xdx = x1;
459 e->ydy = y1;
460 }
461 e->dz += z1;
462 }
463
464 static void usb_pointer_event(void *opaque,
465 int x1, int y1, int z1, int buttons_state)
466 {
467 USBHIDState *hs = opaque;
468 USBMouseState *s = &hs->ptr;
469 unsigned use_slot = (hs->head + hs->n - 1) & QUEUE_MASK;
470 unsigned previous_slot = (use_slot - 1) & QUEUE_MASK;
471
472 /* We combine events where feasible to keep the queue small. We shouldn't
473 * combine anything with the first event of a particular button state, as
474 * that would change the location of the button state change. When the
475 * queue is empty, a second event is needed because we don't know if
476 * the first event changed the button state. */
477 if (hs->n == QUEUE_LENGTH) {
478 /* Queue full. Discard old button state, combine motion normally. */
479 s->queue[use_slot].buttons_state = buttons_state;
480 } else if (hs->n < 2 ||
481 s->queue[use_slot].buttons_state != buttons_state ||
482 s->queue[previous_slot].buttons_state != s->queue[use_slot].buttons_state) {
483 /* Cannot or should not combine, so add an empty item to the queue. */
484 QUEUE_INCR(use_slot);
485 hs->n++;
486 usb_pointer_event_clear(&s->queue[use_slot], buttons_state);
487 }
488 usb_pointer_event_combine(&s->queue[use_slot],
489 hs->kind == USB_MOUSE,
490 x1, y1, z1);
491 usb_hid_changed(hs);
492 }
493
494 static void usb_keyboard_event(void *opaque, int keycode)
495 {
496 USBHIDState *hs = opaque;
497 USBKeyboardState *s = &hs->kbd;
498 int slot;
499
500 if (hs->n == QUEUE_LENGTH) {
501 fprintf(stderr, "usb-kbd: warning: key event queue full\n");
502 return;
503 }
504 slot = (hs->head + hs->n) & QUEUE_MASK; hs->n++;
505 s->keycodes[slot] = keycode;
506 usb_hid_changed(hs);
507 }
508
509 static void usb_keyboard_process_keycode(USBHIDState *hs)
510 {
511 USBKeyboardState *s = &hs->kbd;
512 uint8_t hid_code, key;
513 int i, keycode, slot;
514
515 if (hs->n == 0) {
516 return;
517 }
518 slot = hs->head & QUEUE_MASK; QUEUE_INCR(hs->head); hs->n--;
519 keycode = s->keycodes[slot];
520
521 key = keycode & 0x7f;
522 hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))];
523 s->modifiers &= ~(1 << 8);
524
525 switch (hid_code) {
526 case 0x00:
527 return;
528
529 case 0xe0:
530 if (s->modifiers & (1 << 9)) {
531 s->modifiers ^= 3 << 8;
532 usb_hid_changed(hs);
533 return;
534 }
535 case 0xe1 ... 0xe7:
536 if (keycode & (1 << 7)) {
537 s->modifiers &= ~(1 << (hid_code & 0x0f));
538 usb_hid_changed(hs);
539 return;
540 }
541 case 0xe8 ... 0xef:
542 s->modifiers |= 1 << (hid_code & 0x0f);
543 usb_hid_changed(hs);
544 return;
545 }
546
547 if (keycode & (1 << 7)) {
548 for (i = s->keys - 1; i >= 0; i --)
549 if (s->key[i] == hid_code) {
550 s->key[i] = s->key[-- s->keys];
551 s->key[s->keys] = 0x00;
552 break;
553 }
554 if (i < 0)
555 return;
556 } else {
557 for (i = s->keys - 1; i >= 0; i --)
558 if (s->key[i] == hid_code)
559 break;
560 if (i < 0) {
561 if (s->keys < sizeof(s->key))
562 s->key[s->keys ++] = hid_code;
563 } else
564 return;
565 }
566 }
567
568 static inline int int_clamp(int val, int vmin, int vmax)
569 {
570 if (val < vmin)
571 return vmin;
572 else if (val > vmax)
573 return vmax;
574 else
575 return val;
576 }
577
578 static int usb_pointer_poll(USBHIDState *hs, uint8_t *buf, int len)
579 {
580 int dx, dy, dz, b, l;
581 int index;
582 USBMouseState *s = &hs->ptr;
583 USBPointerEvent *e;
584
585 if (!s->mouse_grabbed) {
586 qemu_activate_mouse_event_handler(s->eh_entry);
587 s->mouse_grabbed = 1;
588 }
589
590 /* When the buffer is empty, return the last event. Relative
591 movements will all be zero. */
592 index = (hs->n ? hs->head : hs->head - 1);
593 e = &s->queue[index & QUEUE_MASK];
594
595 if (hs->kind == USB_MOUSE) {
596 dx = int_clamp(e->xdx, -127, 127);
597 dy = int_clamp(e->ydy, -127, 127);
598 e->xdx -= dx;
599 e->ydy -= dy;
600 } else {
601 dx = e->xdx;
602 dy = e->ydy;
603 }
604 dz = int_clamp(e->dz, -127, 127);
605 e->dz -= dz;
606
607 b = 0;
608 if (e->buttons_state & MOUSE_EVENT_LBUTTON)
609 b |= 0x01;
610 if (e->buttons_state & MOUSE_EVENT_RBUTTON)
611 b |= 0x02;
612 if (e->buttons_state & MOUSE_EVENT_MBUTTON)
613 b |= 0x04;
614
615 if (hs->n &&
616 !e->dz &&
617 (hs->kind == USB_TABLET || (!e->xdx && !e->ydy))) {
618 /* that deals with this event */
619 QUEUE_INCR(hs->head);
620 hs->n--;
621 }
622
623 /* Appears we have to invert the wheel direction */
624 dz = 0 - dz;
625 l = 0;
626 switch (hs->kind) {
627 case USB_MOUSE:
628 if (len > l)
629 buf[l++] = b;
630 if (len > l)
631 buf[l++] = dx;
632 if (len > l)
633 buf[l++] = dy;
634 if (len > l)
635 buf[l++] = dz;
636 break;
637
638 case USB_TABLET:
639 if (len > l)
640 buf[l++] = b;
641 if (len > l)
642 buf[l++] = dx & 0xff;
643 if (len > l)
644 buf[l++] = dx >> 8;
645 if (len > l)
646 buf[l++] = dy & 0xff;
647 if (len > l)
648 buf[l++] = dy >> 8;
649 if (len > l)
650 buf[l++] = dz;
651 break;
652
653 default:
654 abort();
655 }
656
657 return l;
658 }
659
660 static int usb_keyboard_poll(USBHIDState *hs, uint8_t *buf, int len)
661 {
662 USBKeyboardState *s = &hs->kbd;
663 if (len < 2)
664 return 0;
665
666 usb_keyboard_process_keycode(hs);
667
668 buf[0] = s->modifiers & 0xff;
669 buf[1] = 0;
670 if (s->keys > 6)
671 memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
672 else
673 memcpy(buf + 2, s->key, MIN(8, len) - 2);
674
675 return MIN(8, len);
676 }
677
678 static int usb_keyboard_write(USBKeyboardState *s, uint8_t *buf, int len)
679 {
680 if (len > 0) {
681 int ledstate = 0;
682 /* 0x01: Num Lock LED
683 * 0x02: Caps Lock LED
684 * 0x04: Scroll Lock LED
685 * 0x08: Compose LED
686 * 0x10: Kana LED */
687 s->leds = buf[0];
688 if (s->leds & 0x04)
689 ledstate |= QEMU_SCROLL_LOCK_LED;
690 if (s->leds & 0x01)
691 ledstate |= QEMU_NUM_LOCK_LED;
692 if (s->leds & 0x02)
693 ledstate |= QEMU_CAPS_LOCK_LED;
694 kbd_put_ledstate(ledstate);
695 }
696 return 0;
697 }
698
699 static void usb_mouse_handle_reset(USBDevice *dev)
700 {
701 USBHIDState *s = (USBHIDState *)dev;
702
703 memset(s->ptr.queue, 0, sizeof (s->ptr.queue));
704 s->head = 0;
705 s->n = 0;
706 s->protocol = 1;
707 }
708
709 static void usb_keyboard_handle_reset(USBDevice *dev)
710 {
711 USBHIDState *s = (USBHIDState *)dev;
712
713 qemu_add_kbd_event_handler(usb_keyboard_event, s);
714 memset(s->kbd.keycodes, 0, sizeof (s->kbd.keycodes));
715 s->head = 0;
716 s->n = 0;
717 memset(s->kbd.key, 0, sizeof (s->kbd.key));
718 s->kbd.keys = 0;
719 s->protocol = 1;
720 }
721
722 static void usb_hid_set_next_idle(USBHIDState *s, int64_t curtime)
723 {
724 s->next_idle_clock = curtime + (get_ticks_per_sec() * s->idle * 4) / 1000;
725 }
726
727 static int usb_hid_handle_control(USBDevice *dev, int request, int value,
728 int index, int length, uint8_t *data)
729 {
730 USBHIDState *s = (USBHIDState *)dev;
731 int ret;
732
733 ret = usb_desc_handle_control(dev, request, value, index, length, data);
734 if (ret >= 0) {
735 return ret;
736 }
737
738 ret = 0;
739 switch(request) {
740 case DeviceRequest | USB_REQ_GET_INTERFACE:
741 data[0] = 0;
742 ret = 1;
743 break;
744 case DeviceOutRequest | USB_REQ_SET_INTERFACE:
745 ret = 0;
746 break;
747 /* hid specific requests */
748 case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
749 switch(value >> 8) {
750 case 0x22:
751 if (s->kind == USB_MOUSE) {
752 memcpy(data, qemu_mouse_hid_report_descriptor,
753 sizeof(qemu_mouse_hid_report_descriptor));
754 ret = sizeof(qemu_mouse_hid_report_descriptor);
755 } else if (s->kind == USB_TABLET) {
756 memcpy(data, qemu_tablet_hid_report_descriptor,
757 sizeof(qemu_tablet_hid_report_descriptor));
758 ret = sizeof(qemu_tablet_hid_report_descriptor);
759 } else if (s->kind == USB_KEYBOARD) {
760 memcpy(data, qemu_keyboard_hid_report_descriptor,
761 sizeof(qemu_keyboard_hid_report_descriptor));
762 ret = sizeof(qemu_keyboard_hid_report_descriptor);
763 }
764 break;
765 default:
766 goto fail;
767 }
768 break;
769 case GET_REPORT:
770 if (s->kind == USB_MOUSE || s->kind == USB_TABLET)
771 ret = usb_pointer_poll(s, data, length);
772 else if (s->kind == USB_KEYBOARD)
773 ret = usb_keyboard_poll(s, data, length);
774 break;
775 case SET_REPORT:
776 if (s->kind == USB_KEYBOARD)
777 ret = usb_keyboard_write(&s->kbd, data, length);
778 else
779 goto fail;
780 break;
781 case GET_PROTOCOL:
782 if (s->kind != USB_KEYBOARD)
783 goto fail;
784 ret = 1;
785 data[0] = s->protocol;
786 break;
787 case SET_PROTOCOL:
788 if (s->kind != USB_KEYBOARD)
789 goto fail;
790 ret = 0;
791 s->protocol = value;
792 break;
793 case GET_IDLE:
794 ret = 1;
795 data[0] = s->idle;
796 break;
797 case SET_IDLE:
798 s->idle = (uint8_t) (value >> 8);
799 usb_hid_set_next_idle(s, qemu_get_clock(vm_clock));
800 ret = 0;
801 break;
802 default:
803 fail:
804 ret = USB_RET_STALL;
805 break;
806 }
807 return ret;
808 }
809
810 static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
811 {
812 USBHIDState *s = (USBHIDState *)dev;
813 int ret = 0;
814
815 switch(p->pid) {
816 case USB_TOKEN_IN:
817 if (p->devep == 1) {
818 int64_t curtime = qemu_get_clock(vm_clock);
819 if (!s->changed && (!s->idle || s->next_idle_clock - curtime > 0))
820 return USB_RET_NAK;
821 usb_hid_set_next_idle(s, curtime);
822 if (s->kind == USB_MOUSE || s->kind == USB_TABLET) {
823 ret = usb_pointer_poll(s, p->data, p->len);
824 }
825 else if (s->kind == USB_KEYBOARD) {
826 ret = usb_keyboard_poll(s, p->data, p->len);
827 }
828 s->changed = s->n > 0;
829 } else {
830 goto fail;
831 }
832 break;
833 case USB_TOKEN_OUT:
834 default:
835 fail:
836 ret = USB_RET_STALL;
837 break;
838 }
839 return ret;
840 }
841
842 static void usb_hid_handle_destroy(USBDevice *dev)
843 {
844 USBHIDState *s = (USBHIDState *)dev;
845
846 switch(s->kind) {
847 case USB_KEYBOARD:
848 qemu_remove_kbd_event_handler();
849 break;
850 default:
851 qemu_remove_mouse_event_handler(s->ptr.eh_entry);
852 }
853 }
854
855 static int usb_hid_initfn(USBDevice *dev, int kind)
856 {
857 USBHIDState *s = DO_UPCAST(USBHIDState, dev, dev);
858
859 usb_desc_init(dev);
860 s->kind = kind;
861
862 if (s->kind == USB_MOUSE) {
863 s->ptr.eh_entry = qemu_add_mouse_event_handler(usb_pointer_event, s,
864 0, "QEMU USB Mouse");
865 } else if (s->kind == USB_TABLET) {
866 s->ptr.eh_entry = qemu_add_mouse_event_handler(usb_pointer_event, s,
867 1, "QEMU USB Tablet");
868 }
869
870 /* Force poll routine to be run and grab input the first time. */
871 s->changed = 1;
872 return 0;
873 }
874
875 static int usb_tablet_initfn(USBDevice *dev)
876 {
877 return usb_hid_initfn(dev, USB_TABLET);
878 }
879
880 static int usb_mouse_initfn(USBDevice *dev)
881 {
882 return usb_hid_initfn(dev, USB_MOUSE);
883 }
884
885 static int usb_keyboard_initfn(USBDevice *dev)
886 {
887 return usb_hid_initfn(dev, USB_KEYBOARD);
888 }
889
890 void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *))
891 {
892 USBHIDState *s = (USBHIDState *)dev;
893
894 s->datain_opaque = opaque;
895 s->datain = datain;
896 }
897
898 static int usb_hid_post_load(void *opaque, int version_id)
899 {
900 USBHIDState *s = opaque;
901
902 if (s->idle) {
903 usb_hid_set_next_idle(s, qemu_get_clock(vm_clock));
904 }
905 return 0;
906 }
907
908 static const VMStateDescription vmstate_usb_ptr_queue = {
909 .name = "usb-ptr-queue",
910 .version_id = 1,
911 .minimum_version_id = 1,
912 .fields = (VMStateField []) {
913 VMSTATE_INT32(xdx, USBPointerEvent),
914 VMSTATE_INT32(ydy, USBPointerEvent),
915 VMSTATE_INT32(dz, USBPointerEvent),
916 VMSTATE_INT32(buttons_state, USBPointerEvent),
917 VMSTATE_END_OF_LIST()
918 }
919 };
920 static const VMStateDescription vmstate_usb_ptr = {
921 .name = "usb-ptr",
922 .version_id = 1,
923 .minimum_version_id = 1,
924 .post_load = usb_hid_post_load,
925 .fields = (VMStateField []) {
926 VMSTATE_USB_DEVICE(dev, USBHIDState),
927 VMSTATE_STRUCT_ARRAY(ptr.queue, USBHIDState, QUEUE_LENGTH, 0,
928 vmstate_usb_ptr_queue, USBPointerEvent),
929 VMSTATE_UINT32(head, USBHIDState),
930 VMSTATE_UINT32(n, USBHIDState),
931 VMSTATE_INT32(protocol, USBHIDState),
932 VMSTATE_UINT8(idle, USBHIDState),
933 VMSTATE_END_OF_LIST()
934 }
935 };
936
937 static const VMStateDescription vmstate_usb_kbd = {
938 .name = "usb-kbd",
939 .version_id = 1,
940 .minimum_version_id = 1,
941 .post_load = usb_hid_post_load,
942 .fields = (VMStateField []) {
943 VMSTATE_USB_DEVICE(dev, USBHIDState),
944 VMSTATE_UINT32_ARRAY(kbd.keycodes, USBHIDState, QUEUE_LENGTH),
945 VMSTATE_UINT32(head, USBHIDState),
946 VMSTATE_UINT32(n, USBHIDState),
947 VMSTATE_UINT16(kbd.modifiers, USBHIDState),
948 VMSTATE_UINT8(kbd.leds, USBHIDState),
949 VMSTATE_UINT8_ARRAY(kbd.key, USBHIDState, 16),
950 VMSTATE_INT32(kbd.keys, USBHIDState),
951 VMSTATE_INT32(protocol, USBHIDState),
952 VMSTATE_UINT8(idle, USBHIDState),
953 VMSTATE_END_OF_LIST()
954 }
955 };
956
957 static struct USBDeviceInfo hid_info[] = {
958 {
959 .product_desc = "QEMU USB Tablet",
960 .qdev.name = "usb-tablet",
961 .usbdevice_name = "tablet",
962 .qdev.size = sizeof(USBHIDState),
963 .qdev.vmsd = &vmstate_usb_ptr,
964 .usb_desc = &desc_tablet,
965 .init = usb_tablet_initfn,
966 .handle_packet = usb_generic_handle_packet,
967 .handle_reset = usb_mouse_handle_reset,
968 .handle_control = usb_hid_handle_control,
969 .handle_data = usb_hid_handle_data,
970 .handle_destroy = usb_hid_handle_destroy,
971 },{
972 .product_desc = "QEMU USB Mouse",
973 .qdev.name = "usb-mouse",
974 .usbdevice_name = "mouse",
975 .qdev.size = sizeof(USBHIDState),
976 .qdev.vmsd = &vmstate_usb_ptr,
977 .usb_desc = &desc_mouse,
978 .init = usb_mouse_initfn,
979 .handle_packet = usb_generic_handle_packet,
980 .handle_reset = usb_mouse_handle_reset,
981 .handle_control = usb_hid_handle_control,
982 .handle_data = usb_hid_handle_data,
983 .handle_destroy = usb_hid_handle_destroy,
984 },{
985 .product_desc = "QEMU USB Keyboard",
986 .qdev.name = "usb-kbd",
987 .usbdevice_name = "keyboard",
988 .qdev.size = sizeof(USBHIDState),
989 .qdev.vmsd = &vmstate_usb_kbd,
990 .usb_desc = &desc_keyboard,
991 .init = usb_keyboard_initfn,
992 .handle_packet = usb_generic_handle_packet,
993 .handle_reset = usb_keyboard_handle_reset,
994 .handle_control = usb_hid_handle_control,
995 .handle_data = usb_hid_handle_data,
996 .handle_destroy = usb_hid_handle_destroy,
997 },{
998 /* end of list */
999 }
1000 };
1001
1002 static void usb_hid_register_devices(void)
1003 {
1004 usb_qdev_register_many(hid_info);
1005 }
1006 device_init(usb_hid_register_devices)