#input #linux #hid #gadget #usb-hid #usb

async-hidg

基于异步接口的Linux USB HID Gadget仿真

1 个不稳定版本

0.2.0 2024年5月11日

#951 in Unix APIs

MIT 许可证

79KB
1.5K SLoC

Rust 中 HID Gadget 仿真

github crate docs MIT CI

Rust 库,用于与 Linux HID Gadget 设备(/dev/hidgX)接口。该库支持非 tokio 异步运行时,如 smolasync-std

由于所有功能都依赖于 Linux 函数调用,该库仅在 Linux 系统上编译。

  • hidg-core - 核心抽象和低级接口(不面向最终用户)
  • hidg - 仅支持同步操作的标准接口
  • tokio-hidg - 为 tokio 运行时提供的异步接口
  • async-hidg - 其他运行时的异步接口

特性

使用示例

键盘输入模拟

use async_hidg::{Class, Device, Keyboard, Key, Led, StateChange};

#[smol_potat::main]
async fn main() -> std::io::Result<()> {
    let mut device = Device::<Keyboard>::open(0).await?; // open device

    // Create input report
    let mut input = Keyboard.input();

    // Press left ctrl modifier
    input.press_key(Key::LeftCtrl);

    // Press key 'A'
    input.press_key(Key::A);

    // Print pressed keys
    println!("Keys: {:?}", input.pressed().collect::<Vec<Key>>());

    // Send input report
    device.input(&input).await?;

    // Release left ctrl modifier
    input.release_key(Key::LeftCtrl);

    // Release key 'A'
    input.release_key(Key::A);

    // Send input report
    device.input(&input).await?;

    // Create output report
    let mut output = Keyboard.output();

    // Receive output report
    device.output(&mut output).await?;

    // Print lit LEDs
    println!("LEDs: {:?}", output.lit().collect::<Vec<Led>>());

    Ok(())
}

鼠标输入模拟

use async_hidg::{Button, Class, Device, Mouse, StateChange, ValueChange};

#[smol_potat::main]
async fn main() -> std::io::Result<()> {
    let mut device = Device::<Mouse>::open("hidg0").await?; // open device

    // Create input report
    let mut input = Mouse.input();

    // Press primary button
    input.press_button(Button::Primary);

    // Set pointer coordinates
    input.change_pointer((150, 50), false);

    // Send input report
    device.input(&input).await?;

    // Move pointer relatively
    input.change_pointer((70, -30), true);

    // Print pressed buttons
    println!("Buttons: {:?}", input.pressed().collect::<Vec<Button>>());

    // Release primary button
    input.release_button(Button::Primary);

    // Send input report
    device.input(&input).await?;

    Ok(())
}

依赖项

~3–12MB
~140K SLoC