Merge remote branch 'mst/for_anthony' into staging
[qemu.git] / hw / usb-hid.c
blob12bf46fa7e92b97a608de8ccfa92fad47c2e5aec
1 /*
2 * QEMU USB HID devices
4 * Copyright (c) 2005 Fabrice Bellard
5 * Copyright (c) 2007 OpenMoko, Inc. (andrew@openedhand.com)
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
25 #include "hw.h"
26 #include "console.h"
27 #include "usb.h"
28 #include "sysemu.h"
30 /* HID interface requests */
31 #define GET_REPORT 0xa101
32 #define GET_IDLE 0xa102
33 #define GET_PROTOCOL 0xa103
34 #define SET_REPORT 0x2109
35 #define SET_IDLE 0x210a
36 #define SET_PROTOCOL 0x210b
38 /* HID descriptor types */
39 #define USB_DT_HID 0x21
40 #define USB_DT_REPORT 0x22
41 #define USB_DT_PHY 0x23
43 #define USB_MOUSE 1
44 #define USB_TABLET 2
45 #define USB_KEYBOARD 3
47 typedef struct USBMouseState {
48 int dx, dy, dz, buttons_state;
49 int x, y;
50 int mouse_grabbed;
51 QEMUPutMouseEntry *eh_entry;
52 } USBMouseState;
54 typedef struct USBKeyboardState {
55 uint16_t modifiers;
56 uint8_t leds;
57 uint8_t key[16];
58 int keys;
59 } USBKeyboardState;
61 typedef struct USBHIDState {
62 USBDevice dev;
63 union {
64 USBMouseState ptr;
65 USBKeyboardState kbd;
67 int kind;
68 int protocol;
69 uint8_t idle;
70 int64_t next_idle_clock;
71 int changed;
72 void *datain_opaque;
73 void (*datain)(void *);
74 } USBHIDState;
76 /* mostly the same values as the Bochs USB Mouse device */
77 static const uint8_t qemu_mouse_dev_descriptor[] = {
78 0x12, /* u8 bLength; */
79 0x01, /* u8 bDescriptorType; Device */
80 0x00, 0x01, /* u16 bcdUSB; v1.0 */
82 0x00, /* u8 bDeviceClass; */
83 0x00, /* u8 bDeviceSubClass; */
84 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
85 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
87 0x27, 0x06, /* u16 idVendor; */
88 0x01, 0x00, /* u16 idProduct; */
89 0x00, 0x00, /* u16 bcdDevice */
91 0x03, /* u8 iManufacturer; */
92 0x02, /* u8 iProduct; */
93 0x01, /* u8 iSerialNumber; */
94 0x01 /* u8 bNumConfigurations; */
97 static const uint8_t qemu_mouse_config_descriptor[] = {
98 /* one configuration */
99 0x09, /* u8 bLength; */
100 0x02, /* u8 bDescriptorType; Configuration */
101 0x22, 0x00, /* u16 wTotalLength; */
102 0x01, /* u8 bNumInterfaces; (1) */
103 0x01, /* u8 bConfigurationValue; */
104 0x04, /* u8 iConfiguration; */
105 0xe0, /* u8 bmAttributes;
106 Bit 7: must be set,
107 6: Self-powered,
108 5: Remote wakeup,
109 4..0: resvd */
110 50, /* u8 MaxPower; */
112 /* USB 1.1:
113 * USB 2.0, single TT organization (mandatory):
114 * one interface, protocol 0
116 * USB 2.0, multiple TT organization (optional):
117 * two interfaces, protocols 1 (like single TT)
118 * and 2 (multiple TT mode) ... config is
119 * sometimes settable
120 * NOT IMPLEMENTED
123 /* one interface */
124 0x09, /* u8 if_bLength; */
125 0x04, /* u8 if_bDescriptorType; Interface */
126 0x00, /* u8 if_bInterfaceNumber; */
127 0x00, /* u8 if_bAlternateSetting; */
128 0x01, /* u8 if_bNumEndpoints; */
129 0x03, /* u8 if_bInterfaceClass; */
130 0x01, /* u8 if_bInterfaceSubClass; */
131 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
132 0x07, /* u8 if_iInterface; */
134 /* HID descriptor */
135 0x09, /* u8 bLength; */
136 0x21, /* u8 bDescriptorType; */
137 0x01, 0x00, /* u16 HID_class */
138 0x00, /* u8 country_code */
139 0x01, /* u8 num_descriptors */
140 0x22, /* u8 type; Report */
141 52, 0, /* u16 len */
143 /* one endpoint (status change endpoint) */
144 0x07, /* u8 ep_bLength; */
145 0x05, /* u8 ep_bDescriptorType; Endpoint */
146 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
147 0x03, /* u8 ep_bmAttributes; Interrupt */
148 0x04, 0x00, /* u16 ep_wMaxPacketSize; */
149 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
152 static const uint8_t qemu_tablet_config_descriptor[] = {
153 /* one configuration */
154 0x09, /* u8 bLength; */
155 0x02, /* u8 bDescriptorType; Configuration */
156 0x22, 0x00, /* u16 wTotalLength; */
157 0x01, /* u8 bNumInterfaces; (1) */
158 0x01, /* u8 bConfigurationValue; */
159 0x05, /* u8 iConfiguration; */
160 0xa0, /* u8 bmAttributes;
161 Bit 7: must be set,
162 6: Self-powered,
163 5: Remote wakeup,
164 4..0: resvd */
165 50, /* u8 MaxPower; */
167 /* USB 1.1:
168 * USB 2.0, single TT organization (mandatory):
169 * one interface, protocol 0
171 * USB 2.0, multiple TT organization (optional):
172 * two interfaces, protocols 1 (like single TT)
173 * and 2 (multiple TT mode) ... config is
174 * sometimes settable
175 * NOT IMPLEMENTED
178 /* one interface */
179 0x09, /* u8 if_bLength; */
180 0x04, /* u8 if_bDescriptorType; Interface */
181 0x00, /* u8 if_bInterfaceNumber; */
182 0x00, /* u8 if_bAlternateSetting; */
183 0x01, /* u8 if_bNumEndpoints; */
184 0x03, /* u8 if_bInterfaceClass; */
185 0x01, /* u8 if_bInterfaceSubClass; */
186 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
187 0x07, /* u8 if_iInterface; */
189 /* HID descriptor */
190 0x09, /* u8 bLength; */
191 0x21, /* u8 bDescriptorType; */
192 0x01, 0x00, /* u16 HID_class */
193 0x00, /* u8 country_code */
194 0x01, /* u8 num_descriptors */
195 0x22, /* u8 type; Report */
196 74, 0, /* u16 len */
198 /* one endpoint (status change endpoint) */
199 0x07, /* u8 ep_bLength; */
200 0x05, /* u8 ep_bDescriptorType; Endpoint */
201 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
202 0x03, /* u8 ep_bmAttributes; Interrupt */
203 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
204 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
207 static const uint8_t qemu_keyboard_config_descriptor[] = {
208 /* one configuration */
209 0x09, /* u8 bLength; */
210 USB_DT_CONFIG, /* u8 bDescriptorType; Configuration */
211 0x22, 0x00, /* u16 wTotalLength; */
212 0x01, /* u8 bNumInterfaces; (1) */
213 0x01, /* u8 bConfigurationValue; */
214 0x06, /* u8 iConfiguration; */
215 0xa0, /* u8 bmAttributes;
216 Bit 7: must be set,
217 6: Self-powered,
218 5: Remote wakeup,
219 4..0: resvd */
220 0x32, /* u8 MaxPower; */
222 /* USB 1.1:
223 * USB 2.0, single TT organization (mandatory):
224 * one interface, protocol 0
226 * USB 2.0, multiple TT organization (optional):
227 * two interfaces, protocols 1 (like single TT)
228 * and 2 (multiple TT mode) ... config is
229 * sometimes settable
230 * NOT IMPLEMENTED
233 /* one interface */
234 0x09, /* u8 if_bLength; */
235 USB_DT_INTERFACE, /* u8 if_bDescriptorType; Interface */
236 0x00, /* u8 if_bInterfaceNumber; */
237 0x00, /* u8 if_bAlternateSetting; */
238 0x01, /* u8 if_bNumEndpoints; */
239 0x03, /* u8 if_bInterfaceClass; HID */
240 0x01, /* u8 if_bInterfaceSubClass; Boot */
241 0x01, /* u8 if_bInterfaceProtocol; Keyboard */
242 0x07, /* u8 if_iInterface; */
244 /* HID descriptor */
245 0x09, /* u8 bLength; */
246 USB_DT_HID, /* u8 bDescriptorType; */
247 0x11, 0x01, /* u16 HID_class */
248 0x00, /* u8 country_code */
249 0x01, /* u8 num_descriptors */
250 USB_DT_REPORT, /* u8 type; Report */
251 0x3f, 0x00, /* u16 len */
253 /* one endpoint (status change endpoint) */
254 0x07, /* u8 ep_bLength; */
255 USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; Endpoint */
256 USB_DIR_IN | 0x01, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
257 0x03, /* u8 ep_bmAttributes; Interrupt */
258 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
259 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
262 static const uint8_t qemu_mouse_hid_report_descriptor[] = {
263 0x05, 0x01, /* Usage Page (Generic Desktop) */
264 0x09, 0x02, /* Usage (Mouse) */
265 0xa1, 0x01, /* Collection (Application) */
266 0x09, 0x01, /* Usage (Pointer) */
267 0xa1, 0x00, /* Collection (Physical) */
268 0x05, 0x09, /* Usage Page (Button) */
269 0x19, 0x01, /* Usage Minimum (1) */
270 0x29, 0x03, /* Usage Maximum (3) */
271 0x15, 0x00, /* Logical Minimum (0) */
272 0x25, 0x01, /* Logical Maximum (1) */
273 0x95, 0x03, /* Report Count (3) */
274 0x75, 0x01, /* Report Size (1) */
275 0x81, 0x02, /* Input (Data, Variable, Absolute) */
276 0x95, 0x01, /* Report Count (1) */
277 0x75, 0x05, /* Report Size (5) */
278 0x81, 0x01, /* Input (Constant) */
279 0x05, 0x01, /* Usage Page (Generic Desktop) */
280 0x09, 0x30, /* Usage (X) */
281 0x09, 0x31, /* Usage (Y) */
282 0x09, 0x38, /* Usage (Wheel) */
283 0x15, 0x81, /* Logical Minimum (-0x7f) */
284 0x25, 0x7f, /* Logical Maximum (0x7f) */
285 0x75, 0x08, /* Report Size (8) */
286 0x95, 0x03, /* Report Count (3) */
287 0x81, 0x06, /* Input (Data, Variable, Relative) */
288 0xc0, /* End Collection */
289 0xc0, /* End Collection */
292 static const uint8_t qemu_tablet_hid_report_descriptor[] = {
293 0x05, 0x01, /* Usage Page (Generic Desktop) */
294 0x09, 0x01, /* Usage (Pointer) */
295 0xa1, 0x01, /* Collection (Application) */
296 0x09, 0x01, /* Usage (Pointer) */
297 0xa1, 0x00, /* Collection (Physical) */
298 0x05, 0x09, /* Usage Page (Button) */
299 0x19, 0x01, /* Usage Minimum (1) */
300 0x29, 0x03, /* Usage Maximum (3) */
301 0x15, 0x00, /* Logical Minimum (0) */
302 0x25, 0x01, /* Logical Maximum (1) */
303 0x95, 0x03, /* Report Count (3) */
304 0x75, 0x01, /* Report Size (1) */
305 0x81, 0x02, /* Input (Data, Variable, Absolute) */
306 0x95, 0x01, /* Report Count (1) */
307 0x75, 0x05, /* Report Size (5) */
308 0x81, 0x01, /* Input (Constant) */
309 0x05, 0x01, /* Usage Page (Generic Desktop) */
310 0x09, 0x30, /* Usage (X) */
311 0x09, 0x31, /* Usage (Y) */
312 0x15, 0x00, /* Logical Minimum (0) */
313 0x26, 0xff, 0x7f, /* Logical Maximum (0x7fff) */
314 0x35, 0x00, /* Physical Minimum (0) */
315 0x46, 0xff, 0x7f, /* Physical Maximum (0x7fff) */
316 0x75, 0x10, /* Report Size (16) */
317 0x95, 0x02, /* Report Count (2) */
318 0x81, 0x02, /* Input (Data, Variable, Absolute) */
319 0x05, 0x01, /* Usage Page (Generic Desktop) */
320 0x09, 0x38, /* Usage (Wheel) */
321 0x15, 0x81, /* Logical Minimum (-0x7f) */
322 0x25, 0x7f, /* Logical Maximum (0x7f) */
323 0x35, 0x00, /* Physical Minimum (same as logical) */
324 0x45, 0x00, /* Physical Maximum (same as logical) */
325 0x75, 0x08, /* Report Size (8) */
326 0x95, 0x01, /* Report Count (1) */
327 0x81, 0x06, /* Input (Data, Variable, Relative) */
328 0xc0, /* End Collection */
329 0xc0, /* End Collection */
332 static const uint8_t qemu_keyboard_hid_report_descriptor[] = {
333 0x05, 0x01, /* Usage Page (Generic Desktop) */
334 0x09, 0x06, /* Usage (Keyboard) */
335 0xa1, 0x01, /* Collection (Application) */
336 0x75, 0x01, /* Report Size (1) */
337 0x95, 0x08, /* Report Count (8) */
338 0x05, 0x07, /* Usage Page (Key Codes) */
339 0x19, 0xe0, /* Usage Minimum (224) */
340 0x29, 0xe7, /* Usage Maximum (231) */
341 0x15, 0x00, /* Logical Minimum (0) */
342 0x25, 0x01, /* Logical Maximum (1) */
343 0x81, 0x02, /* Input (Data, Variable, Absolute) */
344 0x95, 0x01, /* Report Count (1) */
345 0x75, 0x08, /* Report Size (8) */
346 0x81, 0x01, /* Input (Constant) */
347 0x95, 0x05, /* Report Count (5) */
348 0x75, 0x01, /* Report Size (1) */
349 0x05, 0x08, /* Usage Page (LEDs) */
350 0x19, 0x01, /* Usage Minimum (1) */
351 0x29, 0x05, /* Usage Maximum (5) */
352 0x91, 0x02, /* Output (Data, Variable, Absolute) */
353 0x95, 0x01, /* Report Count (1) */
354 0x75, 0x03, /* Report Size (3) */
355 0x91, 0x01, /* Output (Constant) */
356 0x95, 0x06, /* Report Count (6) */
357 0x75, 0x08, /* Report Size (8) */
358 0x15, 0x00, /* Logical Minimum (0) */
359 0x25, 0xff, /* Logical Maximum (255) */
360 0x05, 0x07, /* Usage Page (Key Codes) */
361 0x19, 0x00, /* Usage Minimum (0) */
362 0x29, 0xff, /* Usage Maximum (255) */
363 0x81, 0x00, /* Input (Data, Array) */
364 0xc0, /* End Collection */
367 #define USB_HID_USAGE_ERROR_ROLLOVER 0x01
368 #define USB_HID_USAGE_POSTFAIL 0x02
369 #define USB_HID_USAGE_ERROR_UNDEFINED 0x03
371 /* Indices are QEMU keycodes, values are from HID Usage Table. Indices
372 * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d. */
373 static const uint8_t usb_hid_usage_keys[0x100] = {
374 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
375 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
376 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
377 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
378 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
379 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
380 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
381 0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
382 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
383 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
384 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
385 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
386 0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
395 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
398 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
400 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
401 0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
402 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 0x00, 0x00,
403 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409 static void usb_hid_changed(USBHIDState *hs)
411 hs->changed = 1;
413 if (hs->datain)
414 hs->datain(hs->datain_opaque);
417 static void usb_mouse_event(void *opaque,
418 int dx1, int dy1, int dz1, int buttons_state)
420 USBHIDState *hs = opaque;
421 USBMouseState *s = &hs->ptr;
423 s->dx += dx1;
424 s->dy += dy1;
425 s->dz += dz1;
426 s->buttons_state = buttons_state;
428 usb_hid_changed(hs);
431 static void usb_tablet_event(void *opaque,
432 int x, int y, int dz, int buttons_state)
434 USBHIDState *hs = opaque;
435 USBMouseState *s = &hs->ptr;
437 s->x = x;
438 s->y = y;
439 s->dz += dz;
440 s->buttons_state = buttons_state;
442 usb_hid_changed(hs);
445 static void usb_keyboard_event(void *opaque, int keycode)
447 USBHIDState *hs = opaque;
448 USBKeyboardState *s = &hs->kbd;
449 uint8_t hid_code, key;
450 int i;
452 key = keycode & 0x7f;
453 hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))];
454 s->modifiers &= ~(1 << 8);
456 switch (hid_code) {
457 case 0x00:
458 return;
460 case 0xe0:
461 if (s->modifiers & (1 << 9)) {
462 s->modifiers ^= 3 << 8;
463 usb_hid_changed(hs);
464 return;
466 case 0xe1 ... 0xe7:
467 if (keycode & (1 << 7)) {
468 s->modifiers &= ~(1 << (hid_code & 0x0f));
469 usb_hid_changed(hs);
470 return;
472 case 0xe8 ... 0xef:
473 s->modifiers |= 1 << (hid_code & 0x0f);
474 usb_hid_changed(hs);
475 return;
478 if (keycode & (1 << 7)) {
479 for (i = s->keys - 1; i >= 0; i --)
480 if (s->key[i] == hid_code) {
481 s->key[i] = s->key[-- s->keys];
482 s->key[s->keys] = 0x00;
483 usb_hid_changed(hs);
484 break;
486 if (i < 0)
487 return;
488 } else {
489 for (i = s->keys - 1; i >= 0; i --)
490 if (s->key[i] == hid_code)
491 break;
492 if (i < 0) {
493 if (s->keys < sizeof(s->key))
494 s->key[s->keys ++] = hid_code;
495 } else
496 return;
499 usb_hid_changed(hs);
502 static inline int int_clamp(int val, int vmin, int vmax)
504 if (val < vmin)
505 return vmin;
506 else if (val > vmax)
507 return vmax;
508 else
509 return val;
512 static int usb_mouse_poll(USBHIDState *hs, uint8_t *buf, int len)
514 int dx, dy, dz, b, l;
515 USBMouseState *s = &hs->ptr;
517 if (!s->mouse_grabbed) {
518 qemu_activate_mouse_event_handler(s->eh_entry);
519 s->mouse_grabbed = 1;
522 dx = int_clamp(s->dx, -127, 127);
523 dy = int_clamp(s->dy, -127, 127);
524 dz = int_clamp(s->dz, -127, 127);
526 s->dx -= dx;
527 s->dy -= dy;
528 s->dz -= dz;
530 /* Appears we have to invert the wheel direction */
531 dz = 0 - dz;
533 b = 0;
534 if (s->buttons_state & MOUSE_EVENT_LBUTTON)
535 b |= 0x01;
536 if (s->buttons_state & MOUSE_EVENT_RBUTTON)
537 b |= 0x02;
538 if (s->buttons_state & MOUSE_EVENT_MBUTTON)
539 b |= 0x04;
541 l = 0;
542 if (len > l)
543 buf[l ++] = b;
544 if (len > l)
545 buf[l ++] = dx;
546 if (len > l)
547 buf[l ++] = dy;
548 if (len > l)
549 buf[l ++] = dz;
550 return l;
553 static int usb_tablet_poll(USBHIDState *hs, uint8_t *buf, int len)
555 int dz, b, l;
556 USBMouseState *s = &hs->ptr;
558 if (!s->mouse_grabbed) {
559 qemu_activate_mouse_event_handler(s->eh_entry);
560 s->mouse_grabbed = 1;
563 dz = int_clamp(s->dz, -127, 127);
564 s->dz -= dz;
566 /* Appears we have to invert the wheel direction */
567 dz = 0 - dz;
568 b = 0;
569 if (s->buttons_state & MOUSE_EVENT_LBUTTON)
570 b |= 0x01;
571 if (s->buttons_state & MOUSE_EVENT_RBUTTON)
572 b |= 0x02;
573 if (s->buttons_state & MOUSE_EVENT_MBUTTON)
574 b |= 0x04;
576 buf[0] = b;
577 buf[1] = s->x & 0xff;
578 buf[2] = s->x >> 8;
579 buf[3] = s->y & 0xff;
580 buf[4] = s->y >> 8;
581 buf[5] = dz;
582 l = 6;
584 return l;
587 static int usb_keyboard_poll(USBKeyboardState *s, uint8_t *buf, int len)
589 if (len < 2)
590 return 0;
592 buf[0] = s->modifiers & 0xff;
593 buf[1] = 0;
594 if (s->keys > 6)
595 memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
596 else
597 memcpy(buf + 2, s->key, MIN(8, len) - 2);
599 return MIN(8, len);
602 static int usb_keyboard_write(USBKeyboardState *s, uint8_t *buf, int len)
604 if (len > 0) {
605 int ledstate = 0;
606 /* 0x01: Num Lock LED
607 * 0x02: Caps Lock LED
608 * 0x04: Scroll Lock LED
609 * 0x08: Compose LED
610 * 0x10: Kana LED */
611 s->leds = buf[0];
612 if (s->leds & 0x04)
613 ledstate |= QEMU_SCROLL_LOCK_LED;
614 if (s->leds & 0x01)
615 ledstate |= QEMU_NUM_LOCK_LED;
616 if (s->leds & 0x02)
617 ledstate |= QEMU_CAPS_LOCK_LED;
618 kbd_put_ledstate(ledstate);
620 return 0;
623 static void usb_mouse_handle_reset(USBDevice *dev)
625 USBHIDState *s = (USBHIDState *)dev;
627 s->ptr.dx = 0;
628 s->ptr.dy = 0;
629 s->ptr.dz = 0;
630 s->ptr.x = 0;
631 s->ptr.y = 0;
632 s->ptr.buttons_state = 0;
633 s->protocol = 1;
636 static void usb_keyboard_handle_reset(USBDevice *dev)
638 USBHIDState *s = (USBHIDState *)dev;
640 qemu_add_kbd_event_handler(usb_keyboard_event, s);
641 s->protocol = 1;
644 static void usb_hid_set_next_idle(USBHIDState *s, int64_t curtime)
646 s->next_idle_clock = curtime + (get_ticks_per_sec() * s->idle * 4) / 1000;
649 static int usb_hid_handle_control(USBDevice *dev, int request, int value,
650 int index, int length, uint8_t *data)
652 USBHIDState *s = (USBHIDState *)dev;
653 int ret = 0;
655 switch(request) {
656 case DeviceRequest | USB_REQ_GET_STATUS:
657 data[0] = (1 << USB_DEVICE_SELF_POWERED) |
658 (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
659 data[1] = 0x00;
660 ret = 2;
661 break;
662 case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
663 if (value == USB_DEVICE_REMOTE_WAKEUP) {
664 dev->remote_wakeup = 0;
665 } else {
666 goto fail;
668 ret = 0;
669 break;
670 case DeviceOutRequest | USB_REQ_SET_FEATURE:
671 if (value == USB_DEVICE_REMOTE_WAKEUP) {
672 dev->remote_wakeup = 1;
673 } else {
674 goto fail;
676 ret = 0;
677 break;
678 case DeviceOutRequest | USB_REQ_SET_ADDRESS:
679 dev->addr = value;
680 ret = 0;
681 break;
682 case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
683 switch(value >> 8) {
684 case USB_DT_DEVICE:
685 memcpy(data, qemu_mouse_dev_descriptor,
686 sizeof(qemu_mouse_dev_descriptor));
687 ret = sizeof(qemu_mouse_dev_descriptor);
688 break;
689 case USB_DT_CONFIG:
690 if (s->kind == USB_MOUSE) {
691 memcpy(data, qemu_mouse_config_descriptor,
692 sizeof(qemu_mouse_config_descriptor));
693 ret = sizeof(qemu_mouse_config_descriptor);
694 } else if (s->kind == USB_TABLET) {
695 memcpy(data, qemu_tablet_config_descriptor,
696 sizeof(qemu_tablet_config_descriptor));
697 ret = sizeof(qemu_tablet_config_descriptor);
698 } else if (s->kind == USB_KEYBOARD) {
699 memcpy(data, qemu_keyboard_config_descriptor,
700 sizeof(qemu_keyboard_config_descriptor));
701 ret = sizeof(qemu_keyboard_config_descriptor);
703 break;
704 case USB_DT_STRING:
705 switch(value & 0xff) {
706 case 0:
707 /* language ids */
708 data[0] = 4;
709 data[1] = 3;
710 data[2] = 0x09;
711 data[3] = 0x04;
712 ret = 4;
713 break;
714 case 1:
715 /* serial number */
716 ret = set_usb_string(data, "1");
717 break;
718 case 2:
719 /* product description */
720 ret = set_usb_string(data, s->dev.product_desc);
721 break;
722 case 3:
723 /* vendor description */
724 ret = set_usb_string(data, "QEMU " QEMU_VERSION);
725 break;
726 case 4:
727 ret = set_usb_string(data, "HID Mouse");
728 break;
729 case 5:
730 ret = set_usb_string(data, "HID Tablet");
731 break;
732 case 6:
733 ret = set_usb_string(data, "HID Keyboard");
734 break;
735 case 7:
736 ret = set_usb_string(data, "Endpoint1 Interrupt Pipe");
737 break;
738 default:
739 goto fail;
741 break;
742 default:
743 goto fail;
745 break;
746 case DeviceRequest | USB_REQ_GET_CONFIGURATION:
747 data[0] = 1;
748 ret = 1;
749 break;
750 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
751 ret = 0;
752 break;
753 case DeviceRequest | USB_REQ_GET_INTERFACE:
754 data[0] = 0;
755 ret = 1;
756 break;
757 case DeviceOutRequest | USB_REQ_SET_INTERFACE:
758 ret = 0;
759 break;
760 /* hid specific requests */
761 case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
762 switch(value >> 8) {
763 case 0x22:
764 if (s->kind == USB_MOUSE) {
765 memcpy(data, qemu_mouse_hid_report_descriptor,
766 sizeof(qemu_mouse_hid_report_descriptor));
767 ret = sizeof(qemu_mouse_hid_report_descriptor);
768 } else if (s->kind == USB_TABLET) {
769 memcpy(data, qemu_tablet_hid_report_descriptor,
770 sizeof(qemu_tablet_hid_report_descriptor));
771 ret = sizeof(qemu_tablet_hid_report_descriptor);
772 } else if (s->kind == USB_KEYBOARD) {
773 memcpy(data, qemu_keyboard_hid_report_descriptor,
774 sizeof(qemu_keyboard_hid_report_descriptor));
775 ret = sizeof(qemu_keyboard_hid_report_descriptor);
777 break;
778 default:
779 goto fail;
781 break;
782 case GET_REPORT:
783 if (s->kind == USB_MOUSE)
784 ret = usb_mouse_poll(s, data, length);
785 else if (s->kind == USB_TABLET)
786 ret = usb_tablet_poll(s, data, length);
787 else if (s->kind == USB_KEYBOARD)
788 ret = usb_keyboard_poll(&s->kbd, data, length);
789 break;
790 case SET_REPORT:
791 if (s->kind == USB_KEYBOARD)
792 ret = usb_keyboard_write(&s->kbd, data, length);
793 else
794 goto fail;
795 break;
796 case GET_PROTOCOL:
797 if (s->kind != USB_KEYBOARD)
798 goto fail;
799 ret = 1;
800 data[0] = s->protocol;
801 break;
802 case SET_PROTOCOL:
803 if (s->kind != USB_KEYBOARD)
804 goto fail;
805 ret = 0;
806 s->protocol = value;
807 break;
808 case GET_IDLE:
809 ret = 1;
810 data[0] = s->idle;
811 break;
812 case SET_IDLE:
813 s->idle = (uint8_t) (value >> 8);
814 usb_hid_set_next_idle(s, qemu_get_clock(vm_clock));
815 ret = 0;
816 break;
817 default:
818 fail:
819 ret = USB_RET_STALL;
820 break;
822 return ret;
825 static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
827 USBHIDState *s = (USBHIDState *)dev;
828 int ret = 0;
830 switch(p->pid) {
831 case USB_TOKEN_IN:
832 if (p->devep == 1) {
833 int64_t curtime = qemu_get_clock(vm_clock);
834 if (!s->changed && (!s->idle || s->next_idle_clock - curtime > 0))
835 return USB_RET_NAK;
836 usb_hid_set_next_idle(s, curtime);
837 s->changed = 0;
838 if (s->kind == USB_MOUSE)
839 ret = usb_mouse_poll(s, p->data, p->len);
840 else if (s->kind == USB_TABLET)
841 ret = usb_tablet_poll(s, p->data, p->len);
842 else if (s->kind == USB_KEYBOARD)
843 ret = usb_keyboard_poll(&s->kbd, p->data, p->len);
844 } else {
845 goto fail;
847 break;
848 case USB_TOKEN_OUT:
849 default:
850 fail:
851 ret = USB_RET_STALL;
852 break;
854 return ret;
857 static void usb_hid_handle_destroy(USBDevice *dev)
859 USBHIDState *s = (USBHIDState *)dev;
861 switch(s->kind) {
862 case USB_KEYBOARD:
863 qemu_remove_kbd_event_handler();
864 break;
865 default:
866 qemu_remove_mouse_event_handler(s->ptr.eh_entry);
870 static int usb_hid_initfn(USBDevice *dev, int kind)
872 USBHIDState *s = DO_UPCAST(USBHIDState, dev, dev);
873 s->dev.speed = USB_SPEED_FULL;
874 s->kind = kind;
876 if (s->kind == USB_MOUSE) {
877 s->ptr.eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, s,
878 0, "QEMU USB Mouse");
879 } else if (s->kind == USB_TABLET) {
880 s->ptr.eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, s,
881 1, "QEMU USB Tablet");
884 /* Force poll routine to be run and grab input the first time. */
885 s->changed = 1;
886 return 0;
889 static int usb_tablet_initfn(USBDevice *dev)
891 return usb_hid_initfn(dev, USB_TABLET);
894 static int usb_mouse_initfn(USBDevice *dev)
896 return usb_hid_initfn(dev, USB_MOUSE);
899 static int usb_keyboard_initfn(USBDevice *dev)
901 return usb_hid_initfn(dev, USB_KEYBOARD);
904 void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *))
906 USBHIDState *s = (USBHIDState *)dev;
908 s->datain_opaque = opaque;
909 s->datain = datain;
912 static struct USBDeviceInfo hid_info[] = {
914 .product_desc = "QEMU USB Tablet",
915 .qdev.name = "usb-tablet",
916 .usbdevice_name = "tablet",
917 .qdev.size = sizeof(USBHIDState),
918 .init = usb_tablet_initfn,
919 .handle_packet = usb_generic_handle_packet,
920 .handle_reset = usb_mouse_handle_reset,
921 .handle_control = usb_hid_handle_control,
922 .handle_data = usb_hid_handle_data,
923 .handle_destroy = usb_hid_handle_destroy,
925 .product_desc = "QEMU USB Mouse",
926 .qdev.name = "usb-mouse",
927 .usbdevice_name = "mouse",
928 .qdev.size = sizeof(USBHIDState),
929 .init = usb_mouse_initfn,
930 .handle_packet = usb_generic_handle_packet,
931 .handle_reset = usb_mouse_handle_reset,
932 .handle_control = usb_hid_handle_control,
933 .handle_data = usb_hid_handle_data,
934 .handle_destroy = usb_hid_handle_destroy,
936 .product_desc = "QEMU USB Keyboard",
937 .qdev.name = "usb-kbd",
938 .usbdevice_name = "keyboard",
939 .qdev.size = sizeof(USBHIDState),
940 .init = usb_keyboard_initfn,
941 .handle_packet = usb_generic_handle_packet,
942 .handle_reset = usb_keyboard_handle_reset,
943 .handle_control = usb_hid_handle_control,
944 .handle_data = usb_hid_handle_data,
945 .handle_destroy = usb_hid_handle_destroy,
947 /* end of list */
951 static void usb_hid_register_devices(void)
953 usb_qdev_register_many(hid_info);
955 device_init(usb_hid_register_devices)