uefi_input2/
key_data.rs

1use uefi::{Char16, Status};
2use uefi::proto::console::text::Key;
3use uefi_raw::protocol::console::InputKey;
4use crate::simple_text_input_ex::*;
5
6/// height-level key data wrapper
7#[derive(Debug, Copy, Clone)]
8pub struct KeyData {
9    pub key: Key,
10    pub key_state: KeyState,
11}
12
13/// reverse conversion to C struct
14impl 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
34/// forward conversion to Rust struct
35impl From<RawKeyData> for KeyData {
36    fn from(raw: RawKeyData) -> Self {
37        Self {
38            key: Key::from(raw.key),
39            // TODO: add new type enum for key state
40            key_state: raw.key_state,
41        }
42    }
43}
44
45impl KeyData {
46    /// Create key data from char
47    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}