events async

Signed-off-by: Frank Villaro-Dixon <frank@villaro-dixon.eu>
This commit is contained in:
Frank Villaro-Dixon 2024-05-07 21:02:22 +02:00
parent f5d307e5bc
commit 9d68409a8a
2 changed files with 120 additions and 89 deletions

View file

@ -5,12 +5,14 @@ use nix::{
sys::epoll, sys::epoll,
}; };
use std::{ use std::{
collections::VecDeque,
io, io,
os::fd::{AsRawFd, FromRawFd, OwnedFd}, os::fd::{AsRawFd, FromRawFd, OwnedFd},
}; };
use evdev; use evdev;
const LASER_POINTER_MAX: i32 = 121;
#[derive(Debug)] #[derive(Debug)]
pub enum Beo5Event { pub enum Beo5Event {
LaserPosition(f32), LaserPosition(f32),
@ -28,10 +30,7 @@ pub enum Beo5Event {
pub struct Beo5Device { pub struct Beo5Device {
device: evdev::Device, device: evdev::Device,
} evts_in_queue: VecDeque<evdev::InputEvent>,
pub struct Beo5DeviceEvents<'a> {
events: Option<evdev::FetchEventsSynced<'a>>,
} }
impl Beo5Device { impl Beo5Device {
@ -46,15 +45,17 @@ impl Beo5Device {
); );
// XXX Is there a better way than this into_iter.nth.unwrap ? // XXX Is there a better way than this into_iter.nth.unwrap ?
let mut d = devices.into_iter().nth(i).unwrap(); let mut d = devices.into_iter().nth(i).unwrap();
//println!("Using device: {}", d.name().unwrap());
//println!(">> {}", d.physical_path().unwrap());
// From evdev's example
let raw_fd = d.as_raw_fd(); let raw_fd = d.as_raw_fd();
d.grab().unwrap();
// Set nonblocking // Set nonblocking
nix::fcntl::fcntl(raw_fd, FcntlArg::F_SETFL(OFlag::O_NONBLOCK)); //("Couldn't set nonblocking"); nix::fcntl::fcntl(raw_fd, FcntlArg::F_SETFL(OFlag::O_NONBLOCK)).unwrap();
// Create epoll handle and attach raw_fd // Create epoll handle and attach raw_fd
//let epoll_fd = epoll::epoll_create1(epoll::EpollCreateFlags::EPOLL_CLOEXEC)?;
let epoll_fd = epoll::epoll_create1(epoll::EpollCreateFlags::EPOLL_CLOEXEC).ok()?; let epoll_fd = epoll::epoll_create1(epoll::EpollCreateFlags::EPOLL_CLOEXEC).ok()?;
println!("epoll_fd: {epoll_fd}.");
let epoll_fd = unsafe { OwnedFd::from_raw_fd(epoll_fd) }; let epoll_fd = unsafe { OwnedFd::from_raw_fd(epoll_fd) };
let mut event = epoll::EpollEvent::new(epoll::EpollFlags::EPOLLIN, 0); let mut event = epoll::EpollEvent::new(epoll::EpollFlags::EPOLLIN, 0);
epoll::epoll_ctl( epoll::epoll_ctl(
@ -65,28 +66,52 @@ impl Beo5Device {
) )
.unwrap(); .unwrap();
//let events = d.fetch_events().unwrap(); //loop {}
return Some(Beo5Device { device: d }); return Some(Beo5Device {
device: d,
evts_in_queue: VecDeque::new(),
});
} }
} }
println!("Couldn't find a Beosound 5 device! Is the Beosound 5 kernel module loaded + device connected?"); println!("Couldn't find a Beosound 5 device! Is the Beosound 5 kernel module loaded + device connected?");
None None
} }
pub fn fetch_events(&self) -> io::Result<Beo5DeviceEvents> {
let events = &mut self.device.fetch_events()?;
Ok(Beo5DeviceEvents {
events: Some(events),
})
}
pub fn get_event_nonblocking(&mut self) -> Option<Beo5Event> { pub fn get_event_nonblocking(&mut self) -> Option<Beo5Event> {
if self.events.is_none() { let evts = self.device.fetch_events();
self.events = Some(self.device.fetch_events().unwrap());
match evts {
Ok(evts) => {
println!("Will iterate!");
for ev in evts {
match ev.kind() {
evdev::InputEventKind::Synchronization(_) => {}
_ => {
self.evts_in_queue.push_back(ev);
}
}
}
}
Err(x) => {
if (x.kind() == std::io::ErrorKind::WouldBlock) {
// Wait forever for bytes available on raw_fd
let mut events = [epoll::EpollEvent::empty(); 2];
epoll::epoll_wait(8, &mut events, -1);
} else {
println!("Error getting event: {x} - {}", x.kind());
//panic!("Error getting event: {x}");
}
}
}
let ev = self.evts_in_queue.pop_front();
if ev.is_some() {
return Beo5Device::parse_event(ev.unwrap());
}
return None;
} }
for ev in self.events.unwrap().into_iter() { fn parse_event(ev: evdev::InputEvent) -> Option<Beo5Event> {
println!("Beosound event: {ev:?}"); println!("Beosound event: {ev:?}");
// XXX What happens with the other events in the iterator? // XXX What happens with the other events in the iterator?
match ev.kind() { match ev.kind() {
@ -106,7 +131,7 @@ impl Beo5Device {
evdev::InputEventKind::AbsAxis(axis) => { evdev::InputEventKind::AbsAxis(axis) => {
match axis { match axis {
evdev::AbsoluteAxisType::ABS_X => { evdev::AbsoluteAxisType::ABS_X => {
let pos_pct = ev.value() as f32 / 255.0; let pos_pct = (ev.value() as f32 / LASER_POINTER_MAX as f32).min(1.0);
return Some(Beo5Event::LaserPosition(pos_pct)); return Some(Beo5Event::LaserPosition(pos_pct));
} }
// Shouldn't be any other absolute axe // Shouldn't be any other absolute axe
@ -155,6 +180,4 @@ impl Beo5Device {
} }
return None; return None;
} }
return None;
}
} }

View file

@ -51,7 +51,7 @@ fn run(
let beo = ui::Beo::new(); let beo = ui::Beo::new();
for app in &beo.apps { for app in &beo.apps {
println!("{}", app.name()); println!(">> {}", app.name());
} }
let start = Instant::now(); let start = Instant::now();
@ -65,15 +65,16 @@ fn run(
let mut font_texture_to_show: Option<usize> = None; let mut font_texture_to_show: Option<usize> = None;
let mut beo_device = hid::Beo5Device::new_autodiscover().expect("Couldn't find Beo5 device"); let mut beo_device = hid::Beo5Device::new_autodiscover().expect("Couldn't find Beo5 device");
/*
loop { loop {
if let Some(ev) = beo_device.get_event_nonblocking() { let ev = beo_device.get_event_nonblocking();
println!("HW Event: {:?}", ev);
} else {
break;
}
} }
*/
let mut t = 0;
el.run(move |event, _, control_flow| { el.run(move |event, _, control_flow| {
t = t + 1;
*control_flow = ControlFlow::Poll; *control_flow = ControlFlow::Poll;
let hw_event = beo_device.get_event_nonblocking(); let hw_event = beo_device.get_event_nonblocking();
@ -162,6 +163,13 @@ fn run(
perf.update(dt); perf.update(dt);
draw_main_menu(&mut canvas, &fonts, &beo); draw_main_menu(&mut canvas, &fonts, &beo);
let mut paint = Paint::color(Color::hex("B7410E"));
paint.set_font(&[fonts.bold]);
paint.set_text_baseline(Baseline::Top);
paint.set_text_align(Align::Right);
let _ = canvas.fill_text(size.width as f32 - 10.0, 10.0, format!("{t}"), &paint);
/* /*
draw_baselines(&mut canvas, &fonts, 5.0, 50.0, font_size); draw_baselines(&mut canvas, &fonts, 5.0, 50.0, font_size);
draw_alignments(&mut canvas, &fonts, 120.0, 200.0, font_size); draw_alignments(&mut canvas, &fonts, 120.0, 200.0, font_size);