Add K5Viewer support to overlay menu and apps

This commit is contained in:
Armel FAUVEAU committed 2026-08-30 18:31:50 +02:00
1 parent 2a82a62ffd
commit 66ca97fa5e
2 files changed
+55 -1

No files matched your search

+21
View File
@@ -25,6 +25,9 @@
#include "driver/system.h"
#include "driver/gpio.h"
#include "ui/helper.h"
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
#include "k5viewer.h"
#endif
/* "F4HWN APPS" banner and the same thin separator used by the multiboot
* selector. Bit 3 leaves room for the selected-row capsule's top edge. */
@@ -75,6 +78,12 @@ static KEY_Code_t app_get_key(void)
{
for (;;)
{
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
/* APP_MenuOpen() is modal and does not return to APP_Update(). Keep
* serial key injection and the viewer connection alive while waiting. */
K5VIEWER_ParseInput();
K5VIEWER_Update(false);
#endif
KEY_Code_t key = KEYBOARD_Poll();
if (key != KEY_INVALID)
{
@@ -179,6 +188,15 @@ _Static_assert(APP_MENU_SLOT_COUNT <= APP_SLOT_COUNT,
void APP_MenuOpen(void)
{
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
/* Detach the modal selector from the key state that triggered F+7. The
* normal K5Viewer updater suppresses frames while a key is held; without
* clearing this stale state, the selector could never publish its first
* frame to the viewer. */
gKeyReading0 = KEY_INVALID;
gKeyReading1 = KEY_INVALID;
#endif
/* Apps are installed from UV Studio (0x073x) into physical slots 0..N-1,
* shown here as 1..N. Keep empty slots in the list so their location is
* visible and selectable while scrolling. */
@@ -245,6 +263,9 @@ void APP_MenuOpen(void)
ST7565_BlitStatusLine();
ST7565_BlitFullScreen();
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
K5VIEWER_Update(false);
#endif
const KEY_Code_t key = app_get_key();
if (key == KEY_EXIT)
+34 -1
View File
@@ -33,6 +33,9 @@
#include "driver/st7565.h"
#include "driver/system.h"
#include "driver/backlight.h"
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
#include "k5viewer.h"
#endif
#include "app/app.h"
#include "ui/helper.h"
#include "ui/main.h"
@@ -50,7 +53,25 @@
_Static_assert(sizeof(app_header_t) == 64, "app_header_t must be 64 bytes");
/* ---- ABI wrappers: the few resident calls that are not a direct signature match ---- */
static uint8_t app_get_key(void) { return (uint8_t)KEYBOARD_GetKey(); }
static uint8_t app_get_key(void)
{
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
/* Overlay apps run synchronously outside APP_Update(). Keep serial key
* injection alive while an app owns the foreground loop. */
K5VIEWER_ParseInput();
#endif
return (uint8_t)KEYBOARD_GetKey();
}
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
static void app_blit_full(void)
{
ST7565_BlitFullScreen();
/* The normal loop mirrors completed frames after drawing. Overlay apps
* bypass that loop, so publish the frame from this ABI wrapper. */
K5VIEWER_Update(false);
}
#endif
static int8_t app_nav_dir(uint8_t key)
{
int8_t direction;
@@ -635,7 +656,11 @@ static const app_api_t app_api = {
.draw_rect = UI_DrawRectangleBuffer,
.print_bold = UI_PrintStringSmallBold,
.print_tiny = GUI_DisplaySmallest,
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
.blit_full = app_blit_full,
#else
.blit_full = ST7565_BlitFullScreen,
#endif
.blit_line = ST7565_BlitLine,
.blit_status = ST7565_BlitStatusLine,
.get_key = app_get_key,
@@ -730,6 +755,14 @@ uint8_t APP_LaunchOverlay(uint8_t slot)
app_fm_dirty = false;
#endif
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
/* The caller enters from a debounced key event, so the resident key state
* still contains that trigger while the modal app is running. Clear it so
* K5Viewer is allowed to mirror overlay frames immediately. */
gKeyReading0 = KEY_INVALID;
gKeyReading1 = KEY_INVALID;
#endif
/* Pin RX to the user-selected VFO before the app runs. Under dual watch
* gRxVfo is whichever VFO the receiver was parked on when F+7 was pressed,
* so an RF app (FoxHunt, a future S-meter, ...) would measure and display a