smart_keymap/
lib.rs

1#![warn(missing_docs)]
2
3//! Smart Keymap library.
4//!
5//! A "smart keyboard" is a keyboard where the keys can perform
6//!  multiple actions, depending on the context.
7//! Features such as layering, tap-hold, and tap-dance are
8//!  examples of smart keyboard functionality.
9//!
10//! The smart keymap library provides an interface for the "smart keymap"
11//!  part of smart keyboard firmware.
12//! i.e. the part that takes key presses and releases as input,
13//!  and outputs HID keyboard reports (or other smart keyboard outputs).
14//!
15//! This crate can be used directly with Rust, or built as a C library.
16//!
17//! # Usage as a C library
18//!
19//! ## Custom Keymap
20//!
21//! When used as a C library, the library should be built by setting
22//!  the environment variable `SMART_KEYMAP_CUSTOM_KEYMAP` to the path
23//!  of a custom keymap file.
24//!
25//! `SMART_KEYMAP_CUSTOM_KEYMAP` can be set either to a `.ncl` file,
26//!  or to a `.rs` file (generated using the scripts under `ncl/`).
27//!
28//! ## Keyboard Firmware Implementation
29//!
30//! When used as a C library, the firmware should call to
31//!  `keymap_init`, `keymap_register_input_keypress`, `keymap_register_input_keyrelease`,
32//!  and `keymap_tick` functions.
33//! The `keymap_tick` function should be called every ms, and should copy the
34//!  HID keyboard report to the given buffer.
35//!
36//! # Implementation Overview
37//!
38//! The heart of the library is the [key] module, and its
39//! [key::Key], [key::Context], [key::KeyState] traits.
40//!
41//! These provide the interface with which 'smart keys' are implemented.
42
43#![cfg_attr(not(feature = "std"), no_std)]
44
45/// Structs for input to the keymap.
46pub mod input;
47/// Smart key interface and implementations.
48///
49/// The core interface for the smart keymap library is [key::Key],
50///  and its associated [key::Context], `PendingKeyState`, and [key::KeyState] types.
51/// Together, these are used to define smart key behaviour.
52pub mod key;
53/// Keymap implementation.
54pub mod keymap;
55/// Keys1, Keys2, etc. tuple structs for defining keymaps.
56pub mod tuples;
57
58/// Split keyboard support.
59pub mod split;
60
61/// A helper value type for Copy-able slices.
62pub mod slice;
63
64/// Types and initial data used for constructing a [keymap::Keymap].
65/// cbindgen:ignore
66#[cfg(not(custom_keymap))]
67pub mod init {
68    use crate::key::{composite, keyboard};
69    use crate::keymap;
70    use crate::tuples::Keys1;
71
72    /// Config used to construct initial context.
73    pub const CONFIG: crate::key::composite::Config = crate::key::composite::DEFAULT_CONFIG;
74
75    /// Number of layers supported by the [crate::key::layered] implementation.
76    pub const LAYER_COUNT: usize = 8;
77
78    /// The maximum number of keys in a chord.
79    pub const MAX_CHORD_SIZE: usize = 16;
80
81    /// The maximum number of chords.
82    pub const MAX_CHORDS: usize = 4;
83
84    /// The maximum number of overlapping chords for a chorded key.
85    pub const MAX_OVERLAPPING_CHORD_SIZE: usize = 16;
86
87    /// The tap-dance definitions.
88    pub const MAX_TAP_DANCE_DEFINITIONS: usize = 3;
89
90    pub use composite::Context;
91
92    pub use composite::Event;
93
94    pub use composite::PendingKeyState;
95
96    pub use composite::KeyState;
97
98    pub use composite::Key;
99
100    /// Initial [Context] value.
101    pub const CONTEXT: Context = composite::Context::from_config(CONFIG);
102
103    /// Alias for a tuples KeysN type. Without a custom keymap, just a single [composite::Key].
104    pub type KeyDefinitionsType = Keys1<Key, Context, Event, PendingKeyState, KeyState>;
105
106    /// Alias for the [keymap::Keymap] type.
107    pub type Keymap = keymap::Keymap<Context, Event, PendingKeyState, KeyState, KeyDefinitionsType>;
108
109    /// A tuples KeysN value with keys. Without a custom keymap, just the letter 'A'.
110    pub const KEY_DEFINITIONS: KeyDefinitionsType =
111        Keys1::new((Key::keyboard(keyboard::Key::new(0x04)),));
112}
113
114#[cfg(custom_keymap)]
115include!(concat!(env!("OUT_DIR"), "/keymap.rs"));