From 6f60635ff2a12149e9d9b1b981daa3383a0cbbe3 Mon Sep 17 00:00:00 2001 From: Johannes Leupolz Date: Wed, 1 Apr 2026 09:57:09 +0000 Subject: [PATCH] Implement vuinput_read for vibration support. poll missing --- vuinputd/src/cuse_device/mod.rs | 3 +- vuinputd/src/cuse_device/vuinput_read.rs | 66 ++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 vuinputd/src/cuse_device/vuinput_read.rs diff --git a/vuinputd/src/cuse_device/mod.rs b/vuinputd/src/cuse_device/mod.rs index bb71a3f..6a92c1b 100644 --- a/vuinputd/src/cuse_device/mod.rs +++ b/vuinputd/src/cuse_device/mod.rs @@ -6,6 +6,7 @@ pub mod device_policy; pub mod state; pub mod vuinput_ioctl; pub mod vuinput_open; +pub mod vuinput_read; pub mod vuinput_release; pub mod vuinput_write; @@ -29,7 +30,7 @@ pub fn vuinput_make_cuse_ops() -> cuse_lowlevel::cuse_lowlevel_ops { init_done: None, destroy: None, open: Some(vuinput_open::vuinput_open), - read: None, + read: Some(vuinput_read::vuinput_read), write: Some(vuinput_write::vuinput_write), flush: None, release: Some(vuinput_release::vuinput_release), diff --git a/vuinputd/src/cuse_device/vuinput_read.rs b/vuinputd/src/cuse_device/vuinput_read.rs new file mode 100644 index 0000000..3c47048 --- /dev/null +++ b/vuinputd/src/cuse_device/vuinput_read.rs @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MIT +// +// Author: Johannes Leupolz + +use crate::cuse_device::*; +use crate::global_config::get_device_policy; +use ::cuse_lowlevel::*; +use libc::{__s32, __u16, input_event}; +use libc::{off_t, size_t, EIO}; +use libc::{uinput_abs_setup, uinput_setup}; +use log::{debug, trace}; +use std::io::{Read, Write}; +use std::os::fd::AsRawFd; +use std::os::raw::c_char; +use uinput_ioctls::*; + +// TODO: compat-mode+ ensure sizeof(struct input_event) +pub unsafe extern "C" fn vuinput_read( + _req: fuse_lowlevel::fuse_req_t, + _size: size_t, + _off: off_t, + _fi: *mut fuse_lowlevel::fuse_file_info, +) { + assert!( + _off == 0, + "vuinput_read: offset needs to be 0 but is {}", + _off + ); + + let fh = &(*_fi).fh; + let vuinput_state_mutex = + get_vuinput_state(&VuFileHandle::from_fuse_file_info(_fi.as_ref().unwrap())).unwrap(); + let mut vuinput_state = vuinput_state_mutex.lock().unwrap(); + + let normal_size = std::mem::size_of::(); + let is_compat = vuinput_state.requesting_process.is_compat; + // TODO: ARM: && !compat_uses_64bit_time() + + let mut buffer: [u8; 24] = [0; 24]; + + // read up to 24 bytes + let result = vuinput_state.file.read(&mut buffer); + match result { + Ok(normal_size) => { + if (!is_compat) { + let buffer = buffer.as_ptr() as *const i8; + fuse_lowlevel::fuse_reply_buf(_req, buffer, 24); + } else { + debug!( + "fh {}: error reading from uinput: not implemented yet for 32 bit users", + fh + ); + // details how to implement it can be found in vuinput_write.rs + fuse_lowlevel::fuse_reply_err(_req, EIO); + } + } + Err(e) => { + debug!("fh {}: error reading from uinput: {e:?}", fh); + fuse_lowlevel::fuse_reply_err(_req, EIO); + } + Ok(_) => { + debug!("fh {}: error reading from uinput: wrong size", fh); + fuse_lowlevel::fuse_reply_err(_req, EIO); + } + } +}