]> Git Repo - qemu.git/blob - hw/usb-hid.c
Fix range in the hid report descriptor for USB tablet.
[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
29 /* HID interface requests */
30 #define GET_REPORT   0xa101
31 #define GET_IDLE     0xa102
32 #define GET_PROTOCOL 0xa103
33 #define SET_REPORT   0x2109
34 #define SET_IDLE     0x210a
35 #define SET_PROTOCOL 0x210b
36
37 /* HID descriptor types */
38 #define USB_DT_HID    0x21
39 #define USB_DT_REPORT 0x22
40 #define USB_DT_PHY    0x23
41
42 #define USB_MOUSE     1
43 #define USB_TABLET    2
44 #define USB_KEYBOARD  3
45
46 typedef struct USBMouseState {
47     int dx, dy, dz, buttons_state;
48     int x, y;
49     int mouse_grabbed;
50     QEMUPutMouseEntry *eh_entry;
51 } USBMouseState;
52
53 typedef struct USBKeyboardState {
54     uint16_t modifiers;
55     uint8_t leds;
56     uint8_t key[16];
57     int keys;
58 } USBKeyboardState;
59
60 typedef struct USBHIDState {
61     USBDevice dev;
62     union {
63         USBMouseState ptr;
64         USBKeyboardState kbd;
65     };
66     int kind;
67     int protocol;
68     int idle;
69     int changed;
70 } USBHIDState;
71
72 /* mostly the same values as the Bochs USB Mouse device */
73 static const uint8_t qemu_mouse_dev_descriptor[] = {
74         0x12,       /*  u8 bLength; */
75         0x01,       /*  u8 bDescriptorType; Device */
76         0x00, 0x01, /*  u16 bcdUSB; v1.0 */
77
78         0x00,       /*  u8  bDeviceClass; */
79         0x00,       /*  u8  bDeviceSubClass; */
80         0x00,       /*  u8  bDeviceProtocol; [ low/full speeds only ] */
81         0x08,       /*  u8  bMaxPacketSize0; 8 Bytes */
82
83         0x27, 0x06, /*  u16 idVendor; */
84         0x01, 0x00, /*  u16 idProduct; */
85         0x00, 0x00, /*  u16 bcdDevice */
86
87         0x03,       /*  u8  iManufacturer; */
88         0x02,       /*  u8  iProduct; */
89         0x01,       /*  u8  iSerialNumber; */
90         0x01        /*  u8  bNumConfigurations; */
91 };
92
93 static const uint8_t qemu_mouse_config_descriptor[] = {
94         /* one configuration */
95         0x09,       /*  u8  bLength; */
96         0x02,       /*  u8  bDescriptorType; Configuration */
97         0x22, 0x00, /*  u16 wTotalLength; */
98         0x01,       /*  u8  bNumInterfaces; (1) */
99         0x01,       /*  u8  bConfigurationValue; */
100         0x04,       /*  u8  iConfiguration; */
101         0xa0,       /*  u8  bmAttributes;
102                                  Bit 7: must be set,
103                                      6: Self-powered,
104                                      5: Remote wakeup,
105                                      4..0: resvd */
106         50,         /*  u8  MaxPower; */
107
108         /* USB 1.1:
109          * USB 2.0, single TT organization (mandatory):
110          *      one interface, protocol 0
111          *
112          * USB 2.0, multiple TT organization (optional):
113          *      two interfaces, protocols 1 (like single TT)
114          *      and 2 (multiple TT mode) ... config is
115          *      sometimes settable
116          *      NOT IMPLEMENTED
117          */
118
119         /* one interface */
120         0x09,       /*  u8  if_bLength; */
121         0x04,       /*  u8  if_bDescriptorType; Interface */
122         0x00,       /*  u8  if_bInterfaceNumber; */
123         0x00,       /*  u8  if_bAlternateSetting; */
124         0x01,       /*  u8  if_bNumEndpoints; */
125         0x03,       /*  u8  if_bInterfaceClass; */
126         0x01,       /*  u8  if_bInterfaceSubClass; */
127         0x02,       /*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
128         0x07,       /*  u8  if_iInterface; */
129
130         /* HID descriptor */
131         0x09,        /*  u8  bLength; */
132         0x21,        /*  u8 bDescriptorType; */
133         0x01, 0x00,  /*  u16 HID_class */
134         0x00,        /*  u8 country_code */
135         0x01,        /*  u8 num_descriptors */
136         0x22,        /*  u8 type; Report */
137         52, 0,       /*  u16 len */
138
139         /* one endpoint (status change endpoint) */
140         0x07,       /*  u8  ep_bLength; */
141         0x05,       /*  u8  ep_bDescriptorType; Endpoint */
142         0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
143         0x03,       /*  u8  ep_bmAttributes; Interrupt */
144         0x04, 0x00, /*  u16 ep_wMaxPacketSize; */
145         0x0a,       /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
146 };
147
148 static const uint8_t qemu_tablet_config_descriptor[] = {
149         /* one configuration */
150         0x09,       /*  u8  bLength; */
151         0x02,       /*  u8  bDescriptorType; Configuration */
152         0x22, 0x00, /*  u16 wTotalLength; */
153         0x01,       /*  u8  bNumInterfaces; (1) */
154         0x01,       /*  u8  bConfigurationValue; */
155         0x05,       /*  u8  iConfiguration; */
156         0xa0,       /*  u8  bmAttributes;
157                                  Bit 7: must be set,
158                                      6: Self-powered,
159                                      5: Remote wakeup,
160                                      4..0: resvd */
161         50,         /*  u8  MaxPower; */
162
163         /* USB 1.1:
164          * USB 2.0, single TT organization (mandatory):
165          *      one interface, protocol 0
166          *
167          * USB 2.0, multiple TT organization (optional):
168          *      two interfaces, protocols 1 (like single TT)
169          *      and 2 (multiple TT mode) ... config is
170          *      sometimes settable
171          *      NOT IMPLEMENTED
172          */
173
174         /* one interface */
175         0x09,       /*  u8  if_bLength; */
176         0x04,       /*  u8  if_bDescriptorType; Interface */
177         0x00,       /*  u8  if_bInterfaceNumber; */
178         0x00,       /*  u8  if_bAlternateSetting; */
179         0x01,       /*  u8  if_bNumEndpoints; */
180         0x03,       /*  u8  if_bInterfaceClass; */
181         0x01,       /*  u8  if_bInterfaceSubClass; */
182         0x02,       /*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
183         0x07,       /*  u8  if_iInterface; */
184
185         /* HID descriptor */
186         0x09,        /*  u8  bLength; */
187         0x21,        /*  u8 bDescriptorType; */
188         0x01, 0x00,  /*  u16 HID_class */
189         0x00,        /*  u8 country_code */
190         0x01,        /*  u8 num_descriptors */
191         0x22,        /*  u8 type; Report */
192         74, 0,       /*  u16 len */
193
194         /* one endpoint (status change endpoint) */
195         0x07,       /*  u8  ep_bLength; */
196         0x05,       /*  u8  ep_bDescriptorType; Endpoint */
197         0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
198         0x03,       /*  u8  ep_bmAttributes; Interrupt */
199         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) */
256 };
257
258 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 */
286 };
287
288 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, 0xff, 0x7f,   /*     Logical Maximum (0x7fff) */
310     0x35, 0x00,         /*     Physical Minimum (0) */
311     0x46, 0xff, 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,
403 };
404
405 static void usb_mouse_event(void *opaque,
406                             int dx1, int dy1, int dz1, int buttons_state)
407 {
408     USBHIDState *hs = opaque;
409     USBMouseState *s = &hs->ptr;
410
411     s->dx += dx1;
412     s->dy += dy1;
413     s->dz += dz1;
414     s->buttons_state = buttons_state;
415     hs->changed = 1;
416 }
417
418 static void usb_tablet_event(void *opaque,
419                              int x, int y, int dz, int buttons_state)
420 {
421     USBHIDState *hs = opaque;
422     USBMouseState *s = &hs->ptr;
423
424     s->x = x;
425     s->y = y;
426     s->dz += dz;
427     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 }
478
479 static inline int int_clamp(int val, int vmin, int vmax)
480 {
481     if (val < vmin)
482         return vmin;
483     else if (val > vmax)
484         return vmax;
485     else
486         return val;
487 }
488
489 static int usb_mouse_poll(USBHIDState *hs, uint8_t *buf, int len)
490 {
491     int dx, dy, dz, b, l;
492     USBMouseState *s = &hs->ptr;
493
494     if (!s->mouse_grabbed) {
495         s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, hs,
496                                                   0, "QEMU USB Mouse");
497         s->mouse_grabbed = 1;
498     }
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);
503
504     s->dx -= dx;
505     s->dy -= dy;
506     s->dz -= dz;
507
508     /* Appears we have to invert the wheel direction */
509     dz = 0 - dz;
510
511     b = 0;
512     if (s->buttons_state & MOUSE_EVENT_LBUTTON)
513         b |= 0x01;
514     if (s->buttons_state & MOUSE_EVENT_RBUTTON)
515         b |= 0x02;
516     if (s->buttons_state & MOUSE_EVENT_MBUTTON)
517         b |= 0x04;
518
519     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;
528     return l;
529 }
530
531 static int usb_tablet_poll(USBHIDState *hs, uint8_t *buf, int len)
532 {
533     int dz, b, l;
534     USBMouseState *s = &hs->ptr;
535
536     if (!s->mouse_grabbed) {
537         s->eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, hs,
538                                                   1, "QEMU USB Tablet");
539         s->mouse_grabbed = 1;
540     }
541
542     dz = int_clamp(s->dz, -127, 127);
543     s->dz -= dz;
544
545     /* Appears we have to invert the wheel direction */
546     dz = 0 - dz;
547     b = 0;
548     if (s->buttons_state & MOUSE_EVENT_LBUTTON)
549         b |= 0x01;
550     if (s->buttons_state & MOUSE_EVENT_RBUTTON)
551         b |= 0x02;
552     if (s->buttons_state & MOUSE_EVENT_MBUTTON)
553         b |= 0x04;
554
555     buf[0] = b;
556     buf[1] = s->x & 0xff;
557     buf[2] = s->x >> 8;
558     buf[3] = s->y & 0xff;
559     buf[4] = s->y >> 8;
560     buf[5] = dz;
561     l = 6;
562
563     return l;
564 }
565
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 static void usb_mouse_handle_reset(USBDevice *dev)
595 {
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,
616                                   int index, int length, uint8_t *data)
617 {
618     USBHIDState *s = (USBHIDState *)dev;
619     int ret = 0;
620
621     switch(request) {
622     case DeviceRequest | USB_REQ_GET_STATUS:
623         data[0] = (1 << USB_DEVICE_SELF_POWERED) |
624             (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
625         data[1] = 0x00;
626         ret = 2;
627         break;
628     case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
629         if (value == USB_DEVICE_REMOTE_WAKEUP) {
630             dev->remote_wakeup = 0;
631         } else {
632             goto fail;
633         }
634         ret = 0;
635         break;
636     case DeviceOutRequest | USB_REQ_SET_FEATURE:
637         if (value == USB_DEVICE_REMOTE_WAKEUP) {
638             dev->remote_wakeup = 1;
639         } else {
640             goto fail;
641         }
642         ret = 0;
643         break;
644     case DeviceOutRequest | USB_REQ_SET_ADDRESS:
645         dev->addr = value;
646         ret = 0;
647         break;
648     case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
649         switch(value >> 8) {
650         case USB_DT_DEVICE:
651             memcpy(data, qemu_mouse_dev_descriptor,
652                    sizeof(qemu_mouse_dev_descriptor));
653             ret = sizeof(qemu_mouse_dev_descriptor);
654             break;
655         case USB_DT_CONFIG:
656             if (s->kind == USB_MOUSE) {
657                 memcpy(data, qemu_mouse_config_descriptor,
658                        sizeof(qemu_mouse_config_descriptor));
659                 ret = sizeof(qemu_mouse_config_descriptor);
660             } else if (s->kind == USB_TABLET) {
661                 memcpy(data, qemu_tablet_config_descriptor,
662                        sizeof(qemu_tablet_config_descriptor));
663                 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             }
669             break;
670         case USB_DT_STRING:
671             switch(value & 0xff) {
672             case 0:
673                 /* language ids */
674                 data[0] = 4;
675                 data[1] = 3;
676                 data[2] = 0x09;
677                 data[3] = 0x04;
678                 ret = 4;
679                 break;
680             case 1:
681                 /* serial number */
682                 ret = set_usb_string(data, "1");
683                 break;
684             case 2:
685                 /* product description */
686                 ret = set_usb_string(data, s->dev.devname);
687                 break;
688             case 3:
689                 /* vendor description */
690                 ret = set_usb_string(data, "QEMU " QEMU_VERSION);
691                 break;
692             case 4:
693                 ret = set_usb_string(data, "HID Mouse");
694                 break;
695             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                 ret = set_usb_string(data, "Endpoint1 Interrupt Pipe");
703                 break;
704             default:
705                 goto fail;
706             }
707             break;
708         default:
709             goto fail;
710         }
711         break;
712     case DeviceRequest | USB_REQ_GET_CONFIGURATION:
713         data[0] = 1;
714         ret = 1;
715         break;
716     case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
717         ret = 0;
718         break;
719     case DeviceRequest | USB_REQ_GET_INTERFACE:
720         data[0] = 0;
721         ret = 1;
722         break;
723     case DeviceOutRequest | USB_REQ_SET_INTERFACE:
724         ret = 0;
725         break;
726         /* hid specific requests */
727     case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
728         switch(value >> 8) {
729         case 0x22:
730             if (s->kind == USB_MOUSE) {
731                 memcpy(data, qemu_mouse_hid_report_descriptor,
732                        sizeof(qemu_mouse_hid_report_descriptor));
733                 ret = sizeof(qemu_mouse_hid_report_descriptor);
734             } else if (s->kind == USB_TABLET) {
735                 memcpy(data, qemu_tablet_hid_report_descriptor,
736                        sizeof(qemu_tablet_hid_report_descriptor));
737                 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;
744         default:
745             goto fail;
746         }
747         break;
748     case GET_REPORT:
749         if (s->kind == USB_MOUSE)
750             ret = usb_mouse_poll(s, data, length);
751         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;
777         break;
778     case SET_IDLE:
779         s->idle = value;
780         ret = 0;
781         break;
782     default:
783     fail:
784         ret = USB_RET_STALL;
785         break;
786     }
787     return ret;
788 }
789
790 static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
791 {
792     USBHIDState *s = (USBHIDState *)dev;
793     int ret = 0;
794
795     switch(p->pid) {
796     case USB_TOKEN_IN:
797         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);
808         } else {
809             goto fail;
810         }
811         break;
812     case USB_TOKEN_OUT:
813     default:
814     fail:
815         ret = USB_RET_STALL;
816         break;
817     }
818     return ret;
819 }
820
821 static void usb_hid_handle_destroy(USBDevice *dev)
822 {
823     USBHIDState *s = (USBHIDState *)dev;
824
825     if (s->kind != USB_KEYBOARD)
826         qemu_remove_mouse_event_handler(s->ptr.eh_entry);
827     /* TODO: else */
828     qemu_free(s);
829 }
830
831 USBDevice *usb_tablet_init(void)
832 {
833     USBHIDState *s;
834
835     s = qemu_mallocz(sizeof(USBHIDState));
836     if (!s)
837         return NULL;
838     s->dev.speed = USB_SPEED_FULL;
839     s->dev.handle_packet = usb_generic_handle_packet;
840
841     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;
845     s->kind = USB_TABLET;
846     /* Force poll routine to be run and grab input the first time.  */
847     s->changed = 1;
848
849     pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
850
851     return (USBDevice *)s;
852 }
853
854 USBDevice *usb_mouse_init(void)
855 {
856     USBHIDState *s;
857
858     s = qemu_mallocz(sizeof(USBHIDState));
859     if (!s)
860         return NULL;
861     s->dev.speed = USB_SPEED_FULL;
862     s->dev.handle_packet = usb_generic_handle_packet;
863
864     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;
868     s->kind = USB_MOUSE;
869     /* Force poll routine to be run and grab input the first time.  */
870     s->changed = 1;
871
872     pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
873
874     return (USBDevice *)s;
875 }
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 }
This page took 0.075011 seconds and 4 git commands to generate.