Statistics
| Branch: | Revision:

root / hw / usb-hid.c @ 5fafdf24

History | View | Annotate | Download (26.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 "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
    int changed;
68
} USBHIDState;
69

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
365
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
366
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368
    0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
369
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371
    0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
372
    0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373
    0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
374
    0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
375
    0x51, 0x4e, 0x49, 0x4c, 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
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381
};
382

    
383
static void usb_mouse_event(void *opaque,
384
                            int dx1, int dy1, int dz1, int buttons_state)
385
{
386
    USBHIDState *hs = opaque;
387
    USBMouseState *s = &hs->ptr;
388

    
389
    s->dx += dx1;
390
    s->dy += dy1;
391
    s->dz += dz1;
392
    s->buttons_state = buttons_state;
393
    hs->changed = 1;
394
}
395

    
396
static void usb_tablet_event(void *opaque,
397
                             int x, int y, int dz, int buttons_state)
398
{
399
    USBHIDState *hs = opaque;
400
    USBMouseState *s = &hs->ptr;
401

    
402
    s->x = x;
403
    s->y = y;
404
    s->dz += dz;
405
    s->buttons_state = buttons_state;
406
    hs->changed = 1;
407
}
408

    
409
static void usb_keyboard_event(void *opaque, int keycode)
410
{
411
    USBHIDState *hs = opaque;
412
    USBKeyboardState *s = &hs->kbd;
413
    uint8_t hid_code, key;
414
    int i;
415

    
416
    key = keycode & 0x7f;
417
    hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))];
418
    s->modifiers &= ~(1 << 8);
419

    
420
    hs->changed = 1;
421

    
422
    switch (hid_code) {
423
    case 0x00:
424
        return;
425

    
426
    case 0xe0:
427
        if (s->modifiers & (1 << 9)) {
428
            s->modifiers ^= 3 << 8;
429
            return;
430
        }
431
    case 0xe1 ... 0xe7:
432
        if (keycode & (1 << 7)) {
433
            s->modifiers &= ~(1 << (hid_code & 0x0f));
434
            return;
435
        }
436
    case 0xe8 ... 0xef:
437
        s->modifiers |= 1 << (hid_code & 0x0f);
438
        return;
439
    }
440

    
441
    if (keycode & (1 << 7)) {
442
        for (i = s->keys - 1; i >= 0; i --)
443
            if (s->key[i] == hid_code) {
444
                s->key[i] = s->key[-- s->keys];
445
                s->key[s->keys] = 0x00;
446
                return;
447
            }
448
    } else {
449
        for (i = s->keys - 1; i >= 0; i --)
450
            if (s->key[i] == hid_code)
451
                return;
452
        if (s->keys < sizeof(s->key))
453
            s->key[s->keys ++] = hid_code;
454
    }
455
}
456

    
457
static inline int int_clamp(int val, int vmin, int vmax)
458
{
459
    if (val < vmin)
460
        return vmin;
461
    else if (val > vmax)
462
        return vmax;
463
    else
464
        return val;
465
}
466

    
467
static int usb_mouse_poll(USBHIDState *hs, uint8_t *buf, int len)
468
{
469
    int dx, dy, dz, b, l;
470
    USBMouseState *s = &hs->ptr;
471

    
472
    if (!s->mouse_grabbed) {
473
        s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, hs,
474
                                                  0, "QEMU USB Mouse");
475
        s->mouse_grabbed = 1;
476
    }
477
   
478
    dx = int_clamp(s->dx, -128, 127);
479
    dy = int_clamp(s->dy, -128, 127);
480
    dz = int_clamp(s->dz, -128, 127);
481

    
482
    s->dx -= dx;
483
    s->dy -= dy;
484
    s->dz -= dz;
485
   
486
    b = 0;
487
    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
488
        b |= 0x01;
489
    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
490
        b |= 0x02;
491
    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
492
        b |= 0x04;
493
   
494
    buf[0] = b;
495
    buf[1] = dx;
496
    buf[2] = dy;
497
    l = 3;
498
    if (len >= 4) {
499
        buf[3] = dz;
500
        l = 4;
501
    }
502
    return l;
503
}
504

    
505
static int usb_tablet_poll(USBHIDState *hs, uint8_t *buf, int len)
506
{
507
    int dz, b, l;
508
    USBMouseState *s = &hs->ptr;
509

    
510
    if (!s->mouse_grabbed) {
511
        s->eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, hs,
512
                                                  1, "QEMU USB Tablet");
513
        s->mouse_grabbed = 1;
514
    }
515
   
516
    dz = int_clamp(s->dz, -128, 127);
517
    s->dz -= dz;
518

    
519
    /* Appears we have to invert the wheel direction */
520
    dz = 0 - dz;
521
    b = 0;
522
    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
523
        b |= 0x01;
524
    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
525
        b |= 0x02;
526
    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
527
        b |= 0x04;
528

    
529
    buf[0] = b;
530
    buf[1] = s->x & 0xff;
531
    buf[2] = s->x >> 8;
532
    buf[3] = s->y & 0xff;
533
    buf[4] = s->y >> 8;
534
    buf[5] = dz;
535
    l = 6;
536

    
537
    return l;
