input_linux/
evdev.rs

1//! An interface to the Linux kernel's event devices (`/dev/input/*`).
2
3use std::io;
4use std::mem::{MaybeUninit, size_of};
5use std::slice::from_raw_parts_mut;
6use std::os::unix::io::{RawFd, AsRawFd, IntoRawFd, FromRawFd};
7use std::os::fd::{AsFd, BorrowedFd, OwnedFd};
8use nix;
9use crate::sys;
10use crate::{
11    AbsoluteAxis, AbsoluteInfo, AutorepeatKind, EventKind, InputId,
12    InputProperty, Key, LedKind, MiscKind, RelativeAxis, SoundKind, SwitchKind,
13    ForceFeedbackKind, ForceFeedbackStatusKind,
14    InputEvent,
15};
16use crate::macros::convert_error;
17use crate::bitmask::Bitmask;
18
19pub use sys::EV_VERSION;
20
21/// A handle to an input device allowing the use of ioctls
22pub struct EvdevHandle<F>(F);
23
24impl<F> EvdevHandle<F> {
25    /// Create a new handle using an existing open file object.
26    pub const fn new(fd: F) -> Self {
27        EvdevHandle(fd)
28    }
29
30    /// Extracts the contained handle.
31    pub fn into_inner(self) -> F {
32        self.0
33    }
34
35    /// A reference to the contained handle.
36    pub const fn as_inner(&self) -> &F {
37        &self.0
38    }
39
40    /// A mutable reference to the contained handle.
41    pub fn as_inner_mut(&mut self) -> &mut F {
42        &mut self.0
43    }
44}
45
46impl<F: AsRawFd> AsFd for EvdevHandle<F> {
47    fn as_fd<'a>(&'a self) -> BorrowedFd<'a> {
48        unsafe {
49            BorrowedFd::borrow_raw(self.fd())
50        }
51    }
52}
53
54impl<F: AsRawFd> AsRawFd for EvdevHandle<F> {
55    fn as_raw_fd(&self) -> RawFd {
56        self.fd()
57    }
58}
59
60impl<F: IntoRawFd> IntoRawFd for EvdevHandle<F> {
61    fn into_raw_fd(self) -> RawFd {
62        self.0.into_raw_fd()
63    }
64}
65
66impl<F: FromRawFd> FromRawFd for EvdevHandle<F> {
67    unsafe fn from_raw_fd(fd: RawFd) -> Self {
68        EvdevHandle(FromRawFd::from_raw_fd(fd))
69    }
70}
71
72impl EvdevHandle<OwnedFd> {
73    /// Create a new handle from a raw file descriptor.
74    pub unsafe fn from_fd(fd: RawFd) -> Self {
75        FromRawFd::from_raw_fd(fd)
76    }
77}
78
79impl<F: AsRawFd> EvdevHandle<F> {
80    #[inline]
81    fn fd(&self) -> RawFd {
82        self.0.as_raw_fd()
83    }
84
85    /// Read events from the input device
86    pub fn read(&self, events: &mut [sys::input_event]) -> io::Result<usize> {
87        let events = unsafe { from_raw_parts_mut(events.as_mut_ptr() as *mut u8, size_of::<sys::input_event>() * events.len()) };
88        nix::unistd::read(self.fd(), events)
89            .map(|len| len / size_of::<sys::input_event>())
90            .map_err(convert_error)
91    }
92
93    /// Read events from the input device
94    pub fn read_input_events<'e>(&self, events: &'e mut [MaybeUninit<InputEvent>]) -> io::Result<&'e mut [InputEvent]> {
95        let res = {
96            let events = unsafe { from_raw_parts_mut(events.as_mut_ptr() as *mut sys::input_event, events.len()) };
97            self.read(events)
98        };
99        res.and_then(|count| {
100            let events = &mut events[..count];
101            for event in events.iter() {
102                let event = event.as_ptr() as *const sys::input_event;
103                let _ = InputEvent::from_raw(unsafe { &*event })?;
104            }
105            Ok(unsafe {
106                from_raw_parts_mut(events.as_mut_ptr() as *mut InputEvent, events.len())
107            })
108        })
109    }
110
111    /// Read a single event from the input device
112    pub fn read_input_event(&self) -> io::Result<InputEvent> {
113        let mut events = [MaybeUninit::<InputEvent>::uninit()];
114        let res = self.read_input_events(&mut events)
115            .and_then(|read| match read.is_empty() {
116                true => Err(io::Error::new(io::ErrorKind::UnexpectedEof, "empty evdev read")),
117                false => Ok(()),
118            });
119        res.map(|()| unsafe {
120            events[0].assume_init()
121        })
122    }
123
124    /// Read a single event from the input device
125    pub fn read_event(&self) -> io::Result<crate::Event> {
126        self.read_input_event()
127            .map(From::from)
128    }
129
130    /// Write events to the input device
131    pub fn write(&self, events: &[sys::input_event]) -> io::Result<usize> {
132        let events = unsafe { from_raw_parts_mut(events.as_ptr() as *mut u8, size_of::<sys::input_event>() * events.len()) };
133        nix::unistd::write(self, events)
134            .map(|len| len / size_of::<sys::input_event>()).map_err(convert_error)
135    }
136
137    ioctl_impl! {
138        {
139            /// `EVIOCGVERSION`
140            @get driver_version = ev_get_version -> i32
141        }
142        {
143            /// `EVIOCGID`
144            @get device_id = ev_get_id -> InputId
145        }
146        {
147            /// `EVIOGREP`
148            @get repeat_settings = ev_get_rep -> sys::repeat_settings
149        }
150        {
151            /// `EVIOSREP`
152            @set set_repeat_settings(&sys::repeat_settings) = ev_set_rep
153        }
154        {
155            /// `EVIOCGKEYCODE`
156            @get keycode_legacy = ev_get_keycode -> [u32; 2]
157        }
158        {
159            /// `EVIOCGKEYCODE_V2`
160            @get keycode = ev_get_keycode_v2 -> sys::input_keymap_entry
161        }
162        {
163            /// `EVIOCSKEYCODE`
164            @set set_keycode_legacy(&[u32; 2]) = ev_set_keycode
165        }
166        {
167            /// `EVIOCSKEYCODE_V2`
168            @set set_keycode(&sys::input_keymap_entry) = ev_set_keycode_v2
169        }
170        {
171            /// `EVIOCGNAME`
172            @get_str device_name, device_name_buf = ev_get_name
173        }
174        {
175            /// `EVIOCGPHYS`
176            @get_str physical_location, physical_location_buf = ev_get_phys
177        }
178        {
179            /// `EVIOCGUNIQ`
180            @get_str unique_id, unique_id_buf = ev_get_uniq
181        }
182        {
183            /// `EVIOCGPROP`
184            @get_buf device_properties_raw(u8) = ev_get_prop
185        }
186        {
187            /// `EVIOCGKEY`
188            @get_buf key_state(u8) = ev_get_key
189        }
190        {
191            /// `EVIOCGLED`
192            @get_buf led_state(u8) = ev_get_led
193        }
194        {
195            /// `EVIOCGSND`
196            @get_buf sounds_state(u8) = ev_get_snd
197        }
198        {
199            /// `EVIOCGSW`
200            @get_buf switch_state(u8) = ev_get_sw
201        }
202        {
203            /// `EVIOCSFF`
204            @set send_force_feedback(&mut sys::ff_effect) = ev_send_ff
205        }
206        {
207            /// `EVIOCRMFF`
208            @set erase_force_feedback(i16) = ev_erase_ff
209        }
210        {
211            /// `EVIOCGEFFECTS`
212            @get effects_count = ev_get_effects -> i32
213        }
214    }
215
216    /// `EVIOCGPROP`
217    pub fn device_properties(&self) -> io::Result<Bitmask<InputProperty>> {
218        let mut bitmask = Bitmask::default();
219        self.device_properties_raw(&mut bitmask).map(|_| bitmask)
220    }
221
222    /// `EVIOCGMTSLOTS`
223    ///
224    /// Warning: the current implementation can leak uninitialized heap memory into `values`
225    pub fn multi_touch_slots(&self, code: AbsoluteAxis, values: &mut [i32]) -> io::Result<()> {
226        let input_len = values.len() + 1;
227        let mut buf = Vec::<i32>::with_capacity(input_len);
228
229        // a perfect example of how not to use ev_get_mtslots
230        unsafe {
231            buf.set_len(input_len);
232            buf[0] = code as _;
233
234            // the first field isn't counted in the len of the fat pointer
235            let ptr = from_raw_parts_mut(buf.as_mut_ptr(), values.len()) as *mut _;
236            sys::ev_get_mtslots(self.fd(), ptr as *mut sys::input_mt_request_layout<[i32]>)
237                .map_err(convert_error)?;
238        }
239
240        values.copy_from_slice(&buf[1..]);
241        Ok(())
242    }
243
244    impl_bitmasks! { EventKind, EventKind::Synchronize,
245        event_mask_events, set_event_mask_events,
246        event_bits
247    }
248
249    impl_bitmasks! { Key, EventKind::Key,
250        key_mask, set_key_mask,
251        key_bits
252    }
253
254    impl_bitmasks! { RelativeAxis, EventKind::Relative,
255        relative_mask, set_relative_mask,
256        relative_bits
257    }
258
259    impl_bitmasks! { AbsoluteAxis, EventKind::Absolute,
260        absolute_mask, set_absolute_mask,
261        absolute_bits
262    }
263
264    impl_bitmasks! { MiscKind, EventKind::Misc,
265        misc_mask, set_misc_mask,
266        misc_bits
267    }
268
269    impl_bitmasks! { SwitchKind, EventKind::Switch,
270        switch_mask, set_switch_mask,
271        switch_bits
272    }
273
274    impl_bitmasks! { LedKind, EventKind::Led,
275        led_mask, set_led_mask,
276        led_bits
277    }
278
279    impl_bitmasks! { SoundKind, EventKind::Sound,
280        sound_mask, set_sound_mask,
281        sound_bits
282    }
283
284    impl_bitmasks! { AutorepeatKind, EventKind::Autorepeat,
285        autorepeat_mask, set_autorepeat_mask,
286        autorepeat_bits
287    }
288
289    impl_bitmasks! { ForceFeedbackKind, EventKind::ForceFeedback,
290        force_feedback_mask, set_force_feedback_mask,
291        force_feedback_bits
292    }
293
294    impl_bitmasks! { ForceFeedbackStatusKind, EventKind::ForceFeedbackStatus,
295        force_feedback_status_mask, set_force_feedback_status_mask,
296        force_feedback_status_bits
297    }
298
299    /// `EVIOCGMASK`
300    pub fn event_mask_raw(&self, kind: EventKind, buffer: &mut [u8]) -> io::Result<()> {
301        unsafe {
302            let mut mask = sys::input_mask {
303                type_: kind as _,
304                codes_size: buffer.len() as _,
305                codes_ptr: buffer.as_mut_ptr() as usize as _,
306            };
307
308            sys::ev_get_mask(self.fd(), &mut mask)
309                .map(drop)
310                .map_err(convert_error)
311        }
312    }
313
314    /// `EVIOCSMASK`
315    pub fn set_event_mask_raw(&self, kind: EventKind, buffer: &[u8]) -> io::Result<()> {
316        unsafe {
317            let mask = sys::input_mask {
318                type_: kind as _,
319                codes_size: buffer.len() as _,
320                codes_ptr: buffer.as_ptr() as usize as _,
321            };
322
323            sys::ev_set_mask(self.fd(), &mask)
324                .map(drop)
325                .map_err(convert_error)
326        }
327    }
328
329    /// `EVIOCGBIT`
330    pub fn event_bits_raw(&self, kind: EventKind, buffer: &mut [u8]) -> io::Result<usize> {
331        unsafe {
332            sys::ev_get_bit(self.fd(), kind as _, buffer)
333                .map(|i| i as _)
334                .map_err(convert_error)
335        }
336    }
337
338    /// `EVIOCGABS`
339    pub fn absolute_info(&self, abs: AbsoluteAxis) -> io::Result<AbsoluteInfo> {
340        unsafe {
341            let mut info = MaybeUninit::uninit();
342            sys::ev_get_abs(self.fd(), abs as _, &mut *info.as_mut_ptr())
343                .map(|_| info.assume_init().into())
344                .map_err(convert_error)
345        }
346    }
347
348    /// `EVIOCSABS`
349    pub fn set_absolute_info(&self, abs: AbsoluteAxis, info: &AbsoluteInfo) -> io::Result<()> {
350        unsafe {
351            let info: &sys::input_absinfo = info.into();
352            sys::ev_set_abs(self.fd(), abs as _, info)
353                .map(drop)
354                .map_err(convert_error)
355        }
356    }
357
358    /// `EVIOCGRAB`
359    pub fn grab(&self, grab: bool) -> io::Result<()> {
360        unsafe {
361            sys::ev_grab(self.fd(), if grab { 1 } else { 0 })
362                .map(drop)
363                .map_err(convert_error)
364        }
365    }
366
367    /// `EVIOCREVOKE`
368    pub fn revoke(&self) -> io::Result<()> {
369        unsafe {
370            sys::ev_revoke(self.fd(), 0)
371                .map(drop)
372                .map_err(convert_error)
373        }
374    }
375
376    /// `EVIOCSCLOCKID`
377    pub fn set_clock_id(&self, value: i32) -> io::Result<()> {
378        unsafe {
379            sys::ev_set_clockid(self.fd(), &value)
380                .map(drop)
381                .map_err(convert_error)
382        }
383    }
384}