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" 90b8fa32fSMarkus Armbruster #include "qemu/module.h" 1055a1d80aSGerd Hoffmann 1155a1d80aSGerd Hoffmann #include "hw/virtio/virtio.h" 12a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h" 1355a1d80aSGerd Hoffmann #include "hw/virtio/virtio-input.h" 1455a1d80aSGerd Hoffmann 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 25ae6b06abSDaniel 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 35ae6b06abSDaniel 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 40ae6b06abSDaniel 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 47*944ae6d9SSergio Lopez static void virtio_input_extend_config(VirtIOInput *vinput, 48*944ae6d9SSergio Lopez const unsigned short *map, 49*944ae6d9SSergio Lopez size_t mapsize, 50*944ae6d9SSergio Lopez uint8_t select, uint8_t subsel) 5155a1d80aSGerd Hoffmann { 52*944ae6d9SSergio Lopez virtio_input_config ext; 5355a1d80aSGerd Hoffmann int i, bit, byte, bmax = 0; 5455a1d80aSGerd Hoffmann 55*944ae6d9SSergio Lopez memset(&ext, 0, sizeof(ext)); 5655a1d80aSGerd Hoffmann for (i = 0; i < mapsize; i++) { 57*944ae6d9SSergio Lopez bit = map[i]; 5855a1d80aSGerd Hoffmann if (!bit) { 5955a1d80aSGerd Hoffmann continue; 6055a1d80aSGerd Hoffmann } 6155a1d80aSGerd Hoffmann byte = bit / 8; 6255a1d80aSGerd Hoffmann bit = bit % 8; 63*944ae6d9SSergio Lopez ext.u.bitmap[byte] |= (1 << bit); 6455a1d80aSGerd Hoffmann if (bmax < byte+1) { 6555a1d80aSGerd Hoffmann bmax = byte+1; 6655a1d80aSGerd Hoffmann } 6755a1d80aSGerd Hoffmann } 68*944ae6d9SSergio Lopez ext.select = select; 69*944ae6d9SSergio Lopez ext.subsel = subsel; 70*944ae6d9SSergio Lopez ext.size = bmax; 71*944ae6d9SSergio Lopez virtio_input_add_config(vinput, &ext); 7255a1d80aSGerd Hoffmann } 7355a1d80aSGerd Hoffmann 7455a1d80aSGerd Hoffmann static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src, 7555a1d80aSGerd Hoffmann InputEvent *evt) 7655a1d80aSGerd Hoffmann { 77f4924974SGerd Hoffmann VirtIOInputHID *vhid = VIRTIO_INPUT_HID(dev); 7855a1d80aSGerd Hoffmann VirtIOInput *vinput = VIRTIO_INPUT(dev); 7955a1d80aSGerd Hoffmann virtio_input_event event; 8055a1d80aSGerd Hoffmann int qcode; 81b5a1b443SEric Blake InputKeyEvent *key; 82b5a1b443SEric Blake InputMoveEvent *move; 83b5a1b443SEric Blake InputBtnEvent *btn; 8455a1d80aSGerd Hoffmann 85568c73a4SEric Blake switch (evt->type) { 8655a1d80aSGerd Hoffmann case INPUT_EVENT_KIND_KEY: 8732bafa8fSEric Blake key = evt->u.key.data; 88b5a1b443SEric Blake qcode = qemu_input_key_value_to_qcode(key->key); 89ae6b06abSDaniel P. Berrange if (qcode < qemu_input_map_qcode_to_linux_len && 90ae6b06abSDaniel P. Berrange qemu_input_map_qcode_to_linux[qcode]) { 9155a1d80aSGerd Hoffmann event.type = cpu_to_le16(EV_KEY); 92ae6b06abSDaniel P. Berrange event.code = cpu_to_le16(qemu_input_map_qcode_to_linux[qcode]); 93b5a1b443SEric Blake event.value = cpu_to_le32(key->down ? 1 : 0); 9455a1d80aSGerd Hoffmann virtio_input_send(vinput, &event); 9555a1d80aSGerd Hoffmann } else { 96b5a1b443SEric Blake if (key->down) { 9755a1d80aSGerd Hoffmann fprintf(stderr, "%s: unmapped key: %d [%s]\n", __func__, 98977c736fSMarkus Armbruster qcode, QKeyCode_str(qcode)); 9955a1d80aSGerd Hoffmann } 10055a1d80aSGerd Hoffmann } 10155a1d80aSGerd Hoffmann break; 10255a1d80aSGerd Hoffmann case INPUT_EVENT_KIND_BTN: 10332bafa8fSEric Blake btn = evt->u.btn.data; 104a5f99be4SMiika S if (vhid->wheel_axis && 105a5f99be4SMiika S (btn->button == INPUT_BUTTON_WHEEL_UP || 106a5f99be4SMiika S btn->button == INPUT_BUTTON_WHEEL_DOWN) && 107a5f99be4SMiika S btn->down) { 108f4924974SGerd Hoffmann event.type = cpu_to_le16(EV_REL); 109f4924974SGerd Hoffmann event.code = cpu_to_le16(REL_WHEEL); 110f4924974SGerd Hoffmann event.value = cpu_to_le32(btn->button == INPUT_BUTTON_WHEEL_UP 111f4924974SGerd Hoffmann ? 1 : -1); 112f4924974SGerd Hoffmann virtio_input_send(vinput, &event); 113f4924974SGerd Hoffmann } else if (keymap_button[btn->button]) { 11455a1d80aSGerd Hoffmann event.type = cpu_to_le16(EV_KEY); 115b5a1b443SEric Blake event.code = cpu_to_le16(keymap_button[btn->button]); 116b5a1b443SEric Blake event.value = cpu_to_le32(btn->down ? 1 : 0); 11755a1d80aSGerd Hoffmann virtio_input_send(vinput, &event); 11855a1d80aSGerd Hoffmann } else { 119b5a1b443SEric Blake if (btn->down) { 12055a1d80aSGerd Hoffmann fprintf(stderr, "%s: unmapped button: %d [%s]\n", __func__, 121b5a1b443SEric Blake btn->button, 122977c736fSMarkus Armbruster InputButton_str(btn->button)); 12355a1d80aSGerd Hoffmann } 12455a1d80aSGerd Hoffmann } 12555a1d80aSGerd Hoffmann break; 12655a1d80aSGerd Hoffmann case INPUT_EVENT_KIND_REL: 12732bafa8fSEric Blake move = evt->u.rel.data; 12855a1d80aSGerd Hoffmann event.type = cpu_to_le16(EV_REL); 129b5a1b443SEric Blake event.code = cpu_to_le16(axismap_rel[move->axis]); 130b5a1b443SEric Blake event.value = cpu_to_le32(move->value); 13155a1d80aSGerd Hoffmann virtio_input_send(vinput, &event); 13255a1d80aSGerd Hoffmann break; 13355a1d80aSGerd Hoffmann case INPUT_EVENT_KIND_ABS: 13432bafa8fSEric Blake move = evt->u.abs.data; 13555a1d80aSGerd Hoffmann event.type = cpu_to_le16(EV_ABS); 136b5a1b443SEric Blake event.code = cpu_to_le16(axismap_abs[move->axis]); 137b5a1b443SEric Blake event.value = cpu_to_le32(move->value); 13855a1d80aSGerd Hoffmann virtio_input_send(vinput, &event); 13955a1d80aSGerd Hoffmann break; 14055a1d80aSGerd Hoffmann default: 14155a1d80aSGerd Hoffmann /* keep gcc happy */ 14255a1d80aSGerd Hoffmann break; 14355a1d80aSGerd Hoffmann } 14455a1d80aSGerd Hoffmann } 14555a1d80aSGerd Hoffmann 14655a1d80aSGerd Hoffmann static void virtio_input_handle_sync(DeviceState *dev) 14755a1d80aSGerd Hoffmann { 14855a1d80aSGerd Hoffmann VirtIOInput *vinput = VIRTIO_INPUT(dev); 14955a1d80aSGerd Hoffmann virtio_input_event event = { 15055a1d80aSGerd Hoffmann .type = cpu_to_le16(EV_SYN), 15155a1d80aSGerd Hoffmann .code = cpu_to_le16(SYN_REPORT), 15255a1d80aSGerd Hoffmann .value = 0, 15355a1d80aSGerd Hoffmann }; 15455a1d80aSGerd Hoffmann 15555a1d80aSGerd Hoffmann virtio_input_send(vinput, &event); 15655a1d80aSGerd Hoffmann } 15755a1d80aSGerd Hoffmann 15855a1d80aSGerd Hoffmann static void virtio_input_hid_realize(DeviceState *dev, Error **errp) 15955a1d80aSGerd Hoffmann { 16055a1d80aSGerd Hoffmann VirtIOInputHID *vhid = VIRTIO_INPUT_HID(dev); 1615cce1733SGerd Hoffmann 16255a1d80aSGerd Hoffmann vhid->hs = qemu_input_handler_register(dev, vhid->handler); 1635cce1733SGerd Hoffmann if (vhid->display && vhid->hs) { 1645cce1733SGerd Hoffmann qemu_input_handler_bind(vhid->hs, vhid->display, vhid->head, NULL); 1655cce1733SGerd Hoffmann } 16655a1d80aSGerd Hoffmann } 16755a1d80aSGerd Hoffmann 168b69c3c21SMarkus Armbruster static void virtio_input_hid_unrealize(DeviceState *dev) 16955a1d80aSGerd Hoffmann { 17055a1d80aSGerd Hoffmann VirtIOInputHID *vhid = VIRTIO_INPUT_HID(dev); 17155a1d80aSGerd Hoffmann qemu_input_handler_unregister(vhid->hs); 17255a1d80aSGerd Hoffmann } 17355a1d80aSGerd Hoffmann 17455a1d80aSGerd Hoffmann static void virtio_input_hid_change_active(VirtIOInput *vinput) 17555a1d80aSGerd Hoffmann { 17655a1d80aSGerd Hoffmann VirtIOInputHID *vhid = VIRTIO_INPUT_HID(vinput); 17755a1d80aSGerd Hoffmann 17855a1d80aSGerd Hoffmann if (vinput->active) { 17955a1d80aSGerd Hoffmann qemu_input_handler_activate(vhid->hs); 18055a1d80aSGerd Hoffmann } else { 18155a1d80aSGerd Hoffmann qemu_input_handler_deactivate(vhid->hs); 18255a1d80aSGerd Hoffmann } 18355a1d80aSGerd Hoffmann } 18455a1d80aSGerd Hoffmann 18555a1d80aSGerd Hoffmann static void virtio_input_hid_handle_status(VirtIOInput *vinput, 18655a1d80aSGerd Hoffmann virtio_input_event *event) 18755a1d80aSGerd Hoffmann { 18855a1d80aSGerd Hoffmann VirtIOInputHID *vhid = VIRTIO_INPUT_HID(vinput); 18955a1d80aSGerd Hoffmann int ledbit = 0; 19055a1d80aSGerd Hoffmann 19155a1d80aSGerd Hoffmann switch (le16_to_cpu(event->type)) { 19255a1d80aSGerd Hoffmann case EV_LED: 19355a1d80aSGerd Hoffmann if (event->code == LED_NUML) { 19455a1d80aSGerd Hoffmann ledbit = QEMU_NUM_LOCK_LED; 19555a1d80aSGerd Hoffmann } else if (event->code == LED_CAPSL) { 19655a1d80aSGerd Hoffmann ledbit = QEMU_CAPS_LOCK_LED; 19755a1d80aSGerd Hoffmann } else if (event->code == LED_SCROLLL) { 19855a1d80aSGerd Hoffmann ledbit = QEMU_SCROLL_LOCK_LED; 19955a1d80aSGerd Hoffmann } 20055a1d80aSGerd Hoffmann if (event->value) { 20155a1d80aSGerd Hoffmann vhid->ledstate |= ledbit; 20255a1d80aSGerd Hoffmann } else { 20355a1d80aSGerd Hoffmann vhid->ledstate &= ~ledbit; 20455a1d80aSGerd Hoffmann } 20555a1d80aSGerd Hoffmann kbd_put_ledstate(vhid->ledstate); 20655a1d80aSGerd Hoffmann break; 20755a1d80aSGerd Hoffmann default: 20855a1d80aSGerd Hoffmann fprintf(stderr, "%s: unknown type %d\n", __func__, 20955a1d80aSGerd Hoffmann le16_to_cpu(event->type)); 21055a1d80aSGerd Hoffmann break; 21155a1d80aSGerd Hoffmann } 21255a1d80aSGerd Hoffmann } 21355a1d80aSGerd Hoffmann 2145cce1733SGerd Hoffmann static Property virtio_input_hid_properties[] = { 2155cce1733SGerd Hoffmann DEFINE_PROP_STRING("display", VirtIOInputHID, display), 2165cce1733SGerd Hoffmann DEFINE_PROP_UINT32("head", VirtIOInputHID, head, 0), 2172a19b229SLin Ma DEFINE_PROP_END_OF_LIST(), 2185cce1733SGerd Hoffmann }; 2195cce1733SGerd Hoffmann 22055a1d80aSGerd Hoffmann static void virtio_input_hid_class_init(ObjectClass *klass, void *data) 22155a1d80aSGerd Hoffmann { 2225cce1733SGerd Hoffmann DeviceClass *dc = DEVICE_CLASS(klass); 22355a1d80aSGerd Hoffmann VirtIOInputClass *vic = VIRTIO_INPUT_CLASS(klass); 22455a1d80aSGerd Hoffmann 2254f67d30bSMarc-André Lureau device_class_set_props(dc, virtio_input_hid_properties); 22655a1d80aSGerd Hoffmann vic->realize = virtio_input_hid_realize; 22755a1d80aSGerd Hoffmann vic->unrealize = virtio_input_hid_unrealize; 22855a1d80aSGerd Hoffmann vic->change_active = virtio_input_hid_change_active; 22955a1d80aSGerd Hoffmann vic->handle_status = virtio_input_hid_handle_status; 23055a1d80aSGerd Hoffmann } 23155a1d80aSGerd Hoffmann 23255a1d80aSGerd Hoffmann static const TypeInfo virtio_input_hid_info = { 23355a1d80aSGerd Hoffmann .name = TYPE_VIRTIO_INPUT_HID, 23455a1d80aSGerd Hoffmann .parent = TYPE_VIRTIO_INPUT, 23555a1d80aSGerd Hoffmann .instance_size = sizeof(VirtIOInputHID), 23655a1d80aSGerd Hoffmann .class_init = virtio_input_hid_class_init, 23755a1d80aSGerd Hoffmann .abstract = true, 23855a1d80aSGerd Hoffmann }; 23955a1d80aSGerd Hoffmann 24055a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */ 24155a1d80aSGerd Hoffmann 24255a1d80aSGerd Hoffmann static QemuInputHandler virtio_keyboard_handler = { 24355a1d80aSGerd Hoffmann .name = VIRTIO_ID_NAME_KEYBOARD, 24455a1d80aSGerd Hoffmann .mask = INPUT_EVENT_MASK_KEY, 24555a1d80aSGerd Hoffmann .event = virtio_input_handle_event, 24655a1d80aSGerd Hoffmann .sync = virtio_input_handle_sync, 24755a1d80aSGerd Hoffmann }; 24855a1d80aSGerd Hoffmann 24955a1d80aSGerd Hoffmann static struct virtio_input_config virtio_keyboard_config[] = { 25055a1d80aSGerd Hoffmann { 25155a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_NAME, 25255a1d80aSGerd Hoffmann .size = sizeof(VIRTIO_ID_NAME_KEYBOARD), 25355a1d80aSGerd Hoffmann .u.string = VIRTIO_ID_NAME_KEYBOARD, 25455a1d80aSGerd Hoffmann },{ 25555a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_DEVIDS, 25655a1d80aSGerd Hoffmann .size = sizeof(struct virtio_input_devids), 25755a1d80aSGerd Hoffmann .u.ids = { 25855a1d80aSGerd Hoffmann .bustype = const_le16(BUS_VIRTUAL), 25955a1d80aSGerd Hoffmann .vendor = const_le16(0x0627), /* same we use for usb hid devices */ 26055a1d80aSGerd Hoffmann .product = const_le16(0x0001), 26155a1d80aSGerd Hoffmann .version = const_le16(0x0001), 26255a1d80aSGerd Hoffmann }, 26355a1d80aSGerd Hoffmann },{ 26455a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_EV_BITS, 26555a1d80aSGerd Hoffmann .subsel = EV_REP, 26655a1d80aSGerd Hoffmann .size = 1, 26755a1d80aSGerd Hoffmann },{ 26855a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_EV_BITS, 26955a1d80aSGerd Hoffmann .subsel = EV_LED, 27055a1d80aSGerd Hoffmann .size = 1, 27155a1d80aSGerd Hoffmann .u.bitmap = { 27255a1d80aSGerd Hoffmann (1 << LED_NUML) | (1 << LED_CAPSL) | (1 << LED_SCROLLL), 27355a1d80aSGerd Hoffmann }, 27455a1d80aSGerd Hoffmann }, 27555a1d80aSGerd Hoffmann { /* end of list */ }, 27655a1d80aSGerd Hoffmann }; 27755a1d80aSGerd Hoffmann 27855a1d80aSGerd Hoffmann static void virtio_keyboard_init(Object *obj) 27955a1d80aSGerd Hoffmann { 28055a1d80aSGerd Hoffmann VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj); 28155a1d80aSGerd Hoffmann VirtIOInput *vinput = VIRTIO_INPUT(obj); 28255a1d80aSGerd Hoffmann 28355a1d80aSGerd Hoffmann vhid->handler = &virtio_keyboard_handler; 28455a1d80aSGerd Hoffmann virtio_input_init_config(vinput, virtio_keyboard_config); 285*944ae6d9SSergio Lopez virtio_input_extend_config(vinput, qemu_input_map_qcode_to_linux, 286*944ae6d9SSergio Lopez qemu_input_map_qcode_to_linux_len, 287*944ae6d9SSergio Lopez VIRTIO_INPUT_CFG_EV_BITS, EV_KEY); 28855a1d80aSGerd Hoffmann } 28955a1d80aSGerd Hoffmann 29055a1d80aSGerd Hoffmann static const TypeInfo virtio_keyboard_info = { 29155a1d80aSGerd Hoffmann .name = TYPE_VIRTIO_KEYBOARD, 29255a1d80aSGerd Hoffmann .parent = TYPE_VIRTIO_INPUT_HID, 29355a1d80aSGerd Hoffmann .instance_size = sizeof(VirtIOInputHID), 29455a1d80aSGerd Hoffmann .instance_init = virtio_keyboard_init, 29555a1d80aSGerd Hoffmann }; 29655a1d80aSGerd Hoffmann 29755a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */ 29855a1d80aSGerd Hoffmann 29955a1d80aSGerd Hoffmann static QemuInputHandler virtio_mouse_handler = { 30055a1d80aSGerd Hoffmann .name = VIRTIO_ID_NAME_MOUSE, 30155a1d80aSGerd Hoffmann .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL, 30255a1d80aSGerd Hoffmann .event = virtio_input_handle_event, 30355a1d80aSGerd Hoffmann .sync = virtio_input_handle_sync, 30455a1d80aSGerd Hoffmann }; 30555a1d80aSGerd Hoffmann 306f4924974SGerd Hoffmann static struct virtio_input_config virtio_mouse_config_v1[] = { 30755a1d80aSGerd Hoffmann { 30855a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_NAME, 30955a1d80aSGerd Hoffmann .size = sizeof(VIRTIO_ID_NAME_MOUSE), 31055a1d80aSGerd Hoffmann .u.string = VIRTIO_ID_NAME_MOUSE, 31155a1d80aSGerd Hoffmann },{ 31255a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_DEVIDS, 31355a1d80aSGerd Hoffmann .size = sizeof(struct virtio_input_devids), 31455a1d80aSGerd Hoffmann .u.ids = { 31555a1d80aSGerd Hoffmann .bustype = const_le16(BUS_VIRTUAL), 31655a1d80aSGerd Hoffmann .vendor = const_le16(0x0627), /* same we use for usb hid devices */ 31755a1d80aSGerd Hoffmann .product = const_le16(0x0002), 31855a1d80aSGerd Hoffmann .version = const_le16(0x0001), 31955a1d80aSGerd Hoffmann }, 32055a1d80aSGerd Hoffmann },{ 32155a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_EV_BITS, 32255a1d80aSGerd Hoffmann .subsel = EV_REL, 32355a1d80aSGerd Hoffmann .size = 1, 32455a1d80aSGerd Hoffmann .u.bitmap = { 32555a1d80aSGerd Hoffmann (1 << REL_X) | (1 << REL_Y), 32655a1d80aSGerd Hoffmann }, 32755a1d80aSGerd Hoffmann }, 32855a1d80aSGerd Hoffmann { /* end of list */ }, 32955a1d80aSGerd Hoffmann }; 33055a1d80aSGerd Hoffmann 331f4924974SGerd Hoffmann static struct virtio_input_config virtio_mouse_config_v2[] = { 332f4924974SGerd Hoffmann { 333f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_NAME, 334f4924974SGerd Hoffmann .size = sizeof(VIRTIO_ID_NAME_MOUSE), 335f4924974SGerd Hoffmann .u.string = VIRTIO_ID_NAME_MOUSE, 336f4924974SGerd Hoffmann },{ 337f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_DEVIDS, 338f4924974SGerd Hoffmann .size = sizeof(struct virtio_input_devids), 339f4924974SGerd Hoffmann .u.ids = { 340f4924974SGerd Hoffmann .bustype = const_le16(BUS_VIRTUAL), 341f4924974SGerd Hoffmann .vendor = const_le16(0x0627), /* same we use for usb hid devices */ 342f4924974SGerd Hoffmann .product = const_le16(0x0002), 343f4924974SGerd Hoffmann .version = const_le16(0x0002), 344f4924974SGerd Hoffmann }, 345f4924974SGerd Hoffmann },{ 346f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_EV_BITS, 347f4924974SGerd Hoffmann .subsel = EV_REL, 348f4924974SGerd Hoffmann .size = 2, 349f4924974SGerd Hoffmann .u.bitmap = { 350f4924974SGerd Hoffmann (1 << REL_X) | (1 << REL_Y), 351f4924974SGerd Hoffmann (1 << (REL_WHEEL - 8)) 352f4924974SGerd Hoffmann }, 353f4924974SGerd Hoffmann }, 354f4924974SGerd Hoffmann { /* end of list */ }, 355f4924974SGerd Hoffmann }; 356f4924974SGerd Hoffmann 357f4924974SGerd Hoffmann static Property virtio_mouse_properties[] = { 358f4924974SGerd Hoffmann DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID, wheel_axis, true), 359f4924974SGerd Hoffmann DEFINE_PROP_END_OF_LIST(), 360f4924974SGerd Hoffmann }; 361f4924974SGerd Hoffmann 362f4924974SGerd Hoffmann static void virtio_mouse_class_init(ObjectClass *klass, void *data) 363f4924974SGerd Hoffmann { 364f4924974SGerd Hoffmann DeviceClass *dc = DEVICE_CLASS(klass); 365f4924974SGerd Hoffmann 3664f67d30bSMarc-André Lureau device_class_set_props(dc, virtio_mouse_properties); 367f4924974SGerd Hoffmann } 368f4924974SGerd Hoffmann 36955a1d80aSGerd Hoffmann static void virtio_mouse_init(Object *obj) 37055a1d80aSGerd Hoffmann { 37155a1d80aSGerd Hoffmann VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj); 37255a1d80aSGerd Hoffmann VirtIOInput *vinput = VIRTIO_INPUT(obj); 37355a1d80aSGerd Hoffmann 37455a1d80aSGerd Hoffmann vhid->handler = &virtio_mouse_handler; 375f4924974SGerd Hoffmann virtio_input_init_config(vinput, vhid->wheel_axis 376f4924974SGerd Hoffmann ? virtio_mouse_config_v2 377f4924974SGerd Hoffmann : virtio_mouse_config_v1); 378*944ae6d9SSergio Lopez virtio_input_extend_config(vinput, keymap_button, 379*944ae6d9SSergio Lopez ARRAY_SIZE(keymap_button), 380*944ae6d9SSergio Lopez VIRTIO_INPUT_CFG_EV_BITS, EV_KEY); 38155a1d80aSGerd Hoffmann } 38255a1d80aSGerd Hoffmann 38355a1d80aSGerd Hoffmann static const TypeInfo virtio_mouse_info = { 38455a1d80aSGerd Hoffmann .name = TYPE_VIRTIO_MOUSE, 38555a1d80aSGerd Hoffmann .parent = TYPE_VIRTIO_INPUT_HID, 38655a1d80aSGerd Hoffmann .instance_size = sizeof(VirtIOInputHID), 38755a1d80aSGerd Hoffmann .instance_init = virtio_mouse_init, 388f4924974SGerd Hoffmann .class_init = virtio_mouse_class_init, 38955a1d80aSGerd Hoffmann }; 39055a1d80aSGerd Hoffmann 39155a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */ 39255a1d80aSGerd Hoffmann 39355a1d80aSGerd Hoffmann static QemuInputHandler virtio_tablet_handler = { 39455a1d80aSGerd Hoffmann .name = VIRTIO_ID_NAME_TABLET, 39555a1d80aSGerd Hoffmann .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS, 39655a1d80aSGerd Hoffmann .event = virtio_input_handle_event, 39755a1d80aSGerd Hoffmann .sync = virtio_input_handle_sync, 39855a1d80aSGerd Hoffmann }; 39955a1d80aSGerd Hoffmann 400f4924974SGerd Hoffmann static struct virtio_input_config virtio_tablet_config_v1[] = { 40155a1d80aSGerd Hoffmann { 40255a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_NAME, 40355a1d80aSGerd Hoffmann .size = sizeof(VIRTIO_ID_NAME_TABLET), 40455a1d80aSGerd Hoffmann .u.string = VIRTIO_ID_NAME_TABLET, 40555a1d80aSGerd Hoffmann },{ 40655a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_DEVIDS, 40755a1d80aSGerd Hoffmann .size = sizeof(struct virtio_input_devids), 40855a1d80aSGerd Hoffmann .u.ids = { 40955a1d80aSGerd Hoffmann .bustype = const_le16(BUS_VIRTUAL), 41055a1d80aSGerd Hoffmann .vendor = const_le16(0x0627), /* same we use for usb hid devices */ 41155a1d80aSGerd Hoffmann .product = const_le16(0x0003), 41255a1d80aSGerd Hoffmann .version = const_le16(0x0001), 41355a1d80aSGerd Hoffmann }, 41455a1d80aSGerd Hoffmann },{ 41555a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_EV_BITS, 41655a1d80aSGerd Hoffmann .subsel = EV_ABS, 41755a1d80aSGerd Hoffmann .size = 1, 41855a1d80aSGerd Hoffmann .u.bitmap = { 41955a1d80aSGerd Hoffmann (1 << ABS_X) | (1 << ABS_Y), 42055a1d80aSGerd Hoffmann }, 42155a1d80aSGerd Hoffmann },{ 42255a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_ABS_INFO, 42355a1d80aSGerd Hoffmann .subsel = ABS_X, 42455a1d80aSGerd Hoffmann .size = sizeof(virtio_input_absinfo), 4259cfa7ab9SPhilippe Voinov .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN), 4269cfa7ab9SPhilippe Voinov .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX), 42755a1d80aSGerd Hoffmann },{ 42855a1d80aSGerd Hoffmann .select = VIRTIO_INPUT_CFG_ABS_INFO, 42955a1d80aSGerd Hoffmann .subsel = ABS_Y, 43055a1d80aSGerd Hoffmann .size = sizeof(virtio_input_absinfo), 4319cfa7ab9SPhilippe Voinov .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN), 4329cfa7ab9SPhilippe Voinov .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX), 43355a1d80aSGerd Hoffmann }, 43455a1d80aSGerd Hoffmann { /* end of list */ }, 43555a1d80aSGerd Hoffmann }; 43655a1d80aSGerd Hoffmann 437f4924974SGerd Hoffmann static struct virtio_input_config virtio_tablet_config_v2[] = { 438f4924974SGerd Hoffmann { 439f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_NAME, 440f4924974SGerd Hoffmann .size = sizeof(VIRTIO_ID_NAME_TABLET), 441f4924974SGerd Hoffmann .u.string = VIRTIO_ID_NAME_TABLET, 442f4924974SGerd Hoffmann },{ 443f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_ID_DEVIDS, 444f4924974SGerd Hoffmann .size = sizeof(struct virtio_input_devids), 445f4924974SGerd Hoffmann .u.ids = { 446f4924974SGerd Hoffmann .bustype = const_le16(BUS_VIRTUAL), 447f4924974SGerd Hoffmann .vendor = const_le16(0x0627), /* same we use for usb hid devices */ 448f4924974SGerd Hoffmann .product = const_le16(0x0003), 449f4924974SGerd Hoffmann .version = const_le16(0x0002), 450f4924974SGerd Hoffmann }, 451f4924974SGerd Hoffmann },{ 452f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_EV_BITS, 453f4924974SGerd Hoffmann .subsel = EV_ABS, 454f4924974SGerd Hoffmann .size = 1, 455f4924974SGerd Hoffmann .u.bitmap = { 456f4924974SGerd Hoffmann (1 << ABS_X) | (1 << ABS_Y), 457f4924974SGerd Hoffmann }, 458f4924974SGerd Hoffmann },{ 459f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_EV_BITS, 460f4924974SGerd Hoffmann .subsel = EV_REL, 461f4924974SGerd Hoffmann .size = 2, 462f4924974SGerd Hoffmann .u.bitmap = { 463f4924974SGerd Hoffmann 0, 464f4924974SGerd Hoffmann (1 << (REL_WHEEL - 8)) 465f4924974SGerd Hoffmann }, 466f4924974SGerd Hoffmann },{ 467f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_ABS_INFO, 468f4924974SGerd Hoffmann .subsel = ABS_X, 469f4924974SGerd Hoffmann .size = sizeof(virtio_input_absinfo), 470f4924974SGerd Hoffmann .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN), 471f4924974SGerd Hoffmann .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX), 472f4924974SGerd Hoffmann },{ 473f4924974SGerd Hoffmann .select = VIRTIO_INPUT_CFG_ABS_INFO, 474f4924974SGerd Hoffmann .subsel = ABS_Y, 475f4924974SGerd Hoffmann .size = sizeof(virtio_input_absinfo), 476f4924974SGerd Hoffmann .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN), 477f4924974SGerd Hoffmann .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX), 478f4924974SGerd Hoffmann }, 479f4924974SGerd Hoffmann { /* end of list */ }, 480f4924974SGerd Hoffmann }; 481f4924974SGerd Hoffmann 482f4924974SGerd Hoffmann static Property virtio_tablet_properties[] = { 483f4924974SGerd Hoffmann DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID, wheel_axis, true), 484f4924974SGerd Hoffmann DEFINE_PROP_END_OF_LIST(), 485f4924974SGerd Hoffmann }; 486f4924974SGerd Hoffmann 487f4924974SGerd Hoffmann static void virtio_tablet_class_init(ObjectClass *klass, void *data) 488f4924974SGerd Hoffmann { 489f4924974SGerd Hoffmann DeviceClass *dc = DEVICE_CLASS(klass); 490f4924974SGerd Hoffmann 4914f67d30bSMarc-André Lureau device_class_set_props(dc, virtio_tablet_properties); 492f4924974SGerd Hoffmann } 493f4924974SGerd Hoffmann 49455a1d80aSGerd Hoffmann static void virtio_tablet_init(Object *obj) 49555a1d80aSGerd Hoffmann { 49655a1d80aSGerd Hoffmann VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj); 49755a1d80aSGerd Hoffmann VirtIOInput *vinput = VIRTIO_INPUT(obj); 49855a1d80aSGerd Hoffmann 49955a1d80aSGerd Hoffmann vhid->handler = &virtio_tablet_handler; 500f4924974SGerd Hoffmann virtio_input_init_config(vinput, vhid->wheel_axis 501f4924974SGerd Hoffmann ? virtio_tablet_config_v2 502f4924974SGerd Hoffmann : virtio_tablet_config_v1); 503*944ae6d9SSergio Lopez virtio_input_extend_config(vinput, keymap_button, 504*944ae6d9SSergio Lopez ARRAY_SIZE(keymap_button), 505*944ae6d9SSergio Lopez VIRTIO_INPUT_CFG_EV_BITS, EV_KEY); 50655a1d80aSGerd Hoffmann } 50755a1d80aSGerd Hoffmann 50855a1d80aSGerd Hoffmann static const TypeInfo virtio_tablet_info = { 50955a1d80aSGerd Hoffmann .name = TYPE_VIRTIO_TABLET, 51055a1d80aSGerd Hoffmann .parent = TYPE_VIRTIO_INPUT_HID, 51155a1d80aSGerd Hoffmann .instance_size = sizeof(VirtIOInputHID), 51255a1d80aSGerd Hoffmann .instance_init = virtio_tablet_init, 513f4924974SGerd Hoffmann .class_init = virtio_tablet_class_init, 51455a1d80aSGerd Hoffmann }; 51555a1d80aSGerd Hoffmann 51655a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */ 51755a1d80aSGerd Hoffmann 51855a1d80aSGerd Hoffmann static void virtio_register_types(void) 51955a1d80aSGerd Hoffmann { 52055a1d80aSGerd Hoffmann type_register_static(&virtio_input_hid_info); 52155a1d80aSGerd Hoffmann type_register_static(&virtio_keyboard_info); 52255a1d80aSGerd Hoffmann type_register_static(&virtio_mouse_info); 52355a1d80aSGerd Hoffmann type_register_static(&virtio_tablet_info); 52455a1d80aSGerd Hoffmann } 52555a1d80aSGerd Hoffmann 52655a1d80aSGerd Hoffmann type_init(virtio_register_types) 527