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