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}