evdev_rs/
device.rs

1use crate::{AbsInfo, GrabMode, InputEvent, LedState, ReadFlag, ReadStatus, TimeVal};
2use libc::{c_int, c_uint, c_void};
3use std::ffi::CString;
4use std::fs::File;
5use std::fs::OpenOptions;
6use std::io::Read;
7use std::mem::ManuallyDrop;
8use std::os::unix::fs::OpenOptionsExt;
9use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
10use std::path::Path;
11use std::{io, ptr};
12
13use crate::enums::*;
14use crate::util::*;
15
16use evdev_sys as raw;
17
18/// Types that can be enabled on a DeviceWrapper (i.e. buttons, keys, relative motion)
19///
20/// Generally this method will not be called directly, but will insted be called through [Device::enable()](crate::Device::enable)
21///
22/// ```rust
23/// # use evdev_rs::{UninitDevice, DeviceWrapper, Enable, enums::{EventCode, EV_REL::REL_X}};
24/// let dev = UninitDevice::new().expect("Device creation failed");
25/// dev.enable(EventCode::EV_REL(REL_X)).expect("Enable failed");
26/// ```
27///
28/// If you need to enable a EV_ABS or EV_REP event code, use
29/// [enable_event_code](crate::Device::enable_event_code), as this
30/// implementation doesn't pass EV_ABS data.
31pub trait Enable {
32    fn enable<D: DeviceWrapper>(&self, device: &D) -> io::Result<()>;
33    fn disable<D: DeviceWrapper>(&self, device: &D) -> io::Result<()>;
34    fn has<D: DeviceWrapper>(&self, device: &D) -> bool;
35}
36
37#[cfg(feature = "libevdev-1-10")]
38impl Enable for InputProp {
39    fn enable<D: DeviceWrapper>(&self, device: &D) -> io::Result<()> {
40        device.enable_property(self)
41    }
42    fn disable<D: DeviceWrapper>(&self, device: &D) -> io::Result<()> {
43        device.disable_property(self)
44    }
45    fn has<D: DeviceWrapper>(&self, device: &D) -> bool {
46        device.has_property(self)
47    }
48}
49
50impl Enable for EventType {
51    fn enable<D: DeviceWrapper>(&self, device: &D) -> io::Result<()> {
52        device.enable_event_type(self)
53    }
54    fn disable<D: DeviceWrapper>(&self, device: &D) -> io::Result<()> {
55        device.disable_event_type(self)
56    }
57    fn has<D: DeviceWrapper>(&self, device: &D) -> bool {
58        device.has_event_type(self)
59    }
60}
61
62impl Enable for EventCode {
63    fn enable<D: DeviceWrapper>(&self, device: &D) -> io::Result<()> {
64        device.enable_event_code(self, None)
65    }
66    fn disable<D: DeviceWrapper>(&self, device: &D) -> io::Result<()> {
67        device.disable_event_code(self)
68    }
69    fn has<D: DeviceWrapper>(&self, device: &D) -> bool {
70        device.has_event_code(self)
71    }
72}
73
74/// Extra data for use with enable_event_code
75#[derive(Clone, Copy, Debug)]
76pub enum EnableCodeData {
77    AbsInfo(AbsInfo),
78    RepInfo(i32),
79}
80
81/// Abstraction over structs which contain an inner `*mut libevdev`
82pub trait DeviceWrapper: Sized {
83    fn raw(&self) -> *mut raw::libevdev;
84
85    /// Forcibly enable an EventType/InputProp on this device, even if the underlying
86    /// device does not support it. While this cannot make the device actually
87    /// report such events, it will now return true for has().
88    ///
89    /// This is a local modification only affecting only this representation of
90    /// this device.
91    fn enable<E: Enable>(&self, e: E) -> io::Result<()> {
92        e.enable(self)
93    }
94
95    /// Enables this property, a call to `set_file` will overwrite any previously set values
96    ///
97    /// Note: Please use the `enable` function instead. This function is only
98    /// available for the sake of maintaining compatibility with libevdev.
99    fn enable_property(&self, prop: &InputProp) -> io::Result<()> {
100        let result =
101            unsafe { raw::libevdev_enable_property(self.raw(), *prop as c_uint) as i32 };
102
103        match result {
104            0 => Ok(()),
105            error => Err(io::Error::from_raw_os_error(-error)),
106        }
107    }
108
109    /// Forcibly enable an event type on this device, even if the underlying
110    /// device does not support it. While this cannot make the device actually
111    /// report such events, it will now return true for libevdev_has_event_type().
112    ///
113    /// This is a local modification only affecting only this representation of
114    /// this device.
115    ///
116    /// Note: Please use the `enable` function instead. This function is only
117    /// available for the sake of maintaining compatibility with libevdev.
118    fn enable_event_type(&self, ev_type: &EventType) -> io::Result<()> {
119        let result =
120            unsafe { raw::libevdev_enable_event_type(self.raw(), *ev_type as c_uint) };
121
122        match result {
123            0 => Ok(()),
124            error => Err(io::Error::from_raw_os_error(-error)),
125        }
126    }
127
128    /// Forcibly enable an event type on this device, even if the underlying
129    /// device does not support it. While this cannot make the device actually
130    /// report such events, it will now return true for libevdev_has_event_code().
131    ///
132    /// The last argument depends on the type and code:
133    /// If type is EV_ABS, data must be a pointer to a struct input_absinfo
134    /// containing the data for this axis.
135    /// If type is EV_REP, data must be a pointer to a int containing the data
136    /// for this axis.
137    /// For all other types, the argument must be `None`.
138    ///
139    /// Note: Please use the `enable` function instead. This function is only
140    /// available for the sake of maintaining compatibility with libevdev.
141    fn enable_event_code(
142        &self,
143        ev_code: &EventCode,
144        data: Option<EnableCodeData>,
145    ) -> io::Result<()> {
146        let data =
147            match ev_code {
148                EventCode::EV_ABS(_) => match data {
149                    Some(EnableCodeData::AbsInfo(info)) => {
150                        &info.as_raw() as *const _ as *const c_void
151                    }
152                    _ => return Err(io::Error::new(
153                        io::ErrorKind::InvalidInput,
154                        "EventCode::EV_ABS must be paired with EnableCodeData::AbsInfo",
155                    )),
156                },
157                EventCode::EV_REP(_) => match data {
158                    Some(EnableCodeData::RepInfo(info)) => {
159                        &libc::c_int::from(info) as *const _ as *const c_void
160                    }
161                    _ => return Err(io::Error::new(
162                        io::ErrorKind::InvalidInput,
163                        "EventCode::EV_REP must be paired with EnableCodeData::RepInfo",
164                    )),
165                },
166                _ => ptr::null(),
167            };
168
169        let (ev_type, ev_code) = event_code_to_int(ev_code);
170
171        let result = unsafe {
172            raw::libevdev_enable_event_code(self.raw(), ev_type, ev_code, data)
173        };
174
175        match result {
176            0 => Ok(()),
177            error => Err(io::Error::from_raw_os_error(-error)),
178        }
179    }
180
181    /// Forcibly disable an EventType/EventCode on this device, even if the
182    /// underlying device provides it. This effectively mutes the respective set of
183    /// events. has() will return false for this EventType/EventCode
184    ///
185    /// In most cases, a caller likely only wants to disable a single code, not
186    /// the whole type.
187    ///
188    /// Disabling EV_SYN will not work. In Peter's Words "Don't shoot yourself
189    /// in the foot. It hurts".
190    ///
191    /// This is a local modification only affecting only this representation of
192    /// this device.
193    fn disable<E: Enable>(&self, d: E) -> io::Result<()> {
194        d.disable(self)
195    }
196
197    /// Forcibly disable an event type on this device, even if the underlying
198    /// device provides it. This effectively mutes the respective set of
199    /// events. libevdev will filter any events matching this type and none will
200    /// reach the caller. libevdev_has_event_type() will return false for this
201    /// type.
202    ///
203    /// In most cases, a caller likely only wants to disable a single code, not
204    /// the whole type. Use `disable_event_code` for that.
205    ///
206    /// Disabling EV_SYN will not work. In Peter's Words "Don't shoot yourself
207    /// in the foot. It hurts".
208    ///
209    /// This is a local modification only affecting only this representation of
210    /// this device.
211    ///
212    /// Note: Please use the `disable` function instead. This function is only
213    /// available for the sake of maintaining compatibility with libevdev.
214    fn disable_event_type(&self, ev_type: &EventType) -> io::Result<()> {
215        let result =
216            unsafe { raw::libevdev_disable_event_type(self.raw(), *ev_type as c_uint) };
217
218        match result {
219            0 => Ok(()),
220            error => Err(io::Error::from_raw_os_error(-error)),
221        }
222    }
223    /// Forcibly disable an event code on this device, even if the underlying
224    /// device provides it. This effectively mutes the respective set of
225    /// events. libevdev will filter any events matching this type and code and
226    /// none will reach the caller. `has_event_code` will return false for
227    /// this code.
228    ///
229    /// Disabling all event codes for a given type will not disable the event
230    /// type. Use `disable_event_type` for that.
231    ///
232    /// This is a local modification only affecting only this representation of
233    /// this device.
234    ///
235    /// Disabling codes of type EV_SYN will not work. Don't shoot yourself in the
236    /// foot. It hurts.
237    ///
238    /// Note: Please use the `disable` function instead. This function is only
239    /// available for the sake of maintaining compatibility with libevdev.
240    fn disable_event_code(&self, code: &EventCode) -> io::Result<()> {
241        let (ev_type, ev_code) = event_code_to_int(code);
242        let result =
243            unsafe { raw::libevdev_disable_event_code(self.raw(), ev_type, ev_code) };
244
245        match result {
246            0 => Ok(()),
247            error => Err(io::Error::from_raw_os_error(-error)),
248        }
249    }
250
251    #[cfg(feature = "libevdev-1-10")]
252    fn disable_property(&self, prop: &InputProp) -> io::Result<()> {
253        let result =
254            unsafe { raw::libevdev_disable_property(self.raw(), (*prop) as c_uint) };
255        match result {
256            0 => Ok(()),
257            error => Err(io::Error::from_raw_os_error(-error)),
258        }
259    }
260
261    /// Returns `true` if device support the InputProp/EventType/EventCode and false otherwise
262    fn has<E: Enable>(&self, e: E) -> bool {
263        e.has(self)
264    }
265
266    /// Returns `true` if device support the property and false otherwise
267    ///
268    /// Note: Please use the `has` function instead. This function is only
269    /// available for the sake of maintaining compatibility with libevdev.
270    fn has_property(&self, prop: &InputProp) -> bool {
271        unsafe { raw::libevdev_has_property(self.raw(), *prop as c_uint) != 0 }
272    }
273
274    /// Returns `true` is the device support this event type and `false` otherwise
275    ///
276    /// Note: Please use the `has` function instead. This function is only
277    /// available for the sake of maintaining compatibility with libevdev.
278    fn has_event_type(&self, ev_type: &EventType) -> bool {
279        unsafe { raw::libevdev_has_event_type(self.raw(), *ev_type as c_uint) != 0 }
280    }
281
282    /// Return `true` is the device support this event type and code and `false` otherwise
283    ///
284    /// Note: Please use the `has` function instead. This function is only
285    /// available for the sake of maintaining compatibility with libevdev.
286    fn has_event_code(&self, code: &EventCode) -> bool {
287        unsafe {
288            let (ev_type, ev_code) = event_code_to_int(code);
289            raw::libevdev_has_event_code(self.raw(), ev_type, ev_code) != 0
290        }
291    }
292
293    string_getter!(
294        #[doc = "Get device's name, as set by the kernel, or overridden by a call to `set_name`"],
295        name, libevdev_get_name,
296        #[doc = "Get device's physical location, as set by the kernel, or overridden by a call to `set_phys`"],
297        phys, libevdev_get_phys,
298        #[doc = "Get device's unique identifier, as set by the kernel, or overridden by a call to `set_uniq`"],
299        uniq, libevdev_get_uniq
300    );
301
302    string_setter!(
303        set_name,
304        libevdev_set_name,
305        set_phys,
306        libevdev_set_phys,
307        set_uniq,
308        libevdev_set_uniq
309    );
310
311    product_getter!(
312        product_id,
313        libevdev_get_id_product,
314        vendor_id,
315        libevdev_get_id_vendor,
316        bustype,
317        libevdev_get_id_bustype,
318        version,
319        libevdev_get_id_version
320    );
321
322    product_setter!(
323        set_product_id,
324        libevdev_set_id_product,
325        set_vendor_id,
326        libevdev_set_id_vendor,
327        set_bustype,
328        libevdev_set_id_bustype,
329        set_version,
330        libevdev_set_id_version
331    );
332
333    /// Get the axis info for the given axis, as advertised by the kernel.
334    ///
335    /// Returns the `AbsInfo` for the given the code or None if the device
336    /// doesn't support this code
337    fn abs_info(&self, code: &EventCode) -> Option<AbsInfo> {
338        let (_, ev_code) = event_code_to_int(code);
339        let a = unsafe { raw::libevdev_get_abs_info(self.raw(), ev_code).as_ref()? };
340
341        Some(AbsInfo {
342            value: a.value,
343            minimum: a.minimum,
344            maximum: a.maximum,
345            fuzz: a.fuzz,
346            flat: a.flat,
347            resolution: a.resolution,
348        })
349    }
350
351    /// Change the abs info for the given EV_ABS event code, if the code exists.
352    ///
353    /// This function has no effect if `has_event_code` returns false for
354    /// this code.
355    fn set_abs_info(&self, code: &EventCode, absinfo: &AbsInfo) {
356        let (_, ev_code) = event_code_to_int(code);
357
358        unsafe {
359            raw::libevdev_set_abs_info(
360                self.raw(),
361                ev_code,
362                &absinfo.as_raw() as *const _,
363            );
364        }
365    }
366
367    ///  Returns the current value of the event type.
368    ///
369    /// If the device supports this event type and code, the return value is
370    /// set to the current value of this axis. Otherwise, `None` is returned.
371    fn event_value(&self, code: &EventCode) -> Option<i32> {
372        let mut value: i32 = 0;
373        let (ev_type, ev_code) = event_code_to_int(code);
374        let valid = unsafe {
375            raw::libevdev_fetch_event_value(self.raw(), ev_type, ev_code, &mut value)
376        };
377
378        match valid {
379            0 => None,
380            _ => Some(value),
381        }
382    }
383
384    /// Set the value for a given event type and code.
385    ///
386    /// This only makes sense for some event types, e.g. setting the value for
387    /// EV_REL is pointless.
388    ///
389    /// This is a local modification only affecting only this representation of
390    /// this device. A future call to event_value() will return this
391    /// value, unless the value was overwritten by an event.
392    ///
393    /// If the device supports ABS_MT_SLOT, the value set for any ABS_MT_*
394    /// event code is the value of the currently active slot. You should use
395    /// `set_slot_value` instead.
396    ///
397    /// If the device supports ABS_MT_SLOT and the type is EV_ABS and the code is
398    /// ABS_MT_SLOT, the value must be a positive number less then the number of
399    /// slots on the device. Otherwise, `set_event_value` returns Err.
400    fn set_event_value(&self, code: &EventCode, val: i32) -> io::Result<()> {
401        let (ev_type, ev_code) = event_code_to_int(code);
402        let result = unsafe {
403            raw::libevdev_set_event_value(self.raw(), ev_type, ev_code, val as c_int)
404        };
405
406        match result {
407            0 => Ok(()),
408            error => Err(io::Error::from_raw_os_error(-error)),
409        }
410    }
411
412    abs_getter!(
413        abs_minimum,
414        libevdev_get_abs_minimum,
415        abs_maximum,
416        libevdev_get_abs_maximum,
417        abs_fuzz,
418        libevdev_get_abs_fuzz,
419        abs_flat,
420        libevdev_get_abs_flat,
421        abs_resolution,
422        libevdev_get_abs_resolution
423    );
424
425    abs_setter!(
426        set_abs_minimum,
427        libevdev_set_abs_minimum,
428        set_abs_maximum,
429        libevdev_set_abs_maximum,
430        set_abs_fuzz,
431        libevdev_set_abs_fuzz,
432        set_abs_flat,
433        libevdev_set_abs_flat,
434        set_abs_resolution,
435        libevdev_set_abs_resolution
436    );
437
438    /// Return the current value of the code for the given slot.
439    ///
440    /// If the device supports this event code, the return value is
441    /// is set to the current value of this axis. Otherwise, or
442    /// if the event code is not an ABS_MT_* event code, `None` is returned
443    fn slot_value(&self, slot: u32, code: &EventCode) -> Option<i32> {
444        let (_, ev_code) = event_code_to_int(code);
445        let mut value: i32 = 0;
446        let valid = unsafe {
447            raw::libevdev_fetch_slot_value(
448                self.raw(),
449                slot as c_uint,
450                ev_code,
451                &mut value,
452            )
453        };
454
455        match valid {
456            0 => None,
457            _ => Some(value),
458        }
459    }
460
461    /// Set the value for a given code for the given slot.
462    ///
463    /// This is a local modification only affecting only this representation of
464    /// this device. A future call to `slot_value` will return this value,
465    /// unless the value was overwritten by an event.
466    ///
467    /// This function does not set event values for axes outside the ABS_MT range,
468    /// use `set_event_value` instead.
469    fn set_slot_value(&self, slot: u32, code: &EventCode, val: i32) -> io::Result<()> {
470        let (_, ev_code) = event_code_to_int(code);
471        let result = unsafe {
472            raw::libevdev_set_slot_value(
473                self.raw(),
474                slot as c_uint,
475                ev_code,
476                val as c_int,
477            )
478        };
479
480        match result {
481            0 => Ok(()),
482            error => Err(io::Error::from_raw_os_error(-error)),
483        }
484    }
485
486    /// Get the number of slots supported by this device.
487    ///
488    /// The number of slots supported, or `None` if the device does not provide
489    /// any slots
490    ///
491    /// A device may provide ABS_MT_SLOT but a total number of 0 slots. Hence
492    /// the return value of `None` for "device does not provide slots at all"
493    fn num_slots(&self) -> Option<i32> {
494        let result = unsafe { raw::libevdev_get_num_slots(self.raw()) };
495
496        match result {
497            -1 => None,
498            slots => Some(slots),
499        }
500    }
501
502    /// Get the currently active slot.
503    ///
504    /// This may differ from the value an ioctl may return at this time as
505    /// events may have been read off the file since changing the slot value
506    /// but those events are still in the buffer waiting to be processed.
507    /// The returned value is the value a caller would see if it were to
508    /// process events manually one-by-one.
509    fn current_slot(&self) -> Option<i32> {
510        let result = unsafe { raw::libevdev_get_current_slot(self.raw()) };
511
512        match result {
513            -1 => None,
514            slots => Some(slots),
515        }
516    }
517}
518
519/// Opaque struct representing an evdev device with no backing file
520pub struct UninitDevice {
521    raw: *mut raw::libevdev,
522}
523
524unsafe impl Send for UninitDevice {}
525
526impl DeviceWrapper for UninitDevice {
527    fn raw(&self) -> *mut raw::libevdev {
528        self.raw
529    }
530}
531
532impl UninitDevice {
533    /// Initialize a new libevdev device.
534    ///
535    /// Generally you should use Device::new_from_file instead of this method
536    /// This function only initializes the struct to sane default values.
537    /// To actually hook up the device to a kernel device, use `set_file`.
538    pub fn new() -> Option<UninitDevice> {
539        let libevdev = unsafe { raw::libevdev_new() };
540
541        if libevdev.is_null() {
542            None
543        } else {
544            Some(UninitDevice { raw: libevdev })
545        }
546    }
547
548    /// Set the file for this struct and initialize internal data.
549    ///
550    /// If the device changed and you need to re-read a device, use `Device::new_from_file` method.
551    /// If you need to change the file after
552    /// closing and re-opening the same device, use `change_file`.
553    pub fn set_file(self, file: File) -> io::Result<Device> {
554        // Don't call UninitDevice's destructor so we can reuse the inner libevdev
555        let leak = ManuallyDrop::new(self);
556        let result = unsafe { raw::libevdev_set_fd(leak.raw, file.as_raw_fd()) };
557        match result {
558            0 => Ok(Device {
559                file,
560                raw: leak.raw,
561            }),
562            error => Err(io::Error::from_raw_os_error(-error)),
563        }
564    }
565
566    #[deprecated(
567        since = "0.5.0",
568        note = "Prefer `set_file`. Some function names were changed so they
569        more closely match their type signature. See issue 42 for discussion
570        https://github.com/ndesh26/evdev-rs/issues/42"
571    )]
572    pub fn set_fd(self, file: File) -> io::Result<Device> {
573        self.set_file(file)
574    }
575}
576
577impl Drop for UninitDevice {
578    fn drop(&mut self) {
579        unsafe {
580            raw::libevdev_free(self.raw);
581        }
582    }
583}
584
585impl std::fmt::Debug for UninitDevice {
586    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
587        f.debug_struct("UninitDevice")
588            .field("name", &self.name())
589            .field("phys", &self.phys())
590            .field("uniq", &self.uniq())
591            .finish()
592    }
593}
594
595/// Opaque struct representing an evdev device
596///
597/// Unlike libevdev, this `Device` mantains an associated file as an invariant
598pub struct Device {
599    file: File,
600    raw: *mut raw::libevdev,
601}
602
603unsafe impl Send for Device {}
604
605impl DeviceWrapper for Device {
606    fn raw(&self) -> *mut raw::libevdev {
607        self.raw
608    }
609}
610
611impl Device {
612    /// Initialize a new libevdev device from the given file.
613    ///
614    /// This is a shortcut for
615    ///
616    /// ```rust,no_run
617    /// use evdev_rs::{Device, UninitDevice};
618    /// # use std::fs::File;
619    ///
620    /// let uninit_device = UninitDevice::new().unwrap();
621    /// # let file = File::open("/dev/input/event0").unwrap();
622    /// let device = uninit_device.set_file(file);
623    /// ```
624    ///
625    /// The caller is responsible for opening the file and setting
626    /// the `O_NONBLOCK` flag and handling permissions.
627    /// If the file is opened without O_NONBLOCK flag then next_event
628    /// should be called with ReadFlag::BLOCKING. Due to the caching
629    /// nature of next_event we might block while trying to buffer
630    /// new events even though some events are already present.
631    pub fn new_from_file(file: File) -> io::Result<Device> {
632        let mut libevdev = std::ptr::null_mut();
633        let result =
634            unsafe { raw::libevdev_new_from_fd(file.as_raw_fd(), &mut libevdev) };
635
636        match result {
637            0 => Ok(Device {
638                file,
639                raw: libevdev,
640            }),
641            error => Err(io::Error::from_raw_os_error(-error)),
642        }
643    }
644
645    #[deprecated(
646        since = "0.5.0",
647        note = "Prefer `new_from_file`. Some function names were changed so they
648        more closely match their type signature. See issue 42 for discussion
649        https://github.com/ndesh26/evdev-rs/issues/42"
650    )]
651    pub fn new_from_fd(file: File) -> io::Result<Device> {
652        Self::new_from_file(file)
653    }
654
655    /// Opens a device with the given path as the location of devnode
656    ///
657    /// The devnode file is opened with `O_NONBLOCK` and all the pending
658    /// events are first read from the file before creating the device.
659    pub fn new_from_path<P: AsRef<Path>>(path: P) -> io::Result<Device> {
660        let mut file = OpenOptions::new()
661            .read(true)
662            .write(true)
663            .custom_flags(libc::O_NONBLOCK)
664            .open(path)?;
665        let mut buffer = [0u8; 20 * std::mem::size_of::<raw::input_event>()];
666        let last_result = loop {
667            let result = file.read(&mut buffer);
668            if !result.is_ok() {
669                break result;
670            }
671        };
672        let _error_code = io::Error::from(io::ErrorKind::WouldBlock);
673        match last_result {
674            Err(_error_code) => Self::new_from_file(file),
675            _ => Err(io::Error::new(
676                io::ErrorKind::WouldBlock,
677                "Unable to open file with O_NONBLOCK",
678            )),
679        }
680    }
681
682    /// Returns the file associated with the device
683    pub fn file(&self) -> &File {
684        &self.file
685    }
686
687    #[deprecated(
688        since = "0.5.0",
689        note = "Prefer `file`. This function can easily be misused. Calling
690        this method, then dropping the returned file will lead to failures
691        e.g. next_event will return an Err()"
692    )]
693    pub fn fd(&self) -> Option<File> {
694        let result = unsafe { raw::libevdev_get_fd(self.raw) };
695        match result {
696            0 => None,
697            _ => unsafe { Some(File::from_raw_fd(result)) },
698        }
699    }
700
701    /// Change the file for this device, without re-reading the actual device.
702    ///
703    /// On success, returns the file that was previously associated with this
704    /// device.
705    ///
706    /// If the file changes after initializing the device, for example after a
707    /// VT-switch in the X.org X server, this function updates the internal
708    /// file to the newly opened. No check is made that new file points to the
709    /// same device. If the device has changed, evdev's behavior is undefined.
710    ///
711    /// evdev device does not sync itself after changing the file and keeps the
712    /// current device state. Use next_event with the FORCE_SYNC flag to force
713    /// a re-sync.
714    ///
715    /// # Example
716    ///
717    /// ```rust,no_run
718    /// use evdev_rs::{Device, UninitDevice, ReadFlag, ReadStatus};
719    /// # use std::fs::File;
720    /// # fn hidden() -> std::io::Result<()> {
721    /// let mut dev = Device::new_from_file(File::open("/dev/input/input0")?)?;
722    /// dev.change_file(File::open("/dev/input/input1")?)?;
723    /// dev.next_event(ReadFlag::FORCE_SYNC);
724    /// while dev.next_event(ReadFlag::SYNC).ok().unwrap().0 == ReadStatus::Sync
725    ///                             {} // noop
726    /// # Ok(())
727    /// # }
728    /// ```
729    /// After changing the file, the device is assumed ungrabbed and a caller must
730    /// call libevdev_grab() again.
731    pub fn change_file(&mut self, file: File) -> io::Result<File> {
732        let result = unsafe { raw::libevdev_change_fd(self.raw, file.as_raw_fd()) };
733
734        match result {
735            0 => {
736                let mut file = file;
737                std::mem::swap(&mut file, &mut self.file);
738                Ok(file)
739            }
740            error => Err(io::Error::from_raw_os_error(-error)),
741        }
742    }
743
744    #[deprecated(
745        since = "0.5.0",
746        note = "Prefer new_from_file. Some function names were changed so they
747        more closely match their type signature. See issue 42 for discussion
748        https://github.com/ndesh26/evdev-rs/issues/42"
749    )]
750    pub fn change_fd(&mut self, file: File) -> io::Result<()> {
751        self.change_file(file)?;
752        Ok(())
753    }
754
755    /// Grab or ungrab the device through a kernel EVIOCGRAB.
756    ///
757    /// This prevents other clients (including kernel-internal ones such as
758    /// rfkill) from receiving events from this device. This is generally a
759    /// bad idea. Don't do this. Grabbing an already grabbed device, or
760    /// ungrabbing an ungrabbed device is a noop and always succeeds.
761    ///
762    /// A grab is an operation tied to a file descriptor, not a device. If a
763    /// client changes the file descriptor with Device::change_file(), it must
764    /// also re-issue a grab with libevdev_grab().
765    pub fn grab(&mut self, grab: GrabMode) -> io::Result<()> {
766        let result = unsafe { raw::libevdev_grab(self.raw, grab as c_int) };
767
768        match result {
769            0 => Ok(()),
770            error => Err(io::Error::from_raw_os_error(-error)),
771        }
772    }
773
774    /// Check if there are events waiting for us.
775    ///
776    /// This function does not consume an event and may not access the device
777    /// file at all. If there are events queued internally this function will
778    /// return true. If the internal queue is empty, this function will poll
779    /// the file descriptor for data.
780    ///
781    /// This is a convenience function for simple processes, most complex programs
782    /// are expected to use select(2) or poll(2) on the file descriptor. The kernel
783    /// guarantees that if data is available, it is a multiple of sizeof(struct
784    /// input_event), and thus calling `next_event` when select(2) or
785    /// poll(2) return is safe. You do not need `has_event_pending` if
786    /// you're using select(2) or poll(2).
787    pub fn has_event_pending(&self) -> bool {
788        unsafe { raw::libevdev_has_event_pending(self.raw) > 0 }
789    }
790
791    /// Return the driver version of a device already intialize with `set_file`
792    pub fn driver_version(&self) -> i32 {
793        unsafe { raw::libevdev_get_driver_version(self.raw) as i32 }
794    }
795
796    /// Set the device's EV_ABS axis to the value defined in the abs
797    /// parameter. This will be written to the kernel.
798    pub fn set_kernel_abs_info(&self, code: &EventCode, absinfo: &AbsInfo) {
799        let (_, ev_code) = event_code_to_int(code);
800
801        unsafe {
802            raw::libevdev_kernel_set_abs_info(
803                self.raw,
804                ev_code,
805                &absinfo.as_raw() as *const _,
806            );
807        }
808    }
809
810    /// Turn an LED on or off.
811    ///
812    /// enabling an LED requires write permissions on the device's file descriptor.
813    pub fn kernel_set_led_value(
814        &self,
815        code: &EventCode,
816        value: LedState,
817    ) -> io::Result<()> {
818        let (_, ev_code) = event_code_to_int(code);
819        let result = unsafe {
820            raw::libevdev_kernel_set_led_value(self.raw, ev_code, value as c_int)
821        };
822
823        match result {
824            0 => Ok(()),
825            error => Err(io::Error::from_raw_os_error(-error)),
826        }
827    }
828
829    /// Set the clock ID to be used for timestamps. Further events from this device
830    /// will report an event time based on the given clock.
831    ///
832    /// This is a modification only affecting this representation of
833    /// this device.
834    pub fn set_clock_id(&self, clockid: i32) -> io::Result<()> {
835        let result = unsafe { raw::libevdev_set_clock_id(self.raw, clockid) };
836
837        match result {
838            0 => Ok(()),
839            error => Err(io::Error::from_raw_os_error(-error)),
840        }
841    }
842
843    /// Get the next event from the device. This function operates in two different
844    /// modes: normal mode or sync mode.
845    ///
846    /// In normal mode (when flags has `evdev::NORMAL` set), this function returns
847    /// `ReadStatus::Success` and returns the event. If no events are available at
848    /// this time, it returns `-EAGAIN` as `Err`.
849    ///
850    /// If the current event is an `EV_SYN::SYN_DROPPED` event, this function returns
851    /// `ReadStatus::Sync` and is set to the `EV_SYN` event.The caller should now call
852    /// this function with the `evdev::SYNC` flag set, to get the set of events that
853    /// make up the device state delta. This function returns ReadStatus::Sync for
854    /// each event part of that delta, until it returns `-EAGAIN` once all events
855    /// have been synced.
856    ///
857    /// If a device needs to be synced by the caller but the caller does not call
858    /// with the `evdev::SYNC` flag set, all events from the diff are dropped after
859    /// evdev updates its internal state and event processing continues as normal.
860    /// Note that the current slot and the state of touch points may have updated
861    /// during the `SYN_DROPPED` event, it is strongly recommended that a caller
862    /// ignoring all sync events calls `current_slot` and checks the
863    /// `ABS_MT_TRACKING_ID` values for all slots.
864    ///
865    /// If a device has changed state without events being enqueued in evdev,
866    /// e.g. after changing the file descriptor, use the `evdev::FORCE_SYNC` flag.
867    /// This triggers an internal sync of the device and `next_event` returns
868    /// `ReadStatus::Sync`.
869    pub fn next_event(&self, flags: ReadFlag) -> io::Result<(ReadStatus, InputEvent)> {
870        let mut ev = raw::input_event {
871            time: raw::timeval {
872                tv_sec: 0,
873                tv_usec: 0,
874            },
875            type_: 0,
876            code: 0,
877            value: 0,
878        };
879
880        let result = unsafe {
881            raw::libevdev_next_event(self.raw, flags.bits() as c_uint, &mut ev)
882        };
883
884        let event = InputEvent {
885            time: TimeVal {
886                tv_sec: ev.time.tv_sec,
887                tv_usec: ev.time.tv_usec,
888            },
889            event_code: int_to_event_code(ev.type_ as u32, ev.code as u32),
890            value: ev.value,
891        };
892
893        match result {
894            raw::LIBEVDEV_READ_STATUS_SUCCESS => Ok((ReadStatus::Success, event)),
895            raw::LIBEVDEV_READ_STATUS_SYNC => Ok((ReadStatus::Sync, event)),
896            error => Err(io::Error::from_raw_os_error(-error)),
897        }
898    }
899}
900
901impl Drop for Device {
902    fn drop(&mut self) {
903        unsafe {
904            raw::libevdev_free(self.raw);
905        }
906    }
907}
908
909impl std::fmt::Debug for Device {
910    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
911        f.debug_struct("Device")
912            .field("name", &self.name())
913            .field("phys", &self.phys())
914            .field("uniq", &self.uniq())
915            .finish()
916    }
917}
918
919impl AsRawFd for Device {
920    fn as_raw_fd(&self) -> RawFd {
921        self.file.as_raw_fd()
922    }
923}