18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * QEMU USB HID devices
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 2005 Fabrice Bellard
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 2007 OpenMoko, Inc.  (andrew@openedhand.com)
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a copy
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of this software and associated documentation files (the "Software"), to deal
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in the Software without restriction, including without limitation the rights
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * copies of the Software, and to permit persons to whom the Software is
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * furnished to do so, subject to the following conditions:
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The above copyright notice and this permission notice shall be included in
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * all copies or substantial portions of the Software.
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE.
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "hw.h"
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "console.h"
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "usb.h"
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* HID interface requests */
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define GET_REPORT   0xa101
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define GET_IDLE     0xa102
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define GET_PROTOCOL 0xa103
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SET_REPORT   0x2109
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SET_IDLE     0x210a
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SET_PROTOCOL 0x210b
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* HID descriptor types */
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define USB_DT_HID    0x21
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define USB_DT_REPORT 0x22
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define USB_DT_PHY    0x23
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define USB_MOUSE     1
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define USB_TABLET    2
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define USB_KEYBOARD  3
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct USBMouseState {
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int dx, dy, dz, buttons_state;
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int x, y;
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int mouse_grabbed;
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    QEMUPutMouseEntry *eh_entry;
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} USBMouseState;
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct USBKeyboardState {
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint16_t modifiers;
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t leds;
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t key[16];
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int keys;
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} USBKeyboardState;
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct USBHIDState {
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USBDevice dev;
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    union {
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        USBMouseState ptr;
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        USBKeyboardState kbd;
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    };
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int kind;
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int protocol;
685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint8_t idle;
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int changed;
705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *datain_opaque;
715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void (*datain)(void *);
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} USBHIDState;
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* mostly the same values as the Bochs USB Mouse device */
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const uint8_t qemu_mouse_dev_descriptor[] = {
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x12,       /*  u8 bLength; */
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x01,       /*  u8 bDescriptorType; Device */
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x00, 0x01, /*  u16 bcdUSB; v1.0 */
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x00,	    /*  u8  bDeviceClass; */
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x00,	    /*  u8  bDeviceSubClass; */
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x00,       /*  u8  bDeviceProtocol; [ low/full speeds only ] */
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x08,       /*  u8  bMaxPacketSize0; 8 Bytes */
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x27, 0x06, /*  u16 idVendor; */
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 	0x01, 0x00, /*  u16 idProduct; */
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x00, 0x00, /*  u16 bcdDevice */
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x03,       /*  u8  iManufacturer; */
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x02,       /*  u8  iProduct; */
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x01,       /*  u8  iSerialNumber; */
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x01        /*  u8  bNumConfigurations; */
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const uint8_t qemu_mouse_config_descriptor[] = {
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/* one configuration */
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x09,       /*  u8  bLength; */
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x02,       /*  u8  bDescriptorType; Configuration */
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x22, 0x00, /*  u16 wTotalLength; */
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x01,       /*  u8  bNumInterfaces; (1) */
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x01,       /*  u8  bConfigurationValue; */
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x04,       /*  u8  iConfiguration; */
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0xa0,       /*  u8  bmAttributes;
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				 Bit 7: must be set,
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				     6: Self-powered,
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				     5: Remote wakeup,
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				     4..0: resvd */
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	50,         /*  u8  MaxPower; */
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/* USB 1.1:
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * USB 2.0, single TT organization (mandatory):
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *	one interface, protocol 0
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * USB 2.0, multiple TT organization (optional):
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *	two interfaces, protocols 1 (like single TT)
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *	and 2 (multiple TT mode) ... config is
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *	sometimes settable
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *	NOT IMPLEMENTED
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/* one interface */
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x09,       /*  u8  if_bLength; */
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x04,       /*  u8  if_bDescriptorType; Interface */
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x00,       /*  u8  if_bInterfaceNumber; */
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x00,       /*  u8  if_bAlternateSetting; */
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x01,       /*  u8  if_bNumEndpoints; */
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x03,       /*  u8  if_bInterfaceClass; */
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x01,       /*  u8  if_bInterfaceSubClass; */
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x02,       /*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x07,       /*  u8  if_iInterface; */
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* HID descriptor */
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        0x09,        /*  u8  bLength; */
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        0x21,        /*  u8 bDescriptorType; */
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        0x01, 0x00,  /*  u16 HID_class */
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        0x00,        /*  u8 country_code */
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        0x01,        /*  u8 num_descriptors */
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        0x22,        /*  u8 type; Report */
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        52, 0,       /*  u16 len */
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/* one endpoint (status change endpoint) */
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x07,       /*  u8  ep_bLength; */
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x05,       /*  u8  ep_bDescriptorType; Endpoint */
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 	0x03,       /*  u8  ep_bmAttributes; Interrupt */
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 	0x04, 0x00, /*  u16 ep_wMaxPacketSize; */
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x0a,       /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const uint8_t qemu_tablet_config_descriptor[] = {
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/* one configuration */
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x09,       /*  u8  bLength; */
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x02,       /*  u8  bDescriptorType; Configuration */
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x22, 0x00, /*  u16 wTotalLength; */
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x01,       /*  u8  bNumInterfaces; (1) */
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x01,       /*  u8  bConfigurationValue; */
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x05,       /*  u8  iConfiguration; */
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0xa0,       /*  u8  bmAttributes;
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				 Bit 7: must be set,
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				     6: Self-powered,
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				     5: Remote wakeup,
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				     4..0: resvd */
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	50,         /*  u8  MaxPower; */
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/* USB 1.1:
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * USB 2.0, single TT organization (mandatory):
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *	one interface, protocol 0
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * USB 2.0, multiple TT organization (optional):
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *	two interfaces, protocols 1 (like single TT)
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *	and 2 (multiple TT mode) ... config is
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *	sometimes settable
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *	NOT IMPLEMENTED
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/* one interface */
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x09,       /*  u8  if_bLength; */
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x04,       /*  u8  if_bDescriptorType; Interface */
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x00,       /*  u8  if_bInterfaceNumber; */
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x00,       /*  u8  if_bAlternateSetting; */
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x01,       /*  u8  if_bNumEndpoints; */
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x03,       /*  u8  if_bInterfaceClass; */
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x01,       /*  u8  if_bInterfaceSubClass; */
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x02,       /*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x07,       /*  u8  if_iInterface; */
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* HID descriptor */
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        0x09,        /*  u8  bLength; */
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        0x21,        /*  u8 bDescriptorType; */
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        0x01, 0x00,  /*  u16 HID_class */
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        0x00,        /*  u8 country_code */
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        0x01,        /*  u8 num_descriptors */
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        0x22,        /*  u8 type; Report */
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        74, 0,       /*  u16 len */
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/* one endpoint (status change endpoint) */
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x07,       /*  u8  ep_bLength; */
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x05,       /*  u8  ep_bDescriptorType; Endpoint */
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 	0x03,       /*  u8  ep_bmAttributes; Interrupt */
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 	0x08, 0x00, /*  u16 ep_wMaxPacketSize; */
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	0x0a,       /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const uint8_t qemu_keyboard_config_descriptor[] = {
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* one configuration */
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x09,		/*  u8  bLength; */
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USB_DT_CONFIG,	/*  u8  bDescriptorType; Configuration */
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x22, 0x00,		/*  u16 wTotalLength; */
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x01,		/*  u8  bNumInterfaces; (1) */
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x01,		/*  u8  bConfigurationValue; */
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x06,		/*  u8  iConfiguration; */
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0xa0,		/*  u8  bmAttributes;
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				Bit 7: must be set,
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				    6: Self-powered,
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				    5: Remote wakeup,
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				    4..0: resvd */
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x32,		/*  u8  MaxPower; */
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* USB 1.1:
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * USB 2.0, single TT organization (mandatory):
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     *	one interface, protocol 0
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     *
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * USB 2.0, multiple TT organization (optional):
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     *	two interfaces, protocols 1 (like single TT)
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     *	and 2 (multiple TT mode) ... config is
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     *	sometimes settable
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     *	NOT IMPLEMENTED
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     */
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* one interface */
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x09,		/*  u8  if_bLength; */
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USB_DT_INTERFACE,	/*  u8  if_bDescriptorType; Interface */
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00,		/*  u8  if_bInterfaceNumber; */
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00,		/*  u8  if_bAlternateSetting; */
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x01,		/*  u8  if_bNumEndpoints; */
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x03,		/*  u8  if_bInterfaceClass; HID */
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x01,		/*  u8  if_bInterfaceSubClass; Boot */
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x01,		/*  u8  if_bInterfaceProtocol; Keyboard */
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x07,		/*  u8  if_iInterface; */
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* HID descriptor */
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x09,		/*  u8  bLength; */
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USB_DT_HID,		/*  u8  bDescriptorType; */
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x11, 0x01,		/*  u16 HID_class */
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00,		/*  u8  country_code */
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x01,		/*  u8  num_descriptors */
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USB_DT_REPORT,	/*  u8  type; Report */
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x3f, 0x00,		/*  u16 len */
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* one endpoint (status change endpoint) */
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x07,		/*  u8  ep_bLength; */
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USB_DT_ENDPOINT,	/*  u8  ep_bDescriptorType; Endpoint */
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USB_DIR_IN | 0x01,	/*  u8  ep_bEndpointAddress; IN Endpoint 1 */
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x03,		/*  u8  ep_bmAttributes; Interrupt */
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x08, 0x00,		/*  u16 ep_wMaxPacketSize; */
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x0a,		/*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const uint8_t qemu_mouse_hid_report_descriptor[] = {
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x05, 0x01,		/* Usage Page (Generic Desktop) */
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x09, 0x02,		/* Usage (Mouse) */
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0xa1, 0x01,		/* Collection (Application) */
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x09, 0x01,		/*   Usage (Pointer) */
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0xa1, 0x00,		/*   Collection (Physical) */
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x05, 0x09,		/*     Usage Page (Button) */
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x19, 0x01,		/*     Usage Minimum (1) */
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x29, 0x03,		/*     Usage Maximum (3) */
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x15, 0x00,		/*     Logical Minimum (0) */
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x25, 0x01,		/*     Logical Maximum (1) */
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x95, 0x03,		/*     Report Count (3) */
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x75, 0x01,		/*     Report Size (1) */
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x81, 0x02,		/*     Input (Data, Variable, Absolute) */
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x95, 0x01,		/*     Report Count (1) */
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x75, 0x05,		/*     Report Size (5) */
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x81, 0x01,		/*     Input (Constant) */
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x05, 0x01,		/*     Usage Page (Generic Desktop) */
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x09, 0x30,		/*     Usage (X) */
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x09, 0x31,		/*     Usage (Y) */
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x09, 0x38,		/*     Usage (Wheel) */
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x15, 0x81,		/*     Logical Minimum (-0x7f) */
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x25, 0x7f,		/*     Logical Maximum (0x7f) */
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x75, 0x08,		/*     Report Size (8) */
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x95, 0x03,		/*     Report Count (3) */
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x81, 0x06,		/*     Input (Data, Variable, Relative) */
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0xc0,		/*   End Collection */
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0xc0,		/* End Collection */
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const uint8_t qemu_tablet_hid_report_descriptor[] = {
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x05, 0x01,		/* Usage Page (Generic Desktop) */
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x09, 0x01,		/* Usage (Pointer) */
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0xa1, 0x01,		/* Collection (Application) */
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x09, 0x01,		/*   Usage (Pointer) */
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0xa1, 0x00,		/*   Collection (Physical) */
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x05, 0x09,		/*     Usage Page (Button) */
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x19, 0x01,		/*     Usage Minimum (1) */
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x29, 0x03,		/*     Usage Maximum (3) */
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x15, 0x00,		/*     Logical Minimum (0) */
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x25, 0x01,		/*     Logical Maximum (1) */
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x95, 0x03,		/*     Report Count (3) */
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x75, 0x01,		/*     Report Size (1) */
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x81, 0x02,		/*     Input (Data, Variable, Absolute) */
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x95, 0x01,		/*     Report Count (1) */
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x75, 0x05,		/*     Report Size (5) */
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x81, 0x01,		/*     Input (Constant) */
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x05, 0x01,		/*     Usage Page (Generic Desktop) */
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x09, 0x30,		/*     Usage (X) */
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x09, 0x31,		/*     Usage (Y) */
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x15, 0x00,		/*     Logical Minimum (0) */
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x26, 0xff, 0x7f,	/*     Logical Maximum (0x7fff) */
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x35, 0x00,		/*     Physical Minimum (0) */
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x46, 0xff, 0x7f,	/*     Physical Maximum (0x7fff) */
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x75, 0x10,		/*     Report Size (16) */
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x95, 0x02,		/*     Report Count (2) */
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x81, 0x02,		/*     Input (Data, Variable, Absolute) */
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x05, 0x01,		/*     Usage Page (Generic Desktop) */
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x09, 0x38,		/*     Usage (Wheel) */
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x15, 0x81,		/*     Logical Minimum (-0x7f) */
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x25, 0x7f,		/*     Logical Maximum (0x7f) */
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x35, 0x00,		/*     Physical Minimum (same as logical) */
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x45, 0x00,		/*     Physical Maximum (same as logical) */
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x75, 0x08,		/*     Report Size (8) */
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x95, 0x01,		/*     Report Count (1) */
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x81, 0x06,		/*     Input (Data, Variable, Relative) */
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0xc0,		/*   End Collection */
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0xc0,		/* End Collection */
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const uint8_t qemu_keyboard_hid_report_descriptor[] = {
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x05, 0x01,		/* Usage Page (Generic Desktop) */
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x09, 0x06,		/* Usage (Keyboard) */
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0xa1, 0x01,		/* Collection (Application) */
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x75, 0x01,		/*   Report Size (1) */
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x95, 0x08,		/*   Report Count (8) */
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x05, 0x07,		/*   Usage Page (Key Codes) */
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x19, 0xe0,		/*   Usage Minimum (224) */
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x29, 0xe7,		/*   Usage Maximum (231) */
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x15, 0x00,		/*   Logical Minimum (0) */
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x25, 0x01,		/*   Logical Maximum (1) */
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x81, 0x02,		/*   Input (Data, Variable, Absolute) */
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x95, 0x01,		/*   Report Count (1) */
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x75, 0x08,		/*   Report Size (8) */
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x81, 0x01,		/*   Input (Constant) */
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x95, 0x05,		/*   Report Count (5) */
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x75, 0x01,		/*   Report Size (1) */
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x05, 0x08,		/*   Usage Page (LEDs) */
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x19, 0x01,		/*   Usage Minimum (1) */
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x29, 0x05,		/*   Usage Maximum (5) */
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x91, 0x02,		/*   Output (Data, Variable, Absolute) */
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x95, 0x01,		/*   Report Count (1) */
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x75, 0x03,		/*   Report Size (3) */
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x91, 0x01,		/*   Output (Constant) */
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x95, 0x06,		/*   Report Count (6) */
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x75, 0x08,		/*   Report Size (8) */
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x15, 0x00,		/*   Logical Minimum (0) */
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x25, 0xff,		/*   Logical Maximum (255) */
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x05, 0x07,		/*   Usage Page (Key Codes) */
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x19, 0x00,		/*   Usage Minimum (0) */
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x29, 0xff,		/*   Usage Maximum (255) */
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x81, 0x00,		/*   Input (Data, Array) */
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0xc0,		/* End Collection */
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define USB_HID_USAGE_ERROR_ROLLOVER	0x01
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define USB_HID_USAGE_POSTFAIL		0x02
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define USB_HID_USAGE_ERROR_UNDEFINED	0x03
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Indices are QEMU keycodes, values are from HID Usage Table.  Indices
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d.  */
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const uint8_t usb_hid_usage_keys[0x100] = {
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void usb_hid_changed(USBHIDState *hs)
4085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    hs->changed = 1;
4105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (hs->datain)
4125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        hs->datain(hs->datain_opaque);
4135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void usb_mouse_event(void *opaque,
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            int dx1, int dy1, int dz1, int buttons_state)
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USBHIDState *hs = opaque;
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USBMouseState *s = &hs->ptr;
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dx += dx1;
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dy += dy1;
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dz += dz1;
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->buttons_state = buttons_state;
4255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_hid_changed(hs);
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void usb_tablet_event(void *opaque,
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			     int x, int y, int dz, int buttons_state)
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USBHIDState *hs = opaque;
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USBMouseState *s = &hs->ptr;
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->x = x;
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->y = y;
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dz += dz;
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->buttons_state = buttons_state;
4395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_hid_changed(hs);
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void usb_keyboard_event(void *opaque, int keycode)
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USBHIDState *hs = opaque;
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USBKeyboardState *s = &hs->kbd;
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t hid_code, key;
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    key = keycode & 0x7f;
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))];
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->modifiers &= ~(1 << 8);
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (hid_code) {
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0x00:
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0xe0:
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (s->modifiers & (1 << 9)) {
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->modifiers ^= 3 << 8;
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return;
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0xe1 ... 0xe7:
4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (keycode & (1 << 7)) {
4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->modifiers &= ~(1 << (hid_code & 0x0f));
4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return;
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0xe8 ... 0xef:
4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->modifiers |= 1 << (hid_code & 0x0f);
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (keycode & (1 << 7)) {
4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (i = s->keys - 1; i >= 0; i --)
4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (s->key[i] == hid_code) {
4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->key[i] = s->key[-- s->keys];
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->key[s->keys] = 0x00;
4785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                usb_hid_changed(hs);
4795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
4815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (i < 0)
4825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return;
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for (i = s->keys - 1; i >= 0; i --)
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (s->key[i] == hid_code)
4865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
4875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (i < 0) {
4885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (s->keys < sizeof(s->key))
4895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                s->key[s->keys ++] = hid_code;
4905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else
4915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return;
4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_hid_changed(hs);
4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int int_clamp(int val, int vmin, int vmax)
4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (val < vmin)
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return vmin;
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if (val > vmax)
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return vmax;
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return val;
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int usb_mouse_poll(USBHIDState *hs, uint8_t *buf, int len)
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int dx, dy, dz, b, l;
5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USBMouseState *s = &hs->ptr;
5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!s->mouse_grabbed) {
5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, hs,
5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                                  0, "QEMU USB Mouse");
5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	s->mouse_grabbed = 1;
5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dx = int_clamp(s->dx, -127, 127);
5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dy = int_clamp(s->dy, -127, 127);
5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dz = int_clamp(s->dz, -127, 127);
5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dx -= dx;
5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dy -= dy;
5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dz -= dz;
5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Appears we have to invert the wheel direction */
5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dz = 0 - dz;
5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    b = 0;
5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        b |= 0x01;
5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        b |= 0x02;
5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        b |= 0x04;
5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    l = 0;
5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (len > l)
5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf[l ++] = b;
5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (len > l)
5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf[l ++] = dx;
5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (len > l)
5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf[l ++] = dy;
5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (len > l)
5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf[l ++] = dz;
5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return l;
5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int usb_tablet_poll(USBHIDState *hs, uint8_t *buf, int len)
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int dz, b, l;
5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USBMouseState *s = &hs->ptr;
5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!s->mouse_grabbed) {
5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	s->eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, hs,
5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                                  1, "QEMU USB Tablet");
5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	s->mouse_grabbed = 1;
5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dz = int_clamp(s->dz, -127, 127);
5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dz -= dz;
5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Appears we have to invert the wheel direction */
5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dz = 0 - dz;
5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    b = 0;
5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        b |= 0x01;
5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        b |= 0x02;
5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        b |= 0x04;
5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf[0] = b;
5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf[1] = s->x & 0xff;
5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf[2] = s->x >> 8;
5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf[3] = s->y & 0xff;
5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf[4] = s->y >> 8;
5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf[5] = dz;
5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    l = 6;
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return l;
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int usb_keyboard_poll(USBKeyboardState *s, uint8_t *buf, int len)
5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (len < 2)
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf[0] = s->modifiers & 0xff;
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf[1] = 0;
5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->keys > 6)
5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memcpy(buf + 2, s->key, MIN(8, len) - 2);
5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return MIN(8, len);
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int usb_keyboard_write(USBKeyboardState *s, uint8_t *buf, int len)
6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (len > 0) {
6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* 0x01: Num Lock LED
6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         * 0x02: Caps Lock LED
6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         * 0x04: Scroll Lock LED
6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         * 0x08: Compose LED
6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         * 0x10: Kana LED */
6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->leds = buf[0];
6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void usb_mouse_handle_reset(USBDevice *dev)
6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USBHIDState *s = (USBHIDState *)dev;
6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->ptr.dx = 0;
6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->ptr.dy = 0;
6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->ptr.dz = 0;
6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->ptr.x = 0;
6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->ptr.y = 0;
6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->ptr.buttons_state = 0;
6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->protocol = 1;
6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void usb_keyboard_handle_reset(USBDevice *dev)
6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USBHIDState *s = (USBHIDState *)dev;
6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    qemu_add_kbd_event_handler(usb_keyboard_event, s);
6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->protocol = 1;
6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int usb_hid_handle_control(USBDevice *dev, int request, int value,
6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                  int index, int length, uint8_t *data)
6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USBHIDState *s = (USBHIDState *)dev;
6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret = 0;
6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch(request) {
6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case DeviceRequest | USB_REQ_GET_STATUS:
6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        data[0] = (1 << USB_DEVICE_SELF_POWERED) |
6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        data[1] = 0x00;
6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = 2;
6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (value == USB_DEVICE_REMOTE_WAKEUP) {
6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dev->remote_wakeup = 0;
6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto fail;
6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = 0;
6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case DeviceOutRequest | USB_REQ_SET_FEATURE:
6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (value == USB_DEVICE_REMOTE_WAKEUP) {
6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dev->remote_wakeup = 1;
6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto fail;
6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = 0;
6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dev->addr = value;
6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = 0;
6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch(value >> 8) {
6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case USB_DT_DEVICE:
6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            memcpy(data, qemu_mouse_dev_descriptor,
6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   sizeof(qemu_mouse_dev_descriptor));
6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ret = sizeof(qemu_mouse_dev_descriptor);
6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case USB_DT_CONFIG:
6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    if (s->kind == USB_MOUSE) {
6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		memcpy(data, qemu_mouse_config_descriptor,
6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		       sizeof(qemu_mouse_config_descriptor));
6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		ret = sizeof(qemu_mouse_config_descriptor);
6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    } else if (s->kind == USB_TABLET) {
6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		memcpy(data, qemu_tablet_config_descriptor,
6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		       sizeof(qemu_tablet_config_descriptor));
6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		ret = sizeof(qemu_tablet_config_descriptor);
6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else if (s->kind == USB_KEYBOARD) {
6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                memcpy(data, qemu_keyboard_config_descriptor,
6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       sizeof(qemu_keyboard_config_descriptor));
6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ret = sizeof(qemu_keyboard_config_descriptor);
6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case USB_DT_STRING:
6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            switch(value & 0xff) {
6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 0:
6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* language ids */
6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                data[0] = 4;
6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                data[1] = 3;
6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                data[2] = 0x09;
6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                data[3] = 0x04;
6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ret = 4;
6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 1:
6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* serial number */
7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ret = set_usb_string(data, "1");
7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 2:
7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* product description */
7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ret = set_usb_string(data, s->dev.devname);
7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 3:
7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* vendor description */
7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ret = set_usb_string(data, "QEMU " QEMU_VERSION);
7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 4:
7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ret = set_usb_string(data, "HID Mouse");
7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 5:
7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ret = set_usb_string(data, "HID Tablet");
7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 6:
7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ret = set_usb_string(data, "HID Keyboard");
7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 7:
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ret = set_usb_string(data, "Endpoint1 Interrupt Pipe");
7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            default:
7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto fail;
7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto fail;
7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case DeviceRequest | USB_REQ_GET_CONFIGURATION:
7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        data[0] = 1;
7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = 1;
7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = 0;
7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case DeviceRequest | USB_REQ_GET_INTERFACE:
7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        data[0] = 0;
7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = 1;
7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case DeviceOutRequest | USB_REQ_SET_INTERFACE:
7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = 0;
7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* hid specific requests */
7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch(value >> 8) {
7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case 0x22:
7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    if (s->kind == USB_MOUSE) {
7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		memcpy(data, qemu_mouse_hid_report_descriptor,
7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		       sizeof(qemu_mouse_hid_report_descriptor));
7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		ret = sizeof(qemu_mouse_hid_report_descriptor);
7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    } else if (s->kind == USB_TABLET) {
7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		memcpy(data, qemu_tablet_hid_report_descriptor,
7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		       sizeof(qemu_tablet_hid_report_descriptor));
7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		ret = sizeof(qemu_tablet_hid_report_descriptor);
7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else if (s->kind == USB_KEYBOARD) {
7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                memcpy(data, qemu_keyboard_hid_report_descriptor,
7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       sizeof(qemu_keyboard_hid_report_descriptor));
7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ret = sizeof(qemu_keyboard_hid_report_descriptor);
7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto fail;
7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case GET_REPORT:
7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (s->kind == USB_MOUSE)
7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ret = usb_mouse_poll(s, data, length);
7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	else if (s->kind == USB_TABLET)
7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ret = usb_tablet_poll(s, data, length);
7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else if (s->kind == USB_KEYBOARD)
7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ret = usb_keyboard_poll(&s->kbd, data, length);
7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SET_REPORT:
7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (s->kind == USB_KEYBOARD)
7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ret = usb_keyboard_write(&s->kbd, data, length);
7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto fail;
7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case GET_PROTOCOL:
7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (s->kind != USB_KEYBOARD)
7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto fail;
7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = 1;
7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        data[0] = s->protocol;
7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SET_PROTOCOL:
7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (s->kind != USB_KEYBOARD)
7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto fail;
7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = 0;
7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->protocol = value;
7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case GET_IDLE:
7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = 1;
7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        data[0] = s->idle;
7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SET_IDLE:
7975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        s->idle = (uint8_t) (value >> 8);
7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = 0;
7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fail:
8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = USB_RET_STALL;
8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USBHIDState *s = (USBHIDState *)dev;
8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret = 0;
8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch(p->pid) {
8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case USB_TOKEN_IN:
8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (p->devep == 1) {
8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* TODO: Implement finite idle delays.  */
8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!(s->changed || s->idle))
8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return USB_RET_NAK;
8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->changed = 0;
8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (s->kind == USB_MOUSE)
8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ret = usb_mouse_poll(s, p->data, p->len);
8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else if (s->kind == USB_TABLET)
8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ret = usb_tablet_poll(s, p->data, p->len);
8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else if (s->kind == USB_KEYBOARD)
8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ret = usb_keyboard_poll(&s->kbd, p->data, p->len);
8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto fail;
8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case USB_TOKEN_OUT:
8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fail:
8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = USB_RET_STALL;
8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void usb_hid_handle_destroy(USBDevice *dev)
8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USBHIDState *s = (USBHIDState *)dev;
8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->kind != USB_KEYBOARD)
8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        qemu_remove_mouse_event_handler(s->ptr.eh_entry);
8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* TODO: else */
8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    qemu_free(s);
8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectUSBDevice *usb_tablet_init(void)
8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USBHIDState *s;
8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s = qemu_mallocz(sizeof(USBHIDState));
8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.speed = USB_SPEED_FULL;
8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.handle_packet = usb_generic_handle_packet;
8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.handle_reset = usb_mouse_handle_reset;
8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.handle_control = usb_hid_handle_control;
8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.handle_data = usb_hid_handle_data;
8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.handle_destroy = usb_hid_handle_destroy;
8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->kind = USB_TABLET;
8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Force poll routine to be run and grab input the first time.  */
8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->changed = 1;
8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (USBDevice *)s;
8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectUSBDevice *usb_mouse_init(void)
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USBHIDState *s;
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s = qemu_mallocz(sizeof(USBHIDState));
8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.speed = USB_SPEED_FULL;
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.handle_packet = usb_generic_handle_packet;
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.handle_reset = usb_mouse_handle_reset;
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.handle_control = usb_hid_handle_control;
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.handle_data = usb_hid_handle_data;
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.handle_destroy = usb_hid_handle_destroy;
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->kind = USB_MOUSE;
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Force poll routine to be run and grab input the first time.  */
8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->changed = 1;
8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (USBDevice *)s;
8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectUSBDevice *usb_keyboard_init(void)
8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    USBHIDState *s;
8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s = qemu_mallocz(sizeof(USBHIDState));
8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.speed = USB_SPEED_FULL;
8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.handle_packet = usb_generic_handle_packet;
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.handle_reset = usb_keyboard_handle_reset;
9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.handle_control = usb_hid_handle_control;
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.handle_data = usb_hid_handle_data;
9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->dev.handle_destroy = usb_hid_handle_destroy;
9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->kind = USB_KEYBOARD;
9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Keyboard");
9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (USBDevice *) s;
9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *))
9115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBHIDState *s = (USBHIDState *)dev;
9135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->datain_opaque = opaque;
9155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->datain = datain;
9165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
917