| 1 | //! Device event types |
| 2 | |
| 3 | use super::EventTrait; |
| 4 | use crate::{ffi, AsRaw, Context, FromRaw, Libinput}; |
| 5 | |
| 6 | /// Common functions all Device-Events implement. |
| 7 | pub trait DeviceEventTrait: AsRaw<ffi::libinput_event_device_notify> + Context { |
| 8 | /// Convert into a general `DeviceEvent` again |
| 9 | fn into_device_event(self) -> DeviceEvent |
| 10 | where |
| 11 | Self: Sized, |
| 12 | { |
| 13 | unsafe { DeviceEvent::from_raw(self.as_raw_mut(), self.context()) } |
| 14 | } |
| 15 | } |
| 16 | |
| 17 | impl<T: AsRaw<ffi::libinput_event_device_notify> + Context> DeviceEventTrait for T {} |
| 18 | |
| 19 | /// A device related `Event` |
| 20 | #[derive (Debug, PartialEq, Eq, Hash)] |
| 21 | #[non_exhaustive ] |
| 22 | pub enum DeviceEvent { |
| 23 | /// Signals that a device has been added to the context. |
| 24 | Added(DeviceAddedEvent), |
| 25 | /// Signals that a device has been removed. |
| 26 | Removed(DeviceRemovedEvent), |
| 27 | } |
| 28 | |
| 29 | impl EventTrait for DeviceEvent { |
| 30 | #[doc (hidden)] |
| 31 | fn as_raw_event(&self) -> *mut ffi::libinput_event { |
| 32 | match self { |
| 33 | DeviceEvent::Added(event: &DeviceAddedEvent) => event.as_raw_event(), |
| 34 | DeviceEvent::Removed(event: &DeviceRemovedEvent) => event.as_raw_event(), |
| 35 | } |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | impl FromRaw<ffi::libinput_event_device_notify> for DeviceEvent { |
| 40 | unsafe fn try_from_raw( |
| 41 | event: *mut ffi::libinput_event_device_notify, |
| 42 | context: &Libinput, |
| 43 | ) -> Option<Self> { |
| 44 | let base: *mut libinput_event = ffi::libinput_event_device_notify_get_base_event(event); |
| 45 | match ffi::libinput_event_get_type(event:base) { |
| 46 | ffi::libinput_event_type_LIBINPUT_EVENT_DEVICE_ADDED => Some(DeviceEvent::Added( |
| 47 | DeviceAddedEvent::try_from_raw(ffi:event, context)?, |
| 48 | )), |
| 49 | ffi::libinput_event_type_LIBINPUT_EVENT_DEVICE_REMOVED => Some(DeviceEvent::Removed( |
| 50 | DeviceRemovedEvent::try_from_raw(ffi:event, context)?, |
| 51 | )), |
| 52 | _ => None, |
| 53 | } |
| 54 | } |
| 55 | unsafe fn from_raw(event: *mut ffi::libinput_event_device_notify, context: &Libinput) -> Self { |
| 56 | Self::try_from_raw(event, context).expect(msg:"Unknown libinput_event_device type" ) |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | impl AsRaw<ffi::libinput_event_device_notify> for DeviceEvent { |
| 61 | fn as_raw(&self) -> *const ffi::libinput_event_device_notify { |
| 62 | match self { |
| 63 | DeviceEvent::Added(event: &DeviceAddedEvent) => event.as_raw(), |
| 64 | DeviceEvent::Removed(event: &DeviceRemovedEvent) => event.as_raw(), |
| 65 | } |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | impl Context for DeviceEvent { |
| 70 | fn context(&self) -> &Libinput { |
| 71 | match self { |
| 72 | DeviceEvent::Added(event: &DeviceAddedEvent) => event.context(), |
| 73 | DeviceEvent::Removed(event: &DeviceRemovedEvent) => event.context(), |
| 74 | } |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | ffi_event_struct! { |
| 79 | /// Signals that a device has been added to the context. |
| 80 | /// |
| 81 | /// The device will not be read until the next time the user calls |
| 82 | /// `Libinput::dispatch` and data is available. |
| 83 | /// |
| 84 | /// This allows setting up initial device configuration before any events are created. |
| 85 | struct DeviceAddedEvent, ffi::libinput_event_device_notify, ffi::libinput_event_device_notify_get_base_event |
| 86 | } |
| 87 | |
| 88 | ffi_event_struct! { |
| 89 | /// Signals that a device has been removed. |
| 90 | /// |
| 91 | /// No more events from the associated device will be in the queue or be queued after this event. |
| 92 | struct DeviceRemovedEvent, ffi::libinput_event_device_notify, ffi::libinput_event_device_notify_get_base_event |
| 93 | } |
| 94 | |