Statistics
| Branch: | Revision:

root / hw / usb-hid.c @ 47b2d338

History | View | Annotate | Download (26.1 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 "vl.h"
26

    
27
/* HID interface requests */
28
#define GET_REPORT   0xa101
29
#define GET_IDLE     0xa102
30
#define GET_PROTOCOL 0xa103
31
#define SET_REPORT   0x2109
32
#define SET_IDLE     0x210a
33
#define SET_PROTOCOL 0x210b
34

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

    
40
#define USB_MOUSE     1
41
#define USB_TABLET    2
42
#define USB_KEYBOARD  3
43

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

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

    
58
typedef struct USBHIDState {
59
    USBDevice dev;
60
    union {
61
        USBMouseState ptr;
62
        USBKeyboardState kbd;
63
    };
64
    int kind;
65
    int protocol;
66
    int idle;
67
} USBHIDState;
68

    
69
/* mostly the same values as the Bochs USB Mouse device */
70
static const uint8_t qemu_mouse_dev_descriptor[] = {
71
        0x12,       /*  u8 bLength; */
72
        0x01,       /*  u8 bDescriptorType; Device */
73
        0x00, 0x01, /*  u16 bcdUSB; v1.0 */
74

    
75
        0x00,            /*  u8  bDeviceClass; */
76
        0x00,            /*  u8  bDeviceSubClass; */
77
        0x00,       /*  u8  bDeviceProtocol; [ low/full speeds only ] */
78
        0x08,       /*  u8  bMaxPacketSize0; 8 Bytes */
79

    
80
        0x27, 0x06, /*  u16 idVendor; */
81
         0x01, 0x00, /*  u16 idProduct; */
82
        0x00, 0x00, /*  u16 bcdDevice */
83

    
84
        0x03,       /*  u8  iManufacturer; */
85
        0x02,       /*  u8  iProduct; */
86
        0x01,       /*  u8  iSerialNumber; */
87
        0x01        /*  u8  bNumConfigurations; */
88
};
89

    
90
static const uint8_t qemu_mouse_config_descriptor[] = {
91
        /* one configuration */
92
        0x09,       /*  u8  bLength; */
93
        0x02,       /*  u8  bDescriptorType; Configuration */
94
        0x22, 0x00, /*  u16 wTotalLength; */
95
        0x01,       /*  u8  bNumInterfaces; (1) */
96
        0x01,       /*  u8  bConfigurationValue; */
97
        0x04,       /*  u8  iConfiguration; */
98
        0xa0,       /*  u8  bmAttributes; 
99
                                 Bit 7: must be set,
100
                                     6: Self-powered,
101
                                     5: Remote wakeup,
102
                                     4..0: resvd */
103
        50,         /*  u8  MaxPower; */
104
      
105
        /* USB 1.1:
106
         * USB 2.0, single TT organization (mandatory):
107
         *        one interface, protocol 0
108
         *
109
         * USB 2.0, multiple TT organization (optional):
110
         *        two interfaces, protocols 1 (like single TT)
111
         *        and 2 (multiple TT mode) ... config is
112
         *        sometimes settable
113
         *        NOT IMPLEMENTED
114
         */
115

    
116
        /* one interface */
117
        0x09,       /*  u8  if_bLength; */
118
        0x04,       /*  u8  if_bDescriptorType; Interface */
119
        0x00,       /*  u8  if_bInterfaceNumber; */
120
        0x00,       /*  u8  if_bAlternateSetting; */
121
        0x01,       /*  u8  if_bNumEndpoints; */
122
        0x03,       /*  u8  if_bInterfaceClass; */
123
        0x01,       /*  u8  if_bInterfaceSubClass; */
124
        0x02,       /*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
125
        0x07,       /*  u8  if_iInterface; */
126
     
127
        /* HID descriptor */
128
        0x09,        /*  u8  bLength; */
129
        0x21,        /*  u8 bDescriptorType; */
130
        0x01, 0x00,  /*  u16 HID_class */
131
        0x00,        /*  u8 country_code */
132
        0x01,        /*  u8 num_descriptors */
133
        0x22,        /*  u8 type; Report */
134
        50, 0,       /*  u16 len */
135

    
136
        /* one endpoint (status change endpoint) */
137
        0x07,       /*  u8  ep_bLength; */
138
        0x05,       /*  u8  ep_bDescriptorType; Endpoint */
139
        0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
140
         0x03,       /*  u8  ep_bmAttributes; Interrupt */
141
         0x03, 0x00, /*  u16 ep_wMaxPacketSize; */
142
        0x0a,       /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
143
};
144

    
145
static const uint8_t qemu_tablet_config_descriptor[] = {
146
        /* one configuration */
147
        0x09,       /*  u8  bLength; */
148
        0x02,       /*  u8  bDescriptorType; Configuration */
149
        0x22, 0x00, /*  u16 wTotalLength; */
150
        0x01,       /*  u8  bNumInterfaces; (1) */
151
        0x01,       /*  u8  bConfigurationValue; */
152
        0x05,       /*  u8  iConfiguration; */
153
        0xa0,       /*  u8  bmAttributes; 
154
                                 Bit 7: must be set,
155
                                     6: Self-powered,
156
                                     5: Remote wakeup,
157
                                     4..0: resvd */
158
        50,         /*  u8  MaxPower; */
159
      
160
        /* USB 1.1:
161
         * USB 2.0, single TT organization (mandatory):
162
         *        one interface, protocol 0
163
         *
164
         * USB 2.0, multiple TT organization (optional):
165
         *        two interfaces, protocols 1 (like single TT)
166
         *        and 2 (multiple TT mode) ... config is
167
         *        sometimes settable
168
         *        NOT IMPLEMENTED
169
         */
170

    
171
        /* one interface */
172
        0x09,       /*  u8  if_bLength; */
173
        0x04,       /*  u8  if_bDescriptorType; Interface */
174
        0x00,       /*  u8  if_bInterfaceNumber; */
175
        0x00,       /*  u8  if_bAlternateSetting; */
176
        0x01,       /*  u8  if_bNumEndpoints; */
177
        0x03,       /*  u8  if_bInterfaceClass; */
178
        0x01,       /*  u8  if_bInterfaceSubClass; */
179
        0x02,       /*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
180
        0x07,       /*  u8  if_iInterface; */
181

    
182
        /* HID descriptor */
183
        0x09,        /*  u8  bLength; */
184
        0x21,        /*  u8 bDescriptorType; */
185
        0x01, 0x00,  /*  u16 HID_class */
186
        0x00,        /*  u8 country_code */
187
        0x01,        /*  u8 num_descriptors */
188
        0x22,        /*  u8 type; Report */
189
        74, 0,       /*  u16 len */
190

    
191
        /* one endpoint (status change endpoint) */
192
        0x07,       /*  u8  ep_bLength; */
193
        0x05,       /*  u8  ep_bDescriptorType; Endpoint */
194
        0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
195
         0x03,       /*  u8  ep_bmAttributes; Interrupt */
196
         0x08, 0x00, /*  u16 ep_wMaxPacketSize; */
197
        0x0a,       /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
198
};
199

    
200
static const uint8_t qemu_keyboard_config_descriptor[] = {
201
    /* one configuration */
202
    0x09,                /*  u8  bLength; */
203
    USB_DT_CONFIG,        /*  u8  bDescriptorType; Configuration */
204
    0x22, 0x00,                /*  u16 wTotalLength; */
205
    0x01,                /*  u8  bNumInterfaces; (1) */
206
    0x01,                /*  u8  bConfigurationValue; */
207
    0x06,                /*  u8  iConfiguration; */
208
    0xa0,                /*  u8  bmAttributes; 
209
                                Bit 7: must be set,
210
                                    6: Self-powered,
211
                                    5: Remote wakeup,
212
                                    4..0: resvd */
213
    0x32,                /*  u8  MaxPower; */
214

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

    
226
    /* one interface */
227
    0x09,                /*  u8  if_bLength; */
228
    USB_DT_INTERFACE,        /*  u8  if_bDescriptorType; Interface */
229
    0x00,                /*  u8  if_bInterfaceNumber; */
230
    0x00,                /*  u8  if_bAlternateSetting; */
231
    0x01,                /*  u8  if_bNumEndpoints; */
232
    0x03,                /*  u8  if_bInterfaceClass; HID */
233
    0x01,                /*  u8  if_bInterfaceSubClass; Boot */
234
    0x01,                /*  u8  if_bInterfaceProtocol; Keyboard */
235
    0x07,                /*  u8  if_iInterface; */
236

    
237
    /* HID descriptor */
238
    0x09,                /*  u8  bLength; */
239
    USB_DT_HID,                /*  u8  bDescriptorType; */
240
    0x11, 0x01,                /*  u16 HID_class */
241
    0x00,                /*  u8  country_code */
242
    0x01,                /*  u8  num_descriptors */
243
    USB_DT_REPORT,        /*  u8  type; Report */
244
    0x3f, 0x00,                /*  u16 len */
245

    
246
    /* one endpoint (status change endpoint) */
247
    0x07,                /*  u8  ep_bLength; */
248
    USB_DT_ENDPOINT,        /*  u8  ep_bDescriptorType; Endpoint */
249
    USB_DIR_IN | 0x01,        /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
250
    0x03,                /*  u8  ep_bmAttributes; Interrupt */
251
    0x08, 0x00,                /*  u16 ep_wMaxPacketSize; */
252
    0x0a,                /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
253
};
254

    
255
static const uint8_t qemu_mouse_hid_report_descriptor[] = {
256
    0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 
257
    0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03,
258
    0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01, 
259
    0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x01,
260
    0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81, 
261
    0x25, 0x7F, 0x75, 0x08, 0x95, 0x02, 0x81, 0x06,
262
    0xC0, 0xC0,
263
};
264

    
265
static const uint8_t qemu_tablet_hid_report_descriptor[] = {
266
        0x05, 0x01, /* Usage Page Generic Desktop */
267
        0x09, 0x01, /* Usage Mouse */
268
        0xA1, 0x01, /* Collection Application */
269
        0x09, 0x01, /* Usage Pointer */
270
        0xA1, 0x00, /* Collection Physical */
271
        0x05, 0x09, /* Usage Page Button */
272
        0x19, 0x01, /* Usage Minimum Button 1 */
273
        0x29, 0x03, /* Usage Maximum Button 3 */
274
        0x15, 0x00, /* Logical Minimum 0 */
275
        0x25, 0x01, /* Logical Maximum 1 */
276
        0x95, 0x03, /* Report Count 3 */
277
        0x75, 0x01, /* Report Size 1 */
278
        0x81, 0x02, /* Input (Data, Var, Abs) */
279
        0x95, 0x01, /* Report Count 1 */
280
        0x75, 0x05, /* Report Size 5 */
281
        0x81, 0x01, /* Input (Cnst, Var, Abs) */
282
        0x05, 0x01, /* Usage Page Generic Desktop */
283
        0x09, 0x30, /* Usage X */
284
        0x09, 0x31, /* Usage Y */
285
        0x15, 0x00, /* Logical Minimum 0 */
286
        0x26, 0xFF, 0x7F, /* Logical Maximum 0x7fff */
287
        0x35, 0x00, /* Physical Minimum 0 */
288
        0x46, 0xFE, 0x7F, /* Physical Maximum 0x7fff */
289
        0x75, 0x10, /* Report Size 16 */
290
        0x95, 0x02, /* Report Count 2 */
291
        0x81, 0x02, /* Input (Data, Var, Abs) */
292
        0x05, 0x01, /* Usage Page Generic Desktop */
293
        0x09, 0x38, /* Usage Wheel */
294
        0x15, 0x81, /* Logical Minimum -127 */
295
        0x25, 0x7F, /* Logical Maximum 127 */
296
        0x35, 0x00, /* Physical Minimum 0 (same as logical) */
297
        0x45, 0x00, /* Physical Maximum 0 (same as logical) */
298
        0x75, 0x08, /* Report Size 8 */
299
        0x95, 0x01, /* Report Count 1 */
300
        0x81, 0x02, /* Input (Data, Var, Rel) */
301
        0xC0,       /* End Collection */
302
        0xC0,       /* End Collection */
303
};
304

    
305
static const uint8_t qemu_keyboard_hid_report_descriptor[] = {
306
    0x05, 0x01,                /* Usage Page (Generic Desktop) */
307
    0x09, 0x06,                /* Usage (Keyboard) */
308
    0xa1, 0x01,                /* Collection (Application) */
309
    0x75, 0x01,                /*   Report Size (1) */
310
    0x95, 0x08,                /*   Report Count (8) */
311
    0x05, 0x07,                /*   Usage Page (Key Codes) */
312
    0x19, 0xe0,                /*   Usage Minimum (224) */
313
    0x29, 0xe7,                /*   Usage Maximum (231) */
314
    0x15, 0x00,                /*   Logical Minimum (0) */
315
    0x25, 0x01,                /*   Logical Maximum (1) */
316
    0x81, 0x02,                /*   Input (Data, Variable, Absolute) */
317
    0x95, 0x01,                /*   Report Count (1) */
318
    0x75, 0x08,                /*   Report Size (8) */
319
    0x81, 0x01,                /*   Input (Constant) */
320
    0x95, 0x05,                /*   Report Count (5) */
321
    0x75, 0x01,                /*   Report Size (1) */
322
    0x05, 0x08,                /*   Usage Page (LEDs) */
323
    0x19, 0x01,                /*   Usage Minimum (1) */
324
    0x29, 0x05,                /*   Usage Maximum (5) */
325
    0x91, 0x02,                /*   Output (Data, Variable, Absolute) */
326
    0x95, 0x01,                /*   Report Count (1) */
327
    0x75, 0x03,                /*   Report Size (3) */
328
    0x91, 0x01,                /*   Output (Constant) */
329
    0x95, 0x06,                /*   Report Count (6) */
330
    0x75, 0x08,                /*   Report Size (8) */
331
    0x15, 0x00,                /*   Logical Minimum (0) */
332
    0x25, 0xff,                /*   Logical Maximum (255) */
333
    0x05, 0x07,                /*   Usage Page (Key Codes) */
334
    0x19, 0x00,                /*   Usage Minimum (0) */
335
    0x29, 0xff,                /*   Usage Maximum (255) */
336
    0x81, 0x00,                /*   Input (Data, Array) */
337
    0xc0,                /* End Collection */
338
};
339

    
340
#define USB_HID_USAGE_ERROR_ROLLOVER        0x01
341
#define USB_HID_USAGE_POSTFAIL                0x02
342
#define USB_HID_USAGE_ERROR_UNDEFINED        0x03
343

    
344
/* Indices are QEMU keycodes, values are from HID Usage Table.  Indices
345
 * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d.  */
346
static const uint8_t usb_hid_usage_keys[0x100] = {
347
    0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
348
    0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
349
    0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
350
    0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
351
    0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
352
    0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
353
    0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
354
    0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
355
    0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
356
    0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
357
    0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
358
    0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
359
    0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
360
    0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
361
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362
    0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
363

    
364
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
366
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367
    0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
368
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370
    0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
371
    0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372
    0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
373
    0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
374
    0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
375
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380
};
381

    
382
static void usb_mouse_event(void *opaque,
383
                            int dx1, int dy1, int dz1, int buttons_state)
384
{
385
    USBMouseState *s = opaque;
386

    
387
    s->dx += dx1;
388
    s->dy += dy1;
389
    s->dz += dz1;
390
    s->buttons_state = buttons_state;
391
}
392

    
393
static void usb_tablet_event(void *opaque,
394
                             int x, int y, int dz, int buttons_state)
395
{
396
    USBMouseState *s = opaque;
397

    
398
    s->x = x;
399
    s->y = y;
400
    s->dz += dz;
401
    s->buttons_state = buttons_state;
402
}
403

    
404
static void usb_keyboard_event(void *opaque, int keycode)
405
{
406
    USBKeyboardState *s = opaque;
407
    uint8_t hid_code, key;
408
    int i;
409

    
410
    key = keycode & 0x7f;
411
    hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))];
