select devices from args

This commit is contained in:
siikamiika 2018-11-13 19:54:41 +02:00
parent 7958f243e1
commit 779947195a
2 changed files with 112 additions and 68 deletions

68
src/input_thread.rs Normal file
View File

@ -0,0 +1,68 @@
use std::thread;
use std::time::Duration;
use evdev_rs::util::event_code_to_int;
use crossbeam::crossbeam_channel::{unbounded, Select, Receiver, Sender};
use super::event::ThreadInputEvent;
use super::hw_device;
pub fn create_evdev_thread(device_path: &str) -> (String, Receiver<ThreadInputEvent>, Sender<bool>) {
// send out input events, receive stop command
let (send_event_channel, recv_event_channel) = unbounded();
let (send_stop_channel, recv_stop_channel) = unbounded();
// thread safety and stuff
let device_path = String::from(device_path);
let return_device_path = device_path.clone();
thread::spawn(move || {
// open device
let mut dev = hw_device::HwDevice::new(&device_path);
// wait for device init
thread::sleep(Duration::from_secs(1));
// don't deliver events elsewhere
dev.device.grab(evdev_rs::GrabMode::Grab).unwrap();
// sleep for testing purposes
thread::sleep(Duration::from_secs(1));
loop {
// check for stop requests
let mut sel = Select::new();
// create stop channel receive operation
let oper1 = sel.recv(&recv_stop_channel);
// try to select from stop channel
let oper = sel.try_select();
match oper {
// no stop requests
Err(_) => (),
// stop request received, break out of the loop
Ok(oper) => match oper.index() {
i if i == oper1 => {
assert_eq!(oper.recv(&recv_stop_channel), Ok(true));
break;
},
// shouldn't happen
_ => (),
},
}
// read next input event
let event = dev.device.next_event(evdev_rs::NORMAL | evdev_rs::BLOCKING);
match event {
// send input event to event channel
Ok(e) => send_event_channel.send(
ThreadInputEvent {
typ: e.1.event_type as u32,
code: event_code_to_int(&e.1.event_code).1,
value: e.1.value,
}
).unwrap(),
Err(_) => (),
}
}
});
(return_device_path, recv_event_channel, send_stop_channel)
}

View File

@ -1,31 +1,39 @@
extern crate uinput; extern crate uinput;
extern crate evdev_rs; extern crate evdev_rs;
#[macro_use]
extern crate crossbeam; extern crate crossbeam;
use std::thread; use std::env::args;
use std::time::Duration; use std::time::Duration;
use std::collections::HashMap;
use evdev_rs::util::event_code_to_int;
use evdev_rs::enums::EventType::{EV_KEY, EV_REL}; use evdev_rs::enums::EventType::{EV_KEY, EV_REL};
use crossbeam::crossbeam_channel::unbounded; use crossbeam::crossbeam_channel:: Select;
use crossbeam::crossbeam_channel::Receiver;
mod virtual_mouse; mod virtual_mouse;
mod virtual_kbd; mod virtual_kbd;
mod hw_device; mod hw_device;
mod event; mod event;
mod input_thread;
use self::event::ThreadInputEvent; use self::input_thread::create_evdev_thread;
fn main() { fn main() {
let kbd_path = "/dev/input/by-id/usb-04d9_USB_Keyboard-event-kbd"; let args: Vec<_> = args().collect();
let mouse_path = "/dev/input/by-id/usb-Kingsis_Peripherals_ZOWIE_Gaming_mouse-event-mouse";
let kbd_receiver = create_evdev_thread(kbd_path); // (path, receiver, stopper)
let mouse_receiver = create_evdev_thread(mouse_path); let mut devices = Vec::new();
// let mut disabled_devices = Vec::new();
for device_path in &args[1..] {
devices.push(create_evdev_thread(&device_path));
}
// testing device removal
// thread::sleep(Duration::from_secs(1));
// devices[1].2.send(true).unwrap();
// disabled_devices.push(devices.remove(1));
// init virtual devices // init virtual devices
let mut virt_kbd = virtual_kbd::VirtualKeyboard::new("test-kbd"); let mut virt_kbd = virtual_kbd::VirtualKeyboard::new("test-kbd");
@ -33,66 +41,34 @@ fn main() {
// read events and feed them to the virtual devices // read events and feed them to the virtual devices
loop { loop {
// TODO: use Select struct // init select
// https://docs.rs/crossbeam/0.5.0/crossbeam/channel/struct.Select.html let mut sel = Select::new();
select! {
recv(kbd_receiver) -> msg => { // create device input event receive operations and map them to devices
match msg { let mut device_idx_by_oper = HashMap::new();
for (i, (_, receiver, _)) in devices.iter().enumerate() {
let o = sel.recv(&receiver);
device_idx_by_oper.insert(o, i);
}
// select from available device(s)
let oper = sel.select();
// read from selected device
let index = oper.index();
match oper.recv(&devices[device_idx_by_oper[&index]].1) {
Ok(e) => { Ok(e) => {
if e.typ == EV_KEY as u32 && e.code == 1 { // mouse event
// quit on esc if e.typ == EV_REL as u32 || (e.code >= 272 && e.code <= 276) {
break; virt_mouse.device.write(e.typ as i32, e.code as i32, e.value).unwrap();
virt_mouse.device.synchronize().unwrap();
// keyboard event
} else if e.typ == EV_KEY as u32 { } else if e.typ == EV_KEY as u32 {
virt_kbd.device.write(e.typ as i32, e.code as i32, e.value).unwrap(); virt_kbd.device.write(e.typ as i32, e.code as i32, e.value).unwrap();
virt_kbd.device.synchronize().unwrap(); virt_kbd.device.synchronize().unwrap();
} }
}
_ => (),
}
}, },
recv(mouse_receiver) -> msg => {
match msg {
Ok(e) => {
if e.typ == EV_REL as u32 || (e.code >= 272 && e.code <= 276) {
virt_mouse.device.write(e.typ as i32, e.code as i32, e.value).unwrap();
virt_mouse.device.synchronize().unwrap();
}
}
_ => (), _ => (),
} }
},
}
} }
} }
fn create_evdev_thread(device_path: &str) -> Receiver<ThreadInputEvent> {
let (send_channel, recv_channel) = unbounded();
// whatever
let device_path = String::from(device_path);
thread::spawn(move || {
// open device
let mut dev = hw_device::HwDevice::new(&device_path);
// wait for device init
thread::sleep(Duration::from_millis(200));
// don't deliver events elsewhere
dev.device.grab(evdev_rs::GrabMode::Grab).unwrap();
// read events and put them to queue
loop {
let event = dev.device.next_event(evdev_rs::NORMAL | evdev_rs::BLOCKING);
match event {
Ok(e) => send_channel.send(
ThreadInputEvent {
typ: e.1.event_type as u32,
code: event_code_to_int(&e.1.event_code).1,
value: e.1.value,
}
).unwrap(),
Err(_) => (),
}
}
});
recv_channel
}