This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new ab4890df16b drivers/input: partial fix of indistinguishable ASCII and 
special keycodes
ab4890df16b is described below

commit ab4890df16b63af85f546d05d7a7fe3a3ebf3980
Author: Pavel Pisa <[email protected]>
AuthorDate: Wed Jul 29 14:29:29 2026 +0200

    drivers/input: partial fix of indistinguishable ASCII and special keycodes
    
    As analyzed, the NuttX initial keyboard API design uses event
    type KBD_SPECPRESS/KBD_SPECREL to deliver special keys
    and KBD_PRESS/KBD_RELEASE to deliver ASCII codes.
    
    But it seems that this design choice has not been followed
    in virtio-input, goldfish_events and sim_keyboard designs
    and result is that external keyboard special keys events
    are mapped to KEYCODE_xxx values which start from 0 and
    overlaps with ASCII keys.
    
    The issue is tracked under #19527 number.
    
    This set of changes correct events reporting for mentioned
    keyboards to report right event type for special keys.
    
    The solution is only partial at this phase.
    
    Virtual and more complex keyboards usually deliver
    key pressures as scancodes (key position on keyboard)
    and mapping to ASCII for keys which corresponds to letter
    and other similar keys lacks mapping of national alphabets,
    second row symbols and switch to capital letter according
    to modifiers.
    
    Signed-off-by: Pavel Pisa <[email protected]>
---
 arch/sim/src/sim/sim_keyboard.c   |  16 ++-
 drivers/input/CMakeLists.txt      |   1 +
 drivers/input/Make.defs           |   1 +
 drivers/input/goldfish_events.c   |  17 ++-
 drivers/input/keyboard_upper.c    |  92 -------------
 drivers/input/virtio_key_decode.c | 281 ++++++++++++++++++++++++++++++++++++++
 drivers/virtio/virtio-input.c     |  18 ++-
 include/nuttx/input/keyboard.h    |   4 +-
 8 files changed, 328 insertions(+), 102 deletions(-)

diff --git a/arch/sim/src/sim/sim_keyboard.c b/arch/sim/src/sim/sim_keyboard.c
index d08556ae8e0..ec3c075d8f6 100644
--- a/arch/sim/src/sim/sim_keyboard.c
+++ b/arch/sim/src/sim/sim_keyboard.c
@@ -204,7 +204,7 @@ static uint32_t translate_x11_key(uint32_t code)
       return KEYCODE_F24;
 
     default:
-      return code;
+      return KEYCODE_NORMAL;
     }
 }
 
@@ -246,10 +246,16 @@ int sim_kbd_initialize(void)
 void sim_kbdevent(uint32_t key, bool is_press)
 {
   uint32_t trans_key;
+  bool is_special;
   struct sim_dev_s *priv = (struct sim_dev_s *) &g_simkeyboard;
-  uint32_t types[2] =
+  static const uint32_t types[2][2] =
     {
-      KEYBOARD_RELEASE, KEYBOARD_PRESS
+      {
+        KEYBOARD_RELEASE, KEYBOARD_PRESS
+      },
+      {
+        KBD_SPECREL, KBD_SPECPRESS
+      }
     };
 
   if (priv->eventloop == 0)
@@ -258,9 +264,11 @@ void sim_kbdevent(uint32_t key, bool is_press)
     }
 
   trans_key = translate_x11_key(key);
+  is_special = trans_key != KEYCODE_NORMAL;
+  trans_key = is_special ? trans_key : key;
   iinfo("key=%04x\n", key);
 
   /* Report data changes */
 
-  keyboard_event(&priv->lower, trans_key, types[is_press]);
+  keyboard_event(&priv->lower, trans_key, types[is_special][is_press]);
 }
diff --git a/drivers/input/CMakeLists.txt b/drivers/input/CMakeLists.txt
index 236da9ca944..4527d2c9530 100644
--- a/drivers/input/CMakeLists.txt
+++ b/drivers/input/CMakeLists.txt
@@ -104,6 +104,7 @@ if(CONFIG_INPUT)
 
   if(CONFIG_INPUT_KEYBOARD)
     list(APPEND SRCS keyboard_upper.c)
+    list(APPEND SRCS virtio_key_decode.c)
   endif()
 
   if(CONFIG_INPUT_KMATRIX)
diff --git a/drivers/input/Make.defs b/drivers/input/Make.defs
index 1c3d7432b01..e5408655a97 100644
--- a/drivers/input/Make.defs
+++ b/drivers/input/Make.defs
@@ -104,6 +104,7 @@ endif
 
 ifeq ($(CONFIG_INPUT_KEYBOARD),y)
   CSRCS += keyboard_upper.c
