Struct Evdev

Source
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

Source

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).

Source

pub fn path(&self) -> &Path

Returns the (canonicalized) file system path this Evdev has been created from.

Source

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.

Source

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.

Source

pub fn driver_version(&self) -> Result<Version>

Returns the evdev subsystem version.

Source

pub fn input_id(&self) -> Result<InputId>

Fetches device hardware information as an InputId.

Source

pub fn name(&self) -> Result<String>

Fetches the device name.

Source

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/input1
  • PNP0C0C/button/input0
  • ALSA

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).

Source

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.

Source

pub fn props(&self) -> Result<BitSet<InputProp>>

Fetches the set of InputProps advertised by the device.

Source

pub fn supported_events(&self) -> Result<BitSet<EventType>>

Returns the set of supported EventTypes.

Source

pub fn supported_keys(&self) -> Result<BitSet<Key>>

Returns the set of supported Keys.

Source

pub fn supported_switches(&self) -> Result<BitSet<Switch>>

Returns the set of supported Switches.

Source

pub fn supported_leds(&self) -> Result<BitSet<Led>>

Returns the set of supported Leds.

Source

pub fn supported_sounds(&self) -> Result<BitSet<Sound>>

Returns the set of supported Sounds.

Source

pub fn supported_misc(&self) -> Result<BitSet<Misc>>

Returns the set of supported Misc event codes.

Source

pub fn supported_rel_axes(&self) -> Result<BitSet<Rel>>

Returns the set of supported Rel axes.

Source

pub fn supported_abs_axes(&self) -> Result<BitSet<Abs>>

Returns the set of supported Abs axes.

Source

pub fn supported_ff_features(&self) -> Result<BitSet<Feature>>

Returns the set of supported force-feedback Features.

Source

pub fn supported_ff_effects(&self) -> Result<u32>

Returns the number of force-feedback effects the device can store at the same time.

Source

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.

Source

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.

Source

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).

Source

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.

Source

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.

Source

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.

Source

pub fn set_key_repeat(&self, rep: KeyRepeat) -> Result<()>

Sets the device’s autorepeat settings.

Also see Evdev::key_repeat.

Source

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.

Source

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.

Source

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!

Source

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.

Source

pub fn key_state(&self) -> Result<BitSet<Key>>

Queries the full key state.

Source

pub fn led_state(&self) -> Result<BitSet<Led>>

Queries the state of all device LEDs.

Source

pub fn sound_state(&self) -> Result<BitSet<Sound>>

Queries the state of all Sounds.

Source

pub fn switch_state(&self) -> Result<BitSet<Switch>>

Queries the state of all Switches.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn erase_ff_effect(&self, id: EffectId) -> Result<()>

Deletes a previously uploaded force-feedback effect.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

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.

Source

pub fn event_mask(&self) -> Result<BitSet<EventType>>

Returns the current event mask.

Source

pub fn set_event_mask(&self, mask: &BitSet<EventType>) -> Result<()>

Sets the event mask.

Only EventTypes included in mask will be forwarded to this Evdev handle.

Source

pub fn key_mask(&self) -> Result<BitSet<Key>>

Returns the current key event mask.

Source

pub fn set_key_mask(&self, mask: &BitSet<Key>) -> Result<()>

Sets the key event mask.

This Evdev handle will only receive KeyEvents whose Key is contained in mask.

Source

pub fn rel_mask(&self) -> Result<BitSet<Rel>>

Returns the current relative axis event mask.

Source

pub fn set_rel_mask(&self, mask: &BitSet<Rel>) -> Result<()>

Sets the relative axis event mask.

Source

pub fn abs_mask(&self) -> Result<BitSet<Abs>>

Returns the current absolute axis event mask.

Source

pub fn set_abs_mask(&self, mask: &BitSet<Abs>) -> Result<()>

Sets the absolute axis event mask.

Source

pub fn switch_mask(&self) -> Result<BitSet<Switch>>

Returns the current switch event mask.

Source

pub fn set_switch_mask(&self, mask: &BitSet<Switch>) -> Result<()>

Sets the switch event mask.

Trait Implementations§

Source§

impl AsFd for Evdev

Source§

fn as_fd(&self) -> BorrowedFd<'_>

Borrows the file descriptor. Read more
Source§

impl AsRawFd for Evdev

Source§

fn as_raw_fd(&self) -> RawFd

Extracts the raw file descriptor. Read more
Source§

impl Debug for Evdev

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl IntoRawFd for Evdev

Source§

fn into_raw_fd(self) -> RawFd

Consumes this object, returning the raw underlying file descriptor. Read more

Auto Trait Implementations§

§

impl Freeze for Evdev

§

impl RefUnwindSafe for Evdev

§

impl Send for Evdev

§

impl Sync for Evdev

§

impl Unpin for Evdev

§

impl UnwindSafe for Evdev

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.