major refactor of keyboard

This commit is contained in:
Elfein Landers 2022-02-01 23:42:09 -08:00
parent 016e94fedf
commit 28f11e33f1
8 changed files with 797 additions and 902 deletions

View file

@ -63,16 +63,16 @@ extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: InterruptStackFr
} }
extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) { extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) {
use crate::keyboard::{ use crate::keyboard::{
CustomLayout, CustomScanCodeSet, DecodedKey, DecodedKeyKind, HandleControl, KeyCode, CustomLayout, CustomScancodeSet, DecodedKey, DecodedKeyKind, HandleControl, KeyCode,
Keyboard, Keyboard,
}; };
use spin::Mutex; use spin::Mutex;
use x86_64::instructions::port::Port; use x86_64::instructions::port::Port;
lazy_static! { lazy_static! {
static ref KEYBOARD: Mutex<Keyboard<CustomLayout, CustomScanCodeSet>> = static ref KEYBOARD: Mutex<Keyboard<CustomLayout, CustomScancodeSet>> =
Mutex::new(Keyboard::new( Mutex::new(Keyboard::new(
CustomLayout::new_us104key(), CustomLayout::new_us104key(),
CustomScanCodeSet::default(), CustomScancodeSet::default(),
HandleControl::Ignore HandleControl::Ignore
)); ));
} }

View file

@ -7,8 +7,8 @@ use vga::writers::GraphicsWriter;
#[derive(Debug)] #[derive(Debug)]
pub struct ScreenSize { pub struct ScreenSize {
pub x: usize, pub x: usize,
pub y: usize, pub y: usize,
} }
const FONT_SCALE: f32 = 1.6; const FONT_SCALE: f32 = 1.6;
@ -21,244 +21,240 @@ lazy_static::lazy_static! {
} }
impl ScreenSize { impl ScreenSize {
pub fn new(x: usize, y: usize) -> Self { pub fn new(x: usize, y: usize) -> Self {
Self { x, y } Self { x, y }
} }
} }
pub enum GraphicsReturn { pub enum GraphicsReturn {
Ok, Ok,
ImproperScreenSize, ImproperScreenSize,
} }
pub struct ScreenBuffer { pub struct ScreenBuffer {
pub size: ScreenSize, pub size: ScreenSize,
pub clear_color: Rgba64, pub clear_color: Rgba64,
pub buff: Box<[Rgba64]>, // Vec<Rgba64>, pub buff: Box<[Rgba64]>, // Vec<Rgba64>,
} }
impl ScreenBuffer { impl ScreenBuffer {
// Add optional size later // Add optional size later
pub fn new(x: usize, y: usize) -> Self { pub fn new(x: usize, y: usize) -> Self {
Self { Self {
size: ScreenSize::new(x, y), size: ScreenSize::new(x, y),
clear_color: 0, clear_color: 0,
buff: vec![0u64; x * y].into_boxed_slice(), buff: vec![0u64; x * y].into_boxed_slice(),
} }
} }
pub fn draw_filled_circle(&mut self, cx: i32, cy: i32, radius: usize, color: Rgba64) { pub fn draw_filled_circle(&mut self, cx: i32, cy: i32, radius: usize, color: Rgba64) {
let r = radius as i32 * 2; let r = radius as i32 * 2;
for y in 0..640 { for y in 0..640 {
for x in 0..480 { for x in 0..480 {
let dx = cx - x as i32 * 2 - 1; let dx = cx - x as i32 * 2 - 1;
let dy = cy - y as i32 * 2 - 1; let dy = cy - y as i32 * 2 - 1;
if dx * dx + dy * dy <= r * r { if dx * dx + dy * dy <= r * r {
self.set_pixel(x, y, color); self.set_pixel(x, y, color);
}; };
}
}
}
#[inline]
pub fn set_pixel(&mut self, x: usize, y: usize, color: Rgba64) {
self.buff[y * self.size.x + x] = color;
}
pub fn clear(&mut self) {
self.buff = vec![0u64; self.buff.len()].into_boxed_slice();
}
pub fn blit(&mut self, _width: usize, _height: usize) {}
pub fn draw_filled_rect(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: Rgba64) {
for y in y1..y2 {
for x in x1..x2 {
self.set_pixel(x, y, color);
}
}
}
pub fn draw_unfilled_rect(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: Rgba64) {
// x1 y1 => x2 y1 => x2 y2 => x1 y2 => x1 y1
self.draw_line(x1, y1, x2, y1, color);
self.draw_line(x2, y1, x2, y2, color);
self.draw_line(x2, y2, x1, y2, color);
self.draw_line(x1, y2, x1, y1, color);
}
#[inline]
pub fn draw_line(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: Rgba64) {
let x = crate::graphics::get_coordinates(
x1.try_into().unwrap(),
y1.try_into().unwrap(),
x2.try_into().unwrap(),
y2.try_into().unwrap(),
);
for coord in x {
self.set_pixel(coord.0, coord.1, color);
}
}
pub fn shade(&mut self) {
for y in 0..100 {
for x in 0..100 {
let rgba_ret = evaluate_shader(x, y, self.buff[y * self.size.x + x]);
match rgba_ret {
Ok(pixel) => {
// info!("{:?}", pixel);
self.set_pixel(x, y, pixel);
}
Err(err) => error!("{}", err),
} }
} }
} }
#[inline] info!("Shaders done");
pub fn set_pixel(&mut self, x: usize, y: usize, color: Rgba64) { }
self.buff[y * self.size.x + x] = color;
}
pub fn clear(&mut self) { // TODO force clear
self.buff = vec![0u64; self.buff.len()].into_boxed_slice(); pub fn force_redraw(&mut self) {
} use shadeable::pixel_format::into_vga_16;
VGAE.lock().clear_screen(into_vga_16(self.clear_color));
}
pub fn blit(&mut self, _width: usize, _height: usize) {} /// Draw a glyph on the screen at the given position
pub fn draw_filled_rect(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: Rgba64) { ///
for y in y1..y2 { /// # Arguments
for x in x1..x2 { /// * `x` - the x position of the glyph
self.set_pixel(x, y, color); /// * `y` - the y position of the glyph
/// * `glyph` - the glyph to draw
/// * `color` - the color of the glyph
pub fn draw_char(&mut self, mut x: u32, mut y: u32, character: char, color: Rgba64) {
// trace!["Judy Hopps is thicc af"];
// let mode = *VGAE.lock();
// trace!["She got them bouncy bunny buns"];
let basic_multingual_plane = FontRef::try_from_slice(include_bytes!(
"../../../ableos/assets/fonts/unifont-14.0.01.ttf"
))
.unwrap();
let supplementary_multilingual_plane = FontRef::try_from_slice(include_bytes!(
"../../../ableos/assets/fonts/unifont_upper-14.0.01.ttf"
))
.unwrap();
// let mut has_char = false;
// for x in font.codepoint_ids() {
// if x.1 == character {
// has_char = true;
// break;
// }
// }
let in_supp_plane = character as u32 > 0xffff;
let plane = match in_supp_plane {
false => basic_multingual_plane,
true => supplementary_multilingual_plane,
};
match character {
'\n' => {
// x = 0;
// y += (GLYPH_HEIGHT * FONT_SCALE) as u32;
}
_ => {
let q_glyph: Glyph = plane.glyph_id(character).with_scale_and_position(
20.0 * FONT_SCALE,
ab_glyph::point(GLYPH_WIDTH * FONT_SCALE, GLYPH_HEIGHT * FONT_SCALE),
);
// elf: I don't know if GLYPH_HEIGHT is in the right units here. I'm just guessing.
if x as usize > self.size.x {
x = 0;
y += (GLYPH_HEIGHT * FONT_SCALE) as u32;
} }
}
}
pub fn draw_unfilled_rect(
&mut self,
x1: usize,
y1: usize,
x2: usize,
y2: usize,
color: Rgba64,
) {
// x1 y1 => x2 y1 => x2 y2 => x1 y2 => x1 y1
self.draw_line(x1, y1, x2, y1, color);
self.draw_line(x2, y1, x2, y2, color);
self.draw_line(x2, y2, x1, y2, color);
self.draw_line(x1, y2, x1, y1, color);
}
#[inline] if let Some(q) = plane.outline_glyph(q_glyph) {
pub fn draw_line(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: Rgba64) { q.draw(|gx, gy, c| {
let x = crate::graphics::get_coordinates( if c > 0.015 {
x1.try_into().unwrap(), let corner = q.px_bounds().min;
y1.try_into().unwrap(), self.set_pixel(
x2.try_into().unwrap(), gx as usize + corner.x as usize + x as usize,
y2.try_into().unwrap(), gy as usize + corner.y as usize + y as usize,
); color,
);
for coord in x { }
self.set_pixel(coord.0, coord.1, color); });
}
}
pub fn shade(&mut self) {
for y in 0..100 {
for x in 0..100 {
let rgba_ret = evaluate_shader(x, y, self.buff[y * self.size.x + x]);
match rgba_ret {
Ok(pixel) => {
// info!("{:?}", pixel);
self.set_pixel(x, y, pixel);
}
Err(err) => error!("{}", err),
}
} }
} }
}
info!("Shaders done"); }
}
// TODO force clear
pub fn force_redraw(&mut self) {
use shadeable::pixel_format::into_vga_16;
VGAE.lock().clear_screen(into_vga_16(self.clear_color));
}
/// Draw a glyph on the screen at the given position
///
/// # Arguments
/// * `x` - the x position of the glyph
/// * `y` - the y position of the glyph
/// * `glyph` - the glyph to draw
/// * `color` - the color of the glyph
pub fn draw_char(&mut self, mut x: u32, mut y: u32, character: char, color: Rgba64) {
// trace!["Judy Hopps is thicc af"];
// let mode = *VGAE.lock();
// trace!["She got them bouncy bunny buns"];
let basic_multingual_plane = FontRef::try_from_slice(include_bytes!(
"../../../ableos/assets/fonts/unifont-14.0.01.ttf"
))
.unwrap();
let supplementary_multilingual_plane = FontRef::try_from_slice(include_bytes!(
"../../../ableos/assets/fonts/unifont_upper-14.0.01.ttf"
))
.unwrap();
// let mut has_char = false;
// for x in font.codepoint_ids() {
// if x.1 == character {
// has_char = true;
// break;
// }
// }
let in_supp_plane = character as u32 > 0xffff;
let plane = match in_supp_plane {
false => basic_multingual_plane,
true => supplementary_multilingual_plane,
};
match character {
'\n' => {}
_ => {
let q_glyph: Glyph = plane.glyph_id(character).with_scale_and_position(
20.0 * FONT_SCALE,
ab_glyph::point(GLYPH_WIDTH * FONT_SCALE, GLYPH_HEIGHT * FONT_SCALE),
);
// elf: I don't know if GLYPH_HEIGHT is in the right units here. I'm just guessing.
if x as usize > self.size.x {
x = 0;
y += (GLYPH_HEIGHT * FONT_SCALE) as u32;
}
if let Some(q) = plane.outline_glyph(q_glyph) {
q.draw(|gx, gy, c| {
if c > 0.015 {
let corner = q.px_bounds().min;
self.set_pixel(
gx as usize + corner.x as usize + x as usize,
gy as usize + corner.y as usize + y as usize,
color,
);
}
});
}
}
}
}
} }
pub trait VgaBuffer { pub trait VgaBuffer {
fn copy_to_buffer(&self) -> GraphicsReturn; fn copy_to_buffer(&self) -> GraphicsReturn;
} }
impl VgaBuffer for ScreenBuffer { impl VgaBuffer for ScreenBuffer {
fn copy_to_buffer(&self) -> GraphicsReturn { fn copy_to_buffer(&self) -> GraphicsReturn {
let mode = VGAE.lock(); let mode = VGAE.lock();
for y in 0..self.size.y { for y in 0..self.size.y {
for x in 0..self.size.x { for x in 0..self.size.x {
use shadeable::pixel_format::into_vga_16; use shadeable::pixel_format::into_vga_16;
// let vga_color = get_color16(self.buff[y * self.size.x + x]); // let vga_color = get_color16(self.buff[y * self.size.x + x]);
let vga_color = into_vga_16(self.buff[y * self.size.x + x]); let vga_color = into_vga_16(self.buff[y * self.size.x + x]);
if into_vga_16(self.clear_color) != vga_color { if into_vga_16(self.clear_color) != vga_color {
mode.set_pixel(x, y, vga_color); mode.set_pixel(x, y, vga_color);
}
} }
} }
}
GraphicsReturn::Ok GraphicsReturn::Ok
} }
} }
pub fn get_coordinates(x1: i32, y1: i32, x2: i32, y2: i32) -> Vec<(usize, usize)> { pub fn get_coordinates(x1: i32, y1: i32, x2: i32, y2: i32) -> Vec<(usize, usize)> {
let mut coordinates: Vec<(usize, usize)> = vec![]; let mut coordinates: Vec<(usize, usize)> = vec![];
let dx: i32 = i32::abs(x2 - x1); let dx: i32 = i32::abs(x2 - x1);
let dy: i32 = i32::abs(y2 - y1); let dy: i32 = i32::abs(y2 - y1);
let sx: i32 = { let sx: i32 = {
if x1 < x2 { if x1 < x2 {
1 1
} else { } else {
-1 -1
} }
}; };
let sy: i32 = { let sy: i32 = {
if y1 < y2 { if y1 < y2 {
1 1
} else { } else {
-1 -1
} }
}; };
let mut error: i32 = (if dx > dy { dx } else { -dy }) / 2; let mut error: i32 = (if dx > dy { dx } else { -dy }) / 2;
let mut current_x: i32 = x1; let mut current_x: i32 = x1;
let mut current_y: i32 = y1; let mut current_y: i32 = y1;
loop { loop {
coordinates.push((current_x as usize, current_y as usize)); coordinates.push((current_x as usize, current_y as usize));
// info!("0 {:?}", (current_x, current_y)); // info!("0 {:?}", (current_x, current_y));
if current_x == x2 && current_y == y2 { if current_x == x2 && current_y == y2 {
break; break;
} }
let error2: i32 = error; let error2: i32 = error;
if error2 > -dx { if error2 > -dx {
error -= dy; error -= dy;
current_x += sx; current_x += sx;
} }
if error2 < dy { if error2 < dy {
error += dx; error += dx;
current_y += sy; current_y += sy;
} }
} }
coordinates coordinates
} }

