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 <lprosek@redhat.com> Message-id: 1460558603-18331-1-git-send-email-lprosek@redhat.com Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
ce47d3d427
commit
b065e275a8
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user