lvgl: lvgl-demo: rework recipe to include wayland backend support

Rework our customizations and apply them as full files instead of patches to
make it easier for users to inspect.

Instead of having one cmake file for all backends, provide a separate file for
each backend and select it dynamically based on the selected backend. To do
this, create a new LVGL_BACKEND variable in lv-conf.inc.

While at it, increase the demo's memory from 256 KiB to 2 MiB to ensure that
the wayland flavor of the demo works properly.

https://onedigi.atlassian.net/browse/DEL-9925

Signed-off-by: Gabriel Valcazar <gabriel.valcazar@digi.com>
This commit is contained in:
Gabriel Valcazar 2026-03-02 16:06:41 +01:00
parent e3df152ccd
commit de238b6d81
9 changed files with 220 additions and 141 deletions

View File

@ -1,29 +0,0 @@
From 1ffdfa2d0d36c566006b5b1f24d2a9e68888a5c1 Mon Sep 17 00:00:00 2001
From: Mike Engel <Mike.Engel@digi.com>
Date: Tue, 2 Sep 2025 10:21:07 +0200
Subject: [PATCH] lvgl-demo: remove demo slideshow
This commit removes the demo slideshow function to
avoid the application changes automatically between
the different taps.
Signed-off-by: Mike Engel <Mike.Engel@digi.com>
---
main.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/main.c b/main.c
index e02cef9..7ec513c 100644
--- a/main.c
+++ b/main.c
@@ -48,7 +48,6 @@ int main(void)
/*Create a Demo*/
lv_demo_widgets();
- lv_demo_widgets_start_slideshow();
/*Handle LVGL tasks*/
while(1) {
--
2.51.0

View File

@ -1,27 +0,0 @@
From 49f99a403e36bb3bb54943d7a351d4aadffe3447 Mon Sep 17 00:00:00 2001
From: Mike Engel <Mike.Engel@digi.com>
Date: Wed, 6 Aug 2025 16:59:28 +0200
Subject: [PATCH] CMakefile: remove libdrm dependency when building fbdev demo
Signed-off-by: Mike Engel <Mike.Engel@digi.com>
---
CMakeLists.txt | 3 ---
1 file changed, 3 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 658193f..c6a2b85 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,9 +12,6 @@ target_include_directories(lvgl PUBLIC ${PROJECT_SOURCE_DIR})
add_executable(main main.c mouse_cursor_icon.c)
-include(${CMAKE_CURRENT_LIST_DIR}/lvgl/tests/FindLibDRM.cmake)
-include_directories(${Libdrm_INCLUDE_DIRS})
-
find_package(SDL2)
find_package(SDL2_image)
include_directories(${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS})
--
2.34.1

View File

@ -1,76 +0,0 @@
From d7696f869a014d6fa15e25cf7818e43f3c110acb Mon Sep 17 00:00:00 2001
From: Mike Engel <Mike.Engel@digi.com>
Date: Tue, 2 Sep 2025 11:49:32 +0200
Subject: [PATCH] lvgl-demo: add input device discovery support to LVGL-demo
This commit adds input device discovery support to the demo.
When input device is a mouse it will create the cursor.
Signed-off-by: Mike Engel <Mike.Engel@digi.com>
---
main.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/main.c b/main.c
index ba03f23..f821936 100644
--- a/main.c
+++ b/main.c
@@ -1,5 +1,6 @@
#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
+#include "lvgl/src/core/lv_global.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
@@ -11,6 +12,30 @@ static const char *getenv_default(const char *name, const char *dflt)
return getenv(name) ? : dflt;
}
+static void indev_deleted_cb(lv_event_t * e)
+{
+ if(LV_GLOBAL_DEFAULT()->deinit_in_progress)
+ return;
+ lv_obj_t * cursor_obj = lv_event_get_user_data(e);
+ lv_obj_delete(cursor_obj);
+}
+
+static void discovery_cb(lv_indev_t * indev, lv_evdev_type_t type, void * user_data)
+{
+ LV_LOG_USER("new '%s' device discovered", type == LV_EVDEV_TYPE_REL ? "REL" :
+ type == LV_EVDEV_TYPE_ABS ? "ABS" :
+ type == LV_EVDEV_TYPE_KEY ? "KEY" :
+ "unknown");
+ /* if input device is mouse add cursor */
+ if(type == LV_EVDEV_TYPE_REL) {
+ LV_IMAGE_DECLARE(mouse_cursor_icon);
+ lv_obj_t * cursor_obj = lv_image_create(lv_screen_active());
+ lv_image_set_src(cursor_obj, &mouse_cursor_icon);
+ lv_indev_set_cursor(indev, cursor_obj);
+ lv_indev_add_event_cb(indev, indev_deleted_cb, LV_EVENT_DELETE, cursor_obj);
+ }
+}
+
#if LV_USE_LINUX_FBDEV
static void lv_linux_disp_init(void)
{
@@ -18,6 +43,8 @@ static void lv_linux_disp_init(void)
lv_display_t * disp = lv_linux_fbdev_create();
lv_linux_fbdev_set_file(disp, device);
+ /* search for input devices */
+ lv_evdev_discovery_start(discovery_cb, NULL);
}
#elif LV_USE_LINUX_DRM
static void lv_linux_disp_init(void)
@@ -26,6 +53,8 @@ static void lv_linux_disp_init(void)
lv_display_t * disp = lv_linux_drm_create();
lv_linux_drm_set_file(disp, device, -1);
+ /* search for input devices */
+ lv_evdev_discovery_start(discovery_cb, NULL);
}
#elif LV_USE_SDL
static void lv_linux_disp_init(void)
--
2.51.0