View file

@ -1,623 +0,0 @@
#![allow(clippy::too_many_arguments)]
use super::*;
pub struct CustomScanCodeSet {
single_byte: [Option<KeyCode>; 256],
extended: [Option<KeyCode>; 256],
}
impl Default for CustomScanCodeSet {
fn default() -> Self {
Self::scancode_set1()
}
}
impl CustomScanCodeSet {
pub fn scancode_set1() -> Self {
let mut scancode_set = Self {
single_byte: [None; 256],
extended: [None; 256],
};
scancode_set.single_byte[0x01] = Some(KeyCode::Escape); // 01
scancode_set.single_byte[0x02] = Some(KeyCode::Key1); // 02
scancode_set.single_byte[0x03] = Some(KeyCode::Key2); // 03
scancode_set.single_byte[0x04] = Some(KeyCode::Key3); // 04
scancode_set.single_byte[0x05] = Some(KeyCode::Key4); // 05
scancode_set.single_byte[0x06] = Some(KeyCode::Key5); // 06
scancode_set.single_byte[0x07] = Some(KeyCode::Key6); // 07
scancode_set.single_byte[0x08] = Some(KeyCode::Key7); // 08
scancode_set.single_byte[0x09] = Some(KeyCode::Key8); // 09
scancode_set.single_byte[0x0A] = Some(KeyCode::Key9); // 0A
scancode_set.single_byte[0x0B] = Some(KeyCode::Key0); // 0B
scancode_set.single_byte[0x0C] = Some(KeyCode::Minus); // 0C
scancode_set.single_byte[0x0D] = Some(KeyCode::Equals); // 0D
scancode_set.single_byte[0x0E] = Some(KeyCode::Backspace); // 0E
scancode_set.single_byte[0x0F] = Some(KeyCode::Tab); // 0F
scancode_set.single_byte[0x10] = Some(KeyCode::Q); // 10
scancode_set.single_byte[0x11] = Some(KeyCode::W); // 11
scancode_set.single_byte[0x12] = Some(KeyCode::E); // 12
scancode_set.single_byte[0x13] = Some(KeyCode::R); // 13
scancode_set.single_byte[0x14] = Some(KeyCode::T); // 14
scancode_set.single_byte[0x15] = Some(KeyCode::Y); // 15
scancode_set.single_byte[0x16] = Some(KeyCode::U); // 16
scancode_set.single_byte[0x17] = Some(KeyCode::I); // 17
scancode_set.single_byte[0x18] = Some(KeyCode::O); // 18
scancode_set.single_byte[0x19] = Some(KeyCode::P); // 19
scancode_set.single_byte[0x1A] = Some(KeyCode::BracketSquareLeft); // 1A
scancode_set.single_byte[0x1B] = Some(KeyCode::BracketSquareRight); // 1B
scancode_set.single_byte[0x1C] = Some(KeyCode::Enter); // 1C
scancode_set.single_byte[0x1D] = Some(KeyCode::ControlLeft); // 1D
scancode_set.single_byte[0x1E] = Some(KeyCode::A); // 1E
scancode_set.single_byte[0x1F] = Some(KeyCode::S); // 1F
scancode_set.single_byte[0x20] = Some(KeyCode::D); // 20
scancode_set.single_byte[0x21] = Some(KeyCode::F); // 21
scancode_set.single_byte[0x22] = Some(KeyCode::G); // 22
scancode_set.single_byte[0x23] = Some(KeyCode::H); // 23
scancode_set.single_byte[0x24] = Some(KeyCode::J); // 24
scancode_set.single_byte[0x25] = Some(KeyCode::K); // 25
scancode_set.single_byte[0x26] = Some(KeyCode::L); // 26
scancode_set.single_byte[0x27] = Some(KeyCode::SemiColon); // 27
scancode_set.single_byte[0x28] = Some(KeyCode::Quote); // 28
scancode_set.single_byte[0x29] = Some(KeyCode::BackTick); // 29
scancode_set.single_byte[0x2A] = Some(KeyCode::ShiftLeft); // 2A
scancode_set.single_byte[0x2B] = Some(KeyCode::BackSlash); // 2B
scancode_set.single_byte[0x2C] = Some(KeyCode::Z); // 2C
scancode_set.single_byte[0x2D] = Some(KeyCode::X); // 2D
scancode_set.single_byte[0x2E] = Some(KeyCode::C); // 2E
scancode_set.single_byte[0x2F] = Some(KeyCode::V); // 2F
scancode_set.single_byte[0x30] = Some(KeyCode::B); // 30
scancode_set.single_byte[0x31] = Some(KeyCode::N); // 31
scancode_set.single_byte[0x32] = Some(KeyCode::M); // 32
scancode_set.single_byte[0x33] = Some(KeyCode::Comma); // 33
scancode_set.single_byte[0x34] = Some(KeyCode::Fullstop); // 34
scancode_set.single_byte[0x35] = Some(KeyCode::Slash); // 35
scancode_set.single_byte[0x36] = Some(KeyCode::ShiftRight); // 36
scancode_set.single_byte[0x37] = Some(KeyCode::NumpadStar); // 37
scancode_set.single_byte[0x38] = Some(KeyCode::AltLeft); // 38
scancode_set.single_byte[0x39] = Some(KeyCode::Spacebar); // 39
scancode_set.single_byte[0x3A] = Some(KeyCode::CapsLock); // 3A
scancode_set.single_byte[0x3B] = Some(KeyCode::F1); // 3B
scancode_set.single_byte[0x3C] = Some(KeyCode::F2); // 3C
scancode_set.single_byte[0x3D] = Some(KeyCode::F3); // 3D
scancode_set.single_byte[0x3E] = Some(KeyCode::F4); // 3E
scancode_set.single_byte[0x3F] = Some(KeyCode::F5); // 3F
scancode_set.single_byte[0x40] = Some(KeyCode::F6); // 40
scancode_set.single_byte[0x41] = Some(KeyCode::F7); // 41
scancode_set.single_byte[0x42] = Some(KeyCode::F8); // 42
scancode_set.single_byte[0x43] = Some(KeyCode::F9); // 43
scancode_set.single_byte[0x44] = Some(KeyCode::F10); // 44
scancode_set.single_byte[0x45] = Some(KeyCode::NumpadLock); // 45
scancode_set.single_byte[0x46] = Some(KeyCode::ScrollLock); // 46
scancode_set.single_byte[0x47] = Some(KeyCode::Numpad7); // 47
scancode_set.single_byte[0x48] = Some(KeyCode::Numpad8); // 48
scancode_set.single_byte[0x49] = Some(KeyCode::Numpad9); // 49
scancode_set.single_byte[0x4A] = Some(KeyCode::NumpadMinus); // 4A
scancode_set.single_byte[0x4B] = Some(KeyCode::Numpad4); // 4B
scancode_set.single_byte[0x4C] = Some(KeyCode::Numpad5); // 4C
scancode_set.single_byte[0x4D] = Some(KeyCode::Numpad6); // 4D
scancode_set.single_byte[0x4E] = Some(KeyCode::NumpadPlus); // 4E
scancode_set.single_byte[0x4F] = Some(KeyCode::Numpad1); // 4F
scancode_set.single_byte[0x50] = Some(KeyCode::Numpad2); // 50
scancode_set.single_byte[0x51] = Some(KeyCode::Numpad3); // 51
scancode_set.single_byte[0x52] = Some(KeyCode::Numpad0); // 52
scancode_set.single_byte[0x53] = Some(KeyCode::NumpadPeriod); // 53
// 0x54
// 0x55
// 0x56
scancode_set.single_byte[0x57] = Some(KeyCode::F11); // 57
scancode_set.single_byte[0x58] = Some(KeyCode::F12); // 58
for i in 0x81..=0xD8 {
scancode_set.single_byte[i] = scancode_set.single_byte[i - 0x80];
}
scancode_set.extended[0x10] = Some(KeyCode::PrevTrack); // E010
//0x11
//0x12
//0x13
//0x14
//0x15
//0x16
//0x17
//0x18
scancode_set.extended[0x19] = Some(KeyCode::NextTrack); // E019
//0x1A
//0x1B
scancode_set.extended[0x1C] = Some(KeyCode::NumpadEnter); // E01C
scancode_set.extended[0x1D] = Some(KeyCode::ControlRight); // E01D
//0x1E
//0x1F
scancode_set.extended[0x20] = Some(KeyCode::Mute); // E020
scancode_set.extended[0x21] = Some(KeyCode::Calculator); // E021
scancode_set.extended[0x22] = Some(KeyCode::Play); // E022
//0x23
scancode_set.extended[0x24] = Some(KeyCode::Stop); // E024
//0x25
//0x26
//0x27
//0x28
//0x29
//0x2A
//0x2B
//0x2C
//0x2D
scancode_set.extended[0x2E] = Some(KeyCode::VolumeDown); // E02E
//0x2F
scancode_set.extended[0x30] = Some(KeyCode::VolumeUp); // E030
//0x31
scancode_set.extended[0x32] = Some(KeyCode::WWWHome); // E032
//0x33
//0x34
scancode_set.extended[0x35] = Some(KeyCode::NumpadSlash); // E035
//0x36
//0x37
scancode_set.extended[0x38] = Some(KeyCode::AltRight); // E038
//0x39
//0x3A
//0x3B
//0x3C
//0x3D
//0x3E
//0x3F
//0x40
//0x41
//0x42
//0x43
//0x44
//0x45
//0x46
scancode_set.extended[0x47] = Some(KeyCode::Home); // E047
scancode_set.extended[0x48] = Some(KeyCode::ArrowUp); // E048
scancode_set.extended[0x49] = Some(KeyCode::PageUp); // E049
//0x4A
scancode_set.extended[0x4B] = Some(KeyCode::ArrowLeft); // E04B
//0x4C
scancode_set.extended[0x4D] = Some(KeyCode::ArrowRight); // E04D
//0x4E
scancode_set.extended[0x4F] = Some(KeyCode::End); // E04F
scancode_set.extended[0x50] = Some(KeyCode::ArrowDown); // E050
scancode_set.extended[0x51] = Some(KeyCode::PageDown); // E051
scancode_set.extended[0x52] = Some(KeyCode::Insert); // E052
scancode_set.extended[0x53] = Some(KeyCode::Delete); // E053
for i in 0x90..=0xED {
scancode_set.extended[i] = scancode_set.extended[i - 0x80];
}
scancode_set
}
pub fn scancode_set2() -> Self {
Self {
single_byte: [None; 256],
extended: [None; 256],
}
}
}
impl ScancodeSet for CustomScanCodeSet {
fn advance_state(&self, state: &mut DecodeState, code: u8) -> Result<Option<KeyEvent>, Error> {
match *state {
DecodeState::Start => {
match code {
EXTENDED_KEY_CODE => {
*state = DecodeState::Extended;
Ok(None)
}
0x80..=0xFF => {
// Release codes
Ok(Some(KeyEvent::new(
self.map_scancode(code - 0x80)?,
KeyState::Up,
)))
}
_ => {
// Normal codes
Ok(Some(KeyEvent::new(
self.map_scancode(code)?,
KeyState::Down,
)))
}
}
}
DecodeState::Extended => {
*state = DecodeState::Start;
match code {
0x80..=0xFF => {
// Extended Release codes
Ok(Some(KeyEvent::new(
self.map_extended_scancode(code - 0x80)?,
KeyState::Up,
)))
}
_ => {
// Normal release codes
Ok(Some(KeyEvent::new(
self.map_extended_scancode(code)?,
KeyState::Down,
)))
}
}
}
_ => {
// Can't get in to this state
unimplemented!();
}
}
}
fn map_scancode(&self, code: u8) -> Result<KeyCode, Error> {
if let Some(kc) = self.single_byte[code as usize] {
Ok(kc)
} else {
Err(Error::UnknownKeyCode)
}
}
fn map_extended_scancode(&self, code: u8) -> Result<KeyCode, Error> {
if let Some(kc) = self.extended[code as usize] {
Ok(kc)
} else {
Err(Error::UnknownKeyCode)
}
}
}
#[derive(Debug, Clone, Copy)]
pub enum LayoutEntry {
Regular {
unshifted: Option<DecodedKey>,
shifted: Option<DecodedKey>,
altgr: Option<DecodedKey>,
raw_unicode: Option<DecodedKey>,
},
Numlockable {
unshifted: Option<DecodedKey>,
shifted: Option<DecodedKey>,
locked: Option<DecodedKey>,
locked_shifted: Option<DecodedKey>,
},
Capslockable {
unshifted: Option<DecodedKey>,
shifted: Option<DecodedKey>,
locked: Option<DecodedKey>,
locked_shifted: Option<DecodedKey>,
altgr: Option<DecodedKey>,
raw_unicode: Option<DecodedKey>,
},
}
// Do not edit this file directly. Instead, create a `Keyboard` and modify that.
pub struct CustomLayout {
mapping: [LayoutEntry; 256],
}
impl Default for CustomLayout {
fn default() -> Self {
Self::new_us104key()
}
}
impl CustomLayout {
#[rustfmt::skip]
pub fn new_us104key() -> Self {
let mut mapping = Self {
mapping: [LayoutEntry::Regular { unshifted: None, shifted: None, altgr: None, raw_unicode: None }; 256],
};
mapping.set_ab_c(KeyCode::BackTick, Some('`'.into()), Some('~'.into()), None);
mapping.set_aa_a(KeyCode::Escape, Some('\x1B'.into()));
mapping.set_ab_n(KeyCode::Key0, Some('0'.into()), Some(')'.into()));
mapping.set_ab_n(KeyCode::Key1, Some('1'.into()), Some('!'.into()));
mapping.set_ab_n(KeyCode::Key2, Some('2'.into()), Some('@'.into()));
mapping.set_ab_n(KeyCode::Key3, Some('3'.into()), Some('#'.into()));
mapping.set_ab_n(KeyCode::Key4, Some('4'.into()), Some('$'.into()));
mapping.set_ab_n(KeyCode::Key5, Some('5'.into()), Some('%'.into()));
mapping.set_ab_n(KeyCode::Key6, Some('6'.into()), Some('^'.into()));
mapping.set_ab_n(KeyCode::Key7, Some('7'.into()), Some('&'.into()));
mapping.set_ab_n(KeyCode::Key8, Some('8'.into()), Some('*'.into()));
mapping.set_ab_n(KeyCode::Key9, Some('9'.into()), Some('('.into()));
mapping.set_ab_n(KeyCode::Minus, Some('-'.into()), Some('_'.into()));
mapping.set_ab_n(KeyCode::Equals, Some('='.into()), Some('+'.into()));
mapping.set_aa_a(KeyCode::Backspace,Some('\x08'.into()));
mapping.set_aa_a(KeyCode::Tab,Some('\x09'.into()));
mapping.set_abcd_e_letter(KeyCode::Q, Some('q'.into()), Some('Q'.into()), Some('Q'.into()),Some('q'.into()), Some('\u{0011}'.into()));
mapping.set_abcd_e_letter(KeyCode::W, Some('w'.into()), Some('W'.into()), Some('W'.into()),Some('w'.into()), Some('\u{0017}'.into()));
mapping.set_abcd_e_letter(KeyCode::E, Some('e'.into()), Some('E'.into()), Some('E'.into()),Some('e'.into()), Some('\u{0005}'.into()));
mapping.set_abcd_e_letter(KeyCode::R, Some('r'.into()), Some('R'.into()), Some('R'.into()),Some('r'.into()), Some('\u{0012}'.into()));
mapping.set_abcd_e_letter(KeyCode::T, Some('t'.into()), Some('T'.into()), Some('T'.into()),Some('t'.into()), Some('\u{0014}'.into()));
mapping.set_abcd_e_letter(KeyCode::Y, Some('y'.into()), Some('Y'.into()), Some('Y'.into()),Some('y'.into()), Some('\u{0019}'.into()));
mapping.set_abcd_e_letter(KeyCode::U, Some('u'.into()), Some('U'.into()), Some('U'.into()),Some('u'.into()), Some('\u{0015}'.into()));
mapping.set_abcd_e_letter(KeyCode::I, Some('i'.into()), Some('I'.into()), Some('I'.into()),Some('i'.into()), Some('\u{0009}'.into()));
mapping.set_abcd_e_letter(KeyCode::O, Some('o'.into()), Some('O'.into()), Some('O'.into()),Some('o'.into()), Some('\u{000F}'.into()));
mapping.set_abcd_e_letter(KeyCode::P, Some('p'.into()), Some('P'.into()), Some('P'.into()),Some('p'.into()), Some('\u{0010}'.into()));
mapping.set_abcd_e_letter(KeyCode::A, Some('a'.into()), Some('A'.into()), Some('A'.into()),Some('a'.into()), Some('\u{0001}'.into()));
mapping.set_abcd_e_letter(KeyCode::S, Some('s'.into()), Some('S'.into()), Some('S'.into()),Some('s'.into()), Some('\u{0013}'.into()));
mapping.set_abcd_e_letter(KeyCode::D, Some('d'.into()), Some('D'.into()), Some('D'.into()),Some('d'.into()), Some('\u{0004}'.into()));
mapping.set_abcd_e_letter(KeyCode::F, Some('f'.into()), Some('F'.into()), Some('F'.into()),Some('f'.into()), Some('\u{0006}'.into()));
mapping.set_abcd_e_letter(KeyCode::G, Some('g'.into()), Some('G'.into()), Some('G'.into()),Some('g'.into()), Some('\u{0007}'.into()));
mapping.set_abcd_e_letter(KeyCode::H, Some('h'.into()), Some('H'.into()), Some('H'.into()),Some('h'.into()), Some('\u{0008}'.into()));
mapping.set_abcd_e_letter(KeyCode::J, Some('j'.into()), Some('J'.into()), Some('J'.into()),Some('j'.into()), Some('\u{000A}'.into()));
mapping.set_abcd_e_letter(KeyCode::K, Some('k'.into()), Some('K'.into()), Some('K'.into()),Some('k'.into()), Some('\u{000B}'.into()));
mapping.set_abcd_e_letter(KeyCode::L, Some('l'.into()), Some('L'.into()), Some('L'.into()),Some('l'.into()), Some('\u{000C}'.into()));
mapping.set_abcd_e_letter(KeyCode::Z, Some('z'.into()), Some('Z'.into()), Some('Z'.into()),Some('z'.into()), Some('\u{001A}'.into()));
mapping.set_abcd_e_letter(KeyCode::X, Some('x'.into()), Some('X'.into()), Some('X'.into()),Some('x'.into()), Some('\u{0018}'.into()));
mapping.set_abcd_e_letter(KeyCode::C, Some('c'.into()), Some('C'.into()), Some('C'.into()),Some('c'.into()), Some('\u{0003}'.into()));
mapping.set_abcd_e_letter(KeyCode::V, Some('v'.into()), Some('V'.into()), Some('V'.into()),Some('v'.into()), Some('\u{0016}'.into()));
mapping.set_abcd_e_letter(KeyCode::B, Some('b'.into()), Some('B'.into()), Some('B'.into()),Some('b'.into()), Some('\u{0002}'.into()));
mapping.set_abcd_e_letter(KeyCode::N, Some('n'.into()), Some('N'.into()), Some('N'.into()),Some('n'.into()), Some('\u{000E}'.into()));
mapping.set_abcd_e_letter(KeyCode::M, Some('m'.into()), Some('M'.into()), Some('M'.into()),Some('m'.into()), Some('\u{000D}'.into()));
mapping.set_ab_n(KeyCode::BracketSquareLeft, Some('{'.into()), Some('['.into()));
mapping.set_ab_n(KeyCode::BracketSquareRight, Some('}'.into()), Some(']'.into()));
mapping.set_ab_n(KeyCode::BackSlash, Some('|'.into()), Some('\\'.into()));
mapping.set_ab_n(KeyCode::SemiColon, Some(';'.into()), Some(':'.into()));
mapping.set_ab_n(KeyCode::Quote, Some('\''.into()), Some('"'.into()));
mapping.set_aa_a(KeyCode::Enter,Some('\x0A'.into()));
mapping.set_ab_n(KeyCode::Comma, Some(','.into()), Some('<'.into()));
mapping.set_ab_n(KeyCode::Fullstop, Some('.'.into()), Some('>'.into()));
mapping.set_ab_n(KeyCode::Slash, Some('/'.into()), Some('?'.into()));
mapping.set_aa_a(KeyCode::Spacebar,Some(' '.into()));
mapping.set_aa_a(KeyCode::Delete,Some('\x7F'.into()));
mapping.set_aaaa_num(KeyCode::NumpadSlash, Some('/'.into()), );
mapping.set_aaaa_num(KeyCode::NumpadStar, Some('*'.into()), );
mapping.set_aaaa_num(KeyCode::NumpadMinus, Some('-'.into()), );
mapping.set_abba_num(KeyCode::Numpad7, Some('7'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::Home as u32 }));
mapping.set_abba_num(KeyCode::Numpad8, Some('8'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::ArrowUp as u32 }));
mapping.set_abba_num(KeyCode::Numpad9, Some('9'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::PageUp as u32 }));
mapping.set_aaaa_num(KeyCode::NumpadPlus, Some('+'.into()));
mapping.set_abba_num(KeyCode::Numpad4, Some('4'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::ArrowLeft as u32 }));
mapping.set_aaaa_num(KeyCode::Numpad5, Some('5'.into()));
mapping.set_abba_num(KeyCode::Numpad6, Some('6'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::ArrowRight as u32 }));
mapping.set_abba_num(KeyCode::Numpad1, Some('1'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::End as u32 }));
mapping.set_abba_num(KeyCode::Numpad2, Some('2'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::ArrowDown as u32 }));
mapping.set_abba_num(KeyCode::Numpad3, Some('3'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::PageDown as u32 }));
mapping.set_abba_num(KeyCode::Numpad0, Some('0'.into()), Some(DecodedKey{ kind: DecodedKeyKind::RawKey, value: KeyCode::Insert as u32 }));
mapping.set_abba_num(KeyCode::NumpadPeriod, Some('.'.into()), Some('\x7F'.into()));
mapping.set_aaaa_num(KeyCode::NumpadEnter, Some('\x0A'.into()));
mapping
}
#[rustfmt::skip]
pub fn new_us105key() -> Self {
let mut mapping = Self::new_us104key();
mapping.set_abcde(KeyCode::BackTick, Some('`'.into()), Some('¬'.into()), Some('|'.into()), None);
mapping.set_ab_n(KeyCode::Key2, Some('2'.into()), Some('"'.into()));
mapping.set_ab_n(KeyCode::Quote, Some('\''.into()), Some('@'.into()));
mapping.set_ab_n(KeyCode::Key3, Some('3'.into()), Some('£'.into()));
mapping.set_abcde(KeyCode::BackTick, Some('4'.into()), Some('$'.into()), Some('€'.into()), None);
mapping.set_ab_n(KeyCode::HashTilde, Some('#'.into()), Some('~'.into()));
mapping
}
}
impl KeyboardLayout for CustomLayout {
fn map_keycode(
&self,
keycode: KeyCode,
modifiers: &Modifiers,
handle_ctrl: HandleControl,
) -> DecodedKey {
let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode;
let spot = &self.mapping[keycode as usize];
if let Some(k) = if map_to_unicode && modifiers.is_ctrl() {
match spot {
LayoutEntry::Regular {
unshifted: _,
shifted: _,
altgr: _,
raw_unicode,
} => raw_unicode,
LayoutEntry::Numlockable {
unshifted: _,
shifted: _,
locked: _,
locked_shifted: _,
} => &None,
LayoutEntry::Capslockable {
unshifted: _,
shifted: _,
locked: _,
locked_shifted: _,
raw_unicode,
altgr: _,
} => raw_unicode,
}
} else if modifiers.alt_gr {
match spot {
LayoutEntry::Regular {
unshifted: _,
shifted: _,
altgr,
raw_unicode: _,
} => altgr,
LayoutEntry::Numlockable {
unshifted: _,
shifted: _,
locked: _,
locked_shifted: _,
} => &None,
LayoutEntry::Capslockable {
unshifted: _,
shifted: _,
locked: _,
locked_shifted: _,
raw_unicode: _,
altgr,
} => altgr,
}
} else if modifiers.is_shifted() {
match spot {
LayoutEntry::Regular {
unshifted: _,
shifted,
altgr: _,
raw_unicode: _,
} => shifted,
LayoutEntry::Numlockable {
unshifted: _,
shifted,
locked: _,
locked_shifted,
} => {
if modifiers.numlock {
locked_shifted
} else {
shifted
}
}
LayoutEntry::Capslockable {
unshifted: _,
shifted,
locked: _,
locked_shifted,
raw_unicode: _,
altgr: _,
} => {
if modifiers.is_caps() {
locked_shifted
} else {
shifted
}
}
}
} else {
match spot {
LayoutEntry::Regular {
unshifted,
shifted: _,
altgr: _,
raw_unicode: _,
} => unshifted,
LayoutEntry::Numlockable {
unshifted,
shifted: _,
locked,
locked_shifted: _,
} => {
if modifiers.numlock {
locked
} else {
unshifted
}
}
LayoutEntry::Capslockable {
unshifted,
shifted: _,
locked,
locked_shifted: _,
raw_unicode: _,
altgr: _,
} => {
if modifiers.is_caps() {
locked
} else {
unshifted
}
}
}
} {
*k
} else {
DecodedKey::RawKey(keycode as u8)
}
}
}
// Note(elfein) Not super hard to get right, but still- DO NOT TOUCH
impl CustomLayout {
pub fn set_abcde(
&mut self,
index: KeyCode,
a: Option<DecodedKey>,
b: Option<DecodedKey>,
c: Option<DecodedKey>,
d: Option<DecodedKey>,
) {
self.mapping[index as usize] = {
LayoutEntry::Regular {
unshifted: a,
shifted: b,
altgr: c,
raw_unicode: d,
}
};
}
pub fn set_ab_c(
&mut self,
index: KeyCode,
a: Option<DecodedKey>,
b: Option<DecodedKey>,
c: Option<DecodedKey>,
) {
self.mapping[index as usize] = {
LayoutEntry::Regular {
unshifted: a,
shifted: b,
altgr: None,
raw_unicode: c,
}
};
}
pub fn set_ab_n(&mut self, index: KeyCode, a: Option<DecodedKey>, b: Option<DecodedKey>) {
self.mapping[index as usize] = {
LayoutEntry::Regular {
unshifted: a,
shifted: b,
altgr: None,
raw_unicode: None,
}
};
}
pub fn set_aa_a(&mut self, index: KeyCode, a: Option<DecodedKey>) {
self.mapping[index as usize] = {
LayoutEntry::Regular {
unshifted: a,
shifted: a,
altgr: None,
raw_unicode: a,
}
};
}
pub fn set_abcdef_letter(
&mut self,
index: KeyCode,
a: Option<DecodedKey>,
b: Option<DecodedKey>,
c: Option<DecodedKey>,
d: Option<DecodedKey>,
e: Option<DecodedKey>,
f: Option<DecodedKey>,
) {
self.mapping[index as usize] = {
LayoutEntry::Capslockable {
unshifted: a,
shifted: b,
altgr: c,
locked: d,
locked_shifted: e,
raw_unicode: f,
}
};
}
pub fn set_abcd_e_letter(
&mut self,
index: KeyCode,
a: Option<DecodedKey>,
b: Option<DecodedKey>,
c: Option<DecodedKey>,
d: Option<DecodedKey>,
e: Option<DecodedKey>,
) {
self.mapping[index as usize] = {
LayoutEntry::Capslockable {
unshifted: a,
shifted: b,
locked: c,
locked_shifted: d,
altgr: None,
raw_unicode: e,
}
};
}
pub fn set_aaaa_num(&mut self, index: KeyCode, a: Option<DecodedKey>) {
self.mapping[index as usize] = {
LayoutEntry::Numlockable {
unshifted: a,
shifted: a,
locked: a,
locked_shifted: a,
}
};
}
pub fn set_abba_num(&mut self, index: KeyCode, a: Option<DecodedKey>, b: Option<DecodedKey>) {
self.mapping[index as usize] = {
LayoutEntry::Numlockable {
unshifted: a,
shifted: b,
locked: b,
locked_shifted: a,
}
};
}
}

