Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/hidkbd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ config EXAMPLES_HIDKBD_DEVNAME
config EXAMPLES_HIDKBD_ENCODED
bool "Encode Special Keys"
default y
depends on HIDKBD_ENCODED && LIBC_KBDCODEC
depends on INPUT_KEYBOARD_BYTESTREAM
---help---
Decode special key press events in the user buffer. In this case,
the example coded will use the interfaces defined in
Expand Down
5 changes: 4 additions & 1 deletion examples/hidkbd/hidkbd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include <nuttx/usb/usbhost.h>

#ifdef CONFIG_EXAMPLES_HIDKBD_ENCODED
# include <ctype.h>

# include <nuttx/streams.h>
# include <nuttx/input/kbd_codec.h>
#endif
Expand All @@ -55,7 +57,8 @@
# define CONFIG_EXAMPLES_HIDKBD_DEVNAME "/dev/kbda"
#endif

#if !defined(CONFIG_HIDKBD_ENCODED) || !defined(CONFIG_LIBC_KBDCODEC)
#if !defined(CONFIG_INPUT_KEYBOARD_BYTESTREAM) || \
!defined(CONFIG_LIBC_KBDCODEC)
# undef CONFIG_EXAMPLES_HIDKBD_ENCODED
#endif

Expand Down
32 changes: 11 additions & 21 deletions examples/lvglterm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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)"
Expand All @@ -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
Expand Down
137 changes: 66 additions & 71 deletions examples/lvglterm/lvglterm_kbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/

/****************************************************************************
Expand All @@ -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
Expand All @@ -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 */

/****************************************************************************
Expand Down Expand Up @@ -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
****************************************************************************/
Expand Down Expand Up @@ -171,90 +191,65 @@ 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)
{
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;
}

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
}
Loading
Loading