Skip to content

Commit 6cb7c88

Browse files
committed
Split up the Keyboard type.
We now have separate types for decoding the PS/2 bitstream, processing Scan Codes into KeyEvents, and decoding KeyEvents according to the current layout. Also adds an 'AnyLayout' type which lets you swap layouts at run-time.
1 parent 549d49e commit 6cb7c88

File tree

12 files changed

+497
-183
lines changed

12 files changed

+497
-183
lines changed

src/layouts/azerty.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
1+
//! French keyboard support
2+
13
use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers};
24

5+
/// A standard French 102-key (or 105-key including Windows keys) keyboard.
6+
///
7+
/// The top row spells `AZERTY`.
8+
///
9+
/// Has a 2-row high Enter key, with Backslash next to the left shift (ISO format).
310
pub struct Azerty;
411

512
impl KeyboardLayout for Azerty {
613
fn map_keycode(
14+
&self,
715
keycode: KeyCode,
816
modifiers: &Modifiers,
917
handle_ctrl: HandleControl,
@@ -514,7 +522,11 @@ mod test {
514522

515523
#[test]
516524
fn test_frazert() {
517-
let mut k = Keyboard::<Azerty, ScancodeSet2>::new(HandleControl::MapLettersToUnicode);
525+
let mut k = Keyboard::new(
526+
ScancodeSet2::new(),
527+
Azerty,
528+
HandleControl::MapLettersToUnicode,
529+
);
518530
assert_eq!(
519531
k.process_keyevent(KeyEvent::new(KeyCode::NumpadDivide, KeyState::Down)),
520532
Some(DecodedKey::Unicode('/'))

src/layouts/colemak.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
//! A Colemak 101-key (or 104-key including Windows keys) keyboard.
2-
//! Has a 1-row high Enter key, with Backslash above.
1+
//! The Colemak keyboard support
32
43
use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers};
54

5+
/// A Colemak 101-key (or 104-key including Windows keys) keyboard.
6+
///
7+
/// Has a 1-row high Enter key, with Backslash above (ANSI layout).
68
pub struct Colemak;
79

810
impl KeyboardLayout for Colemak {
911
fn map_keycode(
12+
&self,
1013
keycode: KeyCode,
1114
modifiers: &Modifiers,
1215
handle_ctrl: HandleControl,

src/layouts/de104.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1-
use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers};
1+
//! German keyboard support
22
3-
pub use super::us104::Us104Key;
3+
use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers};
44

5-
pub struct De104Key;
5+
/// A standard German 102-key (or 105-key including Windows keys) keyboard.
6+
///
7+
/// The top row spells `QWERTZ`.
8+
///
9+
/// Has a 2-row high Enter key, with Backslash next to the left shift (ISO format).
10+
pub struct De105Key;
611

7-
impl KeyboardLayout for De104Key {
12+
impl KeyboardLayout for De105Key {
813
fn map_keycode(
14+
&self,
915
keycode: KeyCode,
1016
modifiers: &Modifiers,
1117
handle_ctrl: HandleControl,
@@ -214,8 +220,10 @@ impl KeyboardLayout for De104Key {
214220
DecodedKey::Unicode('<')
215221
}
216222
}
217-
218-
e => <super::Us104Key as KeyboardLayout>::map_keycode(e, modifiers, handle_ctrl),
223+
e => {
224+
let us = super::Us104Key;
225+
us.map_keycode(e, modifiers, handle_ctrl)
226+
}
219227
}
220228
}
221229
}

src/layouts/dvorak104.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
//! A Dvorak 101-key (or 104-key including Windows keys) keyboard.
2-
//! Has a 1-row high Enter key, with Backslash above.
1+
//! Dvorak keyboard support
32
43
use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers};
54

6-
pub use super::us104::Us104Key;
7-
5+
/// A Dvorak 101-key (or 104-key including Windows keys) keyboard.
6+
///
7+
/// Has a 1-row high Enter key, with Backslash above (ANSI layout).
88
pub struct Dvorak104Key;
99

1010
impl KeyboardLayout for Dvorak104Key {
1111
fn map_keycode(
12+
&self,
1213
keycode: KeyCode,
1314
modifiers: &Modifiers,
1415
handle_ctrl: HandleControl,
@@ -294,7 +295,10 @@ impl KeyboardLayout for Dvorak104Key {
294295
DecodedKey::Unicode('z')
295296
}
296297
}
297-
e => <super::Us104Key as KeyboardLayout>::map_keycode(e, modifiers, handle_ctrl),
298+
e => {
299+
let us = super::Us104Key;
300+
us.map_keycode(e, modifiers, handle_ctrl)
301+
}
298302
}
299303
}
300304
}

src/layouts/dvorak_programmer104.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
//! A Dvorak Programmer 101-key (or 104-key including Windows keys) keyboard.
2-
//! Has a 1-row high Enter key, with Backslash above.
1+
//! Dvorak Programmer keyboard support
32
43
use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers};
54

