use core::convert::TryFrom;
use core::mem::{transmute, size_of};
use core::hint::unreachable_unchecked;
use crate::sys::input_event;
use crate::{
EventTime, RangeError, KeyState,
EventKind, SynchronizeKind, Key, RelativeAxis, AbsoluteAxis,
SwitchKind, MiscKind, LedKind, AutorepeatKind, SoundKind, UInputKind,
ForceFeedbackKind, ForceFeedbackStatusKind,
};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[repr(C)]
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct SynchronizeEvent {
pub time: EventTime,
event: EventKind,
pub kind: SynchronizeKind,
pub value: i32,
}
#[repr(C)]
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct KeyEvent {
pub time: EventTime,
event: EventKind,
pub key: Key,
pub value: KeyState,
}
#[repr(C)]
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct RelativeEvent {
pub time: EventTime,
event: EventKind,
pub axis: RelativeAxis,
pub value: i32,
}
#[repr(C)]
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct AbsoluteEvent {
pub time: EventTime,
event: EventKind,
pub axis: AbsoluteAxis,
pub value: i32,
}
#[repr(C)]
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct SwitchEvent {
pub time: EventTime,
event: EventKind,
pub switch: SwitchKind,
pub value: i32,
}
#[repr(C)]
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct MiscEvent {
pub time: EventTime,
event: EventKind,
pub kind: MiscKind,
pub value: i32,
}
#[repr(C)]
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct LedEvent {
pub time: EventTime,
event: EventKind,
pub led: LedKind,
pub value: i32,
}
#[repr(C)]
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct AutorepeatEvent {
pub time: EventTime,
event: EventKind,
pub kind: AutorepeatKind,
pub value: i32,
}
#[repr(C)]
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct SoundEvent {
pub time: EventTime,
event: EventKind,
pub sound: SoundKind,
pub value: i32,
}
#[repr(C)]
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct ForceFeedbackEvent {
pub time: EventTime,
event: EventKind,
pub kind: ForceFeedbackKind,
pub value: i32,
}
#[repr(C)]
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct ForceFeedbackStatusEvent {
pub time: EventTime,
event: EventKind,
pub kind: ForceFeedbackStatusKind,
pub value: i32,
}
#[repr(C)]
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct UInputEvent {
pub time: EventTime,
event: EventKind,
pub code: UInputKind,
pub value: i32,
}
#[repr(C)]
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct InputEvent {
pub time: EventTime,
pub kind: EventKind,
pub code: u16,
pub value: i32,
}
impl InputEvent {
pub const fn zeroed() -> Self {
Self {
time: EventTime::new(0, 0),
kind: EventKind::Synchronize,
code: SynchronizeKind::Report.code(),
value: 0,
}
}
pub fn with_raw(event: input_event) -> Result<Self, RangeError> {
EventKind::from_type(event.type_).map(move |_| unsafe {
Self::with_raw_unchecked(event)
})
}
pub unsafe fn with_raw_unchecked(event: input_event) -> Self {
unsafe {
transmute(event)
}
}
pub fn into_bytes(self) -> [u8; size_of::<InputEvent>()] {
unsafe {
transmute(self)
}
}
pub fn as_bytes(&self) -> &[u8; size_of::<InputEvent>()] {
unsafe {
transmute(self)
}
}
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8; size_of::<InputEvent>()] {
transmute(self)
}
}
#[test]
fn input_event_zeroed() {
use core::mem::MaybeUninit;
let event = InputEvent::zeroed().into_raw();
let zeroed: input_event = unsafe { MaybeUninit::zeroed().assume_init() };
assert_eq!(event, zeroed);
}
impl SynchronizeEvent {
pub const fn report(time: EventTime) -> Self {
Self::new(time, SynchronizeKind::Report, 0)
}
}
macro_rules! event_impl {
(@impl_event InputEvent $($tt:tt)*) => { };
(@impl_event $name:ident $code:ident $kind:path, $codekind:ident, $valuekind:ident) => {
impl GenericEvent for $name {
fn event_kind(&self) -> EventKind { $kind }
fn time(&self) -> &EventTime { &self.time }
fn code(&self) -> u16 { self.$code as _ }
fn value(&self) -> i32 { self.value.into() }
fn with_event(event: InputEvent) -> Result<Self, RangeError> {
$codekind::from_code(event.code)
.and_then(move |_| if event.kind == $kind {
Ok(unsafe { Self::with_event_unchecked(event) })
} else {
Err(Default::default())
})
}
unsafe fn with_event_unchecked(event: InputEvent) -> Self {
transmute(event)
}
fn from_ref(event: &InputEvent) -> Result<&Self, RangeError> {
$codekind::from_code(event.code)
.and_then(move |_| if event.kind == $kind {
Ok(unsafe { Self::from_event(event) })
} else {
Err(Default::default())
})
}
fn from_mut(event: &mut InputEvent) -> Result<&mut Self, RangeError> {
$codekind::from_code(event.code)
.and_then(move |_| if event.kind == $kind {
Ok(unsafe { Self::from_event_mut(event) })
} else {
Err(Default::default())
})
}
}
impl<'a> TryFrom<&'a InputEvent> for &'a $name {
type Error = RangeError;
fn try_from(event: &'a InputEvent) -> Result<Self, Self::Error> {
$name::from_ref(event)
}
}
impl TryFrom<InputEvent> for $name {
type Error = RangeError;
fn try_from(event: InputEvent) -> Result<Self, Self::Error> {
$name::from_ref(&event).map(|&e| e)
}
}
impl<'a> TryFrom<&'a mut InputEvent> for &'a mut $name {
type Error = RangeError;
fn try_from(event: &'a mut InputEvent) -> Result<Self, Self::Error> {
$name::from_mut(event)
}
}
impl<'a> From<&'a $name> for &'a InputEvent {
fn from(event: &'a $name) -> Self {
event.as_event()
}
}
impl<'a> From<&'a $name> for InputEvent {
fn from(event: &'a $name) -> Self {
event.as_event().clone()
}
}
impl From<$name> for InputEvent {
fn from(event: $name) -> Self {
From::from(&event)
}
}
impl AsRef<InputEvent> for $name {
fn as_ref(&self) -> &InputEvent {
self.as_event()
}
}
impl<'a> $name {
pub const fn new(time: EventTime, $code: $codekind, value: $valuekind) -> Self {
$name {
time,
event: $kind,
$code: $code,
value,
}
}
pub unsafe fn from_event<E: AsRef<input_event>>(event: &E) -> &Self {
let raw = event.as_ref();
transmute(raw)
}
pub unsafe fn from_event_mut(event: &mut InputEvent) -> &mut Self {
transmute(event)
}
pub fn into_event(self) -> InputEvent {
unsafe {
transmute(self)
}
}
pub fn as_event(&self) -> &InputEvent {
unsafe {
transmute(self)
}
}
pub unsafe fn as_event_mut(&mut self) -> &mut InputEvent {
transmute(self)
}
}
};
(@impl $name:ident $code:ident $kind:path, $codekind:ident, $valuekind:ident) => {
event_impl! {
@impl_event $name $code $kind, $codekind, $valuekind
}
impl AsRef<input_event> for $name {
fn as_ref(&self) -> &input_event {
let raw = self as *const _ as *const _;
unsafe { &*raw }
}
}
};
($(struct $name:ident : $kind:path { $code:ident: $codekind:ident, value: $valuekind:ident })*) => {
$(
event_impl! {
@impl $name $code $kind, $codekind, $valuekind
}
)*
};
}
pub trait GenericEvent: AsRef<InputEvent> + AsRef<input_event> {
fn event_kind(&self) -> EventKind;
fn time(&self) -> &EventTime;
fn code(&self) -> u16;
fn value(&self) -> i32;
fn with_event(event: InputEvent) -> Result<Self, RangeError> where
Self: Clone,
{
Self::from_ref(&event).cloned()
}
unsafe fn with_event_unchecked(event: InputEvent) -> Self where
Self: Clone,
{
match Self::from_ref(&event) {
Ok(event) => event.clone(),
Err(..) => unreachable_unchecked(),
}
}
fn from_ref(event: &InputEvent) -> Result<&Self, RangeError>;
fn from_mut(event: &mut InputEvent) -> Result<&mut Self, RangeError>;
}
event_impl! {
struct SynchronizeEvent : EventKind::Synchronize { kind: SynchronizeKind, value: i32 }
struct KeyEvent : EventKind::Key { key: Key, value: KeyState }
struct RelativeEvent : EventKind::Relative { axis: RelativeAxis, value: i32 }
struct AbsoluteEvent : EventKind::Absolute { axis: AbsoluteAxis, value: i32 }
struct SwitchEvent : EventKind::Switch { switch: SwitchKind, value: i32 }
struct MiscEvent : EventKind::Misc { kind: MiscKind, value: i32 }
struct LedEvent : EventKind::Led { led: LedKind, value: i32 }
struct AutorepeatEvent : EventKind::Autorepeat { kind: AutorepeatKind, value: i32 }
struct SoundEvent : EventKind::Sound { sound: SoundKind, value: i32 }
struct ForceFeedbackEvent : EventKind::ForceFeedback { kind: ForceFeedbackKind, value: i32 }
struct ForceFeedbackStatusEvent : EventKind::ForceFeedbackStatus { kind: ForceFeedbackStatusKind, value: i32 }
struct UInputEvent : EventKind::UInput { code: UInputKind, value: i32 }
struct InputEvent : Unknown { code: u16, value: i32 }
}
impl GenericEvent for InputEvent {
fn event_kind(&self) -> EventKind { self.kind }
fn time(&self) -> &EventTime { &self.time }
fn code(&self) -> u16 { self.code }
fn value(&self) -> i32 { self.value }
fn from_ref(event: &InputEvent) -> Result<&Self, RangeError> {
Ok(event)
}
fn from_mut(event: &mut InputEvent) -> Result<&mut Self, RangeError> {
Ok(event)
}
fn with_event(event: InputEvent) -> Result<Self, RangeError> {
Ok(event)
}
unsafe fn with_event_unchecked(event: InputEvent) -> Self {
event
}
}
impl AsRef<InputEvent> for InputEvent {
fn as_ref(&self) -> &InputEvent {
self
}
}
impl InputEvent {
pub fn from_raw(event: &input_event) -> Result<&Self, RangeError> {
EventKind::from_type(event.type_).map(|_| unsafe {
Self::from_raw_unchecked(event)
})
}
pub unsafe fn from_raw_unchecked(event: &input_event) -> &Self {
transmute(event)
}
pub fn from_raw_mut(event: &mut input_event) -> Result<&mut Self, RangeError> {
EventKind::from_type(event.type_).map(move |_| unsafe {
Self::from_raw_mut_unchecked(event)
})
}
pub unsafe fn from_raw_mut_unchecked(event: &mut input_event) -> &mut Self {
transmute(event)
}
pub fn into_raw(self) -> input_event {
unsafe {
transmute(self)
}
}
pub fn as_raw(&self) -> &input_event {
unsafe {
transmute(self)
}
}
pub unsafe fn as_raw_mut(&mut self) -> &mut input_event {
transmute(self)
}
}
impl From<InputEvent> for input_event {
fn from(event: InputEvent) -> Self {
event.into_raw()
}
}
impl<'a> From<&'a InputEvent> for &'a input_event {
fn from(event: &'a InputEvent) -> Self {
event.as_raw()
}
}
impl TryFrom<input_event> for InputEvent {
type Error = RangeError;
fn try_from(event: input_event) -> Result<Self, Self::Error> {
InputEvent::with_raw(event)
}
}
impl<'a> TryFrom<&'a input_event> for &'a InputEvent {
type Error = RangeError;
fn try_from(event: &'a input_event) -> Result<Self, Self::Error> {
InputEvent::from_raw(event)
}
}
impl<'a> TryFrom<&'a mut input_event> for &'a mut InputEvent {
type Error = RangeError;
fn try_from(event: &'a mut input_event) -> Result<Self, Self::Error> {
InputEvent::from_raw_mut(event)
}
}
macro_rules! input_event_enum {
($($variant:ident($ty:ident),)*) => {
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum Event {
$(
#[allow(missing_docs)]
$variant($ty),
)*
Unknown(InputEvent),
}
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
pub enum EventRef<'a> {
$(
#[allow(missing_docs)]
$variant(&'a $ty),
)*
Unknown(&'a InputEvent),
}
#[derive(PartialEq, Eq, Hash, Debug)]
pub enum EventMut<'a> {
$(
#[allow(missing_docs)]
$variant(&'a mut $ty),
)*
Unknown(&'a mut InputEvent),
}
impl Event {
pub fn new(event: InputEvent) -> Result<Self, RangeError> {
match event.kind {
$(
EventKind::$variant => $ty::with_event(event).map(Event::$variant),
)*
_ => Ok(Event::Unknown(event)),
}
}
pub fn with_event(event: InputEvent) -> Self {
Self::new(event)
.unwrap_or_else(|_| Event::Unknown(event))
}
pub fn into_event(self) -> InputEvent {
match self {
$(
Event::$variant(e) => e.into_event(),
)*
Event::Unknown(event) => event,
}
}
pub fn as_event(&self) -> &InputEvent {
match *self {
$(
Event::$variant(ref event) => event.as_event(),
)*
Event::Unknown(ref event) => event,
}
}
pub fn to_ref(&self) -> EventRef {
match *self {
$(
Event::$variant(ref event) => EventRef::$variant(event),
)*
Event::Unknown(ref event) => EventRef::Unknown(event),
}
}
pub fn to_mut(&mut self) -> EventMut {
match *self {
$(
Event::$variant(ref mut event) => EventMut::$variant(event),
)*
Event::Unknown(ref mut event) => EventMut::Unknown(event),
}
}
}
impl<'a> EventRef<'a> {
pub fn new(event: &'a InputEvent) -> Result<Self, RangeError> {
match event.kind {
$(
EventKind::$variant => $ty::from_ref(event).map(EventRef::$variant),
)*
_ => Ok(EventRef::Unknown(event)),
}
}
pub fn to_owned(self) -> Event {
match self {
$(
EventRef::$variant(event) => Event::$variant(event.clone()),
)*
EventRef::Unknown(event) => Event::Unknown(event.clone()),
}
}
pub fn to_ref(&self) -> EventRef {
unsafe {
transmute(*self)
}
}
pub fn as_event(self) -> &'a InputEvent {
match self {
$(
EventRef::$variant(e) => e.as_event(),
)*
EventRef::Unknown(event) => event,
}
}
}
impl<'a> EventMut<'a> {
pub fn new(event: &'a mut InputEvent) -> Result<Self, RangeError> {
match event.kind {
$(
EventKind::$variant => $ty::from_mut(event).map(EventMut::$variant),
)*
_ => Ok(EventMut::Unknown(event)),
}
}
pub fn to_owned(self) -> Event {
match self {
$(
EventMut::$variant(event) => Event::$variant(event.clone()),
)*
EventMut::Unknown(event) => Event::Unknown(event.clone()),
}
}
pub fn into_ref(self) -> EventRef<'a> {
match self {
$(
EventMut::$variant(event) => EventRef::$variant(event),
)*
EventMut::Unknown(event) => EventRef::Unknown(event),
}
}
pub fn to_ref(&self) -> EventRef {
match self {
$(
EventMut::$variant(event) => EventRef::$variant(event),
)*
EventMut::Unknown(event) => EventRef::Unknown(event),
}
}
pub fn to_mut(&mut self) -> EventMut {
match self {
$(
EventMut::$variant(event) => EventMut::$variant(event),
)*
EventMut::Unknown(event) => EventMut::Unknown(event),
}
}
pub fn as_event(&self) -> &InputEvent {
match self {
$(
EventMut::$variant(event) => event.as_event(),
)*
EventMut::Unknown(event) => event,
}
}
pub unsafe fn as_event_mut(self) -> &'a mut InputEvent {
match self {
$(
EventMut::$variant(e) => e.as_event_mut(),
)*
EventMut::Unknown(event) => event,
}
}
}
$(
impl From<$ty> for Event {
fn from(event: $ty) -> Self {
Event::$variant(event)
}
}
)*
$(
impl<'a> From<&'a $ty> for EventRef<'a> {
fn from(event: &'a $ty) -> Self {
EventRef::$variant(event)
}
}
)*
$(
impl<'a> From<&'a mut $ty> for EventMut<'a> {
fn from(event: &'a mut $ty) -> Self {
EventMut::$variant(event)
}
}
)*
impl From<Event> for InputEvent {
fn from(event: Event) -> Self {
event.into_event()
}
}
impl From<InputEvent> for Event {
fn from(event: InputEvent) -> Self {
Event::with_event(event)
}
}
impl<'a> From<&'a Event> for EventRef<'a> {
fn from(event: &'a Event) -> Self {
event.to_ref()
}
}
impl<'a> From<&'a mut Event> for EventMut<'a> {
fn from(event: &'a mut Event) -> Self {
event.to_mut()
}
}
impl<'a> From<EventRef<'a>> for &'a InputEvent {
fn from(event: EventRef<'a>) -> Self {
event.as_event()
}
}
impl<'a> From<EventMut<'a>> for &'a InputEvent {
fn from(event: EventMut<'a>) -> Self {
event.into_ref().as_event()
}
}
impl<'a> From<EventMut<'a>> for EventRef<'a> {
fn from(event: EventMut<'a>) -> Self {
event.into_ref()
}
}
impl<'a, 'b> From<&'a EventMut<'b>> for &'a InputEvent {
fn from(event: &'a EventMut<'b>) -> Self {
event.as_event()
}
}
impl<'a, 'b> From<&'a EventMut<'b>> for EventRef<'a> {
fn from(event: &'a EventMut<'b>) -> Self {
event.to_ref()
}
}
impl AsRef<InputEvent> for Event {
fn as_ref(&self) -> &InputEvent {
self.as_event()
}
}
impl<'a> AsRef<InputEvent> for EventRef<'a> {
fn as_ref(&self) -> &InputEvent {
self.as_event()
}
}
impl<'a> AsRef<InputEvent> for EventMut<'a> {
fn as_ref(&self) -> &InputEvent {
self.as_event()
}
}
};
}
input_event_enum! {
Synchronize(SynchronizeEvent),
Key(KeyEvent),
Relative(RelativeEvent),
Absolute(AbsoluteEvent),
Switch(SwitchEvent),
Misc(MiscEvent),
Led(LedEvent),
Autorepeat(AutorepeatEvent),
Sound(SoundEvent),
ForceFeedback(ForceFeedbackEvent),
ForceFeedbackStatus(ForceFeedbackStatusEvent),
UInput(UInputEvent),
}