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