Map keyboard to bépo
This commit is contained in:
@@ -7,7 +7,5 @@ edition = "2024"
|
|||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2 = "1"
|
|
||||||
quote = "1"
|
|
||||||
syn = { version = "2", features = ["full"] }
|
syn = { version = "2", features = ["full"] }
|
||||||
zyn = "0.5"
|
zyn = "0.5"
|
||||||
|
|||||||
@@ -8,8 +8,5 @@ proc-macro = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
image = "0.25"
|
image = "0.25"
|
||||||
regex = "1"
|
|
||||||
proc-macro2 = "1"
|
|
||||||
quote = "1"
|
|
||||||
syn = { version = "2", features = ["full"] }
|
syn = { version = "2", features = ["full"] }
|
||||||
zyn = "0.5"
|
zyn = "0.5"
|
||||||
|
|||||||
@@ -1,13 +1,6 @@
|
|||||||
use image::{ImageBuffer, Luma};
|
use image::{ImageBuffer, Luma};
|
||||||
use proc_macro::{Span, TokenStream};
|
use proc_macro::TokenStream;
|
||||||
use quote::quote;
|
use zyn::{ToTokens, zyn};
|
||||||
use regex::Regex;
|
|
||||||
use syn::parse::Parse;
|
|
||||||
|
|
||||||
fn remove_non_alphanumeric(input: &str) -> String {
|
|
||||||
let re = Regex::new(r"[^a-zA-Z0-9_]+").unwrap();
|
|
||||||
re.replace_all(input, "").to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_format(img: ImageBuffer<Luma<u8>, Vec<u8>>, width: usize, height: usize) -> Vec<u8> {
|
fn to_format(img: ImageBuffer<Luma<u8>, Vec<u8>>, width: usize, height: usize) -> Vec<u8> {
|
||||||
let mut output = Vec::new();
|
let mut output = Vec::new();
|
||||||
@@ -48,25 +41,10 @@ fn path_to_image(path: &str) -> (Vec<u8>, usize, usize) {
|
|||||||
(bytes, width, height)
|
(bytes, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ParsedArgs {
|
pub fn parse_image(input: TokenStream) -> Result<(u8, u8, usize, Vec<u8>), syn::Error> {
|
||||||
path: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Parse for ParsedArgs {
|
|
||||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
|
||||||
let path: syn::LitStr = input.parse()?;
|
|
||||||
let path = path.value();
|
|
||||||
Ok(ParsedArgs { path })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_image(
|
|
||||||
input: TokenStream,
|
|
||||||
) -> Result<(u8, u8, usize, Vec<proc_macro2::TokenStream>), syn::Error> {
|
|
||||||
// parse the input into a comma separated list of arguments
|
// parse the input into a comma separated list of arguments
|
||||||
let parsed_args = syn::parse::<ParsedArgs>(input)?;
|
let path = syn::parse::<syn::LitStr>(input)?.value();
|
||||||
// let parsed_args = parse_macro_input!(input as ParsedArgs);
|
let (bytes, width, height) = path_to_image(&path);
|
||||||
let (bytes, width, height) = path_to_image(&parsed_args.path);
|
|
||||||
|
|
||||||
let width = width as u8;
|
let width = width as u8;
|
||||||
let height = height as u8;
|
let height = height as u8;
|
||||||
@@ -74,15 +52,19 @@ pub fn parse_image(
|
|||||||
let byte_array = bytes.as_slice();
|
let byte_array = bytes.as_slice();
|
||||||
let byte_count = byte_array.len();
|
let byte_count = byte_array.len();
|
||||||
|
|
||||||
let byte_tokens = bytes.iter().map(|b| quote! { #b }).collect::<Vec<_>>();
|
Ok((width, height, byte_count, bytes))
|
||||||
Ok((width, height, byte_count, byte_tokens))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn include_bitmap_image_impl(input: TokenStream) -> TokenStream {
|
pub fn include_bitmap_image_impl(input: TokenStream) -> TokenStream {
|
||||||
let (_, _, _, byte_tokens) = parse_image(input).unwrap();
|
let (_, _, _, byte_tokens) = parse_image(input).unwrap();
|
||||||
|
|
||||||
let output = quote! {
|
let output = zyn! {
|
||||||
[#(#byte_tokens),*]
|
|
||||||
|
[
|
||||||
|
@for (byte_token in byte_tokens) {
|
||||||
|
{{ byte_token }},
|
||||||
|
}
|
||||||
|
]
|
||||||
};
|
};
|
||||||
output.into()
|
output.to_token_stream().into()
|
||||||
}
|
}
|
||||||
|
|||||||
330
src/keymap.rs
330
src/keymap.rs
@@ -1,64 +1,296 @@
|
|||||||
|
use crate::KeyboardState;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
#[derive_const(PartialEq, Eq)]
|
||||||
|
pub enum ModifierType {
|
||||||
|
Shift,
|
||||||
|
Alt,
|
||||||
|
AltGr,
|
||||||
|
Control,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
#[derive_const(PartialEq, Eq)]
|
||||||
pub enum KeyType {
|
pub enum KeyType {
|
||||||
Ascii(char),
|
Ascii(char),
|
||||||
// Special, // F1, Home, etc.
|
// Special, // F1, Home, etc.
|
||||||
Modifier, // Shift, Ctrl
|
Modifier(ModifierType),
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn map_keycode(code: u16, shift: bool) -> KeyType {
|
pub const fn map_keycode(code: u16, state: &KeyboardState) -> KeyType {
|
||||||
match code {
|
let res = match code {
|
||||||
// Numbers row
|
KEY_BACKSPACE => KeyType::Ascii('\x08'),
|
||||||
2..=11 => {
|
KEY_ESCAPE => KeyType::Ascii('\x1b'),
|
||||||
let val = if shift {
|
KEY_TAB => KeyType::Ascii('\t'),
|
||||||
[')', '!', '@', '#', '$', '%', '^', '&', '*', '('][(code - 2) as usize]
|
KEY_ENTER => KeyType::Ascii('\n'),
|
||||||
} else {
|
KEY_SPACE => KeyType::Ascii(' '),
|
||||||
(code as u8 - 2 + b'1') as char
|
KEY_LEFTSHIFT | KEY_RIGHTSHIFT => KeyType::Modifier(ModifierType::Shift),
|
||||||
|
KEY_LEFTCTRL => KeyType::Modifier(ModifierType::Control),
|
||||||
|
KEY_LEFTALT => KeyType::Modifier(ModifierType::Alt),
|
||||||
|
KEY_RIGHTALT => KeyType::Modifier(ModifierType::AltGr),
|
||||||
|
|
||||||
|
_ => KeyType::Unknown,
|
||||||
};
|
};
|
||||||
if code == 11 && !shift {
|
if res != KeyType::Unknown {
|
||||||
KeyType::Ascii('0')
|
return res;
|
||||||
} else {
|
|
||||||
KeyType::Ascii(val)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Letters (Simplified QWERTY)
|
if state.shift_modifier {
|
||||||
16 => KeyType::Ascii(if shift { 'Q' } else { 'q' }),
|
match code {
|
||||||
17 => KeyType::Ascii(if shift { 'W' } else { 'w' }),
|
KEY_1 => KeyType::Ascii('1'),
|
||||||
18 => KeyType::Ascii(if shift { 'E' } else { 'e' }),
|
KEY_2 => KeyType::Ascii('2'),
|
||||||
19 => KeyType::Ascii(if shift { 'R' } else { 'r' }),
|
KEY_3 => KeyType::Ascii('3'),
|
||||||
20 => KeyType::Ascii(if shift { 'T' } else { 't' }),
|
KEY_4 => KeyType::Ascii('4'),
|
||||||
21 => KeyType::Ascii(if shift { 'Y' } else { 'y' }),
|
KEY_5 => KeyType::Ascii('5'),
|
||||||
22 => KeyType::Ascii(if shift { 'U' } else { 'u' }),
|
KEY_6 => KeyType::Ascii('6'),
|
||||||
23 => KeyType::Ascii(if shift { 'I' } else { 'i' }),
|
KEY_7 => KeyType::Ascii('7'),
|
||||||
24 => KeyType::Ascii(if shift { 'O' } else { 'o' }),
|
KEY_8 => KeyType::Ascii('8'),
|
||||||
25 => KeyType::Ascii(if shift { 'P' } else { 'p' }),
|
KEY_9 => KeyType::Ascii('9'),
|
||||||
30 => KeyType::Ascii(if shift { 'A' } else { 'a' }),
|
KEY_0 => KeyType::Ascii('0'),
|
||||||
31 => KeyType::Ascii(if shift { 'S' } else { 's' }),
|
KEY_MINUS => KeyType::Ascii('°'),
|
||||||
32 => KeyType::Ascii(if shift { 'D' } else { 'd' }),
|
KEY_EQUAL => KeyType::Ascii('`'),
|
||||||
33 => KeyType::Ascii(if shift { 'F' } else { 'f' }),
|
|
||||||
34 => KeyType::Ascii(if shift { 'G' } else { 'g' }),
|
|
||||||
35 => KeyType::Ascii(if shift { 'H' } else { 'h' }),
|
|
||||||
36 => KeyType::Ascii(if shift { 'J' } else { 'j' }),
|
|
||||||
37 => KeyType::Ascii(if shift { 'K' } else { 'k' }),
|
|
||||||
38 => KeyType::Ascii(if shift { 'L' } else { 'l' }),
|
|
||||||
44 => KeyType::Ascii(if shift { 'Z' } else { 'z' }),
|
|
||||||
45 => KeyType::Ascii(if shift { 'X' } else { 'x' }),
|
|
||||||
46 => KeyType::Ascii(if shift { 'C' } else { 'c' }),
|
|
||||||
47 => KeyType::Ascii(if shift { 'V' } else { 'v' }),
|
|
||||||
48 => KeyType::Ascii(if shift { 'B' } else { 'b' }),
|
|
||||||
49 => KeyType::Ascii(if shift { 'N' } else { 'n' }),
|
|
||||||
50 => KeyType::Ascii(if shift { 'M' } else { 'm' }),
|
|
||||||
|
|
||||||
// Control
|
KEY_Q => KeyType::Ascii('B'),
|
||||||
28 => KeyType::Ascii('\n'),
|
KEY_W => KeyType::Ascii('É'),
|
||||||
57 => KeyType::Ascii(' '),
|
KEY_E => KeyType::Ascii('P'),
|
||||||
14 => KeyType::Ascii('\x08'), // Backspace
|
KEY_R => KeyType::Ascii('O'),
|
||||||
1 => KeyType::Ascii('\x1b'), // Escape
|
KEY_T => KeyType::Ascii('È'),
|
||||||
|
KEY_Y => KeyType::Ascii('!'),
|
||||||
|
KEY_U => KeyType::Ascii('V'),
|
||||||
|
KEY_I => KeyType::Ascii('D'),
|
||||||
|
KEY_O => KeyType::Ascii('L'),
|
||||||
|
KEY_P => KeyType::Ascii('J'),
|
||||||
|
KEY_A => KeyType::Ascii('A'),
|
||||||
|
KEY_S => KeyType::Ascii('U'),
|
||||||
|
KEY_D => KeyType::Ascii('I'),
|
||||||
|
KEY_F => KeyType::Ascii('E'),
|
||||||
|
KEY_G => KeyType::Ascii(';'),
|
||||||
|
KEY_H => KeyType::Ascii('C'),
|
||||||
|
KEY_J => KeyType::Ascii('T'),
|
||||||
|
KEY_K => KeyType::Ascii('S'),
|
||||||
|
KEY_L => KeyType::Ascii('R'),
|
||||||
|
KEY_Z => KeyType::Ascii('À'),
|
||||||
|
KEY_X => KeyType::Ascii('Y'),
|
||||||
|
KEY_C => KeyType::Ascii('X'),
|
||||||
|
KEY_V => KeyType::Ascii(':'),
|
||||||
|
KEY_B => KeyType::Ascii('K'),
|
||||||
|
KEY_N => KeyType::Ascii('?'),
|
||||||
|
KEY_M => KeyType::Ascii('Q'),
|
||||||
|
|
||||||
// Modifiers
|
KEY_LEFTBRACE => KeyType::Ascii('Z'),
|
||||||
42 | 54 => KeyType::Modifier, // LShift, RShift
|
KEY_RIGHTBRACE => KeyType::Ascii('W'),
|
||||||
29 | 97 => KeyType::Modifier, // LCtrl, RCtrl
|
KEY_BACKSLASH => KeyType::Ascii('Ç'),
|
||||||
|
|
||||||
|
KEY_SEMICOLON => KeyType::Ascii('N'),
|
||||||
|
KEY_APOSTROPHE => KeyType::Ascii('M'),
|
||||||
|
|
||||||
|
KEY_COMMA => KeyType::Ascii('G'),
|
||||||
|
KEY_DOT => KeyType::Ascii('H'),
|
||||||
|
KEY_SLASH => KeyType::Ascii('F'),
|
||||||
|
|
||||||
_ => KeyType::Unknown,
|
_ => KeyType::Unknown,
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if state.alt_gr_modifier {
|
||||||
|
match code {
|
||||||
|
// KEY_1 => KeyType::Ascii('—'),
|
||||||
|
KEY_2 => KeyType::Ascii('<'),
|
||||||
|
KEY_3 => KeyType::Ascii('>'),
|
||||||
|
KEY_4 => KeyType::Ascii('['),
|
||||||
|
KEY_5 => KeyType::Ascii(']'),
|
||||||
|
KEY_6 => KeyType::Ascii('^'),
|
||||||
|
KEY_7 => KeyType::Ascii('±'),
|
||||||
|
// KEY_8 => KeyType::Ascii('−'),
|
||||||
|
KEY_9 => KeyType::Ascii('÷'),
|
||||||
|
KEY_0 => KeyType::Ascii('×'),
|
||||||
|
// KEY_MINUS => KeyType::Ascii('≠'),
|
||||||
|
// KEY_EQUAL => KeyType::Ascii('‰'),
|
||||||
|
KEY_Q => KeyType::Ascii('|'),
|
||||||
|
// KEY_W => KeyType::Ascii(''),
|
||||||
|
KEY_E => KeyType::Ascii('&'),
|
||||||
|
KEY_R => KeyType::Ascii('œ'),
|
||||||
|
// KEY_T => KeyType::Ascii(''),
|
||||||
|
KEY_Y => KeyType::Ascii('¡'),
|
||||||
|
// KEY_U => KeyType::Ascii(''),
|
||||||
|
KEY_I => KeyType::Ascii('ð'),
|
||||||
|
// KEY_O => KeyType::Ascii(''),
|
||||||
|
KEY_P => KeyType::Ascii('ij'),
|
||||||
|
KEY_A => KeyType::Ascii('æ'),
|
||||||
|
KEY_S => KeyType::Ascii('ù'),
|
||||||
|
// KEY_D => KeyType::Ascii(''),
|
||||||
|
// KEY_F => KeyType::Ascii('€'),
|
||||||
|
// KEY_G => KeyType::Ascii('’'),
|
||||||
|
KEY_H => KeyType::Ascii('©'),
|
||||||
|
KEY_J => KeyType::Ascii('þ'),
|
||||||
|
KEY_K => KeyType::Ascii('ß'),
|
||||||
|
KEY_L => KeyType::Ascii('®'),
|
||||||
|
KEY_Z => KeyType::Ascii('\\'),
|
||||||
|
KEY_X => KeyType::Ascii('{'),
|
||||||
|
KEY_C => KeyType::Ascii('}'),
|
||||||
|
// KEY_V => KeyType::Ascii('…'),
|
||||||
|
KEY_B => KeyType::Ascii('~'),
|
||||||
|
KEY_N => KeyType::Ascii('¿'),
|
||||||
|
// KEY_M => KeyType::Ascii(''),
|
||||||
|
KEY_LEFTBRACE => KeyType::Ascii('ə'),
|
||||||
|
// KEY_RIGHTBRACE => KeyType::Ascii(''),
|
||||||
|
// KEY_SEMICOLON => KeyType::Ascii(''),
|
||||||
|
// KEY_APOSTROPHE => KeyType::Ascii(''),
|
||||||
|
// KEY_COMMA => KeyType::Ascii(''),
|
||||||
|
// KEY_DOT => KeyType::Ascii('†'),
|
||||||
|
// KEY_SLASH => KeyType::Ascii(''),
|
||||||
|
_ => KeyType::Unknown,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
match code {
|
||||||
|
KEY_1 => KeyType::Ascii('"'),
|
||||||
|
KEY_2 => KeyType::Ascii('«'),
|
||||||
|
KEY_3 => KeyType::Ascii('»'),
|
||||||
|
KEY_4 => KeyType::Ascii('('),
|
||||||
|
KEY_5 => KeyType::Ascii(')'),
|
||||||
|
KEY_6 => KeyType::Ascii('@'),
|
||||||
|
KEY_7 => KeyType::Ascii('+'),
|
||||||
|
KEY_8 => KeyType::Ascii('-'),
|
||||||
|
KEY_9 => KeyType::Ascii('/'),
|
||||||
|
KEY_0 => KeyType::Ascii('*'),
|
||||||
|
KEY_MINUS => KeyType::Ascii('='),
|
||||||
|
KEY_EQUAL => KeyType::Ascii('%'),
|
||||||
|
|
||||||
|
KEY_Q => KeyType::Ascii('b'),
|
||||||
|
KEY_W => KeyType::Ascii('é'),
|
||||||
|
KEY_E => KeyType::Ascii('p'),
|
||||||
|
KEY_R => KeyType::Ascii('o'),
|
||||||
|
KEY_T => KeyType::Ascii('è'),
|
||||||
|
KEY_Y => KeyType::Ascii('^'),
|
||||||
|
KEY_U => KeyType::Ascii('v'),
|
||||||
|
KEY_I => KeyType::Ascii('d'),
|
||||||
|
KEY_O => KeyType::Ascii('l'),
|
||||||
|
KEY_P => KeyType::Ascii('j'),
|
||||||
|
KEY_A => KeyType::Ascii('a'),
|
||||||
|
KEY_S => KeyType::Ascii('u'),
|
||||||
|
KEY_D => KeyType::Ascii('i'),
|
||||||
|
KEY_F => KeyType::Ascii('e'),
|
||||||
|
KEY_G => KeyType::Ascii(','),
|
||||||
|
KEY_H => KeyType::Ascii('c'),
|
||||||
|
KEY_J => KeyType::Ascii('t'),
|
||||||
|
KEY_K => KeyType::Ascii('s'),
|
||||||
|
KEY_L => KeyType::Ascii('r'),
|
||||||
|
KEY_Z => KeyType::Ascii('à'),
|
||||||
|
KEY_X => KeyType::Ascii('y'),
|
||||||
|
KEY_C => KeyType::Ascii('x'),
|
||||||
|
KEY_V => KeyType::Ascii('.'),
|
||||||
|
KEY_B => KeyType::Ascii('k'),
|
||||||
|
KEY_N => KeyType::Ascii('\''),
|
||||||
|
KEY_M => KeyType::Ascii('q'),
|
||||||
|
|
||||||
|
KEY_LEFTBRACE => KeyType::Ascii('z'),
|
||||||
|
KEY_RIGHTBRACE => KeyType::Ascii('w'),
|
||||||
|
KEY_BACKSLASH => KeyType::Ascii('ç'),
|
||||||
|
|
||||||
|
KEY_SEMICOLON => KeyType::Ascii('n'),
|
||||||
|
KEY_APOSTROPHE => KeyType::Ascii('m'),
|
||||||
|
|
||||||
|
KEY_COMMA => KeyType::Ascii('g'),
|
||||||
|
KEY_DOT => KeyType::Ascii('h'),
|
||||||
|
KEY_SLASH => KeyType::Ascii('f'),
|
||||||
|
|
||||||
|
_ => KeyType::Unknown,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pub const KEY_RESERVED: u16 = 0;
|
||||||
|
pub const KEY_ESCAPE: u16 = 1;
|
||||||
|
|
||||||
|
pub const KEY_1: u16 = 2;
|
||||||
|
pub const KEY_2: u16 = 3;
|
||||||
|
pub const KEY_3: u16 = 4;
|
||||||
|
pub const KEY_4: u16 = 5;
|
||||||
|
pub const KEY_5: u16 = 6;
|
||||||
|
pub const KEY_6: u16 = 7;
|
||||||
|
pub const KEY_7: u16 = 8;
|
||||||
|
pub const KEY_8: u16 = 9;
|
||||||
|
pub const KEY_9: u16 = 10;
|
||||||
|
pub const KEY_0: u16 = 11;
|
||||||
|
pub const KEY_MINUS: u16 = 12;
|
||||||
|
pub const KEY_EQUAL: u16 = 13;
|
||||||
|
pub const KEY_BACKSPACE: u16 = 14;
|
||||||
|
|
||||||
|
pub const KEY_TAB: u16 = 15;
|
||||||
|
|
||||||
|
pub const KEY_Q: u16 = 16;
|
||||||
|
pub const KEY_W: u16 = 17;
|
||||||
|
pub const KEY_E: u16 = 18;
|
||||||
|
pub const KEY_R: u16 = 19;
|
||||||
|
pub const KEY_T: u16 = 20;
|
||||||
|
pub const KEY_Y: u16 = 21;
|
||||||
|
pub const KEY_U: u16 = 22;
|
||||||
|
pub const KEY_I: u16 = 23;
|
||||||
|
pub const KEY_O: u16 = 24;
|
||||||
|
pub const KEY_P: u16 = 25;
|
||||||
|
|
||||||
|
pub const KEY_LEFTBRACE: u16 = 26;
|
||||||
|
pub const KEY_RIGHTBRACE: u16 = 27;
|
||||||
|
|
||||||
|
pub const KEY_ENTER: u16 = 28;
|
||||||
|
pub const KEY_LEFTCTRL: u16 = 29;
|
||||||
|
|
||||||
|
pub const KEY_A: u16 = 30;
|
||||||
|
pub const KEY_S: u16 = 31;
|
||||||
|
pub const KEY_D: u16 = 32;
|
||||||
|
pub const KEY_F: u16 = 33;
|
||||||
|
pub const KEY_G: u16 = 34;
|
||||||
|
pub const KEY_H: u16 = 35;
|
||||||
|
pub const KEY_J: u16 = 36;
|
||||||
|
pub const KEY_K: u16 = 37;
|
||||||
|
pub const KEY_L: u16 = 38;
|
||||||
|
|
||||||
|
pub const KEY_SEMICOLON: u16 = 39;
|
||||||
|
pub const KEY_APOSTROPHE: u16 = 40;
|
||||||
|
// pub const KEY_GRAVE: u16 = 41;
|
||||||
|
|
||||||
|
pub const KEY_LEFTSHIFT: u16 = 42;
|
||||||
|
pub const KEY_BACKSLASH: u16 = 43;
|
||||||
|
pub const KEY_Z: u16 = 44;
|
||||||
|
pub const KEY_X: u16 = 45;
|
||||||
|
pub const KEY_C: u16 = 46;
|
||||||
|
pub const KEY_V: u16 = 47;
|
||||||
|
pub const KEY_B: u16 = 48;
|
||||||
|
pub const KEY_N: u16 = 49;
|
||||||
|
pub const KEY_M: u16 = 50;
|
||||||
|
pub const KEY_COMMA: u16 = 51;
|
||||||
|
pub const KEY_DOT: u16 = 52;
|
||||||
|
pub const KEY_SLASH: u16 = 53;
|
||||||
|
|
||||||
|
pub const KEY_RIGHTSHIFT: u16 = 54;
|
||||||
|
pub const KEY_LEFTALT: u16 = 56;
|
||||||
|
pub const KEY_SPACE: u16 = 57;
|
||||||
|
// pub const KEY_CAPSLOCK: u16 = 58;
|
||||||
|
|
||||||
|
// pub const KEY_F1: u16 = 59;
|
||||||
|
// pub const KEY_F2: u16 = 60;
|
||||||
|
// pub const KEY_F3: u16 = 61;
|
||||||
|
// pub const KEY_F4: u16 = 62;
|
||||||
|
// pub const KEY_F5: u16 = 63;
|
||||||
|
// pub const KEY_F6: u16 = 64;
|
||||||
|
// pub const KEY_F7: u16 = 65;
|
||||||
|
// pub const KEY_F8: u16 = 66;
|
||||||
|
// pub const KEY_F9: u16 = 67;
|
||||||
|
// pub const KEY_F10: u16 = 68;
|
||||||
|
|
||||||
|
pub const KEY_RIGHTALT: u16 = 100;
|
||||||
|
// pub const KEY_HOME: u16 = 102;
|
||||||
|
// pub const KEY_UP: u16 = 103;
|
||||||
|
// pub const KEY_PAGEUP: u16 = 104;
|
||||||
|
// pub const KEY_LEFT: u16 = 105;
|
||||||
|
// pub const KEY_RIGHT: u16 = 106;
|
||||||
|
// pub const KEY_END: u16 = 107;
|
||||||
|
// pub const KEY_DOWN: u16 = 108;
|
||||||
|
// pub const KEY_PAGEDOWN: u16 = 109;
|
||||||
|
// pub const KEY_INSERT: u16 = 110;
|
||||||
|
// pub const KEY_DELETE: u16 = 111;
|
||||||
|
|
||||||
|
// pub const KEY_MUTE: u16 = 113;
|
||||||
|
// pub const KEY_VOLUMEDOWN: u16 = 114;
|
||||||
|
// pub const KEY_VOLUMEUP: u16 = 115;
|
||||||
|
|||||||
37
src/main.rs
37
src/main.rs
@@ -9,7 +9,10 @@
|
|||||||
#![feature(
|
#![feature(
|
||||||
riscv_ext_intrinsics,
|
riscv_ext_intrinsics,
|
||||||
str_from_raw_parts,
|
str_from_raw_parts,
|
||||||
arbitrary_self_types_pointers
|
arbitrary_self_types_pointers,
|
||||||
|
derive_const,
|
||||||
|
const_cmp,
|
||||||
|
const_trait_impl
|
||||||
)]
|
)]
|
||||||
|
|
||||||
use core::sync::atomic::AtomicBool;
|
use core::sync::atomic::AtomicBool;
|
||||||
@@ -21,7 +24,7 @@ use log::info;
|
|||||||
use crate::{
|
use crate::{
|
||||||
cursor::{clear_cursor, draw_cursor},
|
cursor::{clear_cursor, draw_cursor},
|
||||||
io::init_log,
|
io::init_log,
|
||||||
keymap::map_keycode,
|
keymap::{KeyType, ModifierType, map_keycode},
|
||||||
pci::{PciDeviceIterator, scan_virtio_devices},
|
pci::{PciDeviceIterator, scan_virtio_devices},
|
||||||
riscv::enable_supervisor_interrupt,
|
riscv::enable_supervisor_interrupt,
|
||||||
scheduler::{SCHEDULER, idle},
|
scheduler::{SCHEDULER, idle},
|
||||||
@@ -75,23 +78,24 @@ compile_error! {"This kernel implementation assume endianness is little-endian.
|
|||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct KeyboardState {
|
pub struct KeyboardState {
|
||||||
// ctrl_modifier: bool,
|
// ctrl_modifier: bool,
|
||||||
maj_modifier: bool,
|
pub shift_modifier: bool,
|
||||||
|
pub alt_gr_modifier: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyboardState {
|
impl KeyboardState {
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
// ctrl_modifier: false,
|
// ctrl_modifier: false,
|
||||||
maj_modifier: false,
|
shift_modifier: false,
|
||||||
|
alt_gr_modifier: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut KBD_STATE: KeyboardState = KeyboardState::new();
|
|
||||||
static mut KBD_QUEUE: Virtqueue = unsafe { core::mem::zeroed() };
|
static mut KBD_QUEUE: Virtqueue = unsafe { core::mem::zeroed() };
|
||||||
pub static mut KBD_DRIVER: VirtioPciDriver = unsafe {
|
pub static mut KBD_DRIVER: VirtioPciDriver<KeyboardState> = unsafe {
|
||||||
VirtioPciDriver::new(
|
VirtioPciDriver::new(
|
||||||
|event| {
|
|state, event| {
|
||||||
let mut kbd_buffer = FILE_SYSTEM.open("/dev/input/keyboard".as_ref()).unwrap();
|
let mut kbd_buffer = FILE_SYSTEM.open("/dev/input/keyboard".as_ref()).unwrap();
|
||||||
kbd_buffer
|
kbd_buffer
|
||||||
.write(core::mem::transmute::<
|
.write(core::mem::transmute::<
|
||||||
@@ -102,25 +106,29 @@ pub static mut KBD_DRIVER: VirtioPciDriver = unsafe {
|
|||||||
|
|
||||||
if event.is_key() {
|
if event.is_key() {
|
||||||
let event = event.as_key_event();
|
let event = event.as_key_event();
|
||||||
if event.value == EventCodeValue::Pressed {
|
|
||||||
#[allow(clippy::single_match)]
|
#[allow(clippy::single_match)]
|
||||||
match map_keycode(event.code, KBD_STATE.maj_modifier) {
|
match map_keycode(event.code, state) {
|
||||||
keymap::KeyType::Ascii(c) => {
|
KeyType::Ascii(c) if event.value == EventCodeValue::Pressed => {
|
||||||
let mut buf = [0; 4];
|
let mut buf = [0; 4];
|
||||||
let to_send = c.encode_utf8(&mut buf);
|
let to_send = c.encode_utf8(&mut buf);
|
||||||
for c in to_send.as_bytes() {
|
for c in to_send.as_bytes() {
|
||||||
println!("key: {}", c);
|
|
||||||
TTY0.buffer.borrow_mut().push(*c);
|
TTY0.buffer.borrow_mut().push(*c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
KeyType::Modifier(ModifierType::Shift) => {
|
||||||
|
state.shift_modifier = !state.shift_modifier;
|
||||||
|
}
|
||||||
|
KeyType::Modifier(ModifierType::AltGr) => {
|
||||||
|
state.alt_gr_modifier = !state.alt_gr_modifier;
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
println!("event: {:#?}", event);
|
println!("event: {:#?}", event);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// println!("key pressed, {:#?}", event);
|
// println!("key pressed, {:#?}", event);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
KeyboardState::new(),
|
||||||
&mut KBD_QUEUE,
|
&mut KBD_QUEUE,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
@@ -128,9 +136,9 @@ pub static mut KBD_DRIVER: VirtioPciDriver = unsafe {
|
|||||||
pub static mut MOUSE_POSITION: (u16, u16) = (0, 0);
|
pub static mut MOUSE_POSITION: (u16, u16) = (0, 0);
|
||||||
|
|
||||||
static mut MOUSE_QUEUE: Virtqueue = unsafe { core::mem::zeroed() };
|
static mut MOUSE_QUEUE: Virtqueue = unsafe { core::mem::zeroed() };
|
||||||
pub static mut MOUSE_DRIVER: VirtioPciDriver = unsafe {
|
pub static mut MOUSE_DRIVER: VirtioPciDriver<()> = unsafe {
|
||||||
VirtioPciDriver::new(
|
VirtioPciDriver::new(
|
||||||
|event| {
|
|_, event| {
|
||||||
if event.is_relative() {
|
if event.is_relative() {
|
||||||
let event = event.as_relative_event();
|
let event = event.as_relative_event();
|
||||||
|
|
||||||
@@ -153,6 +161,7 @@ pub static mut MOUSE_DRIVER: VirtioPciDriver = unsafe {
|
|||||||
// println!("mouse moved, {:#?}", event);
|
// println!("mouse moved, {:#?}", event);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
(),
|
||||||
&mut MOUSE_QUEUE,
|
&mut MOUSE_QUEUE,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,8 +8,12 @@ const UART_BASE: *mut u8 = 0x10000000 as *mut _;
|
|||||||
/// console output; it busy-waits until the UART indicates it can accept
|
/// console output; it busy-waits until the UART indicates it can accept
|
||||||
/// a new byte.
|
/// a new byte.
|
||||||
pub fn write_char_uart(c: char) {
|
pub fn write_char_uart(c: char) {
|
||||||
|
let mut buf = [0; 4];
|
||||||
|
c.encode_utf8(&mut buf);
|
||||||
|
(0..c.len_utf8()).for_each(|i| {
|
||||||
while unsafe { (core::ptr::read_volatile(UART_BASE.byte_add(0x5)) >> 5) & 1 == 0 } {}
|
while unsafe { (core::ptr::read_volatile(UART_BASE.byte_add(0x5)) >> 5) & 1 == 0 } {}
|
||||||
unsafe { core::ptr::write_volatile(UART_BASE, c as u8) };
|
unsafe { core::ptr::write_volatile(UART_BASE, buf[i]) };
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a UTF-8 string to the UART.
|
/// Write a UTF-8 string to the UART.
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use crate::{
|
|||||||
virtio::{DeviceStatus, QUEUE_SIZE, VirtioPciCommonCfg, Virtqueue},
|
virtio::{DeviceStatus, QUEUE_SIZE, VirtioPciCommonCfg, Virtqueue},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct VirtioPciDriver<F: Fn(&VirtioInputEvent) = fn(&VirtioInputEvent)> {
|
pub struct VirtioPciDriver<S, F: Fn(&mut S, &VirtioInputEvent) = fn(&mut S, &VirtioInputEvent)> {
|
||||||
common_cfg: *mut VirtioPciCommonCfg,
|
common_cfg: *mut VirtioPciCommonCfg,
|
||||||
notify_cfg: *mut u16,
|
notify_cfg: *mut u16,
|
||||||
isr_cfg: *mut u8,
|
isr_cfg: *mut u8,
|
||||||
@@ -18,6 +18,7 @@ pub struct VirtioPciDriver<F: Fn(&VirtioInputEvent) = fn(&VirtioInputEvent)> {
|
|||||||
notify_off: u32, // Multiplier from PCI notify capability (used to compute notify address)
|
notify_off: u32, // Multiplier from PCI notify capability (used to compute notify address)
|
||||||
|
|
||||||
handle_event: F,
|
handle_event: F,
|
||||||
|
state: S,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(u16)]
|
#[repr(u16)]
|
||||||
@@ -84,8 +85,8 @@ impl VirtioInputEvent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Fn(&VirtioInputEvent)> VirtioPciDriver<F> {
|
impl<S, F: Fn(&mut S, &VirtioInputEvent)> VirtioPciDriver<S, F> {
|
||||||
pub const unsafe fn new(handle_event: F, queue_mem: &'static mut Virtqueue) -> Self {
|
pub const unsafe fn new(handle_event: F, state: S, queue_mem: &'static mut Virtqueue) -> Self {
|
||||||
Self {
|
Self {
|
||||||
common_cfg: core::ptr::null_mut(),
|
common_cfg: core::ptr::null_mut(),
|
||||||
notify_cfg: core::ptr::null_mut(),
|
notify_cfg: core::ptr::null_mut(),
|
||||||
@@ -99,6 +100,7 @@ impl<F: Fn(&VirtioInputEvent)> VirtioPciDriver<F> {
|
|||||||
last_used_idx: 0,
|
last_used_idx: 0,
|
||||||
notify_off: 0,
|
notify_off: 0,
|
||||||
handle_event,
|
handle_event,
|
||||||
|
state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +205,7 @@ impl<F: Fn(&VirtioInputEvent)> VirtioPciDriver<F> {
|
|||||||
let used_elem = &self.queue.used.ring[ring_slot];
|
let used_elem = &self.queue.used.ring[ring_slot];
|
||||||
let event = &self.event_pool[used_elem.id as usize];
|
let event = &self.event_pool[used_elem.id as usize];
|
||||||
|
|
||||||
(self.handle_event)(event);
|
(self.handle_event)(&mut self.state, event);
|
||||||
|
|
||||||
// Recyclage
|
// Recyclage
|
||||||
let avail_head = self.queue.available.idx.load(Ordering::Relaxed) as usize % QUEUE_SIZE;
|
let avail_head = self.queue.available.idx.load(Ordering::Relaxed) as usize % QUEUE_SIZE;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use io::SeekFrom;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
draw::{Color, Draw, FONT_HEIGHT, FONT_WIDTH},
|
draw::{Color, Draw, FONT_HEIGHT, FONT_WIDTH},
|
||||||
|
println,
|
||||||
vga::{self, Vga},
|
vga::{self, Vga},
|
||||||
virtual_fs::{self, FILE_SYSTEM, VirtualFileSystem},
|
virtual_fs::{self, FILE_SYSTEM, VirtualFileSystem},
|
||||||
};
|
};
|
||||||
@@ -40,6 +41,7 @@ impl VirtualConsole {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_char(&mut self, c: char) {
|
pub fn write_char(&mut self, c: char) {
|
||||||
|
println!("char_console: {:?}", c as u64);
|
||||||
let mut last_cursor = self.cursor;
|
let mut last_cursor = self.cursor;
|
||||||
match c {
|
match c {
|
||||||
'\n' => {
|
'\n' => {
|
||||||
@@ -67,7 +69,7 @@ impl VirtualConsole {
|
|||||||
'\t' => {
|
'\t' => {
|
||||||
self.cursor.x = (self.cursor.x / TAB_SIZE + 1) * TAB_SIZE;
|
self.cursor.x = (self.cursor.x / TAB_SIZE + 1) * TAB_SIZE;
|
||||||
}
|
}
|
||||||
_ if c <= 127 as char && c >= 32 as char => {
|
_ if c as u64 <= 42 * 32 && c >= 32 as char => {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.draw_char_bg(
|
self.draw_char_bg(
|
||||||
(self.cursor.x * FONT_WIDTH as u64) as u16,
|
(self.cursor.x * FONT_WIDTH as u64) as u16,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use core::time::Duration;
|
// use core::time::Duration;
|
||||||
|
|
||||||
use os_std::syscall;
|
use os_std::syscall;
|
||||||
os_std::custom_std_setup! {}
|
os_std::custom_std_setup! {}
|
||||||
@@ -11,7 +11,7 @@ fn main() {
|
|||||||
// let mut file = syscall::open("/dev/fb0");
|
// let mut file = syscall::open("/dev/fb0");
|
||||||
// syscall::seek(&mut file, SeekFrom::End(-3));
|
// syscall::seek(&mut file, SeekFrom::End(-3));
|
||||||
// syscall::write(&mut file, &[255; 6400 * 50]);
|
// syscall::write(&mut file, &[255; 6400 * 50]);
|
||||||
syscall::sleep(Duration::from_secs_f64(2.0));
|
// syscall::sleep(Duration::from_secs_f64(2.0));
|
||||||
let mut stdin = syscall::open("/dev/tty0");
|
let mut stdin = syscall::open("/dev/tty0");
|
||||||
let mut file = syscall::open("/dev/tty0");
|
let mut file = syscall::open("/dev/tty0");
|
||||||
loop {
|
loop {
|
||||||
|
|||||||
Reference in New Issue
Block a user