1use core::ffi::c_void;
2use core::ptr::addr_of_mut;
3use uefi::{Event, Result, StatusExt};
4use uefi::proto::unsafe_protocol;
5use crate::key_data::KeyData;
6use crate::simple_text_input_ex::{KeyNotifyFunction, KeyToggleState,
7 RawKeyData, SimpleTextInputExProtocol, Boolean};
8
9#[derive(Debug)]
11#[repr(transparent)]
12#[unsafe_protocol(SimpleTextInputExProtocol::GUID)]
13pub struct Input(SimpleTextInputExProtocol);
14
15impl Input {
16 #[inline]
18 pub fn reset(&mut self, extended_verification: bool) -> Result {
19 let this = addr_of_mut!(self.0);
20 unsafe {
21 (self.0.reset)(this, Boolean::from(extended_verification)).to_result()
22 }
23 }
24
25 #[inline]
27 pub fn read_key_stroke_ex(&mut self) -> Option<KeyData> {
28 let mut raw = RawKeyData::default();
29 let this = addr_of_mut!(self.0);
30
31 let status = unsafe {
32 (self.0.read_key_stroke_ex)(this, &mut raw)
34 };
35
36 status.is_success().then_some(KeyData::from(raw))
38 }
39
40 #[inline]
45 pub fn wait_for_key_event(&self) -> Option<Event> {
46 unsafe { Event::from_ptr(self.0.wait_for_key_ex) }
47 }
48
49 #[inline]
51 pub fn set_state(&mut self, mut state: KeyToggleState) -> Result {
52 let this = addr_of_mut!(self.0);
53 unsafe {
54 (self.0.set_state)(this, &mut state).to_result()
55 }
56 }
57
58 pub fn on_key_callback(
80 &mut self,
81 key_data: &KeyData,
82 notification_function: KeyNotifyFunction,
83 ) -> Result<KeyNotifyHandle<'_>> {
84 let this = addr_of_mut!(self.0);
85
86 let mut handle = core::ptr::null_mut();
87 let mut raw_data = RawKeyData::from(*key_data);
88
89 unsafe {
90 ((*this).register_key_notify)(
91 this,
92 &mut raw_data,
93 notification_function,
94 &mut handle,
95 )
96 .to_result_with_val(|| KeyNotifyHandle {
97 proto: &mut *this,
100 handle,
101 })
102 }
103 }
104
105 pub unsafe fn register_key_notify(
108 &mut self,
109 key_data: &KeyData,
110 notification_function: KeyNotifyFunction,
111 ) -> Result<ManualKeyNotifyHandle> {
112 let this = addr_of_mut!(self.0);
113 let mut handle = core::ptr::null_mut();
114 let mut raw_data = RawKeyData::from(*key_data);
115
116 unsafe {
117 ((*this).register_key_notify)(
118 this,
119 &mut raw_data,
120 notification_function,
121 &mut handle,
122 ).to_result_with_val(|| handle)
123 }
124 }
125
126 pub unsafe fn unregister_key_notify(
128 &mut self,
129 handle: ManualKeyNotifyHandle,
130 ) -> Result {
131 let this = addr_of_mut!(self.0);
132 unsafe {
133 ((*this).unregister_key_notify)(this, handle).to_result()
134 }
135 }
136}
137
138pub struct KeyNotifyHandle<'a> {
140 proto: &'a mut SimpleTextInputExProtocol,
142 handle: *mut c_void,
144}
145
146impl Drop for KeyNotifyHandle<'_> {
147 fn drop(&mut self) {
150 let this = addr_of_mut!(*self.proto);
151 unsafe {
152 let _ = ((*this).unregister_key_notify)(this, self.handle);
153 }
154 }
155}
156
157pub type ManualKeyNotifyHandle = *mut c_void;