Statistics
| Branch: | Revision:

root / hw / usb-hid.c @ 806b6024

History | View | Annotate | Download (28.6 kB)

1
/*
2
 * QEMU USB HID devices
3
 *
4
 * Copyright (c) 2005 Fabrice Bellard
5
 * Copyright (c) 2007 OpenMoko, Inc.  (andrew@openedhand.com)
6
 *
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 "hw.h"
26
#include "console.h"
27
#include "usb.h"
28

    
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
36

    
37
/* HID descriptor types */
38
#define USB_DT_HID    0x21
39
#define USB_DT_REPORT 0x22
40
#define USB_DT_PHY    0x23
41

    
42
#define USB_MOUSE     1
43
#define USB_TABLET    2
44
#define USB_KEYBOARD  3
45

    
46
typedef struct USBMouseState {
47
    int dx, dy, dz, buttons_state;
48
    int x, y;
49
    int mouse_grabbed;
50
    QEMUPutMouseEntry *eh_entry;
51
} USBMouseState;
52

    
53
typedef struct USBKeyboardState {
54
    uint16_t modifiers;
55
    uint8_t leds;
56
    uint8_t key[16];
57
    int keys;
58
} USBKeyboardState;
59

    
60
typedef struct USBHIDState {
61
    USBDevice dev;
62
    union {
63
        USBMouseState ptr;
64
        USBKeyboardState kbd;
65
    };
66
    int kind;
67
    int protocol;
68
    uint8_t idle;
69
    int changed;
70
    void *datain_opaque;
71
    void (*datain)(void *);
72
} USBHIDState;
73

    
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 */
79

    
80
        0x00,            /*  u8  bDeviceClass; */
81
        0x00,            /*  u8  bDeviceSubClass; */
82
        0x00,       /*  u8  bDeviceProtocol; [ low/full speeds only ] */
83
        0x08,       /*  u8  bMaxPacketSize0; 8 Bytes */
84

    
85
        0x27, 0x06, /*  u16 idVendor; */
86
         0x01, 0x00, /*  u16 idProduct; */
87
        0x00, 0x00, /*  u16 bcdDevice */
88

    
89
        0x03,       /*  u8  iManufacturer; */
90
        0x02,       /*  u8  iProduct; */
91
        0x01,       /*  u8  iSerialNumber; */
92
        0x01        /*  u8  bNumConfigurations; */
93
};
94

    
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;
104
                                 Bit 7: must be set,
105
                                     6: Self-powered,
106
                                     5: Remote wakeup,
107
                                     4..0: resvd */
108
        50,         /*  u8  MaxPower; */
109

    
110
        /* USB 1.1:
111
         * USB 2.0, single TT organization (mandatory):
112
         *        one interface, protocol 0
113
         *
114
         * USB 2.0, multiple TT organization (optional):
115
         *        two interfaces, protocols 1 (like single TT)
116
         *        and 2 (multiple TT mode) ... config is
117
         *        sometimes settable
118
         *        NOT IMPLEMENTED
119
         */
120

    
121
        /* one interface */
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; */
131

    
132
        /* HID descriptor */
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 */
139
        52, 0,       /*  u16 len */
140

    
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) */
148
};
149

    
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;
159
                                 Bit 7: must be set,
160
                                     6: Self-powered,
161
                                     5: Remote wakeup,
162
                                     4..0: resvd */
163
        50,         /*  u8  MaxPower; */
164

    
165
        /* USB 1.1:
166
         * USB 2.0, single TT organization (mandatory):
167
         *        one interface, protocol 0
168
         *
169
         * USB 2.0, multiple TT organization (optional):
170
         *        two interfaces, protocols 1 (like single TT)
171
         *        and 2 (multiple TT mode) ... config is
172
         *        sometimes settable
173
         *        NOT IMPLEMENTED
174
         */
175

    
176
        /* one interface */
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; */
186

    
187
        /* HID descriptor */
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 */
194
        74, 0,       /*  u16 len */
195

    
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) */
203
};
204

    
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;
214
                                Bit 7: must be set,
215
                                    6: Self-powered,