412
    s->modifiers &= ~(1 << 8);
413

    
414
    switch (hid_code) {
415
    case 0x00:
416
        return;
417

    
418
    case 0xe0:
419
        if (s->modifiers & (1 << 9)) {
420
            s->modifiers ^= 3 << 8;
421
            return;
422
        }
423
    case 0xe1 ... 0xe7:
424
        if (keycode & (1 << 7)) {
425
            s->modifiers &= ~(1 << (hid_code & 0x0f));
426
            return;
427
        }
428
    case 0xe8 ... 0xef:
429
        s->modifiers |= 1 << (hid_code & 0x0f);
430
        return;
431
    }
432

    
433
    if (keycode & (1 << 7)) {
434
        for (i = s->keys - 1; i >= 0; i --)
435
            if (s->key[i] == hid_code) {
436
                s->key[i] = s->key[-- s->keys];
437
                s->key[s->keys] = 0x00;
438
                return;
439
            }
440
    } else {
441
        for (i = s->keys - 1; i >= 0; i --)
442
            if (s->key[i] == hid_code)
443
                return;
444
        if (s->keys < sizeof(s->key))
445
            s->key[s->keys ++] = hid_code;
446
    }
447
}
448

    
449
static inline int int_clamp(int val, int vmin, int vmax)
450
{
451
    if (val < vmin)
452
        return vmin;
453
    else if (val > vmax)
454
        return vmax;
455
    else
456
        return val;
457
}
458

    
459
static int usb_mouse_poll(USBMouseState *s, uint8_t *buf, int len)
460
{
461
    int dx, dy, dz, b, l;
462

    
463
    if (!s->mouse_grabbed) {
464
        s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, s,
465
                                                  0, "QEMU USB Mouse");
466
        s->mouse_grabbed = 1;
467
    }