View file

@ -0,0 +1,172 @@
use crate::{LayoutEntry, KeyCode, KeyboardLayout, Modifiers, HandleControl, DecodedKey, LayoutEntryKind};
// Do not edit this file directly. Instead, create a `Keyboard` and modify that.
pub struct CustomLayout {
mapping: [LayoutEntry; 256],
}
impl Default for CustomLayout {
fn default() -> Self {
Self::new_us104key()
}
}
impl CustomLayout {
#[rustfmt::skip]
pub fn new_us104key() -> Self {
let mut mapping = Self {
mapping: [LayoutEntry::default(); 256],
};
mapping.set(KeyCode::BackTick, LayoutEntry::regular().unshifted('`').shifted('`'));
mapping.set(KeyCode::Escape, LayoutEntry::regular().unshifted('\x1B'));
mapping.set(KeyCode::Key0, LayoutEntry::regular().unshifted('0').shifted(')'));
mapping.set(KeyCode::Key1, LayoutEntry::regular().unshifted('1').shifted('!'));
mapping.set(KeyCode::Key2, LayoutEntry::regular().unshifted('2').shifted('@'));
mapping.set(KeyCode::Key3, LayoutEntry::regular().unshifted('3').shifted('#'));
mapping.set(KeyCode::Key4, LayoutEntry::regular().unshifted('4').shifted('$'));
mapping.set(KeyCode::Key5, LayoutEntry::regular().unshifted('5').shifted('%'));
mapping.set(KeyCode::Key6, LayoutEntry::regular().unshifted('6').shifted('^'));
mapping.set(KeyCode::Key7, LayoutEntry::regular().unshifted('7').shifted('&'));
mapping.set(KeyCode::Key8, LayoutEntry::regular().unshifted('8').shifted('*'));
mapping.set(KeyCode::Key9, LayoutEntry::regular().unshifted('9').shifted('('));
mapping.set(KeyCode::Minus, LayoutEntry::regular().unshifted('-').shifted('_'));
mapping.set(KeyCode::Equals, LayoutEntry::regular().unshifted('=').shifted('+'));
mapping.set(KeyCode::Backspace, LayoutEntry::regular().unshifted('\x08'));
mapping.set(KeyCode::Tab, LayoutEntry::regular().unshifted('\x09'));
mapping.set(KeyCode::Q, LayoutEntry::regular().unshifted('q').shifted('Q').locked('Q').locked_shifted('q').raw_unicode('\u{0011}'));
mapping.set(KeyCode::W, LayoutEntry::regular().unshifted('w').shifted('W').locked('W').locked_shifted('w').raw_unicode('\u{0017}'));
mapping.set(KeyCode::E, LayoutEntry::regular().unshifted('e').shifted('E').locked('E').locked_shifted('e').raw_unicode('\u{0005}'));
mapping.set(KeyCode::R, LayoutEntry::regular().unshifted('r').shifted('R').locked('R').locked_shifted('r').raw_unicode('\u{0012}'));
mapping.set(KeyCode::T, LayoutEntry::regular().unshifted('t').shifted('T').locked('T').locked_shifted('t').raw_unicode('\u{0014}'));
mapping.set(KeyCode::Y, LayoutEntry::regular().unshifted('y').shifted('Y').locked('Y').locked_shifted('y').raw_unicode('\u{0019}'));
mapping.set(KeyCode::U, LayoutEntry::regular().unshifted('u').shifted('U').locked('U').locked_shifted('u').raw_unicode('\u{0015}'));
mapping.set(KeyCode::I, LayoutEntry::regular().unshifted('i').shifted('I').locked('I').locked_shifted('i').raw_unicode('\u{0009}'));
mapping.set(KeyCode::O, LayoutEntry::regular().unshifted('o').shifted('O').locked('O').locked_shifted('o').raw_unicode('\u{000F}'));
mapping.set(KeyCode::P, LayoutEntry::regular().unshifted('p').shifted('P').locked('P').locked_shifted('p').raw_unicode('\u{0010}'));
mapping.set(KeyCode::A, LayoutEntry::regular().unshifted('a').shifted('A').locked('A').locked_shifted('a').raw_unicode('\u{0001}'));
mapping.set(KeyCode::S, LayoutEntry::regular().unshifted('s').shifted('S').locked('S').locked_shifted('s').raw_unicode('\u{0013}'));
mapping.set(KeyCode::D, LayoutEntry::regular().unshifted('d').shifted('D').locked('D').locked_shifted('d').raw_unicode('\u{0004}'));
mapping.set(KeyCode::F, LayoutEntry::regular().unshifted('f').shifted('F').locked('F').locked_shifted('f').raw_unicode('\u{0006}'));
mapping.set(KeyCode::G, LayoutEntry::regular().unshifted('g').shifted('G').locked('G').locked_shifted('g').raw_unicode('\u{0007}'));
mapping.set(KeyCode::H, LayoutEntry::regular().unshifted('h').shifted('H').locked('H').locked_shifted('h').raw_unicode('\u{0008}'));
mapping.set(KeyCode::J, LayoutEntry::regular().unshifted('j').shifted('J').locked('J').locked_shifted('j').raw_unicode('\u{000A}'));
mapping.set(KeyCode::K, LayoutEntry::regular().unshifted('k').shifted('K').locked('K').locked_shifted('k').raw_unicode('\u{000B}'));
mapping.set(KeyCode::L, LayoutEntry::regular().unshifted('l').shifted('L').locked('L').locked_shifted('l').raw_unicode('\u{000C}'));
mapping.set(KeyCode::Z, LayoutEntry::regular().unshifted('z').shifted('Z').locked('Z').locked_shifted('z').raw_unicode('\u{001A}'));
mapping.set(KeyCode::X, LayoutEntry::regular().unshifted('x').shifted('X').locked('X').locked_shifted('x').raw_unicode('\u{0018}'));
mapping.set(KeyCode::C, LayoutEntry::regular().unshifted('c').shifted('C').locked('C').locked_shifted('c').raw_unicode('\u{0003}'));
mapping.set(KeyCode::V, LayoutEntry::regular().unshifted('v').shifted('V').locked('V').locked_shifted('v').raw_unicode('\u{0016}'));
mapping.set(KeyCode::B, LayoutEntry::regular().unshifted('b').shifted('B').locked('B').locked_shifted('b').raw_unicode('\u{0002}'));
mapping.set(KeyCode::N, LayoutEntry::regular().unshifted('n').shifted('N').locked('N').locked_shifted('n').raw_unicode('\u{000E}'));
mapping.set(KeyCode::M, LayoutEntry::regular().unshifted('m').shifted('M').locked('M').locked_shifted('m').raw_unicode('\u{000D}'));
mapping.set(KeyCode::BracketSquareLeft, LayoutEntry::regular().unshifted('{').shifted('['));
mapping.set(KeyCode::BracketSquareRight, LayoutEntry::regular().unshifted('}').shifted(']'));
mapping.set(KeyCode::BackSlash, LayoutEntry::regular().unshifted('|').shifted('\\'));
mapping.set(KeyCode::SemiColon, LayoutEntry::regular().unshifted(';').shifted(':'));
mapping.set(KeyCode::Quote, LayoutEntry::regular().unshifted('\'').shifted('"'));
mapping.set(KeyCode::Enter, LayoutEntry::regular().unshifted('\x0A'));
mapping.set(KeyCode::Comma, LayoutEntry::regular().unshifted(',').shifted('<'));
mapping.set(KeyCode::Fullstop, LayoutEntry::regular().unshifted('.').shifted('>'));
mapping.set(KeyCode::Slash, LayoutEntry::regular().unshifted('/').shifted('?'));
mapping.set(KeyCode::Spacebar, LayoutEntry::regular().unshifted(' '));
mapping.set(KeyCode::Delete, LayoutEntry::regular().unshifted('\x7F'));
mapping.set(KeyCode::NumpadSlash, LayoutEntry::regular().unshifted('/'));
mapping.set(KeyCode::NumpadStar, LayoutEntry::regular().unshifted('*'));
mapping.set(KeyCode::NumpadMinus, LayoutEntry::regular().unshifted('-'));
mapping.set(KeyCode::Numpad7, LayoutEntry::regular().unshifted('7').shifted(KeyCode::Home));
mapping.set(KeyCode::Numpad8, LayoutEntry::regular().unshifted('8').shifted(KeyCode::ArrowUp));
mapping.set(KeyCode::Numpad9, LayoutEntry::regular().unshifted('9').shifted(KeyCode::PageUp));
mapping.set(KeyCode::NumpadPlus, LayoutEntry::regular().unshifted('+'));
mapping.set(KeyCode::Numpad4, LayoutEntry::regular().unshifted('4').shifted(KeyCode::ArrowLeft));
mapping.set(KeyCode::Numpad5, LayoutEntry::regular().unshifted('5'));
mapping.set(KeyCode::Numpad6, LayoutEntry::regular().unshifted('6').shifted(KeyCode::ArrowRight));
mapping.set(KeyCode::Numpad1, LayoutEntry::regular().unshifted('1').shifted(KeyCode::End));
mapping.set(KeyCode::Numpad2, LayoutEntry::regular().unshifted('2').shifted(KeyCode::ArrowDown));
mapping.set(KeyCode::Numpad3, LayoutEntry::regular().unshifted('3').shifted(KeyCode::PageDown));
mapping.set(KeyCode::Numpad0, LayoutEntry::regular().unshifted('0').shifted(KeyCode::Insert));
mapping.set(KeyCode::NumpadPeriod, LayoutEntry::regular().unshifted('.').shifted('\x7F'));
mapping.set(KeyCode::NumpadEnter, LayoutEntry::regular().unshifted('\x0A'));
mapping
}
#[rustfmt::skip]
pub fn new_us105key() -> Self {
let mut mapping = Self::new_us104key();
mapping.set(KeyCode::BackTick, LayoutEntry::regular()); // Some('`'), Some('¬'), Some('|'), None);
mapping.set(KeyCode::Key2, LayoutEntry::regular()); // Some('2'), Some('"'));
mapping.set(KeyCode::Quote, LayoutEntry::regular()); // Some('\''), Some('@'));
mapping.set(KeyCode::Key3, LayoutEntry::regular()); // Some('3'), Some('£'));
mapping.set(KeyCode::BackTick, LayoutEntry::regular()); // Some('4'), Some('$'), Some('€'), None);
mapping.set(KeyCode::HashTilde, LayoutEntry::regular()); // Some('#'), Some('~'));
mapping
}
}
impl KeyboardLayout for CustomLayout {
fn map_keycode(
&self,
keycode: KeyCode,
modifiers: &Modifiers,
handle_ctrl: HandleControl,
) -> DecodedKey {
let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode;
let spot = &self.mapping[keycode as usize];
if let Some(k) = if map_to_unicode && modifiers.is_ctrl() {
match spot.kind {
LayoutEntryKind::Regular => spot.raw_unicode,
LayoutEntryKind::Numlockable => None,
LayoutEntryKind::Capslockable => spot.raw_unicode,
}
} else if modifiers.alt_gr {
match spot.kind {
LayoutEntryKind::Regular => spot.altgr,
LayoutEntryKind::Numlockable => None,
LayoutEntryKind::Capslockable => spot.altgr,
}
} else if modifiers.is_shifted() {
match spot.kind {
LayoutEntryKind::Regular => spot.shifted,
LayoutEntryKind::Numlockable => {
if modifiers.numlock {
spot.locked_shifted
} else {
spot.shifted
}
}
LayoutEntryKind::Capslockable => {
if modifiers.is_caps() {
spot.locked_shifted
} else {
spot.shifted
}
}
}
} else {
match spot.kind {
LayoutEntryKind::Regular => spot.unshifted,
LayoutEntryKind::Numlockable => {
if modifiers.numlock {
spot.locked
} else {
spot.unshifted
}
}
LayoutEntryKind::Capslockable => {
if modifiers.is_caps() {
spot.locked
} else {
spot.unshifted
}
}
}
} {
k
} else {
DecodedKey::RawKey(keycode as u8)
}
}
}
// Note(elfein) Not super hard to get right, but still- DO NOT TOUCH
impl CustomLayout {
pub fn set(&mut self, pos: KeyCode, entry: LayoutEntry) {
self.mapping[pos as usize] = entry;
}
}

