use std::os::fd::AsFd as _;
use std::time::{Duration, Instant};
use drmkit_input::{
InputEvent, KeyEvent, KeyRepeater, Keyboard, KeymapNames, RepeatConfig, Seat, SeatOptions,
};
use rustix::event::{PollFd, PollFlags, poll};
const KEY_ESC: u32 = 1;
fn main() {
let mut seat = match Seat::open(&SeatOptions::default()) {
Ok(seat) => seat,
Err(error) => {
eprintln!("{error}");
std::process::exit(1);
}
};
let mut keyboard = Keyboard::from_names(&KeymapNames::default()).expect("keymap");
let mut repeater = KeyRepeater::new(RepeatConfig::default()).expect("timer");
let started = Instant::now();
let mut events = Vec::new();
let mut repeats: Vec<KeyEvent> = Vec::new();
let mut leds = keyboard.leds();
loop {
{
let seat_fd = seat.as_fd();
let timer_fd = repeater.fd();
let mut fds = [
PollFd::new(&seat_fd, PollFlags::IN),
PollFd::new(&timer_fd, PollFlags::IN),
];
let timeout = Duration::from_secs(30).try_into().expect("timeout");
if poll(&mut fds, Some(&timeout)).expect("poll") == 0 {
println!("nothing for thirty seconds");
return;
}
}
let now = u32::try_from(started.elapsed().as_millis()).unwrap_or(u32::MAX);
events.clear();
seat.dispatch(&mut events).expect("dispatch");
for event in &mut events {
match event {
InputEvent::Key(key) => {
keyboard.process_key(key);
repeater.on_key(key, keyboard.should_repeat(key.key));
if report(key) {
return;
}
}
other => println!("{other:?}"),
}
}
repeats.clear();
repeater.dispatch(now, &mut repeats).expect("repeat");
for key in &mut repeats {
keyboard.resolve(key);
report(key);
}
let current = keyboard.leds();
if current != leds {
seat.set_leds(current);
leds = current;
}
}
}
fn report(key: &KeyEvent) -> bool {
println!(
"key {:>3} {}{} sym {:#06x} {:?}",
key.key,
if key.pressed { "down" } else { "up " },
if key.repeat { " (repeat)" } else { "" },
key.sym,
key.utf8
);
key.key == KEY_ESC && !key.pressed
}