diff --git a/Cargo.lock b/Cargo.lock index aaad17f3..4e9447b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,6 +35,7 @@ dependencies = [ name = "asusctl" version = "3.1.0" dependencies = [ + "daemon", "gumdrop", "rog_dbus", "rog_types", diff --git a/asusctl/Cargo.toml b/asusctl/Cargo.toml index b04e007e..22210e8e 100644 --- a/asusctl/Cargo.toml +++ b/asusctl/Cargo.toml @@ -11,6 +11,7 @@ edition = "2018" serde_json = "^1.0" rog_dbus = { path = "../rog-dbus" } rog_types = { path = "../rog-types" } +daemon = { path = "../daemon" } gumdrop = "^0.8" yansi-term = "^0.1" diff --git a/asusctl/src/main.rs b/asusctl/src/main.rs index 97195c61..cefda78c 100644 --- a/asusctl/src/main.rs +++ b/asusctl/src/main.rs @@ -1,3 +1,7 @@ +use daemon::{ + ctrl_fan_cpu::FanCpuSupportedFunctions, ctrl_leds::LedSupportedFunctions, + ctrl_supported::SupportedFunctions, +}; use gumdrop::{Opt, Options}; use rog_dbus::AuraDbusClient; use rog_types::{ @@ -104,8 +108,7 @@ struct BiosCommand { } fn main() -> Result<(), Box> { - let mut args: Vec = args().collect(); - args.remove(0); + let mut args: Vec = args().skip(1).collect(); let parsed: CLIStart; let missing_argument_k = gumdrop::Error::missing_argument(Opt::Short('k')); @@ -125,64 +128,26 @@ fn main() -> Result<(), Box> { } } - 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(); + let (dbus, _) = AuraDbusClient::new()?; + + let supported_tmp = dbus.proxies().supported().get_supported_functions()?; + let supported = serde_json::from_str::(&supported_tmp)?; + + if parsed.help { + print_supported_help(&supported, &parsed); + std::process::exit(1); } if parsed.version { - println!(" asusctl version {}", env!("CARGO_PKG_VERSION")); - println!(" rog-dbus version {}", rog_dbus::VERSION); - println!("rog-types version {}", rog_types::VERSION); + println!(" asusctl v{}", env!("CARGO_PKG_VERSION")); + println!(" rog-dbus v{}", rog_dbus::VERSION); + println!("rog-types v{}", rog_types::VERSION); + return Ok(()); } - let (dbus, _) = AuraDbusClient::new()?; - match parsed.command { - Some(CliCommand::LedMode(mode)) => { - if (mode.command.is_none() && !mode.prev_mode && !mode.next_mode) || mode.help { - println!("Missing arg or command\n\n{}", mode.self_usage()); - if let Some(lst) = mode.self_command_list() { - println!("\n{}", lst); - } - println!("\nHelp can also be requested on modes, e.g: static --help"); - } - if mode.next_mode && mode.prev_mode { - println!("Please specify either next or previous") - } - if mode.next_mode { - dbus.proxies().led().next_led_mode()?; - } else if mode.prev_mode { - dbus.proxies().led().prev_led_mode()?; - } else if let Some(command) = mode.command { - dbus.proxies().led().set_led_mode(&command.into())? - } - } - Some(CliCommand::Profile(cmd)) => { - if (!cmd.next - && !cmd.create - && cmd.curve.is_none() - && cmd.max_percentage.is_none() - && cmd.min_percentage.is_none() - && cmd.preset.is_none() - && cmd.profile.is_none() - && cmd.turbo.is_none()) - || cmd.help - { - println!("Missing arg or command\n\n{}", cmd.self_usage()); - if let Some(lst) = cmd.self_command_list() { - println!("\n{}", lst); - } - } - if cmd.next { - dbus.proxies().profile().next_fan()?; - } else { - dbus.proxies() - .profile() - .write_command(&ProfileEvent::Cli(cmd))? - } - } + Some(CliCommand::LedMode(mode)) => handle_led_mode(&dbus, &supported.keyboard_led, &mode)?, + Some(CliCommand::Profile(cmd)) => handle_profile(&dbus, &supported.fan_cpu_ctrl, &cmd)?, Some(CliCommand::Graphics(cmd)) => do_gfx(cmd, &dbus)?, Some(CliCommand::AniMe(cmd)) => { if (cmd.command.is_none() && cmd.boot.is_none() && cmd.turn.is_none()) || cmd.help { @@ -282,6 +247,37 @@ fn main() -> Result<(), Box> { Ok(()) } +fn print_supported_help(supported: &SupportedFunctions, parsed: &CLIStart) { + // As help option don't work with `parse_args_default` + // we will call `parse_args_default_or_exit` instead + println!("{}", parsed.self_usage()); + // command strings are in order of the struct + let commands: Vec = CliCommand::usage().lines().map(|s| s.to_string()).collect(); + + if !supported.fan_cpu_ctrl.stock_fan_modes { + println!("Note: Fan mode control is not supported by this laptop"); + } + if !supported.charge_ctrl.charge_level_set { + println!("Note: Charge control is not supported by this laptop"); + } + + println!("\nCommands available"); + if supported.keyboard_led.stock_led_modes.is_some() { + println!("{}", commands[0]); + } + if supported.fan_cpu_ctrl.stock_fan_modes || supported.fan_cpu_ctrl.fan_curve_set { + println!("{}", commands[1]); + } + // graphics + println!("{}", commands[2]); + if supported.anime_ctrl.0 { + println!("{}", commands[3]); + } + if supported.rog_bios_ctrl.dedicated_gfx_toggle || supported.rog_bios_ctrl.post_sound_toggle { + println!("{}", commands[4]); + } +} + fn do_gfx( command: GraphicsCommand, dbus_client: &AuraDbusClient, @@ -331,3 +327,68 @@ fn do_gfx_action(no_confirm: bool, ask_msg: &str, ok_msg: &str) -> bool { } false } + +fn handle_led_mode( + dbus: &AuraDbusClient, + supported: &LedSupportedFunctions, + mode: &LedModeCommand, +) -> Result<(), Box> { + if mode.command.is_none() && !mode.prev_mode && !mode.next_mode { + if !mode.help { + println!("Missing arg or command\n"); + } + println!("{}", mode.self_usage()); + + if let Some(lst) = mode.self_command_list() { + println!("\n{}", lst); + } + println!("\nHelp can also be requested on modes, e.g: static --help"); + std::process::exit(1); + } + if mode.next_mode && mode.prev_mode { + println!("Please specify either next or previous") + } + if mode.next_mode { + dbus.proxies().led().next_led_mode()?; + } else if mode.prev_mode { + dbus.proxies().led().prev_led_mode()?; + } else if let Some(command) = mode.command.as_ref() { + dbus.proxies().led().set_led_mode(&command.into())? + } + Ok(()) +} + +fn handle_profile( + dbus: &AuraDbusClient, + supported: &FanCpuSupportedFunctions, + cmd: &ProfileCommand, +) -> Result<(), Box> { + if !cmd.next + && !cmd.create + && cmd.curve.is_none() + && cmd.max_percentage.is_none() + && cmd.min_percentage.is_none() + && cmd.preset.is_none() + && cmd.profile.is_none() + && cmd.turbo.is_none() + { + if !cmd.help { + println!("Missing arg or command\n"); + } + println!("{}", cmd.self_usage()); + + if let Some(lst) = cmd.self_command_list() { + println!("\n{}", lst); + } + std::process::exit(1); + } + if cmd.next { + dbus.proxies().profile().next_fan()?; + } else { + dbus.proxies() + .profile() + .write_command(&ProfileEvent::Cli(cmd.clone()))? + } + + Ok(()) +} diff --git a/daemon/src/ctrl_anime.rs b/daemon/src/ctrl_anime.rs index e4c8e712..414a9c22 100644 --- a/daemon/src/ctrl_anime.rs +++ b/daemon/src/ctrl_anime.rs @@ -30,7 +30,7 @@ use crate::GetSupported; use serde_derive::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] -pub struct AnimeSupportedFunctions(bool); +pub struct AnimeSupportedFunctions(pub bool); impl GetSupported for CtrlAnimeDisplay { type A = AnimeSupportedFunctions; diff --git a/daemon/src/ctrl_supported.rs b/daemon/src/ctrl_supported.rs index 9f2b6601..93b3642f 100644 --- a/daemon/src/ctrl_supported.rs +++ b/daemon/src/ctrl_supported.rs @@ -15,11 +15,11 @@ use crate::{ #[derive(Serialize, Deserialize)] pub struct SupportedFunctions { - anime_ctrl: AnimeSupportedFunctions, - charge_ctrl: ChargeSupportedFunctions, - fan_cpu_ctrl: FanCpuSupportedFunctions, - keyboard_led: LedSupportedFunctions, - rog_bios_ctrl: RogBiosSupportedFunctions, + pub anime_ctrl: AnimeSupportedFunctions, + pub charge_ctrl: ChargeSupportedFunctions, + pub fan_cpu_ctrl: FanCpuSupportedFunctions, + pub keyboard_led: LedSupportedFunctions, + pub rog_bios_ctrl: RogBiosSupportedFunctions, } #[dbus_interface(name = "org.asuslinux.Daemon")] diff --git a/rog-types/src/aura_modes.rs b/rog-types/src/aura_modes.rs index 1d97a070..6dde24f7 100644 --- a/rog-types/src/aura_modes.rs +++ b/rog-types/src/aura_modes.rs @@ -223,6 +223,12 @@ impl From for AuraModes { } } +impl From<&SetAuraBuiltin> for AuraModes { + fn from(mode: &SetAuraBuiltin) -> Self { + mode.clone().into() + } +} + /// Very specific mode conversion required because numbering isn't linear impl From for u8 { fn from(mode: AuraModes) -> Self { diff --git a/rog-types/src/profile.rs b/rog-types/src/profile.rs index 876d2b4e..5d79f172 100644 --- a/rog-types/src/profile.rs +++ b/rog-types/src/profile.rs @@ -81,16 +81,16 @@ pub struct ProfileCommand { #[options(help = "create the profile if it doesn't exist")] pub create: bool, - #[options(help = "enable or disable cpu turbo")] + #[options(meta = "", help = "enable or disable cpu turbo")] pub turbo: Option, - #[options(help = "set min cpu scaling (intel)")] + #[options(meta = "", help = "set min cpu scaling (intel)")] pub min_percentage: Option, - #[options(help = "set max cpu scaling (intel)")] + #[options(meta = "", help = "set max cpu scaling (intel)")] pub max_percentage: Option, - #[options(meta = "PWR", help = "")] + #[options(meta = "", help = "")] pub preset: Option, - #[options(parse(try_from_str = "parse_fan_curve"), help = "set fan curve")] + #[options(meta = "", parse(try_from_str = "parse_fan_curve"), help = "set fan curve")] pub curve: Option, #[options(free)] pub profile: Option,