diff --git a/src/backend/input.rs b/src/backend/input.rs index a0be819..f98242c 100644 --- a/src/backend/input.rs +++ b/src/backend/input.rs @@ -65,18 +65,15 @@ pub struct SeatCapabilities { pub touch: bool, } -// FIXME: Maybe refactor this into a struct or move to a more appropriate -// module once fleshed out - -/// Describes a general output that can be focused by a `Seat`. -pub trait Output { - /// Returns size in pixels (width, height) - fn size(&self) -> (u32, u32); - - /// Returns width in pixels - fn width(&self) -> u32; - /// Returns height in pixels - fn height(&self) -> u32; +/// Trait for generic functions every input event does provide/ +pub trait Event { + /// Returns an upward counting variable useful for event ordering. + /// + /// Makes no gurantees about actual time passed between events. + // # TODO: + // - check if events can even arrive out of order. + // - Make stronger time guarantees, if possible + fn time(&self) -> u32; } /// State of key on a keyboard. Either pressed or released @@ -88,6 +85,16 @@ pub enum KeyState { 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 #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum MouseButton { @@ -110,6 +117,14 @@ pub enum MouseButtonState { 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 #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum Axis { @@ -152,6 +167,63 @@ pub enum AxisSource { 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. /// /// 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; + + /// 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; + + /// 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; +} + +pub trait TouchCancelEvent: Event { + /// `TouchSlot`, if the device has multi-touch capabilities + fn slot(&self) -> Option; +} + +pub trait TouchFrameEvent: Event {} + /// Touch event #[derive(Debug, PartialEq, Clone, Copy)] pub enum TouchEvent { @@ -221,6 +378,17 @@ pub trait InputBackend: Sized { /// Type representing errors that may be returned when processing events 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` fn set_handler + 'static>(&mut self, handler: H); /// Get a reference to the currently set handler, if any @@ -231,9 +399,6 @@ pub trait InputBackend: Sized { /// Get current `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`. fn dispatch_new_events(&mut self) -> Result<(), Self::EventError>; } @@ -250,71 +415,80 @@ pub trait InputHandler { /// /// It is not guaranteed that any change has actually happened. fn on_seat_changed(&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` + /// - `event` - The keyboard event /// - /// # 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); + fn on_keyboard_key(&mut self, seat: &Seat, event: B::KeyboardKeyEvent); + /// 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. + /// - `event` - The pointer movement event + fn on_pointer_move(&mut self, seat: &Seat, event: B::PointerMotionEvent); + /// Called when a new pointer absolute movement event was received. /// - /// # 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)); + /// # Arguments + /// + /// - `seat` - The `Seat` the event belongs to + /// - `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. /// /// # 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); + /// - `event` - The pointer button event + fn on_pointer_button(&mut self, seat: &Seat, event: B::PointerButtonEvent); /// 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. + /// - `event` - A upward counting variable useful for event ordering. Makes no gurantees about actual time passed between events. + fn on_pointer_axis(&mut self, seat: &Seat, event: B::PointerAxisEvent); + + /// Called when a new touch down 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`. + /// - `event` - The touch down event + fn on_touch_down(&mut self, seat: &Seat, event: B::TouchDownEvent); + /// Called when a new touch motion event was received. /// - /// # TODO: - /// - check if events can arrive out of order. - /// - Make stronger time guarantees - fn on_touch(&mut self, seat: &Seat, time: u32, event: TouchEvent); + /// # Arguments + /// + /// - `seat` - The `Seat` the event belongs to + /// - `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. /// @@ -336,24 +510,44 @@ impl InputHandler for Box> { (**self).on_seat_changed(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_keyboard_key(&mut self, seat: &Seat, event: B::KeyboardKeyEvent) { + (**self).on_keyboard_key(seat, event) } - fn on_pointer_move(&mut self, seat: &Seat, time: u32, to: (u32, u32)) { - (**self).on_pointer_move(seat, time, to) + fn on_pointer_move(&mut self, seat: &Seat, event: B::PointerMotionEvent) { + (**self).on_pointer_move(seat, event) } - 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_move_absolute(&mut self, seat: &Seat, event: B::PointerMotionAbsoluteEvent) { + (**self).on_pointer_move_absolute(seat, event) } - 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_pointer_button(&mut self, seat: &Seat, event: B::PointerButtonEvent) { + (**self).on_pointer_button(seat, event) } - fn on_touch(&mut self, seat: &Seat, time: u32, event: TouchEvent) { - (**self).on_touch(seat, time, event) + fn on_pointer_axis(&mut self, seat: &Seat, event: B::PointerAxisEvent) { + (**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) {