216
                                    5: Remote wakeup,
217
                                    4..0: resvd */
218
    0x32,                /*  u8  MaxPower; */
219

    
220
    /* USB 1.1:
221
     * USB 2.0, single TT organization (mandatory):
222
     *        one interface, protocol 0
223
     *
224
     * USB 2.0, multiple TT organization (optional):
225
     *        two interfaces, protocols 1 (like single TT)
226
     *        and 2 (multiple TT mode) ... config is
227
     *        sometimes settable
228
     *        NOT IMPLEMENTED
229
     */
230

    
231
    /* one interface */
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; */
241

    
242
    /* HID descriptor */
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 */
250

    
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) */
258
};
259

    
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 */
288
};
289

    
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 */
328
};
329

    
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 */
363
};
364

    
365
#define USB_HID_USAGE_ERROR_ROLLOVER        0x01
366
#define USB_HID_USAGE_POSTFAIL                0x02
367
#define USB_HID_USAGE_ERROR_UNDEFINED        0x03
368

    
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,
388

    
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,
405
};
406

    
407
static void usb_hid_changed(USBHIDState *hs)
408
{
409
    hs->changed = 1;
410

    
411
    if (hs->datain)
412
        hs->datain(hs->datain_opaque);
413
}
414

    
415
static void usb_mouse_event(void *opaque,
416
                            int dx1, int dy1, int dz1, int buttons_state)
417
{
418
    USBHIDState *hs = opaque;
419
    USBMouseState *s = &hs->ptr;
420

    
421
    s->dx += dx1;
422
    s->dy += dy1;
423
    s->dz += dz1;
424
    s->buttons_state = buttons_state;
425

    
426
    usb_hid_changed(hs);
427
}
428

    
429
static void usb_tablet_event(void *opaque,
430
                             int x, int y, int dz, int buttons_state)
431
{
432
    USBHIDState *hs = opaque;
433
    USBMouseState *s = &hs->ptr;
434

    
435
    s->x = x;
436
    s->y = y;
437
    s->dz += dz;
438
    s->buttons_state = buttons_state;
439

    
440
    usb_hid_changed(hs);
441
}
442

    
443
static void usb_keyboard_event(void *opaque, int keycode)
444
{
445
    USBHIDState *hs = opaque;
446
    USBKeyboardState *s = &hs->kbd;
447
    uint8_t hid_code, key;
448
    int i;
449

    
450
    key = keycode & 0x7f;
451
    hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))];
452
    s->modifiers &= ~(1 << 8);
453

    
454
    switch (hid_code) {
455
    case 0x00:
456
        return;
457

    
458
    case 0xe0:
459
        if (s->modifiers & (1 << 9)) {
460
            s->modifiers ^= 3 << 8;
461
            return;
462
        }
463
    case 0xe1 ... 0xe7:
464
        if (keycode & (1 << 7)) {
465
            s->modifiers &= ~(1 << (hid_code & 0x0f));
466
            return;
467
        }
468
    case 0xe8 ... 0xef:
469
        s->modifiers |= 1 << (hid_code & 0x0f);
470
        return;
471
    }
472

    
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;
478
                usb_hid_changed(hs);
479
                break;
480
            }
481
        if (i < 0)
482
            return;
483
    } else {
484
        for (i = s->keys - 1; i >= 0; i --)
485
            if (s->key[i] == hid_code)
486
                break;
487
        if (i < 0) {
488
            if (s->keys < sizeof(s->key))
489
                s->key[s->keys ++] = hid_code;
490
        } else
491
            return;
492
    }
493

    
494
    usb_hid_changed(hs);
495
}
496

    
497
static inline int int_clamp(int val, int vmin, int vmax)
498
{
499
    if (val < vmin)
500
        return vmin;
501
    else if (val > vmax)
502
        return vmax;
503
    else
504
        return val;
505
}
506

    
507
static int usb_mouse_poll(USBHIDState *hs, uint8_t *buf, int len)
508
{
509
    int dx, dy, dz, b, l;
510
    USBMouseState *s = &hs->ptr;
511

    
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;
516
    }
