1use crate::compat::{input_absinfo, input_event};
2use crate::constants::*;
3use crate::device_state::DeviceState;
4use crate::ff::*;
5use crate::raw_stream::RawDevice;
6use crate::{
7 AbsInfo, AttributeSet, AttributeSetRef, AutoRepeat, EventSummary, FFEffect, InputEvent,
8 InputId, KeyCode,
9};
10
11use nix::fcntl;
12use std::fs::File;
13use std::os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd};
14use std::path::Path;
15use std::time::SystemTime;
16use std::{fmt, io};
17
18pub struct Device {
31 raw: RawDevice,
32 prev_state: DeviceState,
33 state: DeviceState,
34 block_dropped: bool,
35}
36
37impl Device {
38 #[inline(always)]
42 pub fn open(path: impl AsRef<Path>) -> io::Result<Device> {
43 Self::_open(path.as_ref())
44 }
45
46 #[inline(always)]
48 pub fn from_fd(fd: OwnedFd) -> io::Result<Device> {
49 RawDevice::from_fd(fd).map(Self::from_raw_device)
50 }
51
52 #[inline]
53 fn _open(path: &Path) -> io::Result<Device> {
54 RawDevice::open(path).map(Self::from_raw_device)
55 }
56
57 pub(crate) fn from_raw_device(raw: RawDevice) -> Device {
59 let state = DeviceState::new(&raw);
60 let prev_state = state.clone();
61
62 Device {
63 raw,
64 prev_state,
65 state,
66 block_dropped: false,
67 }
68 }
69
70 pub fn cached_state(&self) -> &DeviceState {
79 &self.state
80 }
81
82 pub fn name(&self) -> Option<&str> {
84 self.raw.name()
85 }
86
87 pub fn physical_path(&self) -> Option<&str> {
89 self.raw.physical_path()
90 }
91
92 pub fn unique_name(&self) -> Option<&str> {
94 self.raw.unique_name()
95 }
96
97 pub fn input_id(&self) -> InputId {
99 self.raw.input_id()
100 }
101
102 pub fn get_auto_repeat(&self) -> Option<AutoRepeat> {
104 self.raw.get_auto_repeat()
105 }
106
107 pub fn update_auto_repeat(&mut self, repeat: &AutoRepeat) -> io::Result<()> {
109 self.raw.update_auto_repeat(repeat)
110 }
111
112 pub fn get_scancode_by_keycode(&self, keycode: KeyCode) -> io::Result<Vec<u8>> {
114 self.raw.get_scancode_by_keycode(keycode.code() as u32)
115 }
116
117 pub fn get_scancode_by_index(&self, index: u16) -> io::Result<(u32, Vec<u8>)> {
119 self.raw.get_scancode_by_index(index)
120 }
121
122 pub fn update_scancode(&self, keycode: KeyCode, scancode: &[u8]) -> io::Result<KeyCode> {
124 self.raw
125 .update_scancode(keycode.code() as u32, scancode)
126 .map(|keycode| KeyCode::new(keycode as u16))
127 }
128
129 pub fn update_scancode_by_index(
131 &self,
132 index: u16,
133 keycode: KeyCode,
134 scancode: &[u8],
135 ) -> io::Result<u32> {
136 self.raw
137 .update_scancode_by_index(index, keycode.code() as u32, scancode)
138 }
139
140 pub fn properties(&self) -> &AttributeSetRef<PropType> {
142 self.raw.properties()
143 }
144
145 pub fn driver_version(&self) -> (u8, u8, u8) {
147 self.raw.driver_version()
148 }
149
150 pub fn supported_events(&self) -> &AttributeSetRef<EventType> {
155 self.raw.supported_events()
156 }
157
158 pub fn supported_keys(&self) -> Option<&AttributeSetRef<KeyCode>> {
176 self.raw.supported_keys()
177 }
178
179 pub fn supported_relative_axes(&self) -> Option<&AttributeSetRef<RelativeAxisCode>> {
198 self.raw.supported_relative_axes()
199 }
200
201 pub fn supported_absolute_axes(&self) -> Option<&AttributeSetRef<AbsoluteAxisCode>> {
220 self.raw.supported_absolute_axes()
221 }
222
223 pub fn supported_switches(&self) -> Option<&AttributeSetRef<SwitchCode>> {
244 self.raw.supported_switches()
245 }
246
247 pub fn supported_leds(&self) -> Option<&AttributeSetRef<LedCode>> {
252 self.raw.supported_leds()
253 }
254
255 pub fn misc_properties(&self) -> Option<&AttributeSetRef<MiscCode>> {
259 self.raw.misc_properties()
260 }
261
262 pub fn supported_ff(&self) -> Option<&AttributeSetRef<FFEffectCode>> {
264 self.raw.supported_ff()
265 }
266
267 pub fn max_ff_effects(&self) -> usize {
269 self.raw.max_ff_effects()
270 }
271
272 pub fn supported_sounds(&self) -> Option<&AttributeSetRef<SoundCode>> {
277 self.raw.supported_sounds()
278 }
279
280 pub fn get_key_state(&self) -> io::Result<AttributeSet<KeyCode>> {
282 self.raw.get_key_state()
283 }
284
285 pub fn get_abs_state(&self) -> io::Result<[input_absinfo; AbsoluteAxisCode::COUNT]> {
287 self.raw.get_abs_state()
288 }
289
290 pub fn get_absinfo(
292 &self,
293 ) -> io::Result<impl Iterator<Item = (AbsoluteAxisCode, AbsInfo)> + '_> {
294 self.raw.get_absinfo()
295 }
296
297 pub fn get_switch_state(&self) -> io::Result<AttributeSet<SwitchCode>> {
299 self.raw.get_switch_state()
300 }
301
302 pub fn get_led_state(&self) -> io::Result<AttributeSet<LedCode>> {
304 self.raw.get_led_state()
305 }
306
307 fn sync_state(&mut self, now: SystemTime) -> io::Result<()> {
308 if let Some(ref mut key_vals) = self.state.key_vals {
309 self.raw.update_key_state(key_vals)?;
310 }
311 if let Some(ref mut abs_vals) = self.state.abs_vals {
312 self.raw.update_abs_state(abs_vals)?;
313 }
314 if let Some(ref mut switch_vals) = self.state.switch_vals {
315 self.raw.update_switch_state(switch_vals)?;
316 }
317 if let Some(ref mut led_vals) = self.state.led_vals {
318 self.raw.update_led_state(led_vals)?;
319 }
320 self.state.timestamp = now;
321 Ok(())
322 }
323
324 fn fetch_events_inner(&mut self) -> io::Result<Option<SyncState>> {
325 let block_dropped = std::mem::take(&mut self.block_dropped);
326 let sync = if block_dropped {
327 self.prev_state.clone_from(&self.state);
328 let now = SystemTime::now();
329 self.sync_state(now)?;
330 Some(SyncState::KeyTypes {
331 time: crate::systime_to_timeval(&now),
332 start: KeyCode::new(0),
333 })
334 } else {
335 None
336 };
337
338 self.raw.fill_events()?;
339
340 Ok(sync)
341 }
342
343 pub fn fetch_events(&mut self) -> io::Result<FetchEventsSynced<'_>> {
349 let sync = self.fetch_events_inner()?;
350
351 Ok(FetchEventsSynced {
352 dev: self,
353 range: 0..0,
354 consumed_to: 0,
355 sync,
356 })
357 }
358
359 #[cfg(feature = "tokio")]
360 pub fn into_event_stream(self) -> io::Result<EventStream> {
361 EventStream::new(self)
362 }
363
364 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
366 let mut flags =
367 fcntl::OFlag::from_bits_retain(fcntl::fcntl(self.as_raw_fd(), fcntl::F_GETFL)?);
368 flags.set(fcntl::OFlag::O_NONBLOCK, nonblocking);
369 fcntl::fcntl(self.as_raw_fd(), fcntl::F_SETFL(flags))?;
370 Ok(())
371 }
372
373 pub fn grab(&mut self) -> io::Result<()> {
378 self.raw.grab()
379 }
380
381 pub fn ungrab(&mut self) -> io::Result<()> {
383 self.raw.ungrab()
384 }
385
386 pub fn send_events(&mut self, events: &[InputEvent]) -> io::Result<()> {
393 self.raw.send_events(events)
394 }
395
396 pub fn upload_ff_effect(&mut self, data: FFEffectData) -> io::Result<FFEffect> {
398 self.raw.upload_ff_effect(data)
399 }
400
401 pub fn set_ff_gain(&mut self, value: u16) -> io::Result<()> {
404 self.raw.set_ff_gain(value)
405 }
406
407 pub fn set_ff_autocenter(&mut self, value: u16) -> io::Result<()> {
409 self.raw.set_ff_autocenter(value)
410 }
411}
412
413impl AsFd for Device {
414 fn as_fd(&self) -> BorrowedFd<'_> {
415 self.raw.as_fd()
416 }
417}
418
419impl AsRawFd for Device {
420 fn as_raw_fd(&self) -> RawFd {
421 self.raw.as_raw_fd()
422 }
423}
424
425impl TryFrom<File> for Device {
426 type Error = io::Error;
427
428 fn try_from(file: File) -> Result<Self, Self::Error> {
429 RawDevice::try_from(file).map(Self::from_raw_device)
430 }
431}
432
433pub struct FetchEventsSynced<'a> {
435 dev: &'a mut Device,
436 range: std::ops::Range<usize>,
439 consumed_to: usize,
441 sync: Option<SyncState>,
444}
445
446enum SyncState {
447 KeyTypes {
448 time: libc::timeval,
449 start: KeyCode,
450 },
451 Absolutes {
452 time: libc::timeval,
453 start: AbsoluteAxisCode,
454 },
455 Switches {
456 time: libc::timeval,
457 start: SwitchCode,
458 },
459 Leds {
460 time: libc::timeval,
461 start: LedCode,
462 },
463}
464
465#[inline]
466fn compensate_events(state: &mut Option<SyncState>, dev: &mut Device) -> Option<InputEvent> {
467 let sync = state.as_mut()?;
468 macro_rules! try_compensate {
472 ($time:expr, $start:ident : $typ:ident, $evtype:ident, $sync:ident, $supporteds:ident, $state:ty, $get_state:expr, $get_value:expr) => {
473 if let Some(supported_types) = dev.$supporteds() {
474 let types_to_check = supported_types.slice(*$start);
475 let get_state: fn(&DeviceState) -> $state = $get_state;
476 let vals = get_state(&dev.state);
477 let old_vals = get_state(&dev.prev_state);
478 let get_value: fn($state, $typ) -> _ = $get_value;
479 for typ in types_to_check.iter() {
480 let prev = get_value(old_vals, typ);
481 let value = get_value(vals, typ);
482 if prev != value {
483 $start.0 = typ.0 + 1;
484 let ev = InputEvent::from(input_event {
485 time: *$time,
486 type_: EventType::$evtype.0,
487 code: typ.0,
488 value: value as _,
489 });
490 return Some(ev);
491 }
492 }
493 }
494 };
495 }
496 loop {
497 match sync {
499 SyncState::KeyTypes { time, start } => {
500 try_compensate!(
501 time,
502 start: KeyCode,
503 KEY,
504 KeyTypes,
505 supported_keys,
506 &AttributeSetRef<KeyCode>,
507 |st| st.key_vals().unwrap(),
508 |vals, key| vals.contains(key)
509 );
510 *sync = SyncState::Absolutes {
511 time: *time,
512 start: AbsoluteAxisCode(0),
513 };
514 continue;
515 }
516 SyncState::Absolutes { time, start } => {
517 try_compensate!(
518 time,
519 start: AbsoluteAxisCode,
520 ABSOLUTE,
521 Absolutes,
522 supported_absolute_axes,
523 &[input_absinfo],
524 |st| st.abs_vals().unwrap(),
525 |vals, abs| vals[abs.0 as usize].value
526 );
527 *sync = SyncState::Switches {
528 time: *time,
529 start: SwitchCode(0),
530 };
531 continue;
532 }
533 SyncState::Switches { time, start } => {
534 try_compensate!(
535 time,
536 start: SwitchCode,
537 SWITCH,
538 Switches,
539 supported_switches,
540 &AttributeSetRef<SwitchCode>,
541 |st| st.switch_vals().unwrap(),
542 |vals, sw| vals.contains(sw)
543 );
544 *sync = SyncState::Leds {
545 time: *time,
546 start: LedCode(0),
547 };
548 continue;
549 }
550 SyncState::Leds { time, start } => {
551 try_compensate!(
552 time,
553 start: LedCode,
554 LED,
555 Leds,
556 supported_leds,
557 &AttributeSetRef<LedCode>,
558 |st| st.led_vals().unwrap(),
559 |vals, led| vals.contains(led)
560 );
561 let ev = InputEvent::from(input_event {
562 time: *time,
563 type_: EventType::SYNCHRONIZATION.0,
564 code: SynchronizationCode::SYN_REPORT.0,
565 value: 0,
566 });
567 *state = None;
568 return Some(ev);
569 }
570 }
571 }
572}
573
574impl Iterator for FetchEventsSynced<'_> {
575 type Item = InputEvent;
576 fn next(&mut self) -> Option<InputEvent> {
577 if let Some(ev) = compensate_events(&mut self.sync, self.dev) {
580 self.dev.prev_state.process_event(ev);
581 return Some(ev);
582 }
583 let state = &mut self.dev.state;
584 let (res, consumed_to) = sync_events(&mut self.range, &self.dev.raw.event_buf, |ev| {
585 state.process_event(ev)
586 });
587 if let Some(end) = consumed_to {
588 self.consumed_to = end
589 }
590 match res {
591 Ok(ev) => Some(InputEvent::from(ev)),
592 Err(requires_sync) => {
593 if requires_sync {
594 self.dev.block_dropped = true;
595 }
596 None
597 }
598 }
599 }
600}
601
602impl Drop for FetchEventsSynced<'_> {
603 fn drop(&mut self) {
604 self.dev.raw.event_buf.drain(..self.consumed_to);
605 }
606}
607
608#[inline]
610fn sync_events(
611 range: &mut std::ops::Range<usize>,
612 event_buf: &[input_event],
613 mut handle_event: impl FnMut(InputEvent),
614) -> (Result<input_event, bool>, Option<usize>) {
615 let mut consumed_to = None;
616 let res = 'outer: loop {
617 if let Some(idx) = range.next() {
618 break Ok(event_buf[idx]);
620 }
621 let block_start = range.end;
623 let mut block_dropped = false;
624 for (i, ev) in event_buf.iter().enumerate().skip(block_start) {
625 let ev = InputEvent::from(*ev);
626 match ev.destructure() {
627 EventSummary::Synchronization(_, SynchronizationCode::SYN_DROPPED, _) => {
628 block_dropped = true;
629 }
630 EventSummary::Synchronization(_, SynchronizationCode::SYN_REPORT, _) => {
631 consumed_to = Some(i + 1);
632 if block_dropped {
633 *range = event_buf.len()..event_buf.len();
634 break 'outer Err(true);
635 } else {
636 *range = block_start..i + 1;
637 continue 'outer;
638 }
639 }
640 _ => handle_event(ev),
641 }
642 }
643 break Err(false);
644 };
645 (res, consumed_to)
646}
647
648impl fmt::Display for Device {
649 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
650 writeln!(f, "{}:", self.name().unwrap_or("Unnamed device"))?;
651 let (maj, min, pat) = self.driver_version();
652 writeln!(f, " Driver version: {maj}.{min}.{pat}")?;
653 if let Some(ref phys) = self.physical_path() {
654 writeln!(f, " Physical address: {phys:?}")?;
655 }
656 if let Some(ref uniq) = self.unique_name() {
657 writeln!(f, " Unique name: {uniq:?}")?;
658 }
659
660 let id = self.input_id();
661
662 writeln!(f, " Bus: {}", id.bus_type())?;
663 writeln!(f, " Vendor: {:#x}", id.vendor())?;
664 writeln!(f, " Product: {:#x}", id.product())?;
665 writeln!(f, " Version: {:#x}", id.version())?;
666 writeln!(f, " Properties: {:?}", self.properties())?;
667
668 if let (Some(supported_keys), Some(key_vals)) =
669 (self.supported_keys(), self.state.key_vals())
670 {
671 writeln!(f, " KeyTypes supported:")?;
672 for key in supported_keys.iter() {
673 let key_idx = key.code() as usize;
674 writeln!(
675 f,
676 " {:?} ({}index {})",
677 key,
678 if key_vals.contains(key) {
679 "pressed, "
680 } else {
681 ""
682 },
683 key_idx
684 )?;
685 }
686 }
687
688 if let Some(supported_relative) = self.supported_relative_axes() {
689 writeln!(f, " Relative Axes: {supported_relative:?}")?;
690 }
691
692 if let (Some(supported_abs), Some(abs_vals)) =
693 (self.supported_absolute_axes(), &self.state.abs_vals)
694 {
695 writeln!(f, " Absolute Axes:")?;
696 for abs in supported_abs.iter() {
697 writeln!(
698 f,
699 " {:?} ({:?}, index {})",
700 abs, abs_vals[abs.0 as usize], abs.0
701 )?;
702 }
703 }
704
705 if let Some(supported_misc) = self.misc_properties() {
706 writeln!(f, " Miscellaneous capabilities: {supported_misc:?}")?;
707 }
708
709 if let (Some(supported_switch), Some(switch_vals)) =
710 (self.supported_switches(), self.state.switch_vals())
711 {
712 writeln!(f, " Switches:")?;
713 for sw in supported_switch.iter() {
714 writeln!(
715 f,
716 " {:?} ({:?}, index {})",
717 sw,
718 switch_vals.contains(sw),
719 sw.0
720 )?;
721 }
722 }
723
724 if let (Some(supported_led), Some(led_vals)) =
725 (self.supported_leds(), self.state.led_vals())
726 {
727 writeln!(f, " LEDs:")?;
728 for led in supported_led.iter() {
729 writeln!(
730 f,
731 " {:?} ({:?}, index {})",
732 led,
733 led_vals.contains(led),
734 led.0
735 )?;
736 }
737 }
738
739 if let Some(supported_snd) = self.supported_sounds() {
740 write!(f, " Sounds:")?;
741 for snd in supported_snd.iter() {
742 writeln!(f, " {:?} (index {})", snd, snd.0)?;
743 }
744 }
745
746 let evs = self.supported_events();
751
752 if evs.contains(EventType::FORCEFEEDBACK) {
753 writeln!(f, " Force Feedback supported")?;
754 }
755
756 if evs.contains(EventType::POWER) {
757 writeln!(f, " Power supported")?;
758 }
759
760 if evs.contains(EventType::FORCEFEEDBACKSTATUS) {
761 writeln!(f, " Force Feedback status supported")?;
762 }
763
764 Ok(())
765 }
766}
767
768#[cfg(feature = "tokio")]
769mod tokio_stream {
770 use super::*;
771
772 use std::future::poll_fn;
773 use std::task::{ready, Context, Poll};
774 use tokio::io::unix::AsyncFd;
775
776 pub struct EventStream {
783 device: AsyncFd<Device>,
784 event_range: std::ops::Range<usize>,
785 consumed_to: usize,
786 sync: Option<SyncState>,
787 }
788 impl Unpin for EventStream {}
789
790 impl EventStream {
791 pub(crate) fn new(device: Device) -> io::Result<Self> {
792 device.set_nonblocking(true)?;
793 let device = AsyncFd::new(device)?;
794 Ok(Self {
795 device,
796 event_range: 0..0,
797 consumed_to: 0,
798 sync: None,
799 })
800 }
801
802 pub fn device(&self) -> &Device {
804 self.device.get_ref()
805 }
806
807 pub fn device_mut(&mut self) -> &mut Device {
809 self.device.get_mut()
810 }
811
812 pub async fn next_event(&mut self) -> io::Result<InputEvent> {
815 poll_fn(|cx| self.poll_event(cx)).await
816 }
817
818 pub fn poll_event(&mut self, cx: &mut Context<'_>) -> Poll<io::Result<InputEvent>> {
820 'outer: loop {
821 let dev = self.device.get_mut();
822 if let Some(ev) = compensate_events(&mut self.sync, dev) {
823 return Poll::Ready(Ok(ev));
824 }
825 let state = &mut dev.state;
826 let (res, consumed_to) =
827 sync_events(&mut self.event_range, &dev.raw.event_buf, |ev| {
828 state.process_event(ev)
829 });
830 if let Some(end) = consumed_to {
831 self.consumed_to = end
832 }
833 match res {
834 Ok(ev) => return Poll::Ready(Ok(InputEvent::from(ev))),
835 Err(requires_sync) => {
836 if requires_sync {
837 dev.block_dropped = true;
838 }
839 }
840 }
841 dev.raw.event_buf.drain(..self.consumed_to);
842 self.consumed_to = 0;
843
844 loop {
845 let mut guard = ready!(self.device.poll_read_ready_mut(cx))?;
846
847 let res = guard.try_io(|device| device.get_mut().fetch_events_inner());
848 match res {
849 Ok(res) => {
850 self.sync = res?;
851 self.event_range = 0..0;
852 continue 'outer;
853 }
854 Err(_would_block) => continue,
855 }
856 }
857 }
858 }
859 }
860
861 #[cfg(feature = "stream-trait")]
862 impl futures_core::Stream for EventStream {
863 type Item = io::Result<InputEvent>;
864 fn poll_next(
865 self: std::pin::Pin<&mut Self>,
866 cx: &mut Context<'_>,
867 ) -> Poll<Option<Self::Item>> {
868 self.get_mut().poll_event(cx).map(Some)
869 }
870 }
871}
872#[cfg(feature = "tokio")]
873pub use tokio_stream::EventStream;
874
875#[cfg(test)]
876mod tests {
877 use super::*;
878
879 fn result_events_iter(
880 events: &[input_event],
881 ) -> impl Iterator<Item = Result<input_event, ()>> + '_ {
882 let mut range = 0..0;
883 std::iter::from_fn(move || {
884 let (res, _) = sync_events(&mut range, events, |_| {});
885 match res {
886 Ok(x) => Some(Ok(x)),
887 Err(true) => Some(Err(())),
888 Err(false) => None,
889 }
890 })
891 }
892
893 fn events_iter(events: &[input_event]) -> impl Iterator<Item = input_event> + '_ {
894 result_events_iter(events).flatten()
895 }
896
897 #[allow(non_upper_case_globals)]
898 const time: libc::timeval = libc::timeval {
899 tv_sec: 0,
900 tv_usec: 0,
901 };
902 const KEY4: input_event = input_event {
903 time,
904 type_: EventType::KEY.0,
905 code: KeyCode::KEY_4.0,
906 value: 1,
907 };
908 const REPORT: input_event = input_event {
909 time,
910 type_: EventType::SYNCHRONIZATION.0,
911 code: SynchronizationCode::SYN_REPORT.0,
912 value: 0,
913 };
914 const DROPPED: input_event = input_event {
915 code: SynchronizationCode::SYN_DROPPED.0,
916 ..REPORT
917 };
918
919 #[test]
920 fn test_sync_impl() {
921 itertools::assert_equal(events_iter(&[]), vec![]);
922 itertools::assert_equal(events_iter(&[KEY4]), vec![]);
923 itertools::assert_equal(events_iter(&[KEY4, REPORT]), vec![KEY4, REPORT]);
924 itertools::assert_equal(events_iter(&[KEY4, REPORT, KEY4]), vec![KEY4, REPORT]);
925 itertools::assert_equal(
926 result_events_iter(&[KEY4, REPORT, KEY4, DROPPED, REPORT]),
927 vec![Ok(KEY4), Ok(REPORT), Err(())],
928 );
929 }
930
931 #[test]
932 fn test_iter_consistency() {
933 let evs = &[KEY4, REPORT, DROPPED, REPORT, KEY4, REPORT, KEY4];
936 let mut range = 0..0;
937 let mut next = || sync_events(&mut range, evs, |_| {});
938 assert_eq!(next(), (Ok(KEY4), Some(2)));
939 assert_eq!(next(), (Ok(REPORT), None));
940 assert_eq!(next(), (Err(true), Some(4)));
941 assert_eq!(next(), (Err(false), None));
942 assert_eq!(next(), (Err(false), None));
943 assert_eq!(next(), (Err(false), None));
944 }
945}