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