1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
use bitflags::bitflags;
use core::convert;
use core::ffi::c_uchar;
#[derive(Copy, Clone, Debug)]
pub struct Key {
pub asc: c_uchar,
pub scan: u8,
pub modi: Modifiers,
}
impl convert::Into<char> for Key {
fn into(self) -> char {
self.asc as char
}
}
impl convert::Into<u8> for Key {
fn into(self) -> u8 {
self.asc
}
}
// Technically the *Lock are special keys, instead of Modifiers
// but we don't need another type FWIW.
// Mask bits[2:0] to get the leds.
bitflags! {
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct Modifiers:u8 {
const NONE = 0;
// lock states
const SCROLL_LOCK = 1 << 0;
const NUMLOCK = 1 << 1;
const CAPSLOCK = 1 << 2;
// modifiers
const SHIFT = 1 << 3;
const ALT_LEFT = 1 << 4;
const ALT_RIGHT = 1 << 5;
const CTRL_LEFT = 1 << 6;
const CTRL_RIGHT = 1 << 7;
}
}
#[allow(dead_code)]
impl Key {
pub fn new() -> Self {
Self {
asc: 0, // logically scan + modi.shift => asc
scan: 0, // scancode, "raw"
modi: Modifiers::NONE,
}
}
pub fn decode(&mut self) {
// decode key
}
pub fn valid(self) -> bool {
self.scan != 0
}
pub fn invalidate(&mut self) {
self.scan = 0;
}
// setter and getter for ascii and scancode
pub fn set_ascii(&mut self, ascii: u8) {
self.asc = ascii;
}
pub fn get_ascii(self) -> u8 {
self.asc
}
pub fn set_scancode(&mut self, scancode: u8) {
self.scan = scancode;
}
pub fn get_scancode(self) -> u8 {
self.scan
}
// TODO the setters and getters should not be their own functions....
#[inline(always)]
pub fn mod_contains(&self, modi: Modifiers) -> bool {
self.modi.contains(modi)
}
#[inline(always)]
pub fn mod_set(&mut self, modi: Modifiers, pressed: bool) {
if pressed {
self.modi.insert(modi);
} else {
self.modi.remove(modi);
}
}
}
// scan codes of a few specific keys
pub enum Scan {
F1 = 0x3b,
Del = 0x53,
Up = 72,
Down = 80,
Left = 75,
Right = 77,
Div = 8,
}
// Decoding tables ... this shit is so ugly, thanks to rust's strong typing system!!!
// Also, this is a german layout keyboard
// oh btw, the code translation is done by ChatGPT if it's wrong complain to the AI!
pub const NORMAL_TAB: [c_uchar; 100] = [
0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 225, 39, 8, 0, 113, 119, 101, 114, 116, 122, 117,
105, 111, 112, 129, 43, 10, 0, 97, 115, 100, 102, 103, 104, 106, 107, 108, 148, 132, 94, 0, 35,
121, 120, 99, 118, 98, 110, 109, 44, 46, 45, 0, 42, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 45, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
pub const SHIFT_TAB: [c_uchar; 100] = [
0, 0, 33, 34, 21, 36, 37, 38, 47, 40, 41, 61, 63, 96, 0, 0, 81, 87, 69, 82, 84, 90, 85, 73, 79,
80, 154, 42, 0, 0, 65, 83, 68, 70, 71, 72, 74, 75, 76, 153, 142, 248, 0, 39, 89, 88, 67, 86,
66, 78, 77, 59, 58, 95, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
pub const ALT_TAB: [c_uchar; 100] = [
0, 0, 0, 253, 0, 0, 0, 0, 123, 91, 93, 125, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
pub const ASC_NUM_TAB: [c_uchar; 13] = [55, 56, 57, 45, 52, 53, 54, 43, 49, 50, 51, 48, 44];
pub const SCAN_NUM_TAB: [c_uchar; 13] = [8, 9, 10, 53, 5, 6, 7, 27, 2, 3, 4, 11, 51];
|