input/event/
keyboard.rs

1//! Keyboard event types
2
3use super::EventTrait;
4use crate::{ffi, AsRaw, Context, FromRaw, Libinput};
5
6/// State of a Key
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub enum KeyState {
9    /// Key is pressed
10    Pressed,
11    /// Key is released
12    Released,
13}
14
15/// Common functions for all Keyboard-Events implement.
16pub trait KeyboardEventTrait: AsRaw<ffi::libinput_event_keyboard> + Context {
17    ffi_func!(
18    /// The event time for this event
19    fn time, ffi::libinput_event_keyboard_get_time, u32);
20    ffi_func!(
21    /// The event time for this event in microseconds
22    fn time_usec, ffi::libinput_event_keyboard_get_time_usec, u64);
23    ffi_func!(
24    /// The keycode that triggered this key event
25    fn key, ffi::libinput_event_keyboard_get_key, u32);
26
27    /// The state change of the key
28    fn key_state(&self) -> KeyState {
29        match unsafe { ffi::libinput_event_keyboard_get_key_state(self.as_raw() as *mut _) } {
30            ffi::libinput_key_state_LIBINPUT_KEY_STATE_PRESSED => KeyState::Pressed,
31            ffi::libinput_key_state_LIBINPUT_KEY_STATE_RELEASED => KeyState::Released,
32            _ => panic!("libinput returned invalid 'libinput_key_state'"),
33        }
34    }
35
36    /// Convert into a general `KeyboardEvent` again
37    fn into_keyboard_event(self) -> KeyboardEvent
38    where
39        Self: Sized,
40    {
41        unsafe { KeyboardEvent::from_raw(self.as_raw_mut(), self.context()) }
42    }
43}
44
45impl<T: AsRaw<ffi::libinput_event_keyboard> + Context> KeyboardEventTrait for T {}
46
47/// A keyboard related `Event`
48#[derive(Debug, PartialEq, Eq, Hash)]
49#[non_exhaustive]
50pub enum KeyboardEvent {
51    /// An event related to pressing a key
52    Key(KeyboardKeyEvent),
53}
54
55impl EventTrait for KeyboardEvent {
56    #[doc(hidden)]
57    fn as_raw_event(&self) -> *mut ffi::libinput_event {
58        match self {
59            KeyboardEvent::Key(event) => event.as_raw_event(),
60        }
61    }
62}
63
64impl FromRaw<ffi::libinput_event_keyboard> for KeyboardEvent {
65    unsafe fn try_from_raw(
66        event: *mut ffi::libinput_event_keyboard,
67        context: &Libinput,
68    ) -> Option<Self> {
69        let base = ffi::libinput_event_keyboard_get_base_event(event);
70        match ffi::libinput_event_get_type(base) {
71            ffi::libinput_event_type_LIBINPUT_EVENT_KEYBOARD_KEY => Some(KeyboardEvent::Key(
72                KeyboardKeyEvent::try_from_raw(event, context)?,
73            )),
74            _ => None,
75        }
76    }
77    unsafe fn from_raw(event: *mut ffi::libinput_event_keyboard, context: &Libinput) -> Self {
78        Self::try_from_raw(event, context).expect("Unknown key event type")
79    }
80}
81
82impl AsRaw<ffi::libinput_event_keyboard> for KeyboardEvent {
83    fn as_raw(&self) -> *const ffi::libinput_event_keyboard {
84        match self {
85            KeyboardEvent::Key(event) => event.as_raw(),
86        }
87    }
88}
89
90impl Context for KeyboardEvent {
91    fn context(&self) -> &Libinput {
92        match self {
93            KeyboardEvent::Key(event) => event.context(),
94        }
95    }
96}
97
98ffi_event_struct!(
99/// An event related to pressing a key
100struct KeyboardKeyEvent, ffi::libinput_event_keyboard, ffi::libinput_event_keyboard_get_base_event);
101
102impl KeyboardKeyEvent {
103    ffi_func!(
104    /// For the key of a `KeyboardKeyEvent` event, return the total number of keys
105    /// pressed on all devices on the associated seat after the event was triggered.
106    pub fn seat_key_count, ffi::libinput_event_keyboard_get_seat_key_count, u32);
107}