deckhidraw 0.0.0

Steam Deck gamepad raw input
Documentation
use std::fs::File;
use std::io::{self, Read};
use std::os::fd::AsRawFd;
use std::process::ExitCode;
use std::time::{Duration, Instant};

use deckhidraw::*;

unsafe extern "C" {
    unsafe fn ioctl(fd: i32, op: u32, ...) -> i32;
}

fn set_feature_report(f: &File, buf: &[u8; 65]) -> io::Result<()> {
    let ret = unsafe { ioctl(f.as_raw_fd(), 0xC0414806, buf.as_ptr()) };
    if ret < 0 {
        return Err(io::Error::last_os_error());
    }
    Ok(())
}

fn main() -> io::Result<ExitCode> {
    println!("Hello world!");

    let deck_hidraw = find_deck_hidraw()?;
    if deck_hidraw.is_none() {
        println!("Could not find Steam Deck hidraw controls!");
        return Ok(ExitCode::FAILURE);
    }
    let deck_hidraw = deck_hidraw.unwrap();
    println!("Opening {:?}", deck_hidraw);

    let mut dev_node = File::open(deck_hidraw)?;
    println!("Opened! {:?}", dev_node);

    set_feature_report(&dev_node, &commands::turn_on_gyro())?;
    let mut last_gyro_on = Instant::now();
    let mut last_data = InputReport::from([0; 64]);

    loop {
        let mut buf = [0; 64];
        dev_node.read(&mut buf)?;
        let data = InputReport::from(buf);
        println!("\x1b[2J\x1b[1;1H{:#}", data);

        let time_now = Instant::now();

        if time_now - last_gyro_on > Duration::from_secs(5) {
            set_feature_report(&dev_node, &commands::turn_on_gyro())?;
            last_gyro_on = time_now;
        }

        if last_data.buttons & buttons::A == 0 && data.buttons & buttons::A != 0 {
            set_feature_report(&dev_node, &commands::beep(commands::PAD_BOTH, 1000.0, 0.4))?;
        }
        if last_data.buttons & buttons::B == 0 && data.buttons & buttons::B != 0 {
            set_feature_report(&dev_node, &commands::tick(commands::PAD_BOTH, 4, 6))?;
        }
        if last_data.buttons & buttons::X == 0 && data.buttons & buttons::X != 0 {
            set_feature_report(&dev_node, &&commands::rumble(0, 0x7fff, 0x7fff, 2, 0))?;
        }

        last_data = data;
    }
}