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"));