aboutsummaryrefslogtreecommitdiff
path: root/hw/input
diff options
context:
space:
mode:
authorSergio Lopez <slp@redhat.com>2023-05-26 13:29:22 +0200
committerMarc-André Lureau <marcandre.lureau@redhat.com>2023-05-28 13:08:25 +0400
commit8e9ebd7523915900dad0cab6eb807c773c37b5fc (patch)
treec4f48b5027fcbf4bb8076eb66d9597a0f78d3ad6 /hw/input
parent2bfb10dff2a21e42708aa4aef4bb64e8e3674858 (diff)
virtio-input: add a virtio-mulitouch device
Add a virtio-multitouch device to the family of devices emulated by virtio-input implementing the Multi-touch protocol as descripted here: https://www.kernel.org/doc/html/latest/input/multi-touch-protocol.html?highlight=multi+touch This patch just add the device itself, without connecting it to any backends. The following patches will add a PCI-based multitouch device, some helpers in "ui" and will enable the GTK3 backend to transpose multi-touch events from the host to the guest. Signed-off-by: Sergio Lopez <slp@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20230526112925.38794-4-slp@redhat.com>
Diffstat (limited to 'hw/input')
-rw-r--r--hw/input/virtio-input-hid.c118
1 files changed, 115 insertions, 3 deletions
diff --git a/hw/input/virtio-input-hid.c b/hw/input/virtio-input-hid.c
index d28dab69ba..7053ad72d4 100644
--- a/hw/input/virtio-input-hid.c
+++ b/hw/input/virtio-input-hid.c
@@ -16,9 +16,10 @@
#include "standard-headers/linux/input.h"
-#define VIRTIO_ID_NAME_KEYBOARD "QEMU Virtio Keyboard"
-#define VIRTIO_ID_NAME_MOUSE "QEMU Virtio Mouse"
-#define VIRTIO_ID_NAME_TABLET "QEMU Virtio Tablet"
+#define VIRTIO_ID_NAME_KEYBOARD "QEMU Virtio Keyboard"
+#define VIRTIO_ID_NAME_MOUSE "QEMU Virtio Mouse"
+#define VIRTIO_ID_NAME_TABLET "QEMU Virtio Tablet"
+#define VIRTIO_ID_NAME_MULTITOUCH "QEMU Virtio MultiTouch"
/* ----------------------------------------------------------------- */
@@ -30,6 +31,7 @@ static const unsigned short keymap_button[INPUT_BUTTON__MAX] = {
[INPUT_BUTTON_WHEEL_DOWN] = BTN_GEAR_DOWN,
[INPUT_BUTTON_SIDE] = BTN_SIDE,
[INPUT_BUTTON_EXTRA] = BTN_EXTRA,
+ [INPUT_BUTTON_TOUCH] = BTN_TOUCH,
};
static const unsigned short axismap_rel[INPUT_AXIS__MAX] = {
@@ -42,6 +44,11 @@ static const unsigned short axismap_abs[INPUT_AXIS__MAX] = {
[INPUT_AXIS_Y] = ABS_Y,
};
+static const unsigned short axismap_tch[INPUT_AXIS__MAX] = {
+ [INPUT_AXIS_X] = ABS_MT_POSITION_X,
+ [INPUT_AXIS_Y] = ABS_MT_POSITION_Y,
+};
+
/* ----------------------------------------------------------------- */
static void virtio_input_extend_config(VirtIOInput *vinput,
@@ -81,6 +88,7 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,
InputKeyEvent *key;
InputMoveEvent *move;
InputBtnEvent *btn;
+ InputMultiTouchEvent *mtt;
switch (evt->type) {
case INPUT_EVENT_KIND_KEY:
@@ -137,6 +145,24 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,
event.value = cpu_to_le32(move->value);
virtio_input_send(vinput, &event);
break;
+ case INPUT_EVENT_KIND_MTT:
+ mtt = evt->u.mtt.data;
+ if (mtt->type == INPUT_MULTI_TOUCH_TYPE_DATA) {
+ event.type = cpu_to_le16(EV_ABS);
+ event.code = cpu_to_le16(axismap_tch[mtt->axis]);
+ event.value = cpu_to_le32(mtt->value);
+ virtio_input_send(vinput, &event);
+ } else {
+ event.type = cpu_to_le16(EV_ABS);
+ event.code = cpu_to_le16(ABS_MT_SLOT);
+ event.value = cpu_to_le32(mtt->slot);
+ virtio_input_send(vinput, &event);
+ event.type = cpu_to_le16(EV_ABS);
+ event.code = cpu_to_le16(ABS_MT_TRACKING_ID);
+ event.value = cpu_to_le32(mtt->tracking_id);
+ virtio_input_send(vinput, &event);
+ }
+ break;
default:
/* keep gcc happy */
break;
@@ -515,12 +541,98 @@ static const TypeInfo virtio_tablet_info = {
/* ----------------------------------------------------------------- */
+static QemuInputHandler virtio_multitouch_handler = {
+ .name = VIRTIO_ID_NAME_MULTITOUCH,
+ .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_MTT,
+ .event = virtio_input_handle_event,
+ .sync = virtio_input_handle_sync,
+};
+
+static struct virtio_input_config virtio_multitouch_config[] = {
+ {
+ .select = VIRTIO_INPUT_CFG_ID_NAME,
+ .size = sizeof(VIRTIO_ID_NAME_MULTITOUCH),
+ .u.string = VIRTIO_ID_NAME_MULTITOUCH,
+ },{
+ .select = VIRTIO_INPUT_CFG_ID_DEVIDS,
+ .size = sizeof(struct virtio_input_devids),
+ .u.ids = {
+ .bustype = const_le16(BUS_VIRTUAL),
+ .vendor = const_le16(0x0627), /* same we use for usb hid devices */
+ .product = const_le16(0x0003),
+ .version = const_le16(0x0001),
+ },
+ },{
+ .select = VIRTIO_INPUT_CFG_ABS_INFO,
+ .subsel = ABS_MT_SLOT,
+ .size = sizeof(virtio_input_absinfo),
+ .u.abs.min = const_le32(INPUT_EVENT_SLOTS_MIN),
+ .u.abs.max = const_le32(INPUT_EVENT_SLOTS_MAX),
+ },{
+ .select = VIRTIO_INPUT_CFG_ABS_INFO,
+ .subsel = ABS_MT_TRACKING_ID,
+ .size = sizeof(virtio_input_absinfo),
+ .u.abs.min = const_le32(INPUT_EVENT_SLOTS_MIN),
+ .u.abs.max = const_le32(INPUT_EVENT_SLOTS_MAX),
+ },{
+ .select = VIRTIO_INPUT_CFG_ABS_INFO,
+ .subsel = ABS_MT_POSITION_X,
+ .size = sizeof(virtio_input_absinfo),
+ .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
+ .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
+ },{
+ .select = VIRTIO_INPUT_CFG_ABS_INFO,
+ .subsel = ABS_MT_POSITION_Y,
+ .size = sizeof(virtio_input_absinfo),
+ .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
+ .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
+ },
+ { /* end of list */ },
+};
+
+static void virtio_multitouch_init(Object *obj)
+{
+ VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
+ VirtIOInput *vinput = VIRTIO_INPUT(obj);
+ unsigned short abs_props[] = {
+ INPUT_PROP_DIRECT,
+ };
+ unsigned short abs_bits[] = {
+ ABS_MT_SLOT,
+ ABS_MT_TRACKING_ID,
+ ABS_MT_POSITION_X,
+ ABS_MT_POSITION_Y,
+ };
+
+ vhid->handler = &virtio_multitouch_handler;
+ virtio_input_init_config(vinput, virtio_multitouch_config);
+ virtio_input_extend_config(vinput, keymap_button,
+ ARRAY_SIZE(keymap_button),
+ VIRTIO_INPUT_CFG_EV_BITS, EV_KEY);
+ virtio_input_extend_config(vinput, abs_props,
+ ARRAY_SIZE(abs_props),
+ VIRTIO_INPUT_CFG_PROP_BITS, 0);
+ virtio_input_extend_config(vinput, abs_bits,
+ ARRAY_SIZE(abs_bits),
+ VIRTIO_INPUT_CFG_EV_BITS, EV_ABS);
+}
+
+static const TypeInfo virtio_multitouch_info = {
+ .name = TYPE_VIRTIO_MULTITOUCH,
+ .parent = TYPE_VIRTIO_INPUT_HID,
+ .instance_size = sizeof(VirtIOInputHID),
+ .instance_init = virtio_multitouch_init,
+};
+
+/* ----------------------------------------------------------------- */
+
static void virtio_register_types(void)
{
type_register_static(&virtio_input_hid_info);
type_register_static(&virtio_keyboard_info);
type_register_static(&virtio_mouse_info);
type_register_static(&virtio_tablet_info);
+ type_register_static(&virtio_multitouch_info);
}
type_init(virtio_register_types)