5+
/// A Dvorak Programmer 101-key (or 104-key including Windows keys) keyboard.
6+
///
7+
/// Has a 1-row high Enter key, with Backslash above (ANSI layout)
68
pub struct DVP104Key;
79

810
impl KeyboardLayout for DVP104Key {
911
fn map_keycode(
12+
&self,
1013
keycode: KeyCode,
1114
modifiers: &Modifiers,
1215
handle_ctrl: HandleControl,

src/layouts/jis109.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
/// A standard Japan 106-key (or 109-key including Windows keys) keyboard.
2-
/// Has a 2-row high Enter key, with Backslash above.
3-
use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers};
1+
//! JIS keyboard support
42
5-
pub use super::us104::Us104Key;
3+
use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers};
64

5+
/// A standard Japan 106-key (or 109-key including Windows keys) keyboard.
6+
///
7+
/// Has a small space bar, to fit in extra buttons.
78
pub struct Jis109Key;
89

910
impl KeyboardLayout for Jis109Key {
1011
fn map_keycode(
12+
&self,
1113
keycode: KeyCode,
1214
modifiers: &Modifiers,
1315
handle_ctrl: HandleControl,
@@ -140,7 +142,10 @@ impl KeyboardLayout for Jis109Key {
140142
DecodedKey::Unicode('^')
141143
}
142144
}
143-
e => <Us104Key as KeyboardLayout>::map_keycode(e, modifiers, handle_ctrl),
145+
e => {
146+
let us = super::Us104Key;
147+
us.map_keycode(e, modifiers, handle_ctrl)
148+
}
144149
}
145150
}
146151
}

src/layouts/mod.rs

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//!
33
//! We have one layout per file, but where two layouts are similar, you can
44
//! handle all the 'different' keys first, and then jump to another handler -
5-
//! see UK105 and US104 as an example of that.
5+
//! see [`Uk105Key`] and [`Us104Key`] as an example of that.
66
77
mod dvorak_programmer104;
88
pub use self::dvorak_programmer104::DVP104Key;
@@ -26,4 +26,81 @@ mod colemak;
2626
pub use self::colemak::Colemak;
2727

2828
mod de104;
29-
pub use self::de104::De104Key;
29+
pub use self::de104::De105Key;
30+
31+
/// A enum of all the supported keyboard layouts.
32+
pub enum AnyLayout {
33+
DVP104Key(DVP104Key),
34+
Dvorak104Key(Dvorak104Key),
35+
Us104Key(Us104Key),
36+
Uk105Key(Uk105Key),
37+
Jis109Key(Jis109Key),
38+
Azerty(Azerty),
39+
Colemak(Colemak),
40+
De105Key(De105Key),
41+
}
42+
43+
impl super::KeyboardLayout for AnyLayout {
44+
fn map_keycode(
45+
&self,
46+
keycode: super::KeyCode,
47+
modifiers: &super::Modifiers,
48+
handle_ctrl: super::HandleControl,
49+
) -> super::DecodedKey {
50+
match self {
51+
AnyLayout::DVP104Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl),
52+
AnyLayout::Dvorak104Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl),
53+
AnyLayout::Us104Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl),
54+
AnyLayout::Uk105Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl),
55+
AnyLayout::Jis109Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl),
56+
AnyLayout::Azerty(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl),
57+
AnyLayout::Colemak(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl),
58+
AnyLayout::De105Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl),
59+
}
60+
}
61+
}
62+
63+
impl super::KeyboardLayout for &AnyLayout {
64+
fn map_keycode(
65+
&self,
66+
keycode: super::KeyCode,
67+
modifiers: &super::Modifiers,
68+
handle_ctrl: super::HandleControl,
69+
) -> super::DecodedKey {
70+
match self {
71+
AnyLayout::DVP104Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl),
72+
AnyLayout::Dvorak104Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl),
73+
AnyLayout::Us104Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl),
74+
AnyLayout::Uk105Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl),
75+
AnyLayout::Jis109Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl),
76+
AnyLayout::Azerty(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl),
77+
AnyLayout::Colemak(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl),
78+
AnyLayout::De105Key(inner) => inner.map_keycode(keycode, modifiers, handle_ctrl),
79+
}
80+
}
81+
}
82+
83+
#[cfg(test)]
84+
mod test {
85+
use super::*;
86+
use crate::*;
87+
88+
#[test]
89+
fn test_any() {
90+
let mut decoder = EventDecoder::new(AnyLayout::Uk105Key(Uk105Key), HandleControl::Ignore);
91+
// Q gets you a 'q'
92+
let decoded = decoder.process_keyevent(KeyEvent {
93+
code: KeyCode::Q,
94+
state: KeyState::Down,
95+
});
96+
assert_eq!(decoded, Some(DecodedKey::Unicode('q')));
97+
// Swap the layout
98+
decoder.change_layout(AnyLayout::Azerty(Azerty));
99+
// Q gets you a 'a'
100+
let decoded = decoder.process_keyevent(KeyEvent {
101+
code: KeyCode::Q,
102+
state: KeyState::Down,
103+
});
104+
assert_eq!(decoded, Some(DecodedKey::Unicode('a')));
105+
}
106+
}

