Initial commit
This commit is contained in:
91
src/main.rs
Normal file
91
src/main.rs
Normal file
@@ -0,0 +1,91 @@
|
||||
use hidapi::{HidApi, HidDevice, HidError};
|
||||
use libpulse_binding::proplist::Proplist;
|
||||
use pulsectl::controllers::{types::DeviceInfo, DeviceControl, SinkController};
|
||||
|
||||
trait Headset {
|
||||
const VENDOR_ID: u16;
|
||||
const PRODUCT_ID: u16;
|
||||
}
|
||||
|
||||
struct G733;
|
||||
|
||||
impl Headset for G733 {
|
||||
const VENDOR_ID: u16 = 0x046d;
|
||||
const PRODUCT_ID: u16 = 0x0ab5;
|
||||
}
|
||||
|
||||
fn find_device() -> Result<Option<HidDevice>, HidError> {
|
||||
let api = HidApi::new()?;
|
||||
for device in api.device_list() {
|
||||
if device.vendor_id() != G733::VENDOR_ID || device.product_id() != G733::PRODUCT_ID {
|
||||
continue;
|
||||
}
|
||||
return Ok(Some(device.open_device(&api)?));
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn hex_prop_is(proplist: &Proplist, prop_name: &str, expected: u16) -> bool {
|
||||
proplist
|
||||
.get_str(prop_name)
|
||||
.map(|prop| u16::from_str_radix(&prop, 16).unwrap())
|
||||
.map(|prop| prop == expected)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn is_sink_headset(sink: &DeviceInfo) -> bool {
|
||||
let proplist = &sink.proplist;
|
||||
if !hex_prop_is(proplist, "device.vendor.id", G733::VENDOR_ID) {
|
||||
return false;
|
||||
}
|
||||
if !hex_prop_is(proplist, "device.product.id", G733::PRODUCT_ID) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
fn handle_report(device: &HidDevice, report: &[u8]) -> Result<(), HidError> {
|
||||
if report[0] == 17 {
|
||||
if report[2] == 8 {
|
||||
// Power event
|
||||
let mut sink_controller = SinkController::create().unwrap();
|
||||
|
||||
if report[4] == 0 {
|
||||
// Power off
|
||||
|
||||
// Set default sink to non headset
|
||||
let sinks = sink_controller.list_devices().unwrap();
|
||||
let new_sink = sinks.iter().find(|sink| !is_sink_headset(*sink)).unwrap();
|
||||
sink_controller
|
||||
.set_default_device(new_sink.name.as_ref().unwrap())
|
||||
.unwrap();
|
||||
} else {
|
||||
// Power on event
|
||||
|
||||
// Turn off the lights
|
||||
device.write(&[
|
||||
0x11, 0xff, 0x04, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00,
|
||||
])?;
|
||||
|
||||
// Set default sink to the headset
|
||||
let sinks = sink_controller.list_devices().unwrap();
|
||||
let headset = sinks.iter().find(|sink| is_sink_headset(*sink)).unwrap();
|
||||
sink_controller
|
||||
.set_default_device(headset.name.as_ref().unwrap())
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut buf = [0; 100];
|
||||
let device = find_device().unwrap().expect("No supported headset found");
|
||||
loop {
|
||||
let size = device.read(&mut buf).unwrap();
|
||||
let report = &buf[0..size];
|
||||
handle_report(&device, report).unwrap();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user