use std::cell::RefCell;
use std::rc::Rc;
use dharma;
use qualia::{InputConfig, InputForwarding, InputHandling};
use qualia::{EventHandling, HwGraphics, StatePublishing};
use udev;
use device_access::RestrictedOpener;
use input_collector::InputCollector;
use output_collector::OutputCollector;
use device_monitor::DeviceMonitor;
use virtual_terminal;
pub struct DeviceManager<C>
where C: EventHandling + StatePublishing + HwGraphics + Clone
{
udev: udev::Udev,
input_collector: InputCollector<C>,
output_collector: OutputCollector<C>,
coordinator: C,
}
impl<C> DeviceManager<C>
where C: 'static + EventHandling + StatePublishing + HwGraphics + Send + Clone
{
pub fn new(input_handler: Box<InputHandling>,
input_forwarder: Box<InputForwarding>,
input_config: InputConfig,
coordinator: C) -> Self {
let restricted_opener = Self::prepare_restricted_opener();
let vt = Self::setup_virtual_terminal(coordinator.clone(), &restricted_opener.borrow());
let input_collector = InputCollector::new(coordinator.clone(),
input_handler,
input_forwarder,
input_config,
vt,
restricted_opener);
let output_collector = OutputCollector::new(coordinator.clone());
let mut mine = DeviceManager {
udev: udev::Udev::new(),
input_collector: input_collector,
output_collector: output_collector,
coordinator: coordinator,
};
mine.scan_input_devices();
mine.scan_output_devices();
mine.initialize_device_monitor();
mine
}
fn prepare_restricted_opener() -> Rc<RefCell<RestrictedOpener>> {
let mut restricted_opener = RestrictedOpener::new();
if let Err(err) = restricted_opener.initialize_ipc() {
log_warn1!("Failed to initialize IPC ({:?}). \
This may cause problems with access to devices.",
err);
}
Rc::new(RefCell::new(restricted_opener))
}
fn setup_virtual_terminal(coordinator: C,
restricted_opener: &RestrictedOpener)
-> Option<virtual_terminal::VirtualTerminal> {
match virtual_terminal::VirtualTerminal::new(restricted_opener) {
Ok(vt) => {
match vt.get_current() {
Ok(tty_num) => {
match virtual_terminal::setup(tty_num, coordinator, restricted_opener) {
Ok(_) => {}
Err(err) => log_error!("Device Manager: {:?}", err),
}
}
Err(err) => {
log_error!("Device Manager: {:?}", err);
}
}
Some(vt)
}
Err(err) => {
log_error!("Failed to open virtual terminal: {:?}", err);
None
}
}
}
fn scan_input_devices(&mut self) {
if let Err(err) = self.input_collector.scan_devices(&self.udev) {
log_warn1!("Failed to scan input devices: {:?}", err);
}
}
fn scan_output_devices(&mut self) {
let oc = &mut self.output_collector;
self.udev.iterate_output_devices(|devnode, _| {
if let Err(err) = oc.scan_device(devnode) {
log_error!("{}", err);
}
});
}
fn initialize_device_monitor(&mut self) {
match DeviceMonitor::new(self.coordinator.clone()) {
Ok(device_monitor) => {
self.coordinator.add_event_handler(Box::new(device_monitor),
dharma::event_kind::READ);
}
Err(err) => {
log_warn1!("Device Manager: {}", err);
}
}
}
}
impl<C> DeviceManager<C>
where C: 'static + EventHandling + StatePublishing + HwGraphics + Send + Clone
{
pub fn on_suspend(&mut self) {
}
pub fn on_wakeup(&mut self) {
self.scan_input_devices();
}
pub fn on_inputs_changed(&mut self) {
self.scan_input_devices();
}
pub fn on_outputs_changed(&mut self) {
self.scan_output_devices();
}
}