1//! Switch event types
2
3use super::EventTrait;
4use crate::{ffi, AsRaw, Context, FromRaw, Libinput};
5
6/// Common functions all Switch-Events implement.
7pub 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
24impl<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]
29pub enum SwitchEvent {
30 /// An event related a switch, that was toggled
31 Toggle(SwitchToggleEvent),
32}
33
34impl 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
43impl 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
61impl 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
69impl 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]
81pub 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)]
102pub enum SwitchState {
103 /// Switch is off
104 Off,
105 /// Switch is on
106 On,
107}
108
109ffi_event_struct!(
110/// An event related a switch, that was toggled
111struct SwitchToggleEvent, ffi::libinput_event_switch, ffi::libinput_event_switch_get_base_event);
112
113impl 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