]> git.proxmox.com Git - qemu.git/blame - hw/usb-hid.c
find -type f | xargs sed -i 's/[\t ]$//g' # on most files
[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 */
25#include "vl.h"
26
27/* HID interface requests */
28#define GET_REPORT 0xa101
29#define GET_IDLE 0xa102
30#define GET_PROTOCOL 0xa103
47b2d338 31#define SET_REPORT 0x2109
59ae540c
FB
32#define SET_IDLE 0x210a
33#define SET_PROTOCOL 0x210b
34
47b2d338
AZ
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
09b26c5e 43
59ae540c 44typedef struct USBMouseState {
59ae540c 45 int dx, dy, dz, buttons_state;
09b26c5e 46 int x, y;
09b26c5e 47 int mouse_grabbed;
455204eb 48 QEMUPutMouseEntry *eh_entry;
59ae540c
FB
49} USBMouseState;
50
47b2d338
AZ
51typedef struct USBKeyboardState {
52 uint16_t modifiers;
53 uint8_t leds;
54 uint8_t key[16];
55 int keys;
56} USBKeyboardState;
57
58typedef struct USBHIDState {
59 USBDevice dev;
60 union {
61 USBMouseState ptr;
62 USBKeyboardState kbd;
63 };
64 int kind;
65 int protocol;
66 int idle;
117b3ae6 67 int changed;
47b2d338
AZ
68} USBHIDState;
69
59ae540c
FB
70/* mostly the same values as the Bochs USB Mouse device */
71static const uint8_t qemu_mouse_dev_descriptor[] = {
72 0x12, /* u8 bLength; */
73 0x01, /* u8 bDescriptorType; Device */
e126cf13 74 0x00, 0x01, /* u16 bcdUSB; v1.0 */
59ae540c
FB
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
91static 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; */
5fafdf24 99 0xa0, /* u8 bmAttributes;
59ae540c
FB
100 Bit 7: must be set,
101 6: Self-powered,
102 5: Remote wakeup,
103 4..0: resvd */
104 50, /* u8 MaxPower; */
5fafdf24 105
59ae540c
FB
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] */
47b2d338 126 0x07, /* u8 if_iInterface; */
5fafdf24 127
09b26c5e
FB
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
59ae540c
FB
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) */
09b26c5e
FB
144};
145
146static 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; */
47b2d338 153 0x05, /* u8 iConfiguration; */
5fafdf24 154 0xa0, /* u8 bmAttributes;
09b26c5e
FB
155 Bit 7: must be set,
156 6: Self-powered,
157 5: Remote wakeup,
158 4..0: resvd */
159 50, /* u8 MaxPower; */
5fafdf24 160
09b26c5e
FB
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] */
47b2d338 181 0x07, /* u8 if_iInterface; */
59ae540c
FB
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 */
09b26c5e
FB
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; */
f2f1ac82 198 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
59ae540c
FB
199};
200
47b2d338
AZ
201static 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; */
5fafdf24 209 0xa0, /* u8 bmAttributes;
47b2d338
AZ
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
59ae540c 256static const uint8_t qemu_mouse_hid_report_descriptor[] = {
5fafdf24 257 0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01,
59ae540c 258 0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03,
5fafdf24 259 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01,
59ae540c 260 0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x01,
5fafdf24 261 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81,
59ae540c
FB
262 0x25, 0x7F, 0x75, 0x08, 0x95, 0x02, 0x81, 0x06,
263 0xC0, 0xC0,
264};
265
09b26c5e
FB
266static 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
47b2d338
AZ
306static 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. */
347static 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
59ae540c
FB
383static void usb_mouse_event(void *opaque,
384 int dx1, int dy1, int dz1, int buttons_state)
385{
117b3ae6
PB
386 USBHIDState *hs = opaque;
387 USBMouseState *s = &hs->ptr;
59ae540c
FB
388
389 s->dx += dx1;
390 s->dy += dy1;
391 s->dz += dz1;
392 s->buttons_state = buttons_state;
117b3ae6 393 hs->changed = 1;
59ae540c
FB
394}
395
09b26c5e
FB
396static void usb_tablet_event(void *opaque,
397 int x, int y, int dz, int buttons_state)
398{
117b3ae6
PB
399 USBHIDState *hs = opaque;
400 USBMouseState *s = &hs->ptr;
09b26c5e
FB
401
402 s->x = x;
403 s->y = y;
404 s->dz += dz;
405 s->buttons_state = buttons_state;
117b3ae6 406 hs->changed = 1;
09b26c5e
FB
407}
408
47b2d338
AZ
409static void usb_keyboard_event(void *opaque, int keycode)
410{
117b3ae6
PB
411 USBHIDState *hs = opaque;
412 USBKeyboardState *s = &hs->kbd;
47b2d338
AZ
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
117b3ae6
PB
420 hs->changed = 1;
421
47b2d338
AZ
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
59ae540c
FB
457static 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
117b3ae6 467static int usb_mouse_poll(USBHIDState *hs, uint8_t *buf, int len)
59ae540c
FB
468{
469 int dx, dy, dz, b, l;
117b3ae6 470 USBMouseState *s = &hs->ptr;
59ae540c 471
09b26c5e 472 if (!s->mouse_grabbed) {
117b3ae6 473 s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, hs,
455204eb 474 0, "QEMU USB Mouse");
09b26c5e
FB
475 s->mouse_grabbed = 1;
476 }
5fafdf24 477
59ae540c
FB
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;
5fafdf24 485
59ae540c
FB
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;
5fafdf24 493
59ae540c
FB
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
117b3ae6 505static int usb_tablet_poll(USBHIDState *hs, uint8_t *buf, int len)
09b26c5e
FB
506{
507 int dz, b, l;
117b3ae6 508 USBMouseState *s = &hs->ptr;
09b26c5e
FB
509
510 if (!s->mouse_grabbed) {
117b3ae6 511 s->eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, hs,
455204eb 512 1, "QEMU USB Tablet");
09b26c5e
FB
513 s->mouse_grabbed = 1;
514 }
5fafdf24 515
09b26c5e
FB
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
47b2d338
AZ
540static 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
555static 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
059809e4 568static void usb_mouse_handle_reset(USBDevice *dev)
59ae540c 569{
47b2d338
AZ
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
581static 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;
59ae540c
FB
587}
588
47b2d338 589static int usb_hid_handle_control(USBDevice *dev, int request, int value,
59ae540c
FB
590 int index, int length, uint8_t *data)
591{
47b2d338 592 USBHIDState *s = (USBHIDState *)dev;
09b26c5e 593 int ret = 0;
59ae540c
FB
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:
5fafdf24 625 memcpy(data, qemu_mouse_dev_descriptor,
59ae540c
FB
626 sizeof(qemu_mouse_dev_descriptor));
627 ret = sizeof(qemu_mouse_dev_descriptor);
628 break;
629 case USB_DT_CONFIG:
09b26c5e 630 if (s->kind == USB_MOUSE) {
5fafdf24 631 memcpy(data, qemu_mouse_config_descriptor,
09b26c5e
FB
632 sizeof(qemu_mouse_config_descriptor));
633 ret = sizeof(qemu_mouse_config_descriptor);
634 } else if (s->kind == USB_TABLET) {
5fafdf24 635 memcpy(data, qemu_tablet_config_descriptor,
09b26c5e
FB
636 sizeof(qemu_tablet_config_descriptor));
637 ret = sizeof(qemu_tablet_config_descriptor);
47b2d338 638 } else if (s->kind == USB_KEYBOARD) {
5fafdf24 639 memcpy(data, qemu_keyboard_config_descriptor,
47b2d338
AZ
640 sizeof(qemu_keyboard_config_descriptor));
641 ret = sizeof(qemu_keyboard_config_descriptor);
642 }
59ae540c
FB
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 */
47b2d338 660 ret = set_usb_string(data, s->dev.devname);
59ae540c
FB
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:
47b2d338
AZ
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:
59ae540c
FB
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:
09b26c5e 704 if (s->kind == USB_MOUSE) {
5fafdf24 705 memcpy(data, qemu_mouse_hid_report_descriptor,
09b26c5e
FB
706 sizeof(qemu_mouse_hid_report_descriptor));
707 ret = sizeof(qemu_mouse_hid_report_descriptor);
708 } else if (s->kind == USB_TABLET) {
5fafdf24 709 memcpy(data, qemu_tablet_hid_report_descriptor,
09b26c5e
FB
710 sizeof(qemu_tablet_hid_report_descriptor));
711 ret = sizeof(qemu_tablet_hid_report_descriptor);
47b2d338 712 } else if (s->kind == USB_KEYBOARD) {
5fafdf24 713 memcpy(data, qemu_keyboard_hid_report_descriptor,
47b2d338
AZ
714 sizeof(qemu_keyboard_hid_report_descriptor));
715 ret = sizeof(qemu_keyboard_hid_report_descriptor);
716 }
717 break;
59ae540c
FB
718 default:
719 goto fail;
720 }
721 break;
722 case GET_REPORT:
09b26c5e 723 if (s->kind == USB_MOUSE)
117b3ae6 724 ret = usb_mouse_poll(s, data, length);
09b26c5e 725 else if (s->kind == USB_TABLET)
117b3ae6 726 ret = usb_tablet_poll(s, data, length);
47b2d338
AZ
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;
59ae540c
FB
751 break;
752 case SET_IDLE:
47b2d338 753 s->idle = value;
59ae540c
FB
754 ret = 0;
755 break;
756 default:
757 fail:
758 ret = USB_RET_STALL;
759 break;
760 }
761 return ret;
762}
763
47b2d338 764static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
59ae540c 765{
47b2d338 766 USBHIDState *s = (USBHIDState *)dev;
09b26c5e 767 int ret = 0;
59ae540c 768
4d611c9a 769 switch(p->pid) {
59ae540c 770 case USB_TOKEN_IN:
4d611c9a 771 if (p->devep == 1) {
117b3ae6
PB
772 /* TODO: Implement finite idle delays. */
773 if (!(s->changed || s->idle))
774 return USB_RET_NAK;
775 s->changed = 0;
47b2d338 776 if (s->kind == USB_MOUSE)
117b3ae6 777 ret = usb_mouse_poll(s, p->data, p->len);
47b2d338 778 else if (s->kind == USB_TABLET)
117b3ae6 779 ret = usb_tablet_poll(s, p->data, p->len);
47b2d338
AZ
780 else if (s->kind == USB_KEYBOARD)
781 ret = usb_keyboard_poll(&s->kbd, p->data, p->len);
59ae540c
FB
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
47b2d338 795static void usb_hid_handle_destroy(USBDevice *dev)
059809e4 796{
47b2d338 797 USBHIDState *s = (USBHIDState *)dev;
059809e4 798
47b2d338
AZ
799 if (s->kind != USB_KEYBOARD)
800 qemu_remove_mouse_event_handler(s->ptr.eh_entry);
801 /* TODO: else */
059809e4
FB
802 qemu_free(s);
803}
804
09b26c5e
FB
805USBDevice *usb_tablet_init(void)
806{
47b2d338 807 USBHIDState *s;
09b26c5e 808
47b2d338 809 s = qemu_mallocz(sizeof(USBHIDState));
09b26c5e
FB
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;
47b2d338
AZ
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;
09b26c5e 819 s->kind = USB_TABLET;
117b3ae6
PB
820 /* Force poll routine to be run and grab input the first time. */
821 s->changed = 1;
09b26c5e 822
1f6e24e7
FB
823 pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
824
09b26c5e
FB
825 return (USBDevice *)s;
826}
827
59ae540c
FB
828USBDevice *usb_mouse_init(void)
829{
47b2d338 830 USBHIDState *s;
59ae540c 831
47b2d338 832 s = qemu_mallocz(sizeof(USBHIDState));
59ae540c
FB
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;
47b2d338
AZ
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;
09b26c5e 842 s->kind = USB_MOUSE;
117b3ae6
PB
843 /* Force poll routine to be run and grab input the first time. */
844 s->changed = 1;
59ae540c 845
1f6e24e7
FB
846 pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
847
59ae540c
FB
848 return (USBDevice *)s;
849}
47b2d338
AZ
850
851USBDevice *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}