//! Common traits for input backends to receive input from. use backend::NewIdType; /// A seat describes a group of input devices and at least one /// graphics device belonging together. /// /// By default only one seat exists for most systems and smithay backends /// however multiseat configurations are possible and should be treated as /// separated users, all with their own focus, input and cursor available. /// /// Seats can be checked for equality and hashed for differentiation. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Seat { id: u32 } impl NewIdType for Seat { fn new(id: u32) -> Seat { Seat { id: id } } } /// State of key on a keyboard. Either pressed or released #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum KeyState { /// Key is released Released, /// Key is pressed Pressed, } /// A particular mouse button #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum MouseButton { /// Left mouse button Left, /// Middle mouse button Middle, /// Right mouse button Right, /// Other mouse button with index Other(u8), } /// State of a button on a mouse. Either pressed or released #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum MouseButtonState { /// Button is released Released, /// Button is pressed Pressed, } /// Axis when scrolling #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum Axis { /// Vertical axis Vertical, /// Horizonal axis Horizontal, } /// Source of an axis when scrolling #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum AxisSource { /// Finger. Mostly used for trackpads. /// /// Guarantees that a scroll sequence is terminated with a scroll value of 0. /// A caller may use this information to decide on whether kinetic scrolling should /// be triggered on this scroll sequence. /// /// The coordinate system is identical to the /// cursor movement, i.e. a scroll value of 1 represents the equivalent relative /// motion of 1. Finger, /// Continous scrolling device. Almost identical to `Finger` /// /// No terminating event is guaranteed (though it may happen). /// /// The coordinate system is identical to /// the cursor movement, i.e. a scroll value of 1 represents the equivalent relative /// motion of 1. Continous, /// Scroll wheel. /// /// No terminating event is guaranteed (though it may happen). Scrolling is in /// discrete steps. It is up to the caller how to interpret such different step sizes. Wheel, /// Scrolling through tilting the scroll wheel. /// /// No terminating event is guaranteed (though it may happen). Scrolling is in /// discrete steps. It is up to the caller how to interpret such different step sizes. WheelTilt, } /// Slot of a different touch event. /// /// Touch events are groubed by slots, usually to identify different /// fingers on a multi-touch enabled input device. Events should only /// be interpreted in the context of other events on the same slot. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct TouchSlot { id: u32 } impl NewIdType for TouchSlot { fn new(id: u32) -> TouchSlot { TouchSlot { id: id } } } /// Touch event #[derive(Debug, PartialEq, Clone, Copy)] pub enum TouchEvent { /// The start of an event at a given position (x, y). /// /// If the device has multi-touch capabilities a slot is given. Down { /// `TouchSlot`, if the device has multi-touch capabilities slot: Option, /// Absolute x-coordinate of the touch position. x: f64, /// Absolute y-coordinate of the touch position. y: f64 }, /// Movement of a touch on the device surface to a given position (x, y). /// /// If the device has multi-touch capabilities a slot is given. Motion { /// `TouchSlot`, if the device has multi-touch capabilities slot: Option, /// Absolute x-coordinate of the final touch position after the motion. x: f64, /// Absolute y-coordinate of the final touch position after the motion. y: f64 }, /// Stop of an event chain. /// /// If the device has multi-touch capabilities a slot is given. Up { /// `TouchSlot`, if the device has multi-touch capabilities slot: Option }, /// Cancel of an event chain. All previous events in the chain should be ignored. /// /// If the device has multi-touch capabilities a slot is given. Cancel { /// `TouchSlot`, if the device has multi-touch capabilities slot: Option }, /// Signals the end of a set of touchpoints at one device sample time. Frame } /// Trait that describes objects providing a source of input events. All input backends /// need to implemenent this and provide the same base gurantees about the presicion of /// given events. pub trait InputBackend: Sized { /// Type of input device associated with the backend type InputConfig; /// Sets a new handler for this `InputBackend` fn set_handler + 'static>(&mut self, handler: H); /// Get a reference to the currently set handler, if any fn get_handler(&mut self) -> Option<&mut InputHandler>; /// Clears the currently handler, if one is set fn clear_handler(&mut self); /// Get current `InputConfig` fn input_config(&mut self) -> &mut Self::InputConfig; /// Sets the cursor position, useful for e.g. pointer wrapping. /// /// Not guaranteed to be supported on every backend. The result usually /// depends on the capability of the backend, but may also fail for certain /// specific actions. See the backends documentation. fn set_cursor_position(&mut self, x: u32, y: u32) -> Result<(), ()>; } /// Implement to receive input events from any `InputBackend`. pub trait InputHandler { /// Called when a new `Seat` has been created fn on_seat_created(&mut self, seat: &Seat); /// Called when an existing `Seat` has been destroyed. fn on_seat_destroyed(&mut self, seat: &Seat); /// Called when a new keyboard event was received. /// /// # Arguments /// /// - `seat` - The `Seat` the event belongs to /// - `time` - A upward counting variable useful for event ordering. Makes no gurantees about actual time passed between events. /// - `key_code` - Code of the pressed key. See linux/input-event-codes.h /// - `state` - `KeyState` of the event /// - `count` - Total number of keys pressed on all devices on the associated `Seat` /// /// # TODO: /// - check if events can arrive out of order. /// - Make stronger time guarantees fn on_keyboard_key(&mut self, seat: &Seat, time: u32, key_code: u32, state: KeyState, count: u32); /// Called when a new pointer movement event was received. /// /// # Arguments /// /// - `seat` - The `Seat` the event belongs to /// - `time` - A upward counting variable useful for event ordering. Makes no gurantees about actual time passed between events. /// - `to` - Absolute screen coordinates of the pointer moved to. /// /// # TODO: /// - check if events can arrive out of order. /// - Make stronger time guarantees fn on_pointer_move(&mut self, seat: &Seat, time: u32, to: (u32, u32)); /// Called when a new pointer button event was received. /// /// # Arguments /// /// - `seat` - The `Seat` the event belongs to /// - `time` - A upward counting variable useful for event ordering. Makes no gurantees about actual time passed between events. /// - `button` - Which button was pressed.. /// - `state` - `MouseButtonState` of the event /// /// # TODO: /// - check if events can arrive out of order. /// - Make stronger time guarantees fn on_pointer_button(&mut self, seat: &Seat, time: u32, button: MouseButton, state: MouseButtonState); /// Called when a new pointer scroll event was received. /// /// # Arguments /// /// - `seat` - The `Seat` the event belongs to /// - `time` - A upward counting variable useful for event ordering. Makes no gurantees about actual time passed between events. /// - `axis` - `Axis` this event was generated for. /// - `source` - Source of the scroll event. Important for interpretation of `amount`. /// - `amount` - Amount of scrolling on the given `Axis`. See `source` for interpretation. /// /// # TODO: /// - check if events can arrive out of order. /// - Make stronger time guarantees fn on_pointer_scroll(&mut self, seat: &Seat, time: u32, axis: Axis, source: AxisSource, amount: f64); /// Called when a new touch event was received. /// /// # Arguments /// /// - `seat` - The `Seat` the event belongs to /// - `time` - A upward counting variable useful for event ordering. Makes no gurantees about actual time passed between events. /// - `event` - Touch event recieved. See `TouchEvent`. /// /// # TODO: /// - check if events can arrive out of order. /// - Make stronger time guarantees fn on_touch(&mut self, seat: &Seat, time: u32, event: TouchEvent); /// Called when the `InputConfig` was changed through an external event. /// /// What kind of events can trigger this call is completely backend dependent. /// E.g. an input devices was attached/detached or changed it's own configuration. fn on_input_config_changed(&mut self, config: &mut B::InputConfig); } impl InputHandler for Box> { fn on_seat_created(&mut self, seat: &Seat) { (**self).on_seat_created(seat) } fn on_seat_destroyed(&mut self, seat: &Seat) { (**self).on_seat_destroyed(seat) } fn on_keyboard_key(&mut self, seat: &Seat, time: u32, key_code: u32, state: KeyState, count: u32) { (**self).on_keyboard_key(seat, time, key_code, state, count) } fn on_pointer_move(&mut self, seat: &Seat, time: u32, to: (u32, u32)) { (**self).on_pointer_move(seat, time, to) } fn on_pointer_button(&mut self, seat: &Seat, time: u32, button: MouseButton, state: MouseButtonState) { (**self).on_pointer_button(seat, time, button, state) } fn on_pointer_scroll(&mut self, seat: &Seat, time: u32, axis: Axis, source: AxisSource, amount: f64) { (**self).on_pointer_scroll(seat, time, axis, source, amount) } fn on_touch(&mut self, seat: &Seat, time: u32, event: TouchEvent) { (**self).on_touch(seat, time, event) } fn on_input_config_changed(&mut self, config: &mut B::InputConfig) { (**self).on_input_config_changed(config) } }