evdev/
sync_stream.rs

1use crate::compat::{input_absinfo, input_event};
2use crate::constants::*;
3use crate::device_state::DeviceState;
4use crate::ff::*;
5use crate::raw_stream::RawDevice;
6use crate::{
7    AbsInfo, AttributeSet, AttributeSetRef, AutoRepeat, EventSummary, FFEffect, InputEvent,
8    InputId, KeyCode,
9};
10
11use nix::fcntl;
12use std::fs::File;
13use std::os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd};
14use std::path::Path;
15use std::time::SystemTime;
16use std::{fmt, io};
17
18/// A physical or virtual device supported by evdev.
19///
20/// Each device corresponds to a path typically found in `/dev/input`, and supports access via
21/// one or more "types". For example, an optical mouse has buttons that are represented by "keys",
22/// and reflects changes in its position via "relative axis" reports.
23///
24/// This type specifically is a wrapper over [`RawDevice`],that synchronizes with the kernel's
25/// state when events are dropped.
26///
27/// If `fetch_events()` isn't called often enough and the kernel drops events from its internal
28/// buffer, synthetic events will be injected into the iterator returned by `fetch_events()` and
29/// [`Device::cached_state()`] will be kept up to date when `fetch_events()` is called.
30pub struct Device {
31    raw: RawDevice,
32    prev_state: DeviceState,
33    state: DeviceState,
34    block_dropped: bool,
35}
36
37impl Device {
38    /// Opens a device, given its system path.
39    ///
40    /// Paths are typically something like `/dev/input/event0`.
41    #[inline(always)]
42    pub fn open(path: impl AsRef<Path>) -> io::Result<Device> {
43        Self::_open(path.as_ref())
44    }
45
46    /// Opens a device, given an already opened file descriptor.
47    #[inline(always)]
48    pub fn from_fd(fd: OwnedFd) -> io::Result<Device> {
49        RawDevice::from_fd(fd).map(Self::from_raw_device)
50    }
51
52    #[inline]
53    fn _open(path: &Path) -> io::Result<Device> {
54        RawDevice::open(path).map(Self::from_raw_device)
55    }
56
57    // TODO: should this be public?
58    pub(crate) fn from_raw_device(raw: RawDevice) -> Device {
59        let state = DeviceState::new(&raw);
60        let prev_state = state.clone();
61
62        Device {
63            raw,
64            prev_state,
65            state,
66            block_dropped: false,
67        }
68    }
69
70    /// Returns the synchronization engine's current understanding (cache) of the device state.
71    ///
72    /// Note that this represents the internal cache of the synchronization engine as of the last
73    /// entry that was pulled out. The advantage to calling this instead of invoking
74    /// [`get_key_state`](RawDevice::get_key_state)
75    /// and the like directly is speed: because reading this cache doesn't require any syscalls it's
76    /// easy to do inside a tight loop. The downside is that if the stream is not being driven quickly,
77    /// this can very quickly get desynchronized from the kernel and provide inaccurate data.
78    pub fn cached_state(&self) -> &DeviceState {
79        &self.state
80    }
81
82    /// Returns the device's name as read from the kernel.
83    pub fn name(&self) -> Option<&str> {
84        self.raw.name()
85    }
86
87    /// Returns the device's physical location, either as set by the caller or as read from the kernel.
88    pub fn physical_path(&self) -> Option<&str> {
89        self.raw.physical_path()
90    }
91
92    /// Returns the user-defined "unique name" of the device, if one has been set.
93    pub fn unique_name(&self) -> Option<&str> {
94        self.raw.unique_name()
95    }
96
97    /// Returns a struct containing bustype, vendor, product, and version identifiers
98    pub fn input_id(&self) -> InputId {
99        self.raw.input_id()
100    }
101
102    /// Returns a struct containing the delay and period for auto repeat
103    pub fn get_auto_repeat(&self) -> Option<AutoRepeat> {
104        self.raw.get_auto_repeat()
105    }
106
107    /// Update the delay and period for autorepeat
108    pub fn update_auto_repeat(&mut self, repeat: &AutoRepeat) -> io::Result<()> {
109        self.raw.update_auto_repeat(repeat)
110    }
111
112    /// Retrieve the scancode for a keycode, if any
113    pub fn get_scancode_by_keycode(&self, keycode: KeyCode) -> io::Result<Vec<u8>> {
114        self.raw.get_scancode_by_keycode(keycode.code() as u32)
115    }
116
117    /// Retrieve the keycode and scancode by index, starting at 0
118    pub fn get_scancode_by_index(&self, index: u16) -> io::Result<(u32, Vec<u8>)> {
119        self.raw.get_scancode_by_index(index)
120    }
121
122    /// Update a scancode. The return value is the previous keycode
123    pub fn update_scancode(&self, keycode: KeyCode, scancode: &[u8]) -> io::Result<KeyCode> {
124        self.raw
125            .update_scancode(keycode.code() as u32, scancode)
126            .map(|keycode| KeyCode::new(keycode as u16))
127    }
128
129    /// Update a scancode by index. The return value is the previous keycode
130    pub fn update_scancode_by_index(
131        &self,
132        index: u16,
133        keycode: KeyCode,
134        scancode: &[u8],
135    ) -> io::Result<u32> {
136        self.raw
137            .update_scancode_by_index(index, keycode.code() as u32, scancode)
138    }
139
140    /// Returns the set of supported "properties" for the device (see `INPUT_PROP_*` in kernel headers)
141    pub fn properties(&self) -> &AttributeSetRef<PropType> {
142        self.raw.properties()
143    }
144
145    /// Returns a tuple of the driver version containing major, minor, rev
146    pub fn driver_version(&self) -> (u8, u8, u8) {
147        self.raw.driver_version()
148    }
149
150    /// Returns a set of the event types supported by this device (KeyType, Switch, etc)
151    ///
152    /// If you're interested in the individual keys or switches supported, it's probably easier
153    /// to just call the appropriate `supported_*` function instead.
154    pub fn supported_events(&self) -> &AttributeSetRef<EventType> {
155        self.raw.supported_events()
156    }
157
158    /// Returns the set of supported keys reported by the device.
159    ///
160    /// For keyboards, this is the set of all possible keycodes the keyboard may emit. Controllers,
161    /// mice, and other peripherals may also report buttons as keys.
162    ///
163    /// # Examples
164    ///
165    /// ```no_run
166    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
167    /// use evdev::{Device, KeyCode};
168    /// let device = Device::open("/dev/input/event0")?;
169    ///
170    /// // Does this device have an ENTER key?
171    /// let supported = device.supported_keys().map_or(false, |keys| keys.contains(KeyCode::KEY_ENTER));
172    /// # Ok(())
173    /// # }
174    /// ```
175    pub fn supported_keys(&self) -> Option<&AttributeSetRef<KeyCode>> {
176        self.raw.supported_keys()
177    }
178
179    /// Returns the set of supported "relative axes" reported by the device.
180    ///
181    /// Standard mice will generally report `REL_X` and `REL_Y` along with wheel if supported.
182    ///
183    /// # Examples
184    ///
185    /// ```no_run
186    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
187    /// use evdev::{Device, RelativeAxisCode};
188    /// let device = Device::open("/dev/input/event0")?;
189    ///
190    /// // Does the device have a scroll wheel?
191    /// let supported = device
192    ///     .supported_relative_axes()
193    ///     .map_or(false, |axes| axes.contains(RelativeAxisCode::REL_WHEEL));
194    /// # Ok(())
195    /// # }
196    /// ```
197    pub fn supported_relative_axes(&self) -> Option<&AttributeSetRef<RelativeAxisCode>> {
198        self.raw.supported_relative_axes()
199    }
200
201    /// Returns the set of supported "absolute axes" reported by the device.
202    ///
203    /// These are most typically supported by joysticks and touchpads.
204    ///
205    /// # Examples
206    ///
207    /// ```no_run
208    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
209    /// use evdev::{Device, AbsoluteAxisCode};
210    /// let device = Device::open("/dev/input/event0")?;
211    ///
212    /// // Does the device have an absolute X axis?
213    /// let supported = device
214    ///     .supported_absolute_axes()
215    ///     .map_or(false, |axes| axes.contains(AbsoluteAxisCode::ABS_X));
216    /// # Ok(())
217    /// # }
218    /// ```
219    pub fn supported_absolute_axes(&self) -> Option<&AttributeSetRef<AbsoluteAxisCode>> {
220        self.raw.supported_absolute_axes()
221    }
222
223    /// Returns the set of supported switches reported by the device.
224    ///
225    /// These are typically used for things like software switches on laptop lids (which the
226    /// system reacts to by suspending or locking), or virtual switches to indicate whether a
227    /// headphone jack is plugged in (used to disable external speakers).
228    ///
229    /// # Examples
230    ///
231    /// ```no_run
232    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
233    /// use evdev::{Device, SwitchCode};
234    /// let device = Device::open("/dev/input/event0")?;
235    ///
236    /// // Does the device report a laptop lid switch?
237    /// let supported = device
238    ///     .supported_switches()
239    ///     .map_or(false, |axes| axes.contains(SwitchCode::SW_LID));
240    /// # Ok(())
241    /// # }
242    /// ```
243    pub fn supported_switches(&self) -> Option<&AttributeSetRef<SwitchCode>> {
244        self.raw.supported_switches()
245    }
246
247    /// Returns a set of supported LEDs on the device.
248    ///
249    /// Most commonly these are state indicator lights for things like Scroll Lock, but they
250    /// can also be found in cameras and other devices.
251    pub fn supported_leds(&self) -> Option<&AttributeSetRef<LedCode>> {
252        self.raw.supported_leds()
253    }
254
255    /// Returns a set of supported "miscellaneous" capabilities.
256    ///
257    /// Aside from vendor-specific key scancodes, most of these are uncommon.
258    pub fn misc_properties(&self) -> Option<&AttributeSetRef<MiscCode>> {
259        self.raw.misc_properties()
260    }
261
262    /// Returns the set of supported force feedback effects supported by a device.
263    pub fn supported_ff(&self) -> Option<&AttributeSetRef<FFEffectCode>> {
264        self.raw.supported_ff()
265    }
266
267    /// Returns the maximum number of force feedback effects that can be played simultaneously.
268    pub fn max_ff_effects(&self) -> usize {
269        self.raw.max_ff_effects()
270    }
271
272    /// Returns the set of supported simple sounds supported by a device.
273    ///
274    /// You can use these to make really annoying beep sounds come from an internal self-test
275    /// speaker, for instance.
276    pub fn supported_sounds(&self) -> Option<&AttributeSetRef<SoundCode>> {
277        self.raw.supported_sounds()
278    }
279
280    /// Retrieve the current keypress state directly via kernel syscall.
281    pub fn get_key_state(&self) -> io::Result<AttributeSet<KeyCode>> {
282        self.raw.get_key_state()
283    }
284
285    /// Retrieve the current absolute axis state directly via kernel syscall.
286    pub fn get_abs_state(&self) -> io::Result<[input_absinfo; AbsoluteAxisCode::COUNT]> {
287        self.raw.get_abs_state()
288    }
289
290    /// Get the AbsInfo for each supported AbsoluteAxis
291    pub fn get_absinfo(
292        &self,
293    ) -> io::Result<impl Iterator<Item = (AbsoluteAxisCode, AbsInfo)> + '_> {
294        self.raw.get_absinfo()
295    }
296
297    /// Retrieve the current switch state directly via kernel syscall.
298    pub fn get_switch_state(&self) -> io::Result<AttributeSet<SwitchCode>> {
299        self.raw.get_switch_state()
300    }
301
302    /// Retrieve the current LED state directly via kernel syscall.
303    pub fn get_led_state(&self) -> io::Result<AttributeSet<LedCode>> {
304        self.raw.get_led_state()
305    }
306
307    fn sync_state(&mut self, now: SystemTime) -> io::Result<()> {
308        if let Some(ref mut key_vals) = self.state.key_vals {
309            self.raw.update_key_state(key_vals)?;
310        }
311        if let Some(ref mut abs_vals) = self.state.abs_vals {
312            self.raw.update_abs_state(abs_vals)?;
313        }
314        if let Some(ref mut switch_vals) = self.state.switch_vals {
315            self.raw.update_switch_state(switch_vals)?;
316        }
317        if let Some(ref mut led_vals) = self.state.led_vals {
318            self.raw.update_led_state(led_vals)?;
319        }
320        self.state.timestamp = now;
321        Ok(())
322    }
323
324    fn fetch_events_inner(&mut self) -> io::Result<Option<SyncState>> {
325        let block_dropped = std::mem::take(&mut self.block_dropped);
326        let sync = if block_dropped {
327            self.prev_state.clone_from(&self.state);
328            let now = SystemTime::now();
329            self.sync_state(now)?;
330            Some(SyncState::KeyTypes {
331                time: crate::systime_to_timeval(&now),
332                start: KeyCode::new(0),
333            })
334        } else {
335            None
336        };
337
338        self.raw.fill_events()?;
339
340        Ok(sync)
341    }
342
343    /// Fetches and returns events from the kernel ring buffer, doing synchronization on SYN_DROPPED.
344    ///
345    /// By default this will block until events are available. Typically, users will want to call
346    /// this in a tight loop within a thread.
347    /// Will insert "fake" events.
348    pub fn fetch_events(&mut self) -> io::Result<FetchEventsSynced<'_>> {
349        let sync = self.fetch_events_inner()?;
350
351        Ok(FetchEventsSynced {
352            dev: self,
353            range: 0..0,
354            consumed_to: 0,
355            sync,
356        })
357    }
358
359    #[cfg(feature = "tokio")]
360    pub fn into_event_stream(self) -> io::Result<EventStream> {
361        EventStream::new(self)
362    }
363
364    /// Set `O_NONBLOCK` on this device handle.
365    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
366        let mut flags =
367            fcntl::OFlag::from_bits_retain(fcntl::fcntl(self.as_raw_fd(), fcntl::F_GETFL)?);
368        flags.set(fcntl::OFlag::O_NONBLOCK, nonblocking);
369        fcntl::fcntl(self.as_raw_fd(), fcntl::F_SETFL(flags))?;
370        Ok(())
371    }
372
373    /// Grab the device through a kernel syscall.
374    ///
375    /// This prevents other clients (including kernel-internal ones such as rfkill) from receiving
376    /// events from this device.
377    pub fn grab(&mut self) -> io::Result<()> {
378        self.raw.grab()
379    }
380
381    /// Ungrab the device through a kernel syscall.
382    pub fn ungrab(&mut self) -> io::Result<()> {
383        self.raw.ungrab()
384    }
385
386    /// Send an event to the device.
387    ///
388    /// Events that are typically sent to devices are
389    /// [EventType::LED] (turn device LEDs on and off),
390    /// [EventType::SOUND] (play a sound on the device)
391    /// and [EventType::FORCEFEEDBACK] (play force feedback effects on the device, i.e. rumble).
392    pub fn send_events(&mut self, events: &[InputEvent]) -> io::Result<()> {
393        self.raw.send_events(events)
394    }
395
396    /// Uploads a force feedback effect to the device.
397    pub fn upload_ff_effect(&mut self, data: FFEffectData) -> io::Result<FFEffect> {
398        self.raw.upload_ff_effect(data)
399    }
400
401    /// Sets the force feedback gain, i.e. how strong the force feedback effects should be for the
402    /// device. A gain of 0 means no gain, whereas `u16::MAX` is the maximum gain.
403    pub fn set_ff_gain(&mut self, value: u16) -> io::Result<()> {
404        self.raw.set_ff_gain(value)
405    }
406
407    /// Enables or disables autocenter for the force feedback device.
408    pub fn set_ff_autocenter(&mut self, value: u16) -> io::Result<()> {
409        self.raw.set_ff_autocenter(value)
410    }
411}
412
413impl AsFd for Device {
414    fn as_fd(&self) -> BorrowedFd<'_> {
415        self.raw.as_fd()
416    }
417}
418
419impl AsRawFd for Device {
420    fn as_raw_fd(&self) -> RawFd {
421        self.raw.as_raw_fd()
422    }
423}
424
425impl TryFrom<File> for Device {
426    type Error = io::Error;
427
428    fn try_from(file: File) -> Result<Self, Self::Error> {
429        RawDevice::try_from(file).map(Self::from_raw_device)
430    }
431}
432
433/// An iterator over events of a [`Device`], produced by [`Device::fetch_events`].
434pub struct FetchEventsSynced<'a> {
435    dev: &'a mut Device,
436    /// The current block of the events we're returning to the consumer. If empty
437    /// (i.e. for any x, range == x..x) then we'll find another block on the next `next()` call.
438    range: std::ops::Range<usize>,
439    /// The index into dev.raw.event_buf up to which we'll delete events when dropped.
440    consumed_to: usize,
441    /// Our current synchronization state, i.e. whether we're currently diffing key_vals,
442    /// abs_vals, switch_vals, led_vals, or none of them.
443    sync: Option<SyncState>,
444}
445
446enum SyncState {
447    KeyTypes {
448        time: libc::timeval,
449        start: KeyCode,
450    },
451    Absolutes {
452        time: libc::timeval,
453        start: AbsoluteAxisCode,
454    },
455    Switches {
456        time: libc::timeval,
457        start: SwitchCode,
458    },
459    Leds {
460        time: libc::timeval,
461        start: LedCode,
462    },
463}
464
465#[inline]
466fn compensate_events(state: &mut Option<SyncState>, dev: &mut Device) -> Option<InputEvent> {
467    let sync = state.as_mut()?;
468    // this macro checks if there are any differences between the old state and the new for the
469    // specific substate(?) that we're checking and if so returns an input_event with the value set
470    // to the value from the up-to-date state
471    macro_rules! try_compensate {
472        ($time:expr, $start:ident : $typ:ident, $evtype:ident, $sync:ident, $supporteds:ident, $state:ty, $get_state:expr, $get_value:expr) => {
473            if let Some(supported_types) = dev.$supporteds() {
474                let types_to_check = supported_types.slice(*$start);
475                let get_state: fn(&DeviceState) -> $state = $get_state;
476                let vals = get_state(&dev.state);
477                let old_vals = get_state(&dev.prev_state);
478                let get_value: fn($state, $typ) -> _ = $get_value;
479                for typ in types_to_check.iter() {
480                    let prev = get_value(old_vals, typ);
481                    let value = get_value(vals, typ);
482                    if prev != value {
483                        $start.0 = typ.0 + 1;
484                        let ev = InputEvent::from(input_event {
485                            time: *$time,
486                            type_: EventType::$evtype.0,
487                            code: typ.0,
488                            value: value as _,
489                        });
490                        return Some(ev);
491                    }
492                }
493            }
494        };
495    }
496    loop {
497        // check keys, then abs axes, then switches, then leds
498        match sync {
499            SyncState::KeyTypes { time, start } => {
500                try_compensate!(
501                    time,
502                    start: KeyCode,
503                    KEY,
504                    KeyTypes,
505                    supported_keys,
506                    &AttributeSetRef<KeyCode>,
507                    |st| st.key_vals().unwrap(),
508                    |vals, key| vals.contains(key)
509                );
510                *sync = SyncState::Absolutes {
511                    time: *time,
512                    start: AbsoluteAxisCode(0),
513                };
514                continue;
515            }
516            SyncState::Absolutes { time, start } => {
517                try_compensate!(
518                    time,
519                    start: AbsoluteAxisCode,
520                    ABSOLUTE,
521                    Absolutes,
522                    supported_absolute_axes,
523                    &[input_absinfo],
524                    |st| st.abs_vals().unwrap(),
525                    |vals, abs| vals[abs.0 as usize].value
526                );
527                *sync = SyncState::Switches {
528                    time: *time,
529                    start: SwitchCode(0),
530                };
531                continue;
532            }
533            SyncState::Switches { time, start } => {
534                try_compensate!(
535                    time,
536                    start: SwitchCode,
537                    SWITCH,
538                    Switches,
539                    supported_switches,
540                    &AttributeSetRef<SwitchCode>,
541                    |st| st.switch_vals().unwrap(),
542                    |vals, sw| vals.contains(sw)
543                );
544                *sync = SyncState::Leds {
545                    time: *time,
546                    start: LedCode(0),
547                };
548                continue;
549            }
550            SyncState::Leds { time, start } => {
551                try_compensate!(
552                    time,
553                    start: LedCode,
554                    LED,
555                    Leds,
556                    supported_leds,
557                    &AttributeSetRef<LedCode>,
558                    |st| st.led_vals().unwrap(),
559                    |vals, led| vals.contains(led)
560                );
561                let ev = InputEvent::from(input_event {
562                    time: *time,
563                    type_: EventType::SYNCHRONIZATION.0,
564                    code: SynchronizationCode::SYN_REPORT.0,
565                    value: 0,
566                });
567                *state = None;
568                return Some(ev);
569            }
570        }
571    }
572}
573
574impl Iterator for FetchEventsSynced<'_> {
575    type Item = InputEvent;
576    fn next(&mut self) -> Option<InputEvent> {
577        // first: check if we need to emit compensatory events due to a SYN_DROPPED we found in the
578        // last batch of blocks
579        if let Some(ev) = compensate_events(&mut self.sync, self.dev) {
580            self.dev.prev_state.process_event(ev);
581            return Some(ev);
582        }
583        let state = &mut self.dev.state;
584        let (res, consumed_to) = sync_events(&mut self.range, &self.dev.raw.event_buf, |ev| {
585            state.process_event(ev)
586        });
587        if let Some(end) = consumed_to {
588            self.consumed_to = end
589        }
590        match res {
591            Ok(ev) => Some(InputEvent::from(ev)),
592            Err(requires_sync) => {
593                if requires_sync {
594                    self.dev.block_dropped = true;
595                }
596                None
597            }
598        }
599    }
600}
601
602impl Drop for FetchEventsSynced<'_> {
603    fn drop(&mut self) {
604        self.dev.raw.event_buf.drain(..self.consumed_to);
605    }
606}
607
608/// Err(true) means the device should sync the state with ioctl
609#[inline]
610fn sync_events(
611    range: &mut std::ops::Range<usize>,
612    event_buf: &[input_event],
613    mut handle_event: impl FnMut(InputEvent),
614) -> (Result<input_event, bool>, Option<usize>) {
615    let mut consumed_to = None;
616    let res = 'outer: loop {
617        if let Some(idx) = range.next() {
618            // we're going through and emitting the events of a block that we checked
619            break Ok(event_buf[idx]);
620        }
621        // find the range of this new block: look for a SYN_REPORT
622        let block_start = range.end;
623        let mut block_dropped = false;
624        for (i, ev) in event_buf.iter().enumerate().skip(block_start) {
625            let ev = InputEvent::from(*ev);
626            match ev.destructure() {
627                EventSummary::Synchronization(_, SynchronizationCode::SYN_DROPPED, _) => {
628                    block_dropped = true;
629                }
630                EventSummary::Synchronization(_, SynchronizationCode::SYN_REPORT, _) => {
631                    consumed_to = Some(i + 1);
632                    if block_dropped {
633                        *range = event_buf.len()..event_buf.len();
634                        break 'outer Err(true);
635                    } else {
636                        *range = block_start..i + 1;
637                        continue 'outer;
638                    }
639                }
640                _ => handle_event(ev),
641            }
642        }
643        break Err(false);
644    };
645    (res, consumed_to)
646}
647
648impl fmt::Display for Device {
649    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
650        writeln!(f, "{}:", self.name().unwrap_or("Unnamed device"))?;
651        let (maj, min, pat) = self.driver_version();
652        writeln!(f, "  Driver version: {maj}.{min}.{pat}")?;
653        if let Some(ref phys) = self.physical_path() {
654            writeln!(f, "  Physical address: {phys:?}")?;
655        }
656        if let Some(ref uniq) = self.unique_name() {
657            writeln!(f, "  Unique name: {uniq:?}")?;
658        }
659
660        let id = self.input_id();
661
662        writeln!(f, "  Bus: {}", id.bus_type())?;
663        writeln!(f, "  Vendor: {:#x}", id.vendor())?;
664        writeln!(f, "  Product: {:#x}", id.product())?;
665        writeln!(f, "  Version: {:#x}", id.version())?;
666        writeln!(f, "  Properties: {:?}", self.properties())?;
667
668        if let (Some(supported_keys), Some(key_vals)) =
669            (self.supported_keys(), self.state.key_vals())
670        {
671            writeln!(f, "  KeyTypes supported:")?;
672            for key in supported_keys.iter() {
673                let key_idx = key.code() as usize;
674                writeln!(
675                    f,
676                    "    {:?} ({}index {})",
677                    key,
678                    if key_vals.contains(key) {
679                        "pressed, "
680                    } else {
681                        ""
682                    },
683                    key_idx
684                )?;
685            }
686        }
687
688        if let Some(supported_relative) = self.supported_relative_axes() {
689            writeln!(f, "  Relative Axes: {supported_relative:?}")?;
690        }
691
692        if let (Some(supported_abs), Some(abs_vals)) =
693            (self.supported_absolute_axes(), &self.state.abs_vals)
694        {
695            writeln!(f, "  Absolute Axes:")?;
696            for abs in supported_abs.iter() {
697                writeln!(
698                    f,
699                    "    {:?} ({:?}, index {})",
700                    abs, abs_vals[abs.0 as usize], abs.0
701                )?;
702            }
703        }
704
705        if let Some(supported_misc) = self.misc_properties() {
706            writeln!(f, "  Miscellaneous capabilities: {supported_misc:?}")?;
707        }
708
709        if let (Some(supported_switch), Some(switch_vals)) =
710            (self.supported_switches(), self.state.switch_vals())
711        {
712            writeln!(f, "  Switches:")?;
713            for sw in supported_switch.iter() {
714                writeln!(
715                    f,
716                    "    {:?} ({:?}, index {})",
717                    sw,
718                    switch_vals.contains(sw),
719                    sw.0
720                )?;
721            }
722        }
723
724        if let (Some(supported_led), Some(led_vals)) =
725            (self.supported_leds(), self.state.led_vals())
726        {
727            writeln!(f, "  LEDs:")?;
728            for led in supported_led.iter() {
729                writeln!(
730                    f,
731                    "    {:?} ({:?}, index {})",
732                    led,
733                    led_vals.contains(led),
734                    led.0
735                )?;
736            }
737        }
738
739        if let Some(supported_snd) = self.supported_sounds() {
740            write!(f, "  Sounds:")?;
741            for snd in supported_snd.iter() {
742                writeln!(f, "    {:?} (index {})", snd, snd.0)?;
743            }
744        }
745
746        // if let Some(rep) = self.rep {
747        //     writeln!(f, "  Repeats: {:?}", rep)?;
748        // }
749
750        let evs = self.supported_events();
751
752        if evs.contains(EventType::FORCEFEEDBACK) {
753            writeln!(f, "  Force Feedback supported")?;
754        }
755
756        if evs.contains(EventType::POWER) {
757            writeln!(f, "  Power supported")?;
758        }
759
760        if evs.contains(EventType::FORCEFEEDBACKSTATUS) {
761            writeln!(f, "  Force Feedback status supported")?;
762        }
763
764        Ok(())
765    }
766}
767
768#[cfg(feature = "tokio")]
769mod tokio_stream {
770    use super::*;
771
772    use std::future::poll_fn;
773    use std::task::{ready, Context, Poll};
774    use tokio::io::unix::AsyncFd;
775
776    /// An asynchronous stream of input events.
777    ///
778    /// This can be used by calling [`stream.next_event().await?`](Self::next_event), or if you
779    /// need to pass it as a stream somewhere, the [`futures::Stream`](Stream) implementation.
780    /// There's also a lower-level [`Self::poll_event`] function if you need to fetch an event from
781    /// inside a `Future::poll` impl.
782    pub struct EventStream {
783        device: AsyncFd<Device>,
784        event_range: std::ops::Range<usize>,
785        consumed_to: usize,
786        sync: Option<SyncState>,
787    }
788    impl Unpin for EventStream {}
789
790    impl EventStream {
791        pub(crate) fn new(device: Device) -> io::Result<Self> {
792            device.set_nonblocking(true)?;
793            let device = AsyncFd::new(device)?;
794            Ok(Self {
795                device,
796                event_range: 0..0,
797                consumed_to: 0,
798                sync: None,
799            })
800        }
801
802        /// Returns a reference to the underlying device
803        pub fn device(&self) -> &Device {
804            self.device.get_ref()
805        }
806
807        /// Returns a mutable reference to the underlying device
808        pub fn device_mut(&mut self) -> &mut Device {
809            self.device.get_mut()
810        }
811
812        /// Try to wait for the next event in this stream. Any errors are likely to be fatal, i.e.
813        /// any calls afterwards will likely error as well.
814        pub async fn next_event(&mut self) -> io::Result<InputEvent> {
815            poll_fn(|cx| self.poll_event(cx)).await
816        }
817
818        /// A lower-level function for directly polling this stream.
819        pub fn poll_event(&mut self, cx: &mut Context<'_>) -> Poll<io::Result<InputEvent>> {
820            'outer: loop {
821                let dev = self.device.get_mut();
822                if let Some(ev) = compensate_events(&mut self.sync, dev) {
823                    return Poll::Ready(Ok(ev));
824                }
825                let state = &mut dev.state;
826                let (res, consumed_to) =
827                    sync_events(&mut self.event_range, &dev.raw.event_buf, |ev| {
828                        state.process_event(ev)
829                    });
830                if let Some(end) = consumed_to {
831                    self.consumed_to = end
832                }
833                match res {
834                    Ok(ev) => return Poll::Ready(Ok(InputEvent::from(ev))),
835                    Err(requires_sync) => {
836                        if requires_sync {
837                            dev.block_dropped = true;
838                        }
839                    }
840                }
841                dev.raw.event_buf.drain(..self.consumed_to);
842                self.consumed_to = 0;
843
844                loop {
845                    let mut guard = ready!(self.device.poll_read_ready_mut(cx))?;
846
847                    let res = guard.try_io(|device| device.get_mut().fetch_events_inner());
848                    match res {
849                        Ok(res) => {
850                            self.sync = res?;
851                            self.event_range = 0..0;
852                            continue 'outer;
853                        }
854                        Err(_would_block) => continue,
855                    }
856                }
857            }
858        }
859    }
860
861    #[cfg(feature = "stream-trait")]
862    impl futures_core::Stream for EventStream {
863        type Item = io::Result<InputEvent>;
864        fn poll_next(
865            self: std::pin::Pin<&mut Self>,
866            cx: &mut Context<'_>,
867        ) -> Poll<Option<Self::Item>> {
868            self.get_mut().poll_event(cx).map(Some)
869        }
870    }
871}
872#[cfg(feature = "tokio")]
873pub use tokio_stream::EventStream;
874
875#[cfg(test)]
876mod tests {
877    use super::*;
878
879    fn result_events_iter(
880        events: &[input_event],
881    ) -> impl Iterator<Item = Result<input_event, ()>> + '_ {
882        let mut range = 0..0;
883        std::iter::from_fn(move || {
884            let (res, _) = sync_events(&mut range, events, |_| {});
885            match res {
886                Ok(x) => Some(Ok(x)),
887                Err(true) => Some(Err(())),
888                Err(false) => None,
889            }
890        })
891    }
892
893    fn events_iter(events: &[input_event]) -> impl Iterator<Item = input_event> + '_ {
894        result_events_iter(events).flatten()
895    }
896
897    #[allow(non_upper_case_globals)]
898    const time: libc::timeval = libc::timeval {
899        tv_sec: 0,
900        tv_usec: 0,
901    };
902    const KEY4: input_event = input_event {
903        time,
904        type_: EventType::KEY.0,
905        code: KeyCode::KEY_4.0,
906        value: 1,
907    };
908    const REPORT: input_event = input_event {
909        time,
910        type_: EventType::SYNCHRONIZATION.0,
911        code: SynchronizationCode::SYN_REPORT.0,
912        value: 0,
913    };
914    const DROPPED: input_event = input_event {
915        code: SynchronizationCode::SYN_DROPPED.0,
916        ..REPORT
917    };
918
919    #[test]
920    fn test_sync_impl() {
921        itertools::assert_equal(events_iter(&[]), vec![]);
922        itertools::assert_equal(events_iter(&[KEY4]), vec![]);
923        itertools::assert_equal(events_iter(&[KEY4, REPORT]), vec![KEY4, REPORT]);
924        itertools::assert_equal(events_iter(&[KEY4, REPORT, KEY4]), vec![KEY4, REPORT]);
925        itertools::assert_equal(
926            result_events_iter(&[KEY4, REPORT, KEY4, DROPPED, REPORT]),
927            vec![Ok(KEY4), Ok(REPORT), Err(())],
928        );
929    }
930
931    #[test]
932    fn test_iter_consistency() {
933        // once it sees a SYN_DROPPED, it shouldn't mark the block after it as consumed even if we
934        // keep calling the iterator like an idiot
935        let evs = &[KEY4, REPORT, DROPPED, REPORT, KEY4, REPORT, KEY4];
936        let mut range = 0..0;
937        let mut next = || sync_events(&mut range, evs, |_| {});
938        assert_eq!(next(), (Ok(KEY4), Some(2)));
939        assert_eq!(next(), (Ok(REPORT), None));
940        assert_eq!(next(), (Err(true), Some(4)));
941        assert_eq!(next(), (Err(false), None));
942        assert_eq!(next(), (Err(false), None));
943        assert_eq!(next(), (Err(false), None));
944    }
945}