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