sweetacid_evdev/
raw_stream.rs

1use std::fs::{File, OpenOptions};
2use std::mem::MaybeUninit;
3use std::os::unix::io::{AsRawFd, RawFd};
4use std::path::Path;
5use std::{io, mem};
6
7use crate::constants::*;
8use crate::{sys, AttributeSet, AttributeSetRef, InputEvent, InputId, Key};
9
10fn ioctl_get_cstring(
11    f: unsafe fn(RawFd, &mut [u8]) -> nix::Result<libc::c_int>,
12    fd: RawFd,
13) -> Option<Vec<u8>> {
14    let mut buf = vec![0; 256];
15    match unsafe { f(fd, buf.as_mut_slice()) } {
16        Ok(len) if len as usize > buf.capacity() => {
17            panic!("ioctl_get_cstring call overran the provided buffer!");
18        }
19        Ok(len) if len > 1 => {
20            // Our ioctl string functions apparently return the number of bytes written, including
21            // trailing \0.
22            buf.truncate(len as usize);
23            assert_eq!(buf.pop().unwrap(), 0);
24            Some(buf)
25        }
26        _ => None,
27    }
28}
29
30fn bytes_into_string_lossy(v: Vec<u8>) -> String {
31    String::from_utf8(v).unwrap_or_else(|v| String::from_utf8_lossy(v.as_bytes()).into_owned())
32}
33
34#[rustfmt::skip]
35const ABSINFO_ZERO: libc::input_absinfo = libc::input_absinfo {
36    value: 0, minimum: 0, maximum: 0, fuzz: 0, flat: 0, resolution: 0,
37};
38pub(crate) const ABS_VALS_INIT: [libc::input_absinfo; AbsoluteAxisType::COUNT] =
39    [ABSINFO_ZERO; AbsoluteAxisType::COUNT];
40
41const INPUT_KEYMAP_BY_INDEX: u8 = 1;
42
43/// A physical or virtual device supported by evdev.
44///
45/// Each device corresponds to a path typically found in `/dev/input`, and supports access via
46/// one or more "types". For example, an optical mouse has buttons that are represented by "keys",
47/// and reflects changes in its position via "relative axis" reports.
48#[derive(Debug)]
49pub struct RawDevice {
50    file: File,
51    ty: AttributeSet<EventType>,
52    name: Option<String>,
53    phys: Option<String>,
54    uniq: Option<String>,
55    id: libc::input_id,
56    props: AttributeSet<PropType>,
57    driver_version: (u8, u8, u8),
58    supported_keys: Option<AttributeSet<Key>>,
59    supported_relative: Option<AttributeSet<RelativeAxisType>>,
60    supported_absolute: Option<AttributeSet<AbsoluteAxisType>>,
61    supported_switch: Option<AttributeSet<SwitchType>>,
62    supported_led: Option<AttributeSet<LedType>>,
63    supported_misc: Option<AttributeSet<MiscType>>,
64    auto_repeat: Option<AutoRepeat>,
65    // ff: Option<AttributeSet<_>>,
66    // ff_stat: Option<FFStatus>,
67    supported_snd: Option<AttributeSet<SoundType>>,
68    pub(crate) event_buf: Vec<libc::input_event>,
69    grabbed: bool,
70}
71
72#[derive(Debug, Clone)]
73#[repr(C)]
74pub struct AutoRepeat {
75    pub delay: u32,
76    pub period: u32,
77}
78
79impl RawDevice {
80    /// Opens a device, given its system path.
81    ///
82    /// Paths are typically something like `/dev/input/event0`.
83    #[inline(always)]
84    pub fn open(path: impl AsRef<Path>) -> io::Result<RawDevice> {
85        Self::_open(path.as_ref())
86    }
87
88    fn _open(path: &Path) -> io::Result<RawDevice> {
89        let mut options = OpenOptions::new();
90
91        // Try to load read/write, then fall back to read-only.
92        let file = options
93            .read(true)
94            .write(true)
95            .open(path)
96            .or_else(|_| options.write(false).open(path))?;
97
98        let ty = {
99            let mut ty = AttributeSet::<EventType>::new();
100            unsafe { sys::eviocgbit_type(file.as_raw_fd(), ty.as_mut_raw_slice())? };
101            ty
102        };
103
104        let name =
105            ioctl_get_cstring(sys::eviocgname, file.as_raw_fd()).map(bytes_into_string_lossy);
106        let phys =
107            ioctl_get_cstring(sys::eviocgphys, file.as_raw_fd()).map(bytes_into_string_lossy);
108        let uniq =
109            ioctl_get_cstring(sys::eviocguniq, file.as_raw_fd()).map(bytes_into_string_lossy);
110
111        let id = unsafe {
112            let mut id = MaybeUninit::uninit();
113            sys::eviocgid(file.as_raw_fd(), id.as_mut_ptr())?;
114            id.assume_init()
115        };
116        let mut driver_version: i32 = 0;
117        unsafe {
118            sys::eviocgversion(file.as_raw_fd(), &mut driver_version)?;
119        }
120        let driver_version = (
121            ((driver_version >> 16) & 0xff) as u8,
122            ((driver_version >> 8) & 0xff) as u8,
123            (driver_version & 0xff) as u8,
124        );
125
126        let props = {
127            let mut props = AttributeSet::<PropType>::new();
128            unsafe { sys::eviocgprop(file.as_raw_fd(), props.as_mut_raw_slice())? };
129            props
130        }; // FIXME: handle old kernel
131
132        let supported_keys = if ty.contains(EventType::KEY) {
133            let mut keys = AttributeSet::<Key>::new();
134            unsafe { sys::eviocgbit_key(file.as_raw_fd(), keys.as_mut_raw_slice())? };
135            Some(keys)
136        } else {
137            None
138        };
139
140        let supported_relative = if ty.contains(EventType::RELATIVE) {
141            let mut rel = AttributeSet::<RelativeAxisType>::new();
142            unsafe { sys::eviocgbit_relative(file.as_raw_fd(), rel.as_mut_raw_slice())? };
143            Some(rel)
144        } else {
145            None
146        };
147
148        let supported_absolute = if ty.contains(EventType::ABSOLUTE) {
149            let mut abs = AttributeSet::<AbsoluteAxisType>::new();
150            unsafe { sys::eviocgbit_absolute(file.as_raw_fd(), abs.as_mut_raw_slice())? };
151            Some(abs)
152        } else {
153            None
154        };
155
156        let supported_switch = if ty.contains(EventType::SWITCH) {
157            let mut switch = AttributeSet::<SwitchType>::new();
158            unsafe { sys::eviocgbit_switch(file.as_raw_fd(), switch.as_mut_raw_slice())? };
159            Some(switch)
160        } else {
161            None
162        };
163
164        let supported_led = if ty.contains(EventType::LED) {
165            let mut led = AttributeSet::<LedType>::new();
166            unsafe { sys::eviocgbit_led(file.as_raw_fd(), led.as_mut_raw_slice())? };
167            Some(led)
168        } else {
169            None
170        };
171
172        let supported_misc = if ty.contains(EventType::MISC) {
173            let mut misc = AttributeSet::<MiscType>::new();
174            unsafe { sys::eviocgbit_misc(file.as_raw_fd(), misc.as_mut_raw_slice())? };
175            Some(misc)
176        } else {
177            None
178        };
179
180        //unsafe { sys::eviocgbit(file.as_raw_fd(), ffs(FORCEFEEDBACK.bits()), 0x7f, bits_as_u8_slice)?; }
181
182        let supported_snd = if ty.contains(EventType::SOUND) {
183            let mut snd = AttributeSet::<SoundType>::new();
184            unsafe { sys::eviocgbit_sound(file.as_raw_fd(), snd.as_mut_raw_slice())? };
185            Some(snd)
186        } else {
187            None
188        };
189
190        let auto_repeat = if ty.contains(EventType::REPEAT) {
191            let mut auto_repeat: AutoRepeat = AutoRepeat {
192                delay: 0,
193                period: 0,
194            };
195
196            unsafe {
197                sys::eviocgrep(
198                    file.as_raw_fd(),
199                    &mut auto_repeat as *mut AutoRepeat as *mut [u32; 2],
200                )?;
201            }
202
203            Some(auto_repeat)
204        } else {
205            None
206        };
207
208        Ok(RawDevice {
209            file,
210            ty,
211            name,
212            phys,
213            uniq,
214            id,
215            props,
216            driver_version,
217            supported_keys,
218            supported_relative,
219            supported_absolute,
220            supported_switch,
221            supported_led,
222            supported_misc,
223            supported_snd,
224            auto_repeat,
225            event_buf: Vec::new(),
226            grabbed: false,
227        })
228    }
229
230    /// Returns the device's name as read from the kernel.
231    pub fn name(&self) -> Option<&str> {
232        self.name.as_deref()
233    }
234
235    /// Returns the device's physical location, either as set by the caller or as read from the kernel.
236    pub fn physical_path(&self) -> Option<&str> {
237        self.phys.as_deref()
238    }
239
240    /// Returns the user-defined "unique name" of the device, if one has been set.
241    pub fn unique_name(&self) -> Option<&str> {
242        self.uniq.as_deref()
243    }
244
245    /// Returns a struct containing bustype, vendor, product, and version identifiers
246    pub fn input_id(&self) -> InputId {
247        InputId::from(self.id)
248    }
249
250    /// Returns the current auto repeat settings
251    pub fn get_auto_repeat(&self) -> Option<AutoRepeat> {
252        self.auto_repeat.clone()
253    }
254
255    /// Returns the set of supported "properties" for the device (see `INPUT_PROP_*` in kernel headers)
256    pub fn properties(&self) -> &AttributeSetRef<PropType> {
257        &self.props
258    }
259
260    /// Returns a tuple of the driver version containing major, minor, rev
261    pub fn driver_version(&self) -> (u8, u8, u8) {
262        self.driver_version
263    }
264
265    /// Returns a set of the event types supported by this device (Key, Switch, etc)
266    ///
267    /// If you're interested in the individual keys or switches supported, it's probably easier
268    /// to just call the appropriate `supported_*` function instead.
269    pub fn supported_events(&self) -> &AttributeSetRef<EventType> {
270        &self.ty
271    }
272
273    /// Returns the set of supported keys reported by the device.
274    ///
275    /// For keyboards, this is the set of all possible keycodes the keyboard may emit. Controllers,
276    /// mice, and other peripherals may also report buttons as keys.
277    ///
278    /// # Examples
279    ///
280    /// ```no_run
281    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
282    /// use evdev::{Device, Key};
283    /// let device = Device::open("/dev/input/event0")?;
284    ///
285    /// // Does this device have an ENTER key?
286    /// let supported = device.supported_keys().map_or(false, |keys| keys.contains(Key::KEY_ENTER));
287    /// # Ok(())
288    /// # }
289    /// ```
290    pub fn supported_keys(&self) -> Option<&AttributeSetRef<Key>> {
291        self.supported_keys.as_deref()
292    }
293
294    /// Returns the set of supported "relative axes" reported by the device.
295    ///
296    /// Standard mice will generally report `REL_X` and `REL_Y` along with wheel if supported.
297    ///
298    /// # Examples
299    ///
300    /// ```no_run
301    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
302    /// use evdev::{Device, RelativeAxisType};
303    /// let device = Device::open("/dev/input/event0")?;
304    ///
305    /// // Does the device have a scroll wheel?
306    /// let supported = device
307    ///     .supported_relative_axes()
308    ///     .map_or(false, |axes| axes.contains(RelativeAxisType::REL_WHEEL));
309    /// # Ok(())
310    /// # }
311    /// ```
312    pub fn supported_relative_axes(&self) -> Option<&AttributeSetRef<RelativeAxisType>> {
313        self.supported_relative.as_deref()
314    }
315
316    /// Returns the set of supported "absolute axes" reported by the device.
317    ///
318    /// These are most typically supported by joysticks and touchpads.
319    ///
320    /// # Examples
321    ///
322    /// ```no_run
323    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
324    /// use evdev::{Device, AbsoluteAxisType};
325    /// let device = Device::open("/dev/input/event0")?;
326    ///
327    /// // Does the device have an absolute X axis?
328    /// let supported = device
329    ///     .supported_absolute_axes()
330    ///     .map_or(false, |axes| axes.contains(AbsoluteAxisType::ABS_X));
331    /// # Ok(())
332    /// # }
333    /// ```
334    pub fn supported_absolute_axes(&self) -> Option<&AttributeSetRef<AbsoluteAxisType>> {
335        self.supported_absolute.as_deref()
336    }
337
338    /// Returns the set of supported switches reported by the device.
339    ///
340    /// These are typically used for things like software switches on laptop lids (which the
341    /// system reacts to by suspending or locking), or virtual switches to indicate whether a
342    /// headphone jack is plugged in (used to disable external speakers).
343    ///
344    /// # Examples
345    ///
346    /// ```no_run
347    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
348    /// use evdev::{Device, SwitchType};
349    /// let device = Device::open("/dev/input/event0")?;
350    ///
351    /// // Does the device report a laptop lid switch?
352    /// let supported = device
353    ///     .supported_switches()
354    ///     .map_or(false, |axes| axes.contains(SwitchType::SW_LID));
355    /// # Ok(())
356    /// # }
357    /// ```
358    pub fn supported_switches(&self) -> Option<&AttributeSetRef<SwitchType>> {
359        self.supported_switch.as_deref()
360    }
361
362    /// Returns a set of supported LEDs on the device.
363    ///
364    /// Most commonly these are state indicator lights for things like Scroll Lock, but they
365    /// can also be found in cameras and other devices.
366    pub fn supported_leds(&self) -> Option<&AttributeSetRef<LedType>> {
367        self.supported_led.as_deref()
368    }
369
370    /// Returns a set of supported "miscellaneous" capabilities.
371    ///
372    /// Aside from vendor-specific key scancodes, most of these are uncommon.
373    pub fn misc_properties(&self) -> Option<&AttributeSetRef<MiscType>> {
374        self.supported_misc.as_deref()
375    }
376
377    /// Returns the set of supported simple sounds supported by a device.
378    ///
379    /// You can use these to make really annoying beep sounds come from an internal self-test
380    /// speaker, for instance.
381    pub fn supported_sounds(&self) -> Option<&AttributeSetRef<SoundType>> {
382        self.supported_snd.as_deref()
383    }
384
385    /// Read a maximum of `num` events into the internal buffer. If the underlying fd is not
386    /// O_NONBLOCK, this will block.
387    ///
388    /// Returns the number of events that were read, or an error.
389    pub(crate) fn fill_events(&mut self) -> io::Result<usize> {
390        let fd = self.as_raw_fd();
391        self.event_buf.reserve(crate::EVENT_BATCH_SIZE);
392
393        // TODO: use Vec::spare_capacity_mut or Vec::split_at_spare_mut when they stabilize
394        let spare_capacity = vec_spare_capacity_mut(&mut self.event_buf);
395        let spare_capacity_size = std::mem::size_of_val(spare_capacity);
396
397        // use libc::read instead of nix::unistd::read b/c we need to pass an uninitialized buf
398        let res = unsafe { libc::read(fd, spare_capacity.as_mut_ptr() as _, spare_capacity_size) };
399        let bytes_read = nix::errno::Errno::result(res)?;
400        let num_read = bytes_read as usize / mem::size_of::<libc::input_event>();
401        unsafe {
402            let len = self.event_buf.len();
403            self.event_buf.set_len(len + num_read);
404        }
405        Ok(num_read)
406    }
407
408    /// Fetches and returns events from the kernel ring buffer without doing synchronization on
409    /// SYN_DROPPED.
410    ///
411    /// By default this will block until events are available. Typically, users will want to call
412    /// this in a tight loop within a thread.
413    pub fn fetch_events(&mut self) -> io::Result<impl Iterator<Item = InputEvent> + '_> {
414        self.fill_events()?;
415        Ok(self.event_buf.drain(..).map(InputEvent))
416    }
417
418    /// Retrieve the current keypress state directly via kernel syscall.
419    #[inline]
420    pub fn get_key_state(&self) -> io::Result<AttributeSet<Key>> {
421        let mut key_vals = AttributeSet::new();
422        self.update_key_state(&mut key_vals)?;
423        Ok(key_vals)
424    }
425
426    /// Retrieve the current absolute axis state directly via kernel syscall.
427    #[inline]
428    pub fn get_abs_state(&self) -> io::Result<[libc::input_absinfo; AbsoluteAxisType::COUNT]> {
429        let mut abs_vals: [libc::input_absinfo; AbsoluteAxisType::COUNT] = ABS_VALS_INIT;
430        self.update_abs_state(&mut abs_vals)?;
431        Ok(abs_vals)
432    }
433
434    /// Retrieve the current switch state directly via kernel syscall.
435    #[inline]
436    pub fn get_switch_state(&self) -> io::Result<AttributeSet<SwitchType>> {
437        let mut switch_vals = AttributeSet::new();
438        self.update_switch_state(&mut switch_vals)?;
439        Ok(switch_vals)
440    }
441
442    /// Retrieve the current LED state directly via kernel syscall.
443    #[inline]
444    pub fn get_led_state(&self) -> io::Result<AttributeSet<LedType>> {
445        let mut led_vals = AttributeSet::new();
446        self.update_led_state(&mut led_vals)?;
447        Ok(led_vals)
448    }
449
450    /// Fetch the current kernel key state directly into the provided buffer.
451    /// If you don't already have a buffer, you probably want
452    /// [`get_key_state`](Self::get_key_state) instead.
453    #[inline]
454    pub fn update_key_state(&self, key_vals: &mut AttributeSet<Key>) -> io::Result<()> {
455        unsafe { sys::eviocgkey(self.as_raw_fd(), key_vals.as_mut_raw_slice())? };
456        Ok(())
457    }
458
459    /// Fetch the current kernel absolute axis state directly into the provided buffer.
460    /// If you don't already have a buffer, you probably want
461    /// [`get_abs_state`](Self::get_abs_state) instead.
462    #[inline]
463    pub fn update_abs_state(
464        &self,
465        abs_vals: &mut [libc::input_absinfo; AbsoluteAxisType::COUNT],
466    ) -> io::Result<()> {
467        if let Some(supported_abs) = self.supported_absolute_axes() {
468            for AbsoluteAxisType(idx) in supported_abs.iter() {
469                // ignore multitouch, we'll handle that later.
470                //
471                // handling later removed. not sure what the intention of "handling that later" was
472                // the abs data seems to be fine (tested ABS_MT_POSITION_X/Y)
473                unsafe {
474                    sys::eviocgabs(self.as_raw_fd(), idx as u32, &mut abs_vals[idx as usize])?
475                };
476            }
477        }
478        Ok(())
479    }
480
481    /// Fetch the current kernel switch state directly into the provided buffer.
482    /// If you don't already have a buffer, you probably want
483    /// [`get_switch_state`](Self::get_switch_state) instead.
484    #[inline]
485    pub fn update_switch_state(
486        &self,
487        switch_vals: &mut AttributeSet<SwitchType>,
488    ) -> io::Result<()> {
489        unsafe { sys::eviocgsw(self.as_raw_fd(), switch_vals.as_mut_raw_slice())? };
490        Ok(())
491    }
492
493    /// Fetch the current kernel LED state directly into the provided buffer.
494    /// If you don't already have a buffer, you probably want
495    /// [`get_led_state`](Self::get_led_state) instead.
496    #[inline]
497    pub fn update_led_state(&self, led_vals: &mut AttributeSet<LedType>) -> io::Result<()> {
498        unsafe { sys::eviocgled(self.as_raw_fd(), led_vals.as_mut_raw_slice())? };
499        Ok(())
500    }
501
502    /// Update the auto repeat delays
503    #[inline]
504    pub fn update_auto_repeat(&mut self, repeat: &AutoRepeat) -> io::Result<()> {
505        unsafe {
506            sys::eviocsrep(
507                self.as_raw_fd(),
508                repeat as *const AutoRepeat as *const [u32; 2],
509            )?;
510        }
511        self.auto_repeat = Some(repeat.clone());
512        Ok(())
513    }
514
515    /// Retrieve the scancode for a keycode, if any
516    pub fn get_scancode_by_keycode(&self, keycode: u32) -> io::Result<Vec<u8>> {
517        let mut keymap = libc::input_keymap_entry {
518            flags: 0,
519            len: 0,
520            index: 0,
521            keycode,
522            scancode: [0u8; 32],
523        };
524        unsafe { sys::eviocgkeycode_v2(self.as_raw_fd(), &mut keymap)? };
525        Ok(keymap.scancode[..keymap.len as usize].to_vec())
526    }
527
528    /// Retrieve the keycode and scancode by index, starting at 0
529    pub fn get_scancode_by_index(&self, index: u16) -> io::Result<(u32, Vec<u8>)> {
530        let mut keymap = libc::input_keymap_entry {
531            flags: INPUT_KEYMAP_BY_INDEX,
532            len: 0,
533            index,
534            keycode: 0,
535            scancode: [0u8; 32],
536        };
537
538        unsafe { sys::eviocgkeycode_v2(self.as_raw_fd(), &mut keymap)? };
539        Ok((
540            keymap.keycode,
541            keymap.scancode[..keymap.len as usize].to_vec(),
542        ))
543    }
544
545    /// Update a scancode by index. The return value is the previous keycode
546    pub fn update_scancode_by_index(
547        &self,
548        index: u16,
549        keycode: u32,
550        scancode: &[u8],
551    ) -> io::Result<u32> {
552        let len = scancode.len();
553
554        let mut keymap = libc::input_keymap_entry {
555            flags: INPUT_KEYMAP_BY_INDEX,
556            len: len as u8,
557            index,
558            keycode,
559            scancode: [0u8; 32],
560        };
561
562        keymap.scancode[..len].copy_from_slice(scancode);
563
564        let keycode = unsafe { sys::eviocskeycode_v2(self.as_raw_fd(), &keymap)? };
565
566        Ok(keycode as u32)
567    }
568
569    /// Update a scancode. The return value is the previous keycode
570    pub fn update_scancode(&self, keycode: u32, scancode: &[u8]) -> io::Result<u32> {
571        let len = scancode.len();
572
573        let mut keymap = libc::input_keymap_entry {
574            flags: 0,
575            len: len as u8,
576            index: 0,
577            keycode,
578            scancode: [0u8; 32],
579        };
580
581        keymap.scancode[..len].copy_from_slice(scancode);
582
583        let keycode = unsafe { sys::eviocskeycode_v2(self.as_raw_fd(), &keymap)? };
584
585        Ok(keycode as u32)
586    }
587
588    #[cfg(feature = "tokio")]
589    #[inline]
590    pub fn into_event_stream(self) -> io::Result<EventStream> {
591        EventStream::new(self)
592    }
593
594    pub fn grab(&mut self) -> io::Result<()> {
595        if !self.grabbed {
596            unsafe {
597                sys::eviocgrab(self.as_raw_fd(), 1)?;
598            }
599            self.grabbed = true;
600        }
601        Ok(())
602    }
603
604    pub fn ungrab(&mut self) -> io::Result<()> {
605        if self.grabbed {
606            unsafe {
607                sys::eviocgrab(self.as_raw_fd(), 0)?;
608            }
609            self.grabbed = false;
610        }
611        Ok(())
612    }
613}
614
615impl AsRawFd for RawDevice {
616    fn as_raw_fd(&self) -> RawFd {
617        self.file.as_raw_fd()
618    }
619}
620
621/// A copy of the unstable Vec::spare_capacity_mut
622#[inline]
623fn vec_spare_capacity_mut<T>(v: &mut Vec<T>) -> &mut [mem::MaybeUninit<T>] {
624    let (len, cap) = (v.len(), v.capacity());
625    unsafe {
626        std::slice::from_raw_parts_mut(
627            v.as_mut_ptr().add(len) as *mut mem::MaybeUninit<T>,
628            cap - len,
629        )
630    }
631}
632
633/// Crawls `/dev/input` for evdev devices.
634///
635/// Will not bubble up any errors in opening devices or traversing the directory. Instead returns
636/// an empty iterator or omits the devices that could not be opened.
637pub fn enumerate() -> EnumerateDevices {
638    EnumerateDevices {
639        readdir: std::fs::read_dir("/dev/input").ok(),
640    }
641}
642
643pub struct EnumerateDevices {
644    readdir: Option<std::fs::ReadDir>,
645}
646impl Iterator for EnumerateDevices {
647    type Item = RawDevice;
648    fn next(&mut self) -> Option<RawDevice> {
649        use std::os::unix::ffi::OsStrExt;
650        let readdir = self.readdir.as_mut()?;
651        loop {
652            if let Ok(entry) = readdir.next()? {
653                let path = entry.path();
654                let fname = path.file_name().unwrap();
655                if fname.as_bytes().starts_with(b"event") {
656                    if let Ok(dev) = RawDevice::open(&path) {
657                        return Some(dev);
658                    }
659                }
660            }
661        }
662    }
663}
664
665#[cfg(feature = "tokio")]
666mod tokio_stream {
667    use super::*;
668
669    use tokio_1 as tokio;
670
671    use futures_core::{ready, Stream};
672    use std::pin::Pin;
673    use std::task::{Context, Poll};
674    use tokio::io::unix::AsyncFd;
675
676    /// An asynchronous stream of input events.
677    ///
678    /// This can be used by calling [`stream.next_event().await?`](Self::next_event), or if you
679    /// need to pass it as a stream somewhere, the [`futures::Stream`](Stream) implementation.
680    /// There's also a lower-level [`poll_event`] function if you need to fetch an event from
681    /// inside a `Future::poll` impl.
682    pub struct EventStream {
683        device: AsyncFd<RawDevice>,
684        index: usize,
685    }
686    impl Unpin for EventStream {}
687
688    impl EventStream {
689        pub(crate) fn new(device: RawDevice) -> io::Result<Self> {
690            use nix::fcntl;
691            fcntl::fcntl(device.as_raw_fd(), fcntl::F_SETFL(fcntl::OFlag::O_NONBLOCK))?;
692            let device = AsyncFd::new(device)?;
693            Ok(Self { device, index: 0 })
694        }
695
696        /// Returns a reference to the underlying device
697        pub fn device(&self) -> &RawDevice {
698            self.device.get_ref()
699        }
700
701        /// Try to wait for the next event in this stream. Any errors are likely to be fatal, i.e.
702        /// any calls afterwards will likely error as well.
703        pub async fn next_event(&mut self) -> io::Result<InputEvent> {
704            poll_fn(|cx| self.poll_event(cx)).await
705        }
706
707        /// A lower-level function for directly polling this stream.
708        pub fn poll_event(&mut self, cx: &mut Context<'_>) -> Poll<io::Result<InputEvent>> {
709            'outer: loop {
710                if let Some(&ev) = self.device.get_ref().event_buf.get(self.index) {
711                    self.index += 1;
712                    return Poll::Ready(Ok(InputEvent(ev)));
713                }
714
715                self.device.get_mut().event_buf.clear();
716                self.index = 0;
717
718                loop {
719                    let mut guard = ready!(self.device.poll_read_ready_mut(cx))?;
720
721                    let res = guard.try_io(|device| device.get_mut().fill_events());
722                    match res {
723                        Ok(res) => {
724                            let _ = res?;
725                            continue 'outer;
726                        }
727                        Err(_would_block) => continue,
728                    }
729                }
730            }
731        }
732    }
733
734    impl Stream for EventStream {
735        type Item = io::Result<InputEvent>;
736        fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
737            self.get_mut().poll_event(cx).map(Some)
738        }
739    }
740
741    // version of futures_util::future::poll_fn
742    pub(crate) fn poll_fn<T, F: FnMut(&mut Context<'_>) -> Poll<T> + Unpin>(f: F) -> PollFn<F> {
743        PollFn(f)
744    }
745    pub(crate) struct PollFn<F>(F);
746    impl<T, F: FnMut(&mut Context<'_>) -> Poll<T> + Unpin> std::future::Future for PollFn<F> {
747        type Output = T;
748        fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
749            (self.get_mut().0)(cx)
750        }
751    }
752}
753#[cfg(feature = "tokio")]
754pub(crate) use tokio_stream::poll_fn;
755#[cfg(feature = "tokio")]
756pub use tokio_stream::EventStream;