Refactor `InputBackend` to use events.

This commit is contained in:
Drakulix 2017-04-21 23:41:28 +02:00
parent 056ce6312c
commit d62f491801
1 changed files with 257 additions and 63 deletions

View File

@ -65,18 +65,15 @@ pub struct SeatCapabilities {
pub touch: bool, pub touch: bool,
} }
// FIXME: Maybe refactor this into a struct or move to a more appropriate /// Trait for generic functions every input event does provide/
// module once fleshed out pub trait Event {
/// Returns an upward counting variable useful for event ordering.
/// Describes a general output that can be focused by a `Seat`. ///
pub trait Output { /// Makes no gurantees about actual time passed between events.
/// Returns size in pixels (width, height) // # TODO:
fn size(&self) -> (u32, u32); // - check if events can even arrive out of order.
// - Make stronger time guarantees, if possible
/// Returns width in pixels fn time(&self) -> u32;
fn width(&self) -> u32;
/// Returns height in pixels
fn height(&self) -> u32;
} }
/// State of key on a keyboard. Either pressed or released /// State of key on a keyboard. Either pressed or released
@ -88,6 +85,16 @@ pub enum KeyState {
Pressed, Pressed,
} }
/// Trait for keyboard event
pub trait KeyboardKeyEvent: Event {
/// Code of the pressed key. See linux/input-event-codes.h
fn key_code(&self) -> u32;
/// State of the key
fn state(&self) -> KeyState;
/// Total number of keys pressed on all devices on the associated `Seat`
fn count(&self) -> u32;
}
/// A particular mouse button /// A particular mouse button
#[derive(Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum MouseButton { pub enum MouseButton {
@ -110,6 +117,14 @@ pub enum MouseButtonState {
Pressed, Pressed,
} }
/// Common methods pointer event generated by pressed buttons do implement
pub trait PointerButtonEvent: Event {
/// Pressed button of the event
fn button(&self) -> MouseButton;
/// State of the button
fn state(&self) -> MouseButtonState;
}
/// Axis when scrolling /// Axis when scrolling
#[derive(Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Axis { pub enum Axis {
@ -152,6 +167,63 @@ pub enum AxisSource {
WheelTilt, WheelTilt,
} }
/// Trait for pointer events generated by scrolling on an axis.
pub trait PointerAxisEvent: Event {
/// `Axis` this event was generated for.
fn axis(&self) -> Axis;
/// Source of the scroll event. Important for interpretation of `amount`.
fn source(&self) -> AxisSource;
/// Amount of scrolling on the given `Axis`. See `source` for interpretation.
fn amount(&self) -> f64;
}
/// Trait for pointer events generated by relative device movement.
pub trait PointerMotionEvent: Event {
/// Delta between the last and new pointer device position interpreted as pixel movement
fn delta(&self) -> (u32, u32) {
(self.delta_x(), self.delta_y())
}
/// Delta on the x axis between the last and new pointer device position interpreted as pixel movement
fn delta_x(&self) -> u32;
/// Delta on the y axis between the last and new pointer device position interpreted as pixel movement
fn delta_y(&self) -> u32;
}
/// Trait for pointer events generated by absolute device positioning.
pub trait PointerMotionAbsoluteEvent: Event {
/// Device position in it's original coordinate space.
///
/// The format is defined by the backend implementation.
fn position(&self) -> (f64, f64) {
(self.x(), self.y())
}
/// Device x position in it's original coordinate space.
///
/// The format is defined by the backend implementation.
fn x(&self) -> f64;
/// Device y position in it's original coordinate space.
///
/// The format is defined by the backend implementation.
fn y(&self) -> f64;
/// Device position converted to the targets coordinate space.
/// E.g. the focused output's resolution.
fn position_transformed(&self, coordinate_space: (u32, u32)) -> (u32, u32) {
(self.x_transformed(coordinate_space.0), self.y_transformed(coordinate_space.1))
}
/// Device x position converted to the targets coordinate space's width.
/// E.g. the focused output's width.
fn x_transformed(&self, width: u32) -> u32;
/// Device y position converted to the targets coordinate space's height.
/// E.g. the focused output's height.
fn y_transformed(&self, height: u32) -> u32;
}
/// Slot of a different touch event. /// Slot of a different touch event.
/// ///
/// Touch events are groubed by slots, usually to identify different /// Touch events are groubed by slots, usually to identify different
@ -168,6 +240,91 @@ impl TouchSlotInternal for TouchSlot {
} }
} }
/// Trait for touch events starting at a given position.
pub trait TouchDownEvent: Event {
/// `TouchSlot`, if the device has multi-touch capabilities
fn slot(&self) -> Option<TouchSlot>;
/// Touch position in the device's native coordinate space
///
/// The actual format is defined by the implementation.
fn position(&self) -> (f64, f64) {
(self.x(), self.y())
}
/// Touch position converted into the target coordinate space.
/// E.g. the focused output's resolution.
fn position_transformed(&self, coordinate_space: (u32, u32)) -> (u32, u32) {
(self.x_transformed(coordinate_space.0), self.y_transformed(coordinate_space.1))
}
/// Touch event's x-coordinate in the device's native coordinate space
///
/// The actual format is defined by the implementation.
fn x(&self) -> f64;
/// Touch event's x-coordinate in the device's native coordinate space
///
/// The actual format is defined by the implementation.
fn y(&self) -> f64;
/// Touch event's x position converted to the targets coordinate space's width.
/// E.g. the focused output's width.
fn x_transformed(&self, width: u32) -> u32;
/// Touch event's y position converted to the targets coordinate space's width.
/// E.g. the focused output's width.
fn y_transformed(&self, height: u32) -> u32;
}
pub trait TouchMotionEvent: Event {
/// `TouchSlot`, if the device has multi-touch capabilities
fn slot(&self) -> Option<TouchSlot>;
/// Touch position in the device's native coordinate space
///
/// The actual format is defined by the implementation.
fn position(&self) -> (f64, f64) {
(self.x(), self.y())
}
/// Touch position converted into the target coordinate space.
/// E.g. the focused output's resolution.
fn position_transformed(&self, coordinate_space: (u32, u32)) -> (u32, u32) {
(self.x_transformed(coordinate_space.0), self.y_transformed(coordinate_space.1))
}
/// Touch event's x-coordinate in the device's native coordinate space
///
/// The actual format is defined by the implementation.
fn x(&self) -> f64;
/// Touch event's x-coordinate in the device's native coordinate space
///
/// The actual format is defined by the implementation.
fn y(&self) -> f64;
/// Touch event's x position converted to the targets coordinate space's width.
/// E.g. the focused output's width.
fn x_transformed(&self, width: u32) -> u32;
/// Touch event's y position converted to the targets coordinate space's width.
/// E.g. the focused output's width.
fn y_transformed(&self, height: u32) -> u32;
}
pub trait TouchUpEvent: Event {
/// `TouchSlot`, if the device has multi-touch capabilities
fn slot(&self) -> Option<TouchSlot>;
}
pub trait TouchCancelEvent: Event {
/// `TouchSlot`, if the device has multi-touch capabilities
fn slot(&self) -> Option<TouchSlot>;
}
pub trait TouchFrameEvent: Event {}
/// Touch event /// Touch event
#[derive(Debug, PartialEq, Clone, Copy)] #[derive(Debug, PartialEq, Clone, Copy)]
pub enum TouchEvent { pub enum TouchEvent {
@ -221,6 +378,17 @@ pub trait InputBackend: Sized {
/// Type representing errors that may be returned when processing events /// Type representing errors that may be returned when processing events
type EventError: Error; type EventError: Error;
type KeyboardKeyEvent: KeyboardKeyEvent;
type PointerAxisEvent: PointerAxisEvent;
type PointerButtonEvent: PointerButtonEvent;
type PointerMotionEvent: PointerMotionEvent;
type PointerMotionAbsoluteEvent: PointerMotionAbsoluteEvent;
type TouchDownEvent: TouchDownEvent;
type TouchUpEvent: TouchUpEvent;
type TouchMotionEvent: TouchMotionEvent;
type TouchCancelEvent: TouchCancelEvent;
type TouchFrameEvent: TouchFrameEvent;
/// Sets a new handler for this `InputBackend` /// Sets a new handler for this `InputBackend`
fn set_handler<H: InputHandler<Self> + 'static>(&mut self, handler: H); fn set_handler<H: InputHandler<Self> + 'static>(&mut self, handler: H);
/// Get a reference to the currently set handler, if any /// Get a reference to the currently set handler, if any
@ -231,9 +399,6 @@ pub trait InputBackend: Sized {
/// Get current `InputConfig` /// Get current `InputConfig`
fn input_config(&mut self) -> &mut Self::InputConfig; fn input_config(&mut self) -> &mut Self::InputConfig;
/// Called to inform the Input backend about a new focused Output for a `Seat`
fn set_output_metadata(&mut self, seat: &Seat, output: &Output);
/// Processes new events of the underlying backend and drives the `InputHandler`. /// Processes new events of the underlying backend and drives the `InputHandler`.
fn dispatch_new_events(&mut self) -> Result<(), Self::EventError>; fn dispatch_new_events(&mut self) -> Result<(), Self::EventError>;
} }
@ -250,71 +415,80 @@ pub trait InputHandler<B: InputBackend> {
/// ///
/// It is not guaranteed that any change has actually happened. /// It is not guaranteed that any change has actually happened.
fn on_seat_changed(&mut self, seat: &Seat); fn on_seat_changed(&mut self, seat: &Seat);
/// Called when a new keyboard event was received. /// Called when a new keyboard event was received.
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `seat` - The `Seat` the event belongs to /// - `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` - The keyboard event
/// - `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: fn on_keyboard_key(&mut self, seat: &Seat, event: B::KeyboardKeyEvent);
/// - 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. /// Called when a new pointer movement event was received.
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `seat` - The `Seat` the event belongs to /// - `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` - The pointer movement event
/// - `to` - Absolute screen coordinates of the pointer moved to. fn on_pointer_move(&mut self, seat: &Seat, event: B::PointerMotionEvent);
/// Called when a new pointer absolute movement event was received.
/// ///
/// # TODO: /// # Arguments
/// - check if events can arrive out of order. ///
/// - Make stronger time guarantees /// - `seat` - The `Seat` the event belongs to
fn on_pointer_move(&mut self, seat: &Seat, time: u32, to: (u32, u32)); /// - `event` - The pointer absolute movement event
fn on_pointer_move_absolute(&mut self, seat: &Seat, event: B::PointerMotionAbsoluteEvent);
/// Called when a new pointer button event was received. /// Called when a new pointer button event was received.
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `seat` - The `Seat` the event belongs to /// - `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` - The pointer button event
/// - `button` - Which button was pressed.. fn on_pointer_button(&mut self, seat: &Seat, event: B::PointerButtonEvent);
/// - `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. /// Called when a new pointer scroll event was received.
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `seat` - The `Seat` the event belongs to /// - `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` - A upward counting variable useful for event ordering. Makes no gurantees about actual time passed between events.
/// - `axis` - `Axis` this event was generated for. fn on_pointer_axis(&mut self, seat: &Seat, event: B::PointerAxisEvent);
/// - `source` - Source of the scroll event. Important for interpretation of `amount`.
/// - `amount` - Amount of scrolling on the given `Axis`. See `source` for interpretation. /// Called when a new touch down event was received.
///
/// # 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 /// # Arguments
/// ///
/// - `seat` - The `Seat` the event belongs to /// - `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` - The touch down event
/// - `event` - Touch event recieved. See `TouchEvent`. fn on_touch_down(&mut self, seat: &Seat, event: B::TouchDownEvent);
/// Called when a new touch motion event was received.
/// ///
/// # TODO: /// # Arguments
/// - check if events can arrive out of order. ///
/// - Make stronger time guarantees /// - `seat` - The `Seat` the event belongs to
fn on_touch(&mut self, seat: &Seat, time: u32, event: TouchEvent); /// - `event` - The touch motion event.
fn on_touch_motion(&mut self, seat: &Seat, event: B::TouchMotionEvent);
/// Called when a new touch up event was received.
///
/// # Arguments
///
/// - `seat` - The `Seat` the event belongs to
/// - `event` - The touch up event.
fn on_touch_up(&mut self, seat: &Seat, event: B::TouchUpEvent);
/// Called when a new touch cancel event was received.
///
/// # Arguments
///
/// - `seat` - The `Seat` the event belongs to
/// - `event` - The touch cancel event.
fn on_touch_cancel(&mut self, seat: &Seat, event: B::TouchCancelEvent);
/// Called when a new touch frame event was received.
///
/// # Arguments
///
/// - `seat` - The `Seat` the event belongs to
/// - `event` - The touch frame event.
fn on_touch_frame(&mut self, seat: &Seat, event: B::TouchFrameEvent);
/// Called when the `InputConfig` was changed through an external event. /// Called when the `InputConfig` was changed through an external event.
/// ///
@ -336,24 +510,44 @@ impl<B: InputBackend> InputHandler<B> for Box<InputHandler<B>> {
(**self).on_seat_changed(seat) (**self).on_seat_changed(seat)
} }
fn on_keyboard_key(&mut self, seat: &Seat, time: u32, key_code: u32, state: KeyState, count: u32) { fn on_keyboard_key(&mut self, seat: &Seat, event: B::KeyboardKeyEvent) {
(**self).on_keyboard_key(seat, time, key_code, state, count) (**self).on_keyboard_key(seat, event)
} }
fn on_pointer_move(&mut self, seat: &Seat, time: u32, to: (u32, u32)) { fn on_pointer_move(&mut self, seat: &Seat, event: B::PointerMotionEvent) {
(**self).on_pointer_move(seat, time, to) (**self).on_pointer_move(seat, event)
} }
fn on_pointer_button(&mut self, seat: &Seat, time: u32, button: MouseButton, state: MouseButtonState) { fn on_pointer_move_absolute(&mut self, seat: &Seat, event: B::PointerMotionAbsoluteEvent) {
(**self).on_pointer_button(seat, time, button, state) (**self).on_pointer_move_absolute(seat, event)
} }
fn on_pointer_scroll(&mut self, seat: &Seat, time: u32, axis: Axis, source: AxisSource, amount: f64) { fn on_pointer_button(&mut self, seat: &Seat, event: B::PointerButtonEvent) {
(**self).on_pointer_scroll(seat, time, axis, source, amount) (**self).on_pointer_button(seat, event)
} }
fn on_touch(&mut self, seat: &Seat, time: u32, event: TouchEvent) { fn on_pointer_axis(&mut self, seat: &Seat, event: B::PointerAxisEvent) {
(**self).on_touch(seat, time, event) (**self).on_pointer_axis(seat, event)
}
fn on_touch_down(&mut self, seat: &Seat, event: B::TouchDownEvent) {
(**self).on_touch_down(seat, event)
}
fn on_touch_motion(&mut self, seat: &Seat, event: B::TouchMotionEvent) {
(**self).on_touch_motion(seat, event)
}
fn on_touch_up(&mut self, seat: &Seat, event: B::TouchUpEvent) {
(**self).on_touch_up(seat, event)
}
fn on_touch_cancel(&mut self, seat: &Seat, event: B::TouchCancelEvent) {
(**self).on_touch_cancel(seat, event)
}
fn on_touch_frame(&mut self, seat: &Seat, event: B::TouchFrameEvent) {
(**self).on_touch_frame(seat, event)
} }
fn on_input_config_changed(&mut self, config: &mut B::InputConfig) { fn on_input_config_changed(&mut self, config: &mut B::InputConfig) {