Message ID | 20240322102421.2158139-1-christian.poetzsch@kernkonzept.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add support for abs info in vhost-user-input | expand |
Ping. Anyone interested? Thanks Chris On 3/22/24 11:24, Christian Pötzsch wrote: > Absolute input device did not work, cause VIRTIO_INPUT_CFG_ABS_INFO is > missing. Fetch this info when available and provide it to any virtio > client. > > This is basically the same code as in hw/input/virtio-input-host.c, just > modified to work here. > > Signed-off-by: Christian Pötzsch <christian.poetzsch@kernkonzept.com> > --- > contrib/vhost-user-input/main.c | 46 +++++++++++++++++++++++++++++++-- > 1 file changed, 44 insertions(+), 2 deletions(-) > > diff --git a/contrib/vhost-user-input/main.c b/contrib/vhost-user-input/main.c > index 081230da54..9506e34d04 100644 > --- a/contrib/vhost-user-input/main.c > +++ b/contrib/vhost-user-input/main.c > @@ -272,6 +272,32 @@ vi_bits_config(VuInput *vi, int type, int count) > g_array_append_val(vi->config, bits); > } > > +static void > +vi_input_abs_config(VuInput *vi, int axis) > +{ > + virtio_input_config config; > + struct input_absinfo absinfo; > + int rc; > + > + rc = ioctl(vi->evdevfd, 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(struct 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); > + > + g_array_append_val(vi->config, config); > +} > + > static char *opt_evdev; > static int opt_fdnum = -1; > static char *opt_socket_path; > @@ -297,11 +323,12 @@ main(int argc, char *argv[]) > { > GMainLoop *loop = NULL; > VuInput vi = { 0, }; > - int rc, ver, fd; > - virtio_input_config id; > + int rc, ver, fd, i, axis; > + virtio_input_config id, *abs; > struct input_id ids; > GError *error = NULL; > GOptionContext *context; > + uint8_t byte; > > context = g_option_context_new(NULL); > g_option_context_add_main_entries(context, entries, NULL); > @@ -375,6 +402,21 @@ main(int argc, char *argv[]) > vi_bits_config(&vi, EV_ABS, ABS_CNT); > vi_bits_config(&vi, EV_MSC, MSC_CNT); > vi_bits_config(&vi, EV_SW, SW_CNT); > + > + abs = vi_find_config(&vi, 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) { > + vi_input_abs_config(&vi, axis); > + } > + axis++; > + byte >>= 1; > + } > + } > + } > g_debug("config length: %u", vi.config->len); > > if (opt_socket_path) {
diff --git a/contrib/vhost-user-input/main.c b/contrib/vhost-user-input/main.c index 081230da54..9506e34d04 100644 --- a/contrib/vhost-user-input/main.c +++ b/contrib/vhost-user-input/main.c @@ -272,6 +272,32 @@ vi_bits_config(VuInput *vi, int type, int count) g_array_append_val(vi->config, bits); } +static void +vi_input_abs_config(VuInput *vi, int axis) +{ + virtio_input_config config; + struct input_absinfo absinfo; + int rc; + + rc = ioctl(vi->evdevfd, 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(struct 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); + + g_array_append_val(vi->config, config); +} + static char *opt_evdev; static int opt_fdnum = -1; static char *opt_socket_path; @@ -297,11 +323,12 @@ main(int argc, char *argv[]) { GMainLoop *loop = NULL; VuInput vi = { 0, }; - int rc, ver, fd; - virtio_input_config id; + int rc, ver, fd, i, axis; + virtio_input_config id, *abs; struct input_id ids; GError *error = NULL; GOptionContext *context; + uint8_t byte; context = g_option_context_new(NULL); g_option_context_add_main_entries(context, entries, NULL); @@ -375,6 +402,21 @@ main(int argc, char *argv[]) vi_bits_config(&vi, EV_ABS, ABS_CNT); vi_bits_config(&vi, EV_MSC, MSC_CNT); vi_bits_config(&vi, EV_SW, SW_CNT); + + abs = vi_find_config(&vi, 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) { + vi_input_abs_config(&vi, axis); + } + axis++; + byte >>= 1; + } + } + } g_debug("config length: %u", vi.config->len); if (opt_socket_path) {
Absolute input device did not work, cause VIRTIO_INPUT_CFG_ABS_INFO is missing. Fetch this info when available and provide it to any virtio client. This is basically the same code as in hw/input/virtio-input-host.c, just modified to work here. Signed-off-by: Christian Pötzsch <christian.poetzsch@kernkonzept.com> --- contrib/vhost-user-input/main.c | 46 +++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-)