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}