]> Git Repo - qemu.git/blob - hw/usb-hid.c
Do constant folding for unary operations.
[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         /* Windows drivers do not like the 0/0 position and ignore such
463          * events. */
464         if (!(x1 | y1)) {
465             x1 = 1;
466         }
467     }
468     e->dz += z1;
469 }
470
471 static void usb_pointer_event(void *opaque,
472                               int x1, int y1, int z1, int buttons_state)
473 {
474     USBHIDState *hs = opaque;
475     USBMouseState *s = &hs->ptr;
476     unsigned use_slot = (hs->head + hs->n - 1) & QUEUE_MASK;
477     unsigned previous_slot = (use_slot - 1) & QUEUE_MASK;
478
479     /* We combine events where feasible to keep the queue small.  We shouldn't
480      * combine anything with the first event of a particular button state, as
481      * that would change the location of the button state change.  When the
482      * queue is empty, a second event is needed because we don't know if
483      * the first event changed the button state.  */
484     if (hs->n == QUEUE_LENGTH) {
485         /* Queue full.  Discard old button state, combine motion normally.  */
486         s->queue[use_slot].buttons_state = buttons_state;
487     } else if (hs->n < 2 ||
488                s->queue[use_slot].buttons_state != buttons_state ||
489                s->queue[previous_slot].buttons_state != s->queue[use_slot].buttons_state) {
490         /* Cannot or should not combine, so add an empty item to the queue.  */
491         QUEUE_INCR(use_slot);
492         hs->n++;
493         usb_pointer_event_clear(&s->queue[use_slot], buttons_state);
494     }
495     usb_pointer_event_combine(&s->queue[use_slot],
496                               hs->kind == USB_MOUSE,
497                               x1, y1, z1);
498     usb_hid_changed(hs);
499 }
500
501 static void usb_keyboard_event(void *opaque, int keycode)
502 {
503     USBHIDState *hs = opaque;
504     USBKeyboardState *s = &hs->kbd;
505     int slot;
506
507     if (hs->n == QUEUE_LENGTH) {
508         fprintf(stderr, "usb-kbd: warning: key event queue full\n");
509         return;
510     }
511     slot = (hs->head + hs->n) & QUEUE_MASK; hs->n++;
512     s->keycodes[slot] = keycode;
513     usb_hid_changed(hs);
514 }
515
516 static void usb_keyboard_process_keycode(USBHIDState *hs)
517 {
518     USBKeyboardState *s = &hs->kbd;
519     uint8_t hid_code, key;
520     int i, keycode, slot;
521
522     if (hs->n == 0) {
523         return;
524     }
525     slot = hs->head & QUEUE_MASK; QUEUE_INCR(hs->head); hs->n--;
526     keycode = s->keycodes[slot];
527
528     key = keycode & 0x7f;
529     hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))];
530     s->modifiers &= ~(1 << 8);
531
532     switch (hid_code) {
533     case 0x00:
534         return;
535
536     case 0xe0:
537         if (s->modifiers & (1 << 9)) {
538             s->modifiers ^= 3 << 8;
539             return;
540         }
541     case 0xe1 ... 0xe7:
542         if (keycode & (1 << 7)) {
543             s->modifiers &= ~(1 << (hid_code & 0x0f));
544             return;
545         }
546     case 0xe8 ... 0xef:
547         s->modifiers |= 1 << (hid_code & 0x0f);
548         return;
549     }
550
551     if (keycode & (1 << 7)) {
552         for (i = s->keys - 1; i >= 0; i --)
553             if (s->key[i] == hid_code) {
554                 s->key[i] = s->key[-- s->keys];
555                 s->key[s->keys] = 0x00;
556                 break;
557             }
558         if (i < 0)
559             return;
560     } else {
561         for (i = s->keys - 1; i >= 0; i --)
562             if (s->key[i] == hid_code)
563                 break;
564         if (i < 0) {
565             if (s->keys < sizeof(s->key))
566                 s->key[s->keys ++] = hid_code;
567         } else
568             return;
569     }
570 }
571
572 static inline int int_clamp(int val, int vmin, int vmax)
573 {
574     if (val < vmin)
575         return vmin;
576     else if (val > vmax)
577         return vmax;
578     else
579         return val;
580 }
581
582 static int usb_pointer_poll(USBHIDState *hs, uint8_t *buf, int len)
583 {
584     int dx, dy, dz, b, l;
585     int index;
586     USBMouseState *s = &hs->ptr;
587     USBPointerEvent *e;
588
589     if (!s->mouse_grabbed) {
590         qemu_activate_mouse_event_handler(s->eh_entry);
591         s->mouse_grabbed = 1;
592     }
593
594     /* When the buffer is empty, return the last event.  Relative
595        movements will all be zero.  */
596     index = (hs->n ? hs->head : hs->head - 1);
597     e = &s->queue[index & QUEUE_MASK];
598
599     if (hs->kind == USB_MOUSE) {
600         dx = int_clamp(e->xdx, -127, 127);
601         dy = int_clamp(e->ydy, -127, 127);
602         e->xdx -= dx;
603         e->ydy -= dy;
604     } else {
605         dx = e->xdx;
606         dy = e->ydy;
607     }
608     dz = int_clamp(e->dz, -127, 127);
609     e->dz -= dz;
610
611     b = 0;
612     if (e->buttons_state & MOUSE_EVENT_LBUTTON)
613         b |= 0x01;
614     if (e->buttons_state & MOUSE_EVENT_RBUTTON)
615         b |= 0x02;
616     if (e->buttons_state & MOUSE_EVENT_MBUTTON)
617         b |= 0x04;
618
619     if (hs->n &&
620         !e->dz &&
621         (hs->kind == USB_TABLET || (!e->xdx && !e->ydy))) {
622         /* that deals with this event */
623         QUEUE_INCR(hs->head);
624         hs->n--;
625     }
626
627     /* Appears we have to invert the wheel direction */
628     dz = 0 - dz;
629     l = 0;
630     switch (hs->kind) {
631     case USB_MOUSE:
632         if (len > l)
633             buf[l++] = b;
634         if (len > l)
635             buf[l++] = dx;
636         if (len > l)
637             buf[l++] = dy;
638         if (len > l)
639             buf[l++] = dz;
640         break;
641
642     case USB_TABLET:
643         if (len > l)
644             buf[l++] = b;
645         if (len > l)
646             buf[l++] = dx & 0xff;
647         if (len > l)
648             buf[l++] = dx >> 8;
649         if (len > l)
650             buf[l++] = dy & 0xff;
651         if (len > l)
652             buf[l++] = dy >> 8;
653         if (len > l)
654             buf[l++] = dz;
655         break;
656
657     default:
658         abort();
659     }
660
661     return l;
662 }
663
664 static int usb_keyboard_poll(USBHIDState *hs, uint8_t *buf, int len)
665 {
666     USBKeyboardState *s = &hs->kbd;
667     if (len < 2)
668         return 0;
669
670     usb_keyboard_process_keycode(hs);
671
672     buf[0] = s->modifiers & 0xff;
673     buf[1] = 0;
674     if (s->keys > 6)
675         memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
676     else
677         memcpy(buf + 2, s->key, MIN(8, len) - 2);
678
679     return MIN(8, len);
680 }
681
682 static int usb_keyboard_write(USBKeyboardState *s, uint8_t *buf, int len)
683 {
684     if (len > 0) {
685         int ledstate = 0;
686         /* 0x01: Num Lock LED
687          * 0x02: Caps Lock LED
688          * 0x04: Scroll Lock LED
689          * 0x08: Compose LED
690          * 0x10: Kana LED */
691         s->leds = buf[0];
692         if (s->leds & 0x04)
693             ledstate |= QEMU_SCROLL_LOCK_LED;
694         if (s->leds & 0x01)
695             ledstate |= QEMU_NUM_LOCK_LED;
696         if (s->leds & 0x02)
697             ledstate |= QEMU_CAPS_LOCK_LED;
698         kbd_put_ledstate(ledstate);
699     }
700     return 0;
701 }
702
703 static void usb_mouse_handle_reset(USBDevice *dev)
704 {
705     USBHIDState *s = (USBHIDState *)dev;
706
707     memset(s->ptr.queue, 0, sizeof (s->ptr.queue));
708     s->head = 0;
709     s->n = 0;
710     s->protocol = 1;
711 }
712
713 static void usb_keyboard_handle_reset(USBDevice *dev)
714 {
715     USBHIDState *s = (USBHIDState *)dev;
716
717     qemu_add_kbd_event_handler(usb_keyboard_event, s);
718     memset(s->kbd.keycodes, 0, sizeof (s->kbd.keycodes));
719     s->head = 0;
720     s->n = 0;
721     memset(s->kbd.key, 0, sizeof (s->kbd.key));
722     s->kbd.keys = 0;
723     s->protocol = 1;
724 }
725
726 static void usb_hid_set_next_idle(USBHIDState *s, int64_t curtime)
727 {
728     s->next_idle_clock = curtime + (get_ticks_per_sec() * s->idle * 4) / 1000;
729 }
730
731 static int usb_hid_handle_control(USBDevice *dev, USBPacket *p,
732                int request, int value, int index, int length, uint8_t *data)
733 {
734     USBHIDState *s = (USBHIDState *)dev;
735     int ret;
736
737     ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
738     if (ret >= 0) {
739         return ret;
740     }
741
742     ret = 0;
743     switch(request) {
744     case DeviceRequest | USB_REQ_GET_INTERFACE:
745         data[0] = 0;
746         ret = 1;
747         break;
748     case DeviceOutRequest | USB_REQ_SET_INTERFACE:
749         ret = 0;
750         break;
751         /* hid specific requests */
752     case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
753         switch(value >> 8) {
754         case 0x22:
755             if (s->kind == USB_MOUSE) {
756                 memcpy(data, qemu_mouse_hid_report_descriptor,
757                        sizeof(qemu_mouse_hid_report_descriptor));
758                 ret = sizeof(qemu_mouse_hid_report_descriptor);
759             } else if (s->kind == USB_TABLET) {
760                 memcpy(data, qemu_tablet_hid_report_descriptor,
761                        sizeof(qemu_tablet_hid_report_descriptor));
762                 ret = sizeof(qemu_tablet_hid_report_descriptor);
763             } else if (s->kind == USB_KEYBOARD) {
764                 memcpy(data, qemu_keyboard_hid_report_descriptor,
765                        sizeof(qemu_keyboard_hid_report_descriptor));
766                 ret = sizeof(qemu_keyboard_hid_report_descriptor);
767             }
768             break;
769         default:
770             goto fail;
771         }
772         break;
773     case GET_REPORT:
774         if (s->kind == USB_MOUSE || s->kind == USB_TABLET) {
775             ret = usb_pointer_poll(s, data, length);
776         } else if (s->kind == USB_KEYBOARD) {
777             ret = usb_keyboard_poll(s, data, length);
778         }
779         s->changed = s->n > 0;
780         break;
781     case SET_REPORT:
782         if (s->kind == USB_KEYBOARD)
783             ret = usb_keyboard_write(&s->kbd, data, length);
784         else
785             goto fail;
786         break;
787     case GET_PROTOCOL:
788         if (s->kind != USB_KEYBOARD && s->kind != USB_MOUSE)
789             goto fail;
790         ret = 1;
791         data[0] = s->protocol;
792         break;
793     case SET_PROTOCOL:
794         if (s->kind != USB_KEYBOARD && s->kind != USB_MOUSE)
795             goto fail;
796         ret = 0;
797         s->protocol = value;
798         break;
799     case GET_IDLE:
800         ret = 1;
801         data[0] = s->idle;
802         break;
803     case SET_IDLE:
804         s->idle = (uint8_t) (value >> 8);
805         usb_hid_set_next_idle(s, qemu_get_clock_ns(vm_clock));
806         ret = 0;
807         break;
808     default:
809     fail:
810         ret = USB_RET_STALL;
811         break;
812     }
813     return ret;
814 }
815
816 static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
817 {
818     USBHIDState *s = (USBHIDState *)dev;
819     int ret = 0;
820
821     switch(p->pid) {
822     case USB_TOKEN_IN:
823         if (p->devep == 1) {
824             int64_t curtime = qemu_get_clock_ns(vm_clock);
825             if (!s->changed && (!s->idle || s->next_idle_clock - curtime > 0))
826                 return USB_RET_NAK;
827             usb_hid_set_next_idle(s, curtime);
828             if (s->kind == USB_MOUSE || s->kind == USB_TABLET) {
829                 ret = usb_pointer_poll(s, p->data, p->len);
830             }
831             else if (s->kind == USB_KEYBOARD) {
832                 ret = usb_keyboard_poll(s, p->data, p->len);
833             }
834             s->changed = s->n > 0;
835         } else {
836             goto fail;
837         }
838         break;
839     case USB_TOKEN_OUT:
840     default:
841     fail:
842         ret = USB_RET_STALL;
843         break;
844     }
845     return ret;
846 }
847
848 static void usb_hid_handle_destroy(USBDevice *dev)
849 {
850     USBHIDState *s = (USBHIDState *)dev;
851
852     switch(s->kind) {
853     case USB_KEYBOARD:
854         qemu_remove_kbd_event_handler();
855         break;
856     default:
857         qemu_remove_mouse_event_handler(s->ptr.eh_entry);
858     }
859 }
860
861 static int usb_hid_initfn(USBDevice *dev, int kind)
862 {
863     USBHIDState *s = DO_UPCAST(USBHIDState, dev, dev);
864
865     usb_desc_init(dev);
866     s->kind = kind;
867
868     if (s->kind == USB_MOUSE) {
869         s->ptr.eh_entry = qemu_add_mouse_event_handler(usb_pointer_event, s,
870                                                        0, "QEMU USB Mouse");
871     } else if (s->kind == USB_TABLET) {
872         s->ptr.eh_entry = qemu_add_mouse_event_handler(usb_pointer_event, s,
873                                                        1, "QEMU USB Tablet");
874     }
875
876     /* Force poll routine to be run and grab input the first time.  */
877     s->changed = 1;
878     return 0;
879 }
880
881 static int usb_tablet_initfn(USBDevice *dev)
882 {
883     return usb_hid_initfn(dev, USB_TABLET);
884 }
885
886 static int usb_mouse_initfn(USBDevice *dev)
887 {
888     return usb_hid_initfn(dev, USB_MOUSE);
889 }
890
891 static int usb_keyboard_initfn(USBDevice *dev)
892 {
893     return usb_hid_initfn(dev, USB_KEYBOARD);
894 }
895
896 void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *))
897 {
898     USBHIDState *s = (USBHIDState *)dev;
899
900     s->datain_opaque = opaque;
901     s->datain = datain;
902 }
903
904 static int usb_hid_post_load(void *opaque, int version_id)
905 {
906     USBHIDState *s = opaque;
907
908     if (s->idle) {
909         usb_hid_set_next_idle(s, qemu_get_clock_ns(vm_clock));
910     }
911     return 0;
912 }
913
914 static const VMStateDescription vmstate_usb_ptr_queue = {
915     .name = "usb-ptr-queue",
916     .version_id = 1,
917     .minimum_version_id = 1,
918     .fields = (VMStateField []) {
919         VMSTATE_INT32(xdx, USBPointerEvent),
920         VMSTATE_INT32(ydy, USBPointerEvent),
921         VMSTATE_INT32(dz, USBPointerEvent),
922         VMSTATE_INT32(buttons_state, USBPointerEvent),
923         VMSTATE_END_OF_LIST()
924     }
925 };
926 static const VMStateDescription vmstate_usb_ptr = {
927     .name = "usb-ptr",
928     .version_id = 1,
929     .minimum_version_id = 1,
930     .post_load = usb_hid_post_load,
931     .fields = (VMStateField []) {
932         VMSTATE_USB_DEVICE(dev, USBHIDState),
933         VMSTATE_STRUCT_ARRAY(ptr.queue, USBHIDState, QUEUE_LENGTH, 0,
934                              vmstate_usb_ptr_queue, USBPointerEvent),
935         VMSTATE_UINT32(head, USBHIDState),
936         VMSTATE_UINT32(n, USBHIDState),
937         VMSTATE_INT32(protocol, USBHIDState),
938         VMSTATE_UINT8(idle, USBHIDState),
939         VMSTATE_END_OF_LIST()
940     }
941 };
942
943 static const VMStateDescription vmstate_usb_kbd = {
944     .name = "usb-kbd",
945     .version_id = 1,
946     .minimum_version_id = 1,
947     .post_load = usb_hid_post_load,
948     .fields = (VMStateField []) {
949         VMSTATE_USB_DEVICE(dev, USBHIDState),
950         VMSTATE_UINT32_ARRAY(kbd.keycodes, USBHIDState, QUEUE_LENGTH),
951         VMSTATE_UINT32(head, USBHIDState),
952         VMSTATE_UINT32(n, USBHIDState),
953         VMSTATE_UINT16(kbd.modifiers, USBHIDState),
954         VMSTATE_UINT8(kbd.leds, USBHIDState),
955         VMSTATE_UINT8_ARRAY(kbd.key, USBHIDState, 16),
956         VMSTATE_INT32(kbd.keys, USBHIDState),
957         VMSTATE_INT32(protocol, USBHIDState),
958         VMSTATE_UINT8(idle, USBHIDState),
959         VMSTATE_END_OF_LIST()
960     }
961 };
962
963 static struct USBDeviceInfo hid_info[] = {
964     {
965         .product_desc   = "QEMU USB Tablet",
966         .qdev.name      = "usb-tablet",
967         .usbdevice_name = "tablet",
968         .qdev.size      = sizeof(USBHIDState),
969         .qdev.vmsd      = &vmstate_usb_ptr,
970         .usb_desc       = &desc_tablet,
971         .init           = usb_tablet_initfn,
972         .handle_packet  = usb_generic_handle_packet,
973         .handle_reset   = usb_mouse_handle_reset,
974         .handle_control = usb_hid_handle_control,
975         .handle_data    = usb_hid_handle_data,
976         .handle_destroy = usb_hid_handle_destroy,
977     },{
978         .product_desc   = "QEMU USB Mouse",
979         .qdev.name      = "usb-mouse",
980         .usbdevice_name = "mouse",
981         .qdev.size      = sizeof(USBHIDState),
982         .qdev.vmsd      = &vmstate_usb_ptr,
983         .usb_desc       = &desc_mouse,
984         .init           = usb_mouse_initfn,
985         .handle_packet  = usb_generic_handle_packet,
986         .handle_reset   = usb_mouse_handle_reset,
987         .handle_control = usb_hid_handle_control,
988         .handle_data    = usb_hid_handle_data,
989         .handle_destroy = usb_hid_handle_destroy,
990     },{
991         .product_desc   = "QEMU USB Keyboard",
992         .qdev.name      = "usb-kbd",
993         .usbdevice_name = "keyboard",
994         .qdev.size      = sizeof(USBHIDState),
995         .qdev.vmsd      = &vmstate_usb_kbd,
996         .usb_desc       = &desc_keyboard,
997         .init           = usb_keyboard_initfn,
998         .handle_packet  = usb_generic_handle_packet,
999         .handle_reset   = usb_keyboard_handle_reset,
1000         .handle_control = usb_hid_handle_control,
1001         .handle_data    = usb_hid_handle_data,
1002         .handle_destroy = usb_hid_handle_destroy,
1003     },{
1004         /* end of list */
1005     }
1006 };
1007
1008 static void usb_hid_register_devices(void)
1009 {
1010     usb_qdev_register_many(hid_info);
1011 }
1012 device_init(usb_hid_register_devices)
This page took 0.083779 seconds and 4 git commands to generate.