1//! Switch event types
23use super::EventTrait;
4use crate::{ffi, AsRaw, Context, FromRaw, Libinput};
56/// Common functions all Switch-Events implement.
7pub trait SwitchEventTrait: AsRaw<ffi::libinput_event_switch> + Context {
8ffi_func!(
9/// The event time for this event
10fn time, ffi::libinput_event_switch_get_time, u32);
11ffi_func!(
12/// The event time for this event in microseconds
13fn time_usec, ffi::libinput_event_switch_get_time_usec, u64);
1415/// Convert into a general `SwitchEvent` again
16fn into_switch_event(self) -> SwitchEvent
17where
18Self: Sized,
19 {
20unsafe { SwitchEvent::from_raw(self.as_raw_mut(), self.context()) }
21 }
22}
2324impl<T: AsRaw<ffi::libinput_event_switch> + Context> SwitchEventTrait for T {}
2526/// A switch related `Event`
27#[derive(Debug, PartialEq, Eq, Hash)]
28#[non_exhaustive]
29pub enum SwitchEvent {
30/// An event related a switch, that was toggled
31Toggle(SwitchToggleEvent),
32}
3334impl EventTrait for SwitchEvent {
35#[doc(hidden)]
36fn as_raw_event(&self) -> *mut ffi::libinput_event {
37match self {
38 SwitchEvent::Toggle(event) => event.as_raw_event(),
39 }
40 }
41}
4243impl FromRaw<ffi::libinput_event_switch> for SwitchEvent {
44unsafe fn try_from_raw(
45 event: *mut ffi::libinput_event_switch,
46 context: &Libinput,
47 ) -> Option<Self> {
48let base = ffi::libinput_event_switch_get_base_event(event);
49match ffi::libinput_event_get_type(base) {
50 ffi::libinput_event_type_LIBINPUT_EVENT_SWITCH_TOGGLE => Some(SwitchEvent::Toggle(
51 SwitchToggleEvent::try_from_raw(event, context)?,
52 )),
53_ => None,
54 }
55 }
56unsafe fn from_raw(event: *mut ffi::libinput_event_switch, context: &Libinput) -> Self {
57Self::try_from_raw(event, context).expect("Unknown switch event type")
58 }
59}
6061impl AsRaw<ffi::libinput_event_switch> for SwitchEvent {
62fn as_raw(&self) -> *const ffi::libinput_event_switch {
63match self {
64 SwitchEvent::Toggle(event) => event.as_raw(),
65 }
66 }
67}
6869impl Context for SwitchEvent {
70fn context(&self) -> &Libinput {
71match self {
72 SwitchEvent::Toggle(event) => event.context(),
73 }
74 }
75}
7677/// Types of Switches
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
79#[repr(u32)]
80#[non_exhaustive]
81pub enum Switch {
82/// The laptop lid was closed when the `SwitchState` is
83 /// `On`, or was opened when it is `Off`
84Lid = 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.
97TabletMode = ffi::libinput_switch_LIBINPUT_SWITCH_TABLET_MODE,
98}
99100/// State of a Switch
101#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
102pub enum SwitchState {
103/// Switch is off
104Off,
105/// Switch is on
106On,
107}
108109ffi_event_struct!(
110/// An event related a switch, that was toggled
111struct SwitchToggleEvent, ffi::libinput_event_switch, ffi::libinput_event_switch_get_base_event);
112113impl SwitchToggleEvent {
114/// Return the switch that triggered this event.
115 ///
116 /// A return value of `None` means, the switch type is not known
117pub fn switch(&self) -> Option<Switch> {
118match 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")]
123log::warn!("Unknown Switch type returned by libinput: {}", _x);
124None
125}
126 }
127 }
128129/// Return the switch state that triggered this event.
130pub fn switch_state(&self) -> SwitchState {
131match 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}