#![cfg(unix)]
#[macro_use]
mod attribute_set;
mod compat;
mod constants;
mod device_state;
mod error;
mod ff;
mod inputid;
pub mod raw_stream;
mod scancodes;
mod sync_stream;
mod sys;
pub mod uinput;
#[cfg(feature = "serde")]
use serde_1::{Deserialize, Serialize};
use crate::compat::{input_absinfo, input_event, uinput_abs_setup};
use std::fmt;
use std::path::PathBuf;
use std::time::{Duration, SystemTime};
pub use attribute_set::{AttributeSet, AttributeSetRef, EvdevEnum};
pub use constants::*;
pub use device_state::DeviceState;
pub use error::Error;
pub use ff::*;
pub use inputid::*;
pub use raw_stream::{AutoRepeat, FFEffect};
pub use scancodes::*;
pub use sync_stream::*;
const EVENT_BATCH_SIZE: usize = 32;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(crate = "serde_1"))]
pub enum InputEventKind {
Synchronization(Synchronization),
Key(Key),
RelAxis(RelativeAxisType),
AbsAxis(AbsoluteAxisType),
Misc(MiscType),
Switch(SwitchType),
Led(LedType),
Sound(SoundType),
ForceFeedback(u16),
ForceFeedbackStatus(u16),
UInput(u16),
Other,
}
#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct AbsInfo(input_absinfo);
impl AbsInfo {
#[inline]
pub fn value(&self) -> i32 {
self.0.value
}
#[inline]
pub fn minimum(&self) -> i32 {
self.0.minimum
}
#[inline]
pub fn maximum(&self) -> i32 {
self.0.maximum
}
#[inline]
pub fn fuzz(&self) -> i32 {
self.0.fuzz
}
#[inline]
pub fn flat(&self) -> i32 {
self.0.flat
}
#[inline]
pub fn resolution(&self) -> i32 {
self.0.resolution
}
pub fn new(
value: i32,
minimum: i32,
maximum: i32,
fuzz: i32,
flat: i32,
resolution: i32,
) -> Self {
AbsInfo(input_absinfo {
value,
minimum,
maximum,
fuzz,
flat,
resolution,
})
}
}
#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct UinputAbsSetup(uinput_abs_setup);
impl UinputAbsSetup {
#[inline]
pub fn code(&self) -> u16 {
self.0.code
}
#[inline]
pub fn absinfo(&self) -> AbsInfo {
AbsInfo(self.0.absinfo)
}
pub fn new(code: AbsoluteAxisType, absinfo: AbsInfo) -> Self {
UinputAbsSetup(uinput_abs_setup {
code: code.0,
absinfo: absinfo.0,
})
}
}
#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct InputEvent(input_event);
impl InputEvent {
#[inline]
pub fn timestamp(&self) -> SystemTime {
timeval_to_systime(&self.0.time)
}
#[inline]
pub fn event_type(&self) -> EventType {
EventType(self.0.type_)
}
#[inline]
pub fn code(&self) -> u16 {
self.0.code
}
#[inline]
pub fn kind(&self) -> InputEventKind {
let code = self.code();
match self.event_type() {
EventType::SYNCHRONIZATION => InputEventKind::Synchronization(Synchronization(code)),
EventType::KEY => InputEventKind::Key(Key::new(code)),
EventType::RELATIVE => InputEventKind::RelAxis(RelativeAxisType(code)),
EventType::ABSOLUTE => InputEventKind::AbsAxis(AbsoluteAxisType(code)),
EventType::MISC => InputEventKind::Misc(MiscType(code)),
EventType::SWITCH => InputEventKind::Switch(SwitchType(code)),
EventType::LED => InputEventKind::Led(LedType(code)),
EventType::SOUND => InputEventKind::Sound(SoundType(code)),
EventType::FORCEFEEDBACK => InputEventKind::ForceFeedback(code),
EventType::FORCEFEEDBACKSTATUS => InputEventKind::ForceFeedbackStatus(code),
EventType::UINPUT => InputEventKind::UInput(code),
_ => InputEventKind::Other,
}
}
#[inline]
pub fn value(&self) -> i32 {
self.0.value
}
pub fn new(type_: EventType, code: u16, value: i32) -> Self {
InputEvent(input_event {
time: libc::timeval {
tv_sec: 0,
tv_usec: 0,
},
type_: type_.0,
code,
value,
})
}
pub fn new_now(type_: EventType, code: u16, value: i32) -> Self {
InputEvent(input_event {
time: systime_to_timeval(&SystemTime::now()),
type_: type_.0,
code,
value,
})
}
}
impl From<input_event> for InputEvent {
fn from(raw: input_event) -> Self {
Self(raw)
}
}
impl AsRef<input_event> for InputEvent {
fn as_ref(&self) -> &input_event {
&self.0
}
}
impl fmt::Debug for InputEvent {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut debug = f.debug_struct("InputEvent");
debug.field("time", &self.timestamp());
let kind = self.kind();
if let InputEventKind::Other = kind {
debug
.field("type", &self.event_type())
.field("code", &self.code());
} else {
debug.field("kind", &kind);
}
debug.field("value", &self.value()).finish()
}
}
pub fn enumerate() -> EnumerateDevices {
EnumerateDevices {
inner: raw_stream::enumerate(),
}
}
pub struct EnumerateDevices {
inner: raw_stream::EnumerateDevices,
}
impl Iterator for EnumerateDevices {
type Item = (PathBuf, Device);
fn next(&mut self) -> Option<(PathBuf, Device)> {
self.inner
.next()
.map(|(pb, dev)| (pb, Device::from_raw_device(dev)))
}
}
fn systime_to_timeval(time: &SystemTime) -> libc::timeval {
let (sign, dur) = match time.duration_since(SystemTime::UNIX_EPOCH) {
Ok(dur) => (1, dur),
Err(e) => (-1, e.duration()),
};
libc::timeval {
tv_sec: dur.as_secs() as libc::time_t * sign,
tv_usec: dur.subsec_micros() as libc::suseconds_t,
}
}
fn timeval_to_systime(tv: &libc::timeval) -> SystemTime {
let dur = Duration::new(tv.tv_sec.unsigned_abs(), tv.tv_usec as u32 * 1000);
if tv.tv_sec >= 0 {
SystemTime::UNIX_EPOCH + dur
} else {
SystemTime::UNIX_EPOCH - dur
}
}
pub(crate) unsafe fn cast_to_bytes<T: ?Sized>(mem: &T) -> &[u8] {
std::slice::from_raw_parts(mem as *const T as *const u8, std::mem::size_of_val(mem))
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EnumParseError(());