src/layouts/uk105.rs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
//! A standard United Kingdom 102-key (or 105-key including Windows keys) keyboard.
2-
//! Has a 2-row high Enter key, with Backslash next to the left shift.
1+
//! United Kingdom keyboard support
32
43
use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers};
54

6-
pub use super::us104::Us104Key;
7-
5+
/// A standard United Kingdom 102-key (or 105-key including Windows keys) keyboard.
6+
///
7+
/// Has a 2-row high Enter key, with Backslash next to the left shift (ISO format).
88
pub struct Uk105Key;
99

1010
impl KeyboardLayout for Uk105Key {
1111
fn map_keycode(
12+
&self,
1213
keycode: KeyCode,
1314
modifiers: &Modifiers,
1415
handle_ctrl: HandleControl,
@@ -67,7 +68,10 @@ impl KeyboardLayout for Uk105Key {
6768
DecodedKey::Unicode('\\')
6869
}
6970
}
70-
e => <super::Us104Key as KeyboardLayout>::map_keycode(e, modifiers, handle_ctrl),
71+
e => {
72+
let us = super::Us104Key;
73+
us.map_keycode(e, modifiers, handle_ctrl)
74+
}
7175
}
7276
}
7377
}
@@ -79,7 +83,11 @@ mod test {
7983

8084
#[test]
8185
fn test_hash() {
82-
let mut k = Keyboard::<Uk105Key, ScancodeSet2>::new(HandleControl::MapLettersToUnicode);
86+
let mut k = Keyboard::new(
87+
ScancodeSet2::new(),
88+
Uk105Key,
89+
HandleControl::MapLettersToUnicode,
90+
);
8391
// As seen on a UK 105 key Dell PS/2 keyboard when pressing `~#`
8492
let ev = k.add_byte(0x5D).unwrap().unwrap();
8593
let decoded_key = k.process_keyevent(ev);
@@ -88,7 +96,11 @@ mod test {
8896

8997
#[test]
9098
fn test_backslash() {
91-
let mut k = Keyboard::<Uk105Key, ScancodeSet2>::new(HandleControl::MapLettersToUnicode);
99+
let mut k = Keyboard::new(
100+
ScancodeSet2::new(),
101+
Uk105Key,
102+
HandleControl::MapLettersToUnicode,
103+
);
92104
// As seen on a UK 105 key Dell PS/2 keyboard when pressing `|\`
93105
let ev = k.add_byte(0x61).unwrap().unwrap();
94106
let decoded_key = k.process_keyevent(ev);
@@ -97,7 +109,11 @@ mod test {
97109

98110
#[test]
99111
fn test_tilde() {
100-
let mut k = Keyboard::<Uk105Key, ScancodeSet2>::new(HandleControl::MapLettersToUnicode);
112+
let mut k = Keyboard::new(
113+
ScancodeSet2::new(),
114+
Uk105Key,
115+
HandleControl::MapLettersToUnicode,
116+
);
101117
// As seen on a UK 105 key Dell PS/2 keyboard when pressing Shift and `~#`
102118
let ev = k.add_byte(0x12).unwrap().unwrap();
103119
let _ = k.process_keyevent(ev);
@@ -108,7 +124,11 @@ mod test {
108124

109125
#[test]
110126
fn test_pipe() {
111-
let mut k = Keyboard::<Uk105Key, ScancodeSet2>::new(HandleControl::MapLettersToUnicode);
127+
let mut k = Keyboard::new(
128+
ScancodeSet2::new(),
129+
Uk105Key,
130+
HandleControl::MapLettersToUnicode,
131+
);
112132
// As seen on a UK 105 key Dell PS/2 keyboard when pressing Shift and `|\`
113133
let ev = k.add_byte(0x12).unwrap().unwrap();
114134
let _ = k.process_keyevent(ev);

src/layouts/us104.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
//! A standard United States 101-key (or 104-key including Windows keys) keyboard.
2-
//! Has a 1-row high Enter key, with Backslash above.
1+
//! United States keyboard support
32
43
use crate::{DecodedKey, HandleControl, KeyCode, KeyboardLayout, Modifiers};
54

5+
/// A standard United States 101-key (or 104-key including Windows keys) keyboard.
6+
///
7+
/// Has a 1-row high Enter key, with Backslash above (ANSI layout).
68
pub struct Us104Key;
79

810
impl KeyboardLayout for Us104Key {
911
fn map_keycode(
12+
&self,
1013
keycode: KeyCode,
1114
modifiers: &Modifiers,
1215
handle_ctrl: HandleControl,

0 commit comments

Comments
 (0)