From 28f11e33f12dab48edf3adfe78c188512c478c9b Mon Sep 17 00:00:00 2001 From: Elfein Landers Date: Tue, 1 Feb 2022 23:42:09 -0800 Subject: [PATCH] major refactor of keyboard --- ableos/src/arch/x86_64/interrupts.rs | 6 +- ableos/src/graphics/mod.rs | 418 ++++++------ ableos/src/keyboard/abstractions.rs | 623 ------------------ .../keyboard/abstractions/custom_layout.rs | 172 +++++ .../abstractions/custom_scancode_set.rs | 253 +++++++ .../src/keyboard/abstractions/layout_entry.rs | 79 +++ ableos/src/keyboard/abstractions/mod.rs | 10 + ableos/src/keyboard/small_types.rs | 138 ++-- 8 files changed, 797 insertions(+), 902 deletions(-) delete mode 100644 ableos/src/keyboard/abstractions.rs create mode 100644 ableos/src/keyboard/abstractions/custom_layout.rs create mode 100644 ableos/src/keyboard/abstractions/custom_scancode_set.rs create mode 100644 ableos/src/keyboard/abstractions/layout_entry.rs create mode 100644 ableos/src/keyboard/abstractions/mod.rs diff --git a/ableos/src/arch/x86_64/interrupts.rs b/ableos/src/arch/x86_64/interrupts.rs index e2d7af8..eb0e06f 100644 --- a/ableos/src/arch/x86_64/interrupts.rs +++ b/ableos/src/arch/x86_64/interrupts.rs @@ -63,16 +63,16 @@ extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: InterruptStackFr } extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) { use crate::keyboard::{ - CustomLayout, CustomScanCodeSet, DecodedKey, DecodedKeyKind, HandleControl, KeyCode, + CustomLayout, CustomScancodeSet, DecodedKey, DecodedKeyKind, HandleControl, KeyCode, Keyboard, }; use spin::Mutex; use x86_64::instructions::port::Port; lazy_static! { - static ref KEYBOARD: Mutex> = + static ref KEYBOARD: Mutex> = Mutex::new(Keyboard::new( CustomLayout::new_us104key(), - CustomScanCodeSet::default(), + CustomScancodeSet::default(), HandleControl::Ignore )); } diff --git a/ableos/src/graphics/mod.rs b/ableos/src/graphics/mod.rs index 637999e..0a96ad6 100644 --- a/ableos/src/graphics/mod.rs +++ b/ableos/src/graphics/mod.rs @@ -7,8 +7,8 @@ use vga::writers::GraphicsWriter; #[derive(Debug)] pub struct ScreenSize { - pub x: usize, - pub y: usize, + pub x: usize, + pub y: usize, } const FONT_SCALE: f32 = 1.6; @@ -21,244 +21,240 @@ lazy_static::lazy_static! { } impl ScreenSize { - pub fn new(x: usize, y: usize) -> Self { - Self { x, y } - } + pub fn new(x: usize, y: usize) -> Self { + Self { x, y } + } } pub enum GraphicsReturn { - Ok, - ImproperScreenSize, + Ok, + ImproperScreenSize, } pub struct ScreenBuffer { - pub size: ScreenSize, - pub clear_color: Rgba64, - pub buff: Box<[Rgba64]>, // Vec, + pub size: ScreenSize, + pub clear_color: Rgba64, + pub buff: Box<[Rgba64]>, // Vec, } impl ScreenBuffer { - // Add optional size later - pub fn new(x: usize, y: usize) -> Self { - Self { - size: ScreenSize::new(x, y), - clear_color: 0, - buff: vec![0u64; x * y].into_boxed_slice(), - } - } - pub fn draw_filled_circle(&mut self, cx: i32, cy: i32, radius: usize, color: Rgba64) { - let r = radius as i32 * 2; - for y in 0..640 { - for x in 0..480 { - let dx = cx - x as i32 * 2 - 1; - let dy = cy - y as i32 * 2 - 1; + // Add optional size later + pub fn new(x: usize, y: usize) -> Self { + Self { + size: ScreenSize::new(x, y), + clear_color: 0, + buff: vec![0u64; x * y].into_boxed_slice(), + } + } + pub fn draw_filled_circle(&mut self, cx: i32, cy: i32, radius: usize, color: Rgba64) { + let r = radius as i32 * 2; + for y in 0..640 { + for x in 0..480 { + let dx = cx - x as i32 * 2 - 1; + let dy = cy - y as i32 * 2 - 1; - if dx * dx + dy * dy <= r * r { - self.set_pixel(x, y, color); - }; + if dx * dx + dy * dy <= r * r { + 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] - pub fn set_pixel(&mut self, x: usize, y: usize, color: Rgba64) { - self.buff[y * self.size.x + x] = color; - } + info!("Shaders done"); + } - pub fn clear(&mut self) { - self.buff = vec![0u64; self.buff.len()].into_boxed_slice(); - } + // 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)); + } - 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); + /// 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' => { + // 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] - 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), - } + 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, + ); + } + }); } - } - - 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 { - fn copy_to_buffer(&self) -> GraphicsReturn; + fn copy_to_buffer(&self) -> GraphicsReturn; } impl VgaBuffer for ScreenBuffer { - fn copy_to_buffer(&self) -> GraphicsReturn { - let mode = VGAE.lock(); - for y in 0..self.size.y { - for x in 0..self.size.x { - use shadeable::pixel_format::into_vga_16; - // let vga_color = get_color16(self.buff[y * self.size.x + x]); + fn copy_to_buffer(&self) -> GraphicsReturn { + let mode = VGAE.lock(); + for y in 0..self.size.y { + for x in 0..self.size.x { + use shadeable::pixel_format::into_vga_16; + // 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 { - mode.set_pixel(x, y, vga_color); - } + if into_vga_16(self.clear_color) != 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)> { - let mut coordinates: Vec<(usize, usize)> = vec![]; - let dx: i32 = i32::abs(x2 - x1); - let dy: i32 = i32::abs(y2 - y1); - let sx: i32 = { - if x1 < x2 { - 1 - } else { - -1 - } - }; - let sy: i32 = { - if y1 < y2 { - 1 - } else { - -1 - } - }; - let mut error: i32 = (if dx > dy { dx } else { -dy }) / 2; - let mut current_x: i32 = x1; - let mut current_y: i32 = y1; - loop { - coordinates.push((current_x as usize, current_y as usize)); - // info!("0 {:?}", (current_x, current_y)); + let mut coordinates: Vec<(usize, usize)> = vec![]; + let dx: i32 = i32::abs(x2 - x1); + let dy: i32 = i32::abs(y2 - y1); + let sx: i32 = { + if x1 < x2 { + 1 + } else { + -1 + } + }; + let sy: i32 = { + if y1 < y2 { + 1 + } else { + -1 + } + }; + let mut error: i32 = (if dx > dy { dx } else { -dy }) / 2; + let mut current_x: i32 = x1; + let mut current_y: i32 = y1; + loop { + coordinates.push((current_x as usize, current_y as usize)); + // info!("0 {:?}", (current_x, current_y)); - if current_x == x2 && current_y == y2 { - break; - } + if current_x == x2 && current_y == y2 { + break; + } - let error2: i32 = error; + let error2: i32 = error; - if error2 > -dx { - error -= dy; - current_x += sx; - } - if error2 < dy { - error += dx; - current_y += sy; - } - } - coordinates + if error2 > -dx { + error -= dy; + current_x += sx; + } + if error2 < dy { + error += dx; + current_y += sy; + } + } + coordinates } diff --git a/ableos/src/keyboard/abstractions.rs b/ableos/src/keyboard/abstractions.rs deleted file mode 100644 index 36f3e0c..0000000 --- a/ableos/src/keyboard/abstractions.rs +++ /dev/null @@ -1,623 +0,0 @@ -#![allow(clippy::too_many_arguments)] -use super::*; -pub struct CustomScanCodeSet { - single_byte: [Option; 256], - extended: [Option; 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, 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 { - if let Some(kc) = self.single_byte[code as usize] { - Ok(kc) - } else { - Err(Error::UnknownKeyCode) - } - } - fn map_extended_scancode(&self, code: u8) -> Result { - 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, - shifted: Option, - altgr: Option, - raw_unicode: Option, - }, - Numlockable { - unshifted: Option, - shifted: Option, - locked: Option, - locked_shifted: Option, - }, - Capslockable { - unshifted: Option, - shifted: Option, - locked: Option, - locked_shifted: Option, - altgr: Option, - raw_unicode: Option, - }, -} -// 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, - b: Option, - c: Option, - d: Option, - ) { - 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, - b: Option, - c: Option, - ) { - 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, b: Option) { - 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) { - 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, - b: Option, - c: Option, - d: Option, - e: Option, - f: Option, - ) { - 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, - b: Option, - c: Option, - d: Option, - e: Option, - ) { - 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) { - 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, b: Option) { - self.mapping[index as usize] = { - LayoutEntry::Numlockable { - unshifted: a, - shifted: b, - locked: b, - locked_shifted: a, - } - }; - } -} diff --git a/ableos/src/keyboard/abstractions/custom_layout.rs b/ableos/src/keyboard/abstractions/custom_layout.rs new file mode 100644 index 0000000..25e3410 --- /dev/null +++ b/ableos/src/keyboard/abstractions/custom_layout.rs @@ -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; + } +} diff --git a/ableos/src/keyboard/abstractions/custom_scancode_set.rs b/ableos/src/keyboard/abstractions/custom_scancode_set.rs new file mode 100644 index 0000000..5f226d9 --- /dev/null +++ b/ableos/src/keyboard/abstractions/custom_scancode_set.rs @@ -0,0 +1,253 @@ +use crate::{KeyCode, ScancodeSet, DecodeState, KeyEvent, Error, KeyState, keyboard::EXTENDED_KEY_CODE}; + +pub struct CustomScancodeSet { + single_byte: [Option; 256], + extended: [Option; 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, 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 { + if let Some(kc) = self.single_byte[code as usize] { + Ok(kc) + } else { + Err(Error::UnknownKeyCode) + } + } + fn map_extended_scancode(&self, code: u8) -> Result { + if let Some(kc) = self.extended[code as usize] { + Ok(kc) + } else { + Err(Error::UnknownKeyCode) + } + } +} \ No newline at end of file diff --git a/ableos/src/keyboard/abstractions/layout_entry.rs b/ableos/src/keyboard/abstractions/layout_entry.rs new file mode 100644 index 0000000..4a58c86 --- /dev/null +++ b/ableos/src/keyboard/abstractions/layout_entry.rs @@ -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, + pub shifted: Option, + pub locked: Option, + pub locked_shifted: Option, + pub altgr: Option, + pub raw_unicode: Option, +} + +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) -> Self { + self.unshifted = Some(c.into()); + self + } + #[must_use] + pub fn shifted( mut self, c: impl Into) -> Self { + self.shifted = Some(c.into()); + self + } + #[must_use] + pub fn altgr( mut self, c: impl Into) -> Self { + self.altgr = Some(c.into()); + self + } + #[must_use] + pub fn raw_unicode( mut self, c: impl Into) -> Self { + self.raw_unicode = Some(c.into()); + self + } + #[must_use] + pub fn locked(mut self, c: impl Into) -> Self { + self.locked = Some(c.into()); + self + } + #[must_use] + pub fn locked_shifted(mut self, c: impl Into) -> Self { + self.locked_shifted = Some(c.into()); + self + } +} diff --git a/ableos/src/keyboard/abstractions/mod.rs b/ableos/src/keyboard/abstractions/mod.rs new file mode 100644 index 0000000..1f565e8 --- /dev/null +++ b/ableos/src/keyboard/abstractions/mod.rs @@ -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}; diff --git a/ableos/src/keyboard/small_types.rs b/ableos/src/keyboard/small_types.rs index 4d9d5e9..46c3bf7 100644 --- a/ableos/src/keyboard/small_types.rs +++ b/ableos/src/keyboard/small_types.rs @@ -1,103 +1,111 @@ #![allow(non_snake_case)] #[derive(Debug)] 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 lshift: bool, + pub rshift: bool, + pub lctrl: bool, + pub rctrl: bool, + pub numlock: bool, + pub capslock: bool, + pub alt_gr: bool, } impl Modifiers { - pub fn is_shifted(&self) -> bool { - self.lshift | self.rshift - } - pub fn is_ctrl(&self) -> bool { - self.lctrl | self.rctrl - } - pub fn is_caps(&self) -> bool { - self.capslock - } + pub fn is_shifted(&self) -> bool { + self.lshift | self.rshift + } + pub fn is_ctrl(&self) -> bool { + self.lctrl | self.rctrl + } + pub fn is_caps(&self) -> bool { + self.capslock + } } #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub enum KeyState { - Up, - Down, + Up, + Down, } #[derive(Debug, PartialEq, Eq, Clone)] pub struct KeyEvent { - pub code: KeyCode, - pub state: KeyState, + pub code: KeyCode, + pub state: KeyState, } impl KeyEvent { - pub fn new(code: KeyCode, state: KeyState) -> KeyEvent { - KeyEvent { code, state } - } + pub fn new(code: KeyCode, state: KeyState) -> KeyEvent { + KeyEvent { code, state } + } } #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub enum HandleControl { - /// 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 - /// down, letters go through normally. - MapLettersToUnicode, - /// Don't do anything special - send through the Ctrl key up/down events, - /// and leave the letters as letters. - Ignore, + /// 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 + /// down, letters go through normally. + MapLettersToUnicode, + /// Don't do anything special - send through the Ctrl key up/down events, + /// and leave the letters as letters. + Ignore, } #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum DecodeState { - Start, - Extended, - Release, - ExtendedRelease, + Start, + Extended, + Release, + ExtendedRelease, } /// Indicates different error conditions. #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub enum Error { - BadStartBit, - BadStopBit, - ParityError, - UnknownKeyCode, - InvalidState, + BadStartBit, + BadStopBit, + ParityError, + UnknownKeyCode, + InvalidState, } #[derive(Debug, PartialEq, Eq, Copy, Clone)] #[repr(u8)] pub enum DecodedKeyKind { - RawKey = 0, - Unicode = 1, + RawKey = 0, + Unicode = 1, } #[derive(Debug, PartialEq, Eq, Copy, Clone)] #[repr(C)] pub struct DecodedKey { - pub kind: DecodedKeyKind, - pub value: u32, + pub kind: DecodedKeyKind, + pub value: u32, } impl From for DecodedKey { - fn from(ch: char) -> Self { - Self { - kind: DecodedKeyKind::Unicode, - value: ch as u32, - } - } + fn from(ch: char) -> Self { + Self { + kind: DecodedKeyKind::Unicode, + value: ch as u32, + } + } +} +impl From for DecodedKey { + fn from(kc: KeyCode) -> Self { + Self { + kind: DecodedKeyKind::RawKey, + value: kc as u32, + } + } } impl DecodedKey { - pub const ZERO: Self = Self { - kind: DecodedKeyKind::Unicode, - value: 0, - }; - pub fn Unicode(ch: char) -> Self { - Self { - kind: DecodedKeyKind::Unicode, - value: ch.into(), - } - } - pub fn RawKey(byte: u8) -> Self { - Self { - kind: DecodedKeyKind::RawKey, - value: byte.into(), - } - } + pub const ZERO: Self = Self { + kind: DecodedKeyKind::Unicode, + value: 0, + }; + pub fn Unicode(ch: char) -> Self { + Self { + kind: DecodedKeyKind::Unicode, + value: ch.into(), + } + } + pub fn RawKey(byte: u8) -> Self { + Self { + kind: DecodedKeyKind::RawKey, + value: byte.into(), + } + } } macro_rules! keycode_enum { (@get_last $Variant:ident) => {