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