rustubs/machine/
key.rs

1use bitflags::bitflags;
2use core::ffi::c_uchar;
3use core::mem::transmute;
4
5#[derive(Copy, Clone, Debug)]
6#[repr(C, align(4))]
7/// packed into 32bit C struct so that we can use AtomicU32 for L2/L3
8/// synchronization. We mask the highest byte to indicate "None"
9pub struct Key {
10	pub asc: c_uchar,
11	pub scan: u8,
12	pub modi: Modifiers,
13}
14
15impl Key {
16	pub const NONE_KEY: u32 = 0xff00_0000;
17
18	pub fn to_u32(&self) -> u32 { unsafe { transmute::<Key, u32>(*self) } }
19
20	pub fn from_u32(k: u32) -> Option<Self> {
21		if Self::is_none(k) {
22			None
23		} else {
24			Some(unsafe { transmute::<u32, Self>(k) })
25		}
26	}
27
28	pub fn is_none(k: u32) -> bool { k & Self::NONE_KEY != 0 }
29}
30
31bitflags! {
32	/// Technically the *Lock are special keys, instead of Modifiers
33	/// but we don't need another type FWIW.
34	/// Mask `bits[2:0]` to get the leds.
35	#[derive(Copy, Clone, Eq, PartialEq, Debug)]
36	pub struct Modifiers:u8 {
37		const NONE			= 0;
38		// lock states
39		const SCROLL_LOCK	= 1 << 0;
40		const NUMLOCK		= 1 << 1;
41		const CAPSLOCK		= 1 << 2;
42		// modifiers
43		const SHIFT			= 1 << 3;
44		const ALT_LEFT		= 1 << 4;
45		const ALT_RIGHT		= 1 << 5;
46		const CTRL_LEFT		= 1 << 6;
47		const CTRL_RIGHT	= 1 << 7;
48	}
49}
50
51impl Key {
52	pub fn new() -> Self {
53		Self {
54			asc: 0,  // logically scan + modi.shift => asc
55			scan: 0, // scancode, "raw"
56			modi: Modifiers::NONE,
57		}
58	}
59}
60
61/// scan codes of a few specific keys
62pub enum Scan {
63	F1    = 0x3b,
64	Del   = 0x53,
65	Up    = 72,
66	Down  = 80,
67	Left  = 75,
68	Right = 77,
69	Div   = 8,
70}
71
72// oh btw, the code translation is done by ChatGPT if it's wrong complain to the AI!
73#[rustfmt::skip]
74pub const NORMAL_TAB: [c_uchar; 100] = [
75	0  , 0  , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 ,
76	57 , 48 , 45 , 61 , 8  , 0  , 113, 119, 101, 114,
77	116, 121, 117, 105, 111, 112, 91 , 93 , 10 , 0  ,
78	97 , 115, 100, 102, 103, 104, 106, 107, 108, 59 ,
79	39 , 96 , 0  , 134, 122, 120, 99 , 118, 98,  110,
80	109, 44 , 46 , 47 , 0  , 42 , 0  , 32 , 0  , 0  ,
81	0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  ,
82	0  , 0  , 0  , 0  , 45 , 0  , 0  , 0  , 43 , 0  ,
83	0  , 0  , 0  , 0  , 0  , 0  , 60 , 0  , 0  , 0  ,
84	0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  ,
85];
86
87#[rustfmt::skip]
88pub const SHIFT_TAB: [c_uchar; 100] = [
89	0  , 0  , 33 , 64 , 35 , 36 , 37 , 94 , 47 , 42 ,
90	40 , 41 , 95 , 43 , 0  , 0  , 81 , 87 , 69 , 82 ,
91	84 , 89 , 85 , 73 , 79 , 80 , 123, 125 , 0  , 0  ,
92	65 , 83 , 68 , 70 , 71 , 72 , 74 , 75 , 76 , 58,
93	34 , 126, 0  , 124, 90 , 88 , 67 , 86 , 66 , 78 ,
94	77 , 60 , 62 , 63 , 0  , 0  , 0  , 32 , 0  , 0  ,
95	0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  ,
96	0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  ,
97	0  , 0  , 0  , 0  , 0  , 0  , 62 , 0  , 0  , 0  ,
98	0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  ,
99];
100
101#[rustfmt::skip]
102pub const ALT_TAB: [c_uchar; 100] = [
103	0  , 0  , 0  , 253, 0  , 0  , 0  , 0  , 123, 91 ,
104	93 , 125, 92 , 0  , 0  , 0  , 64 , 0  , 0  , 0  ,
105	0  , 0  , 0  , 0  , 0  , 0  , 0  , 126, 0  , 0  ,
106	0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  ,
107	0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  ,
108	230, 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  ,
109	0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  ,
110	0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  ,
111	0  , 0  , 0  , 0  , 0  , 0  , 124, 0  , 0  , 0  ,
112	0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  , 0  ,
113];
114#[rustfmt::skip]
115pub const ASC_NUM_TAB: [c_uchar; 13] = [55, 56, 57, 45, 52, 53, 54, 43, 49, 50, 51, 48, 44];
116#[rustfmt::skip]
117pub const SCAN_NUM_TAB: [c_uchar; 13] = [8, 9, 10, 53, 5, 6, 7, 27, 2, 3, 4, 11, 51];