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 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; 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 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 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 pub fn emit< T >( &self, body: T ) -> Result< (), io::Error > where T: AsRef< InputEventBody > {
606 emit_into( &self.fp, body )
607 }
608}