use std::sync::Arc;
use hidpp::{
channel::HidppChannel,
device::Device,
feature::CreatableFeature,
feature::hires_wheel::{HiResWheelFeature, WheelEventTarget},
};
use tracing::debug;
use crate::route::DeviceRoute;
use crate::write::{SharedChannel, WriteError, open_feature, with_route};
pub async fn set_scroll_inversion(route: &DeviceRoute, inverted: bool) -> Result<(), WriteError> {
let index = route.device_index();
with_route(route, move |channel| async move {
set_scroll_inversion_on_channel(&channel, index, inverted).await
})
.await
}
async fn set_scroll_inversion_on_channel(
channel: &Arc<HidppChannel>,
index: u8,
inverted: bool,
) -> Result<(), WriteError> {
let mut device = Device::new(Arc::clone(channel), index)
.await
.map_err(|_| WriteError::DeviceUnreachable { index })?;
let feature = open_feature::<HiResWheelFeature>(&mut device).await?;
let capabilities = feature
.get_wheel_capabilities()
.await
.map_err(|e| WriteError::Hidpp(format!("{e:?}")))?;
if !capabilities.has_invert {
return Err(WriteError::FeatureUnsupported {
feature_hex: HiResWheelFeature::ID,
});
}
let mode = feature
.get_wheel_mode()
.await
.map_err(|e| WriteError::Hidpp(format!("{e:?}")))?;
let written = feature
.set_wheel_mode(WheelEventTarget::Native, mode.resolution, inverted)
.await
.map_err(|e| WriteError::Hidpp(format!("{e:?}")))?;
debug!(
index,
inverted,
resolution = ?written.resolution,
target = ?written.target,
"wrote native scroll inversion"
);
Ok(())
}
pub async fn set_scroll_inversion_on(
shared: &SharedChannel,
inverted: bool,
) -> Result<(), WriteError> {
set_scroll_inversion_on_channel(shared.channel(), shared.device_index(), inverted).await
}