-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathmod.rs
More file actions
114 lines (92 loc) · 2.83 KB
/
Copy pathmod.rs
File metadata and controls
114 lines (92 loc) · 2.83 KB
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
mod axis;
mod button;
mod error;
pub use axis::Axis;
pub use button::Button;
pub use error::Error;
use input_linux::sys;
use std::{fs, path};
pub struct Joystick {
device: input_linux::UInputHandle<fs::File>,
}
impl Joystick {
pub fn new() -> Result<Self, Error> {
let device = create_joystick_device()?;
Ok(Joystick { device })
}
pub fn device_path(&self) -> Result<path::PathBuf, Error> {
Ok(self.device.evdev_path()?)
}
pub fn move_axis(&self, axis: Axis, position: i32) -> Result<(), Error> {
if position > 512 || position < -512 {
return Err(Error::OutOfRangeError {
min: -512,
max: 512,
actual: position,
});
}
self.write_event(input_linux::AbsoluteEvent::new(
empty_event_time(),
axis.to_evdev_axis(),
position,
))
}
pub fn button_press(&self, button: Button, is_pressed: bool) -> Result<(), Error> {
let value = if is_pressed {
input_linux::KeyState::PRESSED
} else {
input_linux::KeyState::RELEASED
};
self.write_event(input_linux::KeyEvent::new(
empty_event_time(),
button.to_evdev_button(),
value,
))
}
pub fn synchronise(&self) -> Result<(), Error> {
self.write_event(input_linux::SynchronizeEvent::report(empty_event_time()))
}
fn write_event(&self, event: impl std::convert::AsRef<sys::input_event>) -> Result<(), Error> {
self.device.write(&[*event.as_ref()])?;
Ok(())
}
}
fn empty_event_time() -> input_linux::EventTime {
input_linux::EventTime::new(0, 0)
}
fn create_joystick_device() -> Result<input_linux::UInputHandle<fs::File>, Error> {
let uinput_file = fs::File::create("/dev/uinput")?;
let device = input_linux::UInputHandle::new(uinput_file);
let input_id = input_linux::InputId {
bustype: sys::BUS_VIRTUAL,
vendor: 34,
product: 10,
version: 1,
};
let standard_info = input_linux::AbsoluteInfo {
value: 0,
minimum: -512,
maximum: 512,
fuzz: 0,
flat: 0,
resolution: 50,
};
device.set_evbit(input_linux::EventKind::Absolute)?;
device.set_evbit(input_linux::EventKind::Key)?;
device.set_keybit(input_linux::Key::ButtonTrigger)?; // informs linux that this is a joystick
for button in Button::all_buttons() {
device.set_keybit(button.to_evdev_button())?;
}
device.create(
&input_id,
b"arduino-virtual-joystick",
0,
&Axis::all_axes()
.map(|axis| input_linux::AbsoluteInfoSetup {
axis: axis.to_evdev_axis(),
info: standard_info,
})
.collect::<Vec<_>>(),
)?;
Ok(device)
}