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