use std::{error::Error, path::PathBuf};
mod tablet;
pub use tablet::{
ProximityState, TabletToolAxisEvent, TabletToolButtonEvent, TabletToolCapabilitys, TabletToolDescriptor,
TabletToolEvent, TabletToolProximityEvent, TabletToolTipEvent, TabletToolTipState, TabletToolType,
};
use crate::utils::{Logical, Point, Raw, Size};
pub trait Device: PartialEq + Eq + std::hash::Hash {
fn id(&self) -> String;
fn name(&self) -> String;
fn has_capability(&self, capability: DeviceCapability) -> bool;
fn usb_id(&self) -> Option<(u32, u32)>;
fn syspath(&self) -> Option<PathBuf>;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[allow(missing_docs)] pub enum DeviceCapability {
Keyboard,
Pointer,
Touch,
TabletTool,
TabletPad,
Gesture,
Switch,
}
pub trait Event<B: InputBackend> {
fn time(&self) -> u32;
fn device(&self) -> B::Device;
}
#[derive(Debug)]
pub enum UnusedEvent {}
impl<B: InputBackend> Event<B> for UnusedEvent {
fn time(&self) -> u32 {
match *self {}
}
fn device(&self) -> B::Device {
match *self {}
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum KeyState {
Released,
Pressed,
}
pub trait KeyboardKeyEvent<B: InputBackend>: Event<B> {
fn key_code(&self) -> u32;
fn state(&self) -> KeyState;
fn count(&self) -> u32;
}
impl<B: InputBackend> KeyboardKeyEvent<B> for UnusedEvent {
fn key_code(&self) -> u32 {
match *self {}
}
fn state(&self) -> KeyState {
match *self {}
}
fn count(&self) -> u32 {
match *self {}
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum MouseButton {
Left,
Middle,
Right,
Other(u8),
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum ButtonState {
Released,
Pressed,
}
pub trait PointerButtonEvent<B: InputBackend>: Event<B> {
fn button(&self) -> MouseButton;
fn state(&self) -> ButtonState;
}
impl<B: InputBackend> PointerButtonEvent<B> for UnusedEvent {
fn button(&self) -> MouseButton {
match *self {}
}
fn state(&self) -> ButtonState {
match *self {}
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Axis {
Vertical,
Horizontal,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum AxisSource {
Finger,
Continuous,
Wheel,
WheelTilt,
}
pub trait PointerAxisEvent<B: InputBackend>: Event<B> {
fn amount(&self, axis: Axis) -> Option<f64>;
fn amount_discrete(&self, axis: Axis) -> Option<f64>;
fn source(&self) -> AxisSource;
}
impl<B: InputBackend> PointerAxisEvent<B> for UnusedEvent {
fn amount(&self, _axis: Axis) -> Option<f64> {
match *self {}
}
fn amount_discrete(&self, _axis: Axis) -> Option<f64> {
match *self {}
}
fn source(&self) -> AxisSource {
match *self {}
}
}
pub trait PointerMotionEvent<B: InputBackend>: Event<B> {
fn delta(&self) -> Point<f64, Logical> {
(self.delta_x(), self.delta_y()).into()
}
fn delta_x(&self) -> f64;
fn delta_y(&self) -> f64;
}
impl<B: InputBackend> PointerMotionEvent<B> for UnusedEvent {
fn delta_x(&self) -> f64 {
match *self {}
}
fn delta_y(&self) -> f64 {
match *self {}
}
}
pub trait PointerMotionAbsoluteEvent<B: InputBackend>: Event<B> {
fn position(&self) -> Point<f64, Raw> {
(self.x(), self.y()).into()
}
fn x(&self) -> f64;
fn y(&self) -> f64;
fn position_transformed(&self, coordinate_space: Size<i32, Logical>) -> Point<f64, Logical> {
(
self.x_transformed(coordinate_space.w),
self.y_transformed(coordinate_space.h),
)
.into()
}
fn x_transformed(&self, width: i32) -> f64;
fn y_transformed(&self, height: i32) -> f64;
}
impl<B: InputBackend> PointerMotionAbsoluteEvent<B> for UnusedEvent {
fn x(&self) -> f64 {
match *self {}
}
fn y(&self) -> f64 {
match *self {}
}
fn x_transformed(&self, _width: i32) -> f64 {
match *self {}
}
fn y_transformed(&self, _height: i32) -> f64 {
match *self {}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct TouchSlot {
id: u64,
}
#[cfg(any(feature = "backend_winit", feature = "backend_libinput"))]
impl TouchSlot {
pub(crate) fn new(id: u64) -> Self {
TouchSlot { id }
}
}
pub trait TouchDownEvent<B: InputBackend>: Event<B> {
fn slot(&self) -> Option<TouchSlot>;
fn position(&self) -> Point<f64, Raw> {
(self.x(), self.y()).into()
}
fn position_transformed(&self, coordinate_space: Size<i32, Logical>) -> Point<f64, Logical> {
(
self.x_transformed(coordinate_space.w),
self.y_transformed(coordinate_space.h),
)
.into()
}
fn x(&self) -> f64;
fn y(&self) -> f64;
fn x_transformed(&self, width: i32) -> f64;
fn y_transformed(&self, height: i32) -> f64;
}
impl<B: InputBackend> TouchDownEvent<B> for UnusedEvent {
fn slot(&self) -> Option<TouchSlot> {
match *self {}
}
fn x(&self) -> f64 {
match *self {}
}
fn y(&self) -> f64 {
match *self {}
}
fn x_transformed(&self, _width: i32) -> f64 {
match *self {}
}
fn y_transformed(&self, _height: i32) -> f64 {
match *self {}
}
}
pub trait TouchMotionEvent<B: InputBackend>: Event<B> {
fn slot(&self) -> Option<TouchSlot>;
fn position(&self) -> Point<f64, Raw> {
(self.x(), self.y()).into()
}
fn position_transformed(&self, coordinate_space: Size<i32, Logical>) -> Point<f64, Logical> {
(
self.x_transformed(coordinate_space.w),
self.y_transformed(coordinate_space.h),
)
.into()
}
fn x(&self) -> f64;
fn y(&self) -> f64;
fn x_transformed(&self, width: i32) -> f64;
fn y_transformed(&self, height: i32) -> f64;
}
impl<B: InputBackend> TouchMotionEvent<B> for UnusedEvent {
fn slot(&self) -> Option<TouchSlot> {
match *self {}
}
fn x(&self) -> f64 {
match *self {}
}
fn y(&self) -> f64 {
match *self {}
}
fn x_transformed(&self, _width: i32) -> f64 {
match *self {}
}
fn y_transformed(&self, _height: i32) -> f64 {
match *self {}
}
}
pub trait TouchUpEvent<B: InputBackend>: Event<B> {
fn slot(&self) -> Option<TouchSlot>;
}
impl<B: InputBackend> TouchUpEvent<B> for UnusedEvent {
fn slot(&self) -> Option<TouchSlot> {
match *self {}
}
}
pub trait TouchCancelEvent<B: InputBackend>: Event<B> {
fn slot(&self) -> Option<TouchSlot>;
}
impl<B: InputBackend> TouchCancelEvent<B> for UnusedEvent {
fn slot(&self) -> Option<TouchSlot> {
match *self {}
}
}
pub trait TouchFrameEvent<B: InputBackend>: Event<B> {}
impl<B: InputBackend> TouchFrameEvent<B> for UnusedEvent {}
pub trait InputBackend: Sized {
type EventError: Error;
type Device: Device;
type KeyboardKeyEvent: KeyboardKeyEvent<Self>;
type PointerAxisEvent: PointerAxisEvent<Self>;
type PointerButtonEvent: PointerButtonEvent<Self>;
type PointerMotionEvent: PointerMotionEvent<Self>;
type PointerMotionAbsoluteEvent: PointerMotionAbsoluteEvent<Self>;
type TouchDownEvent: TouchDownEvent<Self>;
type TouchUpEvent: TouchUpEvent<Self>;
type TouchMotionEvent: TouchMotionEvent<Self>;
type TouchCancelEvent: TouchCancelEvent<Self>;
type TouchFrameEvent: TouchFrameEvent<Self>;
type TabletToolAxisEvent: TabletToolAxisEvent<Self>;
type TabletToolProximityEvent: TabletToolProximityEvent<Self>;
type TabletToolTipEvent: TabletToolTipEvent<Self>;
type TabletToolButtonEvent: TabletToolButtonEvent<Self>;
type SpecialEvent;
fn dispatch_new_events<F>(&mut self, callback: F) -> Result<(), Self::EventError>
where
F: FnMut(InputEvent<Self>);
}
#[derive(Debug)]
pub enum InputEvent<B: InputBackend> {
DeviceAdded {
device: B::Device,
},
DeviceRemoved {
device: B::Device,
},
Keyboard {
event: B::KeyboardKeyEvent,
},
PointerMotion {
event: B::PointerMotionEvent,
},
PointerMotionAbsolute {
event: B::PointerMotionAbsoluteEvent,
},
PointerButton {
event: B::PointerButtonEvent,
},
PointerAxis {
event: B::PointerAxisEvent,
},
TouchDown {
event: B::TouchDownEvent,
},
TouchMotion {
event: B::TouchMotionEvent,
},
TouchUp {
event: B::TouchUpEvent,
},
TouchCancel {
event: B::TouchCancelEvent,
},
TouchFrame {
event: B::TouchFrameEvent,
},
TabletToolAxis {
event: B::TabletToolAxisEvent,
},
TabletToolProximity {
event: B::TabletToolProximityEvent,
},
TabletToolTip {
event: B::TabletToolTipEvent,
},
TabletToolButton {
event: B::TabletToolButtonEvent,
},
Special(B::SpecialEvent),
}