rmk_types/
keycode.rs

1//! Complete keycode definitions.
2//!
3//! This module provides keycode definitions following the USB HID
4//! specification, extended with additional codes
5use strum::FromRepr;
6
7use crate::modifier::ModifierCombination;
8
9/// KeyCode is the internal representation of all keycodes, keyboard operations, etc.
10/// Use flat representation of keycodes.
11#[repr(u16)]
12#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, FromRepr)]
13#[cfg_attr(feature = "defmt", derive(defmt::Format))]
14#[derive(postcard::experimental::max_size::MaxSize)]
15pub enum KeyCode {
16    /// Reserved, no-key.
17    No = 0x0000,
18    /// Keyboard roll over error, too many keys are pressed simultaneously, not a physical key.
19    /// NKRO: n-key rollover.
20    ErrorRollover = 0x0001,
21    /// Keyboard post fail error, not a physical key.
22    PostFail = 0x0002,
23    /// An undefined error, not a physical key.
24    ErrorUndefined = 0x0003,
25    /// `a` and `A`
26    A = 0x0004,
27    /// `b` and `B`
28    B = 0x0005,
29    /// `c` and `C`
30    C = 0x0006,
31    /// `d` and `D`
32    D = 0x0007,
33    /// `e` and `E`
34    E = 0x0008,
35    /// `f` and `F`
36    F = 0x0009,
37    /// `g` and `G`
38    G = 0x000A,
39    /// `h` and `H`
40    H = 0x000B,
41    /// `i` and `I`
42    I = 0x000C,
43    /// `j` and `J`
44    J = 0x000D,
45    /// `k` and `K`
46    K = 0x000E,
47    /// `l` and `L`
48    L = 0x000F,
49    /// `m` and `M`
50    M = 0x0010,
51    /// `n` and `N`
52    N = 0x0011,
53    /// `o` and `O`
54    O = 0x0012,
55    /// `p` and `P`
56    P = 0x0013,
57    /// `q` and `Q`
58    Q = 0x0014,
59    /// `r` and `R`
60    R = 0x0015,
61    /// `s` and `S`
62    S = 0x0016,
63    /// `t` and `T`
64    T = 0x0017,
65    /// `u` and `U`
66    U = 0x0018,
67    /// `v` and `V`
68    V = 0x0019,
69    /// `w` and `W`
70    W = 0x001A,
71    /// `x` and `X`
72    X = 0x001B,
73    /// `y` and `Y`
74    Y = 0x001C,
75    /// `z` and `Z`
76    Z = 0x001D,
77    /// `1` and `!`
78    Kc1 = 0x001E,
79    /// `2` and `@`
80    Kc2 = 0x001F,
81    /// `3` and `#`
82    Kc3 = 0x0020,
83    /// `4` and `$`
84    Kc4 = 0x0021,
85    /// `5` and `%`
86    Kc5 = 0x0022,
87    /// `6` and `^`
88    Kc6 = 0x0023,
89    /// `7` and `&`
90    Kc7 = 0x0024,
91    /// `8` and `*`
92    Kc8 = 0x0025,
93    /// `9` and `(`
94    Kc9 = 0x0026,
95    /// `0` and `)`
96    Kc0 = 0x0027,
97    /// `Enter`
98    Enter = 0x0028,
99    /// `Esc`
100    Escape = 0x0029,
101    /// `Backspace`
102    Backspace = 0x002A,
103    /// `Tab`
104    Tab = 0x002B,
105    /// `Space`
106    Space = 0x002C,
107    /// `-` and `_`
108    Minus = 0x002D,
109    /// `=` and `+`
110    Equal = 0x002E,
111    /// `[` and `{`
112    LeftBracket = 0x002F,
113    /// `]` and `}`
114    RightBracket = 0x0030,
115    /// `\` and `|`
116    Backslash = 0x0031,
117    /// Non-US `#` and `~`
118    NonusHash = 0x0032,
119    /// `;` and `:`
120    Semicolon = 0x0033,
121    /// `'` and `"`
122    Quote = 0x0034,
123    /// `~` and `\``
124    Grave = 0x0035,
125    /// `,` and `<`
126    Comma = 0x0036,
127    /// `.` and `>`
128    Dot = 0x0037,
129    /// `/` and `?`
130    Slash = 0x0038,
131    /// `CapsLock`
132    CapsLock = 0x0039,
133    /// `F1`
134    F1 = 0x003A,
135    /// `F2`
136    F2 = 0x003B,
137    /// `F3`
138    F3 = 0x003C,
139    /// `F4`
140    F4 = 0x003D,
141    /// `F5`
142    F5 = 0x003E,
143    /// `F6`
144    F6 = 0x003F,
145    /// `F7`
146    F7 = 0x0040,
147    /// `F8`
148    F8 = 0x0041,
149    /// `F9`
150    F9 = 0x0042,
151    /// `F10`
152    F10 = 0x0043,
153    /// `F11`
154    F11 = 0x0044,
155    /// `F12`
156    F12 = 0x0045,
157    /// Print Screen
158    PrintScreen = 0x0046,
159    /// Scroll Lock
160    ScrollLock = 0x0047,
161    /// Pause
162    Pause = 0x0048,
163    /// Insert
164    Insert = 0x0049,
165    /// Home
166    Home = 0x004A,
167    /// Page Up
168    PageUp = 0x004B,
169    /// Delete
170    Delete = 0x004C,
171    /// End
172    End = 0x004D,
173    /// Page Down
174    PageDown = 0x004E,
175    /// Right arrow
176    Right = 0x004F,
177    /// Left arrow
178    Left = 0x0050,
179    /// Down arrow
180    Down = 0x0051,
181    /// Up arrow
182    Up = 0x0052,
183    /// Nums Lock
184    NumLock = 0x0053,
185    /// `/` on keypad
186    KpSlash = 0x0054,
187    /// `*` on keypad
188    KpAsterisk = 0x0055,
189    /// `-` on keypad
190    KpMinus = 0x0056,
191    /// `+` on keypad
192    KpPlus = 0x0057,
193    /// `Enter` on keypad
194    KpEnter = 0x0058,
195    /// `1` on keypad
196    Kp1 = 0x0059,
197    /// `2` on keypad
198    Kp2 = 0x005A,
199    /// `3` on keypad
200    Kp3 = 0x005B,
201    /// `4` on keypad
202    Kp4 = 0x005C,
203    /// `5` on keypad
204    Kp5 = 0x005D,
205    /// `6` on keypad
206    Kp6 = 0x005E,
207    /// `7` on keypad
208    Kp7 = 0x005F,
209    /// `8` on keypad
210    Kp8 = 0x0060,
211    /// `9` on keypad
212    Kp9 = 0x0061,
213    /// `0` on keypad
214    Kp0 = 0x0062,
215    /// `.` on keypad
216    KpDot = 0x0063,
217    /// Non-US `\` or `|`
218    NonusBackslash = 0x0064,
219    /// `Application`
220    Application = 0x0065,
221    /// `Power`
222    KbPower = 0x0066,
223    /// `=` on keypad
224    KpEqual = 0x0067,
225    /// `F13`
226    F13 = 0x0068,
227    /// `F14`
228    F14 = 0x0069,
229    /// `F15`
230    F15 = 0x006A,
231    /// `F16`
232    F16 = 0x006B,
233    /// `F17`
234    F17 = 0x006C,
235    /// `F18`
236    F18 = 0x006D,
237    /// `F19`
238    F19 = 0x006E,
239    /// `F20`
240    F20 = 0x006F,
241    /// `F21`
242    F21 = 0x0070,
243    /// `F22`
244    F22 = 0x0071,
245    /// `F23`
246    F23 = 0x0072,
247    /// `F24`
248    F24 = 0x0073,
249    Execute = 0x0074,
250    Help = 0x0075,
251    Menu = 0x0076,
252    Select = 0x0077,
253    Stop = 0x0078,
254    Again = 0x0079,
255    Undo = 0x007A,
256    Cut = 0x007B,
257    Copy = 0x007C,
258    Paste = 0x007D,
259    Find = 0x007E,
260    /// Mute
261    KbMute = 0x007F,
262    /// Volume Up
263    KbVolumeUp = 0x0080,
264    /// Volume Down
265    KbVolumeDown = 0x0081,
266    /// Locking Caps Lock
267    LockingCapsLock = 0x0082,
268    /// Locking Num Lock
269    LockingNumLock = 0x0083,
270    /// Locking scroll lock
271    LockingScrollLock = 0x0084,
272    KpComma = 0x0085,
273    KpEqualAs400 = 0x0086,
274    International1 = 0x0087,
275    International2 = 0x0088,
276    International3 = 0x0089,
277    International4 = 0x008A,
278    International5 = 0x008B,
279    International6 = 0x008C,
280    International7 = 0x008D,
281    International8 = 0x008E,
282    International9 = 0x008F,
283    Language1 = 0x0090,
284    Language2 = 0x0091,
285    Language3 = 0x0092,
286    Language4 = 0x0093,
287    Language5 = 0x0094,
288    Language6 = 0x0095,
289    Language7 = 0x0096,
290    Language8 = 0x0097,
291    Language9 = 0x0098,
292    AlternateErase = 0x0099,
293    SystemRequest = 0x009A,
294    Cancel = 0x009B,
295    Clear = 0x009C,
296    Prior = 0x009D,
297    Return = 0x009E,
298    Separator = 0x009F,
299    Out = 0x00A0,
300    Oper = 0x00A1,
301    ClearAgain = 0x00A2,
302    Crsel = 0x00A3,
303    Exsel = 0x00A4,
304    SystemPower = 0x00A5,
305    SystemSleep = 0x00A6,
306    SystemWake = 0x00A7,
307    AudioMute = 0x00A8,
308    AudioVolUp = 0x00A9,
309    AudioVolDown = 0x00AA,
310    MediaNextTrack = 0x00AB,
311    MediaPrevTrack = 0x00AC,
312    MediaStop = 0x00AD,
313    MediaPlayPause = 0x00AE,
314    MediaSelect = 0x00AF,
315    MediaEject = 0x00B0,
316    Mail = 0x00B1,
317    Calculator = 0x00B2,
318    MyComputer = 0x00B3,
319    WwwSearch = 0x00B4,
320    WwwHome = 0x00B5,
321    WwwBack = 0x00B6,
322    WwwForward = 0x00B7,
323    WwwStop = 0x00B8,
324    WwwRefresh = 0x00B9,
325    WwwFavorites = 0x00BA,
326    MediaFastForward = 0x00BB,
327    MediaRewind = 0x00BC,
328    /// Brightness Up
329    BrightnessUp = 0x00BD,
330    /// Brightness Down
331    BrightnessDown = 0x00BE,
332    ControlPanel = 0x00BF,
333    Assistant = 0x00C0,
334    MissionControl = 0x00C1,
335    Launchpad = 0x00C2,
336    /// Mouse Up
337    MouseUp = 0x00CD,
338    /// Mouse Down
339    MouseDown = 0x00CE,
340    /// Mouse Left
341    MouseLeft = 0x00CF,
342    /// Mouse Right
343    MouseRight = 0x00D0,
344    /// Mouse Button 1(Left)
345    MouseBtn1 = 0x00D1,
346    /// Mouse Button 2(Right)
347    MouseBtn2 = 0x00D2,
348    /// Mouse Button 3(Middle)
349    MouseBtn3 = 0x00D3,
350    /// Mouse Button 4(Back)
351    MouseBtn4 = 0x00D4,
352    /// Mouse Button 5(Forward)
353    MouseBtn5 = 0x00D5,
354    MouseBtn6 = 0x00D6,
355    MouseBtn7 = 0x00D7,
356    MouseBtn8 = 0x00D8,
357    MouseWheelUp = 0x00D9,
358    MouseWheelDown = 0x00DA,
359    MouseWheelLeft = 0x00DB,
360    MouseWheelRight = 0x00DC,
361    MouseAccel0 = 0x00DD,
362    MouseAccel1 = 0x00DE,
363    MouseAccel2 = 0x00DF,
364    /// Left Control
365    LCtrl = 0x00E0,
366    /// Left Shift
367    LShift = 0x00E1,
368    /// Left Alt
369    LAlt = 0x00E2,
370    /// Left GUI
371    LGui = 0x00E3,
372    /// Right Control
373    RCtrl = 0x00E4,
374    /// Right Shift
375    RShift = 0x00E5,
376    /// Right Alt
377    RAlt = 0x00E6,
378    /// Right GUI
379    RGui = 0x00E7,
380    // Magic keycodes, use 0x100 ~ 0x1FF
381    MagicSwapControlCapsLock = 0x100,
382    MagicUnswapControlCapsLock = 0x101,
383    MagicToggleControlCapsLock = 0x102,
384    MagicCapsLockAsControlOff = 0x103,
385    MagicCapsLockAsControlOn = 0x104,
386    MagicSwapLaltLGui = 0x105,
387    MagicUnswapLaltLGui = 0x106,
388    MagicSwapRaltRGui = 0x107,
389    MagicUnswapRaltRGui = 0x108,
390    MagicGuiOn = 0x109,
391    MagicGuiOff = 0x10A,
392    MagicToggleGui = 0x10B,
393    MagicSwapGraveEsc = 0x10C,
394    MagicUnswapGraveEsc = 0x10D,
395    MagicSwapBackslashBackspace = 0x10E,
396    MagicUnswapBackslashBackspace = 0x10F,
397    MagicToggleBackslashBackspace = 0x110,
398    MagicNkroOn = 0x111,
399    MagicNkroOff = 0x112,
400    MagicToggleNkro = 0x113,
401    MagicSwapAltGui = 0x114,
402    MagicUnswapAltGui = 0x115,
403    MagicToggleAltGui = 0x116,
404    MagicSwapLctlLGui = 0x117,
405    MagicUnswapLctlLGui = 0x118,
406    MagicSwapRctlRGui = 0x119,
407    MagicUnswapRctlRGui = 0x11A,
408    MagicSwapCtlGui = 0x11B,
409    MagicUnswapCtlGui = 0x11C,
410    MagicToggleCtlGui = 0x11D,
411    MagicEeHandsLeft = 0x11E,
412    MagicEeHandsRight = 0x11F,
413    MagicSwapEscapeCapsLock = 0x120,
414    MagicUnswapEscapeCapsLock = 0x121,
415    MagicToggleEscapeCapsLock = 0x122,
416    // Midi keycodes, use 0x200 ~ 0x2FF
417    MidiOn = 0x200,
418    MidiOff = 0x201,
419    MidiToggle = 0x202,
420    MidiNoteC0 = 0x203,
421    MidiNoteCSharp0 = 0x204,
422    MidiNoteD0 = 0x205,
423    MidiNoteDSharp0 = 0x206,
424    MidiNoteE0 = 0x207,
425    MidiNoteF0 = 0x208,
426    MidiNoteFSharp0 = 0x209,
427    MidiNoteG0 = 0x20A,
428    MidiNoteGSharp0 = 0x20B,
429    MidiNoteA0 = 0x20C,
430    MidiNoteASharp0 = 0x20D,
431    MidiNoteB0 = 0x20E,
432    MidiNoteC1 = 0x20F,
433    MidiNoteCSharp1 = 0x210,
434    MidiNoteD1 = 0x211,
435    MidiNoteDSharp1 = 0x212,
436    MidiNoteE1 = 0x213,
437    MidiNoteF1 = 0x214,
438    MidiNoteFSharp1 = 0x215,
439    MidiNoteG1 = 0x216,
440    MidiNoteGSharp1 = 0x217,
441    MidiNoteA1 = 0x218,
442    MidiNoteASharp1 = 0x219,
443    MidiNoteB1 = 0x21A,
444    MidiNoteC2 = 0x21B,
445    MidiNoteCSharp2 = 0x21C,
446    MidiNoteD2 = 0x21D,
447    MidiNoteDSharp2 = 0x21E,
448    MidiNoteE2 = 0x21F,
449    MidiNoteF2 = 0x220,
450    MidiNoteFSharp2 = 0x221,
451    MidiNoteG2 = 0x222,
452    MidiNoteGSharp2 = 0x223,
453    MidiNoteA2 = 0x224,
454    MidiNoteASharp2 = 0x225,
455    MidiNoteB2 = 0x226,
456    MidiNoteC3 = 0x227,
457    MidiNoteCSharp3 = 0x228,
458    MidiNoteD3 = 0x229,
459    MidiNoteDSharp3 = 0x22A,
460    MidiNoteE3 = 0x22B,
461    MidiNoteF3 = 0x22C,
462    MidiNoteFSharp3 = 0x22D,
463    MidiNoteG3 = 0x22E,
464    MidiNoteGSharp3 = 0x22F,
465    MidiNoteA3 = 0x230,
466    MidiNoteASharp3 = 0x231,
467    MidiNoteB3 = 0x232,
468    MidiNoteC4 = 0x233,
469    MidiNoteCSharp4 = 0x234,
470    MidiNoteD4 = 0x235,
471    MidiNoteDSharp4 = 0x236,
472    MidiNoteE4 = 0x237,
473    MidiNoteF4 = 0x238,
474    MidiNoteFSharp4 = 0x239,
475    MidiNoteG4 = 0x23A,
476    MidiNoteGSharp4 = 0x23B,
477    MidiNoteA4 = 0x23C,
478    MidiNoteASharp4 = 0x23D,
479    MidiNoteB4 = 0x23E,
480    MidiNoteC5 = 0x23F,
481    MidiNoteCSharp5 = 0x240,
482    MidiNoteD5 = 0x241,
483    MidiNoteDSharp5 = 0x242,
484    MidiNoteE5 = 0x243,
485    MidiNoteF5 = 0x244,
486    MidiNoteFSharp5 = 0x245,
487    MidiNoteG5 = 0x246,
488    MidiNoteGSharp5 = 0x247,
489    MidiNoteA5 = 0x248,
490    MidiNoteASharp5 = 0x249,
491    MidiNoteB5 = 0x24A,
492    MidiOctaveN2 = 0x24B,
493    MidiOctaveN1 = 0x24C,
494    MidiOctave0 = 0x24D,
495    MidiOctave1 = 0x24E,
496    MidiOctave2 = 0x24F,
497    MidiOctave3 = 0x250,
498    MidiOctave4 = 0x251,
499    MidiOctave5 = 0x252,
500    MidiOctave6 = 0x253,
501    MidiOctave7 = 0x254,
502    MidiOctaveDOWN = 0x255,
503    MidiOctaveUP = 0x256,
504    MidiTransposeN6 = 0x257,
505    MidiTransposeN5 = 0x258,
506    MidiTransposeN4 = 0x259,
507    MidiTransposeN3 = 0x25A,
508    MidiTransposeN2 = 0x25B,
509    MidiTransposeN1 = 0x25C,
510    MidiTranspose0 = 0x25D,
511    MidiTranspose1 = 0x25E,
512    MidiTranspose2 = 0x25F,
513    MidiTranspose3 = 0x260,
514    MidiTranspose4 = 0x261,
515    MidiTranspose5 = 0x262,
516    MidiTranspose6 = 0x263,
517    MidiTransposeDown = 0x264,
518    MidiTransposeUp = 0x265,
519    MidiVelocity0 = 0x266,
520    MidiVelocity1 = 0x267,
521    MidiVelocity2 = 0x268,
522    MidiVelocity3 = 0x269,
523    MidiVelocity4 = 0x26A,
524    MidiVelocity5 = 0x26B,
525    MidiVelocity6 = 0x26C,
526    MidiVelocity7 = 0x26D,
527    MidiVelocity8 = 0x26E,
528    MidiVelocity9 = 0x26F,
529    MidiVelocity10 = 0x270,
530    MidiVelocityDOWN = 0x271,
531    MidiVelocityUP = 0x272,
532    MidiChannel1 = 0x273,
533    MidiChannel2 = 0x274,
534    MidiChannel3 = 0x275,
535    MidiChannel4 = 0x276,
536    MidiChannel5 = 0x277,
537    MidiChannel6 = 0x278,
538    MidiChannel7 = 0x279,
539    MidiChannel8 = 0x27A,
540    MidiChannel9 = 0x27B,
541    MidiChannel10 = 0x27C,
542    MidiChannel11 = 0x27D,
543    MidiChannel12 = 0x27E,
544    MidiChannel13 = 0x27F,
545    MidiChannel14 = 0x280,
546    MidiChannel15 = 0x281,
547    MidiChannel16 = 0x282,
548    MidiChannelDOWN = 0x283,
549    MidiChannelUP = 0x284,
550    MidiAllNotesOff = 0x285,
551    MidiSustain = 0x286,
552    MidiPortamento = 0x287,
553    MidiSostenuto = 0x288,
554    MidiSoft = 0x289,
555    MidiLegato = 0x28A,
556    MidiModulation = 0x28B,
557    MidiModulationSpeedDown = 0x28C,
558    MidiModulationSpeedUp = 0x28D,
559    MidiPitchBendDown = 0x28E,
560    MidiPitchBendUp = 0x28F,
561    // Sequencer keycodes, use 0x300 ~ 0x30F
562    SequencerOn = 0x300,
563    SequencerOff = 0x301,
564    SequencerToggle = 0x302,
565    SequencerTempoDown = 0x303,
566    SequencerTempoUp = 0x304,
567    SequencerResolutionDown = 0x305,
568    SequencerResolutionUp = 0x306,
569    SequencerStepsAll = 0x307,
570    SequencerStepsClear = 0x308,
571    // Joystick button keycodes, use 0x400 ~ 0x41F
572    JoystickButton0 = 0x400,
573    JoystickButton1 = 0x401,
574    JoystickButton2 = 0x402,
575    JoystickButton3 = 0x403,
576    JoystickButton4 = 0x404,
577    JoystickButton5 = 0x405,
578    JoystickButton6 = 0x406,
579    JoystickButton7 = 0x407,
580    JoystickButton8 = 0x408,
581    JoystickButton9 = 0x409,
582    JoystickButton10 = 0x40A,
583    JoystickButton11 = 0x40B,
584    JoystickButton12 = 0x40C,
585    JoystickButton13 = 0x40D,
586    JoystickButton14 = 0x40E,
587    JoystickButton15 = 0x40F,
588    JoystickButton16 = 0x410,
589    JoystickButton17 = 0x411,
590    JoystickButton18 = 0x412,
591    JoystickButton19 = 0x413,
592    JoystickButton20 = 0x414,
593    JoystickButton21 = 0x415,
594    JoystickButton22 = 0x416,
595    JoystickButton23 = 0x417,
596    JoystickButton24 = 0x418,
597    JoystickButton25 = 0x419,
598    JoystickButton26 = 0x41A,
599    JoystickButton27 = 0x41B,
600    JoystickButton28 = 0x41C,
601    JoystickButton29 = 0x41D,
602    JoystickButton30 = 0x41E,
603    JoystickButton31 = 0x41F,
604    // Programmable button keycodes, use 0x420 ~ 0x43F
605    ProgrammableButton1 = 0x420,
606    ProgrammableButton2 = 0x421,
607    ProgrammableButton3 = 0x422,
608    ProgrammableButton4 = 0x423,
609    ProgrammableButton5 = 0x424,
610    ProgrammableButton6 = 0x425,
611    ProgrammableButton7 = 0x426,
612    ProgrammableButton8 = 0x427,
613    ProgrammableButton9 = 0x428,
614    ProgrammableButton10 = 0x429,
615    ProgrammableButton11 = 0x42A,
616    ProgrammableButton12 = 0x42B,
617    ProgrammableButton13 = 0x42C,
618    ProgrammableButton14 = 0x42D,
619    ProgrammableButton15 = 0x42E,
620    ProgrammableButton16 = 0x42F,
621    ProgrammableButton17 = 0x430,
622    ProgrammableButton18 = 0x431,
623    ProgrammableButton19 = 0x432,
624    ProgrammableButton20 = 0x433,
625    ProgrammableButton21 = 0x434,
626    ProgrammableButton22 = 0x435,
627    ProgrammableButton23 = 0x436,
628    ProgrammableButton24 = 0x437,
629    ProgrammableButton25 = 0x438,
630    ProgrammableButton26 = 0x439,
631    ProgrammableButton27 = 0x43A,
632    ProgrammableButton28 = 0x43B,
633    ProgrammableButton29 = 0x43C,
634    ProgrammableButton30 = 0x43D,
635    ProgrammableButton31 = 0x43E,
636    ProgrammableButton32 = 0x43F,
637    // Audio keycodes, use 0x460 ~ 0x47F
638    AudioOn = 0x460,
639    AudioOff = 0x461,
640    AudioToggle = 0x462,
641    AudioClickyToggle = 0x46A,
642    AudioClickyOn = 0x46B,
643    AudioClickyOff = 0x46C,
644    AudioClickyUp = 0x46D,
645    AudioClickyDown = 0x46E,
646    AudioClickyReset = 0x46F,
647    MusicOn = 0x470,
648    MusicOff = 0x471,
649    MusicToggle = 0x472,
650    MusicModeNext = 0x473,
651    AudioVoiceNext = 0x474,
652    AudioVoicePrevious = 0x475,
653    // Steno keycodes, use 0x4F0 ~ 0x4FF
654    StenoBolt = 0x4F0,
655    StenoGemini = 0x4F1,
656    StenoComb = 0x4F2,
657    StenoCombMax = 0x4FC,
658    // Macro keycodes, use 0x500 ~ 0x5FF
659    Macro0 = 0x500,
660    Macro1 = 0x501,
661    Macro2 = 0x502,
662    Macro3 = 0x503,
663    Macro4 = 0x504,
664    Macro5 = 0x505,
665    Macro6 = 0x506,
666    Macro7 = 0x507,
667    Macro8 = 0x508,
668    Macro9 = 0x509,
669    Macro10 = 0x50A,
670    Macro11 = 0x50B,
671    Macro12 = 0x50C,
672    Macro13 = 0x50D,
673    Macro14 = 0x50E,
674    Macro15 = 0x50F,
675    Macro16 = 0x510,
676    Macro17 = 0x511,
677    Macro18 = 0x512,
678    Macro19 = 0x513,
679    Macro20 = 0x514,
680    Macro21 = 0x515,
681    Macro22 = 0x516,
682    Macro23 = 0x517,
683    Macro24 = 0x518,
684    Macro25 = 0x519,
685    Macro26 = 0x51A,
686    Macro27 = 0x51B,
687    Macro28 = 0x51C,
688    Macro29 = 0x51D,
689    Macro30 = 0x51E,
690    Macro31 = 0x51F,
691    // Backlight and RGB keycodes, uses 0x600 ~ 0x6FF
692    BacklightOn = 0x600,
693    BacklightOff = 0x601,
694    BacklightToggle = 0x602,
695    BacklightDown = 0x603,
696    BacklightUp = 0x604,
697    BacklightStep = 0x605,
698    BacklightToggleBreathing = 0x606,
699    RgbTog = 0x620,
700    RgbModeForward = 0x621,
701    RgbModeReverse = 0x622,
702    RgbHui = 0x623,
703    RgbHud = 0x624,
704    RgbSai = 0x625,
705    RgbSad = 0x626,
706    RgbVai = 0x627,
707    RgbVad = 0x628,
708    RgbSpi = 0x629,
709    RgbSpd = 0x62A,
710    RgbModePlain = 0x62B,
711    RgbModeBreathe = 0x62C,
712    RgbModeRainbow = 0x62D,
713    RgbModeSwirl = 0x62E,
714    RgbModeSnake = 0x62F,
715    RgbModeKnight = 0x630,
716    RgbModeXmas = 0x631,
717    RgbModeGradient = 0x632,
718    // Not in vial
719    RgbModeRgbtest = 0x633,
720    RgbModeTwinkle = 0x634,
721    // Internal functional keycodes, use 0x700 ~ 0x7FF
722    Bootloader = 0x700,
723    Reboot = 0x701,
724    DebugToggle = 0x702,
725    ClearEeprom = 0x703,
726    Make = 0x704,
727    AutoShiftDown = 0x710,
728    AutoShiftUp = 0x711,
729    AutoShiftReport = 0x712,
730    AutoShiftOn = 0x713,
731    AutoShiftOff = 0x714,
732    AutoShiftToggle = 0x715,
733    GraveEscape = 0x716,
734    VelocikeyToggle = 0x717,
735    SpaceCadetLCtrlParenthesisOpen = 0x718,
736    SpaceCadetRCtrlParenthesisClose = 0x719,
737    SpaceCadetLShiftParenthesisOpen = 0x71A,
738    SpaceCadetRShiftParenthesisClose = 0x71B,
739    SpaceCadetLAltParenthesisOpen = 0x71C,
740    SpaceCadetRAltParenthesisClose = 0x71D,
741    SpaceCadetRShiftEnter = 0x71E,
742    OutputAuto = 0x720,
743    OutputUsb = 0x721,
744    OutputBluetooth = 0x722,
745    UnicodeModeNext = 0x730,
746    UnicodeModePrevious = 0x731,
747    UnicodeModeMacos = 0x732,
748    UnicodeModeLinux = 0x733,
749    UnicodeModeWindows = 0x734,
750    UnicodeModeBsd = 0x735,
751    UnicodeModeWincompose = 0x736,
752    UnicodeModeEmacs = 0x737,
753    HapticOn = 0x740,
754    HapticOff = 0x741,
755    HapticToggle = 0x742,
756    HapticReset = 0x743,
757    HapticFeedbackToggle = 0x744,
758    HapticBuzzToggle = 0x745,
759    HapticModeNext = 0x746,
760    HapticModePrevious = 0x747,
761    HapticContinuousToggle = 0x748,
762    HapticContinuousUp = 0x749,
763    HapticContinuousDown = 0x74A,
764    HapticDwellUp = 0x74B,
765    HapticDwellDown = 0x74C,
766    ComboOn = 0x750,
767    ComboOff = 0x751,
768    ComboToggle = 0x752,
769    DynamicMacroRecordStart1 = 0x753,
770    DynamicMacroRecordStart2 = 0x754,
771    DynamicMacroRecordStop = 0x755,
772    DynamicMacroPlay1 = 0x756,
773    DynamicMacroPlay2 = 0x757,
774    Leader = 0x758,
775    Lock = 0x759,
776    OneShotOn = 0x75A,
777    OneShotOff = 0x75B,
778    OneShotToggle = 0x75C,
779    KeyOverrideToggle = 0x75D,
780    KeyOverrideOn = 0x75E,
781    KeyOverrideOff = 0x75F,
782    SecureLock = 0x760,
783    SecureUnlock = 0x761,
784    SecureToggle = 0x762,
785    SecureRequest = 0x763,
786    DynamicTappingTermPrint = 0x770,
787    DynamicTappingTermUp = 0x771,
788    DynamicTappingTermDown = 0x772,
789    CapsWordToggle = 0x773,
790    AutocorrectOn = 0x774,
791    AutocorrectOff = 0x775,
792    AutocorrectToggle = 0x776,
793    TriLayerLower = 0x777,
794    TriLayerUpper = 0x778,
795    RepeatKey = 0x779,
796    AltRepeatKey = 0x77A,
797    // Kb keycodes, use 0x800 ~ 0x81F
798    Kb0 = 0x800,
799    Kb1 = 0x801,
800    Kb2 = 0x802,
801    Kb3 = 0x803,
802    Kb4 = 0x804,
803    Kb5 = 0x805,
804    Kb6 = 0x806,
805    Kb7 = 0x807,
806    Kb8 = 0x808,
807    Kb9 = 0x809,
808    Kb10 = 0x80A,
809    Kb11 = 0x80B,
810    Kb12 = 0x80C,
811    Kb13 = 0x80D,
812    Kb14 = 0x80E,
813    Kb15 = 0x80F,
814    Kb16 = 0x810,
815    Kb17 = 0x811,
816    Kb18 = 0x812,
817    Kb19 = 0x813,
818    Kb20 = 0x814,
819    Kb21 = 0x815,
820    Kb22 = 0x816,
821    Kb23 = 0x817,
822    Kb24 = 0x818,
823    Kb25 = 0x819,
824    Kb26 = 0x81A,
825    Kb27 = 0x81B,
826    Kb28 = 0x81C,
827    Kb29 = 0x81D,
828    Kb30 = 0x81E,
829    Kb31 = 0x81F,
830    // User keycodes, use 0x840 ~ 0x85F
831    User0 = 0x840,
832    User1 = 0x841,
833    User2 = 0x842,
834    User3 = 0x843,
835    User4 = 0x844,
836    User5 = 0x845,
837    User6 = 0x846,
838    User7 = 0x847,
839    User8 = 0x848,
840    User9 = 0x849,
841    User10 = 0x84A,
842    User11 = 0x84B,
843    User12 = 0x84C,
844    User13 = 0x84D,
845    User14 = 0x84E,
846    User15 = 0x84F,
847    User16 = 0x850,
848    User17 = 0x851,
849    User18 = 0x852,
850    User19 = 0x853,
851    User20 = 0x854,
852    User21 = 0x855,
853    User22 = 0x856,
854    User23 = 0x857,
855    User24 = 0x858,
856    User25 = 0x859,
857    User26 = 0x85A,
858    User27 = 0x85B,
859    User28 = 0x85C,
860    User29 = 0x85D,
861    User30 = 0x85E,
862    User31 = 0x85F,
863}
864
865// Manual Serialize/Deserialize implementation to avoid derive macro overhead
866// The derive macro on a large enum (~300 variants) generates ~7KB of code
867// Manual implementation serializes directly as u16 repr, saving significant space
868impl serde::Serialize for KeyCode {
869    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
870    where
871        S: serde::Serializer,
872    {
873        serializer.serialize_u16(*self as u16)
874    }
875}
876
877impl<'de> serde::Deserialize<'de> for KeyCode {
878    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
879    where
880        D: serde::Deserializer<'de>,
881    {
882        let value = u16::deserialize(deserializer)?;
883        // Use From<u16> trait which already handles invalid values by returning KeyCode::No
884        // This is more efficient than from_repr + ok_or_else
885        Ok(KeyCode::from(value))
886    }
887}
888
889impl KeyCode {
890    /// Returns `true` if the keycode is a simple keycode defined in HID spec
891    pub fn is_simple_key(self) -> bool {
892        KeyCode::No <= self && self <= KeyCode::MouseAccel2
893    }
894
895    /// Returns `true` if the keycode is a modifier keycode
896    pub fn is_modifier(self) -> bool {
897        KeyCode::LCtrl <= self && self <= KeyCode::RGui
898    }
899
900    /// Returns `true` if the keycode is basic keycode
901    /// The basic keycode = simple key + modifier
902    pub fn is_basic(self) -> bool {
903        KeyCode::No <= self && self <= KeyCode::RGui
904    }
905
906    /// Returns `true` if the keycode is a letter
907    pub fn is_letter(self) -> bool {
908        KeyCode::A <= self && self <= KeyCode::Z
909    }
910
911    /// Returns the byte with the bit corresponding to the USB HID
912    /// modifier bitfield set.
913    pub fn to_hid_modifiers(self) -> ModifierCombination {
914        match self {
915            KeyCode::LCtrl => ModifierCombination::new().with_left_ctrl(true),
916            KeyCode::LShift => ModifierCombination::new().with_left_shift(true),
917            KeyCode::LAlt => ModifierCombination::new().with_left_alt(true),
918            KeyCode::LGui => ModifierCombination::new().with_left_gui(true),
919            KeyCode::RCtrl => ModifierCombination::new().with_right_ctrl(true),
920            KeyCode::RShift => ModifierCombination::new().with_right_shift(true),
921            KeyCode::RAlt => ModifierCombination::new().with_right_alt(true),
922            KeyCode::RGui => ModifierCombination::new().with_right_gui(true),
923            _ => ModifierCombination::new(),
924        }
925    }
926
927    /// Returns `true` if the keycode is a system keycode
928    pub fn is_system(self) -> bool {
929        KeyCode::SystemPower <= self && self <= KeyCode::SystemWake
930    }
931
932    /// Returns `true` if the keycode is a keycode in consumer page
933    pub fn is_consumer(self) -> bool {
934        KeyCode::AudioMute <= self && self <= KeyCode::Launchpad
935    }
936
937    /// Returns `true` if the keycode is a mouse keycode
938    pub fn is_mouse_key(self) -> bool {
939        KeyCode::MouseUp <= self && self <= KeyCode::MouseAccel2
940    }
941
942    /// Returns `true` if the keycode is a magic keycode
943    pub fn is_magic(self) -> bool {
944        KeyCode::MagicSwapControlCapsLock <= self && self <= KeyCode::MagicToggleEscapeCapsLock
945    }
946
947    /// Returns `true` if the keycode is a midi keycode
948    pub fn is_midi(self) -> bool {
949        KeyCode::MidiOn <= self && self <= KeyCode::MidiPitchBendUp
950    }
951
952    /// Returns `true` if the keycode is a sequencer keycode
953    pub fn is_sequencer(self) -> bool {
954        KeyCode::SequencerOn <= self && self <= KeyCode::SequencerStepsClear
955    }
956
957    /// Returns `true` if the keycode is a joystick keycode
958    pub fn is_joystick(self) -> bool {
959        KeyCode::JoystickButton0 <= self && self <= KeyCode::JoystickButton31
960    }
961
962    /// Returns `true` if the keycode is a programmable button keycode
963    pub fn is_programmable_button(self) -> bool {
964        KeyCode::ProgrammableButton1 <= self && self <= KeyCode::ProgrammableButton32
965    }
966
967    /// Returns `true` if the keycode is a audio keycode
968    /// Note: Basic audio keycodes are not included
969    pub fn is_audio(self) -> bool {
970        KeyCode::AudioOn <= self && self <= KeyCode::AudioVoicePrevious
971    }
972
973    /// Returns `true` if the keycode is a steno keycode
974    pub fn is_steno(self) -> bool {
975        KeyCode::StenoBolt <= self && self <= KeyCode::StenoCombMax
976    }
977
978    /// Returns `true` if the keycode is a macro keycode
979    pub fn is_macro(self) -> bool {
980        KeyCode::Macro0 <= self && self <= KeyCode::Macro31
981    }
982
983    /// Returns `true` if the keycode is a backlight keycode
984    pub fn is_backlight(self) -> bool {
985        KeyCode::BacklightOn <= self && self <= KeyCode::BacklightToggleBreathing
986    }
987
988    /// Returns `true` if the keycode is a rgb keycode
989    pub fn is_rgb(self) -> bool {
990        KeyCode::RgbTog <= self && self <= KeyCode::RgbModeTwinkle
991    }
992
993    /// Returns `true` if the keycode is defined by rmk to achieve special functionalities, such as reboot keyboard, goto bootloader, etc.
994    pub fn is_rmk(self) -> bool {
995        KeyCode::Bootloader <= self && self <= KeyCode::AltRepeatKey
996    }
997
998    /// Returns `true` if the keycode is a combo keycode
999    pub fn is_combo(self) -> bool {
1000        KeyCode::ComboOn <= self && self <= KeyCode::ComboToggle
1001    }
1002
1003    /// Returns `true` if the keycode is a boot keycode
1004    pub fn is_boot(self) -> bool {
1005        KeyCode::Bootloader <= self && self <= KeyCode::Reboot
1006    }
1007
1008    /// Returns `true` if the keycode is a kb keycode
1009    pub fn is_kb(self) -> bool {
1010        KeyCode::Kb0 <= self && self <= KeyCode::Kb31
1011    }
1012
1013    /// Returns `true` if the keycode is a user keycode
1014    pub fn is_user(self) -> bool {
1015        KeyCode::User0 <= self && self <= KeyCode::User31
1016    }
1017
1018    /// Convert a keycode to macro number
1019    pub fn as_macro_index(self) -> Option<u8> {
1020        if self.is_macro() {
1021            Some((self as u16 & 0x1F) as u8)
1022        } else {
1023            None
1024        }
1025    }
1026
1027    /// Does current keycode continues Caps Word?
1028    pub fn is_caps_word_continue_key(self) -> bool {
1029        if self >= KeyCode::A && self <= KeyCode::Z {
1030            return true;
1031        }
1032        if self >= KeyCode::Kc1 && self <= KeyCode::Kc0 {
1033            return true;
1034        }
1035        if self == KeyCode::Minus || self == KeyCode::Backspace || self == KeyCode::Delete {
1036            return true;
1037        }
1038        false
1039    }
1040
1041    /// Does current keycode is to be shifted by Caps Word?
1042    pub fn is_caps_word_shifted_key(self) -> bool {
1043        if self >= KeyCode::A && self <= KeyCode::Z {
1044            return true;
1045        }
1046        if self == KeyCode::Minus {
1047            return true;
1048        }
1049        false
1050    }
1051
1052    /// Convert a keycode to usb hid media key
1053    pub fn as_consumer_control_usage_id(self) -> ConsumerKey {
1054        match self {
1055            KeyCode::AudioMute => ConsumerKey::Mute,
1056            KeyCode::AudioVolUp => ConsumerKey::VolumeIncrement,
1057            KeyCode::AudioVolDown => ConsumerKey::VolumeDecrement,
1058            KeyCode::MediaNextTrack => ConsumerKey::NextTrack,
1059            KeyCode::MediaPrevTrack => ConsumerKey::PrevTrack,
1060            KeyCode::MediaStop => ConsumerKey::StopPlay,
1061            KeyCode::MediaPlayPause => ConsumerKey::PlayPause,
1062            KeyCode::MediaSelect => ConsumerKey::Record,
1063            KeyCode::MediaEject => ConsumerKey::Eject,
1064            KeyCode::Mail => ConsumerKey::Email,
1065            KeyCode::Calculator => ConsumerKey::Calculator,
1066            KeyCode::MyComputer => ConsumerKey::LocalBrowser,
1067            KeyCode::WwwSearch => ConsumerKey::Search,
1068            KeyCode::WwwHome => ConsumerKey::Home,
1069            KeyCode::WwwBack => ConsumerKey::Back,
1070            KeyCode::WwwForward => ConsumerKey::Forward,
1071            KeyCode::WwwStop => ConsumerKey::Stop,
1072            KeyCode::WwwRefresh => ConsumerKey::Refresh,
1073            KeyCode::WwwFavorites => ConsumerKey::Bookmarks,
1074            KeyCode::MediaFastForward => ConsumerKey::FastForward,
1075            KeyCode::MediaRewind => ConsumerKey::Rewind,
1076            KeyCode::BrightnessUp => ConsumerKey::BrightnessUp,
1077            KeyCode::BrightnessDown => ConsumerKey::BrightnessDown,
1078            KeyCode::ControlPanel => ConsumerKey::ControlPanel,
1079            KeyCode::Assistant => ConsumerKey::Assistant,
1080            KeyCode::MissionControl => ConsumerKey::DesktopShowAllWindows,
1081            KeyCode::Launchpad => ConsumerKey::AcSoftKeyLeft,
1082            _ => ConsumerKey::No,
1083        }
1084    }
1085
1086    /// Convert a keycode to usb hid media key
1087    pub fn as_system_control_usage_id(self) -> Option<SystemControlKey> {
1088        match self {
1089            KeyCode::SystemPower => Some(SystemControlKey::PowerDown),
1090            KeyCode::SystemSleep => Some(SystemControlKey::Sleep),
1091            KeyCode::SystemWake => Some(SystemControlKey::WakeUp),
1092            _ => None,
1093        }
1094    }
1095}
1096
1097/// Convert a ascii chat to keycode
1098/// bool, if the keycode should be shifted
1099/// assumes en-us keyboard mapping
1100pub fn from_ascii(ascii: u8) -> (KeyCode, bool) {
1101    match ascii {
1102        b'0' => (KeyCode::Kc0, false),
1103        b'1' => (KeyCode::Kc1, false),
1104        b'2' => (KeyCode::Kc2, false),
1105        b'3' => (KeyCode::Kc3, false),
1106        b'4' => (KeyCode::Kc4, false),
1107        b'5' => (KeyCode::Kc5, false),
1108        b'6' => (KeyCode::Kc6, false),
1109        b'7' => (KeyCode::Kc7, false),
1110        b'8' => (KeyCode::Kc8, false),
1111        b'9' => (KeyCode::Kc9, false),
1112        b'a' => (KeyCode::A, false),
1113        b'b' => (KeyCode::B, false),
1114        b'c' => (KeyCode::C, false),
1115        b'd' => (KeyCode::D, false),
1116        b'e' => (KeyCode::E, false),
1117        b'f' => (KeyCode::F, false),
1118        b'g' => (KeyCode::G, false),
1119        b'h' => (KeyCode::H, false),
1120        b'i' => (KeyCode::I, false),
1121        b'j' => (KeyCode::J, false),
1122        b'k' => (KeyCode::K, false),
1123        b'l' => (KeyCode::L, false),
1124        b'm' => (KeyCode::M, false),
1125        b'n' => (KeyCode::N, false),
1126        b'o' => (KeyCode::O, false),
1127        b'p' => (KeyCode::P, false),
1128        b'q' => (KeyCode::Q, false),
1129        b'r' => (KeyCode::R, false),
1130        b's' => (KeyCode::S, false),
1131        b't' => (KeyCode::T, false),
1132        b'u' => (KeyCode::U, false),
1133        b'v' => (KeyCode::V, false),
1134        b'w' => (KeyCode::W, false),
1135        b'x' => (KeyCode::X, false),
1136        b'y' => (KeyCode::Y, false),
1137        b'z' => (KeyCode::Z, false),
1138        b'A' => (KeyCode::A, true),
1139        b'B' => (KeyCode::B, true),
1140        b'C' => (KeyCode::C, true),
1141        b'D' => (KeyCode::D, true),
1142        b'E' => (KeyCode::E, true),
1143        b'F' => (KeyCode::F, true),
1144        b'G' => (KeyCode::G, true),
1145        b'H' => (KeyCode::H, true),
1146        b'I' => (KeyCode::I, true),
1147        b'J' => (KeyCode::J, true),
1148        b'K' => (KeyCode::K, true),
1149        b'L' => (KeyCode::L, true),
1150        b'M' => (KeyCode::M, true),
1151        b'N' => (KeyCode::N, true),
1152        b'O' => (KeyCode::O, true),
1153        b'P' => (KeyCode::P, true),
1154        b'Q' => (KeyCode::Q, true),
1155        b'R' => (KeyCode::R, true),
1156        b'S' => (KeyCode::S, true),
1157        b'T' => (KeyCode::T, true),
1158        b'U' => (KeyCode::U, true),
1159        b'V' => (KeyCode::V, true),
1160        b'W' => (KeyCode::W, true),
1161        b'X' => (KeyCode::X, true),
1162        b'Y' => (KeyCode::Y, true),
1163        b'Z' => (KeyCode::Z, true),
1164        b'!' => (KeyCode::Kc1, true),
1165        b'@' => (KeyCode::Kc2, true),
1166        b'#' => (KeyCode::Kc3, true),
1167        b'$' => (KeyCode::Kc4, true),
1168        b'%' => (KeyCode::Kc5, true),
1169        b'^' => (KeyCode::Kc6, true),
1170        b'&' => (KeyCode::Kc7, true),
1171        b'*' => (KeyCode::Kc8, true),
1172        b'(' => (KeyCode::Kc9, true),
1173        b')' => (KeyCode::Kc0, true),
1174        b'-' => (KeyCode::Minus, false),
1175        b'_' => (KeyCode::Minus, true),
1176        b'=' => (KeyCode::Equal, false),
1177        b'+' => (KeyCode::Equal, true),
1178        b'[' => (KeyCode::LeftBracket, false),
1179        b']' => (KeyCode::RightBracket, false),
1180        b'{' => (KeyCode::LeftBracket, true),
1181        b'}' => (KeyCode::RightBracket, true),
1182        b';' => (KeyCode::Semicolon, false),
1183        b':' => (KeyCode::Semicolon, true),
1184        b'\'' => (KeyCode::Quote, false),
1185        b'"' => (KeyCode::Quote, true),
1186        b'`' => (KeyCode::Grave, false),
1187        b'~' => (KeyCode::Grave, true),
1188        b'\\' => (KeyCode::Backslash, false),
1189        b'|' => (KeyCode::Backslash, true),
1190        b',' => (KeyCode::Comma, false),
1191        b'<' => (KeyCode::Comma, true),
1192        b'.' => (KeyCode::Dot, false),
1193        b'>' => (KeyCode::Dot, true),
1194        b'/' => (KeyCode::Slash, false),
1195        b'?' => (KeyCode::Slash, true),
1196        b' ' => (KeyCode::Space, false),
1197        b'\n' => (KeyCode::Enter, false),
1198        b'\t' => (KeyCode::Tab, false),
1199        b'\x08' => (KeyCode::Backspace, false),
1200        b'\x1B' => (KeyCode::Escape, false),
1201        b'\x7F' => (KeyCode::Delete, false),
1202        _ => (KeyCode::No, false),
1203    }
1204}
1205
1206/// Convert a ascii chat to keycode
1207/// assumes en-us keyboard mapping
1208pub fn to_ascii(keycode: KeyCode, shifted: bool) -> u8 {
1209    match (keycode, shifted) {
1210        (KeyCode::Kc0, false) => b'0',
1211        (KeyCode::Kc1, false) => b'1',
1212        (KeyCode::Kc2, false) => b'2',
1213        (KeyCode::Kc3, false) => b'3',
1214        (KeyCode::Kc4, false) => b'4',
1215        (KeyCode::Kc5, false) => b'5',
1216        (KeyCode::Kc6, false) => b'6',
1217        (KeyCode::Kc7, false) => b'7',
1218        (KeyCode::Kc8, false) => b'8',
1219        (KeyCode::Kc9, false) => b'9',
1220        (KeyCode::A, false) => b'a',
1221        (KeyCode::B, false) => b'b',
1222        (KeyCode::C, false) => b'c',
1223        (KeyCode::D, false) => b'd',
1224        (KeyCode::E, false) => b'e',
1225        (KeyCode::F, false) => b'f',
1226        (KeyCode::G, false) => b'g',
1227        (KeyCode::H, false) => b'h',
1228        (KeyCode::I, false) => b'i',
1229        (KeyCode::J, false) => b'j',
1230        (KeyCode::K, false) => b'k',
1231        (KeyCode::L, false) => b'l',
1232        (KeyCode::M, false) => b'm',
1233        (KeyCode::N, false) => b'n',
1234        (KeyCode::O, false) => b'o',
1235        (KeyCode::P, false) => b'p',
1236        (KeyCode::Q, false) => b'q',
1237        (KeyCode::R, false) => b'r',
1238        (KeyCode::S, false) => b's',
1239        (KeyCode::T, false) => b't',
1240        (KeyCode::U, false) => b'u',
1241        (KeyCode::V, false) => b'v',
1242        (KeyCode::W, false) => b'w',
1243        (KeyCode::X, false) => b'x',
1244        (KeyCode::Y, false) => b'y',
1245        (KeyCode::Z, false) => b'z',
1246        (KeyCode::A, true) => b'A',
1247        (KeyCode::B, true) => b'B',
1248        (KeyCode::C, true) => b'C',
1249        (KeyCode::D, true) => b'D',
1250        (KeyCode::E, true) => b'E',
1251        (KeyCode::F, true) => b'F',
1252        (KeyCode::G, true) => b'G',
1253        (KeyCode::H, true) => b'H',
1254        (KeyCode::I, true) => b'I',
1255        (KeyCode::J, true) => b'J',
1256        (KeyCode::K, true) => b'K',
1257        (KeyCode::L, true) => b'L',
1258        (KeyCode::M, true) => b'M',
1259        (KeyCode::N, true) => b'N',
1260        (KeyCode::O, true) => b'O',
1261        (KeyCode::P, true) => b'P',
1262        (KeyCode::Q, true) => b'Q',
1263        (KeyCode::R, true) => b'R',
1264        (KeyCode::S, true) => b'S',
1265        (KeyCode::T, true) => b'T',
1266        (KeyCode::U, true) => b'U',
1267        (KeyCode::V, true) => b'V',
1268        (KeyCode::W, true) => b'W',
1269        (KeyCode::X, true) => b'X',
1270        (KeyCode::Y, true) => b'Y',
1271        (KeyCode::Z, true) => b'Z',
1272        (KeyCode::Kc1, true) => b'!',
1273        (KeyCode::Kc2, true) => b'@',
1274        (KeyCode::Kc3, true) => b'#',
1275        (KeyCode::Kc4, true) => b'$',
1276        (KeyCode::Kc5, true) => b'%',
1277        (KeyCode::Kc6, true) => b'^',
1278        (KeyCode::Kc7, true) => b'&',
1279        (KeyCode::Kc8, true) => b'*',
1280        (KeyCode::Kc9, true) => b'(',
1281        (KeyCode::Kc0, true) => b')',
1282        (KeyCode::Minus, false) => b'-',
1283        (KeyCode::Minus, true) => b'_',
1284        (KeyCode::Equal, false) => b'=',
1285        (KeyCode::Equal, true) => b'+',
1286        (KeyCode::LeftBracket, false) => b'[',
1287        (KeyCode::RightBracket, false) => b']',
1288        (KeyCode::LeftBracket, true) => b'{',
1289        (KeyCode::RightBracket, true) => b'}',
1290        (KeyCode::Semicolon, false) => b';',
1291        (KeyCode::Semicolon, true) => b':',
1292        (KeyCode::Quote, false) => b'\'',
1293        (KeyCode::Quote, true) => b'"',
1294        (KeyCode::Grave, false) => b'`',
1295        (KeyCode::Grave, true) => b'~',
1296        (KeyCode::Backslash, true) => b'\\',
1297        (KeyCode::Backslash, false) => b'|',
1298        (KeyCode::Comma, false) => b',',
1299        (KeyCode::Comma, true) => b'<',
1300        (KeyCode::Dot, false) => b'.',
1301        (KeyCode::Dot, true) => b'>',
1302        (KeyCode::Slash, false) => b'/',
1303        (KeyCode::Slash, true) => b'?',
1304        (KeyCode::Space, false) => b' ',
1305        (KeyCode::Enter, false) => b'\n',
1306        (KeyCode::Tab, false) => b'\t',
1307        (KeyCode::Backspace, false) => b'\x08',
1308        (KeyCode::Escape, false) => b'\x1B',
1309        (KeyCode::Delete, false) => b'\x7F',
1310        // not supported keycodes
1311        (_, _) => b'X',
1312    }
1313}
1314
1315impl From<u16> for KeyCode {
1316    fn from(value: u16) -> Self {
1317        Self::from_repr(value).unwrap_or(Self::No)
1318    }
1319}
1320
1321/// Keys in consumer page
1322/// Ref: <https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf#page=75>
1323#[non_exhaustive]
1324#[repr(u16)]
1325#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, FromRepr)]
1326#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1327pub enum ConsumerKey {
1328    No = 0x00,
1329    // 15.5 Display Controls
1330    SnapShot = 0x65,
1331    /// <https://www.usb.org/sites/default/files/hutrr41_0.pdf>
1332    BrightnessUp = 0x6F,
1333    BrightnessDown = 0x70,
1334    // 15.7 Transport Controls
1335    Play = 0xB0,
1336    Pause = 0xB1,
1337    Record = 0xB2,
1338    FastForward = 0xB3,
1339    Rewind = 0xB4,
1340    NextTrack = 0xB5,
1341    PrevTrack = 0xB6,
1342    StopPlay = 0xB7,
1343    Eject = 0xB8,
1344    RandomPlay = 0xB9,
1345    Repeat = 0xBC,
1346    StopEject = 0xCC,
1347    PlayPause = 0xCD,
1348    // 15.9.1 Audio Controls - Volume
1349    Mute = 0xE2,
1350    VolumeIncrement = 0xE9,
1351    VolumeDecrement = 0xEA,
1352    Reserved = 0xEB,
1353    // 15.15 Application Launch Buttons
1354    Email = 0x18A,
1355    Calculator = 0x192,
1356    LocalBrowser = 0x194,
1357    Lock = 0x19E,
1358    ControlPanel = 0x19F,
1359    Assistant = 0x1CB,
1360    // 15.16 Generic GUI Application Controls
1361    New = 0x201,
1362    Open = 0x202,
1363    Close = 0x203,
1364    Exit = 0x204,
1365    Maximize = 0x205,
1366    Minimize = 0x206,
1367    Save = 0x207,
1368    Print = 0x208,
1369    Properties = 0x209,
1370    Undo = 0x21A,
1371    Copy = 0x21B,
1372    Cut = 0x21C,
1373    Paste = 0x21D,
1374    SelectAll = 0x21E,
1375    Find = 0x21F,
1376    Search = 0x221,
1377    Home = 0x223,
1378    Back = 0x224,
1379    Forward = 0x225,
1380    Stop = 0x226,
1381    Refresh = 0x227,
1382    Bookmarks = 0x22A,
1383    NextKeyboardLayoutSelect = 0x29D,
1384    DesktopShowAllWindows = 0x29F,
1385    AcSoftKeyLeft = 0x2A0,
1386}
1387
1388impl From<u16> for ConsumerKey {
1389    fn from(value: u16) -> Self {
1390        Self::from_repr(value).unwrap_or(Self::No)
1391    }
1392}
1393
1394/// Keys in `Generic Desktop Page`, generally used for system control
1395/// Ref: <https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf#page=26>
1396#[non_exhaustive]
1397#[repr(u16)]
1398#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, FromRepr)]
1399#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1400pub enum SystemControlKey {
1401    No = 0x00,
1402    PowerDown = 0x81,
1403    Sleep = 0x82,
1404    WakeUp = 0x83,
1405    Restart = 0x8F,
1406}
1407
1408impl From<u16> for SystemControlKey {
1409    fn from(value: u16) -> Self {
1410        Self::from_repr(value).unwrap_or(Self::No)
1411    }
1412}