517

    
518
    dx = int_clamp(s->dx, -127, 127);
519
    dy = int_clamp(s->dy, -127, 127);
520
    dz = int_clamp(s->dz, -127, 127);
521

    
522
    s->dx -= dx;
523
    s->dy -= dy;
524
    s->dz -= dz;
525

    
526
    /* Appears we have to invert the wheel direction */
527
    dz = 0 - dz;
528

    
529
    b = 0;
530
    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
531
        b |= 0x01;
532
    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
533
        b |= 0x02;
534
    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
535
        b |= 0x04;
536

    
537
    l = 0;
538
    if (len > l)
539
        buf[l ++] = b;
540
    if (len > l)
541
        buf[l ++] = dx;
542
    if (len > l)
543
        buf[l ++] = dy;
544
    if (len > l)
545
        buf[l ++] = dz;
546
    return l;
547
}
548

    
549
static int usb_tablet_poll(USBHIDState *hs, uint8_t *buf, int len)
550
{
551
    int dz, b, l;
552
    USBMouseState *s = &hs->ptr;
553

    
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;
558
    }
559

    
560
    dz = int_clamp(s->dz, -127, 127);
561
    s->dz -= dz;
562

    
563
    /* Appears we have to invert the wheel direction */
564
    dz = 0 - dz;
565
    b = 0;
566
    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
567
        b |= 0x01;
568
    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
569
        b |= 0x02;
570
    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
571
        b |= 0x04;
572

    
573
    buf[0] = b;
574
    buf[1] = s->x & 0xff;
575
    buf[2] = s->x >> 8;
576
    buf[3] = s->y & 0xff;
577
    buf[4] = s->y >> 8;
578
    buf[5] = dz;
579
    l = 6;
580

    
581
    return l;
582
}
583

    
584
static int usb_keyboard_poll(USBKeyboardState *s, uint8_t *buf, int len)
585
{
586
    if (len < 2)
587
        return 0;
588

    
589
    buf[0] = s->modifiers & 0xff;
590
    buf[1] = 0;
591
    if (s->keys > 6)
592
        memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
593
    else
594
        memcpy(buf + 2, s->key, MIN(8, len) - 2);
595

    
596
    return MIN(8, len);
597
}
598

    
599
static int usb_keyboard_write(USBKeyboardState *s, uint8_t *buf, int len)
600
{
601
    if (len > 0) {
602
        /* 0x01: Num Lock LED
603
         * 0x02: Caps Lock LED
604
         * 0x04: Scroll Lock LED
605
         * 0x08: Compose LED
606
         * 0x10: Kana LED */
607
        s->leds = buf[0];
608
    }
609
    return 0;
610
}
611

    
612
static void usb_mouse_handle_reset(USBDevice *dev)
613
{
614
    USBHIDState *s = (USBHIDState *)dev;
615

    
616
    s->ptr.dx = 0;
617
    s->ptr.dy = 0;
618
    s->ptr.dz = 0;
619
    s->ptr.x = 0;
620
    s->ptr.y = 0;
621
    s->ptr.buttons_state = 0;
622
    s->protocol = 1;
623
}
624

    
625
static void usb_keyboard_handle_reset(USBDevice *dev)
626
{
627
    USBHIDState *s = (USBHIDState *)dev;
628

    
629
    qemu_add_kbd_event_handler(usb_keyboard_event, s);
630
    s->protocol = 1;
631
}
632

    
633
static int usb_hid_handle_control(USBDevice *dev, int request, int value,
634
                                  int index, int length, uint8_t *data)
