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