1use uefi::{Char16, Status};
2use uefi::proto::console::text::Key;
3use uefi_raw::protocol::console::InputKey;
4use crate::simple_text_input_ex::*;
5
6#[derive(Debug, Copy, Clone)]
8pub struct KeyData {
9 pub key: Key,
10 pub key_state: KeyState,
11}
12
13impl From<KeyData> for RawKeyData {
15 fn from(value: KeyData) -> Self {
16 let input_key = match value.key {
17 Key::Printable(c) => InputKey {
18 scan_code: 0,
19 unicode_char: u16::from(c),
20 },
21 Key::Special(code) => InputKey {
22 scan_code: code.0,
23 unicode_char: 0,
24 },
25 };
26
27 Self {
28 key: input_key,
29 key_state: value.key_state,
30 }
31 }
32}
33
34impl From<RawKeyData> for KeyData {
36 fn from(raw: RawKeyData) -> Self {
37 Self {
38 key: Key::from(raw.key),
39 key_state: raw.key_state,
41 }
42 }
43}
44
45impl KeyData {
46 pub fn new(c: char) -> uefi::Result<Self> {
48 let c = Char16::try_from(c).map_err(|_| Status::INVALID_PARAMETER)?;
49
50 Ok(Self {
51 key: Key::Printable(c),
52 key_state: KeyState::default(),
53 })
54 }
55
56 #[inline(always)]
57 pub fn function_enable(&self) -> bool {
58 (self.key_state.key_shift_state & SHIFT_STATE_VALID) != 0
59 }
60
61 #[inline(always)]
62 pub fn r_shift(&self) -> bool {
63 (self.key_state.key_shift_state & RIGHT_SHIFT_PRESSED) != 0
64 }
65
66 #[inline(always)]
67 pub fn l_shift(&self) -> bool {
68 (self.key_state.key_shift_state & LEFT_SHIFT_PRESSED) != 0
69 }
70
71 #[inline(always)]
72 pub fn shift(&self) -> bool {
73 const SHIFT_MASK: u32 = LEFT_SHIFT_PRESSED | RIGHT_SHIFT_PRESSED;
74 (self.key_state.key_shift_state & SHIFT_MASK) != 0
75 }
76
77 #[inline(always)]
78 pub fn r_ctrl(&self) -> bool {
79 (self.key_state.key_shift_state & RIGHT_CONTROL_PRESSED) != 0
80 }
81
82 #[inline(always)]
83 pub fn l_ctrl(&self) -> bool {
84 (self.key_state.key_shift_state & LEFT_CONTROL_PRESSED) != 0
85 }
86
87 #[inline(always)]
88 pub fn ctrl(&self) -> bool {
89 const CTRL_MASK: u32 = LEFT_CONTROL_PRESSED | RIGHT_CONTROL_PRESSED;
90 (self.key_state.key_shift_state & CTRL_MASK) != 0
91 }
92
93 #[inline(always)]
94 pub fn r_alt(&self) -> bool {
95 (self.key_state.key_shift_state & RIGHT_ALT_PRESSED) != 0
96 }
97
98 #[inline(always)]
99 pub fn l_alt(&self) -> bool {
100 (self.key_state.key_shift_state & LEFT_ALT_PRESSED) != 0
101 }
102
103 #[inline(always)]
104 pub fn alt(&self) -> bool {
105 const ALT_MASK: u32 = LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED;
106 (self.key_state.key_shift_state & ALT_MASK) != 0
107 }
108
109 #[inline(always)]
110 pub fn r_logo(&self) -> bool {
111 (self.key_state.key_shift_state & RIGHT_LOGO_PRESSED) != 0
112 }
113
114 #[inline(always)]
115 pub fn l_logo(&self) -> bool {
116 (self.key_state.key_shift_state & LEFT_LOGO_PRESSED) != 0
117 }
118
119 #[inline(always)]
120 pub fn logo(&self) -> bool {
121 const LOGO_MASK: u32 = LEFT_LOGO_PRESSED | RIGHT_LOGO_PRESSED;
122 (self.key_state.key_shift_state & LOGO_MASK) != 0
123 }
124
125 #[inline(always)]
126 pub fn menu(&self) -> bool {
127 (self.key_state.key_shift_state & MENU_KEY_PRESSED) != 0
128 }
129
130 #[inline(always)]
131 pub fn sys_req(&self) -> bool {
132 (self.key_state.key_shift_state & SYS_REQ_PRESSED) != 0
133 }
134
135 #[inline(always)]
136 pub fn toggle_enable(&self) -> bool {
137 (self.key_state.key_toggle_state & TOGGLE_STATE_VALID) != 0
138 }
139
140 #[inline(always)]
141 pub fn is_realtime(&self) -> bool {
142 (self.key_state.key_toggle_state & KEY_STATE_EXPOSED) != 0
143 }
144
145 #[inline(always)]
146 pub fn scroll_lock(&self) -> bool {
147 (self.key_state.key_toggle_state & SCROLL_LOCK_ACTIVE) != 0
148 }
149
150 #[inline(always)]
151 pub fn num_lock(&self) -> bool {
152 (self.key_state.key_toggle_state & NUM_LOCK_ACTIVE) != 0
153 }
154
155 #[inline(always)]
156 pub fn caps_lock(&self) -> bool {
157 (self.key_state.key_toggle_state & CAPS_LOCK_ACTIVE) != 0
158 }
159}