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