View file

@ -0,0 +1,253 @@
use crate::{KeyCode, ScancodeSet, DecodeState, KeyEvent, Error, KeyState, keyboard::EXTENDED_KEY_CODE};
pub struct CustomScancodeSet {
single_byte: [Option<KeyCode>; 256],
extended: [Option<KeyCode>; 256],
}
impl Default for CustomScancodeSet {
fn default() -> Self {
Self::scancode_set1()
}
}
impl CustomScancodeSet {
pub fn scancode_set1() -> Self {
let mut scancode_set = Self {
single_byte: [None; 256],
extended: [None; 256],
};
scancode_set.single_byte[0x01] = Some(KeyCode::Escape); // 01
scancode_set.single_byte[0x02] = Some(KeyCode::Key1); // 02
scancode_set.single_byte[0x03] = Some(KeyCode::Key2); // 03
scancode_set.single_byte[0x04] = Some(KeyCode::Key3); // 04
scancode_set.single_byte[0x05] = Some(KeyCode::Key4); // 05
scancode_set.single_byte[0x06] = Some(KeyCode::Key5); // 06
scancode_set.single_byte[0x07] = Some(KeyCode::Key6); // 07
scancode_set.single_byte[0x08] = Some(KeyCode::Key7); // 08
scancode_set.single_byte[0x09] = Some(KeyCode::Key8); // 09
scancode_set.single_byte[0x0A] = Some(KeyCode::Key9); // 0A
scancode_set.single_byte[0x0B] = Some(KeyCode::Key0); // 0B
scancode_set.single_byte[0x0C] = Some(KeyCode::Minus); // 0C
scancode_set.single_byte[0x0D] = Some(KeyCode::Equals); // 0D
scancode_set.single_byte[0x0E] = Some(KeyCode::Backspace); // 0E
scancode_set.single_byte[0x0F] = Some(KeyCode::Tab); // 0F
scancode_set.single_byte[0x10] = Some(KeyCode::Q); // 10
scancode_set.single_byte[0x11] = Some(KeyCode::W); // 11
scancode_set.single_byte[0x12] = Some(KeyCode::E); // 12
scancode_set.single_byte[0x13] = Some(KeyCode::R); // 13
scancode_set.single_byte[0x14] = Some(KeyCode::T); // 14
scancode_set.single_byte[0x15] = Some(KeyCode::Y); // 15
scancode_set.single_byte[0x16] = Some(KeyCode::U); // 16
scancode_set.single_byte[0x17] = Some(KeyCode::I); // 17
scancode_set.single_byte[0x18] = Some(KeyCode::O); // 18
scancode_set.single_byte[0x19] = Some(KeyCode::P); // 19
scancode_set.single_byte[0x1A] = Some(KeyCode::BracketSquareLeft); // 1A
scancode_set.single_byte[0x1B] = Some(KeyCode::BracketSquareRight); // 1B
scancode_set.single_byte[0x1C] = Some(KeyCode::Enter); // 1C
scancode_set.single_byte[0x1D] = Some(KeyCode::ControlLeft); // 1D
scancode_set.single_byte[0x1E] = Some(KeyCode::A); // 1E
scancode_set.single_byte[0x1F] = Some(KeyCode::S); // 1F
scancode_set.single_byte[0x20] = Some(KeyCode::D); // 20
scancode_set.single_byte[0x21] = Some(KeyCode::F); // 21
scancode_set.single_byte[0x22] = Some(KeyCode::G); // 22
scancode_set.single_byte[0x23] = Some(KeyCode::H); // 23
scancode_set.single_byte[0x24] = Some(KeyCode::J); // 24
scancode_set.single_byte[0x25] = Some(KeyCode::K); // 25
scancode_set.single_byte[0x26] = Some(KeyCode::L); // 26
scancode_set.single_byte[0x27] = Some(KeyCode::SemiColon); // 27
scancode_set.single_byte[0x28] = Some(KeyCode::Quote); // 28
scancode_set.single_byte[0x29] = Some(KeyCode::BackTick); // 29
scancode_set.single_byte[0x2A] = Some(KeyCode::ShiftLeft); // 2A
scancode_set.single_byte[0x2B] = Some(KeyCode::BackSlash); // 2B
scancode_set.single_byte[0x2C] = Some(KeyCode::Z); // 2C
scancode_set.single_byte[0x2D] = Some(KeyCode::X); // 2D
scancode_set.single_byte[0x2E] = Some(KeyCode::C); // 2E
scancode_set.single_byte[0x2F] = Some(KeyCode::V); // 2F
scancode_set.single_byte[0x30] = Some(KeyCode::B); // 30
scancode_set.single_byte[0x31] = Some(KeyCode::N); // 31
scancode_set.single_byte[0x32] = Some(KeyCode::M); // 32
scancode_set.single_byte[0x33] = Some(KeyCode::Comma); // 33
scancode_set.single_byte[0x34] = Some(KeyCode::Fullstop); // 34
scancode_set.single_byte[0x35] = Some(KeyCode::Slash); // 35
scancode_set.single_byte[0x36] = Some(KeyCode::ShiftRight); // 36
scancode_set.single_byte[0x37] = Some(KeyCode::NumpadStar); // 37
scancode_set.single_byte[0x38] = Some(KeyCode::AltLeft); // 38
scancode_set.single_byte[0x39] = Some(KeyCode::Spacebar); // 39
scancode_set.single_byte[0x3A] = Some(KeyCode::CapsLock); // 3A
scancode_set.single_byte[0x3B] = Some(KeyCode::F1); // 3B
scancode_set.single_byte[0x3C] = Some(KeyCode::F2); // 3C
scancode_set.single_byte[0x3D] = Some(KeyCode::F3); // 3D
scancode_set.single_byte[0x3E] = Some(KeyCode::F4); // 3E
scancode_set.single_byte[0x3F] = Some(KeyCode::F5); // 3F
scancode_set.single_byte[0x40] = Some(KeyCode::F6); // 40
scancode_set.single_byte[0x41] = Some(KeyCode::F7); // 41
scancode_set.single_byte[0x42] = Some(KeyCode::F8); // 42
scancode_set.single_byte[0x43] = Some(KeyCode::F9); // 43
scancode_set.single_byte[0x44] = Some(KeyCode::F10); // 44
scancode_set.single_byte[0x45] = Some(KeyCode::NumpadLock); // 45
scancode_set.single_byte[0x46] = Some(KeyCode::ScrollLock); // 46
scancode_set.single_byte[0x47] = Some(KeyCode::Numpad7); // 47
scancode_set.single_byte[0x48] = Some(KeyCode::Numpad8); // 48
scancode_set.single_byte[0x49] = Some(KeyCode::Numpad9); // 49
scancode_set.single_byte[0x4A] = Some(KeyCode::NumpadMinus); // 4A
scancode_set.single_byte[0x4B] = Some(KeyCode::Numpad4); // 4B
scancode_set.single_byte[0x4C] = Some(KeyCode::Numpad5); // 4C
scancode_set.single_byte[0x4D] = Some(KeyCode::Numpad6); // 4D
scancode_set.single_byte[0x4E] = Some(KeyCode::NumpadPlus); // 4E
scancode_set.single_byte[0x4F] = Some(KeyCode::Numpad1); // 4F
scancode_set.single_byte[0x50] = Some(KeyCode::Numpad2); // 50
scancode_set.single_byte[0x51] = Some(KeyCode::Numpad3); // 51
scancode_set.single_byte[0x52] = Some(KeyCode::Numpad0); // 52
scancode_set.single_byte[0x53] = Some(KeyCode::NumpadPeriod); // 53
// 0x54
// 0x55
// 0x56
scancode_set.single_byte[0x57] = Some(KeyCode::F11); // 57
scancode_set.single_byte[0x58] = Some(KeyCode::F12); // 58
for i in 0x81..=0xD8 {
scancode_set.single_byte[i] = scancode_set.single_byte[i - 0x80];
}
scancode_set.extended[0x10] = Some(KeyCode::PrevTrack); // E010
//0x11
//0x12
//0x13
//0x14
//0x15
//0x16
//0x17
//0x18
scancode_set.extended[0x19] = Some(KeyCode::NextTrack); // E019
//0x1A
//0x1B
scancode_set.extended[0x1C] = Some(KeyCode::NumpadEnter); // E01C
scancode_set.extended[0x1D] = Some(KeyCode::ControlRight); // E01D
//0x1E
//0x1F
scancode_set.extended[0x20] = Some(KeyCode::Mute); // E020
scancode_set.extended[0x21] = Some(KeyCode::Calculator); // E021
scancode_set.extended[0x22] = Some(KeyCode::Play); // E022
//0x23
scancode_set.extended[0x24] = Some(KeyCode::Stop); // E024
//0x25
//0x26
//0x27
//0x28
//0x29
//0x2A
//0x2B
//0x2C
//0x2D
scancode_set.extended[0x2E] = Some(KeyCode::VolumeDown); // E02E
//0x2F
scancode_set.extended[0x30] = Some(KeyCode::VolumeUp); // E030
//0x31
scancode_set.extended[0x32] = Some(KeyCode::WWWHome); // E032
//0x33
//0x34
scancode_set.extended[0x35] = Some(KeyCode::NumpadSlash); // E035
//0x36
//0x37
scancode_set.extended[0x38] = Some(KeyCode::AltRight); // E038
//0x39
//0x3A
//0x3B
//0x3C
//0x3D
//0x3E
//0x3F
//0x40
//0x41
//0x42
//0x43
//0x44
//0x45
//0x46
scancode_set.extended[0x47] = Some(KeyCode::Home); // E047
scancode_set.extended[0x48] = Some(KeyCode::ArrowUp); // E048
scancode_set.extended[0x49] = Some(KeyCode::PageUp); // E049
//0x4A
scancode_set.extended[0x4B] = Some(KeyCode::ArrowLeft); // E04B
//0x4C
scancode_set.extended[0x4D] = Some(KeyCode::ArrowRight); // E04D
//0x4E
scancode_set.extended[0x4F] = Some(KeyCode::End); // E04F
scancode_set.extended[0x50] = Some(KeyCode::ArrowDown); // E050
scancode_set.extended[0x51] = Some(KeyCode::PageDown); // E051
scancode_set.extended[0x52] = Some(KeyCode::Insert); // E052
scancode_set.extended[0x53] = Some(KeyCode::Delete); // E053
for i in 0x90..=0xED {
scancode_set.extended[i] = scancode_set.extended[i - 0x80];
}
scancode_set
}
pub fn scancode_set2() -> Self {
Self {
single_byte: [None; 256],
extended: [None; 256],
}
}
}
impl ScancodeSet for CustomScancodeSet {
fn advance_state(&self, state: &mut DecodeState, code: u8) -> Result<Option<KeyEvent>, Error> {
match *state {
DecodeState::Start => {
match code {
EXTENDED_KEY_CODE => {
*state = DecodeState::Extended;
Ok(None)
}
0x80..=0xFF => {
// Release codes
Ok(Some(KeyEvent::new(
self.map_scancode(code - 0x80)?,
KeyState::Up,
)))
}
_ => {
// Normal codes
Ok(Some(KeyEvent::new(
self.map_scancode(code)?,
KeyState::Down,
)))
}
}
}
DecodeState::Extended => {
*state = DecodeState::Start;
match code {
0x80..=0xFF => {
// Extended Release codes
Ok(Some(KeyEvent::new(
self.map_extended_scancode(code - 0x80)?,
KeyState::Up,
)))
}
_ => {
// Normal release codes
Ok(Some(KeyEvent::new(
self.map_extended_scancode(code)?,
KeyState::Down,
)))
}
}
}
_ => {
// Can't get in to this state
unimplemented!();
}
}
}
fn map_scancode(&self, code: u8) -> Result<KeyCode, Error> {
if let Some(kc) = self.single_byte[code as usize] {
Ok(kc)
} else {
Err(Error::UnknownKeyCode)
}
}
fn map_extended_scancode(&self, code: u8) -> Result<KeyCode, Error> {
if let Some(kc) = self.extended[code as usize] {
Ok(kc)
} else {
Err(Error::UnknownKeyCode)
}
}
}

