1use std::fs::File;
2
3use evdev_rs::enums::{BusType, EventCode, EventType, EV_KEY, EV_REL, EV_SYN};
4use evdev_rs::{Device, DeviceWrapper, InputEvent, ReadFlag, UInputDevice, UninitDevice};
5
6const MOUSE_STEP_X: i32 = 10;
7const MOUSE_STEP_Y: i32 = 10;
8
9fn main() -> Result<(), std::io::Error> {
10 let mut args = std::env::args();
12
13 if args.len() != 2 {
14 let n = args.nth(0).unwrap();
15 println!("Usage: `{} DEVICE`, eg. `{} /dev/input/event13`", n, n);
16 std::process::exit(1);
17 }
18
19 let device = &args.nth(1).unwrap();
20
21 let f = File::open(device)?;
23 let d = Device::new_from_file(f)?;
24
25 if let Some(n) = d.name() {
26 println!(
27 "Connected to device: '{}' ({:04x}:{:04x})",
28 n,
29 d.vendor_id(),
30 d.product_id()
31 );
32 }
33
34 let u = UninitDevice::new().unwrap();
36
37 u.set_name("Virtual Mouse");
41 u.set_bustype(BusType::BUS_USB as u16);
42 u.set_vendor_id(0xabcd);
43 u.set_product_id(0xefef);
44
45 u.enable_event_type(&EventType::EV_KEY)?;
48 u.enable_event_code(&EventCode::EV_KEY(EV_KEY::BTN_LEFT), None)?;
49 u.enable_event_code(&EventCode::EV_KEY(EV_KEY::BTN_RIGHT), None)?;
50
51 u.enable_event_type(&EventType::EV_REL)?;
52 u.enable_event_code(&EventCode::EV_REL(EV_REL::REL_X), None)?;
53 u.enable_event_code(&EventCode::EV_REL(EV_REL::REL_Y), None)?;
54
55 u.enable_event_code(&EventCode::EV_SYN(EV_SYN::SYN_REPORT), None)?;
56
57 let v = UInputDevice::create_from_device(&u)?;
59
60 loop {
61 let (_status, event) = d.next_event(ReadFlag::NORMAL | ReadFlag::BLOCKING)?;
63
64 println!("Event: {:?}", event);
66
67 let e = match event.event_code {
69 EventCode::EV_KEY(EV_KEY::KEY_RIGHT) => Some((EV_REL::REL_X, MOUSE_STEP_X)),
70 EventCode::EV_KEY(EV_KEY::KEY_LEFT) => Some((EV_REL::REL_X, -MOUSE_STEP_X)),
71 EventCode::EV_KEY(EV_KEY::KEY_UP) => Some((EV_REL::REL_Y, -MOUSE_STEP_Y)),
72 EventCode::EV_KEY(EV_KEY::KEY_DOWN) => Some((EV_REL::REL_Y, MOUSE_STEP_Y)),
73 _ => None,
74 };
75
76 if let Some((e, n)) = e {
78 v.write_event(&InputEvent {
79 time: event.time,
80 event_code: EventCode::EV_REL(e),
81 value: n,
82 })?;
83
84 v.write_event(&InputEvent {
85 time: event.time,
86 event_code: EventCode::EV_SYN(EV_SYN::SYN_REPORT),
87 value: 0,
88 })?;
89 }
90 }
91}