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-apps.git

commit 47b3f92f9d054954f7523345cce69b73e0b5b9b8
Author: Jorge Guzman <[email protected]>
AuthorDate: Thu Jul 30 16:55:35 2026 -0300

    examples/lvglterm: read any keyboard through one input path
    
    The terminal had three input sources to choose from, and its own help
    text explained why:  the physical keyboard options "differ in the data
    the keyboard device delivers on read(), so pick the one that matches the
    hardware".  That is the abstraction leaking.  A user had to know that
    the keyboard was USB rather than a matrix in order to compile the
    terminal, and swapping one for the other meant rebuilding.
    
    There are two sources now, touch and physical, and the physical one
    reads any keyboard registered with keyboard_register().  Which format
    arrives is decided by INPUT_KEYBOARD_BYTESTREAM, a property of the build
    rather than of the hardware, so the terminal no longer asks.
    
    Cursor keys reported as special events scroll the terminal, which is
    what a driver following the current contract sends.  The out of band
    codes that the M5Stack Cardputer reports as ordinary presses are still
    honoured, so that board keeps working until its driver is converted.
    
    Signed-off-by: Jorge Guzman <[email protected]>
---
 examples/lvglterm/Kconfig        |  32 ++++-----
 examples/lvglterm/lvglterm_kbd.c | 137 +++++++++++++++++++--------------------
 2 files changed, 77 insertions(+), 92 deletions(-)

diff --git a/examples/lvglterm/Kconfig b/examples/lvglterm/Kconfig
index ca393e845..7c4a70683 100644
--- a/examples/lvglterm/Kconfig
+++ b/examples/lvglterm/Kconfig
@@ -17,9 +17,7 @@ choice
        default EXAMPLES_LVGLTERM_INPUT_TOUCH
        ---help---
                Select how the terminal receives keystrokes.  Only one input 
source
-               is built at a time.  The physical-keyboard options differ in 
the data
-               the keyboard device delivers on read(), so pick the one that 
matches
-               the hardware.
+               is built at a time.
 
 config EXAMPLES_LVGLTERM_INPUT_TOUCH
        bool "On-screen keyboard (touch)"
@@ -28,37 +26,29 @@ config EXAMPLES_LVGLTERM_INPUT_TOUCH
                command line is typed and submitted with Enter.  This is the 
default
                and matches the original behaviour.
 
-config EXAMPLES_LVGLTERM_INPUT_KBD_MATRIX
-       bool "Matrix / upper-half keyboard (keyboard events)"
+config EXAMPLES_LVGLTERM_INPUT_KBD
+       bool "Physical keyboard"
        depends on INPUT_KEYBOARD
        ---help---
-               Physical keyboard registered through the INPUT_KEYBOARD upper 
half,
-               whose read() returns struct keyboard_event_s events (for 
example the
-               M5Stack Cardputer matrix keyboard on /dev/kbd0).  Fn Up/Down 
scroll
-               the terminal.
-
-config EXAMPLES_LVGLTERM_INPUT_KBD_USB
-       bool "USB HID keyboard (byte stream)"
-       depends on USBHOST_HIDKBD
-       select LIBC_KBDCODEC
-       ---help---
-               USB HID keyboard (for example on /dev/kbda with 
CONFIG_USBHOST_HIDKBD).
-               read() returns a byte stream that is decoded with the keyboard 
codec:
-               normal keys go to the shell and, when the driver is built with
-               CONFIG_HIDKBD_ENCODED, the Up/Down cursor keys scroll the 
terminal.
+               Any keyboard registered with keyboard_register():  USB HID, a 
matrix,
+               the simulator, virtio.  The terminal does not need to know 
which one
+               it is.  Cursor Up and Down scroll the terminal, everything else 
goes
+               to the shell.
 
 endchoice
 
 config EXAMPLES_LVGLTERM_KBD_DEV
        string "Keyboard device path"
-       default "/dev/kbda" if EXAMPLES_LVGLTERM_INPUT_KBD_USB
        default "/dev/kbd0"
