diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 77d7f5db..15774185 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -9,6 +9,8 @@ on: env: CARGO_TERM_COLOR: always DEP_LV_CONFIG_PATH: /home/runner/work/lvgl-rs/lvgl-rs/examples/include + LVGL_INCLUDE: /usr/include,/usr/local/include + LVGL_LINK: SDL2 jobs: build: diff --git a/.gitmodules b/.gitmodules index 13afe4f6..ce15f8c1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ [submodule "lvgl-sys/vendor/lvgl"] path = lvgl-sys/vendor/lvgl url = https://github.com/lvgl/lvgl.git + +[submodule "lvgl-sys/vendor/lv_drivers"] + path = lvgl-sys/vendor/lv_drivers + url = https://github.com/lvgl/lv_drivers.git diff --git a/README.md b/README.md index 8362a270..dbd50971 100644 --- a/README.md +++ b/README.md @@ -105,11 +105,15 @@ this section you can check what is implemented at the moment. List of LVGL features that impacts the library usage in general. - [x] Displays: We use [`embedded_graphics`](https://docs.rs/embedded-graphics/0.6.2/embedded_graphics/) library to - draw to the display. You can use `lvgl-rs` with any of the - [`embedded_graphics` supported displays](https://docs.rs/embedded-graphics/0.6.2/embedded_graphics/#supported-displays). + draw to the display, along with [`lv_drivers`](https://github.com/lvgl/lv_drivers). You can + use `lvgl-rs` with any of the [`embedded_graphics`](https://docs.rs/embedded-graphics/0.6.2/embedded_graphics/#supported-displays) supported + displays, and those supported by [`lv_drivers`](https://github.com/lvgl/lv_drivers). + **Note:** [`lv_drivers`](https://github.com/lvgl/lv_drivers) support is currently experimental. - [x] Events: You can listen and trigger events in widget objects. - [x] Styles: You can set styles in any exposed object. We are still missing the possibility of defining global base styles. -- [ ] Input Devices +- [x] Input Devices: Input devices supported by [`lv_drivers`](https://github.com/lvgl/lv_drivers) + can be used. + **Note:** [`lv_drivers`](https://github.com/lvgl/lv_drivers) support is currently experimental. - [ ] Fonts - [ ] Images - [ ] File system diff --git a/examples/app.rs b/examples/app.rs index 3bac0fdf..31e2512a 100644 --- a/examples/app.rs +++ b/examples/app.rs @@ -34,6 +34,4 @@ fn main() { .unwrap(); }) .unwrap(); - - let label: Label = "Nice!".into(); } diff --git a/examples/arc.rs b/examples/arc.rs index 01937059..96561e23 100644 --- a/examples/arc.rs +++ b/examples/arc.rs @@ -10,6 +10,8 @@ use lvgl::widgets::{Arc, Label}; use lvgl::{Align, Color, Display, DrawBuffer, LvError, Part, Widget}; use lvgl_sys; use std::time::Duration; +use std::time::Instant; +use std::thread::sleep; fn mem_info() -> lvgl_sys::lv_mem_monitor_t { let mut info = lvgl_sys::lv_mem_monitor_t { @@ -74,6 +76,7 @@ fn main() -> Result<(), LvError> { let mut i = 0; 'running: loop { + let start = Instant::now(); if i > 270 { forward = if forward { false } else { true }; i = 1; @@ -92,7 +95,8 @@ fn main() -> Result<(), LvError> { _ => {} } } - lvgl::tick_inc(Duration::from_millis(15)); + sleep(Duration::from_millis(15)); + lvgl::tick_inc(Instant::now().duration_since(start)); } println!("meminfo end: {:?}", mem_info()); diff --git a/examples/bar.rs b/examples/bar.rs index b8e120e8..4d3bb2ae 100644 --- a/examples/bar.rs +++ b/examples/bar.rs @@ -10,6 +10,8 @@ use lvgl::widgets::{Bar, Label}; use lvgl::{Align, Animation, Color, Display, DrawBuffer, Event, LvError, Part, Widget}; use std::cell::RefCell; use std::time::Duration; +use std::time::Instant; +use std::thread::sleep; fn main() -> Result<(), LvError> { const HOR_RES: u32 = 240; @@ -64,6 +66,7 @@ fn main() -> Result<(), LvError> { let mut i = 0; 'running: loop { + let start = Instant::now(); if i > 100 { i = 0; lvgl::event_send(&mut bar, Event::Clicked)?; @@ -80,8 +83,8 @@ fn main() -> Result<(), LvError> { _ => {} } } - - lvgl::tick_inc(Duration::from_millis(10)); + sleep(Duration::from_millis(15)); + lvgl::tick_inc(Instant::now().duration_since(start)); } Ok(()) diff --git a/examples/button_click.rs b/examples/button_click.rs index ea4926f1..37539c6a 100644 --- a/examples/button_click.rs +++ b/examples/button_click.rs @@ -14,6 +14,8 @@ use lvgl::style::Style; use lvgl::widgets::{Btn, Label}; use lvgl::{Align, Color, Display, DrawBuffer, LvError, Part, Widget}; use std::time::Duration; +use std::time::Instant; +use std::thread::sleep; #[allow(unused_assignments)] fn main() -> Result<(), LvError> { @@ -71,6 +73,7 @@ fn main() -> Result<(), LvError> { let mut latest_touch_point = Point::new(0, 0); 'running: loop { + let start = Instant::now(); lvgl::task_handler(); window.update(&sim_display); @@ -97,7 +100,8 @@ fn main() -> Result<(), LvError> { _ => {} } } - lvgl::tick_inc(Duration::from_millis(15)); + sleep(Duration::from_millis(15)); + lvgl::tick_inc(Instant::now().duration_since(start)); } Ok(()) diff --git a/examples/demo.rs b/examples/demo.rs index dcb602cf..a362db52 100644 --- a/examples/demo.rs +++ b/examples/demo.rs @@ -11,6 +11,7 @@ use lvgl::{Align, Color, Display, DrawBuffer, LvError, Part, TextAlign, Widget}; use lvgl_sys; use std::thread::sleep; use std::time::Duration; +use std::time::Instant; fn main() -> Result<(), LvError> { const HOR_RES: u32 = 240; @@ -53,7 +54,7 @@ fn main() -> Result<(), LvError> { style_time.set_text_align(TextAlign::Center); // Need to set font too time.add_style(Part::Main, &mut style_time)?; - time.set_align(Align::Center, 0, 0)?; + time.set_align(Align::Center, 0, 100)?; time.set_width(240)?; time.set_height(240)?; @@ -71,6 +72,7 @@ fn main() -> Result<(), LvError> { let mut i = 0; 'running: loop { + let start = Instant::now(); if i > 59 { i = 0; } @@ -89,7 +91,7 @@ fn main() -> Result<(), LvError> { } //println!("During run: {:?}", mem_info()); sleep(Duration::from_secs(1)); - lvgl::tick_inc(Duration::from_secs(1)); + lvgl::tick_inc(Instant::now().duration_since(start)); } //println!("Final part of demo app: {:?}", mem_info()); diff --git a/examples/include/lv_conf.h b/examples/include/lv_conf.h index 06455cc1..d7dd9ef0 100644 --- a/examples/include/lv_conf.h +++ b/examples/include/lv_conf.h @@ -222,7 +222,7 @@ *-----------*/ /*Enable the log module*/ -#define LV_USE_LOG 0 +#define LV_USE_LOG 1 #if LV_USE_LOG /*How important log should be added: @@ -232,7 +232,7 @@ *LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail *LV_LOG_LEVEL_USER Only logs added by the user *LV_LOG_LEVEL_NONE Do not log anything*/ - #define LV_LOG_LEVEL LV_LOG_LEVEL_WARN + #define LV_LOG_LEVEL LV_LOG_LEVEL_INFO /*1: Print the log with 'printf'; *0: User need to register a callback with `lv_log_register_print_cb()`*/ diff --git a/examples/include/lv_drv_conf.h b/examples/include/lv_drv_conf.h new file mode 100644 index 00000000..5c84efab --- /dev/null +++ b/examples/include/lv_drv_conf.h @@ -0,0 +1,494 @@ +/** + * @file lv_drv_conf.h + * Configuration file for v8.3.0 + */ + +/* + * COPY THIS FILE AS lv_drv_conf.h + */ + +/* clang-format off */ +#if 1 /*Set it to "1" to enable the content*/ + +#ifndef LV_DRV_CONF_H +#define LV_DRV_CONF_H + +#include "lv_conf.h" + +/********************* + * DELAY INTERFACE + *********************/ +#define LV_DRV_DELAY_INCLUDE /*Dummy include by default*/ +#define LV_DRV_DELAY_US(us) /*delay_us(us)*/ /*Delay the given number of microseconds*/ +#define LV_DRV_DELAY_MS(ms) /*delay_ms(ms)*/ /*Delay the given number of milliseconds*/ + +/********************* + * DISPLAY INTERFACE + *********************/ + +/*------------ + * Common + *------------*/ +#define LV_DRV_DISP_INCLUDE /*Dummy include by default*/ +#define LV_DRV_DISP_CMD_DATA(val) /*pin_x_set(val)*/ /*Set the command/data pin to 'val'*/ +#define LV_DRV_DISP_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/ + +/*--------- + * SPI + *---------*/ +#define LV_DRV_DISP_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/ +#define LV_DRV_DISP_SPI_WR_BYTE(data) /*spi_wr(data)*/ /*Write a byte the SPI bus*/ +#define LV_DRV_DISP_SPI_WR_ARRAY(adr, n) /*spi_wr_mem(adr, n)*/ /*Write 'n' bytes to SPI bus from 'adr'*/ + +/*------------------ + * Parallel port + *-----------------*/ +#define LV_DRV_DISP_PAR_CS(val) /*par_cs_set(val)*/ /*Set the Parallel port's Chip select to 'val'*/ +#define LV_DRV_DISP_PAR_SLOW /*par_slow()*/ /*Set low speed on the parallel port*/ +#define LV_DRV_DISP_PAR_FAST /*par_fast()*/ /*Set high speed on the parallel port*/ +#define LV_DRV_DISP_PAR_WR_WORD(data) /*par_wr(data)*/ /*Write a word to the parallel port*/ +#define LV_DRV_DISP_PAR_WR_ARRAY(adr, n) /*par_wr_mem(adr,n)*/ /*Write 'n' bytes to Parallel ports from 'adr'*/ + +/*************************** + * INPUT DEVICE INTERFACE + ***************************/ + +/*---------- + * Common + *----------*/ +#define LV_DRV_INDEV_INCLUDE /*Dummy include by default*/ +#define LV_DRV_INDEV_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/ +#define LV_DRV_INDEV_IRQ_READ 0 /*pn_x_read()*/ /*Read the IRQ pin*/ + +/*--------- + * SPI + *---------*/ +#define LV_DRV_INDEV_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/ +#define LV_DRV_INDEV_SPI_XCHG_BYTE(data) 0 /*spi_xchg(val)*/ /*Write 'val' to SPI and give the read value*/ + +/*--------- + * I2C + *---------*/ +#define LV_DRV_INDEV_I2C_START /*i2c_start()*/ /*Make an I2C start*/ +#define LV_DRV_INDEV_I2C_STOP /*i2c_stop()*/ /*Make an I2C stop*/ +#define LV_DRV_INDEV_I2C_RESTART /*i2c_restart()*/ /*Make an I2C restart*/ +#define LV_DRV_INDEV_I2C_WR(data) /*i2c_wr(data)*/ /*Write a byte to the I1C bus*/ +#define LV_DRV_INDEV_I2C_READ(last_read) 0 /*i2c_rd()*/ /*Read a byte from the I2C bud*/ + + +/********************* + * DISPLAY DRIVERS + *********************/ + +/*------------------- + * SDL + *-------------------*/ + +/* SDL based drivers for display, mouse, mousewheel and keyboard*/ +#ifndef USE_SDL +# define USE_SDL 1 +#endif + +/* Hardware accelerated SDL driver */ +#ifndef USE_SDL_GPU +# define USE_SDL_GPU 0 +#endif + +#if USE_SDL || USE_SDL_GPU +# define SDL_HOR_RES 240 +# define SDL_VER_RES 240 + +/* Scale window by this factor (useful when simulating small screens) */ +# define SDL_ZOOM 1 + +/* Used to test true double buffering with only address changing. + * Use 2 draw buffers, bith with SDL_HOR_RES x SDL_VER_RES size*/ +# define SDL_DOUBLE_BUFFERED 0 + +/*Eclipse: Visual Studio: */ +# define SDL_INCLUDE_PATH + +/*Open two windows to test multi display support*/ +# define SDL_DUAL_DISPLAY 0 +#endif + +/*------------------- + * Monitor of PC + *-------------------*/ + +/*DEPRECATED: Use the SDL driver instead. */ +#ifndef USE_MONITOR +# define USE_MONITOR 0 +#endif + +#if USE_MONITOR +# define MONITOR_HOR_RES 480 +# define MONITOR_VER_RES 320 + +/* Scale window by this factor (useful when simulating small screens) */ +# define MONITOR_ZOOM 1 + +/* Used to test true double buffering with only address changing. + * Use 2 draw buffers, bith with MONITOR_HOR_RES x MONITOR_VER_RES size*/ +# define MONITOR_DOUBLE_BUFFERED 0 + +/*Eclipse: Visual Studio: */ +# define MONITOR_SDL_INCLUDE_PATH + +/*Open two windows to test multi display support*/ +# define MONITOR_DUAL 0 +#endif + +/*----------------------------------- + * Native Windows (including mouse) + *----------------------------------*/ +#ifndef USE_WINDOWS +# define USE_WINDOWS 0 +#endif + +#if USE_WINDOWS +# define WINDOW_HOR_RES 480 +# define WINDOW_VER_RES 320 +#endif + +/*---------------------------- + * Native Windows (win32drv) + *---------------------------*/ +#ifndef USE_WIN32DRV +# define USE_WIN32DRV 0 +#endif + +#if USE_WIN32DRV +/* Scale window by this factor (useful when simulating small screens) */ +# define WIN32DRV_MONITOR_ZOOM 1 +#endif + +/*---------------------------------------- + * GTK drivers (monitor, mouse, keyboard + *---------------------------------------*/ +#ifndef USE_GTK +# define USE_GTK 0 +#endif + +/*---------------------------------------- + * Wayland drivers (monitor, mouse, keyboard, touchscreen) + *---------------------------------------*/ +#ifndef USE_WAYLAND +# define USE_WAYLAND 0 +#endif + +#if USE_WAYLAND +/* Support for client-side decorations */ +# ifndef LV_WAYLAND_CLIENT_SIDE_DECORATIONS +# define LV_WAYLAND_CLIENT_SIDE_DECORATIONS 1 +# endif +/* Support for (deprecated) wl-shell protocol */ +# ifndef LV_WAYLAND_WL_SHELL +# define LV_WAYLAND_WL_SHELL 1 +# endif +/* Support for xdg-shell protocol */ +# ifndef LV_WAYLAND_XDG_SHELL +# define LV_WAYLAND_XDG_SHELL 0 +# endif +#endif + +/*---------------- + * SSD1963 + *--------------*/ +#ifndef USE_SSD1963 +# define USE_SSD1963 0 +#endif + +#if USE_SSD1963 +# define SSD1963_HOR_RES LV_HOR_RES +# define SSD1963_VER_RES LV_VER_RES +# define SSD1963_HT 531 +# define SSD1963_HPS 43 +# define SSD1963_LPS 8 +# define SSD1963_HPW 10 +# define SSD1963_VT 288 +# define SSD1963_VPS 12 +# define SSD1963_FPS 4 +# define SSD1963_VPW 10 +# define SSD1963_HS_NEG 0 /*Negative hsync*/ +# define SSD1963_VS_NEG 0 /*Negative vsync*/ +# define SSD1963_ORI 0 /*0, 90, 180, 270*/ +# define SSD1963_COLOR_DEPTH 16 +#endif + +/*---------------- + * R61581 + *--------------*/ +#ifndef USE_R61581 +# define USE_R61581 0 +#endif + +#if USE_R61581 +# define R61581_HOR_RES LV_HOR_RES +# define R61581_VER_RES LV_VER_RES +# define R61581_HSPL 0 /*HSYNC signal polarity*/ +# define R61581_HSL 10 /*HSYNC length (Not Implemented)*/ +# define R61581_HFP 10 /*Horitontal Front poarch (Not Implemented)*/ +# define R61581_HBP 10 /*Horitontal Back poarch (Not Implemented */ +# define R61581_VSPL 0 /*VSYNC signal polarity*/ +# define R61581_VSL 10 /*VSYNC length (Not Implemented)*/ +# define R61581_VFP 8 /*Vertical Front poarch*/ +# define R61581_VBP 8 /*Vertical Back poarch */ +# define R61581_DPL 0 /*DCLK signal polarity*/ +# define R61581_EPL 1 /*ENABLE signal polarity*/ +# define R61581_ORI 0 /*0, 180*/ +# define R61581_LV_COLOR_DEPTH 16 /*Fix 16 bit*/ +#endif + +/*------------------------------ + * ST7565 (Monochrome, low res.) + *-----------------------------*/ +#ifndef USE_ST7565 +# define USE_ST7565 0 +#endif + +#if USE_ST7565 +/*No settings*/ +#endif /*USE_ST7565*/ + +/*------------------------------ + * GC9A01 (color, low res.) + *-----------------------------*/ +#ifndef USE_GC9A01 +# define USE_GC9A01 0 +#endif + +#if USE_GC9A01 +/*No settings*/ +#endif /*USE_GC9A01*/ + +/*------------------------------------------ + * UC1610 (4 gray 160*[104|128]) + * (EA DOGXL160 160x104 tested) + *-----------------------------------------*/ +#ifndef USE_UC1610 +# define USE_UC1610 0 +#endif + +#if USE_UC1610 +# define UC1610_HOR_RES LV_HOR_RES +# define UC1610_VER_RES LV_VER_RES +# define UC1610_INIT_CONTRAST 33 /* init contrast, values in [%] */ +# define UC1610_INIT_HARD_RST 0 /* 1 : hardware reset at init, 0 : software reset */ +# define UC1610_TOP_VIEW 0 /* 0 : Bottom View, 1 : Top View */ +#endif /*USE_UC1610*/ + +/*------------------------------------------------- + * SHARP memory in pixel monochrome display series + * LS012B7DD01 (184x38 pixels.) + * LS013B7DH03 (128x128 pixels.) + * LS013B7DH05 (144x168 pixels.) + * LS027B7DH01 (400x240 pixels.) (tested) + * LS032B7DD02 (336x536 pixels.) + * LS044Q7DH01 (320x240 pixels.) + *------------------------------------------------*/ +#ifndef USE_SHARP_MIP +# define USE_SHARP_MIP 0 +#endif + +#if USE_SHARP_MIP +# define SHARP_MIP_HOR_RES LV_HOR_RES +# define SHARP_MIP_VER_RES LV_VER_RES +# define SHARP_MIP_SOFT_COM_INVERSION 0 +# define SHARP_MIP_REV_BYTE(b) /*((uint8_t) __REV(__RBIT(b)))*/ /*Architecture / compiler dependent byte bits order reverse*/ +#endif /*USE_SHARP_MIP*/ + +/*------------------------------------------------- + * ILI9341 240X320 TFT LCD + *------------------------------------------------*/ +#ifndef USE_ILI9341 +# define USE_ILI9341 0 +#endif + +#if USE_ILI9341 +# define ILI9341_HOR_RES LV_HOR_RES +# define ILI9341_VER_RES LV_VER_RES +# define ILI9341_GAMMA 1 +# define ILI9341_TEARING 0 +#endif /*USE_ILI9341*/ + +/*----------------------------------------- + * Linux frame buffer device (/dev/fbx) + *-----------------------------------------*/ +#ifndef USE_FBDEV +# define USE_FBDEV 1 +#endif + +#if USE_FBDEV +# define FBDEV_PATH "/dev/fb0" +#endif + +/*----------------------------------------- + * FreeBSD frame buffer device (/dev/fbx) + *.........................................*/ +#ifndef USE_BSD_FBDEV +# define USE_BSD_FBDEV 0 +#endif + +#if USE_BSD_FBDEV +# define FBDEV_PATH "/dev/fb0" +#endif + +/*----------------------------------------- + * DRM/KMS device (/dev/dri/cardX) + *-----------------------------------------*/ +#ifndef USE_DRM +# define USE_DRM 0 +#endif + +#if USE_DRM +# define DRM_CARD "/dev/dri/card0" +# define DRM_CONNECTOR_ID -1 /* -1 for the first connected one */ +#endif + +/********************* + * INPUT DEVICES + *********************/ + +/*-------------- + * XPT2046 + *--------------*/ +#ifndef USE_XPT2046 +# define USE_XPT2046 0 +#endif + +#if USE_XPT2046 +# define XPT2046_HOR_RES 480 +# define XPT2046_VER_RES 320 +# define XPT2046_X_MIN 200 +# define XPT2046_Y_MIN 200 +# define XPT2046_X_MAX 3800 +# define XPT2046_Y_MAX 3800 +# define XPT2046_AVG 4 +# define XPT2046_X_INV 0 +# define XPT2046_Y_INV 0 +# define XPT2046_XY_SWAP 0 +#endif + +/*----------------- + * FT5406EE8 + *-----------------*/ +#ifndef USE_FT5406EE8 +# define USE_FT5406EE8 0 +#endif + +#if USE_FT5406EE8 +# define FT5406EE8_I2C_ADR 0x38 /*7 bit address*/ +#endif + +/*--------------- + * AD TOUCH + *--------------*/ +#ifndef USE_AD_TOUCH +# define USE_AD_TOUCH 0 +#endif + +#if USE_AD_TOUCH +/*No settings*/ +#endif + + +/*--------------------------------------- + * Mouse or touchpad on PC (using SDL) + *-------------------------------------*/ +/*DEPRECATED: Use the SDL driver instead. */ +#ifndef USE_MOUSE +# define USE_MOUSE 0 +#endif + +#if USE_MOUSE +/*No settings*/ +#endif + +/*------------------------------------------- + * Mousewheel as encoder on PC (using SDL) + *------------------------------------------*/ +/*DEPRECATED: Use the SDL driver instead. */ +#ifndef USE_MOUSEWHEEL +# define USE_MOUSEWHEEL 0 +#endif + +#if USE_MOUSEWHEEL +/*No settings*/ +#endif + +/*------------------------------------------------- + * Touchscreen, mouse/touchpad or keyboard as libinput interface (for Linux based systems) + *------------------------------------------------*/ +#ifndef USE_LIBINPUT +# define USE_LIBINPUT 0 +#endif + +#ifndef USE_BSD_LIBINPUT +# define USE_BSD_LIBINPUT 0 +#endif + +#if USE_LIBINPUT || USE_BSD_LIBINPUT +/*If only a single device of the same type is connected, you can also auto detect it, e.g.: + *#define LIBINPUT_NAME libinput_find_dev(LIBINPUT_CAPABILITY_TOUCH, false)*/ +# define LIBINPUT_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/ + +#endif /*USE_LIBINPUT || USE_BSD_LIBINPUT*/ + +/*------------------------------------------------- + * Mouse or touchpad as evdev interface (for Linux based systems) + *------------------------------------------------*/ +#ifndef USE_EVDEV +# define USE_EVDEV 0 +#endif + +#ifndef USE_BSD_EVDEV +# define USE_BSD_EVDEV 0 +#endif + +#if USE_EVDEV || USE_BSD_EVDEV +# define EVDEV_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/ +# define EVDEV_SWAP_AXES 0 /*Swap the x and y axes of the touchscreen*/ + +# define EVDEV_CALIBRATE 0 /*Scale and offset the touchscreen coordinates by using maximum and minimum values for each axis*/ + +# if EVDEV_CALIBRATE +# define EVDEV_HOR_MIN 0 /*to invert axis swap EVDEV_XXX_MIN by EVDEV_XXX_MAX*/ +# define EVDEV_HOR_MAX 4096 /*"evtest" Linux tool can help to get the correct calibraion values>*/ +# define EVDEV_VER_MIN 0 +# define EVDEV_VER_MAX 4096 +# endif /*EVDEV_CALIBRATE*/ +#endif /*USE_EVDEV*/ + +/*------------------------------------------------- + * Full keyboard support for evdev and libinput interface + *------------------------------------------------*/ +# ifndef USE_XKB +# define USE_XKB 0 +# endif + +#if USE_LIBINPUT || USE_BSD_LIBINPUT || USE_EVDEV || USE_BSD_EVDEV +# if USE_XKB +# define XKB_KEY_MAP { .rules = NULL, \ + .model = "pc101", \ + .layout = "us", \ + .variant = NULL, \ + .options = NULL } /*"setxkbmap -query" can help find the right values for your keyboard*/ +# endif /*USE_XKB*/ +#endif /*USE_LIBINPUT || USE_BSD_LIBINPUT || USE_EVDEV || USE_BSD_EVDEV*/ + +/*------------------------------- + * Keyboard of a PC (using SDL) + *------------------------------*/ +/*DEPRECATED: Use the SDL driver instead. */ +#ifndef USE_KEYBOARD +# define USE_KEYBOARD 0 +#endif + +#if USE_KEYBOARD +/*No settings*/ +#endif + +#endif /*LV_DRV_CONF_H*/ + +#endif /*End of "Content enable"*/ diff --git a/examples/sdl.rs b/examples/sdl.rs new file mode 100644 index 00000000..7fe20685 --- /dev/null +++ b/examples/sdl.rs @@ -0,0 +1,66 @@ +// Still WIP +//#![allow(unused_labels)] +//#![allow(unused_variables)] +//#![allow(unreachable_code)] + +use lvgl::LvResult; +use lvgl::lv_drv_disp_sdl; +use lvgl::lv_drv_input_pointer_sdl; +use lvgl::input_device::generic::InputDriver; +use lvgl::style::Style; +use lvgl::widgets::{Btn, Label}; +use lvgl::{Align, Color, DrawBuffer, Part, Widget}; +use std::time::Duration; +use std::time::Instant; +use std::thread::sleep; +use cstr_core::CString; + +fn main() -> LvResult<()> { + const HOR_RES: u32 = 240; + const VER_RES: u32 = 240; + + lvgl::init(); + let buffer = DrawBuffer::<{ (HOR_RES * VER_RES) as usize }>::new(); + let display = lv_drv_disp_sdl!(buffer, HOR_RES, VER_RES)?; + let mut input = lv_drv_input_pointer_sdl!(); + lvgl::indev_drv_register(&mut input); + + // Create screen and widgets + let mut screen = display.get_scr_act()?; + + let mut screen_style = Style::default(); + screen_style.set_bg_color(Color::from_rgb((0, 0, 0))); + screen.add_style(Part::Main, &mut screen_style)?; + // Create the button + let mut button = Btn::create(&mut screen)?; + button.set_align(Align::LeftMid, 30, 0)?; + button.set_size(180, 80)?; + let mut btn_lbl = Label::create(&mut button)?; + btn_lbl.set_text(CString::new("Click me!").unwrap().as_c_str())?; + + let mut btn_state = false; + button.on_event(|_btn, event| { + println!("Button received event: {:?}", event); + if let lvgl::Event::Clicked = event { + if btn_state { + let nt = CString::new("Click me!").unwrap(); + btn_lbl.set_text(nt.as_c_str()).unwrap(); + } else { + let nt = CString::new("Clicked!").unwrap(); + btn_lbl.set_text(nt.as_c_str()).unwrap(); + } + btn_state = !btn_state; + //btn.toggle().unwrap(); + } + })?; + + 'running: loop { + let start = Instant::now(); + lvgl::task_handler(); + //println!("Loop"); + sleep(Duration::from_millis(15)); + lvgl::tick_inc(Instant::now().duration_since(start)); + } + + Ok(()) +} \ No newline at end of file diff --git a/lvgl-codegen/Cargo.toml b/lvgl-codegen/Cargo.toml index e40fc212..310c5770 100644 --- a/lvgl-codegen/Cargo.toml +++ b/lvgl-codegen/Cargo.toml @@ -4,7 +4,7 @@ version = "0.5.2" description = "Code generation based on LVGL source code" authors = ["Rafael Caricio "] readme = "README.md" -edition = "2018" +edition = "2021" license = "MIT" repository = "https://github.com/rafaelcaricio/lvgl-rs" diff --git a/lvgl-sys/Cargo.toml b/lvgl-sys/Cargo.toml index f75e41ce..227f6be5 100644 --- a/lvgl-sys/Cargo.toml +++ b/lvgl-sys/Cargo.toml @@ -3,7 +3,7 @@ name = "lvgl-sys" description = "Raw bindings to the LVGL C library." version = "0.5.2" authors = ["Rafael Caricio "] -edition = "2018" +edition = "2021" license = "MIT" homepage = "https://github.com/rafaelcaricio/lvgl-rs" repository = "https://github.com/rafaelcaricio/lvgl-rs" @@ -25,3 +25,4 @@ bindgen = "0.64.0" [features] use-vendored-config = [] +drivers = [] diff --git a/lvgl-sys/README.md b/lvgl-sys/README.md index 5c3ab3fe..93c05d98 100644 --- a/lvgl-sys/README.md +++ b/lvgl-sys/README.md @@ -1,5 +1,5 @@ # lvgl-sys -Rust raw bindings for LittlevGL library. +Rust raw bindings for LittlevGL library and drivers. ## Usage diff --git a/lvgl-sys/build.rs b/lvgl-sys/build.rs index aefe5bf1..23cca76d 100644 --- a/lvgl-sys/build.rs +++ b/lvgl-sys/build.rs @@ -1,13 +1,40 @@ use cc::Build; -use std::{env, path::Path, path::PathBuf}; +use std::{ + collections::HashSet, + env, + path::{Path, PathBuf}, +}; static CONFIG_NAME: &str = "DEP_LV_CONFIG_PATH"; +// See https://github.com/rust-lang/rust-bindgen/issues/687#issuecomment-450750547 +#[cfg(feature = "drivers")] +#[derive(Debug)] +struct IgnoreMacros(HashSet); +#[cfg(feature = "drivers")] +impl bindgen::callbacks::ParseCallbacks for IgnoreMacros { + fn will_parse_macro(&self, name: &str) -> bindgen::callbacks::MacroParsingBehavior { + if self.0.contains(name) { + bindgen::callbacks::MacroParsingBehavior::Ignore + } else { + bindgen::callbacks::MacroParsingBehavior::Default + } + } +} + fn main() { let project_dir = canonicalize(PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())); let shims_dir = project_dir.join("shims"); let vendor = project_dir.join("vendor"); - let vendor_src = vendor.join("lvgl").join("src"); + let lvgl_src = vendor.join("lvgl").join("src"); + + #[cfg(feature = "drivers")] + let incl_extra = env::var("LVGL_INCLUDE").unwrap_or("".to_string()); + #[cfg(feature = "drivers")] + let link_extra = env::var("LVGL_LINK").unwrap_or("".to_string()); + + #[cfg(feature = "drivers")] + let drivers = vendor.join("lv_drivers"); let lv_config_dir = { let conf_path = env::var(CONFIG_NAME) @@ -49,25 +76,51 @@ fn main() { CONFIG_NAME ); } + #[cfg(feature = "drivers")] + if !conf_path.join("lv_drv_conf.h").exists() { + panic!( + "Directory {} referenced by {} needs to contain a file called lv_drv_conf.h", + conf_path.to_string_lossy(), + CONFIG_NAME + ); + } println!( "cargo:rerun-if-changed={}", conf_path.join("lv_conf.h").to_str().unwrap() ); + #[cfg(feature = "drivers")] + println!( + "cargo:rerun-if-changed={}", + conf_path.join("lv_drv_conf.h").to_str().unwrap() + ); conf_path }; + #[cfg(feature = "drivers")] + { + println!("cargo:rerun-if-env-changed=LVGL_INCLUDE"); + println!("cargo:rerun-if-env-changed=LVGL_LINK"); + } + let mut cfg = Build::new(); - add_c_files(&mut cfg, &vendor_src); + add_c_files(&mut cfg, &lvgl_src); add_c_files(&mut cfg, &lv_config_dir); add_c_files(&mut cfg, &shims_dir); + #[cfg(feature = "drivers")] + add_c_files(&mut cfg, &drivers); cfg.define("LV_CONF_INCLUDE_SIMPLE", Some("1")) - .include(&vendor_src) + .include(&lvgl_src) .include(&vendor) .warnings(false) - .include(&lv_config_dir) - .compile("lvgl"); + .include(&lv_config_dir); + #[cfg(feature = "drivers")] + cfg.include(&drivers); + #[cfg(feature = "drivers")] + cfg.includes(incl_extra.split(',')); + + cfg.compile("lvgl"); let mut cc_args = vec![ "-DLV_CONF_INCLUDE_SIMPLE=1", @@ -78,6 +131,9 @@ fn main() { "-fvisibility=default", ]; + //#[cfg(feature = "drivers")] + //incl_extra.split(',').for_each(|a| { cc_args.append(&mut vec!["-l"]); cc_args.append(&mut vec![a]) }); + // Set correct target triple for bindgen when cross-compiling let target = env::var("TARGET").expect("Cargo build scripts always have TARGET"); let host = env::var("HOST").expect("Cargo build scripts always have HOST"); @@ -107,9 +163,28 @@ fn main() { } } + #[cfg(feature = "drivers")] + let ignored_macros = IgnoreMacros( + vec![ + "FP_INFINITE".into(), + "FP_NAN".into(), + "FP_NORMAL".into(), + "FP_SUBNORMAL".into(), + "FP_ZERO".into(), + "IPPORT_RESERVED".into(), + ] + .into_iter() + .collect(), + ); + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); - let bindings = bindgen::Builder::default() - .header(shims_dir.join("lvgl_sys.h").to_str().unwrap()) + let bindings = + bindgen::Builder::default().header(shims_dir.join("lvgl_sys.h").to_str().unwrap()); + #[cfg(feature = "drivers")] + let bindings = bindings + .header(shims_dir.join("lvgl_drv.h").to_str().unwrap()) + .parse_callbacks(Box::new(ignored_macros)); + let bindings = bindings .generate_comments(false) .derive_default(true) .layout_tests(false) @@ -124,6 +199,12 @@ fn main() { bindings .write_to_file(out_path.join("bindings.rs")) .expect("Can't write bindings!"); + + #[cfg(feature = "drivers")] + link_extra.split(',').for_each(|a| { + println!("cargo:rustc-link-lib={a}"); + //println!("cargo:rustc-link-search=") + }) } fn add_c_files(build: &mut cc::Build, path: impl AsRef) { diff --git a/lvgl-sys/shims/lvgl_drv.h b/lvgl-sys/shims/lvgl_drv.h new file mode 100644 index 00000000..33a92e21 --- /dev/null +++ b/lvgl-sys/shims/lvgl_drv.h @@ -0,0 +1,102 @@ +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef LVGL_DRV_H +#define LVGL_DRV_H + +#include "lv_drv_conf.h" + +/* Displays */ + +#if USE_SDL +#include "lv_drivers/sdl/sdl.h" +#endif + +#if USE_MONITOR +#include "lv_drivers/display/monitor.h" +#endif + +#if USE_WINDOWS +#include "lv_drivers/win_drv.h" +#endif + +#if USE_GTK +#include "lv_drivers/gtkdrv/gtkdrv.h" +#endif + +#if USE_SSD1963 +#include "lv_drivers/display/SSD1963.h" +#endif + +#if USE_R61581 +#include "lv_drivers/display/R61581.h" +#endif + +#if USE_ST7565 +#include "lv_drivers/display/ST7565.h" +#endif + +#if USE_GC9A01 +#include "lv_drivers/display/GC9A01.h" +#endif + +#if USE_UC1610 +#include "lv_drivers/display/UC1610.h" +#endif + +#if USE_SHARP_MIP +#include "lv_drivers/display/SHARP_MIP.h" +#endif + +#if USE_ILI9341 +#include "lv_drivers/display/ILI9341.h" +#endif + +#if USE_FBDEV || USE_BSD_FBDEV +#include "lv_drivers/display/fbdev.h" +#endif + +#if USE_DRM +#include "lv_drivers/display/drm.h" +#endif + +/* Input devices */ + +#if USE_XPT2046 +#include "lv_drivers/indev/XPT2046.h" +#endif + +#if USE_FT5406EE8 +#include "lv_drivers/indev/FT5406EE8.h" +#endif + +#if USE_AD_TOUCH +#include "lv_drivers/indev/AD_touch.h" +#endif + +#if USE_MOUSE +#include "lv_drivers/indev/mouse.h" +#endif + +#if USE_MOUSEWHEEL +#include "lv_drivers/indev/mousewheel.h" +#endif + +#if USE_LIBINPUT +#include "lv_drivers/indev/libinput_drv.h" +#endif + +#if USE_EVDEV || USE_BSD_EVDEV +#include "lv_drivers/indev/evdev.h" +#endif + +#if USE_KEYBOARD +#include "lv_drivers/indev/keyboard.h" +#endif + +#endif /* LVGL_DRV_H */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/lvgl-sys/vendor/include/lv_drv_conf.h b/lvgl-sys/vendor/include/lv_drv_conf.h new file mode 100644 index 00000000..23f280d6 --- /dev/null +++ b/lvgl-sys/vendor/include/lv_drv_conf.h @@ -0,0 +1,494 @@ +/** + * @file lv_drv_conf.h + * Configuration file for v8.3.0 + */ + +/* + * COPY THIS FILE AS lv_drv_conf.h + */ + +/* clang-format off */ +#if 1 /*Set it to "1" to enable the content*/ + +#ifndef LV_DRV_CONF_H +#define LV_DRV_CONF_H + +#include "lv_conf.h" + +/********************* + * DELAY INTERFACE + *********************/ +#define LV_DRV_DELAY_INCLUDE /*Dummy include by default*/ +#define LV_DRV_DELAY_US(us) /*delay_us(us)*/ /*Delay the given number of microseconds*/ +#define LV_DRV_DELAY_MS(ms) /*delay_ms(ms)*/ /*Delay the given number of milliseconds*/ + +/********************* + * DISPLAY INTERFACE + *********************/ + +/*------------ + * Common + *------------*/ +#define LV_DRV_DISP_INCLUDE /*Dummy include by default*/ +#define LV_DRV_DISP_CMD_DATA(val) /*pin_x_set(val)*/ /*Set the command/data pin to 'val'*/ +#define LV_DRV_DISP_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/ + +/*--------- + * SPI + *---------*/ +#define LV_DRV_DISP_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/ +#define LV_DRV_DISP_SPI_WR_BYTE(data) /*spi_wr(data)*/ /*Write a byte the SPI bus*/ +#define LV_DRV_DISP_SPI_WR_ARRAY(adr, n) /*spi_wr_mem(adr, n)*/ /*Write 'n' bytes to SPI bus from 'adr'*/ + +/*------------------ + * Parallel port + *-----------------*/ +#define LV_DRV_DISP_PAR_CS(val) /*par_cs_set(val)*/ /*Set the Parallel port's Chip select to 'val'*/ +#define LV_DRV_DISP_PAR_SLOW /*par_slow()*/ /*Set low speed on the parallel port*/ +#define LV_DRV_DISP_PAR_FAST /*par_fast()*/ /*Set high speed on the parallel port*/ +#define LV_DRV_DISP_PAR_WR_WORD(data) /*par_wr(data)*/ /*Write a word to the parallel port*/ +#define LV_DRV_DISP_PAR_WR_ARRAY(adr, n) /*par_wr_mem(adr,n)*/ /*Write 'n' bytes to Parallel ports from 'adr'*/ + +/*************************** + * INPUT DEVICE INTERFACE + ***************************/ + +/*---------- + * Common + *----------*/ +#define LV_DRV_INDEV_INCLUDE /*Dummy include by default*/ +#define LV_DRV_INDEV_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/ +#define LV_DRV_INDEV_IRQ_READ 0 /*pn_x_read()*/ /*Read the IRQ pin*/ + +/*--------- + * SPI + *---------*/ +#define LV_DRV_INDEV_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/ +#define LV_DRV_INDEV_SPI_XCHG_BYTE(data) 0 /*spi_xchg(val)*/ /*Write 'val' to SPI and give the read value*/ + +/*--------- + * I2C + *---------*/ +#define LV_DRV_INDEV_I2C_START /*i2c_start()*/ /*Make an I2C start*/ +#define LV_DRV_INDEV_I2C_STOP /*i2c_stop()*/ /*Make an I2C stop*/ +#define LV_DRV_INDEV_I2C_RESTART /*i2c_restart()*/ /*Make an I2C restart*/ +#define LV_DRV_INDEV_I2C_WR(data) /*i2c_wr(data)*/ /*Write a byte to the I1C bus*/ +#define LV_DRV_INDEV_I2C_READ(last_read) 0 /*i2c_rd()*/ /*Read a byte from the I2C bud*/ + + +/********************* + * DISPLAY DRIVERS + *********************/ + +/*------------------- + * SDL + *-------------------*/ + +/* SDL based drivers for display, mouse, mousewheel and keyboard*/ +#ifndef USE_SDL +# define USE_SDL 0 +#endif + +/* Hardware accelerated SDL driver */ +#ifndef USE_SDL_GPU +# define USE_SDL_GPU 0 +#endif + +#if USE_SDL || USE_SDL_GPU +# define SDL_HOR_RES 480 +# define SDL_VER_RES 320 + +/* Scale window by this factor (useful when simulating small screens) */ +# define SDL_ZOOM 1 + +/* Used to test true double buffering with only address changing. + * Use 2 draw buffers, bith with SDL_HOR_RES x SDL_VER_RES size*/ +# define SDL_DOUBLE_BUFFERED 0 + +/*Eclipse: Visual Studio: */ +# define SDL_INCLUDE_PATH + +/*Open two windows to test multi display support*/ +# define SDL_DUAL_DISPLAY 0 +#endif + +/*------------------- + * Monitor of PC + *-------------------*/ + +/*DEPRECATED: Use the SDL driver instead. */ +#ifndef USE_MONITOR +# define USE_MONITOR 0 +#endif + +#if USE_MONITOR +# define MONITOR_HOR_RES 480 +# define MONITOR_VER_RES 320 + +/* Scale window by this factor (useful when simulating small screens) */ +# define MONITOR_ZOOM 1 + +/* Used to test true double buffering with only address changing. + * Use 2 draw buffers, bith with MONITOR_HOR_RES x MONITOR_VER_RES size*/ +# define MONITOR_DOUBLE_BUFFERED 0 + +/*Eclipse: Visual Studio: */ +# define MONITOR_SDL_INCLUDE_PATH + +/*Open two windows to test multi display support*/ +# define MONITOR_DUAL 0 +#endif + +/*----------------------------------- + * Native Windows (including mouse) + *----------------------------------*/ +#ifndef USE_WINDOWS +# define USE_WINDOWS 0 +#endif + +#if USE_WINDOWS +# define WINDOW_HOR_RES 480 +# define WINDOW_VER_RES 320 +#endif + +/*---------------------------- + * Native Windows (win32drv) + *---------------------------*/ +#ifndef USE_WIN32DRV +# define USE_WIN32DRV 0 +#endif + +#if USE_WIN32DRV +/* Scale window by this factor (useful when simulating small screens) */ +# define WIN32DRV_MONITOR_ZOOM 1 +#endif + +/*---------------------------------------- + * GTK drivers (monitor, mouse, keyboard + *---------------------------------------*/ +#ifndef USE_GTK +# define USE_GTK 0 +#endif + +/*---------------------------------------- + * Wayland drivers (monitor, mouse, keyboard, touchscreen) + *---------------------------------------*/ +#ifndef USE_WAYLAND +# define USE_WAYLAND 0 +#endif + +#if USE_WAYLAND +/* Support for client-side decorations */ +# ifndef LV_WAYLAND_CLIENT_SIDE_DECORATIONS +# define LV_WAYLAND_CLIENT_SIDE_DECORATIONS 1 +# endif +/* Support for (deprecated) wl-shell protocol */ +# ifndef LV_WAYLAND_WL_SHELL +# define LV_WAYLAND_WL_SHELL 1 +# endif +/* Support for xdg-shell protocol */ +# ifndef LV_WAYLAND_XDG_SHELL +# define LV_WAYLAND_XDG_SHELL 0 +# endif +#endif + +/*---------------- + * SSD1963 + *--------------*/ +#ifndef USE_SSD1963 +# define USE_SSD1963 0 +#endif + +#if USE_SSD1963 +# define SSD1963_HOR_RES LV_HOR_RES +# define SSD1963_VER_RES LV_VER_RES +# define SSD1963_HT 531 +# define SSD1963_HPS 43 +# define SSD1963_LPS 8 +# define SSD1963_HPW 10 +# define SSD1963_VT 288 +# define SSD1963_VPS 12 +# define SSD1963_FPS 4 +# define SSD1963_VPW 10 +# define SSD1963_HS_NEG 0 /*Negative hsync*/ +# define SSD1963_VS_NEG 0 /*Negative vsync*/ +# define SSD1963_ORI 0 /*0, 90, 180, 270*/ +# define SSD1963_COLOR_DEPTH 16 +#endif + +/*---------------- + * R61581 + *--------------*/ +#ifndef USE_R61581 +# define USE_R61581 0 +#endif + +#if USE_R61581 +# define R61581_HOR_RES LV_HOR_RES +# define R61581_VER_RES LV_VER_RES +# define R61581_HSPL 0 /*HSYNC signal polarity*/ +# define R61581_HSL 10 /*HSYNC length (Not Implemented)*/ +# define R61581_HFP 10 /*Horitontal Front poarch (Not Implemented)*/ +# define R61581_HBP 10 /*Horitontal Back poarch (Not Implemented */ +# define R61581_VSPL 0 /*VSYNC signal polarity*/ +# define R61581_VSL 10 /*VSYNC length (Not Implemented)*/ +# define R61581_VFP 8 /*Vertical Front poarch*/ +# define R61581_VBP 8 /*Vertical Back poarch */ +# define R61581_DPL 0 /*DCLK signal polarity*/ +# define R61581_EPL 1 /*ENABLE signal polarity*/ +# define R61581_ORI 0 /*0, 180*/ +# define R61581_LV_COLOR_DEPTH 16 /*Fix 16 bit*/ +#endif + +/*------------------------------ + * ST7565 (Monochrome, low res.) + *-----------------------------*/ +#ifndef USE_ST7565 +# define USE_ST7565 0 +#endif + +#if USE_ST7565 +/*No settings*/ +#endif /*USE_ST7565*/ + +/*------------------------------ + * GC9A01 (color, low res.) + *-----------------------------*/ +#ifndef USE_GC9A01 +# define USE_GC9A01 0 +#endif + +#if USE_GC9A01 +/*No settings*/ +#endif /*USE_GC9A01*/ + +/*------------------------------------------ + * UC1610 (4 gray 160*[104|128]) + * (EA DOGXL160 160x104 tested) + *-----------------------------------------*/ +#ifndef USE_UC1610 +# define USE_UC1610 0 +#endif + +#if USE_UC1610 +# define UC1610_HOR_RES LV_HOR_RES +# define UC1610_VER_RES LV_VER_RES +# define UC1610_INIT_CONTRAST 33 /* init contrast, values in [%] */ +# define UC1610_INIT_HARD_RST 0 /* 1 : hardware reset at init, 0 : software reset */ +# define UC1610_TOP_VIEW 0 /* 0 : Bottom View, 1 : Top View */ +#endif /*USE_UC1610*/ + +/*------------------------------------------------- + * SHARP memory in pixel monochrome display series + * LS012B7DD01 (184x38 pixels.) + * LS013B7DH03 (128x128 pixels.) + * LS013B7DH05 (144x168 pixels.) + * LS027B7DH01 (400x240 pixels.) (tested) + * LS032B7DD02 (336x536 pixels.) + * LS044Q7DH01 (320x240 pixels.) + *------------------------------------------------*/ +#ifndef USE_SHARP_MIP +# define USE_SHARP_MIP 0 +#endif + +#if USE_SHARP_MIP +# define SHARP_MIP_HOR_RES LV_HOR_RES +# define SHARP_MIP_VER_RES LV_VER_RES +# define SHARP_MIP_SOFT_COM_INVERSION 0 +# define SHARP_MIP_REV_BYTE(b) /*((uint8_t) __REV(__RBIT(b)))*/ /*Architecture / compiler dependent byte bits order reverse*/ +#endif /*USE_SHARP_MIP*/ + +/*------------------------------------------------- + * ILI9341 240X320 TFT LCD + *------------------------------------------------*/ +#ifndef USE_ILI9341 +# define USE_ILI9341 0 +#endif + +#if USE_ILI9341 +# define ILI9341_HOR_RES LV_HOR_RES +# define ILI9341_VER_RES LV_VER_RES +# define ILI9341_GAMMA 1 +# define ILI9341_TEARING 0 +#endif /*USE_ILI9341*/ + +/*----------------------------------------- + * Linux frame buffer device (/dev/fbx) + *-----------------------------------------*/ +#ifndef USE_FBDEV +# define USE_FBDEV 1 +#endif + +#if USE_FBDEV +# define FBDEV_PATH "/dev/fb0" +#endif + +/*----------------------------------------- + * FreeBSD frame buffer device (/dev/fbx) + *.........................................*/ +#ifndef USE_BSD_FBDEV +# define USE_BSD_FBDEV 0 +#endif + +#if USE_BSD_FBDEV +# define FBDEV_PATH "/dev/fb0" +#endif + +/*----------------------------------------- + * DRM/KMS device (/dev/dri/cardX) + *-----------------------------------------*/ +#ifndef USE_DRM +# define USE_DRM 0 +#endif + +#if USE_DRM +# define DRM_CARD "/dev/dri/card0" +# define DRM_CONNECTOR_ID -1 /* -1 for the first connected one */ +#endif + +/********************* + * INPUT DEVICES + *********************/ + +/*-------------- + * XPT2046 + *--------------*/ +#ifndef USE_XPT2046 +# define USE_XPT2046 0 +#endif + +#if USE_XPT2046 +# define XPT2046_HOR_RES 480 +# define XPT2046_VER_RES 320 +# define XPT2046_X_MIN 200 +# define XPT2046_Y_MIN 200 +# define XPT2046_X_MAX 3800 +# define XPT2046_Y_MAX 3800 +# define XPT2046_AVG 4 +# define XPT2046_X_INV 0 +# define XPT2046_Y_INV 0 +# define XPT2046_XY_SWAP 0 +#endif + +/*----------------- + * FT5406EE8 + *-----------------*/ +#ifndef USE_FT5406EE8 +# define USE_FT5406EE8 0 +#endif + +#if USE_FT5406EE8 +# define FT5406EE8_I2C_ADR 0x38 /*7 bit address*/ +#endif + +/*--------------- + * AD TOUCH + *--------------*/ +#ifndef USE_AD_TOUCH +# define USE_AD_TOUCH 0 +#endif + +#if USE_AD_TOUCH +/*No settings*/ +#endif + + +/*--------------------------------------- + * Mouse or touchpad on PC (using SDL) + *-------------------------------------*/ +/*DEPRECATED: Use the SDL driver instead. */ +#ifndef USE_MOUSE +# define USE_MOUSE 0 +#endif + +#if USE_MOUSE +/*No settings*/ +#endif + +/*------------------------------------------- + * Mousewheel as encoder on PC (using SDL) + *------------------------------------------*/ +/*DEPRECATED: Use the SDL driver instead. */ +#ifndef USE_MOUSEWHEEL +# define USE_MOUSEWHEEL 0 +#endif + +#if USE_MOUSEWHEEL +/*No settings*/ +#endif + +/*------------------------------------------------- + * Touchscreen, mouse/touchpad or keyboard as libinput interface (for Linux based systems) + *------------------------------------------------*/ +#ifndef USE_LIBINPUT +# define USE_LIBINPUT 0 +#endif + +#ifndef USE_BSD_LIBINPUT +# define USE_BSD_LIBINPUT 0 +#endif + +#if USE_LIBINPUT || USE_BSD_LIBINPUT +/*If only a single device of the same type is connected, you can also auto detect it, e.g.: + *#define LIBINPUT_NAME libinput_find_dev(LIBINPUT_CAPABILITY_TOUCH, false)*/ +# define LIBINPUT_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/ + +#endif /*USE_LIBINPUT || USE_BSD_LIBINPUT*/ + +/*------------------------------------------------- + * Mouse or touchpad as evdev interface (for Linux based systems) + *------------------------------------------------*/ +#ifndef USE_EVDEV +# define USE_EVDEV 0 +#endif + +#ifndef USE_BSD_EVDEV +# define USE_BSD_EVDEV 0 +#endif + +#if USE_EVDEV || USE_BSD_EVDEV +# define EVDEV_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/ +# define EVDEV_SWAP_AXES 0 /*Swap the x and y axes of the touchscreen*/ + +# define EVDEV_CALIBRATE 0 /*Scale and offset the touchscreen coordinates by using maximum and minimum values for each axis*/ + +# if EVDEV_CALIBRATE +# define EVDEV_HOR_MIN 0 /*to invert axis swap EVDEV_XXX_MIN by EVDEV_XXX_MAX*/ +# define EVDEV_HOR_MAX 4096 /*"evtest" Linux tool can help to get the correct calibraion values>*/ +# define EVDEV_VER_MIN 0 +# define EVDEV_VER_MAX 4096 +# endif /*EVDEV_CALIBRATE*/ +#endif /*USE_EVDEV*/ + +/*------------------------------------------------- + * Full keyboard support for evdev and libinput interface + *------------------------------------------------*/ +# ifndef USE_XKB +# define USE_XKB 0 +# endif + +#if USE_LIBINPUT || USE_BSD_LIBINPUT || USE_EVDEV || USE_BSD_EVDEV +# if USE_XKB +# define XKB_KEY_MAP { .rules = NULL, \ + .model = "pc101", \ + .layout = "us", \ + .variant = NULL, \ + .options = NULL } /*"setxkbmap -query" can help find the right values for your keyboard*/ +# endif /*USE_XKB*/ +#endif /*USE_LIBINPUT || USE_BSD_LIBINPUT || USE_EVDEV || USE_BSD_EVDEV*/ + +/*------------------------------- + * Keyboard of a PC (using SDL) + *------------------------------*/ +/*DEPRECATED: Use the SDL driver instead. */ +#ifndef USE_KEYBOARD +# define USE_KEYBOARD 0 +#endif + +#if USE_KEYBOARD +/*No settings*/ +#endif + +#endif /*LV_DRV_CONF_H*/ + +#endif /*End of "Content enable"*/ diff --git a/lvgl-sys/vendor/lv_drivers b/lvgl-sys/vendor/lv_drivers new file mode 160000 index 00000000..1413f5eb --- /dev/null +++ b/lvgl-sys/vendor/lv_drivers @@ -0,0 +1 @@ +Subproject commit 1413f5ebb6d21bc8ebb45448826dd7b4bbd3b7a3 diff --git a/lvgl/Cargo.toml b/lvgl/Cargo.toml index 2beeeda6..59d04e47 100644 --- a/lvgl/Cargo.toml +++ b/lvgl/Cargo.toml @@ -3,7 +3,7 @@ name = "lvgl" description = "LVGL bindings for Rust. A powerful and easy-to-use embedded GUI with many widgets, advanced visual effects (opacity, antialiasing, animations) and low memory requirements (16K RAM, 64K Flash)." version = "0.5.2" authors = ["Rafael Caricio "] -edition = "2018" +edition = "2021" repository = "https://github.com/rafaelcaricio/lvgl-rs" license = "MIT" readme = "../README.md" @@ -20,11 +20,12 @@ bitflags = "1.3.2" paste = "1.0.11" [features] -default = ["embedded_graphics"] +default = ["embedded_graphics", "drivers"] embedded_graphics = ["embedded-graphics"] alloc = ["cstr_core/alloc"] lvgl_alloc = ["alloc"] use-vendored-config = ["lvgl-sys/use-vendored-config"] +drivers = ["lvgl-sys/drivers"] [build-dependencies] quote = "1.0.23" @@ -64,3 +65,8 @@ required-features = ["alloc", "embedded_graphics"] name = "arc" path = "../examples/arc.rs" required-features = ["alloc", "embedded_graphics"] + +[[example]] +name = "sdl" +path = "../examples/sdl.rs" +required-features = ["alloc", "drivers"] diff --git a/lvgl/src/display.rs b/lvgl/src/display.rs index f8c20ae4..85167360 100644 --- a/lvgl/src/display.rs +++ b/lvgl/src/display.rs @@ -6,7 +6,6 @@ use core::convert::TryInto; use core::mem::MaybeUninit; use core::ptr::NonNull; use core::{ptr, result}; -use cty::c_void; use lvgl_sys::_lv_disp_draw_buf_t; /// Error in interacting with a `Display`. @@ -22,11 +21,15 @@ type Result = result::Result; /// An LVGL-registered display. Equivalent to an `lv_disp_t`. pub struct Display { pub(crate) disp: NonNull, + drop: Option, } impl<'a> Display { - pub(crate) fn from_raw(disp: NonNull) -> Self { - Self { disp } + pub(crate) fn from_raw( + disp: NonNull, + drop: Option, + ) -> Self { + Self { disp, drop } } /// Registers a given `DrawBuffer` with an associated update function to @@ -44,12 +47,63 @@ impl<'a> Display { let disp_p = &mut display_diver.disp_drv; disp_p.hor_res = hor_res.try_into().unwrap_or(240); disp_p.ver_res = ver_res.try_into().unwrap_or(240); - Ok(disp_drv_register(&mut display_diver)?) + Ok(disp_drv_register(&mut display_diver, None)?) } pub fn get_scr_act(&self) -> Result { Ok(get_str_act(Some(&self))?) } + + pub unsafe fn register_raw( + draw_buffer: DrawBuffer, + hor_res: u32, + ver_res: u32, + flush_cb: Option< + unsafe extern "C" fn( + *mut lvgl_sys::_lv_disp_drv_t, + *const lvgl_sys::lv_area_t, + *mut lvgl_sys::lv_color16_t, + ), + >, + rounder_cb: Option< + unsafe extern "C" fn(*mut lvgl_sys::_lv_disp_drv_t, *mut lvgl_sys::lv_area_t), + >, + set_px_cb: Option< + unsafe extern "C" fn( + *mut lvgl_sys::_lv_disp_drv_t, + *mut u8, + lvgl_sys::lv_coord_t, + lvgl_sys::lv_coord_t, + lvgl_sys::lv_coord_t, + lvgl_sys::lv_color_t, + lvgl_sys::lv_opa_t, + ), + >, + clear_cb: Option, + monitor_cb: Option, + wait_cb: Option, + clean_dcache_cb: Option, + drv_update_cb: Option, + render_start_cb: Option, + drop: Option, + ) -> Result { + let mut display_driver = DisplayDriver::new_raw( + draw_buffer, + flush_cb, + rounder_cb, + set_px_cb, + clear_cb, + monitor_cb, + wait_cb, + clean_dcache_cb, + drv_update_cb, + render_start_cb, + )?; + let disp_p = &mut display_driver.disp_drv; + disp_p.hor_res = hor_res.try_into().unwrap_or(240); + disp_p.ver_res = ver_res.try_into().unwrap_or(240); + Ok(disp_drv_register(&mut display_driver, drop)?) + } } impl Default for Display { @@ -58,6 +112,14 @@ impl Default for Display { } } +impl Drop for Display { + fn drop(&mut self) { + if let Some(drop) = self.drop { + unsafe { drop() } + } + } +} + #[derive(Copy, Clone)] pub(crate) struct DefaultDisplay {} @@ -96,7 +158,7 @@ impl DrawBuffer { let draw_buf = unsafe { lvgl_sys::lv_disp_draw_buf_init( inner.as_mut_ptr(), - primary_buffer_guard.borrow_mut().as_mut_ptr() as *mut _ as *mut cty::c_void, + primary_buffer_guard.borrow_mut().as_mut_ptr() as *mut _, ptr::null_mut(), N as u32, ); @@ -132,7 +194,7 @@ impl<'a, const N: usize> DisplayDriver { .ok_or(DisplayError::FailedToRegister)?, ) as *mut _; - disp_drv.user_data = Box::into_raw(Box::new(display_update_callback)) as *mut c_void; + disp_drv.user_data = Box::into_raw(Box::new(display_update_callback)) as *mut _; // Sets trampoline pointer to the function implementation that uses the `F` type for a // refresh buffer of size N specifically. @@ -144,6 +206,66 @@ impl<'a, const N: usize> DisplayDriver { _buffer: draw_buffer, }) } + + pub unsafe fn new_raw( + draw_buffer: DrawBuffer, + flush_cb: Option< + unsafe extern "C" fn( + *mut lvgl_sys::_lv_disp_drv_t, + *const lvgl_sys::lv_area_t, + *mut lvgl_sys::lv_color16_t, + ), + >, + rounder_cb: Option< + unsafe extern "C" fn(*mut lvgl_sys::_lv_disp_drv_t, *mut lvgl_sys::lv_area_t), + >, + set_px_cb: Option< + unsafe extern "C" fn( + *mut lvgl_sys::_lv_disp_drv_t, + *mut u8, + lvgl_sys::lv_coord_t, + lvgl_sys::lv_coord_t, + lvgl_sys::lv_coord_t, + lvgl_sys::lv_color_t, + lvgl_sys::lv_opa_t, + ), + >, + clear_cb: Option, + monitor_cb: Option, + wait_cb: Option, + clean_dcache_cb: Option, + drv_update_cb: Option, + render_start_cb: Option, + ) -> Result { + let mut disp_drv = unsafe { + let mut inner = MaybeUninit::uninit(); + lvgl_sys::lv_disp_drv_init(inner.as_mut_ptr()); + inner.assume_init() + }; + + disp_drv.draw_buf = Box::<_lv_disp_draw_buf_t>::into_raw( + draw_buffer + .get_ptr() + .ok_or(DisplayError::FailedToRegister)?, + ) as *mut _; + + //disp_drv.user_data = Box::into_raw(Box::new(display_update_callback)) as *mut _; + + disp_drv.flush_cb = flush_cb; + disp_drv.rounder_cb = rounder_cb; + disp_drv.set_px_cb = set_px_cb; + disp_drv.clear_cb = clear_cb; + disp_drv.monitor_cb = monitor_cb; + disp_drv.wait_cb = wait_cb; + disp_drv.clean_dcache_cb = clean_dcache_cb; + disp_drv.drv_update_cb = drv_update_cb; + disp_drv.render_start_cb = render_start_cb; + + Ok(Self { + disp_drv, + _buffer: draw_buffer, + }) + } } /// Represents a sub-area of the display that is being updated. diff --git a/lvgl/src/drivers/lv_drv_display.rs b/lvgl/src/drivers/lv_drv_display.rs new file mode 100644 index 00000000..0c0292f7 --- /dev/null +++ b/lvgl/src/drivers/lv_drv_display.rs @@ -0,0 +1,281 @@ +#[macro_export] +macro_rules! lv_drv_disp_fbdev { + ($draw_buffer:ident, $hor_res:ident, $ver_res:ident) => { + unsafe { + lvgl_sys::fbdev_init(); + $crate::Display::register_raw( + $draw_buffer, + $hor_res, + $ver_res, + Some(lvgl_sys::fbdev_flush), + None, + None, + None, + None, + None, + None, + None, + None, + Some(lvgl_sys::fbdev_exit), + ) + } + } +} + +#[macro_export] +macro_rules! lv_drv_disp_drm { + ($draw_buffer:ident, $hor_res:ident, $ver_res:ident) => { + unsafe { + lvgl_sys::drm_init(); + $crate::Display::register_raw( + $draw_buffer, + $hor_res, + $ver_res, + Some(lvgl_sys::drm_flush), + None, + None, + None, + None, + Some(lvgl_sys::drm_wait_vsync), + None, + None, + None, + Some(lvgl_sys::drm_exit), + ) + } + } +} + +#[macro_export] +macro_rules! lv_drv_disp_gtk { + ($draw_buffer:ident, $hor_res:ident, $ver_res:ident) => { + unsafe { + lvgl_sys::gtkdrv_init(); + $crate::Display::register_raw( + $draw_buffer, + $hor_res, + $ver_res, + Some(lvgl_sys::gtkdrv_flush_cb), + None, + None, + None, + None, + None, + None, + None, + None, + None, + ) + } + } +} + +#[macro_export] +macro_rules! lv_drv_disp_sdl { + ($draw_buffer:ident, $hor_res:ident, $ver_res:ident) => { + unsafe { + lvgl_sys::sdl_init(); + $crate::Display::register_raw( + $draw_buffer, + $hor_res, + $ver_res, + Some(lvgl_sys::sdl_display_flush), + None, + None, + None, + None, + None, + None, + None, + None, + None, + ) + } + } +} + +#[macro_export] +macro_rules! lv_drv_disp_gc9a01 { + ($draw_buffer:ident, $hor_res:ident, $ver_res:ident) => { + unsafe { + match lvgl_sys::GC9A01_init() { + 0 => (), + c = panic!("GC9A01_init() returned error code {c}") + }; + $crate::Display::register_raw( + $draw_buffer, + $hor_res, + $ver_res, + Some(lvgl_sys::GC9A01_flush), + None, + None, + None, + None, + None, + None, + None, + None, + None, + ) + } + } +} + +#[macro_export] +macro_rules! lv_drv_disp_ili9341 { + ($draw_buffer:ident, $hor_res:ident, $ver_res:ident) => { + unsafe { + lvgl_sys::ili9341_init(); + $crate::Display::register_raw( + $draw_buffer, + $hor_res, + $ver_res, + Some(lvgl_sys::ili9341_flush), + None, + None, + None, + None, + None, + None, + None, + None, + None, + ) + } + } +} + +#[macro_export] +macro_rules! lv_drv_disp_r61581 { + ($draw_buffer:ident, $hor_res:ident, $ver_res:ident) => { + unsafe { + lvgl_sys::r61581_init(); + $crate::Display::register_raw( + $draw_buffer, + $hor_res, + $ver_res, + Some(lvgl_sys::r61581_flush), + None, + None, + None, + None, + None, + None, + None, + None, + None, + ) + } + } +} + +#[macro_export] +macro_rules! lv_drv_disp_sharp_mip { + ($draw_buffer:ident, $hor_res:ident, $ver_res:ident) => { + unsafe { + lvgl_sys::sharp_mip_init(); + $crate::Display::register_raw( + $draw_buffer, + $hor_res, + $ver_res, + Some(lvgl_sys::sharp_mip_flush), + Some(lvgl_sys::sharp_mip_rounder), + Some(lvgl_sys::sharp_mip_set_px), + None, + None, + None, + None, + None, + None, + None, + ) + } + } +} + +#[macro_export] +macro_rules! lv_drv_disp_ssd1963 { + ($draw_buffer:ident, $hor_res:ident, $ver_res:ident) => { + unsafe { + lvgl_sys::ssd1963_init(); + $crate::Display::register_raw( + $draw_buffer, + $hor_res, + $ver_res, + Some(lvgl_sys::ssd1963_flush), + None, + None, + None, + None, + None, + None, + None, + None, + None, + ) + } + } +} + +#[macro_export] +macro_rules! lv_drv_disp_st7565 { + ($draw_buffer:ident, $hor_res:ident, $ver_res:ident) => { + unsafe { + lvgl_sys::st7565_init(); + $crate::Display::register_raw( + $draw_buffer, + $hor_res, + $ver_res, + Some(lvgl_sys::st7565_flush), + None, + None, + None, + None, + None, + None, + None, + None, + None, + ) + } + } +} + +#[macro_export] +macro_rules! lv_drv_disp_uc1610 { + ($draw_buffer:ident, $hor_res:ident, $ver_res:ident) => { + unsafe { + lvgl_sys::uc1610_init(); + $crate::Display::register_raw( + $draw_buffer, + $hor_res, + $ver_res, + Some(lvgl_sys::uc1610_flush_cb), + Some(lvgl_sys::uc1610_rounder_cb), + Some(lvgl_sys::uc1610_set_px_cb), + None, + None, + None, + None, + None, + None, + None, + ) + } + } +} + +#[cfg(test)] +mod tests { + use crate::tests; + use crate::DrawBuffer; + + #[test] + fn gtk_test() { + const HOR_RES: u32 = 240; + const VER_RES: u32 = 240; + tests::initialize_test(); + let buffer = DrawBuffer::<{ (HOR_RES * VER_RES) as usize }>::new(); + let _disp = lv_drv_disp_sdl!(buffer, HOR_RES, VER_RES).unwrap(); + } +} \ No newline at end of file diff --git a/lvgl/src/drivers/lv_drv_input.rs b/lvgl/src/drivers/lv_drv_input.rs new file mode 100644 index 00000000..507bda49 --- /dev/null +++ b/lvgl/src/drivers/lv_drv_input.rs @@ -0,0 +1,93 @@ +#[macro_export] +macro_rules! lv_drv_input_pointer_evdev { + () => { + unsafe { + lvgl_sys::evdev_init(); + $crate::input_device::pointer::PointerPointer::new_raw( + Some(lvgl_sys::evdev_read), + None, + ) + } + } +} + +#[macro_export] +macro_rules! lv_drv_input_pointer_gtk { + () => { + unsafe { + $crate::input_device::pointer::Pointer::new_raw( + Some(lvgl_sys::gtkdrv_mouse_read_cb), + None, + ) + } + } +} + +#[macro_export] +macro_rules! lv_drv_input_pointer_sdl { + () => { + unsafe { + $crate::input_device::pointer::Pointer::new_raw( + Some(lvgl_sys::sdl_mouse_read), + None, + ) + } + } +} + +#[macro_export] +macro_rules! lv_drv_input_ad_touch { + () => { + unsafe { + lvgl_sys::ad_touch_init(); + $crate::input_device::pointer::Pointer::new_raw( + Some(lvgl_sys::ad_touch_read), + None, + ) + } + } +} + +#[macro_export] +macro_rules! lv_drv_input_ft5406ee8 { + () => { + unsafe { + lvgl_sys::ft5406ee8_init(); + $crate::input_device::pointer::Pointer::new_raw( + Some(lvgl_sys::ft5406ee8_read), + None, + ) + } + } +} + +#[macro_export] +macro_rules! lv_drv_input_xpt2046 { + () => { + unsafe { + lvgl_sys::xpt2046_init(); + $crate::input_device::pointer::Pointer::new_raw( + Some(lvgl_sys::xpt2046_read), + None, + ) + } + } +} + +#[cfg(test)] +mod tests { + use crate::*; + use crate::tests; + use crate::DrawBuffer; + use crate::input_device::generic::InputDriver; + + #[test] + fn gtk_test() { + const HOR_RES: u32 = 240; + const VER_RES: u32 = 240; + tests::initialize_test(); + let buffer = DrawBuffer::<{ (HOR_RES * VER_RES) as usize }>::new(); + let _disp = lv_drv_disp_sdl!(buffer, HOR_RES, VER_RES).unwrap(); + let _input = lv_drv_input_pointer_sdl!(); + } +} \ No newline at end of file diff --git a/lvgl/src/drivers/mod.rs b/lvgl/src/drivers/mod.rs new file mode 100644 index 00000000..97ed76ec --- /dev/null +++ b/lvgl/src/drivers/mod.rs @@ -0,0 +1,2 @@ +pub mod lv_drv_display; +pub mod lv_drv_input; diff --git a/lvgl/src/functions.rs b/lvgl/src/functions.rs index 2fd93123..0c96e040 100644 --- a/lvgl/src/functions.rs +++ b/lvgl/src/functions.rs @@ -17,10 +17,12 @@ type Result = result::Result; /// Register own buffer pub(crate) fn disp_drv_register( disp_drv: &mut DisplayDriver, + drop: Option, ) -> Result { let disp_ptr = unsafe { lvgl_sys::lv_disp_drv_register(&mut disp_drv.disp_drv as *mut _) }; Ok(Display::from_raw( NonNull::new(disp_ptr).ok_or(CoreError::OperationFailed)?, + drop, )) } @@ -28,6 +30,7 @@ pub(crate) fn disp_get_default() -> Result { let disp_ptr = unsafe { lvgl_sys::lv_disp_get_default() }; Ok(Display::from_raw( NonNull::new(disp_ptr).ok_or(CoreError::OperationFailed)?, + None, )) } diff --git a/lvgl/src/input_device/generic.rs b/lvgl/src/input_device/generic.rs index 5a707e87..98f0ca9e 100644 --- a/lvgl/src/input_device/generic.rs +++ b/lvgl/src/input_device/generic.rs @@ -40,5 +40,11 @@ pub trait InputDriver { F: Fn() -> BufferStatus; fn get_driver(&mut self) -> &mut lvgl_sys::lv_indev_drv_t; + + unsafe fn new_raw( + read_cb: Option, + feedback_cb: Option, + ) -> D; + unsafe fn set_descriptor(&mut self, descriptor: *mut lvgl_sys::lv_indev_t) -> LvResult<()>; } diff --git a/lvgl/src/input_device/pointer.rs b/lvgl/src/input_device/pointer.rs index b80cd566..0df936a6 100644 --- a/lvgl/src/input_device/pointer.rs +++ b/lvgl/src/input_device/pointer.rs @@ -52,6 +52,25 @@ impl InputDriver for Pointer { self.driver.as_mut() } + unsafe fn new_raw( + read_cb: Option, + feedback_cb: Option, + ) -> Self { + let driver = unsafe { + let mut indev_drv = MaybeUninit::uninit(); + lvgl_sys::lv_indev_drv_init(indev_drv.as_mut_ptr()); + let mut indev_drv = Box::new(indev_drv.assume_init()); + indev_drv.type_ = lvgl_sys::lv_indev_type_t_LV_INDEV_TYPE_POINTER; + indev_drv.read_cb = read_cb; + indev_drv.feedback_cb = feedback_cb; + indev_drv + }; + Self { + driver, + descriptor: None, + } + } + unsafe fn set_descriptor(&mut self, descriptor: *mut lvgl_sys::lv_indev_t) -> LvResult<()> { if self.descriptor.is_none() { self.descriptor = Some(descriptor); diff --git a/lvgl/src/lib.rs b/lvgl/src/lib.rs index c712edfc..e2d2b174 100644 --- a/lvgl/src/lib.rs +++ b/lvgl/src/lib.rs @@ -57,6 +57,8 @@ mod support; pub mod input_device; pub mod widgets; +#[cfg(feature = "drivers")] +pub mod drivers; struct RunOnce(AtomicBool);