~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to hw/usb-hid.c

  • Committer: pbrook
  • Date: 2006-10-22 00:18:54 UTC
  • Revision ID: git-v1:e6e5906b6e0a81718066ca43aef57515026c6624
ColdFire target.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2196 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

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