File: virtual_ff.rs

package info (click to toggle)
rust-evdev 0.13.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 540 kB
  • sloc: makefile: 2
file content (64 lines) | stat: -rw-r--r-- 2,419 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// Create a virtual force feedback device, just while this is running.

use evdev::{
    uinput::VirtualDevice, AttributeSet, EventSummary, FFEffectCode, FFStatusCode, InputEvent,
    UInputCode,
};
use std::collections::BTreeSet;

fn main() -> std::io::Result<()> {
    let mut device = VirtualDevice::builder()?
        .name("Fake Force Feedback")
        .with_ff(&AttributeSet::from_iter([FFEffectCode::FF_RUMBLE]))?
        .with_ff_effects_max(16)
        .build()?;

    for path in device.enumerate_dev_nodes_blocking()? {
        let path = path?;
        println!("Available as {}", path.display());
    }

    let mut ids: BTreeSet<u16> = (0..16).collect();

    println!("Waiting for Ctrl-C...");
    loop {
        let events: Vec<InputEvent> = device.fetch_events()?.collect();

        const STOPPED: i32 = FFStatusCode::FF_STATUS_STOPPED.0 as i32;
        const PLAYING: i32 = FFStatusCode::FF_STATUS_PLAYING.0 as i32;

        for event in events {
            match event.destructure() {
                EventSummary::UInput(event, UInputCode::UI_FF_UPLOAD, ..) => {
                    let mut event = device.process_ff_upload(event)?;
                    let id = ids.iter().next().copied();
                    match id {
                        Some(id) => {
                            ids.remove(&id);
                            event.set_effect_id(id as i16);
                            event.set_retval(0);
                        }
                        None => {
                            event.set_retval(-1);
                        }
                    }
                    println!("upload effect {:?}", event.effect());
                }
                EventSummary::UInput(event, UInputCode::UI_FF_ERASE, ..) => {
                    let event = device.process_ff_erase(event)?;
                    ids.insert(event.effect_id() as u16);
                    println!("erase effect ID = {}", event.effect_id());
                }
                EventSummary::ForceFeedback(.., effect_id, STOPPED) => {
                    println!("stopped effect ID = {}", effect_id.0);
                }
                EventSummary::ForceFeedback(.., effect_id, PLAYING) => {
                    println!("playing effect ID = {}", effect_id.0);
                }
                _ => {
                    println!("event = {:?}", event);
                }
            };
        }
    }
}