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 }
