#![cfg_attr(not(test), no_std)]
pub mod layouts;
mod scancodes;
pub use crate::scancodes::{ScancodeSet1, ScancodeSet2};
#[derive(Debug)]
pub struct Keyboard<L, S>
where
S: ScancodeSet,
L: KeyboardLayout,
{
ps2_decoder: Ps2Decoder,
scancode_set: S,
event_decoder: EventDecoder<L>,
}
#[derive(Debug)]
pub struct Ps2Decoder {
register: u16,
num_bits: u8,
}
#[derive(Debug)]
pub struct EventDecoder<L>
where
L: KeyboardLayout,
{
handle_ctrl: HandleControl,
modifiers: Modifiers,
layout: L,
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum Error {
BadStartBit,
BadStopBit,
ParityError,
UnknownKeyCode,
#[doc(hidden)]
InvalidState,
}
#[derive(Debug, PartialEq, Eq, Copy, Clone, PartialOrd, Ord)]
#[repr(u8)]
pub enum KeyCode {
Escape,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
PrintScreen,
SysRq,
ScrollLock,
PauseBreak,
Oem8,
Key1,
Key2,
Key3,
Key4,
Key5,
Key6,
Key7,
Key8,
Key9,
Key0,
OemMinus,
OemPlus,
Backspace,
Insert,
Home,
PageUp,
NumpadLock,
NumpadDivide,
NumpadMultiply,
NumpadSubtract,
Tab,
Q,
W,
E,
R,
T,
Y,
U,
I,
O,
P,
Oem4,
Oem6,
Oem5,
Oem7,
Delete,
End,
PageDown,
Numpad7,
Numpad8,
Numpad9,
NumpadAdd,
CapsLock,
A,
S,
D,
F,
G,
H,
J,
K,
L,
Oem1,
Oem3,
Return,
Numpad4,
Numpad5,
Numpad6,
LShift,
Z,
X,
C,
V,
B,
N,
M,
OemComma,
OemPeriod,
Oem2,
RShift,
ArrowUp,
Numpad1,
Numpad2,
Numpad3,
NumpadEnter,
LControl,
LWin,
LAlt,
Spacebar,
RAltGr,
RWin,
Apps,
RControl,
ArrowLeft,
ArrowDown,
ArrowRight,
Numpad0,
NumpadPeriod,
Oem9,
Oem10,
Oem11,
Oem12,
Oem13,
PrevTrack,
NextTrack,
Mute,
Calculator,
Play,
Stop,
VolumeDown,
VolumeUp,
WWWHome,
PowerOnTestOk,
TooManyKeys,
RControl2,
RAlt2,
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum KeyState {
Up,
Down,
SingleShot,
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum HandleControl {
MapLettersToUnicode,
Ignore,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct KeyEvent {
pub code: KeyCode,
pub state: KeyState,
}
pub trait KeyboardLayout {
fn map_keycode(
&self,
keycode: KeyCode,
modifiers: &Modifiers,
handle_ctrl: HandleControl,
) -> DecodedKey;
}
pub trait ScancodeSet {
fn advance_state(&mut self, code: u8) -> Result<Option<KeyEvent>, Error>;
}
#[derive(Debug, Default)]
pub struct Modifiers {
pub lshift: bool,
pub rshift: bool,
pub lctrl: bool,
pub rctrl: bool,
pub numlock: bool,
pub capslock: bool,
pub alt_gr: bool,
pub rctrl2: bool,
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum DecodedKey {
RawKey(KeyCode),
Unicode(char),
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
enum DecodeState {
Start,
Extended,
Release,
ExtendedRelease,
Extended2,
Extended2Release,
}
const KEYCODE_BITS: u8 = 11;
const EXTENDED_KEY_CODE: u8 = 0xE0;
const EXTENDED2_KEY_CODE: u8 = 0xE1;
const KEY_RELEASE_CODE: u8 = 0xF0;
impl<L, S> Keyboard<L, S>
where
L: KeyboardLayout,
S: ScancodeSet,
{
pub const fn new(scancode_set: S, layout: L, handle_ctrl: HandleControl) -> Keyboard<L, S> {
Keyboard {
ps2_decoder: Ps2Decoder::new(),
scancode_set,
event_decoder: EventDecoder::new(layout, handle_ctrl),
}
}
pub fn set_ctrl_handling(&mut self, new_value: HandleControl) {
self.event_decoder.set_ctrl_handling(new_value);
}
pub const fn get_ctrl_handling(&self) -> HandleControl {
self.event_decoder.get_ctrl_handling()
}
pub fn clear(&mut self) {
self.ps2_decoder.clear();
}
pub fn add_word(&mut self, word: u16) -> Result<Option<KeyEvent>, Error> {
let byte = self.ps2_decoder.add_word(word)?;
self.add_byte(byte)
}
pub fn add_byte(&mut self, byte: u8) -> Result<Option<KeyEvent>, Error> {
self.scancode_set.advance_state(byte)
}
pub fn add_bit(&mut self, bit: bool) -> Result<Option<KeyEvent>, Error> {
if let Some(byte) = self.ps2_decoder.add_bit(bit)? {
self.scancode_set.advance_state(byte)
} else {
Ok(None)
}
}
pub fn process_keyevent(&mut self, ev: KeyEvent) -> Option<DecodedKey> {
self.event_decoder.process_keyevent(ev)
}
}
impl Ps2Decoder {
pub const fn new() -> Ps2Decoder {
Ps2Decoder {
register: 0,
num_bits: 0,
}
}
pub fn clear(&mut self) {
self.register = 0;
self.num_bits = 0;
}
pub fn add_bit(&mut self, bit: bool) -> Result<Option<u8>, Error> {
self.register |= (bit as u16) << self.num_bits;
self.num_bits += 1;
if self.num_bits == KEYCODE_BITS {
let word = self.register;
self.register = 0;
self.num_bits = 0;
let byte = Self::check_word(word)?;
Ok(Some(byte))
} else {
Ok(None)
}
}
pub fn add_word(&self, word: u16) -> Result<u8, Error> {
Self::check_word(word)
}
const fn check_word(word: u16) -> Result<u8, Error> {
let start_bit = Self::get_bit(word, 0);
let parity_bit = Self::get_bit(word, 9);
let stop_bit = Self::get_bit(word, 10);
let data = ((word >> 1) & 0xFF) as u8;
if start_bit {
return Err(Error::BadStartBit);
}
if !stop_bit {
return Err(Error::BadStopBit);
}
let need_parity = Self::has_even_number_bits(data);
if need_parity != parity_bit {
return Err(Error::ParityError);
}
Ok(data)
}
const fn get_bit(word: u16, offset: usize) -> bool {
((word >> offset) & 0x0001) != 0
}
const fn has_even_number_bits(data: u8) -> bool {
(data.count_ones() % 2) == 0
}
}
impl<L> EventDecoder<L>
where
L: KeyboardLayout,
{
pub const fn new(layout: L, handle_ctrl: HandleControl) -> EventDecoder<L> {
EventDecoder {
handle_ctrl,
modifiers: Modifiers {
lshift: false,
rshift: false,
lctrl: false,
rctrl: false,
numlock: true,
capslock: false,
alt_gr: false,
rctrl2: false,
},
layout,
}
}
pub fn set_ctrl_handling(&mut self, new_value: HandleControl) {
self.handle_ctrl = new_value;
}
pub const fn get_ctrl_handling(&self) -> HandleControl {
self.handle_ctrl
}
pub fn process_keyevent(&mut self, ev: KeyEvent) -> Option<DecodedKey> {
match ev {
KeyEvent {
code: KeyCode::LShift,
state: KeyState::Down,
} => {
self.modifiers.lshift = true;
Some(DecodedKey::RawKey(KeyCode::LShift))
}
KeyEvent {
code: KeyCode::RShift,
state: KeyState::Down,
} => {
self.modifiers.rshift = true;
Some(DecodedKey::RawKey(KeyCode::RShift))
}
KeyEvent {
code: KeyCode::LShift,
state: KeyState::Up,
} => {
self.modifiers.lshift = false;
None
}
KeyEvent {
code: KeyCode::RShift,
state: KeyState::Up,
} => {
self.modifiers.rshift = false;
None
}
KeyEvent {
code: KeyCode::CapsLock,
state: KeyState::Down,
} => {
self.modifiers.capslock = !self.modifiers.capslock;
Some(DecodedKey::RawKey(KeyCode::CapsLock))
}
KeyEvent {
code: KeyCode::NumpadLock,
state: KeyState::Down,
} => {
if self.modifiers.rctrl2 {
Some(DecodedKey::RawKey(KeyCode::PauseBreak))
} else {
self.modifiers.numlock = !self.modifiers.numlock;
Some(DecodedKey::RawKey(KeyCode::NumpadLock))
}
}
KeyEvent {
code: KeyCode::LControl,
state: KeyState::Down,
} => {
self.modifiers.lctrl = true;
Some(DecodedKey::RawKey(KeyCode::LControl))
}
KeyEvent {
code: KeyCode::LControl,
state: KeyState::Up,
} => {
self.modifiers.lctrl = false;
None
}
KeyEvent {
code: KeyCode::RControl,
state: KeyState::Down,
} => {
self.modifiers.rctrl = true;
Some(DecodedKey::RawKey(KeyCode::RControl))
}
KeyEvent {
code: KeyCode::RControl,
state: KeyState::Up,
} => {
self.modifiers.rctrl = false;
None
}
KeyEvent {
code: KeyCode::RAltGr,
state: KeyState::Down,
} => {
self.modifiers.alt_gr = true;
Some(DecodedKey::RawKey(KeyCode::RAltGr))
}
KeyEvent {
code: KeyCode::RAltGr,
state: KeyState::Up,
} => {
self.modifiers.alt_gr = false;
None
}
KeyEvent {
code: KeyCode::RControl2,
state: KeyState::Down,
} => {
self.modifiers.rctrl2 = true;
Some(DecodedKey::RawKey(KeyCode::RControl2))
}
KeyEvent {
code: KeyCode::RControl2,
state: KeyState::Up,
} => {
self.modifiers.rctrl2 = false;
None
}
KeyEvent {
code: c,
state: KeyState::Down,
} => Some(
self.layout
.map_keycode(c, &self.modifiers, self.handle_ctrl),
),
_ => None,
}
}
pub fn change_layout(&mut self, new_layout: L) {
self.layout = new_layout;
}
}
impl KeyEvent {
pub const fn new(code: KeyCode, state: KeyState) -> KeyEvent {
KeyEvent { code, state }
}
}
impl Modifiers {
pub const fn is_shifted(&self) -> bool {
self.lshift | self.rshift
}
pub const fn is_ctrl(&self) -> bool {
self.lctrl | self.rctrl
}
pub const fn is_caps(&self) -> bool {
(self.lshift | self.rshift) ^ self.capslock
}
}
#[cfg(test)]
mod test {
use super::*;
fn add_bytes<L, S>(keyboard: &mut Keyboard<L, S>, test_sequence: &[(u8, Option<KeyEvent>)])
where
L: KeyboardLayout,
S: ScancodeSet,
{
for (byte, expected_key) in test_sequence.iter().cloned() {
let result = keyboard.add_byte(byte);
assert_eq!(
result,
Ok(expected_key.clone()),
"0x{:02x} should have given {:?} not {:?}",
byte,
expected_key,
result
);
}
}
fn process_keyevents<L, S>(
keyboard: &mut Keyboard<L, S>,
test_sequence: &[(KeyEvent, Option<DecodedKey>)],
) where
L: KeyboardLayout,
S: ScancodeSet,
{
for (idx, (event, expected_decode)) in test_sequence.iter().cloned().enumerate() {
let result = keyboard.process_keyevent(event.clone());
assert_eq!(
result,
expected_decode.clone(),
"Entry {} {:?} should have given {:?} not {:?}",
idx,
event,
expected_decode,
result
);
}
}
#[test]
fn test_f9() {
let mut k = Keyboard::new(
ScancodeSet2::new(),
layouts::Us104Key,
HandleControl::MapLettersToUnicode,
);
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(true), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(
k.add_bit(true),
Ok(Some(KeyEvent::new(KeyCode::F9, KeyState::Down)))
);
}
#[test]
fn test_f9_word() {
let mut k = Keyboard::new(
ScancodeSet2::new(),
layouts::Us104Key,
HandleControl::MapLettersToUnicode,
);
assert_eq!(
k.add_word(0x0402),
Ok(Some(KeyEvent::new(KeyCode::F9, KeyState::Down)))
);
}
#[test]
fn test_f9_byte() {
let mut k = Keyboard::new(
ScancodeSet2::new(),
layouts::Us104Key,
HandleControl::MapLettersToUnicode,
);
let test_sequence = [(0x01, Some(KeyEvent::new(KeyCode::F9, KeyState::Down)))];
add_bytes(&mut k, &test_sequence);
}
#[test]
fn test_keyup_keydown() {
let mut k = Keyboard::new(
ScancodeSet2::new(),
layouts::Us104Key,
HandleControl::MapLettersToUnicode,
);
let test_sequence = [
(0x01, Some(KeyEvent::new(KeyCode::F9, KeyState::Down))),
(0x01, Some(KeyEvent::new(KeyCode::F9, KeyState::Down))),
(0xF0, None),
(0x01, Some(KeyEvent::new(KeyCode::F9, KeyState::Up))),
];
add_bytes(&mut k, &test_sequence);
}
#[test]
fn test_f5() {
let mut k = Keyboard::new(
ScancodeSet2::new(),
layouts::Us104Key,
HandleControl::MapLettersToUnicode,
);
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(true), Ok(None));
assert_eq!(k.add_bit(true), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(true), Ok(None));
assert_eq!(
k.add_bit(true),
Ok(Some(KeyEvent::new(KeyCode::F5, KeyState::Down)))
);
}
#[test]
fn test_f5_up() {
let mut k = Keyboard::new(
ScancodeSet2::new(),
layouts::Us104Key,
HandleControl::MapLettersToUnicode,
);
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(true), Ok(None));
assert_eq!(k.add_bit(true), Ok(None));
assert_eq!(k.add_bit(true), Ok(None));
assert_eq!(k.add_bit(true), Ok(None));
assert_eq!(k.add_bit(true), Ok(None));
assert_eq!(k.add_bit(true), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(true), Ok(None));
assert_eq!(k.add_bit(true), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(false), Ok(None));
assert_eq!(k.add_bit(true), Ok(None));
assert_eq!(
k.add_bit(true),
Ok(Some(KeyEvent::new(KeyCode::F5, KeyState::Up)))
);
}
#[test]
fn test_shift() {
let mut k = Keyboard::new(
ScancodeSet2::new(),
layouts::Uk105Key,
HandleControl::MapLettersToUnicode,
);
let test_sequence = [
(
KeyEvent::new(KeyCode::LShift, KeyState::Down),
Some(DecodedKey::RawKey(KeyCode::LShift)),
),
(
KeyEvent::new(KeyCode::A, KeyState::Down),
Some(DecodedKey::Unicode('A')),
),
(KeyEvent::new(KeyCode::A, KeyState::Up), None),
(KeyEvent::new(KeyCode::LShift, KeyState::Up), None),
(
KeyEvent::new(KeyCode::A, KeyState::Down),
Some(DecodedKey::Unicode('a')),
),
(KeyEvent::new(KeyCode::A, KeyState::Up), None),
(
KeyEvent::new(KeyCode::RShift, KeyState::Down),
Some(DecodedKey::RawKey(KeyCode::RShift)),
),
(
KeyEvent::new(KeyCode::A, KeyState::Down),
Some(DecodedKey::Unicode('A')),
),
(KeyEvent::new(KeyCode::A, KeyState::Up), None),
(KeyEvent::new(KeyCode::RShift, KeyState::Up), None),
(
KeyEvent::new(KeyCode::CapsLock, KeyState::Down),
Some(DecodedKey::RawKey(KeyCode::CapsLock)),
),
(KeyEvent::new(KeyCode::CapsLock, KeyState::Up), None),
(
KeyEvent::new(KeyCode::X, KeyState::Down),
Some(DecodedKey::Unicode('X')),
),
(KeyEvent::new(KeyCode::X, KeyState::Up), None),
(
KeyEvent::new(KeyCode::RShift, KeyState::Down),
Some(DecodedKey::RawKey(KeyCode::RShift)),
),
(
KeyEvent::new(KeyCode::A, KeyState::Down),
Some(DecodedKey::Unicode('a')),
),
(KeyEvent::new(KeyCode::A, KeyState::Up), None),
(KeyEvent::new(KeyCode::RShift, KeyState::Up), None),
(
KeyEvent::new(KeyCode::Key1, KeyState::Down),
Some(DecodedKey::Unicode('1')),
),
(KeyEvent::new(KeyCode::Key1, KeyState::Up), None),
];
process_keyevents(&mut k, &test_sequence);
}
#[test]
fn test_ctrl() {
let mut k = Keyboard::new(
ScancodeSet2::new(),
layouts::Us104Key,
HandleControl::MapLettersToUnicode,
);
let test_sequence = [
(
KeyEvent::new(KeyCode::A, KeyState::Down),
Some(DecodedKey::Unicode('a')),
),
(KeyEvent::new(KeyCode::A, KeyState::Up), None),
(
KeyEvent::new(KeyCode::LControl, KeyState::Down),
Some(DecodedKey::RawKey(KeyCode::LControl)),
),
(
KeyEvent::new(KeyCode::A, KeyState::Down),
Some(DecodedKey::Unicode('\u{0001}')),
),
(KeyEvent::new(KeyCode::LControl, KeyState::Up), None),
(KeyEvent::new(KeyCode::A, KeyState::Up), None),
(
KeyEvent::new(KeyCode::A, KeyState::Down),
Some(DecodedKey::Unicode('a')),
),
(KeyEvent::new(KeyCode::A, KeyState::Up), None),
(
KeyEvent::new(KeyCode::RControl, KeyState::Down),
Some(DecodedKey::RawKey(KeyCode::RControl)),
),
(
KeyEvent::new(KeyCode::A, KeyState::Down),
Some(DecodedKey::Unicode('\u{0001}')),
),
(KeyEvent::new(KeyCode::RControl, KeyState::Up), None),
(KeyEvent::new(KeyCode::A, KeyState::Up), None),
];
process_keyevents(&mut k, &test_sequence);
}
#[test]
fn test_numlock() {
let mut k = Keyboard::new(
ScancodeSet2::new(),
layouts::Uk105Key,
HandleControl::MapLettersToUnicode,
);
let test_sequence = [
(
KeyEvent::new(KeyCode::Numpad0, KeyState::Down),
Some(DecodedKey::Unicode('0')),
),
(KeyEvent::new(KeyCode::Numpad0, KeyState::Up), None),
(
KeyEvent::new(KeyCode::NumpadLock, KeyState::Down),
Some(DecodedKey::RawKey(KeyCode::NumpadLock)),
),
(KeyEvent::new(KeyCode::NumpadLock, KeyState::Up), None),
(
KeyEvent::new(KeyCode::Numpad0, KeyState::Down),
Some(DecodedKey::RawKey(KeyCode::Insert)),
),
(KeyEvent::new(KeyCode::Numpad0, KeyState::Up), None),
];
process_keyevents(&mut k, &test_sequence);
}
#[test]
fn test_set_1_down_up_down() {
let mut k = Keyboard::new(
ScancodeSet1::new(),
layouts::Us104Key,
HandleControl::MapLettersToUnicode,
);
let test_sequence = [
(0x1e, Some(KeyEvent::new(KeyCode::A, KeyState::Down))),
(0x9e, Some(KeyEvent::new(KeyCode::A, KeyState::Up))),
(0x1f, Some(KeyEvent::new(KeyCode::S, KeyState::Down))),
];
add_bytes(&mut k, &test_sequence);
}
#[test]
fn test_set_1_ext_down_up_down() {
let mut k = Keyboard::new(
ScancodeSet1::new(),
layouts::Us104Key,
HandleControl::MapLettersToUnicode,
);
let test_sequence = [
(0xe0, None),
(
0x1c,
Some(KeyEvent::new(KeyCode::NumpadEnter, KeyState::Down)),
),
(0xe0, None),
(
0x9c,
Some(KeyEvent::new(KeyCode::NumpadEnter, KeyState::Up)),
),
];
add_bytes(&mut k, &test_sequence);
}
#[test]
fn test_set_2_poweron() {
let mut k = Keyboard::new(
ScancodeSet2::new(),
layouts::Us104Key,
HandleControl::MapLettersToUnicode,
);
let test_sequence = [(
0xAA,
Some(KeyEvent::new(KeyCode::PowerOnTestOk, KeyState::SingleShot)),
)];
add_bytes(&mut k, &test_sequence);
}
#[test]
fn test_set_2_toomanykeys() {
let mut k = Keyboard::new(
ScancodeSet2::new(),
layouts::Us104Key,
HandleControl::MapLettersToUnicode,
);
let test_sequence = [(
0x00,
Some(KeyEvent::new(KeyCode::TooManyKeys, KeyState::SingleShot)),
)];
add_bytes(&mut k, &test_sequence);
}
#[test]
fn test_set_2_down_up() {
let mut k = Keyboard::new(
ScancodeSet2::new(),
layouts::Us104Key,
HandleControl::MapLettersToUnicode,
);
let test_sequence = [
(0x29, Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Down))),
(0xF0, None),
(0x29, Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Up))),
(0x29, Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Down))),
(0xF0, None),
(0x29, Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Up))),
(0x29, Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Down))),
(0xF0, None),
(0x29, Some(KeyEvent::new(KeyCode::Spacebar, KeyState::Up))),
];
add_bytes(&mut k, &test_sequence);
}
#[test]
fn test_set_2_ext_down_up() {
let mut k = Keyboard::new(
ScancodeSet2::new(),
layouts::Us104Key,
HandleControl::MapLettersToUnicode,
);
let test_sequence = [
(0xE0, None),
(0x6C, Some(KeyEvent::new(KeyCode::Home, KeyState::Down))),
(0xE0, None),
(0xF0, None),
(0x6C, Some(KeyEvent::new(KeyCode::Home, KeyState::Up))),
];
add_bytes(&mut k, &test_sequence);
}
#[test]
fn test_pause_set1() {
let mut k = Keyboard::new(
ScancodeSet1::new(),
layouts::Uk105Key,
HandleControl::MapLettersToUnicode,
);
let test_sequence = [
(0xE1, None),
(
0x1D,
Some(KeyEvent {
code: KeyCode::RControl2,
state: KeyState::Down,
}),
),
(
0x45,
Some(KeyEvent {
code: KeyCode::NumpadLock,
state: KeyState::Down,
}),
),
(0xE1, None),
(
0x9D,
Some(KeyEvent {
code: KeyCode::RControl2,
state: KeyState::Up,
}),
),
(
0xC5,
Some(KeyEvent {
code: KeyCode::NumpadLock,
state: KeyState::Up,
}),
),
];
add_bytes(&mut k, &test_sequence);
}
#[test]
fn test_pause_set2() {
let mut k = Keyboard::new(
ScancodeSet2::new(),
layouts::Uk105Key,
HandleControl::MapLettersToUnicode,
);
let test_sequence = [
(0xE1, None),
(
0x14,
Some(KeyEvent {
code: KeyCode::RControl2,
state: KeyState::Down,
}),
),
(
0x77,
Some(KeyEvent {
code: KeyCode::NumpadLock,
state: KeyState::Down,
}),
),
(0xE1, None),
(0xF0, None),
(
0x14,
Some(KeyEvent {
code: KeyCode::RControl2,
state: KeyState::Up,
}),
),
(0xF0, None),
(
0x77,
Some(KeyEvent {
code: KeyCode::NumpadLock,
state: KeyState::Up,
}),
),
];
add_bytes(&mut k, &test_sequence);
}
#[test]
fn test_pause_events() {
let mut k = Keyboard::new(
ScancodeSet2::new(),
layouts::Uk105Key,
HandleControl::MapLettersToUnicode,
);
let test_sequence = [
(
KeyEvent {
code: KeyCode::RControl2,
state: KeyState::Down,
},
Some(DecodedKey::RawKey(KeyCode::RControl2)),
),
(
KeyEvent {
code: KeyCode::NumpadLock,
state: KeyState::Down,
},
Some(DecodedKey::RawKey(KeyCode::PauseBreak)),
),
(
KeyEvent {
code: KeyCode::RControl2,
state: KeyState::Up,
},
None,
),
(
KeyEvent {
code: KeyCode::NumpadLock,
state: KeyState::Up,
},
None,
),
];
process_keyevents(&mut k, &test_sequence);
}
#[test]
fn test_print_screen_set1() {
let mut k = Keyboard::new(
ScancodeSet1::new(),
layouts::Uk105Key,
HandleControl::MapLettersToUnicode,
);
let test_sequence = [
(0xE0, None),
(
0x2A,
Some(KeyEvent {
code: KeyCode::RAlt2,
state: KeyState::Down,
}),
),
(0xE0, None),
(
0x37,
Some(KeyEvent {
code: KeyCode::PrintScreen,
state: KeyState::Down,
}),
),
(0xE0, None),
(
0xB7,
Some(KeyEvent {
code: KeyCode::PrintScreen,
state: KeyState::Up,
}),
),
(0xE0, None),
(
0xAA,
Some(KeyEvent {
code: KeyCode::RAlt2,
state: KeyState::Up,
}),
),
];
add_bytes(&mut k, &test_sequence);
}
#[test]
fn test_print_screen_set2() {
let mut k = Keyboard::new(
ScancodeSet2::new(),
layouts::Uk105Key,
HandleControl::MapLettersToUnicode,
);
let test_sequence = [
(0xE0, None),
(
0x12,
Some(KeyEvent {
code: KeyCode::RAlt2,
state: KeyState::Down,
}),
),
(0xE0, None),
(
0x7C,
Some(KeyEvent {
code: KeyCode::PrintScreen,
state: KeyState::Down,
}),
),
(0xE0, None),
(0xF0, None),
(
0x7C,
Some(KeyEvent {
code: KeyCode::PrintScreen,
state: KeyState::Up,
}),
),
(0xE0, None),
(0xF0, None),
(
0x12,
Some(KeyEvent {
code: KeyCode::RAlt2,
state: KeyState::Up,
}),
),
];
add_bytes(&mut k, &test_sequence);
}
#[test]
fn test_print_screen_events() {
let mut k = Keyboard::new(
ScancodeSet2::new(),
layouts::Uk105Key,
HandleControl::MapLettersToUnicode,
);
let test_sequence = [
(
KeyEvent {
code: KeyCode::RAlt2,
state: KeyState::Down,
},
Some(DecodedKey::RawKey(KeyCode::RAlt2)),
),
(
KeyEvent {
code: KeyCode::PrintScreen,
state: KeyState::Down,
},
Some(DecodedKey::RawKey(KeyCode::PrintScreen)),
),
(
KeyEvent {
code: KeyCode::PrintScreen,
state: KeyState::Up,
},
None,
),
(
KeyEvent {
code: KeyCode::RAlt2,
state: KeyState::Up,
},
None,
),
];
process_keyevents(&mut k, &test_sequence);
}
}