]> Git Repo - qemu.git/blob - hw/usb-hid.c
showing a splash picture when start
[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 "usb-desc.h"
29 #include "qemu-timer.h"
30
31 /* HID interface requests */
32 #define GET_REPORT   0xa101
33 #define GET_IDLE     0xa102
34 #define GET_PROTOCOL 0xa103
35 #define SET_REPORT   0x2109
36 #define SET_IDLE     0x210a
37 #define SET_PROTOCOL 0x210b
38
39 /* HID descriptor types */
40 #define USB_DT_HID    0x21
41 #define USB_DT_REPORT 0x22
42 #define USB_DT_PHY    0x23
43
44 #define USB_MOUSE     1
45 #define USB_TABLET    2
46 #define USB_KEYBOARD  3
47
48 typedef struct USBPointerEvent {
49     int32_t xdx, ydy; /* relative iff it's a mouse, otherwise absolute */
50     int32_t dz, buttons_state;
51 } USBPointerEvent;
52
53 #define QUEUE_LENGTH    16 /* should be enough for a triple-click */
54 #define QUEUE_MASK      (QUEUE_LENGTH-1u)
55 #define QUEUE_INCR(v)   ((v)++, (v) &= QUEUE_MASK)
56
57 typedef struct USBMouseState {
58     USBPointerEvent queue[QUEUE_LENGTH];
59     int mouse_grabbed;
60     QEMUPutMouseEntry *eh_entry;
61 } USBMouseState;
62
63 typedef struct USBKeyboardState {
64     uint32_t keycodes[QUEUE_LENGTH];
65     uint16_t modifiers;
66     uint8_t leds;
67     uint8_t key[16];
68     int32_t keys;
69 } USBKeyboardState;
70
71 typedef struct USBHIDState {
72     USBDevice dev;
73     union {
74         USBMouseState ptr;
75         USBKeyboardState kbd;
76     };
77     uint32_t head; /* index into circular queue */
78     uint32_t n;
79     int kind;
80     int32_t protocol;
81     uint8_t idle;
82     int64_t next_idle_clock;
83     int changed;
84     void *datain_opaque;
85     void (*datain)(void *);
86 } USBHIDState;
87
88 enum {
89     STR_MANUFACTURER = 1,
90     STR_PRODUCT_MOUSE,
91     STR_PRODUCT_TABLET,
92     STR_PRODUCT_KEYBOARD,
93     STR_SERIALNUMBER,
94     STR_CONFIG_MOUSE,
95     STR_CONFIG_TABLET,
96     STR_CONFIG_KEYBOARD,
97 };
98
99 static const USBDescStrings desc_strings = {
100     [STR_MANUFACTURER]     = "QEMU " QEMU_VERSION,
101     [STR_PRODUCT_MOUSE]    = "QEMU USB Mouse",
102     [STR_PRODUCT_TABLET]   = "QEMU USB Tablet",
103     [STR_PRODUCT_KEYBOARD] = "QEMU USB Keyboard",
104     [STR_SERIALNUMBER]     = "42", /* == remote wakeup works */
105     [STR_CONFIG_MOUSE]     = "HID Mouse",
106     [STR_CONFIG_TABLET]    = "HID Tablet",
107     [STR_CONFIG_KEYBOARD]  = "HID Keyboard",
108 };
109
110 static const USBDescIface desc_iface_mouse = {
111     .bInterfaceNumber              = 0,
112     .bNumEndpoints                 = 1,
113     .bInterfaceClass               = USB_CLASS_HID,
114     .bInterfaceSubClass            = 0x01, /* boot */
115     .bInterfaceProtocol            = 0x02,
116     .ndesc                         = 1,
117     .descs = (USBDescOther[]) {
118         {
119             /* HID descriptor */
120             .data = (uint8_t[]) {
121                 0x09,          /*  u8  bLength */
122                 USB_DT_HID,    /*  u8  bDescriptorType */
123                 0x01, 0x00,    /*  u16 HID_class */
124                 0x00,          /*  u8  country_code */
125                 0x01,          /*  u8  num_descriptors */
126                 USB_DT_REPORT, /*  u8  type: Report */
127                 52, 0,         /*  u16 len */
128             },
129         },
130     },
131     .eps = (USBDescEndpoint[]) {
132         {
133             .bEndpointAddress      = USB_DIR_IN | 0x01,
134             .bmAttributes          = USB_ENDPOINT_XFER_INT,
135             .wMaxPacketSize        = 4,
136             .bInterval             = 0x0a,
137         },
138     },
139 };
140
141 static const USBDescIface desc_iface_tablet = {
142     .bInterfaceNumber              = 0,
143     .bNumEndpoints                 = 1,
144     .bInterfaceClass               = USB_CLASS_HID,
145     .bInterfaceProtocol            = 0x02,
146     .ndesc                         = 1,
147     .descs = (USBDescOther[]) {
148         {
149             /* HID descriptor */
150             .data = (uint8_t[]) {
151                 0x09,          /*  u8  bLength */
152                 USB_DT_HID,    /*  u8  bDescriptorType */
153                 0x01, 0x00,    /*  u16 HID_class */
154                 0x00,          /*  u8  country_code */
155                 0x01,          /*  u8  num_descriptors */
156                 USB_DT_REPORT, /*  u8  type: Report */
157                 74, 0,         /*  u16 len */
158             },
159         },
160     },
161     .eps = (USBDescEndpoint[]) {
162         {
163             .bEndpointAddress      = USB_DIR_IN | 0x01,
164             .bmAttributes          = USB_ENDPOINT_XFER_INT,
165             .wMaxPacketSize        = 8,
166             .bInterval             = 0x0a,
167         },
168     },
169 };
170
171 static const USBDescIface desc_iface_keyboard = {
172     .bInterfaceNumber              = 0,
173     .bNumEndpoints                 = 1,
174     .bInterfaceClass               = USB_CLASS_HID,
175     .bInterfaceSubClass            = 0x01, /* boot */
176     .bInterfaceProtocol            = 0x01, /* keyboard */
177     .ndesc                         = 1,
178     .descs = (USBDescOther[]) {
179         {
180             /* HID descriptor */
181             .data = (uint8_t[]) {
182                 0x09,          /*  u8  bLength */
183                 USB_DT_HID,    /*  u8  bDescriptorType */
184                 0x11, 0x01,    /*  u16 HID_class */
185                 0x00,          /*  u8  country_code */
186                 0x01,          /*  u8  num_descriptors */
187                 USB_DT_REPORT, /*  u8  type: Report */
188                 0x3f, 0,       /*  u16 len */
189             },
190         },
191     },
192     .eps = (USBDescEndpoint[]) {
193         {
194             .bEndpointAddress      = USB_DIR_IN | 0x01,
195             .bmAttributes          = USB_ENDPOINT_XFER_INT,
196             .wMaxPacketSize        = 8,
197             .bInterval             = 0x0a,
198         },
199     },
200 };
201
202 static const USBDescDevice desc_device_mouse = {
203     .bcdUSB                        = 0x0100,
204     .bMaxPacketSize0               = 8,
205     .bNumConfigurations            = 1,
206     .confs = (USBDescConfig[]) {
207         {
208             .bNumInterfaces        = 1,
209             .bConfigurationValue   = 1,
210             .iConfiguration        = STR_CONFIG_MOUSE,
211             .bmAttributes          = 0xa0,
212             .bMaxPower             = 50,
213             .nif = 1,
214             .ifs = &desc_iface_mouse,
215         },
216     },
217 };
218
219 static const USBDescDevice desc_device_tablet = {
220     .bcdUSB                        = 0x0100,
221     .bMaxPacketSize0               = 8,
222     .bNumConfigurations            = 1,
223     .confs = (USBDescConfig[]) {
224         {
225             .bNumInterfaces        = 1,
226             .bConfigurationValue   = 1,
227             .iConfiguration        = STR_CONFIG_TABLET,
228             .bmAttributes          = 0xa0,
229             .bMaxPower             = 50,
230             .nif = 1,
231             .ifs = &desc_iface_tablet,
232         },
233     },
234 };
235
236 static const USBDescDevice desc_device_keyboard = {
237     .bcdUSB                        = 0x0100,
238     .bMaxPacketSize0               = 8,
239     .bNumConfigurations            = 1,
240     .confs = (USBDescConfig[]) {
241         {
242             .bNumInterfaces        = 1,
243             .bConfigurationValue   = 1,
244             .iConfiguration        = STR_CONFIG_KEYBOARD,
245             .bmAttributes          = 0xa0,
246             .bMaxPower             = 50,
247             .nif = 1,
248             .ifs = &desc_iface_keyboard,
249         },
250     },
251 };
252
253 static const USBDesc desc_mouse = {
254     .id = {
255         .idVendor          = 0x0627,
256         .idProduct         = 0x0001,
257         .bcdDevice         = 0,
258         .iManufacturer     = STR_MANUFACTURER,
259         .iProduct          = STR_PRODUCT_MOUSE,
260         .iSerialNumber     = STR_SERIALNUMBER,
261     },
262     .full = &desc_device_mouse,
263     .str  = desc_strings,
264 };
265
266 static const USBDesc desc_tablet = {
267     .id = {
268         .idVendor          = 0x0627,
269         .idProduct         = 0x0001,
270         .bcdDevice         = 0,
271         .iManufacturer     = STR_MANUFACTURER,
272         .iProduct          = STR_PRODUCT_TABLET,
273         .iSerialNumber     = STR_SERIALNUMBER,
274     },
275     .full = &desc_device_tablet,
276     .str  = desc_strings,
277 };
278
279 static const USBDesc desc_keyboard = {
280     .id = {
281         .idVendor          = 0x0627,
282         .idProduct         = 0x0001,
283         .bcdDevice         = 0,
284         .iManufacturer     = STR_MANUFACTURER,
285         .iProduct          = STR_PRODUCT_KEYBOARD,
286         .iSerialNumber     = STR_SERIALNUMBER,
287     },
288     .full = &desc_device_keyboard,
289     .str  = desc_strings,
290 };
291
292 static const uint8_t qemu_mouse_hid_report_descriptor[] = {
293     0x05, 0x01,         /* Usage Page (Generic Desktop) */
294     0x09, 0x02,         /* Usage (Mouse) */
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     0x09, 0x38,         /*     Usage (Wheel) */
313     0x15, 0x81,         /*     Logical Minimum (-0x7f) */
314     0x25, 0x7f,         /*     Logical Maximum (0x7f) */
315     0x75, 0x08,         /*     Report Size (8) */
316     0x95, 0x03,         /*     Report Count (3) */
317     0x81, 0x06,         /*     Input (Data, Variable, Relative) */
318     0xc0,               /*   End Collection */
319     0xc0,               /* End Collection */
320 };
321
322 static const uint8_t qemu_tablet_hid_report_descriptor[] = {
323     0x05, 0x01,         /* Usage Page (Generic Desktop) */
324     0x09, 0x01,         /* Usage (Pointer) */
325     0xa1, 0x01,         /* Collection (Application) */
326     0x09, 0x01,         /*   Usage (Pointer) */
327     0xa1, 0x00,         /*   Collection (Physical) */
328     0x05, 0x09,         /*     Usage Page (Button) */
329     0x19, 0x01,         /*     Usage Minimum (1) */
330     0x29, 0x03,         /*     Usage Maximum (3) */
331     0x15, 0x00,         /*     Logical Minimum (0) */
332     0x25, 0x01,         /*     Logical Maximum (1) */
333     0x95, 0x03,         /*     Report Count (3) */
334     0x75, 0x01,         /*     Report Size (1) */
335     0x81, 0x02,         /*     Input (Data, Variable, Absolute) */
336     0x95, 0x01,         /*     Report Count (1) */
337     0x75, 0x05,         /*     Report Size (5) */
338     0x81, 0x01,         /*     Input (Constant) */
339     0x05, 0x01,         /*     Usage Page (Generic Desktop) */
340     0x09, 0x30,         /*     Usage (X) */
341     0x09, 0x31,         /*     Usage (Y) */
342     0x15, 0x00,         /*     Logical Minimum (0) */
343     0x26, 0xff, 0x7f,   /*     Logical Maximum (0x7fff) */
344     0x35, 0x00,         /*     Physical Minimum (0) */
345     0x46, 0xff, 0x7f,   /*     Physical Maximum (0x7fff) */
346     0x75, 0x10,         /*     Report Size (16) */
347     0x95, 0x02,         /*     Report Count (2) */
348     0x81, 0x02,         /*     Input (Data, Variable, Absolute) */
349     0x05, 0x01,         /*     Usage Page (Generic Desktop) */
350     0x09, 0x38,         /*     Usage (Wheel) */
351     0x15, 0x81,         /*     Logical Minimum (-0x7f) */
352     0x25, 0x7f,         /*     Logical Maximum (0x7f) */
353     0x35, 0x00,         /*     Physical Minimum (same as logical) */
354     0x45, 0x00,         /*     Physical Maximum (same as logical) */
355     0x75, 0x08,         /*     Report Size (8) */
356     0x95, 0x01,         /*     Report Count (1) */
357     0x81, 0x06,         /*     Input (Data, Variable, Relative) */
358     0xc0,               /*   End Collection */
359     0xc0,               /* End Collection */
360 };
361
362 static const uint8_t qemu_keyboard_hid_report_descriptor[] = {
363     0x05, 0x01,         /* Usage Page (Generic Desktop) */
364     0x09, 0x06,         /* Usage (Keyboard) */
365     0xa1, 0x01,         /* Collection (Application) */
366     0x75, 0x01,         /*   Report Size (1) */
367     0x95, 0x08,         /*   Report Count (8) */
368     0x05, 0x07,         /*   Usage Page (Key Codes) */
369     0x19, 0xe0,         /*   Usage Minimum (224) */
370     0x29, 0xe7,         /*   Usage Maximum (231) */
371     0x15, 0x00,         /*   Logical Minimum (0) */
372     0x25, 0x01,         /*   Logical Maximum (1) */
373     0x81, 0x02,         /*   Input (Data, Variable, Absolute) */
374     0x95, 0x01,         /*   Report Count (1) */
375     0x75, 0x08,         /*   Report Size (8) */
376     0x81, 0x01,         /*   Input (Constant) */
377     0x95, 0x05,         /*   Report Count (5) */
378     0x75, 0x01,         /*   Report Size (1) */
379     0x05, 0x08,         /*   Usage Page (LEDs) */
380     0x19, 0x01,         /*   Usage Minimum (1) */
381     0x29, 0x05,         /*   Usage Maximum (5) */
382     0x91, 0x02,         /*   Output (Data, Variable, Absolute) */
383     0x95, 0x01,         /*   Report Count (1) */
384     0x75, 0x03,         /*   Report Size (3) */
385     0x91, 0x01,         /*   Output (Constant) */
386     0x95, 0x06,         /*   Report Count (6) */
387     0x75, 0x08,         /*   Report Size (8) */
388     0x15, 0x00,         /*   Logical Minimum (0) */
389     0x25, 0xff,         /*   Logical Maximum (255) */
390     0x05, 0x07,         /*   Usage Page (Key Codes) */
391     0x19, 0x00,         /*   Usage Minimum (0) */
392     0x29, 0xff,         /*   Usage Maximum (255) */
393     0x81, 0x00,         /*   Input (Data, Array) */
394     0xc0,               /* End Collection */
395 };
396
397 #define USB_HID_USAGE_ERROR_ROLLOVER    0x01
398 #define USB_HID_USAGE_POSTFAIL          0x02
399 #define USB_HID_USAGE_ERROR_UNDEFINED   0x03
400
401 /* Indices are QEMU keycodes, values are from HID Usage Table.  Indices
402  * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d.  */
403 static const uint8_t usb_hid_usage_keys[0x100] = {
404     0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
405     0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
406     0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
407     0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
408     0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
409     0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
410     0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
411     0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
412     0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
413     0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
414     0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
415     0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
416     0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
417     0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
418     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
419     0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
420
421     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
423     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424     0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
425     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
426     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
427     0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
428     0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
429     0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
430     0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
431     0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
432     0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 0x00, 0x00,
433     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
434     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
435     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
437 };
438
439 static void usb_hid_changed(USBHIDState *hs)
440 {
441     hs->changed = 1;
442
443     if (hs->datain)
444         hs->datain(hs->datain_opaque);
445
446     usb_wakeup(&hs->dev);
447 }
448
449 static void usb_pointer_event_clear(USBPointerEvent *e, int buttons) {
450     e->xdx = e->ydy = e->dz = 0;
451     e->buttons_state = buttons;
452 }
453
454 static void usb_pointer_event_combine(USBPointerEvent *e, int xyrel,
455                                       int x1, int y1, int z1) {
456     if (xyrel) {
457         e->xdx += x1;
458         e->ydy += y1;
459     } else {
460         e->xdx = x1;
461         e->ydy = y1;
462     }
463     e->dz += z1;
464 }
465
466 static void usb_pointer_event(void *opaque,
467                               int x1, int y1, int z1, int buttons_state)
468 {
469     USBHIDState *hs = opaque;
470     USBMouseState *s = &hs->ptr;
471     unsigned use_slot = (hs->head + hs->n - 1) & QUEUE_MASK;
472     unsigned previous_slot = (use_slot - 1) & QUEUE_MASK;
473
474     /* We combine events where feasible to keep the queue small.  We shouldn't
475      * combine anything with the first event of a particular button state, as
476      * that would change the location of the button state change.  When the
477      * queue is empty, a second event is needed because we don't know if
478      * the first event changed the button state.  */
479     if (hs->n == QUEUE_LENGTH) {
480         /* Queue full.  Discard old button state, combine motion normally.  */
481         s->queue[use_slot].buttons_state = buttons_state;
482     } else if (hs->n < 2 ||
483                s->queue[use_slot].buttons_state != buttons_state ||
484                s->queue[previous_slot].buttons_state != s->queue[use_slot].buttons_state) {
485         /* Cannot or should not combine, so add an empty item to the queue.  */
486         QUEUE_INCR(use_slot);
487         hs->n++;
488         usb_pointer_event_clear(&s->queue[use_slot], buttons_state);
489     }
490     usb_pointer_event_combine(&s->queue[use_slot],
491                               hs->kind == USB_MOUSE,
492                               x1, y1, z1);
493     usb_hid_changed(hs);
494 }
495
496 static void usb_keyboard_event(void *opaque, int keycode)
497 {
498     USBHIDState *hs = opaque;
499     USBKeyboardState *s = &hs->kbd;
500     int slot;
501
502     if (hs->n == QUEUE_LENGTH) {
503         fprintf(stderr, "usb-kbd: warning: key event queue full\n");
504         return;
505     }
506     slot = (hs->head + hs->n) & QUEUE_MASK; hs->n++;
507     s->keycodes[slot] = keycode;
508     usb_hid_changed(hs);
509 }
510
511 static void usb_keyboard_process_keycode(USBHIDState *hs)
512 {
513     USBKeyboardState *s = &hs->kbd;
514     uint8_t hid_code, key;
515     int i, keycode, slot;
516
517     if (hs->n == 0) {
518         return;
519     }
520     slot = hs->head & QUEUE_MASK; QUEUE_INCR(hs->head); hs->n--;
521     keycode = s->keycodes[slot];
522
523     key = keycode & 0x7f;
524     hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))];
525     s->modifiers &= ~(1 << 8);
526
527     switch (hid_code) {
528     case 0x00:
529         return;
530
531     case 0xe0:
532         if (s->modifiers & (1 << 9)) {
533             s->modifiers ^= 3 << 8;
534             return;
535         }
536     case 0xe1 ... 0xe7:
537         if (keycode & (1 << 7)) {
538             s->modifiers &= ~(1 << (hid_code & 0x0f));
539             return;
540         }
541     case 0xe8 ... 0xef:
542         s->modifiers |= 1 << (hid_code & 0x0f);
543         return;
544     }
545
546     if (keycode & (1 << 7)) {
547         for (i = s->keys - 1; i >= 0; i --)
548             if (s->key[i] == hid_code) {
549                 s->key[i] = s->key[-- s->keys];
550                 s->key[s->keys] = 0x00;
551                 break;
552             }
553         if (i < 0)
554             return;
555     } else {
556         for (i = s->keys - 1; i >= 0; i --)
557             if (s->key[i] == hid_code)
558                 break;
559         if (i < 0) {
560             if (s->keys < sizeof(s->key))
561                 s->key[s->keys ++] = hid_code;
562         } else
563             return;
564     }
565 }
566
567 static inline int int_clamp(int val, int vmin, int vmax)
568 {
569     if (val < vmin)
570         return vmin;
571     else if (val > vmax)
572         return vmax;
573     else
574         return val;
575 }
576
577 static int usb_pointer_poll(USBHIDState *hs, uint8_t *buf, int len)
578 {
579     int dx, dy, dz, b, l;
580     int index;
581     USBMouseState *s = &hs->ptr;
582     USBPointerEvent *e;
583
584     if (!s->mouse_grabbed) {
585         qemu_activate_mouse_event_handler(s->eh_entry);
586         s->mouse_grabbed = 1;
587     }
588
589     /* When the buffer is empty, return the last event.  Relative
590        movements will all be zero.  */
591     index = (hs->n ? hs->head : hs->head - 1);
592     e = &s->queue[index & QUEUE_MASK];
593
594     if (hs->kind == USB_MOUSE) {
595         dx = int_clamp(e->xdx, -127, 127);
596         dy = int_clamp(e->ydy, -127, 127);
597         e->xdx -= dx;
598         e->ydy -= dy;
599     } else {
600         dx = e->xdx;
601         dy = e->ydy;
602     }
603     dz = int_clamp(e->dz, -127, 127);
604     e->dz -= dz;
605
606     b = 0;
607     if (e->buttons_state & MOUSE_EVENT_LBUTTON)
608         b |= 0x01;
609     if (e->buttons_state & MOUSE_EVENT_RBUTTON)
610         b |= 0x02;
611     if (e->buttons_state & MOUSE_EVENT_MBUTTON)
612         b |= 0x04;
613
614     if (hs->n &&
615         !e->dz &&
616         (hs->kind == USB_TABLET || (!e->xdx && !e->ydy))) {
617         /* that deals with this event */
618         QUEUE_INCR(hs->head);
619         hs->n--;
620     }
621
622     /* Appears we have to invert the wheel direction */
623     dz = 0 - dz;
624     l = 0;
625     switch (hs->kind) {
626     case USB_MOUSE:
627         if (len > l)
628             buf[l++] = b;
629         if (len > l)
630             buf[l++] = dx;
631         if (len > l)
632             buf[l++] = dy;
633         if (len > l)
634             buf[l++] = dz;
635         break;
636
637     case USB_TABLET:
638         if (len > l)
639             buf[l++] = b;
640         if (len > l)
641             buf[l++] = dx & 0xff;
642         if (len > l)
643             buf[l++] = dx >> 8;
644         if (len > l)
645             buf[l++] = dy & 0xff;
646         if (len > l)
647             buf[l++] = dy >> 8;
648         if (len > l)
649             buf[l++] = dz;
650         break;
651
652     default:
653         abort();
654     }
655
656     return l;
657 }
658
659 static int usb_keyboard_poll(USBHIDState *hs, uint8_t *buf, int len)
660 {
661     USBKeyboardState *s = &hs->kbd;
662     if (len < 2)
663         return 0;
664
665     usb_keyboard_process_keycode(hs);
666
667     buf[0] = s->modifiers & 0xff;
668     buf[1] = 0;
669     if (s->keys > 6)
670         memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
671     else
672         memcpy(buf + 2, s->key, MIN(8, len) - 2);
673
674     return MIN(8, len);
675 }
676
677 static int usb_keyboard_write(USBKeyboardState *s, uint8_t *buf, int len)
678 {
679     if (len > 0) {
680         int ledstate = 0;
681         /* 0x01: Num Lock LED
682          * 0x02: Caps Lock LED
683          * 0x04: Scroll Lock LED
684          * 0x08: Compose LED
685          * 0x10: Kana LED */
686         s->leds = buf[0];
687         if (s->leds & 0x04)
688             ledstate |= QEMU_SCROLL_LOCK_LED;
689         if (s->leds & 0x01)
690             ledstate |= QEMU_NUM_LOCK_LED;
691         if (s->leds & 0x02)
692             ledstate |= QEMU_CAPS_LOCK_LED;
693         kbd_put_ledstate(ledstate);
694     }
695     return 0;
696 }
697
698 static void usb_mouse_handle_reset(USBDevice *dev)
699 {
700     USBHIDState *s = (USBHIDState *)dev;
701
702     memset(s->ptr.queue, 0, sizeof (s->ptr.queue));
703     s->head = 0;
704     s->n = 0;
705     s->protocol = 1;
706 }
707
708 static void usb_keyboard_handle_reset(USBDevice *dev)
709 {
710     USBHIDState *s = (USBHIDState *)dev;
711
712     qemu_add_kbd_event_handler(usb_keyboard_event, s);
713     memset(s->kbd.keycodes, 0, sizeof (s->kbd.keycodes));
714     s->head = 0;
715     s->n = 0;
716     memset(s->kbd.key, 0, sizeof (s->kbd.key));
717     s->kbd.keys = 0;
718     s->protocol = 1;
719 }
720
721 static void usb_hid_set_next_idle(USBHIDState *s, int64_t curtime)
722 {
723     s->next_idle_clock = curtime + (get_ticks_per_sec() * s->idle * 4) / 1000;
724 }
725
726 static int usb_hid_handle_control(USBDevice *dev, USBPacket *p,
727                int request, int value, int index, int length, uint8_t *data)
728 {
729     USBHIDState *s = (USBHIDState *)dev;
730     int ret;
731
732     ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
733     if (ret >= 0) {
734         return ret;
735     }
736
737     ret = 0;
738     switch(request) {
739     case DeviceRequest | USB_REQ_GET_INTERFACE:
740         data[0] = 0;
741         ret = 1;
742         break;
743     case DeviceOutRequest | USB_REQ_SET_INTERFACE:
744         ret = 0;
745         break;
746         /* hid specific requests */
747     case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
748         switch(value >> 8) {
749         case 0x22:
750             if (s->kind == USB_MOUSE) {
751                 memcpy(data, qemu_mouse_hid_report_descriptor,
752                        sizeof(qemu_mouse_hid_report_descriptor));
753                 ret = sizeof(qemu_mouse_hid_report_descriptor);
754             } else if (s->kind == USB_TABLET) {
755                 memcpy(data, qemu_tablet_hid_report_descriptor,
756                        sizeof(qemu_tablet_hid_report_descriptor));
757                 ret = sizeof(qemu_tablet_hid_report_descriptor);
758             } else if (s->kind == USB_KEYBOARD) {
759                 memcpy(data, qemu_keyboard_hid_report_descriptor,
760                        sizeof(qemu_keyboard_hid_report_descriptor));
761                 ret = sizeof(qemu_keyboard_hid_report_descriptor);
762             }
763             break;
764         default:
765             goto fail;
766         }
767         break;
768     case GET_REPORT:
769         if (s->kind == USB_MOUSE || s->kind == USB_TABLET) {
770             ret = usb_pointer_poll(s, data, length);
771         } else if (s->kind == USB_KEYBOARD) {
772             ret = usb_keyboard_poll(s, data, length);
773         }
774         s->changed = s->n > 0;
775         break;
776     case SET_REPORT:
777         if (s->kind == USB_KEYBOARD)
778             ret = usb_keyboard_write(&s->kbd, data, length);
779         else
780             goto fail;
781         break;
782     case GET_PROTOCOL:
783         if (s->kind != USB_KEYBOARD && s->kind != USB_MOUSE)
784             goto fail;
785         ret = 1;
786         data[0] = s->protocol;
787         break;
788     case SET_PROTOCOL:
789         if (s->kind != USB_KEYBOARD && s->kind != USB_MOUSE)
790             goto fail;
791         ret = 0;
792         s->protocol = value;
793         break;
794     case GET_IDLE:
795         ret = 1;
796         data[0] = s->idle;
797         break;
798     case SET_IDLE:
799         s->idle = (uint8_t) (value >> 8);
800         usb_hid_set_next_idle(s, qemu_get_clock_ns(vm_clock));
801         ret = 0;
802         break;
803     default:
804     fail:
805         ret = USB_RET_STALL;
806         break;
807     }
808     return ret;
809 }
810
811 static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
812 {
813     USBHIDState *s = (USBHIDState *)dev;
814     int ret = 0;
815
816     switch(p->pid) {
817     case USB_TOKEN_IN:
818         if (p->devep == 1) {
819             int64_t curtime = qemu_get_clock_ns(vm_clock);
820             if (!s->changed && (!s->idle || s->next_idle_clock - curtime > 0))
821                 return USB_RET_NAK;
822             usb_hid_set_next_idle(s, curtime);
823             if (s->kind == USB_MOUSE || s->kind == USB_TABLET) {
824                 ret = usb_pointer_poll(s, p->data, p->len);
825             }
826             else if (s->kind == USB_KEYBOARD) {
827                 ret = usb_keyboard_poll(s, p->data, p->len);
828             }
829             s->changed = s->n > 0;
830         } else {
831             goto fail;
832         }
833         break;
834     case USB_TOKEN_OUT:
835     default:
836     fail:
837         ret = USB_RET_STALL;
838         break;
839     }
840     return ret;
841 }
842
843 static void usb_hid_handle_destroy(USBDevice *dev)
844 {
845     USBHIDState *s = (USBHIDState *)dev;
846
847     switch(s->kind) {
848     case USB_KEYBOARD:
849         qemu_remove_kbd_event_handler();
850         break;
851     default:
852         qemu_remove_mouse_event_handler(s->ptr.eh_entry);
853     }
854 }
855
856 static int usb_hid_initfn(USBDevice *dev, int kind)
857 {
858     USBHIDState *s = DO_UPCAST(USBHIDState, dev, dev);
859
860     usb_desc_init(dev);
861     s->kind = kind;
862
863     if (s->kind == USB_MOUSE) {
864         s->ptr.eh_entry = qemu_add_mouse_event_handler(usb_pointer_event, s,
865                                                        0, "QEMU USB Mouse");
866     } else if (s->kind == USB_TABLET) {
867         s->ptr.eh_entry = qemu_add_mouse_event_handler(usb_pointer_event, s,
868                                                        1, "QEMU USB Tablet");
869     }
870
871     /* Force poll routine to be run and grab input the first time.  */
872     s->changed = 1;
873     return 0;
874 }
875
876 static int usb_tablet_initfn(USBDevice *dev)
877 {
878     return usb_hid_initfn(dev, USB_TABLET);
879 }
880
881 static int usb_mouse_initfn(USBDevice *dev)
882 {
883     return usb_hid_initfn(dev, USB_MOUSE);
884 }
885
886 static int usb_keyboard_initfn(USBDevice *dev)
887 {
888     return usb_hid_initfn(dev, USB_KEYBOARD);
889 }
890
891 void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *))
892 {
893     USBHIDState *s = (USBHIDState *)dev;
894
895     s->datain_opaque = opaque;
896     s->datain = datain;
897 }
898
899 static int usb_hid_post_load(void *opaque, int version_id)
900 {
901     USBHIDState *s = opaque;
902
903     if (s->idle) {
904         usb_hid_set_next_idle(s, qemu_get_clock_ns(vm_clock));
905     }
906     return 0;
907 }
908
909 static const VMStateDescription vmstate_usb_ptr_queue = {
910     .name = "usb-ptr-queue",
911     .version_id = 1,
912     .minimum_version_id = 1,
913     .fields = (VMStateField []) {
914         VMSTATE_INT32(xdx, USBPointerEvent),
915         VMSTATE_INT32(ydy, USBPointerEvent),
916         VMSTATE_INT32(dz, USBPointerEvent),
917         VMSTATE_INT32(buttons_state, USBPointerEvent),
918         VMSTATE_END_OF_LIST()
919     }
920 };
921 static const VMStateDescription vmstate_usb_ptr = {
922     .name = "usb-ptr",
923     .version_id = 1,
924     .minimum_version_id = 1,
925     .post_load = usb_hid_post_load,
926     .fields = (VMStateField []) {
927         VMSTATE_USB_DEVICE(dev, USBHIDState),
928         VMSTATE_STRUCT_ARRAY(ptr.queue, USBHIDState, QUEUE_LENGTH, 0,
929                              vmstate_usb_ptr_queue, USBPointerEvent),
930         VMSTATE_UINT32(head, USBHIDState),
931         VMSTATE_UINT32(n, USBHIDState),
932         VMSTATE_INT32(protocol, USBHIDState),
933         VMSTATE_UINT8(idle, USBHIDState),
934         VMSTATE_END_OF_LIST()
935     }
936 };
937
938 static const VMStateDescription vmstate_usb_kbd = {
939     .name = "usb-kbd",
940     .version_id = 1,
941     .minimum_version_id = 1,
942     .post_load = usb_hid_post_load,
943     .fields = (VMStateField []) {
944         VMSTATE_USB_DEVICE(dev, USBHIDState),
945         VMSTATE_UINT32_ARRAY(kbd.keycodes, USBHIDState, QUEUE_LENGTH),
946         VMSTATE_UINT32(head, USBHIDState),
947         VMSTATE_UINT32(n, USBHIDState),
948         VMSTATE_UINT16(kbd.modifiers, USBHIDState),
949         VMSTATE_UINT8(kbd.leds, USBHIDState),
950         VMSTATE_UINT8_ARRAY(kbd.key, USBHIDState, 16),
951         VMSTATE_INT32(kbd.keys, USBHIDState),
952         VMSTATE_INT32(protocol, USBHIDState),
953         VMSTATE_UINT8(idle, USBHIDState),
954         VMSTATE_END_OF_LIST()
955     }
956 };
957
958 static struct USBDeviceInfo hid_info[] = {
959     {
960         .product_desc   = "QEMU USB Tablet",
961         .qdev.name      = "usb-tablet",
962         .usbdevice_name = "tablet",
963         .qdev.size      = sizeof(USBHIDState),
964         .qdev.vmsd      = &vmstate_usb_ptr,
965         .usb_desc       = &desc_tablet,
966         .init           = usb_tablet_initfn,
967         .handle_packet  = usb_generic_handle_packet,
968         .handle_reset   = usb_mouse_handle_reset,
969         .handle_control = usb_hid_handle_control,
970         .handle_data    = usb_hid_handle_data,
971         .handle_destroy = usb_hid_handle_destroy,
972     },{
973         .product_desc   = "QEMU USB Mouse",
974         .qdev.name      = "usb-mouse",
975         .usbdevice_name = "mouse",
976         .qdev.size      = sizeof(USBHIDState),
977         .qdev.vmsd      = &vmstate_usb_ptr,
978         .usb_desc       = &desc_mouse,
979         .init           = usb_mouse_initfn,
980         .handle_packet  = usb_generic_handle_packet,
981         .handle_reset   = usb_mouse_handle_reset,
982         .handle_control = usb_hid_handle_control,
983         .handle_data    = usb_hid_handle_data,
984         .handle_destroy = usb_hid_handle_destroy,
985     },{
986         .product_desc   = "QEMU USB Keyboard",
987         .qdev.name      = "usb-kbd",
988         .usbdevice_name = "keyboard",
989         .qdev.size      = sizeof(USBHIDState),
990         .qdev.vmsd      = &vmstate_usb_kbd,
991         .usb_desc       = &desc_keyboard,
992         .init           = usb_keyboard_initfn,
993         .handle_packet  = usb_generic_handle_packet,
994         .handle_reset   = usb_keyboard_handle_reset,
995         .handle_control = usb_hid_handle_control,
996         .handle_data    = usb_hid_handle_data,
997         .handle_destroy = usb_hid_handle_destroy,
998     },{
999         /* end of list */
1000     }
1001 };
1002
1003 static void usb_hid_register_devices(void)
1004 {
1005     usb_qdev_register_many(hid_info);
1006 }
1007 device_init(usb_hid_register_devices)
This page took 0.08843 seconds and 4 git commands to generate.