1use core::{cell::RefCell, cmp::min};
2
3use dual_action::DualActionTimer;
4use embassy_futures::select::{select, Either};
5use embassy_sync::{
6 blocking_mutex::raw::{NoopRawMutex, RawMutex},
7 channel::Channel,
8 signal::Signal,
9};
10use embassy_time::{Instant, Timer};
11use macros::Macro;
12use mouse::Mouse;
13use rpk_common::{globals, keycodes::key_range};
14
15use crate::{
16 firmware_functions,
17 key_scanner::{KeyScannerChannel, ScanKey},
18 layout,
19};
20
21pub mod dual_action;
22pub mod macros;
23pub mod mouse;
24
25pub const MOUSE_KEY_BITS_SIZE: usize = 1; #[derive(Copy, Clone, Debug)]
28#[cfg_attr(feature = "defmt", derive(defmt::Format))]
29pub struct TimedScanKey(pub(crate) ScanKey, pub(crate) u64);
30impl TimedScanKey {
31 pub fn same_key(&self, scan_key: &TimedScanKey) -> bool {
32 self.0.same_key(scan_key.0)
33 }
34
35 pub fn is_none(&self) -> bool {
36 self.0.is_none()
37 }
38
39 fn none() -> Self {
40 Self(ScanKey::none(), 0)
41 }
42
43 fn as_memo(&self) -> [u16; 5] {
44 [
45 self.0.as_memo(),
46 u64tou16(self.1, 48),
47 u64tou16(self.1, 32),
48 u64tou16(self.1, 16),
49 u64tou16(self.1, 0),
50 ]
51 }
52
53 fn from_memo(memo: &[u16]) -> Self {
54 Self(
55 ScanKey::from_memo(memo[0]),
56 memo[1..5]
57 .iter()
58 .map(|i| *i as u64)
59 .reduce(|a, i| (a << 16) + i)
60 .unwrap_or(0),
61 )
62 }
63}
64
65#[inline(always)]
66fn u64tou16(t: u64, shift: usize) -> u16 {
67 ((t >> shift) & 0xffff) as u16
68}
69
70enum Oneshot {
71 None,
72 WaitUp(u16),
73 Ready(u16),
74}
75
76#[derive(Debug, PartialEq)]
77#[cfg_attr(feature = "defmt", derive(defmt::Format))]
78pub enum KeyEvent {
79 Basic(u8, bool),
80 PendingModifiers(u8, bool),
81 Modifiers(u8, bool),
82 Consumer(u16),
83 SysCtl(u16),
84 MouseButton(u8),
85 MouseMove(u8, u8, u8),
86 Pending,
87 Clear,
88 Delay(u16),
89}
90impl KeyEvent {
91 fn consumer(kc: u16, is_down: bool) -> Self {
92 let kc = kc - key_range::CONSUMER_MIN;
93 Self::Consumer(if is_down { kc } else { 0 })
94 }
95
96 fn sys_ctl(kc: u16, is_down: bool) -> Self {
97 let kc = kc - key_range::SYS_CTL_MIN + key_range::SYS_CTL_BASE;
98 Self::SysCtl(if is_down { kc } else { 0 })
99 }
100
101 fn basic(kc8: u8, is_down: bool) -> Self {
102 Self::Basic(kc8, is_down)
103 }
104
105 fn mouse_button(mouse: u8) -> Self {
106 Self::MouseButton(mouse)
107 }
108
109 fn mouse_move(mouse: u8, amount: i8, keys: u8) -> Self {
110 Self::MouseMove(mouse, amount as u8, keys)
111 }
112
113 fn modifiers(modifiers: u8, is_down: bool, pending: bool) -> Self {
114 if pending {
115 Self::PendingModifiers(modifiers, is_down)
116 } else {
117 Self::Modifiers(modifiers, is_down)
118 }
119 }
120}
121
122pub enum ControlMessage {
123 LoadLayout { file_location: u32 },
124 TimerExpired,
125 Exit,
126}
127#[derive(Default)]
128pub struct ControlSignal(Signal<NoopRawMutex, ControlMessage>);
129impl ControlSignal {
130 pub fn load_layout(&self, file_location: u32) {
131 self.0.signal(ControlMessage::LoadLayout { file_location });
132 }
133
134 #[cfg(test)]
135 pub fn try_take(&self) -> Option<ControlMessage> {
136 self.0.try_take()
137 }
138}
139
140pub struct MapperTimer {
141 expires_at: RefCell<Instant>,
142 at_sig: Signal<NoopRawMutex, Instant>,
143 ctl_sig: ControlSignal,
144}
145impl Default for MapperTimer {
146 fn default() -> Self {
147 Self {
148 expires_at: RefCell::new(Instant::MAX),
149 at_sig: Default::default(),
150 ctl_sig: Default::default(),
151 }
152 }
153}
154impl MapperTimer {
155 pub fn shutdown(&self) {
156 self.at_sig.signal(Instant::MIN);
157 }
158 fn at(&self, expires_at: Instant) {
159 self.at_sig.signal(expires_at);
160 }
161
162 async fn wait_control(&self) {
163 self.set_expires_at(self.at_sig.wait().await);
164 }
165
166 pub async fn run(timer: &Self) {
167 loop {
168 match timer.get_expires_at() {
169 Instant::MAX => timer.wait_control().await,
170 Instant::MIN => break,
171 expires_at => {
172 if let Either::First(_) =
173 select(Timer::at(expires_at), timer.wait_control()).await
174 {
175 timer.set_expires_at(Instant::MAX);
176 timer.signal(ControlMessage::TimerExpired);
177 }
178 }
179 }
180 }
181 }
182
183 fn signal(&self, msg: ControlMessage) {
184 self.ctl_sig.0.signal(msg);
185 }
186
187 fn get_expires_at(&self) -> Instant {
188 let guard = self.expires_at.borrow();
189 *guard
190 }
191
192 fn set_expires_at(&self, expires_at: Instant) {
193 let mut guard = self.expires_at.borrow_mut();
194 *guard = expires_at;
195 }
196}
197
198pub struct MapperChannel<M: RawMutex, const N: usize>(Channel<M, KeyEvent, N>, MapperTimer);
199impl<M: RawMutex, const N: usize> Default for MapperChannel<M, N> {
200 fn default() -> Self {
201 Self(Channel::new(), MapperTimer::default())
202 }
203}
204impl<M: RawMutex, const N: usize> MapperChannel<M, N> {
205 pub async fn receive(&self) -> KeyEvent {
206 self.0.receive().await
207 }
208
209 pub fn timer(&self) -> &MapperTimer {
210 &self.1
211 }
212
213 async fn wait_control(&self) -> ControlMessage {
214 self.control().0.wait().await
215 }
216
217 pub(crate) fn control(&self) -> &ControlSignal {
218 &self.1.ctl_sig
219 }
220
221 fn report(&self, message: KeyEvent) {
222 if self.0.try_send(message).is_err() {
223 self.clear_reports();
224 let _ = self.0.try_send(KeyEvent::Clear);
225 }
226 }
227
228 fn clear_reports(&self) {
229 self.0.clear();
230 }
231}
232
233#[derive(Debug, Clone, Copy, PartialEq)]
234#[cfg_attr(feature = "defmt", derive(defmt::Format))]
235pub struct KeyPlusMod(u16, u8);
236impl KeyPlusMod {
237 pub fn new(code: u16, modifiers: u8) -> Self {
238 Self(code, modifiers)
239 }
240
241 fn none() -> Self {
242 Self(0, 0)
243 }
244
245 fn modifiers(&self) -> u8 {
246 self.1
247 }
248}
249
250const MIN_REPORT_BUFFER_SIZE: usize = 4;
251
252const fn assert_sizes<const LAYOUT_MAX: usize, const REPORT_BUFFER_SIZE: usize>() -> bool {
253 assert!(REPORT_BUFFER_SIZE >= MIN_REPORT_BUFFER_SIZE);
254 assert!(LAYOUT_MAX > 64);
255 true
256}
257
258pub struct Mapper<
259 'c,
260 const ROW_COUNT: usize,
261 const COL_COUNT: usize,
262 const LAYOUT_MAX: usize,
263 M: RawMutex,
264 const REPORT_BUFFER_SIZE: usize,
265> {
266 layout: layout::Manager<ROW_COUNT, COL_COUNT, LAYOUT_MAX>,
267 active_actions: [[KeyPlusMod; COL_COUNT]; ROW_COUNT],
268 mouse: mouse::Mouse,
269
270 modifier_count: [i8; 8],
271 report_channel: &'c MapperChannel<M, REPORT_BUFFER_SIZE>,
272 wait_time: u64,
273 oneshot: Oneshot,
274 dual_action: DualActionTimer,
275 last_scan_key: TimedScanKey,
276 macro_running: Macro,
277 memo_count: usize,
278 now: u64,
279}
280impl<
281 'c,
282 const ROW_COUNT: usize,
283 const COL_COUNT: usize,
284 M: RawMutex,
285 const LAYOUT_MAX: usize,
286 const REPORT_BUFFER_SIZE: usize,
287 > Mapper<'c, ROW_COUNT, COL_COUNT, LAYOUT_MAX, M, REPORT_BUFFER_SIZE>
288{
289 const OKAY: bool = assert_sizes::<LAYOUT_MAX, REPORT_BUFFER_SIZE>();
290 pub fn new(report_channel: &'c MapperChannel<M, REPORT_BUFFER_SIZE>) -> Self {
291 assert!(Self::OKAY);
292 Self {
293 layout: layout::Manager::default(),
294 active_actions: [[KeyPlusMod::none(); COL_COUNT]; ROW_COUNT],
295 mouse: Mouse::default(),
296 modifier_count: Default::default(),
297 report_channel,
298 wait_time: u64::MAX,
299 oneshot: Oneshot::None,
300 dual_action: Default::default(),
301 last_scan_key: TimedScanKey::none(),
302 macro_running: Macro::Noop,
303 memo_count: 0,
304 now: 1,
305 }
306 }
307
308 fn clear_all(&mut self) {
309 for r in self.active_actions.iter_mut() {
310 for c in r.iter_mut() {
311 *c = KeyPlusMod::none();
312 }
313 }
314 for m in self.modifier_count.iter_mut() {
315 *m = 0;
316 }
317 self.macro_running = Macro::Noop;
318 self.mouse.clear_all();
319 self.layout.clear_all();
320 self.dual_action = DualActionTimer::NoDual;
321 self.report_channel.clear_reports();
322 self.report_channel.report(KeyEvent::Clear);
323 }
324
325 fn clear_layers(&mut self) {
326 for m in self.modifier_count.iter_mut() {
327 *m = 0;
328 }
329 self.layout.clear_layers();
330 self.report_channel.report(KeyEvent::Modifiers(0, false));
331 }
332
333 fn stop_active(&mut self) {
334 for m in self.modifier_count.iter_mut() {
335 *m = 0;
336 }
337 self.layout.clear_modifier_layers();
338 self.report_channel.report(KeyEvent::Clear);
339 }
340
341 pub async fn run<const SCANNER_BUFFER_SIZE: usize>(
342 &mut self,
343 key_scan_channel: &'c KeyScannerChannel<M, SCANNER_BUFFER_SIZE>,
344 ) -> ControlMessage {
345 'outer: loop {
346 while !matches!(self.macro_running, Macro::Noop) {
348 self.wait_for_report_capacity().await;
349 self.check_time();
350 }
351
352 self.wait_for_report_capacity().await;
354 if self.run_memo() {
355 continue 'outer;
356 }
357
358 let event = select(
359 key_scan_channel.receive(),
360 self.report_channel.wait_control(),
361 )
362 .await;
363
364 self.now = Instant::now().as_millis();
365
366 match event {
368 Either::First(scan_key) => self.key_switch(TimedScanKey(scan_key, self.now)),
369 Either::Second(ControlMessage::TimerExpired) => self.check_time(),
370 Either::Second(ControlMessage::Exit) => return ControlMessage::Exit,
371 Either::Second(ctl) => {
372 self.clear_all();
373 return ctl;
374 }
375 }
376 }
377 }
378
379 fn dual_action_expired(&mut self) {
380 self.dual_action.timer_expired();
381 if let DualActionTimer::Hold { scan_key, .. } = &self.dual_action {
382 self.key_switch(*scan_key);
383 }
384 }
385
386 pub fn key_switch(&mut self, k: TimedScanKey) {
387 self.last_scan_key = k;
388 if self.dual_action.key_switch(self.last_scan_key) {
389 self.key_switch_1(k.0);
390 return;
391 }
392
393 match self.dual_action {
394 DualActionTimer::NoDual | DualActionTimer::Wait { .. } => {
395 self.push_scan_key(&k);
396 }
397 DualActionTimer::Hold { scan_key, hold } => {
398 if !scan_key.0.is_same_key(k.0) {
399 self.push_scan_key(&k);
400 }
401 self.dual_action = DualActionTimer::NoDual;
402 self.last_scan_key = scan_key;
403 self.run_action(hold, true);
404 }
405 DualActionTimer::Tap { scan_key, tap } => {
406 if !scan_key.0.is_same_key(k.0) {
407 self.push_scan_key(&k);
408 }
409 self.dual_action = DualActionTimer::NoDual;
410 self.last_scan_key = scan_key;
411 if self.push_action(tap, false) {
412 self.run_action(tap, true);
413 }
414 }
415 }
416 }
417
418 fn key_switch_1(&mut self, k: ScanKey) {
419 if k.is_down() {
420 let Some(kc) = self.layout.find_code(k.row(), k.column()) else {
421 return;
422 };
423 self.activate_action(k.row(), k.column(), kc);
424 let modifiers = kc.modifiers();
425 if modifiers != 0 {
426 self.write_up_modifiers(modifiers, true);
427 }
428 self.run_action(kc.0, true);
429 } else {
430 let kc = self.deactivate_action(k.row(), k.column());
431 let modifiers = kc.modifiers();
432 self.run_action(kc.0, false);
433 if modifiers != 0 {
434 self.write_down_modifiers(modifiers, false);
435 }
436 match self.oneshot {
437 Oneshot::None => {}
438 Oneshot::WaitUp(layern) => self.oneshot = Oneshot::Ready(layern),
439 Oneshot::Ready(layern) => {
440 self.oneshot = Oneshot::None;
441 self.pop_layer(layern);
442 }
443 }
444 };
445 }
446
447 fn run_action(&mut self, mut action: u16, is_down: bool) {
448 let mut modifiers = 0;
449
450 while action != 0 {
451 let mut newkey = KeyPlusMod::none();
452 if is_down && modifiers != 0 {
453 self.write_down_modifiers(modifiers, true);
454 }
455 match action {
456 key_range::MODIFIER_MIN..=key_range::MODIFIER_MAX => {
457 self.modifier(action, is_down);
458 }
459 key_range::BASIC_MIN..=key_range::BASIC_MAX => {
460 self.report_channel
461 .report(KeyEvent::basic(action as u8, is_down));
462 }
463 key_range::MACROS_MIN..=key_range::MACROS_MAX => {
464 newkey = self.macros(action, is_down);
465 }
466 key_range::CONSUMER_MIN..=key_range::CONSUMER_MAX => {
467 self.report_channel
468 .report(KeyEvent::consumer(action, is_down));
469 }
470 key_range::SYS_CTL_MIN..=key_range::SYS_CTL_MAX => {
471 self.report_channel
472 .report(KeyEvent::sys_ctl(action, is_down));
473 }
474 key_range::MOUSE_MIN..=key_range::MOUSE_MAX => self.mouse(action, is_down),
475 key_range::LAYER..=key_range::LAYERS_LAST => self.layer(action, is_down),
476 key_range::FIRMWARE_MIN..=key_range::FIRMWARE_MAX => {
477 self.firmware_action(action, is_down);
478 }
479 _ => {}
480 };
481 if modifiers != 0 && !is_down {
482 self.write_up_modifiers(modifiers, false);
483 }
484
485 action = newkey.0;
486 modifiers = newkey.modifiers();
487 }
488 }
489
490 fn firmware_action(&mut self, action: u16, is_down: bool) {
491 match action {
492 key_range::FW_RESET_KEYBOARD => {
493 if !is_down {
494 firmware_functions::reset();
495 }
496 }
497 key_range::FW_RESET_TO_USB_BOOT => {
498 if !is_down {
499 firmware_functions::reset_to_usb_boot();
500 }
501 }
502 key_range::FW_CLEAR_ALL => {
503 self.clear_all();
504 }
505 key_range::FW_CLEAR_LAYERS => {
506 self.clear_layers();
507 }
508 key_range::FW_STOP_ACTIVE => {
509 self.stop_active();
510 }
511 _ => {
512 crate::info!(
513 "not yet supported: {:?} {:?}",
514 action,
515 key_range::FW_RESET_KEYBOARD
516 );
517 }
518 }
519 }
520
521 pub fn load_layout(
522 &mut self,
523 layout_mapping: impl IntoIterator<Item = u16>,
524 ) -> Result<(), layout::LoadError> {
525 self.layout.load(layout_mapping)?;
526 self.mouse
527 .set_config(self.layout.get_mouse_profile(1).unwrap());
528 Ok(())
529 }
530
531 fn macros(&mut self, code: u16, is_down: bool) -> KeyPlusMod {
532 let id = code - key_range::MACROS_MIN;
533 let mac = self.layout.get_macro(id);
534 match &mac {
535 Macro::Modifier(ref key_plus_mod) => *key_plus_mod,
536 Macro::DualAction(ref tap, ref hold, ref t1, ref t2) => {
537 self.start_dual_action(is_down, *tap, *hold, *t1, *t2);
538 KeyPlusMod::none()
539 }
540 Macro::Noop => KeyPlusMod::none(),
541 Macro::Sequence {
542 mode,
543 location,
544 rem,
545 } => {
546 if *rem > 0 {
547 let run = match mode {
548 macros::SequenceMode::Tap | macros::SequenceMode::Hold => is_down,
549 macros::SequenceMode::Release => !is_down,
550 };
551 if run {
552 self.push_macro(mac);
553 self.next_macro_seq(*location, *rem, *mode);
554 }
555 }
556 KeyPlusMod::none()
557 }
558 Macro::HoldRelease { hold, release } => {
559 self.macros(if is_down { *hold } else { *release }, is_down)
560 }
561 Macro::Delay(n) => {
562 if is_down {
563 self.report_channel.report(KeyEvent::Delay(*n));
564 }
565 KeyPlusMod::none()
566 }
567 }
568 }
569
570 fn push_macro(&mut self, mac: Macro) {
571 let c = self.macro_running;
572 self.layout.update_macro(&c);
573 self.macro_running = self.layout.push_macro(mac);
574 }
575
576 fn pop_macro(&mut self) {
577 self.macro_running = self.layout.pop_macro();
578 self.set_wait_time();
579 }
580
581 fn mouse(&mut self, code: u16, is_down: bool) {
582 let code = code - key_range::MOUSE_MIN;
583 match code {
584 key_range::MOUSE_ACCEL..=key_range::MOUSE_ACCEL_END => {
585 self.mouse.set_config(
586 self.layout
587 .get_mouse_profile((code - key_range::MOUSE_ACCEL) as usize)
588 .unwrap(),
589 );
590 }
591 _ => match self.mouse.action(code, is_down, self.now) {
592 Some(key_event) => self.report_channel.report(key_event),
593 None => self.set_wait_time(),
594 },
595 }
596 }
597
598 fn check_time(&mut self) {
599 if self.wait_time != u64::MAX {
600 match self.macro_running {
601 Macro::Noop => {
602 if self.now >= self.wait_time {
603 if self.now >= self.mouse.next_event_time() {
604 let pending = self.mouse.pending_events(self.now);
605 for event in pending {
606 self.report_channel.report(event);
607 }
608 } else if self.dual_action.wait_until() <= self.now {
609 self.dual_action_expired();
610 }
611 }
612 self.set_wait_time();
613 }
614 Macro::Sequence {
615 mode,
616 location,
617 rem,
618 } => {
619 self.next_macro_seq(location, rem, mode);
620 }
621 _ => {}
622 }
623 }
624 }
625
626 fn next_macro_seq(&mut self, mut location: u32, mut rem: u16, mode: macros::SequenceMode) {
627 let stack = self.layout.macro_stack();
628
629 while self.room_to_report() {
630 let tap = self.layout.macro_code(location as usize);
631
632 if rem > 1 {
633 location += 1;
634 rem -= 1;
635 self.macro_running = Macro::Sequence {
636 mode,
637 location,
638 rem,
639 };
640 } else {
641 self.pop_macro();
642 }
643 match mode {
644 macros::SequenceMode::Hold => {
645 self.run_action(tap, true);
646 }
647 macros::SequenceMode::Release => {
648 self.run_action(tap, false);
649 }
650 macros::SequenceMode::Tap => {
651 self.run_action(tap, true);
652 self.run_action(tap, false);
653 }
654 }
655 if rem == 0 || self.layout.macro_stack() != stack {
656 break;
657 }
658 }
659 self.set_wait_time();
660 }
661
662 fn modifier(&mut self, key: u16, is_down: bool) {
663 let idx = (key - key_range::MODIFIER_MIN) as usize;
664 let layer = match idx {
665 idx if idx < 4 => idx,
666 6 => 4,
667 idx => idx - 4,
668 };
669 if is_down {
670 self.layout.push_layer(layer as u16);
671 self.write_down_modifiers(1 << idx, false);
672 } else {
673 self.layout.pop_layer(layer as u16);
674 self.write_up_modifiers(1 << idx, false);
675 };
676 }
677
678 fn layer(&mut self, key: u16, is_down: bool) {
679 let base = key_range::base_code(key);
680 let layern = key - base;
681 if layern > key_range::MAX_LAYER_N {
682 crate::error!("Layer out of range {}", layern);
683 return;
684 }
685 match base {
686 key_range::LAYER => {
687 if is_down {
688 self.push_layer(layern);
689 } else {
690 self.pop_layer(layern);
691 }
692 }
693 key_range::TOGGLE => {
694 if is_down && !self.pop_layer(layern) {
695 self.push_layer(layern);
696 }
697 }
698 key_range::SET_LAYOUT => {
699 if is_down {
700 self.set_layout(layern);
701 }
702 }
703 key_range::ONESHOT => {
704 if is_down {
705 self.push_layer(layern);
706 } else {
707 self.oneshot(layern);
708 }
709 }
710 _ => {
711 unimplemented!("unimplemented layer action: {}", base);
712 }
713 }
714 }
715
716 fn oneshot(&mut self, layern: u16) {
717 self.oneshot = Oneshot::WaitUp(layern);
718 }
719
720 fn set_layout(&mut self, layern: u16) {
721 self.layout.set_layout(layern);
722 }
723
724 fn push_layer(&mut self, layern: u16) {
725 if self.layout.push_layer(layern) {
726 self.write_down_modifiers(self.layout.get_layer(layern).unwrap().modifiers(), false);
727 }
728 }
729
730 fn pop_layer(&mut self, layern: u16) -> bool {
731 if self.layout.pop_layer(layern) {
732 self.write_up_modifiers(self.layout.get_layer(layern).unwrap().modifiers(), false);
733 true
734 } else {
735 false
736 }
737 }
738
739 fn activate_action(&mut self, row_idx: usize, column_idx: usize, kc: KeyPlusMod) {
740 self.active_actions[row_idx][column_idx] = kc;
741 }
742
743 fn deactivate_action(&mut self, row_idx: usize, column_idx: usize) -> KeyPlusMod {
744 let ans = self.active_actions[row_idx][column_idx];
745 self.active_actions[row_idx][column_idx] = KeyPlusMod::none();
746 ans
747 }
748
749 fn write_up_modifiers(&mut self, modifiers: u8, pending: bool) {
750 let mut changed = 0;
751 let mut bits = modifiers;
752 for i in 0..8 {
753 if bits & 1 == 1 {
754 self.modifier_count[i] -= 1;
755 if self.modifier_count[i] == 0 {
756 changed += 1;
757 }
758 }
759 bits >>= 1;
760 if bits == 0 {
761 if changed != 0 {
762 if changed == 1 && !pending {
763 self.report_channel.report(KeyEvent::basic(
764 key_range::MODIFIER_MIN as u8 + i as u8,
765 false,
766 ));
767 } else {
768 self.report_channel
769 .report(KeyEvent::modifiers(modifiers, false, pending));
770 }
771 }
772 return;
773 }
774 }
775 }
776
777 fn write_down_modifiers(&mut self, modifiers: u8, pending: bool) {
778 let mut changed = 0;
779 let mut bits = modifiers;
780 for i in 0..8 {
781 if bits & 1 == 1 {
782 self.modifier_count[i] += 1;
783 if self.modifier_count[i] == 1 {
784 changed += 1;
785 }
786 }
787 bits >>= 1;
788 if bits == 0 {
789 if changed != 0 {
790 if changed == 1 && !pending {
791 self.report_channel.report(KeyEvent::basic(
792 key_range::MODIFIER_MIN as u8 + i as u8,
793 true,
794 ));
795 } else {
796 self.report_channel
797 .report(KeyEvent::modifiers(modifiers, true, pending));
798 }
799 }
800 return;
801 }
802 }
803 }
804
805 fn set_wait_time(&mut self) {
806 let mut t = min(self.mouse.next_event_time(), self.dual_action.wait_until());
807 if self.macro_running != Macro::Noop {
808 t = min(t, self.now);
809 }
810
811 if t != self.wait_time {
812 self.wait_time = t;
813 self.report_channel.timer().at(if t == u64::MAX {
814 Instant::MAX
815 } else {
816 Instant::from_millis(t)
817 });
818 } else if t != u64::MAX {
819 self.report_channel.timer().at(Instant::from_millis(t));
820 }
821 }
822
823 fn room_to_report(&self) -> bool {
824 self.report_channel.0.free_capacity() >= MIN_REPORT_BUFFER_SIZE
825 }
826
827 async fn wait_for_report_capacity(&self) {
828 for _ in 0..10 {
829 if self.room_to_report() {
830 break;
831 }
832 Timer::after_millis(16).await;
833 }
834 }
835
836 fn start_dual_action(&mut self, is_down: bool, tap: u16, hold: u16, time1: u16, time2: u16) {
837 if is_down {
838 if let DualActionTimer::Wait { hold, .. } = self.dual_action {
839 self.run_action(hold, true);
840 self.dual_action = DualActionTimer::NoDual;
841 }
842 let (time1, time2) = if time1 == u16::MAX {
843 (
844 self.layout.global(globals::DUAL_ACTION_TIMEOUT as usize),
845 self.layout.global(globals::DUAL_ACTION_TIMEOUT2 as usize),
846 )
847 } else if time2 == u16::MAX {
848 (
849 time1,
850 self.layout.global(globals::DUAL_ACTION_TIMEOUT2 as usize),
851 )
852 } else {
853 (time1, time2)
854 };
855
856 self.dual_action
857 .start(self.last_scan_key, tap, hold, time1, time2);
858 } else {
859 self.run_action(hold, false);
860 }
861 self.set_wait_time();
862 }
863
864 fn push_scan_key(&mut self, p2key: &TimedScanKey) -> bool {
865 let memo = p2key.as_memo();
866 if !self.layout.push_memo(&memo) {
867 self.clear_all();
868 false
869 } else {
870 self.memo_count += 1;
871 true
872 }
873 }
874
875 fn push_action(&mut self, tap: u16, is_down: bool) -> bool {
876 if !self.layout.push_memo(&[tap, if is_down { 1 } else { 0 }]) {
877 self.clear_all();
878 false
879 } else {
880 self.memo_count += 1;
881 true
882 }
883 }
884
885 fn run_memo(&mut self) -> bool {
886 if self.dual_action.is_no_timer() && self.memo_count != 0 {
887 self.memo_count -= 1;
888 let mut scan_key = None;
889 let mut action = None;
890 self.layout.pop_memo(|memo| match memo.len() {
891 2 => {
892 action = Some((memo[0], memo[1] != 0));
893 }
894 5 => {
895 scan_key = Some(TimedScanKey::from_memo(memo));
896 }
897 n => {
898 unreachable!("len {n}")
899 }
900 });
901 if let Some(scan_key) = scan_key {
902 self.key_switch(scan_key);
903 } else if let Some((action, is_down)) = action {
904 self.run_action(action, is_down);
905 }
906 true
907 } else {
908 false
909 }
910 }
911}
912
913#[cfg(test)]
914#[path = "mapper_test.rs"]
915mod test;