]> git.proxmox.com Git - qemu.git/blob - hw/usb-hid.c
find -type f | xargs sed -i 's/[\t ]*$//g' # Yes, again. Note the star in the regex.
[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 "vl.h"
26
27 /* HID interface requests */
28 #define GET_REPORT 0xa101
29 #define GET_IDLE 0xa102
30 #define GET_PROTOCOL 0xa103
31 #define SET_REPORT 0x2109
32 #define SET_IDLE 0x210a
33 #define SET_PROTOCOL 0x210b
34
35 /* HID descriptor types */
36 #define USB_DT_HID 0x21
37 #define USB_DT_REPORT 0x22
38 #define USB_DT_PHY 0x23
39
40 #define USB_MOUSE 1
41 #define USB_TABLET 2
42 #define USB_KEYBOARD 3
43
44 typedef struct USBMouseState {
45 int dx, dy, dz, buttons_state;
46 int x, y;
47 int mouse_grabbed;
48 QEMUPutMouseEntry *eh_entry;
49 } USBMouseState;
50
51 typedef struct USBKeyboardState {
52 uint16_t modifiers;
53 uint8_t leds;
54 uint8_t key[16];
55 int keys;
56 } USBKeyboardState;
57
58 typedef struct USBHIDState {
59 USBDevice dev;
60 union {
61 USBMouseState ptr;
62 USBKeyboardState kbd;
63 };
64 int kind;
65 int protocol;
66 int idle;
67 int changed;
68 } USBHIDState;
69
70 /* mostly the same values as the Bochs USB Mouse device */
71 static const uint8_t qemu_mouse_dev_descriptor[] = {
72 0x12, /* u8 bLength; */
73 0x01, /* u8 bDescriptorType; Device */
74 0x00, 0x01, /* u16 bcdUSB; v1.0 */
75
76 0x00, /* u8 bDeviceClass; */
77 0x00, /* u8 bDeviceSubClass; */
78 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
79 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
80
81 0x27, 0x06, /* u16 idVendor; */
82 0x01, 0x00, /* u16 idProduct; */
83 0x00, 0x00, /* u16 bcdDevice */
84
85 0x03, /* u8 iManufacturer; */
86 0x02, /* u8 iProduct; */
87 0x01, /* u8 iSerialNumber; */
88 0x01 /* u8 bNumConfigurations; */
89 };
90
91 static const uint8_t qemu_mouse_config_descriptor[] = {
92 /* one configuration */
93 0x09, /* u8 bLength; */
94 0x02, /* u8 bDescriptorType; Configuration */
95 0x22, 0x00, /* u16 wTotalLength; */
96 0x01, /* u8 bNumInterfaces; (1) */
97 0x01, /* u8 bConfigurationValue; */
98 0x04, /* u8 iConfiguration; */
99 0xa0, /* u8 bmAttributes;
100 Bit 7: must be set,
101 6: Self-powered,
102 5: Remote wakeup,
103 4..0: resvd */
104 50, /* u8 MaxPower; */
105
106 /* USB 1.1:
107 * USB 2.0, single TT organization (mandatory):
108 * one interface, protocol 0
109 *
110 * USB 2.0, multiple TT organization (optional):
111 * two interfaces, protocols 1 (like single TT)
112 * and 2 (multiple TT mode) ... config is
113 * sometimes settable
114 * NOT IMPLEMENTED
115 */
116
117 /* one interface */
118 0x09, /* u8 if_bLength; */
119 0x04, /* u8 if_bDescriptorType; Interface */
120 0x00, /* u8 if_bInterfaceNumber; */
121 0x00, /* u8 if_bAlternateSetting; */
122 0x01, /* u8 if_bNumEndpoints; */
123 0x03, /* u8 if_bInterfaceClass; */
124 0x01, /* u8 if_bInterfaceSubClass; */
125 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
126 0x07, /* u8 if_iInterface; */
127
128 /* HID descriptor */
129 0x09, /* u8 bLength; */
130 0x21, /* u8 bDescriptorType; */
131 0x01, 0x00, /* u16 HID_class */
132 0x00, /* u8 country_code */
133 0x01, /* u8 num_descriptors */
134 0x22, /* u8 type; Report */
135 50, 0, /* u16 len */
136
137 /* one endpoint (status change endpoint) */
138 0x07, /* u8 ep_bLength; */
139 0x05, /* u8 ep_bDescriptorType; Endpoint */
140 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
141 0x03, /* u8 ep_bmAttributes; Interrupt */
142 0x03, 0x00, /* u16 ep_wMaxPacketSize; */
143 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
144 };
145
146 static const uint8_t qemu_tablet_config_descriptor[] = {
147 /* one configuration */
148 0x09, /* u8 bLength; */
149 0x02, /* u8 bDescriptorType; Configuration */
150 0x22, 0x00, /* u16 wTotalLength; */
151 0x01, /* u8 bNumInterfaces; (1) */
152 0x01, /* u8 bConfigurationValue; */
153 0x05, /* u8 iConfiguration; */
154 0xa0, /* u8 bmAttributes;
155 Bit 7: must be set,
156 6: Self-powered,
157 5: Remote wakeup,
158 4..0: resvd */
159 50, /* u8 MaxPower; */
160
161 /* USB 1.1:
162 * USB 2.0, single TT organization (mandatory):
163 * one interface, protocol 0
164 *
165 * USB 2.0, multiple TT organization (optional):
166 * two interfaces, protocols 1 (like single TT)
167 * and 2 (multiple TT mode) ... config is
168 * sometimes settable
169 * NOT IMPLEMENTED
170 */
171
172 /* one interface */
173 0x09, /* u8 if_bLength; */
174 0x04, /* u8 if_bDescriptorType; Interface */
175 0x00, /* u8 if_bInterfaceNumber; */
176 0x00, /* u8 if_bAlternateSetting; */
177 0x01, /* u8 if_bNumEndpoints; */
178 0x03, /* u8 if_bInterfaceClass; */
179 0x01, /* u8 if_bInterfaceSubClass; */
180 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
181 0x07, /* u8 if_iInterface; */
182
183 /* HID descriptor */
184 0x09, /* u8 bLength; */
185 0x21, /* u8 bDescriptorType; */
186 0x01, 0x00, /* u16 HID_class */
187 0x00, /* u8 country_code */
188 0x01, /* u8 num_descriptors */
189 0x22, /* u8 type; Report */
190 74, 0, /* u16 len */
191
192 /* one endpoint (status change endpoint) */
193 0x07, /* u8 ep_bLength; */
194 0x05, /* u8 ep_bDescriptorType; Endpoint */
195 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
196 0x03, /* u8 ep_bmAttributes; Interrupt */
197 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
198 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
199 };
200
201 static const uint8_t qemu_keyboard_config_descriptor[] = {
202 /* one configuration */
203 0x09, /* u8 bLength; */
204 USB_DT_CONFIG, /* u8 bDescriptorType; Configuration */
205 0x22, 0x00, /* u16 wTotalLength; */
206 0x01, /* u8 bNumInterfaces; (1) */
207 0x01, /* u8 bConfigurationValue; */
208 0x06, /* u8 iConfiguration; */
209 0xa0, /* u8 bmAttributes;
210 Bit 7: must be set,
211 6: Self-powered,
212 5: Remote wakeup,
213 4..0: resvd */
214 0x32, /* u8 MaxPower; */
215
216 /* USB 1.1:
217 * USB 2.0, single TT organization (mandatory):
218 * one interface, protocol 0
219 *
220 * USB 2.0, multiple TT organization (optional):
221 * two interfaces, protocols 1 (like single TT)
222 * and 2 (multiple TT mode) ... config is
223 * sometimes settable
224 * NOT IMPLEMENTED
225 */
226
227 /* one interface */
228 0x09, /* u8 if_bLength; */
229 USB_DT_INTERFACE, /* u8 if_bDescriptorType; Interface */
230 0x00, /* u8 if_bInterfaceNumber; */
231 0x00, /* u8 if_bAlternateSetting; */
232 0x01, /* u8 if_bNumEndpoints; */
233 0x03, /* u8 if_bInterfaceClass; HID */
234 0x01, /* u8 if_bInterfaceSubClass; Boot */
235 0x01, /* u8 if_bInterfaceProtocol; Keyboard */
236 0x07, /* u8 if_iInterface; */
237
238 /* HID descriptor */
239 0x09, /* u8 bLength; */
240 USB_DT_HID, /* u8 bDescriptorType; */
241 0x11, 0x01, /* u16 HID_class */
242 0x00, /* u8 country_code */
243 0x01, /* u8 num_descriptors */
244 USB_DT_REPORT, /* u8 type; Report */
245 0x3f, 0x00, /* u16 len */
246
247 /* one endpoint (status change endpoint) */
248 0x07, /* u8 ep_bLength; */
249 USB_DT_ENDPOINT, /* u8 ep_bDescriptorType; Endpoint */
250 USB_DIR_IN | 0x01, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
251 0x03, /* u8 ep_bmAttributes; Interrupt */
252 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
253 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
254 };
255
256 static const uint8_t qemu_mouse_hid_report_descriptor[] = {
257 0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01,
258 0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03,
259 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01,
260 0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x01,
261 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81,
262 0x25, 0x7F, 0x75, 0x08, 0x95, 0x02, 0x81, 0x06,
263 0xC0, 0xC0,
264 };
265
266 static const uint8_t qemu_tablet_hid_report_descriptor[] = {
267 0x05, 0x01, /* Usage Page Generic Desktop */
268 0x09, 0x01, /* Usage Mouse */
269 0xA1, 0x01, /* Collection Application */
270 0x09, 0x01, /* Usage Pointer */
271 0xA1, 0x00, /* Collection Physical */
272 0x05, 0x09, /* Usage Page Button */
273 0x19, 0x01, /* Usage Minimum Button 1 */
274 0x29, 0x03, /* Usage Maximum Button 3 */
275 0x15, 0x00, /* Logical Minimum 0 */
276 0x25, 0x01, /* Logical Maximum 1 */
277 0x95, 0x03, /* Report Count 3 */
278 0x75, 0x01, /* Report Size 1 */
279 0x81, 0x02, /* Input (Data, Var, Abs) */
280 0x95, 0x01, /* Report Count 1 */
281 0x75, 0x05, /* Report Size 5 */
282 0x81, 0x01, /* Input (Cnst, Var, Abs) */
283 0x05, 0x01, /* Usage Page Generic Desktop */
284 0x09, 0x30, /* Usage X */
285 0x09, 0x31, /* Usage Y */
286 0x15, 0x00, /* Logical Minimum 0 */
287 0x26, 0xFF, 0x7F, /* Logical Maximum 0x7fff */
288 0x35, 0x00, /* Physical Minimum 0 */
289 0x46, 0xFE, 0x7F, /* Physical Maximum 0x7fff */
290 0x75, 0x10, /* Report Size 16 */
291 0x95, 0x02, /* Report Count 2 */
292 0x81, 0x02, /* Input (Data, Var, Abs) */
293 0x05, 0x01, /* Usage Page Generic Desktop */
294 0x09, 0x38, /* Usage Wheel */
295 0x15, 0x81, /* Logical Minimum -127 */
296 0x25, 0x7F, /* Logical Maximum 127 */
297 0x35, 0x00, /* Physical Minimum 0 (same as logical) */
298 0x45, 0x00, /* Physical Maximum 0 (same as logical) */
299 0x75, 0x08, /* Report Size 8 */
300 0x95, 0x01, /* Report Count 1 */
301 0x81, 0x02, /* Input (Data, Var, Rel) */
302 0xC0, /* End Collection */
303 0xC0, /* End Collection */
304 };
305
306 static const uint8_t qemu_keyboard_hid_report_descriptor[] = {
307 0x05, 0x01, /* Usage Page (Generic Desktop) */
308 0x09, 0x06, /* Usage (Keyboard) */
309 0xa1, 0x01, /* Collection (Application) */
310 0x75, 0x01, /* Report Size (1) */
311 0x95, 0x08, /* Report Count (8) */
312 0x05, 0x07, /* Usage Page (Key Codes) */
313 0x19, 0xe0, /* Usage Minimum (224) */
314 0x29, 0xe7, /* Usage Maximum (231) */
315 0x15, 0x00, /* Logical Minimum (0) */
316 0x25, 0x01, /* Logical Maximum (1) */
317 0x81, 0x02, /* Input (Data, Variable, Absolute) */
318 0x95, 0x01, /* Report Count (1) */
319 0x75, 0x08, /* Report Size (8) */
320 0x81, 0x01, /* Input (Constant) */
321 0x95, 0x05, /* Report Count (5) */
322 0x75, 0x01, /* Report Size (1) */
323 0x05, 0x08, /* Usage Page (LEDs) */
324 0x19, 0x01, /* Usage Minimum (1) */
325 0x29, 0x05, /* Usage Maximum (5) */
326 0x91, 0x02, /* Output (Data, Variable, Absolute) */
327 0x95, 0x01, /* Report Count (1) */
328 0x75, 0x03, /* Report Size (3) */
329 0x91, 0x01, /* Output (Constant) */
330 0x95, 0x06, /* Report Count (6) */
331 0x75, 0x08, /* Report Size (8) */
332 0x15, 0x00, /* Logical Minimum (0) */
333 0x25, 0xff, /* Logical Maximum (255) */
334 0x05, 0x07, /* Usage Page (Key Codes) */
335 0x19, 0x00, /* Usage Minimum (0) */
336 0x29, 0xff, /* Usage Maximum (255) */
337 0x81, 0x00, /* Input (Data, Array) */
338 0xc0, /* End Collection */
339 };
340
341 #define USB_HID_USAGE_ERROR_ROLLOVER 0x01
342 #define USB_HID_USAGE_POSTFAIL 0x02
343 #define USB_HID_USAGE_ERROR_UNDEFINED 0x03
344
345 /* Indices are QEMU keycodes, values are from HID Usage Table. Indices
346 * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d. */
347 static const uint8_t usb_hid_usage_keys[0x100] = {
348 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
349 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
350 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
351 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
352 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
353 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
354 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
355 0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
356 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
357 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
358 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
359 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
360 0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
361 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
364
365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
366 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
372 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
374 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
375 0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381 };
382
383 static void usb_mouse_event(void *opaque,
384 int dx1, int dy1, int dz1, int buttons_state)
385 {
386 USBHIDState *hs = opaque;
387 USBMouseState *s = &hs->ptr;
388
389 s->dx += dx1;
390 s->dy += dy1;
391 s->dz += dz1;
392 s->buttons_state = buttons_state;
393 hs->changed = 1;
394 }
395
396 static void usb_tablet_event(void *opaque,
397 int x, int y, int dz, int buttons_state)
398 {
399 USBHIDState *hs = opaque;
400 USBMouseState *s = &hs->ptr;
401
402 s->x = x;
403 s->y = y;
404 s->dz += dz;
405 s->buttons_state = buttons_state;
406 hs->changed = 1;
407 }
408
409 static void usb_keyboard_event(void *opaque, int keycode)
410 {
411 USBHIDState *hs = opaque;
412 USBKeyboardState *s = &hs->kbd;
413 uint8_t hid_code, key;
414 int i;
415
416 key = keycode & 0x7f;
417 hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))];
418 s->modifiers &= ~(1 << 8);
419
420 hs->changed = 1;
421
422 switch (hid_code) {
423 case 0x00:
424 return;
425
426 case 0xe0:
427 if (s->modifiers & (1 << 9)) {
428 s->modifiers ^= 3 << 8;
429 return;
430 }
431 case 0xe1 ... 0xe7:
432 if (keycode & (1 << 7)) {
433 s->modifiers &= ~(1 << (hid_code & 0x0f));
434 return;
435 }
436 case 0xe8 ... 0xef:
437 s->modifiers |= 1 << (hid_code & 0x0f);
438 return;
439 }
440
441 if (keycode & (1 << 7)) {
442 for (i = s->keys - 1; i >= 0; i --)
443 if (s->key[i] == hid_code) {
444 s->key[i] = s->key[-- s->keys];
445 s->key[s->keys] = 0x00;
446 return;
447 }
448 } else {
449 for (i = s->keys - 1; i >= 0; i --)
450 if (s->key[i] == hid_code)
451 return;
452 if (s->keys < sizeof(s->key))
453 s->key[s->keys ++] = hid_code;
454 }
455 }
456
457 static inline int int_clamp(int val, int vmin, int vmax)
458 {
459 if (val < vmin)
460 return vmin;
461 else if (val > vmax)
462 return vmax;
463 else
464 return val;
465 }
466
467 static int usb_mouse_poll(USBHIDState *hs, uint8_t *buf, int len)
468 {
469 int dx, dy, dz, b, l;
470 USBMouseState *s = &hs->ptr;
471
472 if (!s->mouse_grabbed) {
473 s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, hs,
474 0, "QEMU USB Mouse");
475 s->mouse_grabbed = 1;
476 }
477
478 dx = int_clamp(s->dx, -128, 127);
479 dy = int_clamp(s->dy, -128, 127);
480 dz = int_clamp(s->dz, -128, 127);
481
482 s->dx -= dx;
483 s->dy -= dy;
484 s->dz -= dz;
485
486 b = 0;
487 if (s->buttons_state & MOUSE_EVENT_LBUTTON)
488 b |= 0x01;
489 if (s->buttons_state & MOUSE_EVENT_RBUTTON)
490 b |= 0x02;
491 if (s->buttons_state & MOUSE_EVENT_MBUTTON)
492 b |= 0x04;
493
494 buf[0] = b;
495 buf[1] = dx;
496 buf[2] = dy;
497 l = 3;
498 if (len >= 4) {
499 buf[3] = dz;
500 l = 4;
501 }
502 return l;
503 }
504
505 static int usb_tablet_poll(USBHIDState *hs, uint8_t *buf, int len)
506 {
507 int dz, b, l;
508 USBMouseState *s = &hs->ptr;
509
510 if (!s->mouse_grabbed) {
511 s->eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, hs,
512 1, "QEMU USB Tablet");
513 s->mouse_grabbed = 1;
514 }
515
516 dz = int_clamp(s->dz, -128, 127);
517 s->dz -= dz;
518
519 /* Appears we have to invert the wheel direction */
520 dz = 0 - dz;
521 b = 0;
522 if (s->buttons_state & MOUSE_EVENT_LBUTTON)
523 b |= 0x01;
524 if (s->buttons_state & MOUSE_EVENT_RBUTTON)
525 b |= 0x02;
526 if (s->buttons_state & MOUSE_EVENT_MBUTTON)
527 b |= 0x04;
528
529 buf[0] = b;
530 buf[1] = s->x & 0xff;
531 buf[2] = s->x >> 8;
532 buf[3] = s->y & 0xff;
533 buf[4] = s->y >> 8;
534 buf[5] = dz;
535 l = 6;
536
537 return l;
538 }
539
540 static int usb_keyboard_poll(USBKeyboardState *s, uint8_t *buf, int len)
541 {
542 if (len < 2)
543 return 0;
544
545 buf[0] = s->modifiers & 0xff;
546 buf[1] = 0;
547 if (s->keys > 6)
548 memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
549 else
550 memcpy(buf + 2, s->key, MIN(8, len) - 2);
551
552 return MIN(8, len);
553 }
554
555 static int usb_keyboard_write(USBKeyboardState *s, uint8_t *buf, int len)
556 {
557 if (len > 0) {
558 /* 0x01: Num Lock LED
559 * 0x02: Caps Lock LED
560 * 0x04: Scroll Lock LED
561 * 0x08: Compose LED
562 * 0x10: Kana LED */
563 s->leds = buf[0];
564 }
565 return 0;
566 }
567
568 static void usb_mouse_handle_reset(USBDevice *dev)
569 {
570 USBHIDState *s = (USBHIDState *)dev;
571
572 s->ptr.dx = 0;
573 s->ptr.dy = 0;
574 s->ptr.dz = 0;
575 s->ptr.x = 0;
576 s->ptr.y = 0;
577 s->ptr.buttons_state = 0;
578 s->protocol = 1;
579 }
580
581 static void usb_keyboard_handle_reset(USBDevice *dev)
582 {
583 USBHIDState *s = (USBHIDState *)dev;
584
585 qemu_add_kbd_event_handler(usb_keyboard_event, &s->kbd);
586 s->protocol = 1;
587 }
588
589 static int usb_hid_handle_control(USBDevice *dev, int request, int value,
590 int index, int length, uint8_t *data)
591 {
592 USBHIDState *s = (USBHIDState *)dev;
593 int ret = 0;
594
595 switch(request) {
596 case DeviceRequest | USB_REQ_GET_STATUS:
597 data[0] = (1 << USB_DEVICE_SELF_POWERED) |
598 (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
599 data[1] = 0x00;
600 ret = 2;
601 break;
602 case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
603 if (value == USB_DEVICE_REMOTE_WAKEUP) {
604 dev->remote_wakeup = 0;
605 } else {
606 goto fail;
607 }
608 ret = 0;
609 break;
610 case DeviceOutRequest | USB_REQ_SET_FEATURE:
611 if (value == USB_DEVICE_REMOTE_WAKEUP) {
612 dev->remote_wakeup = 1;
613 } else {
614 goto fail;
615 }
616 ret = 0;
617 break;
618 case DeviceOutRequest | USB_REQ_SET_ADDRESS:
619 dev->addr = value;
620 ret = 0;
621 break;
622 case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
623 switch(value >> 8) {
624 case USB_DT_DEVICE:
625 memcpy(data, qemu_mouse_dev_descriptor,
626 sizeof(qemu_mouse_dev_descriptor));
627 ret = sizeof(qemu_mouse_dev_descriptor);
628 break;
629 case USB_DT_CONFIG:
630 if (s->kind == USB_MOUSE) {
631 memcpy(data, qemu_mouse_config_descriptor,
632 sizeof(qemu_mouse_config_descriptor));
633 ret = sizeof(qemu_mouse_config_descriptor);
634 } else if (s->kind == USB_TABLET) {
635 memcpy(data, qemu_tablet_config_descriptor,
636 sizeof(qemu_tablet_config_descriptor));
637 ret = sizeof(qemu_tablet_config_descriptor);
638 } else if (s->kind == USB_KEYBOARD) {
639 memcpy(data, qemu_keyboard_config_descriptor,
640 sizeof(qemu_keyboard_config_descriptor));
641 ret = sizeof(qemu_keyboard_config_descriptor);
642 }
643 break;
644 case USB_DT_STRING:
645 switch(value & 0xff) {
646 case 0:
647 /* language ids */
648 data[0] = 4;
649 data[1] = 3;
650 data[2] = 0x09;
651 data[3] = 0x04;
652 ret = 4;
653 break;
654 case 1:
655 /* serial number */
656 ret = set_usb_string(data, "1");
657 break;
658 case 2:
659 /* product description */
660 ret = set_usb_string(data, s->dev.devname);
661 break;
662 case 3:
663 /* vendor description */
664 ret = set_usb_string(data, "QEMU " QEMU_VERSION);
665 break;
666 case 4:
667 ret = set_usb_string(data, "HID Mouse");
668 break;
669 case 5:
670 ret = set_usb_string(data, "HID Tablet");
671 break;
672 case 6:
673 ret = set_usb_string(data, "HID Keyboard");
674 break;
675 case 7:
676 ret = set_usb_string(data, "Endpoint1 Interrupt Pipe");
677 break;
678 default:
679 goto fail;
680 }
681 break;
682 default:
683 goto fail;
684 }
685 break;
686 case DeviceRequest | USB_REQ_GET_CONFIGURATION:
687 data[0] = 1;
688 ret = 1;
689 break;
690 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
691 ret = 0;
692 break;
693 case DeviceRequest | USB_REQ_GET_INTERFACE:
694 data[0] = 0;
695 ret = 1;
696 break;
697 case DeviceOutRequest | USB_REQ_SET_INTERFACE:
698 ret = 0;
699 break;
700 /* hid specific requests */
701 case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
702 switch(value >> 8) {
703 case 0x22:
704 if (s->kind == USB_MOUSE) {
705 memcpy(data, qemu_mouse_hid_report_descriptor,
706 sizeof(qemu_mouse_hid_report_descriptor));
707 ret = sizeof(qemu_mouse_hid_report_descriptor);
708 } else if (s->kind == USB_TABLET) {
709 memcpy(data, qemu_tablet_hid_report_descriptor,
710 sizeof(qemu_tablet_hid_report_descriptor));
711 ret = sizeof(qemu_tablet_hid_report_descriptor);
712 } else if (s->kind == USB_KEYBOARD) {
713 memcpy(data, qemu_keyboard_hid_report_descriptor,
714 sizeof(qemu_keyboard_hid_report_descriptor));
715 ret = sizeof(qemu_keyboard_hid_report_descriptor);
716 }
717 break;
718 default:
719 goto fail;
720 }
721 break;
722 case GET_REPORT:
723 if (s->kind == USB_MOUSE)
724 ret = usb_mouse_poll(s, data, length);
725 else if (s->kind == USB_TABLET)
726 ret = usb_tablet_poll(s, data, length);
727 else if (s->kind == USB_KEYBOARD)
728 ret = usb_keyboard_poll(&s->kbd, data, length);
729 break;
730 case SET_REPORT:
731 if (s->kind == USB_KEYBOARD)
732 ret = usb_keyboard_write(&s->kbd, data, length);
733 else
734 goto fail;
735 break;
736 case GET_PROTOCOL:
737 if (s->kind != USB_KEYBOARD)
738 goto fail;
739 ret = 1;
740 data[0] = s->protocol;
741 break;
742 case SET_PROTOCOL:
743 if (s->kind != USB_KEYBOARD)
744 goto fail;
745 ret = 0;
746 s->protocol = value;
747 break;
748 case GET_IDLE:
749 ret = 1;
750 data[0] = s->idle;
751 break;
752 case SET_IDLE:
753 s->idle = value;
754 ret = 0;
755 break;
756 default:
757 fail:
758 ret = USB_RET_STALL;
759 break;
760 }
761 return ret;
762 }
763
764 static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
765 {
766 USBHIDState *s = (USBHIDState *)dev;
767 int ret = 0;
768
769 switch(p->pid) {
770 case USB_TOKEN_IN:
771 if (p->devep == 1) {
772 /* TODO: Implement finite idle delays. */
773 if (!(s->changed || s->idle))
774 return USB_RET_NAK;
775 s->changed = 0;
776 if (s->kind == USB_MOUSE)
777 ret = usb_mouse_poll(s, p->data, p->len);
778 else if (s->kind == USB_TABLET)
779 ret = usb_tablet_poll(s, p->data, p->len);
780 else if (s->kind == USB_KEYBOARD)
781 ret = usb_keyboard_poll(&s->kbd, p->data, p->len);
782 } else {
783 goto fail;
784 }
785 break;
786 case USB_TOKEN_OUT:
787 default:
788 fail:
789 ret = USB_RET_STALL;
790 break;
791 }
792 return ret;
793 }
794
795 static void usb_hid_handle_destroy(USBDevice *dev)
796 {
797 USBHIDState *s = (USBHIDState *)dev;
798
799 if (s->kind != USB_KEYBOARD)
800 qemu_remove_mouse_event_handler(s->ptr.eh_entry);
801 /* TODO: else */
802 qemu_free(s);
803 }
804
805 USBDevice *usb_tablet_init(void)
806 {
807 USBHIDState *s;
808
809 s = qemu_mallocz(sizeof(USBHIDState));
810 if (!s)
811 return NULL;
812 s->dev.speed = USB_SPEED_FULL;
813 s->dev.handle_packet = usb_generic_handle_packet;
814
815 s->dev.handle_reset = usb_mouse_handle_reset;
816 s->dev.handle_control = usb_hid_handle_control;
817 s->dev.handle_data = usb_hid_handle_data;
818 s->dev.handle_destroy = usb_hid_handle_destroy;
819 s->kind = USB_TABLET;
820 /* Force poll routine to be run and grab input the first time. */
821 s->changed = 1;
822
823 pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
824
825 return (USBDevice *)s;
826 }
827
828 USBDevice *usb_mouse_init(void)
829 {
830 USBHIDState *s;
831
832 s = qemu_mallocz(sizeof(USBHIDState));
833 if (!s)
834 return NULL;
835 s->dev.speed = USB_SPEED_FULL;
836 s->dev.handle_packet = usb_generic_handle_packet;
837
838 s->dev.handle_reset = usb_mouse_handle_reset;
839 s->dev.handle_control = usb_hid_handle_control;
840 s->dev.handle_data = usb_hid_handle_data;
841 s->dev.handle_destroy = usb_hid_handle_destroy;
842 s->kind = USB_MOUSE;
843 /* Force poll routine to be run and grab input the first time. */
844 s->changed = 1;
845
846 pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
847
848 return (USBDevice *)s;
849 }
850
851 USBDevice *usb_keyboard_init(void)
852 {
853 USBHIDState *s;
854
855 s = qemu_mallocz(sizeof(USBHIDState));
856 if (!s)
857 return NULL;
858 s->dev.speed = USB_SPEED_FULL;
859 s->dev.handle_packet = usb_generic_handle_packet;
860
861 s->dev.handle_reset = usb_keyboard_handle_reset;
862 s->dev.handle_control = usb_hid_handle_control;
863 s->dev.handle_data = usb_hid_handle_data;
864 s->dev.handle_destroy = usb_hid_handle_destroy;
865 s->kind = USB_KEYBOARD;
866
867 pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Keyboard");
868
869 return (USBDevice *) s;
870 }