mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ae0f896cf | |||
| fb0374512d | |||
| 14f031ad34 | |||
| bee5508099 | |||
| c741204200 | |||
| 858c9841a7 | |||
| fdc7d88a70 | |||
| da3017bb89 | |||
| 641e762e80 | |||
| 25ecfda095 | |||
| 31af8f9511 | |||
| 8db783d9b4 | |||
| 45a354880a | |||
| ca1c67e803 | |||
| c819fa458a | |||
| 869ab90299 | |||
| c40029f5e7 | |||
| e864dfb0e7 | |||
| 476b394add | |||
| 4ea5480e66 | |||
| cfc46a2b70 | |||
| 235763a615 | |||
| 6e19c16e70 | |||
| 6ea550b6ff | |||
| dd30c8092b | |||
| 2bd751f841 | |||
| 7a6aafded7 | |||
| 940b93a75f | |||
| 5c70fec29a | |||
| 8ac505e0dd | |||
| 3bdb03b1d8 | |||
| 4ac4909881 |
+26
-2
@@ -5,6 +5,30 @@ 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).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
## [v4.6.2]
|
||||||
|
- Fix rog-control-center not reopening if `startup_in_background` is set
|
||||||
|
|
||||||
|
## [v4.6.1]
|
||||||
|
### Added
|
||||||
|
- Support for G733Z LED modes
|
||||||
|
- Support for GU604V LED modes
|
||||||
|
- Support for GX650P LED modes
|
||||||
|
- Support for GV604I LED modes
|
||||||
|
- Support for FX516P LED modes (this laptop still has further issues, will require a patched kernel when patch is ready)
|
||||||
|
- Add device code for the Z13 ACRNM keyboard (requires kernel patch, in progress)
|
||||||
|
- Support for GV301VIC LED modes
|
||||||
|
- Add device code for the plain Z13 keyboard (requires kernel patch, in progress)
|
||||||
|
- Support for GV301V LED modes
|
||||||
|
### Changed
|
||||||
|
- Adjustments to Anime system events thread
|
||||||
|
- Add "sleep" animetion config options to anime config
|
||||||
|
- rog-control-center dark/light mode persistency
|
||||||
|
- Adjustments to keyboard detection
|
||||||
|
- Better support of using supergfxctl when available (tray icon and menu)
|
||||||
|
- Check supergfx version before enabling use in tray (require 5.1.0+)
|
||||||
|
- Update allowed Aura modes on asusd restart if changed
|
||||||
|
- Set tray icon for dgpu to "On" if in Vfio mode to prevent confusion
|
||||||
|
- Add support for Logout/Reboot in notification for KDE
|
||||||
|
|
||||||
## [v4.6.0]
|
## [v4.6.0]
|
||||||
### Added
|
### Added
|
||||||
@@ -44,7 +68,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
## [v4.5.7]
|
## [v4.5.7]
|
||||||
### Changed
|
### Changed
|
||||||
- ROGCC: Don't notify user if changing to same mux mode
|
- ROGCC: Don't notify user if changing to same mux mode
|
||||||
-
|
-
|
||||||
|
|
||||||
## [v4.5.7]
|
## [v4.5.7]
|
||||||
### Changed
|
### Changed
|
||||||
@@ -609,4 +633,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
- Fix small deadlock with awaits
|
- Fix small deadlock with awaits
|
||||||
|
|
||||||
## [1.0.0]
|
## [1.0.0]
|
||||||
Generated
+685
-816
File diff suppressed because it is too large
Load Diff
+3
-1
@@ -2,7 +2,7 @@
|
|||||||
members = ["asusctl", "config-traits", "daemon", "daemon-user", "rog-platform", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "rog-control-center"]
|
members = ["asusctl", "config-traits", "daemon", "daemon-user", "rog-platform", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "rog-control-center"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "4.6.0"
|
version = "4.6.2"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
async-trait = "^0.1"
|
async-trait = "^0.1"
|
||||||
@@ -35,6 +35,8 @@ pix = "^0.13"
|
|||||||
tinybmp = "^0.4.0"
|
tinybmp = "^0.4.0"
|
||||||
gif = "^0.12.0"
|
gif = "^0.12.0"
|
||||||
|
|
||||||
|
versions = "4.1"
|
||||||
|
|
||||||
notify-rust = { git = "https://github.com/flukejones/notify-rust.git", default-features = false, features = ["z"] }
|
notify-rust = { git = "https://github.com/flukejones/notify-rust.git", default-features = false, features = ["z"] }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
|||||||
@@ -38,16 +38,18 @@ clean:
|
|||||||
distclean:
|
distclean:
|
||||||
rm -rf .cargo vendor vendor.tar.xz
|
rm -rf .cargo vendor vendor.tar.xz
|
||||||
|
|
||||||
install:
|
install-program:
|
||||||
$(INSTALL_PROGRAM) "./target/release/$(BIN_ROG)" "$(DESTDIR)$(bindir)/$(BIN_ROG)"
|
$(INSTALL_PROGRAM) "./target/release/$(BIN_ROG)" "$(DESTDIR)$(bindir)/$(BIN_ROG)"
|
||||||
$(INSTALL_DATA) "./rog-control-center/data/$(BIN_ROG).desktop" "$(DESTDIR)$(datarootdir)/applications/$(BIN_ROG).desktop"
|
|
||||||
$(INSTALL_DATA) "./rog-control-center/data/$(BIN_ROG).png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/$(BIN_ROG).png"
|
|
||||||
cd rog-aura/data/layouts && find . -type f -name "*.ron" -exec $(INSTALL_DATA) "{}" "$(DESTDIR)$(datarootdir)/rog-gui/layouts/{}" \;
|
|
||||||
|
|
||||||
$(INSTALL_PROGRAM) "./target/release/$(BIN_C)" "$(DESTDIR)$(bindir)/$(BIN_C)"
|
$(INSTALL_PROGRAM) "./target/release/$(BIN_C)" "$(DESTDIR)$(bindir)/$(BIN_C)"
|
||||||
$(INSTALL_PROGRAM) "./target/release/$(BIN_D)" "$(DESTDIR)$(bindir)/$(BIN_D)"
|
$(INSTALL_PROGRAM) "./target/release/$(BIN_D)" "$(DESTDIR)$(bindir)/$(BIN_D)"
|
||||||
$(INSTALL_PROGRAM) "./target/release/$(BIN_U)" "$(DESTDIR)$(bindir)/$(BIN_U)"
|
$(INSTALL_PROGRAM) "./target/release/$(BIN_U)" "$(DESTDIR)$(bindir)/$(BIN_U)"
|
||||||
|
|
||||||
|
install-data:
|
||||||
|
$(INSTALL_DATA) "./rog-control-center/data/$(BIN_ROG).desktop" "$(DESTDIR)$(datarootdir)/applications/$(BIN_ROG).desktop"
|
||||||
|
$(INSTALL_DATA) "./rog-control-center/data/$(BIN_ROG).png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/$(BIN_ROG).png"
|
||||||
|
cd rog-aura/data/layouts && find . -type f -name "*.ron" -exec $(INSTALL_DATA) "{}" "$(DESTDIR)$(datarootdir)/rog-gui/layouts/{}" \;
|
||||||
|
|
||||||
$(INSTALL_DATA) "./data/$(BIN_D).rules" "$(DESTDIR)$(libdir)/udev/rules.d/99-$(BIN_D).rules"
|
$(INSTALL_DATA) "./data/$(BIN_D).rules" "$(DESTDIR)$(libdir)/udev/rules.d/99-$(BIN_D).rules"
|
||||||
$(INSTALL_DATA) "./rog-aura/data/$(LEDCFG)" "$(DESTDIR)$(datarootdir)/asusd/$(LEDCFG)"
|
$(INSTALL_DATA) "./rog-aura/data/$(LEDCFG)" "$(DESTDIR)$(datarootdir)/asusd/$(LEDCFG)"
|
||||||
$(INSTALL_DATA) "./data/$(BIN_D).conf" "$(DESTDIR)$(datarootdir)/dbus-1/system.d/$(BIN_D).conf"
|
$(INSTALL_DATA) "./data/$(BIN_D).conf" "$(DESTDIR)$(datarootdir)/dbus-1/system.d/$(BIN_D).conf"
|
||||||
@@ -71,6 +73,8 @@ install:
|
|||||||
|
|
||||||
cd rog-anime/data && find "./anime" -type f -exec $(INSTALL_DATA) "{}" "$(DESTDIR)$(datarootdir)/asusd/{}" \;
|
cd rog-anime/data && find "./anime" -type f -exec $(INSTALL_DATA) "{}" "$(DESTDIR)$(datarootdir)/asusd/{}" \;
|
||||||
|
|
||||||
|
install: install-program install-data
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -f "$(DESTDIR)$(bindir)/$(BIN_ROG)"
|
rm -f "$(DESTDIR)$(bindir)/$(BIN_ROG)"
|
||||||
rm -r "$(DESTDIR)$(datarootdir)/applications/$(BIN_ROG).desktop"
|
rm -r "$(DESTDIR)$(datarootdir)/applications/$(BIN_ROG).desktop"
|
||||||
|
|||||||
+30
-30
@@ -10,7 +10,7 @@ use gumdrop::{Opt, Options};
|
|||||||
use profiles_cli::{FanCurveCommand, ProfileCommand};
|
use profiles_cli::{FanCurveCommand, ProfileCommand};
|
||||||
use rog_anime::usb::get_anime_type;
|
use rog_anime::usb::get_anime_type;
|
||||||
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, Vec2};
|
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, Vec2};
|
||||||
use rog_aura::usb::{AuraDev1866, AuraDev19b6, AuraDevTuf, AuraDevice, AuraPowerDev};
|
use rog_aura::usb::{AuraDevRog1, AuraDevRog2, AuraDevTuf, AuraDevice, AuraPowerDev};
|
||||||
use rog_aura::{self, AuraEffect};
|
use rog_aura::{self, AuraEffect};
|
||||||
use rog_dbus::RogDbusClientBlocking;
|
use rog_dbus::RogDbusClientBlocking;
|
||||||
use rog_platform::platform::GpuMode;
|
use rog_platform::platform::GpuMode;
|
||||||
@@ -157,7 +157,7 @@ fn do_parsed(
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if supported.keyboard_led.dev_id != AuraDevice::X19B6
|
if supported.keyboard_led.dev_id != AuraDevice::X19b6
|
||||||
&& command.trim().starts_with("led-pow-2")
|
&& command.trim().starts_with("led-pow-2")
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -472,10 +472,10 @@ fn handle_led_power_1_do_1866(
|
|||||||
dbus: &RogDbusClientBlocking<'_>,
|
dbus: &RogDbusClientBlocking<'_>,
|
||||||
power: &LedPowerCommand1,
|
power: &LedPowerCommand1,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut enabled: Vec<AuraDev1866> = Vec::new();
|
let mut enabled: Vec<AuraDevRog1> = Vec::new();
|
||||||
let mut disabled: Vec<AuraDev1866> = Vec::new();
|
let mut disabled: Vec<AuraDevRog1> = Vec::new();
|
||||||
|
|
||||||
let mut check = |e: Option<bool>, a: AuraDev1866| {
|
let mut check = |e: Option<bool>, a: AuraDevRog1| {
|
||||||
if let Some(arg) = e {
|
if let Some(arg) = e {
|
||||||
if arg {
|
if arg {
|
||||||
enabled.push(a);
|
enabled.push(a);
|
||||||
@@ -485,11 +485,11 @@ fn handle_led_power_1_do_1866(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
check(power.awake, AuraDev1866::Awake);
|
check(power.awake, AuraDevRog1::Awake);
|
||||||
check(power.boot, AuraDev1866::Boot);
|
check(power.boot, AuraDevRog1::Boot);
|
||||||
check(power.sleep, AuraDev1866::Sleep);
|
check(power.sleep, AuraDevRog1::Sleep);
|
||||||
check(power.keyboard, AuraDev1866::Keyboard);
|
check(power.keyboard, AuraDevRog1::Keyboard);
|
||||||
check(power.lightbar, AuraDev1866::Lightbar);
|
check(power.lightbar, AuraDevRog1::Lightbar);
|
||||||
|
|
||||||
let data = AuraPowerDev {
|
let data = AuraPowerDev {
|
||||||
x1866: enabled,
|
x1866: enabled,
|
||||||
@@ -576,13 +576,13 @@ fn handle_led_power2(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if supported.dev_id != AuraDevice::X19B6 {
|
if supported.dev_id != AuraDevice::X19b6 {
|
||||||
println!("This option applies only to keyboards with product ID 0x19b6");
|
println!("This option applies only to keyboards with product ID 0x19b6");
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut enabled: Vec<AuraDev19b6> = Vec::new();
|
let mut enabled: Vec<AuraDevRog2> = Vec::new();
|
||||||
let mut disabled: Vec<AuraDev19b6> = Vec::new();
|
let mut disabled: Vec<AuraDevRog2> = Vec::new();
|
||||||
let mut check = |e: Option<bool>, a: AuraDev19b6| {
|
let mut check = |e: Option<bool>, a: AuraDevRog2| {
|
||||||
if let Some(arg) = e {
|
if let Some(arg) = e {
|
||||||
if arg {
|
if arg {
|
||||||
enabled.push(a);
|
enabled.push(a);
|
||||||
@@ -594,28 +594,28 @@ fn handle_led_power2(
|
|||||||
|
|
||||||
match pow {
|
match pow {
|
||||||
aura_cli::SetAuraEnabled::Boot(arg) => {
|
aura_cli::SetAuraEnabled::Boot(arg) => {
|
||||||
check(arg.keyboard, AuraDev19b6::BootKeyb);
|
check(arg.keyboard, AuraDevRog2::BootKeyb);
|
||||||
check(arg.logo, AuraDev19b6::BootLogo);
|
check(arg.logo, AuraDevRog2::BootLogo);
|
||||||
check(arg.lightbar, AuraDev19b6::BootBar);
|
check(arg.lightbar, AuraDevRog2::BootBar);
|
||||||
check(arg.lid, AuraDev19b6::AwakeLid);
|
check(arg.lid, AuraDevRog2::AwakeLid);
|
||||||
}
|
}
|
||||||
aura_cli::SetAuraEnabled::Sleep(arg) => {
|
aura_cli::SetAuraEnabled::Sleep(arg) => {
|
||||||
check(arg.keyboard, AuraDev19b6::SleepKeyb);
|
check(arg.keyboard, AuraDevRog2::SleepKeyb);
|
||||||
check(arg.logo, AuraDev19b6::SleepLogo);
|
check(arg.logo, AuraDevRog2::SleepLogo);
|
||||||
check(arg.lightbar, AuraDev19b6::SleepBar);
|
check(arg.lightbar, AuraDevRog2::SleepBar);
|
||||||
check(arg.lid, AuraDev19b6::SleepLid);
|
check(arg.lid, AuraDevRog2::SleepLid);
|
||||||
}
|
}
|
||||||
aura_cli::SetAuraEnabled::Awake(arg) => {
|
aura_cli::SetAuraEnabled::Awake(arg) => {
|
||||||
check(arg.keyboard, AuraDev19b6::AwakeKeyb);
|
check(arg.keyboard, AuraDevRog2::AwakeKeyb);
|
||||||
check(arg.logo, AuraDev19b6::AwakeLogo);
|
check(arg.logo, AuraDevRog2::AwakeLogo);
|
||||||
check(arg.lightbar, AuraDev19b6::AwakeBar);
|
check(arg.lightbar, AuraDevRog2::AwakeBar);
|
||||||
check(arg.lid, AuraDev19b6::AwakeLid);
|
check(arg.lid, AuraDevRog2::AwakeLid);
|
||||||
}
|
}
|
||||||
aura_cli::SetAuraEnabled::Shutdown(arg) => {
|
aura_cli::SetAuraEnabled::Shutdown(arg) => {
|
||||||
check(arg.keyboard, AuraDev19b6::ShutdownKeyb);
|
check(arg.keyboard, AuraDevRog2::ShutdownKeyb);
|
||||||
check(arg.logo, AuraDev19b6::ShutdownLogo);
|
check(arg.logo, AuraDevRog2::ShutdownLogo);
|
||||||
check(arg.lightbar, AuraDev19b6::ShutdownBar);
|
check(arg.lightbar, AuraDevRog2::ShutdownBar);
|
||||||
check(arg.lid, AuraDev19b6::ShutdownBar);
|
check(arg.lid, AuraDevRog2::ShutdownBar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,12 @@ impl From<AnimeConfigV341> for AnimeConfig {
|
|||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
},
|
},
|
||||||
shutdown: if let Some(ani) = c.shutdown {
|
shutdown: if let Some(ani) = c.shutdown.clone() {
|
||||||
|
vec![ani]
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
},
|
||||||
|
sleep: if let Some(ani) = c.shutdown.clone() {
|
||||||
vec![ani]
|
vec![ani]
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
@@ -60,6 +65,32 @@ impl From<AnimeConfigV352> for AnimeConfig {
|
|||||||
system: c.system,
|
system: c.system,
|
||||||
boot: c.boot,
|
boot: c.boot,
|
||||||
wake: c.wake,
|
wake: c.wake,
|
||||||
|
sleep: c.shutdown.clone(),
|
||||||
|
shutdown: c.shutdown,
|
||||||
|
brightness: 1.0,
|
||||||
|
awake_enabled: true,
|
||||||
|
boot_anim_enabled: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct AnimeConfigV460 {
|
||||||
|
pub system: Vec<ActionLoader>,
|
||||||
|
pub boot: Vec<ActionLoader>,
|
||||||
|
pub wake: Vec<ActionLoader>,
|
||||||
|
pub sleep: Vec<ActionLoader>,
|
||||||
|
pub shutdown: Vec<ActionLoader>,
|
||||||
|
pub brightness: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AnimeConfigV460> for AnimeConfig {
|
||||||
|
fn from(c: AnimeConfigV460) -> AnimeConfig {
|
||||||
|
AnimeConfig {
|
||||||
|
system: c.system,
|
||||||
|
boot: c.boot,
|
||||||
|
wake: c.wake,
|
||||||
|
sleep: c.sleep,
|
||||||
shutdown: c.shutdown,
|
shutdown: c.shutdown,
|
||||||
brightness: 1.0,
|
brightness: 1.0,
|
||||||
awake_enabled: true,
|
awake_enabled: true,
|
||||||
@@ -73,6 +104,7 @@ pub struct AnimeConfigCached {
|
|||||||
pub system: Vec<ActionData>,
|
pub system: Vec<ActionData>,
|
||||||
pub boot: Vec<ActionData>,
|
pub boot: Vec<ActionData>,
|
||||||
pub wake: Vec<ActionData>,
|
pub wake: Vec<ActionData>,
|
||||||
|
pub sleep: Vec<ActionData>,
|
||||||
pub shutdown: Vec<ActionData>,
|
pub shutdown: Vec<ActionData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +132,12 @@ impl AnimeConfigCached {
|
|||||||
}
|
}
|
||||||
self.wake = wake;
|
self.wake = wake;
|
||||||
|
|
||||||
|
let mut sleep = Vec::with_capacity(config.sleep.len());
|
||||||
|
for ani in &config.sleep {
|
||||||
|
sleep.push(ActionData::from_anime_action(anime_type, ani)?);
|
||||||
|
}
|
||||||
|
self.sleep = sleep;
|
||||||
|
|
||||||
let mut shutdown = Vec::with_capacity(config.shutdown.len());
|
let mut shutdown = Vec::with_capacity(config.shutdown.len());
|
||||||
for ani in &config.shutdown {
|
for ani in &config.shutdown {
|
||||||
shutdown.push(ActionData::from_anime_action(anime_type, ani)?);
|
shutdown.push(ActionData::from_anime_action(anime_type, ani)?);
|
||||||
@@ -115,6 +153,7 @@ pub struct AnimeConfig {
|
|||||||
pub system: Vec<ActionLoader>,
|
pub system: Vec<ActionLoader>,
|
||||||
pub boot: Vec<ActionLoader>,
|
pub boot: Vec<ActionLoader>,
|
||||||
pub wake: Vec<ActionLoader>,
|
pub wake: Vec<ActionLoader>,
|
||||||
|
pub sleep: Vec<ActionLoader>,
|
||||||
pub shutdown: Vec<ActionLoader>,
|
pub shutdown: Vec<ActionLoader>,
|
||||||
pub brightness: f32,
|
pub brightness: f32,
|
||||||
pub awake_enabled: bool,
|
pub awake_enabled: bool,
|
||||||
@@ -127,6 +166,7 @@ impl Default for AnimeConfig {
|
|||||||
system: Vec::new(),
|
system: Vec::new(),
|
||||||
boot: Vec::new(),
|
boot: Vec::new(),
|
||||||
wake: Vec::new(),
|
wake: Vec::new(),
|
||||||
|
sleep: Vec::new(),
|
||||||
shutdown: Vec::new(),
|
shutdown: Vec::new(),
|
||||||
brightness: 1.0,
|
brightness: 1.0,
|
||||||
awake_enabled: true,
|
awake_enabled: true,
|
||||||
@@ -190,6 +230,14 @@ impl AnimeConfig {
|
|||||||
Duration::from_secs(2),
|
Duration::from_secs(2),
|
||||||
)),
|
)),
|
||||||
}],
|
}],
|
||||||
|
sleep: vec![ActionLoader::ImageAnimation {
|
||||||
|
file: "/usr/share/asusd/anime/custom/sonic-wait.gif".into(),
|
||||||
|
scale: 0.9,
|
||||||
|
angle: 0.0,
|
||||||
|
translation: Vec2::new(3.0, 2.0),
|
||||||
|
brightness: 1.0,
|
||||||
|
time: AnimTime::Infinite,
|
||||||
|
}],
|
||||||
shutdown: vec![ActionLoader::ImageAnimation {
|
shutdown: vec![ActionLoader::ImageAnimation {
|
||||||
file: "/usr/share/asusd/anime/custom/sonic-wait.gif".into(),
|
file: "/usr/share/asusd/anime/custom/sonic-wait.gif".into(),
|
||||||
scale: 0.9,
|
scale: 0.9,
|
||||||
|
|||||||
@@ -113,9 +113,8 @@ impl CtrlAnime {
|
|||||||
|
|
||||||
info!("AniMe no previous system thread running (now)");
|
info!("AniMe no previous system thread running (now)");
|
||||||
thread_exit.store(false, Ordering::SeqCst);
|
thread_exit.store(false, Ordering::SeqCst);
|
||||||
|
thread_running.store(true, Ordering::SeqCst);
|
||||||
'main: loop {
|
'main: loop {
|
||||||
thread_running.store(true, Ordering::SeqCst);
|
|
||||||
for action in &actions {
|
for action in &actions {
|
||||||
if thread_exit.load(Ordering::SeqCst) {
|
if thread_exit.load(Ordering::SeqCst) {
|
||||||
break 'main;
|
break 'main;
|
||||||
@@ -124,7 +123,7 @@ impl CtrlAnime {
|
|||||||
ActionData::Animation(frames) => {
|
ActionData::Animation(frames) => {
|
||||||
rog_anime::run_animation(frames, &|frame| {
|
rog_anime::run_animation(frames, &|frame| {
|
||||||
if thread_exit.load(Ordering::Acquire) {
|
if thread_exit.load(Ordering::Acquire) {
|
||||||
info!("rog-anime: frame-loop was asked to exit");
|
info!("rog-anime: animation sub-loop was asked to exit");
|
||||||
return Ok(true); // Do safe exit
|
return Ok(true); // Do safe exit
|
||||||
}
|
}
|
||||||
inner
|
inner
|
||||||
@@ -148,6 +147,10 @@ impl CtrlAnime {
|
|||||||
Ok,
|
Ok,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
if thread_exit.load(Ordering::Acquire) {
|
||||||
|
info!("rog-anime: sub-loop exited and main loop exiting now");
|
||||||
|
break 'main;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ActionData::Image(image) => {
|
ActionData::Image(image) => {
|
||||||
once = false;
|
once = false;
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use config_traits::StdConfig;
|
use config_traits::StdConfig;
|
||||||
use log::{info, warn};
|
use log::warn;
|
||||||
use rog_anime::usb::{pkt_for_apply, pkt_for_set_boot, pkt_for_set_on};
|
use rog_anime::usb::{pkt_for_apply, pkt_for_set_boot, pkt_for_set_on};
|
||||||
use rog_anime::{AnimeDataBuffer, AnimePowerStates};
|
use rog_anime::{AnimeDataBuffer, AnimePowerStates};
|
||||||
use zbus::export::futures_util::lock::{Mutex, MutexGuard};
|
use zbus::export::futures_util::lock::Mutex;
|
||||||
use zbus::{dbus_interface, Connection, SignalContext};
|
use zbus::{dbus_interface, Connection, SignalContext};
|
||||||
|
|
||||||
use super::CtrlAnime;
|
use super::CtrlAnime;
|
||||||
@@ -149,50 +149,41 @@ impl crate::CtrlTask for CtrlAnimeZbus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
|
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
|
||||||
let run_action =
|
|
||||||
|start: bool, lock: MutexGuard<'_, CtrlAnime>, inner: Arc<Mutex<CtrlAnime>>| {
|
|
||||||
if start {
|
|
||||||
info!("CtrlAnimeTask running sleep animation");
|
|
||||||
CtrlAnime::run_thread(inner, lock.cache.shutdown.clone(), true);
|
|
||||||
} else {
|
|
||||||
info!("CtrlAnimeTask running wake animation");
|
|
||||||
CtrlAnime::run_thread(inner, lock.cache.wake.clone(), true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let inner1 = self.0.clone();
|
let inner1 = self.0.clone();
|
||||||
let inner2 = self.0.clone();
|
let inner2 = self.0.clone();
|
||||||
let inner3 = self.0.clone();
|
let inner3 = self.0.clone();
|
||||||
let inner4 = self.0.clone();
|
let inner4 = self.0.clone();
|
||||||
self.create_sys_event_tasks(
|
self.create_sys_event_tasks(
|
||||||
// Loop is required to try an attempt to get the mutex *without* blocking
|
|
||||||
// other threads - it is possible to end up with deadlocks otherwise.
|
|
||||||
move || {
|
move || {
|
||||||
|
// on_sleep
|
||||||
let inner1 = inner1.clone();
|
let inner1 = inner1.clone();
|
||||||
async move {
|
async move {
|
||||||
let lock = inner1.lock().await;
|
let lock = inner1.lock().await;
|
||||||
run_action(true, lock, inner1.clone());
|
CtrlAnime::run_thread(inner1.clone(), lock.cache.sleep.clone(), true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move || {
|
move || {
|
||||||
|
// on_wake
|
||||||
let inner2 = inner2.clone();
|
let inner2 = inner2.clone();
|
||||||
async move {
|
async move {
|
||||||
let lock = inner2.lock().await;
|
let lock = inner2.lock().await;
|
||||||
run_action(true, lock, inner2.clone());
|
CtrlAnime::run_thread(inner2.clone(), lock.cache.wake.clone(), true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move || {
|
move || {
|
||||||
|
// on_shutdown
|
||||||
let inner3 = inner3.clone();
|
let inner3 = inner3.clone();
|
||||||
async move {
|
async move {
|
||||||
let lock = inner3.lock().await;
|
let lock = inner3.lock().await;
|
||||||
run_action(true, lock, inner3.clone());
|
CtrlAnime::run_thread(inner3.clone(), lock.cache.shutdown.clone(), true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move || {
|
move || {
|
||||||
|
// on_boot
|
||||||
let inner4 = inner4.clone();
|
let inner4 = inner4.clone();
|
||||||
async move {
|
async move {
|
||||||
let lock = inner4.lock().await;
|
let lock = inner4.lock().await;
|
||||||
run_action(true, lock, inner4.clone());
|
CtrlAnime::run_thread(inner4.clone(), lock.cache.boot.clone(), true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
use std::collections::{BTreeMap, HashSet};
|
use std::collections::{BTreeMap, HashSet};
|
||||||
|
|
||||||
use config_traits::{StdConfig, StdConfigLoad};
|
use config_traits::{StdConfig, StdConfigLoad};
|
||||||
use rog_aura::aura_detection::{LaptopLedData, ASUS_KEYBOARD_DEVICES};
|
use rog_aura::aura_detection::LaptopLedData;
|
||||||
use rog_aura::usb::{AuraDev1866, AuraDev19b6, AuraDevTuf, AuraDevice, AuraPowerDev};
|
use rog_aura::usb::{AuraDevRog1, AuraDevRog2, AuraDevTuf, AuraDevice, AuraPowerDev};
|
||||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Direction, LedBrightness, Speed, GRADIENT};
|
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Direction, LedBrightness, Speed, GRADIENT};
|
||||||
use rog_platform::hid_raw::HidRaw;
|
|
||||||
use rog_platform::keyboard_led::KeyboardLed;
|
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
const CONFIG_FILE: &str = "aura.ron";
|
const CONFIG_FILE: &str = "aura.ron";
|
||||||
@@ -16,8 +14,8 @@ const CONFIG_FILE: &str = "aura.ron";
|
|||||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub enum AuraPowerConfig {
|
pub enum AuraPowerConfig {
|
||||||
AuraDevTuf(HashSet<AuraDevTuf>),
|
AuraDevTuf(HashSet<AuraDevTuf>),
|
||||||
AuraDev1866(HashSet<AuraDev1866>),
|
AuraDevRog1(HashSet<AuraDevRog1>),
|
||||||
AuraDev19b6(HashSet<AuraDev19b6>),
|
AuraDevRog2(HashSet<AuraDevRog2>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AuraPowerConfig {
|
impl AuraPowerConfig {
|
||||||
@@ -25,13 +23,13 @@ impl AuraPowerConfig {
|
|||||||
pub fn to_bytes(control: &Self) -> [u8; 3] {
|
pub fn to_bytes(control: &Self) -> [u8; 3] {
|
||||||
match control {
|
match control {
|
||||||
AuraPowerConfig::AuraDevTuf(_) => [0, 0, 0],
|
AuraPowerConfig::AuraDevTuf(_) => [0, 0, 0],
|
||||||
AuraPowerConfig::AuraDev1866(c) => {
|
AuraPowerConfig::AuraDevRog1(c) => {
|
||||||
let c: Vec<AuraDev1866> = c.iter().copied().collect();
|
let c: Vec<AuraDevRog1> = c.iter().copied().collect();
|
||||||
AuraDev1866::to_bytes(&c)
|
AuraDevRog1::to_bytes(&c)
|
||||||
}
|
}
|
||||||
AuraPowerConfig::AuraDev19b6(c) => {
|
AuraPowerConfig::AuraDevRog2(c) => {
|
||||||
let c: Vec<AuraDev19b6> = c.iter().copied().collect();
|
let c: Vec<AuraDevRog2> = c.iter().copied().collect();
|
||||||
AuraDev19b6::to_bytes(&c)
|
AuraDevRog2::to_bytes(&c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,13 +45,13 @@ impl AuraPowerConfig {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Self::AuraDev1866(c) = control {
|
if let Self::AuraDevRog1(c) = control {
|
||||||
return Some([
|
return Some([
|
||||||
true,
|
true,
|
||||||
c.contains(&AuraDev1866::Boot),
|
c.contains(&AuraDevRog1::Boot),
|
||||||
c.contains(&AuraDev1866::Awake),
|
c.contains(&AuraDevRog1::Awake),
|
||||||
c.contains(&AuraDev1866::Sleep),
|
c.contains(&AuraDevRog1::Sleep),
|
||||||
c.contains(&AuraDev1866::Keyboard),
|
c.contains(&AuraDevRog1::Keyboard),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,8 +68,8 @@ impl AuraPowerConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_0x1866(&mut self, power: AuraDev1866, on: bool) {
|
pub fn set_0x1866(&mut self, power: AuraDevRog1, on: bool) {
|
||||||
if let Self::AuraDev1866(p) = self {
|
if let Self::AuraDevRog1(p) = self {
|
||||||
if on {
|
if on {
|
||||||
p.insert(power);
|
p.insert(power);
|
||||||
} else {
|
} else {
|
||||||
@@ -80,8 +78,8 @@ impl AuraPowerConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_0x19b6(&mut self, power: AuraDev19b6, on: bool) {
|
pub fn set_0x19b6(&mut self, power: AuraDevRog2, on: bool) {
|
||||||
if let Self::AuraDev19b6(p) = self {
|
if let Self::AuraDevRog2(p) = self {
|
||||||
if on {
|
if on {
|
||||||
p.insert(power);
|
p.insert(power);
|
||||||
} else {
|
} else {
|
||||||
@@ -99,12 +97,12 @@ impl From<&AuraPowerConfig> for AuraPowerDev {
|
|||||||
x1866: vec![],
|
x1866: vec![],
|
||||||
x19b6: vec![],
|
x19b6: vec![],
|
||||||
},
|
},
|
||||||
AuraPowerConfig::AuraDev1866(d) => AuraPowerDev {
|
AuraPowerConfig::AuraDevRog1(d) => AuraPowerDev {
|
||||||
tuf: vec![],
|
tuf: vec![],
|
||||||
x1866: d.iter().copied().collect(),
|
x1866: d.iter().copied().collect(),
|
||||||
x19b6: vec![],
|
x19b6: vec![],
|
||||||
},
|
},
|
||||||
AuraPowerConfig::AuraDev19b6(d) => AuraPowerDev {
|
AuraPowerConfig::AuraDevRog2(d) => AuraPowerDev {
|
||||||
tuf: vec![],
|
tuf: vec![],
|
||||||
x1866: vec![],
|
x1866: vec![],
|
||||||
x19b6: d.iter().copied().collect(),
|
x19b6: d.iter().copied().collect(),
|
||||||
@@ -113,7 +111,7 @@ impl From<&AuraPowerConfig> for AuraPowerDev {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug)]
|
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||||
// #[serde(default)]
|
// #[serde(default)]
|
||||||
pub struct AuraConfig {
|
pub struct AuraConfig {
|
||||||
pub brightness: LedBrightness,
|
pub brightness: LedBrightness,
|
||||||
@@ -124,70 +122,10 @@ pub struct AuraConfig {
|
|||||||
pub enabled: AuraPowerConfig,
|
pub enabled: AuraPowerConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AuraConfig {
|
|
||||||
fn default() -> Self {
|
|
||||||
let mut prod_id = AuraDevice::Unknown;
|
|
||||||
for prod in &ASUS_KEYBOARD_DEVICES {
|
|
||||||
if HidRaw::new(prod).is_ok() {
|
|
||||||
prod_id = AuraDevice::from(*prod);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if prod_id == AuraDevice::Unknown {
|
|
||||||
if let Ok(p) = KeyboardLed::new() {
|
|
||||||
if p.has_kbd_rgb_mode() {
|
|
||||||
prod_id = AuraDevice::Tuf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let enabled = if prod_id == AuraDevice::X19B6 {
|
|
||||||
AuraPowerConfig::AuraDev19b6(HashSet::from([
|
|
||||||
AuraDev19b6::BootLogo,
|
|
||||||
AuraDev19b6::BootKeyb,
|
|
||||||
AuraDev19b6::SleepLogo,
|
|
||||||
AuraDev19b6::SleepKeyb,
|
|
||||||
AuraDev19b6::AwakeLogo,
|
|
||||||
AuraDev19b6::AwakeKeyb,
|
|
||||||
AuraDev19b6::ShutdownLogo,
|
|
||||||
AuraDev19b6::ShutdownKeyb,
|
|
||||||
AuraDev19b6::BootBar,
|
|
||||||
AuraDev19b6::AwakeBar,
|
|
||||||
AuraDev19b6::SleepBar,
|
|
||||||
AuraDev19b6::ShutdownBar,
|
|
||||||
]))
|
|
||||||
} else if prod_id == AuraDevice::Tuf {
|
|
||||||
AuraPowerConfig::AuraDevTuf(HashSet::from([
|
|
||||||
AuraDevTuf::Awake,
|
|
||||||
AuraDevTuf::Boot,
|
|
||||||
AuraDevTuf::Sleep,
|
|
||||||
AuraDevTuf::Keyboard,
|
|
||||||
]))
|
|
||||||
} else {
|
|
||||||
AuraPowerConfig::AuraDev1866(HashSet::from([
|
|
||||||
AuraDev1866::Awake,
|
|
||||||
AuraDev1866::Boot,
|
|
||||||
AuraDev1866::Sleep,
|
|
||||||
AuraDev1866::Keyboard,
|
|
||||||
AuraDev1866::Lightbar,
|
|
||||||
]))
|
|
||||||
};
|
|
||||||
|
|
||||||
AuraConfig {
|
|
||||||
brightness: LedBrightness::Med,
|
|
||||||
current_mode: AuraModeNum::Static,
|
|
||||||
builtins: BTreeMap::new(),
|
|
||||||
multizone: None,
|
|
||||||
multizone_on: false,
|
|
||||||
enabled,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StdConfig for AuraConfig {
|
impl StdConfig for AuraConfig {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self::create_default(&LaptopLedData::get_data())
|
// Self::create_default(AuraDevice::X19b6, &LaptopLedData::get_data())
|
||||||
|
panic!("AuraConfig::new() should not be used, use AuraConfig::create_default() instead");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn config_dir() -> std::path::PathBuf {
|
fn config_dir() -> std::path::PathBuf {
|
||||||
@@ -202,9 +140,47 @@ impl StdConfig for AuraConfig {
|
|||||||
impl StdConfigLoad for AuraConfig {}
|
impl StdConfigLoad for AuraConfig {}
|
||||||
|
|
||||||
impl AuraConfig {
|
impl AuraConfig {
|
||||||
fn create_default(support_data: &LaptopLedData) -> Self {
|
pub fn create_default(prod_id: AuraDevice, support_data: &LaptopLedData) -> Self {
|
||||||
// create a default config here
|
// create a default config here
|
||||||
let mut config = AuraConfig::default();
|
let enabled = if prod_id == AuraDevice::X19b6 {
|
||||||
|
AuraPowerConfig::AuraDevRog2(HashSet::from([
|
||||||
|
AuraDevRog2::BootLogo,
|
||||||
|
AuraDevRog2::BootKeyb,
|
||||||
|
AuraDevRog2::SleepLogo,
|
||||||
|
AuraDevRog2::SleepKeyb,
|
||||||
|
AuraDevRog2::AwakeLogo,
|
||||||
|
AuraDevRog2::AwakeKeyb,
|
||||||
|
AuraDevRog2::ShutdownLogo,
|
||||||
|
AuraDevRog2::ShutdownKeyb,
|
||||||
|
AuraDevRog2::BootBar,
|
||||||
|
AuraDevRog2::AwakeBar,
|
||||||
|
AuraDevRog2::SleepBar,
|
||||||
|
AuraDevRog2::ShutdownBar,
|
||||||
|
]))
|
||||||
|
} else if prod_id == AuraDevice::Tuf {
|
||||||
|
AuraPowerConfig::AuraDevTuf(HashSet::from([
|
||||||
|
AuraDevTuf::Awake,
|
||||||
|
AuraDevTuf::Boot,
|
||||||
|
AuraDevTuf::Sleep,
|
||||||
|
AuraDevTuf::Keyboard,
|
||||||
|
]))
|
||||||
|
} else {
|
||||||
|
AuraPowerConfig::AuraDevRog1(HashSet::from([
|
||||||
|
AuraDevRog1::Awake,
|
||||||
|
AuraDevRog1::Boot,
|
||||||
|
AuraDevRog1::Sleep,
|
||||||
|
AuraDevRog1::Keyboard,
|
||||||
|
AuraDevRog1::Lightbar,
|
||||||
|
]))
|
||||||
|
};
|
||||||
|
let mut config = AuraConfig {
|
||||||
|
brightness: LedBrightness::Med,
|
||||||
|
current_mode: AuraModeNum::Static,
|
||||||
|
builtins: BTreeMap::new(),
|
||||||
|
multizone: None,
|
||||||
|
multizone_on: false,
|
||||||
|
enabled,
|
||||||
|
};
|
||||||
|
|
||||||
for n in &support_data.basic_modes {
|
for n in &support_data.basic_modes {
|
||||||
config
|
config
|
||||||
@@ -276,13 +252,15 @@ impl AuraConfig {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use rog_aura::aura_detection::LaptopLedData;
|
||||||
|
use rog_aura::usb::AuraDevice;
|
||||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour};
|
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour};
|
||||||
|
|
||||||
use super::AuraConfig;
|
use super::AuraConfig;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn set_multizone_4key_config() {
|
fn set_multizone_4key_config() {
|
||||||
let mut config = AuraConfig::default();
|
let mut config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
|
||||||
|
|
||||||
let effect = AuraEffect {
|
let effect = AuraEffect {
|
||||||
colour1: Colour(0xff, 0x00, 0xff),
|
colour1: Colour(0xff, 0x00, 0xff),
|
||||||
@@ -328,7 +306,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn set_multizone_multimode_config() {
|
fn set_multizone_multimode_config() {
|
||||||
let mut config = AuraConfig::default();
|
let mut config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
|
||||||
|
|
||||||
let effect = AuraEffect {
|
let effect = AuraEffect {
|
||||||
zone: AuraZone::Key1,
|
zone: AuraZone::Key1,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use config_traits::StdConfig;
|
use config_traits::{StdConfig, StdConfigLoad};
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
use rog_aura::advanced::{LedUsbPackets, UsbPackets};
|
use rog_aura::advanced::{LedUsbPackets, UsbPackets};
|
||||||
use rog_aura::aura_detection::{LaptopLedData, ASUS_KEYBOARD_DEVICES};
|
use rog_aura::aura_detection::{LaptopLedData, ASUS_KEYBOARD_DEVICES};
|
||||||
@@ -25,9 +25,9 @@ impl GetSupported for CtrlKbdLed {
|
|||||||
let advanced_type = laptop.advanced_type;
|
let advanced_type = laptop.advanced_type;
|
||||||
|
|
||||||
let mut prod_id = AuraDevice::Unknown;
|
let mut prod_id = AuraDevice::Unknown;
|
||||||
for prod in &ASUS_KEYBOARD_DEVICES {
|
for prod in ASUS_KEYBOARD_DEVICES {
|
||||||
if HidRaw::new(prod).is_ok() {
|
if HidRaw::new(prod.into()).is_ok() {
|
||||||
prod_id = AuraDevice::from(*prod);
|
prod_id = prod;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ pub enum LEDNode {
|
|||||||
|
|
||||||
pub struct CtrlKbdLed {
|
pub struct CtrlKbdLed {
|
||||||
// TODO: config stores the keyboard type as an AuraPower, use or update this
|
// TODO: config stores the keyboard type as an AuraPower, use or update this
|
||||||
pub led_prod: Option<String>,
|
pub led_prod: AuraDevice,
|
||||||
pub led_node: LEDNode,
|
pub led_node: LEDNode,
|
||||||
pub kd_brightness: KeyboardLed,
|
pub kd_brightness: KeyboardLed,
|
||||||
pub supported_modes: LaptopLedData,
|
pub supported_modes: LaptopLedData,
|
||||||
@@ -68,34 +68,43 @@ pub struct CtrlKbdLed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CtrlKbdLed {
|
impl CtrlKbdLed {
|
||||||
pub fn new(supported_modes: LaptopLedData, config: AuraConfig) -> Result<Self, RogError> {
|
pub fn new(supported_modes: LaptopLedData) -> Result<Self, RogError> {
|
||||||
let mut led_prod = None;
|
let mut led_prod = AuraDevice::Unknown;
|
||||||
let mut led_node = None;
|
let mut usb_node = None;
|
||||||
for prod in &ASUS_KEYBOARD_DEVICES {
|
for prod in ASUS_KEYBOARD_DEVICES {
|
||||||
match HidRaw::new(prod) {
|
match HidRaw::new(prod.into()) {
|
||||||
Ok(node) => {
|
Ok(node) => {
|
||||||
led_prod = Some((*prod).to_owned());
|
led_prod = prod;
|
||||||
led_node = Some(node);
|
usb_node = Some(node);
|
||||||
info!("Looked for keyboard controller 0x{prod}: Found");
|
info!(
|
||||||
|
"Looked for keyboard controller 0x{}: Found",
|
||||||
|
<&str>::from(prod)
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Err(err) => info!("Looked for keyboard controller 0x{prod}: {err}"),
|
Err(err) => info!(
|
||||||
|
"Looked for keyboard controller 0x{}: {err}",
|
||||||
|
<&str>::from(prod)
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let rgb_led = KeyboardLed::new()?;
|
let rgb_led = KeyboardLed::new()?;
|
||||||
|
|
||||||
if led_node.is_none() && !rgb_led.has_kbd_rgb_mode() {
|
if usb_node.is_none() && !rgb_led.has_kbd_rgb_mode() {
|
||||||
let dmi = sysfs_class::DmiId::default();
|
let dmi = sysfs_class::DmiId::default();
|
||||||
if let Ok(prod_family) = dmi.product_family() {
|
if let Ok(prod_family) = dmi.product_family() {
|
||||||
if prod_family.contains("TUF") {
|
if prod_family.contains("TUF") {
|
||||||
warn!("A kernel patch is in progress for TUF RGB support");
|
warn!(
|
||||||
|
"kbd_rgb_mode was not found in the /sys/. You require a minimum 6.1 \
|
||||||
|
kernel and a supported TUF laptop"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Err(RogError::NoAuraKeyboard);
|
return Err(RogError::NoAuraKeyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
let led_node = if let Some(rog) = led_node {
|
let led_node = if let Some(rog) = usb_node {
|
||||||
info!("Found ROG USB keyboard");
|
info!("Found ROG USB keyboard");
|
||||||
LEDNode::Rog(rog)
|
LEDNode::Rog(rog)
|
||||||
} else if rgb_led.has_kbd_rgb_mode() {
|
} else if rgb_led.has_kbd_rgb_mode() {
|
||||||
@@ -105,14 +114,44 @@ impl CtrlKbdLed {
|
|||||||
LEDNode::None
|
LEDNode::None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut config_init = AuraConfig::create_default(led_prod, &supported_modes);
|
||||||
|
let mut config_loaded = config_init.clone().load();
|
||||||
|
|
||||||
|
for mode in &mut config_init.builtins {
|
||||||
|
// update init values from loaded values if they exist
|
||||||
|
if let Some(loaded) = config_loaded.builtins.get(mode.0) {
|
||||||
|
*mode.1 = loaded.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config_loaded.builtins = config_init.builtins;
|
||||||
|
|
||||||
|
if let (Some(mut multizone_init), Some(multizone_loaded)) =
|
||||||
|
(config_init.multizone, config_loaded.multizone.as_mut())
|
||||||
|
{
|
||||||
|
for mode in multizone_init.iter_mut() {
|
||||||
|
// update init values from loaded values if they exist
|
||||||
|
if let Some(loaded) = multizone_loaded.get(mode.0) {
|
||||||
|
let mut new_set = Vec::new();
|
||||||
|
// only reuse a zone mode if the mode is supported
|
||||||
|
for mode in loaded {
|
||||||
|
if supported_modes.basic_modes.contains(&mode.mode) {
|
||||||
|
new_set.push(mode.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*mode.1 = new_set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*multizone_loaded = multizone_init;
|
||||||
|
}
|
||||||
|
|
||||||
let ctrl = CtrlKbdLed {
|
let ctrl = CtrlKbdLed {
|
||||||
led_prod,
|
led_prod,
|
||||||
led_node,
|
led_node, // on TUF this is the same as rgb_led / kd_brightness
|
||||||
kd_brightness: rgb_led, // If was none then we already returned above
|
kd_brightness: rgb_led, // If was none then we already returned above
|
||||||
supported_modes,
|
supported_modes,
|
||||||
flip_effect_write: false,
|
flip_effect_write: false,
|
||||||
per_key_mode_active: false,
|
per_key_mode_active: false,
|
||||||
config,
|
config: config_loaded,
|
||||||
};
|
};
|
||||||
Ok(ctrl)
|
Ok(ctrl)
|
||||||
}
|
}
|
||||||
@@ -356,6 +395,7 @@ impl CtrlKbdLed {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use rog_aura::aura_detection::LaptopLedData;
|
use rog_aura::aura_detection::LaptopLedData;
|
||||||
|
use rog_aura::usb::AuraDevice;
|
||||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour};
|
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour};
|
||||||
use rog_platform::keyboard_led::KeyboardLed;
|
use rog_platform::keyboard_led::KeyboardLed;
|
||||||
|
|
||||||
@@ -367,7 +407,7 @@ mod tests {
|
|||||||
// #[ignore = "Must be manually run due to detection stage"]
|
// #[ignore = "Must be manually run due to detection stage"]
|
||||||
fn check_set_mode_errors() {
|
fn check_set_mode_errors() {
|
||||||
// Checking to ensure set_mode errors when unsupported modes are tried
|
// Checking to ensure set_mode errors when unsupported modes are tried
|
||||||
let config = AuraConfig::default();
|
let config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
|
||||||
let supported_modes = LaptopLedData {
|
let supported_modes = LaptopLedData {
|
||||||
board_name: String::new(),
|
board_name: String::new(),
|
||||||
layout_name: "ga401".to_owned(),
|
layout_name: "ga401".to_owned(),
|
||||||
@@ -376,7 +416,7 @@ mod tests {
|
|||||||
advanced_type: rog_aura::AdvancedAuraType::None,
|
advanced_type: rog_aura::AdvancedAuraType::None,
|
||||||
};
|
};
|
||||||
let mut controller = CtrlKbdLed {
|
let mut controller = CtrlKbdLed {
|
||||||
led_prod: None,
|
led_prod: AuraDevice::X19b6,
|
||||||
led_node: LEDNode::None,
|
led_node: LEDNode::None,
|
||||||
kd_brightness: KeyboardLed::default(),
|
kd_brightness: KeyboardLed::default(),
|
||||||
supported_modes,
|
supported_modes,
|
||||||
@@ -430,7 +470,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn create_multizone_if_no_config() {
|
fn create_multizone_if_no_config() {
|
||||||
// Checking to ensure set_mode errors when unsupported modes are tried
|
// Checking to ensure set_mode errors when unsupported modes are tried
|
||||||
let config = AuraConfig::default();
|
let config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
|
||||||
let supported_modes = LaptopLedData {
|
let supported_modes = LaptopLedData {
|
||||||
board_name: String::new(),
|
board_name: String::new(),
|
||||||
layout_name: "ga401".to_owned(),
|
layout_name: "ga401".to_owned(),
|
||||||
@@ -439,7 +479,7 @@ mod tests {
|
|||||||
advanced_type: rog_aura::AdvancedAuraType::None,
|
advanced_type: rog_aura::AdvancedAuraType::None,
|
||||||
};
|
};
|
||||||
let mut controller = CtrlKbdLed {
|
let mut controller = CtrlKbdLed {
|
||||||
led_prod: None,
|
led_prod: AuraDevice::X19b6,
|
||||||
led_node: LEDNode::None,
|
led_node: LEDNode::None,
|
||||||
kd_brightness: KeyboardLed::default(),
|
kd_brightness: KeyboardLed::default(),
|
||||||
supported_modes,
|
supported_modes,
|
||||||
@@ -468,7 +508,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn next_mode_create_multizone_if_no_config() {
|
fn next_mode_create_multizone_if_no_config() {
|
||||||
// Checking to ensure set_mode errors when unsupported modes are tried
|
// Checking to ensure set_mode errors when unsupported modes are tried
|
||||||
let config = AuraConfig::default();
|
let config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
|
||||||
let supported_modes = LaptopLedData {
|
let supported_modes = LaptopLedData {
|
||||||
board_name: String::new(),
|
board_name: String::new(),
|
||||||
layout_name: "ga401".to_owned(),
|
layout_name: "ga401".to_owned(),
|
||||||
@@ -477,7 +517,7 @@ mod tests {
|
|||||||
advanced_type: rog_aura::AdvancedAuraType::None,
|
advanced_type: rog_aura::AdvancedAuraType::None,
|
||||||
};
|
};
|
||||||
let mut controller = CtrlKbdLed {
|
let mut controller = CtrlKbdLed {
|
||||||
led_prod: None,
|
led_prod: AuraDevice::X19b6,
|
||||||
led_node: LEDNode::None,
|
led_node: LEDNode::None,
|
||||||
kd_brightness: KeyboardLed::default(),
|
kd_brightness: KeyboardLed::default(),
|
||||||
supported_modes,
|
supported_modes,
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ use daemon::config::Config;
|
|||||||
use daemon::ctrl_anime::config::AnimeConfig;
|
use daemon::ctrl_anime::config::AnimeConfig;
|
||||||
use daemon::ctrl_anime::trait_impls::CtrlAnimeZbus;
|
use daemon::ctrl_anime::trait_impls::CtrlAnimeZbus;
|
||||||
use daemon::ctrl_anime::CtrlAnime;
|
use daemon::ctrl_anime::CtrlAnime;
|
||||||
use daemon::ctrl_aura::config::AuraConfig;
|
|
||||||
use daemon::ctrl_aura::controller::CtrlKbdLed;
|
use daemon::ctrl_aura::controller::CtrlKbdLed;
|
||||||
use daemon::ctrl_aura::trait_impls::CtrlKbdLedZbus;
|
use daemon::ctrl_aura::trait_impls::CtrlKbdLedZbus;
|
||||||
use daemon::ctrl_platform::CtrlPlatform;
|
use daemon::ctrl_platform::CtrlPlatform;
|
||||||
@@ -124,8 +123,9 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let laptop = LaptopLedData::get_data();
|
let laptop = LaptopLedData::get_data();
|
||||||
let aura_config = AuraConfig::new().load();
|
// CtrlKbdLed deviates from the config pattern above due to requiring a keyboard
|
||||||
match CtrlKbdLed::new(laptop, aura_config) {
|
// detection first
|
||||||
|
match CtrlKbdLed::new(laptop) {
|
||||||
Ok(ctrl) => {
|
Ok(ctrl) => {
|
||||||
let zbus = CtrlKbdLedZbus(Arc::new(Mutex::new(ctrl)));
|
let zbus = CtrlKbdLedZbus(Arc::new(Mutex::new(ctrl)));
|
||||||
let sig_ctx = CtrlKbdLedZbus::signal_context(&connection)?;
|
let sig_ctx = CtrlKbdLedZbus::signal_context(&connection)?;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ zbus = { workspace = true, optional = true }
|
|||||||
|
|
||||||
sysfs-class = { workspace = true, optional = true }
|
sysfs-class = { workspace = true, optional = true }
|
||||||
|
|
||||||
uhid-virt = "^0.0.5"
|
uhid-virt = "^0.0.6"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
cargo-husky.workspace = true
|
cargo-husky.workspace = true
|
||||||
@@ -212,7 +212,7 @@ pub fn run_animation(frames: &AnimeGif, callback: &dyn Fn(AnimeDataBuffer) -> Re
|
|||||||
|
|
||||||
// TODO: Log this error
|
// TODO: Log this error
|
||||||
if matches!(callback(output), Ok(true)) {
|
if matches!(callback(output), Ok(true)) {
|
||||||
info!("rog-anime: frame-loop callback asked to exit early");
|
info!("rog-anime: animation frame-loop callback asked to exit early");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,20 @@
|
|||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: None,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
board_name: "FX506LH",
|
||||||
|
layout_name: "fa506i",
|
||||||
|
basic_modes: [Static, Breathe, Strobe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
board_name: "FX516P",
|
||||||
|
layout_name: "fa506i",
|
||||||
|
basic_modes: [Static, Breathe, Strobe],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
),
|
||||||
(
|
(
|
||||||
board_name: "G512",
|
board_name: "G512",
|
||||||
layout_name: "g512",
|
layout_name: "g512",
|
||||||
@@ -293,6 +307,13 @@
|
|||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: PerKey,
|
advanced_type: PerKey,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
board_name: "G733Z",
|
||||||
|
layout_name: "g513i-per-key",
|
||||||
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: PerKey,
|
||||||
|
),
|
||||||
(
|
(
|
||||||
board_name: "GA401Q",
|
board_name: "GA401Q",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
@@ -405,6 +426,13 @@
|
|||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: Zoned([SingleZone]),
|
advanced_type: Zoned([SingleZone]),
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
board_name: "GU604V",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: Zoned([SingleZone]),
|
||||||
|
),
|
||||||
(
|
(
|
||||||
board_name: "GV301Q",
|
board_name: "GV301Q",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
@@ -412,6 +440,20 @@
|
|||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: None,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
board_name: "GV301V",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
board_name: "GV301VIC",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
),
|
||||||
(
|
(
|
||||||
board_name: "GV601R",
|
board_name: "GV601R",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
@@ -419,6 +461,13 @@
|
|||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: None,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
board_name: "GV604V",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Strobe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
),
|
||||||
(
|
(
|
||||||
board_name: "GX502",
|
board_name: "GX502",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
@@ -447,6 +496,13 @@
|
|||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: PerKey,
|
advanced_type: PerKey,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
board_name: "GX650P",
|
||||||
|
layout_name: "gx531-per-key",
|
||||||
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: PerKey,
|
||||||
|
),
|
||||||
(
|
(
|
||||||
board_name: "GX701",
|
board_name: "GX701",
|
||||||
layout_name: "gx531-per-key",
|
layout_name: "gx531-per-key",
|
||||||
@@ -461,4 +517,18 @@
|
|||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: None,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
board_name: "GZ301V",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
board_name: "GZ301VIC",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
),
|
||||||
])
|
])
|
||||||
@@ -1,11 +1,20 @@
|
|||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::usb::AuraDevice;
|
||||||
use crate::{AdvancedAuraType, AuraModeNum, AuraZone};
|
use crate::{AdvancedAuraType, AuraModeNum, AuraZone};
|
||||||
|
|
||||||
pub const ASUS_LED_MODE_CONF: &str = "/usr/share/asusd/aura_support.ron";
|
pub const ASUS_LED_MODE_CONF: &str = "/usr/share/asusd/aura_support.ron";
|
||||||
pub const ASUS_LED_MODE_USER_CONF: &str = "/etc/asusd/asusd_user_ledmodes.ron";
|
pub const ASUS_LED_MODE_USER_CONF: &str = "/etc/asusd/asusd_user_ledmodes.ron";
|
||||||
pub const ASUS_KEYBOARD_DEVICES: [&str; 4] = ["1866", "1869", "1854", "19b6"];
|
pub const ASUS_KEYBOARD_DEVICES: [AuraDevice; 7] = [
|
||||||
|
AuraDevice::Tuf,
|
||||||
|
AuraDevice::X1854,
|
||||||
|
AuraDevice::X1869,
|
||||||
|
AuraDevice::X1866,
|
||||||
|
AuraDevice::X18c6,
|
||||||
|
AuraDevice::X19b6,
|
||||||
|
AuraDevice::X1a30,
|
||||||
|
];
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub struct LedSupportFile(Vec<LaptopLedData>);
|
pub struct LedSupportFile(Vec<LaptopLedData>);
|
||||||
|
|||||||
@@ -280,7 +280,13 @@ impl KeyLayout {
|
|||||||
/// Find a layout matching the name in `LaptopLedData` in the provided dir
|
/// Find a layout matching the name in `LaptopLedData` in the provided dir
|
||||||
pub fn find_layout(led_data: LaptopLedData, mut data_path: PathBuf) -> Result<Self, Error> {
|
pub fn find_layout(led_data: LaptopLedData, mut data_path: PathBuf) -> Result<Self, Error> {
|
||||||
// TODO: locales
|
// TODO: locales
|
||||||
let layout_file = format!("{}_US.ron", led_data.layout_name);
|
let layout_name = if led_data.layout_name.is_empty() {
|
||||||
|
"ga401q".to_owned() // Need some sort of default here due to ROGCC
|
||||||
|
// expecting it
|
||||||
|
} else {
|
||||||
|
led_data.layout_name
|
||||||
|
};
|
||||||
|
let layout_file = format!("{layout_name}_US.ron");
|
||||||
data_path.push("layouts");
|
data_path.push("layouts");
|
||||||
data_path.push(layout_file);
|
data_path.push(layout_file);
|
||||||
let path = data_path.as_path();
|
let path = data_path.as_path();
|
||||||
|
|||||||
+131
-110
@@ -23,25 +23,44 @@ pub const fn aura_brightness_bytes(brightness: u8) -> [u8; 17] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Serialize, Deserialize, Default)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Serialize, Deserialize, Default)]
|
||||||
pub enum AuraDevice {
|
pub enum AuraDevice {
|
||||||
Tuf,
|
Tuf,
|
||||||
X1854,
|
X1854,
|
||||||
X1869,
|
X1869,
|
||||||
X1866,
|
X1866,
|
||||||
|
X18c6,
|
||||||
#[default]
|
#[default]
|
||||||
X19B6,
|
X19b6,
|
||||||
|
X1a30,
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<AuraDevice> for &str {
|
||||||
|
fn from(a: AuraDevice) -> Self {
|
||||||
|
match a {
|
||||||
|
AuraDevice::Tuf => "tuf",
|
||||||
|
AuraDevice::X1854 => "1854",
|
||||||
|
AuraDevice::X1869 => "1869",
|
||||||
|
AuraDevice::X1866 => "1866",
|
||||||
|
AuraDevice::X18c6 => "18c6",
|
||||||
|
AuraDevice::X19b6 => "19b6",
|
||||||
|
AuraDevice::X1a30 => "1a30",
|
||||||
|
AuraDevice::Unknown => "unknown",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<&str> for AuraDevice {
|
impl From<&str> for AuraDevice {
|
||||||
fn from(s: &str) -> Self {
|
fn from(s: &str) -> Self {
|
||||||
match s.to_lowercase().as_str() {
|
match s.to_lowercase().as_str() {
|
||||||
"tuf" => AuraDevice::Tuf,
|
"tuf" => AuraDevice::Tuf,
|
||||||
"1866" | "0x1866" => AuraDevice::X1866,
|
"1866" | "0x1866" => AuraDevice::X1866,
|
||||||
|
"18c6" | "0x18c6" => AuraDevice::X18c6,
|
||||||
"1869" | "0x1869" => AuraDevice::X1869,
|
"1869" | "0x1869" => AuraDevice::X1869,
|
||||||
"1854" | "0x1854" => AuraDevice::X1854,
|
"1854" | "0x1854" => AuraDevice::X1854,
|
||||||
"19b6" | "0x19b6" => AuraDevice::X19B6,
|
"19b6" | "0x19b6" => AuraDevice::X19b6,
|
||||||
|
"1a30" | "0x1a30" => AuraDevice::X1a30,
|
||||||
_ => AuraDevice::Unknown,
|
_ => AuraDevice::Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,7 +73,9 @@ impl Debug for AuraDevice {
|
|||||||
Self::X1854 => write!(f, "0x1854"),
|
Self::X1854 => write!(f, "0x1854"),
|
||||||
Self::X1869 => write!(f, "0x1869"),
|
Self::X1869 => write!(f, "0x1869"),
|
||||||
Self::X1866 => write!(f, "0x1866"),
|
Self::X1866 => write!(f, "0x1866"),
|
||||||
Self::X19B6 => write!(f, "0x19B6"),
|
Self::X18c6 => write!(f, "0x18c6"),
|
||||||
|
Self::X19b6 => write!(f, "0x19B6"),
|
||||||
|
Self::X1a30 => write!(f, "0x1A30"),
|
||||||
Self::Unknown => write!(f, "Unknown"),
|
Self::Unknown => write!(f, "Unknown"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,8 +86,8 @@ impl Debug for AuraDevice {
|
|||||||
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
|
||||||
pub struct AuraPowerDev {
|
pub struct AuraPowerDev {
|
||||||
pub tuf: Vec<AuraDevTuf>,
|
pub tuf: Vec<AuraDevTuf>,
|
||||||
pub x1866: Vec<AuraDev1866>,
|
pub x1866: Vec<AuraDevRog1>,
|
||||||
pub x19b6: Vec<AuraDev19b6>,
|
pub x19b6: Vec<AuraDevRog2>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||||
@@ -85,7 +106,7 @@ impl AuraDevTuf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Bits for older 0x1866 keyboard model
|
/// # Bits for older 0x1866, 0x1869, 0x1854 keyboard models
|
||||||
///
|
///
|
||||||
/// Keybord and Lightbar require Awake, Boot and Sleep apply to both
|
/// Keybord and Lightbar require Awake, Boot and Sleep apply to both
|
||||||
/// Keybord and Lightbar regardless of if either are enabled (or Awake is
|
/// Keybord and Lightbar regardless of if either are enabled (or Awake is
|
||||||
@@ -102,7 +123,7 @@ impl AuraDevTuf {
|
|||||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum AuraDev1866 {
|
pub enum AuraDevRog1 {
|
||||||
Awake = 0x000002,
|
Awake = 0x000002,
|
||||||
Keyboard = 0x080000,
|
Keyboard = 0x080000,
|
||||||
Lightbar = 0x040500,
|
Lightbar = 0x040500,
|
||||||
@@ -110,13 +131,13 @@ pub enum AuraDev1866 {
|
|||||||
Sleep = 0x300804,
|
Sleep = 0x300804,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<AuraDev1866> for u32 {
|
impl From<AuraDevRog1> for u32 {
|
||||||
fn from(a: AuraDev1866) -> Self {
|
fn from(a: AuraDevRog1) -> Self {
|
||||||
a as u32
|
a as u32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AuraDev1866 {
|
impl AuraDevRog1 {
|
||||||
pub fn to_bytes(control: &[Self]) -> [u8; 3] {
|
pub fn to_bytes(control: &[Self]) -> [u8; 3] {
|
||||||
let mut a: u32 = 0;
|
let mut a: u32 = 0;
|
||||||
for n in control {
|
for n in control {
|
||||||
@@ -134,23 +155,23 @@ impl AuraDev1866 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitOr<AuraDev1866> for AuraDev1866 {
|
impl BitOr<AuraDevRog1> for AuraDevRog1 {
|
||||||
type Output = u32;
|
type Output = u32;
|
||||||
|
|
||||||
fn bitor(self, rhs: AuraDev1866) -> Self::Output {
|
fn bitor(self, rhs: AuraDevRog1) -> Self::Output {
|
||||||
self as u32 | rhs as u32
|
self as u32 | rhs as u32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitAnd<AuraDev1866> for AuraDev1866 {
|
impl BitAnd<AuraDevRog1> for AuraDevRog1 {
|
||||||
type Output = u32;
|
type Output = u32;
|
||||||
|
|
||||||
fn bitand(self, rhs: AuraDev1866) -> Self::Output {
|
fn bitand(self, rhs: AuraDevRog1) -> Self::Output {
|
||||||
self as u32 & rhs as u32
|
self as u32 & rhs as u32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Bits for 0x19b6 keyboard model
|
/// # Bits for newer 0x18c6, 0x19B6, 0x1a30, keyboard models
|
||||||
///
|
///
|
||||||
/// byte 4 in the USB packet is for keyboard + logo power states
|
/// byte 4 in the USB packet is for keyboard + logo power states
|
||||||
/// default is on, `ff`
|
/// default is on, `ff`
|
||||||
@@ -179,7 +200,7 @@ impl BitAnd<AuraDev1866> for AuraDev1866 {
|
|||||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum AuraDev19b6 {
|
pub enum AuraDevRog2 {
|
||||||
BootLogo = 1,
|
BootLogo = 1,
|
||||||
BootKeyb = 1 << 1,
|
BootKeyb = 1 << 1,
|
||||||
AwakeLogo = 1 << 2,
|
AwakeLogo = 1 << 2,
|
||||||
@@ -198,13 +219,13 @@ pub enum AuraDev19b6 {
|
|||||||
ShutdownLid = 1 << (15 + 4),
|
ShutdownLid = 1 << (15 + 4),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<AuraDev19b6> for u32 {
|
impl From<AuraDevRog2> for u32 {
|
||||||
fn from(a: AuraDev19b6) -> Self {
|
fn from(a: AuraDevRog2) -> Self {
|
||||||
a as u32
|
a as u32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AuraDev19b6 {
|
impl AuraDevRog2 {
|
||||||
pub fn to_bytes(control: &[Self]) -> [u8; 3] {
|
pub fn to_bytes(control: &[Self]) -> [u8; 3] {
|
||||||
let mut a: u32 = 0;
|
let mut a: u32 = 0;
|
||||||
for n in control {
|
for n in control {
|
||||||
@@ -222,58 +243,58 @@ impl AuraDev19b6 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitOr<AuraDev19b6> for AuraDev19b6 {
|
impl BitOr<AuraDevRog2> for AuraDevRog2 {
|
||||||
type Output = u16;
|
type Output = u16;
|
||||||
|
|
||||||
fn bitor(self, rhs: AuraDev19b6) -> Self::Output {
|
fn bitor(self, rhs: AuraDevRog2) -> Self::Output {
|
||||||
self as u16 | rhs as u16
|
self as u16 | rhs as u16
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitAnd<AuraDev19b6> for AuraDev19b6 {
|
impl BitAnd<AuraDevRog2> for AuraDevRog2 {
|
||||||
type Output = u16;
|
type Output = u16;
|
||||||
|
|
||||||
fn bitand(self, rhs: AuraDev19b6) -> Self::Output {
|
fn bitand(self, rhs: AuraDevRog2) -> Self::Output {
|
||||||
self as u16 & rhs as u16
|
self as u16 & rhs as u16
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::AuraDev1866;
|
use super::AuraDevRog1;
|
||||||
use crate::usb::AuraDev19b6;
|
use crate::usb::AuraDevRog2;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_0x1866_control_bytes() {
|
fn check_0x1866_control_bytes() {
|
||||||
let bytes = [AuraDev1866::Keyboard, AuraDev1866::Awake];
|
let bytes = [AuraDevRog1::Keyboard, AuraDevRog1::Awake];
|
||||||
let bytes = AuraDev1866::to_bytes(&bytes);
|
let bytes = AuraDevRog1::to_bytes(&bytes);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes, [0x08, 0x00, 0x02]);
|
assert_eq!(bytes, [0x08, 0x00, 0x02]);
|
||||||
|
|
||||||
let bytes = [AuraDev1866::Lightbar, AuraDev1866::Awake];
|
let bytes = [AuraDevRog1::Lightbar, AuraDevRog1::Awake];
|
||||||
let bytes = AuraDev1866::to_bytes(&bytes);
|
let bytes = AuraDevRog1::to_bytes(&bytes);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes, [0x04, 0x05, 0x02]);
|
assert_eq!(bytes, [0x04, 0x05, 0x02]);
|
||||||
|
|
||||||
let bytes = [AuraDev1866::Sleep];
|
let bytes = [AuraDevRog1::Sleep];
|
||||||
let bytes = AuraDev1866::to_bytes(&bytes);
|
let bytes = AuraDevRog1::to_bytes(&bytes);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes, [0x30, 0x08, 0x04]);
|
assert_eq!(bytes, [0x30, 0x08, 0x04]);
|
||||||
|
|
||||||
let bytes = [AuraDev1866::Boot];
|
let bytes = [AuraDevRog1::Boot];
|
||||||
let bytes = AuraDev1866::to_bytes(&bytes);
|
let bytes = AuraDevRog1::to_bytes(&bytes);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes, [0xc3, 0x12, 0x09]);
|
assert_eq!(bytes, [0xc3, 0x12, 0x09]);
|
||||||
|
|
||||||
let bytes = [
|
let bytes = [
|
||||||
AuraDev1866::Keyboard,
|
AuraDevRog1::Keyboard,
|
||||||
AuraDev1866::Lightbar,
|
AuraDevRog1::Lightbar,
|
||||||
AuraDev1866::Awake,
|
AuraDevRog1::Awake,
|
||||||
AuraDev1866::Sleep,
|
AuraDevRog1::Sleep,
|
||||||
AuraDev1866::Boot,
|
AuraDevRog1::Boot,
|
||||||
];
|
];
|
||||||
|
|
||||||
let bytes = AuraDev1866::to_bytes(&bytes);
|
let bytes = AuraDevRog1::to_bytes(&bytes);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes, [0xff, 0x1f, 0x000f]);
|
assert_eq!(bytes, [0xff, 0x1f, 0x000f]);
|
||||||
}
|
}
|
||||||
@@ -282,143 +303,143 @@ mod tests {
|
|||||||
fn check_0x19b6_control_bytes() {
|
fn check_0x19b6_control_bytes() {
|
||||||
// All on
|
// All on
|
||||||
let byte1 = [
|
let byte1 = [
|
||||||
AuraDev19b6::BootLogo,
|
AuraDevRog2::BootLogo,
|
||||||
AuraDev19b6::BootKeyb,
|
AuraDevRog2::BootKeyb,
|
||||||
AuraDev19b6::SleepLogo,
|
AuraDevRog2::SleepLogo,
|
||||||
AuraDev19b6::SleepKeyb,
|
AuraDevRog2::SleepKeyb,
|
||||||
AuraDev19b6::AwakeLogo,
|
AuraDevRog2::AwakeLogo,
|
||||||
AuraDev19b6::AwakeKeyb,
|
AuraDevRog2::AwakeKeyb,
|
||||||
AuraDev19b6::ShutdownLogo,
|
AuraDevRog2::ShutdownLogo,
|
||||||
AuraDev19b6::ShutdownKeyb,
|
AuraDevRog2::ShutdownKeyb,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte1);
|
let bytes = AuraDevRog2::to_bytes(&byte1);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes[0], 0xff);
|
assert_eq!(bytes[0], 0xff);
|
||||||
|
|
||||||
//
|
//
|
||||||
let byte1 = [
|
let byte1 = [
|
||||||
// AuraControl::BootLogo,
|
// AuraControl::BootLogo,
|
||||||
AuraDev19b6::BootKeyb,
|
AuraDevRog2::BootKeyb,
|
||||||
AuraDev19b6::SleepLogo,
|
AuraDevRog2::SleepLogo,
|
||||||
AuraDev19b6::SleepKeyb,
|
AuraDevRog2::SleepKeyb,
|
||||||
AuraDev19b6::AwakeLogo,
|
AuraDevRog2::AwakeLogo,
|
||||||
AuraDev19b6::AwakeKeyb,
|
AuraDevRog2::AwakeKeyb,
|
||||||
AuraDev19b6::ShutdownLogo,
|
AuraDevRog2::ShutdownLogo,
|
||||||
AuraDev19b6::ShutdownKeyb,
|
AuraDevRog2::ShutdownKeyb,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte1);
|
let bytes = AuraDevRog2::to_bytes(&byte1);
|
||||||
println!("{:08b}", bytes[0]);
|
println!("{:08b}", bytes[0]);
|
||||||
assert_eq!(bytes[0], 0xfe);
|
assert_eq!(bytes[0], 0xfe);
|
||||||
|
|
||||||
let byte1 = [
|
let byte1 = [
|
||||||
AuraDev19b6::BootLogo,
|
AuraDevRog2::BootLogo,
|
||||||
// AuraControl::BootKeyb,
|
// AuraControl::BootKeyb,
|
||||||
AuraDev19b6::SleepLogo,
|
AuraDevRog2::SleepLogo,
|
||||||
AuraDev19b6::SleepKeyb,
|
AuraDevRog2::SleepKeyb,
|
||||||
AuraDev19b6::AwakeLogo,
|
AuraDevRog2::AwakeLogo,
|
||||||
AuraDev19b6::AwakeKeyb,
|
AuraDevRog2::AwakeKeyb,
|
||||||
AuraDev19b6::ShutdownLogo,
|
AuraDevRog2::ShutdownLogo,
|
||||||
AuraDev19b6::ShutdownKeyb,
|
AuraDevRog2::ShutdownKeyb,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte1);
|
let bytes = AuraDevRog2::to_bytes(&byte1);
|
||||||
println!("{:08b}", bytes[0]);
|
println!("{:08b}", bytes[0]);
|
||||||
assert_eq!(bytes[0], 0xfd);
|
assert_eq!(bytes[0], 0xfd);
|
||||||
|
|
||||||
let byte1 = [
|
let byte1 = [
|
||||||
AuraDev19b6::BootLogo,
|
AuraDevRog2::BootLogo,
|
||||||
AuraDev19b6::BootKeyb,
|
AuraDevRog2::BootKeyb,
|
||||||
// AuraControl::SleepLogo,
|
// AuraControl::SleepLogo,
|
||||||
AuraDev19b6::SleepKeyb,
|
AuraDevRog2::SleepKeyb,
|
||||||
AuraDev19b6::AwakeLogo,
|
AuraDevRog2::AwakeLogo,
|
||||||
AuraDev19b6::AwakeKeyb,
|
AuraDevRog2::AwakeKeyb,
|
||||||
AuraDev19b6::ShutdownLogo,
|
AuraDevRog2::ShutdownLogo,
|
||||||
AuraDev19b6::ShutdownKeyb,
|
AuraDevRog2::ShutdownKeyb,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte1);
|
let bytes = AuraDevRog2::to_bytes(&byte1);
|
||||||
println!("{:08b}", bytes[0]);
|
println!("{:08b}", bytes[0]);
|
||||||
assert_eq!(bytes[0], 0xef);
|
assert_eq!(bytes[0], 0xef);
|
||||||
|
|
||||||
let byte1 = [
|
let byte1 = [
|
||||||
AuraDev19b6::BootLogo,
|
AuraDevRog2::BootLogo,
|
||||||
AuraDev19b6::BootKeyb,
|
AuraDevRog2::BootKeyb,
|
||||||
AuraDev19b6::SleepLogo,
|
AuraDevRog2::SleepLogo,
|
||||||
// AuraControl::SleepKeyb,
|
// AuraControl::SleepKeyb,
|
||||||
AuraDev19b6::AwakeLogo,
|
AuraDevRog2::AwakeLogo,
|
||||||
AuraDev19b6::AwakeKeyb,
|
AuraDevRog2::AwakeKeyb,
|
||||||
AuraDev19b6::ShutdownLogo,
|
AuraDevRog2::ShutdownLogo,
|
||||||
AuraDev19b6::ShutdownKeyb,
|
AuraDevRog2::ShutdownKeyb,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte1);
|
let bytes = AuraDevRog2::to_bytes(&byte1);
|
||||||
println!("{:08b}", bytes[0]);
|
println!("{:08b}", bytes[0]);
|
||||||
assert_eq!(bytes[0], 0xdf);
|
assert_eq!(bytes[0], 0xdf);
|
||||||
|
|
||||||
let byte2 = [
|
let byte2 = [
|
||||||
AuraDev19b6::BootBar,
|
AuraDevRog2::BootBar,
|
||||||
AuraDev19b6::AwakeBar,
|
AuraDevRog2::AwakeBar,
|
||||||
AuraDev19b6::SleepBar,
|
AuraDevRog2::SleepBar,
|
||||||
AuraDev19b6::ShutdownBar,
|
AuraDevRog2::ShutdownBar,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte2);
|
let bytes = AuraDevRog2::to_bytes(&byte2);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes[1], 0x1e);
|
assert_eq!(bytes[1], 0x1e);
|
||||||
|
|
||||||
let byte2 = [
|
let byte2 = [
|
||||||
AuraDev19b6::BootBar,
|
AuraDevRog2::BootBar,
|
||||||
AuraDev19b6::AwakeBar,
|
AuraDevRog2::AwakeBar,
|
||||||
// AuraControl::SleepBar,
|
// AuraControl::SleepBar,
|
||||||
AuraDev19b6::ShutdownBar,
|
AuraDevRog2::ShutdownBar,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte2);
|
let bytes = AuraDevRog2::to_bytes(&byte2);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes[1], 0x16);
|
assert_eq!(bytes[1], 0x16);
|
||||||
|
|
||||||
let byte3 = [
|
let byte3 = [
|
||||||
AuraDev19b6::AwakeLid,
|
AuraDevRog2::AwakeLid,
|
||||||
AuraDev19b6::BootLid,
|
AuraDevRog2::BootLid,
|
||||||
AuraDev19b6::SleepLid,
|
AuraDevRog2::SleepLid,
|
||||||
AuraDev19b6::ShutdownLid,
|
AuraDevRog2::ShutdownLid,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte3);
|
let bytes = AuraDevRog2::to_bytes(&byte3);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes[2], 0x0f);
|
assert_eq!(bytes[2], 0x0f);
|
||||||
|
|
||||||
let byte3 = [
|
let byte3 = [
|
||||||
// AuraDev19b6::AwakeLid,
|
// AuraDev19b6::AwakeLid,
|
||||||
AuraDev19b6::BootLid,
|
AuraDevRog2::BootLid,
|
||||||
AuraDev19b6::SleepLid,
|
AuraDevRog2::SleepLid,
|
||||||
AuraDev19b6::ShutdownLid,
|
AuraDevRog2::ShutdownLid,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte3);
|
let bytes = AuraDevRog2::to_bytes(&byte3);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes[2], 0x0d);
|
assert_eq!(bytes[2], 0x0d);
|
||||||
|
|
||||||
let byte3 = [
|
let byte3 = [
|
||||||
AuraDev19b6::AwakeLid,
|
AuraDevRog2::AwakeLid,
|
||||||
AuraDev19b6::BootLid,
|
AuraDevRog2::BootLid,
|
||||||
// AuraControl::SleepLid,
|
// AuraControl::SleepLid,
|
||||||
AuraDev19b6::ShutdownLid,
|
AuraDevRog2::ShutdownLid,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte3);
|
let bytes = AuraDevRog2::to_bytes(&byte3);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes[2], 0x0b);
|
assert_eq!(bytes[2], 0x0b);
|
||||||
|
|
||||||
let byte3 = [
|
let byte3 = [
|
||||||
AuraDev19b6::AwakeLid,
|
AuraDevRog2::AwakeLid,
|
||||||
AuraDev19b6::BootLid,
|
AuraDevRog2::BootLid,
|
||||||
AuraDev19b6::SleepLid,
|
AuraDevRog2::SleepLid,
|
||||||
// AuraDev19b6::ShutdownLid,
|
// AuraDev19b6::ShutdownLid,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte3);
|
let bytes = AuraDevRog2::to_bytes(&byte3);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes[2], 0x07);
|
assert_eq!(bytes[2], 0x07);
|
||||||
|
|
||||||
let byte3 = [
|
let byte3 = [
|
||||||
AuraDev19b6::AwakeLid,
|
AuraDevRog2::AwakeLid,
|
||||||
// AuraDev19b6::BootLid,
|
// AuraDev19b6::BootLid,
|
||||||
AuraDev19b6::SleepLid,
|
AuraDevRog2::SleepLid,
|
||||||
// AuraDev19b6::ShutdownLid,
|
// AuraDev19b6::ShutdownLid,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte3);
|
let bytes = AuraDevRog2::to_bytes(&byte3);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes[2], 0x06);
|
assert_eq!(bytes[2], 0x06);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,13 @@ edition = "2021"
|
|||||||
mocking = []
|
mocking = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
egui = { git = "https://github.com/flukejones/egui", branch = "wayland_dark_theme" }
|
egui = { git = "https://github.com/emilk/egui", rev = "b8e798777de519de3a1878798097ab2ab0bd4def"}
|
||||||
eframe = { git = "https://github.com/flukejones/egui", branch = "wayland_dark_theme" }
|
eframe = { git = "https://github.com/emilk/egui", rev = "b8e798777de519de3a1878798097ab2ab0bd4def"}
|
||||||
|
# egui = { path = "../../egui/crates/egui" }
|
||||||
|
# eframe = { path = "../../egui/crates/eframe" }
|
||||||
|
|
||||||
libappindicator = "0.7" # Tray icon
|
libappindicator = "0.8" # Tray icon
|
||||||
gtk = "0.15.5"
|
gtk = "0.16"
|
||||||
|
|
||||||
daemon = { path = "../daemon" }
|
daemon = { path = "../daemon" }
|
||||||
rog_anime = { path = "../rog-anime" }
|
rog_anime = { path = "../rog-anime" }
|
||||||
@@ -39,8 +41,14 @@ notify-rust.workspace = true
|
|||||||
|
|
||||||
png_pong.workspace = true
|
png_pong.workspace = true
|
||||||
|
|
||||||
|
versions.workspace = true
|
||||||
|
|
||||||
nix = "^0.26.1"
|
nix = "^0.26.1"
|
||||||
tempfile = "3.3.0"
|
tempfile = "3.3.0"
|
||||||
|
|
||||||
|
# [patch.crates-io]
|
||||||
|
# egui = { git = "https://github.com/flukejones/egui" }
|
||||||
|
# eframe = { git = "https://github.com/flukejones/egui" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
cargo-husky.workspace = true
|
cargo-husky.workspace = true
|
||||||
@@ -17,6 +17,7 @@ pub struct Config {
|
|||||||
pub ac_command: String,
|
pub ac_command: String,
|
||||||
pub bat_command: String,
|
pub bat_command: String,
|
||||||
pub enable_notifications: bool,
|
pub enable_notifications: bool,
|
||||||
|
pub dark_mode: bool,
|
||||||
// This field must be last
|
// This field must be last
|
||||||
pub enabled_notifications: EnabledNotifications,
|
pub enabled_notifications: EnabledNotifications,
|
||||||
}
|
}
|
||||||
@@ -27,6 +28,7 @@ impl Default for Config {
|
|||||||
run_in_background: true,
|
run_in_background: true,
|
||||||
startup_in_background: false,
|
startup_in_background: false,
|
||||||
enable_notifications: true,
|
enable_notifications: true,
|
||||||
|
dark_mode: true,
|
||||||
enabled_notifications: EnabledNotifications::default(),
|
enabled_notifications: EnabledNotifications::default(),
|
||||||
ac_command: String::new(),
|
ac_command: String::new(),
|
||||||
bat_command: String::new(),
|
bat_command: String::new(),
|
||||||
@@ -72,6 +74,9 @@ impl Config {
|
|||||||
} else if let Ok(data) = toml::from_str::<Config>(&buf) {
|
} else if let Ok(data) = toml::from_str::<Config>(&buf) {
|
||||||
info!("Loaded config file {path:?}");
|
info!("Loaded config file {path:?}");
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
|
} else if let Ok(data) = toml::from_str::<Config460>(&buf) {
|
||||||
|
info!("Loaded old v4.6.0 config file {path:?}");
|
||||||
|
return Ok(data.into());
|
||||||
} else if let Ok(data) = toml::from_str::<Config455>(&buf) {
|
} else if let Ok(data) = toml::from_str::<Config455>(&buf) {
|
||||||
info!("Loaded old v4.5.5 config file {path:?}");
|
info!("Loaded old v4.5.5 config file {path:?}");
|
||||||
return Ok(data.into());
|
return Ok(data.into());
|
||||||
@@ -124,8 +129,33 @@ impl From<Config455> for Config {
|
|||||||
startup_in_background: c.startup_in_background,
|
startup_in_background: c.startup_in_background,
|
||||||
enable_notifications: c.enable_notifications,
|
enable_notifications: c.enable_notifications,
|
||||||
enabled_notifications: c.enabled_notifications,
|
enabled_notifications: c.enabled_notifications,
|
||||||
|
dark_mode: true,
|
||||||
ac_command: String::new(),
|
ac_command: String::new(),
|
||||||
bat_command: String::new(),
|
bat_command: String::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
pub struct Config460 {
|
||||||
|
pub run_in_background: bool,
|
||||||
|
pub startup_in_background: bool,
|
||||||
|
pub ac_command: String,
|
||||||
|
pub bat_command: String,
|
||||||
|
pub enable_notifications: bool,
|
||||||
|
pub enabled_notifications: EnabledNotifications,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Config460> for Config {
|
||||||
|
fn from(c: Config460) -> Self {
|
||||||
|
Self {
|
||||||
|
run_in_background: c.run_in_background,
|
||||||
|
startup_in_background: c.startup_in_background,
|
||||||
|
ac_command: c.ac_command,
|
||||||
|
bat_command: c.bat_command,
|
||||||
|
dark_mode: true,
|
||||||
|
enable_notifications: c.enable_notifications,
|
||||||
|
enabled_notifications: c.enabled_notifications,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ pub enum Error {
|
|||||||
XdgVars,
|
XdgVars,
|
||||||
Zbus(zbus::Error),
|
Zbus(zbus::Error),
|
||||||
Notification(notify_rust::error::Error),
|
Notification(notify_rust::error::Error),
|
||||||
|
Eframe(eframe::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
@@ -24,6 +25,7 @@ impl fmt::Display for Error {
|
|||||||
Error::XdgVars => write!(f, "XDG environment vars appear unset"),
|
Error::XdgVars => write!(f, "XDG environment vars appear unset"),
|
||||||
Error::Zbus(err) => write!(f, "Error: {}", err),
|
Error::Zbus(err) => write!(f, "Error: {}", err),
|
||||||
Error::Notification(err) => write!(f, "Notification Error: {}", err),
|
Error::Notification(err) => write!(f, "Notification Error: {}", err),
|
||||||
|
Error::Eframe(err) => write!(f, "Eframe Error: {}", err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,3 +55,9 @@ impl From<notify_rust::error::Error> for Error {
|
|||||||
Error::Notification(err)
|
Error::Notification(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<eframe::Error> for Error {
|
||||||
|
fn from(err: eframe::Error) -> Self {
|
||||||
|
Error::Eframe(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -105,6 +105,6 @@ pub fn get_ipc_file() -> Result<File, crate::error::Error> {
|
|||||||
Ok(OpenOptions::new()
|
Ok(OpenOptions::new()
|
||||||
.read(true)
|
.read(true)
|
||||||
.write(true)
|
.write(true)
|
||||||
.truncate(true)
|
// .truncate(true)
|
||||||
.open(&fifo_path)?)
|
.open(&fifo_path)?)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
use std::env::args;
|
use std::env::args;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::thread;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use eframe::{IconData, NativeOptions};
|
use eframe::IconData;
|
||||||
use gumdrop::Options;
|
use gumdrop::Options;
|
||||||
use log::{error, info, warn};
|
use log::{debug, error, info, warn, LevelFilter};
|
||||||
use rog_aura::aura_detection::{LaptopLedData, LedSupportFile};
|
use rog_aura::aura_detection::{LaptopLedData, LedSupportFile};
|
||||||
use rog_aura::layouts::KeyLayout;
|
use rog_aura::layouts::KeyLayout;
|
||||||
use rog_control_center::cli_options::CliStart;
|
use rog_control_center::cli_options::CliStart;
|
||||||
@@ -45,6 +48,7 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
let mut logger = env_logger::Builder::new();
|
let mut logger = env_logger::Builder::new();
|
||||||
logger
|
logger
|
||||||
|
.filter_level(LevelFilter::Warn)
|
||||||
.parse_default_env()
|
.parse_default_env()
|
||||||
.target(env_logger::Target::Stdout)
|
.target(env_logger::Target::Stdout)
|
||||||
.format(|buf, record| writeln!(buf, "{}: {}", record.level(), record.args()))
|
.format(|buf, record| writeln!(buf, "{}: {}", record.level(), record.args()))
|
||||||
@@ -72,7 +76,9 @@ fn main() -> Result<()> {
|
|||||||
"ROG Control Center",
|
"ROG Control Center",
|
||||||
native_options.clone(),
|
native_options.clone(),
|
||||||
Box::new(move |_| Box::new(AppErrorShow::new(e.to_string()))),
|
Box::new(move |_| Box::new(AppErrorShow::new(e.to_string()))),
|
||||||
);
|
)
|
||||||
|
.map_err(|e| error!("{e}"))
|
||||||
|
.ok();
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -83,14 +89,16 @@ fn main() -> Result<()> {
|
|||||||
"ROG Control Center",
|
"ROG Control Center",
|
||||||
native_options.clone(),
|
native_options.clone(),
|
||||||
Box::new(move |_| Box::new(AppErrorShow::new(e.to_string()))),
|
Box::new(move |_| Box::new(AppErrorShow::new(e.to_string()))),
|
||||||
);
|
)
|
||||||
|
.map_err(|e| error!("{e}"))
|
||||||
|
.ok();
|
||||||
SupportedFunctions::default()
|
SupportedFunctions::default()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Startup
|
// Startup
|
||||||
let mut config = Config::load()?;
|
let mut config = Config::load()?;
|
||||||
let mut start_closed = config.startup_in_background;
|
let running_in_bg = Arc::new(AtomicBool::new(config.startup_in_background));
|
||||||
|
|
||||||
if config.startup_in_background {
|
if config.startup_in_background {
|
||||||
config.run_in_background = true;
|
config.run_in_background = true;
|
||||||
@@ -183,26 +191,48 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
init_tray(supported, states.clone());
|
init_tray(supported, states.clone());
|
||||||
|
|
||||||
|
let mut bg_check_spawned = false;
|
||||||
loop {
|
loop {
|
||||||
if !start_closed {
|
if !running_in_bg.load(Ordering::Relaxed) {
|
||||||
start_app(states.clone(), native_options.clone())?;
|
// blocks until window is closed
|
||||||
|
let states = states.clone();
|
||||||
|
let mut ipc_file = get_ipc_file()?;
|
||||||
|
ipc_file.write_all(&[SHOWING_GUI])?;
|
||||||
|
eframe::run_native(
|
||||||
|
"ROG Control Center",
|
||||||
|
native_options.clone(),
|
||||||
|
Box::new(move |cc| {
|
||||||
|
Box::new(RogApp::new(Config::load().unwrap(), states, cc).unwrap())
|
||||||
|
}),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
running_in_bg.store(true, Ordering::SeqCst);
|
||||||
|
bg_check_spawned = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let config = Config::load()?;
|
|
||||||
if !config.run_in_background || cli_parsed.board_name.is_some() || cli_parsed.layout_viewing
|
if !config.run_in_background || cli_parsed.board_name.is_some() || cli_parsed.layout_viewing
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.run_in_background {
|
if config.run_in_background && running_in_bg.load(Ordering::Acquire) && !bg_check_spawned {
|
||||||
let mut buf = [0u8; 4];
|
let running_in_bg = running_in_bg.clone();
|
||||||
// blocks until it is read, typically the read will happen after a second
|
thread::spawn(move || {
|
||||||
// process writes to the IPC (so there is data to actually read)
|
let mut buf = [0u8; 4];
|
||||||
if get_ipc_file()?.read(&mut buf).is_ok() && buf[0] == SHOW_GUI {
|
// blocks until it is read, typically the read will happen after a second
|
||||||
start_closed = false;
|
// process writes to the IPC (so there is data to actually read)
|
||||||
continue;
|
loop {
|
||||||
}
|
if get_ipc_file().unwrap().read(&mut buf).is_ok() && buf[0] == SHOW_GUI {
|
||||||
|
running_in_bg.store(false, Ordering::Release);
|
||||||
|
debug!("Wait thread got from tray {buf:#?}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
bg_check_spawned = true;
|
||||||
}
|
}
|
||||||
|
// Prevent hogging CPU
|
||||||
|
thread::sleep(Duration::from_millis(500));
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop {
|
// loop {
|
||||||
@@ -233,17 +263,6 @@ fn setup_page_state_and_notifs(
|
|||||||
Ok(page_states)
|
Ok(page_states)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_app(states: Arc<Mutex<SystemState>>, native_options: NativeOptions) -> Result<()> {
|
|
||||||
let mut ipc_file = get_ipc_file()?;
|
|
||||||
ipc_file.write_all(&[SHOWING_GUI])?;
|
|
||||||
eframe::run_native(
|
|
||||||
"ROG Control Center",
|
|
||||||
native_options,
|
|
||||||
Box::new(move |cc| Box::new(RogApp::new(Config::load().unwrap(), states, cc).unwrap())),
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Bah.. the icon dosn't work on wayland anyway, but we'll leave it in for now.
|
/// Bah.. the icon dosn't work on wayland anyway, but we'll leave it in for now.
|
||||||
fn load_icon() -> IconData {
|
fn load_icon() -> IconData {
|
||||||
let path = PathBuf::from(APP_ICON_PATH);
|
let path = PathBuf::from(APP_ICON_PATH);
|
||||||
|
|||||||
+94
-131
@@ -2,7 +2,6 @@
|
|||||||
//! commands over an MPSC channel.
|
//! commands over an MPSC channel.
|
||||||
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
|
||||||
use std::sync::mpsc::{channel, Receiver};
|
use std::sync::mpsc::{channel, Receiver};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@@ -14,8 +13,10 @@ use log::{debug, error, info, trace, warn};
|
|||||||
use rog_dbus::zbus_platform::RogBiosProxyBlocking;
|
use rog_dbus::zbus_platform::RogBiosProxyBlocking;
|
||||||
use rog_platform::platform::GpuMode;
|
use rog_platform::platform::GpuMode;
|
||||||
use rog_platform::supported::SupportedFunctions;
|
use rog_platform::supported::SupportedFunctions;
|
||||||
|
use supergfxctl::actions::UserActionRequired as GfxUserActionRequired;
|
||||||
use supergfxctl::pci_device::{GfxMode, GfxPower};
|
use supergfxctl::pci_device::{GfxMode, GfxPower};
|
||||||
use supergfxctl::zbus_proxy::DaemonProxyBlocking as GfxProxyBlocking;
|
use supergfxctl::zbus_proxy::DaemonProxyBlocking as GfxProxyBlocking;
|
||||||
|
use versions::Versioning;
|
||||||
|
|
||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
use crate::system_state::SystemState;
|
use crate::system_state::SystemState;
|
||||||
@@ -79,6 +80,8 @@ pub struct ROGTray {
|
|||||||
menu: gtk::Menu,
|
menu: gtk::Menu,
|
||||||
icon: &'static str,
|
icon: &'static str,
|
||||||
bios_proxy: RogBiosProxyBlocking<'static>,
|
bios_proxy: RogBiosProxyBlocking<'static>,
|
||||||
|
gfx_proxy_is_active: bool,
|
||||||
|
gfx_action: Arc<Mutex<GfxUserActionRequired>>,
|
||||||
gfx_proxy: GfxProxyBlocking<'static>,
|
gfx_proxy: GfxProxyBlocking<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,6 +91,12 @@ impl ROGTray {
|
|||||||
error!("ROGTray: {e}");
|
error!("ROGTray: {e}");
|
||||||
e
|
e
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
let gfx_proxy = GfxProxyBlocking::new(&conn).map_err(|e| {
|
||||||
|
error!("ROGTray: {e}");
|
||||||
|
e
|
||||||
|
})?;
|
||||||
|
|
||||||
let rog_tray = Self {
|
let rog_tray = Self {
|
||||||
tray: AppIndicator::new(TRAY_LABEL, TRAY_APP_ICON),
|
tray: AppIndicator::new(TRAY_LABEL, TRAY_APP_ICON),
|
||||||
menu: gtk::Menu::new(),
|
menu: gtk::Menu::new(),
|
||||||
@@ -96,10 +105,9 @@ impl ROGTray {
|
|||||||
error!("ROGTray: {e}");
|
error!("ROGTray: {e}");
|
||||||
e
|
e
|
||||||
})?,
|
})?,
|
||||||
gfx_proxy: GfxProxyBlocking::new(&conn).map_err(|e| {
|
gfx_proxy_is_active: gfx_proxy.mode().is_ok(),
|
||||||
error!("ROGTray: {e}");
|
gfx_action: Arc::new(Mutex::new(GfxUserActionRequired::Nothing)),
|
||||||
e
|
gfx_proxy,
|
||||||
})?,
|
|
||||||
};
|
};
|
||||||
Ok(rog_tray)
|
Ok(rog_tray)
|
||||||
}
|
}
|
||||||
@@ -208,6 +216,7 @@ impl ROGTray {
|
|||||||
if let Ok(mut ipc) = get_ipc_file().map_err(|e| {
|
if let Ok(mut ipc) = get_ipc_file().map_err(|e| {
|
||||||
error!("ROGTray: get_ipc_file: {}", e);
|
error!("ROGTray: get_ipc_file: {}", e);
|
||||||
}) {
|
}) {
|
||||||
|
debug!("Tray told app to show self");
|
||||||
ipc.write_all(&[SHOW_GUI]).ok();
|
ipc.write_all(&[SHOW_GUI]).ok();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -238,133 +247,64 @@ impl ROGTray {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn menu_add_gpu(&mut self, supported: &SupportedFunctions, current_mode: GfxMode) {
|
fn menu_add_supergfx(&mut self, supported_gfx: &[GfxMode], current_mode: GfxMode) {
|
||||||
let set_mux_off = Arc::new(AtomicBool::new(false));
|
if !self.gfx_proxy_is_active {
|
||||||
|
trace!("menu_add_supergfx: gfx_proxy_is_active is false");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let gfx_dbus = self.gfx_proxy.clone();
|
let gfx_dbus = self.gfx_proxy.clone();
|
||||||
let set_mux_off1 = set_mux_off.clone();
|
let gfx_action = self.gfx_action.clone();
|
||||||
let mut gpu_menu = RadioGroup::new("Integrated", move |_| {
|
let mut gpu_menu = RadioGroup::new("Integrated", move |_| {
|
||||||
let mode = gfx_dbus
|
if current_mode != GfxMode::Integrated {
|
||||||
.mode()
|
if let Ok(res) = gfx_dbus.set_mode(&GfxMode::Integrated).map_err(|e| {
|
||||||
.map_err(|e| {
|
error!("ROGTray: srt_mode: {e}");
|
||||||
error!("ROGTray: mode: {e}");
|
|
||||||
e
|
e
|
||||||
})
|
}) {
|
||||||
.unwrap_or(GfxMode::None);
|
if let Ok(mut lock) = gfx_action.lock() {
|
||||||
if mode != GfxMode::Integrated {
|
*lock = res;
|
||||||
gfx_dbus
|
}
|
||||||
.set_mode(&GfxMode::Integrated)
|
}
|
||||||
.map_err(|e| {
|
|
||||||
error!("ROGTray: srt_mode: {e}");
|
|
||||||
e
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
set_mux_off1.store(true, Ordering::Relaxed);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let gfx_dbus = self.gfx_proxy.clone();
|
let mut func = |menu_mode: GfxMode| {
|
||||||
let set_mux_off1 = set_mux_off.clone();
|
|
||||||
gpu_menu.add("Hybrid", move |_| {
|
|
||||||
let mode = gfx_dbus
|
|
||||||
.mode()
|
|
||||||
.map_err(|e| {
|
|
||||||
error!("ROGTray: mode: {e}");
|
|
||||||
e
|
|
||||||
})
|
|
||||||
.unwrap_or(GfxMode::None);
|
|
||||||
if mode != GfxMode::Hybrid {
|
|
||||||
gfx_dbus
|
|
||||||
.set_mode(&GfxMode::Hybrid)
|
|
||||||
.map_err(|e| {
|
|
||||||
error!("ROGTray: set_mode: {e}");
|
|
||||||
e
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
set_mux_off1.store(true, Ordering::Relaxed);
|
|
||||||
});
|
|
||||||
if supported.rog_bios_ctrl.egpu_enable {
|
|
||||||
let set_mux_off1 = set_mux_off.clone();
|
|
||||||
let gfx_dbus = self.gfx_proxy.clone();
|
let gfx_dbus = self.gfx_proxy.clone();
|
||||||
gpu_menu.add("eGPU", move |_| {
|
let gfx_action = self.gfx_action.clone();
|
||||||
let mode = gfx_dbus
|
gpu_menu.add(&format!("{menu_mode}"), move |_| {
|
||||||
.mode()
|
if current_mode != menu_mode {
|
||||||
.map_err(|e| {
|
if let Ok(res) = gfx_dbus.set_mode(&menu_mode).map_err(|e| {
|
||||||
error!("ROGTray: mode: {e}");
|
|
||||||
e
|
|
||||||
})
|
|
||||||
.unwrap_or(GfxMode::None);
|
|
||||||
if mode != GfxMode::Egpu {
|
|
||||||
gfx_dbus
|
|
||||||
.set_mode(&GfxMode::Egpu)
|
|
||||||
.map_err(|e| {
|
|
||||||
error!("ROGTray: set_mode: {e}");
|
|
||||||
e
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
set_mux_off1.store(true, Ordering::Relaxed);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut reboot_required = false;
|
|
||||||
if supported.rog_bios_ctrl.gpu_mux {
|
|
||||||
let gfx_dbus = self.bios_proxy.clone();
|
|
||||||
gpu_menu.add("Ultimate (Reboot required)", move |_| {
|
|
||||||
let mode = gfx_dbus
|
|
||||||
.gpu_mux_mode()
|
|
||||||
.map_err(|e| {
|
|
||||||
error!("ROGTray: mode: {e}");
|
|
||||||
e
|
|
||||||
})
|
|
||||||
.unwrap_or(GpuMode::Error);
|
|
||||||
if mode != GpuMode::Discrete {
|
|
||||||
gfx_dbus
|
|
||||||
.set_gpu_mux_mode(GpuMode::Discrete)
|
|
||||||
.map_err(|e| {
|
|
||||||
error!("ROGTray: set_mode: {e}");
|
|
||||||
e
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if set_mux_off.load(Ordering::Relaxed) {
|
|
||||||
warn!("Selected non-dgpu mode, must set MUX to optimus");
|
|
||||||
self.bios_proxy
|
|
||||||
.set_gpu_mux_mode(GpuMode::Optimus)
|
|
||||||
.map_err(|e| {
|
|
||||||
error!("ROGTray: set_mode: {e}");
|
error!("ROGTray: set_mode: {e}");
|
||||||
e
|
e
|
||||||
})
|
}) {
|
||||||
.ok();
|
if let Ok(mut lock) = gfx_action.lock() {
|
||||||
}
|
*lock = res;
|
||||||
|
}
|
||||||
if let Ok(mode) = self.bios_proxy.gpu_mux_mode() {
|
}
|
||||||
// TODO: this is not taking in to account supergfxctl
|
}
|
||||||
let mode = match mode {
|
});
|
||||||
GpuMode::Discrete => GfxMode::AsusMuxDiscreet,
|
|
||||||
_ => GfxMode::Hybrid,
|
|
||||||
};
|
|
||||||
reboot_required = mode != current_mode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let active = match current_mode {
|
|
||||||
GfxMode::AsusMuxDiscreet => "Discreet".to_owned(),
|
|
||||||
_ => current_mode.to_string(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let reboot_required = if reboot_required {
|
for item in supported_gfx {
|
||||||
"(Reboot required)"
|
if *item == GfxMode::Integrated {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
func(*item);
|
||||||
|
}
|
||||||
|
|
||||||
|
let action_required = if let Ok(lock) = self.gfx_action.lock() {
|
||||||
|
if matches!(*lock, GfxUserActionRequired::Nothing) {
|
||||||
|
""
|
||||||
|
} else {
|
||||||
|
<&str>::from(*lock)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
|
|
||||||
self.add_radio_sub_menu(
|
self.add_radio_sub_menu(
|
||||||
&format!("GPU Mode: {active} {reboot_required}"),
|
&format!("GPU Mode: {current_mode} {action_required}"),
|
||||||
active.as_str(),
|
¤t_mode.to_string(),
|
||||||
&gpu_menu,
|
&gpu_menu,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -377,7 +317,7 @@ impl ROGTray {
|
|||||||
let mut reboot_required = false;
|
let mut reboot_required = false;
|
||||||
if let Ok(mode) = gfx_dbus.gpu_mux_mode() {
|
if let Ok(mode) = gfx_dbus.gpu_mux_mode() {
|
||||||
let mode = match mode {
|
let mode = match mode {
|
||||||
GpuMode::Discrete => GfxMode::AsusMuxDiscreet,
|
GpuMode::Discrete => GfxMode::AsusMuxDgpu,
|
||||||
_ => GfxMode::Hybrid,
|
_ => GfxMode::Hybrid,
|
||||||
};
|
};
|
||||||
reboot_required = mode != current_mode;
|
reboot_required = mode != current_mode;
|
||||||
@@ -407,7 +347,7 @@ impl ROGTray {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let active = match current_mode {
|
let active = match current_mode {
|
||||||
GfxMode::AsusMuxDiscreet => "Ultimate".to_owned(),
|
GfxMode::AsusMuxDgpu => "Ultimate".to_owned(),
|
||||||
GfxMode::Hybrid => "Optimus".to_owned(),
|
GfxMode::Hybrid => "Optimus".to_owned(),
|
||||||
_ => current_mode.to_string(),
|
_ => current_mode.to_string(),
|
||||||
};
|
};
|
||||||
@@ -442,7 +382,7 @@ impl ROGTray {
|
|||||||
fn rebuild_and_update(
|
fn rebuild_and_update(
|
||||||
&mut self,
|
&mut self,
|
||||||
supported: &SupportedFunctions,
|
supported: &SupportedFunctions,
|
||||||
has_supergfx: bool,
|
supported_gfx: &[GfxMode],
|
||||||
current_gfx_mode: GfxMode,
|
current_gfx_mode: GfxMode,
|
||||||
charge_limit: u8,
|
charge_limit: u8,
|
||||||
panel_od: bool,
|
panel_od: bool,
|
||||||
@@ -451,8 +391,9 @@ impl ROGTray {
|
|||||||
self.menu_add_base();
|
self.menu_add_base();
|
||||||
self.menu_add_charge_limit(supported, charge_limit);
|
self.menu_add_charge_limit(supported, charge_limit);
|
||||||
self.menu_add_panel_od(supported, panel_od);
|
self.menu_add_panel_od(supported, panel_od);
|
||||||
if has_supergfx {
|
if self.gfx_proxy_is_active {
|
||||||
self.menu_add_gpu(supported, current_gfx_mode);
|
// Add a supergfxctl specific menu
|
||||||
|
self.menu_add_supergfx(supported_gfx, current_gfx_mode);
|
||||||
} else if supported.rog_bios_ctrl.gpu_mux {
|
} else if supported.rog_bios_ctrl.gpu_mux {
|
||||||
self.menu_add_mux(current_gfx_mode);
|
self.menu_add_mux(current_gfx_mode);
|
||||||
}
|
}
|
||||||
@@ -467,12 +408,6 @@ pub fn init_tray(
|
|||||||
let (send, recv) = channel();
|
let (send, recv) = channel();
|
||||||
let _send = Arc::new(Mutex::new(send));
|
let _send = Arc::new(Mutex::new(send));
|
||||||
|
|
||||||
let has_supergfx = if let Ok(lock) = states.try_lock() {
|
|
||||||
lock.gfx_state.has_supergfx
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let gtk_init = gtk::init().map_err(|e| {
|
let gtk_init = gtk::init().map_err(|e| {
|
||||||
error!("ROGTray: gtk init {e}");
|
error!("ROGTray: gtk init {e}");
|
||||||
@@ -496,7 +431,29 @@ pub fn init_tray(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
tray.rebuild_and_update(&supported, has_supergfx, GfxMode::Hybrid, 100, false);
|
|
||||||
|
let supported_gfx = if tray.gfx_proxy_is_active {
|
||||||
|
if let Ok(version) = tray.gfx_proxy.version() {
|
||||||
|
if let Some(version) = Versioning::new(&version) {
|
||||||
|
let curr_gfx = Versioning::new("5.0.3-RC4").unwrap();
|
||||||
|
warn!("supergfxd version = {version}");
|
||||||
|
if version < curr_gfx {
|
||||||
|
// Don't allow mode changing if too old a version
|
||||||
|
warn!("supergfxd found but is too old to use");
|
||||||
|
tray.gfx_proxy_is_active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if tray.gfx_proxy_is_active {
|
||||||
|
tray.gfx_proxy.supported().unwrap()
|
||||||
|
} else {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
tray.rebuild_and_update(&supported, &supported_gfx, GfxMode::Hybrid, 100, false);
|
||||||
tray.set_icon(TRAY_APP_ICON);
|
tray.set_icon(TRAY_APP_ICON);
|
||||||
info!("Started ROGTray");
|
info!("Started ROGTray");
|
||||||
|
|
||||||
@@ -508,13 +465,13 @@ pub fn init_tray(
|
|||||||
lock.gfx_state.mode
|
lock.gfx_state.mode
|
||||||
} else {
|
} else {
|
||||||
match lock.bios.dedicated_gfx {
|
match lock.bios.dedicated_gfx {
|
||||||
GpuMode::Discrete => GfxMode::AsusMuxDiscreet,
|
GpuMode::Discrete => GfxMode::AsusMuxDgpu,
|
||||||
_ => GfxMode::Hybrid,
|
_ => GfxMode::Hybrid,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
tray.rebuild_and_update(
|
tray.rebuild_and_update(
|
||||||
&supported,
|
&supported,
|
||||||
has_supergfx,
|
&supported_gfx,
|
||||||
current_gpu_mode,
|
current_gpu_mode,
|
||||||
lock.power_state.charge_limit,
|
lock.power_state.charge_limit,
|
||||||
lock.bios.panel_overdrive,
|
lock.bios.panel_overdrive,
|
||||||
@@ -524,13 +481,19 @@ pub fn init_tray(
|
|||||||
|
|
||||||
match lock.gfx_state.power_status {
|
match lock.gfx_state.power_status {
|
||||||
GfxPower::Suspended => tray.set_icon("asus_notif_blue"),
|
GfxPower::Suspended => tray.set_icon("asus_notif_blue"),
|
||||||
GfxPower::Off => tray.set_icon("asus_notif_green"),
|
GfxPower::Off => {
|
||||||
|
if lock.gfx_state.mode == GfxMode::Vfio {
|
||||||
|
tray.set_icon("asus_notif_red")
|
||||||
|
} else {
|
||||||
|
tray.set_icon("asus_notif_green")
|
||||||
|
}
|
||||||
|
}
|
||||||
GfxPower::AsusDisabled => tray.set_icon("asus_notif_white"),
|
GfxPower::AsusDisabled => tray.set_icon("asus_notif_white"),
|
||||||
GfxPower::AsusMuxDiscreet | GfxPower::Active => {
|
GfxPower::AsusMuxDiscreet | GfxPower::Active => {
|
||||||
tray.set_icon("asus_notif_red");
|
tray.set_icon("asus_notif_red");
|
||||||
}
|
}
|
||||||
GfxPower::Unknown => {
|
GfxPower::Unknown => {
|
||||||
if has_supergfx {
|
if tray.gfx_proxy_is_active {
|
||||||
tray.set_icon("gpu-integrated");
|
tray.set_icon("gpu-integrated");
|
||||||
} else {
|
} else {
|
||||||
tray.set_icon("asus_notif_red");
|
tray.set_icon("asus_notif_red");
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ use rog_dbus::zbus_profile::ProfileProxy;
|
|||||||
use rog_platform::platform::GpuMode;
|
use rog_platform::platform::GpuMode;
|
||||||
use rog_profiles::Profile;
|
use rog_profiles::Profile;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use supergfxctl::pci_device::GfxPower;
|
use supergfxctl::actions::UserActionRequired as GfxUserAction;
|
||||||
|
use supergfxctl::pci_device::{GfxMode, GfxPower};
|
||||||
use supergfxctl::zbus_proxy::DaemonProxy as SuperProxy;
|
use supergfxctl::zbus_proxy::DaemonProxy as SuperProxy;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
use zbus::export::futures_util::{future, StreamExt};
|
use zbus::export::futures_util::{future, StreamExt};
|
||||||
@@ -406,6 +407,7 @@ pub fn start_notifications(
|
|||||||
do_notification
|
do_notification
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let page_states1 = page_states.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let conn = zbus::Connection::system()
|
let conn = zbus::Connection::system()
|
||||||
.await
|
.await
|
||||||
@@ -426,15 +428,25 @@ pub fn start_notifications(
|
|||||||
while let Some(e) = p.next().await {
|
while let Some(e) = p.next().await {
|
||||||
if let Ok(out) = e.args() {
|
if let Ok(out) = e.args() {
|
||||||
let action = out.action();
|
let action = out.action();
|
||||||
do_gfx_action_notif(
|
let mode = if let Ok(lock) = page_states1.lock() {
|
||||||
"Gfx mode change requires",
|
convert_gfx_mode(lock.gfx_state.mode)
|
||||||
&format!("{action:?}",),
|
} else {
|
||||||
)
|
GpuMode::Error
|
||||||
|
};
|
||||||
|
match action {
|
||||||
|
supergfxctl::actions::UserActionRequired::Reboot => {
|
||||||
|
do_mux_notification(
|
||||||
|
"Graphics mode change requires reboot",
|
||||||
|
&mode,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
_ => do_gfx_action_notif(<&str>::from(action), *action, mode),
|
||||||
|
}
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
error!("zbus signal: do_gfx_action_notif: {e}");
|
error!("zbus signal: do_gfx_action_notif: {e}");
|
||||||
e
|
e
|
||||||
})
|
})
|
||||||
.unwrap();
|
.ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -445,6 +457,18 @@ pub fn start_notifications(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn convert_gfx_mode(gfx: GfxMode) -> GpuMode {
|
||||||
|
match gfx {
|
||||||
|
GfxMode::Hybrid => GpuMode::Optimus,
|
||||||
|
GfxMode::Integrated => GpuMode::Integrated,
|
||||||
|
GfxMode::NvidiaNoModeset => GpuMode::Discrete,
|
||||||
|
GfxMode::Vfio => GpuMode::Vfio,
|
||||||
|
GfxMode::AsusEgpu => GpuMode::Egpu,
|
||||||
|
GfxMode::AsusMuxDgpu => GpuMode::Ultimate,
|
||||||
|
GfxMode::None => GpuMode::Error,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn base_notification<T>(message: &str, data: &T) -> Notification
|
fn base_notification<T>(message: &str, data: &T) -> Notification
|
||||||
where
|
where
|
||||||
T: Display,
|
T: Display,
|
||||||
@@ -516,47 +540,91 @@ fn do_gpu_status_notif(message: &str, data: &GfxPower) -> Result<NotificationHan
|
|||||||
Ok(Notification::show(¬if)?)
|
Ok(Notification::show(¬if)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_gfx_action_notif<T>(message: &str, data: &T) -> Result<()>
|
fn do_gfx_action_notif(message: &str, action: GfxUserAction, mode: GpuMode) -> Result<()> {
|
||||||
where
|
if matches!(action, GfxUserAction::Reboot) {
|
||||||
T: Display,
|
do_mux_notification("Graphics mode change requires reboot", &mode).ok();
|
||||||
{
|
return Ok(());
|
||||||
let mut notif = base_notification(message, data);
|
}
|
||||||
notif.action("gnome-session-quit", "Logout");
|
|
||||||
notif.urgency(Urgency::Critical);
|
let mut notif = Notification::new();
|
||||||
notif.timeout(3000);
|
notif
|
||||||
notif.icon("dialog-warning");
|
.summary(NOTIF_HEADER)
|
||||||
notif.hint(Hint::Transient(true));
|
.body(&format!("Changing to {mode}. {message}"))
|
||||||
let handle = notif.show()?;
|
.timeout(2000)
|
||||||
handle.wait_for_action(|id| {
|
//.hint(Hint::Resident(true))
|
||||||
if id == "gnome-session-quit" {
|
.hint(Hint::Category("device".into()))
|
||||||
let mut cmd = Command::new("gnome-session-quit");
|
.urgency(Urgency::Critical)
|
||||||
cmd.spawn().ok();
|
.timeout(3000)
|
||||||
} else if id == "__closed" {
|
.icon("dialog-warning")
|
||||||
// TODO: cancel the switching
|
.hint(Hint::Transient(true));
|
||||||
|
|
||||||
|
if matches!(action, GfxUserAction::Logout) {
|
||||||
|
notif.action("gfx-mode-session-action", "Logout");
|
||||||
|
let handle = notif.show()?;
|
||||||
|
if let Ok(desktop) = std::env::var("XDG_CURRENT_DESKTOP") {
|
||||||
|
if desktop.to_lowercase() == "gnome" {
|
||||||
|
handle.wait_for_action(|id| {
|
||||||
|
if id == "gfx-mode-session-action" {
|
||||||
|
let mut cmd = Command::new("gnome-session-quit");
|
||||||
|
cmd.spawn().ok();
|
||||||
|
} else if id == "__closed" {
|
||||||
|
// TODO: cancel the switching
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if desktop.to_lowercase() == "kde" {
|
||||||
|
handle.wait_for_action(|id| {
|
||||||
|
if id == "gfx-mode-session-action" {
|
||||||
|
let mut cmd = Command::new("qdbus");
|
||||||
|
cmd.args(["org.kde.ksmserver", "/KSMServer", "logout", "1", "0", "0"]);
|
||||||
|
cmd.spawn().ok();
|
||||||
|
} else if id == "__closed" {
|
||||||
|
// TODO: cancel the switching
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// todo: handle alternatives
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
} else {
|
||||||
|
notif.show()?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Actual `GpuMode` unused as data is never correct until switched by reboot
|
/// Actual `GpuMode` unused as data is never correct until switched by reboot
|
||||||
fn do_mux_notification(message: &str, m: &GpuMode) -> Result<()> {
|
fn do_mux_notification(message: &str, m: &GpuMode) -> Result<()> {
|
||||||
let mut notif = base_notification(message, &m.to_string());
|
let mut notif = base_notification(message, &m.to_string());
|
||||||
notif.action("gnome-session-quit", "Reboot");
|
notif
|
||||||
notif.urgency(Urgency::Critical);
|
.action("gfx-mode-session-action", "Reboot")
|
||||||
notif.icon("system-reboot-symbolic");
|
.urgency(Urgency::Critical)
|
||||||
notif.hint(Hint::Transient(true));
|
.icon("system-reboot-symbolic")
|
||||||
|
.hint(Hint::Transient(true));
|
||||||
let handle = notif.show()?;
|
let handle = notif.show()?;
|
||||||
|
|
||||||
std::thread::spawn(|| {
|
std::thread::spawn(|| {
|
||||||
handle.wait_for_action(|id| {
|
if let Ok(desktop) = std::env::var("XDG_CURRENT_DESKTOP") {
|
||||||
if id == "gnome-session-quit" {
|
if desktop.to_lowercase() == "gnome" {
|
||||||
let mut cmd = Command::new("gnome-session-quit");
|
handle.wait_for_action(|id| {
|
||||||
cmd.arg("--reboot");
|
if id == "gfx-mode-session-action" {
|
||||||
cmd.spawn().ok();
|
let mut cmd = Command::new("gnome-session-quit");
|
||||||
} else if id == "__closed" {
|
cmd.arg("--reboot");
|
||||||
// TODO: cancel the switching
|
cmd.spawn().ok();
|
||||||
|
} else if id == "__closed" {
|
||||||
|
// TODO: cancel the switching
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if desktop.to_lowercase() == "kde" {
|
||||||
|
handle.wait_for_action(|id| {
|
||||||
|
if id == "gfx-mode-session-action" {
|
||||||
|
let mut cmd = Command::new("qdbus");
|
||||||
|
cmd.args(["org.kde.ksmserver", "/KSMServer", "logout", "1", "1", "0"]);
|
||||||
|
cmd.spawn().ok();
|
||||||
|
} else if id == "__closed" {
|
||||||
|
// TODO: cancel the switching
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use egui::{RichText, Ui};
|
use egui::{RichText, Ui};
|
||||||
use rog_aura::usb::{AuraDev1866, AuraDev19b6, AuraDevTuf, AuraDevice, AuraPowerDev};
|
use rog_aura::usb::{AuraDevRog1, AuraDevRog2, AuraDevTuf, AuraDevice, AuraPowerDev};
|
||||||
use rog_aura::AuraZone;
|
use rog_aura::AuraZone;
|
||||||
use rog_platform::supported::SupportedFunctions;
|
use rog_platform::supported::SupportedFunctions;
|
||||||
|
|
||||||
@@ -12,7 +12,9 @@ pub fn aura_power_group(supported: &SupportedFunctions, states: &mut SystemState
|
|||||||
AuraDevice::X1854 | AuraDevice::X1869 | AuraDevice::X1866 => {
|
AuraDevice::X1854 | AuraDevice::X1869 | AuraDevice::X1866 => {
|
||||||
aura_power1(supported, states, ui);
|
aura_power1(supported, states, ui);
|
||||||
}
|
}
|
||||||
AuraDevice::X19B6 => aura_power2(supported, states, ui),
|
AuraDevice::X19b6 | AuraDevice::X18c6 | AuraDevice::X1a30 => {
|
||||||
|
aura_power2(supported, states, ui)
|
||||||
|
}
|
||||||
AuraDevice::Tuf => aura_power1(supported, states, ui),
|
AuraDevice::Tuf => aura_power1(supported, states, ui),
|
||||||
AuraDevice::Unknown => {}
|
AuraDevice::Unknown => {}
|
||||||
}
|
}
|
||||||
@@ -20,10 +22,10 @@ pub fn aura_power_group(supported: &SupportedFunctions, states: &mut SystemState
|
|||||||
|
|
||||||
fn aura_power1(supported: &SupportedFunctions, states: &mut SystemState, ui: &mut Ui) {
|
fn aura_power1(supported: &SupportedFunctions, states: &mut SystemState, ui: &mut Ui) {
|
||||||
let enabled_states = &mut states.aura.enabled;
|
let enabled_states = &mut states.aura.enabled;
|
||||||
let mut boot = enabled_states.x1866.contains(&AuraDev1866::Boot);
|
let mut boot = enabled_states.x1866.contains(&AuraDevRog1::Boot);
|
||||||
let mut sleep = enabled_states.x1866.contains(&AuraDev1866::Sleep);
|
let mut sleep = enabled_states.x1866.contains(&AuraDevRog1::Sleep);
|
||||||
let mut keyboard = enabled_states.x1866.contains(&AuraDev1866::Keyboard);
|
let mut keyboard = enabled_states.x1866.contains(&AuraDevRog1::Keyboard);
|
||||||
let mut lightbar = enabled_states.x1866.contains(&AuraDev1866::Lightbar);
|
let mut lightbar = enabled_states.x1866.contains(&AuraDevRog1::Lightbar);
|
||||||
if supported.keyboard_led.dev_id == AuraDevice::Tuf {
|
if supported.keyboard_led.dev_id == AuraDevice::Tuf {
|
||||||
boot = enabled_states.tuf.contains(&AuraDevTuf::Boot);
|
boot = enabled_states.tuf.contains(&AuraDevTuf::Boot);
|
||||||
sleep = enabled_states.tuf.contains(&AuraDevTuf::Sleep);
|
sleep = enabled_states.tuf.contains(&AuraDevTuf::Sleep);
|
||||||
@@ -148,7 +150,7 @@ fn aura_power1(supported: &SupportedFunctions, states: &mut SystemState, ui: &mu
|
|||||||
let mut enabled = Vec::new();
|
let mut enabled = Vec::new();
|
||||||
let mut disabled = Vec::new();
|
let mut disabled = Vec::new();
|
||||||
|
|
||||||
let mut modify_x1866 = |b: bool, a: AuraDev1866| {
|
let mut modify_x1866 = |b: bool, a: AuraDevRog1| {
|
||||||
if b {
|
if b {
|
||||||
enabled.push(a);
|
enabled.push(a);
|
||||||
if !enabled_states.x1866.contains(&a) {
|
if !enabled_states.x1866.contains(&a) {
|
||||||
@@ -169,14 +171,14 @@ fn aura_power1(supported: &SupportedFunctions, states: &mut SystemState, ui: &mu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
modify_x1866(boot, AuraDev1866::Boot);
|
modify_x1866(boot, AuraDevRog1::Boot);
|
||||||
modify_x1866(sleep, AuraDev1866::Sleep);
|
modify_x1866(sleep, AuraDevRog1::Sleep);
|
||||||
modify_x1866(keyboard, AuraDev1866::Keyboard);
|
modify_x1866(keyboard, AuraDevRog1::Keyboard);
|
||||||
if !supported.keyboard_led.basic_zones.is_empty() {
|
if !supported.keyboard_led.basic_zones.is_empty() {
|
||||||
modify_x1866(lightbar, AuraDev1866::Lightbar);
|
modify_x1866(lightbar, AuraDevRog1::Lightbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut send = |enable: bool, data: Vec<AuraDev1866>| {
|
let mut send = |enable: bool, data: Vec<AuraDevRog1>| {
|
||||||
let options = AuraPowerDev {
|
let options = AuraPowerDev {
|
||||||
tuf: vec![],
|
tuf: vec![],
|
||||||
x1866: data,
|
x1866: data,
|
||||||
@@ -211,17 +213,17 @@ fn aura_power2(supported: &SupportedFunctions, states: &mut SystemState, ui: &mu
|
|||||||
.basic_zones
|
.basic_zones
|
||||||
.contains(&AuraZone::BarRight);
|
.contains(&AuraZone::BarRight);
|
||||||
|
|
||||||
let boot_bar = &mut enabled_states.x19b6.contains(&AuraDev19b6::AwakeBar);
|
let boot_bar = &mut enabled_states.x19b6.contains(&AuraDevRog2::AwakeBar);
|
||||||
let boot_logo = &mut enabled_states.x19b6.contains(&AuraDev19b6::BootLogo);
|
let boot_logo = &mut enabled_states.x19b6.contains(&AuraDevRog2::BootLogo);
|
||||||
let boot_keyb = &mut enabled_states.x19b6.contains(&AuraDev19b6::BootKeyb);
|
let boot_keyb = &mut enabled_states.x19b6.contains(&AuraDevRog2::BootKeyb);
|
||||||
|
|
||||||
let awake_bar = &mut enabled_states.x19b6.contains(&AuraDev19b6::BootBar);
|
let awake_bar = &mut enabled_states.x19b6.contains(&AuraDevRog2::BootBar);
|
||||||
let awake_logo = &mut enabled_states.x19b6.contains(&AuraDev19b6::AwakeLogo);
|
let awake_logo = &mut enabled_states.x19b6.contains(&AuraDevRog2::AwakeLogo);
|
||||||
let awake_keyb = &mut enabled_states.x19b6.contains(&AuraDev19b6::AwakeKeyb);
|
let awake_keyb = &mut enabled_states.x19b6.contains(&AuraDevRog2::AwakeKeyb);
|
||||||
|
|
||||||
let sleep_bar = &mut enabled_states.x19b6.contains(&AuraDev19b6::SleepBar);
|
let sleep_bar = &mut enabled_states.x19b6.contains(&AuraDevRog2::SleepBar);
|
||||||
let sleep_logo = &mut enabled_states.x19b6.contains(&AuraDev19b6::SleepLogo);
|
let sleep_logo = &mut enabled_states.x19b6.contains(&AuraDevRog2::SleepLogo);
|
||||||
let sleep_keyb = &mut enabled_states.x19b6.contains(&AuraDev19b6::SleepKeyb);
|
let sleep_keyb = &mut enabled_states.x19b6.contains(&AuraDevRog2::SleepKeyb);
|
||||||
|
|
||||||
let mut changed = false;
|
let mut changed = false;
|
||||||
|
|
||||||
@@ -265,7 +267,7 @@ fn aura_power2(supported: &SupportedFunctions, states: &mut SystemState, ui: &mu
|
|||||||
let mut enabled = Vec::new();
|
let mut enabled = Vec::new();
|
||||||
let mut disabled = Vec::new();
|
let mut disabled = Vec::new();
|
||||||
|
|
||||||
let mut modify = |b: bool, a: AuraDev19b6| {
|
let mut modify = |b: bool, a: AuraDevRog2| {
|
||||||
if b {
|
if b {
|
||||||
enabled.push(a);
|
enabled.push(a);
|
||||||
if !enabled_states.x19b6.contains(&a) {
|
if !enabled_states.x19b6.contains(&a) {
|
||||||
@@ -286,25 +288,25 @@ fn aura_power2(supported: &SupportedFunctions, states: &mut SystemState, ui: &mu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
modify(*boot_keyb, AuraDev19b6::BootKeyb);
|
modify(*boot_keyb, AuraDevRog2::BootKeyb);
|
||||||
modify(*sleep_keyb, AuraDev19b6::SleepKeyb);
|
modify(*sleep_keyb, AuraDevRog2::SleepKeyb);
|
||||||
modify(*awake_keyb, AuraDev19b6::AwakeKeyb);
|
modify(*awake_keyb, AuraDevRog2::AwakeKeyb);
|
||||||
if supported.keyboard_led.basic_zones.contains(&AuraZone::Logo) {
|
if supported.keyboard_led.basic_zones.contains(&AuraZone::Logo) {
|
||||||
modify(*boot_logo, AuraDev19b6::BootLogo);
|
modify(*boot_logo, AuraDevRog2::BootLogo);
|
||||||
modify(*sleep_logo, AuraDev19b6::SleepLogo);
|
modify(*sleep_logo, AuraDevRog2::SleepLogo);
|
||||||
modify(*awake_logo, AuraDev19b6::AwakeLogo);
|
modify(*awake_logo, AuraDevRog2::AwakeLogo);
|
||||||
}
|
}
|
||||||
if supported
|
if supported
|
||||||
.keyboard_led
|
.keyboard_led
|
||||||
.basic_zones
|
.basic_zones
|
||||||
.contains(&AuraZone::BarLeft)
|
.contains(&AuraZone::BarLeft)
|
||||||
{
|
{
|
||||||
modify(*boot_bar, AuraDev19b6::AwakeBar);
|
modify(*boot_bar, AuraDevRog2::AwakeBar);
|
||||||
modify(*sleep_bar, AuraDev19b6::SleepBar);
|
modify(*sleep_bar, AuraDevRog2::SleepBar);
|
||||||
modify(*awake_bar, AuraDev19b6::BootBar);
|
modify(*awake_bar, AuraDevRog2::BootBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut send = |enable: bool, data: Vec<AuraDev19b6>| {
|
let mut send = |enable: bool, data: Vec<AuraDevRog2>| {
|
||||||
let options = AuraPowerDev {
|
let options = AuraPowerDev {
|
||||||
tuf: vec![],
|
tuf: vec![],
|
||||||
x1866: vec![],
|
x1866: vec![],
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ impl RogApp {
|
|||||||
// The top panel is often a good place for a menu bar:
|
// The top panel is often a good place for a menu bar:
|
||||||
egui::menu::bar(ui, |ui| {
|
egui::menu::bar(ui, |ui| {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
egui::global_dark_light_mode_buttons(ui);
|
self.dark_light_mode_buttons(ui);
|
||||||
egui::warn_if_debug_build(ui);
|
egui::warn_if_debug_build(ui);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -45,4 +45,34 @@ impl RogApp {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dark_light_mode_buttons(&mut self, ui: &mut egui::Ui) {
|
||||||
|
let load_from_cfg = self.config.dark_mode != ui.ctx().style().visuals.dark_mode;
|
||||||
|
|
||||||
|
if ui
|
||||||
|
.add(egui::SelectableLabel::new(
|
||||||
|
!self.config.dark_mode,
|
||||||
|
"☀ Light",
|
||||||
|
))
|
||||||
|
.clicked()
|
||||||
|
|| (load_from_cfg && !self.config.dark_mode)
|
||||||
|
{
|
||||||
|
ui.ctx().set_visuals(egui::Visuals::light());
|
||||||
|
}
|
||||||
|
if ui
|
||||||
|
.add(egui::SelectableLabel::new(self.config.dark_mode, "🌙 Dark"))
|
||||||
|
.clicked()
|
||||||
|
|| (load_from_cfg && self.config.dark_mode)
|
||||||
|
{
|
||||||
|
ui.ctx().set_visuals(egui::Visuals::dark());
|
||||||
|
}
|
||||||
|
|
||||||
|
let applied_dark_mode = ui.ctx().style().visuals.dark_mode;
|
||||||
|
|
||||||
|
if self.config.dark_mode != applied_dark_mode {
|
||||||
|
self.config.dark_mode = applied_dark_mode;
|
||||||
|
let tmp = self.config.enabled_notifications.clone();
|
||||||
|
self.config.save(&tmp).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ pub enum GpuMode {
|
|||||||
Optimus,
|
Optimus,
|
||||||
Integrated,
|
Integrated,
|
||||||
Egpu,
|
Egpu,
|
||||||
|
Vfio,
|
||||||
|
Ultimate,
|
||||||
#[default]
|
#[default]
|
||||||
Error,
|
Error,
|
||||||
NotSupported,
|
NotSupported,
|
||||||
@@ -135,6 +137,8 @@ impl Display for GpuMode {
|
|||||||
GpuMode::Optimus => write!(f, "Optimus"),
|
GpuMode::Optimus => write!(f, "Optimus"),
|
||||||
GpuMode::Integrated => write!(f, "Integrated"),
|
GpuMode::Integrated => write!(f, "Integrated"),
|
||||||
GpuMode::Egpu => write!(f, "eGPU"),
|
GpuMode::Egpu => write!(f, "eGPU"),
|
||||||
|
GpuMode::Vfio => write!(f, "VFIO"),
|
||||||
|
GpuMode::Ultimate => write!(f, "Ultimate"),
|
||||||
GpuMode::Error => write!(f, "Error"),
|
GpuMode::Error => write!(f, "Error"),
|
||||||
GpuMode::NotSupported => write!(f, "Not Supported"),
|
GpuMode::NotSupported => write!(f, "Not Supported"),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user