View file

@ -0,0 +1,79 @@
use super::DecodedKey;
#[derive(Debug, Clone, Copy)]
pub enum LayoutEntryKind {
Regular,
Numlockable,
Capslockable,
}
impl Default for LayoutEntryKind {
fn default() -> Self {
Self::Regular
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct LayoutEntry {
pub kind: LayoutEntryKind,
pub unshifted: Option<DecodedKey>,
pub shifted: Option<DecodedKey>,
pub locked: Option<DecodedKey>,
pub locked_shifted: Option<DecodedKey>,
pub altgr: Option<DecodedKey>,
pub raw_unicode: Option<DecodedKey>,
}
impl LayoutEntry {
#[must_use]
pub fn regular() -> Self {
Self {
kind: LayoutEntryKind::Regular,
..Default::default()
}
}
#[must_use]
pub fn numlockable() -> Self {
Self {
kind: LayoutEntryKind::Numlockable,
..Default::default()
}
}
#[must_use]
pub fn capslockable() -> Self {
Self {
kind: LayoutEntryKind::Capslockable,
..Default::default()
}
}
#[must_use]
pub fn unshifted( mut self, c: impl Into<DecodedKey>) -> Self {
self.unshifted = Some(c.into());
self
}
#[must_use]
pub fn shifted( mut self, c: impl Into<DecodedKey>) -> Self {
self.shifted = Some(c.into());
self
}
#[must_use]
pub fn altgr( mut self, c: impl Into<DecodedKey>) -> Self {
self.altgr = Some(c.into());
self
}
#[must_use]
pub fn raw_unicode( mut self, c: impl Into<DecodedKey>) -> Self {
self.raw_unicode = Some(c.into());
self
}
#[must_use]
pub fn locked(mut self, c: impl Into<DecodedKey>) -> Self {
self.locked = Some(c.into());
self
}
#[must_use]
pub fn locked_shifted(mut self, c: impl Into<DecodedKey>) -> Self {
self.locked_shifted = Some(c.into());
self
}
}

View file

@ -0,0 +1,10 @@
#![allow(clippy::too_many_arguments)]
use super::*;
mod custom_layout;
mod custom_scancode_set;
mod layout_entry;
pub use custom_layout::CustomLayout;
pub use custom_scancode_set::CustomScancodeSet;
pub use layout_entry::{LayoutEntry, LayoutEntryKind};

View file

@ -1,103 +1,111 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
#[derive(Debug)] #[derive(Debug)]
pub struct Modifiers { pub struct Modifiers {
pub lshift: bool, pub lshift: bool,
pub rshift: bool, pub rshift: bool,
pub lctrl: bool, pub lctrl: bool,
pub rctrl: bool, pub rctrl: bool,
pub numlock: bool, pub numlock: bool,
pub capslock: bool, pub capslock: bool,
pub alt_gr: bool, pub alt_gr: bool,
} }
impl Modifiers { impl Modifiers {
pub fn is_shifted(&self) -> bool { pub fn is_shifted(&self) -> bool {
self.lshift | self.rshift self.lshift | self.rshift
} }
pub fn is_ctrl(&self) -> bool { pub fn is_ctrl(&self) -> bool {
self.lctrl | self.rctrl self.lctrl | self.rctrl
} }
pub fn is_caps(&self) -> bool { pub fn is_caps(&self) -> bool {
self.capslock self.capslock
} }
} }
#[derive(Debug, PartialEq, Eq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum KeyState { pub enum KeyState {
Up, Up,
Down, Down,
} }
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
pub struct KeyEvent { pub struct KeyEvent {
pub code: KeyCode, pub code: KeyCode,
pub state: KeyState, pub state: KeyState,
} }
impl KeyEvent { impl KeyEvent {
pub fn new(code: KeyCode, state: KeyState) -> KeyEvent { pub fn new(code: KeyCode, state: KeyState) -> KeyEvent {
KeyEvent { code, state } KeyEvent { code, state }
} }
} }
#[derive(Debug, PartialEq, Eq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum HandleControl { pub enum HandleControl {
/// If either Ctrl key is held down, convert the letters A through Z into /// If either Ctrl key is held down, convert the letters A through Z into
/// Unicode chars U+0001 through U+001A. If the Ctrl keys are not held /// Unicode chars U+0001 through U+001A. If the Ctrl keys are not held
/// down, letters go through normally. /// down, letters go through normally.
MapLettersToUnicode, MapLettersToUnicode,
/// Don't do anything special - send through the Ctrl key up/down events, /// Don't do anything special - send through the Ctrl key up/down events,
/// and leave the letters as letters. /// and leave the letters as letters.
Ignore, Ignore,
} }
#[derive(Debug, Copy, Clone, Eq, PartialEq)] #[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum DecodeState { pub enum DecodeState {
Start, Start,
Extended, Extended,
Release, Release,
ExtendedRelease, ExtendedRelease,
} }
/// Indicates different error conditions. /// Indicates different error conditions.
#[derive(Debug, PartialEq, Eq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum Error { pub enum Error {
BadStartBit, BadStartBit,
BadStopBit, BadStopBit,
ParityError, ParityError,
UnknownKeyCode, UnknownKeyCode,
InvalidState, InvalidState,
} }
#[derive(Debug, PartialEq, Eq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[repr(u8)] #[repr(u8)]
pub enum DecodedKeyKind { pub enum DecodedKeyKind {
RawKey = 0, RawKey = 0,
Unicode = 1, Unicode = 1,
} }
#[derive(Debug, PartialEq, Eq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[repr(C)] #[repr(C)]
pub struct DecodedKey { pub struct DecodedKey {
pub kind: DecodedKeyKind, pub kind: DecodedKeyKind,
pub value: u32, pub value: u32,
} }
impl From<char> for DecodedKey { impl From<char> for DecodedKey {
fn from(ch: char) -> Self { fn from(ch: char) -> Self {
Self { Self {
kind: DecodedKeyKind::Unicode, kind: DecodedKeyKind::Unicode,
value: ch as u32, value: ch as u32,
} }
} }
}
impl From<KeyCode> for DecodedKey {
fn from(kc: KeyCode) -> Self {
Self {
kind: DecodedKeyKind::RawKey,
value: kc as u32,
}
}
} }
impl DecodedKey { impl DecodedKey {
pub const ZERO: Self = Self { pub const ZERO: Self = Self {
kind: DecodedKeyKind::Unicode, kind: DecodedKeyKind::Unicode,
value: 0, value: 0,
}; };
pub fn Unicode(ch: char) -> Self { pub fn Unicode(ch: char) -> Self {
Self { Self {
kind: DecodedKeyKind::Unicode, kind: DecodedKeyKind::Unicode,
value: ch.into(), value: ch.into(),
} }
} }
pub fn RawKey(byte: u8) -> Self { pub fn RawKey(byte: u8) -> Self {
Self { Self {
kind: DecodedKeyKind::RawKey, kind: DecodedKeyKind::RawKey,
value: byte.into(), value: byte.into(),
} }
} }
} }
macro_rules! keycode_enum { macro_rules! keycode_enum {
(@get_last $Variant:ident) => { (@get_last $Variant:ident) => {