hidg_core/
keyboard.rs

1use bitflags::bitflags;
2use core::mem::{size_of, transmute};
3use static_assertions::const_assert_eq;
4
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7
8use crate::{Class, StateChange};
9
10/// Keyboard HID class
11#[derive(Clone, Copy, Debug)]
12pub struct Keyboard;
13
14impl Class for Keyboard {
15    type Input = KeyboardInput;
16    type Output = KeyboardOutput;
17
18    fn input(&self) -> Self::Input {
19        Self::Input::default()
20    }
21
22    fn output(&self) -> Self::Output {
23        Self::Output::default()
24    }
25}
26
27impl AsRef<str> for Keyboard {
28    fn as_ref(&self) -> &str {
29        "keyboard"
30    }
31}
32
33impl core::fmt::Display for Keyboard {
34    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
35        f.write_str(self.as_ref())
36    }
37}
38
39bitflags! {
40    /// Modifier mask
41    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
42    pub struct Modifiers: u8 {
43        /// Left Control
44        const LeftCtrl = 0x01;
45        /// Left Shift
46        const LeftShift = 0x02;
47        /// Left Alt
48        const LeftAlt = 0x04;
49        /// Left Meta
50        const LeftMeta = 0x08;
51        /// Right Control
52        const RightCtrl = 0x10;
53        /// Right Shift
54        const RightShift = 0x20;
55        /// Right Alt
56        const RightAlt = 0x40;
57        /// Right Meta
58        const RightMeta = 0x80;
59    }
60}
61
62const_assert_eq!(size_of::<Modifiers>(), 1);
63
64impl Default for Modifiers {
65    fn default() -> Self {
66        Self::empty()
67    }
68}
69
70impl Modifiers {
71    /// Converts from raw value safely
72    pub fn safe_from(raw: u8) -> Option<Self> {
73        Self::from_bits(raw)
74    }
75}
76
77impl From<Modifiers> for u8 {
78    fn from(mods: Modifiers) -> Self {
79        mods.bits()
80    }
81}
82
83code_enum! {
84    /// Key code
85    Key: u8 {
86        /// No key
87        None = 0x00 => "none",
88
89        /// Keyboard Error Roll Over - used for all slots if too many keys are pressed ("Phantom key")
90        Overflow = 0x01 => "overflow",
91        /// Keyboard POST Fail
92        PostFail = 0x02 => "post-fail" | "postfail",
93        /// Keyboard Error Undefined
94        Undefined = 0x03 => "undefined",
95
96        /// Keyboard a and A
97        A = 0x04 => "a",
98        /// Keyboard b and B
99        B = 0x05 => "b",
100        /// Keyboard c and C
101        C = 0x06 => "c",
102        /// Keyboard d and D
103        D = 0x07 => "d",
104        /// Keyboard e and E
105        E = 0x08 => "e",
106        /// Keyboard f and F
107        F = 0x09 => "f",
108        /// Keyboard g and G
109        G = 0x0a => "g",
110        /// Keyboard h and H
111        H = 0x0b => "h",
112        /// Keyboard i and I
113        I = 0x0c => "i",
114        /// Keyboard j and J
115        J = 0x0d => "j",
116        /// Keyboard k and K
117        K = 0x0e => "k",
118        /// Keyboard l and L
119        L = 0x0f => "l",
120        /// Keyboard m and M
121        M = 0x10 => "m",
122        /// Keyboard n and N
123        N = 0x11 => "n",
124        /// Keyboard o and O
125        O = 0x12 => "o",
126        /// Keyboard p and P
127        P = 0x13 => "p",
128        /// Keyboard q and Q
129        Q = 0x14 => "q",
130        /// Keyboard r and R
131        R = 0x15 => "r",
132        /// Keyboard s and S
133        S = 0x16 => "s",
134        /// Keyboard t and T
135        T = 0x17 => "t",
136        /// Keyboard u and U
137        U = 0x18 => "u",
138        /// Keyboard v and V
139        V = 0x19 => "v",
140        /// Keyboard w and W
141        W = 0x1a => "w",
142        /// Keyboard x and X
143        X = 0x1b => "x",
144        /// Keyboard y and Y
145        Y = 0x1c => "y",
146        /// Keyboard z and Z
147        Z = 0x1d => "z",
148
149        /// Keyboard 1 and !
150        Num1 = 0x1e => "1",
151        /// Keyboard 2 and @
152        Num2 = 0x1f => "2",
153        /// Keyboard 3 and #
154        Num3 = 0x20 => "3",
155        /// Keyboard 4 and $
156        Num4 = 0x21 => "4",
157        /// Keyboard 5 and %
158        Num5 = 0x22 => "5",
159        /// Keyboard 6 and ^
160        Num6 = 0x23 => "6",
161        /// Keyboard 7 and &
162        Num7 = 0x24 => "7",
163        /// Keyboard 8 and *
164        Num8 = 0x25 => "8",
165        /// Keyboard 9 and (
166        Num9 = 0x26 => "9",
167        /// Keyboard 0 and )
168        Num0 = 0x27 => "0",
169
170        /// Keyboard Return (ENTER)
171        Enter = 0x28 => "enter",
172        /// Keyboard ESCAPE
173        Esc = 0x29 => "esc" | "escape",
174        /// Keyboard DELETE (Backspace)
175        BackSpace = 0x2a => "backspace" | "back-space",
176        /// Keyboard Tab
177        Tab = 0x2b => "tab",
178        /// Keyboard Spacebar
179        Space = 0x2c => "space",
180        /// Keyboard - and _
181        Minus = 0x2d => "minus" | "-",
182        /// Keyboard = and +
183        Equal = 0x2e => "equal" | "=",
184        /// Keyboard [ and {
185        LeftBrace = 0x2f => "left-brace" | "{" | "[",
186        /// Keyboard ] and }
187        RightBrace = 0x30 => "right-brace" | "}" | "]",
188        /// Keyboard \ and |
189        BackSlash = 0x31 => "back-slash" | "\\" | "|",
190        /// Keyboard Non-US # and ~
191        HashTilde = 0x32 => "hash-tilde" | "hash" | "tilde" | "#" | "~",
192        /// Keyboard ; and :
193        Semicolon = 0x33 => "semicolon" | ";",
194        /// Keyboard ' and "
195        Apostrophe = 0x34 => "apostrophe" | "'" | "\"",
196        /// Keyboard ` and ~
197        Grave = 0x35 => "grave" | "`",
198        /// Keyboard , and <
199        Comma = 0x36 => "comma" | ",",
200        /// Keyboard . and >
201        Dot = 0x37 => "dot" | ".",
202        /// Keyboard / and ?
203        Slash = 0x38 => "slash" | "/",
204        /// Keyboard Caps Lock
205        CapsLock = 0x39 => "caps-lock" | "capslock",
206
207        /// Keyboard F1
208        F1 = 0x3a => "f1",
209        /// Keyboard F2
210        F2 = 0x3b => "f2",
211        /// Keyboard F3
212        F3 = 0x3c => "f3",
213        /// Keyboard F4
214        F4 = 0x3d => "f4",
215        /// Keyboard F5
216        F5 = 0x3e => "f5",
217        /// Keyboard F6
218        F6 = 0x3f => "f6",
219        /// Keyboard F7
220        F7 = 0x40 => "f7",
221        /// Keyboard F8
222        F8 = 0x41 => "f8",
223        /// Keyboard F9
224        F9 = 0x42 => "f9",
225        /// Keyboard F10
226        F10 = 0x43 => "f10",
227        /// Keyboard F11
228        F11 = 0x44 => "f11",
229        /// Keyboard F12
230        F12 = 0x45 => "f12",
231
232        /// Keyboard Print Screen
233        SysRq = 0x46 => "sysrq" | "print-screen",
234        /// Keyboard Scroll Lock
235        ScrollLock = 0x47 => "scroll-lock" | "scrolllock",
236        /// Keyboard Pause
237        Pause = 0x48 => "pause",
238        /// Keyboard Insert
239        Insert = 0x49 => "insert",
240        /// Keyboard Home
241        Home = 0x4a => "home",
242        /// Keyboard Page Up
243        PageUp = 0x4b => "page-up" | "pageup",
244        /// Keyboard Delete Forward
245        Delete = 0x4c => "delete",
246        /// Keyboard End
247        End = 0x4d => "end",
248        /// Keyboard Page Down
249        PageDown = 0x4e => "page-down" | "pagedown",
250        /// Keyboard Right Arrow
251        Right = 0x4f => "right",
252        /// Keyboard Left Arrow
253        Left = 0x50 => "left",
254        /// Keyboard Down Arrow
255        Down = 0x51 => "down",
256        /// Keyboard Up Arrow
257        Up = 0x52 => "up",
258
259        /// Keyboard Num Lock and Clear
260        NumLock = 0x53 => "num-lock" | "numlock",
261        /// Keypad /
262        KeyPadSlash = 0x54 => "keypad-slash",
263        /// Keypad *
264        KeyPadAsterisk = 0x55 => "keypad-asterisk",
265        /// Keypad -
266        KeyPadMinus = 0x56 => "keypad-minus",
267        /// Keypad +
268        KeyPadPlus = 0x57 => "keypad-plus",
269        /// Keypad ENTER
270        KeyPadEnter = 0x58 => "keypad-enter",
271        /// Keypad 1 and End
272        KeyPad1 = 0x59 => "keypad-1",
273        /// Keypad 2 and Down Arrow
274        KeyPad2 = 0x5a => "keypad-2",
275        /// Keypad 3 and PageDn
276        KeyPad3 = 0x5b => "keypad-3",
277        /// Keypad 4 and Left Arrow
278        KeyPad4 = 0x5c => "keypad-4",
279        /// Keypad 5
280        KeyPad5 = 0x5d => "keypad-5",
281        /// Keypad 6 and Right Arrow
282        KeyPad6 = 0x5e => "keypad-6",
283        /// Keypad 7 and Home
284        KeyPad7 = 0x5f => "keypad-7",
285        /// Keypad 8 and Up Arrow
286        KeyPad8 = 0x60 => "keypad-8",
287        /// Keypad 9 and Page Up
288        KeyPad9 = 0x61 => "keypad-9",
289        /// Keypad 0 and Insert
290        KeyPad0 = 0x62 => "keypad-0",
291        /// Keypad . and Delete
292        KeyPadDot = 0x63 => "keypad-dot",
293
294        /// Keyboard Non-US \ and |
295        NonUsBackSlash = 0x64 => "nonus-backslash",
296        /// Keyboard Application
297        Compose = 0x65 => "compose",
298        /// Keyboard Power
299        Power = 0x66 => "power",
300        /// Keypad =
301        KeyPadEqual = 0x67 => "keypad-equal",
302
303        /// Keyboard F13
304        F13 = 0x68 => "f13",
305        /// Keyboard F14
306        F14 = 0x69 => "f14",
307        /// Keyboard F15
308        F15 = 0x6a => "f15",
309        /// Keyboard F16
310        F16 = 0x6b => "f16",
311        /// Keyboard F17
312        F17 = 0x6c => "f17",
313        /// Keyboard F18
314        F18 = 0x6d => "f18",
315        /// Keyboard F19
316        F19 = 0x6e => "f19",
317        /// Keyboard F20
318        F20 = 0x6f => "f20",
319        /// Keyboard F21
320        F21 = 0x70 => "f21",
321        /// Keyboard F22
322        F22 = 0x71 => "f22",
323        /// Keyboard F23
324        F23 = 0x72 => "f23",
325        /// Keyboard F24
326        F24 = 0x73 => "f24",
327
328        /// Keyboard Execute
329        Open = 0x74 => "open",
330        /// Keyboard Help
331        Help = 0x75 => "help",
332        /// Keyboard Menu
333        Props = 0x76 => "props",
334        /// Keyboard Select
335        Front = 0x77 => "front",
336        /// Keyboard Stop
337        Stop = 0x78 => "stop",
338        /// Keyboard Again
339        Again = 0x79 => "again",
340        /// Keyboard Undo
341        Undo = 0x7a => "undo",
342        /// Keyboard Cut
343        Cut = 0x7b => "cut",
344        /// Keyboard Copy
345        Copy = 0x7c => "copy",
346        /// Keyboard Paste
347        Paste = 0x7d => "paste",
348        /// Keyboard Find
349        Find = 0x7e => "find",
350        /// Keyboard Mute
351        Mute = 0x7f => "mute",
352        /// Keyboard Volume Up
353        VolumeUp = 0x80 => "volume-up" | "volumeup",
354        /// Keyboard Volume Down
355        VolumeDown = 0x81 => "volume-down" | "volumedown",
356        /// Keyboard Locking Caps Lock
357        LockingCapsLock = 0x82 => "locking-caps-lock" | "locking-capslock",
358        /// Keyboard Locking Num Lock
359        LockingNumLock = 0x83 => "locking-num-lock" | "locking-numlock",
360        /// Keyboard Locking Scroll Lock
361        LockingScrollLock = 0x84 => "locking-scroll-lock" | "locking-scrolllock",
362        /// Keypad Comma
363        KeyPadComma = 0x85 => "keypad-comma",
364        /// Keypad Equal Sign
365        KeyPadEqualSign = 0x86 => "keypad-equal-sign",
366        /// Keyboard International1
367        Ro = 0x87 => "ro",
368        /// Keyboard International2
369        KatakanaHiragana = 0x88 => "katakana-hiragana",
370        /// Keyboard International3
371        Yen = 0x89 => "yen",
372        /// Keyboard International4
373        Henkan = 0x8a => "henkan",
374        /// Keyboard International5
375        Munenkan = 0x8b => "munenkan",
376        /// Keyboard International6
377        KeyPadJpComma = 0x8c => "keypad-jp-comma",
378        // 0x8d  Keyboard International7
379        // 0x8e  Keyboard International8
380        // 0x8f  Keyboard International9
381        /// Keyboard LANG1
382        Hangeul = 0x90 => "hangeul",
383        /// Keyboard LANG2
384        Hanja = 0x91 => "hanja",
385        /// Keyboard LANG3
386        Katakana = 0x92 => "katakana",
387        /// Keyboard LANG4
388        Hiragana = 0x93 => "hiragana",
389        /// Keyboard LANG5
390        ZankakuHankaku = 0x94 => "zenkaku-hankaku",
391        // 0x95  Keyboard LANG6
392        // 0x96  Keyboard LANG7
393        // 0x97  Keyboard LANG8
394        // 0x98  Keyboard LANG9
395        // 0x99  Keyboard Alternate Erase
396        // 0x9a  Keyboard SysReq/Attention
397        // 0x9b  Keyboard Cancel
398        // 0x9c  Keyboard Clear
399        // 0x9d  Keyboard Prior
400        // 0x9e  Keyboard Return
401        // 0x9f  Keyboard Separator
402        // 0xa0  Keyboard Out
403        // 0xa1  Keyboard Oper
404        // 0xa2  Keyboard Clear/Again
405        // 0xa3  Keyboard CrSel/Props
406        // 0xa4  Keyboard ExSel
407
408        // 0xb0  Keypad 00
409        // 0xb1  Keypad 000
410        // 0xb2  Thousands Separator
411        // 0xb3  Decimal Separator
412        // 0xb4  Currency Unit
413        // 0xb5  Currency Sub-unit
414        /// Keypad (
415        KeyPadLeftParen = 0xb6 => "keypad-left-paren",
416        /// Keypad )
417        KeyPadRightParen = 0xb7 => "keypad-right-paren",
418        // 0xb8  Keypad {
419        // 0xb9  Keypad }
420        // 0xba  Keypad Tab
421        // 0xbb  Keypad Backspace
422        // 0xbc  Keypad A
423        // 0xbd  Keypad B
424        // 0xbe  Keypad C
425        // 0xbf  Keypad D
426        // 0xc0  Keypad E
427        // 0xc1  Keypad F
428        // 0xc2  Keypad XOR
429        // 0xc3  Keypad ^
430        // 0xc4  Keypad %
431        // 0xc5  Keypad <
432        // 0xc6  Keypad >
433        // 0xc7  Keypad &
434        // 0xc8  Keypad &&
435        // 0xc9  Keypad |
436        // 0xca  Keypad ||
437        // 0xcb  Keypad :
438        // 0xcc  Keypad #
439        // 0xcd  Keypad Space
440        // 0xce  Keypad @
441        // 0xcf  Keypad !
442        // 0xd0  Keypad Memory Store
443        // 0xd1  Keypad Memory Recall
444        // 0xd2  Keypad Memory Clear
445        // 0xd3  Keypad Memory Add
446        // 0xd4  Keypad Memory Subtract
447        // 0xd5  Keypad Memory Multiply
448        // 0xd6  Keypad Memory Divide
449        // 0xd7  Keypad +/-
450        // 0xd8  Keypad Clear
451        // 0xd9  Keypad Clear Entry
452        // 0xda  Keypad Binary
453        // 0xdb  Keypad Octal
454        // 0xdc  Keypad Decimal
455        // 0xdd  Keypad Hexadecimal
456        /// Keyboard Left Control
457        LeftCtrl = 0xe0 => "left-ctrl" | "ctrl",
458        /// Keyboard Left Shift
459        LeftShift = 0xe1 => "left-shift" | "shift",
460        /// Keyboard Left Alt
461        LeftAlt = 0xe2 => "left-alt" | "alt",
462        /// Keyboard Left GUI
463        LeftMeta = 0xe3 => "left-meta" | "meta",
464        /// Keyboard Right Control
465        RightCtrl = 0xe4 => "right-ctrl",
466        /// Keyboard Right Shift
467        RightShift = 0xe5 => "right-shift",
468        /// Keyboard Right Alt
469        RightAlt = 0xe6 => "right-alt",
470        /// Keyboard Right GUI
471        RightMeta = 0xe7 => "right-meta",
472    }
473}
474
475impl From<Modifiers> for Key {
476    fn from(mods: Modifiers) -> Self {
477        let off = mods.bits().trailing_zeros() as u8;
478        if off < 8 {
479            Key::from(0xe0u8 + off)
480        } else {
481            Key::None
482        }
483    }
484}
485
486impl From<Key> for Modifiers {
487    fn from(key: Key) -> Self {
488        let code = key as u8;
489        Modifiers::from_bits_retain(if (0xe0..=0xe7).contains(&code) {
490            1 << (code - 0xe0)
491        } else {
492            0
493        })
494    }
495}
496
497impl Key {
498    /// Converts from raw value safely
499    pub fn safe_from(raw: u8) -> Option<Self> {
500        if raw <= 0xe7 {
501            Some(From::from(raw))
502        } else {
503            None
504        }
505    }
506}
507
508impl Default for Key {
509    fn default() -> Self {
510        Self::None
511    }
512}
513
514code_enum! {
515    /// LED code
516    Led: u8 {
517        /// No LED
518        None = 0x00 => "none",
519        /// Num lock
520        NumLock = 0x01 => "num-lock" | "numlock",
521        /// Caps lock
522        CapsLock = 0x02 => "caps-lock" | "capslock",
523        /// Scroll lock
524        ScrollLock = 0x03 => "scroll-lock" | "scrollock",
525        /// Compose LED
526        Compose = 0x04 => "compose",
527        /// Kana LED
528        Kana = 0x05 => "kana",
529    }
530}
531
532impl Led {
533    /// Converts from raw value safely
534    pub fn safe_from(raw: u8) -> Option<Self> {
535        if (0x01..=0x05).contains(&raw) {
536            Some(From::from(raw))
537        } else {
538            None
539        }
540    }
541}
542
543bitflags! {
544    /// LED mask
545    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
546    pub struct Leds: u8 {
547        /// Num lock
548        const NumLock = 0x01;
549        /// Caps lock
550        const CapsLock = 0x02;
551        /// Scroll lock
552        const ScrollLock = 0x04;
553        /// Compose LED
554        const Compose = 0x08;
555        /// Kana LED
556        const Kana = 0x10;
557    }
558}
559
560const_assert_eq!(size_of::<Leds>(), 1);
561
562impl Default for Leds {
563    fn default() -> Self {
564        Self::empty()
565    }
566}
567
568impl Leds {
569    /// Convert from raw value safely
570    pub fn safe_from(raw: u8) -> Option<Self> {
571        if raw & 0xe0 == 0 {
572            Self::from_bits(raw)
573        } else {
574            None
575        }
576    }
577}
578
579impl From<Leds> for u8 {
580    fn from(leds: Leds) -> Self {
581        leds.bits()
582    }
583}
584
585impl From<Led> for Leds {
586    fn from(code: Led) -> Self {
587        Self::from_bits_retain(if matches!(code, Led::None) {
588            0u8
589        } else {
590            1u8 << (code as u8 - Led::NumLock as u8)
591        })
592    }
593}
594
595impl From<Leds> for Led {
596    fn from(leds: Leds) -> Self {
597        let off = leds.bits().trailing_zeros() as u8;
598        if off < 8 {
599            Led::from(Led::NumLock as u8 + off)
600        } else {
601            Led::None
602        }
603    }
604}
605
606serde_num! {
607    Modifiers: u8, "a modifier mask";
608    Leds: u8, "a LED mask";
609    Key: u8, "a numeric key code";
610    Led: u8, "a numeric LED code";
611}
612
613/// Keyboard input report
614#[derive(Clone, Copy, Debug, Default)]
615#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
616#[repr(C, packed)]
617pub struct KeyboardInput {
618    /// Pressed modifier keys
619    #[cfg_attr(feature = "serde", serde(rename = "mod"))]
620    modifier: Modifiers,
621    /// Reserved unused
622    #[cfg_attr(feature = "serde", serde(skip))]
623    reserved: u8,
624    /// Pressed key codes
625    #[cfg_attr(feature = "serde", serde(rename = "key"))]
626    keycodes: [Key; 6],
627}
628
629const_assert_eq!(size_of::<KeyboardInput>(), 8);
630
631impl KeyboardInput {
632    /// Get iterator over pressed keys
633    ///
634    /// Modifiers also returned as key codes before ordinary keys
635    pub fn pressed(&self) -> AllPressedKeys<'_> {
636        AllPressedKeys {
637            report: self,
638            element: 0,
639        }
640    }
641
642    /// Get modifier mask
643    pub fn mods(&self) -> Modifiers {
644        self.modifier
645    }
646
647    /// Get number of all pressed keys
648    pub fn count_pressed(&self) -> usize {
649        self.count_pressed_mods() + self.count_pressed_keys()
650    }
651
652    /// Get number of pressed modifiers
653    pub fn count_pressed_mods(&self) -> usize {
654        self.modifier.bits().count_ones() as _
655    }
656
657    /// Get number of pressed keys excepting modifiers
658    pub fn count_pressed_keys(&self) -> usize {
659        for i in 0..6 {
660            if matches!(self.keycodes[i], Key::None) {
661                return i;
662            }
663        }
664        6
665    }
666
667    /// Get slice of pressed keys excepting modifiers
668    pub fn pressed_keys(&self) -> &[Key] {
669        &self.keycodes[0..self.count_pressed_keys()]
670    }
671
672    /// Check is key pressed excepting modifiers
673    pub fn is_pressed_key(&self, key: Key) -> bool {
674        for index in 0..6 {
675            if self.keycodes[index] == key {
676                return true;
677            }
678        }
679        false
680    }
681
682    /// Press or release modifiers only
683    pub fn change_mods(&mut self, mask: Modifiers, state: bool) {
684        if state {
685            self.modifier |= mask;
686        } else {
687            self.modifier &= !mask;
688        }
689    }
690
691    /// Press modifiers only
692    pub fn press_mods(&mut self, mask: Modifiers) {
693        self.change_mods(mask, true);
694    }
695
696    /// Release modifiers only
697    pub fn release_mods(&mut self, mask: Modifiers) {
698        self.change_mods(mask, false);
699    }
700
701    /// Press or release key
702    pub fn change_key(&mut self, key: Key, state: bool) {
703        if matches!(key, Key::None) {
704            return;
705        }
706        let modifier = Modifiers::from(key);
707        if modifier.bits() == 0 {
708            // ordinary key
709            let mut len = self.count_pressed_keys();
710            if state {
711                // press key
712                if len < 6 {
713                    for i in 0..len {
714                        if self.keycodes[i] == key {
715                            // key already pressed
716                            return;
717                        }
718                    }
719                    self.keycodes[len] = key;
720                }
721            } else {
722                // release key
723                let mut i = 0;
724                while i < len {
725                    // find key in pressed
726                    if self.keycodes[i] == key {
727                        len -= 1;
728                        for j in i..len {
729                            // remove key
730                            self.keycodes[j] = self.keycodes[j + 1];
731                        }
732                        self.keycodes[len] = Key::None;
733                    } else {
734                        i += 1;
735                    }
736                }
737            }
738        } else {
739            // modifier key
740            if state {
741                // press key
742                self.modifier |= modifier;
743            } else {
744                // release key
745                self.modifier &= !modifier;
746            }
747        }
748    }
749
750    /// Press key
751    pub fn press_key(&mut self, key: Key) {
752        self.change_key(key, true);
753    }
754
755    /// Release key
756    pub fn release_key(&mut self, key: Key) {
757        self.change_key(key, false);
758    }
759
760    /// Get key state changes between two reports
761    ///
762    /// Difference of two reports
763    pub fn diff<'i>(&'i self, other: &'i Self) -> KeyStateChanges<'i> {
764        KeyStateChanges {
765            new: self,
766            old: other,
767            element: 0,
768        }
769    }
770}
771
772impl<'i> core::ops::Sub<&'i KeyboardInput> for &'i KeyboardInput {
773    type Output = KeyStateChanges<'i>;
774
775    fn sub(self, other: Self) -> Self::Output {
776        self.diff(other)
777    }
778}
779
780/// Changes between keyboard input reports
781pub struct KeyStateChanges<'i> {
782    new: &'i KeyboardInput,
783    old: &'i KeyboardInput,
784    element: u8,
785}
786
787impl<'i> Iterator for KeyStateChanges<'i> {
788    type Item = StateChange<Key>;
789
790    fn next(&mut self) -> Option<Self::Item> {
791        loop {
792            if self.element < 8 {
793                // find changed modifies
794                let modifier = Modifiers::from_bits_retain(1 << self.element);
795                self.element += 1;
796                if Modifiers::empty() != ((self.new.modifier ^ self.old.modifier) & modifier) {
797                    let key = Key::from(modifier);
798                    let old_key = Key::from(self.old.modifier & modifier);
799                    return Some(StateChange::new(key, matches!(old_key, Key::None)));
800                }
801            } else if self.element < 8 + 6 {
802                // find released keys
803                let index = (self.element - 8) as usize;
804                let key = self.old.keycodes[index];
805                if matches!(key, Key::None) {
806                    self.element = 8 + 6;
807                } else {
808                    self.element += 1;
809                    if !self.new.is_pressed_key(key) {
810                        return Some(StateChange::new(key, false));
811                    }
812                }
813            } else if self.element < 8 + 6 + 6 {
814                // find pressed keys
815                let index = (self.element - (8 + 6)) as usize;
816                let key = self.new.keycodes[index];
817                if matches!(key, Key::None) {
818                    self.element = 8 + 6 + 6;
819                } else {
820                    self.element += 1;
821                    if !self.old.is_pressed_key(key) {
822                        return Some(StateChange::new(key, true));
823                    }
824                }
825            } else {
826                return None;
827            }
828        }
829    }
830}
831
832impl Extend<StateChange<Modifiers>> for KeyboardInput {
833    fn extend<T>(&mut self, iter: T)
834    where
835        T: IntoIterator<Item = StateChange<Modifiers>>,
836    {
837        for StateChange { data, state } in iter {
838            self.change_mods(data, state);
839        }
840    }
841}
842
843impl Extend<StateChange<Key>> for KeyboardInput {
844    fn extend<T>(&mut self, iter: T)
845    where
846        T: IntoIterator<Item = StateChange<Key>>,
847    {
848        for StateChange { data, state } in iter {
849            self.change_key(data, state);
850        }
851    }
852}
853
854impl Extend<KeyboardInput> for KeyboardInput {
855    fn extend<T>(&mut self, iter: T)
856    where
857        T: IntoIterator<Item = KeyboardInput>,
858    {
859        for item in iter {
860            *self = item;
861        }
862    }
863}
864
865/// An iterator over all pressed keys including modifiers
866pub struct AllPressedKeys<'i> {
867    report: &'i KeyboardInput,
868    element: u8,
869}
870
871impl<'i> Iterator for AllPressedKeys<'i> {
872    type Item = Key;
873
874    fn next(&mut self) -> Option<Self::Item> {
875        loop {
876            if self.element < 8 {
877                let modifier = Modifiers::from_bits_retain(1 << self.element);
878                self.element += 1;
879                let key = Key::from(self.report.modifier & modifier);
880                if !matches!(key, Key::None) {
881                    return Some(key);
882                }
883            } else if self.element < 8 + 6 {
884                let key = self.report.keycodes[(self.element - 8) as usize];
885                self.element += 1;
886                if !matches!(key, Key::None) {
887                    return Some(key);
888                }
889            } else {
890                return None;
891            }
892        }
893    }
894}
895
896/// Keyboard output report
897#[derive(Clone, Copy, Debug, Default)]
898#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
899#[repr(C, packed)]
900pub struct KeyboardOutput {
901    /// Active LEDs
902    #[cfg_attr(feature = "serde", serde(rename = "led"))]
903    leds: Leds,
904}
905
906const_assert_eq!(size_of::<KeyboardOutput>(), 1);
907
908impl KeyboardOutput {
909    /// Get reference to LEDs mask
910    pub fn leds(&self) -> &Leds {
911        &self.leds
912    }
913
914    /// Get number of lit LEDs
915    pub fn count_lit(&self) -> usize {
916        self.leds.bits().count_ones() as _
917    }
918
919    /// Get iterator over lit LEDs
920    pub fn lit(&self) -> LitLeds {
921        LitLeds {
922            report: self,
923            element: 0,
924        }
925    }
926
927    /// Change LEDs state
928    pub fn change_leds(&mut self, leds: Leds, state: bool) {
929        if state {
930            self.leds |= leds;
931        } else {
932            self.leds &= !leds;
933        }
934    }
935
936    /// Turn LEDs on
937    pub fn on_leds(&mut self, leds: Leds) {
938        self.change_leds(leds, true);
939    }
940
941    /// Turn LEDs off
942    pub fn off_leds(&mut self, leds: Leds) {
943        self.change_leds(leds, false);
944    }
945
946    /// Change LED state
947    pub fn change_led(&mut self, led: Led, state: bool) {
948        self.change_leds(led.into(), state);
949    }
950
951    /// Turn LED on
952    pub fn on_led(&mut self, led: Led) {
953        self.change_led(led, true);
954    }
955
956    /// Turn LED off
957    pub fn off_led(&mut self, led: Led) {
958        self.change_led(led, false);
959    }
960
961    /// Get LED state changes between two reports
962    ///
963    /// Difference of two reports
964    pub fn diff<'i>(&'i self, other: &'i Self) -> LedStateChanges<'i> {
965        LedStateChanges {
966            new: self,
967            old: other,
968            element: 0,
969        }
970    }
971}
972
973impl<'i> core::ops::Sub<&'i KeyboardOutput> for &'i KeyboardOutput {
974    type Output = LedStateChanges<'i>;
975
976    fn sub(self, other: Self) -> Self::Output {
977        self.diff(other)
978    }
979}
980
981/// Changes between keyboard output reports
982pub struct LedStateChanges<'i> {
983    new: &'i KeyboardOutput,
984    old: &'i KeyboardOutput,
985    element: u8,
986}
987
988impl<'i> Iterator for LedStateChanges<'i> {
989    type Item = StateChange<Led>;
990
991    fn next(&mut self) -> Option<Self::Item> {
992        loop {
993            if self.element < 8 {
994                // find changed leds
995                let leds = Leds::from_bits_retain(1 << self.element);
996                self.element += 1;
997                if Leds::empty() != ((self.new.leds ^ self.old.leds) & leds) {
998                    let led = Led::from(leds);
999                    let old_led = Led::from(self.old.leds & leds);
1000                    return Some(StateChange::new(led, matches!(old_led, Led::None)));
1001                }
1002            } else {
1003                return None;
1004            }
1005        }
1006    }
1007}
1008
1009impl Extend<StateChange<Leds>> for KeyboardOutput {
1010    fn extend<T>(&mut self, iter: T)
1011    where
1012        T: IntoIterator<Item = StateChange<Leds>>,
1013    {
1014        for StateChange { data, state } in iter {
1015            self.change_leds(data, state);
1016        }
1017    }
1018}
1019
1020impl Extend<StateChange<Led>> for KeyboardOutput {
1021    fn extend<T>(&mut self, iter: T)
1022    where
1023        T: IntoIterator<Item = StateChange<Led>>,
1024    {
1025        for StateChange { data, state } in iter {
1026            self.change_led(data, state);
1027        }
1028    }
1029}
1030
1031impl Extend<KeyboardOutput> for KeyboardOutput {
1032    fn extend<T>(&mut self, iter: T)
1033    where
1034        T: IntoIterator<Item = KeyboardOutput>,
1035    {
1036        for item in iter {
1037            *self = item;
1038        }
1039    }
1040}
1041
1042/// An iterator over lit LEDs
1043pub struct LitLeds<'i> {
1044    report: &'i KeyboardOutput,
1045    element: u8,
1046}
1047
1048impl<'i> Iterator for LitLeds<'i> {
1049    type Item = Led;
1050
1051    fn next(&mut self) -> Option<Self::Item> {
1052        while self.element < 8 {
1053            let led = Leds::from_bits_retain(1u8 << self.element);
1054            self.element += 1;
1055            if self.report.leds.contains(led) {
1056                return Some(led.into());
1057            }
1058        }
1059        None
1060    }
1061}
1062
1063raw_ref! {
1064    Modifiers;
1065    Leds;
1066    Key;
1067    Led;
1068    KeyboardInput;
1069    KeyboardOutput;
1070}
1071
1072#[cfg(test)]
1073mod test {
1074    use super::*;
1075
1076    #[test]
1077    fn mod_mask_to_key_code() {
1078        assert_eq!(Key::from(Modifiers::empty()), Key::None);
1079        assert_eq!(Key::from(Modifiers::LeftCtrl), Key::LeftCtrl);
1080        assert_eq!(Key::from(Modifiers::RightAlt), Key::RightAlt);
1081        assert_eq!(Key::from(Modifiers::RightMeta), Key::RightMeta);
1082    }
1083
1084    #[test]
1085    fn key_code_to_mod_mask() {
1086        assert_eq!(Modifiers::from(Key::A), Modifiers::default());
1087        assert_eq!(Modifiers::from(Key::LeftCtrl), Modifiers::LeftCtrl);
1088        assert_eq!(Modifiers::from(Key::RightShift), Modifiers::RightShift);
1089        assert_eq!(Modifiers::from(Key::RightMeta), Modifiers::RightMeta);
1090    }
1091
1092    #[test]
1093    fn keyboard_input() {
1094        let mut report = KeyboardInput::default();
1095        assert_eq!(report.count_pressed_keys(), 0);
1096        assert_eq!(report.count_pressed(), 0);
1097
1098        report.press_mods(Modifiers::LeftAlt | Modifiers::RightShift | Modifiers::RightMeta);
1099        assert_eq!(report.count_pressed_keys(), 0);
1100        assert_eq!(report.count_pressed_mods(), 3);
1101        assert_eq!(report.count_pressed(), 3);
1102
1103        report.press_key(Key::A);
1104        assert_eq!(report.count_pressed_keys(), 1);
1105        assert_eq!(report.count_pressed(), 4);
1106
1107        report.press_key(Key::Esc);
1108        assert_eq!(report.count_pressed_keys(), 2);
1109        assert_eq!(report.count_pressed_mods(), 3);
1110        assert_eq!(report.count_pressed(), 5);
1111
1112        report.release_mods(Modifiers::RightMeta);
1113        assert_eq!(report.count_pressed_keys(), 2);
1114        assert_eq!(report.count_pressed_mods(), 2);
1115        assert_eq!(report.count_pressed(), 4);
1116
1117        report.press_key(Key::Enter);
1118        assert_eq!(report.count_pressed_keys(), 3);
1119
1120        report.press_key(Key::A);
1121        assert_eq!(report.count_pressed_keys(), 3);
1122
1123        report.press_key(Key::B);
1124        assert_eq!(report.count_pressed_keys(), 4);
1125
1126        report.press_key(Key::LeftMeta);
1127        assert_eq!(report.count_pressed_keys(), 4);
1128        assert_eq!(report.count_pressed(), 7);
1129
1130        report.release_key(Key::Esc);
1131        assert_eq!(report.count_pressed_keys(), 3);
1132
1133        report.press_key(Key::Tab);
1134        assert_eq!(report.count_pressed_keys(), 4);
1135
1136        report.release_key(Key::B);
1137        assert_eq!(report.count_pressed_keys(), 3);
1138        assert_eq!(report.count_pressed(), 6);
1139
1140        let mut iter = report.pressed();
1141        assert_eq!(iter.next(), Some(Key::LeftAlt));
1142        assert_eq!(iter.next(), Some(Key::LeftMeta));
1143        assert_eq!(iter.next(), Some(Key::RightShift));
1144        assert_eq!(iter.next(), Some(Key::A));
1145        assert_eq!(iter.next(), Some(Key::Enter));
1146        assert_eq!(iter.next(), Some(Key::Tab));
1147        assert_eq!(iter.next(), None);
1148    }
1149
1150    #[test]
1151    fn keyboard_output() {
1152        let mut report = KeyboardOutput::default();
1153        assert_eq!(report.count_lit(), 0);
1154
1155        report.on_leds(Leds::NumLock | Leds::CapsLock);
1156        assert_eq!(report.count_lit(), 2);
1157
1158        report.off_led(Led::CapsLock);
1159        eprintln!("{:?}", report.leds.bits());
1160        assert_eq!(report.count_lit(), 1);
1161
1162        report.on_leds(Leds::ScrollLock);
1163        assert_eq!(report.count_lit(), 2);
1164
1165        report.on_led(Led::NumLock);
1166        assert_eq!(report.count_lit(), 2);
1167
1168        report.on_led(Led::Compose);
1169        assert_eq!(report.count_lit(), 3);
1170
1171        let mut iter = report.lit();
1172        assert_eq!(iter.next(), Some(Led::NumLock));
1173        assert_eq!(iter.next(), Some(Led::ScrollLock));
1174        assert_eq!(iter.next(), Some(Led::Compose));
1175        assert_eq!(iter.next(), None);
1176    }
1177
1178    #[test]
1179    fn keyboard_input_diff() {
1180        let mut old = KeyboardInput::default();
1181        old.press_key(Key::A);
1182        old.press_key(Key::LeftCtrl);
1183        old.press_key(Key::LeftAlt);
1184        old.press_key(Key::Enter);
1185        old.press_key(Key::B);
1186        assert_eq!(old.count_pressed_keys(), 3);
1187
1188        let mut new = KeyboardInput::default();
1189        new.press_key(Key::RightMeta);
1190        new.press_key(Key::LeftAlt);
1191        new.press_key(Key::B);
1192        new.press_key(Key::C);
1193        new.press_key(Key::D);
1194        new.press_key(Key::Tab);
1195        new.press_key(Key::Esc);
1196        assert_eq!(new.count_pressed_keys(), 5);
1197
1198        let mut changes = &new - &old;
1199        assert_eq!(changes.next(), Some(StateChange::new(Key::LeftCtrl, false)));
1200        assert_eq!(changes.next(), Some(StateChange::new(Key::RightMeta, true)));
1201        assert_eq!(changes.next(), Some(StateChange::new(Key::A, false)));
1202        assert_eq!(changes.next(), Some(StateChange::new(Key::Enter, false)));
1203        assert_eq!(changes.next(), Some(StateChange::new(Key::C, true)));
1204        assert_eq!(changes.next(), Some(StateChange::new(Key::D, true)));
1205        assert_eq!(changes.next(), Some(StateChange::new(Key::Tab, true)));
1206        assert_eq!(changes.next(), Some(StateChange::new(Key::Esc, true)));
1207        assert_eq!(changes.next(), None);
1208    }
1209
1210    #[test]
1211    fn keyboard_output_diff() {
1212        let mut old = KeyboardOutput::default();
1213        old.on_led(Led::CapsLock);
1214        old.on_led(Led::Kana);
1215
1216        let mut new = KeyboardOutput::default();
1217        new.on_led(Led::ScrollLock);
1218        new.on_led(Led::NumLock);
1219        new.on_led(Led::Kana);
1220
1221        let mut changes = &new - &old;
1222        assert_eq!(changes.next(), Some(StateChange::new(Led::NumLock, true)));
1223        assert_eq!(changes.next(), Some(StateChange::new(Led::CapsLock, false)));
1224        assert_eq!(
1225            changes.next(),
1226            Some(StateChange::new(Led::ScrollLock, true))
1227        );
1228        assert_eq!(changes.next(), None);
1229    }
1230}