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}