events async
Signed-off-by: Frank Villaro-Dixon <frank@villaro-dixon.eu>
This commit is contained in:
parent
f5d307e5bc
commit
9d68409a8a
2 changed files with 120 additions and 89 deletions
189
src/hid.rs
189
src/hid.rs
|
@ -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,95 +66,117 @@ 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> {
|
pub fn get_event_nonblocking(&mut self) -> Option<Beo5Event> {
|
||||||
let events = &mut self.device.fetch_events()?;
|
let evts = self.device.fetch_events();
|
||||||
Ok(Beo5DeviceEvents {
|
|
||||||
events: Some(events),
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_event_nonblocking(&mut self) -> Option<Beo5Event> {
|
fn parse_event(ev: evdev::InputEvent) -> Option<Beo5Event> {
|
||||||
if self.events.is_none() {
|
println!("Beosound event: {ev:?}");
|
||||||
self.events = Some(self.device.fetch_events().unwrap());
|
// XXX What happens with the other events in the iterator?
|
||||||
}
|
match ev.kind() {
|
||||||
|
// Look at the beosound 5 kernel module for the correct event codes
|
||||||
for ev in self.events.unwrap().into_iter() {
|
evdev::InputEventKind::RelAxis(axis) => {
|
||||||
println!("Beosound event: {ev:?}");
|
match axis {
|
||||||
// XXX What happens with the other events in the iterator?
|
evdev::RelativeAxisType::REL_Y => {
|
||||||
match ev.kind() {
|
return Some(Beo5Event::SelectionWheelRel(ev.value()));
|
||||||
// Look at the beosound 5 kernel module for the correct event codes
|
|
||||||
evdev::InputEventKind::RelAxis(axis) => {
|
|
||||||
match axis {
|
|
||||||
evdev::RelativeAxisType::REL_Y => {
|
|
||||||
return Some(Beo5Event::SelectionWheelRel(ev.value()));
|
|
||||||
}
|
|
||||||
evdev::RelativeAxisType::REL_Z => {
|
|
||||||
return Some(Beo5Event::VolumeWheelRel(ev.value()));
|
|
||||||
}
|
|
||||||
// Shouldn't be any more relative axe
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
evdev::RelativeAxisType::REL_Z => {
|
||||||
evdev::InputEventKind::AbsAxis(axis) => {
|
return Some(Beo5Event::VolumeWheelRel(ev.value()));
|
||||||
match axis {
|
|
||||||
evdev::AbsoluteAxisType::ABS_X => {
|
|
||||||
let pos_pct = ev.value() as f32 / 255.0;
|
|
||||||
return Some(Beo5Event::LaserPosition(pos_pct));
|
|
||||||
}
|
|
||||||
// Shouldn't be any other absolute axe
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
// Shouldn't be any more relative axe
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
evdev::InputEventKind::Switch(switch) => {
|
|
||||||
/*
|
|
||||||
match switch {
|
|
||||||
evdev::SwitchType::LE=> {
|
|
||||||
if ev.value() == 1 {
|
|
||||||
return Beo5Event::RightButtonPressed;
|
|
||||||
} else {
|
|
||||||
return Beo5Event::RightButtonReleased;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
evdev::Switch::SW_LEFT => {
|
|
||||||
if ev.value() == 1 {
|
|
||||||
return Beo5Event::LeftButtonPressed;
|
|
||||||
} else {
|
|
||||||
return Beo5Event::LeftButtonReleased;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
evdev::Switch::SW_GO => {
|
|
||||||
if ev.value() == 1 {
|
|
||||||
return Beo5Event::GoButtonPressed;
|
|
||||||
} else {
|
|
||||||
return Beo5Event::GoButtonReleased;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
evdev::Switch::SW_POWER => {
|
|
||||||
if ev.value() == 1 {
|
|
||||||
return Beo5Event::PowerButtonPressed;
|
|
||||||
} else {
|
|
||||||
return Beo5Event::PowerButtonReleased;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Shouldn't be any other switches
|
|
||||||
_ => {
|
|
||||||
panic!("Unknown switch event: {ev:?}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
_ => {} //SYN et al
|
|
||||||
}
|
}
|
||||||
return None;
|
evdev::InputEventKind::AbsAxis(axis) => {
|
||||||
|
match axis {
|
||||||
|
evdev::AbsoluteAxisType::ABS_X => {
|
||||||
|
let pos_pct = (ev.value() as f32 / LASER_POINTER_MAX as f32).min(1.0);
|
||||||
|
return Some(Beo5Event::LaserPosition(pos_pct));
|
||||||
|
}
|
||||||
|
// Shouldn't be any other absolute axe
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
evdev::InputEventKind::Switch(switch) => {
|
||||||
|
/*
|
||||||
|
match switch {
|
||||||
|
evdev::SwitchType::LE=> {
|
||||||
|
if ev.value() == 1 {
|
||||||
|
return Beo5Event::RightButtonPressed;
|
||||||
|
} else {
|
||||||
|
return Beo5Event::RightButtonReleased;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
evdev::Switch::SW_LEFT => {
|
||||||
|
if ev.value() == 1 {
|
||||||
|
return Beo5Event::LeftButtonPressed;
|
||||||
|
} else {
|
||||||
|
return Beo5Event::LeftButtonReleased;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
evdev::Switch::SW_GO => {
|
||||||
|
if ev.value() == 1 {
|
||||||
|
return Beo5Event::GoButtonPressed;
|
||||||
|
} else {
|
||||||
|
return Beo5Event::GoButtonReleased;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
evdev::Switch::SW_POWER => {
|
||||||
|
if ev.value() == 1 {
|
||||||
|
return Beo5Event::PowerButtonPressed;
|
||||||
|
} else {
|
||||||
|
return Beo5Event::PowerButtonReleased;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Shouldn't be any other switches
|
||||||
|
_ => {
|
||||||
|
panic!("Unknown switch event: {ev:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
_ => {} //SYN et al
|
||||||
}
|
}
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
20
src/main.rs
20
src/main.rs
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue