mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
feature: add support for screenpad brightness
This commit is contained in:
75
rog-platform/src/backlight.rs
Normal file
75
rog-platform/src/backlight.rs
Normal file
@@ -0,0 +1,75 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use log::{info, warn};
|
||||
|
||||
use crate::error::{PlatformError, Result};
|
||||
use crate::{attr_num, to_device};
|
||||
|
||||
/// The "backlight" device provides access to screen brightness control
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Clone)]
|
||||
pub struct Backlight {
|
||||
path: PathBuf,
|
||||
device_type: BacklightType,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Clone)]
|
||||
pub enum BacklightType {
|
||||
Primary,
|
||||
Screenpad,
|
||||
}
|
||||
|
||||
impl Backlight {
|
||||
attr_num!("brightness", path, i32);
|
||||
|
||||
attr_num!("max_brightness", path, i32);
|
||||
|
||||
attr_num!("bl_power", path, i32);
|
||||
|
||||
pub fn new(device_type: BacklightType) -> Result<Self> {
|
||||
let mut enumerator = udev::Enumerator::new().map_err(|err| {
|
||||
warn!("{}", err);
|
||||
PlatformError::Udev("enumerator failed".into(), err)
|
||||
})?;
|
||||
enumerator.match_subsystem("backlight").map_err(|err| {
|
||||
warn!("{}", err);
|
||||
PlatformError::Udev("match_subsystem failed".into(), err)
|
||||
})?;
|
||||
|
||||
for device in enumerator.scan_devices().map_err(|err| {
|
||||
warn!("{}", err);
|
||||
PlatformError::Udev("scan_devices failed".into(), err)
|
||||
})? {
|
||||
info!("Backlight: Checking {:?}", device.syspath());
|
||||
match device_type {
|
||||
BacklightType::Primary => {
|
||||
if device.sysname().to_string_lossy() == "intel_backlight" {
|
||||
info!("Found primary backlight at {:?}", device.sysname());
|
||||
return Ok(Self {
|
||||
path: device.syspath().to_path_buf(),
|
||||
device_type,
|
||||
});
|
||||
}
|
||||
}
|
||||
BacklightType::Screenpad => {
|
||||
let name = device.sysname().to_string_lossy();
|
||||
if name == "asus_screenpad" || name == "asus_screenpad_backlight" {
|
||||
info!("Found screenpad backlight at {:?}", device.sysname());
|
||||
return Ok(Self {
|
||||
path: device.syspath().to_path_buf(),
|
||||
device_type,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(PlatformError::MissingFunction(format!(
|
||||
"Backlight {:?} not found",
|
||||
device_type
|
||||
)))
|
||||
}
|
||||
|
||||
pub fn device_type(&self) -> &BacklightType {
|
||||
&self.device_type
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ use std::path::PathBuf;
|
||||
use log::{info, warn};
|
||||
|
||||
use crate::error::{PlatformError, Result};
|
||||
use crate::{attr_u8, has_attr, set_attr_u8_array, to_device};
|
||||
use crate::{attr_num, has_attr, set_attr_u8_array, to_device};
|
||||
|
||||
/// The sysfs control for backlight levels. This is only for the 3-step
|
||||
/// backlight setting, and for TUF laptops. It is not a hard requirement
|
||||
@@ -14,7 +14,7 @@ pub struct KeyboardBacklight {
|
||||
}
|
||||
|
||||
impl KeyboardBacklight {
|
||||
attr_u8!("brightness", path);
|
||||
attr_num!("brightness", path, u8);
|
||||
|
||||
has_attr!("kbd_rgb_mode" path);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
//! on ROG, Strix, and TUF laptops.
|
||||
|
||||
pub mod asus_armoury;
|
||||
pub mod backlight;
|
||||
pub mod cpu;
|
||||
pub mod error;
|
||||
pub mod hid_raw;
|
||||
@@ -55,18 +56,29 @@ pub fn write_attr_bool(device: &mut Device, attr: &str, value: bool) -> Result<(
|
||||
})
|
||||
}
|
||||
|
||||
pub fn read_attr_u8(device: &Device, attr_name: &str) -> Result<u8> {
|
||||
pub fn read_attr_num<T>(device: &Device, attr_name: &str) -> Result<T>
|
||||
where
|
||||
T: std::str::FromStr,
|
||||
<T as std::str::FromStr>::Err: std::fmt::Debug,
|
||||
{
|
||||
if let Some(value) = device.attribute_value(attr_name) {
|
||||
let tmp = value.to_string_lossy();
|
||||
return tmp.parse::<u8>().map_err(|_e| PlatformError::ParseNum);
|
||||
return tmp.parse::<T>().map_err(|_e| PlatformError::ParseNum);
|
||||
}
|
||||
Err(PlatformError::AttrNotFound(attr_name.to_owned()))
|
||||
}
|
||||
|
||||
pub fn write_attr_u8(device: &mut Device, attr: &str, value: u8) -> Result<()> {
|
||||
device
|
||||
.set_attribute_value(attr, value.to_string())
|
||||
.map_err(|e| PlatformError::IoPath(attr.into(), e))
|
||||
pub fn write_attr_num<T>(device: &mut Device, attr_name: &str, value: T) -> Result<()>
|
||||
where
|
||||
T: std::fmt::Display,
|
||||
{
|
||||
if device
|
||||
.set_attribute_value(attr_name, format!("{value}"))
|
||||
.is_err()
|
||||
{
|
||||
return Err(PlatformError::AttrNotFound(attr_name.to_owned()));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn read_attr_u8_array(device: &Device, attr_name: &str) -> Result<Vec<u8>> {
|
||||
|
||||
@@ -74,36 +74,41 @@ macro_rules! attr_bool {
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! get_attr_u8 {
|
||||
($(#[$attr:meta])* $attr_name:literal $item:ident) => {
|
||||
macro_rules! get_attr_num {
|
||||
($(#[$attr:meta])* $attr_name:literal $item:ident $type:ty) => {
|
||||
concat_idents::concat_idents!(fn_name = get_, $attr_name {
|
||||
$(#[$attr])*
|
||||
pub fn fn_name(&self) -> Result<u8> {
|
||||
$crate::read_attr_u8(&to_device(&self.$item)?, $attr_name)
|
||||
pub fn fn_name(&self) -> Result<$type> {
|
||||
$crate::read_attr_num::<$type>(&to_device(&self.$item)?, $attr_name)
|
||||
}
|
||||
});
|
||||
};
|
||||
($(#[$attr:meta])* $attr_name:literal $item:ident) => {
|
||||
$crate::get_attr_num!($(#[$attr])* $attr_name $item $type);
|
||||
};
|
||||
}
|
||||
|
||||
/// Most attributes expect `u8` as a char, so `1` should be written as `b'1'`.
|
||||
#[macro_export]
|
||||
macro_rules! set_attr_u8 {
|
||||
($(#[$attr:meta])* $attr_name:literal $item:ident) => {
|
||||
macro_rules! set_attr_num {
|
||||
($(#[$attr:meta])* $attr_name:literal $item:ident $type:ty) => {
|
||||
concat_idents::concat_idents!(fn_name = set_, $attr_name {
|
||||
$(#[$attr])*
|
||||
pub fn fn_name(&self, value: u8) -> Result<()> {
|
||||
$crate::write_attr_u8(&mut to_device(&self.$item)?, $attr_name, value)
|
||||
pub fn fn_name(&self, value: $type) -> Result<()> {
|
||||
$crate::write_attr_num(&mut to_device(&self.$item)?, $attr_name, value as $type)
|
||||
}
|
||||
});
|
||||
};
|
||||
($(#[$attr:meta])* $attr_name:literal $item:ident) => {
|
||||
$crate::set_attr_num!($(#[$attr])* $attr_name $item $type);
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! attr_u8 {
|
||||
($(#[$attr:meta])* $attr_name:literal, $item:ident) => {
|
||||
macro_rules! attr_num {
|
||||
($(#[$attr:meta])* $attr_name:literal, $item:ident, $type:ty) => {
|
||||
$crate::has_attr!($(#[$attr])* $attr_name $item);
|
||||
$crate::get_attr_u8!($(#[$attr])* $attr_name $item);
|
||||
$crate::set_attr_u8!($(#[$attr])* $attr_name $item);
|
||||
$crate::get_attr_num!($(#[$attr])* $attr_name $item $type);
|
||||
$crate::set_attr_num!($(#[$attr])* $attr_name $item $type);
|
||||
$crate::watch_attr!($(#[$attr])* $attr_name $item);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::path::PathBuf;
|
||||
use log::{info, warn};
|
||||
|
||||
use crate::error::{PlatformError, Result};
|
||||
use crate::{attr_u8, to_device};
|
||||
use crate::{attr_num, to_device};
|
||||
|
||||
/// The "platform" device provides access to things like:
|
||||
/// - `dgpu_disable`
|
||||
@@ -20,9 +20,9 @@ pub struct AsusPower {
|
||||
}
|
||||
|
||||
impl AsusPower {
|
||||
attr_u8!("charge_control_end_threshold", battery);
|
||||
attr_num!("charge_control_end_threshold", battery, u8);
|
||||
|
||||
attr_u8!("online", mains);
|
||||
attr_num!("online", mains, u8);
|
||||
|
||||
/// When checking for battery this will look in order:
|
||||
/// - if attr `manufacturer` contains `asus`
|
||||
|
||||
Reference in New Issue
Block a user