First draft of a libinput backend
- Only does DeviceEvent parsing for now - No way to initialize it
This commit is contained in:
parent
cba111bf4f
commit
5369cc2927
|
@ -0,0 +1,147 @@
|
|||
//! Implementation of input backend trait for types provided by `libinput`
|
||||
|
||||
use backend::SeatInternal;
|
||||
use backend::input::{InputBackend, InputHandler, Seat, SeatCapabilities};
|
||||
use input::{Libinput, Device, Seat as LibinputSeat, DeviceCapability};
|
||||
use input::event::*;
|
||||
|
||||
use std::io::Error as IoError;
|
||||
use std::collections::hash_map::{DefaultHasher, HashMap};
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
pub struct LibinputInputBackend {
|
||||
context: Libinput,
|
||||
devices: Vec<Device>,
|
||||
seats: HashMap<LibinputSeat, Seat>,
|
||||
handler: Option<Box<InputHandler<LibinputInputBackend> + 'static>>,
|
||||
}
|
||||
|
||||
impl InputBackend for LibinputInputBackend {
|
||||
type InputConfig = [Device];
|
||||
type EventError = IoError;
|
||||
|
||||
fn set_handler<H: InputHandler<Self> + 'static>(&mut self, mut handler: H) {
|
||||
if self.handler.is_some() {
|
||||
self.clear_handler();
|
||||
}
|
||||
for seat in self.seats.values() {
|
||||
handler.on_seat_created(&seat);
|
||||
}
|
||||
self.handler = Some(Box::new(handler));
|
||||
}
|
||||
|
||||
fn get_handler(&mut self) -> Option<&mut InputHandler<Self>> {
|
||||
self.handler
|
||||
.as_mut()
|
||||
.map(|handler| handler as &mut InputHandler<Self>)
|
||||
}
|
||||
|
||||
fn clear_handler(&mut self) {
|
||||
if let Some(mut handler) = self.handler.take() {
|
||||
for seat in self.seats.values() {
|
||||
handler.on_seat_destroyed(&seat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn input_config(&mut self) -> &mut Self::InputConfig {
|
||||
&mut self.devices
|
||||
}
|
||||
|
||||
fn set_cursor_position(&mut self, _x: u32, _y: u32) -> Result<(), ()> {
|
||||
// FIXME later.
|
||||
// This will be doable with the hardware cursor api and probably some more cases
|
||||
Err(())
|
||||
}
|
||||
|
||||
fn dispatch_new_events(&mut self) -> Result<(), IoError> {
|
||||
self.context.dispatch()?;
|
||||
for event in &mut self.context {
|
||||
match event {
|
||||
Event::Device(device_event) => {
|
||||
use input::event::device::*;
|
||||
match device_event {
|
||||
DeviceEvent::Added(device_added_event) => {
|
||||
let added = device_added_event.into_event().device();
|
||||
|
||||
let new_caps = SeatCapabilities {
|
||||
pointer: added.has_capability(DeviceCapability::Pointer),
|
||||
keyboard: added.has_capability(DeviceCapability::Keyboard),
|
||||
touch: added.has_capability(DeviceCapability::Touch),
|
||||
};
|
||||
|
||||
let device_seat = added.seat();
|
||||
self.devices.push(added);
|
||||
|
||||
let contains = self.seats.contains_key(&device_seat);
|
||||
if contains {
|
||||
let old_seat = self.seats.get_mut(&device_seat).unwrap();
|
||||
{
|
||||
let caps = old_seat.capabilities_mut();
|
||||
caps.pointer = new_caps.pointer || caps.pointer;
|
||||
caps.keyboard = new_caps.keyboard || caps.keyboard;
|
||||
caps.touch = new_caps.touch || caps.touch;
|
||||
}
|
||||
if let Some(ref mut handler) = self.handler {
|
||||
handler.on_seat_changed(old_seat);
|
||||
}
|
||||
} else {
|
||||
let mut hasher = DefaultHasher::default();
|
||||
device_seat.hash(&mut hasher);
|
||||
self.seats.insert(device_seat.clone(), Seat::new(hasher.finish(), new_caps));
|
||||
if let Some(ref mut handler) = self.handler {
|
||||
handler.on_seat_created(self.seats.get(&device_seat).unwrap());
|
||||
}
|
||||
}
|
||||
},
|
||||
DeviceEvent::Removed(device_removed_event) => {
|
||||
let removed = device_removed_event.into_event().device();
|
||||
|
||||
// remove device
|
||||
self.devices.retain(|dev| *dev == removed);
|
||||
|
||||
let device_seat = removed.seat();
|
||||
|
||||
// update capabilities, so they appear correctly on `on_seat_changed` and `on_seat_destroyed`.
|
||||
if let Some(seat) = self.seats.get_mut(&device_seat) {
|
||||
let caps = seat.capabilities_mut();
|
||||
caps.pointer = self.devices.iter().any(|x| x.has_capability(DeviceCapability::Pointer));
|
||||
caps.keyboard = self.devices.iter().any(|x| x.has_capability(DeviceCapability::Keyboard));
|
||||
caps.touch = self.devices.iter().any(|x| x.has_capability(DeviceCapability::Touch));
|
||||
} else {
|
||||
//TODO is this the best we can do?
|
||||
panic!("Seat changed that was never created")
|
||||
}
|
||||
|
||||
// check if the seat has any other devices
|
||||
if !self.devices.iter().any(|x| x.seat() == device_seat) {
|
||||
// it has not, lets destroy it
|
||||
if let Some(seat) = self.seats.remove(&device_seat) {
|
||||
if let Some(ref mut handler) = self.handler {
|
||||
handler.on_seat_destroyed(&seat);
|
||||
}
|
||||
} else {
|
||||
//TODO is this the best we can do?
|
||||
panic!("Seat destroyed that was never created");
|
||||
}
|
||||
} else {
|
||||
// it has, notify about updates
|
||||
if let Some(ref mut handler) = self.handler {
|
||||
handler.on_seat_changed(self.seats.get(&device_seat).unwrap());
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
if let Some(ref mut handler) = self.handler {
|
||||
handler.on_input_config_changed(&mut self.devices);
|
||||
}
|
||||
},
|
||||
Event::Touch(touch_event) => {},
|
||||
Event::Keyboard(keyboard_event) => {},
|
||||
Event::Pointer(pointer_event) => {},
|
||||
_ => {}, //FIXME: What to do with the rest.
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue