mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| de3b803f14 | |||
| 0558f919c4 | |||
| 68ea73c847 | |||
| 96ddb7132d | |||
| d36ac44603 | |||
| 5d06c87943 | |||
| 588e3c0102 | |||
| 6ce32c1cab | |||
| a23c51e5db | |||
| 3845071ba3 | |||
| a48b3634bf | |||
| 806882b2e9 | |||
| 9ac3c46fe6 | |||
| 6817a1c027 | |||
| cf2be1b12b | |||
| a7f6e8bd24 |
@@ -5,6 +5,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
# [2.1.0] - 2020-10-25
|
||||
### Added
|
||||
- Option to turn off AniMe display (@asere)
|
||||
### Changed
|
||||
- Change option -k to show current LED bright (@asere)
|
||||
- Correctly disable GFX control via config
|
||||
- Panic and exit if config can't be parsed
|
||||
- Add DBUS method to toggle to next fan/thermal profile
|
||||
- Add DBUS method to toggle to next/prev Aura mode
|
||||
|
||||
# [2.0.5] - 2020-09-29
|
||||
### Changed
|
||||
- Bugfixes
|
||||
|
||||
Generated
+3
-3
@@ -29,7 +29,7 @@ checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
|
||||
|
||||
[[package]]
|
||||
name = "asus-nb"
|
||||
version = "2.0.4"
|
||||
version = "2.1.0"
|
||||
dependencies = [
|
||||
"ctrl-gfx",
|
||||
"dbus",
|
||||
@@ -46,7 +46,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "asus-nb-ctrl"
|
||||
version = "2.0.4"
|
||||
version = "2.1.0"
|
||||
dependencies = [
|
||||
"asus-nb",
|
||||
"ctrl-gfx",
|
||||
@@ -191,7 +191,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ctrl-gfx"
|
||||
version = "2.1.1"
|
||||
version = "2.1.3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"sysfs-class",
|
||||
|
||||
@@ -52,6 +52,7 @@ install: all
|
||||
install -D -m 0644 "data/icons/asus_notif_yellow.png" "$(DESTDIR)/usr/share/icons/hicolor/512x512/apps/asus_notif_yellow.png"
|
||||
install -D -m 0644 "data/icons/asus_notif_green.png" "$(DESTDIR)/usr/share/icons/hicolor/512x512/apps/asus_notif_green.png"
|
||||
install -D -m 0644 "data/icons/asus_notif_red.png" "$(DESTDIR)/usr/share/icons/hicolor/512x512/apps/asus_notif_red.png"
|
||||
install -D -m 0644 "data/_asusctl" "$(DESTDIR)/usr/share/zsh/site-functions/_asusctl"
|
||||
|
||||
uninstall:
|
||||
rm -f "$(DESTDIR)$(bindir)/$(BIN_C)"
|
||||
@@ -64,6 +65,7 @@ uninstall:
|
||||
rm -f "$(DESTDIR)/lib/systemd/system/$(BIN_D).service"
|
||||
rm -r "$(DESTDIR)/lib/systemd/user/$(BIN_N).service"
|
||||
rm -r "$(DESTDIR)/usr/share/icons/hicolor/512x512/apps/asus_notif_*"
|
||||
rm -f "$(DESTDIR)/usr/share/zsh/site-functions/_asusctl"
|
||||
|
||||
update:
|
||||
cargo update
|
||||
|
||||
@@ -117,6 +117,20 @@ If you model isn't getting the correct led modes, you can edit the file
|
||||
|
||||
use `cat /sys/class/dmi/id/product_name` to get details about your laptop.
|
||||
|
||||
# Keybinds
|
||||
|
||||
To switch to next/previous Aura modes you will need to bind both the aura keys (if available) to one of:
|
||||
**Next**
|
||||
```
|
||||
asusctl led-mode -n
|
||||
```
|
||||
**Previous**
|
||||
```
|
||||
asusctl led-mode -p
|
||||
```
|
||||
|
||||
To switch Fan/Thermal profiles you need to bind the Fn+F5 key to `asusctl profile -n`.
|
||||
|
||||
# BUILDING
|
||||
|
||||
Requirements are:
|
||||
|
||||
@@ -76,6 +76,12 @@ Accepts an integer from the following:
|
||||
- `1`: Boost mode
|
||||
- `2`: Silent mode
|
||||
|
||||
## dbus-send examples:
|
||||
|
||||
```
|
||||
dbus-send --system --type=method_call --dest=org.asuslinux.Daemon /org/asuslinux/Profile org.asuslinux.Daemon.NextProfile
|
||||
```
|
||||
|
||||
## dbus-send examples OUTDATED
|
||||
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "asus-nb-ctrl"
|
||||
version = "2.0.5"
|
||||
version = "2.1.0"
|
||||
license = "MPL-2.0"
|
||||
readme = "README.md"
|
||||
authors = ["Luke <luke@ljones.dev>"]
|
||||
|
||||
@@ -30,18 +30,18 @@ impl Config {
|
||||
.write(true)
|
||||
.create(true)
|
||||
.open(&CONFIG_PATH)
|
||||
.expect(&format!("The file {} or directory /etc/asusd/ is missing", CONFIG_PATH)); // okay to cause panic here
|
||||
.expect(&format!(
|
||||
"The file {} or directory /etc/asusd/ is missing",
|
||||
CONFIG_PATH
|
||||
)); // okay to cause panic here
|
||||
let mut buf = String::new();
|
||||
if let Ok(l) = file.read_to_string(&mut buf) {
|
||||
if l == 0 {
|
||||
self = Config::create_default(&mut file, &supported_led_modes);
|
||||
} else {
|
||||
self = serde_json::from_str(&buf).unwrap_or_else(|_| {
|
||||
warn!(
|
||||
"Could not deserialise {}. Overwriting with default",
|
||||
CONFIG_PATH
|
||||
);
|
||||
Config::create_default(&mut file, &supported_led_modes)
|
||||
warn!("Could not deserialise {}", CONFIG_PATH);
|
||||
panic!("Please remove {} then restart asusd", CONFIG_PATH);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -61,11 +61,14 @@ impl Config {
|
||||
config.kbd_backlight_modes.push(AuraModes::from(*n))
|
||||
}
|
||||
|
||||
let profile = Profile::default();
|
||||
let mut profile = Profile::default();
|
||||
profile.fan_preset = 0;
|
||||
profile.turbo = true;
|
||||
config.power_profiles.insert("normal".into(), profile);
|
||||
|
||||
let mut profile = Profile::default();
|
||||
profile.fan_preset = 1;
|
||||
profile.turbo = true;
|
||||
config.power_profiles.insert("boost".into(), profile);
|
||||
|
||||
let mut profile = Profile::default();
|
||||
|
||||
@@ -9,6 +9,10 @@ const INIT: u8 = 0xc2;
|
||||
const APPLY: u8 = 0xc3;
|
||||
const SET: u8 = 0xc4;
|
||||
|
||||
// Used to turn the panel on and off
|
||||
// The next byte can be 0x03 for "on" and 0x00 for "off"
|
||||
const ON_OFF : u8 = 0x04;
|
||||
|
||||
use asus_nb::error::AuraError;
|
||||
use log::{error, info, warn};
|
||||
use rusb::{Device, DeviceHandle};
|
||||
@@ -22,6 +26,7 @@ use zbus::dbus_interface;
|
||||
pub enum AnimatrixCommand {
|
||||
Apply,
|
||||
Set,
|
||||
Write(Vec<u8>),
|
||||
WriteImage(Vec<Vec<u8>>),
|
||||
//ReloadLast,
|
||||
}
|
||||
@@ -34,6 +39,8 @@ pub struct CtrlAnimeDisplay {
|
||||
//AnimatrixWrite
|
||||
pub trait Dbus {
|
||||
fn set_anime(&mut self, input: Vec<Vec<u8>>);
|
||||
|
||||
fn set_on_off(&mut self, status: bool);
|
||||
}
|
||||
|
||||
impl crate::ZbusAdd for CtrlAnimeDisplay {
|
||||
@@ -54,6 +61,26 @@ impl Dbus for CtrlAnimeDisplay {
|
||||
self.do_command(AnimatrixCommand::WriteImage(input))
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
|
||||
fn set_on_off(&mut self, status: bool) {
|
||||
let mut activity : Vec<u8> = vec![0; PACKET_SIZE];
|
||||
activity[0] = DEV_PAGE;
|
||||
activity[1] = WRITE;
|
||||
activity[2] = ON_OFF;
|
||||
|
||||
let status_str;
|
||||
if status {
|
||||
activity[3] = 0x03;
|
||||
status_str = "on";
|
||||
} else {
|
||||
activity[3] = 0x00;
|
||||
status_str = "off";
|
||||
}
|
||||
info!("Turning {} the AniMe", status_str);
|
||||
|
||||
self.do_command(AnimatrixCommand::Write(activity))
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
}
|
||||
|
||||
impl CtrlAnimeDisplay {
|
||||
@@ -99,9 +126,10 @@ impl CtrlAnimeDisplay {
|
||||
}
|
||||
|
||||
match command {
|
||||
AnimatrixCommand::WriteImage(effect) => self.write_image(effect)?,
|
||||
AnimatrixCommand::Set => self.do_set()?,
|
||||
AnimatrixCommand::Apply => self.do_apply()?,
|
||||
AnimatrixCommand::Set => self.do_set()?,
|
||||
AnimatrixCommand::Write(bytes) => self.write_bytes(&bytes)?,
|
||||
AnimatrixCommand::WriteImage(effect) => self.write_image(effect)?,
|
||||
//AnimatrixCommand::ReloadLast => self.reload_last_builtin(&config).await?,
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -31,6 +31,7 @@ impl DbusFanAndCpu {
|
||||
|
||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
||||
impl DbusFanAndCpu {
|
||||
/// Set profile details
|
||||
fn set_profile(&self, profile: String) {
|
||||
if let Ok(event) = serde_json::from_str(&profile) {
|
||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
||||
@@ -45,6 +46,23 @@ impl DbusFanAndCpu {
|
||||
}
|
||||
}
|
||||
|
||||
/// Fetch the active profile name
|
||||
fn next_profile(&mut self) {
|
||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
||||
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
|
||||
ctrl.do_next_profile(&mut cfg)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
if let Some(profile) = cfg.power_profiles.get(&cfg.active_profile) {
|
||||
if let Ok(json) = serde_json::to_string(profile) {
|
||||
self.notify_profile(&json)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Fetch the active profile name
|
||||
fn active_profile_name(&mut self) -> String {
|
||||
if let Ok(ctrl) = self.inner.try_lock() {
|
||||
if let Ok(mut cfg) = ctrl.config.try_lock() {
|
||||
@@ -55,6 +73,7 @@ impl DbusFanAndCpu {
|
||||
"Failed".to_string()
|
||||
}
|
||||
|
||||
/// Fetch the active profile details
|
||||
fn profile(&mut self) -> String {
|
||||
if let Ok(ctrl) = self.inner.try_lock() {
|
||||
if let Ok(mut cfg) = ctrl.config.try_lock() {
|
||||
@@ -178,7 +197,8 @@ impl CtrlFanAndCPU {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn do_update(&mut self, config: &mut Config) -> Result<(), RogError> {
|
||||
/// Toggle to next profile in list
|
||||
pub(super) fn do_next_profile(&mut self, config: &mut Config) -> Result<(), RogError> {
|
||||
config.read();
|
||||
|
||||
let mut i = config
|
||||
@@ -232,7 +252,7 @@ impl CtrlFanAndCPU {
|
||||
config: &mut Config,
|
||||
) -> Result<(), RogError> {
|
||||
match event {
|
||||
ProfileEvent::Toggle => self.do_update(config)?,
|
||||
ProfileEvent::Toggle => self.do_next_profile(config)?,
|
||||
ProfileEvent::ChangeMode(mode) => {
|
||||
self.set_fan_mode(*mode, config)?;
|
||||
}
|
||||
|
||||
@@ -72,6 +72,25 @@ impl DbusKbdBacklight {
|
||||
}
|
||||
}
|
||||
|
||||
fn next_led_mode(&self) {
|
||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
||||
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
|
||||
ctrl.toggle_mode(false, &mut cfg)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn prev_led_mode(&self) {
|
||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
||||
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
|
||||
ctrl.toggle_mode(true, &mut cfg)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the current mode data
|
||||
fn led_mode(&self) -> String {
|
||||
if let Ok(ctrl) = self.inner.try_lock() {
|
||||
if let Ok(cfg) = ctrl.config.clone().try_lock() {
|
||||
@@ -86,6 +105,7 @@ impl DbusKbdBacklight {
|
||||
"SetKeyBacklight could not deserialise".to_string()
|
||||
}
|
||||
|
||||
/// Return a list of available modes
|
||||
fn led_modes(&self) -> String {
|
||||
if let Ok(ctrl) = self.inner.try_lock() {
|
||||
if let Ok(cfg) = ctrl.config.clone().try_lock() {
|
||||
@@ -98,6 +118,17 @@ impl DbusKbdBacklight {
|
||||
"SetKeyBacklight could not deserialise".to_string()
|
||||
}
|
||||
|
||||
/// Return the current LED brightness
|
||||
fn led_brightness(&self) -> i8 {
|
||||
if let Ok(ctrl) = self.inner.try_lock() {
|
||||
if let Ok(cfg) = ctrl.config.clone().try_lock() {
|
||||
return cfg.kbd_led_brightness as i8;
|
||||
}
|
||||
}
|
||||
warn!("SetKeyBacklight could not deserialise");
|
||||
-1
|
||||
}
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
fn notify_led(&self, data: &str) -> zbus::Result<()>;
|
||||
}
|
||||
@@ -152,11 +183,11 @@ impl crate::CtrlTask for CtrlKbdBacklight {
|
||||
let mut file = OpenOptions::new()
|
||||
.read(true)
|
||||
.open(&self.bright_node)
|
||||
.map_err(|err| {
|
||||
match err.kind() {
|
||||
std::io::ErrorKind::NotFound => RogError::MissingLedBrightNode((&self.bright_node).into(), err),
|
||||
_ => RogError::Path((&self.bright_node).into(), err),
|
||||
.map_err(|err| match err.kind() {
|
||||
std::io::ErrorKind::NotFound => {
|
||||
RogError::MissingLedBrightNode((&self.bright_node).into(), err)
|
||||
}
|
||||
_ => RogError::Path((&self.bright_node).into(), err),
|
||||
})?;
|
||||
let mut buf = [0u8; 1];
|
||||
file.read_exact(&mut buf)
|
||||
@@ -311,7 +342,9 @@ impl CtrlKbdBacklight {
|
||||
fn write_bytes(&self, message: &[u8]) -> Result<(), RogError> {
|
||||
if let Some(led_node) = &self.led_node {
|
||||
if let Ok(mut file) = OpenOptions::new().write(true).open(led_node) {
|
||||
return file.write_all(message).map_err(|err| RogError::Write("write_bytes".into(), err));
|
||||
return file
|
||||
.write_all(message)
|
||||
.map_err(|err| RogError::Write("write_bytes".into(), err));
|
||||
}
|
||||
}
|
||||
Err(RogError::NotSupported)
|
||||
@@ -367,6 +400,38 @@ impl CtrlKbdBacklight {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn toggle_mode(&mut self, reverse: bool, config: &mut Config) -> Result<(), RogError> {
|
||||
let current = config.kbd_backlight_mode;
|
||||
if let Some(idx) = self.supported_modes.iter().position(|v| *v == current) {
|
||||
|
||||
let mut idx = idx;
|
||||
// goes past end of array
|
||||
if reverse {
|
||||
if idx == 0 {
|
||||
idx = self.supported_modes.len() - 1;
|
||||
} else {
|
||||
idx -= 1;
|
||||
}
|
||||
} else {
|
||||
idx += 1;
|
||||
if idx == self.supported_modes.len() {
|
||||
idx = 0;
|
||||
}
|
||||
}
|
||||
let next = self.supported_modes[idx];
|
||||
|
||||
config.read();
|
||||
if let Some(data) = config.get_led_mode_data(next) {
|
||||
self.write_mode(&data)?;
|
||||
config.kbd_backlight_mode = next;
|
||||
}
|
||||
config.write();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_mode(&mut self, mode: &AuraModes) -> Result<(), RogError> {
|
||||
match mode {
|
||||
|
||||
+19
-15
@@ -15,10 +15,10 @@ use std::io::Write;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use zbus::fdo;
|
||||
use zbus::Connection;
|
||||
use std::convert::Into;
|
||||
use std::convert::TryInto;
|
||||
use zbus::fdo;
|
||||
use zbus::Connection;
|
||||
|
||||
pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut logger = env_logger::Builder::new();
|
||||
@@ -55,6 +55,7 @@ fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
.request_name(DBUS_NAME, fdo::RequestNameFlags::ReplaceExisting.into())?;
|
||||
let mut object_server = zbus::ObjectServer::new(&connection);
|
||||
|
||||
let enable_gfx_switching = config.gfx_managed;
|
||||
let config = Arc::new(Mutex::new(config));
|
||||
|
||||
match CtrlCharge::new(config.clone()) {
|
||||
@@ -79,14 +80,16 @@ fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
}
|
||||
|
||||
match CtrlGraphics::new() {
|
||||
Ok(mut ctrl) => {
|
||||
ctrl.reload()
|
||||
.unwrap_or_else(|err| warn!("Gfx controller: {}", err));
|
||||
ctrl.add_to_server(&mut object_server);
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Gfx control: {}", err);
|
||||
if enable_gfx_switching {
|
||||
match CtrlGraphics::new() {
|
||||
Ok(mut ctrl) => {
|
||||
ctrl.reload()
|
||||
.unwrap_or_else(|err| warn!("Gfx controller: {}", err));
|
||||
ctrl.add_to_server(&mut object_server);
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Gfx control: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,10 +131,11 @@ fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
for ctrl in tasks.iter() {
|
||||
if let Ok(mut lock) = ctrl.try_lock() {
|
||||
lock.do_task().map_err(|err| {
|
||||
warn!("do_task error: {}", err);
|
||||
})
|
||||
.ok();
|
||||
lock.do_task()
|
||||
.map_err(|err| {
|
||||
warn!("do_task error: {}", err);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -140,7 +144,7 @@ fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
let x = obj.limit();
|
||||
obj.notify_charge(x as u8)
|
||||
})?;
|
||||
|
||||
|
||||
loop {
|
||||
if let Err(err) = object_server.try_handle_next() {
|
||||
eprintln!("{}", err);
|
||||
|
||||
+87
-11
@@ -1,20 +1,20 @@
|
||||
use asus_nb::{
|
||||
cli_options::{LedBrightness, SetAuraBuiltin},
|
||||
anime_dbus::AniMeDbusWriter,
|
||||
cli_options::{AniMeActions, LedBrightness, SetAuraBuiltin},
|
||||
core_dbus::AuraDbusClient,
|
||||
profile::{ProfileCommand, ProfileEvent},
|
||||
};
|
||||
use ctrl_gfx::vendors::GfxVendors;
|
||||
use daemon::ctrl_fan_cpu::FanLevel;
|
||||
use gumdrop::Options;
|
||||
use gumdrop::{Opt, Options};
|
||||
use log::LevelFilter;
|
||||
use std::io::Write;
|
||||
use std::process::Command;
|
||||
use std::{env::args, io::Write, process::Command};
|
||||
use yansi_term::Colour::Green;
|
||||
use yansi_term::Colour::Red;
|
||||
|
||||
#[derive(Options)]
|
||||
#[derive(Default, Options)]
|
||||
struct CLIStart {
|
||||
#[options(help = "print help message")]
|
||||
#[options(help_flag, help = "print help message")]
|
||||
help: bool,
|
||||
#[options(help = "show program version number")]
|
||||
version: bool,
|
||||
@@ -36,13 +36,19 @@ enum CliCommand {
|
||||
Profile(ProfileCommand),
|
||||
#[options(help = "Set the graphics mode")]
|
||||
Graphics(GraphicsCommand),
|
||||
#[options(name = "anime", help = "Manage AniMe Matrix")]
|
||||
AniMe(AniMeCommand),
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
struct LedModeCommand {
|
||||
#[options(help = "print help message")]
|
||||
help: bool,
|
||||
#[options(command, required)]
|
||||
#[options(help = "switch to next aura mode")]
|
||||
next_mode: bool,
|
||||
#[options(help = "switch to previous aura mode")]
|
||||
prev_mode: bool,
|
||||
#[options(command)]
|
||||
command: Option<SetAuraBuiltin>,
|
||||
}
|
||||
|
||||
@@ -60,6 +66,18 @@ struct GraphicsCommand {
|
||||
force: bool,
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
struct AniMeCommand {
|
||||
#[options(help = "print help message")]
|
||||
help: bool,
|
||||
#[options(help = "turn on the panel (and accept write requests)", no_short)]
|
||||
on: bool,
|
||||
#[options(help = "turn off the panel (and reject write requests)", no_short)]
|
||||
off: bool,
|
||||
#[options(command)]
|
||||
command: Option<AniMeActions>,
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut logger = env_logger::Builder::new();
|
||||
logger
|
||||
@@ -68,30 +86,88 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.filter(None, LevelFilter::Info)
|
||||
.init();
|
||||
|
||||
let parsed = CLIStart::parse_args_default_or_exit();
|
||||
let mut args: Vec<String> = args().collect();
|
||||
args.remove(0);
|
||||
|
||||
let parsed: CLIStart;
|
||||
let missing_argument_k = gumdrop::Error::missing_argument(Opt::Short('k'));
|
||||
match CLIStart::parse_args_default(&args) {
|
||||
Ok(p) => {
|
||||
parsed = p;
|
||||
}
|
||||
Err(err) if err.to_string() == missing_argument_k.to_string() => {
|
||||
parsed = CLIStart {
|
||||
kbd_bright: Some(LedBrightness::new(None)),
|
||||
..Default::default()
|
||||
};
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("source {:?}", err);
|
||||
std::process::exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
if parsed.help_requested() {
|
||||
// As help option don't work with `parse_args_default`
|
||||
// we will call `parse_args_default_or_exit` instead
|
||||
CLIStart::parse_args_default_or_exit();
|
||||
}
|
||||
|
||||
if parsed.version {
|
||||
println!("Version: {}", daemon::VERSION);
|
||||
}
|
||||
|
||||
let writer = AuraDbusClient::new()?;
|
||||
let anime_writer = AniMeDbusWriter::new()?;
|
||||
|
||||
match parsed.command {
|
||||
Some(CliCommand::LedMode(mode)) => {
|
||||
if let Some(command) = mode.command {
|
||||
if mode.next_mode && mode.prev_mode {
|
||||
println!("Please specify either next or previous")
|
||||
}
|
||||
if mode.next_mode {
|
||||
writer.next_keyboard_led_mode()?;
|
||||
} else if mode.prev_mode {
|
||||
writer.prev_keyboard_led_mode()?;
|
||||
} else if let Some(command) = mode.command {
|
||||
writer.write_builtin_mode(&command.into())?
|
||||
}
|
||||
}
|
||||
Some(CliCommand::Profile(command)) => {
|
||||
writer.write_profile_command(&ProfileEvent::Cli(command))?
|
||||
if command.next {
|
||||
writer.next_fan_profile()?;
|
||||
} else {
|
||||
writer.write_profile_command(&ProfileEvent::Cli(command))?
|
||||
}
|
||||
}
|
||||
Some(CliCommand::Graphics(command)) => do_gfx(command, &writer)?,
|
||||
Some(CliCommand::AniMe(anime)) => {
|
||||
if anime.on {
|
||||
anime_writer.turn_on()?;
|
||||
} else if anime.off {
|
||||
anime_writer.turn_off()?;
|
||||
} else if let Some(action) = anime.command {
|
||||
match action {
|
||||
AniMeActions::Leds(anime_leds) => {
|
||||
let led_brightness = anime_leds.led_brightness();
|
||||
anime_writer.set_leds_brightness(led_brightness)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None => (),
|
||||
}
|
||||
|
||||
if let Some(brightness) = parsed.kbd_bright {
|
||||
writer.write_brightness(brightness.level())?;
|
||||
match brightness.level() {
|
||||
None => {
|
||||
let level = writer.get_led_brightness()?;
|
||||
println!("Current keyboard led brightness: {}", level.to_string());
|
||||
}
|
||||
Some(level) => writer.write_brightness(level)?,
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(fan_level) = parsed.pwr_profile {
|
||||
writer.write_fan_mode(fan_level.into())?;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "asus-nb"
|
||||
version = "2.0.4"
|
||||
version = "2.1.0"
|
||||
license = "MPL-2.0"
|
||||
readme = "README.md"
|
||||
authors = ["Luke <luke@ljones.dev>"]
|
||||
|
||||
+67
-33
@@ -1,16 +1,18 @@
|
||||
use crate::anime_matrix::AniMePacketType;
|
||||
use crate::{DBUS_IFACE, DBUS_NAME};
|
||||
use dbus::channel::Sender;
|
||||
use dbus::{blocking::Connection, Message};
|
||||
const DBUS_ANIME_PATH : &str = "/org/asuslinux/Anime";
|
||||
pub const ANIME_PANE1_PREFIX: [u8; 7] =
|
||||
[0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02];
|
||||
pub const ANIME_PANE2_PREFIX: [u8; 7] =
|
||||
[0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02];
|
||||
|
||||
use crate::anime_matrix::{AniMeMatrix, AniMePacketType};
|
||||
use crate::DBUS_NAME;
|
||||
use dbus::blocking::{Connection, Proxy};
|
||||
use std::error::Error;
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
};
|
||||
use std::{thread, time::Duration};
|
||||
|
||||
pub const ANIME_PANE1_PREFIX: [u8; 7] = [0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02];
|
||||
pub const ANIME_PANE2_PREFIX: [u8; 7] = [0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02];
|
||||
use crate::dbus_anime::{
|
||||
OrgAsuslinuxDaemon as OrgAsuslinuxDaemonAniMe,
|
||||
};
|
||||
|
||||
/// Interface for the AniMe dot-matrix display
|
||||
///
|
||||
@@ -23,7 +25,6 @@ pub const ANIME_PANE2_PREFIX: [u8; 7] = [0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x0
|
||||
pub struct AniMeDbusWriter {
|
||||
connection: Box<Connection>,
|
||||
block_time: u64,
|
||||
stop: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
impl AniMeDbusWriter {
|
||||
@@ -33,47 +34,80 @@ impl AniMeDbusWriter {
|
||||
Ok(AniMeDbusWriter {
|
||||
connection: Box::new(connection),
|
||||
block_time: 25,
|
||||
stop: Arc::new(AtomicBool::new(false)),
|
||||
})
|
||||
}
|
||||
|
||||
// Create D-Bus proxy
|
||||
fn new_proxy(&self) -> Proxy<&Connection>{
|
||||
self.connection.with_proxy(
|
||||
DBUS_NAME,
|
||||
DBUS_ANIME_PATH,
|
||||
Duration::from_millis(200),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn write_image_to_buf(_buf: &mut AniMePacketType, _image_data: &[u8]) {
|
||||
unimplemented!("Image format is in progress of being worked out")
|
||||
}
|
||||
|
||||
/// Write an Animatrix image
|
||||
///
|
||||
/// The expected input here is *two* Vectors, 640 bytes in length. The two vectors
|
||||
/// are each one half of the full image write.
|
||||
/// The expected input here is *two* Vectors, 640 bytes in length.
|
||||
/// The two vectors are each one half of the full image write.
|
||||
///
|
||||
/// After each write a flush is written, it is assumed that this tells the device to
|
||||
/// go ahead and display the written bytes
|
||||
/// After each write a flush is written, it is assumed that this tells the
|
||||
/// device to go ahead and display the written bytes
|
||||
///
|
||||
/// # Note:
|
||||
/// The vectors are expected to contain the full sequence of bytes as follows
|
||||
/// # Note: The vectors are expected to contain the full sequence of bytes
|
||||
/// as follows
|
||||
///
|
||||
/// - Write packet 1: 0x5e 0xc0 0x02 0x01 0x00 0x73 0x02 .. <led brightness>
|
||||
/// - Write packet 2: 0x5e 0xc0 0x02 0x74 0x02 0x73 0x02 .. <led brightness>
|
||||
///
|
||||
/// Where led brightness is 0..255, low to high
|
||||
#[inline]
|
||||
pub fn write_image(&mut self, image: &mut AniMePacketType) -> Result<(), Box<dyn Error>> {
|
||||
if image[0][0] != ANIME_PANE1_PREFIX[0] && image[0][6] != ANIME_PANE1_PREFIX[6] {
|
||||
image[0][..7].copy_from_slice(&ANIME_PANE1_PREFIX);
|
||||
}
|
||||
if image[1][0] != ANIME_PANE2_PREFIX[0] && image[1][6] != ANIME_PANE2_PREFIX[6] {
|
||||
image[1][..7].copy_from_slice(&ANIME_PANE2_PREFIX);
|
||||
}
|
||||
pub fn write_image(&self, image: &mut AniMePacketType)
|
||||
-> Result<(), Box<dyn Error>> {
|
||||
let proxy = self.new_proxy();
|
||||
|
||||
let mut msg =
|
||||
Message::new_method_call(DBUS_NAME, "/org/asuslinux/Anime", DBUS_IFACE, "SetAnime")?
|
||||
.append2(image[0].to_vec(), image[1].to_vec());
|
||||
msg.set_no_reply(true);
|
||||
self.connection.send(msg).unwrap();
|
||||
image[0][..7].copy_from_slice(&ANIME_PANE1_PREFIX);
|
||||
image[1][..7].copy_from_slice(&ANIME_PANE2_PREFIX);
|
||||
|
||||
proxy.set_anime(vec![image[0].to_vec(), image[1].to_vec()])?;
|
||||
thread::sleep(Duration::from_millis(self.block_time));
|
||||
if self.stop.load(Ordering::Relaxed) {
|
||||
panic!("Got signal to stop!");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_leds_brightness(&self, led_brightness: u8)
|
||||
-> Result<(), Box<dyn Error>> {
|
||||
let mut anime_matrix = AniMeMatrix::new();
|
||||
|
||||
anime_matrix.fill_with(led_brightness);
|
||||
self.write_image(&mut AniMePacketType::from(anime_matrix))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn turn_on_off(&self, status : bool) -> Result<(), Box<dyn Error>> {
|
||||
let proxy = self.new_proxy();
|
||||
|
||||
proxy.set_on_off(status)?;
|
||||
thread::sleep(Duration::from_millis(self.block_time));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn turn_on(&self) -> Result<(), Box<dyn Error>> {
|
||||
self.turn_on_off(true)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn turn_off(&self) -> Result<(), Box<dyn Error>> {
|
||||
self.turn_on_off(false)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,14 @@ use std::str::FromStr;
|
||||
|
||||
#[derive(Options)]
|
||||
pub struct LedBrightness {
|
||||
level: u8,
|
||||
level: Option<u8>,
|
||||
}
|
||||
impl LedBrightness {
|
||||
pub fn level(&self) -> u8 {
|
||||
pub fn new(level: Option<u8>) -> Self {
|
||||
LedBrightness { level }
|
||||
}
|
||||
|
||||
pub fn level(&self) -> Option<u8> {
|
||||
self.level
|
||||
}
|
||||
}
|
||||
@@ -18,17 +22,30 @@ impl FromStr for LedBrightness {
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let s = s.to_lowercase();
|
||||
match s.as_str() {
|
||||
"off" => Ok(LedBrightness { level: 0x00 }),
|
||||
"low" => Ok(LedBrightness { level: 0x01 }),
|
||||
"med" => Ok(LedBrightness { level: 0x02 }),
|
||||
"high" => Ok(LedBrightness { level: 0x03 }),
|
||||
"off" => Ok(LedBrightness { level: Some(0x00) }),
|
||||
"low" => Ok(LedBrightness { level: Some(0x01) }),
|
||||
"med" => Ok(LedBrightness { level: Some(0x02) }),
|
||||
"high" => Ok(LedBrightness { level: Some(0x03) }),
|
||||
_ => {
|
||||
println!("Missing required argument, must be one of:\noff,low,med,high\n");
|
||||
print!("{}\n{}\n",
|
||||
"Invalid argument, must be one of:",
|
||||
"off, low, med, high");
|
||||
Err(AuraError::ParseBrightness)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl ToString for LedBrightness {
|
||||
fn to_string(&self) -> String {
|
||||
let s = match self.level {
|
||||
Some(0x00) => "low",
|
||||
Some(0x01) => "med",
|
||||
Some(0x02) => "high",
|
||||
_ => "unknown",
|
||||
};
|
||||
s.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Colour(pub u8, pub u8, pub u8);
|
||||
@@ -213,3 +230,25 @@ impl Default for SetAuraBuiltin {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
pub struct AniMeLeds {
|
||||
#[options(help = "print help message")]
|
||||
help: bool,
|
||||
#[options(no_long, required,
|
||||
short = "b", meta = "BYTE",
|
||||
help = "set all leds brightness value")]
|
||||
led_brightness: u8,
|
||||
}
|
||||
|
||||
impl AniMeLeds {
|
||||
pub fn led_brightness(&self) -> u8 {
|
||||
self.led_brightness
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
pub enum AniMeActions {
|
||||
#[options(help = "change all leds brightness")]
|
||||
Leds(AniMeLeds),
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::cli_options::LedBrightness;
|
||||
use super::*;
|
||||
use crate::fancy::KeyColourArray;
|
||||
use crate::profile::ProfileEvent;
|
||||
@@ -230,6 +231,28 @@ impl AuraDbusClient {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn next_keyboard_led_mode(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let proxy = self.connection.with_proxy(
|
||||
"org.asuslinux.Daemon",
|
||||
"/org/asuslinux/Led",
|
||||
Duration::from_secs(2),
|
||||
);
|
||||
proxy.next_led_mode()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn prev_keyboard_led_mode(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let proxy = self.connection.with_proxy(
|
||||
"org.asuslinux.Daemon",
|
||||
"/org/asuslinux/Led",
|
||||
Duration::from_secs(2),
|
||||
);
|
||||
proxy.prev_led_mode()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_gfx_pwr(&self) -> Result<String, Box<dyn std::error::Error>> {
|
||||
let proxy = self.connection.with_proxy(
|
||||
@@ -263,6 +286,17 @@ impl AuraDbusClient {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn next_fan_profile(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let proxy = self.connection.with_proxy(
|
||||
"org.asuslinux.Daemon",
|
||||
"/org/asuslinux/Profile",
|
||||
Duration::from_secs(2),
|
||||
);
|
||||
proxy.next_profile()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn write_fan_mode(&self, level: u8) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let proxy = self.connection.with_proxy(
|
||||
@@ -305,8 +339,21 @@ impl AuraDbusClient {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn write_brightness(&self, level: u8) -> Result<String, Box<dyn std::error::Error>> {
|
||||
pub fn get_led_brightness(&self) -> Result<LedBrightness, Box<dyn Error>> {
|
||||
let proxy = self.connection.with_proxy(
|
||||
"org.asuslinux.Daemon",
|
||||
"/org/asuslinux/Led",
|
||||
Duration::from_secs(2),
|
||||
);
|
||||
match proxy.led_brightness()? {
|
||||
-1 => Ok(LedBrightness::new(None)),
|
||||
level => Ok(LedBrightness::new(Some(level as u8))),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn write_brightness(&self, level: u8) -> Result<(), Box<dyn std::error::Error>> {
|
||||
self.write_keyboard_leds(&AuraModes::LedBrightness(level))?;
|
||||
Ok(String::new())
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// This code was autogenerated with `dbus-codegen-rust -s -d org.asuslinux.Daemon -p /org/asuslinux/Anime -m None -f org.asuslinux.Daemon -c blocking`, see https://github.com/diwic/dbus-rs
|
||||
use dbus as dbus;
|
||||
#[allow(unused_imports)]
|
||||
use dbus::arg;
|
||||
use dbus::blocking;
|
||||
|
||||
pub trait OrgAsuslinuxDaemon {
|
||||
fn set_anime(&self, input: Vec<Vec<u8>>) -> Result<(), dbus::Error>;
|
||||
fn set_on_off(&self, status: bool) -> Result<(), dbus::Error>;
|
||||
}
|
||||
|
||||
impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref<Target=T>> OrgAsuslinuxDaemon for blocking::Proxy<'a, C> {
|
||||
|
||||
fn set_anime(&self, input: Vec<Vec<u8>>) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.asuslinux.Daemon", "SetAnime", (input, ))
|
||||
}
|
||||
|
||||
fn set_on_off(&self, status: bool) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.asuslinux.Daemon", "SetOnOff", (status, ))
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,11 @@ use dbus::blocking;
|
||||
|
||||
pub trait OrgAsuslinuxDaemon {
|
||||
fn set_led_mode(&self, data: &str) -> Result<(), dbus::Error>;
|
||||
fn next_led_mode(&self) -> Result<(), dbus::Error>;
|
||||
fn prev_led_mode(&self) -> Result<(), dbus::Error>;
|
||||
fn led_mode(&self) -> Result<String, dbus::Error>;
|
||||
fn led_modes(&self) -> Result<String, dbus::Error>;
|
||||
fn led_brightness(&self) -> Result<i16, dbus::Error>;
|
||||
}
|
||||
|
||||
impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref<Target=T>> OrgAsuslinuxDaemon for blocking::Proxy<'a, C> {
|
||||
@@ -16,6 +19,14 @@ impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref<Target=T>> OrgAsuslin
|
||||
self.method_call("org.asuslinux.Daemon", "SetLedMode", (data, ))
|
||||
}
|
||||
|
||||
fn next_led_mode(&self) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.asuslinux.Daemon", "NextLedMode", ())
|
||||
}
|
||||
|
||||
fn prev_led_mode(&self) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.asuslinux.Daemon", "PrevLedMode", ())
|
||||
}
|
||||
|
||||
fn led_mode(&self) -> Result<String, dbus::Error> {
|
||||
self.method_call("org.asuslinux.Daemon", "LedMode", ())
|
||||
.and_then(|r: (String, )| Ok(r.0, ))
|
||||
@@ -25,6 +36,11 @@ impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref<Target=T>> OrgAsuslin
|
||||
self.method_call("org.asuslinux.Daemon", "LedModes", ())
|
||||
.and_then(|r: (String, )| Ok(r.0, ))
|
||||
}
|
||||
|
||||
fn led_brightness(&self) -> Result<i16, dbus::Error> {
|
||||
self.method_call("org.asuslinux.Daemon", "LedBrightness", ())
|
||||
.and_then(|r: (i16, )| Ok(r.0, ))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
||||
@@ -1,30 +1,40 @@
|
||||
// This code was autogenerated with `dbus-codegen-rust -s -d org.asuslinux.Daemon -f org.asuslinux.Daemon -c blocking -p /org/asuslinux/Profile -m None`, see https://github.com/diwic/dbus-rs
|
||||
use dbus;
|
||||
// This code was autogenerated with `dbus-codegen-rust -s -d org.asuslinux.Daemon -p /org/asuslinux/Profile -m None -f org.asuslinux.Daemon -c blocking`, see https://github.com/diwic/dbus-rs
|
||||
use dbus as dbus;
|
||||
#[allow(unused_imports)]
|
||||
use dbus::arg;
|
||||
use dbus::blocking;
|
||||
|
||||
pub trait OrgAsuslinuxDaemon {
|
||||
fn set_profile(&self, profile: &str) -> Result<(), dbus::Error>;
|
||||
fn next_profile(&self) -> Result<(), dbus::Error>;
|
||||
fn active_profile_name(&self) -> Result<String, dbus::Error>;
|
||||
fn profile(&self) -> Result<String, dbus::Error>;
|
||||
fn profiles(&self) -> Result<String, dbus::Error>;
|
||||
}
|
||||
|
||||
impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref<Target = T>> OrgAsuslinuxDaemon
|
||||
for blocking::Proxy<'a, C>
|
||||
{
|
||||
impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref<Target=T>> OrgAsuslinuxDaemon for blocking::Proxy<'a, C> {
|
||||
|
||||
fn set_profile(&self, profile: &str) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.asuslinux.Daemon", "SetProfile", (profile,))
|
||||
self.method_call("org.asuslinux.Daemon", "SetProfile", (profile, ))
|
||||
}
|
||||
|
||||
fn next_profile(&self) -> Result<(), dbus::Error> {
|
||||
self.method_call("org.asuslinux.Daemon", "NextProfile", ())
|
||||
}
|
||||
|
||||
fn active_profile_name(&self) -> Result<String, dbus::Error> {
|
||||
self.method_call("org.asuslinux.Daemon", "ActiveProfileName", ())
|
||||
.and_then(|r: (String, )| Ok(r.0, ))
|
||||
}
|
||||
|
||||
fn profile(&self) -> Result<String, dbus::Error> {
|
||||
self.method_call("org.asuslinux.Daemon", "Profile", ())
|
||||
.and_then(|r: (String,)| Ok(r.0))
|
||||
.and_then(|r: (String, )| Ok(r.0, ))
|
||||
}
|
||||
|
||||
fn profiles(&self) -> Result<String, dbus::Error> {
|
||||
self.method_call("org.asuslinux.Daemon", "Profiles", ())
|
||||
.and_then(|r: (String,)| Ok(r.0))
|
||||
.and_then(|r: (String, )| Ok(r.0, ))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +51,9 @@ impl arg::AppendAll for OrgAsuslinuxDaemonNotifyProfile {
|
||||
|
||||
impl arg::ReadAll for OrgAsuslinuxDaemonNotifyProfile {
|
||||
fn read(i: &mut arg::Iter) -> Result<Self, arg::TypeMismatchError> {
|
||||
Ok(OrgAsuslinuxDaemonNotifyProfile { profile: i.read()? })
|
||||
Ok(OrgAsuslinuxDaemonNotifyProfile {
|
||||
profile: i.read()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ pub enum AuraError {
|
||||
ParseSpeed,
|
||||
ParseDirection,
|
||||
ParseBrightness,
|
||||
ParseAnime,
|
||||
}
|
||||
|
||||
impl fmt::Display for AuraError {
|
||||
@@ -17,6 +18,7 @@ impl fmt::Display for AuraError {
|
||||
AuraError::ParseSpeed => write!(f, "Could not parse speed"),
|
||||
AuraError::ParseDirection => write!(f, "Could not parse direction"),
|
||||
AuraError::ParseBrightness => write!(f, "Could not parse brightness"),
|
||||
AuraError::ParseAnime => write!(f, "Could not parse anime"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ pub mod dbus_gfx;
|
||||
pub mod dbus_ledmode;
|
||||
pub mod dbus_profile;
|
||||
pub mod dbus_charge;
|
||||
pub mod dbus_anime;
|
||||
|
||||
pub mod error;
|
||||
|
||||
|
||||
@@ -76,6 +76,8 @@ fn parse_fan_curve(data: &str) -> Result<Curve, String> {
|
||||
pub struct ProfileCommand {
|
||||
#[options(help = "print help message")]
|
||||
help: bool,
|
||||
#[options(help = "toggle to next profile in list")]
|
||||
pub next: bool,
|
||||
#[options(help = "create the profile if it doesn't exist")]
|
||||
pub create: bool,
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ctrl-gfx"
|
||||
version = "2.1.1"
|
||||
version = "2.1.3"
|
||||
license = "MPL-2.0"
|
||||
readme = "README.md"
|
||||
authors = ["Luke <luke@ljones.dev>"]
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
function _asusctl() {
|
||||
local line
|
||||
|
||||
_arguments -C \
|
||||
{-h,--help}'[print help message]' \
|
||||
{-v,--version}'[print version number]' \
|
||||
{-k,--kbd-bright}':[Set keyboard brightness (off, low, med, high)]' \
|
||||
{-p,--pwr-profile}':[Set power profile (silent, normal, boost)]' \
|
||||
{-c,--chg-limit}':[Set charging limit (20-100)]' \
|
||||
': :((led-mode\:"Set the keyboard lighting from built-in modes" profile\:"Create and configure profiles" graphics\:"Set the graphics mode"))' \
|
||||
'*::arg:->args'
|
||||
case $line[1] in
|
||||
led-mode)
|
||||
_arguments ': :((static\:"set a single static colour"
|
||||
breathe\:"pulse between one or two colours"
|
||||
strobe\:"strobe through all colours"
|
||||
rainbow\:"rainbow cycling in one of four directions"
|
||||
star\:"rain pattern mimicking raindrops"
|
||||
rain\:"rain pattern of three preset colours"
|
||||
highlight\:"pressed keys are highlighted to fade"
|
||||
laser\:"pressed keys generate horizontal laser"
|
||||
ripple\:"pressed keys ripple outwards like a splash"
|
||||
pulse\:"set a rapid pulse"
|
||||
comet\:"set a vertical line zooming from left"
|
||||
flash\:"set a wide vertical line zooming from left"
|
||||
multi-static\:"4-zone multi-colour"))' \
|
||||
{-h,--help}'[print help message]' \
|
||||
'-c:[set the RGB value e.g, ff00ff]' \
|
||||
'-s:[set the speed (low, med, high)]'
|
||||
;;
|
||||
profile)
|
||||
_arguments {-h,--help}'[print help message]' \
|
||||
{-c,--create}"[create the profile if it doesn't exist]" \
|
||||
{-t,--turbo}':[enable or disable cpu turbo]' \
|
||||
{-m,--min-percentage}':[set min cpu scaling (intel)]' \
|
||||
{-M,--max-percentage}':[set max cpu scaling (intel)]' \
|
||||
{-p,--preset}':[<silent, normal, boost>]' \
|
||||
{-C,--curve}':[set fan curve]'
|
||||
|
||||
;;
|
||||
graphics)
|
||||
_arguments {-h,--help}'[print help message]' \
|
||||
{-m,--mode}':[Set graphics mode (nvidia, hybrid, compute, integrated)]' \
|
||||
{-g,--get}'[Get the current mode]' \
|
||||
{-p,--pow}'[Get the current power status]' \
|
||||
{-f,--force}'[Do not ask for confirmation]'
|
||||
;;
|
||||
esac
|
||||
}
|
||||
compdef _asusctl asusctl
|
||||
@@ -4,9 +4,9 @@ StartLimitInterval=200
|
||||
StartLimitBurst=2
|
||||
|
||||
[Service]
|
||||
ExecStartPre=/usr/bin/sleep 2
|
||||
ExecStart=/usr/bin/asus-notify
|
||||
Restart=on-failure
|
||||
Restart=always
|
||||
RestartSec=1
|
||||
Type=simple
|
||||
|
||||
|
||||
Reference in New Issue
Block a user