sweetacid_evdev/
device_state.rs

1use crate::{constants::*, raw_stream::RawDevice};
2use crate::{AttributeSet, AttributeSetRef, InputEvent, InputEventKind, Key};
3use std::time::SystemTime;
4
5/// A **cached** representation of device state at a certain time.
6#[derive(Debug)]
7pub struct DeviceState {
8    /// The state corresponds to kernel state at this timestamp.
9    pub(crate) timestamp: SystemTime,
10    /// Set = key pressed
11    pub(crate) key_vals: Option<AttributeSet<Key>>,
12    pub(crate) abs_vals: Option<Box<[libc::input_absinfo; AbsoluteAxisType::COUNT]>>,
13    /// Set = switch enabled (closed)
14    pub(crate) switch_vals: Option<AttributeSet<SwitchType>>,
15    /// Set = LED lit
16    pub(crate) led_vals: Option<AttributeSet<LedType>>,
17}
18
19// manual Clone impl for clone_from optimization
20impl Clone for DeviceState {
21    fn clone(&self) -> Self {
22        Self {
23            timestamp: self.timestamp,
24            key_vals: self.key_vals.clone(),
25            abs_vals: self.abs_vals.clone(),
26            switch_vals: self.switch_vals.clone(),
27            led_vals: self.led_vals.clone(),
28        }
29    }
30    fn clone_from(&mut self, other: &Self) {
31        self.timestamp.clone_from(&other.timestamp);
32        self.key_vals.clone_from(&other.key_vals);
33        self.abs_vals.clone_from(&other.abs_vals);
34        self.switch_vals.clone_from(&other.switch_vals);
35        self.led_vals.clone_from(&other.led_vals);
36    }
37}
38
39impl DeviceState {
40    /// Create an empty `DeviceState`. The `{abs,key,etc}_vals` for the returned state will return
41    /// `Some` if `supported_events()` contains that `EventType`.
42    pub(crate) fn new(device: &RawDevice) -> Self {
43        let supports = device.supported_events();
44
45        let key_vals = if supports.contains(EventType::KEY) {
46            Some(AttributeSet::new())
47        } else {
48            None
49        };
50        let abs_vals = if supports.contains(EventType::ABSOLUTE) {
51            Some(Box::new(crate::raw_stream::ABS_VALS_INIT))
52        } else {
53            None
54        };
55        let switch_vals = if supports.contains(EventType::SWITCH) {
56            Some(AttributeSet::new())
57        } else {
58            None
59        };
60        let led_vals = if supports.contains(EventType::LED) {
61            Some(AttributeSet::new())
62        } else {
63            None
64        };
65
66        DeviceState {
67            timestamp: std::time::UNIX_EPOCH,
68            key_vals,
69            abs_vals,
70            switch_vals,
71            led_vals,
72        }
73    }
74    /// Returns the time when this snapshot was taken.
75    pub fn timestamp(&self) -> SystemTime {
76        self.timestamp
77    }
78
79    /// Returns the set of keys pressed when the snapshot was taken.
80    ///
81    /// Returns `None` if keys are not supported by this device.
82    pub fn key_vals(&self) -> Option<&AttributeSetRef<Key>> {
83        self.key_vals.as_deref()
84    }
85
86    /// Returns the set of absolute axis measurements when the snapshot was taken.
87    ///
88    /// Returns `None` if not supported by this device.
89    pub fn abs_vals(&self) -> Option<&[libc::input_absinfo]> {
90        self.abs_vals.as_deref().map(|v| &v[..])
91    }
92
93    /// Returns the set of switches triggered when the snapshot was taken.
94    ///
95    /// Returns `None` if switches are not supported by this device.
96    pub fn switch_vals(&self) -> Option<&AttributeSetRef<SwitchType>> {
97        self.switch_vals.as_deref()
98    }
99
100    /// Returns the set of LEDs turned on when the snapshot was taken.
101    ///
102    /// Returns `None` if LEDs are not supported by this device.
103    pub fn led_vals(&self) -> Option<&AttributeSetRef<LedType>> {
104        self.led_vals.as_deref()
105    }
106
107    #[inline]
108    pub(crate) fn process_event(&mut self, ev: InputEvent) {
109        match ev.kind() {
110            InputEventKind::Key(code) => {
111                let keys = self
112                    .key_vals
113                    .as_deref_mut()
114                    .expect("got a key event despite not supporting keys");
115                keys.set(code, ev.value() != 0);
116            }
117            InputEventKind::AbsAxis(axis) => {
118                let axes = self
119                    .abs_vals
120                    .as_deref_mut()
121                    .expect("got an abs event despite not supporting absolute axes");
122                axes[axis.0 as usize].value = ev.value();
123            }
124            _ => {}
125        }
126    }
127}