+  CSRCS += virtio_key_decode.c
 endif
 
 ifeq ($(CONFIG_INPUT_DJOYSTICK),y)
diff --git a/drivers/input/goldfish_events.c b/drivers/input/goldfish_events.c
index 6e371d53641..e6486cc3263 100644
--- a/drivers/input/goldfish_events.c
+++ b/drivers/input/goldfish_events.c
@@ -108,11 +108,24 @@ static bool
 goldfish_events_send_keyboard_event(FAR struct goldfish_events_s *events,
                                     FAR struct goldfish_input_event *evt)
 {
+  uint32_t trans_key;
+  bool is_special;
+  static const uint32_t types[2][2] =
+    {
+      {
+        KEYBOARD_RELEASE, KEYBOARD_PRESS
+      },
+      {
+        KBD_SPECREL, KBD_SPECPRESS
+      }
+    };
+
   if (evt->type == EV_KEY)
     {
+      trans_key = keyboard_translate_virtio_code(evt->code, &is_special);
       keyboard_event(&(events->keyboardlower),
-                     keyboard_translate_virtio_code(evt->code),
-                     !evt->value);
+                     trans_key,
+                     types[is_special][evt->value & 1]);
       return true;
     }
 
diff --git a/drivers/input/keyboard_upper.c b/drivers/input/keyboard_upper.c
index 5436a270e52..994190e57d1 100644
--- a/drivers/input/keyboard_upper.c
+++ b/drivers/input/keyboard_upper.c
@@ -33,7 +33,6 @@
 
 #include <nuttx/input/keyboard.h>
 #include <nuttx/input/kbd_codec.h>
-#include <nuttx/input/virtio-input-event-codes.h>
 #include <nuttx/kmalloc.h>
 #include <nuttx/list.h>
 #include <nuttx/circbuf.h>
@@ -423,94 +422,3 @@ void keyboard_event(FAR struct keyboard_lowerhalf_s 
*lower, uint32_t keycode,
 
   nxmutex_unlock(&upper->lock);
 }
