linux_input/
input.rs

1use {
2    std::{
3        fmt,
4        fs::{
5            self,
6            File
7        },
8        io::{
9            self
10        },
11        os::{
12            unix::{
13                io::{
14                    AsRawFd
15                }
16            }
17        },
18        iter::{
19            FusedIterator
20        },
21        mem::{
22            self
23        },
24        path::{
25            Path
26        },
27        slice,
28        time::{
29            Duration
30        }
31    },
32    crate::{
33        event_bits_iter::{
34            EventBitsIter
35        },
36        input_sys::{
37            self,
38            AbsoluteAxis,
39            Bus,
40            EventKind,
41            ForceFeedback,
42            Key,
43            RawAbsInfo,
44            RawDeviceId,
45            RawForceFeedbackBody,
46            RawForceFeedbackEffect,
47            RawForceFeedbackReplay,
48            RawForceFeedbackRumbleEffect,
49            RawForceFeedbackTrigger,
50            RawInputEvent,
51            RelativeAxis,
52            Timestamp
53        },
54        utils::{
55            ioctl_get_string
56        }
57    }
58};
59
60impl fmt::Debug for RawInputEvent {
61    fn fmt( &self, fmt: &mut fmt::Formatter ) -> fmt::Result {
62        fmt.debug_struct( "RawInputEvent" )
63            .field( "timestamp", &self.timestamp )
64            .field( "kind", &EventKind::from( self.kind ) )
65            .field( "code", &self.code )
66            .field( "value", &self.value )
67            .finish()
68    }
69}
70
71#[derive(Clone, PartialEq, Eq, Debug)]
72pub struct InputEvent {
73    pub timestamp: Timestamp,
74    pub body: InputEventBody
75}
76
77#[derive(Clone, PartialEq, Eq, Debug)]
78pub enum InputEventBody {
79    KeyPress( Key ),
80    KeyRelease( Key ),
81    RelativeMove {
82        axis: RelativeAxis,
83        delta: i32
84    },
85    AbsoluteMove {
86        axis: AbsoluteAxis,
87        position: i32
88    },
89    Flush,
90    Dropped,
91    Other {
92        kind: EventKind,
93        code: u16,
94        value: i32
95    }
96}
97
98impl From< RawInputEvent > for InputEvent {
99    fn from( raw_event: RawInputEvent ) -> Self {
100        let kind: EventKind = raw_event.kind.into();
101        let body = match kind {
102            EventKind::Key if raw_event.value == 1 => InputEventBody::KeyPress( raw_event.code.into() ),
103            EventKind::Key if raw_event.value == 0 => InputEventBody::KeyRelease( raw_event.code.into() ),
104            EventKind::RelativeAxis => InputEventBody::RelativeMove { axis: raw_event.code.into(), delta: raw_event.value },
105            EventKind::AbsoluteAxis => InputEventBody::AbsoluteMove { axis: raw_event.code.into(), position: raw_event.value },
106            EventKind::Synchronization if raw_event.code == 0 && raw_event.value == 0 => InputEventBody::Flush,
107            EventKind::Synchronization if raw_event.code == 3 && raw_event.value == 0 => InputEventBody::Dropped,
108            _ => InputEventBody::Other{
109                kind: raw_event.kind.into(),
110                code: raw_event.code,
111                value: raw_event.value
112            }
113        };
114
115        InputEvent {
116            timestamp: raw_event.timestamp,
117            body
118        }
119    }
120}
121
122impl From< InputEvent > for RawInputEvent {
123    fn from( event: InputEvent ) -> Self {
124        let (kind, code, value) = match event.body {
125            InputEventBody::KeyPress( key ) => (EventKind::Key, key.into(), 1),
126            InputEventBody::KeyRelease( key ) => (EventKind::Key, key.into(), 0),
127            InputEventBody::RelativeMove { axis, delta } => (EventKind::RelativeAxis, axis.into(), delta),
128            InputEventBody::AbsoluteMove { axis, position } => (EventKind::AbsoluteAxis, axis.into(), position),
129            InputEventBody::Flush => (EventKind::Synchronization, 0, 0),
130            InputEventBody::Dropped => (EventKind::Synchronization, 3, 0),
131            InputEventBody::Other { kind, code, value } => (kind, code, value)
132        };
133
134        RawInputEvent {
135            timestamp: event.timestamp,
136            kind: kind.into(),
137            code,
138            value
139        }
140    }
141}
142
143impl From< InputEvent > for InputEventBody {
144    fn from( event: InputEvent ) -> Self {
145        event.body
146    }
147}
148
149impl AsRef< InputEventBody > for InputEvent {
150    fn as_ref( &self ) -> &InputEventBody {
151        &self.body
152    }
153}
154
155impl AsRef< InputEventBody > for InputEventBody {
156    fn as_ref( &self ) -> &InputEventBody {
157        self
158    }
159}
160
161pub trait EventCode: From< u16 > {
162    const EVENT_KIND: EventKind;
163}
164
165impl EventCode for Key {
166    const EVENT_KIND: EventKind = EventKind::Key;
167}
168
169impl EventCode for RelativeAxis {
170    const EVENT_KIND: EventKind = EventKind::RelativeAxis;
171}
172
173impl EventCode for AbsoluteAxis {
174    const EVENT_KIND: EventKind = EventKind::AbsoluteAxis;
175}
176
177impl EventCode for ForceFeedback {
178    const EVENT_KIND: EventKind = EventKind::ForceFeedback;
179}
180
181#[derive(Clone, PartialEq, Eq, Debug)]
182pub struct DeviceId {
183    pub bus: Bus,
184    pub vendor: u16,
185    pub product: u16,
186    pub version: u16
187}
188
189impl From< RawDeviceId > for DeviceId {
190    fn from( id: RawDeviceId ) -> Self {
191        DeviceId {
192            bus: id.bus.into(),
193            vendor: id.vendor,
194            product: id.product,
195            version: id.version
196        }
197    }
198}
199
200impl From< DeviceId > for RawDeviceId {
201    fn from( id: DeviceId ) -> Self {
202        RawDeviceId {
203            bus: id.bus.into(),
204            vendor: id.vendor,
205            product: id.product,
206            version: id.version
207        }
208    }
209}
210
211pub(crate) fn emit_into< T >( fp: &File, body: T ) -> Result< (), io::Error > where T: AsRef< InputEventBody > {
212    let raw_event: RawInputEvent = InputEvent {
213        timestamp: Timestamp {
214            sec: 0,
215            usec: 0
216        },
217        body: body.as_ref().clone()
218    }.into();
219
220    let bytes = &raw_event as *const RawInputEvent as *const u8;
221    let bytes = unsafe { slice::from_raw_parts( bytes, mem::size_of::< RawInputEvent >() ) };
222    let result = unsafe { libc::write( fp.as_raw_fd(), bytes.as_ptr() as *const libc::c_void, bytes.len() ) };
223    if result < 0 {
224        return Err( io::Error::last_os_error() );
225    }
226
227    let count = result as usize;
228    assert_eq!( count, bytes.len() );
229
230    Ok(())
231}
232
233#[derive(Clone, Debug)]
234pub struct AbsoluteAxisBit {
235    pub axis: AbsoluteAxis,
236    pub initial_value: i32,
237    pub minimum: i32,
238    pub maximum: i32,
239    pub noise_threshold: i32,
240    pub deadzone: i32,
241    pub resolution: i32
242}
243
244#[derive(Clone, Debug)]
245pub enum EventBit {
246    Key( Key ),
247    RelativeAxis( RelativeAxis ),
248    AbsoluteAxis( AbsoluteAxisBit ),
249    ForceFeedback( ForceFeedback )
250}
251
252#[derive(Clone, Debug)]
253pub enum ForceFeedbackEffectKind {
254    Rumble {
255        strong_magnitude: u16,
256        weak_magnitude: u16
257    }
258}
259
260impl ForceFeedbackEffectKind {
261    unsafe fn from_raw( kind: u16, body: &RawForceFeedbackBody ) -> Self {
262        match kind {
263            crate::input_sys::FF_RUMBLE => {
264                let raw_effect = &body.rumble;
265                ForceFeedbackEffectKind::Rumble {
266                    strong_magnitude: raw_effect.strong_magnitude,
267                    weak_magnitude: raw_effect.weak_magnitude
268                }
269            },
270            kind => unimplemented!( "unsupported force feedback effect: {}", kind )
271        }
272    }
273}
274
275#[derive(Clone, Debug)]
276pub enum ForceFeedbackDuration {
277    Finite( std::time::Duration ),
278    Infinite
279}
280
281#[derive(Clone, Debug)]
282pub struct ForceFeedbackEffect {
283    pub id: i16,
284    pub direction: u16,
285    pub kind: ForceFeedbackEffectKind,
286    pub duration: ForceFeedbackDuration,
287    pub delay: std::time::Duration,
288    pub trigger: RawForceFeedbackTrigger
289}
290
291impl ForceFeedbackEffect {
292    pub(crate) unsafe fn from_raw( raw_effect: &RawForceFeedbackEffect ) -> Self {
293        ForceFeedbackEffect {
294            id: raw_effect.id,
295            direction: raw_effect.direction,
296            kind: ForceFeedbackEffectKind::from_raw( raw_effect.kind, &raw_effect.body ),
297            trigger: raw_effect.trigger,
298            duration: match raw_effect.replay.length {
299                0 => ForceFeedbackDuration::Infinite,
300                length => ForceFeedbackDuration::Finite( std::time::Duration::from_millis( length as u64 ) )
301            },
302            delay: std::time::Duration::from_millis( raw_effect.replay.delay as u64 )
303        }
304    }
305}
306
307fn convert_and_clip( duration: std::time::Duration ) -> u16 {
308    let duration = duration.as_millis();
309    if duration > 0x7fff {
310        0x7fff
311    } else {
312        duration as u16
313    }
314}
315
316impl From< ForceFeedbackEffect > for RawForceFeedbackEffect {
317    fn from( effect: ForceFeedbackEffect ) -> Self {
318        RawForceFeedbackEffect {
319            id: effect.id,
320            direction: effect.direction,
321            trigger: effect.trigger,
322            replay: RawForceFeedbackReplay {
323                length: match effect.duration {
324                    ForceFeedbackDuration::Finite( duration ) => convert_and_clip( duration ),
325                    ForceFeedbackDuration::Infinite => 0
326                },
327                delay: convert_and_clip( effect.delay )
328            },
329            body: match effect.kind {
330                ForceFeedbackEffectKind::Rumble { weak_magnitude, strong_magnitude } => {
331                    RawForceFeedbackBody {
332                        rumble: RawForceFeedbackRumbleEffect {
333                            weak_magnitude, strong_magnitude
334                        }
335                    }
336                }
337            },
338            kind: match effect.kind {
339                ForceFeedbackEffectKind::Rumble { .. } => crate::input_sys::FF_RUMBLE
340            }
341        }
342    }
343}
344
345pub struct Device {
346    fp: File
347}
348
349pub fn poll_read( fd: std::os::unix::io::RawFd, timeout: Option< Duration > ) -> Result< bool, io::Error > {
350    let timeout = timeout.map( |timeout| {
351        libc::timespec {
352            tv_sec: timeout.as_secs() as _,
353            tv_nsec: timeout.subsec_nanos() as _
354        }
355    });
356
357    let timeout_p = timeout.as_ref().map( |timeout: &libc::timespec| timeout as *const libc::timespec ).unwrap_or( std::ptr::null() );
358    let mut pollfd = libc::pollfd {
359        fd,
360        events: libc::POLLIN,
361        revents: 0
362    };
363
364    let sigmask = unsafe {
365        let mut sigmask = std::mem::MaybeUninit::uninit();
366        let errcode = libc::sigemptyset( sigmask.as_mut_ptr() );
367        assert_eq!( errcode, 0 );
368
369        sigmask.assume_init()
370    };
371
372    // `nix`'s bindings for this are broken, so we call it manually.
373    let result = unsafe {
374        libc::ppoll( &mut pollfd, 1, timeout_p, &sigmask )
375    };
376
377    std::mem::drop( timeout );
378
379    if result < 0 {
380        let error = io::Error::last_os_error();
381        if error.kind() == io::ErrorKind::Interrupted {
382            return Ok( false );
383        }
384        return Err( error );
385    } else if result == 0 {
386        return Ok( false );
387    }
388
389    Ok( pollfd.revents & (libc::POLLIN | libc::POLLHUP) != 0 )
390}
391
392pub(crate) fn read_raw_input_event( fp: &File, timeout: Option< Duration > ) -> Result< Option< RawInputEvent >, io::Error > {
393    if poll_read( fp.as_raw_fd(), timeout )? {
394        let mut buffer = RawInputEvent::default();
395        let raw_buffer = unsafe {
396            std::slice::from_raw_parts_mut( &mut buffer as *mut RawInputEvent as *mut u8, mem::size_of::< RawInputEvent >() )
397        };
398
399        let result = unsafe { libc::read( fp.as_raw_fd(), raw_buffer.as_mut_ptr() as *mut libc::c_void, raw_buffer.len() as libc::size_t ) };
400        if result < 0 {
401            return Err( io::Error::last_os_error() );
402        }
403
404        let count = result as usize;
405        if count == mem::size_of::< RawInputEvent >() {
406            return Ok( Some( buffer ) );
407        }
408
409        assert_eq!( count, 0 );
410    }
411
412    Ok( None )
413}
414
415#[derive(Copy, Clone, PartialEq, Eq, Debug)]
416pub struct ForceFeedbackEffectId( i16 );
417
418impl Device {
419    pub fn open< P >( path: P ) -> Result< Self, io::Error > where P: AsRef< Path > {
420        let path = path.as_ref();
421        let fp = fs::OpenOptions::new()
422            .read( true )
423            .write( true )
424            .create( false )
425            .open( path )?;
426
427        let flags = unsafe { libc::fcntl( fp.as_raw_fd(), libc::F_GETFL, 0 ) };
428        if flags < 0 {
429            let error = io::Error::last_os_error();
430            return Err( error );
431        }
432
433        if unsafe { libc::fcntl( fp.as_raw_fd(), libc::F_SETFL, flags | libc::O_NONBLOCK ) < -1 } {
434            let error = io::Error::last_os_error();
435            return Err( error );
436        }
437
438        let device = Device {
439            fp
440        };
441
442        device.set_clock_source( libc::CLOCK_MONOTONIC )
443            .map_err( |error| io::Error::new( io::ErrorKind::Other, format!( "failed to set the clock source to CLOCK_MONOTONIC: {}", error ) ) )?;
444
445        Ok( device )
446    }
447
448    pub fn id( &self ) -> Result< DeviceId, nix::Error > {
449        let mut raw_id = RawDeviceId {
450            bus: 0,
451            vendor: 0,
452            product: 0,
453            version: 0
454        };
455
456        unsafe {
457            input_sys::evdev_get_id( self.fp.as_raw_fd(), &mut raw_id )?;
458        }
459
460        Ok( raw_id.into() )
461    }
462
463    pub fn name( &self ) -> Result< String, nix::Error > {
464        unsafe {
465            ioctl_get_string( self.fp.as_raw_fd(), b'E', 0x06 )
466        }
467    }
468
469    pub fn physical_location( &self ) -> Result< String, nix::Error > {
470        unsafe {
471            ioctl_get_string( self.fp.as_raw_fd(), b'E', 0x07 )
472        }
473    }
474
475    pub fn read( &self, timeout: Option< Duration > ) -> Result< Option< InputEvent >, io::Error > {
476        read_raw_input_event( &self.fp, timeout ).map( |event| event.map( |event| event.into() ) )
477    }
478
479    pub fn get_raw_abs_info( &self, axis: AbsoluteAxis ) -> Result< RawAbsInfo, nix::Error > {
480        unsafe {
481            crate::input_sys::evdev_get_abs_info( self.fp.as_raw_fd(), axis )
482        }
483    }
484
485    fn append_event_bits_into_buffer( &self, kind: EventKind, buffer: &mut Vec< u8 > ) -> Result< usize, nix::Error > {
486        let length = buffer.len();
487        buffer.resize( length + 1024, 0 );
488        let count = unsafe {
489            crate::input_sys::evdev_get_event_bits( self.fp.as_raw_fd(), kind, buffer[ length..length + 1024 ].as_mut_ptr(), 1024 )?
490        } as usize;
491        buffer.truncate( length + count );
492
493        Ok( count )
494    }
495
496    pub fn event_bits_of_kind< T >( &self ) -> Result< impl Iterator< Item = T > + FusedIterator, nix::Error > where T: EventCode {
497        let mut buffer = Vec::new();
498        self.append_event_bits_into_buffer( T::EVENT_KIND, &mut buffer )?;
499        let iter = EventBitsIter::< T >::new( buffer.into() );
500        Ok( iter )
501    }
502
503    pub fn absolute_axis_event_bits( &self ) -> Result< impl Iterator< Item = AbsoluteAxisBit > + FusedIterator, nix::Error > {
504        let mut buffer = Vec::new();
505        for axis in self.event_bits_of_kind::< AbsoluteAxis >()? {
506            let info = self.get_raw_abs_info( axis )?;
507            buffer.push( AbsoluteAxisBit {
508                axis,
509                initial_value: info.value,
510                minimum: info.minimum,
511                maximum: info.maximum,
512                noise_threshold: info.noise_threshold,
513                deadzone: info.deadzone,
514                resolution: info.resolution
515            });
516        }
517
518        Ok( buffer.into_iter() )
519    }
520
521    pub fn event_bits( &self ) -> Result< impl Iterator< Item = EventBit > + FusedIterator, nix::Error > {
522        let mut output = Vec::new();
523        let mut buffer = Vec::new();
524
525        buffer.clear();
526        self.append_event_bits_into_buffer( EventKind::Key, &mut buffer )?;
527        output.extend( EventBitsIter::< Key >::new( (&buffer).into() ).map( EventBit::Key ) );
528
529        buffer.clear();
530        self.append_event_bits_into_buffer( EventKind::RelativeAxis, &mut buffer )?;
531        output.extend( EventBitsIter::< RelativeAxis >::new( (&buffer).into() ).map( EventBit::RelativeAxis ) );
532
533        output.extend( self.absolute_axis_event_bits()?.map( EventBit::AbsoluteAxis ) );
534
535        Ok( output.into_iter() )
536    }
537
538    fn set_clock_source( &self, clock_source: libc::c_int ) -> Result< (), nix::Error > {
539        unsafe {
540            input_sys::evdev_set_clock_id( self.fp.as_raw_fd(), &clock_source )?;
541        }
542
543        Ok(())
544    }
545
546    pub fn upload_force_feedback_effect( &self, effect: impl Into< RawForceFeedbackEffect > ) -> Result< ForceFeedbackEffectId, nix::Error > {
547        let mut effect = effect.into();
548        effect.id = -1; // The kernel will automatically assign an ID.
549
550        let id = unsafe {
551            input_sys::evdev_start_force_feedback( self.fp.as_raw_fd(), &effect )?
552        };
553
554        assert!( id >= 0 && id <= std::i16::MAX as _ );
555        Ok( ForceFeedbackEffectId( id as i16 ) )
556    }
557
558    pub fn erase_force_feedback_effect( &self, id: ForceFeedbackEffectId ) -> Result< (), nix::Error > {
559        unsafe {
560            input_sys::evdev_stop_force_feedback( self.fp.as_raw_fd(), id.0 as _ )?;
561        }
562
563        Ok(())
564    }
565
566    pub fn enable_force_feedback_effect( &self, effect_id: ForceFeedbackEffectId, cycle_count: i32 ) -> Result< (), io::Error > {
567        self.emit( InputEventBody::Other {
568            kind: EventKind::ForceFeedback,
569            code: effect_id.0 as u16,
570            value: cycle_count
571        })
572    }
573
574    pub fn disable_force_feedback_effect( &self, effect_id: ForceFeedbackEffectId ) -> Result< (), io::Error > {
575        self.emit( InputEventBody::Other {
576            kind: EventKind::ForceFeedback,
577            code: effect_id.0 as u16,
578            value: 0
579        })
580    }
581
582    /// Grabs the device for exclusive access.
583    ///
584    /// No one else will receive any events from it.
585    pub fn grab( &self ) -> Result< (), nix::Error > {
586        unsafe {
587            input_sys::evdev_grab_or_release( self.fp.as_raw_fd(), 1 )?;
588        }
589
590        Ok(())
591    }
592
593    /// Releases the device from exclusive access.
594    pub fn release( &self ) -> Result< (), nix::Error > {
595        unsafe {
596            input_sys::evdev_grab_or_release( self.fp.as_raw_fd(), 0 )?;
597        }
598
599        Ok(())
600    }
601
602    /// Emits a given event just as if it was sent by the device itself.
603    ///
604    /// Makes sense only when the device is *not* grabbed for exclusive access.
605    pub fn emit< T >( &self, body: T ) -> Result< (), io::Error > where T: AsRef< InputEventBody > {
606        emit_into( &self.fp, body )
607    }
608}