From b065e275a8066c3ec478f326f39c5fc3c9db103c Mon Sep 17 00:00:00 2001 From: Ladi Prosek Date: Wed, 13 Apr 2016 16:43:23 +0200 Subject: [PATCH] virtio-input: support absolute axis config in pass-through VIRTIO_INPUT_CFG_ABS_INFO was not implemented for pass-through input devices. This patch follows the existing design and pre-fetches the config for all absolute axes using EVIOCGABS at realize time. Signed-off-by: Ladi Prosek Message-id: 1460558603-18331-1-git-send-email-lprosek@redhat.com Signed-off-by: Gerd Hoffmann --- hw/input/virtio-input-host.c | 46 ++++++++++++++++++++++++++++++-- hw/input/virtio-input.c | 6 ++--- include/hw/virtio/virtio-input.h | 3 +++ 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/hw/input/virtio-input-host.c b/hw/input/virtio-input-host.c index 96124f47c1..cb79e80024 100644 --- a/hw/input/virtio-input-host.c +++ b/hw/input/virtio-input-host.c @@ -70,13 +70,39 @@ static void virtio_input_bits_config(VirtIOInputHost *vih, virtio_input_add_config(VIRTIO_INPUT(vih), &bits); } +static void virtio_input_abs_config(VirtIOInputHost *vih, int axis) +{ + virtio_input_config config; + struct input_absinfo absinfo; + int rc; + + rc = ioctl(vih->fd, EVIOCGABS(axis), &absinfo); + if (rc < 0) { + return; + } + + memset(&config, 0, sizeof(config)); + config.select = VIRTIO_INPUT_CFG_ABS_INFO; + config.subsel = axis; + config.size = sizeof(virtio_input_absinfo); + + config.u.abs.min = cpu_to_le32(absinfo.minimum); + config.u.abs.max = cpu_to_le32(absinfo.maximum); + config.u.abs.fuzz = cpu_to_le32(absinfo.fuzz); + config.u.abs.flat = cpu_to_le32(absinfo.flat); + config.u.abs.res = cpu_to_le32(absinfo.resolution); + + virtio_input_add_config(VIRTIO_INPUT(vih), &config); +} + static void virtio_input_host_realize(DeviceState *dev, Error **errp) { VirtIOInputHost *vih = VIRTIO_INPUT_HOST(dev); VirtIOInput *vinput = VIRTIO_INPUT(dev); - virtio_input_config id; + virtio_input_config id, *abs; struct input_id ids; - int rc, ver; + int rc, ver, i, axis; + uint8_t byte; if (!vih->evdev) { error_setg(errp, "evdev property is required"); @@ -127,6 +153,22 @@ static void virtio_input_host_realize(DeviceState *dev, Error **errp) virtio_input_bits_config(vih, EV_SW, SW_CNT); virtio_input_bits_config(vih, EV_LED, LED_CNT); + abs = virtio_input_find_config(VIRTIO_INPUT(vih), + VIRTIO_INPUT_CFG_EV_BITS, EV_ABS); + if (abs) { + for (i = 0; i < abs->size; i++) { + byte = abs->u.bitmap[i]; + axis = 8 * i; + while (byte) { + if (byte & 1) { + virtio_input_abs_config(vih, axis); + } + axis++; + byte >>= 1; + } + } + } + qemu_set_fd_handler(vih->fd, virtio_input_host_event, NULL, vih); return; diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c index ac019c7d23..f59749a943 100644 --- a/hw/input/virtio-input.c +++ b/hw/input/virtio-input.c @@ -99,9 +99,9 @@ static void virtio_input_handle_sts(VirtIODevice *vdev, VirtQueue *vq) virtio_notify(vdev, vinput->sts); } -static virtio_input_config *virtio_input_find_config(VirtIOInput *vinput, - uint8_t select, - uint8_t subsel) +virtio_input_config *virtio_input_find_config(VirtIOInput *vinput, + uint8_t select, + uint8_t subsel) { VirtIOInputConfig *cfg; diff --git a/include/hw/virtio/virtio-input.h b/include/hw/virtio/virtio-input.h index 1b414c4217..bddbd4b287 100644 --- a/include/hw/virtio/virtio-input.h +++ b/include/hw/virtio/virtio-input.h @@ -97,6 +97,9 @@ struct VirtIOInputHost { void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event); void virtio_input_init_config(VirtIOInput *vinput, virtio_input_config *config); +virtio_input_config *virtio_input_find_config(VirtIOInput *vinput, + uint8_t select, + uint8_t subsel); void virtio_input_add_config(VirtIOInput *vinput, virtio_input_config *config); void virtio_input_idstr_config(VirtIOInput *vinput, -- GitLab