Completely unsafe example using SDL2
This commit is contained in:
parent
35dbaaf3e8
commit
df0ff1f8eb
6 changed files with 20601 additions and 8 deletions
|
@ -1,3 +1,7 @@
|
|||
[workspace]
|
||||
members = ["lvgl-sys", "lvgl"]
|
||||
members = [
|
||||
"lvgl-sys",
|
||||
"lvgl",
|
||||
"examples/demo",
|
||||
]
|
||||
|
||||
|
|
11
examples/demo/Cargo.toml
Normal file
11
examples/demo/Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "demo"
|
||||
version = "0.1.0"
|
||||
authors = ["Rafael Caricio <crates@caric.io>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
lvgl-sys = { path = "../../lvgl-sys" }
|
||||
sdl2 = "0.33.0"
|
103
examples/demo/src/main.rs
Normal file
103
examples/demo/src/main.rs
Normal file
|
@ -0,0 +1,103 @@
|
|||
use std::ffi::CString;
|
||||
use std::os::raw::c_void;
|
||||
use std::time::Duration;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
use sdl2::event::Event;
|
||||
use sdl2::keyboard::Keycode;
|
||||
use sdl2::pixels::{Color, PixelFormat, PixelFormatEnum};
|
||||
|
||||
use lvgl_sys;
|
||||
use lvgl_sys::{lv_btn_create, lv_color_t, lv_disp_buf_init, lv_disp_buf_t, lv_disp_drv_init, lv_disp_drv_register, lv_disp_drv_t, lv_disp_get_hor_res, lv_disp_get_scr_act, lv_disp_get_ver_res, lv_label_create, lv_label_set_text, lv_obj_set_pos, lv_obj_set_size, lv_obj_set_x, lv_obj_set_y, lv_obj_t, lv_task_handler, lv_area_t, lv_disp_flush_ready, LV_HOR_RES_MAX, lv_style_t, lv_style_copy, lv_style_btn_rel, LV_BTN_STYLE_PR, LV_BTN_STYLE_REL, lv_slider_set_style};
|
||||
|
||||
fn main() -> Result<(), String> {
|
||||
unsafe {
|
||||
lvgl_sys::lv_init();
|
||||
}
|
||||
|
||||
let sdl_context = sdl2::init()?;
|
||||
let video_subsystem = sdl_context.video()?;
|
||||
|
||||
let hr: u32 = unsafe { lv_disp_get_hor_res(std::ptr::null_mut()) as u32 };
|
||||
let vr: u32 = unsafe { lv_disp_get_ver_res(std::ptr::null_mut()) as u32 };
|
||||
|
||||
let window = video_subsystem.window("TFT Display: Demo", hr, vr)
|
||||
.position_centered()
|
||||
.opengl()
|
||||
.build()
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
let mut canvas = window.into_canvas().build().map_err(|e| e.to_string())?;
|
||||
|
||||
canvas.set_draw_color(Color::RGB(255, 0, 0));
|
||||
canvas.clear();
|
||||
canvas.present();
|
||||
let mut event_pump = sdl_context.event_pump()?;
|
||||
|
||||
// Create a display buffer for LittlevGL
|
||||
let mut disp_buf = MaybeUninit::<lv_disp_buf_t>::uninit();
|
||||
let mut buf: [MaybeUninit<lv_color_t>; LV_HOR_RES_MAX as usize * 10] = unsafe { MaybeUninit::uninit().assume_init() }; /*Declare a buffer for 10 lines*/
|
||||
unsafe {
|
||||
lv_disp_buf_init(disp_buf.as_mut_ptr(), buf.as_mut_ptr() as *mut c_void, std::ptr::null_mut(), (hr * 10) as u32); /*Initialize the display buffer*/
|
||||
}
|
||||
|
||||
// Implement and register a function which can copy a pixel array to an area of your display:
|
||||
unsafe {
|
||||
unsafe extern "C" fn my_disp_flush(disp_drv: *mut lv_disp_drv_t, area: *const lv_area_t, color_p: *mut lv_color_t) {
|
||||
let mut i = 1;
|
||||
for y in (*area).y1..(*area).y2 {
|
||||
for x in (*area).x1..(*area).x2 {
|
||||
// Put a pixel to the display.
|
||||
let raw_color = *color_p.add(i);
|
||||
let color = Color::from((raw_color.ch.red, raw_color.ch.green, raw_color.ch.blue, raw_color.ch.alpha));
|
||||
if raw_color.ch.blue != 255 {
|
||||
println!("{}x{} - {:?}", x, y, color.rgb());
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
lv_disp_flush_ready(disp_drv); /* Indicate you are ready with the flushing*/
|
||||
}
|
||||
|
||||
let mut disp_drv = MaybeUninit::<lv_disp_drv_t>::uninit().assume_init(); /*Descriptor of a display driver*/
|
||||
lv_disp_drv_init(&mut disp_drv); /*Basic initialization*/
|
||||
disp_drv.flush_cb = Some(my_disp_flush); /*Set your driver function*/
|
||||
disp_drv.buffer = disp_buf.as_mut_ptr(); /*Assign the buffer to the display*/
|
||||
lv_disp_drv_register(&mut disp_drv); /*Finally register the driver*/
|
||||
}
|
||||
|
||||
// Create screen and widgets
|
||||
let mut screen = unsafe { lv_disp_get_scr_act(std::ptr::null_mut()) };
|
||||
let mut btn = unsafe { lv_btn_create(screen, std::ptr::null_mut()) };
|
||||
unsafe {
|
||||
lv_obj_set_pos(btn, 10, 10);
|
||||
lv_obj_set_size(btn, 200, 50)
|
||||
}
|
||||
let mut label = unsafe { lv_label_create(btn, std::ptr::null_mut()) };
|
||||
unsafe {
|
||||
lv_label_set_text(label, CString::new("Click me!").unwrap().as_ptr());
|
||||
}
|
||||
|
||||
'running: loop {
|
||||
for event in event_pump.poll_iter() {
|
||||
match event {
|
||||
Event::Quit { .. } | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
|
||||
break 'running;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
canvas.clear();
|
||||
canvas.present();
|
||||
::std::thread::sleep(Duration::from_millis(300));
|
||||
// The rest of the game loop goes here...
|
||||
|
||||
unsafe {
|
||||
lv_task_handler();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -8,6 +8,7 @@ fn main() {
|
|||
.unwrap();
|
||||
let root_dir = project_dir.parent().unwrap();
|
||||
let vendor = root_dir.join("vendor");
|
||||
let lvgl_sys_src = root_dir.join("lvgl-sys").join("src");
|
||||
let src = vendor.join("lvgl").join("src");
|
||||
|
||||
// TODO: Make it configurable! Needs to be linked to final proj defs, define as an env var.
|
||||
|
@ -29,14 +30,13 @@ fn main() {
|
|||
.include(&lvgl_config_path)
|
||||
.compile("lvgl");
|
||||
|
||||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
let cc_args = ["-DLV_CONF_INCLUDE_SIMPLE=1", "-I", lvgl_config_path.to_str().unwrap()];
|
||||
bindgen::Builder::default()
|
||||
.header(src.parent().unwrap().join("lvgl.h").to_str().unwrap())
|
||||
.clang_args(&cc_args)
|
||||
.generate()
|
||||
.expect("Unable to generate bindings")
|
||||
.write_to_file(out_path.join("bindings.rs"))
|
||||
.write_to_file(lvgl_sys_src.join("bindings.rs"))
|
||||
.expect("Can't write bindings!");
|
||||
}
|
||||
|
||||
|
|
20474
lvgl-sys/src/bindings.rs
Normal file
20474
lvgl-sys/src/bindings.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -2,7 +2,8 @@
|
|||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_upper_case_globals)]
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||
pub mod bindings;
|
||||
pub use bindings::*;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
@ -13,11 +14,11 @@ mod tests {
|
|||
unsafe {
|
||||
lv_init();
|
||||
|
||||
let hres = lv_disp_get_hor_res(std::ptr::null_mut());
|
||||
assert_eq!(hres, 480);
|
||||
let horizontal_resolution = lv_disp_get_hor_res(std::ptr::null_mut());
|
||||
assert_eq!(horizontal_resolution, 480);
|
||||
|
||||
let vres = lv_disp_get_ver_res(std::ptr::null_mut());
|
||||
assert_eq!(vres, 320);
|
||||
let vertical_resolution = lv_disp_get_ver_res(std::ptr::null_mut());
|
||||
assert_eq!(vertical_resolution, 320);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue