原始仓库地址:lvgl/lv_port_linux: LVGL configured to work with a standard Linux framebuffer
直接上改完后的CMakeLists.txt:
C
cmake_minimum_required(VERSION 3.11)
project(lvgl)
option(WERROR "Treat warnings as errors for LVGL targets" OFF)
# Set policy to allow to run the target_link_libraries cmd on targets that are build
# in another directory.
# Currently, the linking is not handled by env_support/cmake/os.cmakel
# This means that if a driver is enabled and it requires linking an external library
# it needs to be handled in the top-level project.
cmake_policy(SET CMP0079 NEW)
# Uncomment if the program needs debugging
#set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_C_STANDARD 99) # LVGL officially supports C99 and above
set(CMAKE_CXX_STANDARD 17) #C17
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wpedantic")
option(CONFIG "Config to use leave empty for `lv_conf.defaults`" "default")
set(LV_CONF_DEFAULTS_PATH "${CMAKE_SOURCE_DIR}/lv_conf.defaults")
set(LV_CONF_DEFAULTS_OLD_PATH "${CMAKE_SOURCE_DIR}/lv_conf.defaults.old")
# If CONFIG is not default, copy the selected config to lv_conf.defaults
if(NOT CONFIG STREQUAL "default")
set(CONFIG_FILE "${CMAKE_SOURCE_DIR}/configs/${CONFIG}.defaults")
# Verify the config file exists
if(NOT EXISTS "${CONFIG_FILE}")
message(FATAL_ERROR "Config file not found: ${CONFIG_FILE}")
endif()
# Backup the current lv_conf.defaults to lv_conf.defaults.old
if(EXISTS "${LV_CONF_DEFAULTS_PATH}")
file(RENAME "${LV_CONF_DEFAULTS_PATH}" "${LV_CONF_DEFAULTS_OLD_PATH}")
message(STATUS "Backed up lv_conf.defaults to lv_conf.defaults.old")
endif()
# Copy the config file to lv_conf.defaults
configure_file("${CONFIG_FILE}" "${LV_CONF_DEFAULTS_PATH}" COPYONLY)
message(STATUS "Copied configs/${CONFIG}.defaults to ${LV_CONF_DEFAULTS_PATH}")
message(STATUS "Using config: configs/${CONFIG}.defaults")
else()
if(NOT EXISTS "${LV_CONF_DEFAULTS_PATH}")
message(FATAL_ERROR "Config file not found: ${LV_CONF_DEFAULTS_PATH}")
endif()
message(STATUS "Using default lv_conf.defaults")
message(STATUS "Using config: ${LV_CONF_DEFAULTS_PATH}")
endif()
set(LV_BUILD_SET_CONFIG_OPTS ON CACHE BOOL
"create CMAKE variables from lv_conf_internal.h" FORCE)
set(LV_BUILD_CONF_PATH
"${CMAKE_BINARY_DIR}/lv_conf.h"
CACHE PATH "path to lv_conf.h" FORCE)
set(LVGL_TEMPLATE_PATH "${CMAKE_SOURCE_DIR}/lvgl/lv_conf_template.h")
set(GENERATE_SCRIPT_PATH "${CMAKE_SOURCE_DIR}/lvgl/scripts/generate_lv_conf.py")
configure_file(${LVGL_TEMPLATE_PATH} ${CMAKE_BINARY_DIR}/lv_conf_template.h
COPYONLY)
configure_file(${LV_CONF_DEFAULTS_PATH} ${CMAKE_BINARY_DIR}/lv_conf.defaults
COPYONLY)
configure_file(${GENERATE_SCRIPT_PATH} ${CMAKE_BINARY_DIR}/generate_lv_conf.py
COPYONLY)
execute_process(
COMMAND
${Python3_EXECUTABLE} ${GENERATE_SCRIPT_PATH} --template
${LVGL_TEMPLATE_PATH} --defaults ${LV_CONF_DEFAULTS_PATH} --config
${LV_BUILD_CONF_PATH}
RESULT_VARIABLE config_result
OUTPUT_VARIABLE config_output
ERROR_VARIABLE config_output)
if(NOT config_result EQUAL 0)
message(FATAL_ERROR "Failed to generate lv_conf.h: ${config_output}")
endif()
message(STATUS "${LV_BUILD_CONF_PATH} generated successfully")
add_subdirectory(lvgl)
//添加交叉编译选项
option(CROSS_BUILD "Enable cross-compiling mode" OFF)
if (CONFIG_LV_USE_EVDEV)
message("Including EVDEV support")
//对evdev使用交叉编译条件判断
if(CROSS_BUILD)
message(STATUS "Detected cross-compilation environment")
//交叉编译环境下用到的库与头文件目录
set(EVDEV_LIBRARIES ${STAGING_DIR}/usr/lib/libevdev.so)
set(EVDEV_INCLUDE_DIRS ${STAGING_DIR}/usr/include)
list(APPEND PKG_CONFIG_LIB ${EVDEV_LIBRARIES})
list(APPEND PKG_CONFIG_INC ${EVDEV_INCLUDE_DIRS})
else()
message(STATUS "Native build (using host pkg-config)")
find_package(PkgConfig REQUIRED)
pkg_check_modules(EVDEV REQUIRED libevdev)
list(APPEND PKG_CONFIG_LIB ${EVDEV_LIBRARIES})
list(APPEND PKG_CONFIG_INC ${EVDEV_INCLUDE_DIRS})
endif()
list(APPEND LV_LINUX_BACKEND_SRC src/lib/indev_backends/evdev.c)
endif()
//在此处添加TSLIB支持
if (CONFIG_LV_USE_TSLIB)
message("Including TSLIB support")
//必须使用交叉编译条件
if(CROSS_BUILD)
message(STATUS "Detected cross-compilation environment")
//交叉编译环境下用到的库与头文件目录
set(TSLIB_LIBRARIES ${STAGING_DIR}/usr/lib/libts.so)
set(TSLIB_INCLUDE_DIRS ${STAGING_DIR}/usr/include)
list(APPEND PKG_CONFIG_LIB ${TSLIB_LIBRARIES})
list(APPEND PKG_CONFIG_INC ${TSLIB_INCLUDE_DIRS})
endif()
//添加源文件到编译列表
list(APPEND LV_LINUX_BACKEND_SRC src/lib/indev_backends/tslib.c)
endif()
if (CONFIG_LV_USE_LINUX_DRM)
message("Including DRM support")
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBDRM REQUIRED libdrm)
list(APPEND PKG_CONFIG_LIB ${LIBDRM_LIBRARIES})
list(APPEND PKG_CONFIG_INC ${LIBDRM_INCLUDE_DIRS})
list(APPEND LV_LINUX_BACKEND_SRC src/lib/display_backends/drm.c)
endif()
if (CONFIG_LV_USE_LINUX_DRM_GBM_BUFFERS OR CONFIG_LV_LINUX_DRM_USE_EGL)
message("Including GBM support")
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBGBM REQUIRED gbm)
list(APPEND PKG_CONFIG_LIB ${LIBGBM_LIBRARIES})
list(APPEND PKG_CONFIG_INC ${LIBGBM_INCLUDE_DIRS})
endif()
if (CONFIG_LV_USE_LIBINPUT)
message("Including libinput support")
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBINPUT REQUIRED libinput)
list(APPEND PKG_CONFIG_LIB ${LIBINPUT_LIBRARIES})
list(APPEND PKG_CONFIG_INC ${LIBINPUT_INCLUDE_DIRS})
endif()
if (CONFIG_LV_USE_FREETYPE)
message("Including Freetype support")
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBFREETYPE REQUIRED freetype2)
list(APPEND PKG_CONFIG_LIB ${LIBFREETYPE_LIBRARIES})
list(APPEND PKG_CONFIG_INC ${LIBFREETYPE_INCLUDE_DIRS})
endif()
if (CONFIG_LV_USE_SDL OR CONFIG_LV_USE_DRAW_SDL)
message("Including SDL2 support")
find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2)
pkg_check_modules(SDL2_IMAGE REQUIRED SDL2_image)
list(APPEND PKG_CONFIG_LIB ${SDL2_LIBRARIES} ${SDL2_IMAGE_LIBRARIES})
list(APPEND PKG_CONFIG_INC ${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS})
list(APPEND LV_LINUX_BACKEND_SRC src/lib/display_backends/sdl.c)
endif()
if (CONFIG_LV_USE_WAYLAND)
message("Including Wayland support")
find_package(PkgConfig REQUIRED)
pkg_check_modules(WAYLAND_CLIENT REQUIRED wayland-client)
pkg_check_modules(WAYLAND_CURSOR REQUIRED wayland-cursor)
pkg_check_modules(XKBCOMMON REQUIRED xkbcommon)
list(APPEND PKG_CONFIG_LIB ${WAYLAND_CLIENT_LIBRARIES})
list(APPEND PKG_CONFIG_LIB ${WAYLAND_CURSOR_LIBRARIES})
list(APPEND PKG_CONFIG_LIB ${XKBCOMMON_LIBRARIES})
# Wayland protocols
pkg_check_modules(WAYLAND_PROTOCOLS REQUIRED wayland-protocols>=1.25)
pkg_get_variable(WAYLAND_PROTOCOLS_BASE wayland-protocols pkgdatadir)
if(DEFINED ENV{SDKTARGETSYSROOT} AND DEFINED ENV{SYSROOT})
message(FATAL_ERROR "Both SDKTARGETSYSROOT and SYSROOT are set. Please set only one.")
endif()
if(DEFINED ENV{SDKTARGETSYSROOT})
set(PROTOCOL_ROOT "$ENV{SDKTARGETSYSROOT}/usr/share/wayland-protocols")
elseif(DEFINED ENV{SYSROOT})
set(PROTOCOL_ROOT "$ENV{SYSROOT}/usr/share/wayland-protocols")
else()
set(PROTOCOL_ROOT "/usr/share/wayland-protocols")
endif()
if(NOT EXISTS ${PROTOCOL_ROOT})
message(FATAL_ERROR "Wayland protocols not found at ${PROTOCOL_ROOT}")
endif()
set(PROTOCOLS_DIR "${CMAKE_CURRENT_BINARY_DIR}/protocols")
file(MAKE_DIRECTORY ${PROTOCOLS_DIR})
set(WAYLAND_PROTOCOLS_SRC "")
# Generate xdg-shell protocol (always)
set(XDG_SHELL_XML "${PROTOCOL_ROOT}/stable/xdg-shell/xdg-shell.xml")
set(XDG_SHELL_HEADER "${PROTOCOLS_DIR}/wayland_xdg_shell.h")
set(XDG_SHELL_SOURCE "${PROTOCOLS_DIR}/wayland_xdg_shell.c")
if(NOT EXISTS ${XDG_SHELL_HEADER} OR NOT EXISTS ${XDG_SHELL_SOURCE})
execute_process(COMMAND wayland-scanner client-header ${XDG_SHELL_XML} ${XDG_SHELL_HEADER})
execute_process(COMMAND wayland-scanner private-code ${XDG_SHELL_XML} ${XDG_SHELL_SOURCE})
endif()
list(APPEND WAYLAND_PROTOCOLS_SRC ${XDG_SHELL_SOURCE})
# Generate dmabuf protocol (if config is set)
if(CONFIG_LV_WAYLAND_USE_DMABUF)
set(DMABUF_XML "${PROTOCOL_ROOT}/stable/linux-dmabuf/linux-dmabuf-v1.xml")
set(DMABUF_HEADER "${PROTOCOLS_DIR}/wayland_linux_dmabuf.h")
set(DMABUF_SOURCE "${PROTOCOLS_DIR}/wayland_linux_dmabuf.c")
if(NOT EXISTS ${DMABUF_HEADER} OR NOT EXISTS ${DMABUF_SOURCE})
execute_process(COMMAND wayland-scanner client-header ${DMABUF_XML} ${DMABUF_HEADER})
execute_process(COMMAND wayland-scanner private-code ${DMABUF_XML} ${DMABUF_SOURCE})
endif()
list(APPEND WAYLAND_PROTOCOLS_SRC ${DMABUF_SOURCE})
endif()
list(APPEND PKG_CONFIG_INC ${PROTOCOLS_DIR})
list(APPEND LV_LINUX_BACKEND_SRC src/lib/display_backends/wayland.c ${WAYLAND_PROTOCOLS_SRC})
endif()
if (CONFIG_LV_USE_X11)
find_package(PkgConfig REQUIRED)
pkg_check_modules(X11 REQUIRED x11)
message("Including X11 support")
list(APPEND PKG_CONFIG_INC ${X11_INCLUDE_DIRS})
list(APPEND PKG_CONFIG_LIB ${X11_LIBRARIES})
list(APPEND LV_LINUX_BACKEND_SRC src/lib/display_backends/x11.c)
endif()
if (CONFIG_LV_USE_LINUX_FBDEV)
# FBDEV has no dependencies
message("Including FBDEV support")
list(APPEND LV_LINUX_BACKEND_SRC src/lib/display_backends/fbdev.c)
endif()
if (CONFIG_LV_USE_GLFW)
message("Including GLFW support")
find_package(PkgConfig REQUIRED)
pkg_check_modules(GLFW3 REQUIRED glfw3)
pkg_check_modules(GLEW REQUIRED glew)
list(APPEND PKG_CONFIG_LIB ${GLFW3_LIBRARIES})
list(APPEND PKG_CONFIG_LIB ${GLEW_LIBRARIES})
list(APPEND LV_LINUX_BACKEND_SRC src/lib/display_backends/glfw3.c)
endif()
if (CONFIG_LV_USE_DRAW_G2D)
message("Including G2D support")
find_library(G2D_LIBRARY NAMES g2d)
list(APPEND PKG_CONFIG_LIB ${G2D_LIBRARY})
endif()
if (CONFIG_LV_USE_GLTF)
message(STATUS "Including with GLTF support")
include(FetchContent)
FetchContent_Declare(
fastgltf
GIT_REPOSITORY https://github.com/spnda/fastgltf
GIT_TAG 4e2261350888bae7c35a1f39991f6233d57795f5)
set(FASTGLTF_ENABLE_DEPRECATED_EXT
ON
CACHE BOOL "" FORCE)
set(FASTGLTF_DIFFUSE_TRANSMISSION_SUPPORT
ON
CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(fastgltf)
set(WEBP_BUILD_ANIM_UTILS
OFF
CACHE BOOL "" FORCE)
set(WEBP_BUILD_CWEBP
OFF
CACHE BOOL "" FORCE)
set(WEBP_BUILD_DWEBP
OFF
CACHE BOOL "" FORCE)
set(WEBP_BUILD_GIF2WEBP
OFF
CACHE BOOL "" FORCE)
set(WEBP_BUILD_IMG2WEBP
OFF
CACHE BOOL "" FORCE)
set(WEBP_BUILD_VWEBP
OFF
CACHE BOOL "" FORCE)
set(WEBP_BUILD_WEBPINFO
OFF
CACHE BOOL "" FORCE)
set(WEBP_BUILD_WEBPMUX
OFF
CACHE BOOL "" FORCE)
set(WEBP_BUILD_EXTRAS
OFF
CACHE BOOL "" FORCE)
FetchContent_Declare(
webp
GIT_REPOSITORY https://github.com/webmproject/libwebp
GIT_TAG fa6f56496a442eed59b103250021e4b14ebf1427)
FetchContent_MakeAvailable(webp)
list(APPEND PKG_CONFIG_LIB fastgltf webp)
endif()
if (CONFIG_LV_USE_GSTREAMER)
message("Including GSTREAMER support")
find_package(PkgConfig REQUIRED)
pkg_check_modules(GSTREAMER REQUIRED gstreamer-1.0)
pkg_check_modules(GSTREAMER_VIDEO REQUIRED gstreamer-video-1.0)
pkg_check_modules(GSTREAMER_APP REQUIRED gstreamer-app-1.0)
list(APPEND PKG_CONFIG_LIB ${GSTREAMER_VIDEO_LIBRARIES} ${GSTREAMER_APP_LIBRARIES})
list(APPEND PKG_CONFIG_INC ${GSTREAMER_VIDEO_INCLUDE_DIRS} ${GSTREAMER_APP_INCLUDE_DIRS})
endif()
# Check for external demos
if(CONFIG_LV_USE_DEMO_FLEX_LAYOUT
OR CONFIG_LV_USE_DEMO_MULTILANG
OR CONFIG_LV_USE_DEMO_TRANSFORM
OR CONFIG_LV_USE_DEMO_SCROLL
OR CONFIG_LV_USE_DEMO_EBIKE
OR CONFIG_LV_USE_DEMO_HIGH_RES
OR CONFIG_LV_USE_DEMO_SMARTWATCH)
set(USE_EXTERNAL_DEMOS ON)
else()
set(USE_EXTERNAL_DEMOS OFF)
endif()
if(USE_EXTERNAL_DEMOS)
message("Including external demos")
include(FetchContent)
FetchContent_Declare(lv_demos_ext GIT_REPOSITORY https://github.com/lvgl/lv_demos)
FetchContent_MakeAvailable(lv_demos_ext)
list(APPEND PKG_CONFIG_LIB lv_demos_ext)
endif()
file(GLOB LV_LINUX_SRC src/lib/*.c)
set(LV_LINUX_INC src/lib)
target_include_directories(lvgl PUBLIC ${PKG_CONFIG_INC})
add_library(lvgl_linux STATIC ${LV_LINUX_SRC} ${LV_LINUX_BACKEND_SRC})
target_include_directories(lvgl_linux PUBLIC ${PKG_CONFIG_INC})
# If LVGL is configured to use LV_CONF_PATH or Kconfig
# Set the exactly the same definitions on the lvgl_linux target
set_target_properties(lvgl_linux PROPERTIES COMPILE_DEFINITIONS "${LVGL_COMPILER_DEFINES}")
target_include_directories(lvgl_linux PUBLIC
${LV_LINUX_INC} ${CMAKE_CURRENT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/src/lib ${LVGL_CONF_INC_DIR})
# Link LVGL with external dependencies - Modern CMake/CMP0079 allows this
target_link_libraries(lvgl PUBLIC ${PKG_CONFIG_LIB} m pthread)
add_executable(lvglsim src/main.c ${LV_LINUX_SRC} ${LV_LINUX_BACKEND_SRC})
target_link_libraries(lvglsim lvgl_linux lvgl)
if(WERROR)
target_compile_options(lvglsim PRIVATE -Werror)
target_compile_options(lvgl PRIVATE -Werror)
target_compile_options(lvgl_linux PRIVATE -Werror)
endif()
# Install the lvgl_linux library and its headers
install(DIRECTORY src/lib/
DESTINATION include/lvgl
FILES_MATCHING
PATTERN "backends*" EXCLUDE
PATTERN "*.h")
install(TARGETS lvgl_linux
ARCHIVE DESTINATION lib
)
add_custom_target(run COMMAND ${EXECUTABLE_OUTPUT_PATH}/lvglsim DEPENDS lvglsim)
修改configs/fbdev.default:
C
LV_COLOR_DEPTH 24
LV_USE_LINUX_FBDEV 1
LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT
LV_LINUX_FBDEV_BUFFER_COUNT 2
# Input support
LV_USE_EVDEV 0
LV_USE_LIBINPUT 0
LV_USE_TSLIB 1 #添加该字段,启用tslib支持
# Examples
LV_BUILD_EXAMPLES 1
# Demos
LV_BUILD_DEMOS 1
LV_USE_DEMO_WIDGETS 1
LV_USE_DEMO_KEYPAD_AND_ENCODER 0
LV_USE_DEMO_BENCHMARK 0
LV_USE_DEMO_RENDER 0
LV_USE_DEMO_STRESS 0
LV_USE_DEMO_MUSIC 0
......
为了使得LV_USE_TSLIB能够生成CONFIG_LV_USE_TSLIB,需要修改lvgl/lv_conf_template.h:
C
......
/** Interface for Lovyan_GFX */
#define LV_USE_LOVYAN_GFX 0
#if LV_USE_LOVYAN_GFX
#define LV_LGFX_USER_INCLUDE "lv_lgfx_user.hpp"
#endif /*LV_USE_LOVYAN_GFX*/
/** Driver for tslib input devices */
#define LV_USE_TSLIB 0 //添加该字段
/** Driver for evdev input devices */
#define LV_USE_EVDEV 0
/** Driver for libinput input devices */
#define LV_USE_LIBINPUT 0
......
使用交叉编译环境时,cmake命令还需搭配文件user_cross_compile_setup.cmake
bash
# Usage:
# cmake -DCMAKE_TOOLCHAIN_FILE=./user_cross_compile_setup.cmake -B build -S .
# make -C build -j
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CROSS_COMPILE /home/ender/sunxi/buildroot/buildroot-2025.02.7/output/host/bin/arm-buildroot-linux-gnueabi-)
set(CMAKE_C_COMPILER ${CROSS_COMPILE}gcc)
set(CMAKE_CXX_COMPILER ${CROSS_COMPILE}g++)
# If necessary, set STAGING_DIR
# if not work, please try(in shell command): export STAGING_DIR=/home/ubuntu/Your_SDK/out/xxx/openwrt/staging_dir/target
set(STAGING_DIR "/home/ender/sunxi/buildroot/buildroot-2025.02.7/output/staging")
STAGING_DIR指向自己的staging rootfs即可。 添加文件src/lib/indev_backends/tslib.c,添加tslib触摸驱动注册接口:
C
/**
*
* @file evdev.c
*
* The lib evdev driver
*
* Based on the original file from the repository
*
* - Move the driver to a separate file to avoid excessive conditional
* compilation
* Author: EDGEMTech Ltd, Erik Tagirov (erik.tagirov@edgemtech.ch)
*
* Copyright (c) 2025 EDGEMTech Ltd.
*
*/
/*********************
* INCLUDES
*********************/
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include "lvgl/lvgl.h"
#if LV_USE_TSLIB
#include "lvgl/src/core/lv_global.h"
#include "../backends.h"
#include "tslib.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static lv_indev_t *init_pointer_tslib(lv_display_t *display);
/**********************
* STATIC VARIABLES
**********************/
static char *backend_name = "TSLIB";
static struct tsdev *ts = NULL;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/*
* Initialize the tslib driver
*
* @param backend the backend descriptor
*/
int backend_init_tslib(backend_t *backend)
{
LV_ASSERT_NULL(backend);
backend->handle->indev = malloc(sizeof(indev_backend_t));
LV_ASSERT_NULL(backend->handle->indev);
backend->handle->indev->init_indev = init_pointer_tslib;
backend->name = backend_name;
backend->type = BACKEND_INDEV;
return 0;
}
/**********************
* STATIC FUNCTIONS
**********************/
static lv_coord_t last_x = 0;
static lv_coord_t last_y = 0;
static lv_indev_state_t last_state = LV_INDEV_STATE_RELEASED;
static void tslib_read_cb(lv_indev_t *indev, lv_indev_data_t *data)
{
struct ts_sample samp;
if(!ts) {
data->state = LV_INDEV_STATE_RELEASED;
data->point.x = 0;
data->point.y = 0;
data->continue_reading = false;
return;
}
/* 读取队列中所有事件,最后一个点作为当前状态 */
while(ts_read(ts, &samp, 1) > 0) {
last_x = samp.x;
last_y = samp.y;
last_state = (samp.pressure > 0) ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
}
data->point.x = last_x;
data->point.y = last_y;
data->state = last_state;
data->continue_reading = false;
/* 限幅到屏幕分辨率 */
lv_disp_t *disp = lv_indev_get_display(indev);
lv_coord_t hor_res = lv_disp_get_hor_res(disp);
lv_coord_t ver_res = lv_disp_get_ver_res(disp);
if(data->point.x < 0) data->point.x = 0;
if(data->point.y < 0) data->point.y = 0;
if(data->point.x >= hor_res) data->point.x = hor_res - 1;
if(data->point.y >= ver_res) data->point.y = ver_res - 1;
}
static lv_indev_t *init_pointer_tslib(lv_display_t *display)
{
const char *input_device = getenv("TSLIB_TSDEVICE");
if(!input_device)
{
input_device = "/dev/input/event0";
LV_LOG_USER("Using default input device %s\r\n", input_device);
}
ts = ts_setup(input_device, O_RDONLY | O_NONBLOCK);
if(!ts) {
LV_LOG_ERROR("ts_setup failed");
return NULL;
}
lv_indev_t * indev = lv_indev_create();
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
lv_indev_set_read_cb(indev, tslib_read_cb);
lv_indev_set_display(indev, display);
return indev;
}
#endif /*#if LV_USE_TSLIB*/
记得在src/lib/driver_backends.c里的available_backends数组中添加一项新的backends
C
/* The default backend is the one that will end up at index 0
* To add support for a new driver backend add the declaration
* and append an entry to the available_backends array
*/
backend_init_t available_backends[] = {
#if LV_USE_LINUX_FBDEV
backend_init_fbdev,
#endif
#if LV_USE_LINUX_DRM
backend_init_drm,
#endif
#if LV_USE_SDL
backend_init_sdl,
#endif
#if LV_USE_WAYLAND
backend_init_wayland,
#endif
#if LV_USE_X11
backend_init_x11,
#endif
#if LV_USE_GLFW
backend_init_glfw3,
#endif
#if LV_USE_EVDEV
backend_init_evdev,
#endif
#if LV_USE_TSLIB
backend_init_tslib,
#endif
NULL /* Sentinel */
};
最后别忘了src/main.c里要手动去初始化
C
/**
* @brief entry point
* @description start a demo
* @param argc the count of arguments in argv
* @param argv The arguments
*/
int main(int argc, char **argv)
{
configure_simulator(argc, argv);
/* Initialize LVGL. */
lv_init();
/* Initialize the configured backend */
if (driver_backends_init_backend(selected_backend) == -1) {
die("Failed to initialize display backend");
}
/* Enable for EVDEV support */
#if LV_USE_EVDEV
if (driver_backends_init_backend("EVDEV") == -1) {
die("Failed to initialize evdev");
}
#endif
/* Enable for TSLIB support */
#if LV_USE_TSLIB
if (driver_backends_init_backend("TSLIB") == -1) {
die("Failed to initialize tslib");
}
#endif
/*Create a Demo*/
lv_demo_widgets();
//lv_demo_widgets_start_slideshow();
/* Enter the run loop of the selected backend */
driver_backends_run_loop();
return 0;
}
都完成后执行
sh
cmake CMakeLists.txt -DCMAKE_TOOLCHAIN_FILE=./user_cross_compile_setup.cmake -B build -DCONFIG=fbdev -DCROSS_BUILD=ON
即可完成,这样改动的优点是保持lvgl原有的构建架构,同时tslib作为可选模块被添加到了构建系统中,避免了硬编码,保证了未来更新的兼容性。