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: &KeyboardKeyEvent) => 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: *mut libinput_event = ffi::libinput_event_keyboard_get_base_event(event);
70 match ffi::libinput_event_get_type(event:base) {
71 ffi::libinput_event_type_LIBINPUT_EVENT_KEYBOARD_KEY => Some(KeyboardEvent::Key(
72 KeyboardKeyEvent::try_from_raw(ffi: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(msg:"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: &KeyboardKeyEvent) => event.as_raw(),
86 }
87 }
88}
89
90impl Context for KeyboardEvent {
91 fn context(&self) -> &Libinput {
92 match self {
93 KeyboardEvent::Key(event: &KeyboardKeyEvent) => 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}
108