| 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 | |