evdevil/evdev.rs
1use std::{
2 error::Error,
3 ffi::{c_char, c_int, c_uint, c_void},
4 fmt,
5 fs::File,
6 io::{self, Read as _, Write},
7 mem::{self, MaybeUninit},
8 os::{
9 fd::{AsFd, AsRawFd, IntoRawFd},
10 unix::prelude::{BorrowedFd, RawFd},
11 },
12 path::{Path, PathBuf},
13 slice,
14 time::Instant,
15};
16
17use libc::clockid_t;
18use uoctl::Ioctl;
19
20use crate::{
21 AbsInfo, InputProp, KeyRepeat, KeymapEntry, Version,
22 bits::{BitSet, BitValue, Word},
23 event::{
24 Abs, EventType, ForceFeedbackEvent, InputEvent, Key, Led, LedEvent, Misc, Rel, Sound,
25 Switch,
26 },
27 ff,
28 input_id::InputId,
29 keymap_entry::Scancode,
30 raw::input::{
31 EVIOCGABS, EVIOCGBIT, EVIOCGEFFECTS, EVIOCGID, EVIOCGKEY, EVIOCGKEYCODE_V2, EVIOCGLED,
32 EVIOCGMASK, EVIOCGNAME, EVIOCGPHYS, EVIOCGPROP, EVIOCGRAB, EVIOCGREP, EVIOCGSND, EVIOCGSW,
33 EVIOCGUNIQ, EVIOCGVERSION, EVIOCREVOKE, EVIOCRMFF, EVIOCSABS, EVIOCSCLOCKID, EVIOCSFF,
34 EVIOCSKEYCODE_V2, EVIOCSMASK, EVIOCSREP, INPUT_KEYMAP_BY_INDEX, input_mask,
35 },
36 reader::EventReader,
37 util::{block_until_readable, is_readable, set_nonblocking},
38};
39
40/// A handle to an *event device*.
41///
42/// A device can be opened via [`Evdev::open`] or by iterating over all evdev devices using
43/// [`enumerate`] or [`enumerate_hotplug`].
44///
45/// [`Evdev`]s support non-blocking I/O for reading and writing events (but not for any
46/// functionality that uses ioctls), which can be enabled or disabled by calling
47/// [`Evdev::set_nonblocking`].
48///
49/// Just like [`File`]s, [`TcpStream`]s, and other wrappers around file descriptors, [`Evdev`] can
50/// be duplicated by calling [`Evdev::try_clone`]. The underlying handle will be shared between
51/// all cloned instances.
52///
53/// Since multiple [`Evdev`]s can refer to the same file handle, none of the methods require a
54/// mutable reference, again mirroring the API of [`TcpStream`].
55///
56/// [`TcpStream`]: std::net::TcpStream
57/// [`enumerate`]: crate::enumerate()
58/// [`enumerate_hotplug`]: crate::enumerate_hotplug
59#[derive(Debug)]
60pub struct Evdev {
61 pub(crate) file: File,
62 path: PathBuf,
63}
64
65impl AsFd for Evdev {
66 #[inline]
67 fn as_fd(&self) -> BorrowedFd<'_> {
68 // Safety: we own the fd, so this lifetime constrains it properly
69 unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
70 }
71}
72
73impl AsRawFd for Evdev {
74 #[inline]
75 fn as_raw_fd(&self) -> RawFd {
76 self.file.as_raw_fd()
77 }
78}
79
80impl IntoRawFd for Evdev {
81 #[inline]
82 fn into_raw_fd(self) -> RawFd {
83 self.file.into_raw_fd()
84 }
85}
86
87impl Evdev {
88 /// Opens a filesystem path referring to an `evdev` node.
89 ///
90 /// The path must belong to an `evdev` device like `/dev/input/event*`, not to a legacy
91 /// *"joydev"* device (`/dev/input/js`) and not to a legacy *"mousedev"* (`/dev/input/mouse` or
92 /// `/dev/input/mice`).
93 ///
94 /// # Permissions
95 ///
96 /// This method will attempt to open `path` with read-write permissions (allowing methods based
97 /// on [`Evdev::write`] to work), fall back to read-only permissions if the current user
98 /// does not have read and write permissions, and finally fall back to write-only permissions.
99 ///
100 /// If all of these attempts fail with a [`io::ErrorKind::PermissionDenied`] error, this method
101 /// will return that error to the caller.
102 ///
103 /// # Errors
104 ///
105 /// This method will return an error if `path` doesn't refer to a path matching
106 /// `/dev/input/event*` (after resolving symlinks).
107 pub fn open<P: AsRef<Path>>(path: P) -> io::Result<Self> {
108 let path = path.as_ref();
109 Self::open_impl(path)
110 }
111
112 fn open_impl(path: &Path) -> io::Result<Self> {
113 let path = path.canonicalize()?;
114 if !path
115 .as_os_str()
116 .as_encoded_bytes()
117 .starts_with(b"/dev/input/event")
118 {
119 return Err(io::Error::new(
120 io::ErrorKind::InvalidInput,
121 format!(
122 "evdev device path '{}' must match '/dev/input/event*'",
123 path.display()
124 ),
125 ));
126 }
127
128 Self::open_unchecked(path)
129 }
130
131 /// Opens `path` without checking that it is one of the `/dev/input/event*` paths.
132 pub(crate) fn open_unchecked(path: PathBuf) -> io::Result<Self> {
133 let now = Instant::now();
134
135 let file = match Self::try_open(&path) {
136 Ok(file) => file,
137 Err(e) => {
138 return Err(io::Error::new(
139 e.kind(),
140 format!("failed to open '{}': {e}", path.display()),
141 ));
142 }
143 };
144 let this = Self { file, path };
145 let version = this.driver_version()?;
146 log::debug!(
147 "opened '{}' in {:?}; driver version {version}",
148 this.path().display(),
149 now.elapsed(),
150 );
151 Ok(this)
152 }
153
154 fn try_open(path: &Path) -> io::Result<File> {
155 match File::options().read(true).write(true).open(path) {
156 Ok(file) => return Ok(file),
157 Err(e) if e.kind() == io::ErrorKind::PermissionDenied => {
158 log::warn!(
159 "no permission to open '{}' in read-write mode, retrying in read-only",
160 path.display()
161 );
162 }
163 Err(e) => return Err(e),
164 }
165
166 match File::options().read(true).open(path) {
167 Ok(file) => return Ok(file),
168 Err(e) if e.kind() == io::ErrorKind::PermissionDenied => {
169 log::warn!(
170 "no permission to open '{}' in read-only mode, retrying in write-only",
171 path.display()
172 );
173 }
174 Err(e) => return Err(e),
175 }
176
177 File::options().write(true).open(path)
178 }
179
180 /// Returns the (canonicalized) file system path this [`Evdev`] has been created from.
181 pub fn path(&self) -> &Path {
182 &self.path
183 }
184
185 /// Moves this handle into or out of non-blocking mode.
186 ///
187 /// Returns whether the [`Evdev`] was previously in non-blocking mode.
188 ///
189 /// [`Evdev`]s start out in *blocking* mode, in which every attempt to read from the device
190 /// (either via [`Evdev::raw_events`] or via [`EventReader`]) will *block* until the next event
191 /// is available.
192 ///
193 /// If the [`Evdev`] is put in non-blocking mode, attempts to read from it will no longer block,
194 /// but instead fail with [`io::ErrorKind::WouldBlock`].
195 ///
196 /// This mechanism, alongside the [`AsRawFd`] impl, can be used to integrate [`Evdev`] into an
197 /// `async` runtime. It can also be used by applications that want to occasionally retrieve all
198 /// the device state, but don't want to block until new events are available (eg. games).
199 ///
200 /// **Note**: Non-blocking mode only works for reading and writing *events*. It does not work
201 /// for any of the other device functionality, like force-feedback effect upload, which will
202 /// always block.
203 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<bool> {
204 set_nonblocking(self.as_raw_fd(), nonblocking)
205 }
206
207 /// Creates a new [`Evdev`] instance that refers to the same underlying file handle.
208 ///
209 /// All state of the [`Evdev`] will be shared between the instances.
210 ///
211 /// **Note**: Care must be taken when using this method.
212 /// Functionality in this crate (like [`EventReader`]) may assume that no other file handle is
213 /// used to modify device state or read events from it.
214 pub fn try_clone(&self) -> io::Result<Self> {
215 Ok(Self {
216 file: self.file.try_clone()?,
217 path: self.path.clone(),
218 })
219 }
220
221 /// Executes `ioctl` and adds context to the error.
222 pub(crate) unsafe fn ioctl<T>(
223 &self,
224 name: &'static str,
225 ioctl: Ioctl<T>,
226 arg: T,
227 ) -> io::Result<c_int> {
228 match unsafe { ioctl.ioctl(self, arg) } {
229 Ok(ok) => Ok(ok),
230 Err(e) => {
231 #[derive(Debug)]
232 struct WrappedError {
233 cause: io::Error,
234 msg: String,
235 }
236
237 impl fmt::Display for WrappedError {
238 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
239 f.write_str(&self.msg)
240 }
241 }
242 impl Error for WrappedError {
243 fn source(&self) -> Option<&(dyn Error + 'static)> {
244 Some(&self.cause)
245 }
246 }
247
248 let msg = format!(
249 "ioctl {name} failed for device {} ({:?})",
250 self.path().display(),
251 e.kind()
252 );
253 Err(io::Error::new(e.kind(), WrappedError { cause: e, msg }))
254 }
255 }
256 }
257
258 unsafe fn fetch_string(
259 &self,
260 ioctl_name: &'static str,
261 ioctl: fn(usize) -> Ioctl<*mut c_char>,
262 ) -> io::Result<String> {
263 // "fetch string" ioctls will return the number of bytes they've copied into our buffer.
264 // This will be at most the length of the buffer. If that happens, some bytes might be lost,
265 // so we retry the call after doubling the buffer size.
266
267 const INITIAL_LEN: usize = 64;
268 let mut buf = vec![0_u8; INITIAL_LEN];
269 let len = loop {
270 let len = unsafe {
271 self.ioctl(
272 ioctl_name,
273 ioctl(buf.len()),
274 buf.as_mut_ptr() as *mut c_char,
275 )?
276 };
277 if len as usize == buf.len() {
278 // Not enough space; double the buffer size and retry.
279 buf.resize(buf.len() * 2, 0);
280 } else {
281 break len;
282 }
283 };
284
285 // `len` includes the trailing 0 byte
286 buf.truncate(len.saturating_sub(1) as usize);
287
288 let string =
289 String::from_utf8(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
290 Ok(string)
291 }
292
293 unsafe fn fetch_bits<V: BitValue>(
294 &self,
295 ioctl_name: &'static str,
296 ioctl: fn(usize) -> Ioctl<*mut c_void>,
297 ) -> io::Result<BitSet<V>> {
298 let mut set = BitSet::<V>::new();
299 let words = set.words_mut();
300 unsafe {
301 self.ioctl(
302 ioctl_name,
303 ioctl(words.len() * mem::size_of::<Word>()),
304 words.as_mut_ptr().cast(),
305 )?;
306 };
307 Ok(set)
308 }
309
310 /// Returns the evdev subsystem version.
311 pub fn driver_version(&self) -> io::Result<Version> {
312 unsafe {
313 let mut version = 0;
314 self.ioctl("EVIOCGVERSION", EVIOCGVERSION, &mut version)?;
315 Ok(Version(version))
316 }
317 }
318
319 /// Fetches device hardware information as an [`InputId`].
320 pub fn input_id(&self) -> io::Result<InputId> {
321 let mut out = MaybeUninit::uninit();
322 unsafe {
323 self.ioctl("EVIOCGID", EVIOCGID, out.as_mut_ptr())?;
324 Ok(InputId(out.assume_init()))
325 }
326 }
327
328 /// Fetches the device name.
329 pub fn name(&self) -> io::Result<String> {
330 unsafe { self.fetch_string("EVIOCGNAME", EVIOCGNAME) }
331 }
332
333 /// Fetches a string describing the physical location of the device.
334 ///
335 /// Possible location strings might look like:
336 /// - `usb-0000:02:00.0-5/input1`
337 /// - `PNP0C0C/button/input0`
338 /// - `ALSA`
339 ///
340 /// Returns [`None`] when the device does not have a physical location (typically because it is
341 /// a virtual device with no associated physical location; however, virtual device *are* allowed
342 /// to set this value to any string).
343 pub fn phys(&self) -> io::Result<Option<String>> {
344 unsafe {
345 match self.fetch_string("EVIOCGPHYS", EVIOCGPHYS) {
346 Ok(loc) => Ok(Some(loc)),
347 Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(None),
348 Err(e) => Err(e),
349 }
350 }
351 }
352
353 /// Fetches the unique identifier of this device.
354 ///
355 /// For USB device, this is typically the device serial number (`iSerial`), which is often just
356 /// the empty string.
357 pub fn unique_id(&self) -> io::Result<Option<String>> {
358 unsafe {
359 match self.fetch_string("EVIOCGUNIQ", EVIOCGUNIQ) {
360 Ok(loc) => Ok(Some(loc)),
361 Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(None),
362 Err(e) => Err(e),
363 }
364 }
365 }
366
367 /// Fetches the set of [`InputProp`]s advertised by the device.
368 pub fn props(&self) -> io::Result<BitSet<InputProp>> {
369 unsafe { self.fetch_bits("EVIOCGPROP", EVIOCGPROP) }
370 }
371
372 /// Returns the set of supported [`EventType`]s.
373 pub fn supported_events(&self) -> io::Result<BitSet<EventType>> {
374 unsafe { self.fetch_bits("EVIOCGBIT", |len| EVIOCGBIT(0, len)) }
375 }
376
377 /// Returns the set of supported [`Key`]s.
378 pub fn supported_keys(&self) -> io::Result<BitSet<Key>> {
379 unsafe { self.fetch_bits("EVIOCGBIT", |len| EVIOCGBIT(EventType::KEY.0 as u8, len)) }
380 }
381
382 /// Returns the set of supported [`Switch`]es.
383 pub fn supported_switches(&self) -> io::Result<BitSet<Switch>> {
384 unsafe { self.fetch_bits("EVIOCGBIT", |len| EVIOCGBIT(EventType::SW.0 as u8, len)) }
385 }
386
387 /// Returns the set of supported [`Led`]s.
388 pub fn supported_leds(&self) -> io::Result<BitSet<Led>> {
389 unsafe { self.fetch_bits("EVIOCGBIT", |len| EVIOCGBIT(EventType::LED.0 as u8, len)) }
390 }
391
392 /// Returns the set of supported [`Sound`]s.
393 pub fn supported_sounds(&self) -> io::Result<BitSet<Sound>> {
394 unsafe { self.fetch_bits("EVIOCGBIT", |len| EVIOCGBIT(EventType::SND.0 as u8, len)) }
395 }
396
397 /// Returns the set of supported [`Misc`] event codes.
398 pub fn supported_misc(&self) -> io::Result<BitSet<Misc>> {
399 unsafe { self.fetch_bits("EVIOCGBIT", |len| EVIOCGBIT(EventType::MSC.0 as u8, len)) }
400 }
401
402 /// Returns the set of supported [`Rel`] axes.
403 pub fn supported_rel_axes(&self) -> io::Result<BitSet<Rel>> {
404 unsafe { self.fetch_bits("EVIOCGBIT", |len| EVIOCGBIT(EventType::REL.0 as u8, len)) }
405 }
406
407 /// Returns the set of supported [`Abs`] axes.
408 pub fn supported_abs_axes(&self) -> io::Result<BitSet<Abs>> {
409 unsafe { self.fetch_bits("EVIOCGBIT", |len| EVIOCGBIT(EventType::ABS.0 as u8, len)) }
410 }
411
412 /// Returns the set of supported force-feedback [`Feature`][ff::Feature]s.
413 pub fn supported_ff_features(&self) -> io::Result<BitSet<ff::Feature>> {
414 unsafe { self.fetch_bits("EVIOCGBIT", |len| EVIOCGBIT(EventType::FF.0 as u8, len)) }
415 }
416
417 /// Returns the number of force-feedback effects the device can store at the same time.
418 pub fn supported_ff_effects(&self) -> io::Result<u32> {
419 unsafe {
420 let mut out = 0;
421 self.ioctl("EVIOCGEFFECTS", EVIOCGEFFECTS, &mut out)?;
422 Ok(out.try_into().unwrap())
423 }
424 }
425
426 /// Returns information about absolute axis `abs`.
427 ///
428 /// The supported absolute axes can be queried by calling [`Evdev::supported_abs_axes`].
429 ///
430 /// Calling this with an [`Abs`] axis that isn't supported by the device will either return an
431 /// error or return a meaningless [`AbsInfo`] object with arbitrary values.
432 ///
433 /// Note that many devices don't send the correct values by default, and that userspace
434 /// applications can generally override these values via [`Evdev::set_abs_info`].
435 pub fn abs_info(&self, abs: Abs) -> io::Result<AbsInfo> {
436 if abs.0 > Abs::MAX.0 {
437 return Err(io::Error::new(
438 io::ErrorKind::InvalidInput,
439 format!("absolute axis {:?} exceeds maximum axis value", abs),
440 ));
441 }
442
443 unsafe {
444 let mut out = MaybeUninit::uninit();
445 self.ioctl("EVIOCGABS", EVIOCGABS(abs.0 as u8), out.as_mut_ptr())?;
446 Ok(AbsInfo(out.assume_init()))
447 }
448 }
449
450 /// Sets the [`AbsInfo`] data associated with absolute axis `abs`.
451 ///
452 /// The supported absolute axes can be queried by calling [`Evdev::supported_abs_axes`].
453 ///
454 /// This method should generally not be used by applications, as it modifies globally visible
455 /// device properties and can lead to the device not working correctly.
456 pub fn set_abs_info(&self, abs: Abs, info: AbsInfo) -> io::Result<()> {
457 if abs.0 > Abs::MAX.0 {
458 return Err(io::Error::new(
459 io::ErrorKind::InvalidInput,
460 format!("absolute axis {:?} exceeds maximum axis value", abs),
461 ));
462 }
463
464 unsafe {
465 self.ioctl("EVIOCSABS", EVIOCSABS(abs.raw() as u8), &info.0)?;
466 }
467 Ok(())
468 }
469
470 /// Grabs this input device, making its events unavailable to other programs.
471 ///
472 /// This can be undone by calling [`Evdev::ungrab`]. The kernel will automatically *ungrab* a
473 /// grabbed device when the program closes its file descriptor.
474 ///
475 /// # Errors
476 ///
477 /// This will return an error of type [`io::ErrorKind::ResourceBusy`] if the device is already
478 /// grabbed by an application (including *this* application; in other words, calling `grab()`
479 /// twice in a row will error).
480 pub fn grab(&self) -> io::Result<()> {
481 unsafe {
482 self.ioctl("EVIOCGRAB", EVIOCGRAB, 1)?;
483 Ok(())
484 }
485 }
486
487 /// Ungrabs this input device, making its events available to other programs again.
488 ///
489 /// Undoes the effect of [`Evdev::grab`].
490 ///
491 /// # Errors
492 ///
493 /// This will return an error of type [`io::ErrorKind::InvalidInput`] is the device is **not**
494 /// currently grabbed.
495 pub fn ungrab(&self) -> io::Result<()> {
496 unsafe {
497 self.ioctl("EVIOCGRAB", EVIOCGRAB, 0)?;
498 Ok(())
499 }
500 }
501
502 /// Revokes device access from this [`Evdev`] handle.
503 ///
504 /// This prevents this handle from receiving any more input events, and makes writes and ioctls
505 /// (including this one) fail with `ENODEV`.
506 pub fn revoke(&self) -> io::Result<()> {
507 unsafe {
508 self.ioctl("EVIOCREVOKE", EVIOCREVOKE, 0)?;
509 Ok(())
510 }
511 }
512
513 /// Queries the current autorepeat settings.
514 ///
515 /// If the device doesn't support key repeat, this will return `Ok(None)`.
516 /// Whether key repeat is supported can also be determined by checking whether
517 /// [`EventType::REP`] is advertised by [`Evdev::supported_events`].
518 pub fn key_repeat(&self) -> io::Result<Option<KeyRepeat>> {
519 unsafe {
520 let mut rep = [0; 2];
521 match self.ioctl("EVIOCGREP", EVIOCGREP, &mut rep) {
522 Ok(_) => Ok(Some(KeyRepeat {
523 delay: rep[0] as u32,
524 period: rep[1] as u32,
525 })),
526 Err(e) if e.kind() == io::ErrorKind::Unsupported => Ok(None),
527 Err(e) => Err(e),
528 }
529 }
530 }
531
532 /// Sets the device's autorepeat settings.
533 ///
534 /// Also see [`Evdev::key_repeat`].
535 pub fn set_key_repeat(&self, rep: KeyRepeat) -> io::Result<()> {
536 unsafe {
537 let rep = [rep.delay() as c_uint, rep.period() as c_uint];
538 self.ioctl("EVIOCSREP", EVIOCSREP, &rep)?;
539 Ok(())
540 }
541 }
542
543 /// Queries a keymap entry by its associated [`Scancode`].
544 ///
545 /// Scancodes can appear in the keymap multiple times. Typically, the first entry takes
546 /// precedence.
547 ///
548 /// The keymap can also be queried by index. See [`Evdev::keymap_entry_by_index`] for how to do
549 /// that.
550 /// The keymap can *not* be queried by *key* code.
551 ///
552 /// Devices without [`Key`]s don't have any keymap entries, and not all drivers support this
553 /// functionality.
554 ///
555 /// Devices that support keymaps and have internal scancodes will typically send a
556 /// [`Misc::SCAN`] event immediately before a key press or release event.
557 ///
558 /// Return `Ok(None)` when `index` is out of range.
559 pub fn keymap_entry(&self, code: Scancode) -> io::Result<Option<KeymapEntry>> {
560 unsafe {
561 let mut entry = KeymapEntry::zeroed();
562 entry.0.len = code.len;
563 entry.0.scancode = code.bytes;
564 match self.ioctl("EVIOCGKEYCODE_V2", EVIOCGKEYCODE_V2, &mut entry.0) {
565 Ok(_) => Ok(Some(entry)),
566 Err(e) if e.kind() == io::ErrorKind::InvalidInput => Ok(None),
567 Err(e) => Err(e),
568 }
569 }
570 }
571
572 /// Queries a keymap entry by its zero-based index.
573 ///
574 /// The keymap can also be queried by scancode. See [`Evdev::keymap_entry`].
575 /// The keymap can *not* be queried by *key* code.
576 ///
577 /// Devices without [`Key`]s don't have any keymap entries, and not all drivers support this
578 /// functionality.
579 ///
580 /// Return `Ok(None)` when `index` is out of range.
581 /// This is the only way to determine the number of entries in the keymap.
582 pub fn keymap_entry_by_index(&self, index: u16) -> io::Result<Option<KeymapEntry>> {
583 unsafe {
584 let mut entry = KeymapEntry::zeroed();
585 entry.0.index = index;
586 entry.0.flags = INPUT_KEYMAP_BY_INDEX;
587 match self.ioctl("EVIOCGKEYCODE_V2", EVIOCGKEYCODE_V2, &mut entry.0) {
588 Ok(_) => Ok(Some(entry)),
589 Err(e) if e.kind() == io::ErrorKind::InvalidInput => Ok(None),
590 Err(e) => Err(e),
591 }
592 }
593 }
594
595 /// Sets a keymap entry by scancode.
596 ///
597 /// This will remap the given [`Scancode`] to produce `keycode`. Use with caution!
598 pub fn set_keymap_entry(&self, scancode: Scancode, keycode: Key) -> io::Result<()> {
599 unsafe {
600 let mut entry = KeymapEntry::zeroed();
601 entry.0.keycode = keycode.raw().into();
602 entry.0.len = scancode.len;
603 entry.0.scancode = scancode.bytes;
604 self.ioctl("EVIOCSKEYCODE_V2", EVIOCSKEYCODE_V2, &entry.0)?;
605 Ok(())
606 }
607 }
608
609 /// Sets a keymap entry by index.
610 ///
611 /// To find the [`Scancode`] at this index, or the valid indices, use
612 /// [`Evdev::keymap_entry_by_index`].
613 pub fn set_keymap_entry_by_index(&self, index: u16, keycode: Key) -> io::Result<()> {
614 unsafe {
615 let mut entry = KeymapEntry::zeroed();
616 entry.0.flags = INPUT_KEYMAP_BY_INDEX;
617 entry.0.keycode = keycode.raw().into();
618 entry.0.index = index;
619 self.ioctl("EVIOCSKEYCODE_V2", EVIOCSKEYCODE_V2, &entry.0)?;
620 Ok(())
621 }
622 }
623
624 /// Queries the full key state.
625 pub fn key_state(&self) -> io::Result<BitSet<Key>> {
626 unsafe { self.fetch_bits("EVIOCGKEY", EVIOCGKEY) }
627 }
628
629 /// Queries the state of all device LEDs.
630 pub fn led_state(&self) -> io::Result<BitSet<Led>> {
631 unsafe { self.fetch_bits("EVIOCGLED", EVIOCGLED) }
632 }
633
634 /// Queries the state of all [`Sound`]s.
635 pub fn sound_state(&self) -> io::Result<BitSet<Sound>> {
636 unsafe { self.fetch_bits("EVIOCGSND", EVIOCGSND) }
637 }
638
639 /// Queries the state of all [`Switch`]es.
640 pub fn switch_state(&self) -> io::Result<BitSet<Switch>> {
641 unsafe { self.fetch_bits("EVIOCGSW", EVIOCGSW) }
642 }
643
644 /// Creates an [`EventReader`] wrapping this device.
645 ///
646 /// This is the recommended way of receiving input events.
647 /// The [`EventReader`] will automatically resynchronize with the kernel's view of the device
648 /// when an event is lost due to overflow.
649 pub fn into_reader(self) -> io::Result<EventReader> {
650 EventReader::new(self)
651 }
652
653 /// Returns whether this device has any pending *raw* events that can be read without blocking.
654 ///
655 /// If this returns `true`, calling [`Evdev::raw_events()`] and then calling
656 /// [`RawEvents::next()`] is guaranteed to not block (but only for a single event).
657 ///
658 /// Note that this does not work for [`Evdev`]s wrapped in an [`EventReader`], since
659 /// [`EventReader`] might read and discard several events from the underlying device. For
660 /// updating an [`EventReader`] without blocking, use [`EventReader::update`].
661 pub fn is_readable(&self) -> io::Result<bool> {
662 is_readable(self.as_raw_fd())
663 }
664
665 /// Blocks the calling thread until [`Evdev::is_readable`] would return `true`.
666 ///
667 /// This will block even if `self` is in non-blocking mode (via [`Evdev::set_nonblocking`]).
668 /// For checking whether events can be read from `self` without blocking, use
669 /// [`Evdev::is_readable`], which will *never* block.
670 ///
671 /// If `self` is already readable, this will return immediately.
672 pub fn block_until_readable(&self) -> io::Result<()> {
673 block_until_readable(self.as_raw_fd())
674 }
675
676 /// Returns an iterator over the raw `evdev` events.
677 ///
678 /// This will directly read from the `evdev`, without any buffering, filtering, synchronization
679 /// on lost events, or fetching of the kernel's view of the device state.
680 ///
681 /// It is recommended to use [`Evdev::into_reader`] instead.
682 ///
683 /// [`RawEvents`] can be used (correctly) if the user is only interested in events pertaining to
684 /// relative axes ([`RelEvent`][crate::event::RelEvent]), since those have no state.
685 ///
686 /// If the [`Evdev`] is in non-blocking mode, the iterator will return [`None`] when reading
687 /// fails with a [`WouldBlock`][io::ErrorKind::WouldBlock] error.
688 /// If it is in blocking mode, [`RawEvents::next`] will block until an event is available.
689 ///
690 /// **Note**: If this method is used while the device is wrapped in an [`EventReader`], the
691 /// [`EventReader`] will miss events and go out of sync with the device state. Don't do that.
692 pub fn raw_events(&self) -> RawEvents<'_> {
693 RawEvents { file: &self.file }
694 }
695
696 /// Reads incoming raw events into `buf`.
697 ///
698 /// This may read multiple events at once, which is more efficient than using
699 /// [`Evdev::raw_events`] to read them one-by-one.
700 ///
701 /// This method will block until at least 1 event is available when the [`Evdev`] is in blocking
702 /// mode.
703 /// If it is in non-blocking mode, this method will return an [`io::ErrorKind::WouldBlock`]
704 /// error when there are no events to read.
705 pub fn read_events(&self, buf: &mut [InputEvent]) -> io::Result<usize> {
706 read_raw(&self.file, buf)
707 }
708
709 /// Uploads a force-feedback effect to the device.
710 ///
711 /// This is always a blocking operation, even if the [`Evdev`] is in non-blocking mode.
712 /// If the device is a `uinput` device, bugs in the userspace driver might cause this to block
713 /// for a *very* long time (there appears to be a timeout at 20-30 seconds).
714 ///
715 /// Also see [`Evdev::supported_ff_effects`] for the number of supported effect slots, and
716 /// [`Evdev::supported_ff_features`] for the supported force-feedback feature set.
717 ///
718 /// Uploaded effects will stay in device memory until removed via [`Evdev::erase_ff_effect`].
719 pub fn upload_ff_effect<'a>(
720 &self,
721 effect: impl Into<ff::Effect<'a>>,
722 ) -> io::Result<ff::EffectId> {
723 self.upload_ff_effect_impl(effect.into())
724 }
725 fn upload_ff_effect_impl(&self, mut effect: ff::Effect<'_>) -> io::Result<ff::EffectId> {
726 log::trace!("uploading FF effect: {:?}", effect);
727 let now = Instant::now();
728 unsafe {
729 self.ioctl("EVIOCSFF", EVIOCSFF, &mut effect.raw)?;
730 }
731 log::debug!("upload_ff_effect: ioctl took {:?}", now.elapsed());
732
733 Ok(ff::EffectId(effect.raw.id))
734 }
735
736 /// Deletes a previously uploaded force-feedback effect.
737 pub fn erase_ff_effect(&self, id: ff::EffectId) -> io::Result<()> {
738 unsafe {
739 self.ioctl("EVIOCRMFF", EVIOCRMFF, id.0 as c_int)?;
740 }
741 Ok(())
742 }
743
744 /// Sets the state of a device LED.
745 ///
746 /// To query the list of LEDs available on the device, use [`Evdev::supported_leds`].
747 ///
748 /// Convenience wrapper around [`Evdev::write`].
749 pub fn set_led(&self, led: Led, on: bool) -> io::Result<()> {
750 self.write(&[LedEvent::new(led, on).into()])
751 }
752
753 /// Plays or stops a force-feedback effect (eg. rumble).
754 ///
755 /// Before an effect can be started with this method, it needs to be uploaded via
756 /// [`Evdev::upload_ff_effect`].
757 ///
758 /// Convenience wrapper around [`Evdev::write`].
759 pub fn control_ff(&self, effect: ff::EffectId, active: bool) -> io::Result<()> {
760 self.write(&[ForceFeedbackEvent::new_control_effect(effect, active).into()])
761 }
762
763 /// Sets the global gain for force-feedback effects.
764 ///
765 /// Requires that the device supports [`ff::Feature::GAIN`].
766 ///
767 /// Convenience wrapper around [`Evdev::write`].
768 pub fn set_ff_gain(&self, gain: u16) -> io::Result<()> {
769 self.write(&[ForceFeedbackEvent::new_set_gain(gain).into()])
770 }
771
772 /// Controls the autocenter feature for force-feedback effects.
773 ///
774 /// Requires that the device supports [`ff::Feature::AUTOCENTER`].
775 ///
776 /// Convenience wrapper around [`Evdev::write`].
777 pub fn set_ff_autocenter(&self, autocenter: u16) -> io::Result<()> {
778 self.write(&[ForceFeedbackEvent::new_set_autocenter(autocenter).into()])
779 }
780
781 /// *Writes* input events *to* the device.
782 ///
783 /// This can be used to change certain device states such as LEDs or sounds, or to play
784 /// force-feedback effects.
785 ///
786 /// Prefer using one of the convenience wrappers around this method if possible:
787 /// [`Evdev::control_ff`], [`Evdev::set_led`], etc.
788 ///
789 /// **Note**: As per usual for file descriptors, writing data to the device is only possible if
790 /// it was opened with write permission.
791 /// [`Evdev::open`] will *try* to open the device with read+write permissions, and fall back to
792 /// read-only mode if the user does not have write permission for the evdev files.
793 /// If that also fails, one last attempt to open in *write-only* mode is made, to cover certain
794 /// misconfigured systems.
795 /// If the [`Evdev`] does not have write permission, this method will return an error of type
796 /// [`io::ErrorKind::PermissionDenied`].
797 pub fn write(&self, events: &[InputEvent]) -> io::Result<()> {
798 unsafe {
799 let bytes = slice::from_raw_parts(
800 events.as_ptr().cast(),
801 events.len() * size_of::<InputEvent>(),
802 );
803 (&self.file).write_all(bytes)
804 }
805 }
806
807 /// Sets the [`clockid_t`] to be used for event timestamps.
808 ///
809 /// `evdev` doesn't support *all* clocks. This method will fail with
810 /// [`io::ErrorKind::InvalidInput`] when a `clockid` is passed that `evdev` doesn't like.
811 /// At least [`libc::CLOCK_REALTIME`] and [`libc::CLOCK_MONOTONIC`] seem to be supported.
812 ///
813 /// By default, [`libc::CLOCK_REALTIME`] is used, which is the same clock source used by
814 /// [`SystemTime::now`][std::time::SystemTime::now].
815 ///
816 /// If this is called while there are any events in the kernel buffer, the buffer will be
817 /// cleared and a [`Syn::DROPPED`] event will be enqueued.
818 ///
819 /// [`Syn::DROPPED`]: crate::event::Syn::DROPPED
820 pub fn set_clockid(&self, clockid: clockid_t) -> io::Result<()> {
821 unsafe {
822 self.ioctl("EVIOCSCLOCKID", EVIOCSCLOCKID, &clockid)?;
823 Ok(())
824 }
825 }
826}
827
828/// Event masks can be optionally configured to hide event types if a consumer isn't interested in
829/// them.
830///
831/// This can help avoid wasted work and unnecessary process wakeups, which can save battery.
832///
833/// **Note**: Fetching the device state directly (via [`Evdev::key_state`] et al) will still report
834/// the *true* device state, without any bits masked out. The event masks only control which
835/// *events* are forwarded to the program.
836///
837/// **Note 2**: [`EventReader`] is not aware of event masks and may insert some synthetic events
838/// that have been disabled with the event masks. Your application should configure the masks as
839/// desired *and* actively ignore any events that it sees if it isn't interested in them.
840///
841/// # Platform Support
842///
843/// FreeBSD does not support these APIs, so they will return an error when used.
844/// Applications should degrade gracefully when that happens, since the consequence of not filtering
845/// events is merely a decrease in performance.
846impl Evdev {
847 fn fetch_mask<V: BitValue>(&self, ty: EventType) -> io::Result<BitSet<V>> {
848 let mut set = BitSet::<V>::new();
849 let words = set.words_mut();
850 unsafe {
851 let mut mask = input_mask {
852 type_: ty.0.into(),
853 codes_size: (words.len() * mem::size_of::<Word>()) as u32,
854 codes_ptr: words.as_mut_ptr().expose_provenance() as u64,
855 };
856 self.ioctl("EVIOCGMASK", EVIOCGMASK, &mut mask)?;
857 }
858 Ok(set)
859 }
860
861 fn set_mask<V: BitValue>(&self, ty: EventType, mask: &BitSet<V>) -> io::Result<()> {
862 let words = mask.words();
863 unsafe {
864 let mask = input_mask {
865 type_: ty.0.into(),
866 codes_size: (words.len() * mem::size_of::<Word>()) as u32,
867 codes_ptr: words.as_ptr().expose_provenance() as u64,
868 };
869 self.ioctl("EVIOCSMASK", EVIOCSMASK, &mask)?;
870 }
871 Ok(())
872 }
873
874 /// Returns the current event mask.
875 pub fn event_mask(&self) -> io::Result<BitSet<EventType>> {
876 self.fetch_mask(EventType::from_raw(0))
877 }
878
879 /// Sets the event mask.
880 ///
881 /// Only [`EventType`]s included in `mask` will be forwarded to this [`Evdev`] handle.
882 pub fn set_event_mask(&self, mask: &BitSet<EventType>) -> io::Result<()> {
883 self.set_mask(EventType::from_raw(0), mask)
884 }
885
886 /// Returns the current key event mask.
887 pub fn key_mask(&self) -> io::Result<BitSet<Key>> {
888 self.fetch_mask(EventType::KEY)
889 }
890
891 /// Sets the key event mask.
892 ///
893 /// This [`Evdev`] handle will only receive [`KeyEvent`]s whose [`Key`] is contained in `mask`.
894 ///
895 /// [`KeyEvent`]: crate::event::KeyEvent
896 pub fn set_key_mask(&self, mask: &BitSet<Key>) -> io::Result<()> {
897 self.set_mask(EventType::KEY, mask)
898 }
899
900 /// Returns the current relative axis event mask.
901 pub fn rel_mask(&self) -> io::Result<BitSet<Rel>> {
902 self.fetch_mask(EventType::REL)
903 }
904
905 /// Sets the relative axis event mask.
906 pub fn set_rel_mask(&self, mask: &BitSet<Rel>) -> io::Result<()> {
907 self.set_mask(EventType::REL, mask)
908 }
909
910 /// Returns the current absolute axis event mask.
911 pub fn abs_mask(&self) -> io::Result<BitSet<Abs>> {
912 self.fetch_mask(EventType::ABS)
913 }
914
915 /// Sets the absolute axis event mask.
916 pub fn set_abs_mask(&self, mask: &BitSet<Abs>) -> io::Result<()> {
917 self.set_mask(EventType::ABS, mask)
918 }
919
920 /// Returns the current switch event mask.
921 pub fn switch_mask(&self) -> io::Result<BitSet<Switch>> {
922 self.fetch_mask(EventType::SW)
923 }
924
925 /// Sets the switch event mask.
926 pub fn set_switch_mask(&self, mask: &BitSet<Switch>) -> io::Result<()> {
927 self.set_mask(EventType::SW, mask)
928 }
929}
930
931/// Reads raw [`InputEvent`]s from an [`Evdev`].
932///
933/// Returned by [`Evdev::raw_events`].
934///
935/// This holds no state and performs no batching, so it can be created at will via
936/// [`Evdev::raw_events`].
937///
938/// [`UinputDevice`]: crate::uinput::UinputDevice
939/// [`UinputDevice::events`]: crate::uinput::UinputDevice::events
940#[derive(Debug)]
941pub struct RawEvents<'a> {
942 pub(crate) file: &'a File,
943}
944
945impl Iterator for RawEvents<'_> {
946 type Item = io::Result<InputEvent>;
947
948 fn next(&mut self) -> Option<Self::Item> {
949 let mut dest = InputEvent::zeroed();
950 match read_raw(&self.file, slice::from_mut(&mut dest)) {
951 Err(e) if e.kind() == io::ErrorKind::WouldBlock => None,
952 Err(e) => Some(Err(e)),
953 Ok(0) => None,
954 Ok(1) => Some(Ok(dest)),
955 Ok(n) => unreachable!("read {n} events, but can only hold 1"),
956 }
957 }
958}
959
960fn read_raw(mut file: &File, dest: &mut [InputEvent]) -> io::Result<usize> {
961 let bptr = dest.as_mut_ptr().cast::<u8>();
962 let byte_buf =
963 unsafe { slice::from_raw_parts_mut(bptr, mem::size_of::<InputEvent>() * dest.len()) };
964 let bytes = file.read(byte_buf)?;
965 debug_assert_eq!(bytes % mem::size_of::<InputEvent>(), 0);
966 Ok(bytes / mem::size_of::<InputEvent>())
967}