diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..8a8ff5e6 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,62 @@ +name: Test building the project in different environments + +on: [push, pull_request] + +jobs: + build: + strategy: + matrix: + os: + - { image: "debian:bullseye", dockerfile: "Dockerfile_DEBIAN" } + - { image: "debian:bookworm", dockerfile: "Dockerfile_DEBIAN" } + - { image: "ubuntu:20.04", dockerfile: "Dockerfile_DEBIAN" } + - { image: "ubuntu:22.04", dockerfile: "Dockerfile_DEBIAN" } + - { image: "rockylinux:8", dockerfile: "Dockerfile_RHEL" } + - { image: "rockylinux:9", dockerfile: "Dockerfile_RHEL" } + - { image: "oraclelinux:8", dockerfile: "Dockerfile_RHEL" } + - { image: "oraclelinux:9", dockerfile: "Dockerfile_RHEL" } + fail-fast: false + + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build the Docker image + run: | + docker build \ + --build-arg BASE_OS=${{ matrix.os.image }} \ + -f docker/${{ matrix.os.dockerfile }} \ + -t test_${{ matrix.os.image }} . + + - name: FBDEV Test building the project + run: | + sed -i "s/^#define LV_USE_LINUX_FBDEV.*$/#define LV_USE_LINUX_FBDEV 1/g" lv_conf.h && \ + sed -i "s/^#define LV_USE_LINUX_DRM.*$/#define LV_USE_LINUX_DRM 0/g" lv_conf.h && \ + sed -i "s/^#define LV_USE_SDL.*$/#define LV_USE_SDL 0/g" lv_conf.h && \ + docker run --rm -v "$(pwd)":/workdir -t test_${{ matrix.os.image }} \ + /bin/bash -ec "mkdir build/ && cd build/ && cmake .. && make -j && ldd ../bin/main" + + - name: DRM Test building the project + run: | + sudo rm -Rf build/ bin/ && \ + sed -i "s/^#define LV_USE_LINUX_FBDEV.*$/#define LV_USE_LINUX_FBDEV 0/g" lv_conf.h && \ + sed -i "s/^#define LV_USE_LINUX_DRM.*$/#define LV_USE_LINUX_DRM 1/g" lv_conf.h && \ + sed -i "s/^#define LV_USE_SDL.*$/#define LV_USE_SDL 0/g" lv_conf.h && \ + docker run --rm -v "$(pwd)":/workdir -t test_${{ matrix.os.image }} \ + /bin/bash -ec "mkdir build/ && cd build/ && cmake .. && make -j && ldd ../bin/main" + + - name: SDL Test building the project + run: | + sudo rm -Rf build/ bin/ && \ + sed -i "s/^#define LV_USE_LINUX_FBDEV.*$/#define LV_USE_LINUX_FBDEV 0/g" lv_conf.h && \ + sed -i "s/^#define LV_USE_LINUX_DRM.*$/#define LV_USE_LINUX_DRM 0/g" lv_conf.h && \ + sed -i "s/^#define LV_USE_SDL.*$/#define LV_USE_SDL 1/g" lv_conf.h && \ + docker run --rm -v "$(pwd)":/workdir -t test_${{ matrix.os.image }} \ + /bin/bash -ec "mkdir build/ && cd build/ && cmake .. && make -j && ldd ../bin/main" diff --git a/CMakeLists.txt b/CMakeLists.txt index 658193f3..220cb758 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,17 +8,26 @@ 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}) - -find_package(SDL2) -find_package(SDL2_image) -include_directories(${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS}) - -target_link_libraries(main lvgl lvgl::examples lvgl::demos lvgl::thorvg ${SDL2_LIBRARIES} ${SDL2_IMAGE_LIBRARIES} ${Libdrm_LIBRARIES} m pthread) -add_custom_target (run COMMAND ${EXECUTABLE_OUTPUT_PATH}/main DEPENDS main) +find_package(PkgConfig REQUIRED) # We use the platform independent pkg-config to find all the libs +pkg_check_modules(LIBDRM REQUIRED libdrm) +pkg_check_modules(SDL2 REQUIRED sdl2) +pkg_check_modules(SDL2_image REQUIRED SDL2_image) +target_include_directories(lvgl PUBLIC ${PROJECT_SOURCE_DIR}) +target_include_directories(lvgl PRIVATE ${SDL2_INCLUDE_DIRS}) +target_include_directories(lvgl PRIVATE ${SDL2_IMAGE_INCLUDE_DIRS}) +target_include_directories(lvgl PRIVATE ${LIBDRM_INCLUDE_DIRS}) + +target_link_libraries(main PRIVATE lvgl) # Add '-static' if you want a standalone binary +target_link_libraries(main PRIVATE lvgl::examples) +target_link_libraries(main PRIVATE lvgl::demos) +target_link_libraries(main PRIVATE lvgl::thorvg) +target_link_libraries(main PRIVATE ${SDL2_LIBRARIES}) +target_link_libraries(main PRIVATE ${SDL2_IMAGE_LIBRARIES}) +target_link_libraries(main PRIVATE ${LIBDRM_LIBRARIES}) +target_link_libraries(main PRIVATE m) +target_link_libraries(main PRIVATE pthread) + +add_custom_target(run COMMAND ${EXECUTABLE_OUTPUT_PATH}/main DEPENDS main) diff --git a/README.md b/README.md index dfb4571b..bb4ffd4b 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,9 @@ resolution of 800x480. Check out this blog post for a step by step tutorial: https://blog.lvgl.io/2018-01-03/linux_fb +## Build dependencies +Check the [Dockerfiles](docker/) for the build dependencies. + ## Clone the project Clone the LVGL Framebuffer Demo project and its related sub modules. @@ -70,6 +73,11 @@ The following variables are supported. - `LV_LINUX_FBDEV_DEVICE` - override default (`/dev/fb0`) framebuffer device node. + +### EVDEV touchscreen/mouse pointer device + +- `LV_LINUX_EVDEV_POINTER_DEVICE` - override default (`/dev/input/by-id/my-mouse-or-touchscreen`) input device + ### DRM/KMS - `LV_LINUX_DRM_CARD` - override default (`/dev/dri/card0`) card. diff --git a/docker/Dockerfile_DEBIAN b/docker/Dockerfile_DEBIAN new file mode 100644 index 00000000..2f9b3f84 --- /dev/null +++ b/docker/Dockerfile_DEBIAN @@ -0,0 +1,16 @@ +ARG BASE_OS +FROM "$BASE_OS" + +RUN DEBIAN_FRONTEND="noninteractive" apt-get update + +# Build tools +RUN DEBIAN_FRONTEND="noninteractive" apt-get install -y make cmake build-essential + +# Required for LV_USE_SDL +RUN DEBIAN_FRONTEND="noninteractive" apt-get install -y libsdl2-dev libsdl2-image-dev + +# Required for LV_USE_LINUX_DRM linux-headers-generic provides an included header file +RUN DEBIAN_FRONTEND="noninteractive" apt-get install -y libdrm-dev linux-headers-generic + +RUN mkdir /workdir +WORKDIR /workdir diff --git a/docker/Dockerfile_RHEL b/docker/Dockerfile_RHEL new file mode 100644 index 00000000..3c0f1c81 --- /dev/null +++ b/docker/Dockerfile_RHEL @@ -0,0 +1,31 @@ +ARG BASE_OS +FROM "$BASE_OS" + +RUN dnf makecache --refresh +RUN dnf -y install 'dnf-command(config-manager)' +RUN dnf repolist --all + +# Rocky 8 +RUN dnf config-manager --set-enabled powertools || true + +# Oracle 8 +RUN dnf config-manager --set-enabled ol8_codeready_builder || true + +# Rocky/Oracle 9+ +RUN dnf config-manager --set-enabled crb || true + +RUN dnf -y install epel-release +RUN dnf makecache --refresh + +# Build tools +RUN dnf -y groupinstall "Development Tools" +RUN dnf -y install cmake + +# Required for LV_USE_SDL +RUN dnf -y install SDL2-devel SDL2_image-devel + +# Required for LV_USE_LINUX_DRM +RUN dnf -y install libdrm-devel + +RUN mkdir /workdir +WORKDIR /workdir diff --git a/main.c b/main.c index e02cef92..2af18412 100644 --- a/main.c +++ b/main.c @@ -11,12 +11,34 @@ static const char *getenv_default(const char *name, const char *dflt) return getenv(name) ? : dflt; } +#if LV_USE_EVDEV +static void lv_linux_init_input_pointer(lv_display_t *disp) +{ + // Enables a pointer (touchscreen/mouse) input device + // Use 'evtest' to find the correct input device. /dev/input/by-id/ is recommeded if possible + // Use /dev/input/by-id/my-mouse-or-touchscreen or /dev/input/eventX + const char *input_device = getenv_default("LV_LINUX_EVDEV_POINTER_DEVICE", "/dev/input/by-id/my-mouse-or-touchscreen"); + lv_indev_t *touch = lv_evdev_create(LV_INDEV_TYPE_POINTER, input_device); + lv_indev_set_display(touch, disp); + + // Disable this if you want no cursor + LV_IMAGE_DECLARE(mouse_cursor_icon); /*Declare the image source.*/ + lv_obj_t * cursor_obj = lv_image_create(lv_screen_active()); /*Create an image object for the cursor */ + lv_image_set_src(cursor_obj, &mouse_cursor_icon); /*Set the image source*/ + lv_indev_set_cursor(touch, cursor_obj); /*Connect the image object to the driver*/ +} +#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(); - + + #if LV_USE_EVDEV + lv_linux_init_input_pointer(disp); + #endif + lv_linux_fbdev_set_file(disp, device); } #elif LV_USE_LINUX_DRM @@ -25,6 +47,10 @@ 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(); + #if LV_USE_EVDEV + lv_linux_init_input_pointer(disp); + #endif + lv_linux_drm_set_file(disp, device, -1); } #elif LV_USE_SDL