1 | //! Switch event types |
2 | |
3 | use super::EventTrait; |
4 | use crate::{ffi, AsRaw, Context, FromRaw, Libinput}; |
5 | |
6 | /// Common functions all Switch-Events implement. |
7 | pub trait SwitchEventTrait: AsRaw<ffi::libinput_event_switch> + Context { |
8 | ffi_func!( |
9 | /// The event time for this event |
10 | fn time, ffi::libinput_event_switch_get_time, u32); |
11 | ffi_func!( |
12 | /// The event time for this event in microseconds |
13 | fn time_usec, ffi::libinput_event_switch_get_time_usec, u64); |
14 | |
15 | /// Convert into a general `SwitchEvent` again |
16 | fn into_switch_event(self) -> SwitchEvent |
17 | where |
18 | Self: Sized, |
19 | { |
20 | unsafe { SwitchEvent::from_raw(self.as_raw_mut(), self.context()) } |
21 | } |
22 | } |
23 | |
24 | impl<T: AsRaw<ffi::libinput_event_switch> + Context> SwitchEventTrait for T {} |
25 | |
26 | /// A switch related `Event` |
27 | #[derive (Debug, PartialEq, Eq, Hash)] |
28 | #[non_exhaustive ] |
29 | pub enum SwitchEvent { |
30 | /// An event related a switch, that was toggled |
31 | Toggle(SwitchToggleEvent), |
32 | } |
33 | |
34 | impl EventTrait for SwitchEvent { |
35 | #[doc (hidden)] |
36 | fn as_raw_event(&self) -> *mut ffi::libinput_event { |
37 | match self { |
38 | SwitchEvent::Toggle(event: &SwitchToggleEvent) => event.as_raw_event(), |
39 | } |
40 | } |
41 | } |
42 | |
43 | impl FromRaw<ffi::libinput_event_switch> for SwitchEvent { |
44 | unsafe fn try_from_raw( |
45 | event: *mut ffi::libinput_event_switch, |
46 | context: &Libinput, |
47 | ) -> Option<Self> { |
48 | let base: *mut libinput_event = ffi::libinput_event_switch_get_base_event(event); |
49 | match ffi::libinput_event_get_type(event:base) { |
50 | ffi::libinput_event_type_LIBINPUT_EVENT_SWITCH_TOGGLE => Some(SwitchEvent::Toggle( |
51 | SwitchToggleEvent::try_from_raw(ffi:event, context)?, |
52 | )), |
53 | _ => None, |
54 | } |
55 | } |
56 | unsafe fn from_raw(event: *mut ffi::libinput_event_switch, context: &Libinput) -> Self { |
57 | Self::try_from_raw(event, context).expect(msg:"Unknown switch event type" ) |
58 | } |
59 | } |
60 | |
61 | impl AsRaw<ffi::libinput_event_switch> for SwitchEvent { |
62 | fn as_raw(&self) -> *const ffi::libinput_event_switch { |
63 | match self { |
64 | SwitchEvent::Toggle(event: &SwitchToggleEvent) => event.as_raw(), |
65 | } |
66 | } |
67 | } |
68 | |
69 | impl Context for SwitchEvent { |
70 | fn context(&self) -> &Libinput { |
71 | match self { |
72 | SwitchEvent::Toggle(event: &SwitchToggleEvent) => event.context(), |
73 | } |
74 | } |
75 | } |
76 | |
77 | /// Types of Switches |
78 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
79 | #[repr (u32)] |
80 | #[non_exhaustive ] |
81 | pub enum Switch { |
82 | /// The laptop lid was closed when the `SwitchState` is |
83 | /// `On`, or was opened when it is `Off` |
84 | Lid = ffi::libinput_switch_LIBINPUT_SWITCH_LID, |
85 | /// This switch indicates whether the device is in normal laptop mode |
86 | /// or behaves like a tablet-like device where the primary |
87 | /// interaction is usually a touch screen. When in tablet mode, the |
88 | /// keyboard and touchpad are usually inaccessible. |
89 | /// |
90 | /// If the switch is in state `SwitchState::Off`, the |
91 | /// device is in laptop mode. If the switch is in state |
92 | /// `SwitchState::On`, the device is in tablet mode and the |
93 | /// keyboard or touchpad may not be accessible. |
94 | /// |
95 | /// It is up to the caller to identify which devices are inaccessible |
96 | /// `in tablet mode. |
97 | TabletMode = ffi::libinput_switch_LIBINPUT_SWITCH_TABLET_MODE, |
98 | } |
99 | |
100 | /// State of a Switch |
101 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
102 | pub enum SwitchState { |
103 | /// Switch is off |
104 | Off, |
105 | /// Switch is on |
106 | On, |
107 | } |
108 | |
109 | ffi_event_struct!( |
110 | /// An event related a switch, that was toggled |
111 | struct SwitchToggleEvent, ffi::libinput_event_switch, ffi::libinput_event_switch_get_base_event); |
112 | |
113 | impl SwitchToggleEvent { |
114 | /// Return the switch that triggered this event. |
115 | /// |
116 | /// A return value of `None` means, the switch type is not known |
117 | pub fn switch(&self) -> Option<Switch> { |
118 | match unsafe { ffi::libinput_event_switch_get_switch(self.as_raw_mut()) } { |
119 | ffi::libinput_switch_LIBINPUT_SWITCH_LID => Some(Switch::Lid), |
120 | ffi::libinput_switch_LIBINPUT_SWITCH_TABLET_MODE => Some(Switch::TabletMode), |
121 | _x => { |
122 | #[cfg (feature = "log" )] |
123 | log::warn!("Unknown Switch type returned by libinput: {}" , _x); |
124 | None |
125 | } |
126 | } |
127 | } |
128 | |
129 | /// Return the switch state that triggered this event. |
130 | pub fn switch_state(&self) -> SwitchState { |
131 | match unsafe { ffi::libinput_event_switch_get_switch_state(self.as_raw_mut()) } { |
132 | ffi::libinput_switch_state_LIBINPUT_SWITCH_STATE_OFF => SwitchState::Off, |
133 | ffi::libinput_switch_state_LIBINPUT_SWITCH_STATE_ON => SwitchState::On, |
134 | _ => panic!("libinput returned invalid 'libinput_switch_state'" ), |
135 | } |
136 | } |
137 | } |
138 | |