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
{
71 void (*datain
)(void *);
74 /* mostly the same values as the Bochs USB Mouse device */
75 static const uint8_t qemu_mouse_dev_descriptor
[] = {
76 0x12, /* u8 bLength; */
77 0x01, /* u8 bDescriptorType; Device */
78 0x00, 0x01, /* u16 bcdUSB; v1.0 */
80 0x00, /* u8 bDeviceClass; */
81 0x00, /* u8 bDeviceSubClass; */
82 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
83 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
85 0x27, 0x06, /* u16 idVendor; */
86 0x01, 0x00, /* u16 idProduct; */
87 0x00, 0x00, /* u16 bcdDevice */
89 0x03, /* u8 iManufacturer; */
90 0x02, /* u8 iProduct; */
91 0x01, /* u8 iSerialNumber; */
92 0x01 /* u8 bNumConfigurations; */
95 static const uint8_t qemu_mouse_config_descriptor
[] = {
96 /* one configuration */
97 0x09, /* u8 bLength; */
98 0x02, /* u8 bDescriptorType; Configuration */
99 0x22, 0x00, /* u16 wTotalLength; */
100 0x01, /* u8 bNumInterfaces; (1) */
101 0x01, /* u8 bConfigurationValue; */
102 0x04, /* u8 iConfiguration; */
103 0xa0, /* u8 bmAttributes;
108 50, /* u8 MaxPower; */
111 * USB 2.0, single TT organization (mandatory):
112 * one interface, protocol 0
114 * USB 2.0, multiple TT organization (optional):
115 * two interfaces, protocols 1 (like single TT)
116 * and 2 (multiple TT mode) ... config is
122 0x09, /* u8 if_bLength; */
123 0x04, /* u8 if_bDescriptorType; Interface */
124 0x00, /* u8 if_bInterfaceNumber; */
125 0x00, /* u8 if_bAlternateSetting; */
126 0x01, /* u8 if_bNumEndpoints; */
127 0x03, /* u8 if_bInterfaceClass; */
128 0x01, /* u8 if_bInterfaceSubClass; */
129 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
130 0x07, /* u8 if_iInterface; */
133 0x09, /* u8 bLength; */
134 0x21, /* u8 bDescriptorType; */
135 0x01, 0x00, /* u16 HID_class */
136 0x00, /* u8 country_code */
137 0x01, /* u8 num_descriptors */
138 0x22, /* u8 type; Report */
141 /* one endpoint (status change endpoint) */
142 0x07, /* u8 ep_bLength; */
143 0x05, /* u8 ep_bDescriptorType; Endpoint */
144 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
145 0x03, /* u8 ep_bmAttributes; Interrupt */
146 0x04, 0x00, /* u16 ep_wMaxPacketSize; */
147 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
150 static const uint8_t qemu_tablet_config_descriptor
[] = {
151 /* one configuration */
152 0x09, /* u8 bLength; */
153 0x02, /* u8 bDescriptorType; Configuration */
154 0x22, 0x00, /* u16 wTotalLength; */
155 0x01, /* u8 bNumInterfaces; (1) */
156 0x01, /* u8 bConfigurationValue; */
157 0x05, /* u8 iConfiguration; */
158 0xa0, /* u8 bmAttributes;
163 50, /* u8 MaxPower; */
166 * USB 2.0, single TT organization (mandatory):
167 * one interface, protocol 0
169 * USB 2.0, multiple TT organization (optional):
170 * two interfaces, protocols 1 (like single TT)
171 * and 2 (multiple TT mode) ... config is
177 0x09, /* u8 if_bLength; */
178 0x04, /* u8 if_bDescriptorType; Interface */
179 0x00, /* u8 if_bInterfaceNumber; */
180 0x00, /* u8 if_bAlternateSetting; */
181 0x01, /* u8 if_bNumEndpoints; */
182 0x03, /* u8 if_bInterfaceClass; */
183 0x01, /* u8 if_bInterfaceSubClass; */
184 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
185 0x07, /* u8 if_iInterface; */
188 0x09, /* u8 bLength; */
189 0x21, /* u8 bDescriptorType; */
190 0x01, 0x00, /* u16 HID_class */
191 0x00, /* u8 country_code */
192 0x01, /* u8 num_descriptors */
193 0x22, /* u8 type; Report */
196 /* one endpoint (status change endpoint) */
197 0x07, /* u8 ep_bLength; */
198 0x05, /* u8 ep_bDescriptorType; Endpoint */
199 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
200 0x03, /* u8 ep_bmAttributes; Interrupt */
201 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
202 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
205 static const uint8_t qemu_keyboard_config_descriptor
[] = {
206 /* one configuration */
207 0x09, /* u8 bLength; */
208 USB_DT_CONFIG
, /* u8 bDescriptorType; Configuration */
209 0x22, 0x00, /* u16 wTotalLength; */
210 0x01, /* u8 bNumInterfaces; (1) */
211 0x01, /* u8 bConfigurationValue; */
212 0x06, /* u8 iConfiguration; */
213 0xa0, /* u8 bmAttributes;
218 0x32, /* u8 MaxPower; */
221 * USB 2.0, single TT organization (mandatory):
222 * one interface, protocol 0
224 * USB 2.0, multiple TT organization (optional):
225 * two interfaces, protocols 1 (like single TT)
226 * and 2 (multiple TT mode) ... config is
232 0x09, /* u8 if_bLength; */
233 USB_DT_INTERFACE
, /* u8 if_bDescriptorType; Interface */
234 0x00, /* u8 if_bInterfaceNumber; */
235 0x00, /* u8 if_bAlternateSetting; */
236 0x01, /* u8 if_bNumEndpoints; */
237 0x03, /* u8 if_bInterfaceClass; HID */
238 0x01, /* u8 if_bInterfaceSubClass; Boot */
239 0x01, /* u8 if_bInterfaceProtocol; Keyboard */
240 0x07, /* u8 if_iInterface; */
243 0x09, /* u8 bLength; */
244 USB_DT_HID
, /* u8 bDescriptorType; */
245 0x11, 0x01, /* u16 HID_class */
246 0x00, /* u8 country_code */
247 0x01, /* u8 num_descriptors */
248 USB_DT_REPORT
, /* u8 type; Report */
249 0x3f, 0x00, /* u16 len */
251 /* one endpoint (status change endpoint) */
252 0x07, /* u8 ep_bLength; */
253 USB_DT_ENDPOINT
, /* u8 ep_bDescriptorType; Endpoint */
254 USB_DIR_IN
| 0x01, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
255 0x03, /* u8 ep_bmAttributes; Interrupt */
256 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
257 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
260 static const uint8_t qemu_mouse_hid_report_descriptor
[] = {
261 0x05, 0x01, /* Usage Page (Generic Desktop) */
262 0x09, 0x02, /* Usage (Mouse) */
263 0xa1, 0x01, /* Collection (Application) */
264 0x09, 0x01, /* Usage (Pointer) */
265 0xa1, 0x00, /* Collection (Physical) */
266 0x05, 0x09, /* Usage Page (Button) */
267 0x19, 0x01, /* Usage Minimum (1) */
268 0x29, 0x03, /* Usage Maximum (3) */
269 0x15, 0x00, /* Logical Minimum (0) */
270 0x25, 0x01, /* Logical Maximum (1) */
271 0x95, 0x03, /* Report Count (3) */
272 0x75, 0x01, /* Report Size (1) */
273 0x81, 0x02, /* Input (Data, Variable, Absolute) */
274 0x95, 0x01, /* Report Count (1) */
275 0x75, 0x05, /* Report Size (5) */
276 0x81, 0x01, /* Input (Constant) */
277 0x05, 0x01, /* Usage Page (Generic Desktop) */
278 0x09, 0x30, /* Usage (X) */
279 0x09, 0x31, /* Usage (Y) */
280 0x09, 0x38, /* Usage (Wheel) */
281 0x15, 0x81, /* Logical Minimum (-0x7f) */
282 0x25, 0x7f, /* Logical Maximum (0x7f) */
283 0x75, 0x08, /* Report Size (8) */
284 0x95, 0x03, /* Report Count (3) */
285 0x81, 0x06, /* Input (Data, Variable, Relative) */
286 0xc0, /* End Collection */
287 0xc0, /* End Collection */
290 static const uint8_t qemu_tablet_hid_report_descriptor
[] = {
291 0x05, 0x01, /* Usage Page (Generic Desktop) */
292 0x09, 0x01, /* Usage (Pointer) */
293 0xa1, 0x01, /* Collection (Application) */
294 0x09, 0x01, /* Usage (Pointer) */
295 0xa1, 0x00, /* Collection (Physical) */
296 0x05, 0x09, /* Usage Page (Button) */
297 0x19, 0x01, /* Usage Minimum (1) */
298 0x29, 0x03, /* Usage Maximum (3) */
299 0x15, 0x00, /* Logical Minimum (0) */
300 0x25, 0x01, /* Logical Maximum (1) */
301 0x95, 0x03, /* Report Count (3) */
302 0x75, 0x01, /* Report Size (1) */
303 0x81, 0x02, /* Input (Data, Variable, Absolute) */
304 0x95, 0x01, /* Report Count (1) */
305 0x75, 0x05, /* Report Size (5) */
306 0x81, 0x01, /* Input (Constant) */
307 0x05, 0x01, /* Usage Page (Generic Desktop) */
308 0x09, 0x30, /* Usage (X) */
309 0x09, 0x31, /* Usage (Y) */
310 0x15, 0x00, /* Logical Minimum (0) */
311 0x26, 0xff, 0x7f, /* Logical Maximum (0x7fff) */
312 0x35, 0x00, /* Physical Minimum (0) */
313 0x46, 0xff, 0x7f, /* Physical Maximum (0x7fff) */
314 0x75, 0x10, /* Report Size (16) */
315 0x95, 0x02, /* Report Count (2) */
316 0x81, 0x02, /* Input (Data, Variable, Absolute) */
317 0x05, 0x01, /* Usage Page (Generic Desktop) */
318 0x09, 0x38, /* Usage (Wheel) */
319 0x15, 0x81, /* Logical Minimum (-0x7f) */
320 0x25, 0x7f, /* Logical Maximum (0x7f) */
321 0x35, 0x00, /* Physical Minimum (same as logical) */
322 0x45, 0x00, /* Physical Maximum (same as logical) */
323 0x75, 0x08, /* Report Size (8) */
324 0x95, 0x01, /* Report Count (1) */
325 0x81, 0x06, /* Input (Data, Variable, Relative) */
326 0xc0, /* End Collection */
327 0xc0, /* End Collection */
330 static const uint8_t qemu_keyboard_hid_report_descriptor
[] = {
331 0x05, 0x01, /* Usage Page (Generic Desktop) */
332 0x09, 0x06, /* Usage (Keyboard) */
333 0xa1, 0x01, /* Collection (Application) */
334 0x75, 0x01, /* Report Size (1) */
335 0x95, 0x08, /* Report Count (8) */
336 0x05, 0x07, /* Usage Page (Key Codes) */
337 0x19, 0xe0, /* Usage Minimum (224) */
338 0x29, 0xe7, /* Usage Maximum (231) */
339 0x15, 0x00, /* Logical Minimum (0) */
340 0x25, 0x01, /* Logical Maximum (1) */
341 0x81, 0x02, /* Input (Data, Variable, Absolute) */
342 0x95, 0x01, /* Report Count (1) */
343 0x75, 0x08, /* Report Size (8) */
344 0x81, 0x01, /* Input (Constant) */
345 0x95, 0x05, /* Report Count (5) */
346 0x75, 0x01, /* Report Size (1) */
347 0x05, 0x08, /* Usage Page (LEDs) */
348 0x19, 0x01, /* Usage Minimum (1) */
349 0x29, 0x05, /* Usage Maximum (5) */
350 0x91, 0x02, /* Output (Data, Variable, Absolute) */
351 0x95, 0x01, /* Report Count (1) */
352 0x75, 0x03, /* Report Size (3) */
353 0x91, 0x01, /* Output (Constant) */
354 0x95, 0x06, /* Report Count (6) */
355 0x75, 0x08, /* Report Size (8) */
356 0x15, 0x00, /* Logical Minimum (0) */
357 0x25, 0xff, /* Logical Maximum (255) */
358 0x05, 0x07, /* Usage Page (Key Codes) */
359 0x19, 0x00, /* Usage Minimum (0) */
360 0x29, 0xff, /* Usage Maximum (255) */
361 0x81, 0x00, /* Input (Data, Array) */
362 0xc0, /* End Collection */
365 #define USB_HID_USAGE_ERROR_ROLLOVER 0x01
366 #define USB_HID_USAGE_POSTFAIL 0x02
367 #define USB_HID_USAGE_ERROR_UNDEFINED 0x03
369 /* Indices are QEMU keycodes, values are from HID Usage Table. Indices
370 * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d. */
371 static const uint8_t usb_hid_usage_keys
[0x100] = {
372 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
373 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
374 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
375 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
376 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
377 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
378 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
379 0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
380 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
381 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
382 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
383 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
384 0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
396 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
398 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
399 0x51, 0x4e, 0x49, 0x4c, 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,
403 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407 static void usb_hid_changed(USBHIDState
*hs
)
412 hs
->datain(hs
->datain_opaque
);
415 static void usb_mouse_event(void *opaque
,
416 int dx1
, int dy1
, int dz1
, int buttons_state
)
418 USBHIDState
*hs
= opaque
;
419 USBMouseState
*s
= &hs
->ptr
;
424 s
->buttons_state
= buttons_state
;
429 static void usb_tablet_event(void *opaque
,
430 int x
, int y
, int dz
, int buttons_state
)
432 USBHIDState
*hs
= opaque
;
433 USBMouseState
*s
= &hs
->ptr
;
438 s
->buttons_state
= buttons_state
;
443 static void usb_keyboard_event(void *opaque
, int keycode
)
445 USBHIDState
*hs
= opaque
;
446 USBKeyboardState
*s
= &hs
->kbd
;
447 uint8_t hid_code
, key
;
450 key
= keycode
& 0x7f;
451 hid_code
= usb_hid_usage_keys
[key
| ((s
->modifiers
>> 1) & (1 << 7))];
452 s
->modifiers
&= ~(1 << 8);
459 if (s
->modifiers
& (1 << 9)) {
460 s
->modifiers
^= 3 << 8;
464 if (keycode
& (1 << 7)) {
465 s
->modifiers
&= ~(1 << (hid_code
& 0x0f));
469 s
->modifiers
|= 1 << (hid_code
& 0x0f);
473 if (keycode
& (1 << 7)) {
474 for (i
= s
->keys
- 1; i
>= 0; i
--)
475 if (s
->key
[i
] == hid_code
) {
476 s
->key
[i
] = s
->key
[-- s
->keys
];
477 s
->key
[s
->keys
] = 0x00;
484 for (i
= s
->keys
- 1; i
>= 0; i
--)
485 if (s
->key
[i
] == hid_code
)
488 if (s
->keys
< sizeof(s
->key
))
489 s
->key
[s
->keys
++] = hid_code
;
497 static inline int int_clamp(int val
, int vmin
, int vmax
)
507 static int usb_mouse_poll(USBHIDState
*hs
, uint8_t *buf
, int len
)
509 int dx
, dy
, dz
, b
, l
;
510 USBMouseState
*s
= &hs
->ptr
;
512 if (!s
->mouse_grabbed
) {
513 s
->eh_entry
= qemu_add_mouse_event_handler(usb_mouse_event
, hs
,
514 0, "QEMU USB Mouse");
515 s
->mouse_grabbed
= 1;
518 dx
= int_clamp(s
->dx
, -127, 127);
519 dy
= int_clamp(s
->dy
, -127, 127);
520 dz
= int_clamp(s
->dz
, -127, 127);
526 /* Appears we have to invert the wheel direction */
530 if (s
->buttons_state
& MOUSE_EVENT_LBUTTON
)
532 if (s
->buttons_state
& MOUSE_EVENT_RBUTTON
)
534 if (s
->buttons_state
& MOUSE_EVENT_MBUTTON
)
549 static int usb_tablet_poll(USBHIDState
*hs
, uint8_t *buf
, int len
)
552 USBMouseState
*s
= &hs
->ptr
;
554 if (!s
->mouse_grabbed
) {
555 s
->eh_entry
= qemu_add_mouse_event_handler(usb_tablet_event
, hs
,
556 1, "QEMU USB Tablet");
557 s
->mouse_grabbed
= 1;
560 dz
= int_clamp(s
->dz
, -127, 127);
563 /* Appears we have to invert the wheel direction */
566 if (s
->buttons_state
& MOUSE_EVENT_LBUTTON
)
568 if (s
->buttons_state
& MOUSE_EVENT_RBUTTON
)
570 if (s
->buttons_state
& MOUSE_EVENT_MBUTTON
)
574 buf
[1] = s
->x
& 0xff;
576 buf
[3] = s
->y
& 0xff;
584 static int usb_keyboard_poll(USBKeyboardState
*s
, uint8_t *buf
, int len
)
589 buf
[0] = s
->modifiers
& 0xff;
592 memset(buf
+ 2, USB_HID_USAGE_ERROR_ROLLOVER
, MIN(8, len
) - 2);
594 memcpy(buf
+ 2, s
->key
, MIN(8, len
) - 2);
599 static int usb_keyboard_write(USBKeyboardState
*s
, uint8_t *buf
, int len
)
602 /* 0x01: Num Lock LED
603 * 0x02: Caps Lock LED
604 * 0x04: Scroll Lock LED
612 static void usb_mouse_handle_reset(USBDevice
*dev
)
614 USBHIDState
*s
= (USBHIDState
*)dev
;
621 s
->ptr
.buttons_state
= 0;
625 static void usb_keyboard_handle_reset(USBDevice
*dev
)
627 USBHIDState
*s
= (USBHIDState
*)dev
;
629 qemu_add_kbd_event_handler(usb_keyboard_event
, s
);
633 static int usb_hid_handle_control(USBDevice
*dev
, int request
, int value
,
634 int index
, int length
, uint8_t *data
)
636 USBHIDState
*s
= (USBHIDState
*)dev
;
640 case DeviceRequest
| USB_REQ_GET_STATUS
:
641 data
[0] = (1 << USB_DEVICE_SELF_POWERED
) |
642 (dev
->remote_wakeup
<< USB_DEVICE_REMOTE_WAKEUP
);
646 case DeviceOutRequest
| USB_REQ_CLEAR_FEATURE
:
647 if (value
== USB_DEVICE_REMOTE_WAKEUP
) {
648 dev
->remote_wakeup
= 0;
654 case DeviceOutRequest
| USB_REQ_SET_FEATURE
:
655 if (value
== USB_DEVICE_REMOTE_WAKEUP
) {
656 dev
->remote_wakeup
= 1;
662 case DeviceOutRequest
| USB_REQ_SET_ADDRESS
:
666 case DeviceRequest
| USB_REQ_GET_DESCRIPTOR
:
669 memcpy(data
, qemu_mouse_dev_descriptor
,
670 sizeof(qemu_mouse_dev_descriptor
));
671 ret
= sizeof(qemu_mouse_dev_descriptor
);
674 if (s
->kind
== USB_MOUSE
) {
675 memcpy(data
, qemu_mouse_config_descriptor
,
676 sizeof(qemu_mouse_config_descriptor
));
677 ret
= sizeof(qemu_mouse_config_descriptor
);
678 } else if (s
->kind
== USB_TABLET
) {
679 memcpy(data
, qemu_tablet_config_descriptor
,
680 sizeof(qemu_tablet_config_descriptor
));
681 ret
= sizeof(qemu_tablet_config_descriptor
);
682 } else if (s
->kind
== USB_KEYBOARD
) {
683 memcpy(data
, qemu_keyboard_config_descriptor
,
684 sizeof(qemu_keyboard_config_descriptor
));
685 ret
= sizeof(qemu_keyboard_config_descriptor
);
689 switch(value
& 0xff) {
700 ret
= set_usb_string(data
, "1");
703 /* product description */
704 ret
= set_usb_string(data
, s
->dev
.devname
);
707 /* vendor description */
708 ret
= set_usb_string(data
, "QEMU " QEMU_VERSION
);
711 ret
= set_usb_string(data
, "HID Mouse");
714 ret
= set_usb_string(data
, "HID Tablet");
717 ret
= set_usb_string(data
, "HID Keyboard");
720 ret
= set_usb_string(data
, "Endpoint1 Interrupt Pipe");
730 case DeviceRequest
| USB_REQ_GET_CONFIGURATION
:
734 case DeviceOutRequest
| USB_REQ_SET_CONFIGURATION
:
737 case DeviceRequest
| USB_REQ_GET_INTERFACE
:
741 case DeviceOutRequest
| USB_REQ_SET_INTERFACE
:
744 /* hid specific requests */
745 case InterfaceRequest
| USB_REQ_GET_DESCRIPTOR
:
748 if (s
->kind
== USB_MOUSE
) {
749 memcpy(data
, qemu_mouse_hid_report_descriptor
,
750 sizeof(qemu_mouse_hid_report_descriptor
));
751 ret
= sizeof(qemu_mouse_hid_report_descriptor
);
752 } else if (s
->kind
== USB_TABLET
) {
753 memcpy(data
, qemu_tablet_hid_report_descriptor
,
754 sizeof(qemu_tablet_hid_report_descriptor
));
755 ret
= sizeof(qemu_tablet_hid_report_descriptor
);
756 } else if (s
->kind
== USB_KEYBOARD
) {
757 memcpy(data
, qemu_keyboard_hid_report_descriptor
,
758 sizeof(qemu_keyboard_hid_report_descriptor
));
759 ret
= sizeof(qemu_keyboard_hid_report_descriptor
);
767 if (s
->kind
== USB_MOUSE
)
768 ret
= usb_mouse_poll(s
, data
, length
);
769 else if (s
->kind
== USB_TABLET
)
770 ret
= usb_tablet_poll(s
, data
, length
);
771 else if (s
->kind
== USB_KEYBOARD
)
772 ret
= usb_keyboard_poll(&s
->kbd
, data
, length
);
775 if (s
->kind
== USB_KEYBOARD
)
776 ret
= usb_keyboard_write(&s
->kbd
, data
, length
);
781 if (s
->kind
!= USB_KEYBOARD
)
784 data
[0] = s
->protocol
;
787 if (s
->kind
!= USB_KEYBOARD
)
797 s
->idle
= (uint8_t) (value
>> 8);
808 static int usb_hid_handle_data(USBDevice
*dev
, USBPacket
*p
)
810 USBHIDState
*s
= (USBHIDState
*)dev
;
816 /* TODO: Implement finite idle delays. */
817 if (!(s
->changed
|| s
->idle
))
820 if (s
->kind
== USB_MOUSE
)
821 ret
= usb_mouse_poll(s
, p
->data
, p
->len
);
822 else if (s
->kind
== USB_TABLET
)
823 ret
= usb_tablet_poll(s
, p
->data
, p
->len
);
824 else if (s
->kind
== USB_KEYBOARD
)
825 ret
= usb_keyboard_poll(&s
->kbd
, p
->data
, p
->len
);
839 static void usb_hid_handle_destroy(USBDevice
*dev
)
841 USBHIDState
*s
= (USBHIDState
*)dev
;
843 if (s
->kind
!= USB_KEYBOARD
)
844 qemu_remove_mouse_event_handler(s
->ptr
.eh_entry
);
848 static int usb_hid_initfn(USBDevice
*dev
, int kind
)
850 USBHIDState
*s
= DO_UPCAST(USBHIDState
, dev
, dev
);
851 s
->dev
.speed
= USB_SPEED_FULL
;
853 /* Force poll routine to be run and grab input the first time. */
858 static int usb_tablet_initfn(USBDevice
*dev
)
860 return usb_hid_initfn(dev
, USB_TABLET
);
863 static int usb_mouse_initfn(USBDevice
*dev
)
865 return usb_hid_initfn(dev
, USB_MOUSE
);
868 static int usb_keyboard_initfn(USBDevice
*dev
)
870 return usb_hid_initfn(dev
, USB_KEYBOARD
);
873 void usb_hid_datain_cb(USBDevice
*dev
, void *opaque
, void (*datain
)(void *))
875 USBHIDState
*s
= (USBHIDState
*)dev
;
877 s
->datain_opaque
= opaque
;
881 static struct USBDeviceInfo hid_info
[] = {
883 .qdev
.name
= "QEMU USB Tablet",
884 .qdev
.alias
= "usb-tablet",
885 .usbdevice_name
= "tablet",
886 .qdev
.size
= sizeof(USBHIDState
),
887 .init
= usb_tablet_initfn
,
888 .handle_packet
= usb_generic_handle_packet
,
889 .handle_reset
= usb_mouse_handle_reset
,
890 .handle_control
= usb_hid_handle_control
,
891 .handle_data
= usb_hid_handle_data
,
892 .handle_destroy
= usb_hid_handle_destroy
,
894 .qdev
.name
= "QEMU USB Mouse",
895 .qdev
.alias
= "usb-mouse",
896 .usbdevice_name
= "mouse",
897 .qdev
.size
= sizeof(USBHIDState
),
898 .init
= usb_mouse_initfn
,
899 .handle_packet
= usb_generic_handle_packet
,
900 .handle_reset
= usb_mouse_handle_reset
,
901 .handle_control
= usb_hid_handle_control
,
902 .handle_data
= usb_hid_handle_data
,
903 .handle_destroy
= usb_hid_handle_destroy
,
905 .qdev
.name
= "QEMU USB Keyboard",
906 .qdev
.alias
= "usb-kbd",
907 .usbdevice_name
= "keyboard",
908 .qdev
.size
= sizeof(USBHIDState
),
909 .init
= usb_keyboard_initfn
,
910 .handle_packet
= usb_generic_handle_packet
,
911 .handle_reset
= usb_keyboard_handle_reset
,
912 .handle_control
= usb_hid_handle_control
,
913 .handle_data
= usb_hid_handle_data
,
914 .handle_destroy
= usb_hid_handle_destroy
,
920 static void usb_hid_register_devices(void)
922 usb_qdev_register_many(hid_info
);
924 device_init(usb_hid_register_devices
)