#[cfg(not(target_os = "linux"))]
fn main() {
eprintln!("this needs Linux and evdev");
}
#[cfg(target_os = "linux")]
fn main() -> Result<(), Box<dyn std::error::Error>> {
use std::time::{Duration, Instant};
use denise::{ElementState, InputEvent, InputSource, KeyCode, Modifiers, Size};
use denise_evdev::{InputBackend, layout};
let seconds: u64 = std::env::args()
.nth(1)
.and_then(|a| a.parse().ok())
.unwrap_or(30)
.clamp(1, 600);
let mut input = InputBackend::open_all(Size::new(1280, 800))?;
let (chosen, source) = match std::env::args().nth(2) {
Some(name) => match layout::by_name(layout::normalise_name(&name)) {
Some(layout) => {
input.set_layout(layout);
(layout, layout::LayoutSource::Denise)
}
None => {
eprintln!("no layout called {name:?}; falling back to the system's");
input.set_layout_from_system()
}
},
None => input.set_layout_from_system(),
};
for device in input.devices() {
eprintln!("input {}: {}", device.capabilities(), device.name());
}
eprintln!(
"keymap {} (from {source}) (available: {})",
chosen.name,
layout::BUILT_IN
.iter()
.map(|l| l.name)
.collect::<Vec<_>>()
.join(", ")
);
eprintln!("\npress keys — Escape quits\n");
let deadline = Instant::now() + Duration::from_secs(seconds);
let mut events = Vec::new();
let mut keys = 0u32;
let mut characters = 0u32;
let mut quit = false;
while !quit && Instant::now() < deadline {
events.clear();
input.poll(&mut events);
for event in &events {
match event {
InputEvent::Key {
code,
state: ElementState::Down,
modifiers,
repeat,
} => {
keys += 1;
let mut held = String::new();
for (bit, name) in [
(Modifiers::SHIFT, "shift"),
(Modifiers::CTRL, "ctrl"),
(Modifiers::ALT, "alt"),
(Modifiers::SUPER, "super"),
] {
if modifiers.contains(bit) {
held.push(' ');
held.push_str(name);
}
}
let repeat = if *repeat { " (repeat)" } else { "" };
eprintln!("key {code:?}{held}{repeat}");
if *code == KeyCode::Escape {
quit = true;
}
}
InputEvent::Text { ch } => {
characters += 1;
eprintln!(" --> text {ch:?} U+{:04X}", *ch as u32);
}
_ => {}
}
}
std::thread::sleep(Duration::from_millis(8));
}
eprintln!("\n{keys} key presses produced {characters} characters");
if keys > 0 && characters == 0 {
eprintln!("nothing typed: either the keys pressed are not text keys, or");
eprintln!("the layout above is not the one on the keyboard");
}
Ok(())
}