diff --git a/src/backend/glutin.rs b/src/backend/glutin.rs index a79bd93..e635f7e 100644 --- a/src/backend/glutin.rs +++ b/src/backend/glutin.rs @@ -5,7 +5,7 @@ use backend::{SeatInternal, TouchSlotInternal}; use backend::graphics::GraphicsBackend; use backend::graphics::opengl::{Api, OpenglGraphicsBackend, PixelFormat, SwapBuffersError}; use backend::input::{Axis, AxisSource, InputBackend, InputHandler, KeyState, MouseButton, MouseButtonState, - Seat, SeatCapabilities, TouchEvent, TouchSlot}; + Seat, SeatCapabilities, TouchEvent, TouchSlot, Output}; use glutin::{Api as GlutinApi, MouseButton as GlutinMouseButton, PixelFormat as GlutinPixelFormat}; use glutin::{ContextError, CreationError, ElementState, Event, GlContext, HeadlessContext, HeadlessRendererBuilder, MouseScrollDelta, Touch, TouchPhase, Window, WindowBuilder}; @@ -376,6 +376,8 @@ impl InputBackend for GlutinInputBackend { } Ok(()) } + + fn set_output_metadata(&mut self, seat: &Seat, output: &Output) {} } impl GlutinInputBackend { diff --git a/src/backend/input.rs b/src/backend/input.rs index 6251682..a0be819 100644 --- a/src/backend/input.rs +++ b/src/backend/input.rs @@ -3,6 +3,7 @@ use backend::{SeatInternal, TouchSlotInternal}; use std::error::Error; +use std::hash::Hash; /// A seat describes a group of input devices and at least one /// graphics device belonging together. @@ -64,6 +65,20 @@ 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; +} + /// State of key on a keyboard. Either pressed or released #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum KeyState { @@ -216,6 +231,9 @@ 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>; } @@ -232,7 +250,6 @@ 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 diff --git a/src/backend/libinput.rs b/src/backend/libinput.rs index f65097e..63c29e9 100644 --- a/src/backend/libinput.rs +++ b/src/backend/libinput.rs @@ -1,7 +1,7 @@ //! Implementation of input backend trait for types provided by `libinput` -use backend::SeatInternal; -use backend::input::{InputBackend, InputHandler, Seat, SeatCapabilities, MouseButton}; +use backend::{SeatInternal, TouchSlotInternal}; +use backend::input::{InputBackend, InputHandler, Seat, SeatCapabilities, MouseButton, TouchEvent as BackendTouchEvent, TouchSlot as BackendTouchSlot, Output}; use input::{Libinput, Device, Seat as LibinputSeat, DeviceCapability}; use input::event::*; @@ -12,6 +12,7 @@ use std::hash::{Hash, Hasher}; struct SeatDesc { seat: Seat, pointer: (u32, u32), + size: (u32, u32), } /// Libinput based `InputBackend`. @@ -118,7 +119,8 @@ impl InputBackend for LibinputInputBackend { seat_entry.key().hash(&mut hasher); let desc = seat_entry.insert(SeatDesc { seat: Seat::new(hasher.finish(), new_caps), - pointer: (0, 0) //FIXME: What position to assume? Maybe center of the screen instead. Probably call `set_cursor_position` after this. + pointer: (0, 0), //FIXME: We should not assume a position. Some backends might force a position on us. + size: (1280, 800), //FIXME: Document the requirement of calling `set_output_metadata` on `on_seat_created`. }); if let Some(ref mut handler) = self.handler { trace!(self.logger, "Calling on_seat_created with {:?}", desc.seat); @@ -174,9 +176,28 @@ impl InputBackend for LibinputInputBackend { use ::input::event::touch::*; if let Some(ref mut handler) = self.handler { let device_seat = touch_event.device().seat(); + let desc = self.seats.get(&device_seat).expect("Recieved key event of non existing Seat"); trace!(self.logger, "Calling on_touch with {:?}", touch_event); - handler.on_touch(&self.seats.get(&device_seat).expect("Recieved key event of non existing Seat").seat, - touch_event.time(), touch_event.into()) + handler.on_touch(&desc.seat, touch_event.time(), + match touch_event { + TouchEvent::Down(down_event) => BackendTouchEvent::Down { + slot: down_event.slot().map(|x| BackendTouchSlot::new(x)), + x: down_event.x_transformed(desc.size.0), + y: down_event.x_transformed(desc.size.1), + }, + TouchEvent::Motion(motion_event) => BackendTouchEvent::Motion { + slot: motion_event.slot().map(|x| BackendTouchSlot::new(x)), + x: motion_event.x_transformed(desc.size.0), + y: motion_event.x_transformed(desc.size.1), + }, + TouchEvent::Up(up_event) => BackendTouchEvent::Up { + slot: up_event.slot().map(|x| BackendTouchSlot::new(x)), + }, + TouchEvent::Cancel(cancel_event) => BackendTouchEvent::Cancel { + slot: cancel_event.slot().map(|x| BackendTouchSlot::new(x)), + }, + TouchEvent::Frame(_) => ::backend::input::TouchEvent::Frame, + }) } }, Event::Keyboard(keyboard_event) => { @@ -209,10 +230,8 @@ impl InputBackend for LibinputInputBackend { let device_seat = motion_event.device().seat(); let desc = self.seats.get_mut(&device_seat).expect("Recieved pointer event of non existing Seat"); desc.pointer = ( - motion_event.absolute_x_transformed( - /*FIXME: global.get_focused_output_for_seat(&desc.seat).width() or something like that*/ 1280) as u32, - motion_event.absolute_y_transformed( - /*FIXME: global.get_focused_output_for_seat(&desc.seat).height() or something like that*/ 800) as u32, + motion_event.absolute_x_transformed(desc.size.0) as u32, + motion_event.absolute_y_transformed(desc.size.1) as u32, ); if let Some(ref mut handler) = self.handler { trace!(self.logger, "Calling on_pointer_move with {:?}", desc.pointer); @@ -263,6 +282,16 @@ impl InputBackend for LibinputInputBackend { }; Ok(()) } + + fn set_output_metadata(&mut self, seat: &Seat, output: &Output) { + for desc in self.seats.values_mut() { + if desc.seat == *seat { + desc.size = output.size(); + return; + } + } + panic!("Got metadata for non-existant seat"); + } } impl From<::input::event::keyboard::KeyState> for ::backend::input::KeyState { @@ -293,30 +322,3 @@ impl From<::input::event::pointer::ButtonState> for ::backend::input::MouseButto } } } - -impl From<::input::event::touch::TouchEvent> for ::backend::input::TouchEvent { - fn from(libinput: ::input::event::touch::TouchEvent) -> Self { - use ::input::event::touch::{TouchEventSlot, TouchEventPosition}; - use ::backend::TouchSlotInternal; - - match libinput { - ::input::event::touch::TouchEvent::Down(down_event) => ::backend::input::TouchEvent::Down { - slot: down_event.slot().map(|x| ::backend::input::TouchSlot::new(x)), - x: down_event.x_transformed(/*FIXME: global.get_focused_output_for_seat(&desc.seat).width() or something like that*/ 1280), - y: down_event.x_transformed(/*FIXME: global.get_focused_output_for_seat(&desc.seat).height() or something like that*/ 800), - }, - ::input::event::touch::TouchEvent::Motion(motion_event) => ::backend::input::TouchEvent::Motion { - slot: motion_event.slot().map(|x| ::backend::input::TouchSlot::new(x)), - x: motion_event.x_transformed(/*FIXME: global.get_focused_output_for_seat(&desc.seat).width() or something like that*/ 1280), - y: motion_event.x_transformed(/*FIXME: global.get_focused_output_for_seat(&desc.seat).height() or something like that*/ 800), - }, - ::input::event::touch::TouchEvent::Up(up_event) => ::backend::input::TouchEvent::Up { - slot: up_event.slot().map(|x| ::backend::input::TouchSlot::new(x)), - }, - ::input::event::touch::TouchEvent::Cancel(cancel_event) => ::backend::input::TouchEvent::Cancel { - slot: cancel_event.slot().map(|x| ::backend::input::TouchSlot::new(x)), - }, - ::input::event::touch::TouchEvent::Frame(_) => ::backend::input::TouchEvent::Frame, - } - } -}