468
    
469
    dx = int_clamp(s->dx, -128, 127);
470
    dy = int_clamp(s->dy, -128, 127);
471
    dz = int_clamp(s->dz, -128, 127);
472

    
473
    s->dx -= dx;
474
    s->dy -= dy;
475
    s->dz -= dz;
476
    
477
    b = 0;
478
    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
479
        b |= 0x01;
480
    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
481
        b |= 0x02;
482
    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
483
        b |= 0x04;
484
    
485
    buf[0] = b;
486
    buf[1] = dx;
487
    buf[2] = dy;
488
    l = 3;
489
    if (len >= 4) {
490
        buf[3] = dz;
491
        l = 4;
492
    }
493
    return l;
494
}
495

    
496
static int usb_tablet_poll(USBMouseState *s, uint8_t *buf, int len)
497
{
498
    int dz, b, l;
499

    
500
    if (!s->mouse_grabbed) {
501
        s->eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, s,
502
                                                  1, "QEMU USB Tablet");
503
        s->mouse_grabbed = 1;
504
    }
505
    
506
    dz = int_clamp(s->dz, -128, 127);
507
    s->dz -= dz;
508

    
509
    /* Appears we have to invert the wheel direction */
510
    dz = 0 - dz;
511
    b = 0;
512
    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
