diff --git a/src/main.rs b/src/main.rs index 5a97e18..9b7613c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,24 @@ +/*! +# Drum Pedal Keyboard + +Imagine if you will a keyboard made in the image of drum pedals. +Consumers of your input certainly will. + +This program offers boilerplate to allow you to write in Rust simple keyboard macros +for GNU/Linux, utilizing Linux input subsystem userland API, wrapped with +libevdev and evdev-rs libraries. Focusing on simple 'key hold => repeat action' +pattern. + +This program works at the basic keypress level, before any translation into +symbols or meanings takes place. +As such this program requires access to /dev/input and /dev/uinput interfaces. +It can be granted by input and uinput user groups or superuser privileges. + +# Usage + +./dpk [/PATH/TO/INPUT/DEVICE] +*/ + use std::io::Write; //for .flush() #[macro_use] @@ -5,7 +26,10 @@ extern crate lazy_static; mod pedals; +#[doc(hidden)] fn main() -> () { + // Open the requested device. Wrap in into lazy evaluated static + // to share between threads lazy_static! { static ref INPUT_DEVICE: evdev::Device = { let d = pick_device(); @@ -23,6 +47,7 @@ fn main() -> () { ); } +/// Main program flow. fn run( input_device: &'static evdev::Device, output_device: &mut evdev::uinput::VirtualDevice, @@ -30,6 +55,7 @@ fn run( ) { let mut handles: Vec<_> = Vec::new(); let (tx, rx) = std::sync::mpsc::channel(); + // Make a separate thread for each pedal macro for pedal in pedals { let tx = tx.clone(); let handle = std::thread::spawn(move || loop { @@ -50,6 +76,8 @@ fn run( } } +/// Open the device on the path provided in the first cli argument +/// or, if none present, allow user to choose one fn pick_device() -> evdev::Device { let mut args = std::env::args_os(); args.next(); @@ -72,8 +100,11 @@ fn pick_device() -> evdev::Device { } use evdev::{uinput::VirtualDeviceBuilder, AttributeSet, Key}; +/// Create new uinput device to send generated events into +/// Enables explicitly allowed here key press events to be generated fn create_device() -> Result> { let mut keys = AttributeSet::::new(); + // Addtional buttons go here in `keys.insert(evdev::Key)` format keys.insert(Key::KEY_F); keys.insert(Key::KEY_SPACE); keys.insert(Key::BTN_LEFT); @@ -87,6 +118,7 @@ fn create_device() -> Result) -> () + Send + 'static>, diff --git a/src/pedals.rs b/src/pedals.rs index 3b50363..1e29f5f 100644 --- a/src/pedals.rs +++ b/src/pedals.rs @@ -1,6 +1,11 @@ +//! A small collection of key-action pairs. Extandable. Explicit. In Rust. +//! Simply add more Pedal { key, action } structs to the vector. +//! Remember to allow additional buttons, if any, in crate::create_device() + pub use crate::Pedal; use evdev::{EventType, InputEvent, Key}; +/// Returns a vector of currently defined key-action pairs pub fn pedals() -> Vec { vec![ Pedal {