rpk_firmware/
mapper.rs

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; // 8 keys needs one byte
26
27#[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            // run this first because no macros may be present when running memos
347            while !matches!(self.macro_running, Macro::Noop) {
348                self.wait_for_report_capacity().await;
349                self.check_time();
350            }
351
352            // run second
353            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            // now look for events
367            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;