optimize mouse events, refactoring
This commit is contained in:
parent
779947195a
commit
a5de77f321
@ -2,6 +2,7 @@ use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use evdev_rs::util::event_code_to_int;
|
||||
use evdev_rs::enums::EventType::EV_REL;
|
||||
|
||||
use crossbeam::crossbeam_channel::{unbounded, Select, Receiver, Sender};
|
||||
|
||||
@ -27,42 +28,81 @@ pub fn create_evdev_thread(device_path: &str) -> (String, Receiver<ThreadInputEv
|
||||
// sleep for testing purposes
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
|
||||
// cache mouse movement before consuming all events
|
||||
let mut mouse_move = vec![0, 0];
|
||||
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
|
||||
_ => (),
|
||||
},
|
||||
if stop_requested(&recv_stop_channel) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 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,
|
||||
loop {
|
||||
// block before starting while loop again
|
||||
let mut first = true;
|
||||
let mut event = dev.device.next_event(evdev_rs::NORMAL | evdev_rs::BLOCKING);
|
||||
// pending events not required for first round
|
||||
while first || dev.device.has_event_pending() {
|
||||
first = false;
|
||||
match event {
|
||||
// send input event to event channel
|
||||
Ok(e) => {
|
||||
let e = ThreadInputEvent {
|
||||
typ: e.1.event_type as u32,
|
||||
code: event_code_to_int(&e.1.event_code).1,
|
||||
value: e.1.value,
|
||||
};
|
||||
if e.typ == 2 && e.code <= 1 {
|
||||
mouse_move[e.code as usize] += e.value;
|
||||
} else {
|
||||
send_event_channel.send(e).unwrap();
|
||||
}
|
||||
},
|
||||
Err(_) => (),
|
||||
}
|
||||
).unwrap(),
|
||||
Err(_) => (),
|
||||
// read next input event
|
||||
event = dev.device.next_event(evdev_rs::NORMAL | evdev_rs::BLOCKING);
|
||||
}
|
||||
// combined mouse event
|
||||
send_combined_mouse_move(&mut mouse_move, &send_event_channel);
|
||||
// save cpu by sleeping after consuming all events
|
||||
thread::sleep(Duration::from_millis(5));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
(return_device_path, recv_event_channel, send_stop_channel)
|
||||
}
|
||||
|
||||
fn stop_requested(chan: &Receiver<bool>) -> bool {
|
||||
// check for stop requests
|
||||
let mut sel = Select::new();
|
||||
// create stop channel receive operation
|
||||
let oper1 = sel.recv(&chan);
|
||||
// try to select from stop channel
|
||||
let oper = sel.try_select();
|
||||
match oper {
|
||||
// no stop requests
|
||||
Err(_) => false,
|
||||
// stop request received, break out of the loop
|
||||
Ok(oper) => match oper.index() {
|
||||
i if i == oper1 => {
|
||||
oper.recv(&chan).unwrap()
|
||||
},
|
||||
// shouldn't happen
|
||||
_ => false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn send_combined_mouse_move(mouse_move: &mut Vec<i32>, chan: &Sender<ThreadInputEvent>) {
|
||||
// REL_X..=REL_Y
|
||||
for code in 0..=1 {
|
||||
if mouse_move[code] != 0 {
|
||||
chan.send(ThreadInputEvent {
|
||||
typ: EV_REL as u32,
|
||||
code: code as u32,
|
||||
value: mouse_move[code],
|
||||
}).unwrap();
|
||||
mouse_move[code] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ extern crate uinput;
|
||||
extern crate evdev_rs;
|
||||
extern crate crossbeam;
|
||||
|
||||
use std::thread;
|
||||
use std::env::args;
|
||||
use std::time::Duration;
|
||||
use std::collections::HashMap;
|
||||
|
Loading…
Reference in New Issue
Block a user