-       depends on EXAMPLES_LVGLTERM_INPUT_KBD_MATRIX || 
EXAMPLES_LVGLTERM_INPUT_KBD_USB
+       depends on EXAMPLES_LVGLTERM_INPUT_KBD
        ---help---
                Keyboard device the terminal reads from.  Can also be 
overridden at
                run time by passing the path as the first command-line argument
                (useful when more than one keyboard is present).
 
+               Note that the USB HID driver names its devices /dev/kbda 
onwards,
+               since they come and go as keyboards are plugged in.
+
 choice
        prompt "LVGL Terminal font"
        default EXAMPLES_LVGLTERM_FONT_UNSCII_16
diff --git a/examples/lvglterm/lvglterm_kbd.c b/examples/lvglterm/lvglterm_kbd.c
index 08ae83612..daea4c50b 100644
--- a/examples/lvglterm/lvglterm_kbd.c
+++ b/examples/lvglterm/lvglterm_kbd.c
@@ -26,15 +26,13 @@
  * a keyboard driver; the device defaults to CONFIG_EXAMPLES_LVGLTERM_KBD_DEV
  * and can be overridden by the first command-line argument.
  *
- * Two device flavours are supported, selected at build time:
+ * Any keyboard registered with keyboard_register() works:  USB HID, a
+ * matrix, the simulator, virtio.  Which one it is makes no difference here.
  *
- *   - Upper-half keyboards (INPUT_KEYBOARD, e.g. the M5Stack Cardputer
- *     matrix on /dev/kbd0) deliver struct keyboard_event_s events; the Fn
- *     Up/Down keys are handled locally as scroll requests.
- *   - USB HID keyboards (EXAMPLES_LVGLTERM_INPUT_KBD_USB, e.g. /dev/kbda)
- *     deliver a byte stream decoded with the NuttX keyboard codec: normal
- *     keys are forwarded to the shell and, when the driver is built with
- *     CONFIG_HIDKBD_ENCODED, the Up/Down cursor keys scroll the terminal.
+ * The device delivers struct keyboard_event_s events unless the kernel was
+ * built with INPUT_KEYBOARD_BYTESTREAM, in which case it delivers the byte
+ * stream that the keyboard codec defines.  That is a property of the build
+ * rather than of the hardware, so it is what selects the reader below.
  */
 
 /****************************************************************************
@@ -50,11 +48,9 @@
 #include <errno.h>
 #include <debug.h>
 
-#ifdef CONFIG_EXAMPLES_LVGLTERM_INPUT_KBD_MATRIX
-#  include <nuttx/input/keyboard.h>
-#endif
+#include <nuttx/input/keyboard.h>
 
-#ifdef CONFIG_EXAMPLES_LVGLTERM_INPUT_KBD_USB
+#ifdef CONFIG_INPUT_KEYBOARD_BYTESTREAM
 #  include <nuttx/streams.h>
 #  include <nuttx/input/kbd_codec.h>
 #endif
@@ -67,17 +63,6 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-/* Out-of-band key codes for the Fn + navigation cluster (cursor keys),
- * reported by keyboard drivers that follow this convention (for example the
- * M5Stack Cardputer).  Up/Down scroll the terminal instead of going to the
- * shell; drivers that do not emit these codes keep normal behaviour.
- */
-
-#define KEY_UP         0x80
-#define KEY_DOWN       0x81
-#define KEY_LEFT       0x82
-#define KEY_RIGHT      0x83
-
 #define SCROLL_STEP    24          /* Pixels scrolled per Up/Down keypress */
 
 /****************************************************************************
@@ -134,6 +119,41 @@ static void scroll_terminal(bool up)
   lv_obj_scroll_by(g_output, 0, dy, LV_ANIM_OFF);
 }
 
+/****************************************************************************
+ * Name: handle_key
+ *
+ * Description:
+ *   Act on one key press.  Cursor Up and Down scroll the terminal, anything
+ *   else goes to the shell.
+ *
+ * Input Parameters:
+ *   code    - The character, or a value from enum kbd_keycode_e
+ *   special - True if the code is a keycode rather than a character.  The
+ *             two ranges overlap, so this is what tells them apart.
+ *
+ ****************************************************************************/
+
+static void handle_key(uint32_t code, bool special)
+{
+  if (special)
+    {
+      if (code == KEYCODE_UP)
+        {
+          scroll_terminal(true);
+        }
+      else if (code == KEYCODE_DOWN)
+        {
+          scroll_terminal(false);
+        }
+
+      /* Any other special key has no meaning to a terminal */
+
+      return;
+    }
+
+  feed_char(code);
+}
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -171,25 +191,21 @@ void lvglterm_input_create(int argc, FAR char *argv[])
 
 void lvglterm_input_poll(void)
 {
-  if (g_kfd < 0)
-    {
-      return;
-    }
-
-#ifdef CONFIG_EXAMPLES_LVGLTERM_INPUT_KBD_USB
-  /* USB HID keyboard: read() returns a byte stream that is decoded with the
-   * keyboard codec.  Normal keys are fed to the shell; the Up/Down cursor
-   * keys (only emitted when the driver is built with CONFIG_HIDKBD_ENCODED)
-   * scroll the terminal.  On a plain-ASCII stream every byte simply decodes
-   * to a normal key press, so this also works without encoding.
-   */
-
-  struct lib_meminstream_s stream;
-  struct kbd_getstate_s state;
   char buf[64];
   ssize_t nread;
+#ifdef CONFIG_INPUT_KEYBOARD_BYTESTREAM
+  struct lib_meminstream_s stream;
+  struct kbd_getstate_s state;
   uint8_t ch;
   int ret;
+#else
+  FAR struct keyboard_event_s *evt;
+#endif
+
+  if (g_kfd < 0)
+    {
+      return;
+    }
 
   nread = read(g_kfd, buf, sizeof(buf));
   if (nread <= 0)
@@ -197,12 +213,13 @@ void lvglterm_input_poll(void)
       return;
     }
 
