155a1d80aSGerd Hoffmann /* 255a1d80aSGerd Hoffmann * This work is licensed under the terms of the GNU GPL, version 2 or 355a1d80aSGerd Hoffmann * (at your option) any later version. See the COPYING file in the 455a1d80aSGerd Hoffmann * top-level directory. 555a1d80aSGerd Hoffmann */ 655a1d80aSGerd Hoffmann 79b8bfe21SPeter Maydell #include "qemu/osdep.h" 855a1d80aSGerd Hoffmann #include "qemu/iov.h" 955a1d80aSGerd Hoffmann 1055a1d80aSGerd Hoffmann #include "hw/qdev.h" 1155a1d80aSGerd Hoffmann #include "hw/virtio/virtio.h" 1255a1d80aSGerd Hoffmann #include "hw/virtio/virtio-input.h" 1355a1d80aSGerd Hoffmann 1455a1d80aSGerd Hoffmann #undef CONFIG_CURSES 1555a1d80aSGerd Hoffmann #include "ui/console.h" 1655a1d80aSGerd Hoffmann 1755a1d80aSGerd Hoffmann #include "standard-headers/linux/input.h" 1855a1d80aSGerd Hoffmann 1955a1d80aSGerd Hoffmann #define VIRTIO_ID_NAME_KEYBOARD "QEMU Virtio Keyboard" 2055a1d80aSGerd Hoffmann #define VIRTIO_ID_NAME_MOUSE "QEMU Virtio Mouse" 2155a1d80aSGerd Hoffmann #define VIRTIO_ID_NAME_TABLET "QEMU Virtio Tablet" 2255a1d80aSGerd Hoffmann 2355a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */ 2455a1d80aSGerd Hoffmann 25*ae6b06abSDaniel P. Berrange static const unsigned short keymap_button[INPUT_BUTTON__MAX] = { 2655a1d80aSGerd Hoffmann [INPUT_BUTTON_LEFT] = BTN_LEFT, 2755a1d80aSGerd Hoffmann [INPUT_BUTTON_RIGHT] = BTN_RIGHT, 2855a1d80aSGerd Hoffmann [INPUT_BUTTON_MIDDLE] = BTN_MIDDLE, 29f22d0af0SGerd Hoffmann [INPUT_BUTTON_WHEEL_UP] = BTN_GEAR_UP, 30f22d0af0SGerd Hoffmann [INPUT_BUTTON_WHEEL_DOWN] = BTN_GEAR_DOWN, 312416760fSMiika S [INPUT_BUTTON_SIDE] = BTN_SIDE, 322416760fSMiika S [INPUT_BUTTON_EXTRA] = BTN_EXTRA, 3355a1d80aSGerd Hoffmann }; 3455a1d80aSGerd Hoffmann 35*ae6b06abSDaniel P. Berrange static const unsigned short axismap_rel[INPUT_AXIS__MAX] = { 3655a1d80aSGerd Hoffmann [INPUT_AXIS_X] = REL_X, 3755a1d80aSGerd Hoffmann [INPUT_AXIS_Y] = REL_Y, 3855a1d80aSGerd Hoffmann }; 3955a1d80aSGerd Hoffmann 40*ae6b06abSDaniel P. Berrange static const unsigned short axismap_abs[INPUT_AXIS__MAX] = { 4155a1d80aSGerd Hoffmann [INPUT_AXIS_X] = ABS_X, 4255a1d80aSGerd Hoffmann [INPUT_AXIS_Y] = ABS_Y, 4355a1d80aSGerd Hoffmann }; 4455a1d80aSGerd Hoffmann 4555a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */ 4655a1d80aSGerd Hoffmann 4755a1d80aSGerd Hoffmann static void virtio_input_key_config(VirtIOInput *vinput, 48*ae6b06abSDaniel P. Berrange const unsigned short *keymap, 4955a1d80aSGerd Hoffmann size_t mapsize) 5055a1d80aSGerd Hoffmann { 5155a1d80aSGerd Hoffmann virtio_input_config keys; 5255a1d80aSGerd Hoffmann int i, bit, byte, bmax = 0; 5355a1d80aSGerd Hoffmann 5455a1d80aSGerd Hoffmann memset(&keys, 0, sizeof(keys)); 5555a1d80aSGerd Hoffmann for (i = 0; i < mapsize; i++) { 5655a1d80aSGerd Hoffmann bit = keymap[i]; 5755a1d80aSGerd Hoffmann if (!bit) { 5855a1d80aSGerd Hoffmann continue; 5955a1d80aSGerd Hoffmann } 6055a1d80aSGerd Hoffmann byte = bit / 8; 6155a1d80aSGerd Hoffmann bit = bit % 8; 6255a1d80aSGerd Hoffmann keys.u.bitmap[byte] |= (1 << bit); 6355a1d80aSGerd Hoffmann if (bmax < byte+1) { 6455a1d80aSGerd Hoffmann bmax = byte+1; 6555a1d80aSGerd Hoffmann } 6655a1d80aSGerd Hoffmann } 6755a1d80aSGerd Hoffmann keys.select = VIRTIO_INPUT_CFG_EV_BITS; 6855a1d80aSGerd Hoffmann keys.subsel = EV_KEY; 6955a1d80aSGerd Hoffmann keys.size = bmax; 7055a1d80aSGerd Hoffmann virtio_input_add_config(vinput, &keys); 7155a1d80aSGerd Hoffmann } 7255a1d80aSGerd Hoffmann 7355a1d80aSGerd Hoffmann static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src, 7455a1d80aSGerd Hoffmann InputEvent *evt) 7555a1d80aSGerd Hoffmann { 76f4924974SGerd Hoffmann VirtIOInputHID *vhid = VIRTIO_INPUT_HID(dev); 7755a1d80aSGerd Hoffmann VirtIOInput *vinput = VIRTIO_INPUT(dev); 7855a1d80aSGerd Hoffmann virtio_input_event event; 7955a1d80aSGerd Hoffmann int qcode; 80b5a1b443SEric Blake InputKeyEvent *key; 81b5a1b443SEric Blake InputMoveEvent *move; 82b5a1b443SEric Blake InputBtnEvent *btn; 8355a1d80aSGerd Hoffmann 84568c73a4SEric Blake switch (evt->type) { 8555a1d80aSGerd Hoffmann case INPUT_EVENT_KIND_KEY: 8632bafa8fSEric Blake key = evt->u.key.data; 87b5a1b443SEric Blake qcode = qemu_input_key_value_to_qcode(key->key); 88*ae6b06abSDaniel P. Berrange if (qcode < qemu_input_map_qcode_to_linux_len && 89*ae6b06abSDaniel P. Berrange qemu_input_map_qcode_to_linux[qcode]) { 9055a1d80aSGerd Hoffmann event.type = cpu_to_le16(EV_KEY); 91*ae6b06abSDaniel P. Berrange event.code = cpu_to_le16(qemu_input_map_qcode_to_linux[qcode]); 92b5a1b443SEric Blake event.value = cpu_to_le32(key->down ? 1 : 0); 9355a1d80aSGerd Hoffmann virtio_input_send(vinput, &event); 9455a1d80aSGerd Hoffmann } else { 95b5a1b443SEric Blake if (key->down) { 9655a1d80aSGerd Hoffmann fprintf(stderr, "%s: unmapped key: %d [%s]\n", __func__, 97977c736fSMarkus Armbruster qcode, QKeyCode_str(qcode)); 9855a1d80aSGerd Hoffmann } 9955a1d80aSGerd Hoffmann } 10055a1d80aSGerd Hoffmann break; 10155a1d80aSGerd Hoffmann case INPUT_EVENT_KIND_BTN: 10232bafa8fSEric Blake btn = evt->u.btn.data; 103a5f99be4SMiika S if (vhid->wheel_axis && 104a5f99be4SMiika S (btn->button == INPUT_BUTTON_WHEEL_UP || 105a5f99be4SMiika S btn->button == INPUT_BUTTON_WHEEL_DOWN) && 106a5f99be4SMiika S btn->down) { 107f4924974SGerd Hoffmann event.type = cpu_to_le16(EV_REL); 108f4924974SGerd Hoffmann event.code = cpu_to_le16(REL_WHEEL); 109f4924974SGerd Hoffmann event.value = cpu_to_le32(btn->button == INPUT_BUTTON_WHEEL_UP 110f4924974SGerd Hoffmann ? 1 : -1); 111f4924974SGerd Hoffmann virtio_input_send(vinput, &event); 112f4924974SGerd Hoffmann } else if (keymap_button[btn->button]) { 11355a1d80aSGerd Hoffmann event.type = cpu_to_le16(EV_KEY); 114b5a1b443SEric Blake event.code = cpu_to_le16(keymap_button[btn->button]); 115b5a1b443SEric Blake event.value = cpu_to_le32(btn->down ? 1 : 0); 11655a1d80aSGerd Hoffmann virtio_input_send(vinput, &event); 11755a1d80aSGerd Hoffmann } else { 118b5a1b443SEric Blake if (btn->down) { 11955a1d80aSGerd Hoffmann fprintf(stderr, "%s: unmapped button: %d [%s]\n", __func__, 120b5a1b443SEric Blake btn->button, 121977c736fSMarkus Armbruster InputButton_str(btn->button)); 12255a1d80aSGerd Hoffmann } 12355a1d80aSGerd Hoffmann } 12455a1d80aSGerd Hoffmann break; 12555a1d80aSGerd Hoffmann case INPUT_EVENT_KIND_REL: 12632bafa8fSEric Blake move = evt->u.rel.data; 12755a1d80aSGerd Hoffmann event.type = cpu_to_le16(EV_REL); 128b5a1b443SEric Blake event.code = cpu_to_le16(axismap_rel[move->axis]); 129b5a1b443SEric Blake event.value = cpu_to_le32(move->value); 13055a1d80aSGerd Hoffmann virtio_input_send(vinput, &event); 13155a1d80aSGerd Hoffmann break; 13255a1d80aSGerd Hoffmann case INPUT_EVENT_KIND_ABS: 13332bafa8fSEric Blake move = evt->u.abs.data; 13455a1d80aSGerd Hoffmann event.type = cpu_to_le16(EV_ABS); 135b5a1b443SEric Blake event.code = cpu_to_le16(axismap_abs[move->axis]); 136b5a1b443SEric Blake event.value = cpu_to_le32(move->value); 13755a1d80aSGerd Hoffmann virtio_input_send(vinput, &event); 13855a1d80aSGerd Hoffmann break; 13955a1d80aSGerd Hoffmann default: 14055a1d80aSGerd Hoffmann /* keep gcc happy */ 14155a1d80aSGerd Hoffmann break; 14255a1d80aSGerd Hoffmann } 14355a1d80aSGerd Hoffmann } 14455a1d80aSGerd Hoffmann 14555a1d80aSGerd Hoffmann static void virtio_input_handle_sync(DeviceState *dev) 14655a1d80aSGerd Hoffmann { 14755a1d80aSGerd Hoffmann VirtIOInput *vinput = VIRTIO_INPUT(dev); 14855a1d80aSGerd Hoffmann virtio_input_event event = { 14955a1d80aSGerd Hoffmann .type = cpu_to_le16(EV_SYN), 15055a1d80aSGerd Hoffmann .code = cpu_to_le16(SYN_REPORT), 15155a1d80aSGerd Hoffmann .value = 0, 15255a1d80aSGerd Hoffmann }; 15355a1d80aSGerd Hoffmann 15455a1d80aSGerd Hoffmann virtio_input_send(vinput, &event); 15555a1d80aSGerd Hoffmann } 15655a1d80aSGerd Hoffmann 15755a1d80aSGerd Hoffmann static void virtio_input_hid_realize(DeviceState *dev, Error **errp) 15855a1d80aSGerd Hoffmann { 15955a1d80aSGerd Hoffmann VirtIOInputHID *vhid = VIRTIO_INPUT_HID(dev); 1605cce1733SGerd Hoffmann 16155a1d80aSGerd Hoffmann vhid->hs = qemu_input_handler_register(dev, vhid->handler); 1625cce1733SGerd Hoffmann if (vhid->display && vhid->hs) { 1635cce1733SGerd Hoffmann qemu_input_handler_bind(vhid->hs, vhid->display, vhid->head, NULL); 1645cce1733SGerd Hoffmann } 16555a1d80aSGerd Hoffmann } 16655a1d80aSGerd Hoffmann 16755a1d80aSGerd Hoffmann static void virtio_input_hid_unrealize(DeviceState *dev, Error **errp) 16855a1d80aSGerd Hoffmann { 16955a1d80aSGerd Hoffmann VirtIOInputHID *vhid = VIRTIO_INPUT_HID(dev); 17055a1d80aSGerd Hoffmann qemu_input_handler_unregister(vhid->hs); 17155a1d80aSGerd Hoffmann } 17255a1d80aSGerd Hoffmann 17355a1d80aSGerd Hoffmann static void virtio_input_hid_change_active(VirtIOInput *vinput) 17455a1d80aSGerd Hoffmann { 17555a1d80aSGerd Hoffmann VirtIOInputHID *vhid = VIRTIO_INPUT_HID(vinput); 17655a1d80aSGerd Hoffmann 17755a1d80aSGerd Hoffmann if (vinput->active) { 17855a1d80aSGerd Hoffmann qemu_input_handler_activate(vhid->hs); 17955a1d80aSGerd Hoffmann } else { 18055a1d80aSGerd Hoffmann qemu_input_handler_deactivate(vhid->hs); 18155a1d80aSGerd Hoffmann } 18255a1d80aSGerd Hoffmann } 18355a1d80aSGerd Hoffmann 18455a1d80aSGerd Hoffmann static void virtio_input_hid_handle_status(VirtIOInput *vinput, 18555a1d80aSGerd Hoffmann virtio_input_event *event) 18655a1d80aSGerd Hoffmann { 18755a1d80aSGerd Hoffmann VirtIOInputHID *vhid = VIRTIO_INPUT_HID(vinput); 18855a1d80aSGerd Hoffmann int ledbit = 0; 18955a1d80aSGerd Hoffmann 19055a1d80aSGerd Hoffmann switch (le16_to_cpu(event->type)) { 19155a1d80aSGerd Hoffmann case EV_LED: 19255a1d80aSGerd Hoffmann if (event->code == LED_NUML) { 19355a1d80aSGerd Hoffmann ledbit = QEMU_NUM_LOCK_LED; 19455a1d80aSGerd Hoffmann } else if (event->code == LED_CAPSL) { 19555a1d80aSGerd Hoffmann ledbit = QEMU_CAPS_LOCK_LED; 19655a1d80aSGerd Hoffmann } else if (event->code == LED_SCROLLL) { 19755a1d80aSGerd Hoffmann ledbit = QEMU_SCROLL_LOCK_LED; 19855a1d80aSGerd Hoffmann } 19955a1d80aSGerd Hoffmann if (event->value) { 20055a1d80aSGerd Hoffmann vhid->ledstate |= ledbit; 20155a1d80aSGerd Hoffmann } else { 20255a1d80aSGerd Hoffmann vhid->ledstate &= ~ledbit; 20355a1d80aSGerd Hoffmann } 20455a1d80aSGerd Hoffmann kbd_put_ledstate(vhid->ledstate); 20555a1d80aSGerd Hoffmann break; 20655a1d80aSGerd Hoffmann default: 20755a1d80aSGerd Hoffmann fprintf(stderr, "%s: unknown type %d\n", __func__, 20855a1d80aSGerd Hoffmann le16_to_cpu(event->type)); 20955a1d80aSGerd Hoffmann break; 21055a1d80aSGerd Hoffmann } 21155a1d80aSGerd Hoffmann } 21255a1d80aSGerd Hoffmann 2135cce1733SGerd Hoffmann static Property virtio_input_hid_properties[] = { 2145cce1733SGerd Hoffmann DEFINE_PROP_STRING("display", VirtIOInputHID, display), 2155cce1733SGerd Hoffmann DEFINE_PROP_UINT32("head", VirtIOInputHID, head, 0), 2162a19b229SLin Ma DEFINE_PROP_END_OF_LIST(), 2175cce1733SGerd Hoffmann }; 2185cce1733SGerd Hoffmann 21955a1d80aSGerd Hoffmann static void virtio_input_hid_class_init(ObjectClass *klass, void *data) 22055a1d80aSGerd Hoffmann { 2215cce1733SGerd Hoffmann DeviceClass *dc = DEVICE_CLASS(klass); 22255a1d80aSGerd Hoffmann VirtIOInputClass *vic = VIRTIO_INPUT_CLASS(klass); 22355a1d80aSGerd Hoffmann 2245cce1733SGerd Hoffmann dc->props = virtio_input_hid_properties; 22555a1d80aSGerd Hoffmann vic->realize = virtio_input_hid_realize; 22655a1d80aSGerd Hoffmann vic->unrealize = virtio_input_hid_unrealize; 22755a1d80aSGerd Hoffmann vic->change_active = virtio_input_hid_change_active; 22855a1d80aSGerd Hoffmann vic->handle_status = virtio_input_hid_handle_status; 22955a1d80aSGerd Hoffmann } 23055a1d80aSGerd Hoffmann 23155a1d80aSGerd Hoffmann static const TypeInfo virtio_input_hid_info = { 23255a1d80aSGerd Hoffmann .name = TYPE_VIRTIO_INPUT_HID, 23355a1d80aSGerd Hoffmann .parent = TYPE_VIRTIO_INPUT, 23455a1d80aSGerd Hoffmann .instance_size = sizeof(VirtIOInputHID), 23555a1d80aSGerd Hoffmann .class_init = virtio_input_hid_class_init, 23655a1d80aSGerd Hoffmann .abstract = true, 23755a1d80aSGerd Hoffmann }; 23855a1d80aSGerd Hoffmann 23955a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */ 24055a1d80aSGerd Hoffmann 24155a1d80aSGerd Hoffmann static QemuInputHandler virtio_keyboard_handler = { 24255a1d80aSGerd Hoffmann .name = VIRTIO_ID_NAME_KEYBOARD, 24355a1d80aSGerd Hoffmann .mask = INPUT_EVENT_MASK_KEY, 24455a1d80aSGerd Hoffmann .event = virtio_input_handle_event, 24555a1d80aSGerd Hoffmann .sync = virtio_input_handle_sync, 24655a1d80aSGerd Hoffmann }; 24755a1d80aSGerd Hoffmann 24855a1d80aSGerd Hoffmann static struct virtio_input_config virtio_keyboard_config[] = { 24955a1d80aSGerd Hoffmann { 25055a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_NAME, 25155a1d80aSGerd Hoffmann .size = sizeof(VIRTIO_ID_NAME_KEYBOARD), 25255a1d80aSGerd Hoffmann .u.string = VIRTIO_ID_NAME_KEYBOARD, 25355a1d80aSGerd Hoffmann },{ 25455a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_DEVIDS, 25555a1d80aSGerd Hoffmann .size = sizeof(struct virtio_input_devids), 25655a1d80aSGerd Hoffmann .u.ids = { 25755a1d80aSGerd Hoffmann .bustype = const_le16(BUS_VIRTUAL), 25855a1d80aSGerd Hoffmann .vendor = const_le16(0x0627), /* same we use for usb hid devices */ 25955a1d80aSGerd Hoffmann .product = const_le16(0x0001), 26055a1d80aSGerd Hoffmann .version = const_le16(0x0001), 26155a1d80aSGerd Hoffmann }, 26255a1d80aSGerd Hoffmann },{ 26355a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_EV_BITS, 26455a1d80aSGerd Hoffmann .subsel = EV_REP, 26555a1d80aSGerd Hoffmann .size = 1, 26655a1d80aSGerd Hoffmann },{ 26755a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_EV_BITS, 26855a1d80aSGerd Hoffmann .subsel = EV_LED, 26955a1d80aSGerd Hoffmann .size = 1, 27055a1d80aSGerd Hoffmann .u.bitmap = { 27155a1d80aSGerd Hoffmann (1 << LED_NUML) | (1 << LED_CAPSL) | (1 << LED_SCROLLL), 27255a1d80aSGerd Hoffmann }, 27355a1d80aSGerd Hoffmann }, 27455a1d80aSGerd Hoffmann { /* end of list */ }, 27555a1d80aSGerd Hoffmann }; 27655a1d80aSGerd Hoffmann 27755a1d80aSGerd Hoffmann static void virtio_keyboard_init(Object *obj) 27855a1d80aSGerd Hoffmann { 27955a1d80aSGerd Hoffmann VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj); 28055a1d80aSGerd Hoffmann VirtIOInput *vinput = VIRTIO_INPUT(obj); 28155a1d80aSGerd Hoffmann 28255a1d80aSGerd Hoffmann vhid->handler = &virtio_keyboard_handler; 28355a1d80aSGerd Hoffmann virtio_input_init_config(vinput, virtio_keyboard_config); 284*ae6b06abSDaniel P. Berrange virtio_input_key_config(vinput, qemu_input_map_qcode_to_linux, 285*ae6b06abSDaniel P. Berrange qemu_input_map_qcode_to_linux_len); 28655a1d80aSGerd Hoffmann } 28755a1d80aSGerd Hoffmann 28855a1d80aSGerd Hoffmann static const TypeInfo virtio_keyboard_info = { 28955a1d80aSGerd Hoffmann .name = TYPE_VIRTIO_KEYBOARD, 29055a1d80aSGerd Hoffmann .parent = TYPE_VIRTIO_INPUT_HID, 29155a1d80aSGerd Hoffmann .instance_size = sizeof(VirtIOInputHID), 29255a1d80aSGerd Hoffmann .instance_init = virtio_keyboard_init, 29355a1d80aSGerd Hoffmann }; 29455a1d80aSGerd Hoffmann 29555a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */ 29655a1d80aSGerd Hoffmann 29755a1d80aSGerd Hoffmann static QemuInputHandler virtio_mouse_handler = { 29855a1d80aSGerd Hoffmann .name = VIRTIO_ID_NAME_MOUSE, 29955a1d80aSGerd Hoffmann .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL, 30055a1d80aSGerd Hoffmann .event = virtio_input_handle_event, 30155a1d80aSGerd Hoffmann .sync = virtio_input_handle_sync, 30255a1d80aSGerd Hoffmann }; 30355a1d80aSGerd Hoffmann 304f4924974SGerd Hoffmann static struct virtio_input_config virtio_mouse_config_v1[] = { 30555a1d80aSGerd Hoffmann { 30655a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_NAME, 30755a1d80aSGerd Hoffmann .size = sizeof(VIRTIO_ID_NAME_MOUSE), 30855a1d80aSGerd Hoffmann .u.string = VIRTIO_ID_NAME_MOUSE, 30955a1d80aSGerd Hoffmann },{ 31055a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_DEVIDS, 31155a1d80aSGerd Hoffmann .size = sizeof(struct virtio_input_devids), 31255a1d80aSGerd Hoffmann .u.ids = { 31355a1d80aSGerd Hoffmann .bustype = const_le16(BUS_VIRTUAL), 31455a1d80aSGerd Hoffmann .vendor = const_le16(0x0627), /* same we use for usb hid devices */ 31555a1d80aSGerd Hoffmann .product = const_le16(0x0002), 31655a1d80aSGerd Hoffmann .version = const_le16(0x0001), 31755a1d80aSGerd Hoffmann }, 31855a1d80aSGerd Hoffmann },{ 31955a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_EV_BITS, 32055a1d80aSGerd Hoffmann .subsel = EV_REL, 32155a1d80aSGerd Hoffmann .size = 1, 32255a1d80aSGerd Hoffmann .u.bitmap = { 32355a1d80aSGerd Hoffmann (1 << REL_X) | (1 << REL_Y), 32455a1d80aSGerd Hoffmann }, 32555a1d80aSGerd Hoffmann }, 32655a1d80aSGerd Hoffmann { /* end of list */ }, 32755a1d80aSGerd Hoffmann }; 32855a1d80aSGerd Hoffmann 329f4924974SGerd Hoffmann static struct virtio_input_config virtio_mouse_config_v2[] = { 330f4924974SGerd Hoffmann { 331f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_NAME, 332f4924974SGerd Hoffmann .size = sizeof(VIRTIO_ID_NAME_MOUSE), 333f4924974SGerd Hoffmann .u.string = VIRTIO_ID_NAME_MOUSE, 334f4924974SGerd Hoffmann },{ 335f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_DEVIDS, 336f4924974SGerd Hoffmann .size = sizeof(struct virtio_input_devids), 337f4924974SGerd Hoffmann .u.ids = { 338f4924974SGerd Hoffmann .bustype = const_le16(BUS_VIRTUAL), 339f4924974SGerd Hoffmann .vendor = const_le16(0x0627), /* same we use for usb hid devices */ 340f4924974SGerd Hoffmann .product = const_le16(0x0002), 341f4924974SGerd Hoffmann .version = const_le16(0x0002), 342f4924974SGerd Hoffmann }, 343f4924974SGerd Hoffmann },{ 344f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_EV_BITS, 345f4924974SGerd Hoffmann .subsel = EV_REL, 346f4924974SGerd Hoffmann .size = 2, 347f4924974SGerd Hoffmann .u.bitmap = { 348f4924974SGerd Hoffmann (1 << REL_X) | (1 << REL_Y), 349f4924974SGerd Hoffmann (1 << (REL_WHEEL - 8)) 350f4924974SGerd Hoffmann }, 351f4924974SGerd Hoffmann }, 352f4924974SGerd Hoffmann { /* end of list */ }, 353f4924974SGerd Hoffmann }; 354f4924974SGerd Hoffmann 355f4924974SGerd Hoffmann static Property virtio_mouse_properties[] = { 356f4924974SGerd Hoffmann DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID, wheel_axis, true), 357f4924974SGerd Hoffmann DEFINE_PROP_END_OF_LIST(), 358f4924974SGerd Hoffmann }; 359f4924974SGerd Hoffmann 360f4924974SGerd Hoffmann static void virtio_mouse_class_init(ObjectClass *klass, void *data) 361f4924974SGerd Hoffmann { 362f4924974SGerd Hoffmann DeviceClass *dc = DEVICE_CLASS(klass); 363f4924974SGerd Hoffmann 364f4924974SGerd Hoffmann dc->props = virtio_mouse_properties; 365f4924974SGerd Hoffmann } 366f4924974SGerd Hoffmann 36755a1d80aSGerd Hoffmann static void virtio_mouse_init(Object *obj) 36855a1d80aSGerd Hoffmann { 36955a1d80aSGerd Hoffmann VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj); 37055a1d80aSGerd Hoffmann VirtIOInput *vinput = VIRTIO_INPUT(obj); 37155a1d80aSGerd Hoffmann 37255a1d80aSGerd Hoffmann vhid->handler = &virtio_mouse_handler; 373f4924974SGerd Hoffmann virtio_input_init_config(vinput, vhid->wheel_axis 374f4924974SGerd Hoffmann ? virtio_mouse_config_v2 375f4924974SGerd Hoffmann : virtio_mouse_config_v1); 37655a1d80aSGerd Hoffmann virtio_input_key_config(vinput, keymap_button, 37755a1d80aSGerd Hoffmann ARRAY_SIZE(keymap_button)); 37855a1d80aSGerd Hoffmann } 37955a1d80aSGerd Hoffmann 38055a1d80aSGerd Hoffmann static const TypeInfo virtio_mouse_info = { 38155a1d80aSGerd Hoffmann .name = TYPE_VIRTIO_MOUSE, 38255a1d80aSGerd Hoffmann .parent = TYPE_VIRTIO_INPUT_HID, 38355a1d80aSGerd Hoffmann .instance_size = sizeof(VirtIOInputHID), 38455a1d80aSGerd Hoffmann .instance_init = virtio_mouse_init, 385f4924974SGerd Hoffmann .class_init = virtio_mouse_class_init, 38655a1d80aSGerd Hoffmann }; 38755a1d80aSGerd Hoffmann 38855a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */ 38955a1d80aSGerd Hoffmann 39055a1d80aSGerd Hoffmann static QemuInputHandler virtio_tablet_handler = { 39155a1d80aSGerd Hoffmann .name = VIRTIO_ID_NAME_TABLET, 39255a1d80aSGerd Hoffmann .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS, 39355a1d80aSGerd Hoffmann .event = virtio_input_handle_event, 39455a1d80aSGerd Hoffmann .sync = virtio_input_handle_sync, 39555a1d80aSGerd Hoffmann }; 39655a1d80aSGerd Hoffmann 397f4924974SGerd Hoffmann static struct virtio_input_config virtio_tablet_config_v1[] = { 39855a1d80aSGerd Hoffmann { 39955a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_NAME, 40055a1d80aSGerd Hoffmann .size = sizeof(VIRTIO_ID_NAME_TABLET), 40155a1d80aSGerd Hoffmann .u.string = VIRTIO_ID_NAME_TABLET, 40255a1d80aSGerd Hoffmann },{ 40355a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_DEVIDS, 40455a1d80aSGerd Hoffmann .size = sizeof(struct virtio_input_devids), 40555a1d80aSGerd Hoffmann .u.ids = { 40655a1d80aSGerd Hoffmann .bustype = const_le16(BUS_VIRTUAL), 40755a1d80aSGerd Hoffmann .vendor = const_le16(0x0627), /* same we use for usb hid devices */ 40855a1d80aSGerd Hoffmann .product = const_le16(0x0003), 40955a1d80aSGerd Hoffmann .version = const_le16(0x0001), 41055a1d80aSGerd Hoffmann }, 41155a1d80aSGerd Hoffmann },{ 41255a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_EV_BITS, 41355a1d80aSGerd Hoffmann .subsel = EV_ABS, 41455a1d80aSGerd Hoffmann .size = 1, 41555a1d80aSGerd Hoffmann .u.bitmap = { 41655a1d80aSGerd Hoffmann (1 << ABS_X) | (1 << ABS_Y), 41755a1d80aSGerd Hoffmann }, 41855a1d80aSGerd Hoffmann },{ 41955a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_ABS_INFO, 42055a1d80aSGerd Hoffmann .subsel = ABS_X, 42155a1d80aSGerd Hoffmann .size = sizeof(virtio_input_absinfo), 4229cfa7ab9SPhilippe Voinov .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN), 4239cfa7ab9SPhilippe Voinov .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX), 42455a1d80aSGerd Hoffmann },{ 42555a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_ABS_INFO, 42655a1d80aSGerd Hoffmann .subsel = ABS_Y, 42755a1d80aSGerd Hoffmann .size = sizeof(virtio_input_absinfo), 4289cfa7ab9SPhilippe Voinov .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN), 4299cfa7ab9SPhilippe Voinov .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX), 43055a1d80aSGerd Hoffmann }, 43155a1d80aSGerd Hoffmann { /* end of list */ }, 43255a1d80aSGerd Hoffmann }; 43355a1d80aSGerd Hoffmann 434f4924974SGerd Hoffmann static struct virtio_input_config virtio_tablet_config_v2[] = { 435f4924974SGerd Hoffmann { 436f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_NAME, 437f4924974SGerd Hoffmann .size = sizeof(VIRTIO_ID_NAME_TABLET), 438f4924974SGerd Hoffmann .u.string = VIRTIO_ID_NAME_TABLET, 439f4924974SGerd Hoffmann },{ 440f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_DEVIDS, 441f4924974SGerd Hoffmann .size = sizeof(struct virtio_input_devids), 442f4924974SGerd Hoffmann .u.ids = { 443f4924974SGerd Hoffmann .bustype = const_le16(BUS_VIRTUAL), 444f4924974SGerd Hoffmann .vendor = const_le16(0x0627), /* same we use for usb hid devices */ 445f4924974SGerd Hoffmann .product = const_le16(0x0003), 446f4924974SGerd Hoffmann .version = const_le16(0x0002), 447f4924974SGerd Hoffmann }, 448f4924974SGerd Hoffmann },{ 449f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_EV_BITS, 450f4924974SGerd Hoffmann .subsel = EV_ABS, 451f4924974SGerd Hoffmann .size = 1, 452f4924974SGerd Hoffmann .u.bitmap = { 453f4924974SGerd Hoffmann (1 << ABS_X) | (1 << ABS_Y), 454f4924974SGerd Hoffmann }, 455f4924974SGerd Hoffmann },{ 456f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_EV_BITS, 457f4924974SGerd Hoffmann .subsel = EV_REL, 458f4924974SGerd Hoffmann .size = 2, 459f4924974SGerd Hoffmann .u.bitmap = { 460f4924974SGerd Hoffmann 0, 461f4924974SGerd Hoffmann (1 << (REL_WHEEL - 8)) 462f4924974SGerd Hoffmann }, 463f4924974SGerd Hoffmann },{ 464f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_ABS_INFO, 465f4924974SGerd Hoffmann .subsel = ABS_X, 466f4924974SGerd Hoffmann .size = sizeof(virtio_input_absinfo), 467f4924974SGerd Hoffmann .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN), 468f4924974SGerd Hoffmann .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX), 469f4924974SGerd Hoffmann },{ 470f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_ABS_INFO, 471f4924974SGerd Hoffmann .subsel = ABS_Y, 472f4924974SGerd Hoffmann .size = sizeof(virtio_input_absinfo), 473f4924974SGerd Hoffmann .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN), 474f4924974SGerd Hoffmann .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX), 475f4924974SGerd Hoffmann }, 476f4924974SGerd Hoffmann { /* end of list */ }, 477f4924974SGerd Hoffmann }; 478f4924974SGerd Hoffmann 479f4924974SGerd Hoffmann static Property virtio_tablet_properties[] = { 480f4924974SGerd Hoffmann DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID, wheel_axis, true), 481f4924974SGerd Hoffmann DEFINE_PROP_END_OF_LIST(), 482f4924974SGerd Hoffmann }; 483f4924974SGerd Hoffmann 484f4924974SGerd Hoffmann static void virtio_tablet_class_init(ObjectClass *klass, void *data) 485f4924974SGerd Hoffmann { 486f4924974SGerd Hoffmann DeviceClass *dc = DEVICE_CLASS(klass); 487f4924974SGerd Hoffmann 488f4924974SGerd Hoffmann dc->props = virtio_tablet_properties; 489f4924974SGerd Hoffmann } 490f4924974SGerd Hoffmann 49155a1d80aSGerd Hoffmann static void virtio_tablet_init(Object *obj) 49255a1d80aSGerd Hoffmann { 49355a1d80aSGerd Hoffmann VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj); 49455a1d80aSGerd Hoffmann VirtIOInput *vinput = VIRTIO_INPUT(obj); 49555a1d80aSGerd Hoffmann 49655a1d80aSGerd Hoffmann vhid->handler = &virtio_tablet_handler; 497f4924974SGerd Hoffmann virtio_input_init_config(vinput, vhid->wheel_axis 498f4924974SGerd Hoffmann ? virtio_tablet_config_v2 499f4924974SGerd Hoffmann : virtio_tablet_config_v1); 50055a1d80aSGerd Hoffmann virtio_input_key_config(vinput, keymap_button, 50155a1d80aSGerd Hoffmann ARRAY_SIZE(keymap_button)); 50255a1d80aSGerd Hoffmann } 50355a1d80aSGerd Hoffmann 50455a1d80aSGerd Hoffmann static const TypeInfo virtio_tablet_info = { 50555a1d80aSGerd Hoffmann .name = TYPE_VIRTIO_TABLET, 50655a1d80aSGerd Hoffmann .parent = TYPE_VIRTIO_INPUT_HID, 50755a1d80aSGerd Hoffmann .instance_size = sizeof(VirtIOInputHID), 50855a1d80aSGerd Hoffmann .instance_init = virtio_tablet_init, 509f4924974SGerd Hoffmann .class_init = virtio_tablet_class_init, 51055a1d80aSGerd Hoffmann }; 51155a1d80aSGerd Hoffmann 51255a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */ 51355a1d80aSGerd Hoffmann 51455a1d80aSGerd Hoffmann static void virtio_register_types(void) 51555a1d80aSGerd Hoffmann { 51655a1d80aSGerd Hoffmann type_register_static(&virtio_input_hid_info); 51755a1d80aSGerd Hoffmann type_register_static(&virtio_keyboard_info); 51855a1d80aSGerd Hoffmann type_register_static(&virtio_mouse_info); 51955a1d80aSGerd Hoffmann type_register_static(&virtio_tablet_info); 52055a1d80aSGerd Hoffmann } 52155a1d80aSGerd Hoffmann 52255a1d80aSGerd Hoffmann type_init(virtio_register_types) 523