Add Device::send_event and RawDevice::send_event.

Some devices (such as keyboards) support writing events through event nodes to
turn LEDs off and on, play sound effects or play ff effects.
This commits adds the appropriate methods in the public API of the crate.

I also added an example to showcase the new functionality.
This commit is contained in:
Nicolas Koch 2021-12-05 19:25:15 +01:00
parent 898bb5c27a
commit 16810308e4
3 changed files with 57 additions and 0 deletions

View file

@ -0,0 +1,31 @@
use evdev::{EventType, InputEvent, LedType};
mod _pick_device;
fn main() {
let mut d = _pick_device::pick_device();
println!("{}", d);
println!("Blinking the Keyboard LEDS...");
for i in 0..5 {
let on = i % 2 != 0;
d.send_event(&InputEvent::new(
EventType::LED,
LedType::LED_CAPSL.0,
if on { i32::MAX } else { 0 },
))
.unwrap();
d.send_event(&InputEvent::new(
EventType::LED,
LedType::LED_NUML.0,
if on { i32::MAX } else { 0 },
))
.unwrap();
d.send_event(&InputEvent::new(
EventType::LED,
LedType::LED_SCROLLL.0,
if on { i32::MAX } else { 0 },
))
.unwrap();
std::thread::sleep(std::time::Duration::from_secs(1));
}
}

View file

@ -610,6 +610,22 @@ impl RawDevice {
} }
Ok(()) Ok(())
} }
/// Send an event to the device.
///
/// Events that are typically sent to devices are
/// [EventType::LED] (turn device LEDs on and off),
/// [EventType::SOUND] (play a sound on the device)
/// and [EventType::FORCEFEEDBACK] (play force feedback events on the device, i.e. rumble).
pub fn send_event(&mut self, event: &InputEvent) -> io::Result<()> {
let raw_event = event.as_ref();
let bytes_written = unsafe {
let buf = crate::cast_to_bytes(raw_event);
nix::unistd::write(self.as_raw_fd(), buf)?
};
debug_assert_eq!(bytes_written, mem::size_of_val(raw_event));
Ok(())
}
} }
impl AsRawFd for RawDevice { impl AsRawFd for RawDevice {

View file

@ -342,6 +342,16 @@ impl Device {
pub fn ungrab(&mut self) -> io::Result<()> { pub fn ungrab(&mut self) -> io::Result<()> {
self.raw.ungrab() self.raw.ungrab()
} }
/// Send an event to the device.
///
/// Events that are typically sent to devices are
/// [EventType::LED] (turn device LEDs on and off),
/// [EventType::SOUND] (play a sound on the device)
/// and [EventType::FORCEFEEDBACK] (play force feedback events on the device, i.e. rumble).
pub fn send_event(&mut self, event: &InputEvent) -> io::Result<()> {
self.raw.send_event(event)
}
} }
impl AsRawFd for Device { impl AsRawFd for Device {