You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2026/10/22 02:21:23 UTC
(nuttx) 02/02: drivers/virtio-input: support virtio-tablet device
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 <ro...@xiaomi.com>
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 <ro...@xiaomi.com>
---
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);
}