1use crate::constants::*;
2use crate::device_state::DeviceState;
3use crate::raw_stream::RawDevice;
4use crate::{AttributeSet, AttributeSetRef, AutoRepeat, InputEvent, InputEventKind, InputId, Key};
5use std::os::unix::io::{AsRawFd, RawFd};
6use std::path::Path;
7use std::time::SystemTime;
8use std::{fmt, io};
9
10pub struct Device {
23 raw: RawDevice,
24 prev_state: DeviceState,
25 state: DeviceState,
26 block_dropped: bool,
27}
28
29impl Device {
30 #[inline(always)]
34 pub fn open(path: impl AsRef<Path>) -> io::Result<Device> {
35 Self::_open(path.as_ref())
36 }
37
38 #[inline]
39 fn _open(path: &Path) -> io::Result<Device> {
40 RawDevice::open(path).map(Self::from_raw_device)
41 }
42
43 pub(crate) fn from_raw_device(raw: RawDevice) -> Device {
45 let state = DeviceState::new(&raw);
46 let prev_state = state.clone();
47
48 Device {
49 raw,
50 prev_state,
51 state,
52 block_dropped: false,
53 }
54 }
55
56 pub fn cached_state(&self) -> &DeviceState {
65 &self.state
66 }
67
68 pub fn name(&self) -> Option<&str> {
70 self.raw.name()
71 }
72
73 pub fn physical_path(&self) -> Option<&str> {
75 self.raw.physical_path()
76 }
77
78 pub fn unique_name(&self) -> Option<&str> {
80 self.raw.unique_name()
81 }
82
83 pub fn input_id(&self) -> InputId {
85 self.raw.input_id()
86 }
87
88 pub fn get_auto_repeat(&self) -> Option<AutoRepeat> {
90 self.raw.get_auto_repeat()
91 }
92
93 pub fn update_auto_repeat(&mut self, repeat: &AutoRepeat) -> io::Result<()> {
95 self.raw.update_auto_repeat(repeat)
96 }
97
98 pub fn get_scancode_by_keycode(&self, keycode: Key) -> io::Result<Vec<u8>> {
100 self.raw.get_scancode_by_keycode(keycode.code() as u32)
101 }
102
103 pub fn get_scancode_by_index(&self, index: u16) -> io::Result<(u32, Vec<u8>)> {
105 self.raw.get_scancode_by_index(index)
106 }
107
108 pub fn update_scancode(&self, keycode: Key, scancode: &[u8]) -> io::Result<Key> {
110 self.raw
111 .update_scancode(keycode.code() as u32, scancode)
112 .map(|keycode| Key::new(keycode as u16))
113 }
114
115 pub fn update_scancode_by_index(
117 &self,
118 index: u16,
119 keycode: Key,
120 scancode: &[u8],
121 ) -> io::Result<u32> {
122 self.raw
123 .update_scancode_by_index(index, keycode.code() as u32, scancode)
124 }
125
126 pub fn properties(&self) -> &AttributeSetRef<PropType> {
128 self.raw.properties()
129 }
130
131 pub fn driver_version(&self) -> (u8, u8, u8) {
133 self.raw.driver_version()
134 }
135
136 pub fn supported_events(&self) -> &AttributeSetRef<EventType> {
141 self.raw.supported_events()
142 }
143
144 pub fn supported_keys(&self) -> Option<&AttributeSetRef<Key>> {
162 self.raw.supported_keys()
163 }
164
165 pub fn supported_relative_axes(&self) -> Option<&AttributeSetRef<RelativeAxisType>> {
184 self.raw.supported_relative_axes()
185 }
186
187 pub fn supported_absolute_axes(&self) -> Option<&AttributeSetRef<AbsoluteAxisType>> {
206 self.raw.supported_absolute_axes()
207 }
208
209 pub fn supported_switches(&self) -> Option<&AttributeSetRef<SwitchType>> {
230 self.raw.supported_switches()
231 }
232
233 pub fn supported_leds(&self) -> Option<&AttributeSetRef<LedType>> {
238 self.raw.supported_leds()
239 }
240
241 pub fn misc_properties(&self) -> Option<&AttributeSetRef<MiscType>> {
245 self.raw.misc_properties()
246 }
247
248 pub fn supported_sounds(&self) -> Option<&AttributeSetRef<SoundType>> {
253 self.raw.supported_sounds()
254 }
255
256 pub fn get_key_state(&self) -> io::Result<AttributeSet<Key>> {
258 self.raw.get_key_state()
259 }
260
261 pub fn get_abs_state(&self) -> io::Result<[libc::input_absinfo; AbsoluteAxisType::COUNT]> {
263 self.raw.get_abs_state()
264 }
265
266 pub fn get_switch_state(&self) -> io::Result<AttributeSet<SwitchType>> {
268 self.raw.get_switch_state()
269 }
270
271 pub fn get_led_state(&self) -> io::Result<AttributeSet<LedType>> {
273 self.raw.get_led_state()
274 }
275
276 fn sync_state(&mut self, now: SystemTime) -> io::Result<()> {
277 if let Some(ref mut key_vals) = self.state.key_vals {
278 self.raw.update_key_state(key_vals)?;
279 }
280 if let Some(ref mut abs_vals) = self.state.abs_vals {
281 self.raw.update_abs_state(abs_vals)?;
282 }
283 if let Some(ref mut switch_vals) = self.state.switch_vals {
284 self.raw.update_switch_state(switch_vals)?;
285 }
286 if let Some(ref mut led_vals) = self.state.led_vals {
287 self.raw.update_led_state(led_vals)?;
288 }
289 self.state.timestamp = now;
290 Ok(())
291 }
292
293 fn fetch_events_inner(&mut self) -> io::Result<Option<SyncState>> {
294 let block_dropped = std::mem::take(&mut self.block_dropped);
295 let sync = if block_dropped {
296 self.prev_state.clone_from(&self.state);
297 let now = SystemTime::now();
298 self.sync_state(now)?;
299 Some(SyncState::Keys {
300 time: crate::systime_to_timeval(&now),
301 start: Key::new(0),
302 })
303 } else {
304 None
305 };
306
307 self.raw.fill_events()?;
308
309 Ok(sync)
310 }
311
312 pub fn fetch_events(&mut self) -> io::Result<FetchEventsSynced<'_>> {
318 let sync = self.fetch_events_inner()?;
319
320 Ok(FetchEventsSynced {
321 dev: self,
322 range: 0..0,
323 consumed_to: 0,
324 sync,
325 })
326 }
327
328 #[cfg(feature = "tokio")]
329 pub fn into_event_stream(self) -> io::Result<EventStream> {
330 EventStream::new(self)
331 }
332
333 pub fn grab(&mut self) -> io::Result<()> {
338 self.raw.grab()
339 }
340
341 pub fn ungrab(&mut self) -> io::Result<()> {
343 self.raw.ungrab()
344 }
345}
346
347impl AsRawFd for Device {
348 fn as_raw_fd(&self) -> RawFd {
349 self.raw.as_raw_fd()
350 }
351}
352
353pub struct FetchEventsSynced<'a> {
355 dev: &'a mut Device,
356 range: std::ops::Range<usize>,
359 consumed_to: usize,
361 sync: Option<SyncState>,
364}
365
366enum SyncState {
367 Keys {
368 time: libc::timeval,
369 start: Key,
370 },
371 Absolutes {
372 time: libc::timeval,
373 start: AbsoluteAxisType,
374 },
375 Switches {
376 time: libc::timeval,
377 start: SwitchType,
378 },
379 Leds {
380 time: libc::timeval,
381 start: LedType,
382 },
383}
384
385#[inline]
386fn compensate_events(state: &mut Option<SyncState>, dev: &mut Device) -> Option<InputEvent> {
387 let sync = state.as_mut()?;
388 macro_rules! try_compensate {
392 ($time:expr, $start:ident : $typ:ident, $evtype:ident, $sync:ident, $supporteds:ident, $state:ty, $get_state:expr, $get_value:expr) => {
393 if let Some(supported_types) = dev.$supporteds() {
394 let types_to_check = supported_types.slice(*$start);
395 let get_state: fn(&DeviceState) -> $state = $get_state;
396 let vals = get_state(&dev.state);
397 let old_vals = get_state(&dev.prev_state);
398 let get_value: fn($state, $typ) -> _ = $get_value;
399 for typ in types_to_check.iter() {
400 let prev = get_value(old_vals, typ);
401 let value = get_value(vals, typ);
402 if prev != value {
403 $start.0 = typ.0 + 1;
404 let ev = InputEvent(libc::input_event {
405 time: *$time,
406 type_: EventType::$evtype.0,
407 code: typ.0,
408 value: value as _,
409 });
410 return Some(ev);
411 }
412 }
413 }
414 };
415 }
416 loop {
417 match sync {
419 SyncState::Keys { time, start } => {
420 try_compensate!(
421 time,
422 start: Key,
423 KEY,
424 Keys,
425 supported_keys,
426 &AttributeSetRef<Key>,
427 |st| st.key_vals().unwrap(),
428 |vals, key| vals.contains(key)
429 );
430 *sync = SyncState::Absolutes {
431 time: *time,
432 start: AbsoluteAxisType(0),
433 };
434 continue;
435 }
436 SyncState::Absolutes { time, start } => {
437 try_compensate!(
438 time,
439 start: AbsoluteAxisType,
440 ABSOLUTE,
441 Absolutes,
442 supported_absolute_axes,
443 &[libc::input_absinfo],
444 |st| st.abs_vals().unwrap(),
445 |vals, abs| vals[abs.0 as usize].value
446 );
447 *sync = SyncState::Switches {
448 time: *time,
449 start: SwitchType(0),
450 };
451 continue;
452 }
453 SyncState::Switches { time, start } => {
454 try_compensate!(
455 time,
456 start: SwitchType,
457 SWITCH,
458 Switches,
459 supported_switches,
460 &AttributeSetRef<SwitchType>,
461 |st| st.switch_vals().unwrap(),
462 |vals, sw| vals.contains(sw)
463 );
464 *sync = SyncState::Leds {
465 time: *time,
466 start: LedType(0),
467 };
468 continue;
469 }
470 SyncState::Leds { time, start } => {
471 try_compensate!(
472 time,
473 start: LedType,
474 LED,
475 Leds,
476 supported_leds,
477 &AttributeSetRef<LedType>,
478 |st| st.led_vals().unwrap(),
479 |vals, led| vals.contains(led)
480 );
481 let ev = InputEvent(libc::input_event {
482 time: *time,
483 type_: EventType::SYNCHRONIZATION.0,
484 code: Synchronization::SYN_REPORT.0,
485 value: 0,
486 });
487 *state = None;
488 return Some(ev);
489 }
490 }
491 }
492}
493
494impl<'a> Iterator for FetchEventsSynced<'a> {
495 type Item = InputEvent;
496 fn next(&mut self) -> Option<InputEvent> {
497 if let Some(ev) = compensate_events(&mut self.sync, &mut self.dev) {
500 return Some(ev);
501 }
502 let state = &mut self.dev.state;
503 let (res, consumed_to) = sync_events(&mut self.range, &self.dev.raw.event_buf, |ev| {
504 state.process_event(ev)
505 });
506 if let Some(end) = consumed_to {
507 self.consumed_to = end
508 }
509 match res {
510 Ok(ev) => Some(InputEvent(ev)),
511 Err(requires_sync) => {
512 if requires_sync {
513 self.dev.block_dropped = true;
514 }
515 None
516 }
517 }
518 }
519}
520
521impl<'a> Drop for FetchEventsSynced<'a> {
522 fn drop(&mut self) {
523 self.dev.raw.event_buf.drain(..self.consumed_to);
524 }
525}
526
527#[inline]
529fn sync_events(
530 range: &mut std::ops::Range<usize>,
531 event_buf: &[libc::input_event],
532 mut handle_event: impl FnMut(InputEvent),
533) -> (Result<libc::input_event, bool>, Option<usize>) {
534 let mut consumed_to = None;
535 let res = 'outer: loop {
536 if let Some(idx) = range.next() {
537 break Ok(event_buf[idx]);
539 }
540 let block_start = range.end;
542 let mut block_dropped = false;
543 for (i, ev) in event_buf.iter().enumerate().skip(block_start) {
544 let ev = InputEvent(*ev);
545 match ev.kind() {
546 InputEventKind::Synchronization(Synchronization::SYN_DROPPED) => {
547 block_dropped = true;
548 }
549 InputEventKind::Synchronization(Synchronization::SYN_REPORT) => {
550 consumed_to = Some(i + 1);
551 if block_dropped {
552 *range = event_buf.len()..event_buf.len();
553 break 'outer Err(true);
554 } else {
555 *range = block_start..i + 1;
556 continue 'outer;
557 }
558 }
559 _ => handle_event(ev),
560 }
561 }
562 break Err(false);
563 };
564 (res, consumed_to)
565}
566
567impl fmt::Display for Device {
568 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
569 writeln!(f, "{}:", self.name().unwrap_or("Unnamed device"))?;
570 let (maj, min, pat) = self.driver_version();
571 writeln!(f, " Driver version: {}.{}.{}", maj, min, pat)?;
572 if let Some(ref phys) = self.physical_path() {
573 writeln!(f, " Physical address: {:?}", phys)?;
574 }
575 if let Some(ref uniq) = self.unique_name() {
576 writeln!(f, " Unique name: {:?}", uniq)?;
577 }
578
579 let id = self.input_id();
580
581 writeln!(f, " Bus: {}", id.bus_type())?;
582 writeln!(f, " Vendor: {:#x}", id.vendor())?;
583 writeln!(f, " Product: {:#x}", id.product())?;
584 writeln!(f, " Version: {:#x}", id.version())?;
585 writeln!(f, " Properties: {:?}", self.properties())?;
586
587 if let (Some(supported_keys), Some(key_vals)) =
588 (self.supported_keys(), self.state.key_vals())
589 {
590 writeln!(f, " Keys supported:")?;
591 for key in supported_keys.iter() {
592 let key_idx = key.code() as usize;
593 writeln!(
594 f,
595 " {:?} ({}index {})",
596 key,
597 if key_vals.contains(key) {
598 "pressed, "
599 } else {
600 ""
601 },
602 key_idx
603 )?;
604 }
605 }
606
607 if let Some(supported_relative) = self.supported_relative_axes() {
608 writeln!(f, " Relative Axes: {:?}", supported_relative)?;
609 }
610
611 if let (Some(supported_abs), Some(abs_vals)) =
612 (self.supported_absolute_axes(), &self.state.abs_vals)
613 {
614 writeln!(f, " Absolute Axes:")?;
615 for abs in supported_abs.iter() {
616 writeln!(
617 f,
618 " {:?} ({:?}, index {})",
619 abs, abs_vals[abs.0 as usize], abs.0
620 )?;
621 }
622 }
623
624 if let Some(supported_misc) = self.misc_properties() {
625 writeln!(f, " Miscellaneous capabilities: {:?}", supported_misc)?;
626 }
627
628 if let (Some(supported_switch), Some(switch_vals)) =
629 (self.supported_switches(), self.state.switch_vals())
630 {
631 writeln!(f, " Switches:")?;
632 for sw in supported_switch.iter() {
633 writeln!(
634 f,
635 " {:?} ({:?}, index {})",
636 sw,
637 switch_vals.contains(sw),
638 sw.0
639 )?;
640 }
641 }
642
643 if let (Some(supported_led), Some(led_vals)) =
644 (self.supported_leds(), self.state.led_vals())
645 {
646 writeln!(f, " LEDs:")?;
647 for led in supported_led.iter() {
648 writeln!(
649 f,
650 " {:?} ({:?}, index {})",
651 led,
652 led_vals.contains(led),
653 led.0
654 )?;
655 }
656 }
657
658 if let Some(supported_snd) = self.supported_sounds() {
659 write!(f, " Sounds:")?;
660 for snd in supported_snd.iter() {
661 writeln!(f, " {:?} (index {})", snd, snd.0)?;
662 }
663 }
664
665 let evs = self.supported_events();
670
671 if evs.contains(EventType::FORCEFEEDBACK) {
672 writeln!(f, " Force Feedback supported")?;
673 }
674
675 if evs.contains(EventType::POWER) {
676 writeln!(f, " Power supported")?;
677 }
678
679 if evs.contains(EventType::FORCEFEEDBACKSTATUS) {
680 writeln!(f, " Force Feedback status supported")?;
681 }
682
683 Ok(())
684 }
685}
686
687#[cfg(feature = "tokio")]
688mod tokio_stream {
689 use super::*;
690
691 use tokio_1 as tokio;
692
693 use crate::raw_stream::poll_fn;
694 use futures_core::{ready, Stream};
695 use std::pin::Pin;
696 use std::task::{Context, Poll};
697 use tokio::io::unix::AsyncFd;
698
699 pub struct EventStream {
706 device: AsyncFd<Device>,
707 event_range: std::ops::Range<usize>,
708 consumed_to: usize,
709 sync: Option<SyncState>,
710 }
711 impl Unpin for EventStream {}
712
713 impl EventStream {
714 pub(crate) fn new(device: Device) -> io::Result<Self> {
715 use nix::fcntl;
716 fcntl::fcntl(device.as_raw_fd(), fcntl::F_SETFL(fcntl::OFlag::O_NONBLOCK))?;
717 let device = AsyncFd::new(device)?;
718 Ok(Self {
719 device,
720 event_range: 0..0,
721 consumed_to: 0,
722 sync: None,
723 })
724 }
725
726 pub fn device(&self) -> &Device {
728 self.device.get_ref()
729 }
730
731 pub async fn next_event(&mut self) -> io::Result<InputEvent> {
734 poll_fn(|cx| self.poll_event(cx)).await
735 }
736
737 pub fn poll_event(&mut self, cx: &mut Context<'_>) -> Poll<io::Result<InputEvent>> {
739 'outer: loop {
740 let dev = self.device.get_mut();
741 if let Some(ev) = compensate_events(&mut self.sync, dev) {
742 return Poll::Ready(Ok(ev));
743 }
744 let state = &mut dev.state;
745 let (res, consumed_to) =
746 sync_events(&mut self.event_range, &dev.raw.event_buf, |ev| {
747 state.process_event(ev)
748 });
749 if let Some(end) = consumed_to {
750 self.consumed_to = end
751 }
752 match res {
753 Ok(ev) => return Poll::Ready(Ok(InputEvent(ev))),
754 Err(requires_sync) => {
755 if requires_sync {
756 dev.block_dropped = true;
757 }
758 }
759 }
760 dev.raw.event_buf.drain(..self.consumed_to);
761 self.consumed_to = 0;
762
763 loop {
764 let mut guard = ready!(self.device.poll_read_ready_mut(cx))?;
765
766 let res = guard.try_io(|device| device.get_mut().fetch_events_inner());
767 match res {
768 Ok(res) => {
769 self.sync = res?;
770 self.event_range = 0..0;
771 continue 'outer;
772 }
773 Err(_would_block) => continue,
774 }
775 }
776 }
777 }
778 }
779
780 impl Stream for EventStream {
781 type Item = io::Result<InputEvent>;
782 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
783 self.get_mut().poll_event(cx).map(Some)
784 }
785 }
786}
787#[cfg(feature = "tokio")]
788pub use tokio_stream::EventStream;
789
790#[cfg(test)]
791mod tests {
792 use super::*;
793
794 fn result_events_iter(
795 events: &[libc::input_event],
796 ) -> impl Iterator<Item = Result<libc::input_event, ()>> + '_ {
797 let mut range = 0..0;
798 std::iter::from_fn(move || {
799 let (res, _) = sync_events(&mut range, events, |_| {});
800 match res {
801 Ok(x) => Some(Ok(x)),
802 Err(true) => Some(Err(())),
803 Err(false) => None,
804 }
805 })
806 }
807
808 fn events_iter(events: &[libc::input_event]) -> impl Iterator<Item = libc::input_event> + '_ {
809 result_events_iter(events).flatten()
810 }
811
812 #[allow(non_upper_case_globals)]
813 const time: libc::timeval = libc::timeval {
814 tv_sec: 0,
815 tv_usec: 0,
816 };
817 const KEY4: libc::input_event = libc::input_event {
818 time,
819 type_: EventType::KEY.0,
820 code: Key::KEY_4.0,
821 value: 1,
822 };
823 const REPORT: libc::input_event = libc::input_event {
824 time,
825 type_: EventType::SYNCHRONIZATION.0,
826 code: Synchronization::SYN_REPORT.0,
827 value: 0,
828 };
829 const DROPPED: libc::input_event = libc::input_event {
830 code: Synchronization::SYN_DROPPED.0,
831 ..REPORT
832 };
833
834 #[test]
835 fn test_sync_impl() {
836 itertools::assert_equal(events_iter(&[]), vec![]);
837 itertools::assert_equal(events_iter(&[KEY4]), vec![]);
838 itertools::assert_equal(events_iter(&[KEY4, REPORT]), vec![KEY4, REPORT]);
839 itertools::assert_equal(events_iter(&[KEY4, REPORT, KEY4]), vec![KEY4, REPORT]);
840 itertools::assert_equal(
841 result_events_iter(&[KEY4, REPORT, KEY4, DROPPED, REPORT]),
842 vec![Ok(KEY4), Ok(REPORT), Err(())],
843 );
844 }
845
846 #[test]
847 fn test_iter_consistency() {
848 let evs = &[KEY4, REPORT, DROPPED, REPORT, KEY4, REPORT, KEY4];
851 let mut range = 0..0;
852 let mut next = || sync_events(&mut range, evs, |_| {});
853 assert_eq!(next(), (Ok(KEY4), Some(2)));
854 assert_eq!(next(), (Ok(REPORT), None));
855 assert_eq!(next(), (Err(true), Some(4)));
856 assert_eq!(next(), (Err(false), None));
857 assert_eq!(next(), (Err(false), None));
858 assert_eq!(next(), (Err(false), None));
859 }
860}