+#ifdef CONFIG_INPUT_KEYBOARD_BYTESTREAM
   memset(&state, 0, sizeof(state));
   lib_meminstream(&stream, buf, nread);
 
   for (; ; )
     {
-      ret = kbd_decode((FAR struct lib_instream_s *)&stream, &state, &ch);
+      ret = kbd_decode(&stream.common, &state, &ch);
       if (ret == KBD_ERROR)
         {
           break;
@@ -210,51 +227,29 @@ void lvglterm_input_poll(void)
 
       if (ret == KBD_PRESS)
         {
-          feed_char((char)ch);
+          handle_key(ch, false);
         }
       else if (ret == KBD_SPECPRESS)
         {
-          if (ch == KEYCODE_UP)
-            {
-              scroll_terminal(true);
-            }
-          else if (ch == KEYCODE_DOWN)
-            {
-              scroll_terminal(false);
-            }
+          handle_key(ch, true);
         }
     }
 #else
-  /* Upper-half keyboard: read() returns keyboard_event_s events */
-
-  struct keyboard_event_s evt;
+  evt = (FAR struct keyboard_event_s *)buf;
 
-  while (read(g_kfd, &evt, sizeof(evt)) == (ssize_t)sizeof(evt))
+  while (nread >= (ssize_t)sizeof(struct keyboard_event_s))
     {
-      if (evt.type != KEYBOARD_PRESS)
+      if (evt->type == KEYBOARD_PRESS)
         {
-          continue;
+          handle_key(evt->code, false);
         }
-
-      /* Fn navigation keys are handled locally: Up/Down scroll the terminal;
-       * Left/Right are reserved and simply swallowed for now.
-       */
-
-      if (evt.code >= KEY_UP && evt.code <= KEY_RIGHT)
+      else if (evt->type == KEYBOARD_SPECPRESS)
         {
-          if (evt.code == KEY_UP)
-            {
-              scroll_terminal(true);
-            }
-          else if (evt.code == KEY_DOWN)
-            {
-              scroll_terminal(false);
-            }
-
-          continue;
+          handle_key(evt->code, true);
         }
 
-      feed_char((char)evt.code);
+      nread -= sizeof(struct keyboard_event_s);
+      evt++;
     }
 #endif
 }

Reply via email to