forked from koniifer/ableos
Merge branch 'master' of ssh://git.ablecorp.us:20/able/ableos
This commit is contained in:
commit
b3b79e1694
|
@ -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
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
176
ableos/src/keyboard/abstractions/custom_layout.rs
Normal file
176
ableos/src/keyboard/abstractions/custom_layout.rs
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
use crate::{
|
||||||
|
DecodedKey, HandleControl, KeyCode, KeyboardLayout, LayoutEntry, LayoutEntryKind, Modifiers,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[rustfmt::skip]
|
||||||
|
impl CustomLayout {
|
||||||
|
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().all('\x08'));
|
||||||
|
mapping.set(KeyCode::Tab, LayoutEntry::regular().all('\x09'));
|
||||||
|
mapping.set(KeyCode::Q, LayoutEntry::alphabet().low('q').high('Q').raw_unicode('\u{0011}'));
|
||||||
|
mapping.set(KeyCode::W, LayoutEntry::alphabet().low('w').high('W').raw_unicode('\u{0017}'));
|
||||||
|
mapping.set(KeyCode::E, LayoutEntry::alphabet().low('e').high('E').raw_unicode('\u{0005}'));
|
||||||
|
mapping.set(KeyCode::R, LayoutEntry::alphabet().low('r').high('R').raw_unicode('\u{0012}'));
|
||||||
|
mapping.set(KeyCode::T, LayoutEntry::alphabet().low('t').high('T').raw_unicode('\u{0014}'));
|
||||||
|
mapping.set(KeyCode::Y, LayoutEntry::alphabet().low('y').high('Y').raw_unicode('\u{0019}'));
|
||||||
|
mapping.set(KeyCode::U, LayoutEntry::alphabet().low('u').high('U').raw_unicode('\u{0015}'));
|
||||||
|
mapping.set(KeyCode::I, LayoutEntry::alphabet().low('i').high('I').raw_unicode('\u{0009}'));
|
||||||
|
mapping.set(KeyCode::O, LayoutEntry::alphabet().low('o').high('O').raw_unicode('\u{000F}'));
|
||||||
|
mapping.set(KeyCode::P, LayoutEntry::alphabet().low('p').high('P').raw_unicode('\u{0010}'));
|
||||||
|
mapping.set(KeyCode::A, LayoutEntry::alphabet().low('a').high('A').raw_unicode('\u{0001}'));
|
||||||
|
mapping.set(KeyCode::S, LayoutEntry::alphabet().low('s').high('S').raw_unicode('\u{0013}'));
|
||||||
|
mapping.set(KeyCode::D, LayoutEntry::alphabet().low('d').high('D').raw_unicode('\u{0004}'));
|
||||||
|
mapping.set(KeyCode::F, LayoutEntry::alphabet().low('f').high('F').raw_unicode('\u{0006}'));
|
||||||
|
mapping.set(KeyCode::G, LayoutEntry::alphabet().low('g').high('G').raw_unicode('\u{0007}'));
|
||||||
|
mapping.set(KeyCode::H, LayoutEntry::alphabet().low('h').high('H').raw_unicode('\u{0008}'));
|
||||||
|
mapping.set(KeyCode::J, LayoutEntry::alphabet().low('j').high('J').raw_unicode('\u{000A}'));
|
||||||
|
mapping.set(KeyCode::K, LayoutEntry::alphabet().low('k').high('K').raw_unicode('\u{000B}'));
|
||||||
|
mapping.set(KeyCode::L, LayoutEntry::alphabet().low('l').high('L').raw_unicode('\u{000C}'));
|
||||||
|
mapping.set(KeyCode::Z, LayoutEntry::alphabet().low('z').high('Z').raw_unicode('\u{001A}'));
|
||||||
|
mapping.set(KeyCode::X, LayoutEntry::alphabet().low('x').high('X').raw_unicode('\u{0018}'));
|
||||||
|
mapping.set(KeyCode::C, LayoutEntry::alphabet().low('c').high('C').raw_unicode('\u{0003}'));
|
||||||
|
mapping.set(KeyCode::V, LayoutEntry::alphabet().low('v').high('V').raw_unicode('\u{0016}'));
|
||||||
|
mapping.set(KeyCode::B, LayoutEntry::alphabet().low('b').high('B').raw_unicode('\u{0002}'));
|
||||||
|
mapping.set(KeyCode::N, LayoutEntry::alphabet().low('n').high('N').raw_unicode('\u{000E}'));
|
||||||
|
mapping.set(KeyCode::M, LayoutEntry::alphabet().low('m').high('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().all('\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().all(' '));
|
||||||
|
mapping.set(KeyCode::Delete, LayoutEntry::regular().all('\x7F'));
|
||||||
|
mapping.set(KeyCode::NumpadSlash, LayoutEntry::numpad().all('/'));
|
||||||
|
mapping.set(KeyCode::NumpadStar, LayoutEntry::numpad().all('*'));
|
||||||
|
mapping.set(KeyCode::NumpadMinus, LayoutEntry::numpad().all('-'));
|
||||||
|
mapping.set(KeyCode::Numpad7, LayoutEntry::numpad().low('7').high(KeyCode::Home));
|
||||||
|
mapping.set(KeyCode::Numpad8, LayoutEntry::numpad().low('8').high(KeyCode::ArrowUp));
|
||||||
|
mapping.set(KeyCode::Numpad9, LayoutEntry::numpad().low('9').high(KeyCode::PageUp));
|
||||||
|
mapping.set(KeyCode::NumpadPlus, LayoutEntry::numpad().all('+'));
|
||||||
|
mapping.set(KeyCode::Numpad4, LayoutEntry::numpad().low('4').high(KeyCode::ArrowLeft));
|
||||||
|
mapping.set(KeyCode::Numpad5, LayoutEntry::numpad().all('5'));
|
||||||
|
mapping.set(KeyCode::Numpad6, LayoutEntry::numpad().low('6').high(KeyCode::ArrowRight));
|
||||||
|
mapping.set(KeyCode::Numpad1, LayoutEntry::numpad().low('1').high(KeyCode::End));
|
||||||
|
mapping.set(KeyCode::Numpad2, LayoutEntry::numpad().low('2').high(KeyCode::ArrowDown));
|
||||||
|
mapping.set(KeyCode::Numpad3, LayoutEntry::numpad().low('3').high(KeyCode::PageDown));
|
||||||
|
mapping.set(KeyCode::Numpad0, LayoutEntry::numpad().low('0').high(KeyCode::Insert));
|
||||||
|
mapping.set(KeyCode::NumpadPeriod, LayoutEntry::numpad().low('.').high('\x7F'));
|
||||||
|
mapping.set(KeyCode::NumpadEnter, LayoutEntry::numpad().all('\x0A'));
|
||||||
|
mapping
|
||||||
|
}
|
||||||
|
pub fn new_us105key() -> Self {
|
||||||
|
let mut mapping = Self::new_us104key();
|
||||||
|
mapping.set(KeyCode::BackTick, LayoutEntry::regular().unshifted('`').shifted('¬').altgr('|'));
|
||||||
|
mapping.set(KeyCode::Key2, LayoutEntry::regular().unshifted('2').shifted('"'));
|
||||||
|
mapping.set(KeyCode::Quote, LayoutEntry::regular().unshifted('\'').shifted('@'));
|
||||||
|
mapping.set(KeyCode::Key3, LayoutEntry::regular().unshifted('3').shifted('£'));
|
||||||
|
mapping.set(KeyCode::BackTick, LayoutEntry::regular().unshifted('4').shifted('$').altgr('€'));
|
||||||
|
mapping.set(KeyCode::HashTilde, LayoutEntry::regular().unshifted('#').shifted('~'));
|
||||||
|
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 {
|
||||||
|
// See how hard this is to get right?
|
||||||
|
// See the complexity of all the methods?
|
||||||
|
// Yeah- if you don't know what you're doing, ask before you touch!
|
||||||
|
pub fn set(&mut self, pos: KeyCode, entry: LayoutEntry) {
|
||||||
|
self.mapping[pos as usize] = entry;
|
||||||
|
}
|
||||||
|
}
|
253
ableos/src/keyboard/abstractions/custom_scancode_set.rs
Normal file
253
ableos/src/keyboard/abstractions/custom_scancode_set.rs
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
105
ableos/src/keyboard/abstractions/layout_entry.rs
Normal file
105
ableos/src/keyboard/abstractions/layout_entry.rs
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
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 numpad() -> Self {
|
||||||
|
Self {
|
||||||
|
kind: LayoutEntryKind::Numlockable,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[must_use]
|
||||||
|
pub fn alphabet() -> 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
|
||||||
|
}
|
||||||
|
#[must_use]
|
||||||
|
pub fn common(self, c: impl Into<DecodedKey> + Clone) -> Self {
|
||||||
|
self
|
||||||
|
.unshifted(c.clone())
|
||||||
|
.shifted(c.clone())
|
||||||
|
.locked(c.clone())
|
||||||
|
.locked_shifted(c)
|
||||||
|
}
|
||||||
|
#[must_use]
|
||||||
|
pub fn low(self, c: impl Into<DecodedKey> + Clone) -> Self {
|
||||||
|
self.unshifted(c.clone()).locked_shifted(c)
|
||||||
|
}
|
||||||
|
#[must_use]
|
||||||
|
pub fn high(self, c: impl Into<DecodedKey> + Clone) -> Self {
|
||||||
|
self.shifted(c.clone()).locked(c)
|
||||||
|
}
|
||||||
|
#[must_use]
|
||||||
|
pub fn all(self, c: impl Into<DecodedKey> + Clone) -> Self {
|
||||||
|
self
|
||||||
|
.unshifted(c.clone())
|
||||||
|
.shifted(c.clone())
|
||||||
|
.locked(c.clone())
|
||||||
|
.locked_shifted(c.clone())
|
||||||
|
.altgr(c.clone())
|
||||||
|
.raw_unicode(c)
|
||||||
|
}
|
||||||
|
}
|
9
ableos/src/keyboard/abstractions/mod.rs
Normal file
9
ableos/src/keyboard/abstractions/mod.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
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};
|
|
@ -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) => {
|
||||||
|
|
Loading…
Reference in a new issue