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