513
        b |= 0x01;
514
    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
515
        b |= 0x02;
516
    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
517
        b |= 0x04;
518

    
519
    buf[0] = b;
520
    buf[1] = s->x & 0xff;
521
    buf[2] = s->x >> 8;
522
    buf[3] = s->y & 0xff;
523
    buf[4] = s->y >> 8;
524
    buf[5] = dz;
525
    l = 6;
526

    
527
    return l;
528
}
529

    
530
static int usb_keyboard_poll(USBKeyboardState *s, uint8_t *buf, int len)
531
{
532
    if (len < 2)
533
        return 0;
534

    
535
    buf[0] = s->modifiers & 0xff;
536
    buf[1] = 0;
537
    if (s->keys > 6)
538
        memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
539
    else
540
        memcpy(buf + 2, s->key, MIN(8, len) - 2);
541

    
542
    return MIN(8, len);
543
}
544

    
545
static int usb_keyboard_write(USBKeyboardState *s, uint8_t *buf, int len)
546
{
547
    if (len > 0) {
548
        /* 0x01: Num Lock LED
549
         * 0x02: Caps Lock LED
550
         * 0x04: Scroll Lock LED
551
         * 0x08: Compose LED
552
         * 0x10: Kana LED */
553
        s->leds = buf[0];
554
    }
555
    return 0;
556
}
557

    
558
static void usb_mouse_handle_reset(USBDevice *dev)
559
{
560
    USBHIDState *s = (USBHIDState *)dev;
561

    
562
    s->ptr.dx = 0;
563
    s->ptr.dy = 0;
564
    s->ptr.dz = 0;
565
    s->ptr.x = 0;
566
    s->ptr.y = 0;
567
    s->ptr.buttons_state = 0;
568
    s->protocol = 1;
569
}
570

    
571
static void usb_keyboard_handle_reset(USBDevice *dev)
572
{
573
    USBHIDState *s = (USBHIDState *)dev;
574

    
575
    qemu_add_kbd_event_handler(usb_keyboard_event, &s->kbd);
576
    s->protocol = 1;
577
}
578

    
579
static int usb_hid_handle_control(USBDevice *dev, int request, int value,
580
                                  int index, int length, uint8_t *data)
