diff --git a/src/backend/glutin.rs b/src/backend/glutin.rs index 0478ce7..6e53401 100644 --- a/src/backend/glutin.rs +++ b/src/backend/glutin.rs @@ -4,10 +4,12 @@ use glutin::{ContextError, CreationError, Event, ElementState, MouseScrollDelta, use glutin::{Api as GlutinApi, PixelFormat as GlutinPixelFormat, MouseButton as GlutinMouseButton}; use nix::c_void; use std::rc::Rc; +use std::error::Error; +use std::fmt; -use backend::NewIdType; +use backend::{SeatInternal, TouchSlotInternal}; use backend::graphics::opengl::{Api, OpenglGraphicsBackend, PixelFormat, SwapBuffersError}; -use backend::input::{InputBackend, InputHandler, Seat, KeyState, MouseButton, MouseButtonState, Axis, AxisSource, TouchEvent, TouchSlot}; +use backend::input::{InputBackend, InputHandler, Seat, SeatCapabilities, KeyState, MouseButton, MouseButtonState, Axis, AxisSource, TouchEvent, TouchSlot}; /// Create a new `GlutinHeadlessRenderer` which implements the `OpenglRenderer` graphics /// backend trait @@ -182,6 +184,7 @@ impl OpenglGraphicsBackend for GlutinWindowedRenderer } /// Errors that may happen when driving the event loop of `GlutinInputBackend` +#[derive(Debug)] pub enum GlutinInputError { /// The underlying `glutin` `Window` was closed. No further events can be processed. @@ -190,6 +193,24 @@ pub enum GlutinInputError WindowClosed } +impl Error for GlutinInputError +{ + fn description(&self) -> &str + { + match *self { + GlutinInputError::WindowClosed => "Glutin Window was closed", + } + } +} + +impl fmt::Display for GlutinInputError +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result + { + write!(f, "{}", self.description()) + } +} + /// Abstracted event loop of a `glutin` `Window` implementing the `InputBackend` trait /// /// You need to call `process_new_events` periodically to receive any events. @@ -205,6 +226,7 @@ pub struct GlutinInputBackend impl InputBackend for GlutinInputBackend { type InputConfig = (); + type EventError = GlutinInputError; fn set_handler + 'static>(&mut self, mut handler: H) { if self.handler.is_some() { @@ -236,20 +258,6 @@ impl InputBackend for GlutinInputBackend Err(()) } } -} - -impl GlutinInputBackend -{ - fn new(window: Rc) -> GlutinInputBackend - { - GlutinInputBackend { - window: window, - time_counter: 0, - seat: Seat::new(0), - input_config: (), - handler: None, - } - } /// Processes new events of the underlying event loop to drive the set `InputHandler`. /// @@ -263,7 +271,7 @@ impl GlutinInputBackend /// /// The linked `GlutinWindowedRenderer` will error with a lost Context and should /// not be used anymore as well. - pub fn process_new_events(&mut self) -> Result<(), GlutinInputError> + fn dispatch_new_events(&mut self) -> Result<(), GlutinInputError> { for event in self.window.poll_events() { @@ -307,6 +315,24 @@ impl GlutinInputBackend } } +impl GlutinInputBackend +{ + fn new(window: Rc) -> GlutinInputBackend + { + GlutinInputBackend { + window: window, + time_counter: 0, + seat: Seat::new(0, SeatCapabilities { + pointer: true, + keyboard: true, + touch: true, + }), + input_config: (), + handler: None, + } + } +} + impl From for Api { fn from(api: GlutinApi) -> Self { match api { diff --git a/src/backend/input.rs b/src/backend/input.rs index 5bd3164..b02bd6c 100644 --- a/src/backend/input.rs +++ b/src/backend/input.rs @@ -1,6 +1,7 @@ //! Common traits for input backends to receive input from. +use backend::{SeatInternal, TouchSlotInternal}; -use backend::NewIdType; +use std::error::Error; /// A seat describes a group of input devices and at least one /// graphics device belonging together. @@ -11,16 +12,35 @@ use backend::NewIdType; /// /// Seats can be checked for equality and hashed for differentiation. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Seat { id: u32 } +pub struct Seat { id: u32, capabilities: SeatCapabilities } -impl NewIdType for Seat +impl SeatInternal for Seat { - fn new(id: u32) -> Seat + fn new(id: u32, capabilities: SeatCapabilities) -> Seat { - Seat { id: id } + Seat { id: id, capabilities: capabilities } } } +impl Seat { + /// Get the currently capabilities of this `Seat` + pub fn capabilities(&self) -> &SeatCapabilities + { + &self.capabilities + } +} + +/// 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 + pub touch: bool +} + /// State of key on a keyboard. Either pressed or released #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum KeyState { @@ -104,9 +124,9 @@ pub enum AxisSource #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct TouchSlot { id: u32 } -impl NewIdType for TouchSlot +impl TouchSlotInternal for TouchSlot { - fn new(id: u32) -> TouchSlot + fn new(id: u32) -> Self { TouchSlot { id: id } } @@ -161,6 +181,10 @@ pub enum TouchEvent pub trait InputBackend: Sized { /// Type of input device associated with the backend type InputConfig; + + /// Type representing errors that may be returned when processing events + type EventError: Error; + /// 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 @@ -171,6 +195,9 @@ pub trait InputBackend: Sized { /// Get current `InputConfig` fn input_config(&mut self) -> &mut Self::InputConfig; + /// Processes new events of the underlying backend and drives the `InputHandler`. + fn dispatch_new_events(&mut self) -> Result<(), Self::EventError>; + /// Sets the cursor position, useful for e.g. pointer wrapping. /// /// Not guaranteed to be supported on every backend. The result usually @@ -185,6 +212,9 @@ pub trait InputHandler { 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 `Seat`'s properties have changed. + fn on_seat_changed(&mut self, seat: &Seat); + /// Called when a new keyboard event was received. /// /// # Arguments @@ -267,6 +297,10 @@ impl InputHandler for Box> { (**self).on_seat_destroyed(seat) } + fn on_seat_changed(&mut self, seat: &Seat) { + (**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) } diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 6047505..6e01f97 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -23,6 +23,12 @@ mod glium; #[cfg(feature = "renderer_glium")] pub use glium::*; -trait NewIdType { +/// Internal functions that need to be accessible by the different backend implementations + +trait SeatInternal { + fn new(id: u32, capabilities: input::SeatCapabilities) -> Self; +} + +trait TouchSlotInternal { fn new(id: u32) -> Self; }