View File

@ -0,0 +1,20 @@
cmake_minimum_required(VERSION 3.10)
project(lvgl)
set(CMAKE_C_STANDARD 99)#C99 # lvgl officially support C99 and above
set(CMAKE_CXX_STANDARD 17)#C17
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
add_subdirectory(lvgl)
target_include_directories(lvgl PUBLIC ${PROJECT_SOURCE_DIR})
add_executable(main main.c mouse_cursor_icon.c)
include(${CMAKE_CURRENT_LIST_DIR}/lvgl/tests/FindLibDRM.cmake)
include_directories(${Libdrm_INCLUDE_DIRS})
target_link_libraries(main lvgl lvgl::examples lvgl::demos ${Libdrm_LIBRARIES} m pthread)
add_custom_target (run COMMAND ${EXECUTABLE_OUTPUT_PATH}/main DEPENDS main)

View File

@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.10)
project(lvgl)
set(CMAKE_C_STANDARD 99)#C99 # lvgl officially support C99 and above
set(CMAKE_CXX_STANDARD 17)#C17
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
add_subdirectory(lvgl)
target_include_directories(lvgl PUBLIC ${PROJECT_SOURCE_DIR})
add_executable(main main.c mouse_cursor_icon.c)
target_link_libraries(main lvgl lvgl::examples lvgl::demos m pthread)
add_custom_target (run COMMAND ${EXECUTABLE_OUTPUT_PATH}/main DEPENDS main)

View File