581
{
582
    USBHIDState *s = (USBHIDState *)dev;
583
    int ret = 0;
584

    
585
    switch(request) {
586
    case DeviceRequest | USB_REQ_GET_STATUS:
587
        data[0] = (1 << USB_DEVICE_SELF_POWERED) |
588
            (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
589
        data[1] = 0x00;
590
        ret = 2;
591
        break;
592
    case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
593
        if (value == USB_DEVICE_REMOTE_WAKEUP) {
594
            dev->remote_wakeup = 0;
595
        } else {
596
            goto fail;
597
        }
598
        ret = 0;
599
        break;
600
    case DeviceOutRequest | USB_REQ_SET_FEATURE:
601
        if (value == USB_DEVICE_REMOTE_WAKEUP) {
602
            dev->remote_wakeup = 1;
603
        } else {
604
            goto fail;
605
        }
606
        ret = 0;
607
        break;
608
    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
609
        dev->addr = value;
610
        ret = 0;
611
        break;
612
    case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
613
        switch(value >> 8) {
614
        case USB_DT_DEVICE:
615
            memcpy(data, qemu_mouse_dev_descriptor, 
616
                   sizeof(qemu_mouse_dev_descriptor));
617
            ret = sizeof(qemu_mouse_dev_descriptor);
618
            break;
619
        case USB_DT_CONFIG:
620
            if (s->kind == USB_MOUSE) {
621
                memcpy(data, qemu_mouse_config_descriptor, 
622
                       sizeof(qemu_mouse_config_descriptor));
623
                ret = sizeof(qemu_mouse_config_descriptor);
624
            } else if (s->kind == USB_TABLET) {
625
                memcpy(data, qemu_tablet_config_descriptor, 
626
                       sizeof(qemu_tablet_config_descriptor));
627
                ret = sizeof(qemu_tablet_config_descriptor);
628
            } else if (s->kind == USB_KEYBOARD) {
629
                memcpy(data, qemu_keyboard_config_descriptor, 
630
                       sizeof(qemu_keyboard_config_descriptor));
631
                ret = sizeof(qemu_keyboard_config_descriptor);
632
            }
633
            break;
634
        case USB_DT_STRING:
635
            switch(value & 0xff) {
636
            case 0:
637
                /* language ids */
638
                data[0] = 4;
639
                data[1] = 3;
640
                data[2] = 0x09;
641
                data[3] = 0x04;
642
                ret = 4;
643
                break;
644
            case 1:
645
                /* serial number */
646
                ret = set_usb_string(data, "1");
647
                break;
648
            case 2:
649
                /* product description */
650
                ret = set_usb_string(data, s->dev.devname);
651
                break;
652
            case 3:
653
                /* vendor description */
654
                ret = set_usb_string(data, "QEMU " QEMU_VERSION);
655
                break;
656
            case 4:
657
                ret = set_usb_string(data, "HID Mouse");
658
                break;
659
            case 5:
660
                ret = set_usb_string(data, "HID Tablet");
661
                break;
662
            case 6:
663
                ret = set_usb_string(data, "HID Keyboard");
664
                break;
665
            case 7:
666
                ret = set_usb_string(data, "Endpoint1 Interrupt Pipe");
667
                break;
668
            default:
669
                goto fail;
670
            }
671
            break;
672
        default:
673
            goto fail;
674
        }
675
        break;
676
    case DeviceRequest | USB_REQ_GET_CONFIGURATION:
677
        data[0] = 1;
678
        ret = 1;
679
        break;
680
    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
681
        ret = 0;
682
        break;
683
    case DeviceRequest | USB_REQ_GET_INTERFACE:
684
        data[0] = 0;
685
        ret = 1;
686
        break;
687
    case DeviceOutRequest | USB_REQ_SET_INTERFACE:
688
        ret = 0;
689
        break;
690
        /* hid specific requests */
691
    case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
692
        switch(value >> 8) {
693
        case 0x22:
694
            if (s->kind == USB_MOUSE) {
695
                memcpy(data, qemu_mouse_hid_report_descriptor, 
696
                       sizeof(qemu_mouse_hid_report_descriptor));
697
                ret = sizeof(qemu_mouse_hid_report_descriptor);
698
            } else if (s->kind == USB_TABLET) {
699
                memcpy(data, qemu_tablet_hid_report_descriptor, 
700
                       sizeof(qemu_tablet_hid_report_descriptor));
701
                ret = sizeof(qemu_tablet_hid_report_descriptor);
702
            } else if (s->kind == USB_KEYBOARD) {
703
                memcpy(data, qemu_keyboard_hid_report_descriptor, 
704
                       sizeof(qemu_keyboard_hid_report_descriptor));
705
                ret = sizeof(qemu_keyboard_hid_report_descriptor);
706
            }
707
            break;
708
        default:
709
            goto fail;
710
        }
711
        break;
712
    case GET_REPORT:
713
        if (s->kind == USB_MOUSE)
714
            ret = usb_mouse_poll(&s->ptr, data, length);
715
        else if (s->kind == USB_TABLET)
716
            ret = usb_tablet_poll(&s->ptr, data, length);
717
        else if (s->kind == USB_KEYBOARD)
718
            ret = usb_keyboard_poll(&s->kbd, data, length);
719
        break;
720
    case SET_REPORT:
721
        if (s->kind == USB_KEYBOARD)
722
            ret = usb_keyboard_write(&s->kbd, data, length);
723
        else
724
            goto fail;
725
        break;
726
    case GET_PROTOCOL:
727
        if (s->kind != USB_KEYBOARD)
728
            goto fail;
729
        ret = 1;
730
        data[0] = s->protocol;
731
        break;
732
    case SET_PROTOCOL:
733
        if (s->kind != USB_KEYBOARD)
734
            goto fail;
735
        ret = 0;
736
        s->protocol = value;
737
        break;
738
    case GET_IDLE:
739
        ret = 1;
740
        data[0] = s->idle;
741
        break;
742
    case SET_IDLE:
743
        s->idle = value;
744
        ret = 0;
745
        break;
746
    default:
747
    fail:
748
        ret = USB_RET_STALL;
749
        break;
750
    }
751
    return ret;
752
}
753

    
754
static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
755
{
756
    USBHIDState *s = (USBHIDState *)dev;
757
    int ret = 0;
758

    
759
    switch(p->pid) {
760
    case USB_TOKEN_IN:
761
        if (p->devep == 1) {
762
            if (s->kind == USB_MOUSE)
763
                ret = usb_mouse_poll(&s->ptr, p->data, p->len);
764
            else if (s->kind == USB_TABLET)
765
                ret = usb_tablet_poll(&s->ptr, p->data, p->len);
766
            else if (s->kind == USB_KEYBOARD)
767
                ret = usb_keyboard_poll(&s->kbd, p->data, p->len);
768
        } else {
769
            goto fail;
770
        }
771
        break;
772
    case USB_TOKEN_OUT:
773
    default:
774
    fail:
775
        ret = USB_RET_STALL;
776
        break;
777
    }
778
    return ret;
779
}
780

    
781
static void usb_hid_handle_destroy(USBDevice *dev)
782
{
783
    USBHIDState *s = (USBHIDState *)dev;
784

    
785
    if (s->kind != USB_KEYBOARD)
786
        qemu_remove_mouse_event_handler(s->ptr.eh_entry);
787
    /* TODO: else */
788
    qemu_free(s);
789
}
790

    
791
USBDevice *usb_tablet_init(void)
792
{
793
    USBHIDState *s;
794

    
795
    s = qemu_mallocz(sizeof(USBHIDState));
796
    if (!s)
797
        return NULL;
798
    s->dev.speed = USB_SPEED_FULL;
799
    s->dev.handle_packet = usb_generic_handle_packet;
800

    
801
    s->dev.handle_reset = usb_mouse_handle_reset;
802
    s->dev.handle_control = usb_hid_handle_control;
803
    s->dev.handle_data = usb_hid_handle_data;
804
    s->dev.handle_destroy = usb_hid_handle_destroy;
805
    s->kind = USB_TABLET;
806

    
807
    pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
808

    
809
    return (USBDevice *)s;
810
}
811

    
812
USBDevice *usb_mouse_init(void)
813
{
814
    USBHIDState *s;
815

    
816
    s = qemu_mallocz(sizeof(USBHIDState));
817
    if (!s)
818
        return NULL;
819
    s->dev.speed = USB_SPEED_FULL;
820
    s->dev.handle_packet = usb_generic_handle_packet;
821

    
822
    s->dev.handle_reset = usb_mouse_handle_reset;
823
    s->dev.handle_control = usb_hid_handle_control;
824
    s->dev.handle_data = usb_hid_handle_data;
825
    s->dev.handle_destroy = usb_hid_handle_destroy;
826
    s->kind = USB_MOUSE;
827

    
828
    pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
829

    
830
    return (USBDevice *)s;
831
}
832

    
833
USBDevice *usb_keyboard_init(void)
834
{
835
    USBHIDState *s;
836

    
837
    s = qemu_mallocz(sizeof(USBHIDState));
838
    if (!s)
839
        return NULL;
840
    s->dev.speed = USB_SPEED_FULL;
841
    s->dev.handle_packet = usb_generic_handle_packet;
842

    
843
    s->dev.handle_reset = usb_keyboard_handle_reset;
844
    s->dev.handle_control = usb_hid_handle_control;
845
    s->dev.handle_data = usb_hid_handle_data;
846
    s->dev.handle_destroy = usb_hid_handle_destroy;
847
    s->kind = USB_KEYBOARD;
848

    
849
    pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Keyboard");
850

    
851
    return (USBDevice *) s;
852
}