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
29 /* HID interface requests */
30 #define GET_REPORT 0xa101
31 #define GET_IDLE 0xa102
32 #define GET_PROTOCOL 0xa103
33 #define SET_REPORT 0x2109
34 #define SET_IDLE 0x210a
35 #define SET_PROTOCOL 0x210b
37 /* HID descriptor types */
38 #define USB_DT_HID 0x21
39 #define USB_DT_REPORT 0x22
40 #define USB_DT_PHY 0x23
44 #define USB_KEYBOARD 3
46 typedef struct USBMouseState
{
47 int dx
, dy
, dz
, buttons_state
;
50 QEMUPutMouseEntry
*eh_entry
;
53 typedef struct USBKeyboardState
{
60 typedef struct USBHIDState
{
72 /* mostly the same values as the Bochs USB Mouse device */
73 static const uint8_t qemu_mouse_dev_descriptor
[] = {
74 0x12, /* u8 bLength; */
75 0x01, /* u8 bDescriptorType; Device */
76 0x00, 0x01, /* u16 bcdUSB; v1.0 */
78 0x00, /* u8 bDeviceClass; */
79 0x00, /* u8 bDeviceSubClass; */
80 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
81 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
83 0x27, 0x06, /* u16 idVendor; */
84 0x01, 0x00, /* u16 idProduct; */
85 0x00, 0x00, /* u16 bcdDevice */
87 0x03, /* u8 iManufacturer; */
88 0x02, /* u8 iProduct; */
89 0x01, /* u8 iSerialNumber; */
90 0x01 /* u8 bNumConfigurations; */
93 static const uint8_t qemu_mouse_config_descriptor
[] = {
94 /* one configuration */
95 0x09, /* u8 bLength; */
96 0x02, /* u8 bDescriptorType; Configuration */
97 0x22, 0x00, /* u16 wTotalLength; */
98 0x01, /* u8 bNumInterfaces; (1) */
99 0x01, /* u8 bConfigurationValue; */
100 0x04, /* u8 iConfiguration; */
101 0xa0, /* u8 bmAttributes;
106 50, /* u8 MaxPower; */
109 * USB 2.0, single TT organization (mandatory):
110 * one interface, protocol 0
112 * USB 2.0, multiple TT organization (optional):
113 * two interfaces, protocols 1 (like single TT)
114 * and 2 (multiple TT mode) ... config is
120 0x09, /* u8 if_bLength; */
121 0x04, /* u8 if_bDescriptorType; Interface */
122 0x00, /* u8 if_bInterfaceNumber; */
123 0x00, /* u8 if_bAlternateSetting; */
124 0x01, /* u8 if_bNumEndpoints; */
125 0x03, /* u8 if_bInterfaceClass; */
126 0x01, /* u8 if_bInterfaceSubClass; */
127 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
128 0x07, /* u8 if_iInterface; */
131 0x09, /* u8 bLength; */
132 0x21, /* u8 bDescriptorType; */
133 0x01, 0x00, /* u16 HID_class */
134 0x00, /* u8 country_code */
135 0x01, /* u8 num_descriptors */
136 0x22, /* u8 type; Report */
139 /* one endpoint (status change endpoint) */
140 0x07, /* u8 ep_bLength; */
141 0x05, /* u8 ep_bDescriptorType; Endpoint */
142 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
143 0x03, /* u8 ep_bmAttributes; Interrupt */
144 0x04, 0x00, /* u16 ep_wMaxPacketSize; */
145 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
148 static const uint8_t qemu_tablet_config_descriptor
[] = {
149 /* one configuration */
150 0x09, /* u8 bLength; */
151 0x02, /* u8 bDescriptorType; Configuration */
152 0x22, 0x00, /* u16 wTotalLength; */
153 0x01, /* u8 bNumInterfaces; (1) */
154 0x01, /* u8 bConfigurationValue; */
155 0x05, /* u8 iConfiguration; */
156 0xa0, /* u8 bmAttributes;
161 50, /* u8 MaxPower; */
164 * USB 2.0, single TT organization (mandatory):
165 * one interface, protocol 0
167 * USB 2.0, multiple TT organization (optional):
168 * two interfaces, protocols 1 (like single TT)
169 * and 2 (multiple TT mode) ... config is
175 0x09, /* u8 if_bLength; */
176 0x04, /* u8 if_bDescriptorType; Interface */
177 0x00, /* u8 if_bInterfaceNumber; */
178 0x00, /* u8 if_bAlternateSetting; */
179 0x01, /* u8 if_bNumEndpoints; */
180 0x03, /* u8 if_bInterfaceClass; */
181 0x01, /* u8 if_bInterfaceSubClass; */
182 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
183 0x07, /* u8 if_iInterface; */
186 0x09, /* u8 bLength; */
187 0x21, /* u8 bDescriptorType; */
188 0x01, 0x00, /* u16 HID_class */
189 0x00, /* u8 country_code */
190 0x01, /* u8 num_descriptors */
191 0x22, /* u8 type; Report */
194 /* one endpoint (status change endpoint) */
195 0x07, /* u8 ep_bLength; */
196 0x05, /* u8 ep_bDescriptorType; Endpoint */
197 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
198 0x03, /* u8 ep_bmAttributes; Interrupt */
199 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
200 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
203 static const uint8_t qemu_keyboard_config_descriptor
[] = {
204 /* one configuration */
205 0x09, /* u8 bLength; */
206 USB_DT_CONFIG
, /* u8 bDescriptorType; Configuration */
207 0x22, 0x00, /* u16 wTotalLength; */
208 0x01, /* u8 bNumInterfaces; (1) */
209 0x01, /* u8 bConfigurationValue; */
210 0x06, /* u8 iConfiguration; */
211 0xa0, /* u8 bmAttributes;
216 0x32, /* u8 MaxPower; */
219 * USB 2.0, single TT organization (mandatory):
220 * one interface, protocol 0
222 * USB 2.0, multiple TT organization (optional):
223 * two interfaces, protocols 1 (like single TT)
224 * and 2 (multiple TT mode) ... config is
230 0x09, /* u8 if_bLength; */
231 USB_DT_INTERFACE
, /* u8 if_bDescriptorType; Interface */
232 0x00, /* u8 if_bInterfaceNumber; */
233 0x00, /* u8 if_bAlternateSetting; */
234 0x01, /* u8 if_bNumEndpoints; */
235 0x03, /* u8 if_bInterfaceClass; HID */
236 0x01, /* u8 if_bInterfaceSubClass; Boot */
237 0x01, /* u8 if_bInterfaceProtocol; Keyboard */
238 0x07, /* u8 if_iInterface; */
241 0x09, /* u8 bLength; */
242 USB_DT_HID
, /* u8 bDescriptorType; */
243 0x11, 0x01, /* u16 HID_class */
244 0x00, /* u8 country_code */
245 0x01, /* u8 num_descriptors */
246 USB_DT_REPORT
, /* u8 type; Report */
247 0x3f, 0x00, /* u16 len */
249 /* one endpoint (status change endpoint) */
250 0x07, /* u8 ep_bLength; */
251 USB_DT_ENDPOINT
, /* u8 ep_bDescriptorType; Endpoint */
252 USB_DIR_IN
| 0x01, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
253 0x03, /* u8 ep_bmAttributes; Interrupt */
254 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
255 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
258 static const uint8_t qemu_mouse_hid_report_descriptor
[] = {
259 0x05, 0x01, /* Usage Page (Generic Desktop) */
260 0x09, 0x02, /* Usage (Mouse) */
261 0xa1, 0x01, /* Collection (Application) */
262 0x09, 0x01, /* Usage (Pointer) */
263 0xa1, 0x00, /* Collection (Physical) */
264 0x05, 0x09, /* Usage Page (Button) */
265 0x19, 0x01, /* Usage Minimum (1) */
266 0x29, 0x03, /* Usage Maximum (3) */
267 0x15, 0x00, /* Logical Minimum (0) */
268 0x25, 0x01, /* Logical Maximum (1) */
269 0x95, 0x03, /* Report Count (3) */
270 0x75, 0x01, /* Report Size (1) */
271 0x81, 0x02, /* Input (Data, Variable, Absolute) */
272 0x95, 0x01, /* Report Count (1) */
273 0x75, 0x05, /* Report Size (5) */
274 0x81, 0x01, /* Input (Constant) */
275 0x05, 0x01, /* Usage Page (Generic Desktop) */
276 0x09, 0x30, /* Usage (X) */
277 0x09, 0x31, /* Usage (Y) */
278 0x09, 0x38, /* Usage (Wheel) */
279 0x15, 0x81, /* Logical Minimum (-0x7f) */
280 0x25, 0x7f, /* Logical Maximum (0x7f) */
281 0x75, 0x08, /* Report Size (8) */
282 0x95, 0x03, /* Report Count (3) */
283 0x81, 0x06, /* Input (Data, Variable, Relative) */
284 0xc0, /* End Collection */
285 0xc0, /* End Collection */
288 static const uint8_t qemu_tablet_hid_report_descriptor
[] = {
289 0x05, 0x01, /* Usage Page (Generic Desktop) */
290 0x09, 0x01, /* Usage (Pointer) */
291 0xa1, 0x01, /* Collection (Application) */
292 0x09, 0x01, /* Usage (Pointer) */
293 0xa1, 0x00, /* Collection (Physical) */
294 0x05, 0x09, /* Usage Page (Button) */
295 0x19, 0x01, /* Usage Minimum (1) */
296 0x29, 0x03, /* Usage Maximum (3) */
297 0x15, 0x00, /* Logical Minimum (0) */
298 0x25, 0x01, /* Logical Maximum (1) */
299 0x95, 0x03, /* Report Count (3) */
300 0x75, 0x01, /* Report Size (1) */
301 0x81, 0x02, /* Input (Data, Variable, Absolute) */
302 0x95, 0x01, /* Report Count (1) */
303 0x75, 0x05, /* Report Size (5) */
304 0x81, 0x01, /* Input (Constant) */
305 0x05, 0x01, /* Usage Page (Generic Desktop) */
306 0x09, 0x30, /* Usage (X) */
307 0x09, 0x31, /* Usage (Y) */
308 0x15, 0x00, /* Logical Minimum (0) */
309 0x26, 0xfe, 0x7f, /* Logical Maximum (0x7fff) */
310 0x35, 0x00, /* Physical Minimum (0) */
311 0x46, 0xfe, 0x7f, /* Physical Maximum (0x7fff) */
312 0x75, 0x10, /* Report Size (16) */
313 0x95, 0x02, /* Report Count (2) */
314 0x81, 0x02, /* Input (Data, Variable, Absolute) */
315 0x05, 0x01, /* Usage Page (Generic Desktop) */
316 0x09, 0x38, /* Usage (Wheel) */
317 0x15, 0x81, /* Logical Minimum (-0x7f) */
318 0x25, 0x7f, /* Logical Maximum (0x7f) */
319 0x35, 0x00, /* Physical Minimum (same as logical) */
320 0x45, 0x00, /* Physical Maximum (same as logical) */
321 0x75, 0x08, /* Report Size (8) */
322 0x95, 0x01, /* Report Count (1) */
323 0x81, 0x06, /* Input (Data, Variable, Relative) */
324 0xc0, /* End Collection */
325 0xc0, /* End Collection */
328 static const uint8_t qemu_keyboard_hid_report_descriptor
[] = {
329 0x05, 0x01, /* Usage Page (Generic Desktop) */
330 0x09, 0x06, /* Usage (Keyboard) */
331 0xa1, 0x01, /* Collection (Application) */
332 0x75, 0x01, /* Report Size (1) */
333 0x95, 0x08, /* Report Count (8) */
334 0x05, 0x07, /* Usage Page (Key Codes) */
335 0x19, 0xe0, /* Usage Minimum (224) */
336 0x29, 0xe7, /* Usage Maximum (231) */
337 0x15, 0x00, /* Logical Minimum (0) */
338 0x25, 0x01, /* Logical Maximum (1) */
339 0x81, 0x02, /* Input (Data, Variable, Absolute) */
340 0x95, 0x01, /* Report Count (1) */
341 0x75, 0x08, /* Report Size (8) */
342 0x81, 0x01, /* Input (Constant) */
343 0x95, 0x05, /* Report Count (5) */
344 0x75, 0x01, /* Report Size (1) */
345 0x05, 0x08, /* Usage Page (LEDs) */
346 0x19, 0x01, /* Usage Minimum (1) */
347 0x29, 0x05, /* Usage Maximum (5) */
348 0x91, 0x02, /* Output (Data, Variable, Absolute) */
349 0x95, 0x01, /* Report Count (1) */
350 0x75, 0x03, /* Report Size (3) */
351 0x91, 0x01, /* Output (Constant) */
352 0x95, 0x06, /* Report Count (6) */
353 0x75, 0x08, /* Report Size (8) */
354 0x15, 0x00, /* Logical Minimum (0) */
355 0x25, 0xff, /* Logical Maximum (255) */
356 0x05, 0x07, /* Usage Page (Key Codes) */
357 0x19, 0x00, /* Usage Minimum (0) */
358 0x29, 0xff, /* Usage Maximum (255) */
359 0x81, 0x00, /* Input (Data, Array) */
360 0xc0, /* End Collection */
363 #define USB_HID_USAGE_ERROR_ROLLOVER 0x01
364 #define USB_HID_USAGE_POSTFAIL 0x02
365 #define USB_HID_USAGE_ERROR_UNDEFINED 0x03
367 /* Indices are QEMU keycodes, values are from HID Usage Table. Indices
368 * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d. */
369 static const uint8_t usb_hid_usage_keys
[0x100] = {
370 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
371 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
372 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
373 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
374 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
375 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
376 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
377 0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
378 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
379 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
380 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
381 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
382 0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
383 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
387 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
394 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
396 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
397 0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 static void usb_mouse_event(void *opaque
,
406 int dx1
, int dy1
, int dz1
, int buttons_state
)
408 USBHIDState
*hs
= opaque
;
409 USBMouseState
*s
= &hs
->ptr
;
414 s
->buttons_state
= buttons_state
;
418 static void usb_tablet_event(void *opaque
,
419 int x
, int y
, int dz
, int buttons_state
)
421 USBHIDState
*hs
= opaque
;
422 USBMouseState
*s
= &hs
->ptr
;
427 s
->buttons_state
= buttons_state
;
431 static void usb_keyboard_event(void *opaque
, int keycode
)
433 USBHIDState
*hs
= opaque
;
434 USBKeyboardState
*s
= &hs
->kbd
;
435 uint8_t hid_code
, key
;
438 key
= keycode
& 0x7f;
439 hid_code
= usb_hid_usage_keys
[key
| ((s
->modifiers
>> 1) & (1 << 7))];
440 s
->modifiers
&= ~(1 << 8);
449 if (s
->modifiers
& (1 << 9)) {
450 s
->modifiers
^= 3 << 8;
454 if (keycode
& (1 << 7)) {
455 s
->modifiers
&= ~(1 << (hid_code
& 0x0f));
459 s
->modifiers
|= 1 << (hid_code
& 0x0f);
463 if (keycode
& (1 << 7)) {
464 for (i
= s
->keys
- 1; i
>= 0; i
--)
465 if (s
->key
[i
] == hid_code
) {
466 s
->key
[i
] = s
->key
[-- s
->keys
];
467 s
->key
[s
->keys
] = 0x00;
471 for (i
= s
->keys
- 1; i
>= 0; i
--)
472 if (s
->key
[i
] == hid_code
)
474 if (s
->keys
< sizeof(s
->key
))
475 s
->key
[s
->keys
++] = hid_code
;
479 static inline int int_clamp(int val
, int vmin
, int vmax
)
489 static int usb_mouse_poll(USBHIDState
*hs
, uint8_t *buf
, int len
)
491 int dx
, dy
, dz
, b
, l
;
492 USBMouseState
*s
= &hs
->ptr
;
494 if (!s
->mouse_grabbed
) {
495 s
->eh_entry
= qemu_add_mouse_event_handler(usb_mouse_event
, hs
,
496 0, "QEMU USB Mouse");
497 s
->mouse_grabbed
= 1;
500 dx
= int_clamp(s
->dx
, -127, 127);
501 dy
= int_clamp(s
->dy
, -127, 127);
502 dz
= int_clamp(s
->dz
, -127, 127);
508 /* Appears we have to invert the wheel direction */
512 if (s
->buttons_state
& MOUSE_EVENT_LBUTTON
)
514 if (s
->buttons_state
& MOUSE_EVENT_RBUTTON
)
516 if (s
->buttons_state
& MOUSE_EVENT_MBUTTON
)
531 static int usb_tablet_poll(USBHIDState
*hs
, uint8_t *buf
, int len
)
534 USBMouseState
*s
= &hs
->ptr
;
536 if (!s
->mouse_grabbed
) {
537 s
->eh_entry
= qemu_add_mouse_event_handler(usb_tablet_event
, hs
,
538 1, "QEMU USB Tablet");
539 s
->mouse_grabbed
= 1;
542 dz
= int_clamp(s
->dz
, -127, 127);
545 /* Appears we have to invert the wheel direction */
548 if (s
->buttons_state
& MOUSE_EVENT_LBUTTON
)
550 if (s
->buttons_state
& MOUSE_EVENT_RBUTTON
)
552 if (s
->buttons_state
& MOUSE_EVENT_MBUTTON
)
556 buf
[1] = s
->x
& 0xff;
558 buf
[3] = s
->y
& 0xff;
566 static int usb_keyboard_poll(USBKeyboardState
*s
, uint8_t *buf
, int len
)
571 buf
[0] = s
->modifiers
& 0xff;
574 memset(buf
+ 2, USB_HID_USAGE_ERROR_ROLLOVER
, MIN(8, len
) - 2);
576 memcpy(buf
+ 2, s
->key
, MIN(8, len
) - 2);
581 static int usb_keyboard_write(USBKeyboardState
*s
, uint8_t *buf
, int len
)
584 /* 0x01: Num Lock LED
585 * 0x02: Caps Lock LED
586 * 0x04: Scroll Lock LED
594 static void usb_mouse_handle_reset(USBDevice
*dev
)
596 USBHIDState
*s
= (USBHIDState
*)dev
;
603 s
->ptr
.buttons_state
= 0;
607 static void usb_keyboard_handle_reset(USBDevice
*dev
)
609 USBHIDState
*s
= (USBHIDState
*)dev
;
611 qemu_add_kbd_event_handler(usb_keyboard_event
, s
);
615 static int usb_hid_handle_control(USBDevice
*dev
, int request
, int value
,
616 int index
, int length
, uint8_t *data
)
618 USBHIDState
*s
= (USBHIDState
*)dev
;
622 case DeviceRequest
| USB_REQ_GET_STATUS
:
623 data
[0] = (1 << USB_DEVICE_SELF_POWERED
) |
624 (dev
->remote_wakeup
<< USB_DEVICE_REMOTE_WAKEUP
);
628 case DeviceOutRequest
| USB_REQ_CLEAR_FEATURE
:
629 if (value
== USB_DEVICE_REMOTE_WAKEUP
) {
630 dev
->remote_wakeup
= 0;
636 case DeviceOutRequest
| USB_REQ_SET_FEATURE
:
637 if (value
== USB_DEVICE_REMOTE_WAKEUP
) {
638 dev
->remote_wakeup
= 1;
644 case DeviceOutRequest
| USB_REQ_SET_ADDRESS
:
648 case DeviceRequest
| USB_REQ_GET_DESCRIPTOR
:
651 memcpy(data
, qemu_mouse_dev_descriptor
,
652 sizeof(qemu_mouse_dev_descriptor
));
653 ret
= sizeof(qemu_mouse_dev_descriptor
);
656 if (s
->kind
== USB_MOUSE
) {
657 memcpy(data
, qemu_mouse_config_descriptor
,
658 sizeof(qemu_mouse_config_descriptor
));
659 ret
= sizeof(qemu_mouse_config_descriptor
);
660 } else if (s
->kind
== USB_TABLET
) {
661 memcpy(data
, qemu_tablet_config_descriptor
,
662 sizeof(qemu_tablet_config_descriptor
));
663 ret
= sizeof(qemu_tablet_config_descriptor
);
664 } else if (s
->kind
== USB_KEYBOARD
) {
665 memcpy(data
, qemu_keyboard_config_descriptor
,
666 sizeof(qemu_keyboard_config_descriptor
));
667 ret
= sizeof(qemu_keyboard_config_descriptor
);
671 switch(value
& 0xff) {
682 ret
= set_usb_string(data
, "1");
685 /* product description */
686 ret
= set_usb_string(data
, s
->dev
.devname
);
689 /* vendor description */
690 ret
= set_usb_string(data
, "QEMU " QEMU_VERSION
);
693 ret
= set_usb_string(data
, "HID Mouse");
696 ret
= set_usb_string(data
, "HID Tablet");
699 ret
= set_usb_string(data
, "HID Keyboard");
702 ret
= set_usb_string(data
, "Endpoint1 Interrupt Pipe");
712 case DeviceRequest
| USB_REQ_GET_CONFIGURATION
:
716 case DeviceOutRequest
| USB_REQ_SET_CONFIGURATION
:
719 case DeviceRequest
| USB_REQ_GET_INTERFACE
:
723 case DeviceOutRequest
| USB_REQ_SET_INTERFACE
:
726 /* hid specific requests */
727 case InterfaceRequest
| USB_REQ_GET_DESCRIPTOR
:
730 if (s
->kind
== USB_MOUSE
) {
731 memcpy(data
, qemu_mouse_hid_report_descriptor
,
732 sizeof(qemu_mouse_hid_report_descriptor
));
733 ret
= sizeof(qemu_mouse_hid_report_descriptor
);
734 } else if (s
->kind
== USB_TABLET
) {
735 memcpy(data
, qemu_tablet_hid_report_descriptor
,
736 sizeof(qemu_tablet_hid_report_descriptor
));
737 ret
= sizeof(qemu_tablet_hid_report_descriptor
);
738 } else if (s
->kind
== USB_KEYBOARD
) {
739 memcpy(data
, qemu_keyboard_hid_report_descriptor
,
740 sizeof(qemu_keyboard_hid_report_descriptor
));
741 ret
= sizeof(qemu_keyboard_hid_report_descriptor
);
749 if (s
->kind
== USB_MOUSE
)
750 ret
= usb_mouse_poll(s
, data
, length
);
751 else if (s
->kind
== USB_TABLET
)
752 ret
= usb_tablet_poll(s
, data
, length
);
753 else if (s
->kind
== USB_KEYBOARD
)
754 ret
= usb_keyboard_poll(&s
->kbd
, data
, length
);
757 if (s
->kind
== USB_KEYBOARD
)
758 ret
= usb_keyboard_write(&s
->kbd
, data
, length
);
763 if (s
->kind
!= USB_KEYBOARD
)
766 data
[0] = s
->protocol
;
769 if (s
->kind
!= USB_KEYBOARD
)
790 static int usb_hid_handle_data(USBDevice
*dev
, USBPacket
*p
)
792 USBHIDState
*s
= (USBHIDState
*)dev
;
798 /* TODO: Implement finite idle delays. */
799 if (!(s
->changed
|| s
->idle
))
802 if (s
->kind
== USB_MOUSE
)
803 ret
= usb_mouse_poll(s
, p
->data
, p
->len
);
804 else if (s
->kind
== USB_TABLET
)
805 ret
= usb_tablet_poll(s
, p
->data
, p
->len
);
806 else if (s
->kind
== USB_KEYBOARD
)
807 ret
= usb_keyboard_poll(&s
->kbd
, p
->data
, p
->len
);
821 static void usb_hid_handle_destroy(USBDevice
*dev
)
823 USBHIDState
*s
= (USBHIDState
*)dev
;
825 if (s
->kind
!= USB_KEYBOARD
)
826 qemu_remove_mouse_event_handler(s
->ptr
.eh_entry
);
831 USBDevice
*usb_tablet_init(void)
835 s
= qemu_mallocz(sizeof(USBHIDState
));
838 s
->dev
.speed
= USB_SPEED_FULL
;
839 s
->dev
.handle_packet
= usb_generic_handle_packet
;
841 s
->dev
.handle_reset
= usb_mouse_handle_reset
;
842 s
->dev
.handle_control
= usb_hid_handle_control
;
843 s
->dev
.handle_data
= usb_hid_handle_data
;
844 s
->dev
.handle_destroy
= usb_hid_handle_destroy
;
845 s
->kind
= USB_TABLET
;
846 /* Force poll routine to be run and grab input the first time. */
849 pstrcpy(s
->dev
.devname
, sizeof(s
->dev
.devname
), "QEMU USB Tablet");
851 return (USBDevice
*)s
;
854 USBDevice
*usb_mouse_init(void)
858 s
= qemu_mallocz(sizeof(USBHIDState
));
861 s
->dev
.speed
= USB_SPEED_FULL
;
862 s
->dev
.handle_packet
= usb_generic_handle_packet
;
864 s
->dev
.handle_reset
= usb_mouse_handle_reset
;
865 s
->dev
.handle_control
= usb_hid_handle_control
;
866 s
->dev
.handle_data
= usb_hid_handle_data
;
867 s
->dev
.handle_destroy
= usb_hid_handle_destroy
;
869 /* Force poll routine to be run and grab input the first time. */
872 pstrcpy(s
->dev
.devname
, sizeof(s
->dev
.devname
), "QEMU USB Mouse");
874 return (USBDevice
*)s
;
877 USBDevice
*usb_keyboard_init(void)
881 s
= qemu_mallocz(sizeof(USBHIDState
));
884 s
->dev
.speed
= USB_SPEED_FULL
;
885 s
->dev
.handle_packet
= usb_generic_handle_packet
;
887 s
->dev
.handle_reset
= usb_keyboard_handle_reset
;
888 s
->dev
.handle_control
= usb_hid_handle_control
;
889 s
->dev
.handle_data
= usb_hid_handle_data
;
890 s
->dev
.handle_destroy
= usb_hid_handle_destroy
;
891 s
->kind
= USB_KEYBOARD
;
893 pstrcpy(s
->dev
.devname
, sizeof(s
->dev
.devname
), "QEMU USB Keyboard");
895 return (USBDevice
*) s
;