@ -0,0 +1,51 @@
cmake_minimum_required(VERSION 3.10)
project(lvgl)
set(CMAKE_C_STANDARD 99)#C99 # lvgl officially support C99 and above
set(CMAKE_CXX_STANDARD 17)#C17
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
find_package(PkgConfig)
pkg_check_modules(PKG_WAYLAND wayland-client wayland-cursor xkbcommon)
# Wayland protocols
find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner)
pkg_check_modules(WAYLAND_PROTOCOLS REQUIRED wayland-protocols>=1.25)
pkg_get_variable(WAYLAND_PROTOCOLS_BASE wayland-protocols pkgdatadir)
macro(wayland_generate protocol_xml_file output_dir output_name target)
set(output_file_noext "${output_dir}/${output_name}")
add_custom_command(OUTPUT "${output_file_noext}.h"
COMMAND "${WAYLAND_SCANNER_EXECUTABLE}" client-header "${protocol_xml_file}" "${output_file_noext}.h"
DEPENDS "${protocol_xml_file}"
VERBATIM)
add_custom_command(OUTPUT "${output_file_noext}.c"
COMMAND "${WAYLAND_SCANNER_EXECUTABLE}" private-code "${protocol_xml_file}" "${output_file_noext}.c"
DEPENDS "${protocol_xml_file}"
VERBATIM)
if(NOT EXISTS ${protocol_xml_file})
message("Protocol XML file not found: " ${protocol_xml_file})
else()
set_property(TARGET ${target} APPEND PROPERTY SOURCES "${output_file_noext}.h" "${output_file_noext}.c")
endif()
endmacro()
set(WAYLAND_PROTOCOLS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/wl_protocols")
file(MAKE_DIRECTORY ${WAYLAND_PROTOCOLS_DIR})
add_custom_target(generate_xdg_shell_protocol ALL)
wayland_generate("${WAYLAND_PROTOCOLS_BASE}/stable/xdg-shell/xdg-shell.xml" "${WAYLAND_PROTOCOLS_DIR}" "wayland_xdg_shell" generate_xdg_shell_protocol)
add_subdirectory(lvgl)
target_include_directories(lvgl PRIVATE ${WAYLAND_PROTOCOLS_DIR})
target_include_directories(lvgl PUBLIC ${PROJECT_SOURCE_DIR})
add_executable(main main.c mouse_cursor_icon.c ${WAYLAND_PROTOCOLS_DIR}/wayland_xdg_shell.c)
target_link_libraries(main lvgl lvgl::examples lvgl::demos ${PKG_WAYLAND_LIBRARIES} m pthread)
add_custom_target (run COMMAND ${EXECUTABLE_OUTPUT_PATH}/main DEPENDS main)

View File

@ -0,0 +1,109 @@
#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include "lvgl/src/core/lv_global.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
static const char *getenv_default(const char *name, const char *dflt)
{
return getenv(name) ? : dflt;
}
#if LV_USE_LINUX_FBDEV || LV_USE_LINUX_DRM
static void indev_deleted_cb(lv_event_t * e)
{
if(LV_GLOBAL_DEFAULT()->deinit_in_progress)
return;
lv_obj_t * cursor_obj = lv_event_get_user_data(e);
lv_obj_delete(cursor_obj);
}
static void discovery_cb(lv_indev_t * indev, lv_evdev_type_t type, void * user_data)
{
LV_LOG_USER("new '%s' device discovered", type == LV_EVDEV_TYPE_REL ? "REL" :
type == LV_EVDEV_TYPE_ABS ? "ABS" :
type == LV_EVDEV_TYPE_KEY ? "KEY" :
"unknown");
/* if input device is mouse add cursor */
if(type == LV_EVDEV_TYPE_REL) {
LV_IMAGE_DECLARE(mouse_cursor_icon);
lv_obj_t * cursor_obj = lv_image_create(lv_screen_active());
lv_image_set_src(cursor_obj, &mouse_cursor_icon);
lv_indev_set_cursor(indev, cursor_obj);
lv_indev_add_event_cb(indev, indev_deleted_cb, LV_EVENT_DELETE, cursor_obj);
}
}
#endif
#if LV_USE_LINUX_FBDEV
static void lv_linux_disp_init(void)
{
const char *device = getenv_default("LV_LINUX_FBDEV_DEVICE", "/dev/fb0");
lv_display_t * disp = lv_linux_fbdev_create();
lv_linux_fbdev_set_file(disp, device);
/* search for input devices */
lv_evdev_discovery_start(discovery_cb, NULL);
}
#elif LV_USE_LINUX_DRM
static void lv_linux_disp_init(void)
{
const char *device = getenv_default("LV_LINUX_DRM_CARD", "/dev/dri/card0");
lv_display_t * disp = lv_linux_drm_create();
lv_linux_drm_set_file(disp, device, -1);
/* search for input devices */
lv_evdev_discovery_start(discovery_cb, NULL);
}
#elif LV_USE_WAYLAND
static void lv_linux_disp_init(void)
{
/*
* Initial resolution doesn't really matter if we're changing to fullscreen
* immediately after. It should be fine as long as it's big enough to
* display all widgets correctly.
*/
lv_display_t * disp = lv_wayland_window_create(1280, 800, "LVGL Demo", NULL);
lv_wayland_window_set_fullscreen(disp, true);
if(LV_COLOR_DEPTH == 32) {
lv_display_set_color_format(disp, LV_COLOR_FORMAT_ARGB8888);
}
}
#else
#error Unsupported configuration
#endif
int main(void)
{
lv_init();
/*Linux display device init*/
lv_linux_disp_init();
/*Create a Demo*/
lv_demo_widgets();
#if LV_USE_WAYLAND
while (1) {
lv_wayland_timer_handler();
usleep(5000);
/* Run until the last window closes */
if (!lv_wayland_window_is_open(NULL)) {
break;
}
}
#else
/*Handle LVGL tasks*/
while(1) {
lv_timer_handler();
usleep(5000);
}
#endif
return 0;
}

View File

@ -3,7 +3,9 @@
MINIMAL_LVGL_BACKEND ?= "drm"
MINIMAL_LVGL_BACKEND:ccimx6 = "fbdev"
MINIMAL_LVGL_BACKEND:ccimx6ul = "fbdev"
PACKAGECONFIG = "${@bb.utils.contains('DISTRO_FEATURES', 'wayland', 'wayland', '${MINIMAL_LVGL_BACKEND}', d)}"
LVGL_BACKEND ?= "${@bb.utils.contains('DISTRO_FEATURES', 'wayland', 'wayland', '${MINIMAL_LVGL_BACKEND}', d)}"
PACKAGECONFIG ?= "${LVGL_BACKEND}"
PACKAGECONFIG[drm] = ",,libdrm"
PACKAGECONFIG[fbdev] = ",,"

View File

@ -7,18 +7,21 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=802d3d83ae80ef5f343050bf96cce3a4 \
SRC_URI = "\
git://github.com/lvgl/lv_port_linux_frame_buffer.git;protocol=https;branch=release/v9.3;name=demo \
git://github.com/lvgl/lvgl;protocol=https;branch=release/v9.3;name=lvgl;subdir=git/lvgl \
file://0001-lvgl-demo-remove-demo-slideshow.patch \
file://0004-lvgl-demo-add-input-device-discovery-support-to-LVGL.patch \
file://digi_main.c \
file://CMakeLists.txt_fbdev \
file://CMakeLists.txt_drm \
file://CMakeLists.txt_wayland \
file://lvgl-demo-init \
file://lvgl-demo-init.service \
"
SRC_URI:append:ccimx6ul = "\
file://0003-CMakefile-remove-libdrm-dependency-when-building-fbd.patch \
SRC_URI:remove:ccimx6 = "\
file://CMakeLists.txt_drm \
"
SRC_URI:append:ccimx6 = "\
file://0003-CMakefile-remove-libdrm-dependency-when-building-fbd.patch \
SRC_URI:remove:ccimx6ul = "\
file://CMakeLists.txt_drm \
file://CMakeLists.txt_wayland \
"
SRCREV_demo = "d07de027a8eb220f4e20f0e1b8be28729332e9ea"
@ -35,18 +38,27 @@ LVGL_CONFIG_FBDEV_DEVICE ?= "/dev/fb0"
LVGL_CONFIG_FBDEV_DEVICE:ccimx6 = "/dev/fb3"
LVGL_CONFIG_LV_USE_LOG = "1"
LVGL_CONFIG_LV_LOG_PRINTF = "1"
LVGL_CONFIG_LV_MEM_SIZE = "(256 * 1024U)"
LVGL_CONFIG_LV_MEM_SIZE = "(2 * 1024U * 1024U)"
LVGL_CONFIG_LV_USE_FONT_COMPRESSED = "1"
require lv-conf.inc
inherit cmake systemd update-rc.d
inherit cmake systemd update-rc.d pkgconfig
S = "${WORKDIR}/git"
LVGL_DEMO_ENV ?= "DISPLAY=:0.0 XDG_RUNTIME_DIR=/run/user/0 WAYLAND_DISPLAY=\$\{DEMO_DISPLAY\}"
LVGL_DEMO_ENV:ccimx6ul ?= ""
do_configure:prepend() {
cp ${WORKDIR}/digi_main.c ${S}/main.c
if [ -f "${WORKDIR}/CMakeLists.txt_${LVGL_BACKEND}" ] ; then
cp ${WORKDIR}/CMakeLists.txt_${LVGL_BACKEND} ${S}/CMakeLists.txt
else
bbfatal "Unsupported LVGL demo backend '${LVGL_BACKEND}'"
fi
}
do_install:append() {
install -d ${D}${bindir}
install -m 0755 ${S}/bin/main ${D}${bindir}/lvgl-demo