Rust bindings API review #51
26
examples/app.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
use embedded_graphics::pixelcolor::Rgb565;
|
||||||
|
use embedded_graphics::prelude::*;
|
||||||
|
use embedded_graphics_simulator::{OutputSettingsBuilder, SimulatorDisplay, Window};
|
||||||
|
use lvgl;
|
||||||
|
use lvgl::display::{Display, DisplayBuffer, DisplayDriver};
|
||||||
|
|
||||||
|
type ColorSpace = Rgb565;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut embedded_graphics_display: SimulatorDisplay<ColorSpace> = SimulatorDisplay::new(
|
||||||
|
Size::new(lvgl_sys::LV_HOR_RES_MAX, lvgl_sys::LV_VER_RES_MAX),
|
||||||
|
);
|
||||||
|
|
||||||
|
let output_settings = OutputSettingsBuilder::new().scale(2).build();
|
||||||
|
let mut window = Window::new("App Example", &output_settings);
|
||||||
|
|
||||||
|
// LVGL usage
|
||||||
|
lvgl::init();
|
||||||
|
|
||||||
|
let mut display_diver: DisplayDriver<ColorSpace> =
|
||||||
|
DisplayDriver::new(DisplayBuffer::new(), |pixels| {
|
||||||
|
// Here we draw to the external display
|
||||||
|
let _ = embedded_graphics_display.draw_iter(pixels);
|
||||||
|
});
|
||||||
|
let _display = lvgl::disp_drv_register(&mut display_diver).unwrap();
|
||||||
|
}
|
|
@ -114,6 +114,7 @@ fn main() {
|
||||||
let bindings = bindgen::Builder::default()
|
let bindings = bindgen::Builder::default()
|
||||||
.header(shims_dir.join("lvgl_sys.h").to_str().unwrap())
|
.header(shims_dir.join("lvgl_sys.h").to_str().unwrap())
|
||||||
.generate_comments(false)
|
.generate_comments(false)
|
||||||
|
.derive_default(true)
|
||||||
|
|||||||
.layout_tests(false)
|
.layout_tests(false)
|
||||||
.use_core()
|
.use_core()
|
||||||
.rustfmt_bindings(true)
|
.rustfmt_bindings(true)
|
||||||
|
|
|
@ -32,6 +32,11 @@ lvgl-sys = { version = "0.5.2", path = "../lvgl-sys" }
|
||||||
embedded-graphics-simulator = "0.2.1"
|
embedded-graphics-simulator = "0.2.1"
|
||||||
heapless = "0.5.5"
|
heapless = "0.5.5"
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "app"
|
||||||
|
path = "../examples/app.rs"
|
||||||
|
required-features = ["alloc"]
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "demo"
|
name = "demo"
|
||||||
path = "../examples/demo.rs"
|
path = "../examples/demo.rs"
|
||||||
|
|
150
lvgl/src/display.rs
Normal file
|
@ -0,0 +1,150 @@
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
use crate::{Color, LvError, LvResult, Obj};
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
use core::marker::PhantomData;
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
use core::mem::{ManuallyDrop, MaybeUninit};
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
use core::ptr;
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
use core::ptr::NonNull;
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
use embedded_graphics::drawable;
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
use embedded_graphics::prelude::*;
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
// TODO: Make this an external configuration
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
const REFRESH_BUFFER_LEN: usize = 2;
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
// Declare a buffer for the refresh rate
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
pub(crate) const BUF_SIZE: usize = lvgl_sys::LV_HOR_RES_MAX as usize * REFRESH_BUFFER_LEN;
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
pub enum DisplayError {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
FailedToRegister,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
NotRegistered,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
#[derive(Copy, Clone)]
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
pub struct Display {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
disp: NonNull<lvgl_sys::lv_disp_t>,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
impl Display {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
pub(crate) fn from_raw(disp: NonNull<lvgl_sys::lv_disp_t>) -> Self {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
Self { disp }
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
#[derive(Copy, Clone)]
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
pub struct DefaultDisplay {}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
impl DefaultDisplay {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
pub fn get_screen_active() -> Result<Obj, DisplayError> {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
Err(DisplayError::NotRegistered)
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
#[derive(Copy, Clone)]
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
pub struct DisplayBuffer {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
disp_buf: lvgl_sys::lv_disp_buf_t,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
impl DisplayBuffer {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
pub fn new() -> Self {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let disp_buf = unsafe {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let mut disp_buf = MaybeUninit::uninit();
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let mut refresh_buffer = ManuallyDrop::new([lvgl_sys::lv_color_t::default(); BUF_SIZE]);
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
lvgl_sys::lv_disp_buf_init(
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
disp_buf.as_mut_ptr(),
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
refresh_buffer.as_mut_ptr() as *mut cty::c_void,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
ptr::null_mut(),
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
lvgl_sys::LV_HOR_RES_MAX * REFRESH_BUFFER_LEN as u32,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
);
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
disp_buf.assume_init()
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
};
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
Self { disp_buf }
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
#[derive(Copy, Clone)]
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
pub struct DisplayDriver<C>
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
where
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
C: PixelColor + From<Color>,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
{
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
I'm using a Mutex here just to make this I'm using a Mutex here just to make this `Sync`, not sure if there is a way to remove it but still keep the memory statically allocated.
|
|||||||
|
pub(crate) disp_drv: lvgl_sys::lv_disp_drv_t,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
phantom: PhantomData<C>,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
impl<C> DisplayDriver<C>
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
where
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
C: PixelColor + From<Color>,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
{
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
pub fn new<I, F>(display_buffer: DisplayBuffer, callback: F) -> Self
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
where
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
I: IntoIterator<Item = drawable::Pixel<C>>,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
F: FnMut(I) + 'static,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
{
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let mut disp_buf = ManuallyDrop::new(display_buffer.disp_buf);
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let mut callback = ManuallyDrop::new(callback);
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let mut disp_drv = unsafe {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
I would like to find a way to make this memory statically allocated. This seems to be a requirement for LVGL v8. I would like to find a way to make this memory statically allocated. This seems to be [a requirement for LVGL v8](https://docs.lvgl.io/8.0/get-started/quick-overview.html#add-lvgl-into-your-project).
|
|||||||
|
let mut disp_drv = MaybeUninit::uninit();
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
lvgl_sys::lv_disp_drv_init(disp_drv.as_mut_ptr());
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
disp_drv.assume_init()
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
};
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
disp_drv.buffer = &mut *disp_buf as *mut lvgl_sys::lv_disp_buf_t;
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
disp_drv.user_data = &mut callback as *mut _ as lvgl_sys::lv_disp_drv_user_data_t;
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
disp_drv.flush_cb = Some(disp_flush_trampoline::<C, I, F>);
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
Self {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
disp_drv,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
phantom: PhantomData,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
// impl Default for DisplayDriver {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
// fn default() -> Self {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
// Self::new(DisplayBuffer::new())
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
// }
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
// }
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
pub struct DisplayDriverBuilder {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
disp_buf: Option<DisplayBuffer>,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
impl DisplayDriverBuilder {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
pub fn with_callback() {}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
unsafe extern "C" fn disp_flush_trampoline<C, I, F>(
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
disp_drv: *mut lvgl_sys::lv_disp_drv_t,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
area: *const lvgl_sys::lv_area_t,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
color_p: *mut lvgl_sys::lv_color_t,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
) where
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
C: PixelColor + From<Color>,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
I: IntoIterator<Item = drawable::Pixel<C>>,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
F: FnMut(I) + 'static,
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
{
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let display_driver = *disp_drv;
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
if !display_driver.user_data.is_null() {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let callback = &mut *(display_driver.user_data as *mut F);
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let x1 = (*area).x1;
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let x2 = (*area).x2;
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let y1 = (*area).y1;
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let y2 = (*area).y2;
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let ys = y1..=y2;
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let xs = (x1..=x2).enumerate();
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let x_len = (x2 - x1 + 1) as usize;
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
// We use iterators here to ensure that the Rust compiler can apply all possible
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
// optimizations at compile time.
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let pixels = ys
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
.enumerate()
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
.map(|(iy, y)| {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
xs.clone().map(move |(ix, x)| {
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let color_len = x_len * iy + ix;
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let lv_color = unsafe { *color_p.add(color_len) };
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
let raw_color = Color::from_raw(lv_color);
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
drawable::Pixel(Point::new(x as i32, y as i32), raw_color.into())
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
})
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
})
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
.flatten();
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
callback(pixels);
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
|||||||
|
}
|
||||||
TODO: Remove this code duplication. TODO: Remove this code duplication.
I use a I use a `Mutex` here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.
|
16
lvgl/src/functions.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
use crate::display::{Display, DisplayDriver, DisplayError};
|
||||||
|
use crate::Color;
|
||||||
|
use core::ptr::NonNull;
|
||||||
|
use embedded_graphics::drawable;
|
||||||
|
use embedded_graphics::prelude::*;
|
||||||
|
|
||||||
|
pub fn disp_drv_register<C: PixelColor + From<Color>>(
|
||||||
|
disp_drv: &mut DisplayDriver<C>,
|
||||||
|
) -> Result<Display, DisplayError> {
|
||||||
|
let disp_ptr = unsafe {
|
||||||
|
lvgl_sys::lv_disp_drv_register(&mut disp_drv.disp_drv as *mut lvgl_sys::lv_disp_drv_t)
|
||||||
|
};
|
||||||
|
Ok(Display::from_raw(
|
||||||
|
NonNull::new(disp_ptr).ok_or(DisplayError::FailedToRegister)?,
|
||||||
|
))
|
||||||
|
}
|
|
@ -31,6 +31,8 @@ use ::alloc::boxed::Box;
|
||||||
#[cfg(feature = "lvgl_alloc")]
|
#[cfg(feature = "lvgl_alloc")]
|
||||||
mod allocator;
|
mod allocator;
|
||||||
|
|
||||||
|
pub mod display;
|
||||||
|
mod functions;
|
||||||
mod support;
|
mod support;
|
||||||
mod ui;
|
mod ui;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -47,6 +49,7 @@ pub(crate) mod mem;
|
||||||
#[cfg(not(feature = "lvgl_alloc"))]
|
#[cfg(not(feature = "lvgl_alloc"))]
|
||||||
use crate::mem::Box;
|
use crate::mem::Box;
|
||||||
|
|
||||||
|
pub use functions::*;
|
||||||
pub use lv_core::*;
|
pub use lv_core::*;
|
||||||
pub use support::*;
|
pub use support::*;
|
||||||
pub use ui::*;
|
pub use ui::*;
|
||||||
|
@ -56,7 +59,7 @@ use core::sync::atomic::{AtomicBool, Ordering};
|
||||||
// Initialize LVGL only once.
|
// Initialize LVGL only once.
|
||||||
static LVGL_INITIALIZED: AtomicBool = AtomicBool::new(false);
|
static LVGL_INITIALIZED: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
pub(crate) fn lvgl_init() {
|
pub fn init() {
|
||||||
if LVGL_INITIALIZED
|
if LVGL_INITIALIZED
|
||||||
.compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
|
.compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
|
||||||
.is_ok()
|
.is_ok()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::Box;
|
use crate::Box;
|
||||||
use crate::{Color, Event, LvError, LvResult, Obj, Widget};
|
use crate::{Color, Event, LvError, LvResult, Obj, Widget};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::mem::MaybeUninit;
|
use core::mem::{ManuallyDrop, MaybeUninit};
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
use core::ptr::NonNull;
|
use core::ptr::NonNull;
|
||||||
use core::sync::atomic::{AtomicBool, Ordering};
|
use core::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
@ -47,7 +47,7 @@ where
|
||||||
.compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
|
.compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
crate::lvgl_init();
|
crate::init();
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
_not_sync: PhantomData,
|
_not_sync: PhantomData,
|
||||||
display_data: None,
|
display_data: None,
|
||||||
|
@ -80,10 +80,13 @@ where
|
||||||
// Basic initialization of the display driver
|
// Basic initialization of the display driver
|
||||||
lvgl_sys::lv_disp_drv_init(disp_drv.as_mut_ptr());
|
lvgl_sys::lv_disp_drv_init(disp_drv.as_mut_ptr());
|
||||||
let mut disp_drv = Box::new(disp_drv.assume_init());
|
let mut disp_drv = Box::new(disp_drv.assume_init());
|
||||||
// Assign the buffer to the display
|
// Assign the buffer to the display, the memory "leaks" here since
|
||||||
|
// the `disp_drv` is dropped in the end of this method. This is not a problem
|
||||||
|
// since this should live for the whole lifetime of the program anyways.
|
||||||
disp_drv.buffer = Box::into_raw(Box::new(disp_buf.assume_init()));
|
disp_drv.buffer = Box::into_raw(Box::new(disp_buf.assume_init()));
|
||||||
// Set your driver function
|
// Set your driver function
|
||||||
disp_drv.flush_cb = Some(display_callback_wrapper::<T, C>);
|
disp_drv.flush_cb = Some(display_callback_wrapper::<T, C>);
|
||||||
|
// The memory of `display_data` is kept because of the reference in `self`
|
||||||
disp_drv.user_data = &mut self.display_data as *mut _ as *mut cty::c_void;
|
disp_drv.user_data = &mut self.display_data as *mut _ as *mut cty::c_void;
|
||||||
// We need to remember to deallocate the `disp_drv` memory when dropping UI
|
// We need to remember to deallocate the `disp_drv` memory when dropping UI
|
||||||
lvgl_sys::lv_disp_drv_register(Box::into_raw(disp_drv));
|
lvgl_sys::lv_disp_drv_register(Box::into_raw(disp_drv));
|
||||||
|
@ -110,7 +113,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn event_send<W>(&mut self, obj: &mut W, event: Event<W::SpecialEvent>) -> LvResult<()>
|
pub fn event_send<W>(&self, obj: &mut W, event: Event<W::SpecialEvent>) -> LvResult<()>
|
||||||
where
|
where
|
||||||
W: Widget,
|
W: Widget,
|
||||||
{
|
{
|
||||||
|
|
Extremely useful feature of
bindgen
. 💅🏽