Initial commit

This commit is contained in:
2022-02-16 23:17:05 +01:00
commit 7844d4f6eb
5 changed files with 292 additions and 0 deletions

91
src/main.rs Normal file
View 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();
}
}