Statistics
| Branch: | Revision:

root / hw / usb-hid.c @ 02cb1585

History | View | Annotate | Download (26.7 kB)

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