85 lines
2.9 KiB
Rust
85 lines
2.9 KiB
Rust
|
extern crate uinput;
|
||
|
extern crate evdev_rs;
|
||
|
|
||
|
use std::thread;
|
||
|
use std::time::Duration;
|
||
|
use std::sync::{Arc, Mutex};
|
||
|
use std::collections::VecDeque;
|
||
|
|
||
|
use evdev_rs::util::event_code_to_int;
|
||
|
use evdev_rs::enums::EventType::{EV_KEY, EV_REL};
|
||
|
|
||
|
mod virtual_mouse;
|
||
|
mod virtual_kbd;
|
||
|
mod hw_device;
|
||
|
mod event;
|
||
|
|
||
|
use self::event::ThreadInputEvent;
|
||
|
|
||
|
|
||
|
fn main() {
|
||
|
let kbd_path = "/dev/input/by-id/usb-04d9_USB_Keyboard-event-kbd";
|
||
|
let mouse_path = "/dev/input/by-id/usb-Kingsis_Peripherals_ZOWIE_Gaming_mouse-event-mouse";
|
||
|
|
||
|
// thread-safe event queue
|
||
|
let queue = Arc::new(Mutex::new(VecDeque::new()));
|
||
|
|
||
|
// start a thread listening to input events for each device
|
||
|
for &p in [kbd_path, mouse_path].iter() {
|
||
|
// clone queue mutex reference for this thread
|
||
|
let thread_queue = queue.clone();
|
||
|
|
||
|
thread::spawn(move || {
|
||
|
// open device
|
||
|
let mut dev = hw_device::HwDevice::new(p);
|
||
|
// 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) => thread_queue.lock().unwrap().push_back(
|
||
|
ThreadInputEvent {
|
||
|
typ: e.1.event_type as u32,
|
||
|
code: event_code_to_int(&e.1.event_code).1,
|
||
|
value: e.1.value,
|
||
|
}
|
||
|
),
|
||
|
Err(_) => (),
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// init virtual devices
|
||
|
let mut virt_kbd = virtual_kbd::VirtualKeyboard::new("test-kbd");
|
||
|
let mut virt_mouse = virtual_mouse::VirtualMouse::new("test-mouse");
|
||
|
|
||
|
// read events and feed them to the virtual devices
|
||
|
loop {
|
||
|
let event = queue.lock().unwrap().pop_front();
|
||
|
match event {
|
||
|
// quit on esc
|
||
|
Some(e) if e.typ == EV_KEY as u32 && e.code == 1 => break,
|
||
|
// mouse event
|
||
|
Some(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();
|
||
|
},
|
||
|
// keyboard event
|
||
|
Some(e) 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.synchronize().unwrap();
|
||
|
},
|
||
|
// balance responsiveness and low cpu load
|
||
|
None => thread::sleep(Duration::from_millis(10)),
|
||
|
// print unknown events
|
||
|
// Some(e) => println!("{} {} {}", e.typ, e.code, e.value),
|
||
|
_ => (),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|