pub struct Evdev { /* private fields */ }Expand description
A handle to an event device.
A device can be opened via Evdev::open or by iterating over all evdev devices using
enumerate or enumerate_hotplug.
Evdevs support non-blocking I/O for reading and writing events (but not for any
functionality that uses ioctls), which can be enabled or disabled by calling
Evdev::set_nonblocking.
Just like Files, TcpStreams, and other wrappers around file descriptors, Evdev can
be duplicated by calling Evdev::try_clone. The underlying handle will be shared between
all cloned instances.
Since multiple Evdevs can refer to the same file handle, none of the methods require a
mutable reference, again mirroring the API of TcpStream.
Implementations§
Source§impl Evdev
impl Evdev
Sourcepub fn open<P: AsRef<Path>>(path: P) -> Result<Self>
pub fn open<P: AsRef<Path>>(path: P) -> Result<Self>
Opens a filesystem path referring to an evdev node.
The path must belong to an evdev device like /dev/input/event*, not to a legacy
“joydev” device (/dev/input/js) and not to a legacy “mousedev” (/dev/input/mouse or
/dev/input/mice).
§Permissions
This method will attempt to open path with read-write permissions (allowing methods based
on Evdev::write to work), fall back to read-only permissions if the current user
does not have read and write permissions, and finally fall back to write-only permissions.
If all of these attempts fail with a io::ErrorKind::PermissionDenied error, this method
will return that error to the caller.
§Errors
This method will return an error if path doesn’t refer to a path matching
/dev/input/event* (after resolving symlinks).
Sourcepub fn path(&self) -> &Path
pub fn path(&self) -> &Path
Returns the (canonicalized) file system path this Evdev has been created from.
Sourcepub fn set_nonblocking(&self, nonblocking: bool) -> Result<bool>
pub fn set_nonblocking(&self, nonblocking: bool) -> Result<bool>
Moves this handle into or out of non-blocking mode.
Returns whether the Evdev was previously in non-blocking mode.
Evdevs start out in blocking mode, in which every attempt to read from the device
(either via Evdev::raw_events or via EventReader) will block until the next event
is available.
If the Evdev is put in non-blocking mode, attempts to read from it will no longer block,
but instead fail with io::ErrorKind::WouldBlock.
This mechanism, alongside the AsRawFd impl, can be used to integrate Evdev into an
async runtime. It can also be used by applications that want to occasionally retrieve all
the device state, but don’t want to block until new events are available (eg. games).
Note: Non-blocking mode only works for reading and writing events. It does not work for any of the other device functionality, like force-feedback effect upload, which will always block.
Sourcepub fn try_clone(&self) -> Result<Self>
pub fn try_clone(&self) -> Result<Self>
Creates a new Evdev instance that refers to the same underlying file handle.
All state of the Evdev will be shared between the instances.
Note: Care must be taken when using this method.
Functionality in this crate (like EventReader) may assume that no other file handle is
used to modify device state or read events from it.
Sourcepub fn driver_version(&self) -> Result<Version>
pub fn driver_version(&self) -> Result<Version>
Returns the evdev subsystem version.
Sourcepub fn phys(&self) -> Result<Option<String>>
pub fn phys(&self) -> Result<Option<String>>
Fetches a string describing the physical location of the device.
Possible location strings might look like:
usb-0000:02:00.0-5/input1PNP0C0C/button/input0ALSA
Returns None when the device does not have a physical location (typically because it is
a virtual device with no associated physical location; however, virtual device are allowed
to set this value to any string).
Sourcepub fn unique_id(&self) -> Result<Option<String>>
pub fn unique_id(&self) -> Result<Option<String>>
Fetches the unique identifier of this device.
For USB device, this is typically the device serial number (iSerial), which is often just
the empty string.
Sourcepub fn props(&self) -> Result<BitSet<InputProp>>
pub fn props(&self) -> Result<BitSet<InputProp>>
Fetches the set of InputProps advertised by the device.
Sourcepub fn supported_events(&self) -> Result<BitSet<EventType>>
pub fn supported_events(&self) -> Result<BitSet<EventType>>
Returns the set of supported EventTypes.
Sourcepub fn supported_switches(&self) -> Result<BitSet<Switch>>
pub fn supported_switches(&self) -> Result<BitSet<Switch>>
Returns the set of supported Switches.
Sourcepub fn supported_misc(&self) -> Result<BitSet<Misc>>
pub fn supported_misc(&self) -> Result<BitSet<Misc>>
Returns the set of supported Misc event codes.
Sourcepub fn supported_ff_features(&self) -> Result<BitSet<Feature>>
pub fn supported_ff_features(&self) -> Result<BitSet<Feature>>
Returns the set of supported force-feedback Features.
Sourcepub fn supported_ff_effects(&self) -> Result<u32>
pub fn supported_ff_effects(&self) -> Result<u32>
Returns the number of force-feedback effects the device can store at the same time.
Sourcepub fn abs_info(&self, abs: Abs) -> Result<AbsInfo>
pub fn abs_info(&self, abs: Abs) -> Result<AbsInfo>
Returns information about absolute axis abs.
The supported absolute axes can be queried by calling Evdev::supported_abs_axes.
Calling this with an Abs axis that isn’t supported by the device will either return an
error or return a meaningless AbsInfo object with arbitrary values.
Note that many devices don’t send the correct values by default, and that userspace
applications can generally override these values via Evdev::set_abs_info.
Sourcepub fn set_abs_info(&self, abs: Abs, info: AbsInfo) -> Result<()>
pub fn set_abs_info(&self, abs: Abs, info: AbsInfo) -> Result<()>
Sets the AbsInfo data associated with absolute axis abs.
The supported absolute axes can be queried by calling Evdev::supported_abs_axes.
This method should generally not be used by applications, as it modifies globally visible device properties and can lead to the device not working correctly.
Sourcepub fn grab(&self) -> Result<()>
pub fn grab(&self) -> Result<()>
Grabs this input device, making its events unavailable to other programs.
This can be undone by calling Evdev::ungrab. The kernel will automatically ungrab a
grabbed device when the program closes its file descriptor.
§Errors
This will return an error of type io::ErrorKind::ResourceBusy if the device is already
grabbed by an application (including this application; in other words, calling grab()
twice in a row will error).
Sourcepub fn ungrab(&self) -> Result<()>
pub fn ungrab(&self) -> Result<()>
Ungrabs this input device, making its events available to other programs again.
Undoes the effect of Evdev::grab.
§Errors
This will return an error of type io::ErrorKind::InvalidInput is the device is not
currently grabbed.
Sourcepub fn revoke(&self) -> Result<()>
pub fn revoke(&self) -> Result<()>
Revokes device access from this Evdev handle.
This prevents this handle from receiving any more input events, and makes writes and ioctls
(including this one) fail with ENODEV.
Sourcepub fn key_repeat(&self) -> Result<Option<KeyRepeat>>
pub fn key_repeat(&self) -> Result<Option<KeyRepeat>>
Queries the current autorepeat settings.
If the device doesn’t support key repeat, this will return Ok(None).
Whether key repeat is supported can also be determined by checking whether
EventType::REP is advertised by Evdev::supported_events.
Sourcepub fn set_key_repeat(&self, rep: KeyRepeat) -> Result<()>
pub fn set_key_repeat(&self, rep: KeyRepeat) -> Result<()>
Sets the device’s autorepeat settings.
Also see Evdev::key_repeat.
Sourcepub fn keymap_entry(&self, code: Scancode) -> Result<Option<KeymapEntry>>
pub fn keymap_entry(&self, code: Scancode) -> Result<Option<KeymapEntry>>
Queries a keymap entry by its associated Scancode.
Scancodes can appear in the keymap multiple times. Typically, the first entry takes precedence.
The keymap can also be queried by index. See Evdev::keymap_entry_by_index for how to do
that.
The keymap can not be queried by key code.
Devices without Keys don’t have any keymap entries, and not all drivers support this
functionality.
Devices that support keymaps and have internal scancodes will typically send a
Misc::SCAN event immediately before a key press or release event.
Return Ok(None) when index is out of range.
Sourcepub fn keymap_entry_by_index(&self, index: u16) -> Result<Option<KeymapEntry>>
pub fn keymap_entry_by_index(&self, index: u16) -> Result<Option<KeymapEntry>>
Queries a keymap entry by its zero-based index.
The keymap can also be queried by scancode. See Evdev::keymap_entry.
The keymap can not be queried by key code.
Devices without Keys don’t have any keymap entries, and not all drivers support this
functionality.
Return Ok(None) when index is out of range.
This is the only way to determine the number of entries in the keymap.
Sourcepub fn set_keymap_entry(&self, scancode: Scancode, keycode: Key) -> Result<()>
pub fn set_keymap_entry(&self, scancode: Scancode, keycode: Key) -> Result<()>
Sets a keymap entry by scancode.
This will remap the given Scancode to produce keycode. Use with caution!
Sourcepub fn set_keymap_entry_by_index(&self, index: u16, keycode: Key) -> Result<()>
pub fn set_keymap_entry_by_index(&self, index: u16, keycode: Key) -> Result<()>
Sets a keymap entry by index.
To find the Scancode at this index, or the valid indices, use
Evdev::keymap_entry_by_index.
Sourcepub fn into_reader(self) -> Result<EventReader>
pub fn into_reader(self) -> Result<EventReader>
Creates an EventReader wrapping this device.
This is the recommended way of receiving input events.
The EventReader will automatically resynchronize with the kernel’s view of the device
when an event is lost due to overflow.
Sourcepub fn is_readable(&self) -> Result<bool>
pub fn is_readable(&self) -> Result<bool>
Returns whether this device has any pending raw events that can be read without blocking.
If this returns true, calling Evdev::raw_events() and then calling
RawEvents::next() is guaranteed to not block (but only for a single event).
Note that this does not work for Evdevs wrapped in an EventReader, since
EventReader might read and discard several events from the underlying device. For
updating an EventReader without blocking, use EventReader::update.
Sourcepub fn block_until_readable(&self) -> Result<()>
pub fn block_until_readable(&self) -> Result<()>
Blocks the calling thread until Evdev::is_readable would return true.
This will block even if self is in non-blocking mode (via Evdev::set_nonblocking).
For checking whether events can be read from self without blocking, use
Evdev::is_readable, which will never block.
If self is already readable, this will return immediately.
Sourcepub fn raw_events(&self) -> RawEvents<'_> ⓘ
pub fn raw_events(&self) -> RawEvents<'_> ⓘ
Returns an iterator over the raw evdev events.
This will directly read from the evdev, without any buffering, filtering, synchronization
on lost events, or fetching of the kernel’s view of the device state.
It is recommended to use Evdev::into_reader instead.
RawEvents can be used (correctly) if the user is only interested in events pertaining to
relative axes (RelEvent), since those have no state.
If the Evdev is in non-blocking mode, the iterator will return None when reading
fails with a WouldBlock error.
If it is in blocking mode, RawEvents::next will block until an event is available.
Note: If this method is used while the device is wrapped in an EventReader, the
EventReader will miss events and go out of sync with the device state. Don’t do that.
Sourcepub fn read_events(&self, buf: &mut [InputEvent]) -> Result<usize>
pub fn read_events(&self, buf: &mut [InputEvent]) -> Result<usize>
Reads incoming raw events into buf.
This may read multiple events at once, which is more efficient than using
Evdev::raw_events to read them one-by-one.
This method will block until at least 1 event is available when the Evdev is in blocking
mode.
If it is in non-blocking mode, this method will return an io::ErrorKind::WouldBlock
error when there are no events to read.
Sourcepub fn upload_ff_effect<'a>(
&self,
effect: impl Into<Effect<'a>>,
) -> Result<EffectId>
pub fn upload_ff_effect<'a>( &self, effect: impl Into<Effect<'a>>, ) -> Result<EffectId>
Uploads a force-feedback effect to the device.
This is always a blocking operation, even if the Evdev is in non-blocking mode.
If the device is a uinput device, bugs in the userspace driver might cause this to block
for a very long time (there appears to be a timeout at 20-30 seconds).
Also see Evdev::supported_ff_effects for the number of supported effect slots, and
Evdev::supported_ff_features for the supported force-feedback feature set.
Uploaded effects will stay in device memory until removed via Evdev::erase_ff_effect.
Sourcepub fn erase_ff_effect(&self, id: EffectId) -> Result<()>
pub fn erase_ff_effect(&self, id: EffectId) -> Result<()>
Deletes a previously uploaded force-feedback effect.
Sourcepub fn set_led(&self, led: Led, on: bool) -> Result<()>
pub fn set_led(&self, led: Led, on: bool) -> Result<()>
Sets the state of a device LED.
To query the list of LEDs available on the device, use Evdev::supported_leds.
Convenience wrapper around Evdev::write.
Sourcepub fn control_ff(&self, effect: EffectId, active: bool) -> Result<()>
pub fn control_ff(&self, effect: EffectId, active: bool) -> Result<()>
Plays or stops a force-feedback effect (eg. rumble).
Before an effect can be started with this method, it needs to be uploaded via
Evdev::upload_ff_effect.
Convenience wrapper around Evdev::write.
Sourcepub fn set_ff_gain(&self, gain: u16) -> Result<()>
pub fn set_ff_gain(&self, gain: u16) -> Result<()>
Sets the global gain for force-feedback effects.
Requires that the device supports ff::Feature::GAIN.
Convenience wrapper around Evdev::write.
Sourcepub fn set_ff_autocenter(&self, autocenter: u16) -> Result<()>
pub fn set_ff_autocenter(&self, autocenter: u16) -> Result<()>
Controls the autocenter feature for force-feedback effects.
Requires that the device supports ff::Feature::AUTOCENTER.
Convenience wrapper around Evdev::write.
Sourcepub fn write(&self, events: &[InputEvent]) -> Result<()>
pub fn write(&self, events: &[InputEvent]) -> Result<()>
Writes input events to the device.
This can be used to change certain device states such as LEDs or sounds, or to play force-feedback effects.
Prefer using one of the convenience wrappers around this method if possible:
Evdev::control_ff, Evdev::set_led, etc.
Note: As per usual for file descriptors, writing data to the device is only possible if
it was opened with write permission.
Evdev::open will try to open the device with read+write permissions, and fall back to
read-only mode if the user does not have write permission for the evdev files.
If that also fails, one last attempt to open in write-only mode is made, to cover certain
misconfigured systems.
If the Evdev does not have write permission, this method will return an error of type
io::ErrorKind::PermissionDenied.
Sourcepub fn set_clockid(&self, clockid: clockid_t) -> Result<()>
pub fn set_clockid(&self, clockid: clockid_t) -> Result<()>
Sets the clockid_t to be used for event timestamps.
evdev doesn’t support all clocks. This method will fail with
io::ErrorKind::InvalidInput when a clockid is passed that evdev doesn’t like.
At least libc::CLOCK_REALTIME and libc::CLOCK_MONOTONIC seem to be supported.
By default, libc::CLOCK_REALTIME is used, which is the same clock source used by
SystemTime::now.
If this is called while there are any events in the kernel buffer, the buffer will be
cleared and a Syn::DROPPED event will be enqueued.
Source§impl Evdev
Event masks can be optionally configured to hide event types if a consumer isn’t interested in
them.
impl Evdev
Event masks can be optionally configured to hide event types if a consumer isn’t interested in them.
This can help avoid wasted work and unnecessary process wakeups, which can save battery.
Note: Fetching the device state directly (via Evdev::key_state et al) will still report
the true device state, without any bits masked out. The event masks only control which
events are forwarded to the program.
Note 2: EventReader is not aware of event masks and may insert some synthetic events
that have been disabled with the event masks. Your application should configure the masks as
desired and actively ignore any events that it sees if it isn’t interested in them.
§Platform Support
FreeBSD does not support these APIs, so they will return an error when used. Applications should degrade gracefully when that happens, since the consequence of not filtering events is merely a decrease in performance.
Sourcepub fn event_mask(&self) -> Result<BitSet<EventType>>
pub fn event_mask(&self) -> Result<BitSet<EventType>>
Returns the current event mask.
Sourcepub fn set_rel_mask(&self, mask: &BitSet<Rel>) -> Result<()>
pub fn set_rel_mask(&self, mask: &BitSet<Rel>) -> Result<()>
Sets the relative axis event mask.
Sourcepub fn set_abs_mask(&self, mask: &BitSet<Abs>) -> Result<()>
pub fn set_abs_mask(&self, mask: &BitSet<Abs>) -> Result<()>
Sets the absolute axis event mask.
Sourcepub fn switch_mask(&self) -> Result<BitSet<Switch>>
pub fn switch_mask(&self) -> Result<BitSet<Switch>>
Returns the current switch event mask.