Skip to main content

krun_input/
lib.rs

1mod rust_to_c;
2
3use bitflags::bitflags;
4pub use rust_to_c::*;
5use std::cmp::max;
6
7mod c_to_rust;
8pub use c_to_rust::{
9    InputConfigBackend, InputConfigInstance, InputEventProviderBackend, InputEventProviderInstance,
10};
11
12use thiserror::Error;
13
14#[allow(
15    non_upper_case_globals,
16    non_snake_case,
17    non_camel_case_types,
18    dead_code,
19    unused_variables
20)]
21mod header {
22    include!(concat!(env!("OUT_DIR"), "/input_header.rs"));
23}
24
25bitflags! {
26    pub struct ConfigFeatures: u64 {
27        const QUERY = header::KRUN_INPUT_EVENT_PROVIDER_FEATURE_QUEUE as u64;
28    }
29}
30
31bitflags! {
32    pub struct EventProviderFeatures: u64 {
33        const QUEUE  = header::KRUN_INPUT_EVENT_PROVIDER_FEATURE_QUEUE as u64;
34    }
35}
36
37#[derive(Error, Debug)]
38#[repr(i32)]
39pub enum InputBackendError {
40    #[error("Backend implementation error")]
41    InternalError = header::KRUN_INPUT_ERR_INTERNAL,
42    #[error("Try again later")]
43    Again = header::KRUN_INPUT_ERR_EAGAIN,
44    #[error("Method not supported")]
45    MethodNotSupported = header::KRUN_INPUT_ERR_METHOD_UNSUPPORTED,
46    #[error("Invalid parameter")]
47    InvalidParam = header::KRUN_INPUT_ERR_INVALID_PARAM,
48}
49
50/// Input event types matching Linux input event types
51#[derive(Debug, Clone, Copy, PartialEq, Eq)]
52#[repr(u16)]
53pub enum InputEventType {
54    Syn = 0x00, // EV_SYN
55    Key = 0x01, // EV_KEY
56    Rel = 0x02, // EV_REL
57    Abs = 0x03, // EV_ABS
58    Msc = 0x04, // EV_MSC
59    Sw = 0x05,  // EV_SW
60    Led = 0x11, // EV_LED
61    Snd = 0x12, // EV_SND
62    Rep = 0x14, // EV_REP
63}
64
65impl TryFrom<u16> for InputEventType {
66    type Error = ();
67
68    fn try_from(value: u16) -> Result<Self, Self::Error> {
69        match value {
70            0x00 => Ok(Self::Syn),
71            0x01 => Ok(Self::Key),
72            0x02 => Ok(Self::Rel),
73            0x03 => Ok(Self::Abs),
74            0x04 => Ok(Self::Msc),
75            0x05 => Ok(Self::Sw),
76            0x11 => Ok(Self::Led),
77            0x12 => Ok(Self::Snd),
78            0x14 => Ok(Self::Rep),
79            _ => Err(()),
80        }
81    }
82}
83
84impl From<InputEventType> for u16 {
85    fn from(val: InputEventType) -> Self {
86        val as u16
87    }
88}
89
90pub type InputEvent = header::krun_input_event;
91pub type InputDeviceIds = header::krun_input_device_ids;
92pub type InputAbsInfo = header::krun_input_absinfo;
93
94/// Writes the specific bits in bitmap, given the indices of the bits
95/// Return the "length" of the newly constructed bitmap
96pub fn write_bitmap(bitmap: &mut [u8], active_bits: &[u16]) -> u8 {
97    let mut max_byte: u8 = 0;
98    for idx in active_bits {
99        let byte_pos = (idx / 8).try_into().unwrap();
100        let additional_bit = 1 << (idx % 8);
101        if byte_pos as usize > bitmap.len() {
102            panic!("Bit index {idx} out of bounds");
103        }
104        bitmap[byte_pos as usize] |= additional_bit;
105        max_byte = max(max_byte, byte_pos);
106    }
107    max_byte.checked_add(1).unwrap()
108}