1 //! Pointer device access.
2 
3 use crate::proto::unsafe_protocol;
4 use crate::{Event, Result, Status, StatusExt};
5 use uefi_raw::protocol::console::SimplePointerProtocol;
6 
7 /// Provides information about a pointer device.
8 #[derive(Debug)]
9 #[repr(transparent)]
10 #[unsafe_protocol(SimplePointerProtocol::GUID)]
11 pub struct Pointer(SimplePointerProtocol);
12 
13 impl Pointer {
14     /// Resets the pointer device hardware.
15     ///
16     /// The `extended_verification` parameter is used to request that UEFI
17     /// performs an extended check and reset of the input device.
18     ///
19     /// # Errors
20     ///
21     /// - `DeviceError` if the device is malfunctioning and cannot be reset.
reset(&mut self, extended_verification: bool) -> Result22     pub fn reset(&mut self, extended_verification: bool) -> Result {
23         unsafe { (self.0.reset)(&mut self.0, extended_verification) }.to_result()
24     }
25 
26     /// Retrieves the pointer device's current state, if a state change occurred
27     /// since the last time this function was called.
28     ///
29     /// Use `wait_for_input_event()` with the [`boot::wait_for_event`]
30     /// interface in order to wait for input from the pointer device.
31     ///
32     /// # Errors
33     /// - `DeviceError` if there was an issue with the pointer device.
34     ///
35     /// [`boot::wait_for_event`]: crate::boot::wait_for_event
read_state(&mut self) -> Result<Option<PointerState>>36     pub fn read_state(&mut self) -> Result<Option<PointerState>> {
37         let mut pointer_state = PointerState::default();
38         let pointer_state_ptr: *mut _ = &mut pointer_state;
39 
40         match unsafe { (self.0.get_state)(&mut self.0, pointer_state_ptr.cast()) } {
41             Status::NOT_READY => Ok(None),
42             other => other.to_result_with_val(|| Some(pointer_state)),
43         }
44     }
45 
46     /// Event to be used with [`boot::wait_for_event`] in order to wait
47     /// for input from the pointer device
48     ///
49     /// [`boot::wait_for_event`]: crate::boot::wait_for_event
50     #[must_use]
wait_for_input_event(&self) -> Option<Event>51     pub fn wait_for_input_event(&self) -> Option<Event> {
52         unsafe { Event::from_ptr(self.0.wait_for_input) }
53     }
54 
55     /// Returns a reference to the pointer device information.
56     #[must_use]
mode(&self) -> &PointerMode57     pub const fn mode(&self) -> &PointerMode {
58         unsafe { &*self.0.mode.cast() }
59     }
60 }
61 
62 /// Information about this pointer device.
63 #[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
64 #[repr(C)]
65 pub struct PointerMode {
66     /// The pointer device's resolution on the X/Y/Z axis in counts/mm.
67     /// If a value is 0, then the device does _not_ support that axis.
68     pub resolution: [u64; 3],
69     /// Whether the devices has a left button / right button.
70     pub has_button: [bool; 2],
71 }
72 
73 /// The relative change in the pointer's state.
74 #[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
75 #[repr(C)]
76 pub struct PointerState {
77     /// The relative movement on the X/Y/Z axis.
78     ///
79     /// If `PointerMode` indicates an axis is not supported, it must be ignored.
80     pub relative_movement: [i32; 3],
81     /// Whether the left / right mouse button is currently pressed.
82     ///
83     /// If `PointerMode` indicates a button is not supported, it must be ignored.
84     pub button: [bool; 2],
85 }
86