pub struct UInputDevice { /* private fields */ }
Expand description
Opaque struct representing an evdev uinput device
Implementations§
Source§impl UInputDevice
impl UInputDevice
Sourcepub fn create_from_device<T: DeviceWrapper>(device: &T) -> Result<UInputDevice>
pub fn create_from_device<T: DeviceWrapper>(device: &T) -> Result<UInputDevice>
Create a uinput device based on the given libevdev device.
The uinput device will be an exact copy of the libevdev device, minus the bits that uinput doesn’t allow to be set.
Examples found in repository?
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
fn main() -> Result<(), std::io::Error> {
// Parse command line arguments
let mut args = std::env::args();
if args.len() != 2 {
let n = args.nth(0).unwrap();
println!("Usage: `{} DEVICE`, eg. `{} /dev/input/event13`", n, n);
std::process::exit(1);
}
let device = &args.nth(1).unwrap();
// Connect to real keyboard
let f = File::open(device)?;
let d = Device::new_from_file(f)?;
if let Some(n) = d.name() {
println!(
"Connected to device: '{}' ({:04x}:{:04x})",
n,
d.vendor_id(),
d.product_id()
);
}
// Create virtual device
let u = UninitDevice::new().unwrap();
// Setup device
// per: https://01.org/linuxgraphics/gfx-docs/drm/input/uinput.html#mouse-movements
u.set_name("Virtual Mouse");
u.set_bustype(BusType::BUS_USB as u16);
u.set_vendor_id(0xabcd);
u.set_product_id(0xefef);
// Note mouse keys have to be enabled for this to be detected
// as a usable device, see: https://stackoverflow.com/a/64559658/6074942
u.enable_event_type(&EventType::EV_KEY)?;
u.enable_event_code(&EventCode::EV_KEY(EV_KEY::BTN_LEFT), None)?;
u.enable_event_code(&EventCode::EV_KEY(EV_KEY::BTN_RIGHT), None)?;
u.enable_event_type(&EventType::EV_REL)?;
u.enable_event_code(&EventCode::EV_REL(EV_REL::REL_X), None)?;
u.enable_event_code(&EventCode::EV_REL(EV_REL::REL_Y), None)?;
u.enable_event_code(&EventCode::EV_SYN(EV_SYN::SYN_REPORT), None)?;
// Attempt to create UInputDevice from UninitDevice
let v = UInputDevice::create_from_device(&u)?;
loop {
// Fetch keyboard events
let (_status, event) = d.next_event(ReadFlag::NORMAL | ReadFlag::BLOCKING)?;
// Map these to mouse events
println!("Event: {:?}", event);
// Map direction keys to mouse events
let e = match event.event_code {
EventCode::EV_KEY(EV_KEY::KEY_RIGHT) => Some((EV_REL::REL_X, MOUSE_STEP_X)),
EventCode::EV_KEY(EV_KEY::KEY_LEFT) => Some((EV_REL::REL_X, -MOUSE_STEP_X)),
EventCode::EV_KEY(EV_KEY::KEY_UP) => Some((EV_REL::REL_Y, -MOUSE_STEP_Y)),
EventCode::EV_KEY(EV_KEY::KEY_DOWN) => Some((EV_REL::REL_Y, MOUSE_STEP_Y)),
_ => None,
};
// Write mapped event
if let Some((e, n)) = e {
v.write_event(&InputEvent {
time: event.time,
event_code: EventCode::EV_REL(e),
value: n,
})?;
v.write_event(&InputEvent {
time: event.time,
event_code: EventCode::EV_SYN(EV_SYN::SYN_REPORT),
value: 0,
})?;
}
}
}
Sourcepub fn devnode(&self) -> Option<&str>
pub fn devnode(&self) -> Option<&str>
Return the device node representing this uinput device.
This relies on libevdev_uinput_get_syspath()
to provide a valid syspath.
Sourcepub fn syspath(&self) -> Option<&str>
pub fn syspath(&self) -> Option<&str>
Return the syspath representing this uinput device.
If the UI_GET_SYSNAME ioctl not available, libevdev makes an educated guess. The UI_GET_SYSNAME ioctl is available since Linux 3.15.
The syspath returned is the one of the input node itself (e.g. /sys/devices/virtual/input/input123), not the syspath of the device node returned with libevdev_uinput_get_devnode().
Sourcepub fn as_fd(&self) -> Option<RawFd>
pub fn as_fd(&self) -> Option<RawFd>
Return the file descriptor used to create this uinput device.
This is the fd pointing to /dev/uinput. This file descriptor may be used to write events that are emitted by the uinput device. Closing this file descriptor will destroy the uinput device.
pub fn fd(&self) -> Option<RawFd>
as_fd
. Some function names were changed so they
more closely match their type signature. See issue 42 for discussion
https://github.com/ndesh26/evdev-rs/issues/42Sourcepub fn write_event(&self, event: &InputEvent) -> Result<()>
pub fn write_event(&self, event: &InputEvent) -> Result<()>
Post an event through the uinput device.
It is the caller’s responsibility that any event sequence is terminated with an EV_SYN/SYN_REPORT/0 event. Otherwise, listeners on the device node will not see the events until the next EV_SYN event is posted.
Examples found in repository?
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
fn main() -> Result<(), std::io::Error> {
// Parse command line arguments
let mut args = std::env::args();
if args.len() != 2 {
let n = args.nth(0).unwrap();
println!("Usage: `{} DEVICE`, eg. `{} /dev/input/event13`", n, n);
std::process::exit(1);
}
let device = &args.nth(1).unwrap();
// Connect to real keyboard
let f = File::open(device)?;
let d = Device::new_from_file(f)?;
if let Some(n) = d.name() {
println!(
"Connected to device: '{}' ({:04x}:{:04x})",
n,
d.vendor_id(),
d.product_id()
);
}
// Create virtual device
let u = UninitDevice::new().unwrap();
// Setup device
// per: https://01.org/linuxgraphics/gfx-docs/drm/input/uinput.html#mouse-movements
u.set_name("Virtual Mouse");
u.set_bustype(BusType::BUS_USB as u16);
u.set_vendor_id(0xabcd);
u.set_product_id(0xefef);
// Note mouse keys have to be enabled for this to be detected
// as a usable device, see: https://stackoverflow.com/a/64559658/6074942
u.enable_event_type(&EventType::EV_KEY)?;
u.enable_event_code(&EventCode::EV_KEY(EV_KEY::BTN_LEFT), None)?;
u.enable_event_code(&EventCode::EV_KEY(EV_KEY::BTN_RIGHT), None)?;
u.enable_event_type(&EventType::EV_REL)?;
u.enable_event_code(&EventCode::EV_REL(EV_REL::REL_X), None)?;
u.enable_event_code(&EventCode::EV_REL(EV_REL::REL_Y), None)?;
u.enable_event_code(&EventCode::EV_SYN(EV_SYN::SYN_REPORT), None)?;
// Attempt to create UInputDevice from UninitDevice
let v = UInputDevice::create_from_device(&u)?;
loop {
// Fetch keyboard events
let (_status, event) = d.next_event(ReadFlag::NORMAL | ReadFlag::BLOCKING)?;
// Map these to mouse events
println!("Event: {:?}", event);
// Map direction keys to mouse events
let e = match event.event_code {
EventCode::EV_KEY(EV_KEY::KEY_RIGHT) => Some((EV_REL::REL_X, MOUSE_STEP_X)),
EventCode::EV_KEY(EV_KEY::KEY_LEFT) => Some((EV_REL::REL_X, -MOUSE_STEP_X)),
EventCode::EV_KEY(EV_KEY::KEY_UP) => Some((EV_REL::REL_Y, -MOUSE_STEP_Y)),
EventCode::EV_KEY(EV_KEY::KEY_DOWN) => Some((EV_REL::REL_Y, MOUSE_STEP_Y)),
_ => None,
};
// Write mapped event
if let Some((e, n)) = e {
v.write_event(&InputEvent {
time: event.time,
event_code: EventCode::EV_REL(e),
value: n,
})?;
v.write_event(&InputEvent {
time: event.time,
event_code: EventCode::EV_SYN(EV_SYN::SYN_REPORT),
value: 0,
})?;
}
}
}