538
}
539

    
540
static int usb_keyboard_poll(USBKeyboardState *s, uint8_t *buf, int len)
541
{
542
    if (len < 2)
543
        return 0;
544

    
545
    buf[0] = s->modifiers & 0xff;
546
    buf[1] = 0;
547
    if (s->keys > 6)
548
        memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
549
    else
550
        memcpy(buf + 2, s->key, MIN(8, len) - 2);
551

    
552
    return MIN(8, len);
553
}
554

    
555
static int usb_keyboard_write(USBKeyboardState *s, uint8_t *buf, int len)
556
{
557
    if (len > 0) {
558
        /* 0x01: Num Lock LED
559
         * 0x02: Caps Lock LED
560
         * 0x04: Scroll Lock LED
561
         * 0x08: Compose LED
562
         * 0x10: Kana LED */
563
        s->leds = buf[0];
564
    }
565
    return 0;
566
}
567

    
568
static void usb_mouse_handle_reset(USBDevice *dev)
569
{
570
    USBHIDState *s = (USBHIDState *)dev;
571

    
572
    s->ptr.dx = 0;
573
    s->ptr.dy = 0;
574
    s->ptr.dz = 0;
575
    s->ptr.x = 0;
576
    s->ptr.y = 0;
577
    s->ptr.buttons_state = 0;
578
    s->protocol = 1;
579
}
580

    
581
static void usb_keyboard_handle_reset(USBDevice *dev)
582
{
583
    USBHIDState *s = (USBHIDState *)dev;
584

    
585
    qemu_add_kbd_event_handler(usb_keyboard_event, &s->kbd);
586
    s->protocol = 1;
587
}
588

    
589
static int usb_hid_handle_control(USBDevice *dev, int request, int value,
590
                                  int index, int length, uint8_t *data)
591
{
592
    USBHIDState *s = (USBHIDState *)dev;
593
    int ret = 0;
594

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

    
764
static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
765
{
766
    USBHIDState *s = (USBHIDState *)dev;
767
    int ret = 0;
768

    
769
    switch(p->pid) {
770
    case USB_TOKEN_IN:
771
        if (p->devep == 1) {
772
            /* TODO: Implement finite idle delays.  */
773
            if (!(s->changed || s->idle))
774
                return USB_RET_NAK;
775
            s->changed = 0;
776
            if (s->kind == USB_MOUSE)
777
                ret = usb_mouse_poll(s, p->data, p->len);
778
            else if (s->kind == USB_TABLET)
779
                ret = usb_tablet_poll(s, p->data, p->len);
780
            else if (s->kind == USB_KEYBOARD)
781
                ret = usb_keyboard_poll(&s->kbd, p->data, p->len);
782
        } else {
783
            goto fail;
784
        }
785
        break;
786
    case USB_TOKEN_OUT:
787
    default:
788
    fail:
789
        ret = USB_RET_STALL;
790
        break;
791
    }
792
    return ret;
793
}
794

    
795
static void usb_hid_handle_destroy(USBDevice *dev)
796
{
797
    USBHIDState *s = (USBHIDState *)dev;
798

    
799
    if (s->kind != USB_KEYBOARD)
800
        qemu_remove_mouse_event_handler(s->ptr.eh_entry);
801
    /* TODO: else */
802
    qemu_free(s);
803
}
804

    
805
USBDevice *usb_tablet_init(void)
806
{
807
    USBHIDState *s;
808

    
809
    s = qemu_mallocz(sizeof(USBHIDState));
810
    if (!s)
811
        return NULL;
812
    s->dev.speed = USB_SPEED_FULL;
813
    s->dev.handle_packet = usb_generic_handle_packet;
814

    
815
    s->dev.handle_reset = usb_mouse_handle_reset;
816
    s->dev.handle_control = usb_hid_handle_control;
817
    s->dev.handle_data = usb_hid_handle_data;
818
    s->dev.handle_destroy = usb_hid_handle_destroy;
819
    s->kind = USB_TABLET;
820
    /* Force poll routine to be run and grab input the first time.  */
821
    s->changed = 1;
822

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

    
825
    return (USBDevice *)s;
826
}
827

    
828
USBDevice *usb_mouse_init(void)
829
{
830
    USBHIDState *s;
831

    
832
    s = qemu_mallocz(sizeof(USBHIDState));
833
    if (!s)
834
        return NULL;
835
    s->dev.speed = USB_SPEED_FULL;
836
    s->dev.handle_packet = usb_generic_handle_packet;
837

    
838
    s->dev.handle_reset = usb_mouse_handle_reset;
839
    s->dev.handle_control = usb_hid_handle_control;
840
    s->dev.handle_data = usb_hid_handle_data;
841
    s->dev.handle_destroy = usb_hid_handle_destroy;
842
    s->kind = USB_MOUSE;
843
    /* Force poll routine to be run and grab input the first time.  */
844
    s->changed = 1;
845

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

    
848
    return (USBDevice *)s;
849
}
850

    
851
USBDevice *usb_keyboard_init(void)
852
{
853
    USBHIDState *s;
854

    
855
    s = qemu_mallocz(sizeof(USBHIDState));
856
    if (!s)
857
        return NULL;
858
    s->dev.speed = USB_SPEED_FULL;
859
    s->dev.handle_packet = usb_generic_handle_packet;
860

    
861
    s->dev.handle_reset = usb_keyboard_handle_reset;
862
    s->dev.handle_control = usb_hid_handle_control;
863
    s->dev.handle_data = usb_hid_handle_data;
864
    s->dev.handle_destroy = usb_hid_handle_destroy;
865
    s->kind = USB_KEYBOARD;
866

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

    
869
    return (USBDevice *) s;
870
}