635
{
636
    USBHIDState *s = (USBHIDState *)dev;
637
    int ret = 0;
638

    
639
    switch(request) {
640
    case DeviceRequest | USB_REQ_GET_STATUS:
641
        data[0] = (1 << USB_DEVICE_SELF_POWERED) |
642
            (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
643
        data[1] = 0x00;
644
        ret = 2;
645
        break;
646
    case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
647
        if (value == USB_DEVICE_REMOTE_WAKEUP) {
648
            dev->remote_wakeup = 0;
649
        } else {
650
            goto fail;
651
        }
652
        ret = 0;
653
        break;
654
    case DeviceOutRequest | USB_REQ_SET_FEATURE:
655
        if (value == USB_DEVICE_REMOTE_WAKEUP) {
656
            dev->remote_wakeup = 1;
657
        } else {
658
            goto fail;
659
        }
660
        ret = 0;
661
        break;
662
    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
663
        dev->addr = value;
664
        ret = 0;
665
        break;
666
    case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
667
        switch(value >> 8) {
668
        case USB_DT_DEVICE:
669
            memcpy(data, qemu_mouse_dev_descriptor,
670
                   sizeof(qemu_mouse_dev_descriptor));
671
            ret = sizeof(qemu_mouse_dev_descriptor);
672
            break;
673
        case USB_DT_CONFIG:
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);
686
            }
687
            break;
688
        case USB_DT_STRING:
689
            switch(value & 0xff) {
690
            case 0:
691
                /* language ids */
692
                data[0] = 4;
693
                data[1] = 3;
694
                data[2] = 0x09;
695
                data[3] = 0x04;
696
                ret = 4;
697
                break;
698
            case 1:
699
                /* serial number */
700
                ret = set_usb_string(data, "1");
701
                break;
702
            case 2:
703
                /* product description */
704
                ret = set_usb_string(data, s->dev.devname);
705
                break;
706
            case 3:
707
                /* vendor description */
708
                ret = set_usb_string(data, "QEMU " QEMU_VERSION);
709
                break;
710
            case 4:
711
                ret = set_usb_string(data, "HID Mouse");
712
                break;
713
            case 5:
714
                ret = set_usb_string(data, "HID Tablet");
715
                break;
716
            case 6:
717
                ret = set_usb_string(data, "HID Keyboard");
718
                break;
719
            case 7:
720
                ret = set_usb_string(data, "Endpoint1 Interrupt Pipe");
721
                break;
722
            default:
723
                goto fail;
724
            }
725
            break;
726
        default:
727
            goto fail;
728
        }
729
        break;
730
    case DeviceRequest | USB_REQ_GET_CONFIGURATION:
731
        data[0] = 1;
732
        ret = 1;
733
        break;
734
    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
735
        ret = 0;
736
        break;
737
    case DeviceRequest | USB_REQ_GET_INTERFACE:
738
        data[0] = 0;
739
        ret = 1;
740
        break;
741
    case DeviceOutRequest | USB_REQ_SET_INTERFACE:
742
        ret = 0;
743
        break;
744
        /* hid specific requests */
745
    case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
746
        switch(value >> 8) {
747
        case 0x22:
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);
760
            }
761
            break;
762
        default:
763
            goto fail;
764
        }
765
        break;
766
    case GET_REPORT:
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);
773
        break;
774
    case SET_REPORT:
775
        if (s->kind == USB_KEYBOARD)
776
            ret = usb_keyboard_write(&s->kbd, data, length);
777
        else
778
            goto fail;
779
        break;
780
    case GET_PROTOCOL:
781
        if (s->kind != USB_KEYBOARD)
782
            goto fail;
783
        ret = 1;
784
        data[0] = s->protocol;
785
        break;
786
    case SET_PROTOCOL:
787
        if (s->kind != USB_KEYBOARD)
788
            goto fail;
789
        ret = 0;
790
        s->protocol = value;
791
        break;
792
    case GET_IDLE:
793
        ret = 1;
794
        data[0] = s->idle;
795
        break;
796
    case SET_IDLE:
797
        s->idle = (uint8_t) (value >> 8);
798
        ret = 0;
799
        break;
800
    default:
801
    fail:
802
        ret = USB_RET_STALL;
803
        break;
804
    }
805
    return ret;
