1
0
mirror of https://github.com/4yn/slidershim.git synced 2024-11-14 09:47:40 +01:00

but hotplug isnt impl for libusb in windows

This commit is contained in:
4yn 2022-01-30 23:45:59 +08:00
parent 3be06955ea
commit 08d0c3013e
2 changed files with 113 additions and 52 deletions

View File

@ -9,19 +9,9 @@ fn main() {
.filter_level(log::LevelFilter::Debug) .filter_level(log::LevelFilter::Debug)
.init(); .init();
// let config = Config::from_str(
// r#"{
// "deviceMode": "yuancon",
// "outputMode": "kb-32-tasoller",
// "ledMode": "reactive-8",
// "keyboardSensitivity": 50
// }"#,
// )
// .unwrap();
let config = Config::from_str( let config = Config::from_str(
r#"{ r#"{
"deviceMode": "tasoller-two", "deviceMode": "yuancon",
"outputMode": "kb-32-tasoller", "outputMode": "kb-32-tasoller",
"keyboardSensitivity": 50, "keyboardSensitivity": 50,
"ledMode": "reactive-8", "ledMode": "reactive-8",
@ -30,6 +20,17 @@ fn main() {
) )
.unwrap(); .unwrap();
// let config = Config::from_str(
// r#"{
// "deviceMode": "tasoller-two",
// "outputMode": "kb-32-tasoller",
// "keyboardSensitivity": 50,
// "ledMode": "reactive-8",
// "ledSensitivity": 50
// }"#,
// )
// .unwrap();
let manager = Manager::new(config); let manager = Manager::new(config);
let mut input = String::new(); let mut input = String::new();

View File

@ -1,13 +1,14 @@
use std::{ use std::{
error, error,
ops::{Deref, DerefMut}, ops::{Deref, DerefMut},
sync::mpsc,
thread, thread,
time::Duration, time::Duration,
}; };
use log::{error, info}; use log::{error, info};
use rusb::{self, DeviceHandle, GlobalContext}; use rusb::{self, Device, DeviceHandle, GlobalContext, Hotplug, HotplugBuilder, Registration};
use crate::slider_io::{ use crate::slider_io::{
config::DeviceMode, config::DeviceMode,
@ -41,6 +42,36 @@ enum WriteType {
Interrupt, Interrupt,
} }
type HandleOption = Option<DeviceHandle<GlobalContext>>;
type HandleSender = mpsc::SyncSender<HandleOption>;
type HandleReceiver = mpsc::Receiver<HandleOption>;
struct HidDeviceHotplug {
sender: HandleSender,
}
impl HidDeviceHotplug {
fn build() -> (HandleSender, HandleReceiver) {
return mpsc::sync_channel::<HandleOption>(10);
}
fn new(sender: HandleSender) -> Self {
Self { sender }
}
}
impl Hotplug<GlobalContext> for HidDeviceHotplug {
fn device_arrived(&mut self, device: Device<GlobalContext>) {
info!("Hotplug arrived {:?}", device);
self.sender.send(device.open().ok());
}
fn device_left(&mut self, device: Device<GlobalContext>) {
info!("Hotplug left {:?}", device);
self.sender.send(None);
}
}
pub struct HidDeviceJob { pub struct HidDeviceJob {
state: FullState, state: FullState,
vid: u16, vid: u16,
@ -55,7 +86,9 @@ pub struct HidDeviceJob {
led_callback: HidLedCallback, led_callback: HidLedCallback,
led_buf: Buffer, led_buf: Buffer,
handle: Option<DeviceHandle<GlobalContext>>, registration: Option<Registration<GlobalContext>>,
handle_rx: Option<HandleReceiver>,
handle: HandleOption,
} }
impl HidDeviceJob { impl HidDeviceJob {
@ -80,6 +113,9 @@ impl HidDeviceJob {
led_write_type: led_type, led_write_type: led_type,
led_callback, led_callback,
led_buf: Buffer::new(), led_buf: Buffer::new(),
registration: None,
handle_rx: None,
handle: None, handle: None,
} }
} }
@ -203,13 +239,30 @@ impl HidDeviceJob {
} }
} }
fn setup_impl(&mut self) -> Result<(), Box<dyn error::Error>> { fn setup_impl(&mut self) {
info!("Device finding vid {} pid {}", self.vid, self.pid); let (tx, rx) = HidDeviceHotplug::build();
let handle = rusb::open_device_with_vid_pid(self.vid, self.pid); info!("Registering hotplug");
if handle.is_none() { let registration_result = HotplugBuilder::new()
.vendor_id(self.vid)
.product_id(self.pid)
.enumerate(true)
.register(GlobalContext {}, Box::new(HidDeviceHotplug::new(tx)));
if registration_result.is_ok() {
self.registration = registration_result.ok();
info!("Registering OK");
} else {
error!("Registering error {:?}", registration_result.err().unwrap());
}
self.handle_rx = Some(rx);
}
fn init_handle(&mut self) -> Result<(), Box<dyn error::Error>> {
if self.handle.is_none() {
error!("Could not find device"); error!("Could not find device");
} }
let mut handle = handle.unwrap(); let mut handle = self.handle.as_mut().unwrap();
info!("Device found {:?}", handle); info!("Device found {:?}", handle);
if handle.kernel_driver_active(0).unwrap_or(false) { if handle.kernel_driver_active(0).unwrap_or(false) {
@ -220,7 +273,7 @@ impl HidDeviceJob {
handle.set_active_configuration(1)?; handle.set_active_configuration(1)?;
info!("Device claiming interface"); info!("Device claiming interface");
handle.claim_interface(0)?; handle.claim_interface(0)?;
self.handle = Some(handle);
Ok(()) Ok(())
} }
} }
@ -229,53 +282,60 @@ const TIMEOUT: Duration = Duration::from_millis(20);
impl Job for HidDeviceJob { impl Job for HidDeviceJob {
fn setup(&mut self) { fn setup(&mut self) {
self.setup_impl().unwrap(); self.setup_impl();
} }
fn tick(&mut self) { fn tick(&mut self) {
// Input loop if let Some(handle) = self.handle.as_mut() {
let handle = self.handle.as_mut().unwrap(); // Input loop
{
let res = handle
.read_interrupt(self.read_endpoint, &mut self.read_buf.data, TIMEOUT)
.unwrap_or(0);
self.read_buf.len = res;
if self.read_buf.len != 0 {
let mut controller_state_handle = self.state.controller_state.lock().unwrap();
(self.read_callback)(&self.read_buf, controller_state_handle.deref_mut());
}
}
// Led loop
{
{ {
let mut led_state_handle = self.state.led_state.lock().unwrap(); let res = handle
if led_state_handle.dirty { .read_interrupt(self.read_endpoint, &mut self.read_buf.data, TIMEOUT)
(self.led_callback)(&mut self.led_buf, led_state_handle.deref()); .unwrap_or(0);
led_state_handle.dirty = false; self.read_buf.len = res;
if self.read_buf.len != 0 {
let mut controller_state_handle = self.state.controller_state.lock().unwrap();
(self.read_callback)(&self.read_buf, controller_state_handle.deref_mut());
} }
} }
if self.led_buf.len != 0 { // Led loop
let res = (match self.led_write_type { {
WriteType::Bulk => handle.write_bulk(self.led_endpoint, &self.led_buf.data, TIMEOUT), {
WriteType::Interrupt => { let mut led_state_handle = self.state.led_state.lock().unwrap();
handle.write_interrupt(self.led_endpoint, &self.led_buf.data, TIMEOUT) if led_state_handle.dirty {
(self.led_callback)(&mut self.led_buf, led_state_handle.deref());
led_state_handle.dirty = false;
}
}
if self.led_buf.len != 0 {
let res = (match self.led_write_type {
WriteType::Bulk => handle.write_bulk(self.led_endpoint, &self.led_buf.data, TIMEOUT),
WriteType::Interrupt => {
handle.write_interrupt(self.led_endpoint, &self.led_buf.data, TIMEOUT)
}
})
.unwrap_or(0);
if res == self.led_buf.len + 1 {
self.led_buf.len = 0;
} }
})
.unwrap_or(0);
if res == self.led_buf.len + 1 {
self.led_buf.len = 0;
} }
} }
} else {
// Stall a while, wait for hotplug
thread::sleep(Duration::from_millis(1000));
} }
// thread::sleep(Duration::from_millis(10)); // Hotplug recieved
if let Some(handle_msg) = self.handle_rx.as_ref().unwrap().try_recv().ok() {
self.handle = handle_msg;
}
} }
fn teardown(&mut self) { fn teardown(&mut self) {
let handle = self.handle.as_mut().unwrap(); if let Some(mut handle) = self.handle.take() {
handle.release_interface(0).ok(); handle.release_interface(0).ok();
}
} }
} }