From b627d305d0fa21f97878a055a6fd404517956632 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Wed, 6 Aug 2025 22:13:17 -0500 Subject: [PATCH] Add SDL option to BaseUI on Native --- arch/portduino/portduino.ini | 2 +- src/graphics/TFTDisplay.cpp | 60 +++++++++++++++++++++++- src/graphics/TFTDisplay.h | 1 + src/main.cpp | 8 +++- variants/native/portduino/platformio.ini | 1 + 5 files changed, 68 insertions(+), 4 deletions(-) diff --git a/arch/portduino/portduino.ini b/arch/portduino/portduino.ini index 693ab63b7..aa10f70fd 100644 --- a/arch/portduino/portduino.ini +++ b/arch/portduino/portduino.ini @@ -27,7 +27,7 @@ lib_deps = # renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto rweather/Crypto@0.4.0 # renovate: datasource=custom.pio depName=LovyanGFX packageName=lovyan03/library/LovyanGFX - lovyan03/LovyanGFX@^1.2.0 + https://github.com/jp-bennett/LovyanGFX/archive/83eeeb971bf859b0e2edf59e21ac1c4f5f89f732.zip # renovate: datasource=git-refs depName=libch341-spi-userspace packageName=https://github.com/pine64/libch341-spi-userspace gitBranch=main https://github.com/pine64/libch341-spi-userspace/archive/af9bc27c9c30fa90772279925b7c5913dff789b4.zip # renovate: datasource=custom.pio depName=adafruit/Adafruit seesaw Library packageName=adafruit/library/Adafruit seesaw Library diff --git a/src/graphics/TFTDisplay.cpp b/src/graphics/TFTDisplay.cpp index 3e9bafc6c..ac9cd8c55 100644 --- a/src/graphics/TFTDisplay.cpp +++ b/src/graphics/TFTDisplay.cpp @@ -667,15 +667,17 @@ static LGFX *tft = nullptr; static TFT_eSPI *tft = nullptr; // Invoke library, pins defined in User_Setup.h #elif ARCH_PORTDUINO #include // Graphics and font library for ST7735 driver chip +#include class LGFX : public lgfx::LGFX_Device { - lgfx::Panel_Device *_panel_instance; lgfx::Bus_SPI _bus_instance; lgfx::ITouch *_touch_instance; public: + lgfx::Panel_Device *_panel_instance; + LGFX(void) { if (settingsMap[displayPanel] == st7789) @@ -694,6 +696,11 @@ class LGFX : public lgfx::LGFX_Device _panel_instance = new lgfx::Panel_ILI9488; else if (settingsMap[displayPanel] == hx8357d) _panel_instance = new lgfx::Panel_HX8357D; +#if defined(SDL_h_) + else if (settingsMap[displayPanel] == x11) { + _panel_instance = new lgfx::Panel_sdl; + } +#endif else { _panel_instance = new lgfx::Panel_NULL; LOG_ERROR("Unknown display panel configured!"); @@ -754,7 +761,13 @@ class LGFX : public lgfx::LGFX_Device _touch_instance->config(touch_cfg); _panel_instance->setTouch(_touch_instance); } - +#if defined(SDL_h_) + if (settingsMap[displayPanel] == x11) { + lgfx::Panel_sdl *sdl_panel_ = (lgfx::Panel_sdl *)_panel_instance; + sdl_panel_->setup(); + sdl_panel_->addKeyCodeMapping(SDLK_RETURN, SDL_SCANCODE_KP_ENTER); + } +#endif setPanel(_panel_instance); // Sets the panel to use. } }; @@ -1040,6 +1053,49 @@ void TFTDisplay::display(bool fromBlank) } } +void TFTDisplay::sdlLoop() +{ +#if defined(SDL_h_) + static int lastPressed = 0; + static int shuttingDown = false; + if (settingsMap[displayPanel] == x11) { + lgfx::Panel_sdl *sdl_panel_ = (lgfx::Panel_sdl *)tft->_panel_instance; + if (sdl_panel_->loop() && !shuttingDown) { + LOG_WARN("Window Closed!"); + InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_SHUTDOWN, .kbchar = 0, .touchX = 0, .touchY = 0}; + inputBroker->injectInputEvent(&event); + } + + // debounce + if (lastPressed != 0 && !lgfx::v1::gpio_in(lastPressed)) + return; + if (!lgfx::v1::gpio_in(37)) { + lastPressed = 37; + InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_RIGHT, .kbchar = 0, .touchX = 0, .touchY = 0}; + inputBroker->injectInputEvent(&event); + } else if (!lgfx::v1::gpio_in(36)) { + lastPressed = 36; + InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_UP, .kbchar = 0, .touchX = 0, .touchY = 0}; + inputBroker->injectInputEvent(&event); + } else if (!lgfx::v1::gpio_in(38)) { + lastPressed = 38; + InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_DOWN, .kbchar = 0, .touchX = 0, .touchY = 0}; + inputBroker->injectInputEvent(&event); + } else if (!lgfx::v1::gpio_in(39)) { + lastPressed = 39; + InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_LEFT, .kbchar = 0, .touchX = 0, .touchY = 0}; + inputBroker->injectInputEvent(&event); + } else if (!lgfx::v1::gpio_in(SDL_SCANCODE_KP_ENTER)) { + lastPressed = SDL_SCANCODE_KP_ENTER; + InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_SELECT, .kbchar = 0, .touchX = 0, .touchY = 0}; + inputBroker->injectInputEvent(&event); + } else { + lastPressed = 0; + } + } +#endif +} + // Send a command to the display (low level function) void TFTDisplay::sendCommand(uint8_t com) { diff --git a/src/graphics/TFTDisplay.h b/src/graphics/TFTDisplay.h index 38cd53ebb..60adfdf7c 100644 --- a/src/graphics/TFTDisplay.h +++ b/src/graphics/TFTDisplay.h @@ -23,6 +23,7 @@ class TFTDisplay : public OLEDDisplay // Write the buffer to the display memory virtual void display() override { display(false); }; virtual void display(bool fromBlank); + void sdlLoop(); // Turn the display upside down virtual void flipScreenVertically(); diff --git a/src/main.cpp b/src/main.cpp index 605fbe50a..989fca810 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1555,7 +1555,13 @@ void loop() #endif service->loop(); - +#if defined(ARCH_PORTDUINO) + if (screen) { + auto dispdev = screen->getDisplayDevice(); + if (dispdev) + static_cast(dispdev)->sdlLoop(); + } +#endif long delayMsec = mainController.runOrDelay(); // We want to sleep as long as possible here - because it saves power diff --git a/variants/native/portduino/platformio.ini b/variants/native/portduino/platformio.ini index 732b2a1d4..1db24a3d9 100644 --- a/variants/native/portduino/platformio.ini +++ b/variants/native/portduino/platformio.ini @@ -39,6 +39,7 @@ build_flags = ${native_base.build_flags} -Os -lX11 -linput -lxkbcommon -ffunctio -D VIEW_320x240 !pkg-config --libs libulfius --silence-errors || : !pkg-config --libs openssl --silence-errors || : + !pkg-config --cflags --libs sdl2 --silence-errors || : build_src_filter = ${native_base.build_src_filter}