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