1use heapless::Vec;
2use usbd_hid::descriptor::{KeyboardReport, MediaKeyboardReport, MouseReport};
3
4use crate::interface::state::{
5 KeymapInfo,
6 input_event::InputEvent,
7 output_event::{EventType, OutputEvent},
8};
9
10#[derive(Debug, PartialEq, Clone)]
11pub struct Report {
12 pub keyboard_report: Option<KeyboardReport>,
13 pub mouse_report: Option<MouseReport>,
14 pub media_keyboard_report: Option<MediaKeyboardReport>,
15 pub highest_layer: u8,
16}
17
18pub struct HidReportState<
19 const LAYER: usize,
20 const ROW: usize,
21 const COL: usize,
22 const ENCODER_COUNT: usize,
23 const NORMAL_MAX_PRESSED_KEYS: usize,
24 const ONESHOT_STATE_SIZE: usize,
25 const TAP_DANCE_MAX_DEFINITIONS: usize,
26 const TAP_DANCE_MAX_REPEATS: usize,
27 const COMBO_KEY_MAX_DEFINITIONS: usize,
28 const COMBO_KEY_MAX_SOURCES: usize,
29> {
30 state: super::State<
31 LAYER,
32 ROW,
33 COL,
34 ENCODER_COUNT,
35 NORMAL_MAX_PRESSED_KEYS,
36 ONESHOT_STATE_SIZE,
37 TAP_DANCE_MAX_DEFINITIONS,
38 TAP_DANCE_MAX_REPEATS,
39 COMBO_KEY_MAX_DEFINITIONS,
40 COMBO_KEY_MAX_SOURCES,
41 >,
42 next_send_keyboard_report: bool,
43 next_send_mkb_report: bool,
44}
45
46impl<
47 const LAYER: usize,
48 const ROW: usize,
49 const COL: usize,
50 const ENCODER_COUNT: usize,
51 const NORMAL_MAX_PRESSED_KEYS: usize,
52 const ONESHOT_STATE_SIZE: usize,
53 const TAP_DANCE_MAX_DEFINITIONS: usize,
54 const TAP_DANCE_MAX_REPEATS: usize,
55 const COMBO_KEY_MAX_DEFINITIONS: usize,
56 const COMBO_KEY_MAX_SOURCES: usize,
57>
58 HidReportState<
59 LAYER,
60 ROW,
61 COL,
62 ENCODER_COUNT,
63 NORMAL_MAX_PRESSED_KEYS,
64 ONESHOT_STATE_SIZE,
65 TAP_DANCE_MAX_DEFINITIONS,
66 TAP_DANCE_MAX_REPEATS,
67 COMBO_KEY_MAX_DEFINITIONS,
68 COMBO_KEY_MAX_SOURCES,
69 >
70{
71 pub fn new(
72 keymap: crate::keymap::Keymap<
73 LAYER,
74 ROW,
75 COL,
76 ENCODER_COUNT,
77 TAP_DANCE_MAX_DEFINITIONS,
78 TAP_DANCE_MAX_REPEATS,
79 COMBO_KEY_MAX_DEFINITIONS,
80 COMBO_KEY_MAX_SOURCES,
81 >,
82 config: crate::interface::state::config::StateConfig,
83 ) -> Self {
84 Self {
85 state: super::State::new(keymap, config),
86 next_send_keyboard_report: false,
87 next_send_mkb_report: false,
88 }
89 }
90
91 pub fn update(&mut self, event: InputEvent, since_last_update: core::time::Duration) -> Report {
92 self.update_with_cb(event, since_last_update, |_| {})
93 }
94
95 pub fn update_with_cb(
96 &mut self,
97 event: InputEvent,
98 since_last_update: core::time::Duration,
99 mut cb: impl FnMut(OutputEvent),
100 ) -> Report {
101 let mut keyboard_change = self.next_send_keyboard_report;
102 self.next_send_keyboard_report = false;
103 let mut keys: Vec<u8, 6> = Vec::new();
104 let mut modifier = 0u8;
105
106 let mut mouse_change = false;
107 let mut movement = (0, 0);
108 let mut scroll = (0, 0);
109 let mut mouse_buttons = 0u8;
110
111 let mut media_keyboard_change = self.next_send_mkb_report;
112 let mut media_keys = 0u16;
113
114 self.state.update(event, since_last_update, |ev| {
115 match ev {
116 OutputEvent::Key((key, ev)) => {
117 if ev != EventType::Pressing {
118 keyboard_change = true;
119 }
120 if ev != EventType::Released && !keys.contains(&(key as u8)) {
121 let _ = keys.push(key as u8);
122 }
123 if ev == EventType::Released && keys.contains(&(key as u8)) {
126 self.next_send_keyboard_report = true;
127 }
128 }
129 OutputEvent::MediaKey((m, ev)) => {
130 if ev != EventType::Pressing {
131 media_keyboard_change = true;
132 }
133 if ev != EventType::Released {
134 media_keys = m as u16;
135 }
136 if ev == EventType::Released && media_keys == m as u16 {
137 self.next_send_mkb_report = true;
138 }
139 }
140 OutputEvent::Modifier((m, ev)) => {
141 if ev != EventType::Pressing {
142 keyboard_change = true;
143 }
144 if ev != EventType::Released {
145 modifier |= m as u8;
146 }
147 }
148 OutputEvent::MouseButton((m, ev)) => {
149 if ev != EventType::Pressing {
150 mouse_change = true;
151 }
152 if ev != EventType::Released {
153 mouse_buttons |= m as u8;
154 }
155 }
156 OutputEvent::MouseMove(m) => {
157 mouse_change = true;
158 movement.0 += m.0;
159 movement.1 += m.1;
160 }
161 OutputEvent::MouseScroll((pan, wheel)) => {
162 mouse_change = true;
163 scroll.0 += pan;
164 scroll.1 += wheel;
165 }
166 _ => {}
167 }
168 cb(ev);
169 });
170
171 Report {
172 keyboard_report: if keyboard_change {
173 keys.resize_default(6).unwrap();
174 let keycodes = keys.into_array().unwrap();
175 Some(KeyboardReport {
176 keycodes,
177 modifier,
178 leds: 0,
179 reserved: 0,
180 })
181 } else {
182 None
183 },
184 mouse_report: if mouse_change {
185 Some(MouseReport {
186 buttons: mouse_buttons,
187 x: movement.0,
188 y: movement.1,
189 pan: scroll.0,
190 wheel: scroll.1,
191 })
192 } else {
193 None
194 },
195 media_keyboard_report: if media_keyboard_change {
196 Some(MediaKeyboardReport {
197 usage_id: media_keys,
198 })
199 } else {
200 None
201 },
202 highest_layer: self.state.shared.highest_layer() as u8,
203 }
204 }
205
206 pub fn inner(
207 &self,
208 ) -> &super::State<
209 LAYER,
210 ROW,
211 COL,
212 ENCODER_COUNT,
213 NORMAL_MAX_PRESSED_KEYS,
214 ONESHOT_STATE_SIZE,
215 TAP_DANCE_MAX_DEFINITIONS,
216 TAP_DANCE_MAX_REPEATS,
217 COMBO_KEY_MAX_DEFINITIONS,
218 COMBO_KEY_MAX_SOURCES,
219 > {
220 &self.state
221 }
222
223 pub fn get_keymap_info() -> KeymapInfo {
224 KeymapInfo {
225 layer_count: LAYER as u8,
226 max_tap_dance_key_count: TAP_DANCE_MAX_DEFINITIONS as u8,
227 max_tap_dance_repeat_count: TAP_DANCE_MAX_REPEATS as u8,
228 oneshot_state_size: ONESHOT_STATE_SIZE as u8,
229 }
230 }
231}