2017-03-07 10:53:57 +00:00
|
|
|
//! Common traits for input backends to receive input from.
|
2017-03-20 13:33:27 +00:00
|
|
|
|
2017-03-19 20:55:32 +00:00
|
|
|
use backend::{SeatInternal, TouchSlotInternal};
|
2017-03-07 10:53:57 +00:00
|
|
|
|
2017-03-19 20:55:32 +00:00
|
|
|
use std::error::Error;
|
2017-03-07 10:53:57 +00:00
|
|
|
|
|
|
|
/// 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.
|
2017-04-15 20:42:42 +00:00
|
|
|
#[derive(Debug, Clone, Copy, Eq)]
|
2017-03-20 13:33:27 +00:00
|
|
|
pub struct Seat {
|
2017-04-14 22:24:23 +00:00
|
|
|
id: u64,
|
2017-03-20 13:33:27 +00:00
|
|
|
capabilities: SeatCapabilities,
|
|
|
|
}
|
2017-03-07 10:53:57 +00:00
|
|
|
|
2017-03-20 13:33:27 +00:00
|
|
|
impl SeatInternal for Seat {
|
2017-04-14 22:24:23 +00:00
|
|
|
fn new(id: u64, capabilities: SeatCapabilities) -> Seat {
|
2017-03-20 13:33:27 +00:00
|
|
|
Seat {
|
|
|
|
id: id,
|
|
|
|
capabilities: capabilities,
|
|
|
|
}
|
2017-03-07 10:53:57 +00:00
|
|
|
}
|
2017-04-14 22:24:23 +00:00
|
|
|
|
|
|
|
fn capabilities_mut(&mut self) -> &mut SeatCapabilities {
|
|
|
|
&mut self.capabilities
|
|
|
|
}
|
2017-03-07 10:53:57 +00:00
|
|
|
}
|
|
|
|
|
2017-03-19 20:55:32 +00:00
|
|
|
impl Seat {
|
|
|
|
/// Get the currently capabilities of this `Seat`
|
2017-03-20 13:33:27 +00:00
|
|
|
pub fn capabilities(&self) -> &SeatCapabilities {
|
2017-03-19 20:55:32 +00:00
|
|
|
&self.capabilities
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-15 20:42:42 +00:00
|
|
|
impl ::std::cmp::PartialEq for Seat {
|
|
|
|
fn eq(&self, other: &Seat) -> bool {
|
|
|
|
self.id == other.id
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ::std::hash::Hash for Seat {
|
|
|
|
fn hash<H>(&self, state: &mut H) where H: ::std::hash::Hasher {
|
|
|
|
self.id.hash(state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-19 20:55:32 +00:00
|
|
|
/// Describes capabilities a `Seat` has.
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct SeatCapabilities {
|
|
|
|
/// `Seat` has a pointer
|
|
|
|
pub pointer: bool,
|
|
|
|
/// `Seat` has a keyboard
|
|
|
|
pub keyboard: bool,
|
|
|
|
/// `Seat` has a touchscreen
|
2017-03-20 13:33:27 +00:00
|
|
|
pub touch: bool,
|
2017-03-19 20:55:32 +00:00
|
|
|
}
|
|
|
|
|
2017-03-07 10:53:57 +00:00
|
|
|
/// 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)]
|
2017-03-20 13:33:27 +00:00
|
|
|
pub enum Axis {
|
2017-03-07 10:53:57 +00:00
|
|
|
/// Vertical axis
|
|
|
|
Vertical,
|
|
|
|
/// Horizonal axis
|
|
|
|
Horizontal,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Source of an axis when scrolling
|
|
|
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
2017-03-20 13:33:27 +00:00
|
|
|
pub enum AxisSource {
|
2017-03-07 10:53:57 +00:00
|
|
|
/// 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.
|
2017-04-15 19:46:27 +00:00
|
|
|
Continuous,
|
2017-03-07 10:53:57 +00:00
|
|
|
/// 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)]
|
2017-03-20 13:33:27 +00:00
|
|
|
pub struct TouchSlot {
|
|
|
|
id: u32,
|
|
|
|
}
|
2017-03-07 10:53:57 +00:00
|
|
|
|
2017-03-20 13:33:27 +00:00
|
|
|
impl TouchSlotInternal for TouchSlot {
|
|
|
|
fn new(id: u32) -> Self {
|
2017-03-07 10:53:57 +00:00
|
|
|
TouchSlot { id: id }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Touch event
|
|
|
|
#[derive(Debug, PartialEq, Clone, Copy)]
|
2017-03-20 13:33:27 +00:00
|
|
|
pub enum TouchEvent {
|
2017-03-07 10:53:57 +00:00
|
|
|
/// 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<TouchSlot>,
|
|
|
|
/// Absolute x-coordinate of the touch position.
|
|
|
|
x: f64,
|
|
|
|
/// Absolute y-coordinate of the touch position.
|
2017-03-20 13:33:27 +00:00
|
|
|
y: f64,
|
2017-03-07 10:53:57 +00:00
|
|
|
},
|
|
|
|
/// 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<TouchSlot>,
|
|
|
|
/// Absolute x-coordinate of the final touch position after the motion.
|
|
|
|
x: f64,
|
|
|
|
/// Absolute y-coordinate of the final touch position after the motion.
|
2017-03-20 13:33:27 +00:00
|
|
|
y: f64,
|
|
|
|
},
|
2017-03-07 10:53:57 +00:00
|
|
|
/// 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
|
2017-03-20 13:33:27 +00:00
|
|
|
slot: Option<TouchSlot>,
|
2017-03-07 10:53:57 +00:00
|
|
|
},
|
|
|
|
/// 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
|
2017-03-20 13:33:27 +00:00
|
|
|
slot: Option<TouchSlot>,
|
2017-03-07 10:53:57 +00:00
|
|
|
},
|
|
|
|
/// Signals the end of a set of touchpoints at one device sample time.
|
2017-03-20 13:33:27 +00:00
|
|
|
Frame,
|
2017-03-07 10:53:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// 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.
|
2017-03-18 16:09:29 +00:00
|
|
|
pub trait InputBackend: Sized {
|
|
|
|
/// Type of input device associated with the backend
|
2017-04-14 22:24:23 +00:00
|
|
|
type InputConfig: ?Sized;
|
2017-03-19 20:55:32 +00:00
|
|
|
|
|
|
|
/// Type representing errors that may be returned when processing events
|
|
|
|
type EventError: Error;
|
|
|
|
|
2017-03-07 10:53:57 +00:00
|
|
|
/// Sets a new handler for this `InputBackend`
|
2017-03-18 16:09:29 +00:00
|
|
|
fn set_handler<H: InputHandler<Self> + 'static>(&mut self, handler: H);
|
2017-03-07 10:53:57 +00:00
|
|
|
/// Get a reference to the currently set handler, if any
|
2017-03-18 16:09:29 +00:00
|
|
|
fn get_handler(&mut self) -> Option<&mut InputHandler<Self>>;
|
2017-03-07 10:53:57 +00:00
|
|
|
/// Clears the currently handler, if one is set
|
|
|
|
fn clear_handler(&mut self);
|
2017-03-18 16:09:29 +00:00
|
|
|
|
|
|
|
/// Get current `InputConfig`
|
|
|
|
fn input_config(&mut self) -> &mut Self::InputConfig;
|
|
|
|
|
2017-03-19 20:55:32 +00:00
|
|
|
/// Processes new events of the underlying backend and drives the `InputHandler`.
|
|
|
|
fn dispatch_new_events(&mut self) -> Result<(), Self::EventError>;
|
|
|
|
|
2017-03-07 10:53:57 +00:00
|
|
|
/// 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`.
|
2017-03-18 16:09:29 +00:00
|
|
|
pub trait InputHandler<B: InputBackend> {
|
2017-03-07 10:53:57 +00:00
|
|
|
/// 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);
|
2017-03-19 20:55:32 +00:00
|
|
|
/// Called when a `Seat`'s properties have changed.
|
|
|
|
fn on_seat_changed(&mut self, seat: &Seat);
|
|
|
|
|
2017-03-07 10:53:57 +00:00
|
|
|
/// 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
|
2017-03-14 18:14:22 +00:00
|
|
|
/// - `count` - Total number of keys pressed on all devices on the associated `Seat`
|
2017-03-07 10:53:57 +00:00
|
|
|
///
|
|
|
|
/// # 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);
|
2017-03-14 18:14:22 +00:00
|
|
|
/// Called when a new pointer movement event was received.
|
2017-03-07 10:53:57 +00:00
|
|
|
///
|
|
|
|
/// # 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));
|
2017-03-14 18:14:22 +00:00
|
|
|
/// Called when a new pointer button event was received.
|
2017-03-07 10:53:57 +00:00
|
|
|
///
|
|
|
|
/// # 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);
|
2017-03-14 18:14:22 +00:00
|
|
|
/// Called when a new pointer scroll event was received.
|
2017-03-07 10:53:57 +00:00
|
|
|
///
|
|
|
|
/// # 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);
|
2017-03-14 18:14:22 +00:00
|
|
|
/// Called when a new touch event was received.
|
2017-03-07 10:53:57 +00:00
|
|
|
///
|
|
|
|
/// # 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);
|
2017-03-18 16:09:29 +00:00
|
|
|
|
|
|
|
/// 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);
|
2017-03-07 10:53:57 +00:00
|
|
|
}
|
|
|
|
|
2017-03-18 16:09:29 +00:00
|
|
|
impl<B: InputBackend> InputHandler<B> for Box<InputHandler<B>> {
|
2017-03-07 10:53:57 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2017-03-19 20:55:32 +00:00
|
|
|
fn on_seat_changed(&mut self, seat: &Seat) {
|
|
|
|
(**self).on_seat_changed(seat)
|
|
|
|
}
|
|
|
|
|
2017-03-07 10:53:57 +00:00
|
|
|
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)
|
|
|
|
}
|
2017-03-18 16:09:29 +00:00
|
|
|
|
|
|
|
fn on_input_config_changed(&mut self, config: &mut B::InputConfig) {
|
|
|
|
(**self).on_input_config_changed(config)
|
|
|
|
}
|
2017-03-07 10:53:57 +00:00
|
|
|
}
|