-
-/****************************************************************************
- * keyboard_translate_virtio_code
- ****************************************************************************/
-
-uint32_t keyboard_translate_virtio_code(uint16_t keycode)
-{
-  switch (keycode)
-    {
-      case KEY_DELETE:
-        return KEYCODE_FWDDEL;
-      case KEY_BACKSPACE:
-        return KEYCODE_BACKDEL;
-      case KEY_HOME:
-        return KEYCODE_HOME;
-      case KEY_END:
-        return KEYCODE_END;
-      case KEY_LEFT:
-        return KEYCODE_LEFT;
-      case KEY_RIGHT:
-        return KEYCODE_RIGHT;
-      case KEY_UP:
-        return KEYCODE_UP;
-      case KEY_DOWN:
-        return KEYCODE_DOWN;
-      case KEY_PAGEUP:
-        return KEYCODE_PAGEUP;
-      case KEY_PAGEDOWN:
-        return KEYCODE_PAGEDOWN;
-      case KEY_ENTER:
-        return KEYCODE_ENTER;
-      case KEY_CAPSLOCK:
-        return KEYCODE_CAPSLOCK;
-      case KEY_SCROLLLOCK:
-        return KEYCODE_SCROLLLOCK;
-      case KEY_NUMLOCK:
-        return KEYCODE_NUMLOCK;
-      case KEY_SYSRQ:
-        return KEYCODE_PRTSCRN;
-      case KEY_F1:
-        return KEYCODE_F1;
-      case KEY_F2:
-        return KEYCODE_F2;
-      case KEY_F3:
-        return KEYCODE_F3;
-      case KEY_F4:
-        return KEYCODE_F4;
-      case KEY_F5:
-        return KEYCODE_F5;
-      case KEY_F6:
-        return KEYCODE_F6;
-      case KEY_F7:
-        return KEYCODE_F7;
-      case KEY_F8:
-        return KEYCODE_F8;
-      case KEY_F9:
-        return KEYCODE_F9;
-      case KEY_F10:
-        return KEYCODE_F10;
-      case KEY_F11:
-        return KEYCODE_F11;
-      case KEY_F12:
-        return KEYCODE_F12;
-      case KEY_F13:
-        return KEYCODE_F13;
-      case KEY_F14:
-        return KEYCODE_F14;
-      case KEY_F15:
-        return KEYCODE_F15;
-      case KEY_F16:
-        return KEYCODE_F16;
-      case KEY_F17:
-        return KEYCODE_F17;
-      case KEY_F18:
-        return KEYCODE_F18;
-      case KEY_F19:
-        return KEYCODE_F19;
-      case KEY_F20:
-        return KEYCODE_F20;
-      case KEY_F21:
-        return KEYCODE_F21;
-      case KEY_F22:
-        return KEYCODE_F22;
-      case KEY_F23:
-        return KEYCODE_F23;
-      case KEY_F24:
-        return KEYCODE_F24;
-      default:
-        return keycode;
-    }
-}
diff --git a/drivers/input/virtio_key_decode.c 
b/drivers/input/virtio_key_decode.c
new file mode 100644
index 00000000000..7db6879c5f2
--- /dev/null
+++ b/drivers/input/virtio_key_decode.c
@@ -0,0 +1,281 @@
+/****************************************************************************
+ * drivers/input/virtio_key_decode.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdbool.h>
+
+#include <nuttx/config.h>
+
+#include <nuttx/input/kbd_codec.h>
+#include <nuttx/input/virtio-input-event-codes.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function
+ ****************************************************************************/
+
+/****************************************************************************
+ * keyboard_translate_virtio_code
+ ****************************************************************************/
+
+uint32_t keyboard_translate_virtio_code(uint16_t keycode, bool *special)
+{
+  *special = true;
+  switch (keycode)
+    {
+      case KEY_DELETE:
+        return KEYCODE_FWDDEL;
+      case KEY_BACKSPACE:
+        return KEYCODE_BACKDEL;
+      case KEY_HOME:
+        return KEYCODE_HOME;
+      case KEY_END:
+        return KEYCODE_END;
+      case KEY_LEFT:
+        return KEYCODE_LEFT;
+      case KEY_RIGHT:
+        return KEYCODE_RIGHT;
+      case KEY_UP:
+        return KEYCODE_UP;
+      case KEY_DOWN:
+        return KEYCODE_DOWN;
+      case KEY_PAGEUP:
+        return KEYCODE_PAGEUP;
+      case KEY_PAGEDOWN:
+        return KEYCODE_PAGEDOWN;
+      case KEY_ENTER:
+        return KEYCODE_ENTER;
+      case KEY_CAPSLOCK:
+        return KEYCODE_CAPSLOCK;
+      case KEY_SCROLLLOCK:
+        return KEYCODE_SCROLLLOCK;
+      case KEY_NUMLOCK:
+        return KEYCODE_NUMLOCK;
+      case KEY_SYSRQ:
+        return KEYCODE_PRTSCRN;
+      case KEY_F1:
+        return KEYCODE_F1;
+      case KEY_F2:
+        return KEYCODE_F2;
+      case KEY_F3:
+        return KEYCODE_F3;
+      case KEY_F4:
+        return KEYCODE_F4;
+      case KEY_F5:
+        return KEYCODE_F5;
+      case KEY_F6:
+        return KEYCODE_F6;
+      case KEY_F7:
+        return KEYCODE_F7;
+      case KEY_F8:
+        return KEYCODE_F8;
+      case KEY_F9:
+        return KEYCODE_F9;
+      case KEY_F10:
+        return KEYCODE_F10;
+      case KEY_F11:
+        return KEYCODE_F11;
+      case KEY_F12:
+        return KEYCODE_F12;
+      case KEY_F13:
+        return KEYCODE_F13;
+      case KEY_F14:
+        return KEYCODE_F14;
+      case KEY_F15:
+        return KEYCODE_F15;
+      case KEY_F16:
+        return KEYCODE_F16;
+      case KEY_F17:
+        return KEYCODE_F17;
+      case KEY_F18:
+        return KEYCODE_F18;
+      case KEY_F19:
+        return KEYCODE_F19;
+      case KEY_F20:
+        return KEYCODE_F20;
+      case KEY_F21:
+        return KEYCODE_F21;
+      case KEY_F22:
+        return KEYCODE_F22;
+      case KEY_F23:
+        return KEYCODE_F23;
+      case KEY_F24:
+        return KEYCODE_F24;
+      default:
+    }
+
+  *special = false;
+  switch (keycode)
+    {
+       case KEY_ESC:
+        return '\e';
+      case KEY_1:
+        return '1';
+      case KEY_2:
+        return '2';
+      case KEY_3:
+        return '3';
+      case KEY_4:
+        return '4';
+      case KEY_5:
+        return '5';
+      case KEY_6:
+        return '6';
+      case KEY_7:
+        return '7';
+      case KEY_8:
+        return '8';
+      case KEY_9:
+        return '9';
+      case KEY_0:
+        return '0';
+      case KEY_MINUS:
+        return '-';
+      case KEY_EQUAL:
+        return '=';
+      case KEY_TAB:
+        return '\t';
+      case KEY_Q:
+        return 'q';
+      case KEY_W:
+        return 'w';
+      case KEY_E:
+        return 'e';
+      case KEY_R:
+        return 'r';
+      case KEY_T:
+        return 't';
+      case KEY_Y:
+        return 'y';
+      case KEY_U:
+        return 'u';
+      case KEY_I:
+        return 'i';
+      case KEY_O:
+        return 'o';
+      case KEY_P:
+        return 'p';
+      case KEY_LEFTBRACE:
+        return '(';
+      case KEY_RIGHTBRACE:
+        return ')';
+      case KEY_A:
+        return 'a';
+      case KEY_S:
+        return 's';
+      case KEY_D:
+        return 'd';
+      case KEY_F:
+        return 'f';
+      case KEY_G:
+        return 'g';
+      case KEY_H:
+        return 'h';
+      case KEY_J:
+        return 'j';
+      case KEY_K:
+        return 'k';
+      case KEY_L:
+        return 'l';
+      case KEY_SEMICOLON:
+        return ';';
+      case KEY_APOSTROPHE:
+        return '\'';
+      case KEY_BACKSLASH:
+        return '\\';
+      case KEY_Z:
+        return 'z';
+      case KEY_X:
+        return 'x';
+      case KEY_C:
+        return 'c';
+      case KEY_V:
+        return 'v';
+      case KEY_B:
+        return 'b';
+      case KEY_N:
+        return 'n';
+      case KEY_M:
+        return 'm';
+      case KEY_COMMA:
+        return ',';
+      case KEY_DOT:
+        return '.';
+      case KEY_SLASH:
+        return '/';
+      case KEY_KPASTERISK:
+        return '*';
+      case KEY_SPACE:
+        return ' ';
+      case KEY_KP7:
+        return '7';
+      case KEY_KP8:
+        return '8';
+      case KEY_KP9:
+        return '9';
+      case KEY_KPMINUS:
+        return '-';
+      case KEY_KP4:
+        return '4';
+      case KEY_KP5:
+        return '5';
+      case KEY_KP6:
+        return '6';
+      case KEY_KPPLUS:
+        return '+';
+      case KEY_KP1:
+        return '1';
+      case KEY_KP2:
+        return '2';
+      case KEY_KP3:
+        return '3';
+      case KEY_KP0:
+        return '0';
+      case KEY_KPDOT:
+        return '.';
+      default:
+    }
+
+  return 0;
+}
diff --git a/drivers/virtio/virtio-input.c b/drivers/virtio/virtio-input.c
index e8561a1c513..d68007452bd 100644
--- a/drivers/virtio/virtio-input.c
+++ b/drivers/virtio/virtio-input.c
@@ -117,11 +117,23 @@ static void
 virtio_input_send_keyboard_event(FAR struct virtio_input_priv *priv,
                                  FAR struct virtio_input_event *event)
 {
+  static const uint32_t types[2][2] =
+    {
+      {
+        KEYBOARD_RELEASE, KEYBOARD_PRESS
+      },
+      {
+        KBD_SPECREL, KBD_SPECPRESS
+      }
+    };
+
   if (event->type == EV_KEY)
     {
-      priv->keyboardsample.code =
-        keyboard_translate_virtio_code(event->code);
-      priv->keyboardsample.type = event->value;
+      uint32_t trans_key;
+      bool is_special;
+      trans_key = keyboard_translate_virtio_code(event->code, &is_special);
+      priv->keyboardsample.code = trans_key;
+      priv->keyboardsample.type = types[is_special][event->value & 1];
     }
   else if (event->type == EV_SYN && event->code == SYN_REPORT)
     {
diff --git a/include/nuttx/input/keyboard.h b/include/nuttx/input/keyboard.h
index 0f52d9bf179..98b408a4d64 100644
--- a/include/nuttx/input/keyboard.h
+++ b/include/nuttx/input/keyboard.h
@@ -27,6 +27,8 @@
  * Included Files
  ****************************************************************************/
 
+#include <stdbool.h>
+
 #include <nuttx/config.h>
 
 #include <nuttx/input/x11_keysym.h>
@@ -95,7 +97,7 @@ int keyboard_unregister(FAR struct keyboard_lowerhalf_s 
*lower,
  * Name: keyboard_translate_virtio_code
  ****************************************************************************/
 
-uint32_t keyboard_translate_virtio_code(uint16_t keycode);
+uint32_t keyboard_translate_virtio_code(uint16_t keycode, bool *special);
 
 #undef EXTERN
 #ifdef __cplusplus

Reply via email to