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);
     }

Reply via email to