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>
This commit is contained in:
parent
2bfb10dff2
commit
8e9ebd7523
@ -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)
|
||||
|
@ -24,10 +24,11 @@ OBJECT_DECLARE_TYPE(VirtIOInput, VirtIOInputClass,
|
||||
#define VIRTIO_INPUT_GET_PARENT_CLASS(obj) \
|
||||
OBJECT_GET_PARENT_CLASS(obj, TYPE_VIRTIO_INPUT)
|
||||
|
||||
#define TYPE_VIRTIO_INPUT_HID "virtio-input-hid-device"
|
||||
#define TYPE_VIRTIO_KEYBOARD "virtio-keyboard-device"
|
||||
#define TYPE_VIRTIO_MOUSE "virtio-mouse-device"
|
||||
#define TYPE_VIRTIO_TABLET "virtio-tablet-device"
|
||||
#define TYPE_VIRTIO_INPUT_HID "virtio-input-hid-device"
|
||||
#define TYPE_VIRTIO_KEYBOARD "virtio-keyboard-device"
|
||||
#define TYPE_VIRTIO_MOUSE "virtio-mouse-device"
|
||||
#define TYPE_VIRTIO_TABLET "virtio-tablet-device"
|
||||
#define TYPE_VIRTIO_MULTITOUCH "virtio-multitouch-device"
|
||||
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(VirtIOInputHID, VIRTIO_INPUT_HID)
|
||||
#define VIRTIO_INPUT_HID_GET_PARENT_CLASS(obj) \
|
||||
|
Loading…
Reference in New Issue
Block a user