Rust bindings API review #51
|
@ -3,6 +3,10 @@ use embedded_graphics::prelude::*;
|
||||||
use embedded_graphics_simulator::{OutputSettingsBuilder, SimulatorDisplay, Window};
|
use embedded_graphics_simulator::{OutputSettingsBuilder, SimulatorDisplay, Window};
|
||||||
use lvgl;
|
use lvgl;
|
||||||
use lvgl::display::Display;
|
use lvgl::display::Display;
|
||||||
|
use lvgl::widgets::Label;
|
||||||
|
use parking_lot::Mutex;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
type ColorSpace = Rgb565;
|
type ColorSpace = Rgb565;
|
||||||
|
|
||||||
|
@ -15,7 +19,15 @@ fn main() {
|
||||||
let output_settings = OutputSettingsBuilder::new().scale(2).build();
|
let output_settings = OutputSettingsBuilder::new().scale(2).build();
|
||||||
let mut window = Window::new("App Example", &output_settings);
|
let mut window = Window::new("App Example", &output_settings);
|
||||||
|
|
||||||
|
let mut shared_native_display = Arc::new(Mutex::new(embedded_graphics_display));
|
||||||
|
|
||||||
// LVGL usage
|
// LVGL usage
|
||||||
lvgl::init();
|
lvgl::init();
|
||||||
Display::register(embedded_graphics_display).unwrap();
|
let display = Display::register_shared(&shared_native_display).unwrap();
|
||||||
|
let label = Label::new().unwrap();
|
||||||
|
|
||||||
|
|||||||
|
{
|
||||||
|
let mut val = shared_native_display.lock();
|
||||||
|
val.draw_pixel(Pixel::default()).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,17 @@ use crate::Box;
|
||||||
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::{disp_drv_register, disp_get_default, get_str_act};
|
use crate::{disp_drv_register, disp_get_default, get_str_act};
|
||||||
use crate::{Color, Obj};
|
use crate::{Color, Obj};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::mem::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::NonNull;
|
use core::ptr::NonNull;
|
||||||
use core::{ptr, result};
|
use core::{ptr, result};
|
||||||
use embedded_graphics::drawable;
|
use embedded_graphics::drawable;
|
||||||
use embedded_graphics::prelude::*;
|
use embedded_graphics::prelude::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
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 parking_lot::Mutex;
|
||||||
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.
|
|||||||
|
#[cfg(feature = "alloc")]
|
||||||
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 alloc::sync::Arc;
|
||||||
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: Make this an external configuration
|
||||||
const REFRESH_BUFFER_LEN: usize = 2;
|
const REFRESH_BUFFER_LEN: usize = 2;
|
||||||
// Declare a buffer for the refresh rate
|
// Declare a buffer for the refresh rate
|
||||||
|
@ -23,7 +28,9 @@ 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.
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.
|
|||||||
|
|
||||||
type Result<T> = result::Result<T, DisplayError>;
|
type Result<T> = result::Result<T, DisplayError>;
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[cfg(feature = "alloc")]
|
||||||
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 type SharedNativeDisplay<T> = Arc<Mutex<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.
|
|||||||
pub struct Display {
|
pub struct Display {
|
||||||
pub(crate) disp: NonNull<lvgl_sys::lv_disp_t>,
|
pub(crate) disp: NonNull<lvgl_sys::lv_disp_t>,
|
||||||
}
|
}
|
||||||
|
@ -33,11 +40,23 @@ 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.
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 }
|
Self { disp }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register<C>(embedded_graphics_display: impl DrawTarget<C>) -> Result<Self>
|
// pub fn register<T, C>(native_display: T) -> Result<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.
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.
|
|||||||
|
// T: DrawTarget<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.
|
|||||||
|
// 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.
|
|||||||
|
// let mut display_diver = DisplayDriver::new(DisplayBuffer::new(), native_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.
|
|||||||
|
// Ok(disp_drv_register(&mut display_diver)?)
|
||||||
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.
|
|||||||
|
#[cfg(feature = "alloc")]
|
||||||
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 register_shared<T, C>(shared_native_display: &SharedNativeDisplay<T>) -> Result<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
|
where
|
||||||
|
T: DrawTarget<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.
|
|||||||
C: PixelColor + From<Color>,
|
C: PixelColor + From<Color>,
|
||||||
{
|
{
|
||||||
let mut display_diver = DisplayDriver::new(DisplayBuffer::new(), embedded_graphics_display);
|
let mut display_diver =
|
||||||
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.
|
|||||||
|
DisplayDriver::new_shared(DisplayBuffer::new(), Arc::clone(shared_native_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.
|
|||||||
Ok(disp_drv_register(&mut display_diver)?)
|
Ok(disp_drv_register(&mut display_diver)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,37 +81,36 @@ 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.
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).
|
|||||||
#[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 {
|
pub struct DisplayBuffer {
|
||||||
disp_buf: lvgl_sys::lv_disp_buf_t,
|
disp_buf: Box<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.
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DisplayBuffer {
|
impl DisplayBuffer {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let disp_buf = unsafe {
|
let 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.
|
|||||||
let mut disp_buf = MaybeUninit::uninit();
|
let mut disp_buf = Box::new(lvgl_sys::lv_disp_buf_t::default());
|
||||||
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 refresh_buffer = Box::new([lvgl_sys::lv_color_t::default(); BUF_SIZE]);
|
let refresh_buffer = Box::new([lvgl_sys::lv_color_t::default(); BUF_SIZE]);
|
||||||
|
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.
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(
|
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.
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(),
|
disp_buf.as_mut() as *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.
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.
|
|||||||
Box::into_raw(refresh_buffer) as *mut cty::c_void,
|
Box::into_raw(refresh_buffer) 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.
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(),
|
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.
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,
|
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.
|
|||||||
);
|
);
|
||||||
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.
|
|||||||
|
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.
|
|||||||
};
|
};
|
||||||
|
|
||||||
Self { disp_buf }
|
Self { disp_buf }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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<T, C>
|
pub struct DisplayDriver<T, C>
|
||||||
where
|
where
|
||||||
T: DrawTarget<C>,
|
T: DrawTarget<C>,
|
||||||
C: PixelColor + From<Color>,
|
C: PixelColor + From<Color>,
|
||||||
{
|
{
|
||||||
pub(crate) disp_drv: lvgl_sys::lv_disp_drv_t,
|
pub(crate) disp_drv: Box<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.
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_display: PhantomData<T>,
|
phantom_display: PhantomData<T>,
|
||||||
phantom_color: PhantomData<C>,
|
phantom_color: PhantomData<C>,
|
||||||
}
|
}
|
||||||
|
@ -102,25 +120,29 @@ 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.
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.
|
|||||||
T: DrawTarget<C>,
|
T: DrawTarget<C>,
|
||||||
C: PixelColor + From<Color>,
|
C: PixelColor + From<Color>,
|
||||||
{
|
{
|
||||||
pub fn new(display_buffer: DisplayBuffer, native_display: T) -> Self {
|
#[cfg(feature = "alloc")]
|
||||||
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_drv = unsafe {
|
pub fn new_shared(
|
||||||
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_drv = MaybeUninit::uninit();
|
display_buffer: 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.
|
|||||||
lvgl_sys::lv_disp_drv_init(disp_drv.as_mut_ptr());
|
shared_native_display: SharedNativeDisplay<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.
|
|||||||
disp_drv.assume_init()
|
) -> 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.
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 = Box::new(lvgl_sys::lv_disp_drv_t::default());
|
||||||
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 {
|
||||||
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() as *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.
|
|||||||
|
}
|
||||||
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 need to add to a `Box`, so it's copied to a memory location in the "heap" (LVGL statically allocated heap).
|
// We need to add to a `Box`, so it's copied to a memory location in the "heap" (LVGL statically allocated heap).
|
||||||
let disp_buf = Box::new(display_buffer.disp_buf);
|
disp_drv.buffer = Box::into_raw(display_buffer.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.
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 = Box::into_raw(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.
|
|||||||
|
|
||||||
let native_display = Box::new(DisplayUserData {
|
let native_display = Box::new(SharedDisplayUserData {
|
||||||
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.
|
|||||||
display: native_display,
|
display: shared_native_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.
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,
|
phantom: PhantomData,
|
||||||
});
|
});
|
||||||
disp_drv.user_data =
|
disp_drv.user_data =
|
||||||
Box::into_raw(native_display) as *mut _ as lvgl_sys::lv_disp_drv_user_data_t;
|
Box::into_raw(native_display) as *mut _ as lvgl_sys::lv_disp_drv_user_data_t;
|
||||||
|
|
||||||
disp_drv.flush_cb = Some(disp_flush_trampoline::<T, C>);
|
// Sets trampoline pointer to the function implementation using the types (T, C) that
|
||||||
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.
|
|||||||
|
// are used in this instance of `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.
|
|||||||
|
disp_drv.flush_cb = Some(shared_disp_flush_trampoline::<T, 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.
|
|||||||
|
|
||||||
// We do not store any memory that can be accidentally deallocated by on the Rust side.
|
// We do not store any memory that can be accidentally deallocated by on the Rust side.
|
||||||
Self {
|
Self {
|
||||||
|
@ -131,16 +153,18 @@ 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.
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) struct DisplayUserData<T, C>
|
#[cfg(feature = "alloc")]
|
||||||
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(crate) struct SharedDisplayUserData<T, 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
|
where
|
||||||
T: DrawTarget<C>,
|
T: DrawTarget<C>,
|
||||||
C: PixelColor + From<Color>,
|
C: PixelColor + From<Color>,
|
||||||
{
|
{
|
||||||
display: T,
|
display: SharedNativeDisplay<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.
|
|||||||
phantom: PhantomData<C>,
|
phantom: PhantomData<C>,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn disp_flush_trampoline<T, C>(
|
#[cfg(feature = "alloc")]
|
||||||
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 shared_disp_flush_trampoline<T, 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.
|
|||||||
disp_drv: *mut lvgl_sys::lv_disp_drv_t,
|
disp_drv: *mut lvgl_sys::lv_disp_drv_t,
|
||||||
area: *const lvgl_sys::lv_area_t,
|
area: *const lvgl_sys::lv_area_t,
|
||||||
color_p: *mut lvgl_sys::lv_color_t,
|
color_p: *mut lvgl_sys::lv_color_t,
|
||||||
|
@ -150,7 +174,7 @@ unsafe extern "C" fn disp_flush_trampoline<T, 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.
|
|||||||
{
|
{
|
||||||
let display_driver = *disp_drv;
|
let display_driver = *disp_drv;
|
||||||
if !display_driver.user_data.is_null() {
|
if !display_driver.user_data.is_null() {
|
||||||
let user_data = &mut *(display_driver.user_data as *mut DisplayUserData<T, C>);
|
let user_data = &mut *(display_driver.user_data as *mut SharedDisplayUserData<T, 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.
|
|||||||
let x1 = (*area).x1;
|
let x1 = (*area).x1;
|
||||||
let x2 = (*area).x2;
|
let x2 = (*area).x2;
|
||||||
let y1 = (*area).y1;
|
let y1 = (*area).y1;
|
||||||
|
@ -174,7 +198,10 @@ unsafe extern "C" fn disp_flush_trampoline<T, 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.
|
|||||||
})
|
})
|
||||||
.flatten();
|
.flatten();
|
||||||
|
|
||||||
let _ = user_data.display.draw_iter(pixels);
|
let _ = user_data
|
||||||
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.
|
|||||||
|
.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.
|
|||||||
|
.try_lock()
|
||||||
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(move |mut display| display.draw_iter(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,9 +16,7 @@ type Result<T> = result::Result<T, CoreError>;
|
||||||
pub fn disp_drv_register<C: PixelColor + From<Color>, T: DrawTarget<C>>(
|
pub fn disp_drv_register<C: PixelColor + From<Color>, T: DrawTarget<C>>(
|
||||||
disp_drv: &mut DisplayDriver<T, C>,
|
disp_drv: &mut DisplayDriver<T, C>,
|
||||||
) -> Result<Display> {
|
) -> Result<Display> {
|
||||||
let disp_ptr = unsafe {
|
let disp_ptr = unsafe { lvgl_sys::lv_disp_drv_register(disp_drv.disp_drv.as_mut() as *mut _) };
|
||||||
lvgl_sys::lv_disp_drv_register(&mut disp_drv.disp_drv as *mut lvgl_sys::lv_disp_drv_t)
|
|
||||||
};
|
|
||||||
Ok(Display::from_raw(
|
Ok(Display::from_raw(
|
||||||
NonNull::new(disp_ptr).ok_or(CoreError::OperationFailed)?,
|
NonNull::new(disp_ptr).ok_or(CoreError::OperationFailed)?,
|
||||||
))
|
))
|
||||||
|
|
Making this statically allocated will avoid dropping this memory address by mistake in an app code.