806
}
807

    
808
static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
809
{
810
    USBHIDState *s = (USBHIDState *)dev;
811
    int ret = 0;
812

    
813
    switch(p->pid) {
814
    case USB_TOKEN_IN:
815
        if (p->devep == 1) {
816
            /* TODO: Implement finite idle delays.  */
817
            if (!(s->changed || s->idle))
818
                return USB_RET_NAK;
819
            s->changed = 0;
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);
826
        } else {
827
            goto fail;
828
        }
829
        break;
830
    case USB_TOKEN_OUT:
831
    default:
832
    fail:
833
        ret = USB_RET_STALL;
834
        break;
835
    }
836
    return ret;
837
}
838

    
839
static void usb_hid_handle_destroy(USBDevice *dev)
840
{
841
    USBHIDState *s = (USBHIDState *)dev;
842

    
843
    if (s->kind != USB_KEYBOARD)
844
        qemu_remove_mouse_event_handler(s->ptr.eh_entry);
845
    /* TODO: else */
846
    qemu_free(s);
847
}
848

    
849
static int usb_hid_initfn(USBDevice *dev, int kind)
850
{
851
    USBHIDState *s = DO_UPCAST(USBHIDState, dev, dev);
852
    s->dev.speed = USB_SPEED_FULL;
853
    s->kind = kind;
854
    /* Force poll routine to be run and grab input the first time.  */
855
    s->changed = 1;
856
    return 0;
857
}
858

    
859
static int usb_tablet_initfn(USBDevice *dev)
860
{
861
    return usb_hid_initfn(dev, USB_TABLET);
862
}
863

    
864
static int usb_mouse_initfn(USBDevice *dev)
865
{
866
    return usb_hid_initfn(dev, USB_MOUSE);
867
}
868

    
869
static int usb_keyboard_initfn(USBDevice *dev)
870
{
871
    return usb_hid_initfn(dev, USB_KEYBOARD);
872
}
873

    
874
USBDevice *usb_tablet_init(void)
875
{
876
    return usb_create_simple(NULL /* FIXME */, "QEMU USB Tablet");
877
}
878

    
879
USBDevice *usb_mouse_init(void)
880
{
881
    return usb_create_simple(NULL /* FIXME */, "QEMU USB Mouse");
882
}
883

    
884
USBDevice *usb_keyboard_init(void)
885
{
886
    return usb_create_simple(NULL /* FIXME */, "QEMU USB Keyboard");
887
}
888

    
889
void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *))
890
{
891
    USBHIDState *s = (USBHIDState *)dev;
892

    
893
    s->datain_opaque = opaque;
894
    s->datain = datain;
895
}
896

    
897
static struct USBDeviceInfo hid_info[] = {
898
    {
899
        .qdev.name      = "QEMU USB Tablet",
900
        .qdev.size      = sizeof(USBHIDState),
901
        .init           = usb_tablet_initfn,
902
        .handle_packet  = usb_generic_handle_packet,
903
        .handle_reset   = usb_mouse_handle_reset,
904
        .handle_control = usb_hid_handle_control,
905
        .handle_data    = usb_hid_handle_data,
906
        .handle_destroy = usb_hid_handle_destroy,
907
    },{
908
        .qdev.name      = "QEMU USB Mouse",
909
        .qdev.size      = sizeof(USBHIDState),
910
        .init           = usb_mouse_initfn,
911
        .handle_packet  = usb_generic_handle_packet,
912
        .handle_reset   = usb_mouse_handle_reset,
913
        .handle_control = usb_hid_handle_control,
914
        .handle_data    = usb_hid_handle_data,
915
        .handle_destroy = usb_hid_handle_destroy,
916
    },{
917
        .qdev.name      = "QEMU USB Keyboard",
918
        .qdev.size      = sizeof(USBHIDState),
919
        .init           = usb_keyboard_initfn,
920
        .handle_packet  = usb_generic_handle_packet,
921
        .handle_reset   = usb_keyboard_handle_reset,
922
        .handle_control = usb_hid_handle_control,
923
        .handle_data    = usb_hid_handle_data,
924
        .handle_destroy = usb_hid_handle_destroy,
925
    },{
926
        /* end of list */
927
    }
928
};
929

    
930
static void usb_hid_register_devices(void)
931
{
932
    usb_qdev_register_many(hid_info);
933
}
934
device_init(usb_hid_register_devices)