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