i really should organise my commits better lmao
This commit is contained in:
parent
99d0aa6350
commit
374e96d231
4 changed files with 177 additions and 0 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -8,3 +8,8 @@ Cargo.lock
|
||||||
|
|
||||||
# These are backup files generated by rustfmt
|
# These are backup files generated by rustfmt
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
|
||||||
|
|
||||||
|
# Added by cargo
|
||||||
|
|
||||||
|
/target
|
||||||
|
|
78
src/main.rs
Normal file
78
src/main.rs
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
use std::sync::{Arc, mpsc, Mutex};
|
||||||
|
use std::sync::mpsc::Receiver;
|
||||||
|
use std::thread;
|
||||||
|
use evdev::{Device, enumerate, InputEvent};
|
||||||
|
use crate::modifiers::ModifierStates;
|
||||||
|
use crate::virt_kb::VirtKb;
|
||||||
|
|
||||||
|
mod modifiers;
|
||||||
|
mod virt_kb;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let devices = enumerate();
|
||||||
|
let kb_name = "py-evdev-uinput";
|
||||||
|
|
||||||
|
let mut kbs = {
|
||||||
|
let mut r = Vec::new();
|
||||||
|
|
||||||
|
for dev in devices {
|
||||||
|
if let Some(keyboard) = dev.name() {
|
||||||
|
if keyboard == kb_name {
|
||||||
|
r.push(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
let virt_kb = VirtKb::new(&kbs);
|
||||||
|
let mod_states = ModifierStates::new();
|
||||||
|
|
||||||
|
let reader = KeyReader::new(kbs);
|
||||||
|
let event_receiver = reader.init();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct KeyReader {
|
||||||
|
keyboards: Arc<Mutex<Vec<Device>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeyReader {
|
||||||
|
pub fn new(kbs: Vec<Device>) -> Self {
|
||||||
|
let mut kbs = kbs;
|
||||||
|
|
||||||
|
for kb in kbs.iter_mut() {
|
||||||
|
match kb.grab() {
|
||||||
|
Ok(_) => println!("Keyboard {} grabbed!", kb.name().get_or_insert("[Unnamed]")),
|
||||||
|
Err(_) => println!("Failed to grab keyboard {}.", kb.name().get_or_insert("[Unnamed]")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Self { keyboards: Arc::new(Mutex::new(kbs)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(&self) -> Receiver<Vec<InputEvent>>{
|
||||||
|
let (tx, rx) = mpsc::channel();
|
||||||
|
|
||||||
|
let keyboards = self.keyboards.clone();
|
||||||
|
thread::spawn(move || {
|
||||||
|
let mut kbs_locked = keyboards.lock().unwrap();
|
||||||
|
loop {
|
||||||
|
for kb in kbs_locked.iter_mut() {
|
||||||
|
let mut events = kb
|
||||||
|
.fetch_events()
|
||||||
|
.unwrap()
|
||||||
|
.collect::<Vec<InputEvent>>();
|
||||||
|
|
||||||
|
tx.send(events)
|
||||||
|
.expect("Couldn't send keyboard events from reader to main thread.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
rx
|
||||||
|
}
|
||||||
|
}
|
57
src/modifiers.rs
Normal file
57
src/modifiers.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
use evdev::{InputEvent, Key};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ModifierStates {
|
||||||
|
ctrl: bool,
|
||||||
|
alt: bool,
|
||||||
|
shift: bool,
|
||||||
|
meta: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModifierStates {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
ModifierStates {
|
||||||
|
ctrl: false,
|
||||||
|
alt: false,
|
||||||
|
shift: false,
|
||||||
|
meta: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn update(&mut self, event: InputEvent) {
|
||||||
|
let code = event.code();
|
||||||
|
let val = event.value();
|
||||||
|
|
||||||
|
self.update_ctrl(code, val);
|
||||||
|
self.update_alt(code, val);
|
||||||
|
self.update_shift(code, val);
|
||||||
|
self.update_meta(code, val);
|
||||||
|
}
|
||||||
|
pub fn mod_pressed(&self) -> bool {
|
||||||
|
self.ctrl || self.alt || self.shift || self.meta
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_ctrl(&mut self, code: u16, val: i32) {
|
||||||
|
if code == Key::KEY_LEFTCTRL.code() || code == Key::KEY_RIGHTCTRL.code() {
|
||||||
|
self.ctrl = val != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_alt(&mut self, code: u16, val: i32) {
|
||||||
|
if code == Key::KEY_LEFTALT.code() || code == Key::KEY_RIGHTALT.code() {
|
||||||
|
self.ctrl = val != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_shift(&mut self, code: u16, val: i32) {
|
||||||
|
if code == Key::KEY_LEFTSHIFT.code() || code == Key::KEY_RIGHTSHIFT.code() {
|
||||||
|
self.ctrl = val != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_meta(&mut self, code: u16, val: i32) {
|
||||||
|
if code == Key::KEY_LEFTMETA.code() || code == Key::KEY_RIGHTMETA.code() {
|
||||||
|
self.ctrl = val != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
37
src/virt_kb.rs
Normal file
37
src/virt_kb.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
use std::sync::mpsc;
|
||||||
|
use std::sync::mpsc::{Sender, SendError};
|
||||||
|
use std::thread;
|
||||||
|
use evdev::{Device, InputEvent};
|
||||||
|
use evdev::uinput::VirtualDeviceBuilder;
|
||||||
|
|
||||||
|
pub struct VirtKb {
|
||||||
|
tx: Sender<Vec<InputEvent>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VirtKb {
|
||||||
|
pub fn new(physical_kbs: &Vec<Device>) -> Self {
|
||||||
|
let (tx, rx) = mpsc::channel::<Vec<InputEvent>>();
|
||||||
|
|
||||||
|
let mut virt_kb_builder = VirtualDeviceBuilder::new()
|
||||||
|
.expect("Failed to create UInput device")
|
||||||
|
.name("EasyMacros");
|
||||||
|
|
||||||
|
for phys_kb in physical_kbs {
|
||||||
|
virt_kb_builder = virt_kb_builder.with_keys(phys_kb.supported_keys().unwrap()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut virt_kb = virt_kb_builder.build().expect("Failed to build virt_kb");
|
||||||
|
|
||||||
|
thread::spawn(move || {
|
||||||
|
for received in rx {
|
||||||
|
virt_kb.emit(&received).expect("Virtual keyboard failed to send events");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self { tx }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_events(&self, events: Vec<InputEvent>) -> Result<(), SendError<Vec<InputEvent>>> {
|
||||||
|
self.tx.send(events)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue