Skip to main content

keyberon_smart_keyboard/input/
smart_keymap.rs

1/// Callbacks for the keymap.
2pub struct KeymapCallbacks {
3    /// Callback for resetting keyboard state.
4    pub reset: Option<fn() -> ()>,
5    /// Callback for entering the bootloader.
6    pub reset_to_bootloader: Option<fn() -> ()>,
7}
8
9/// The keyboard "backend", manages the keyboard from the events received
10/// (presses/releases of coordinates on a keyboard layout).
11/// through to listing HID scancodes to report using HIDs.
12#[derive(Debug)]
13pub struct KeyboardBackend {
14    keymap: smart_keymap::Keymap,
15    keymap_output: smart_keymap::keymap::KeymapOutput,
16}
17
18impl Default for KeyboardBackend {
19    fn default() -> Self {
20        Self::new()
21    }
22}
23
24impl KeyboardBackend {
25    /// Constructs a new keyboard backend.
26    pub fn new() -> Self {
27        Self::new_with_keymap(smart_keymap::new_keymap())
28    }
29
30    /// Constructs a new keyboard backend with the given keymap.
31    pub fn new_with_keymap(keymap: smart_keymap::Keymap) -> Self {
32        Self {
33            keymap,
34            keymap_output: smart_keymap::keymap::KeymapOutput::default(),
35        }
36    }
37
38    /// Set the keymap callbacks.
39    pub fn set_callbacks(&mut self, callbacks: KeymapCallbacks) {
40        use smart_keymap::keymap::KeymapCallback;
41        if let Some(callback_fn) = callbacks.reset {
42            self.keymap.set_callback(KeymapCallback::Reset, callback_fn);
43        }
44        if let Some(callback_fn) = callbacks.reset_to_bootloader {
45            self.keymap
46                .set_callback(KeymapCallback::ResetToBootloader, callback_fn);
47        }
48    }
49
50    /// Register a key event.
51    pub fn event(&mut self, event: smart_keymap::input::Event) {
52        self.keymap.handle_input(event);
53    }
54
55    /// A time event.
56    ///
57    /// This method must be called regularly, typically every millisecond.
58    ///
59    /// Returns true if the pressed_key_codes have changed.
60    pub fn tick(&mut self) -> bool {
61        self.keymap.tick();
62
63        let keymap_output = self.keymap.report_output();
64
65        let old_keymap_output = core::mem::replace(&mut self.keymap_output, keymap_output);
66
67        old_keymap_output != self.keymap_output
68    }
69
70    pub fn keymap_output(&self) -> &smart_keymap::keymap::KeymapOutput {
71        &self.keymap_output
72    }
73}
74
75/// Constructs a [smart_keymap::input::Event] from a [keyberon::layout::Event],
76///  using a map from row, column to (maybe) keymap index.
77pub fn keymap_index_of<const COLS: usize, const ROWS: usize>(
78    indices: &[[Option<u16>; COLS]; ROWS],
79    ev: keyberon::layout::Event,
80) -> Option<smart_keymap::input::Event> {
81    match ev {
82        keyberon::layout::Event::Press(r, c) => indices[r as usize][c as usize]
83            .map(|keymap_index| smart_keymap::input::Event::Press { keymap_index }),
84        keyberon::layout::Event::Release(r, c) => indices[r as usize][c as usize]
85            .map(|keymap_index| smart_keymap::input::Event::Release { keymap_index }),
86    }
87}