1//! Device event types
2
3use super::EventTrait;
4use crate::{ffi, AsRaw, Context, FromRaw, Libinput};
5
6/// Common functions all Device-Events implement.
7pub 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
17impl<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]
22pub 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
29impl 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
39impl 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
60impl 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
69impl 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
78ffi_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
88ffi_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