This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 6b4d2b31168a7e387e738436adaa3f25344a466c Author: rongyichang <[email protected]> AuthorDate: Wed Jun 10 20:37:14 2026 +0800 drivers/virtio-input: support virtio-tablet device QEMU's virtio-tablet-device reports absolute EV_ABS positions with BTN_LEFT/BTN_TOUCH as the contact, but no ABS_PRESSURE. The touch handler treated it as a touchscreen and never produced usable samples. Register a device that advertises EV_KEY together with EV_ABS as a tablet and translate its events into single-point touch samples. Raise the event ring from 8 to 64 entries so a burst of ABS/KEY/SYN events is not dropped. Signed-off-by: rongyichang <[email protected]> --- drivers/virtio/virtio-input.c | 80 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/drivers/virtio/virtio-input.c b/drivers/virtio/virtio-input.c index aa6571476c8..76dd7436156 100644 --- a/drivers/virtio/virtio-input.c +++ b/drivers/virtio/virtio-input.c @@ -47,7 +47,7 @@ #define VIRTIO_INPUT_EVENT 0 #define VIRTIO_INPUT_NUM 1 -#define VIRTIO_INPUT_EVT_NUM 8 +#define VIRTIO_INPUT_EVT_NUM 64 /**************************************************************************** * Private Types @@ -256,6 +256,68 @@ virtio_input_send_touch_event(FAR struct virtio_input_priv *priv, } } +/**************************************************************************** + * Name: virtio_input_send_tablet_event + ****************************************************************************/ + +static void +virtio_input_send_tablet_event(FAR struct virtio_input_priv *priv, + FAR struct virtio_input_event *event) +{ + FAR struct touch_point_s *point = &priv->touchsample.point[0]; + + if (event->type == EV_ABS) + { + switch (event->code) + { + case ABS_X: + point->x = event->value; + break; + + case ABS_Y: + point->y = event->value; + break; + } + } + else if (event->type == EV_KEY) + { + if (event->code == BTN_LEFT || event->code == BTN_TOUCH) + { + if (!event->value) + { + point->flags = TOUCH_UP; + } + else if (point->flags == TOUCH_UP) + { + point->flags = TOUCH_DOWN; + } + else + { + point->flags = TOUCH_MOVE; + } + } + } + else if (event->type == EV_SYN && event->code == SYN_REPORT) + { + if (point->flags & TOUCH_UP) + { + point->flags = TOUCH_UP | TOUCH_ID_VALID; + } + else + { + point->flags |= TOUCH_ID_VALID | TOUCH_POS_VALID; + } + + priv->touchsample.npoints = 1; + point->timestamp = touch_get_time(); + touch_event(priv->touchlower.priv, &priv->touchsample); + + /* Reset flags: keep UP as idle, DOWN transitions to MOVE */ + + point->flags = (point->flags & TOUCH_UP) ? TOUCH_UP : TOUCH_MOVE; + } +} + /**************************************************************************** * Name: virtio_input_worker ****************************************************************************/ @@ -354,7 +416,18 @@ static void virtio_input_register(FAR struct virtio_input_priv *priv) touch_register(&(priv->touchlower), priv->name, priv->evtnum); - priv->eventhandler = virtio_input_send_touch_event; + + /* Tablet (BTN_LEFT) vs real touchscreen (ABS_PRESSURE) */ + + if (virtio_input_select_cfg(priv, VIRTIO_INPUT_CFG_EV_BITS, EV_KEY)) + { + priv->touchsample.point[0].flags = TOUCH_UP; + priv->eventhandler = virtio_input_send_tablet_event; + } + else + { + priv->eventhandler = virtio_input_send_touch_event; + } } else if (virtio_input_select_cfg(priv, VIRTIO_INPUT_CFG_EV_BITS, EV_REL)) { @@ -446,7 +519,8 @@ static void virtio_input_remove(FAR struct virtio_device *vdev) { mouse_unregister(&(priv->mouselower), priv->name); } - else if (priv->eventhandler == virtio_input_send_touch_event) + else if (priv->eventhandler == virtio_input_send_touch_event || + priv->eventhandler == virtio_input_send_tablet_event) { touch_unregister(&(priv->touchlower), priv->name); }
