graphics/input/
input.rs

1use alloc::boxed::Box;
2use file_system::DirectCharacterDevice;
3
4use core::ffi::c_void;
5
6use crate::{Result, lvgl};
7
8use super::{InputKind, UserData, binding_callback_function};
9
10pub struct Input {
11    #[allow(dead_code)]
12    input_device: *mut lvgl::lv_indev_t,
13}
14
15impl Drop for Input {
16    fn drop(&mut self) {
17        unsafe {
18            let _ = Box::from_raw(lvgl::lv_indev_get_user_data(self.input_device) as *mut UserData);
19
20            lvgl::lv_indev_delete(self.input_device);
21
22            // User_data will be dropped here.
23        }
24    }
25}
26
27unsafe impl Send for Input {}
28
29unsafe impl Sync for Input {}
30
31impl Input {
32    pub fn new(device: &'static dyn DirectCharacterDevice, kind: InputKind) -> Result<Self> {
33        // User_data is a pinned box, so it's ownership can be transferred to LVGL and will not move or dropper until the Input_device is dropped.
34        let user_data = Box::new(UserData { device });
35
36        let input_device = unsafe {
37            let input_device = lvgl::lv_indev_create();
38            lvgl::lv_indev_set_type(input_device, kind.into());
39            lvgl::lv_indev_set_read_cb(input_device, Some(binding_callback_function));
40            lvgl::lv_indev_set_user_data(input_device, Box::into_raw(user_data) as *mut c_void);
41
42            if kind == InputKind::Keypad {
43                let group = lvgl::lv_group_get_default();
44
45                lvgl::lv_indev_set_group(input_device, group);
46            }
47
48            input_device
49        };
50
51        Ok(Self { input_device })
52    }
53}