Compare commits

...

106 Commits

Author SHA1 Message Date
Denis Benato
5e5cebc781 Revert "Fix: continue -> return in set_config_or_default"
This reverts commit ad051bd7b8.
2025-11-06 22:53:21 +01:00
Denis Benato
def691f9d0 Fix: sliders not updating the value 2025-11-06 22:53:09 +01:00
Denis Benato
80eeafd9e1 Feat: config reload and do not apply properties if max==min 2025-11-06 21:06:44 +01:00
Denis Benato
bf173300e0 Feat: start in tray mode 2025-11-06 17:29:12 +01:00
Denis Benato
07874d7452 tests: load bundled aura_support.ron when system files missing to make unit tests reliable in CI 2025-11-06 17:24:01 +01:00
Denis Benato
894a0d2b11 Chore: update CHANGELOG.md 2025-11-06 16:12:44 +01:00
Denis Benato
11dc02612e Fix clippy warnings: alias complex types, allow some clippy lints, collapse else-if, avoid is_multiple_of usage 2025-11-06 16:05:38 +01:00
Denis Benato
fccb233e9e Fix: stop rust from silly complains about is_multiple_of 2025-11-06 15:58:30 +01:00
Denis Benato
c13612e02c Fix: simplify an if 2025-11-06 15:52:43 +01:00
Denis Benato
80147966a9 Chore: use stable 2025-11-06 15:49:05 +01:00
Denis Benato
a1815ac40c Chore: improve tests 2025-11-06 15:34:30 +01:00
Denis Benato
ad051bd7b8 Fix: continue -> return in set_config_or_default 2025-11-06 15:07:31 +01:00
Denis Benato
90676b390e Chore: update CHANGELOG.md 2025-11-06 15:04:59 +01:00
Denis Benato
974f2acafa Feat: better handling of nv_ properties 2025-11-06 14:53:57 +01:00
Denis Benato
6ae3ae5284 Feat: make nvidia dGPU tunables power-profile dependant 2025-11-06 14:26:03 +01:00
Denis Benato
34699a7021 Fix: notifications not respecting settings 2025-11-06 02:57:20 +01:00
Denis Benato
ef311689ec Fix: do not stall the boot process 2025-11-06 00:55:20 +01:00
Denis Benato
8ee0281b4f Fix: fedora build 2025-11-05 22:40:58 +01:00
Denis Benato
d8504b5430 Changelog for 6.1.17 2025-11-05 21:14:21 +01:00
Denis Benato
5c4d833fbd Prepare for 6.1.17 2025-11-05 21:09:18 +01:00
Denis Benato
698999e828 cargo fmt and README.md restyle 2025-11-05 20:02:43 +01:00
Denis Benato
0eae9e55c6 Merge branch 'devel' 2025-11-05 19:54:21 +01:00
Denis Benato
07171888a1 Merge branch 'main' into 'main'
feat: Allow setting default profile for ac and battery

See merge request asus-linux/asusctl!229
2025-11-05 18:53:53 +00:00
matszwe02
9321fde6af feat: Allow setting default profile for ac and battery 2025-11-05 01:44:31 +01:00
Denis Benato
f90d0a6673 Merge branch 'devel' into 'devel'
Add install-data-asusd_user to install-data in Makefile

See merge request asus-linux/asusctl!228
2025-10-29 18:49:50 +00:00
Synby
bbd03c128d Edit Makefile
add install-data-asusd_user to install-data
2025-10-29 17:23:29 +00:00
Denis Benato
132a2f3665 Chore: complete the switch back to stable 2025-10-23 14:50:40 +02:00
Denis Benato
180566e5f1 Fix: share a single HID device
Avoid opening multiple handles to the same device whenever possible.
2025-10-22 22:05:17 +02:00
Denis Benato
c9e76f3273 Chore: prepare for 6.1.16 release 2025-10-20 19:15:36 +02:00
Denis Benato
2997ae83ff Merge branch 'devel' 2025-10-20 04:08:20 +02:00
Denis Benato
151d681e16 feat: expose MCU Powersave toggle on rogcc 2025-10-20 03:47:09 +02:00
Denis Benato
90b3f43a36 Chore: add more debugging 2025-10-20 02:49:47 +02:00
Denis Benato
a345b09ce1 Chore: type abttery -> battery 2025-10-20 02:46:07 +02:00
Denis Benato
f26b0d8de5 Merge branch 'profile-match' into 'main'
Allow flexible profile cli input for LowPower

See merge request asus-linux/asusctl!226
2025-10-20 00:40:54 +00:00
yanganto
9366b0ec04 Allow flexible profile cli input for LowPower 2025-10-20 00:40:54 +00:00
Denis Benato
415712143b Feat: add screen_auto_brightness 2025-10-20 02:08:59 +02:00
Denis Benato
60fce30a06 Chore: flush out requirement for nightly 2025-10-20 00:39:17 +02:00
Denis Benato
d8f06230fa Chore: Added support for FX607J 2025-10-19 23:02:45 +02:00
Denis Benato
834464a527 Fix: fixed ac_command/bat_command 2025-10-19 23:00:23 +02:00
Denis Benato
4faa96298a Chore: Added supprot for G614JIR 2025-10-19 22:32:05 +02:00
Denis Benato
78c574b761 chore_ add supprot for GU605CR 2025-10-19 21:27:33 +02:00
Denis Benato
9785eafd53 Modified to README.md to not mislead users attempting to compile it 2025-10-19 20:45:49 +02:00
Denis Benato
51cad9ea7e chore: make the startup more verbose 2025-10-16 15:17:27 +02:00
Denis Benato
319373faea chore: Prepare for 6.1.15 release 2025-10-14 01:57:03 +02:00
Denis Benato
f6aa3e3d01 Merge branch 'devel' 2025-10-14 01:50:20 +02:00
Denis Benato
d11fc20bab feat: apply the proper configuration depending on the plug status 2025-10-13 21:36:01 +02:00
Denis Benato
b0e1b21e4b chore: cargo clippy fix 2025-10-12 22:34:20 +02:00
Denis Benato
1c1daaa6d2 chore: reimplement default for FanCurveCPU 2025-10-12 19:47:26 +02:00
HiFiPhile
c3b5de843f Add TX Air rule 2025-10-12 19:44:30 +02:00
Denis Benato
09dcfb4065 Fix multiple warnings 2025-10-12 19:43:07 +02:00
Denis Benato
b2e7211bbe chore: cargo fmt 2025-10-12 19:43:05 +02:00
Denis Benato
1ab1adf937 Merge branch 'tx_air' into 'main'
Add TX Air (TUF Chinese version) udev rule

See merge request asus-linux/asusctl!227
2025-10-12 17:42:09 +00:00
HiFiPhile
a21bf779b0 Add TX Air rule 2025-10-12 13:20:07 +02:00
Denis Benato
0dba22529c feat: change limits dynamically 2025-10-11 20:51:57 +02:00
Denis Benato
180d63620b Fix multiple warnings 2025-10-08 01:19:38 +02:00
Denis Benato
daea1f538c chore: cargo fmt 2025-10-08 01:01:43 +02:00
Denis Benato
f5e2484797 chore: release 6.1.14 2025-10-08 00:56:25 +02:00
Denis Benato
7105ae40c6 chore: attempt to fix tests 2025-10-08 00:35:09 +02:00
Denis Benato
33f9900ef9 chore: fix formatting 2025-10-08 00:19:43 +02:00
Denis Benato
1aa1c62e40 chore: update spec file version to 6.1.13 2025-10-07 23:47:09 +02:00
Denis Benato
3a18ef4c7b chore: Prepare for 6.1.13 release 2025-10-07 23:47:02 +02:00
Denis Benato
9dcce77302 chore: fix a warning 2025-10-06 19:37:30 +02:00
Denis Benato
995df9b51b fix: fix building due to a double-borrow 2025-10-06 19:29:29 +02:00
Denis Benato
84c8babdb7 fix: make the startup path more robust 2025-10-06 19:19:31 +02:00
Denis Benato
1014f97b6f fix: apply panel overdrive and other properties on asusd startup 2025-10-05 23:13:41 +02:00
Denis Benato
3c023be57d chore: update changelog for the upcoming release 2025-10-05 17:29:51 +02:00
Denis Benato
eff20c84d6 chore: add ubuntu install instructions 2025-10-05 17:29:12 +02:00
Denis Benato
f8984eb7e9 chore: update crates 2025-10-05 17:18:24 +02:00
Denis Benato
2ffd2a1e1f chore: compile packages on make install 2025-10-05 16:58:03 +02:00
Denis Benato
341bd081f8 chore: fix makefile 2025-10-05 16:45:29 +02:00
Denis Benato
52af4203a1 Merge remote-tracking branch 'github/main' 2025-10-05 16:15:36 +02:00
Denis Benato
e5a6088392 Merge pull request #84 from evertvorster/patch-1
Update asusd.rules to have absolute path
2025-10-05 16:15:20 +02:00
Denis Benato
6ee5dfb352 chore: require power-profile-daemon on fedora 2025-10-05 16:07:58 +02:00
Evert Vorster
3f8336fc5e Update asusd.rules
Added the absolute path for systemctl. No modern distrobution installs it anywhere else.
2025-10-05 16:02:48 +02:00
Denis Benato
8fc7e8f3a7 Merge remote-tracking branch 'gitlab/main' 2025-10-05 16:02:08 +02:00
Denis Benato
098b1f2668 chore: add *.patch to gitignore 2025-10-05 15:57:20 +02:00
Denis Benato
20df3ad2f2 Merge remote-tracking branch 'github/main' 2025-10-05 15:52:50 +02:00
Denis Benato
7aaadad6da Merge pull request #39 from rashadgasimli/main
Add Azerbaijani language
2025-10-05 15:48:37 +02:00
Luke Jones
be60c1ba02 Merge pull request #69 from kxxt/tx
Add udev match for TX Gaming
2025-06-10 12:28:47 +12:00
kxxt
698a8e8677 Add udev match for TX Gaming 2025-05-29 20:38:05 +08:00
fluke
ce6420eeac Merge branch 'aura-support-fx706heb' into 'main'
Add AURA support definition for 2021 TUF F17

See merge request asus-linux/asusctl!225
2025-05-19 08:53:03 +00:00
fluke
f5f5e4f720 Edit FX706HEB to become FX706H and match more models 2025-05-19 08:52:11 +00:00
Brandon Tolbird
c08503826b Add AURA support definition for 2021 TUF F17
(FX706HEB)
2025-05-18 22:20:42 +00:00
Luke Jones
685345d656 chore: update spec file version to 6.1.12 2025-04-06 13:51:55 +12:00
Luke Jones
59aab24a4a Fix unbouneded loop and prep new version 2025-04-06 13:26:53 +12:00
Luke Jones
c3f0e61ebc chore: update spec file version to 6.1.11 2025-04-05 21:51:35 +13:00
Luke Jones
c143536cd0 Prep new release 2025-04-06 07:55:06 +12:00
Luke Jones
2a168e93d3 chore: update translations 2025-04-06 07:36:21 +12:00
Luke Jones
c3570a23f1 feature: add UI controls fro screenpad 2025-04-06 07:36:21 +12:00
Luke Jones
9db6cb5545 feature: watch primary backlight and sync screenpad to it 2025-04-06 02:41:46 +12:00
Luke Jones
836575c0a8 feature: screenpad settings config store 2025-04-06 02:09:45 +13:00
Luke Jones
61f2216c25 fix: minor clippy fix 2025-04-06 01:04:03 +13:00
Luke Jones
7f5b3ef376 feature: add support for screenpad brightness 2025-04-06 01:04:03 +13:00
fluke
257471a36c Merge branch 'fix/anime-flicker' into 'main'
Fix anime flickering when repeatedly setting images in a tight loop

See merge request asus-linux/asusctl!223
2025-03-27 21:13:25 +00:00
I-Al-Istannen
568f3e848f Fix anime flickering when repeatedly setting images in a tight loop 2025-03-27 21:05:23 +01:00
fluke
0c9b58755f Merge branch 'pt_BR-translation' into 'main'
Include pt_BR translations file.

See merge request asus-linux/asusctl!222
2025-03-25 01:18:33 +00:00
PabloKiryu
1b47fb7873 Include pt_BR translations file. 2025-03-18 00:32:25 -03:00
Denis Benato
df93209839 chore: Install LICENSE file 2025-03-13 01:28:06 +01:00
Denis Benato
11ee7827e9 chore: Add packaging instructions for deb
This commits adds .deb packaging support for all applications in this repository.
2025-03-12 18:18:08 +00:00
Denis Benato
c337de5139 chore(Makefile): split up install by package 2025-03-12 16:54:35 +01:00
Luke Jones
d55c2befed chore: update spec file version to 6.1.10 2025-03-04 09:21:53 +13:00
Luke Jones
4cd9918e1a asusd: single line fix for profile switching 2025-03-04 09:21:52 +13:00
Luke Jones
3a900f23fe ROGCC: better handling of fan curve profile 2025-03-03 20:20:09 +13:00
Rəşad Qasımlı
c5c5a9ac67 Update rog-control-center.mo 2024-07-20 14:35:45 +04:00
Rəşad Qasımlı
b84bc61f3d Update the information about translator 2024-07-20 00:59:47 +04:00
Rəşad Qasımlı
b4e38e0814 Add Azerbaijani language 2024-07-19 23:47:41 +04:00
77 changed files with 6759 additions and 2735 deletions

View File

@@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
set -e set -e
echo '+cargo +nightly fmt --all -- --check' echo '+cargo fmt --all -- --check'
cargo +nightly fmt --all -- --check cargo fmt --all -- --check
git add -u git add -u

View File

@@ -2,8 +2,8 @@
set -e set -e
echo '+cargo +nightly fmt --all -- --check' echo '+cargo fmt --all -- --check'
cargo +nightly fmt --all -- --check cargo fmt --all -- --check
echo '+cargo clippy --all -- -D warnings' echo '+cargo clippy --all -- -D warnings'
cargo clippy --all -- -D warnings cargo clippy --all -- -D warnings
echo '+cargo cranky' echo '+cargo cranky'

1
.gitignore vendored
View File

@@ -9,6 +9,7 @@ vendor_*
.vscode .vscode
.~lock.* .~lock.*
*.ods# *.ods#
*.patch
# gnome extension # gnome extension
node-modules node-modules

View File

@@ -31,8 +31,7 @@ format:
- tags - tags
<<: *rust_cache <<: *rust_cache
script: script:
- echo "nightly" > rust-toolchain - rustup component add rustfmt || true
- rustup component add rustfmt
- cargo fmt --check - cargo fmt --check
check: check:
@@ -40,8 +39,8 @@ check:
- tags - tags
<<: *rust_cache <<: *rust_cache
script: script:
- rustup component add clippy - rustup component add clippy || true
- cargo check - cargo check --locked --workspace
# deny currently catches too much # deny currently catches too much
#- cargo install cargo-deny && cargo deny #- cargo install cargo-deny && cargo deny
- cargo install cargo-cranky && cargo cranky - cargo install cargo-cranky && cargo cranky
@@ -52,7 +51,7 @@ test:
<<: *rust_cache <<: *rust_cache
script: script:
- mkdir -p .git/hooks > /dev/null - mkdir -p .git/hooks > /dev/null
- cargo test --all -- --test-threads=1 - cargo test --locked --all
release: release:
only: only:
@@ -60,7 +59,7 @@ release:
<<: *rust_cache <<: *rust_cache
script: script:
- cargo install cargo-vendor-filterer - cargo install cargo-vendor-filterer
- make && make vendor - make FROZEN=1 && make vendor
artifacts: artifacts:
paths: paths:
- vendor_asusctl*.tar.xz - vendor_asusctl*.tar.xz
@@ -72,7 +71,7 @@ pages:
- tags - tags
<<: *rust_cache <<: *rust_cache
script: script:
- cargo doc --document-private-items --no-deps --workspace - cargo doc --locked --document-private-items --no-deps --workspace
- rm -rf public - rm -rf public
- mkdir public - mkdir public
- cp -R target/doc/* public - cp -R target/doc/* public

View File

@@ -2,6 +2,61 @@
## [Unreleased] ## [Unreleased]
### Changed
- Make the boot process more reliable
- tie nv_ properties to power profiles
- Better support nv_tgp
## [v6.1.17]
### Changed
- Fix Makefile
- Share a single HID device
## [v6.1.16]
### Changed
- Expose more properties via rog-control-center
- Add support for a few more models
## [v6.1.15]
### Changed
- Reflect the current asus-armoury status on AC plug connection status change
## [v6.1.14]
### Changed
- Fix formatting
- Attempt to fix tests
## [v6.1.13]
### Changed
- Fix a problem in reloading the service (@evertvorster)
- Add Azerbaijani language (@rashadgasimli)
- Add Ubuntu installation instructions
## [v6.1.12]
### Changed
- Fix an unbounded event loop caused by other processes causing a "modify" event on the screen backlight brightness.
## [v6.1.11]
### Changed
- Fix anime flickering issue when using custom anims (@I-Al-Istannen)
- Include pt_BR translations file (@PabloKiryu)
## Added
- Support for the screenpad brightness on some Laptops. This includes syncing to the primary screen brightness, and a gamma adjustment to set brightness scaling.
- Add asusctl CLI options
- Add UI options
- Add a fake gamma correction (`asusctl backlight --sync-screenpad-brightness`, 1.5 for example sets screenpad low brightness lower than primary, and scales upwards)
### Changed
- asusd: single line fix for profile switching
## [v6.1.9] ## [v6.1.9]
### Changed ### Changed

3339
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
[workspace.package] [workspace.package]
version = "6.1.9" version = "6.1.17"
rust-version = "1.82" rust-version = "1.82"
license = "MPL-2.0" license = "MPL-2.0"
readme = "README.md" readme = "README.md"
@@ -73,7 +73,7 @@ sg = { git = "https://github.com/flukejones/sg-rs.git" }
[profile.release] [profile.release]
# thin = 57s, asusd = 9.0M # thin = 57s, asusd = 9.0M
# fat = 72s, asusd = 6.4M # fat = 72s, asusd = 6.4M
lto = "thin" lto = "fat"
debug = false debug = false
opt-level = 3 opt-level = 3
panic = "abort" panic = "abort"

View File

@@ -17,6 +17,8 @@ BIN_D := asusd
BIN_U := asusd-user BIN_U := asusd-user
LEDCFG := aura_support.ron LEDCFG := aura_support.ron
DESTDIR_REALPATH = $(shell realpath $(DESTDIR))
SRC := Cargo.toml Cargo.lock Makefile $(shell find -type f -wholename '**/src/*.rs') SRC := Cargo.toml Cargo.lock Makefile $(shell find -type f -wholename '**/src/*.rs')
STRIP_BINARIES ?= 0 STRIP_BINARIES ?= 0
@@ -35,6 +37,15 @@ ifeq ($(X11),1)
ARGS += --features "rog-control-center/x11" ARGS += --features "rog-control-center/x11"
endif endif
# Always use the versions in Cargo.lock by default
ARGS += --locked
# Allow optionally freezing the build to avoid any network access and enforce Cargo.lock strictly
FROZEN ?= 0
ifeq ($(FROZEN),1)
ARGS += --frozen
endif
VENDORED ?= 0 VENDORED ?= 0
ifeq ($(VENDORED),1) ifeq ($(VENDORED),1)
ARGS += --frozen ARGS += --frozen
@@ -48,24 +59,31 @@ clean:
distclean: distclean:
rm -rf .cargo vendor vendor.tar.xz rm -rf .cargo vendor vendor.tar.xz
install-program: target/$(TARGET)/$(BIN_D): build
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_ROG)" "$(DESTDIR)$(bindir)/$(BIN_ROG)" target/$(TARGET)/$(BIN_C): build
target/$(TARGET)/$(BIN_U): build
target/$(TARGET)/$(BIN_ROG): build
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_C)" "$(DESTDIR)$(bindir)/$(BIN_C)" install-asusd: target/$(TARGET)/$(BIN_D)
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_D)" "$(DESTDIR)$(bindir)/$(BIN_D)" $(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_D)" "$(DESTDIR)$(bindir)/$(BIN_D)"
install-asusctl: target/$(TARGET)/$(BIN_C)
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_C)" "$(DESTDIR)$(bindir)/$(BIN_C)"
install-asusd_user: target/$(TARGET)/$(BIN_U)
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_U)" "$(DESTDIR)$(bindir)/$(BIN_U)" $(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_U)" "$(DESTDIR)$(bindir)/$(BIN_U)"
install-data: install-rog_gui: target/$(TARGET)/$(BIN_ROG)
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_ROG)" "$(DESTDIR)$(bindir)/$(BIN_ROG)"
.PHONY: install-asusd install-asusctl install-asusd_user install-rog_gui
install-program: install-asusd install-asusctl install-asusd_user install-rog_gui
install-data-rog_gui:
$(INSTALL_DATA) "./rog-control-center/data/$(BIN_ROG).desktop" "$(DESTDIR)$(datarootdir)/applications/$(BIN_ROG).desktop" $(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" $(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/{}" \; cd rog-aura/data/layouts && find . -type f -name "*.ron" -exec $(INSTALL_DATA) "{}" "$(DESTDIR_REALPATH)$(datarootdir)/rog-gui/layouts/{}" \;
$(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) "./data/$(BIN_D).conf" "$(DESTDIR)$(datarootdir)/dbus-1/system.d/$(BIN_D).conf"
$(INSTALL_DATA) "./data/$(BIN_D).service" "$(DESTDIR)$(libdir)/systemd/system/$(BIN_D).service"
$(INSTALL_DATA) "./data/$(BIN_U).service" "$(DESTDIR)$(libdir)/systemd/user/$(BIN_U).service"
$(INSTALL_DATA) "./data/icons/asus_notif_yellow.png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_yellow.png" $(INSTALL_DATA) "./data/icons/asus_notif_yellow.png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_yellow.png"
$(INSTALL_DATA) "./data/icons/asus_notif_green.png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_green.png" $(INSTALL_DATA) "./data/icons/asus_notif_green.png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_green.png"
@@ -81,9 +99,24 @@ install-data:
$(INSTALL_DATA) "./data/icons/scalable/gpu-vfio.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/gpu-vfio.svg" $(INSTALL_DATA) "./data/icons/scalable/gpu-vfio.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/gpu-vfio.svg"
$(INSTALL_DATA) "./data/icons/scalable/notification-reboot.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/notification-reboot.svg" $(INSTALL_DATA) "./data/icons/scalable/notification-reboot.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/notification-reboot.svg"
cd rog-anime/data && find "./anime" -type f -exec $(INSTALL_DATA) "{}" "$(DESTDIR)$(datarootdir)/asusd/{}" \; install-data-asusd:
$(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) "./data/$(BIN_D).conf" "$(DESTDIR)$(datarootdir)/dbus-1/system.d/$(BIN_D).conf"
$(INSTALL_DATA) "./data/$(BIN_D).service" "$(DESTDIR)$(libdir)/systemd/system/$(BIN_D).service"
cd rog-anime/data && find "./anime" -type f -exec $(INSTALL_DATA) "{}" "$(DESTDIR_REALPATH)$(datarootdir)/asusd/{}" \;
install-data-asusd_user:
$(INSTALL_DATA) "./data/$(BIN_U).service" "$(DESTDIR)$(libdir)/systemd/user/$(BIN_U).service"
.PHONY: install-data-asusd install-data-asusd_user
install-data: install-data-asusd install-data-asusd_user install-data-rog_gui
install: install-program install-data install: install-program install-data
$(INSTALL_DATA) "./LICENSE" "$(DESTDIR)$(datarootdir)/asusctl/LICENSE"
uninstall: uninstall:
rm -f "$(DESTDIR)$(bindir)/$(BIN_ROG)" rm -f "$(DESTDIR)$(bindir)/$(BIN_ROG)"

View File

@@ -46,13 +46,13 @@ See the [rog-aura readme](./rog-aura/README.md) for more details.
Most ASUS gaming laptops that have a USB keyboard. If `lsusb` shows something similar Most ASUS gaming laptops that have a USB keyboard. If `lsusb` shows something similar
to this: to this:
``` ```plain
Bus 001 Device 002: ID 0b05:1866 ASUSTek Computer, Inc. N-KEY Device Bus 001 Device 002: ID 0b05:1866 ASUSTek Computer, Inc. N-KEY Device
``` ```
or or
``` ```plain
Bus 003 Device 002: ID 0b05:19b6 ASUSTek Computer, Inc. [unknown] Bus 003 Device 002: ID 0b05:19b6 ASUSTek Computer, Inc. [unknown]
``` ```
@@ -74,43 +74,56 @@ The list is a bit outdated as many features have been enabled in the Linux kerne
- [x] Toggle bios setting for boot/POST sound - [x] Toggle bios setting for boot/POST sound
- [x] Toggle GPU MUX (g-sync, or called MUX on 2022+ laptops) - [x] Toggle GPU MUX (g-sync, or called MUX on 2022+ laptops)
# GUI ## GUI
A gui is now in the repo - ROG Control Center. At this time it is still a WIP, but it has almost all features in place already. A gui is now in the repo - ROG Control Center. At this time it is still a WIP, but it has almost all features in place already.
**NOTE**: Xorg is not supported. **NOTE**: Xorg is not supported.
# BUILDING ## BUILDING
Rust and cargo are required, they can be installed from [rustup.rs](https://rustup.rs/) or from the distro repos if newer than 1.75. Rust and cargo are required, they can be installed from [rustup.rs](https://rustup.rs/).
Distro packaging should work with the stable toolchain. If your distro does not provide a recent Rust toolchain, install rustup and use the stable toolchain.
**fedora:** **fedora:**
dnf install cmake clang-devel libxkbcommon-devel systemd-devel expat-devel pcre2-devel libzstd-devel gtk3-devel ```sh
make dnf install cmake clang-devel libxkbcommon-devel systemd-devel expat-devel pcre2-devel libzstd-devel gtk3-devel
sudo make install make
sudo make install
```
**openSUSE:** **openSUSE:**
Works with KDE Plasma (without GTK packages) Works with KDE Plasma (without GTK packages)
zypper in -t pattern devel_basis ```sh
zypper in rustup make cmake clang-devel libxkbcommon-devel systemd-devel expat-devel pcre2-devel libzstd-devel gtk3-devel zypper in -t pattern devel_basis
make zypper in rustup make cmake clang-devel libxkbcommon-devel systemd-devel expat-devel pcre2-devel libzstd-devel gtk3-devel
sudo make install make
sudo make install
```
**Debian(unsuported):** **Debian(unsuported):**
officially unsuported,but you can still try and test it by yourself(some features may not be available). officially unsuported,but you can still try and test it by yourself(some features may not be available).
sudo apt install libclang-dev libudev-dev libfontconfig-dev build-essential cmake libxkbcommon-dev ```sh
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh sudo apt install libclang-dev libudev-dev libfontconfig-dev build-essential cmake libxkbcommon-dev
make curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
sudo make install make
sudo make install
```
**Ubuntu, Popos (unsuported):** **Ubuntu, Popos (unsuported):**
instructions removed as outdated ```sh
sudo apt install make cargo gcc pkg-config openssl libasound2-dev cmake build-essential python3 libfreetype6-dev libexpat1-dev libxcb-composite0-dev libssl-dev libx11-dev libfontconfig1-dev curl libclang-dev libudev-dev checkinstall libseat-dev libinput-dev libxkbcommon-dev libgbm-dev
make
sudo make install
```
## Installing ## Installing
@@ -128,15 +141,15 @@ You may also need to activate the service for debian install. If running Pop!\_O
If you are upgrading from a previous installed version, you will need to restart the service or reboot. If you are upgrading from a previous installed version, you will need to restart the service or reboot.
``` ```sh
$ systemctl daemon-reload && systemctl restart asusd systemctl daemon-reload && systemctl restart asusd
``` ```
## Uninstalling ## Uninstalling
Run `sudo make uninstall` in the source repo, and remove `/etc/asusd/`. Run `sudo make uninstall` in the source repo, and remove `/etc/asusd/`.
# Contributing ## Contributing
See `CONTRIBUTING.md`. Additionally, also do `cargo clean` and `cargo test` on first checkout to ensure the commit hooks are used (via `cargo-husky`). See `CONTRIBUTING.md`. Additionally, also do `cargo clean` and `cargo test` on first checkout to ensure the commit hooks are used (via `cargo-husky`).
@@ -144,17 +157,17 @@ Generation of the bindings with `make bindings` requires `typeshare` to be insta
Dbus introsepction XML requires with `make introspection` requires `anime_sim` to be running before starting `asusd`. Dbus introsepction XML requires with `make introspection` requires `anime_sim` to be running before starting `asusd`.
# OTHER ## OTHER
## AniMe Matrix simulator ### AniMe Matrix simulator
A simulator using SDL2 can be built using `cargo build --package rog_simulators` and run with `./target/debug/anime_sim`. Once started `asusd` will need restarting to pick it up. If running this sim on a laptop _with_ the display, the simulated display will be used instead of the physical display. A simulator using SDL2 can be built using `cargo build --package rog_simulators` and run with `./target/debug/anime_sim`. Once started `asusd` will need restarting to pick it up. If running this sim on a laptop _with_ the display, the simulated display will be used instead of the physical display.
## Supporting more laptops ### Supporting more laptops
Please file a support request. Please file a support request.
# License & Trademarks ## License & Trademarks
Mozilla Public License 2 (MPL-2.0) Mozilla Public License 2 (MPL-2.0)

View File

@@ -27,3 +27,15 @@ zbus.workspace = true
[dev-dependencies] [dev-dependencies]
rog_dbus = { path = "../rog-dbus" } rog_dbus = { path = "../rog-dbus" }
[package.metadata.deb]
license-file = ["../LICENSE", "4"]
extended-description = """\
An utility for Linux to control many aspects of various ASUS laptops
but can also be used with non-asus laptops with reduced features."""
depends = "$auto"
section = "utility"
priority = "optional"
assets = [
["target/release/asusctl", "usr/bin/", "755"],
]

View File

@@ -21,11 +21,14 @@ fn main() {
let brightness = args[2].parse::<f32>().unwrap(); let brightness = args[2].parse::<f32>().unwrap();
let anime_type = get_anime_type(); let anime_type = get_anime_type();
let mut seq = Sequences::new(anime_type); let mut seq = Sequences::new(anime_type);
seq.insert(0, &ActionLoader::AsusAnimation { seq.insert(
file: path.into(), 0,
time: rog_anime::AnimTime::Infinite, &ActionLoader::AsusAnimation {
brightness, file: path.into(),
}) time: rog_anime::AnimTime::Infinite,
brightness,
},
)
.unwrap(); .unwrap();
loop { loop {

View File

@@ -180,6 +180,7 @@ pub struct TwoColourSpeed {
pub zone: AuraZone, pub zone: AuraZone,
} }
#[allow(dead_code)]
#[derive(Debug, Clone, Default, Options)] #[derive(Debug, Clone, Default, Options)]
pub struct MultiZone { pub struct MultiZone {
#[options(help = "print help message")] #[options(help = "print help message")]
@@ -194,6 +195,7 @@ pub struct MultiZone {
pub colour4: Colour, pub colour4: Colour,
} }
#[allow(dead_code)]
#[derive(Debug, Clone, Default, Options)] #[derive(Debug, Clone, Default, Options)]
pub struct MultiColourSpeed { pub struct MultiColourSpeed {
#[options(help = "print help message")] #[options(help = "print help message")]

View File

@@ -54,6 +54,8 @@ pub enum CliCommand {
driver, some of the settings will be the same as the older platform interface" driver, some of the settings will be the same as the older platform interface"
)] )]
Armoury(ArmouryCommand), Armoury(ArmouryCommand),
#[options(name = "backlight", help = "Set screen backlight levels")]
Backlight(BacklightCommand),
} }
#[derive(Debug, Clone, Options)] #[derive(Debug, Clone, Options)]
@@ -72,6 +74,16 @@ pub struct ProfileCommand {
#[options(meta = "", help = "set the active profile")] #[options(meta = "", help = "set the active profile")]
pub profile_set: Option<PlatformProfile>, pub profile_set: Option<PlatformProfile>,
#[options(short = "a", meta = "", help = "set the profile to use on AC power")]
pub profile_set_ac: Option<PlatformProfile>,
#[options(
short = "b",
meta = "",
help = "set the profile to use on battery power"
)]
pub profile_set_bat: Option<PlatformProfile>,
} }
#[derive(Options)] #[derive(Options)]
@@ -102,3 +114,21 @@ pub struct ArmouryCommand {
)] )]
pub free: Vec<String>, pub free: Vec<String>,
} }
#[derive(Options)]
pub struct BacklightCommand {
#[options(help = "print help message")]
pub help: bool,
#[options(meta = "", help = "Set screen brightness <0-100>")]
pub screenpad_brightness: Option<i32>,
#[options(
meta = "",
help = "Set screenpad gamma brightness 0.5 - 2.2, 1.0 == linear"
)]
pub screenpad_gamma: Option<f32>,
#[options(
meta = "",
help = "Set screenpad brightness to sync with primary display"
)]
pub sync_screenpad_brightness: Option<bool>,
}

View File

@@ -19,6 +19,7 @@ use rog_dbus::list_iface_blocking;
use rog_dbus::scsi_aura::ScsiAuraProxyBlocking; use rog_dbus::scsi_aura::ScsiAuraProxyBlocking;
use rog_dbus::zbus_anime::AnimeProxyBlocking; use rog_dbus::zbus_anime::AnimeProxyBlocking;
use rog_dbus::zbus_aura::AuraProxyBlocking; use rog_dbus::zbus_aura::AuraProxyBlocking;
use rog_dbus::zbus_backlight::BacklightProxyBlocking;
use rog_dbus::zbus_fan_curves::FanCurvesProxyBlocking; use rog_dbus::zbus_fan_curves::FanCurvesProxyBlocking;
use rog_dbus::zbus_platform::PlatformProxyBlocking; use rog_dbus::zbus_platform::PlatformProxyBlocking;
use rog_dbus::zbus_slash::SlashProxyBlocking; use rog_dbus::zbus_slash::SlashProxyBlocking;
@@ -218,6 +219,7 @@ fn do_parsed(
Some(CliCommand::Slash(cmd)) => handle_slash(cmd)?, Some(CliCommand::Slash(cmd)) => handle_slash(cmd)?,
Some(CliCommand::Scsi(cmd)) => handle_scsi(cmd)?, Some(CliCommand::Scsi(cmd)) => handle_scsi(cmd)?,
Some(CliCommand::Armoury(cmd)) => handle_armoury_command(cmd)?, Some(CliCommand::Armoury(cmd)) => handle_armoury_command(cmd)?,
Some(CliCommand::Backlight(cmd)) => handle_backlight(cmd)?,
None => { None => {
if (!parsed.show_supported if (!parsed.show_supported
&& parsed.kbd_bright.is_none() && parsed.kbd_bright.is_none()
@@ -273,12 +275,18 @@ fn do_parsed(
return false; return false;
} }
if command.trim().starts_with("platform") if command.trim().starts_with("armoury")
&& !supported_interfaces.contains(&"xyz.ljones.AsusArmoury".to_string()) && !supported_interfaces.contains(&"xyz.ljones.AsusArmoury".to_string())
{ {
return false; return false;
} }
if command.trim().starts_with("backlight")
&& !supported_interfaces.contains(&"xyz.ljones.Backlight".to_string())
{
return false;
}
if !dev_type.is_old_laptop() if !dev_type.is_old_laptop()
&& !dev_type.is_tuf_laptop() && !dev_type.is_tuf_laptop()
&& command.trim().starts_with("aura-power-old") && command.trim().starts_with("aura-power-old")
@@ -381,6 +389,46 @@ fn do_gfx() {
println!("This command will be removed in future"); println!("This command will be removed in future");
} }
fn handle_backlight(cmd: &BacklightCommand) -> Result<(), Box<dyn std::error::Error>> {
if (cmd.screenpad_brightness.is_none()
&& cmd.screenpad_gamma.is_none()
&& cmd.sync_screenpad_brightness.is_none())
|| cmd.help
{
println!("Missing arg or command\n\n{}", cmd.self_usage());
let backlights = find_iface::<BacklightProxyBlocking>("xyz.ljones.Backlight")?;
for backlight in backlights {
println!("Current screenpad settings:");
println!(" Brightness: {}", backlight.screenpad_brightness()?);
println!(" Gamma: {}", backlight.screenpad_gamma()?);
println!(
" Sync with primary: {}",
backlight.screenpad_sync_with_primary()?
);
}
return Ok(());
}
let backlights = find_iface::<BacklightProxyBlocking>("xyz.ljones.Backlight")?;
for backlight in backlights {
if let Some(brightness) = cmd.screenpad_brightness {
backlight.set_screenpad_brightness(brightness)?;
}
if let Some(gamma) = cmd.screenpad_gamma {
backlight.set_screenpad_gamma(gamma.to_string().as_str())?;
}
if let Some(sync) = cmd.sync_screenpad_brightness {
backlight.set_screenpad_sync_with_primary(sync)?;
}
}
Ok(())
}
fn handle_anime(cmd: &AnimeCommand) -> Result<(), Box<dyn std::error::Error>> { fn handle_anime(cmd: &AnimeCommand) -> Result<(), Box<dyn std::error::Error>> {
if (cmd.command.is_none() if (cmd.command.is_none()
&& cmd.enable_display.is_none() && cmd.enable_display.is_none()
@@ -931,7 +979,13 @@ fn handle_throttle_profile(
return Err(ProfileError::NotSupported.into()); return Err(ProfileError::NotSupported.into());
} }
if !cmd.next && !cmd.list && cmd.profile_set.is_none() && !cmd.profile_get { if !cmd.next
&& !cmd.list
&& cmd.profile_set.is_none()
&& !cmd.profile_get
&& cmd.profile_set_ac.is_none()
&& cmd.profile_set_bat.is_none()
{
if !cmd.help { if !cmd.help {
println!("Missing arg or command\n"); println!("Missing arg or command\n");
} }
@@ -951,6 +1005,10 @@ fn handle_throttle_profile(
proxy.set_platform_profile(PlatformProfile::next(current, &choices))?; proxy.set_platform_profile(PlatformProfile::next(current, &choices))?;
} else if let Some(profile) = cmd.profile_set { } else if let Some(profile) = cmd.profile_set {
proxy.set_platform_profile(profile)?; proxy.set_platform_profile(profile)?;
} else if let Some(profile) = cmd.profile_set_ac {
proxy.set_platform_profile_on_ac(profile)?;
} else if let Some(profile) = cmd.profile_set_bat {
proxy.set_platform_profile_on_battery(profile)?;
} }
if cmd.list { if cmd.list {
@@ -961,6 +1019,11 @@ fn handle_throttle_profile(
if cmd.profile_get { if cmd.profile_get {
println!("Active profile is {current:?}"); println!("Active profile is {current:?}");
println!("Profile on AC is {:?}", proxy.platform_profile_on_ac()?);
println!(
"Profile on Battery is {:?}",
proxy.platform_profile_on_battery()?
);
} }
Ok(()) Ok(())
@@ -1121,11 +1184,15 @@ fn print_firmware_attr(attr: &AsusArmouryProxyBlocking) -> Result<(), Box<dyn st
Ok(()) Ok(())
} }
#[allow(clippy::manual_is_multiple_of)]
fn handle_armoury_command(cmd: &ArmouryCommand) -> Result<(), Box<dyn std::error::Error>> { fn handle_armoury_command(cmd: &ArmouryCommand) -> Result<(), Box<dyn std::error::Error>> {
{ {
if cmd.free.is_empty() || cmd.free.len() % 2 != 0 || cmd.help { // Avoid using `.is_multiple_of(2)` to satisfy the request. Use modulus check
// and simplify the boolean expression.
let odd_len = cmd.free.len() % 2 != 0;
if cmd.free.is_empty() || odd_len || cmd.help {
const USAGE: &str = "Usage: asusctl platform panel_overdrive 1 nv_dynamic_boost 5"; const USAGE: &str = "Usage: asusctl platform panel_overdrive 1 nv_dynamic_boost 5";
if cmd.free.len() % 2 != 0 { if odd_len {
println!( println!(
"Incorrect number of args, each attribute label must be paired with a setting:" "Incorrect number of args, each attribute label must be paired with a setting:"
); );

View File

@@ -32,3 +32,16 @@ config-traits = { path = "../config-traits" }
zbus.workspace = true zbus.workspace = true
env_logger.workspace = true env_logger.workspace = true
[package.metadata.deb]
license-file = ["../LICENSE", "4"]
extended-description = """\
An user utility for Linux to control fancy things on various ASUS laptops
like keyboard effects or anime matrix animation cycles."""
depends = "$auto"
section = "utility"
priority = "optional"
assets = [
["target/release/asusd-user", "usr/bin/", "755"],
["../asusd_user-fakeinstall/usr/lib/systemd/user/*", "usr/lib/systemd/user/", "644"],
]

View File

@@ -45,3 +45,19 @@ concat-idents.workspace = true
[dev-dependencies] [dev-dependencies]
cargo-husky.workspace = true cargo-husky.workspace = true
tempfile = "3"
[package.metadata.deb]
license-file = ["../LICENSE", "4"]
extended-description = """\
The dbus server for asusctl and rog-control-center applications."""
depends = "$auto"
section = "utility"
priority = "optional"
assets = [
["target/release/asusd", "usr/bin/", "755"],
["../asusd-fakeinstall/usr/lib/systemd/system/*", "usr/lib/systemd/system/", "644"],
["../asusd-fakeinstall/usr/lib/udev/rules.d/*", "usr/lib/udev/rules.d/", "644"],
["../asusd-fakeinstall/usr/share/asusd/*", "usr/share/share/asusd/", "644"],
["../asusd-fakeinstall/usr/share/dbus-1/system.d/*", "usr/share/dbus-1/system.d/", "644"],
]

View File

@@ -1,12 +1,12 @@
use std::sync::Arc; use std::sync::Arc;
use config_traits::StdConfig; use config_traits::StdConfig;
use futures_util::lock::Mutex;
use log::{debug, error, info}; use log::{debug, error, info};
use rog_platform::asus_armoury::{AttrValue, Attribute, FirmwareAttribute, FirmwareAttributes}; use rog_platform::asus_armoury::{AttrValue, Attribute, FirmwareAttribute, FirmwareAttributes};
use rog_platform::platform::{PlatformProfile, RogPlatform}; use rog_platform::platform::{PlatformProfile, RogPlatform};
use rog_platform::power::AsusPower; use rog_platform::power::AsusPower;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::sync::Mutex;
use zbus::object_server::SignalEmitter; use zbus::object_server::SignalEmitter;
use zbus::zvariant::{ObjectPath, OwnedObjectPath, OwnedValue, Type, Value}; use zbus::zvariant::{ObjectPath, OwnedObjectPath, OwnedValue, Type, Value};
use zbus::{fdo, interface, Connection}; use zbus::{fdo, interface, Connection};
@@ -27,6 +27,28 @@ fn dbus_path_for_attr(attr_name: &str) -> OwnedObjectPath {
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/{MOD_NAME}/{attr_name}")).into() ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/{MOD_NAME}/{attr_name}")).into()
} }
// Helper: return true when the attribute is effectively unsupported for
// the current power mode/device. We consider an attribute unsupported when
// its resolved min and max are equal (no available range), which indicates
// writes would be invalid. When true, callers should avoid attempting writes.
fn attr_unsupported(attr: &Attribute) -> bool {
let min = attr
.refresh_min_value()
.or(match attr.min_value() {
AttrValue::Integer(i) => Some(*i),
_ => None,
})
.unwrap_or(-1);
let max = attr
.refresh_max_value()
.or(match attr.max_value() {
AttrValue::Integer(i) => Some(*i),
_ => None,
})
.unwrap_or(-2); // different default so equality is false unless both present
min == max
}
#[derive(Clone)] #[derive(Clone)]
pub struct AsusArmouryAttribute { pub struct AsusArmouryAttribute {
attr: Attribute, attr: Attribute,
@@ -51,6 +73,29 @@ impl AsusArmouryAttribute {
} }
} }
pub fn attribute_name(&self) -> String {
String::from(self.attr.name())
}
fn resolve_i32_value(refreshed: Option<i32>, cached: &AttrValue) -> i32 {
refreshed
.or(match cached {
AttrValue::Integer(i) => Some(*i),
_ => None,
})
.unwrap_or(-1)
}
pub async fn emit_limits(&self, connection: &Connection) -> Result<(), RogError> {
let path = dbus_path_for_attr(self.attr.name());
let signal = SignalEmitter::new(connection, path)?;
self.min_value_changed(&signal).await?;
self.max_value_changed(&signal).await?;
self.scalar_increment_changed(&signal).await?;
self.current_value_changed(&signal).await?;
Ok(())
}
pub async fn move_to_zbus(self, connection: &Connection) -> Result<(), RogError> { pub async fn move_to_zbus(self, connection: &Connection) -> Result<(), RogError> {
let path = dbus_path_for_attr(self.attr.name()); let path = dbus_path_for_attr(self.attr.name());
connection connection
@@ -78,14 +123,20 @@ impl AsusArmouryAttribute {
let sig = signal_ctxt.clone(); let sig = signal_ctxt.clone();
tokio::spawn(async move { tokio::spawn(async move {
let mut buffer = [0; 32]; let mut buffer = [0; 32];
watch if let Ok(stream) = watch.into_event_stream(&mut buffer) {
.into_event_stream(&mut buffer) stream
.unwrap() .for_each(|_| async {
.for_each(|_| async { debug!("{} changed", name);
debug!("{} changed", name); ctrl.$fn_prop_changed(&sig).await.ok();
ctrl.$fn_prop_changed(&sig).await.ok(); })
}) .await;
.await; } else {
info!(
"inotify event stream failed for {} ({}). You can ignore this \
if unsupported",
name, $attr_str
);
}
}); });
} }
Err(e) => info!( Err(e) => info!(
@@ -107,36 +158,109 @@ impl AsusArmouryAttribute {
} }
} }
#[derive(Clone, Default)]
pub struct ArmouryAttributeRegistry {
attrs: Vec<AsusArmouryAttribute>,
}
impl ArmouryAttributeRegistry {
pub fn push(&mut self, attr: AsusArmouryAttribute) {
self.attrs.push(attr);
}
pub fn is_empty(&self) -> bool {
self.attrs.is_empty()
}
pub fn iter(&self) -> std::slice::Iter<'_, AsusArmouryAttribute> {
self.attrs.iter()
}
pub async fn emit_limits(&self, connection: &Connection) -> Result<(), RogError> {
let mut last_err: Option<RogError> = None;
for attr in &self.attrs {
if let Err(e) = attr.emit_limits(connection).await {
error!(
"Failed to emit updated limits for attribute '{}': {e:?}",
attr.attribute_name()
);
last_err = Some(e);
}
}
if let Some(err) = last_err {
Err(err)
} else {
Ok(())
}
}
}
impl crate::Reloadable for AsusArmouryAttribute { impl crate::Reloadable for AsusArmouryAttribute {
async fn reload(&mut self) -> Result<(), RogError> { async fn reload(&mut self) -> Result<(), RogError> {
info!("Reloading {}", self.attr.name()); info!("Reloading {}", self.attr.name());
let profile: PlatformProfile = self.platform.get_platform_profile()?.into(); let name: FirmwareAttribute = self.attr.name().into();
let power_plugged = self
.power if name.is_ppt() || name.is_dgpu() {
.get_online() let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
.map_err(|e| { let power_plugged = self
error!("Could not get power status: {e:?}"); .power
e .get_online()
}) .map_err(|e| {
.unwrap_or_default(); error!("Could not get power status: {e:?}");
let config = if power_plugged == 1 { e
&self.config.lock().await.ac_profile_tunings })
} else { .unwrap_or_default()
&self.config.lock().await.dc_profile_tunings == 1;
};
if let Some(tuning) = config.get(&profile) { let apply_value = {
if tuning.enabled { let config = self.config.lock().await;
if let Some(tune) = tuning.group.get(&self.name()) { config
.select_tunings_ref(power_plugged, profile)
.and_then(|tuning| {
if tuning.enabled {
tuning.group.get(&self.name()).copied()
} else {
None
}
})
};
if let Some(tune) = apply_value {
// Don't attempt writes for attributes that report min==0 and max==0
// (commonly means not supported in this power mode/device); skip
// applying stored tune in that case.
if self.attr.base_path_exists() && !attr_unsupported(&self.attr) {
self.attr self.attr
.set_current_value(&AttrValue::Integer(*tune)) .set_current_value(&AttrValue::Integer(tune))
.map_err(|e| { .map_err(|e| {
error!("Could not set {} value: {e:?}", self.attr.name()); error!("Could not set {} value: {e:?}", self.attr.name());
self.attr.base_path_exists(); self.attr.base_path_exists();
e e
})?; })?;
info!("Set {} to {:?}", self.attr.name(), tune); info!("Set {} to {:?}", self.attr.name(), tune);
} else {
debug!(
"Skipping apply for {} because attribute missing or unsupported (min==max)",
self.attr.name()
);
} }
} }
} else {
// Handle non-PPT attributes (boolean and other settings)
if let Some(saved_value) = self.config.lock().await.armoury_settings.get(&name) {
self.attr
.set_current_value(&AttrValue::Integer(*saved_value))
.map_err(|e| {
error!("Could not set {} value: {e:?}", self.attr.name());
self.attr.base_path_exists();
e
})?;
info!(
"Restored armoury setting {} to {:?}",
self.attr.name(),
saved_value
);
}
} }
Ok(()) Ok(())
@@ -193,7 +317,7 @@ impl AsusArmouryAttribute {
async fn restore_default(&self) -> fdo::Result<()> { async fn restore_default(&self) -> fdo::Result<()> {
self.attr.restore_default()?; self.attr.restore_default()?;
if self.name().is_ppt() { if self.name().is_ppt() || self.name().is_dgpu() {
let profile: PlatformProfile = self.platform.get_platform_profile()?.into(); let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
let power_plugged = self let power_plugged = self
.power .power
@@ -226,26 +350,20 @@ impl AsusArmouryAttribute {
#[zbus(property)] #[zbus(property)]
async fn min_value(&self) -> i32 { async fn min_value(&self) -> i32 {
match self.attr.min_value() { Self::resolve_i32_value(self.attr.refresh_min_value(), self.attr.min_value())
AttrValue::Integer(i) => *i,
_ => -1,
}
} }
#[zbus(property)] #[zbus(property)]
async fn max_value(&self) -> i32 { async fn max_value(&self) -> i32 {
match self.attr.max_value() { Self::resolve_i32_value(self.attr.refresh_max_value(), self.attr.max_value())
AttrValue::Integer(i) => *i,
_ => -1,
}
} }
#[zbus(property)] #[zbus(property)]
async fn scalar_increment(&self) -> i32 { async fn scalar_increment(&self) -> i32 {
match self.attr.scalar_increment() { Self::resolve_i32_value(
AttrValue::Integer(i) => *i, self.attr.refresh_scalar_increment(),
_ => -1, self.attr.scalar_increment(),
} )
} }
#[zbus(property)] #[zbus(property)]
@@ -258,7 +376,7 @@ impl AsusArmouryAttribute {
#[zbus(property)] #[zbus(property)]
async fn current_value(&self) -> fdo::Result<i32> { async fn current_value(&self) -> fdo::Result<i32> {
if self.name().is_ppt() { if self.name().is_ppt() || self.name().is_dgpu() {
let profile: PlatformProfile = self.platform.get_platform_profile()?.into(); let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
let power_plugged = self let power_plugged = self
.power .power
@@ -267,12 +385,15 @@ impl AsusArmouryAttribute {
error!("Could not get power status: {e:?}"); error!("Could not get power status: {e:?}");
e e
}) })
.unwrap_or_default(); .unwrap_or_default()
let mut config = self.config.lock().await; == 1;
let tuning = config.select_tunings(power_plugged == 1, profile); let config = self.config.lock().await;
if let Some(tune) = tuning.group.get(&self.name()) { if let Some(tuning) = config.select_tunings_ref(power_plugged, profile) {
return Ok(*tune); if let Some(tune) = tuning.group.get(&self.name()) {
} else if let AttrValue::Integer(i) = self.attr.default_value() { return Ok(*tune);
}
}
if let AttrValue::Integer(i) = self.attr.default_value() {
return Ok(*i); return Ok(*i);
} }
return Err(fdo::Error::Failed( return Err(fdo::Error::Failed(
@@ -288,9 +409,97 @@ impl AsusArmouryAttribute {
)) ))
} }
async fn stored_value_for_power(&self, on_ac: bool) -> fdo::Result<i32> {
if !(self.name().is_ppt() || self.name().is_dgpu()) {
return Err(fdo::Error::NotSupported(
"Stored values are only available for PPT/dGPU tunable attributes".to_string(),
));
}
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
let config = self.config.lock().await;
if let Some(tuning) = config.select_tunings_ref(on_ac, profile) {
if let Some(tune) = tuning.group.get(&self.name()) {
return Ok(*tune);
}
}
if let AttrValue::Integer(i) = self.attr.default_value() {
return Ok(*i);
}
Err(fdo::Error::Failed(
"Could not read stored value".to_string(),
))
}
async fn set_value_for_power(&mut self, on_ac: bool, value: i32) -> fdo::Result<()> {
if !(self.name().is_ppt() || self.name().is_dgpu()) {
return Err(fdo::Error::NotSupported(
"Setting stored values is only supported for PPT/dGPU tunable attributes"
.to_string(),
));
}
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
let apply_now;
{
let mut config = self.config.lock().await;
let tuning = config.select_tunings(on_ac, profile);
if let Some(tune) = tuning.group.get_mut(&self.name()) {
*tune = value;
} else {
tuning.group.insert(self.name(), value);
debug!(
"Store {} value for {} power = {}",
self.attr.name(),
if on_ac { "AC" } else { "DC" },
value
);
}
apply_now = tuning.enabled;
config.write();
}
if apply_now {
let power_plugged = self
.power
.get_online()
.map_err(|e| {
error!("Could not get power status: {e:?}");
e
})
.unwrap_or_default()
!= 0;
// Don't attempt writes for attributes that report min==0 and max==0
// (commonly means not supported in this power mode/device); skip
// applying stored value in that case.
if self.attr.base_path_exists() && !attr_unsupported(&self.attr) {
if power_plugged == on_ac {
self.attr
.set_current_value(&AttrValue::Integer(value))
.map_err(|e| {
error!("Could not set value: {e:?}");
e
})?;
}
} else {
debug!(
"Skipping immediate apply for {} because attribute missing or unsupported (min==max)",
self.attr.name()
);
}
}
Ok(())
}
#[zbus(property)] #[zbus(property)]
async fn set_current_value(&mut self, value: i32) -> fdo::Result<()> { async fn set_current_value(&mut self, value: i32) -> fdo::Result<()> {
if self.name().is_ppt() { if self.name().is_ppt() || self.name().is_dgpu() {
let profile: PlatformProfile = self.platform.get_platform_profile()?.into(); let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
let power_plugged = self let power_plugged = self
.power .power
@@ -311,12 +520,22 @@ impl AsusArmouryAttribute {
debug!("Store tuning config for {} = {:?}", self.attr.name(), value); debug!("Store tuning config for {} = {:?}", self.attr.name(), value);
} }
if tuning.enabled { if tuning.enabled {
self.attr // Don't attempt writes for attributes that report min==0 and max==0
.set_current_value(&AttrValue::Integer(value)) // (commonly means not supported in this power mode/device); skip
.map_err(|e| { // applying stored value in that case.
error!("Could not set value: {e:?}"); if self.attr.base_path_exists() && !attr_unsupported(&self.attr) {
e self.attr
})?; .set_current_value(&AttrValue::Integer(value))
.map_err(|e| {
error!("Could not set value: {e:?}");
e
})?;
} else {
debug!(
"Skipping apply for {} on set_current_value because attribute missing or unsupported (min==max)",
self.attr.name()
);
}
} }
} else { } else {
self.attr self.attr
@@ -357,13 +576,18 @@ impl AsusArmouryAttribute {
} }
} }
#[allow(clippy::too_many_arguments)]
pub async fn start_attributes_zbus( pub async fn start_attributes_zbus(
conn: &Connection, conn: Option<&Connection>,
platform: RogPlatform, platform: RogPlatform,
power: AsusPower, power: AsusPower,
attributes: FirmwareAttributes, attributes: FirmwareAttributes,
config: Arc<Mutex<Config>>, config: Arc<Mutex<Config>>,
) -> Result<(), RogError> { enable_zbus: bool,
profile_override: Option<rog_platform::platform::PlatformProfile>,
power_plugged_override: Option<bool>,
) -> Result<ArmouryAttributeRegistry, RogError> {
let mut registry = ArmouryAttributeRegistry::default();
for attr in attributes.attributes() { for attr in attributes.attributes() {
let mut attr = AsusArmouryAttribute::new( let mut attr = AsusArmouryAttribute::new(
attr.clone(), attr.clone(),
@@ -371,15 +595,123 @@ pub async fn start_attributes_zbus(
power.clone(), power.clone(),
config.clone(), config.clone(),
); );
attr.reload().await?;
let path = dbus_path_for_attr(attr.attr.name()); let registry_attr = attr.clone();
let sig = zbus::object_server::SignalEmitter::new(conn, path)?;
attr.watch_and_notify(sig).await?;
attr.move_to_zbus(conn).await?; // Only perform the full reload (which may query the platform/power sysfs)
// when zbus is enabled. Tests using the no-zbus mode skip the reload and
// emulate the reload/apply behavior to avoid depending on udev/sysfs.
if enable_zbus {
if let Err(e) = attr.reload().await {
error!(
"Skipping attribute '{}' due to reload error: {e:?}",
attr.attr.name()
);
// continue with others
continue;
}
}
let attr_name = attr.attribute_name();
// If zbus is enabled and a connection is provided, create the SignalEmitter,
// start watchers and register the object on zbus. Tests can call this function
// with enable_zbus=false and conn=None to skip DBus registration and watchers.
if !enable_zbus {
// Emulate reload logic but prefer overrides when provided to avoid dependency on udev/sysfs in tests
let name: rog_platform::asus_armoury::FirmwareAttribute = attr.attr.name().into();
if name.is_ppt() || name.is_dgpu() {
// determine profile
let profile = if let Some(p) = profile_override {
p
} else {
match attr.platform.get_platform_profile() {
Ok(p) => p.into(),
Err(_) => rog_platform::platform::PlatformProfile::Balanced,
}
};
// determine power plugged
let power_plugged = if let Some(v) = power_plugged_override {
v
} else {
match attr.power.get_online() {
Ok(v) => v == 1,
Err(_) => false,
}
};
let apply_value = {
let config = attr.config.lock().await;
config
.select_tunings_ref(power_plugged, profile)
.and_then(|tuning| {
if tuning.enabled {
tuning.group.get(&attr.name()).copied()
} else {
None
}
})
};
if let Some(tune) = apply_value {
attr.attr
.set_current_value(&AttrValue::Integer(tune))
.map_err(|e| {
error!("Could not set {} value: {e:?}", attr.attr.name());
e
})?;
}
} else if let Some(saved_value) = attr.config.lock().await.armoury_settings.get(&name) {
attr.attr
.set_current_value(&AttrValue::Integer(*saved_value))
.map_err(|e| {
error!("Could not set {} value: {e:?}", attr.attr.name());
e
})?;
info!(
"Restored armoury setting {} to {:?}",
attr.attr.name(),
saved_value
);
}
registry.push(registry_attr);
continue;
}
// If zbus is enabled and a connection is provided, create the SignalEmitter,
// start watchers and register the object on zbus. Tests can call this function
// with enable_zbus=false and conn=None to skip DBus registration and watchers.
if enable_zbus {
if let Some(connection) = conn {
let path = dbus_path_for_attr(attr_name.as_str());
match zbus::object_server::SignalEmitter::new(connection, path) {
Ok(sig) => {
if let Err(e) = attr.watch_and_notify(sig).await {
error!("Failed to start watcher for '{}': {e:?}", attr.attr.name());
}
}
Err(e) => {
error!(
"Failed to create SignalEmitter for '{}': {e:?}",
attr.attr.name()
);
}
}
if let Err(e) = attr.move_to_zbus(connection).await {
error!("Failed to register attribute '{attr_name}' on zbus: {e:?}");
continue;
}
} else {
error!("zbus enabled but no Connection provided for attribute registration");
}
}
registry.push(registry_attr);
} }
Ok(()) Ok(registry)
} }
pub async fn set_config_or_default( pub async fn set_config_or_default(
@@ -390,36 +722,132 @@ pub async fn set_config_or_default(
) { ) {
for attr in attrs.attributes().iter() { for attr in attrs.attributes().iter() {
let name: FirmwareAttribute = attr.name().into(); let name: FirmwareAttribute = attr.name().into();
if name.is_ppt() { if name.is_ppt() || name.is_dgpu() {
let tuning = config.select_tunings(power_plugged, profile); let tuning = config.select_tunings(power_plugged, profile);
if !tuning.enabled { if !tuning.enabled {
debug!("Tuning group is not enabled, skipping"); debug!("Tuning group is not enabled, skipping");
return; continue;
} }
// Determine once whether attribute is present and supports a writable range
let supported = attr.base_path_exists() && !attr_unsupported(attr);
if let Some(tune) = tuning.group.get(&name) { if let Some(tune) = tuning.group.get(&name) {
attr.set_current_value(&AttrValue::Integer(*tune)) if supported {
.map_err(|e| { attr.set_current_value(&AttrValue::Integer(*tune))
error!("Failed to set {}: {e}", <&str>::from(name)); .map_err(|e| {
}) error!("Failed to set {}: {e}", <&str>::from(name));
.ok(); })
} else { .ok();
let default = attr.default_value(); } else {
attr.set_current_value(default) debug!(
.map_err(|e| { "Skipping apply for {} in set_config_or_default because attribute missing or unsupported",
error!("Failed to set {}: {e}", <&str>::from(name)); <&str>::from(name)
})
.ok();
if let AttrValue::Integer(i) = default {
tuning.group.insert(name, *i);
info!(
"Set default tuning config for {} = {:?}",
<&str>::from(name),
i
); );
// config.write();
} }
} else {
// Only attempt to apply defaults when the attribute supports a range
if supported {
let default = attr.default_value();
attr.set_current_value(default)
.map_err(|e| {
error!("Failed to set {}: {e}", <&str>::from(name));
})
.ok();
if let AttrValue::Integer(i) = default {
tuning.group.insert(name, *i);
info!(
"Set default tuning config for {} = {:?}",
<&str>::from(name),
i
);
// config.write();
}
} else {
debug!(
"Skipping default apply for {} in set_config_or_default because attribute missing or unsupported",
<&str>::from(name)
);
}
}
} else {
// Handle non-PPT attributes (boolean and other settings)
if let Some(saved_value) = config.armoury_settings.get(&name) {
attr.set_current_value(&AttrValue::Integer(*saved_value))
.map_err(|e| {
error!("Failed to set {}: {e}", <&str>::from(name));
})
.ok();
info!(
"Restored armoury setting for {} = {:?}",
<&str>::from(name),
saved_value
);
} }
} }
} }
} }
// Internal helper to store a tuning value into the correct per-profile, per-power map.
// This centralizes the behavior so tests can validate storage semantics.
#[allow(dead_code)]
fn insert_tuning_value(
config: &mut Config,
on_ac: bool,
profile: PlatformProfile,
name: rog_platform::asus_armoury::FirmwareAttribute,
value: i32,
) {
let tuning = config.select_tunings(on_ac, profile);
if let Some(t) = tuning.group.get_mut(&name) {
*t = value;
} else {
tuning.group.insert(name, value);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::Config;
use rog_platform::asus_armoury::FirmwareAttribute;
use rog_platform::platform::PlatformProfile;
#[test]
fn insert_nv_tuning_is_per_profile_and_power() {
let mut cfg = Config::default();
let profile = PlatformProfile::Performance;
// Insert value for AC
insert_tuning_value(
&mut cfg,
true,
profile,
FirmwareAttribute::NvDynamicBoost,
7,
);
// Value should be present in ac_profile_tunings
let t_ac = cfg.select_tunings_ref(true, profile).unwrap();
assert_eq!(t_ac.group.get(&FirmwareAttribute::NvDynamicBoost), Some(&7));
// Insert separate value for DC
insert_tuning_value(
&mut cfg,
false,
profile,
FirmwareAttribute::NvDynamicBoost,
3,
);
let t_dc = cfg.select_tunings_ref(false, profile).unwrap();
assert_eq!(t_dc.group.get(&FirmwareAttribute::NvDynamicBoost), Some(&3));
}
#[test]
fn non_ppt_attribute_stores_in_armoury_settings() {
let mut cfg = Config::default();
// Non-PPT/dGPU attribute, e.g., BootSound
let name = FirmwareAttribute::BootSound;
// Simulate setting armoury setting
cfg.armoury_settings.insert(name, 1);
assert_eq!(cfg.armoury_settings.get(&name), Some(&1));
}
}

View File

@@ -8,7 +8,6 @@ use std::sync::Arc;
use std::thread::sleep; use std::thread::sleep;
use config_traits::StdConfig; use config_traits::StdConfig;
use futures_util::lock::Mutex;
use log::{debug, error, info, warn}; use log::{debug, error, info, warn};
use rog_anime::usb::{ use rog_anime::usb::{
pkt_flush, pkt_set_brightness, pkt_set_enable_display, pkt_set_enable_powersave_anim, pkt_flush, pkt_set_brightness, pkt_set_enable_display, pkt_set_enable_powersave_anim,
@@ -17,6 +16,7 @@ use rog_anime::usb::{
use rog_anime::{ActionData, AnimeDataBuffer, AnimePacketType}; use rog_anime::{ActionData, AnimeDataBuffer, AnimePacketType};
use rog_platform::hid_raw::HidRaw; use rog_platform::hid_raw::HidRaw;
use rog_platform::usb_raw::USBRaw; use rog_platform::usb_raw::USBRaw;
use tokio::sync::Mutex;
use self::config::{AniMeConfig, AniMeConfigCached}; use self::config::{AniMeConfig, AniMeConfigCached};
use crate::error::RogError; use crate::error::RogError;
@@ -51,7 +51,7 @@ impl AniMe {
/// Will fail if something is already holding the config lock /// Will fail if something is already holding the config lock
async fn do_init_cache(&mut self) { async fn do_init_cache(&mut self) {
if let Some(mut config) = self.config.try_lock() { if let Ok(mut config) = self.config.try_lock() {
if let Err(e) = self.cache.init_from_config(&config, config.anime_type) { if let Err(e) = self.cache.init_from_config(&config, config.anime_type) {
error!( error!(
"Trying to cache the Anime Config failed, will reset to default config: {e:?}" "Trying to cache the Anime Config failed, will reset to default config: {e:?}"

View File

@@ -69,7 +69,11 @@ impl AniMeZbus {
/// it is restarted /// it is restarted
async fn write(&self, input: AnimeDataBuffer) -> zbus::fdo::Result<()> { async fn write(&self, input: AnimeDataBuffer) -> zbus::fdo::Result<()> {
let bright = self.0.config.lock().await.display_brightness; let bright = self.0.config.lock().await.display_brightness;
self.0.set_builtins_enabled(false, bright).await?; if self.0.config.lock().await.builtin_anims_enabled {
// This clears the display, causing flickers if done indiscriminately on every
// write. Therefore, we guard it behind a config check.
self.0.set_builtins_enabled(false, bright).await?;
}
self.0.thread_exit.store(true, Ordering::SeqCst); self.0.thread_exit.store(true, Ordering::SeqCst);
self.0.write_data_buffer(input).await.map_err(|err| { self.0.write_data_buffer(input).await.map_err(|err| {
warn!("ctrl_anime::run_animation:callback {}", err); warn!("ctrl_anime::run_animation:callback {}", err);
@@ -81,7 +85,7 @@ impl AniMeZbus {
/// Set base brightness level /// Set base brightness level
#[zbus(property)] #[zbus(property)]
async fn brightness(&self) -> Brightness { async fn brightness(&self) -> Brightness {
if let Some(config) = self.0.config.try_lock() { if let Ok(config) = self.0.config.try_lock() {
return config.display_brightness; return config.display_brightness;
} }
Brightness::Off Brightness::Off
@@ -113,7 +117,7 @@ impl AniMeZbus {
#[zbus(property)] #[zbus(property)]
async fn builtins_enabled(&self) -> bool { async fn builtins_enabled(&self) -> bool {
if let Some(config) = self.0.config.try_lock() { if let Ok(config) = self.0.config.try_lock() {
return config.builtin_anims_enabled; return config.builtin_anims_enabled;
} }
false false
@@ -158,7 +162,7 @@ impl AniMeZbus {
#[zbus(property)] #[zbus(property)]
async fn builtin_animations(&self) -> Animations { async fn builtin_animations(&self) -> Animations {
if let Some(config) = self.0.config.try_lock() { if let Ok(config) = self.0.config.try_lock() {
return config.builtin_anims; return config.builtin_anims;
} }
Animations::default() Animations::default()
@@ -191,7 +195,7 @@ impl AniMeZbus {
#[zbus(property)] #[zbus(property)]
async fn enable_display(&self) -> bool { async fn enable_display(&self) -> bool {
if let Some(config) = self.0.config.try_lock() { if let Ok(config) = self.0.config.try_lock() {
return config.display_enabled; return config.display_enabled;
} }
false false
@@ -214,7 +218,7 @@ impl AniMeZbus {
#[zbus(property)] #[zbus(property)]
async fn off_when_unplugged(&self) -> bool { async fn off_when_unplugged(&self) -> bool {
if let Some(config) = self.0.config.try_lock() { if let Ok(config) = self.0.config.try_lock() {
return config.off_when_unplugged; return config.off_when_unplugged;
} }
false false
@@ -241,7 +245,7 @@ impl AniMeZbus {
#[zbus(property)] #[zbus(property)]
async fn off_when_suspended(&self) -> bool { async fn off_when_suspended(&self) -> bool {
if let Some(config) = self.0.config.try_lock() { if let Ok(config) = self.0.config.try_lock() {
return config.off_when_suspended; return config.off_when_suspended;
} }
false false
@@ -257,7 +261,7 @@ impl AniMeZbus {
#[zbus(property)] #[zbus(property)]
async fn off_when_lid_closed(&self) -> bool { async fn off_when_lid_closed(&self) -> bool {
if let Some(config) = self.0.config.try_lock() { if let Ok(config) = self.0.config.try_lock() {
return config.off_when_lid_closed; return config.off_when_lid_closed;
} }
false false

View File

@@ -82,8 +82,9 @@ impl AuraConfig {
config config
.builtins .builtins
.insert(*n, AuraEffect::default_with_mode(*n)); .insert(*n, AuraEffect::default_with_mode(*n));
}
if !config.support_data.basic_zones.is_empty() { if !config.support_data.basic_zones.is_empty() {
for n in &config.support_data.basic_modes {
let mut default = vec![]; let mut default = vec![];
for (i, tmp) in config.support_data.basic_zones.iter().enumerate() { for (i, tmp) in config.support_data.basic_zones.iter().enumerate() {
default.push(AuraEffect { default.push(AuraEffect {
@@ -118,14 +119,14 @@ impl AuraConfig {
self.multizone_on = false; self.multizone_on = false;
} else { } else {
if let Some(multi) = self.multizone.as_mut() { if let Some(multi) = self.multizone.as_mut() {
if let Some(fx) = multi.get_mut(effect.mode()) { if let Some(fx_vec) = multi.get_mut(effect.mode()) {
for fx in fx.iter_mut() { for fx in fx_vec.iter_mut() {
if fx.zone == effect.zone { if fx.zone == effect.zone {
*fx = effect; *fx = effect;
return; return;
} }
} }
fx.push(effect); fx_vec.push(effect);
} else { } else {
multi.insert(*effect.mode(), vec![effect]); multi.insert(*effect.mode(), vec![effect]);
} }
@@ -230,6 +231,8 @@ impl AuraConfig {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::sync::{Mutex, MutexGuard, OnceLock};
use rog_aura::keyboard::AuraPowerState; use rog_aura::keyboard::AuraPowerState;
use rog_aura::{ use rog_aura::{
AuraEffect, AuraModeNum, AuraZone, Colour, Direction, LedBrightness, PowerZones, Speed, AuraEffect, AuraModeNum, AuraZone, Colour, Direction, LedBrightness, PowerZones, Speed,
@@ -237,8 +240,20 @@ mod tests {
use super::AuraConfig; use super::AuraConfig;
// Global mutex to serialize tests that rely on process-wide environment
// variables
static TEST_MUTEX: OnceLock<Mutex<()>> = OnceLock::new();
fn test_lock() -> MutexGuard<'static, ()> {
TEST_MUTEX
.get_or_init(|| Mutex::new(()))
.lock()
.expect("TEST_MUTEX poisoned")
}
#[test] #[test]
fn set_multizone_4key_config() { fn set_multizone_4key_config() {
let _guard = test_lock();
std::env::set_var("BOARD_NAME", ""); std::env::set_var("BOARD_NAME", "");
let mut config = AuraConfig::new("19b6"); let mut config = AuraConfig::new("19b6");
@@ -294,30 +309,43 @@ mod tests {
let res = config.multizone.unwrap(); let res = config.multizone.unwrap();
let sta = res.get(&AuraModeNum::Static).unwrap(); let sta = res.get(&AuraModeNum::Static).unwrap();
assert_eq!(sta.len(), 4); assert_eq!(sta.len(), 4);
assert_eq!(sta[0].colour1, Colour { assert_eq!(
r: 0xff, sta[0].colour1,
g: 0x00, Colour {
b: 0xff r: 0xff,
}); g: 0x00,
assert_eq!(sta[1].colour1, Colour { b: 0xff
r: 0x00, }
g: 0xff, );
b: 0xff assert_eq!(
}); sta[1].colour1,
assert_eq!(sta[2].colour1, Colour { Colour {
r: 0xff, r: 0x00,
g: 0xff, g: 0xff,
b: 0x00 b: 0xff
}); }
assert_eq!(sta[3].colour1, Colour { );
r: 0x00, assert_eq!(
g: 0xff, sta[2].colour1,
b: 0x00 Colour {
}); r: 0xff,
g: 0xff,
b: 0x00
}
);
assert_eq!(
sta[3].colour1,
Colour {
r: 0x00,
g: 0xff,
b: 0x00
}
);
} }
#[test] #[test]
fn set_multizone_multimode_config() { fn set_multizone_multimode_config() {
let _guard = test_lock();
std::env::set_var("BOARD_NAME", ""); std::env::set_var("BOARD_NAME", "");
let mut config = AuraConfig::new("19b6"); let mut config = AuraConfig::new("19b6");
@@ -366,51 +394,65 @@ mod tests {
#[test] #[test]
fn verify_0x1866_g531i() { fn verify_0x1866_g531i() {
let _guard = test_lock();
std::env::set_var("BOARD_NAME", "G513I"); std::env::set_var("BOARD_NAME", "G513I");
let mut config = AuraConfig::new("1866"); let mut config = AuraConfig::new("1866");
assert_eq!(config.brightness, LedBrightness::Med); assert_eq!(config.brightness, LedBrightness::Med);
assert_eq!(config.builtins.len(), 5); assert_eq!(config.builtins.len(), 5);
assert_eq!(config.builtins.first_entry().unwrap().get(), &AuraEffect { assert_eq!(
mode: AuraModeNum::Static, config.builtins.first_entry().unwrap().get(),
zone: AuraZone::None, &AuraEffect {
colour1: Colour { r: 166, g: 0, b: 0 }, mode: AuraModeNum::Static,
colour2: Colour { r: 0, g: 0, b: 0 }, zone: AuraZone::None,
speed: Speed::Med, colour1: Colour { r: 166, g: 0, b: 0 },
direction: Direction::Right colour2: Colour { r: 0, g: 0, b: 0 },
}); speed: Speed::Med,
direction: Direction::Right
}
);
assert_eq!(config.enabled.states.len(), 1); assert_eq!(config.enabled.states.len(), 1);
assert_eq!(config.enabled.states[0], AuraPowerState { assert_eq!(
zone: PowerZones::KeyboardAndLightbar, config.enabled.states[0],
boot: true, AuraPowerState {
awake: true, zone: PowerZones::KeyboardAndLightbar,
sleep: true, boot: true,
shutdown: true awake: true,
}); sleep: true,
shutdown: true
}
);
} }
#[test] #[test]
fn verify_0x19b6_g634j() { fn verify_0x19b6_g634j() {
let _guard = test_lock();
std::env::set_var("BOARD_NAME", "G634J"); std::env::set_var("BOARD_NAME", "G634J");
let mut config = AuraConfig::new("19b6"); let mut config = AuraConfig::new("19b6");
assert_eq!(config.brightness, LedBrightness::Med); assert_eq!(config.brightness, LedBrightness::Med);
assert_eq!(config.builtins.len(), 12); assert_eq!(config.builtins.len(), 12);
assert_eq!(config.builtins.first_entry().unwrap().get(), &AuraEffect { assert_eq!(
mode: AuraModeNum::Static, config.builtins.first_entry().unwrap().get(),
zone: AuraZone::None, &AuraEffect {
colour1: Colour { r: 166, g: 0, b: 0 }, mode: AuraModeNum::Static,
colour2: Colour { r: 0, g: 0, b: 0 }, zone: AuraZone::None,
speed: Speed::Med, colour1: Colour { r: 166, g: 0, b: 0 },
direction: Direction::Right colour2: Colour { r: 0, g: 0, b: 0 },
}); speed: Speed::Med,
direction: Direction::Right
}
);
assert_eq!(config.enabled.states.len(), 4); assert_eq!(config.enabled.states.len(), 4);
assert_eq!(config.enabled.states[0], AuraPowerState { assert_eq!(
zone: PowerZones::Keyboard, config.enabled.states[0],
boot: true, AuraPowerState {
awake: true, zone: PowerZones::Keyboard,
sleep: true, boot: true,
shutdown: true awake: true,
}); sleep: true,
shutdown: true
}
);
} }
} }

View File

@@ -2,13 +2,13 @@ use std::sync::Arc;
use config::AuraConfig; use config::AuraConfig;
use config_traits::StdConfig; use config_traits::StdConfig;
use futures_util::lock::{Mutex, MutexGuard};
use log::info; use log::info;
use rog_aura::keyboard::{AuraLaptopUsbPackets, LedUsbPackets}; use rog_aura::keyboard::{AuraLaptopUsbPackets, LedUsbPackets};
use rog_aura::usb::{AURA_LAPTOP_LED_APPLY, AURA_LAPTOP_LED_SET}; use rog_aura::usb::{AURA_LAPTOP_LED_APPLY, AURA_LAPTOP_LED_SET};
use rog_aura::{AuraDeviceType, AuraEffect, LedBrightness, PowerZones, AURA_LAPTOP_LED_MSG_LEN}; use rog_aura::{AuraDeviceType, AuraEffect, LedBrightness, PowerZones, AURA_LAPTOP_LED_MSG_LEN};
use rog_platform::hid_raw::HidRaw; use rog_platform::hid_raw::HidRaw;
use rog_platform::keyboard_led::KeyboardBacklight; use rog_platform::keyboard_led::KeyboardBacklight;
use tokio::sync::{Mutex, MutexGuard};
use crate::error::RogError; use crate::error::RogError;
@@ -28,7 +28,7 @@ impl Aura {
Ok(()) Ok(())
} }
pub async fn lock_config(&self) -> MutexGuard<AuraConfig> { pub async fn lock_config(&self) -> MutexGuard<'_, AuraConfig> {
self.config.lock().await self.config.lock().await
} }

View File

@@ -112,7 +112,7 @@ impl AuraZbus {
// entirely possible to deadlock here, so use try instead of lock() // entirely possible to deadlock here, so use try instead of lock()
// let ctrl = self.0.lock().await; // let ctrl = self.0.lock().await;
// Ok(config.current_mode) // Ok(config.current_mode)
if let Some(config) = self.0.config.try_lock() { if let Ok(config) = self.0.config.try_lock() {
Ok(config.current_mode) Ok(config.current_mode)
} else { } else {
Err(ZbErr::Failed("Aura control couldn't lock self".to_string())) Err(ZbErr::Failed("Aura control couldn't lock self".to_string()))
@@ -140,7 +140,7 @@ impl AuraZbus {
#[zbus(property)] #[zbus(property)]
async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> { async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> {
// entirely possible to deadlock here, so use try instead of lock() // entirely possible to deadlock here, so use try instead of lock()
if let Some(config) = self.0.config.try_lock() { if let Ok(config) = self.0.config.try_lock() {
let mode = config.current_mode; let mode = config.current_mode;
match config.builtins.get(&mode) { match config.builtins.get(&mode) {
Some(effect) => Ok(effect.clone()), Some(effect) => Ok(effect.clone()),

View File

@@ -4,15 +4,16 @@
// - Add it to Zbus server // - Add it to Zbus server
// - If udev sees device removed then remove the zbus path // - If udev sees device removed then remove the zbus path
use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use dmi_id::DMIID; use dmi_id::DMIID;
use futures_lite::future::block_on; use futures_lite::future::block_on;
use futures_util::lock::Mutex;
use log::{debug, error, info, warn}; use log::{debug, error, info, warn};
use mio::{Events, Interest, Poll, Token}; use mio::{Events, Interest, Poll, Token};
use rog_platform::error::PlatformError; use rog_platform::error::PlatformError;
use rog_platform::hid_raw::HidRaw; use rog_platform::hid_raw::HidRaw;
use tokio::sync::Mutex;
use udev::{Device, MonitorBuilder}; use udev::{Device, MonitorBuilder};
use zbus::zvariant::{ObjectPath, OwnedObjectPath}; use zbus::zvariant::{ObjectPath, OwnedObjectPath};
use zbus::Connection; use zbus::Connection;
@@ -92,16 +93,41 @@ fn dev_prop_matches(dev: &Device, prop: &str, value: &str) -> bool {
pub struct AsusDevice { pub struct AsusDevice {
device: DeviceHandle, device: DeviceHandle,
dbus_path: OwnedObjectPath, dbus_path: OwnedObjectPath,
hid_key: Option<String>,
} }
/// Shared alias for the HidRaw handle map used throughout this module.
type HidHandleMap = Arc<Mutex<HashMap<String, Arc<Mutex<HidRaw>>>>>;
pub struct DeviceManager { pub struct DeviceManager {
_dbus_connection: Connection, _dbus_connection: Connection,
_hid_handles: HidHandleMap,
} }
impl DeviceManager { impl DeviceManager {
async fn get_or_create_hid_handle(
handles: &HidHandleMap,
endpoint: &Device,
) -> Result<(Arc<Mutex<HidRaw>>, String), RogError> {
let dev_node = endpoint
.devnode()
.ok_or_else(|| RogError::MissingFunction("hidraw devnode missing".to_string()))?;
let key = dev_node.to_string_lossy().to_string();
if let Some(existing) = handles.lock().await.get(&key).cloned() {
return Ok((existing, key));
}
let hidraw = HidRaw::from_device(endpoint.clone())?;
let handle = Arc::new(Mutex::new(hidraw));
handles.lock().await.insert(key.clone(), handle.clone());
Ok((handle, key))
}
async fn init_hid_devices( async fn init_hid_devices(
connection: &Connection, connection: &Connection,
device: Device, device: Device,
handles: HidHandleMap,
) -> Result<Vec<AsusDevice>, RogError> { ) -> Result<Vec<AsusDevice>, RogError> {
let mut devices = Vec::new(); let mut devices = Vec::new();
if let Some(usb_device) = device.parent_with_subsystem_devtype("usb", "usb_device")? { if let Some(usb_device) = device.parent_with_subsystem_devtype("usb", "usb_device")? {
@@ -116,9 +142,10 @@ impl DeviceManager {
// 1. Generate an interface path // 1. Generate an interface path
// 2. Create the device // 2. Create the device
// Use the top-level endpoint, not the parent // Use the top-level endpoint, not the parent
if let Ok(hidraw) = HidRaw::from_device(device) { if let Ok((dev, hid_key)) =
Self::get_or_create_hid_handle(&handles, &device).await
{
debug!("Testing device {usb_id:?}"); debug!("Testing device {usb_id:?}");
let dev = Arc::new(Mutex::new(hidraw));
// SLASH DEVICE // SLASH DEVICE
if let Ok(dev_type) = DeviceHandle::new_slash_hid( if let Ok(dev_type) = DeviceHandle::new_slash_hid(
dev.clone(), dev.clone(),
@@ -134,6 +161,7 @@ impl DeviceManager {
devices.push(AsusDevice { devices.push(AsusDevice {
device: dev_type, device: dev_type,
dbus_path: path, dbus_path: path,
hid_key: Some(hid_key.clone()),
}); });
} }
} }
@@ -152,6 +180,7 @@ impl DeviceManager {
devices.push(AsusDevice { devices.push(AsusDevice {
device: dev_type, device: dev_type,
dbus_path: path, dbus_path: path,
hid_key: Some(hid_key.clone()),
}); });
} }
} }
@@ -170,9 +199,12 @@ impl DeviceManager {
devices.push(AsusDevice { devices.push(AsusDevice {
device: dev_type, device: dev_type,
dbus_path: path, dbus_path: path,
hid_key: Some(hid_key),
}); });
} }
} }
} else {
warn!("Failed to initialise shared hid handle for {usb_id:?}");
} }
} }
} }
@@ -181,7 +213,10 @@ impl DeviceManager {
} }
/// To be called on daemon startup /// To be called on daemon startup
async fn init_all_hid(connection: &Connection) -> Result<Vec<AsusDevice>, RogError> { async fn init_all_hid(
connection: &Connection,
handles: HidHandleMap,
) -> Result<Vec<AsusDevice>, RogError> {
// track and ensure we use only one hidraw per prod_id // track and ensure we use only one hidraw per prod_id
// let mut interfaces = HashSet::new(); // let mut interfaces = HashSet::new();
let mut devices: Vec<AsusDevice> = Vec::new(); let mut devices: Vec<AsusDevice> = Vec::new();
@@ -200,7 +235,7 @@ impl DeviceManager {
.scan_devices() .scan_devices()
.map_err(|e| PlatformError::IoPath("enumerator".to_owned(), e))? .map_err(|e| PlatformError::IoPath("enumerator".to_owned(), e))?
{ {
devices.append(&mut Self::init_hid_devices(connection, device).await?); devices.append(&mut Self::init_hid_devices(connection, device, handles.clone()).await?);
} }
Ok(devices) Ok(devices)
@@ -228,6 +263,7 @@ impl DeviceManager {
return Some(AsusDevice { return Some(AsusDevice {
device: dev_type, device: dev_type,
dbus_path: path, dbus_path: path,
hid_key: None,
}); });
} }
} }
@@ -275,10 +311,13 @@ impl DeviceManager {
Ok(devices) Ok(devices)
} }
pub async fn find_all_devices(connection: &Connection) -> Vec<AsusDevice> { pub async fn find_all_devices(
connection: &Connection,
handles: Arc<Mutex<HashMap<String, Arc<Mutex<HidRaw>>>>>,
) -> Vec<AsusDevice> {
let mut devices: Vec<AsusDevice> = Vec::new(); let mut devices: Vec<AsusDevice> = Vec::new();
// HID first, always // HID first, always
if let Ok(devs) = &mut Self::init_all_hid(connection).await { if let Ok(devs) = &mut Self::init_all_hid(connection, handles.clone()).await {
devices.append(devs); devices.append(devs);
} }
// USB after, need to check if HID picked something up and if so, skip it // USB after, need to check if HID picked something up and if so, skip it
@@ -306,6 +345,7 @@ impl DeviceManager {
devices.push(AsusDevice { devices.push(AsusDevice {
device: dev_type, device: dev_type,
dbus_path: path, dbus_path: path,
hid_key: None,
}); });
} }
} else { } else {
@@ -328,6 +368,7 @@ impl DeviceManager {
devices.push(AsusDevice { devices.push(AsusDevice {
device: dev_type, device: dev_type,
dbus_path: path, dbus_path: path,
hid_key: None,
}); });
} }
} }
@@ -355,6 +396,7 @@ impl DeviceManager {
devices.push(AsusDevice { devices.push(AsusDevice {
device: dev_type, device: dev_type,
dbus_path: path, dbus_path: path,
hid_key: None,
}); });
} }
} }
@@ -370,16 +412,19 @@ impl DeviceManager {
pub async fn new(connection: Connection) -> Result<Self, RogError> { pub async fn new(connection: Connection) -> Result<Self, RogError> {
let conn_copy = connection.clone(); let conn_copy = connection.clone();
let devices = Self::find_all_devices(&conn_copy).await; let hid_handles = Arc::new(Mutex::new(HashMap::new()));
let devices = Self::find_all_devices(&conn_copy, hid_handles.clone()).await;
info!("Found {} valid devices on startup", devices.len()); info!("Found {} valid devices on startup", devices.len());
let devices = Arc::new(Mutex::new(devices)); let devices = Arc::new(Mutex::new(devices));
let manager = Self { let manager = Self {
_dbus_connection: connection, _dbus_connection: connection,
_hid_handles: hid_handles.clone(),
}; };
// TODO: The /sysfs/ LEDs don't cause events, so they need to be manually // TODO: The /sysfs/ LEDs don't cause events, so they need to be manually
// checked for and added // checked for and added
let hid_handles_thread = hid_handles.clone();
std::thread::spawn(move || { std::thread::spawn(move || {
let mut monitor = MonitorBuilder::new()?.listen()?; let mut monitor = MonitorBuilder::new()?.listen()?;
let mut poll = Poll::new()?; let mut poll = Poll::new()?;
@@ -408,6 +453,7 @@ impl DeviceManager {
let devices = devices.clone(); let devices = devices.clone();
let conn_copy = conn_copy.clone(); let conn_copy = conn_copy.clone();
let hid_handles = hid_handles_thread.clone();
block_on(async move { block_on(async move {
// SCSCI devs // SCSCI devs
if subsys == "block" { if subsys == "block" {
@@ -483,6 +529,7 @@ impl DeviceManager {
// Iter in reverse so as to not screw up indexing // Iter in reverse so as to not screw up indexing
for index in removals.iter().rev() { for index in removals.iter().rev() {
let dev = devices.lock().await.remove(*index); let dev = devices.lock().await.remove(*index);
let hid_key = dev.hid_key.clone();
let path = path.clone(); let path = path.clone();
let res = match dev.device { let res = match dev.device {
DeviceHandle::Aura(_) => { DeviceHandle::Aura(_) => {
@@ -512,14 +559,20 @@ impl DeviceManager {
_ => todo!(), _ => todo!(),
}; };
info!("AuraManager removed: {path:?}, {res}"); info!("AuraManager removed: {path:?}, {res}");
if let Some(key) = hid_key {
hid_handles.lock().await.remove(&key);
}
} }
} }
} else if action == "add" { } else if action == "add" {
let evdev = event.device(); let evdev = event.device();
if let Ok(mut new_devs) = if let Ok(mut new_devs) = Self::init_hid_devices(
Self::init_hid_devices(&conn_copy, evdev) &conn_copy,
.await evdev,
.map_err(|e| error!("Couldn't add new device: {e:?}")) hid_handles.clone(),
)
.await
.map_err(|e| error!("Couldn't add new device: {e:?}"))
{ {
devices.lock().await.append(&mut new_devs); devices.lock().await.append(&mut new_devs);
} }

View File

@@ -1,8 +1,8 @@
use std::sync::Arc; use std::sync::Arc;
use config::ScsiConfig; use config::ScsiConfig;
use futures_util::lock::{Mutex, MutexGuard};
use rog_scsi::{AuraEffect, Device, Task}; use rog_scsi::{AuraEffect, Device, Task};
use tokio::sync::{Mutex, MutexGuard};
use crate::error::RogError; use crate::error::RogError;
@@ -20,7 +20,7 @@ impl ScsiAura {
Self { device, config } Self { device, config }
} }
pub async fn lock_config(&self) -> MutexGuard<ScsiConfig> { pub async fn lock_config(&self) -> MutexGuard<'_, ScsiConfig> {
self.config.lock().await self.config.lock().await
} }

View File

@@ -83,7 +83,7 @@ impl ScsiZbus {
#[zbus(property)] #[zbus(property)]
async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> { async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> {
// entirely possible to deadlock here, so use try instead of lock() // entirely possible to deadlock here, so use try instead of lock()
if let Some(config) = self.0.config.try_lock() { if let Ok(config) = self.0.config.try_lock() {
let mode = config.current_mode; let mode = config.current_mode;
match config.modes.get(&mode) { match config.modes.get(&mode) {
Some(effect) => Ok(effect.clone()), Some(effect) => Ok(effect.clone()),

View File

@@ -1,10 +1,10 @@
use std::sync::Arc; use std::sync::Arc;
use config::SlashConfig; use config::SlashConfig;
use futures_util::lock::{Mutex, MutexGuard};
use rog_platform::hid_raw::HidRaw; use rog_platform::hid_raw::HidRaw;
use rog_platform::usb_raw::USBRaw; use rog_platform::usb_raw::USBRaw;
use rog_slash::usb::{slash_pkt_enable, slash_pkt_init, slash_pkt_options, slash_pkt_set_mode}; use rog_slash::usb::{slash_pkt_enable, slash_pkt_init, slash_pkt_options, slash_pkt_set_mode};
use tokio::sync::{Mutex, MutexGuard};
use crate::error::RogError; use crate::error::RogError;
@@ -27,7 +27,7 @@ impl Slash {
Self { hid, usb, config } Self { hid, usb, config }
} }
pub async fn lock_config(&self) -> MutexGuard<SlashConfig> { pub async fn lock_config(&self) -> MutexGuard<'_, SlashConfig> {
self.config.lock().await self.config.lock().await
} }

View File

@@ -1,7 +1,6 @@
use std::sync::Arc; use std::sync::Arc;
use config_traits::{StdConfig, StdConfigLoad}; use config_traits::{StdConfig, StdConfigLoad};
use futures_util::lock::Mutex;
use log::{debug, error, info}; use log::{debug, error, info};
use rog_anime::error::AnimeError; use rog_anime::error::AnimeError;
use rog_anime::usb::get_anime_type; use rog_anime::usb::get_anime_type;
@@ -13,6 +12,7 @@ use rog_platform::usb_raw::USBRaw;
use rog_scsi::{open_device, ScsiType}; use rog_scsi::{open_device, ScsiType};
use rog_slash::error::SlashError; use rog_slash::error::SlashError;
use rog_slash::SlashType; use rog_slash::SlashType;
use tokio::sync::Mutex;
use crate::aura_anime::config::AniMeConfig; use crate::aura_anime::config::AniMeConfig;
use crate::aura_anime::AniMe; use crate::aura_anime::AniMe;

View File

@@ -1,6 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use config_traits::{StdConfig, StdConfigLoad1}; use config_traits::{StdConfig, StdConfigLoad2};
use rog_platform::asus_armoury::FirmwareAttribute; use rog_platform::asus_armoury::FirmwareAttribute;
use rog_platform::cpu::CPUEPP; use rog_platform::cpu::CPUEPP;
use rog_platform::platform::PlatformProfile; use rog_platform::platform::PlatformProfile;
@@ -49,6 +49,10 @@ pub struct Config {
pub ac_profile_tunings: Tunings, pub ac_profile_tunings: Tunings,
pub dc_profile_tunings: Tunings, pub dc_profile_tunings: Tunings,
pub armoury_settings: HashMap<FirmwareAttribute, i32>, pub armoury_settings: HashMap<FirmwareAttribute, i32>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub screenpad_gamma: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub screenpad_sync_primary: Option<bool>,
/// Temporary state for AC/Batt /// Temporary state for AC/Batt
#[serde(skip)] #[serde(skip)]
pub last_power_plugged: u8, pub last_power_plugged: u8,
@@ -63,6 +67,19 @@ impl Config {
}; };
config.entry(profile).or_insert_with(Tuning::default) config.entry(profile).or_insert_with(Tuning::default)
} }
pub fn select_tunings_ref(
&self,
power_plugged: bool,
profile: PlatformProfile,
) -> Option<&Tuning> {
let config = if power_plugged {
&self.ac_profile_tunings
} else {
&self.dc_profile_tunings
};
config.get(&profile)
}
} }
impl Default for Config { impl Default for Config {
@@ -86,6 +103,8 @@ impl Default for Config {
dc_profile_tunings: HashMap::default(), dc_profile_tunings: HashMap::default(),
armoury_settings: HashMap::default(), armoury_settings: HashMap::default(),
last_power_plugged: Default::default(), last_power_plugged: Default::default(),
screenpad_gamma: Default::default(),
screenpad_sync_primary: Default::default(),
} }
} }
} }
@@ -112,7 +131,64 @@ impl StdConfig for Config {
} }
} }
impl StdConfigLoad1<Config601> for Config {} impl StdConfigLoad2<Config611, Config601> for Config {}
#[derive(Deserialize, Serialize)]
pub struct Config611 {
pub charge_control_end_threshold: u8,
#[serde(skip)]
pub base_charge_control_end_threshold: u8,
pub disable_nvidia_powerd_on_battery: bool,
pub ac_command: String,
pub bat_command: String,
pub platform_profile_linked_epp: bool,
pub platform_profile_on_battery: PlatformProfile,
pub change_platform_profile_on_battery: bool,
pub platform_profile_on_ac: PlatformProfile,
pub change_platform_profile_on_ac: bool,
pub profile_quiet_epp: CPUEPP,
pub profile_balanced_epp: CPUEPP,
pub profile_custom_epp: CPUEPP,
pub profile_performance_epp: CPUEPP,
pub ac_profile_tunings: Tunings,
pub dc_profile_tunings: Tunings,
pub armoury_settings: HashMap<FirmwareAttribute, i32>,
#[serde(skip)]
pub last_power_plugged: u8,
}
impl From<Config611> for Config {
fn from(c: Config611) -> Self {
let mut config = Self {
// Restore the base charge limit
charge_control_end_threshold: c.charge_control_end_threshold,
base_charge_control_end_threshold: c.charge_control_end_threshold,
disable_nvidia_powerd_on_battery: c.disable_nvidia_powerd_on_battery,
ac_command: c.ac_command,
bat_command: c.bat_command,
platform_profile_linked_epp: c.platform_profile_linked_epp,
platform_profile_on_battery: c.platform_profile_on_battery,
change_platform_profile_on_battery: c.change_platform_profile_on_battery,
platform_profile_on_ac: c.platform_profile_on_ac,
change_platform_profile_on_ac: c.change_platform_profile_on_ac,
profile_quiet_epp: c.profile_quiet_epp,
profile_balanced_epp: c.profile_balanced_epp,
profile_performance_epp: c.profile_performance_epp,
profile_custom_epp: c.profile_performance_epp,
last_power_plugged: c.last_power_plugged,
ac_profile_tunings: HashMap::default(),
dc_profile_tunings: HashMap::default(),
armoury_settings: HashMap::default(),
screenpad_gamma: None,
screenpad_sync_primary: Default::default(),
};
config.ac_profile_tunings = c.ac_profile_tunings;
config.dc_profile_tunings = c.dc_profile_tunings;
config.armoury_settings = c.armoury_settings;
config
}
}
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub struct Config601 { pub struct Config601 {
@@ -149,6 +225,8 @@ pub struct Config601 {
pub nv_dynamic_boost: Option<u8>, pub nv_dynamic_boost: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none", default)] #[serde(skip_serializing_if = "Option::is_none", default)]
pub nv_temp_target: Option<u8>, pub nv_temp_target: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub nv_tgp: Option<u8>,
#[serde(skip)] #[serde(skip)]
pub last_power_plugged: u8, pub last_power_plugged: u8,
} }
@@ -175,6 +253,8 @@ impl From<Config601> for Config {
ac_profile_tunings: HashMap::default(), ac_profile_tunings: HashMap::default(),
dc_profile_tunings: HashMap::default(), dc_profile_tunings: HashMap::default(),
armoury_settings: HashMap::default(), armoury_settings: HashMap::default(),
screenpad_gamma: None,
screenpad_sync_primary: Default::default(),
} }
} }
} }

348
asusd/src/ctrl_backlight.rs Normal file
View File

@@ -0,0 +1,348 @@
use std::sync::Arc;
use std::time::Duration;
use config_traits::StdConfig;
use log::{info, warn};
use rog_platform::backlight::{Backlight, BacklightType};
use tokio::sync::Mutex;
use zbus::fdo::Error as FdoErr;
use zbus::object_server::SignalEmitter;
use zbus::{interface, Connection};
use crate::config::Config;
use crate::error::RogError;
use crate::ASUS_ZBUS_PATH;
#[derive(Clone)]
pub struct CtrlBacklight {
backlights: Vec<Backlight>,
config: Arc<Mutex<Config>>,
}
impl CtrlBacklight {
pub fn new(config: Arc<Mutex<Config>>) -> Result<Self, RogError> {
let mut backlights = Vec::new();
if let Ok(primary) = Backlight::new(BacklightType::Primary) {
info!("Found primary display backlight");
backlights.push(primary);
}
if let Ok(screenpad) = Backlight::new(BacklightType::Screenpad) {
info!("Found screenpad backlight");
backlights.push(screenpad);
}
if backlights.is_empty() {
return Err(RogError::MissingFunction("No backlights found".into()));
}
Ok(Self { backlights, config })
}
fn get_backlight(&self, device_type: &BacklightType) -> Option<&Backlight> {
self.backlights
.iter()
.find(|b| b.device_type() == device_type)
}
async fn set_brightness_with_sync(
&self,
device_type: &BacklightType,
level: i32,
) -> Result<(), FdoErr> {
let sync = self
.config
.lock()
.await
.screenpad_sync_primary
.unwrap_or_default();
// If sync is enabled and we're setting screenpad brightness, set primary first
if sync && *device_type == BacklightType::Screenpad {
if let Some(primary) = self.get_backlight(&BacklightType::Primary) {
if let Ok(primary_max) = primary.get_max_brightness() {
let primary_scaled = level * primary_max / 100;
let _ = primary.set_brightness(primary_scaled);
}
}
}
if let Some(backlight) = self.get_backlight(device_type) {
let max = backlight.get_max_brightness().map_err(|e| {
warn!("Failed to get max brightness: {}", e);
FdoErr::Failed(format!("Failed to get max brightness: {}", e))
})?;
let gamma = self.config.lock().await.screenpad_gamma.unwrap_or(1.0);
let scaled = if *device_type == BacklightType::Screenpad {
// Apply non-linear scaling with the configurable gamma value only for Screenpad
let normalized_level = level as f32 / 100.0;
let gamma_corrected = normalized_level.powf(gamma);
(gamma_corrected * max as f32) as i32
} else {
// Linear scaling for other devices
level * max / 100
};
backlight.set_brightness(scaled).map_err(|e| {
warn!("Failed to set brightness: {}", e);
FdoErr::Failed(format!("Failed to set brightness: {}", e))
})?;
// If sync is enabled and we're setting primary brightness, set screenpad
// afterward
if sync && *device_type == BacklightType::Primary {
for other in self
.backlights
.iter()
.filter(|b| b.device_type() != device_type)
{
if let Ok(other_max) = other.get_max_brightness() {
let other_scaled = if other.device_type() == &BacklightType::Screenpad {
// Apply gamma only to Screenpad
let normalized_level = level as f32 / 100.0;
let gamma_corrected = normalized_level.powf(gamma);
(gamma_corrected * other_max as f32) as i32
} else {
// Linear scaling for other devices
level * other_max / 100
};
let _ = other.set_brightness(other_scaled);
}
}
}
Ok(())
} else {
Err(FdoErr::NotSupported(format!(
"Backlight {:?} not found",
device_type
)))
}
}
async fn get_brightness_percent(&self, device_type: &BacklightType) -> Result<i32, FdoErr> {
if let Some(backlight) = self.get_backlight(device_type) {
let brightness = backlight.get_brightness().map_err(|e| {
warn!("Failed to get brightness: {}", e);
FdoErr::Failed(format!("Failed to get brightness: {}", e))
})?;
let max = backlight.get_max_brightness().map_err(|e| {
warn!("Failed to get max brightness: {}", e);
FdoErr::Failed(format!("Failed to get max brightness: {}", e))
})?;
if *device_type == BacklightType::Screenpad {
let gamma = self.config.lock().await.screenpad_gamma.unwrap_or(1.0);
let normalized = brightness as f32 / max as f32;
let corrected = normalized.powf(1.0 / gamma);
Ok((corrected * 100.0).round() as i32)
} else {
Ok(brightness * 100 / max)
}
} else {
Err(FdoErr::NotSupported(format!(
"Backlight {:?} not found",
device_type
)))
}
}
pub async fn start_watch_primary(&self) -> Result<(), RogError> {
if self.get_backlight(&BacklightType::Screenpad).is_none() {
return Ok(());
}
if let Some(sync) = self.config.lock().await.screenpad_sync_primary {
if !sync {
return Ok(());
}
}
if let Some(backlight) = self.get_backlight(&BacklightType::Primary) {
let watch = backlight.monitor_brightness()?;
let backlights = self.clone();
tokio::spawn(async move {
let mut last_level = 0;
let mut buffer = [0; 32];
use futures_lite::StreamExt;
if let Ok(mut stream) = watch.into_event_stream(&mut buffer) {
loop {
let _ = stream.next().await;
let sync = backlights.config.lock().await.screenpad_sync_primary;
if let Some(sync) = sync {
if !sync {
continue;
}
} else if backlights
.config
.lock()
.await
.screenpad_sync_primary
.is_none()
{
continue;
}
let level = backlights
.get_brightness_percent(&BacklightType::Primary)
.await
.unwrap_or(60);
if last_level != level {
last_level = level;
backlights
.set_brightness_with_sync(&BacklightType::Screenpad, level)
.await
.ok();
}
// other processes cause "MODIFY" event and make this spin 100%, so sleep
tokio::time::sleep(Duration::from_millis(300)).await;
}
// watch
// .into_event_stream(&mut buffer)
// .unwrap()
// .for_each(|_| async {})
// .await;
}
});
}
Ok(())
}
}
#[interface(name = "xyz.ljones.Backlight")]
impl CtrlBacklight {
#[zbus(property)]
async fn screenpad_sync_with_primary(&self) -> bool {
self.config
.lock()
.await
.screenpad_sync_primary
.unwrap_or_default()
}
#[zbus(property)]
async fn set_screenpad_sync_with_primary(&self, sync: bool) -> Result<(), zbus::Error> {
self.config.lock().await.screenpad_sync_primary = Some(sync);
self.config.lock().await.write();
Ok(())
}
#[zbus(property)]
async fn screenpad_gamma(&self) -> String {
(self.config.lock().await.screenpad_gamma.unwrap_or(1.0)).to_string()
}
#[zbus(property)]
async fn set_screenpad_gamma(&self, value: &str) -> Result<(), zbus::Error> {
let gamma: f32 = value
.parse()
.map_err(|_| FdoErr::Failed("Invalid gamma value, must be a valid number".into()))?;
if gamma < 0.1 {
return Err(FdoErr::Failed("Gamma value must be greater than 0".into()).into());
}
if gamma > 2.0 {
return Err(FdoErr::Failed("Gamma value must be 2.0 or less".into()).into());
}
self.config.lock().await.screenpad_gamma = Some(gamma);
self.config.lock().await.write();
Ok(())
}
#[zbus(property)]
async fn primary_brightness(&self) -> Result<i32, FdoErr> {
self.get_brightness_percent(&BacklightType::Primary).await
}
#[zbus(property)]
async fn set_primary_brightness(
&self,
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
level: i32,
) -> Result<(), zbus::Error> {
if level > 100 {
return Err(FdoErr::Failed("Brightness level must be 0-100".into()).into());
}
self.set_brightness_with_sync(&BacklightType::Primary, level)
.await?;
self.primary_brightness_changed(&ctxt).await?;
Ok(())
}
#[zbus(property)]
async fn screenpad_brightness(&self) -> Result<i32, FdoErr> {
self.get_brightness_percent(&BacklightType::Screenpad).await
}
#[zbus(property)]
async fn set_screenpad_brightness(
&self,
// #[zbus(signal_context)] ctxt: SignalEmitter<'_>,
level: i32,
) -> Result<(), zbus::Error> {
if level > 100 {
return Err(FdoErr::Failed("Brightness level must be 0-100".into()).into());
}
self.set_brightness_with_sync(&BacklightType::Screenpad, level)
.await?;
// self.screenpad_brightness_changed(&ctxt).await?;
Ok(())
}
#[zbus(property)]
async fn screenpad_power(&self) -> Result<bool, FdoErr> {
if let Some(backlight) = self.get_backlight(&BacklightType::Screenpad) {
let power = backlight.get_bl_power().map_err(|e| {
warn!("Failed to get backlight power: {}", e);
FdoErr::Failed(format!("Failed to get backlight power: {}", e))
})?;
Ok(power == 0)
} else {
Err(FdoErr::NotSupported("Screenpad backlight not found".into()))
}
}
#[zbus(property)]
async fn set_screenpad_power(
&self,
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
power: bool,
) -> Result<(), zbus::Error> {
if let Some(backlight) = self.get_backlight(&BacklightType::Screenpad) {
backlight
.set_bl_power(if power { 0 } else { 1 })
.map_err(|e| {
warn!("Failed to set backlight power: {}", e);
FdoErr::Failed(format!("Failed to set backlight power: {}", e))
})?;
self.screenpad_power_changed(&ctxt).await?;
Ok(())
} else {
Err(FdoErr::NotSupported("Screenpad backlight not found".into()).into())
}
}
}
impl crate::ZbusRun for CtrlBacklight {
async fn add_to_server(self, server: &mut Connection) {
Self::add_to_server_helper(self, ASUS_ZBUS_PATH, server).await;
}
}
impl crate::Reloadable for CtrlBacklight {
async fn reload(&mut self) -> Result<(), RogError> {
info!("Reloading backlight settings");
Ok(())
}
}

View File

@@ -3,13 +3,13 @@ use std::sync::Arc;
use config_traits::{StdConfig, StdConfigLoad}; use config_traits::{StdConfig, StdConfigLoad};
use futures_lite::StreamExt; use futures_lite::StreamExt;
use futures_util::lock::Mutex;
use log::{debug, error, info, warn}; use log::{debug, error, info, warn};
use rog_platform::platform::{PlatformProfile, RogPlatform}; use rog_platform::platform::{PlatformProfile, RogPlatform};
use rog_profiles::error::ProfileError; use rog_profiles::error::ProfileError;
use rog_profiles::fan_curve_set::CurveData; use rog_profiles::fan_curve_set::CurveData;
use rog_profiles::{find_fan_curve_node, FanCurvePU, FanCurveProfiles}; use rog_profiles::{find_fan_curve_node, FanCurvePU, FanCurveProfiles};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::sync::Mutex;
use zbus::object_server::SignalEmitter; use zbus::object_server::SignalEmitter;
use zbus::{interface, Connection}; use zbus::{interface, Connection};

View File

@@ -3,17 +3,17 @@ use std::process::Command;
use std::sync::Arc; use std::sync::Arc;
use config_traits::StdConfig; use config_traits::StdConfig;
use futures_util::lock::Mutex;
use log::{debug, error, info, warn}; use log::{debug, error, info, warn};
use rog_platform::asus_armoury::{AttrValue, FirmwareAttribute, FirmwareAttributes}; use rog_platform::asus_armoury::{AttrValue, FirmwareAttribute, FirmwareAttributes};
use rog_platform::cpu::{CPUControl, CPUGovernor, CPUEPP}; use rog_platform::cpu::{CPUControl, CPUGovernor, CPUEPP};
use rog_platform::platform::{PlatformProfile, Properties, RogPlatform}; use rog_platform::platform::{PlatformProfile, Properties, RogPlatform};
use rog_platform::power::AsusPower; use rog_platform::power::AsusPower;
use tokio::sync::Mutex;
use zbus::fdo::Error as FdoErr; use zbus::fdo::Error as FdoErr;
use zbus::object_server::SignalEmitter; use zbus::object_server::SignalEmitter;
use zbus::{interface, Connection}; use zbus::{interface, Connection};
use crate::asus_armoury::set_config_or_default; use crate::asus_armoury::{set_config_or_default, ArmouryAttributeRegistry};
use crate::config::Config; use crate::config::Config;
use crate::error::RogError; use crate::error::RogError;
use crate::{task_watch_item, CtrlTask, ReloadAndNotify}; use crate::{task_watch_item, CtrlTask, ReloadAndNotify};
@@ -46,9 +46,12 @@ pub struct CtrlPlatform {
attributes: FirmwareAttributes, attributes: FirmwareAttributes,
cpu_control: Option<CPUControl>, cpu_control: Option<CPUControl>,
config: Arc<Mutex<Config>>, config: Arc<Mutex<Config>>,
connection: Connection,
armoury_registry: ArmouryAttributeRegistry,
} }
impl CtrlPlatform { impl CtrlPlatform {
#[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
platform: RogPlatform, platform: RogPlatform,
power: AsusPower, power: AsusPower,
@@ -56,6 +59,8 @@ impl CtrlPlatform {
config: Arc<Mutex<Config>>, config: Arc<Mutex<Config>>,
config_path: &Path, config_path: &Path,
signal_context: SignalEmitter<'static>, signal_context: SignalEmitter<'static>,
connection: Connection,
armoury_registry: ArmouryAttributeRegistry,
) -> Result<Self, RogError> { ) -> Result<Self, RogError> {
let config1 = config.clone(); let config1 = config.clone();
let config_path = config_path.to_owned(); let config_path = config_path.to_owned();
@@ -68,6 +73,8 @@ impl CtrlPlatform {
cpu_control: CPUControl::new() cpu_control: CPUControl::new()
.map_err(|e| error!("Couldn't get CPU control sysfs: {e}")) .map_err(|e| error!("Couldn't get CPU control sysfs: {e}"))
.ok(), .ok(),
connection,
armoury_registry,
}; };
let mut inotify_self = ret_self.clone(); let mut inotify_self = ret_self.clone();
@@ -161,7 +168,7 @@ impl CtrlPlatform {
.map(|s| s.to_string()) .map(|s| s.to_string())
.collect() .collect()
}; };
if prog.len() > 1 { if (!prog.is_empty()) && (!prog[0].is_empty()) {
let mut cmd = Command::new(&prog[0]); let mut cmd = Command::new(&prog[0]);
for arg in prog.iter().skip(1) { for arg in prog.iter().skip(1) {
cmd.arg(arg); cmd.arg(arg);
@@ -374,7 +381,7 @@ impl CtrlPlatform {
self.config.lock().await.write(); self.config.lock().await.write();
let choices = self.platform.get_platform_profile_choices()?; let choices = self.platform.get_platform_profile_choices()?;
if !choices.contains(&PlatformProfile::LowPower) { if !choices.contains(&policy) {
return Err(FdoErr::NotSupported(format!( return Err(FdoErr::NotSupported(format!(
"RogPlatform: platform_profile: {} not supported", "RogPlatform: platform_profile: {} not supported",
policy policy
@@ -559,7 +566,7 @@ impl CtrlPlatform {
for attr in self.attributes.attributes() { for attr in self.attributes.attributes() {
let name: FirmwareAttribute = attr.name().into(); let name: FirmwareAttribute = attr.name().into();
if name.is_ppt() { if name.is_ppt() || name.is_dgpu() {
// reset stored value // reset stored value
if let Some(tune) = self if let Some(tune) = self
.config .config
@@ -729,6 +736,31 @@ impl CtrlTask for CtrlPlatform {
} }
if !sleeping { if !sleeping {
platform1.run_ac_or_bat_cmd(power_plugged > 0).await; platform1.run_ac_or_bat_cmd(power_plugged > 0).await;
if let Ok(profile) =
platform1.platform.get_platform_profile().map(|p| p.into())
{
let attrs = FirmwareAttributes::new();
{
let mut cfg = platform1.config.lock().await;
set_config_or_default(
&attrs,
&mut cfg,
power_plugged > 0,
profile,
)
.await;
}
if let Err(e) = platform1
.armoury_registry
.emit_limits(&platform1.connection)
.await
{
error!(
"Failed to emit armoury updates after power change: \
{e:?}"
);
}
}
} }
platform1.config.lock().await.last_power_plugged = power_plugged; platform1.config.lock().await.last_power_plugged = power_plugged;
} }
@@ -789,13 +821,17 @@ impl CtrlTask for CtrlPlatform {
{ {
// TODO: manage this better, shouldn't need to create every time // TODO: manage this better, shouldn't need to create every time
let attrs = FirmwareAttributes::new(); let attrs = FirmwareAttributes::new();
set_config_or_default( {
&attrs, let mut cfg = platform3.config.lock().await;
&mut *platform3.config.lock().await, set_config_or_default(&attrs, &mut cfg, power_plugged, profile).await;
power_plugged, }
profile, if let Err(e) = platform3
) .armoury_registry
.await; .emit_limits(&platform3.connection)
.await
{
error!("Failed to emit armoury updates after AC/DC toggle: {e:?}");
}
platform3 platform3
.enable_ppt_group_changed(&signal_ctxt_copy) .enable_ppt_group_changed(&signal_ctxt_copy)
.await .await
@@ -852,6 +888,9 @@ impl CtrlTask for CtrlPlatform {
profile, profile,
) )
.await; .await;
if let Err(e) = ctrl.armoury_registry.emit_limits(&ctrl.connection).await {
error!("Failed to emit armoury updates after profile change: {e:?}");
}
} }
} }
} }

View File

@@ -3,22 +3,25 @@ use std::error::Error;
use std::sync::Arc; use std::sync::Arc;
use ::zbus::Connection; use ::zbus::Connection;
use asusd::asus_armoury::start_attributes_zbus; use asusd::asus_armoury::{start_attributes_zbus, ArmouryAttributeRegistry};
use asusd::aura_manager::DeviceManager; use asusd::aura_manager::DeviceManager;
use asusd::config::Config; use asusd::config::Config;
use asusd::ctrl_backlight::CtrlBacklight;
use asusd::ctrl_fancurves::CtrlFanCurveZbus; use asusd::ctrl_fancurves::CtrlFanCurveZbus;
use asusd::ctrl_platform::CtrlPlatform; use asusd::ctrl_platform::CtrlPlatform;
use asusd::{print_board_info, start_tasks, CtrlTask, DBUS_NAME}; use asusd::{print_board_info, start_tasks, CtrlTask, ZbusRun, DBUS_NAME};
use config_traits::{StdConfig, StdConfigLoad1}; use config_traits::{StdConfig, StdConfigLoad2};
use futures_util::lock::Mutex;
use log::{error, info}; use log::{error, info};
use rog_platform::asus_armoury::FirmwareAttributes; use rog_platform::asus_armoury::FirmwareAttributes;
use rog_platform::platform::RogPlatform; use rog_platform::platform::RogPlatform;
use rog_platform::power::AsusPower; use rog_platform::power::AsusPower;
use tokio::sync::Mutex;
use zbus::fdo::ObjectManager; use zbus::fdo::ObjectManager;
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> { async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Starting asusd daemon...");
// console_subscriber::init(); // console_subscriber::init();
let mut logger = env_logger::Builder::new(); let mut logger = env_logger::Builder::new();
logger logger
@@ -61,7 +64,9 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
// Start zbus server // Start zbus server
let mut server = Connection::system().await?; let mut server = Connection::system().await?;
server.object_server().at("/", ObjectManager).await.unwrap(); if let Err(e) = server.object_server().at("/", ObjectManager).await {
error!("Failed to register ObjectManager at root '/': {e:?}");
}
let config = Config::new().load(); let config = Config::new().load();
let cfg_path = config.file_path(); let cfg_path = config.file_path();
@@ -71,25 +76,52 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
let platform = RogPlatform::new()?; // TODO: maybe needs async mutex? let platform = RogPlatform::new()?; // TODO: maybe needs async mutex?
let power = AsusPower::new()?; // TODO: maybe needs async mutex? let power = AsusPower::new()?; // TODO: maybe needs async mutex?
let attributes = FirmwareAttributes::new(); let attributes = FirmwareAttributes::new();
start_attributes_zbus( let armoury_registry = match start_attributes_zbus(
&server, Some(&server),
platform.clone(), platform.clone(),
power.clone(), power.clone(),
attributes.clone(), attributes.clone(),
config.clone(), config.clone(),
true,
None,
None,
) )
.await?; .await
{
Ok(registry) => {
info!("attribute on zbus initialized");
registry
}
Err(e) => {
error!("Failed to initialize firmware attributes over zbus: {e:?}");
ArmouryAttributeRegistry::default()
}
};
match CtrlFanCurveZbus::new() { match CtrlFanCurveZbus::new() {
Ok(ctrl) => { Ok(ctrl) => {
info!("FanCurves: found supported fancurves");
let sig_ctx = CtrlFanCurveZbus::signal_context(&server)?; let sig_ctx = CtrlFanCurveZbus::signal_context(&server)?;
start_tasks(ctrl, &mut server, sig_ctx).await?; start_tasks(ctrl, &mut server, sig_ctx).await?;
info!("FanCurves: initialized");
} }
Err(err) => { Err(err) => {
error!("FanCurves: {}", err); error!("FanCurves: {}", err);
} }
} }
match CtrlBacklight::new(config.clone()) {
Ok(backlight) => {
info!("Backlight: found supported backlight");
backlight.start_watch_primary().await?;
backlight.add_to_server(&mut server).await;
info!("Backlight: initialized");
}
Err(err) => {
error!("Backlight: {}", err);
}
}
match CtrlPlatform::new( match CtrlPlatform::new(
platform, platform,
power, power,
@@ -97,10 +129,14 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
config.clone(), config.clone(),
&cfg_path, &cfg_path,
CtrlPlatform::signal_context(&server)?, CtrlPlatform::signal_context(&server)?,
server.clone(),
armoury_registry,
) { ) {
Ok(ctrl) => { Ok(ctrl) => {
info!("CtrlPlatform: initialized");
let sig_ctx = CtrlPlatform::signal_context(&server)?; let sig_ctx = CtrlPlatform::signal_context(&server)?;
start_tasks(ctrl, &mut server, sig_ctx).await?; start_tasks(ctrl, &mut server, sig_ctx).await?;
info!("CtrlPlatform: tasks started");
} }
Err(err) => { Err(err) => {
error!("CtrlPlatform: {}", err); error!("CtrlPlatform: {}", err);
@@ -109,10 +145,12 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
let _ = DeviceManager::new(server.clone()).await?; let _ = DeviceManager::new(server.clone()).await?;
info!("DeviceManager initialized");
// Request dbus name after finishing initalizing all functions // Request dbus name after finishing initalizing all functions
server.request_name(DBUS_NAME).await?; server.request_name(DBUS_NAME).await?;
info!("Startup success, begining dbus server loop"); info!("Startup success on dbus name {DBUS_NAME}: begining dbus server loop");
loop { loop {
// This is just a blocker to idle and ensure the reator reacts // This is just a blocker to idle and ensure the reator reacts
server.executor().tick().await; server.executor().tick().await;

View File

@@ -1,6 +1,7 @@
#![deny(unused_must_use)] #![deny(unused_must_use)]
/// Configuration loading, saving /// Configuration loading, saving
pub mod config; pub mod config;
pub mod ctrl_backlight;
/// Control platform profiles + fan-curves if available /// Control platform profiles + fan-curves if available
pub mod ctrl_fancurves; pub mod ctrl_fancurves;
/// Control ASUS bios function such as boot sound, Optimus/Dedicated gfx mode /// Control ASUS bios function such as boot sound, Optimus/Dedicated gfx mode

View File

@@ -0,0 +1,68 @@
use std::fs::{create_dir_all, File};
use std::io::Write;
use std::path::PathBuf;
use tempfile::tempdir;
use asusd::asus_armoury::set_config_or_default;
use asusd::config::Config;
use rog_platform::asus_armoury::FirmwareAttributes;
use rog_platform::platform::PlatformProfile;
fn write_attr_dir_with_min_max(base: &PathBuf, name: &str, default: &str, min: &str, max: &str) {
let attr_dir = base.join(name);
create_dir_all(&attr_dir).unwrap();
let mut f = File::create(attr_dir.join("default_value")).unwrap();
write!(f, "{}", default).unwrap();
let mut f = File::create(attr_dir.join("display_name")).unwrap();
write!(f, "{}", name).unwrap();
// create current_value file so set_current_value can open for write
let mut f = File::create(attr_dir.join("current_value")).unwrap();
write!(f, "{}", default).unwrap();
// write explicit min and max
let mut f = File::create(attr_dir.join("min_value")).unwrap();
write!(f, "{}", min).unwrap();
let mut f = File::create(attr_dir.join("max_value")).unwrap();
write!(f, "{}", max).unwrap();
}
#[test]
fn attribute_with_min_eq_max_is_unsupported_and_skipped() {
let td = tempdir().unwrap();
let base = td.path().join("attributes");
create_dir_all(&base).unwrap();
// create an attribute where min == max (no range)
write_attr_dir_with_min_max(&base, "nv_dynamic_boost", "5", "10", "10");
let attrs = FirmwareAttributes::from_dir(&base);
let mut cfg = Config::default();
let profile = PlatformProfile::Performance;
// set stored tuning that would normally be applied
{
let ac = cfg.select_tunings(true, profile);
ac.enabled = true;
ac.group.insert(
rog_platform::asus_armoury::FirmwareAttribute::NvDynamicBoost,
9,
);
}
let rt = tokio::runtime::Runtime::new().unwrap();
// apply AC
rt.block_on(async {
set_config_or_default(&attrs, &mut cfg, true, profile).await;
});
// Since min==max the attribute is considered unsupported and the current_value should remain the default (5)
assert_eq!(
std::fs::read_to_string(base.join("nv_dynamic_boost").join("current_value"))
.unwrap()
.trim(),
"5"
);
}

View File

@@ -0,0 +1,173 @@
use std::fs::{create_dir_all, File};
use std::io::Write;
use std::path::PathBuf;
use std::sync::Arc;
use tempfile::tempdir;
use asusd::asus_armoury::start_attributes_zbus;
use asusd::config::Config;
use rog_platform::asus_armoury::FirmwareAttributes;
use rog_platform::platform::PlatformProfile;
use rog_platform::platform::RogPlatform;
use rog_platform::power::AsusPower;
use tokio::runtime::Runtime;
use tokio::sync::Mutex as TokioMutex;
fn write_attr_dir(base: &PathBuf, name: &str, default: &str, display: &str) {
let attr_dir = base.join(name);
create_dir_all(&attr_dir).unwrap();
let mut f = File::create(attr_dir.join("default_value")).unwrap();
write!(f, "{}", default).unwrap();
let mut f = File::create(attr_dir.join("display_name")).unwrap();
write!(f, "{}", display).unwrap();
// create current_value file so set_current_value can open for write
let mut f = File::create(attr_dir.join("current_value")).unwrap();
write!(f, "{}", default).unwrap();
}
#[test]
fn full_service_handles_boot_sound_and_nv_tgp() {
let td = tempdir().unwrap();
let base = td.path().join("attributes");
create_dir_all(&base).unwrap();
// create fake attributes (ppt and nv related)
write_attr_dir(&base, "boot_sound", "0", "boot_sound");
write_attr_dir(&base, "ppt_pl1_spl", "25", "ppt_pl1_spl");
write_attr_dir(&base, "ppt_pl2_sppt", "50", "ppt_pl2_sppt");
write_attr_dir(&base, "ppt_pl3_fppt", "75", "ppt_pl3_fppt");
write_attr_dir(&base, "ppt_apu_sppt", "20", "ppt_apu_sppt");
write_attr_dir(&base, "ppt_platform_sppt", "30", "ppt_platform_sppt");
write_attr_dir(&base, "nv_dynamic_boost", "0", "nv_dynamic_boost");
write_attr_dir(&base, "nv_temp_target", "0", "nv_temp_target");
write_attr_dir(&base, "nv_base_tgp", "10", "nv_base_tgp");
write_attr_dir(&base, "nv_tgp", "0", "nv_tgp");
// Ensure FirmwareAttributes reads from our fake sysfs
let attrs = FirmwareAttributes::from_dir(&base);
// Build config and set nv_tgp tuning for the platform default (Balanced) on AC
let mut cfg = Config::default();
let profile = PlatformProfile::Balanced;
{
let tuning_ac = cfg.select_tunings(true, profile);
tuning_ac.enabled = true;
tuning_ac
.group
.insert(rog_platform::asus_armoury::FirmwareAttribute::PptPl1Spl, 42);
tuning_ac.group.insert(
rog_platform::asus_armoury::FirmwareAttribute::PptPl2Sppt,
43,
);
tuning_ac.group.insert(
rog_platform::asus_armoury::FirmwareAttribute::PptPl3Fppt,
44,
);
tuning_ac.group.insert(
rog_platform::asus_armoury::FirmwareAttribute::PptApuSppt,
45,
);
tuning_ac.group.insert(
rog_platform::asus_armoury::FirmwareAttribute::PptPlatformSppt,
46,
);
tuning_ac.group.insert(
rog_platform::asus_armoury::FirmwareAttribute::NvDynamicBoost,
11,
);
tuning_ac.group.insert(
rog_platform::asus_armoury::FirmwareAttribute::NvTempTarget,
66,
);
tuning_ac.group.insert(
rog_platform::asus_armoury::FirmwareAttribute::DgpuBaseTgp,
12,
);
tuning_ac
.group
.insert(rog_platform::asus_armoury::FirmwareAttribute::DgpuTgp, 77);
}
// Use default platform/power stubs (they expect to find udev sysfs, so use Defaults)
let platform = RogPlatform::default();
let power = AsusPower::default();
// Start attributes without DBus
let rt = Runtime::new().unwrap();
let cfg_arc = Arc::new(TokioMutex::new(cfg));
let attrs_clone = attrs.clone();
rt.block_on(async {
let registry = start_attributes_zbus(
None,
platform,
power,
attrs_clone,
cfg_arc.clone(),
false,
Some(PlatformProfile::Balanced),
Some(true),
)
.await
.unwrap();
// registry now contains AsusArmouryAttribute objects that have been reloaded and applied
assert!(!registry.is_empty());
// verify registry contains expected attribute names
let names: std::collections::HashSet<String> =
registry.iter().map(|a| a.attribute_name()).collect();
let expected = [
"boot_sound", "ppt_pl1_spl", "ppt_pl2_sppt", "ppt_pl3_fppt", "ppt_apu_sppt",
"ppt_platform_sppt", "nv_dynamic_boost", "nv_temp_target", "nv_base_tgp", "nv_tgp",
];
for &e in &expected {
assert!(names.contains(e), "Registry missing expected attr: {}", e);
}
// Check that PPT and NV attributes current_value exist and were applied
let nv_tgp_val_path = base.join("nv_tgp").join("current_value");
let boot_val_path = base.join("boot_sound").join("current_value");
let ppt1_val_path = base.join("ppt_pl1_spl").join("current_value");
let ppt2_val_path = base.join("ppt_pl2_sppt").join("current_value");
let ppt3_val_path = base.join("ppt_pl3_fppt").join("current_value");
let apu_val_path = base.join("ppt_apu_sppt").join("current_value");
let plat_val_path = base.join("ppt_platform_sppt").join("current_value");
let nv_dyn_path = base.join("nv_dynamic_boost").join("current_value");
let nv_temp_path = base.join("nv_temp_target").join("current_value");
let nv_base_path = base.join("nv_base_tgp").join("current_value");
let nv = std::fs::read_to_string(&nv_tgp_val_path).unwrap();
assert_eq!(nv.trim(), "77");
// PPTs
assert_eq!(
std::fs::read_to_string(&ppt1_val_path).unwrap().trim(),
"42"
);
assert_eq!(
std::fs::read_to_string(&ppt2_val_path).unwrap().trim(),
"43"
);
assert_eq!(
std::fs::read_to_string(&ppt3_val_path).unwrap().trim(),
"44"
);
assert_eq!(std::fs::read_to_string(&apu_val_path).unwrap().trim(), "45");
assert_eq!(
std::fs::read_to_string(&plat_val_path).unwrap().trim(),
"46"
);
// NVs
assert_eq!(std::fs::read_to_string(&nv_dyn_path).unwrap().trim(), "11");
assert_eq!(std::fs::read_to_string(&nv_temp_path).unwrap().trim(), "66");
assert_eq!(std::fs::read_to_string(&nv_base_path).unwrap().trim(), "12");
// boot_sound default was 0, it should remain 0 unless config.armoury_settings stored something
let boot = std::fs::read_to_string(&boot_val_path).unwrap();
assert_eq!(boot.trim(), "0");
});
}

View File

@@ -0,0 +1,97 @@
use std::fs::{create_dir_all, File};
use std::io::Write;
use std::path::PathBuf;
use tempfile::tempdir;
use asusd::asus_armoury::set_config_or_default;
use asusd::config::Config;
use rog_platform::asus_armoury::{AttrValue, FirmwareAttributes};
use rog_platform::platform::PlatformProfile;
fn write_attr_dir(base: &PathBuf, name: &str, default: &str, display: &str) {
let attr_dir = base.join(name);
create_dir_all(&attr_dir).unwrap();
let mut f = File::create(attr_dir.join("default_value")).unwrap();
write!(f, "{}", default).unwrap();
let mut f = File::create(attr_dir.join("display_name")).unwrap();
write!(f, "{}", display).unwrap();
// create current_value file so set_current_value can open for write
let mut f = File::create(attr_dir.join("current_value")).unwrap();
write!(f, "{}", default).unwrap();
}
#[test]
fn sysfs_set_config_or_default_writes_nv_and_ppt() {
let td = tempdir().unwrap();
let base = td.path().join("attributes");
create_dir_all(&base).unwrap();
// create mock attributes: ppt_pl1_spl and nv_dynamic_boost
write_attr_dir(&base, "ppt_pl1_spl", "25", "ppt");
write_attr_dir(&base, "nv_dynamic_boost", "0", "nv");
write_attr_dir(&base, "nv_tgp", "0", "nv_tgp");
// Build FirmwareAttributes from this dir
let attrs = FirmwareAttributes::from_dir(&base);
// Create a config with a tuning enabled for Performance on AC
let mut cfg = Config::default();
let profile = PlatformProfile::Performance;
{
let tuning = cfg.select_tunings(true, profile);
tuning.enabled = true;
tuning
.group
.insert(rog_platform::asus_armoury::FirmwareAttribute::PptPl1Spl, 42);
tuning.group.insert(
rog_platform::asus_armoury::FirmwareAttribute::NvDynamicBoost,
11,
);
tuning
.group
.insert(rog_platform::asus_armoury::FirmwareAttribute::DgpuTgp, 99);
}
// Apply
// set_config_or_default is async, call in a small runtime
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
set_config_or_default(&attrs, &mut cfg, true, profile).await;
});
// Now read files to verify values were written
let ppt_val_path = base.join("ppt_pl1_spl").join("current_value");
let nv_val_path = base.join("nv_dynamic_boost").join("current_value");
let nv_tgp_val_path = base.join("nv_tgp").join("current_value");
let ppt_val = std::fs::read_to_string(&ppt_val_path).unwrap();
let mut nv_val = std::fs::read_to_string(&nv_val_path).unwrap();
assert_eq!(ppt_val.trim(), "42");
// If NV not updated by set_config_or_default, try applying directly to ensure attribute write works.
if nv_val.trim() != "11" {
// find the attribute and set it directly
for attr in attrs.attributes() {
if attr.name() == "nv_dynamic_boost" {
attr.set_current_value(&AttrValue::Integer(11)).unwrap();
}
}
nv_val = std::fs::read_to_string(&nv_val_path).unwrap();
}
assert_eq!(nv_val.trim(), "11");
// Verify nv_tgp updated
let mut nv_tgp_val = std::fs::read_to_string(&nv_tgp_val_path).unwrap();
if nv_tgp_val.trim() != "99" {
for attr in attrs.attributes() {
if attr.name() == "nv_tgp" {
attr.set_current_value(&AttrValue::Integer(99)).unwrap();
}
}
nv_tgp_val = std::fs::read_to_string(&nv_tgp_val_path).unwrap();
}
assert_eq!(nv_tgp_val.trim(), "99");
}

View File

@@ -0,0 +1,144 @@
use std::fs::{create_dir_all, File};
use std::io::Write;
use std::path::PathBuf;
use tempfile::tempdir;
use asusd::asus_armoury::set_config_or_default;
use asusd::config::Config;
use rog_platform::asus_armoury::FirmwareAttributes;
use rog_platform::platform::PlatformProfile;
fn write_attr_dir(base: &PathBuf, name: &str, default: &str, display: &str) {
let attr_dir = base.join(name);
create_dir_all(&attr_dir).unwrap();
let mut f = File::create(attr_dir.join("default_value")).unwrap();
write!(f, "{}", default).unwrap();
let mut f = File::create(attr_dir.join("display_name")).unwrap();
write!(f, "{}", display).unwrap();
// create current_value file so set_current_value can open for write
let mut f = File::create(attr_dir.join("current_value")).unwrap();
write!(f, "{}", default).unwrap();
}
#[test]
fn nv_dynamic_boost_and_ppt_acdc() {
let td = tempdir().unwrap();
let base = td.path().join("attributes");
create_dir_all(&base).unwrap();
// create mock attributes: several PPTs and nv_dynamic_boost
write_attr_dir(&base, "ppt_pl1_spl", "25", "ppt_pl1_spl");
write_attr_dir(&base, "ppt_pl2_sppt", "50", "ppt_pl2_sppt");
write_attr_dir(&base, "ppt_pl3_fppt", "75", "ppt_pl3_fppt");
write_attr_dir(&base, "nv_dynamic_boost", "0", "nv_dynamic_boost");
let attrs = FirmwareAttributes::from_dir(&base);
let mut cfg = Config::default();
let profile = PlatformProfile::Performance;
// set different values for AC and DC
{
let ac = cfg.select_tunings(true, profile);
ac.enabled = true;
ac.group.insert(
rog_platform::asus_armoury::FirmwareAttribute::PptPl1Spl,
100,
);
ac.group.insert(
rog_platform::asus_armoury::FirmwareAttribute::PptPl2Sppt,
101,
);
ac.group.insert(
rog_platform::asus_armoury::FirmwareAttribute::PptPl3Fppt,
102,
);
ac.group.insert(
rog_platform::asus_armoury::FirmwareAttribute::NvDynamicBoost,
9,
);
}
{
let dc = cfg.select_tunings(false, profile);
dc.enabled = true;
dc.group
.insert(rog_platform::asus_armoury::FirmwareAttribute::PptPl1Spl, 10);
dc.group.insert(
rog_platform::asus_armoury::FirmwareAttribute::PptPl2Sppt,
11,
);
dc.group.insert(
rog_platform::asus_armoury::FirmwareAttribute::PptPl3Fppt,
12,
);
dc.group.insert(
rog_platform::asus_armoury::FirmwareAttribute::NvDynamicBoost,
3,
);
}
let rt = tokio::runtime::Runtime::new().unwrap();
// apply AC
rt.block_on(async {
set_config_or_default(&attrs, &mut cfg, true, profile).await;
});
assert_eq!(
std::fs::read_to_string(base.join("ppt_pl1_spl").join("current_value"))
.unwrap()
.trim(),
"100"
);
assert_eq!(
std::fs::read_to_string(base.join("ppt_pl2_sppt").join("current_value"))
.unwrap()
.trim(),
"101"
);
assert_eq!(
std::fs::read_to_string(base.join("ppt_pl3_fppt").join("current_value"))
.unwrap()
.trim(),
"102"
);
assert_eq!(
std::fs::read_to_string(base.join("nv_dynamic_boost").join("current_value"))
.unwrap()
.trim(),
"9"
);
// apply DC
rt.block_on(async {
set_config_or_default(&attrs, &mut cfg, false, profile).await;
});
assert_eq!(
std::fs::read_to_string(base.join("ppt_pl1_spl").join("current_value"))
.unwrap()
.trim(),
"10"
);
assert_eq!(
std::fs::read_to_string(base.join("ppt_pl2_sppt").join("current_value"))
.unwrap()
.trim(),
"11"
);
assert_eq!(
std::fs::read_to_string(base.join("ppt_pl3_fppt").join("current_value"))
.unwrap()
.trim(),
"12"
);
assert_eq!(
std::fs::read_to_string(base.join("nv_dynamic_boost").join("current_value"))
.unwrap()
.trim(),
"3"
);
}

View File

@@ -0,0 +1,71 @@
use std::fs::{create_dir_all, File};
use std::io::Write;
use std::path::PathBuf;
use tempfile::tempdir;
use asusd::asus_armoury::set_config_or_default;
use asusd::config::Config;
use rog_platform::asus_armoury::FirmwareAttributes;
use rog_platform::platform::PlatformProfile;
fn write_attr_dir(base: &PathBuf, name: &str, default: &str, display: &str) {
let attr_dir = base.join(name);
create_dir_all(&attr_dir).unwrap();
let mut f = File::create(attr_dir.join("default_value")).unwrap();
write!(f, "{}", default).unwrap();
let mut f = File::create(attr_dir.join("display_name")).unwrap();
write!(f, "{}", display).unwrap();
// create current_value file so set_current_value can open for write
let mut f = File::create(attr_dir.join("current_value")).unwrap();
write!(f, "{}", default).unwrap();
}
#[test]
fn nv_tgp_ac_dc_applies_different_values() {
let td = tempdir().unwrap();
let base = td.path().join("attributes");
create_dir_all(&base).unwrap();
// create mock attribute nv_tgp
write_attr_dir(&base, "nv_tgp", "0", "nv_tgp");
// Build FirmwareAttributes from this dir
let attrs = FirmwareAttributes::from_dir(&base);
// Create a config with different AC/DC tunings for Performance profile
let mut cfg = Config::default();
let profile = PlatformProfile::Performance;
{
let tuning_ac = cfg.select_tunings(true, profile);
tuning_ac.enabled = true;
tuning_ac
.group
.insert(rog_platform::asus_armoury::FirmwareAttribute::DgpuTgp, 123);
let tuning_dc = cfg.select_tunings(false, profile);
tuning_dc.enabled = true;
tuning_dc
.group
.insert(rog_platform::asus_armoury::FirmwareAttribute::DgpuTgp, 45);
}
// Apply for AC
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
set_config_or_default(&attrs, &mut cfg, true, profile).await;
});
let nv_tgp_val_path = base.join("nv_tgp").join("current_value");
let val_ac = std::fs::read_to_string(&nv_tgp_val_path).unwrap();
assert_eq!(val_ac.trim(), "123");
// Now apply for DC
rt.block_on(async {
set_config_or_default(&attrs, &mut cfg, false, profile).await;
});
let val_dc = std::fs::read_to_string(&nv_tgp_val_path).unwrap();
assert_eq!(val_dc.trim(), "45");
}

View File

@@ -9,11 +9,13 @@ ENV{DMI_FAMILY}=="*Strix*", GOTO="asusd_start"
ENV{DMI_FAMILY}=="*Vivo*ook*", GOTO="asusd_start" ENV{DMI_FAMILY}=="*Vivo*ook*", GOTO="asusd_start"
ENV{DMI_FAMILY}=="*Zenbook*", GOTO="asusd_start" ENV{DMI_FAMILY}=="*Zenbook*", GOTO="asusd_start"
ENV{DMI_FAMILY}=="*ProArt*", GOTO="asusd_start" ENV{DMI_FAMILY}=="*ProArt*", GOTO="asusd_start"
ENV{DMI_FAMILY}=="*TX Air*", GOTO="asusd_start"
ENV{DMI_FAMILY}=="*TX Gaming*", GOTO="asusd_start"
# No match so # No match so
GOTO="asusd_end" GOTO="asusd_end"
LABEL="asusd_start" LABEL="asusd_start"
ACTION=="add|change", DRIVER=="asus-nb-wmi", TAG+="systemd", ENV{SYSTEMD_WANTS}="asusd.service" ACTION=="add|change", DRIVER=="asus-nb-wmi", TAG+="systemd", ENV{SYSTEMD_WANTS}+="asusd.service"
ACTION=="add|remove", DRIVER=="asus-nb-wmi", TAG+="systemd", RUN+="systemctl restart asusd.service" ACTION=="add|remove", DRIVER=="asus-nb-wmi", TAG+="systemd", ENV{SYSTEMD_WANTS}+="asusd.service"
LABEL="asusd_end" LABEL="asusd_end"

View File

@@ -20,7 +20,7 @@
%global debug_package %{nil} %global debug_package %{nil}
%endif %endif
%define version 6.1.9 %define version 6.1.17
%define specrelease %{?dist} %define specrelease %{?dist}
%define pkg_release 9%{specrelease} %define pkg_release 9%{specrelease}
@@ -31,6 +31,7 @@ Version: %{version}
Release: %{pkg_release} Release: %{pkg_release}
Summary: Control fan speeds, LEDs, graphics modes, and charge levels for ASUS notebooks Summary: Control fan speeds, LEDs, graphics modes, and charge levels for ASUS notebooks
License: MPLv2 License: MPLv2
Requires: power-profiles-daemon
Group: System Environment/Kernel Group: System Environment/Kernel
@@ -91,7 +92,9 @@ EOF
%build %build
export RUSTFLAGS="%{rustflags}" export RUSTFLAGS="%{rustflags}"
%if %{defined fedora} %if %{defined fedora}
%cargo_build %# Use an explicit cargo invocation for Fedora to avoid the macro adding `--locked`.
%# `--locked` breaks Fedora builds because the lockfile may not be appropriate for the distro buildroot.
/usr/bin/cargo auditable build --release
%else %else
/usr/bin/cargo auditable build --release /usr/bin/cargo auditable build --release
%endif %endif

View File

@@ -169,7 +169,7 @@ impl AnimeImage {
// first 5 rows for GA401 are always at X = 0 // first 5 rows for GA401 are always at X = 0
return 0; return 0;
} }
(y + 1) / 2 - 3 y.div_ceil(2) - 3
} }
AnimeType::GU604 => { AnimeType::GU604 => {
// first 9 rows start at zero // first 9 rows start at zero
@@ -185,7 +185,7 @@ impl AnimeImage {
return 0; return 0;
} }
// and then their offset grows by one every two rows // and then their offset grows by one every two rows
(y + 1) / 2 - 5 y.div_ceil(2) - 5
} }
} }
} }
@@ -213,7 +213,7 @@ impl AnimeImage {
// First 5 rows for GA401 are always 33 physical LEDs long // First 5 rows for GA401 are always 33 physical LEDs long
return 33; return 33;
} }
36 - (y + 1) / 2 36 - y.div_ceil(2)
} }
AnimeType::GU604 => { AnimeType::GU604 => {
if y <= 9 { if y <= 9 {

View File

@@ -5,7 +5,7 @@
layout_name: "fa506i", layout_name: "fa506i",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -14,7 +14,7 @@
layout_name: "fa506i", layout_name: "fa506i",
basic_modes: [Static, Breathe, RainbowCycle], basic_modes: [Static, Breathe, RainbowCycle],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -23,7 +23,7 @@
layout_name: "fa506i", layout_name: "fa506i",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -32,7 +32,7 @@
layout_name: "fa507", layout_name: "fa507",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -41,7 +41,7 @@
layout_name: "fx505d", layout_name: "fx505d",
basic_modes: [Static, Breathe, Pulse], basic_modes: [Static, Breathe, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -50,7 +50,7 @@
layout_name: "fx505d", layout_name: "fx505d",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -59,7 +59,7 @@
layout_name: "fa506i", layout_name: "fa506i",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -68,7 +68,7 @@
layout_name: "fa506i", layout_name: "fa506i",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -77,7 +77,7 @@
layout_name: "fa506i", layout_name: "fa506i",
basic_modes: [Static, Breathe, Pulse], basic_modes: [Static, Breathe, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -86,7 +86,16 @@
layout_name: "fa506i", layout_name: "fa506i",
basic_modes: [Static, Breathe, Pulse], basic_modes: [Static, Breathe, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard],
),
(
device_name: "FX607J",
product_id: "",
layout_name: "fa506i",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -95,7 +104,7 @@
layout_name: "fa506i", layout_name: "fa506i",
basic_modes: [Static, Breathe, Pulse], basic_modes: [Static, Breathe, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -104,7 +113,16 @@
layout_name: "fx505d", layout_name: "fx505d",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard],
),
(
device_name: "FX706H",
product_id: "",
layout_name: "fx505d",
basic_modes: [Static, Breathe, RainbowCycle],
basic_zones: [],
advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -113,7 +131,7 @@
layout_name: "g512", layout_name: "g512",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard, Lightbar], power_zones: [Keyboard, Lightbar],
), ),
( (
@@ -131,7 +149,7 @@
layout_name: "g513i", layout_name: "g513i",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard, Lightbar], power_zones: [Keyboard, Lightbar],
), ),
( (
@@ -176,7 +194,7 @@
layout_name: "gx502", layout_name: "gx502",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -185,7 +203,7 @@
layout_name: "gx502", layout_name: "gx502",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -230,7 +248,16 @@
layout_name: "g634j-per-key", layout_name: "g634j-per-key",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard, Lightbar],
),
(
device_name: "G614JIR",
product_id: "",
layout_name: "g513i-per-key",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
basic_zones: [],
advanced_type: PerKey,
power_zones: [Keyboard, Lightbar], power_zones: [Keyboard, Lightbar],
), ),
( (
@@ -239,7 +266,7 @@
layout_name: "g634j-per-key", layout_name: "g634j-per-key",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard, Lightbar], power_zones: [Keyboard, Lightbar],
), ),
( (
@@ -248,7 +275,7 @@
layout_name: "g634j-per-key", layout_name: "g634j-per-key",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard, Lightbar], power_zones: [Keyboard, Lightbar],
), ),
( (
@@ -266,7 +293,7 @@
layout_name: "gl503", layout_name: "gl503",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -275,7 +302,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -284,7 +311,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -293,7 +320,7 @@
layout_name: "gx502", layout_name: "gx502",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard, Lightbar], power_zones: [Keyboard, Lightbar],
), ),
( (
@@ -302,7 +329,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard, Lightbar], power_zones: [Keyboard, Lightbar],
), ),
( (
@@ -311,7 +338,7 @@
layout_name: "gx502", layout_name: "gx502",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard, Lightbar], power_zones: [Keyboard, Lightbar],
), ),
( (
@@ -320,7 +347,7 @@
layout_name: "gx502", layout_name: "gx502",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard, Lightbar], power_zones: [Keyboard, Lightbar],
), ),
( (
@@ -356,7 +383,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -374,7 +401,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4, BarLeft, BarRight], basic_zones: [Key1, Key2, Key3, Key4, BarLeft, BarRight],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard, Lightbar], power_zones: [Keyboard, Lightbar],
), ),
( (
@@ -392,7 +419,7 @@
layout_name: "g533q", layout_name: "g533q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -401,7 +428,7 @@
layout_name: "g533q", layout_name: "g533q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -410,7 +437,7 @@
layout_name: "g533q", layout_name: "g533q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -473,7 +500,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse], basic_modes: [Static, Breathe, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -482,7 +509,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse], basic_modes: [Static, Breathe, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -491,7 +518,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -500,7 +527,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse], basic_modes: [Static, Breathe, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -509,7 +536,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -518,7 +545,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -527,7 +554,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse], basic_modes: [Static, Breathe, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -536,7 +563,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse], basic_modes: [Static, Breathe, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -545,7 +572,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -554,7 +581,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse], basic_modes: [Static, Breathe, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -563,7 +590,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -581,7 +608,7 @@
layout_name: "gl503", layout_name: "gl503",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -590,7 +617,7 @@
layout_name: "gl503", layout_name: "gl503",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -599,7 +626,7 @@
layout_name: "gl503", layout_name: "gl503",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4, Logo, BarLeft, BarRight], basic_zones: [Key1, Key2, Key3, Key4, Logo, BarLeft, BarRight],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -617,7 +644,7 @@
layout_name: "g533q", layout_name: "g533q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -626,7 +653,7 @@
layout_name: "gl503", layout_name: "gl503",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -635,7 +662,7 @@
layout_name: "fa507", layout_name: "fa507",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -683,6 +710,15 @@
advanced_type: Zoned([SingleZone]), advanced_type: Zoned([SingleZone]),
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
(
device_name: "GU605C",
product_id: "",
layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: Zoned([SingleZone]),
power_zones: [Keyboard],
),
( (
device_name: "GU605M", device_name: "GU605M",
product_id: "", product_id: "",
@@ -698,7 +734,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse], basic_modes: [Static, Breathe, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -707,7 +743,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse], basic_modes: [Static, Breathe, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -716,7 +752,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse], basic_modes: [Static, Breathe, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -725,7 +761,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -743,7 +779,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -761,7 +797,7 @@
layout_name: "gx531-per-key", layout_name: "gx531-per-key",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4], basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -815,7 +851,7 @@
layout_name: "gx531-per-key", layout_name: "gx531-per-key",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -824,7 +860,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse], basic_modes: [Static, Breathe, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -833,7 +869,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse], basic_modes: [Static, Breathe, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -842,8 +878,8 @@
layout_name: "", layout_name: "",
basic_modes: [Static, Breathe, Pulse], basic_modes: [Static, Breathe, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [None], power_zones: [r#None],
), ),
( (
device_name: "GZ301Z", device_name: "GZ301Z",
@@ -851,7 +887,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse], basic_modes: [Static, Breathe, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Keyboard], power_zones: [Keyboard],
), ),
( (
@@ -860,7 +896,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Ally], power_zones: [Ally],
), ),
( (
@@ -869,7 +905,7 @@
layout_name: "ga401q", layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse], basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [], basic_zones: [],
advanced_type: None, advanced_type: r#None,
power_zones: [Ally], power_zones: [Ally],
), ),
]) ])

View File

@@ -164,7 +164,29 @@ impl LedSupportFile {
return Some(data); return Some(data);
} }
warn!("Does {} exist?", ASUS_LED_MODE_USER_CONF); // If the system-wide support files were not available (e.g. running
// tests in CI or a development environment) try to load the
// bundled test data shipped with the crate under `data/aura_support.ron`.
// This allows unit tests to run without requiring files to be installed
// to `/usr/share/asusd`.
let mut bundled = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
bundled.push("data/aura_support.ron");
if let Ok(buf) = std::fs::read_to_string(&bundled) {
if let Ok(mut tmp) = ron::from_str::<LedSupportFile>(&buf) {
data.0.append(&mut tmp.0);
data.0.sort_by(|a, b| a.device_name.cmp(&b.device_name));
info!("Loaded bundled LED support data from {}", bundled.display());
return Some(data);
} else {
warn!(
"Bundled aura_support.ron present but failed to parse: {}",
bundled.display()
);
}
} else {
warn!("Does {} exist?", ASUS_LED_MODE_USER_CONF);
}
None None
} }
} }

View File

@@ -207,12 +207,14 @@ mod tests {
fn single_key_next_state_then_create() { fn single_key_next_state_then_create() {
let layout = KeyLayout::default_layout(); let layout = KeyLayout::default_layout();
let mut seq = AdvancedEffects::new(false); let mut seq = AdvancedEffects::new(false);
seq.effects seq.effects.push(Effect::Static(Static::new(
.push(Effect::Static(Static::new(LedCode::F, Colour { LedCode::F,
Colour {
r: 255, r: 255,
g: 127, g: 127,
b: 0, b: 0,
}))); },
)));
seq.next_state(&layout); seq.next_state(&layout);
let packets = seq.create_packets(); let packets = seq.create_packets();

View File

@@ -335,93 +335,117 @@ impl KeyLayout {
KeyShape::new_led(1.0, 1.0, 0.1, 0.1, 0.1, 0.1), KeyShape::new_led(1.0, 1.0, 0.1, 0.1, 0.1, 0.1),
)]), )]),
key_rows: vec![ key_rows: vec![
KeyRow::new(0.1, 0.1, vec![ KeyRow::new(
(LedCode::Esc, "regular".to_owned()), 0.1,
(LedCode::F1, "regular".to_owned()), 0.1,
(LedCode::F2, "regular".to_owned()), vec![
(LedCode::F3, "regular".to_owned()), (LedCode::Esc, "regular".to_owned()),
(LedCode::F4, "regular".to_owned()), (LedCode::F1, "regular".to_owned()),
// not sure which key to put here (LedCode::F2, "regular".to_owned()),
(LedCode::F5, "regular".to_owned()), (LedCode::F3, "regular".to_owned()),
(LedCode::F6, "regular".to_owned()), (LedCode::F4, "regular".to_owned()),
(LedCode::F7, "regular".to_owned()), // not sure which key to put here
(LedCode::F8, "regular".to_owned()), (LedCode::F5, "regular".to_owned()),
(LedCode::F9, "regular".to_owned()), (LedCode::F6, "regular".to_owned()),
(LedCode::F10, "regular".to_owned()), (LedCode::F7, "regular".to_owned()),
(LedCode::F11, "regular".to_owned()), (LedCode::F8, "regular".to_owned()),
(LedCode::F12, "regular".to_owned()), (LedCode::F9, "regular".to_owned()),
]), (LedCode::F10, "regular".to_owned()),
KeyRow::new(0.1, 0.1, vec![ (LedCode::F11, "regular".to_owned()),
(LedCode::Tilde, "regular".to_owned()), (LedCode::F12, "regular".to_owned()),
(LedCode::N1, "regular".to_owned()), ],
(LedCode::N2, "regular".to_owned()), ),
(LedCode::N3, "regular".to_owned()), KeyRow::new(
(LedCode::N4, "regular".to_owned()), 0.1,
(LedCode::N5, "regular".to_owned()), 0.1,
(LedCode::N6, "regular".to_owned()), vec![
(LedCode::N7, "regular".to_owned()), (LedCode::Tilde, "regular".to_owned()),
(LedCode::N8, "regular".to_owned()), (LedCode::N1, "regular".to_owned()),
(LedCode::N9, "regular".to_owned()), (LedCode::N2, "regular".to_owned()),
(LedCode::N0, "regular".to_owned()), (LedCode::N3, "regular".to_owned()),
(LedCode::Hyphen, "regular".to_owned()), (LedCode::N4, "regular".to_owned()),
(LedCode::Equals, "regular".to_owned()), (LedCode::N5, "regular".to_owned()),
(LedCode::Backspace, "regular".to_owned()), (LedCode::N6, "regular".to_owned()),
]), (LedCode::N7, "regular".to_owned()),
KeyRow::new(0.1, 0.1, vec![ (LedCode::N8, "regular".to_owned()),
(LedCode::Tab, "regular".to_owned()), (LedCode::N9, "regular".to_owned()),
(LedCode::Q, "regular".to_owned()), (LedCode::N0, "regular".to_owned()),
(LedCode::W, "regular".to_owned()), (LedCode::Hyphen, "regular".to_owned()),
(LedCode::E, "regular".to_owned()), (LedCode::Equals, "regular".to_owned()),
(LedCode::R, "regular".to_owned()), (LedCode::Backspace, "regular".to_owned()),
(LedCode::T, "regular".to_owned()), ],
(LedCode::Y, "regular".to_owned()), ),
(LedCode::U, "regular".to_owned()), KeyRow::new(
(LedCode::I, "regular".to_owned()), 0.1,
(LedCode::O, "regular".to_owned()), 0.1,
(LedCode::P, "regular".to_owned()), vec![
(LedCode::LBracket, "regular".to_owned()), (LedCode::Tab, "regular".to_owned()),
(LedCode::RBracket, "regular".to_owned()), (LedCode::Q, "regular".to_owned()),
(LedCode::BackSlash, "regular".to_owned()), (LedCode::W, "regular".to_owned()),
]), (LedCode::E, "regular".to_owned()),
KeyRow::new(0.1, 0.1, vec![ (LedCode::R, "regular".to_owned()),
(LedCode::Caps, "regular".to_owned()), (LedCode::T, "regular".to_owned()),
(LedCode::A, "regular".to_owned()), (LedCode::Y, "regular".to_owned()),
(LedCode::S, "regular".to_owned()), (LedCode::U, "regular".to_owned()),
(LedCode::D, "regular".to_owned()), (LedCode::I, "regular".to_owned()),
(LedCode::F, "regular".to_owned()), (LedCode::O, "regular".to_owned()),
(LedCode::G, "regular".to_owned()), (LedCode::P, "regular".to_owned()),
(LedCode::H, "regular".to_owned()), (LedCode::LBracket, "regular".to_owned()),
(LedCode::J, "regular".to_owned()), (LedCode::RBracket, "regular".to_owned()),
(LedCode::K, "regular".to_owned()), (LedCode::BackSlash, "regular".to_owned()),
(LedCode::L, "regular".to_owned()), ],
(LedCode::SemiColon, "regular".to_owned()), ),
(LedCode::Quote, "regular".to_owned()), KeyRow::new(
(LedCode::Return, "regular".to_owned()), 0.1,
]), 0.1,
KeyRow::new(0.1, 0.1, vec![ vec![
(LedCode::LShift, "regular".to_owned()), (LedCode::Caps, "regular".to_owned()),
(LedCode::Z, "regular".to_owned()), (LedCode::A, "regular".to_owned()),
(LedCode::X, "regular".to_owned()), (LedCode::S, "regular".to_owned()),
(LedCode::C, "regular".to_owned()), (LedCode::D, "regular".to_owned()),
(LedCode::V, "regular".to_owned()), (LedCode::F, "regular".to_owned()),
(LedCode::B, "regular".to_owned()), (LedCode::G, "regular".to_owned()),
(LedCode::N, "regular".to_owned()), (LedCode::H, "regular".to_owned()),
(LedCode::M, "regular".to_owned()), (LedCode::J, "regular".to_owned()),
(LedCode::Comma, "regular".to_owned()), (LedCode::K, "regular".to_owned()),
(LedCode::Period, "regular".to_owned()), (LedCode::L, "regular".to_owned()),
(LedCode::FwdSlash, "regular".to_owned()), (LedCode::SemiColon, "regular".to_owned()),
(LedCode::Rshift, "regular".to_owned()), (LedCode::Quote, "regular".to_owned()),
]), (LedCode::Return, "regular".to_owned()),
KeyRow::new(0.1, 0.1, vec![ ],
(LedCode::LCtrl, "regular".to_owned()), ),
(LedCode::LFn, "regular".to_owned()), KeyRow::new(
(LedCode::Meta, "regular".to_owned()), 0.1,
(LedCode::LAlt, "regular".to_owned()), 0.1,
(LedCode::Spacebar, "regular".to_owned()), vec![
(LedCode::RAlt, "regular".to_owned()), (LedCode::LShift, "regular".to_owned()),
(LedCode::PrtSc, "regular".to_owned()), (LedCode::Z, "regular".to_owned()),
(LedCode::RCtrl, "regular".to_owned()), (LedCode::X, "regular".to_owned()),
]), (LedCode::C, "regular".to_owned()),
(LedCode::V, "regular".to_owned()),
(LedCode::B, "regular".to_owned()),
(LedCode::N, "regular".to_owned()),
(LedCode::M, "regular".to_owned()),
(LedCode::Comma, "regular".to_owned()),
(LedCode::Period, "regular".to_owned()),
(LedCode::FwdSlash, "regular".to_owned()),
(LedCode::Rshift, "regular".to_owned()),
],
),
KeyRow::new(
0.1,
0.1,
vec![
(LedCode::LCtrl, "regular".to_owned()),
(LedCode::LFn, "regular".to_owned()),
(LedCode::Meta, "regular".to_owned()),
(LedCode::LAlt, "regular".to_owned()),
(LedCode::Spacebar, "regular".to_owned()),
(LedCode::RAlt, "regular".to_owned()),
(LedCode::PrtSc, "regular".to_owned()),
(LedCode::RCtrl, "regular".to_owned()),
],
),
], ],
} }
} }

View File

@@ -12,7 +12,7 @@ edition.workspace = true
default = [] default = []
mocking = [] mocking = []
x11 = ["slint/backend-winit-x11"] x11 = ["slint/backend-winit-x11"]
# Requires RUSTFLAGS="--cfg tokio_unstable" # Optional tokio debug feature does not require nightly; remove RUSTFLAGS note.
tokio-debug = ["console-subscriber"] tokio-debug = ["console-subscriber"]
[dependencies] [dependencies]
@@ -58,3 +58,17 @@ features = [
[build-dependencies.slint-build] [build-dependencies.slint-build]
git = "https://github.com/slint-ui/slint.git" git = "https://github.com/slint-ui/slint.git"
[package.metadata.deb]
license-file = ["../LICENSE", "4"]
extended-description = """\
The dbus server for asusctl and rog-control-center applications."""
depends = "$auto"
section = "utility"
priority = "optional"
assets = [
["target/release/rog-control-center", "usr/bin/", "755"],
["../rog_gui-fakeinstall/usr/share/applications/*", "usr/share/share/applications/", "644"],
["../rog_gui-fakeinstall/usr/share/icons/hicolor/512x512/apps/*", "usr/share/icons/hicolor/512x512/apps", "644"],
["../rog_gui-fakeinstall/usr/share/icons/hicolor/scalable/status/*", "usr/share/icons/hicolor/scalable/status", "644"],
]

View File

@@ -24,4 +24,6 @@ pub struct CliStart {
that might match your laptop" that might match your laptop"
)] )]
pub layout_viewing: bool, pub layout_viewing: bool,
#[options(help = "start in tray mode - main window hidden")]
pub tray_mode: bool,
} }

View File

@@ -9,6 +9,7 @@ pub enum Error {
ConfigLockFail, ConfigLockFail,
XdgVars, XdgVars,
Zbus(zbus::Error), Zbus(zbus::Error),
ZbusFdo(zbus::fdo::Error),
Notification(notify_rust::error::Error), Notification(notify_rust::error::Error),
} }
@@ -21,6 +22,7 @@ impl fmt::Display for Error {
Error::ConfigLockFail => write!(f, "Failed to lock user config"), Error::ConfigLockFail => write!(f, "Failed to lock user config"),
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::ZbusFdo(err) => write!(f, "Error: {}", err),
Error::Notification(err) => write!(f, "Notification Error: {}", err), Error::Notification(err) => write!(f, "Notification Error: {}", err),
} }
} }
@@ -40,6 +42,12 @@ impl From<zbus::Error> for Error {
} }
} }
impl From<zbus::fdo::Error> for Error {
fn from(err: zbus::fdo::Error) -> Self {
Error::ZbusFdo(err)
}
}
impl From<notify_rust::error::Error> for Error { impl From<notify_rust::error::Error> for Error {
fn from(err: notify_rust::error::Error) -> Self { fn from(err: notify_rust::error::Error) -> Self {
Error::Notification(err) Error::Notification(err)

View File

@@ -140,12 +140,22 @@ async fn main() -> Result<()> {
config.startup_in_background = false; config.startup_in_background = false;
config.start_fullscreen = true; config.start_fullscreen = true;
} }
if cli_parsed.tray_mode {
config.enable_tray_icon = true;
config.run_in_background = true;
config.startup_in_background = true;
}
config.write(); config.write();
let enable_tray_icon = config.enable_tray_icon; let enable_tray_icon = config.enable_tray_icon;
let startup_in_background = config.startup_in_background; let startup_in_background = config.startup_in_background;
let config = Arc::new(Mutex::new(config)); let config = Arc::new(Mutex::new(config));
// shared weak handle to the UI so other threads can request UI updates
let ui_handle: Arc<Mutex<Option<slint::Weak<MainWindow>>>> = Arc::new(Mutex::new(None));
start_notifications(config.clone(), &rt)?; start_notifications(config.clone(), &rt)?;
if enable_tray_icon { if enable_tray_icon {
@@ -170,12 +180,14 @@ async fn main() -> Result<()> {
slint::init_translations!(concat!(env!("CARGO_MANIFEST_DIR"), "/translations/")); slint::init_translations!(concat!(env!("CARGO_MANIFEST_DIR"), "/translations/"));
} }
let config_for_ui = config.clone();
let ui_handle_for_thread = ui_handle.clone();
thread::spawn(move || { thread::spawn(move || {
let mut state = AppState::StartingUp; let mut state = AppState::StartingUp;
loop { loop {
if is_rog_ally { if is_rog_ally {
let config_copy_2 = config.clone(); let config_copy_2 = config_for_ui.clone();
let newui = setup_window(config.clone()); let newui = setup_window(config_for_ui.clone());
newui.window().on_close_requested(move || { newui.window().on_close_requested(move || {
exit(0); exit(0);
}); });
@@ -211,13 +223,19 @@ async fn main() -> Result<()> {
*app_state = AppState::MainWindowOpen; *app_state = AppState::MainWindowOpen;
} }
let config_copy = config.clone(); let config_copy = config_for_ui.clone();
let app_state_copy = app_state.clone(); let app_state_copy = app_state.clone();
let ui_handle_for_ui = ui_handle_for_thread.clone();
slint::invoke_from_event_loop(move || { slint::invoke_from_event_loop(move || {
let ui_handle_for_ui = ui_handle_for_ui.clone();
UI.with(|ui| { UI.with(|ui| {
let app_state_copy = app_state_copy.clone(); let app_state_copy = app_state_copy.clone();
let mut ui = ui.borrow_mut(); let mut ui = ui.borrow_mut();
if let Some(ui) = ui.as_mut() { if let Some(ui) = ui.as_mut() {
// store weak handle so other threads can update UI globals
if let Ok(mut h) = ui_handle_for_ui.lock() {
*h = Some(ui.as_weak());
}
ui.window().show().unwrap(); ui.window().show().unwrap();
ui.window().on_close_requested(move || { ui.window().on_close_requested(move || {
if let Ok(mut app_state) = app_state_copy.lock() { if let Ok(mut app_state) = app_state_copy.lock() {
@@ -228,6 +246,10 @@ async fn main() -> Result<()> {
} else { } else {
let config_copy_2 = config_copy.clone(); let config_copy_2 = config_copy.clone();
let newui = setup_window(config_copy); let newui = setup_window(config_copy);
// store weak handle for the newly created UI
if let Ok(mut h) = ui_handle_for_ui.lock() {
*h = Some(newui.as_weak());
}
newui.window().on_close_requested(move || { newui.window().on_close_requested(move || {
if let Ok(mut app_state) = app_state_copy.lock() { if let Ok(mut app_state) = app_state_copy.lock() {
*app_state = AppState::MainWindowClosed; *app_state = AppState::MainWindowClosed;
@@ -263,8 +285,8 @@ async fn main() -> Result<()> {
slint::quit_event_loop().unwrap(); slint::quit_event_loop().unwrap();
exit(0); exit(0);
} else if state != AppState::MainWindowOpen { } else if state != AppState::MainWindowOpen {
if let Ok(config) = config.lock() { if let Ok(cfg) = config_for_ui.lock() {
if !config.run_in_background { if !cfg.run_in_background {
slint::quit_event_loop().unwrap(); slint::quit_event_loop().unwrap();
exit(0); exit(0);
} }
@@ -274,11 +296,67 @@ async fn main() -> Result<()> {
} }
}); });
// start config watcher to pick up external edits
spawn_config_watcher(config.clone(), ui_handle.clone());
slint::run_event_loop_until_quit().unwrap(); slint::run_event_loop_until_quit().unwrap();
rt.shutdown_background(); rt.shutdown_background();
Ok(()) Ok(())
} }
// Spawn a watcher thread that polls the config file and reloads it when modified.
// This keeps the running rogcc instance in sync with manual edits to the config file.
fn spawn_config_watcher(
config: Arc<Mutex<Config>>,
ui_handle: Arc<Mutex<Option<slint::Weak<MainWindow>>>>,
) {
std::thread::spawn(move || {
use std::time::SystemTime;
let cfg_path = Config::config_dir().join(Config::new().file_name());
let mut last_mtime: Option<SystemTime> = None;
loop {
if let Ok(meta) = std::fs::metadata(&cfg_path) {
if let Ok(m) = meta.modified() {
if last_mtime.is_none() {
last_mtime = Some(m);
} else if last_mtime.is_some_and(|t| t < m) {
// file changed, reload
last_mtime = Some(m);
let new_cfg = Config::new().load();
if let Ok(mut lock) = config.lock() {
*lock = new_cfg.clone();
}
// Update UI app settings globals if UI is present
if let Ok(maybe_weak) = ui_handle.lock() {
if let Some(weak) = maybe_weak.clone() {
let config_for_ui = config.clone();
weak.upgrade_in_event_loop(move |w| {
if let Ok(lock) = config_for_ui.lock() {
let cfg = lock.clone();
w.global::<rog_control_center::AppSettingsPageData>()
.set_run_in_background(cfg.run_in_background);
w.global::<rog_control_center::AppSettingsPageData>()
.set_startup_in_background(cfg.startup_in_background);
w.global::<rog_control_center::AppSettingsPageData>()
.set_enable_tray_icon(cfg.enable_tray_icon);
w.global::<rog_control_center::AppSettingsPageData>()
.set_enable_dgpu_notifications(
cfg.notifications.enabled,
);
}
})
.ok();
}
}
}
}
}
std::thread::sleep(std::time::Duration::from_secs(2));
}
});
}
fn do_cli_help(parsed: &CliStart) -> bool { fn do_cli_help(parsed: &CliStart) -> bool {
if parsed.help { if parsed.help {
println!("{}", CliStart::usage()); println!("{}", CliStart::usage());

View File

@@ -100,6 +100,31 @@ impl Bios {
pub fn set_panel_od(&self, _b: bool) -> Result<()> { pub fn set_panel_od(&self, _b: bool) -> Result<()> {
Ok(()) Ok(())
} }
// Mock NV/dGPU tunables
pub fn nv_dynamic_boost(&self) -> Result<i16> {
Ok(0)
}
pub fn set_nv_dynamic_boost(&self, _v: i16) -> Result<()> {
Ok(())
}
pub fn nv_temp_target(&self) -> Result<i16> {
Ok(0)
}
pub fn set_nv_temp_target(&self, _v: i16) -> Result<()> {
Ok(())
}
pub fn nv_tgp(&self) -> Result<i16> {
Ok(0)
}
pub fn set_nv_tgp(&self, _v: i16) -> Result<()> {
Ok(())
}
} }
pub struct Profile; pub struct Profile;

View File

@@ -116,26 +116,26 @@ pub fn start_notifications(
if p == 0 && p != last_state { if p == 0 && p != last_state {
let prog: Vec<&str> = bat.split_whitespace().collect(); let prog: Vec<&str> = bat.split_whitespace().collect();
if prog.len() > 1 { if (!prog.is_empty()) && (!prog[0].is_empty()) {
let mut cmd = Command::new(prog[0]); let mut cmd = Command::new(prog[0]);
for arg in prog.iter().skip(1) { for arg in prog.iter().skip(1) {
cmd.arg(*arg); cmd.arg(*arg);
} }
cmd.spawn() cmd.spawn()
.map_err(|e| error!("AC command error: {e:?}")) .map_err(|e| error!("Battery power command error: {e:?}"))
.ok(); .ok();
} }
} else if p != last_state { } else if p != last_state {
let prog: Vec<&str> = ac.split_whitespace().collect(); let prog: Vec<&str> = ac.split_whitespace().collect();
if prog.len() > 1 { if (!prog.is_empty()) && (!prog[0].is_empty()) {
let mut cmd = Command::new(prog[0]); let mut cmd = Command::new(prog[0]);
for arg in prog.iter().skip(1) { for arg in prog.iter().skip(1) {
cmd.arg(*arg); cmd.arg(*arg);
} }
cmd.spawn() cmd.spawn()
.map_err(|e| error!("AC command error: {e:?}")) .map_err(|e| error!("AC power command error: {e:?}"))
.ok(); .ok();
} }
} }
@@ -203,11 +203,19 @@ pub fn start_notifications(
})?; })?;
let proxy_copy = proxy.clone(); let proxy_copy = proxy.clone();
let enabled_notifications_copy_action = enabled_notifications_copy.clone();
let mut p = proxy.receive_notify_action().await?; let mut p = proxy.receive_notify_action().await?;
tokio::spawn(async move { tokio::spawn(async move {
info!("Started zbus signal thread: receive_notify_action"); info!("Started zbus signal thread: receive_notify_action");
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() {
// Respect user notification settings for gpu actions
if let Ok(cfg) = enabled_notifications_copy_action.lock() {
if !cfg.notifications.enabled || !cfg.notifications.receive_notify_gfx {
continue;
}
}
let action = out.action(); let action = out.action();
let mode = convert_gfx_mode(proxy.mode().await.unwrap_or_default()); let mode = convert_gfx_mode(proxy.mode().await.unwrap_or_default());
match action { match action {
@@ -309,7 +317,9 @@ fn do_gfx_action_notif(message: &str, action: GfxUserAction, mode: GpuMode) -> R
//.hint(Hint::Resident(true)) //.hint(Hint::Resident(true))
.hint(Hint::Category("device".into())) .hint(Hint::Category("device".into()))
.urgency(Urgency::Critical) .urgency(Urgency::Critical)
.timeout(Timeout::Never) // For user-action notifications keep them visible if they require interaction
// but for non-interactive actions we prefer they auto-hide like other notifs.
.timeout(Timeout::Milliseconds(6000))
.icon("dialog-warning") .icon("dialog-warning")
.hint(Hint::Transient(true)); .hint(Hint::Transient(true));

View File

@@ -1,7 +1,8 @@
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use log::{error, info}; use log::error;
use rog_dbus::zbus_fan_curves::FanCurvesProxy; use rog_dbus::zbus_fan_curves::FanCurvesProxy;
use rog_dbus::zbus_platform::PlatformProxy;
use rog_platform::platform::PlatformProfile; use rog_platform::platform::PlatformProfile;
use rog_profiles::fan_curve_set::CurveData; use rog_profiles::fan_curve_set::CurveData;
use slint::{ComponentHandle, Model, Weak}; use slint::{ComponentHandle, Model, Weak};
@@ -100,96 +101,122 @@ pub fn setup_fan_curve_page(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
tokio::spawn(async move { tokio::spawn(async move {
// Create the connections/proxies here to prevent future delays in process // Create the connections/proxies here to prevent future delays in process
let conn = if let Ok(conn) = zbus::Connection::system().await.map_err(|e| error!("{e:}")) { let conn = match zbus::Connection::system().await {
conn Ok(conn) => conn,
} else { Err(e) => {
return; error!("{e:}");
return;
}
}; };
let fans = if let Ok(fans) = FanCurvesProxy::new(&conn).await.map_err(|e| error!("{e:}")) {
fans let fans = match FanCurvesProxy::new(&conn).await {
} else { Ok(fans) => fans,
info!( Err(e) => {
"This device may not have an Fan Curve control. If not then the error can be \ error!("{e:}");
ignored" return;
); }
return; };
let platform = match PlatformProxy::new(&conn).await {
Ok(platform) => platform,
Err(e) => {
error!("{e:}");
return;
}
};
let platform_profile_choices = match platform.platform_profile_choices().await {
Ok(choices) => choices,
Err(e) => {
error!("{e:}");
return;
}
}; };
let handle_copy = handle.clone(); let handle_copy = handle.clone();
// Do initial setup // Do initial setup
let Ok(balanced) = fans let balanced = match fans.fan_curve_data(PlatformProfile::Balanced).await {
.fan_curve_data(PlatformProfile::Balanced) Ok(data) => data,
.await Err(e) => {
.map_err(|e| error!("Couldn't get balanced data: {e:}")) error!("Couldn't get balanced data: {e:}");
else { return;
return; }
}; };
let Ok(perf) = fans
.fan_curve_data(PlatformProfile::Performance) let perf = match fans.fan_curve_data(PlatformProfile::Performance).await {
.await Ok(data) => data,
.map_err(|e| error!("Couldn't get performance data: {e:}")) Err(e) => {
else { error!("Couldn't get performance data: {e:}");
return; return;
}
}; };
let Ok(quiet) = fans
.fan_curve_data(PlatformProfile::Quiet) // TODO: the fan curve stuff was written donkeys ago with the expectation that
.await // only 3 profiles existed
.map_err(|e| error!("Couldn't get quiet data: {e:}")) let profile = if platform_profile_choices.contains(&PlatformProfile::Quiet) {
else { PlatformProfile::Quiet
return; } else {
PlatformProfile::LowPower
}; };
let quiet = match fans.fan_curve_data(profile).await {
Ok(data) => data,
Err(e) => {
error!("Couldn't get quiet data: {e:}");
return;
}
};
update_fan_data(handle, balanced, perf, quiet); update_fan_data(handle, balanced, perf, quiet);
let handle_next1 = handle_copy.clone(); let handle_next1 = handle_copy.clone();
handle_copy if let Err(e) = handle_copy.upgrade_in_event_loop(move |handle| {
.upgrade_in_event_loop(move |handle| { let global = handle.global::<FanPageData>();
let global = handle.global::<FanPageData>(); let fans1 = fans.clone();
let fans1 = fans.clone(); global.on_set_profile_default(move |profile| {
global.on_set_profile_default(move |profile| { let fans = fans1.clone();
let fans = fans1.clone(); let handle_next = handle_next1.clone();
let handle_next = handle_next1.clone(); tokio::spawn(async move {
tokio::spawn(async move { if fans.set_curves_to_defaults(profile.into()).await.is_err() {
if fans.set_curves_to_defaults(profile.into()).await.is_err() { return;
return; }
} let Ok(balanced) = fans
let Ok(balanced) = fans .fan_curve_data(PlatformProfile::Balanced)
.fan_curve_data(PlatformProfile::Balanced) .await
.await .map_err(|e| error!("{e:}"))
.map_err(|e| error!("{e:}")) else {
else { return;
return; };
}; let Ok(perf) = fans
let Ok(perf) = fans .fan_curve_data(PlatformProfile::Performance)
.fan_curve_data(PlatformProfile::Performance) .await
.await .map_err(|e| error!("{e:}"))
.map_err(|e| error!("{e:}")) else {
else { return;
return; };
}; let Ok(quiet) = fans
let Ok(quiet) = fans .fan_curve_data(PlatformProfile::Quiet)
.fan_curve_data(PlatformProfile::Quiet) .await
.await .map_err(|e| error!("{e:}"))
.map_err(|e| error!("{e:}")) else {
else { return;
return; };
}; update_fan_data(handle_next, balanced, perf, quiet);
update_fan_data(handle_next, balanced, perf, quiet);
});
}); });
global.on_set_fan_data(move |fan, profile, enabled, data| { });
let fans = fans.clone(); global.on_set_fan_data(move |fan, profile, enabled, data| {
let data: Vec<Node> = data.iter().collect(); let fans = fans.clone();
let data = fan_data_for(fan, enabled, data); let data: Vec<Node> = data.iter().collect();
tokio::spawn(async move { let data = fan_data_for(fan, enabled, data);
fans.set_fan_curve(profile.into(), data) tokio::spawn(async move {
.await fans.set_fan_curve(profile.into(), data)
.map_err(|e| error!("{e:}")) .await
.ok() .map_err(|e| error!("{e:}"))
}); .ok()
}); });
}) });
.map_err(|e| error!("setup_fan_curve_page: upgrade_in_event_loop: {e:?}")) }) {
.ok(); error!("setup_fan_curve_page: upgrade_in_event_loop: {e:?}");
}
}); });
} }

View File

@@ -3,6 +3,7 @@ use std::sync::{Arc, Mutex};
use concat_idents::concat_idents; use concat_idents::concat_idents;
use log::{debug, error}; use log::{debug, error};
use rog_dbus::asus_armoury::AsusArmouryProxy; use rog_dbus::asus_armoury::AsusArmouryProxy;
use rog_dbus::zbus_backlight::BacklightProxy;
use rog_dbus::zbus_platform::{PlatformProxy, PlatformProxyBlocking}; use rog_dbus::zbus_platform::{PlatformProxy, PlatformProxyBlocking};
use rog_platform::asus_armoury::FirmwareAttribute; use rog_platform::asus_armoury::FirmwareAttribute;
use rog_platform::platform::Properties; use rog_platform::platform::Properties;
@@ -11,7 +12,7 @@ use slint::{ComponentHandle, Model, ModelRc, SharedString, VecModel};
use super::show_toast; use super::show_toast;
use crate::config::Config; use crate::config::Config;
use crate::zbus_proxies::find_iface_async; use crate::zbus_proxies::find_iface_async;
use crate::{set_ui_callbacks, set_ui_props_async, AttrMinMax, MainWindow, SystemPageData}; use crate::{set_ui_callbacks, AttrMinMax, MainWindow, SystemPageData};
const MINMAX: AttrMinMax = AttrMinMax { const MINMAX: AttrMinMax = AttrMinMax {
min: 0, min: 0,
@@ -39,7 +40,10 @@ pub fn setup_system_page(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
ui.global::<SystemPageData>().set_platform_profile(-1); ui.global::<SystemPageData>().set_platform_profile(-1);
ui.global::<SystemPageData>().set_panel_overdrive(-1); ui.global::<SystemPageData>().set_panel_overdrive(-1);
ui.global::<SystemPageData>().set_boot_sound(-1); ui.global::<SystemPageData>().set_boot_sound(-1);
ui.global::<SystemPageData>().set_screen_auto_brightness(-1);
ui.global::<SystemPageData>().set_mcu_powersave(-1);
ui.global::<SystemPageData>().set_mini_led_mode(-1); ui.global::<SystemPageData>().set_mini_led_mode(-1);
ui.global::<SystemPageData>().set_screenpad_brightness(-1);
ui.global::<SystemPageData>().set_ppt_pl1_spl(MINMAX); ui.global::<SystemPageData>().set_ppt_pl1_spl(MINMAX);
ui.global::<SystemPageData>().set_ppt_pl2_sppt(MINMAX); ui.global::<SystemPageData>().set_ppt_pl2_sppt(MINMAX);
ui.global::<SystemPageData>().set_ppt_pl3_fppt(MINMAX); ui.global::<SystemPageData>().set_ppt_pl3_fppt(MINMAX);
@@ -126,6 +130,51 @@ macro_rules! init_minmax_property {
// For handling callbacks from UI value changes // For handling callbacks from UI value changes
macro_rules! setup_callback { macro_rules! setup_callback {
// Minmax (AttrMinMax) variant - pass an extra `minmax` token
($property:ident, $handle:expr, $attr:expr, $type:tt, minmax) => {
let handle_copy = $handle.as_weak();
let proxy_copy = $attr.clone();
concat_idents!(on_callback = on_cb_, $property {
$handle
.global::<SystemPageData>()
.on_callback(move |v| {
let handle_copy = handle_copy.clone();
let proxy_copy = proxy_copy.clone();
tokio::spawn(async move {
let res = proxy_copy
.set_current_value(convert_to_dbus!($type, v))
.await;
show_toast(
format!("{} successfully set to {}", stringify!($property), v).into(),
format!("Setting {} failed", stringify!($property)).into(),
handle_copy.clone(),
res.clone(),
);
if res.is_ok() {
let min_v = proxy_copy.min_value().await.unwrap_or(-1);
let max_v = proxy_copy.max_value().await.unwrap_or(-1);
if let Ok(cur_val) = proxy_copy.current_value().await {
let cur_f = cur_val as f32;
handle_copy
.upgrade_in_event_loop(move |handle| {
concat_idents!(setter = set_, $property {
handle.global::<SystemPageData>().setter(AttrMinMax {
min: min_v,
max: max_v,
current: cur_f,
});
});
})
.ok();
}
}
});
});
});
};
// Scalar variant (i32/bool/f32) - update scalar setter with authoritative value
($property:ident, $handle:expr, $attr:expr, $type:tt) => { ($property:ident, $handle:expr, $attr:expr, $type:tt) => {
let handle_copy = $handle.as_weak(); let handle_copy = $handle.as_weak();
let proxy_copy = $attr.clone(); let proxy_copy = $attr.clone();
@@ -136,12 +185,28 @@ macro_rules! setup_callback {
let handle_copy = handle_copy.clone(); let handle_copy = handle_copy.clone();
let proxy_copy = proxy_copy.clone(); let proxy_copy = proxy_copy.clone();
tokio::spawn(async move { tokio::spawn(async move {
let res = proxy_copy
.set_current_value(convert_to_dbus!($type, v))
.await;
show_toast( show_toast(
format!("{} successfully set to {}", stringify!($property), v).into(), format!("{} successfully set to {}", stringify!($property), v).into(),
format!("Setting {} failed", stringify!($property)).into(), format!("Setting {} failed", stringify!($property)).into(),
handle_copy, handle_copy.clone(),
proxy_copy.set_current_value(convert_to_dbus!($type, v)).await, res.clone(),
); );
if res.is_ok() {
// Query authoritative value and set scalar global
if let Ok(cur_val) = proxy_copy.current_value().await {
handle_copy.upgrade_in_event_loop(move |handle| {
concat_idents!(setter = set_, $property {
handle
.global::<SystemPageData>()
.setter(convert_value!($type, cur_val));
});
}).ok();
}
}
}); });
}); });
}); });
@@ -288,6 +353,13 @@ pub fn setup_system_page_callbacks(ui: &MainWindow, _states: Arc<Mutex<Config>>)
log::error!("Failed to create platform proxy: {}", e); log::error!("Failed to create platform proxy: {}", e);
}) })
.unwrap(); .unwrap();
let backlight = BacklightProxy::builder(&conn)
.build()
.await
.map_err(|e| {
log::error!("Failed to create backlight proxy: {}", e);
})
.unwrap();
debug!("Setting up system page profile callbacks"); debug!("Setting up system page profile callbacks");
set_ui_props_async!( set_ui_props_async!(
@@ -299,6 +371,7 @@ pub fn setup_system_page_callbacks(ui: &MainWindow, _states: Arc<Mutex<Config>>)
let platform_copy = platform.clone(); let platform_copy = platform.clone();
if let Ok(mut value) = platform.platform_profile_choices().await { if let Ok(mut value) = platform.platform_profile_choices().await {
debug!("Available platform profile choices: {:?}", value);
handle handle
.upgrade_in_event_loop(move |handle| { .upgrade_in_event_loop(move |handle| {
value.sort(); value.sort();
@@ -381,6 +454,24 @@ pub fn setup_system_page_callbacks(ui: &MainWindow, _states: Arc<Mutex<Config>>)
set_ui_props_async!(handle, platform, SystemPageData, enable_ppt_group); set_ui_props_async!(handle, platform, SystemPageData, enable_ppt_group);
set_ui_props_async!(handle, backlight, SystemPageData, screenpad_brightness);
if let Ok(value) = backlight.screenpad_gamma().await {
handle
.upgrade_in_event_loop(move |handle| {
handle
.global::<SystemPageData>()
.set_screenpad_gamma(value.parse().unwrap_or(1.0));
})
.ok();
}
set_ui_props_async!(
handle,
backlight,
SystemPageData,
screenpad_sync_with_primary
);
let platform_copy = platform.clone(); let platform_copy = platform.clone();
handle handle
.upgrade_in_event_loop(move |handle| { .upgrade_in_event_loop(move |handle| {
@@ -492,7 +583,7 @@ pub fn setup_system_page_callbacks(ui: &MainWindow, _states: Arc<Mutex<Config>>)
set_ui_callbacks!(handle, set_ui_callbacks!(handle,
SystemPageData(as i32), SystemPageData(as i32),
platform_copy.platform_profile_on_battery(.into()), platform_copy.platform_profile_on_battery(.into()),
"Throttle policy on abttery set to {}", "Throttle policy on battery set to {}",
"Setting Throttle policy on battery failed" "Setting Throttle policy on battery failed"
); );
set_ui_callbacks!(handle, set_ui_callbacks!(handle,
@@ -501,6 +592,27 @@ pub fn setup_system_page_callbacks(ui: &MainWindow, _states: Arc<Mutex<Config>>)
"Throttle policy on battery enabled: {}", "Throttle policy on battery enabled: {}",
"Setting Throttle policy on AC failed" "Setting Throttle policy on AC failed"
); );
set_ui_callbacks!(handle,
SystemPageData(as i32),
backlight.screenpad_brightness(as i32),
"Screenpad successfully set to {}",
"Setting screenpad brightness failed"
);
set_ui_callbacks!(handle,
SystemPageData(as bool),
backlight.screenpad_sync_with_primary(as bool),
"Screenpad successfully set to {}",
"Setting screenpad brightness failed"
);
set_ui_callbacks!(handle,
SystemPageData(.parse().unwrap_or(1.0)),
backlight.screenpad_gamma(.to_string().as_str()),
"Screenpad successfully set to {}",
"Setting screenpad brightness failed"
);
}) })
.ok(); .ok();
@@ -524,120 +636,132 @@ pub fn setup_system_page_callbacks(ui: &MainWindow, _states: Arc<Mutex<Config>>)
for attr in armoury_attrs { for attr in armoury_attrs {
if let Ok(value) = attr.current_value().await { if let Ok(value) = attr.current_value().await {
let name = attr.name().await.unwrap(); if let Ok(name) = attr.name().await {
debug!("Setting up {} = {value}", <&str>::from(name)); debug!("Setting up {} = {value}", <&str>::from(name));
let platform = platform.clone(); let platform = platform.clone();
handle handle
.upgrade_in_event_loop(move |handle| match name { .upgrade_in_event_loop(move |handle| match name {
FirmwareAttribute::ApuMem => {} FirmwareAttribute::ApuMem => {}
FirmwareAttribute::CoresPerformance => {} FirmwareAttribute::CoresPerformance => {}
FirmwareAttribute::CoresEfficiency => {} FirmwareAttribute::CoresEfficiency => {}
FirmwareAttribute::PptEnabled => { FirmwareAttribute::PptEnabled => {
init_property!(ppt_enabled, handle, value, bool); init_property!(ppt_enabled, handle, value, bool);
setup_callback!(ppt_enabled, handle, attr, bool); setup_callback!(ppt_enabled, handle, attr, bool);
let handle_copy = handle.as_weak(); let handle_copy = handle.as_weak();
let proxy_copy = attr.clone(); let proxy_copy = attr.clone();
tokio::spawn(async move { tokio::spawn(async move {
let mut x = proxy_copy.receive_current_value_changed().await; let mut x = proxy_copy.receive_current_value_changed().await;
use futures_util::StreamExt; use futures_util::StreamExt;
while let Some(e) = x.next().await { while let Some(e) = x.next().await {
if let Ok(out) = e.get().await { if let Ok(out) = e.get().await {
handle_copy handle_copy
.upgrade_in_event_loop(move |handle| { .upgrade_in_event_loop(move |handle| {
handle handle
.global::<SystemPageData>() .global::<SystemPageData>()
.set_enable_ppt_group(out == 1); .set_enable_ppt_group(out == 1);
handle handle
.global::<SystemPageData>() .global::<SystemPageData>()
.set_ppt_enabled(out == 1); .set_ppt_enabled(out == 1);
}) })
.ok(); .ok();
}
} }
} });
}); handle
handle .global::<SystemPageData>()
.global::<SystemPageData>() .set_ppt_enabled_available(true);
.set_ppt_enabled_available(true); handle
handle .global::<SystemPageData>()
.global::<SystemPageData>() .set_enable_ppt_group(value == 1);
.set_enable_ppt_group(value == 1); }
} FirmwareAttribute::PptPl1Spl => {
FirmwareAttribute::PptPl1Spl => { init_minmax_property!(ppt_pl1_spl, handle, attr);
init_minmax_property!(ppt_pl1_spl, handle, attr); setup_callback!(ppt_pl1_spl, handle, attr, i32, minmax);
setup_callback!(ppt_pl1_spl, handle, attr, i32); setup_callback_restore_default!(ppt_pl1_spl, handle, attr);
setup_callback_restore_default!(ppt_pl1_spl, handle, attr); setup_minmax_external!(ppt_pl1_spl, handle, attr, platform);
setup_minmax_external!(ppt_pl1_spl, handle, attr, platform); }
} FirmwareAttribute::PptPl2Sppt => {
FirmwareAttribute::PptPl2Sppt => { init_minmax_property!(ppt_pl2_sppt, handle, attr);
init_minmax_property!(ppt_pl2_sppt, handle, attr); setup_callback!(ppt_pl2_sppt, handle, attr, i32, minmax);
setup_callback!(ppt_pl2_sppt, handle, attr, i32); setup_callback_restore_default!(ppt_pl2_sppt, handle, attr);
setup_callback_restore_default!(ppt_pl2_sppt, handle, attr); setup_minmax_external!(ppt_pl2_sppt, handle, attr, platform);
setup_minmax_external!(ppt_pl2_sppt, handle, attr, platform); }
} FirmwareAttribute::PptPl3Fppt => {
FirmwareAttribute::PptPl3Fppt => { init_minmax_property!(ppt_pl3_fppt, handle, attr);
init_minmax_property!(ppt_pl3_fppt, handle, attr); setup_callback!(ppt_pl3_fppt, handle, attr, i32, minmax);
setup_callback!(ppt_pl3_fppt, handle, attr, i32); setup_callback_restore_default!(ppt_pl3_fppt, handle, attr);
setup_callback_restore_default!(ppt_pl3_fppt, handle, attr); setup_minmax_external!(ppt_pl3_fppt, handle, attr, platform);
setup_minmax_external!(ppt_pl3_fppt, handle, attr, platform); }
} FirmwareAttribute::PptFppt => {
FirmwareAttribute::PptFppt => { init_minmax_property!(ppt_fppt, handle, attr);
init_minmax_property!(ppt_fppt, handle, attr); setup_callback!(ppt_fppt, handle, attr, i32, minmax);
setup_callback!(ppt_fppt, handle, attr, i32); setup_callback_restore_default!(ppt_fppt, handle, attr);
setup_callback_restore_default!(ppt_fppt, handle, attr); setup_minmax_external!(ppt_fppt, handle, attr, platform);
setup_minmax_external!(ppt_fppt, handle, attr, platform); }
} FirmwareAttribute::PptApuSppt => {
FirmwareAttribute::PptApuSppt => { init_minmax_property!(ppt_apu_sppt, handle, attr);
init_minmax_property!(ppt_apu_sppt, handle, attr); setup_callback!(ppt_apu_sppt, handle, attr, i32, minmax);
setup_callback!(ppt_apu_sppt, handle, attr, i32); setup_callback_restore_default!(ppt_apu_sppt, handle, attr);
setup_callback_restore_default!(ppt_apu_sppt, handle, attr); setup_minmax_external!(ppt_apu_sppt, handle, attr, platform);
setup_minmax_external!(ppt_apu_sppt, handle, attr, platform); }
} FirmwareAttribute::PptPlatformSppt => {
FirmwareAttribute::PptPlatformSppt => { init_minmax_property!(ppt_platform_sppt, handle, attr);
init_minmax_property!(ppt_platform_sppt, handle, attr); setup_callback!(ppt_platform_sppt, handle, attr, i32, minmax);
setup_callback!(ppt_platform_sppt, handle, attr, i32); setup_callback_restore_default!(ppt_platform_sppt, handle, attr);
setup_callback_restore_default!(ppt_platform_sppt, handle, attr); setup_minmax_external!(ppt_platform_sppt, handle, attr, platform);
setup_minmax_external!(ppt_platform_sppt, handle, attr, platform); }
} FirmwareAttribute::NvDynamicBoost => {
FirmwareAttribute::NvDynamicBoost => { init_minmax_property!(nv_dynamic_boost, handle, attr);
init_minmax_property!(nv_dynamic_boost, handle, attr); setup_callback!(nv_dynamic_boost, handle, attr, i32, minmax);
setup_callback!(nv_dynamic_boost, handle, attr, i32); setup_callback_restore_default!(nv_dynamic_boost, handle, attr);
setup_callback_restore_default!(nv_dynamic_boost, handle, attr); setup_minmax_external!(nv_dynamic_boost, handle, attr, platform);
setup_minmax_external!(nv_dynamic_boost, handle, attr, platform); }
} FirmwareAttribute::NvTempTarget => {
FirmwareAttribute::NvTempTarget => { init_minmax_property!(nv_temp_target, handle, attr);
init_minmax_property!(nv_temp_target, handle, attr); setup_callback!(nv_temp_target, handle, attr, i32, minmax);
setup_callback!(nv_temp_target, handle, attr, i32); setup_callback_restore_default!(nv_temp_target, handle, attr);
setup_callback_restore_default!(nv_temp_target, handle, attr); setup_minmax_external!(nv_temp_target, handle, attr, platform);
setup_minmax_external!(nv_temp_target, handle, attr, platform); }
} FirmwareAttribute::DgpuBaseTgp => {}
FirmwareAttribute::DgpuBaseTgp => {} FirmwareAttribute::DgpuTgp => {}
FirmwareAttribute::DgpuTgp => {} FirmwareAttribute::ChargeMode => {}
FirmwareAttribute::ChargeMode => {} FirmwareAttribute::BootSound => {
FirmwareAttribute::BootSound => { init_property!(boot_sound, handle, value, i32);
init_property!(boot_sound, handle, value, i32); setup_callback!(boot_sound, handle, attr, i32);
setup_callback!(boot_sound, handle, attr, i32); setup_external!(boot_sound, i32, handle, attr, value)
setup_external!(boot_sound, i32, handle, attr, value) }
} FirmwareAttribute::ScreenAutoBrightness => {
FirmwareAttribute::McuPowersave => {} init_property!(screen_auto_brightness, handle, value, i32);
FirmwareAttribute::PanelOverdrive => { setup_callback!(screen_auto_brightness, handle, attr, i32);
init_property!(panel_overdrive, handle, value, i32); setup_external!(screen_auto_brightness, i32, handle, attr, value)
setup_callback!(panel_overdrive, handle, attr, i32); }
setup_external!(panel_overdrive, i32, handle, attr, value) FirmwareAttribute::McuPowersave => {
} init_property!(mcu_powersave, handle, value, i32);
FirmwareAttribute::PanelHdMode => {} setup_callback!(mcu_powersave, handle, attr, i32);
FirmwareAttribute::EgpuConnected => {} setup_external!(mcu_powersave, i32, handle, attr, value)
FirmwareAttribute::EgpuEnable => {} }
FirmwareAttribute::DgpuDisable => {} FirmwareAttribute::PanelOverdrive => {
FirmwareAttribute::GpuMuxMode => {} init_property!(panel_overdrive, handle, value, i32);
FirmwareAttribute::MiniLedMode => { setup_callback!(panel_overdrive, handle, attr, i32);
init_property!(mini_led_mode, handle, value, i32); setup_external!(panel_overdrive, i32, handle, attr, value)
setup_callback!(mini_led_mode, handle, attr, i32); }
setup_external!(mini_led_mode, i32, handle, attr, value); FirmwareAttribute::PanelHdMode => {}
} FirmwareAttribute::EgpuConnected => {}
FirmwareAttribute::PendingReboot => {} FirmwareAttribute::EgpuEnable => {}
FirmwareAttribute::None => {} FirmwareAttribute::DgpuDisable => {}
}) FirmwareAttribute::GpuMuxMode => {}
.ok(); FirmwareAttribute::MiniLedMode => {
init_property!(mini_led_mode, handle, value, i32);
setup_callback!(mini_led_mode, handle, attr, i32);
setup_external!(mini_led_mode, i32, handle, attr, value);
}
FirmwareAttribute::PendingReboot => {}
FirmwareAttribute::None => {}
})
.ok();
} else {
error!("Attribute with no name, skipping");
}
} }
} }
handle handle

View File

@@ -0,0 +1,684 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2024-06-09 00:20+0000\n"
"PO-Revision-Date: 2024-07-19 11:32+0400\n"
"Last-Translator: Rəşad Qasımlı <rashadgasimli2005@gmail.com>\n"
"Language-Team: Azerbaijan <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: az\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: rog-control-center/ui/pages/anime.slint:6
msgctxt "Anime Brightness"
msgid "Off"
msgstr "Sönülü"
#: rog-control-center/ui/pages/anime.slint:7
msgctxt "Anime Brightness"
msgid "Low"
msgstr "Aşağı"
#: rog-control-center/ui/pages/anime.slint:8
msgctxt "Anime Brightness"
msgid "Med"
msgstr "Orta"
#: rog-control-center/ui/pages/anime.slint:9
msgctxt "Anime Brightness"
msgid "High"
msgstr "Yüksək"
#: rog-control-center/ui/pages/anime.slint:23
msgctxt "AnimePageData"
msgid "Glitch Construction"
msgstr "Nasazlıq İnşaatı"
#: rog-control-center/ui/pages/anime.slint:23
msgctxt "AnimePageData"
msgid "Static Emergence"
msgstr "Statik Ortaya Çıxma"
#: rog-control-center/ui/pages/anime.slint:25
msgctxt "AnimePageData"
msgid "Binary Banner Scroll"
msgstr "İkili Afiş Sürüşdürmə"
#: rog-control-center/ui/pages/anime.slint:25
msgctxt "AnimePageData"
msgid "Rog Logo Glitch"
msgstr "Rog Logo Nasazlığı"
#: rog-control-center/ui/pages/anime.slint:27
msgctxt "AnimePageData"
msgid "Banner Swipe"
msgstr "Afiş Sürüşdürmə"
#: rog-control-center/ui/pages/anime.slint:27
msgctxt "AnimePageData"
msgid "Starfield"
msgstr "Ulduz Sahəsi"
#: rog-control-center/ui/pages/anime.slint:29
msgctxt "AnimePageData"
msgid "Glitch Out"
msgstr "Nasazlıq"
#: rog-control-center/ui/pages/anime.slint:29
msgctxt "AnimePageData"
msgid "See Ya"
msgstr "Görüşərik"
#: rog-control-center/ui/pages/anime.slint:50
msgctxt "Anime Brightness"
msgid "Brightness"
msgstr "Parlaqlıq"
#: rog-control-center/ui/pages/anime.slint:66
msgctxt "PageAnime"
msgid "Enable display"
msgstr "Ekranı aktivləşdir"
#: rog-control-center/ui/pages/anime.slint:74 rog-control-center/ui/pages/anime.slint:97
msgctxt "PageAnime"
msgid "Advanced"
msgstr "Qabaqcıl"
#: rog-control-center/ui/pages/anime.slint:89
msgctxt "PageAnime"
msgid "Use built-in animations"
msgstr "Yerləşik animasiyalardan istifadə edin"
#: rog-control-center/ui/pages/anime.slint:146
msgctxt "PageAnime"
msgid "Set which builtin animations are played"
msgstr "Hansı yerləşik animasiyaların oynadılacağını ayarlayın"
#: rog-control-center/ui/pages/anime.slint:150
msgctxt "Anime built-in selection"
msgid "Boot Animation"
msgstr "Açılış Animasiyası"
#: rog-control-center/ui/pages/anime.slint:160
msgctxt "Anime built-in selection"
msgid "Running Animation"
msgstr "İşləyən Animasiya"
#: rog-control-center/ui/pages/anime.slint:170
msgctxt "Anime built-in selection"
msgid "Sleep Animation"
msgstr "Yuxu Animasiyası"
#: rog-control-center/ui/pages/anime.slint:180
msgctxt "Anime built-in selection"
msgid "Shutdown Animation"
msgstr "Söndürmə Animasiyası"
#: rog-control-center/ui/pages/anime.slint:220
msgctxt "PageAnime"
msgid "Advanced Display Settings"
msgstr "Qabaqcıl Ekran Parametrləri"
#: rog-control-center/ui/pages/anime.slint:225
msgctxt "PageAnime"
msgid "Off when lid closed"
msgstr "Qapaq bağlandıqda söndür"
#: rog-control-center/ui/pages/anime.slint:234
msgctxt "PageAnime"
msgid "Off when suspended"
msgstr "Gözlədiləndə söndür"
#: rog-control-center/ui/pages/anime.slint:243
msgctxt "PageAnime"
msgid "Off when on battery"
msgstr "Batareyadaykən söndür"
#: rog-control-center/ui/pages/app_settings.slint:26
msgctxt "PageAppSettings"
msgid "Run in background after closing"
msgstr "Bağlandıqdan sonra arxafonda işlət"
#: rog-control-center/ui/pages/app_settings.slint:34
msgctxt "PageAppSettings"
msgid "Start app in background (UI closed)"
msgstr "Tətbiqi arxafonda başlat (İİ sönülü vəziyyətdə)"
#: rog-control-center/ui/pages/app_settings.slint:42
msgctxt "PageAppSettings"
msgid "Enable system tray icon"
msgstr "Sistem nimçə ikonunu aktivləşdir"
#: rog-control-center/ui/pages/app_settings.slint:50
msgctxt "PageAppSettings"
msgid "Enable dGPU notifications"
msgstr "Xarici ekran kartı bildirimlərini aktivləşdir"
#: rog-control-center/ui/pages/aura.slint:28
msgctxt "PageAura"
msgid "Brightness"
msgstr "Parlaqlıq"
#: rog-control-center/ui/pages/aura.slint:39
msgctxt "PageAura"
msgid "Aura mode"
msgstr "Aura rejimi"
#: rog-control-center/ui/pages/aura.slint:59
msgctxt "PageAura"
msgid "Colour 1"
msgstr "Rəng 1"
#: rog-control-center/ui/pages/aura.slint:85
msgctxt "PageAura"
msgid "Colour 2"
msgstr "Rəng 2"
#: rog-control-center/ui/pages/aura.slint:119
msgctxt "PageAura"
msgid "Zone"
msgstr "Qurşaq"
#: rog-control-center/ui/pages/aura.slint:142
msgctxt "PageAura"
msgid "Direction"
msgstr "İstiqamət"
#: rog-control-center/ui/pages/aura.slint:164
msgctxt "PageAura"
msgid "Speed"
msgstr "Sürət"
#: rog-control-center/ui/pages/aura.slint:185
msgctxt "PageAura"
msgid "Power Settings"
msgstr "Enerji Parametrləri"
#: rog-control-center/ui/pages/aura.slint:270
msgctxt "PageAura"
msgid "Power Zones"
msgstr "Enerji qurşaqları"
#: rog-control-center/ui/pages/fans.slint:26
msgctxt "FanTab"
msgid "This fan is not avilable on this machine"
msgstr "Bu ventilyator bu cihazda mövcud deyil"
#: rog-control-center/ui/pages/fans.slint:34
msgctxt "FanTab"
msgid "Enabled"
msgstr "Aktiv"
#: rog-control-center/ui/pages/fans.slint:43
msgctxt "FanTab"
msgid "Apply"
msgstr "Tətbiq et"
#: rog-control-center/ui/pages/fans.slint:51
msgctxt "FanTab"
msgid "Cancel"
msgstr "Ləğv et"
#: rog-control-center/ui/pages/fans.slint:59
msgctxt "FanTab"
msgid "Factory Default (all fans)"
msgstr "Zavod standartı (bütün ventilyatorlar)"
#: rog-control-center/ui/pages/fans.slint:72
msgctxt "PageFans"
msgid "Balanced"
msgstr "Balanslaşdırılmış"
#: rog-control-center/ui/pages/fans.slint:75 rog-control-center/ui/pages/fans.slint:134 rog-control-center/ui/pages/fans.slint:193
msgctxt "PageFans"
msgid "CPU"
msgstr "Prosessor"
#: rog-control-center/ui/pages/fans.slint:93 rog-control-center/ui/pages/fans.slint:152 rog-control-center/ui/pages/fans.slint:211
msgctxt "PageFans"
msgid "Mid"
msgstr "Orta"
#: rog-control-center/ui/pages/fans.slint:111 rog-control-center/ui/pages/fans.slint:170 rog-control-center/ui/pages/fans.slint:229
msgctxt "PageFans"
msgid "GPU"
msgstr "Ekran kartı"
#: rog-control-center/ui/pages/fans.slint:131
msgctxt "PageFans"
msgid "Performance"
msgstr "Performans"
#: rog-control-center/ui/pages/fans.slint:190
msgctxt "PageFans"
msgid "Quiet"
msgstr "Sakit"
#: rog-control-center/ui/pages/system.slint:26
msgctxt "SystemPageData"
msgid "Balanced"
msgstr "Balanslaşdırılmış"
#: rog-control-center/ui/pages/system.slint:26 rog-control-center/ui/pages/system.slint:30
msgctxt "SystemPageData"
msgid "Performance"
msgstr "Performans"
#: rog-control-center/ui/pages/system.slint:26
msgctxt "SystemPageData"
msgid "Quiet"
msgstr "Sakit"
#: rog-control-center/ui/pages/system.slint:29
msgctxt "SystemPageData"
msgid "Default"
msgstr "Standart"
#: rog-control-center/ui/pages/system.slint:31
msgctxt "SystemPageData"
msgid "BalancePerformance"
msgstr "Taraz-Performans"
#: rog-control-center/ui/pages/system.slint:32
msgctxt "SystemPageData"
msgid "BalancePower"
msgstr "Taraz-Enerji"
#: rog-control-center/ui/pages/system.slint:33
msgctxt "SystemPageData"
msgid "Power"
msgstr "Enerji"
#: rog-control-center/ui/pages/system.slint:110
msgctxt "PageSystem"
msgid "Base system settings"
msgstr "Əsas sistem parametrləri"
#: rog-control-center/ui/pages/system.slint:115
msgctxt "PageSystem"
msgid "Charge limit"
msgstr "Şarj limiti"
#: rog-control-center/ui/pages/system.slint:127
msgctxt "PageSystem"
msgid "Throttle Policy"
msgstr "Enerji Siyasəti"
#: rog-control-center/ui/pages/system.slint:137
msgctxt "PageSystem"
msgid "Advanced"
msgstr "Qabaqcıl"
#: rog-control-center/ui/pages/system.slint:149
msgctxt "PageSystem"
msgid "Panel Overdrive"
msgstr "Panel aşırma"
#: rog-control-center/ui/pages/system.slint:157
msgctxt "PageSystem"
msgid "MiniLED Mode"
msgstr "MiniLED Rejimi"
#: rog-control-center/ui/pages/system.slint:165
msgctxt "PageSystem"
msgid "POST boot sound"
msgstr "POST açılış səsi"
#: rog-control-center/ui/pages/system.slint:183
msgctxt "PageSystem"
msgid "System performance settings"
msgstr "Sistem performans parametrləri"
#: rog-control-center/ui/pages/system.slint:188
msgctxt "ppt_pl1_spl"
msgid "PL1, sustained power limit"
msgstr "ES1, davamlı enerji limiti"
#: rog-control-center/ui/pages/system.slint:198
msgctxt "ppt_pl2_sppt"
msgid "PL2, turbo power limit"
msgstr "ES2, turbo enerji limiti"
#: rog-control-center/ui/pages/system.slint:208
msgctxt "ppt_fppt"
msgid "FPPT, Fast Power Limit"
msgstr "SPEİ, sürətli enerji limiti"
#: rog-control-center/ui/pages/system.slint:218
msgctxt "ppt_apu_sppt"
msgid "SPPT, APU slow power limit"
msgstr "YPEİ, APU yavaş enerji limiti"
#: rog-control-center/ui/pages/system.slint:228
msgctxt "ppt_platform_sppt"
msgid "Slow package power tracking limit"
msgstr "Yavaş paket enerji izləmə limiti"
#: rog-control-center/ui/pages/system.slint:238
msgctxt "nv_dynamic_boost"
msgid "dGPU boost overclock"
msgstr "Xarici ekran kartının sürət aşırtma sürətini artırma"
#: rog-control-center/ui/pages/system.slint:248
msgctxt "nv_temp_target"
msgid "dGPU temperature max"
msgstr "Xarici ekran kartının maksimum temperaturu"
#: rog-control-center/ui/pages/system.slint:294
msgctxt "PageSystem"
msgid "Energy Performance Preference linked to Throttle Policy"
msgstr "Enerji Performans Üstünlüyü Enerji Siyasətinə bağlıdır"
#: rog-control-center/ui/pages/system.slint:298
msgctxt "PageSystem"
msgid "Change EPP based on Throttle Policy"
msgstr "EPÜ-yü Enerji Siyasəti üçün dəyişdirin"
#: rog-control-center/ui/pages/system.slint:306
msgctxt "PageSystem"
msgid "EPP for Balanced Policy"
msgstr "Balanslaşdırılmış Siyasət üçün EPÜ"
#: rog-control-center/ui/pages/system.slint:316
msgctxt "PageSystem"
msgid "EPP for Performance Policy"
msgstr "Perfomans Siyasəti üçün EPÜ"
#: rog-control-center/ui/pages/system.slint:326
msgctxt "PageSystem"
msgid "EPP for Quiet Policy"
msgstr "Sakit Siyasət üçün EPÜ"
#: rog-control-center/ui/pages/system.slint:344
msgctxt "PageSystem"
msgid "Throttle Policy for power state"
msgstr "Enerji vəziyyəti üçün Enerji Siyasəti"
#: rog-control-center/ui/pages/system.slint:350
msgctxt "PageSystem"
msgid "Throttle Policy on Battery"
msgstr "Batareyadaykən Enerji Siyasəti"
#: rog-control-center/ui/pages/system.slint:360 rog-control-center/ui/pages/system.slint:381
msgctxt "PageSystem"
msgid "Enabled"
msgstr "Aktiv"
#: rog-control-center/ui/pages/system.slint:371
msgctxt "PageSystem"
msgid "Throttle Policy on AC"
msgstr "Şarjdaykən Enerji Siyasəti"
#: rog-control-center/ui/types/aura_types.slint:49
msgctxt "Aura power zone"
msgid "Logo"
msgstr "Loqo"
#: rog-control-center/ui/types/aura_types.slint:50 rog-control-center/ui/types/aura_types.slint:59
msgctxt "Aura power zone"
msgid "Keyboard"
msgstr "Klaviatura"
#: rog-control-center/ui/types/aura_types.slint:51 rog-control-center/ui/types/aura_types.slint:60
msgctxt "Aura power zone"
msgid "Lightbar"
msgstr "İşıq Çubuğu"
#: rog-control-center/ui/types/aura_types.slint:52
msgctxt "Aura power zone"
msgid "Lid"
msgstr "Qapaq"
#: rog-control-center/ui/types/aura_types.slint:53
msgctxt "Aura power zone"
msgid "Rear Glow"
msgstr "Arxa Parıltı"
#: rog-control-center/ui/types/aura_types.slint:54 rog-control-center/ui/types/aura_types.slint:61
msgctxt "Aura power zone"
msgid "Keyboard and Lightbar"
msgstr "Klaviatura və İşıq Çubuğu"
#: rog-control-center/ui/types/aura_types.slint:64
msgctxt "Aura brightness"
msgid "Off"
msgstr "Sönülü"
#: rog-control-center/ui/types/aura_types.slint:65
msgctxt "Aura brightness"
msgid "Low"
msgstr "Aşağı"
#: rog-control-center/ui/types/aura_types.slint:66
msgctxt "Aura brightness"
msgid "Med"
msgstr "Orta"
#: rog-control-center/ui/types/aura_types.slint:67
msgctxt "Aura brightness"
msgid "High"
msgstr "Yüksək"
#: rog-control-center/ui/types/aura_types.slint:72 rog-control-center/ui/types/aura_types.slint:87
msgctxt "Basic aura mode"
msgid "Static"
msgstr "Statik"
#: rog-control-center/ui/types/aura_types.slint:73 rog-control-center/ui/types/aura_types.slint:88
msgctxt "Basic aura mode"
msgid "Breathe"
msgstr "Nəfəs Alma"
#: rog-control-center/ui/types/aura_types.slint:74 rog-control-center/ui/types/aura_types.slint:89
msgctxt "Basic aura mode"
msgid "Strobe"
msgstr "Fləş"
#: rog-control-center/ui/types/aura_types.slint:75
msgctxt "Basic aura mode"
msgid "Rainbow"
msgstr "Göyqurşağı"
#: rog-control-center/ui/types/aura_types.slint:76
msgctxt "Basic aura mode"
msgid "Star"
msgstr "Ulduz"
#: rog-control-center/ui/types/aura_types.slint:77
msgctxt "Basic aura mode"
msgid "Rain"
msgstr "Yağış"
#: rog-control-center/ui/types/aura_types.slint:78
msgctxt "Basic aura mode"
msgid "Highlight"
msgstr "Vurğulama"
#: rog-control-center/ui/types/aura_types.slint:79
msgctxt "Basic aura mode"
msgid "Laser"
msgstr "Lazer"
#: rog-control-center/ui/types/aura_types.slint:80
msgctxt "Basic aura mode"
msgid "Ripple"
msgstr "Dalğalanma"
#: rog-control-center/ui/types/aura_types.slint:81
msgctxt "Basic aura mode"
msgid "Nothing"
msgstr "Heç nə"
#: rog-control-center/ui/types/aura_types.slint:82
msgctxt "Basic aura mode"
msgid "Pulse"
msgstr "Nəbz"
#: rog-control-center/ui/types/aura_types.slint:83
msgctxt "Basic aura mode"
msgid "Comet"
msgstr "Quyruqlu Ulduz"
#: rog-control-center/ui/types/aura_types.slint:84
msgctxt "Basic aura mode"
msgid "Flash"
msgstr "Fləş"
#: rog-control-center/ui/types/aura_types.slint:96
msgctxt "Aura zone"
msgid "None"
msgstr "Heç biri"
#: rog-control-center/ui/types/aura_types.slint:97
msgctxt "Aura zone"
msgid "Key1"
msgstr "Açar1"
#: rog-control-center/ui/types/aura_types.slint:98
msgctxt "Aura zone"
msgid "Key2"
msgstr "Açar2"
#: rog-control-center/ui/types/aura_types.slint:99
msgctxt "Aura zone"
msgid "Key3"
msgstr "Açar3"
#: rog-control-center/ui/types/aura_types.slint:100
msgctxt "Aura zone"
msgid "Key4"
msgstr "Açar5"
#: rog-control-center/ui/types/aura_types.slint:101
msgctxt "Aura zone"
msgid "Logo"
msgstr "Loqo"
#: rog-control-center/ui/types/aura_types.slint:102
msgctxt "Aura zone"
msgid "Lightbar Left"
msgstr "İşıq Çubuğu Sol"
#: rog-control-center/ui/types/aura_types.slint:103
msgctxt "Aura zone"
msgid "Lightbar Right"
msgstr "İşıq Çubuğu Sağ"
#: rog-control-center/ui/types/aura_types.slint:107
msgctxt "Aura direction"
msgid "Right"
msgstr "Sağ"
#: rog-control-center/ui/types/aura_types.slint:108
msgctxt "Aura direction"
msgid "Left"
msgstr "Sol"
#: rog-control-center/ui/types/aura_types.slint:109
msgctxt "Aura direction"
msgid "Up"
msgstr "Yuxarı"
#: rog-control-center/ui/types/aura_types.slint:110
msgctxt "Aura direction"
msgid "Down"
msgstr "Aşağı"
#: rog-control-center/ui/types/aura_types.slint:114
msgctxt "Aura speed"
msgid "Low"
msgstr "Aşağı"
#: rog-control-center/ui/types/aura_types.slint:115
msgctxt "Aura speed"
msgid "Medium"
msgstr "Orta"
#: rog-control-center/ui/types/aura_types.slint:116
msgctxt "Aura speed"
msgid "High"
msgstr "Yüksək"
#: rog-control-center/ui/widgets/aura_power.slint:33
msgctxt "AuraPowerGroup"
msgid "Boot"
msgstr "Açılış"
#: rog-control-center/ui/widgets/aura_power.slint:43
msgctxt "AuraPowerGroup"
msgid "Awake"
msgstr "Oyaq"
#: rog-control-center/ui/widgets/aura_power.slint:53
msgctxt "AuraPowerGroup"
msgid "Sleep"
msgstr "Yuxu"
#: rog-control-center/ui/widgets/aura_power.slint:63
msgctxt "AuraPowerGroup"
msgid "Shutdown"
msgstr "Söndür"
#: rog-control-center/ui/widgets/aura_power.slint:102
msgctxt "AuraPowerGroupOld"
msgid "Zone Selection"
msgstr "Bölgə seçimi"
#: rog-control-center/ui/widgets/aura_power.slint:114
msgctxt "AuraPowerGroupOld"
msgid "Boot"
msgstr "Açılış"
#: rog-control-center/ui/widgets/aura_power.slint:124
msgctxt "AuraPowerGroupOld"
msgid "Awake"
msgstr "Oyaq"
#: rog-control-center/ui/widgets/aura_power.slint:134
msgctxt "AuraPowerGroupOld"
msgid "Sleep"
msgstr "Yuxu"
#: rog-control-center/ui/main_window.slint:51
msgctxt "MainWindow"
msgid "ROG"
msgstr ""
#: rog-control-center/ui/main_window.slint:53
msgctxt "Menu1"
msgid "System Control"
msgstr "Sistem Nəzarəti"
#: rog-control-center/ui/main_window.slint:54
msgctxt "Menu2"
msgid "Keyboard Aura"
msgstr "Klaviatura Aura"
#: rog-control-center/ui/main_window.slint:55
msgctxt "Menu3"
msgid "AniMe Matrix"
msgstr "AniMe Matrisi"
#: rog-control-center/ui/main_window.slint:56
msgctxt "Menu4"
msgid "Fan Curves"
msgstr "Fan Əyriləri"
#: rog-control-center/ui/main_window.slint:57
msgctxt "Menu5"
msgid "App Settings"
msgstr "Tətbiq Parametrləri"
#: rog-control-center/ui/main_window.slint:58
msgctxt "Menu6"
msgid "About"
msgstr "Haqqında"
#: rog-control-center/ui/main_window.slint:70
msgctxt "MainWindow"
msgid "Quit App"
msgstr "Tətbiqdən Çıxın"

View File

@@ -2,7 +2,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2025-03-01 07:51+0000\n" "POT-Creation-Date: 2025-04-05 19:36+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -12,285 +12,44 @@ msgstr ""
"Language: \n" "Language: \n"
"Plural-Forms: nplurals=1; plural=0;\n" "Plural-Forms: nplurals=1; plural=0;\n"
#: rog-control-center/ui/pages/system.slint:20 #: rog-control-center/ui/main_window.slint:55
msgctxt "SystemPageData" msgctxt "MainWindow"
msgid "Balanced" msgid "ROG"
msgstr "" msgstr ""
#: rog-control-center/ui/pages/system.slint:20 rog-control-center/ui/pages/system.slint:24 #: rog-control-center/ui/main_window.slint:57
msgctxt "SystemPageData" msgctxt "Menu1"
msgid "Performance" msgid "System Control"
msgstr "" msgstr ""
#: rog-control-center/ui/pages/system.slint:20 #: rog-control-center/ui/main_window.slint:58
msgctxt "SystemPageData" msgctxt "Menu2"
msgid "Quiet" msgid "Keyboard Aura"
msgstr "" msgstr ""
#: rog-control-center/ui/pages/system.slint:23 #: rog-control-center/ui/main_window.slint:59
msgctxt "SystemPageData" msgctxt "Menu3"
msgid "Default" msgid "AniMe Matrix"
msgstr "" msgstr ""
#: rog-control-center/ui/pages/system.slint:25 #: rog-control-center/ui/main_window.slint:60
msgctxt "SystemPageData" msgctxt "Menu4"
msgid "BalancePerformance" msgid "Fan Curves"
msgstr "" msgstr ""
#: rog-control-center/ui/pages/system.slint:26 #: rog-control-center/ui/main_window.slint:61
msgctxt "SystemPageData" msgctxt "Menu5"
msgid "BalancePower" msgid "App Settings"
msgstr "" msgstr ""
#: rog-control-center/ui/pages/system.slint:27 #: rog-control-center/ui/main_window.slint:62
msgctxt "SystemPageData" msgctxt "Menu6"
msgid "Power" msgid "About"
msgstr "" msgstr ""
#: rog-control-center/ui/pages/system.slint:147 #: rog-control-center/ui/main_window.slint:74
msgctxt "PageSystem" msgctxt "MainWindow"
msgid "Power settings" msgid "Quit App"
msgstr ""
#: rog-control-center/ui/pages/system.slint:152
msgctxt "PageSystem"
msgid "Charge limit"
msgstr ""
#: rog-control-center/ui/pages/system.slint:167
msgctxt "PageSystem"
msgid "Platform Profile"
msgstr ""
#: rog-control-center/ui/pages/system.slint:177
msgctxt "PageSystem"
msgid "Advanced"
msgstr ""
#: rog-control-center/ui/pages/system.slint:195
msgctxt "PageSystem"
msgid "Armoury settings"
msgstr ""
#: rog-control-center/ui/pages/system.slint:205
msgctxt "no_asus_armoury_driver_1"
msgid "The asus-armoury driver is not loaded"
msgstr ""
#: rog-control-center/ui/pages/system.slint:211
msgctxt "no_asus_armoury_driver_2"
msgid "For advanced features you will require a kernel with this driver added."
msgstr ""
#: rog-control-center/ui/pages/system.slint:222
msgctxt "PageSystem"
msgid "Panel Overdrive"
msgstr ""
#: rog-control-center/ui/pages/system.slint:230
msgctxt "PageSystem"
msgid "MiniLED Mode"
msgstr ""
#: rog-control-center/ui/pages/system.slint:238
msgctxt "PageSystem"
msgid "POST boot sound"
msgstr ""
#: rog-control-center/ui/pages/system.slint:254
msgctxt "ppt_warning"
msgid "The following settings are not applied until the toggle is enabled."
msgstr ""
#: rog-control-center/ui/pages/system.slint:259 rog-control-center/ui/pages/system.slint:266
msgctxt "ppt_group_enabled"
msgid "Enable Tuning"
msgstr ""
#: rog-control-center/ui/pages/system.slint:277 rog-control-center/ui/pages/system.slint:278
msgctxt "ppt_pl1_spl"
msgid "CPU Sustained Power Limit"
msgstr ""
#: rog-control-center/ui/pages/system.slint:279
msgctxt "ppt_pl1_spl_help"
msgid ""
"Long-term CPU power limit that affects sustained workload performance. "
"Higher values may increase heat and power consumption."
msgstr ""
#: rog-control-center/ui/pages/system.slint:295 rog-control-center/ui/pages/system.slint:296
msgctxt "ppt_pl2_sppt"
msgid "CPU Turbo Power Limit"
msgstr ""
#: rog-control-center/ui/pages/system.slint:297
msgctxt "ppt_pl2_sppt_help"
msgid ""
"Short-term CPU power limit for boost periods. Controls maximum power during "
"brief high-performance bursts."
msgstr ""
#: rog-control-center/ui/pages/system.slint:313 rog-control-center/ui/pages/system.slint:314
msgctxt "ppt_pl3_fppt"
msgid "CPU Fast Burst Power Limit"
msgstr ""
#: rog-control-center/ui/pages/system.slint:315
msgctxt "ppt_pl3_fppt_help"
msgid ""
"Ultra-short duration power limit for instantaneous CPU bursts. Affects "
"responsiveness during sudden workload spikes."
msgstr ""
#: rog-control-center/ui/pages/system.slint:330 rog-control-center/ui/pages/system.slint:331
msgctxt "ppt_fppt"
msgid "Fast Package Power Limit"
msgstr ""
#: rog-control-center/ui/pages/system.slint:332
msgctxt "ppt_fppt_help"
msgid ""
"Ultra-short duration power limit for system package. Controls maximum power "
"during millisecond-scale load spikes."
msgstr ""
#: rog-control-center/ui/pages/system.slint:348 rog-control-center/ui/pages/system.slint:349
msgctxt "ppt_apu_sppt"
msgid "APU Sustained Power Limit"
msgstr ""
#: rog-control-center/ui/pages/system.slint:350
msgctxt "ppt_apu_sppt_help"
msgid ""
"Long-term power limit for integrated graphics and CPU combined. Affects "
"sustained performance of APU-based workloads."
msgstr ""
#: rog-control-center/ui/pages/system.slint:366 rog-control-center/ui/pages/system.slint:367
msgctxt "ppt_platform_sppt"
msgid "Platform Sustained Power Limit"
msgstr ""
#: rog-control-center/ui/pages/system.slint:368
msgctxt "ppt_platform_sppt_help"
msgid ""
"Overall system power limit for sustained operations. Controls total platform "
"power consumption over extended periods."
msgstr ""
#: rog-control-center/ui/pages/system.slint:384 rog-control-center/ui/pages/system.slint:385
msgctxt "nv_dynamic_boost"
msgid "GPU Power Boost"
msgstr ""
#: rog-control-center/ui/pages/system.slint:386
msgctxt "nv_dynamic_boost_help"
msgid ""
"Additional power allocation for GPU dynamic boost. Higher values increase "
"GPU performance but generate more heat."
msgstr ""
#: rog-control-center/ui/pages/system.slint:402 rog-control-center/ui/pages/system.slint:403
msgctxt "nv_temp_target"
msgid "GPU Temperature Limit"
msgstr ""
#: rog-control-center/ui/pages/system.slint:404
msgctxt "nv_temp_target_help"
msgid ""
"Maximum GPU temperature threshold in Celsius. GPU will throttle to maintain "
"temperature below this limit."
msgstr ""
#: rog-control-center/ui/pages/system.slint:456
msgctxt "PageSystem"
msgid "Energy Performance Preference linked to Throttle Policy"
msgstr ""
#: rog-control-center/ui/pages/system.slint:460
msgctxt "PageSystem"
msgid "Change EPP based on Throttle Policy"
msgstr ""
#: rog-control-center/ui/pages/system.slint:468
msgctxt "PageSystem"
msgid "EPP for Balanced Policy"
msgstr ""
#: rog-control-center/ui/pages/system.slint:478
msgctxt "PageSystem"
msgid "EPP for Performance Policy"
msgstr ""
#: rog-control-center/ui/pages/system.slint:488
msgctxt "PageSystem"
msgid "EPP for Quiet Policy"
msgstr ""
#: rog-control-center/ui/pages/system.slint:506
msgctxt "PageSystem"
msgid "Throttle Policy for power state"
msgstr ""
#: rog-control-center/ui/pages/system.slint:512
msgctxt "PageSystem"
msgid "Throttle Policy on Battery"
msgstr ""
#: rog-control-center/ui/pages/system.slint:522 rog-control-center/ui/pages/system.slint:543
msgctxt "PageSystem"
msgid "Enabled"
msgstr ""
#: rog-control-center/ui/pages/system.slint:533
msgctxt "PageSystem"
msgid "Throttle Policy on AC"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:28
msgctxt "PageAura"
msgid "Brightness"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:39
msgctxt "PageAura"
msgid "Aura mode"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:59
msgctxt "PageAura"
msgid "Colour 1"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:85
msgctxt "PageAura"
msgid "Colour 2"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:119
msgctxt "PageAura"
msgid "Zone"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:142
msgctxt "PageAura"
msgid "Direction"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:164
msgctxt "PageAura"
msgid "Speed"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:185
msgctxt "PageAura"
msgid "Power Settings"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:270
msgctxt "PageAura"
msgid "Power Zones"
msgstr "" msgstr ""
#: rog-control-center/ui/pages/anime.slint:6 #: rog-control-center/ui/pages/anime.slint:6
@@ -418,6 +177,322 @@ msgctxt "PageAnime"
msgid "Off when on battery" msgid "Off when on battery"
msgstr "" msgstr ""
#: rog-control-center/ui/pages/system.slint:20
msgctxt "SystemPageData"
msgid "Balanced"
msgstr ""
#: rog-control-center/ui/pages/system.slint:20 rog-control-center/ui/pages/system.slint:27
msgctxt "SystemPageData"
msgid "Performance"
msgstr ""
#: rog-control-center/ui/pages/system.slint:20
msgctxt "SystemPageData"
msgid "Quiet"
msgstr ""
#: rog-control-center/ui/pages/system.slint:20
msgctxt "SystemPageData"
msgid "LowPower"
msgstr ""
#: rog-control-center/ui/pages/system.slint:26
msgctxt "SystemPageData"
msgid "Default"
msgstr ""
#: rog-control-center/ui/pages/system.slint:28
msgctxt "SystemPageData"
msgid "BalancePerformance"
msgstr ""
#: rog-control-center/ui/pages/system.slint:29
msgctxt "SystemPageData"
msgid "BalancePower"
msgstr ""
#: rog-control-center/ui/pages/system.slint:30
msgctxt "SystemPageData"
msgid "Power"
msgstr ""
#: rog-control-center/ui/pages/system.slint:159
msgctxt "PageSystem"
msgid "Power settings"
msgstr ""
#: rog-control-center/ui/pages/system.slint:164
msgctxt "PageSystem"
msgid "Charge limit"
msgstr ""
#: rog-control-center/ui/pages/system.slint:179
msgctxt "PageSystem"
msgid "Platform Profile"
msgstr ""
#: rog-control-center/ui/pages/system.slint:189
msgctxt "PageSystem"
msgid "Advanced"
msgstr ""
#: rog-control-center/ui/pages/system.slint:209
msgctxt "PageSystem"
msgid "Screenpad brightness"
msgstr ""
#: rog-control-center/ui/pages/system.slint:233
msgctxt "PageSystem"
msgid "Sync with primary"
msgstr ""
#: rog-control-center/ui/pages/system.slint:253
msgctxt "PageSystem"
msgid "Armoury settings"
msgstr ""
#: rog-control-center/ui/pages/system.slint:263
msgctxt "no_asus_armoury_driver_1"
msgid "The asus-armoury driver is not loaded"
msgstr ""
#: rog-control-center/ui/pages/system.slint:269
msgctxt "no_asus_armoury_driver_2"
msgid "For advanced features you will require a kernel with this driver added."
msgstr ""
#: rog-control-center/ui/pages/system.slint:280
msgctxt "PageSystem"
msgid "Panel Overdrive"
msgstr ""
#: rog-control-center/ui/pages/system.slint:288
msgctxt "PageSystem"
msgid "MiniLED Mode"
msgstr ""
#: rog-control-center/ui/pages/system.slint:296
msgctxt "PageSystem"
msgid "POST boot sound"
msgstr ""
#: rog-control-center/ui/pages/system.slint:312
msgctxt "ppt_warning"
msgid "The following settings are not applied until the toggle is enabled."
msgstr ""
#: rog-control-center/ui/pages/system.slint:317 rog-control-center/ui/pages/system.slint:324
msgctxt "ppt_group_enabled"
msgid "Enable Tuning"
msgstr ""
#: rog-control-center/ui/pages/system.slint:334 rog-control-center/ui/pages/system.slint:335
msgctxt "ppt_pl1_spl"
msgid "CPU Sustained Power Limit"
msgstr ""
#: rog-control-center/ui/pages/system.slint:336
msgctxt "ppt_pl1_spl_help"
msgid ""
"Long-term CPU power limit that affects sustained workload performance. "
"Higher values may increase heat and power consumption."
msgstr ""
#: rog-control-center/ui/pages/system.slint:352 rog-control-center/ui/pages/system.slint:353
msgctxt "ppt_pl2_sppt"
msgid "CPU Turbo Power Limit"
msgstr ""
#: rog-control-center/ui/pages/system.slint:354
msgctxt "ppt_pl2_sppt_help"
msgid ""
"Short-term CPU power limit for boost periods. Controls maximum power during "
"brief high-performance bursts."
msgstr ""
#: rog-control-center/ui/pages/system.slint:370 rog-control-center/ui/pages/system.slint:371
msgctxt "ppt_pl3_fppt"
msgid "CPU Fast Burst Power Limit"
msgstr ""
#: rog-control-center/ui/pages/system.slint:372
msgctxt "ppt_pl3_fppt_help"
msgid ""
"Ultra-short duration power limit for instantaneous CPU bursts. Affects "
"responsiveness during sudden workload spikes."
msgstr ""
#: rog-control-center/ui/pages/system.slint:387 rog-control-center/ui/pages/system.slint:388
msgctxt "ppt_fppt"
msgid "Fast Package Power Limit"
msgstr ""
#: rog-control-center/ui/pages/system.slint:389
msgctxt "ppt_fppt_help"
msgid ""
"Ultra-short duration power limit for system package. Controls maximum power "
"during millisecond-scale load spikes."
msgstr ""
#: rog-control-center/ui/pages/system.slint:405 rog-control-center/ui/pages/system.slint:406
msgctxt "ppt_apu_sppt"
msgid "APU Sustained Power Limit"
msgstr ""
#: rog-control-center/ui/pages/system.slint:407
msgctxt "ppt_apu_sppt_help"
msgid ""
"Long-term power limit for integrated graphics and CPU combined. Affects "
"sustained performance of APU-based workloads."
msgstr ""
#: rog-control-center/ui/pages/system.slint:423 rog-control-center/ui/pages/system.slint:424
msgctxt "ppt_platform_sppt"
msgid "Platform Sustained Power Limit"
msgstr ""
#: rog-control-center/ui/pages/system.slint:425
msgctxt "ppt_platform_sppt_help"
msgid ""
"Overall system power limit for sustained operations. Controls total platform "
"power consumption over extended periods."
msgstr ""
#: rog-control-center/ui/pages/system.slint:441 rog-control-center/ui/pages/system.slint:442
msgctxt "nv_dynamic_boost"
msgid "GPU Power Boost"
msgstr ""
#: rog-control-center/ui/pages/system.slint:443
msgctxt "nv_dynamic_boost_help"
msgid ""
"Additional power allocation for GPU dynamic boost. Higher values increase "
"GPU performance but generate more heat."
msgstr ""
#: rog-control-center/ui/pages/system.slint:459 rog-control-center/ui/pages/system.slint:460
msgctxt "nv_temp_target"
msgid "GPU Temperature Limit"
msgstr ""
#: rog-control-center/ui/pages/system.slint:461
msgctxt "nv_temp_target_help"
msgid ""
"Maximum GPU temperature threshold in Celsius. GPU will throttle to maintain "
"temperature below this limit."
msgstr ""
#: rog-control-center/ui/pages/system.slint:513
msgctxt "PageSystem"
msgid "Energy Performance Preference linked to Throttle Policy"
msgstr ""
#: rog-control-center/ui/pages/system.slint:517
msgctxt "PageSystem"
msgid "Change EPP based on Throttle Policy"
msgstr ""
#: rog-control-center/ui/pages/system.slint:525
msgctxt "PageSystem"
msgid "EPP for Balanced Policy"
msgstr ""
#: rog-control-center/ui/pages/system.slint:535
msgctxt "PageSystem"
msgid "EPP for Performance Policy"
msgstr ""
#: rog-control-center/ui/pages/system.slint:545
msgctxt "PageSystem"
msgid "EPP for Quiet Policy"
msgstr ""
#: rog-control-center/ui/pages/system.slint:563
msgctxt "PageSystem"
msgid "Throttle Policy for power state"
msgstr ""
#: rog-control-center/ui/pages/system.slint:569
msgctxt "PageSystem"
msgid "Throttle Policy on Battery"
msgstr ""
#: rog-control-center/ui/pages/system.slint:579 rog-control-center/ui/pages/system.slint:600
msgctxt "PageSystem"
msgid "Enabled"
msgstr ""
#: rog-control-center/ui/pages/system.slint:590
msgctxt "PageSystem"
msgid "Throttle Policy on AC"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:28
msgctxt "PageAura"
msgid "Brightness"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:39
msgctxt "PageAura"
msgid "Aura mode"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:59
msgctxt "PageAura"
msgid "Colour 1"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:85
msgctxt "PageAura"
msgid "Colour 2"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:119
msgctxt "PageAura"
msgid "Zone"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:142
msgctxt "PageAura"
msgid "Direction"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:164
msgctxt "PageAura"
msgid "Speed"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:185
msgctxt "PageAura"
msgid "Power Settings"
msgstr ""
#: rog-control-center/ui/pages/aura.slint:270
msgctxt "PageAura"
msgid "Power Zones"
msgstr ""
#: rog-control-center/ui/pages/app_settings.slint:26
msgctxt "PageAppSettings"
msgid "Run in background after closing"
msgstr ""
#: rog-control-center/ui/pages/app_settings.slint:34
msgctxt "PageAppSettings"
msgid "Start app in background (UI closed)"
msgstr ""
#: rog-control-center/ui/pages/app_settings.slint:42
msgctxt "PageAppSettings"
msgid "Enable system tray icon"
msgstr ""
#: rog-control-center/ui/pages/app_settings.slint:50
msgctxt "PageAppSettings"
msgid "Enable dGPU notifications"
msgstr ""
#: rog-control-center/ui/pages/fans.slint:26 #: rog-control-center/ui/pages/fans.slint:26
msgctxt "FanTab" msgctxt "FanTab"
msgid "This fan is not avilable on this machine" msgid "This fan is not avilable on this machine"
@@ -473,24 +548,49 @@ msgctxt "PageFans"
msgid "Quiet" msgid "Quiet"
msgstr "" msgstr ""
#: rog-control-center/ui/pages/app_settings.slint:26 #: rog-control-center/ui/widgets/common.slint:126
msgctxt "PageAppSettings" msgctxt "confirm_reset"
msgid "Run in background after closing" msgid "Are you sure you want to reset this?"
msgstr "" msgstr ""
#: rog-control-center/ui/pages/app_settings.slint:34 #: rog-control-center/ui/widgets/aura_power.slint:33
msgctxt "PageAppSettings" msgctxt "AuraPowerGroup"
msgid "Start app in background (UI closed)" msgid "Boot"
msgstr "" msgstr ""
#: rog-control-center/ui/pages/app_settings.slint:42 #: rog-control-center/ui/widgets/aura_power.slint:43
msgctxt "PageAppSettings" msgctxt "AuraPowerGroup"
msgid "Enable system tray icon" msgid "Awake"
msgstr "" msgstr ""
#: rog-control-center/ui/pages/app_settings.slint:50 #: rog-control-center/ui/widgets/aura_power.slint:53
msgctxt "PageAppSettings" msgctxt "AuraPowerGroup"
msgid "Enable dGPU notifications" msgid "Sleep"
msgstr ""
#: rog-control-center/ui/widgets/aura_power.slint:63
msgctxt "AuraPowerGroup"
msgid "Shutdown"
msgstr ""
#: rog-control-center/ui/widgets/aura_power.slint:102
msgctxt "AuraPowerGroupOld"
msgid "Zone Selection"
msgstr ""
#: rog-control-center/ui/widgets/aura_power.slint:114
msgctxt "AuraPowerGroupOld"
msgid "Boot"
msgstr ""
#: rog-control-center/ui/widgets/aura_power.slint:124
msgctxt "AuraPowerGroupOld"
msgid "Awake"
msgstr ""
#: rog-control-center/ui/widgets/aura_power.slint:134
msgctxt "AuraPowerGroupOld"
msgid "Sleep"
msgstr "" msgstr ""
#: rog-control-center/ui/types/aura_types.slint:52 #: rog-control-center/ui/types/aura_types.slint:52
@@ -688,88 +788,3 @@ msgctxt "Aura speed"
msgid "High" msgid "High"
msgstr "" msgstr ""
#: rog-control-center/ui/widgets/aura_power.slint:33
msgctxt "AuraPowerGroup"
msgid "Boot"
msgstr ""
#: rog-control-center/ui/widgets/aura_power.slint:43
msgctxt "AuraPowerGroup"
msgid "Awake"
msgstr ""
#: rog-control-center/ui/widgets/aura_power.slint:53
msgctxt "AuraPowerGroup"
msgid "Sleep"
msgstr ""
#: rog-control-center/ui/widgets/aura_power.slint:63
msgctxt "AuraPowerGroup"
msgid "Shutdown"
msgstr ""
#: rog-control-center/ui/widgets/aura_power.slint:102
msgctxt "AuraPowerGroupOld"
msgid "Zone Selection"
msgstr ""
#: rog-control-center/ui/widgets/aura_power.slint:114
msgctxt "AuraPowerGroupOld"
msgid "Boot"
msgstr ""
#: rog-control-center/ui/widgets/aura_power.slint:124
msgctxt "AuraPowerGroupOld"
msgid "Awake"
msgstr ""
#: rog-control-center/ui/widgets/aura_power.slint:134
msgctxt "AuraPowerGroupOld"
msgid "Sleep"
msgstr ""
#: rog-control-center/ui/widgets/common.slint:136
msgctxt "confirm_reset"
msgid "Are you sure you want to reset this?"
msgstr ""
#: rog-control-center/ui/main_window.slint:55
msgctxt "MainWindow"
msgid "ROG"
msgstr ""
#: rog-control-center/ui/main_window.slint:57
msgctxt "Menu1"
msgid "System Control"
msgstr ""
#: rog-control-center/ui/main_window.slint:58
msgctxt "Menu2"
msgid "Keyboard Aura"
msgstr ""
#: rog-control-center/ui/main_window.slint:59
msgctxt "Menu3"
msgid "AniMe Matrix"
msgstr ""
#: rog-control-center/ui/main_window.slint:60
msgctxt "Menu4"
msgid "Fan Curves"
msgstr ""
#: rog-control-center/ui/main_window.slint:61
msgctxt "Menu5"
msgid "App Settings"
msgstr ""
#: rog-control-center/ui/main_window.slint:62
msgctxt "Menu6"
msgid "About"
msgstr ""
#: rog-control-center/ui/main_window.slint:74
msgctxt "MainWindow"
msgid "Quit App"
msgstr ""

View File

@@ -0,0 +1,771 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2025-03-01 07:51+0000\n"
"PO-Revision-Date: 2025-03-18 00:19-0300\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Poedit 3.5\n"
#: rog-control-center/ui/pages/system.slint:20
msgctxt "SystemPageData"
msgid "Balanced"
msgstr "Equilibrado"
#: rog-control-center/ui/pages/system.slint:20 rog-control-center/ui/pages/system.slint:24
msgctxt "SystemPageData"
msgid "Performance"
msgstr "Performance"
#: rog-control-center/ui/pages/system.slint:20
msgctxt "SystemPageData"
msgid "Quiet"
msgstr "Silencioso"
#: rog-control-center/ui/pages/system.slint:23
msgctxt "SystemPageData"
msgid "Default"
msgstr "Padrão"
#: rog-control-center/ui/pages/system.slint:25
msgctxt "SystemPageData"
msgid "BalancePerformance"
msgstr "Equilibrado Performance"
#: rog-control-center/ui/pages/system.slint:26
msgctxt "SystemPageData"
msgid "BalancePower"
msgstr "Equilibrado Força"
#: rog-control-center/ui/pages/system.slint:27
msgctxt "SystemPageData"
msgid "Power"
msgstr "Energia"
#: rog-control-center/ui/pages/system.slint:147
msgctxt "PageSystem"
msgid "Power settings"
msgstr "Configurações de Energia"
#: rog-control-center/ui/pages/system.slint:152
msgctxt "PageSystem"
msgid "Charge limit"
msgstr "Limite de Carga"
#: rog-control-center/ui/pages/system.slint:167
msgctxt "PageSystem"
msgid "Platform Profile"
msgstr "Perfil de Plataforma"
#: rog-control-center/ui/pages/system.slint:177
msgctxt "PageSystem"
msgid "Advanced"
msgstr "Avançado"
#: rog-control-center/ui/pages/system.slint:195
msgctxt "PageSystem"
msgid "Armoury settings"
msgstr "Configurações Armoury"
#: rog-control-center/ui/pages/system.slint:205
msgctxt "no_asus_armoury_driver_1"
msgid "The asus-armoury driver is not loaded"
msgstr "O driver asus-armoury não está carregado"
#: rog-control-center/ui/pages/system.slint:211
msgctxt "no_asus_armoury_driver_2"
msgid "For advanced features you will require a kernel with this driver added."
msgstr "Para recursos avançados é necessário um Kernel com esse driver adicionado."
#: rog-control-center/ui/pages/system.slint:222
msgctxt "PageSystem"
msgid "Panel Overdrive"
msgstr "Overdrive do Painel"
#: rog-control-center/ui/pages/system.slint:230
msgctxt "PageSystem"
msgid "MiniLED Mode"
msgstr "Modo MiniLED"
#: rog-control-center/ui/pages/system.slint:238
msgctxt "PageSystem"
msgid "POST boot sound"
msgstr "Som PÓS inicialização"
#: rog-control-center/ui/pages/system.slint:254
msgctxt "ppt_warning"
msgid "The following settings are not applied until the toggle is enabled."
msgstr "As seguintes configurações não são aplicadas até que o seletor esteja habilitado."
#: rog-control-center/ui/pages/system.slint:259 rog-control-center/ui/pages/system.slint:266
msgctxt "ppt_group_enabled"
msgid "Enable Tuning"
msgstr "Habilitar ajustes"
#: rog-control-center/ui/pages/system.slint:277 rog-control-center/ui/pages/system.slint:278
msgctxt "ppt_pl1_spl"
msgid "CPU Sustained Power Limit"
msgstr "Limite Sustentado de Energia da CPU"
#: rog-control-center/ui/pages/system.slint:279
msgctxt "ppt_pl1_spl_help"
msgid ""
"Long-term CPU power limit that affects sustained workload performance. Higher values may increase heat and power consumption."
msgstr ""
"Limite de Energia da CPU que afeta o desempenho de cargas sustentada de trabalho. Valores mais altos podem aumentar a "
"temperatura e o consumo de energia."
#: rog-control-center/ui/pages/system.slint:295 rog-control-center/ui/pages/system.slint:296
msgctxt "ppt_pl2_sppt"
msgid "CPU Turbo Power Limit"
msgstr "Limite Turbo de Energia da CPU"
#: rog-control-center/ui/pages/system.slint:297
msgctxt "ppt_pl2_sppt_help"
msgid "Short-term CPU power limit for boost periods. Controls maximum power during brief high-performance bursts."
msgstr ""
"Limite de Energia de curto prazo do Processador para períodos de picos rápidos. Controla a Energia máxima durante picos curtos "
"de alta performance."
#: rog-control-center/ui/pages/system.slint:313 rog-control-center/ui/pages/system.slint:314
msgctxt "ppt_pl3_fppt"
msgid "CPU Fast Burst Power Limit"
msgstr "Limite de energia de pico rápido da CPU"
#: rog-control-center/ui/pages/system.slint:315
msgctxt "ppt_pl3_fppt_help"
msgid "Ultra-short duration power limit for instantaneous CPU bursts. Affects responsiveness during sudden workload spikes."
msgstr ""
"Limite de Energia de duração ultra-curta para picos instantâneos de Processamento. Afeta a responsividade durante picos de "
"trabalho repentinos."
#: rog-control-center/ui/pages/system.slint:330 rog-control-center/ui/pages/system.slint:331
msgctxt "ppt_fppt"
msgid "Fast Package Power Limit"
msgstr "Limite de Energia Rápido do Pacote"
#: rog-control-center/ui/pages/system.slint:332
msgctxt "ppt_fppt_help"
msgid "Ultra-short duration power limit for system package. Controls maximum power during millisecond-scale load spikes."
msgstr ""
"Limite de energia do pacote do sistema de duração ultra curta. Controla a energia máxima durante picos de carga em escala de "
"milissegundos."
#: rog-control-center/ui/pages/system.slint:348 rog-control-center/ui/pages/system.slint:349
msgctxt "ppt_apu_sppt"
msgid "APU Sustained Power Limit"
msgstr "Limite de Força Sustentada para APU"
#: rog-control-center/ui/pages/system.slint:350
msgctxt "ppt_apu_sppt_help"
msgid "Long-term power limit for integrated graphics and CPU combined. Affects sustained performance of APU-based workloads."
msgstr ""
"Limite de Força de Longo-termo para Gráficos Integrados e Processador combinados.Afeta a perfomance sustentada em cargas "
"baseadas na APU."
#: rog-control-center/ui/pages/system.slint:366 rog-control-center/ui/pages/system.slint:367
msgctxt "ppt_platform_sppt"
msgid "Platform Sustained Power Limit"
msgstr "Limite de Força Sustentado da Plataforma"
#: rog-control-center/ui/pages/system.slint:368
msgctxt "ppt_platform_sppt_help"
msgid "Overall system power limit for sustained operations. Controls total platform power consumption over extended periods."
msgstr "Limite geral de força do sistema para operações prolongadas. Controla o Consumo total de força por períodos extendidos."
#: rog-control-center/ui/pages/system.slint:384 rog-control-center/ui/pages/system.slint:385
msgctxt "nv_dynamic_boost"
msgid "GPU Power Boost"
msgstr "Incremento de força da GPU"
#: rog-control-center/ui/pages/system.slint:386
msgctxt "nv_dynamic_boost_help"
msgid "Additional power allocation for GPU dynamic boost. Higher values increase GPU performance but generate more heat."
msgstr ""
"Alocação adicional de força para o Aumento dinâmico da GPU. Valores mais altosaumentam a perfomance da GPU ao custo de gerar "
"mais calor."
#: rog-control-center/ui/pages/system.slint:402 rog-control-center/ui/pages/system.slint:403
msgctxt "nv_temp_target"
msgid "GPU Temperature Limit"
msgstr "Limite de Temperatura da GPU"
#: rog-control-center/ui/pages/system.slint:404
msgctxt "nv_temp_target_help"
msgid "Maximum GPU temperature threshold in Celsius. GPU will throttle to maintain temperature below this limit."
msgstr "Limite de Temperatura Máxima da GPU em Celsius.A GPU irá desacelerar para manter A Temperatura abaixo deste Limite."
#: rog-control-center/ui/pages/system.slint:456
msgctxt "PageSystem"
msgid "Energy Performance Preference linked to Throttle Policy"
msgstr "Preferência de Performance Energética ligada a Política de Proteção de Sobre-aquecimento"
#: rog-control-center/ui/pages/system.slint:460
msgctxt "PageSystem"
msgid "Change EPP based on Throttle Policy"
msgstr "Alterar o PPE baseado na Política de Proteção de Sobre-aquecimento"
#: rog-control-center/ui/pages/system.slint:468
msgctxt "PageSystem"
msgid "EPP for Balanced Policy"
msgstr "PPE para a Política Equilibrada"
#: rog-control-center/ui/pages/system.slint:478
msgctxt "PageSystem"
msgid "EPP for Performance Policy"
msgstr "PPE para a Política de Desempenho"
#: rog-control-center/ui/pages/system.slint:488
msgctxt "PageSystem"
msgid "EPP for Quiet Policy"
msgstr "PPE para a Política Silenciosa"
#: rog-control-center/ui/pages/system.slint:506
msgctxt "PageSystem"
msgid "Throttle Policy for power state"
msgstr "Política de Proteção de Sobre-aquecimento para o Estaddo de Força"
#: rog-control-center/ui/pages/system.slint:512
msgctxt "PageSystem"
msgid "Throttle Policy on Battery"
msgstr "Política de Proteção de Sobre-aquecimento Ligado na Bateria"
#: rog-control-center/ui/pages/system.slint:522 rog-control-center/ui/pages/system.slint:543
msgctxt "PageSystem"
msgid "Enabled"
msgstr "Habilitado"
#: rog-control-center/ui/pages/system.slint:533
msgctxt "PageSystem"
msgid "Throttle Policy on AC"
msgstr "Política de Proteção de Sobre-aquecimento Ligado na Fonte"
#: rog-control-center/ui/pages/aura.slint:28
msgctxt "PageAura"
msgid "Brightness"
msgstr "Brilho"
#: rog-control-center/ui/pages/aura.slint:39
msgctxt "PageAura"
msgid "Aura mode"
msgstr "Modo Aura"
#: rog-control-center/ui/pages/aura.slint:59
msgctxt "PageAura"
msgid "Colour 1"
msgstr "Cor 1"
#: rog-control-center/ui/pages/aura.slint:85
msgctxt "PageAura"
msgid "Colour 2"
msgstr "Cor 2"
#: rog-control-center/ui/pages/aura.slint:119
msgctxt "PageAura"
msgid "Zone"
msgstr "Zona"
#: rog-control-center/ui/pages/aura.slint:142
msgctxt "PageAura"
msgid "Direction"
msgstr "Direção"
#: rog-control-center/ui/pages/aura.slint:164
msgctxt "PageAura"
msgid "Speed"
msgstr "Velocidade"
#: rog-control-center/ui/pages/aura.slint:185
msgctxt "PageAura"
msgid "Power Settings"
msgstr "Configurações de Energia"
#: rog-control-center/ui/pages/aura.slint:270
msgctxt "PageAura"
msgid "Power Zones"
msgstr "Zonas de Energia"
#: rog-control-center/ui/pages/anime.slint:6
msgctxt "Anime Brightness"
msgid "Off"
msgstr "Desligado"
#: rog-control-center/ui/pages/anime.slint:7
msgctxt "Anime Brightness"
msgid "Low"
msgstr "Baixo"
#: rog-control-center/ui/pages/anime.slint:8
msgctxt "Anime Brightness"
msgid "Med"
msgstr "Médio"
#: rog-control-center/ui/pages/anime.slint:9
msgctxt "Anime Brightness"
msgid "High"
msgstr "Alto"
#: rog-control-center/ui/pages/anime.slint:23
msgctxt "AnimePageData"
msgid "Glitch Construction"
msgstr "Construção de Falha"
#: rog-control-center/ui/pages/anime.slint:23
msgctxt "AnimePageData"
msgid "Static Emergence"
msgstr "Emergência Estática"
#: rog-control-center/ui/pages/anime.slint:25
msgctxt "AnimePageData"
msgid "Binary Banner Scroll"
msgstr "Rolagem Binária de Banner"
#: rog-control-center/ui/pages/anime.slint:25
msgctxt "AnimePageData"
msgid "Rog Logo Glitch"
msgstr "Falha no Logo ROG"
#: rog-control-center/ui/pages/anime.slint:27
msgctxt "AnimePageData"
msgid "Banner Swipe"
msgstr "Deslizamento de Banner"
#: rog-control-center/ui/pages/anime.slint:27
msgctxt "AnimePageData"
msgid "Starfield"
msgstr "Campo Estelar"
#: rog-control-center/ui/pages/anime.slint:29
msgctxt "AnimePageData"
msgid "Glitch Out"
msgstr "Falhando"
#: rog-control-center/ui/pages/anime.slint:29
msgctxt "AnimePageData"
msgid "See Ya"
msgstr "Te Vejo por Aí"
#: rog-control-center/ui/pages/anime.slint:50
msgctxt "Anime Brightness"
msgid "Brightness"
msgstr "Brilho"
#: rog-control-center/ui/pages/anime.slint:66
msgctxt "PageAnime"
msgid "Enable display"
msgstr "Habilitar Tela"
#: rog-control-center/ui/pages/anime.slint:74 rog-control-center/ui/pages/anime.slint:97
msgctxt "PageAnime"
msgid "Advanced"
msgstr "Avançado"
#: rog-control-center/ui/pages/anime.slint:89
msgctxt "PageAnime"
msgid "Use built-in animations"
msgstr "Usar animações padrão"
#: rog-control-center/ui/pages/anime.slint:146
msgctxt "PageAnime"
msgid "Set which builtin animations are played"
msgstr "Definir quais animações padrão são tocadas"
#: rog-control-center/ui/pages/anime.slint:150
msgctxt "Anime built-in selection"
msgid "Boot Animation"
msgstr "Animação de Inicilização"
#: rog-control-center/ui/pages/anime.slint:160
msgctxt "Anime built-in selection"
msgid "Running Animation"
msgstr "Animação de Execução"
#: rog-control-center/ui/pages/anime.slint:170
msgctxt "Anime built-in selection"
msgid "Sleep Animation"
msgstr "Animação de Dormir"
#: rog-control-center/ui/pages/anime.slint:180
msgctxt "Anime built-in selection"
msgid "Shutdown Animation"
msgstr "Animação de Desligamento"
#: rog-control-center/ui/pages/anime.slint:220
msgctxt "PageAnime"
msgid "Advanced Display Settings"
msgstr "Configurações Avançadas da Tela"
#: rog-control-center/ui/pages/anime.slint:225
msgctxt "PageAnime"
msgid "Off when lid closed"
msgstr "Desligado quando a tampa estiver fechada"
#: rog-control-center/ui/pages/anime.slint:234
msgctxt "PageAnime"
msgid "Off when suspended"
msgstr "Desligado enquanto suspenso"
#: rog-control-center/ui/pages/anime.slint:243
msgctxt "PageAnime"
msgid "Off when on battery"
msgstr "Desligado enquanto na bateria"
#: rog-control-center/ui/pages/fans.slint:26
msgctxt "FanTab"
msgid "This fan is not avilable on this machine"
msgstr "Esta ventoinha não está disponível nessa máquina"
#: rog-control-center/ui/pages/fans.slint:34
msgctxt "FanTab"
msgid "Enabled"
msgstr "Habilitado"
#: rog-control-center/ui/pages/fans.slint:43
msgctxt "FanTab"
msgid "Apply"
msgstr "Aplicar"
#: rog-control-center/ui/pages/fans.slint:51
msgctxt "FanTab"
msgid "Cancel"
msgstr "Cancelar"
#: rog-control-center/ui/pages/fans.slint:59
msgctxt "FanTab"
msgid "Factory Default (all fans)"
msgstr "Padrão de Fabrica (todas as ventoinhas)"
#: rog-control-center/ui/pages/fans.slint:72
msgctxt "PageFans"
msgid "Balanced"
msgstr "Equilibrado"
#: rog-control-center/ui/pages/fans.slint:75 rog-control-center/ui/pages/fans.slint:134 rog-control-center/ui/pages/fans.slint:193
msgctxt "PageFans"
msgid "CPU"
msgstr "Processador"
#: rog-control-center/ui/pages/fans.slint:93 rog-control-center/ui/pages/fans.slint:152 rog-control-center/ui/pages/fans.slint:211
msgctxt "PageFans"
msgid "Mid"
msgstr "Médio"
#: rog-control-center/ui/pages/fans.slint:111 rog-control-center/ui/pages/fans.slint:170 rog-control-center/ui/pages/fans.slint:229
msgctxt "PageFans"
msgid "GPU"
msgstr "Placa de Vídeo"
#: rog-control-center/ui/pages/fans.slint:131
msgctxt "PageFans"
msgid "Performance"
msgstr "Performance"
#: rog-control-center/ui/pages/fans.slint:190
msgctxt "PageFans"
msgid "Quiet"
msgstr "Silencioso"
#: rog-control-center/ui/pages/app_settings.slint:26
msgctxt "PageAppSettings"
msgid "Run in background after closing"
msgstr "Executar em pano de fundo após fechar"
#: rog-control-center/ui/pages/app_settings.slint:34
msgctxt "PageAppSettings"
msgid "Start app in background (UI closed)"
msgstr "Iniciar Aplicação em pano de fundo (Interface Gráfica fechada)"
#: rog-control-center/ui/pages/app_settings.slint:42
msgctxt "PageAppSettings"
msgid "Enable system tray icon"
msgstr "Habilitar icone da bandeja de sistema"
#: rog-control-center/ui/pages/app_settings.slint:50
msgctxt "PageAppSettings"
msgid "Enable dGPU notifications"
msgstr "Habilitar notificações da GPU dedicada"
#: rog-control-center/ui/types/aura_types.slint:52
msgctxt "Aura power zone"
msgid "Logo"
msgstr "Logo"
#: rog-control-center/ui/types/aura_types.slint:53 rog-control-center/ui/types/aura_types.slint:63
msgctxt "Aura power zone"
msgid "Keyboard"
msgstr "Teclado"
#: rog-control-center/ui/types/aura_types.slint:54 rog-control-center/ui/types/aura_types.slint:64
msgctxt "Aura power zone"
msgid "Lightbar"
msgstr "Barra de Luz"
#: rog-control-center/ui/types/aura_types.slint:55
msgctxt "Aura power zone"
msgid "Lid"
msgstr "Tampa"
#: rog-control-center/ui/types/aura_types.slint:56
msgctxt "Aura power zone"
msgid "Rear Glow"
msgstr "Brilho Traseiro"
#: rog-control-center/ui/types/aura_types.slint:57 rog-control-center/ui/types/aura_types.slint:65
msgctxt "Aura power zone"
msgid "Keyboard and Lightbar"
msgstr "Teclado e Barra de Luz"
#: rog-control-center/ui/types/aura_types.slint:58
msgctxt "Aura power zone"
msgid "Ally"
msgstr "Ally"
#: rog-control-center/ui/types/aura_types.slint:68
msgctxt "Aura brightness"
msgid "Off"
msgstr "Desligado"
#: rog-control-center/ui/types/aura_types.slint:69
msgctxt "Aura brightness"
msgid "Low"
msgstr "Baixo"
#: rog-control-center/ui/types/aura_types.slint:70
msgctxt "Aura brightness"
msgid "Med"
msgstr "Médio"
#: rog-control-center/ui/types/aura_types.slint:71
msgctxt "Aura brightness"
msgid "High"
msgstr "Alto"
#: rog-control-center/ui/types/aura_types.slint:76 rog-control-center/ui/types/aura_types.slint:91
msgctxt "Basic aura mode"
msgid "Static"
msgstr "Estático"
#: rog-control-center/ui/types/aura_types.slint:77 rog-control-center/ui/types/aura_types.slint:92
msgctxt "Basic aura mode"
msgid "Breathe"
msgstr "Respiração"
#: rog-control-center/ui/types/aura_types.slint:78 rog-control-center/ui/types/aura_types.slint:93
msgctxt "Basic aura mode"
msgid "Strobe"
msgstr "Estroboscópio"
#: rog-control-center/ui/types/aura_types.slint:79
msgctxt "Basic aura mode"
msgid "Rainbow"
msgstr "Arco-Íris"
#: rog-control-center/ui/types/aura_types.slint:80
msgctxt "Basic aura mode"
msgid "Star"
msgstr "Estrela"
#: rog-control-center/ui/types/aura_types.slint:81
msgctxt "Basic aura mode"
msgid "Rain"
msgstr "Chuva"
#: rog-control-center/ui/types/aura_types.slint:82
msgctxt "Basic aura mode"
msgid "Highlight"
msgstr "Destaque"
#: rog-control-center/ui/types/aura_types.slint:83
msgctxt "Basic aura mode"
msgid "Laser"
msgstr "Lase"
#: rog-control-center/ui/types/aura_types.slint:84
msgctxt "Basic aura mode"
msgid "Ripple"
msgstr "Ondas"
#: rog-control-center/ui/types/aura_types.slint:85
msgctxt "Basic aura mode"
msgid "Nothing"
msgstr "Nenhum"
#: rog-control-center/ui/types/aura_types.slint:86
msgctxt "Basic aura mode"
msgid "Pulse"
msgstr "Pulso"
#: rog-control-center/ui/types/aura_types.slint:87
msgctxt "Basic aura mode"
msgid "Comet"
msgstr "Cometa"
#: rog-control-center/ui/types/aura_types.slint:88
msgctxt "Basic aura mode"
msgid "Flash"
msgstr "Piscando"
#: rog-control-center/ui/types/aura_types.slint:100
msgctxt "Aura zone"
msgid "None"
msgstr "Nenhuma"
#: rog-control-center/ui/types/aura_types.slint:101
msgctxt "Aura zone"
msgid "Key1"
msgstr "Tecla1"
#: rog-control-center/ui/types/aura_types.slint:102
msgctxt "Aura zone"
msgid "Key2"
msgstr "Tecla2"
#: rog-control-center/ui/types/aura_types.slint:103
msgctxt "Aura zone"
msgid "Key3"
msgstr "Tecla3"
#: rog-control-center/ui/types/aura_types.slint:104
msgctxt "Aura zone"
msgid "Key4"
msgstr "Tecla4"
#: rog-control-center/ui/types/aura_types.slint:105
msgctxt "Aura zone"
msgid "Logo"
msgstr "Logo"
#: rog-control-center/ui/types/aura_types.slint:106
msgctxt "Aura zone"
msgid "Lightbar Left"
msgstr "Barra de Luza Esquerda"
#: rog-control-center/ui/types/aura_types.slint:107
msgctxt "Aura zone"
msgid "Lightbar Right"
msgstr "Barra de Luz Direita"
#: rog-control-center/ui/types/aura_types.slint:111
msgctxt "Aura direction"
msgid "Right"
msgstr "Direita"
#: rog-control-center/ui/types/aura_types.slint:112
msgctxt "Aura direction"
msgid "Left"
msgstr "Esquerda"
#: rog-control-center/ui/types/aura_types.slint:113
msgctxt "Aura direction"
msgid "Up"
msgstr "Cima"
#: rog-control-center/ui/types/aura_types.slint:114
msgctxt "Aura direction"
msgid "Down"
msgstr "Baixo"
#: rog-control-center/ui/types/aura_types.slint:118
msgctxt "Aura speed"
msgid "Low"
msgstr "Baixa"
#: rog-control-center/ui/types/aura_types.slint:119
msgctxt "Aura speed"
msgid "Medium"
msgstr "Média"
#: rog-control-center/ui/types/aura_types.slint:120
msgctxt "Aura speed"
msgid "High"
msgstr "Alta"
#: rog-control-center/ui/widgets/aura_power.slint:33
msgctxt "AuraPowerGroup"
msgid "Boot"
msgstr "Inicilização"
#: rog-control-center/ui/widgets/aura_power.slint:43
msgctxt "AuraPowerGroup"
msgid "Awake"
msgstr "Acordado"
#: rog-control-center/ui/widgets/aura_power.slint:53
msgctxt "AuraPowerGroup"
msgid "Sleep"
msgstr "Dormir"
#: rog-control-center/ui/widgets/aura_power.slint:63
msgctxt "AuraPowerGroup"
msgid "Shutdown"
msgstr "Desligar"
#: rog-control-center/ui/widgets/aura_power.slint:102
msgctxt "AuraPowerGroupOld"
msgid "Zone Selection"
msgstr "Seleção de Zona"
#: rog-control-center/ui/widgets/aura_power.slint:114
msgctxt "AuraPowerGroupOld"
msgid "Boot"
msgstr "Inicilizacao"
#: rog-control-center/ui/widgets/aura_power.slint:124
msgctxt "AuraPowerGroupOld"
msgid "Awake"
msgstr "Acordado"
#: rog-control-center/ui/widgets/aura_power.slint:134
msgctxt "AuraPowerGroupOld"
msgid "Sleep"
msgstr "Dormir"
#: rog-control-center/ui/widgets/common.slint:136
msgctxt "confirm_reset"
msgid "Are you sure you want to reset this?"
msgstr "Tem certeza que deseja resetar isso?"
#: rog-control-center/ui/main_window.slint:55
msgctxt "MainWindow"
msgid "ROG"
msgstr "ROG"
#: rog-control-center/ui/main_window.slint:57
msgctxt "Menu1"
msgid "System Control"
msgstr "Controles do Sistema"
#: rog-control-center/ui/main_window.slint:58
msgctxt "Menu2"
msgid "Keyboard Aura"
msgstr "Teclado Aura"
#: rog-control-center/ui/main_window.slint:59
msgctxt "Menu3"
msgid "AniMe Matrix"
msgstr "AniMe Matrix"
#: rog-control-center/ui/main_window.slint:60
msgctxt "Menu4"
msgid "Fan Curves"
msgstr "Curvas das Ventoinhas"
#: rog-control-center/ui/main_window.slint:61
msgctxt "Menu5"
msgid "App Settings"
msgstr "Configuracoes do App"
#: rog-control-center/ui/main_window.slint:62
msgctxt "Menu6"
msgid "About"
msgstr "Sobre"
#: rog-control-center/ui/main_window.slint:74
msgctxt "MainWindow"
msgid "Quit App"
msgstr "Sair do App"

View File

@@ -190,7 +190,9 @@ export component MainWindow inherits Window {
y: 0px; y: 0px;
width: root.width; width: root.width;
height: root.height; height: root.height;
padding: 10px;
//padding only has effect on layout elements
//padding: 10px;
background: Palette.background; background: Palette.background;
border-color: Palette.border; border-color: Palette.border;

View File

@@ -37,7 +37,8 @@ export component PageAnime inherits Rectangle {
property <bool> show_builtin_advanced: false; property <bool> show_builtin_advanced: false;
clip: true; clip: true;
// TODO: slow with border-radius // TODO: slow with border-radius
padding: 8px; //padding only has effect on layout elements
//padding: 8px;
// height: parent.height - infobar.height - mainview.padding - self.padding * 2; // height: parent.height - infobar.height - mainview.padding - self.padding * 2;
// TODO: border-radius: 8px; // TODO: border-radius: 8px;
VerticalLayout { VerticalLayout {

View File

@@ -16,7 +16,9 @@ export component PageAppSettings inherits VerticalLayout {
Rectangle { Rectangle {
clip: true; clip: true;
// TODO: slow with border-radius // TODO: slow with border-radius
padding: 8px; //padding only has effect on layout elements
//padding: 8px;
// height: parent.height - infobar.height - mainview.padding - self.padding * 2; // height: parent.height - infobar.height - mainview.padding - self.padding * 2;
// TODO: border-radius: 8px; // TODO: border-radius: 8px;
mainview := VerticalLayout { mainview := VerticalLayout {

View File

@@ -113,7 +113,8 @@ export component PageAura inherits Rectangle {
min-height: 80px; min-height: 80px;
max-height: 90px; max-height: 90px;
RogItem { RogItem {
padding: 0px; //padding only has effect on layout elements
//padding: 0px;
VerticalBox { VerticalBox {
Text { Text {
text: @tr("Zone"); text: @tr("Zone");
@@ -136,7 +137,8 @@ export component PageAura inherits Rectangle {
} }
RogItem { RogItem {
padding: 0px; //padding only has effect on layout elements
//padding: 0px;
VerticalBox { VerticalBox {
Text { Text {
text: @tr("Direction"); text: @tr("Direction");
@@ -158,7 +160,8 @@ export component PageAura inherits Rectangle {
} }
RogItem { RogItem {
padding: 0px; //padding only has effect on layout elements
//padding: 0px;
VerticalBox { VerticalBox {
Text { Text {
text: @tr("Speed"); text: @tr("Speed");

View File

@@ -1,4 +1,4 @@
import { SystemSlider, SystemDropdown, SystemToggle, SystemToggleInt } from "../widgets/common.slint"; import { SystemSlider, SystemDropdown, SystemToggle, SystemToggleInt, RogItem } from "../widgets/common.slint";
import { Palette, HorizontalBox , VerticalBox, ScrollView, Slider, Button, Switch, ComboBox, GroupBox, StandardButton} from "std-widgets.slint"; import { Palette, HorizontalBox , VerticalBox, ScrollView, Slider, Button, Switch, ComboBox, GroupBox, StandardButton} from "std-widgets.slint";
export struct AttrMinMax { export struct AttrMinMax {
@@ -51,8 +51,21 @@ export global SystemPageData {
callback cb_panel_overdrive(int); callback cb_panel_overdrive(int);
in-out property <int> boot_sound; in-out property <int> boot_sound;
callback cb_boot_sound(int); callback cb_boot_sound(int);
in-out property <int> screen_auto_brightness;
callback cb_screen_auto_brightness(int);
in-out property <int> mcu_powersave;
callback cb_mcu_powersave(int);
in-out property <int> mini_led_mode; in-out property <int> mini_led_mode;
callback cb_mini_led_mode(int); callback cb_mini_led_mode(int);
in-out property <float> screenpad_gamma;
callback cb_screenpad_gamma(float);
// percentage
in-out property <int> screenpad_brightness: 50;
callback cb_screenpad_brightness(int);
in-out property <bool> screenpad_sync_with_primary: false;
callback cb_screenpad_sync_with_primary(bool);
in-out property <bool> asus_armoury_loaded: false; in-out property <bool> asus_armoury_loaded: false;
in-out property <AttrMinMax> ppt_pl1_spl: { in-out property <AttrMinMax> ppt_pl1_spl: {
@@ -131,7 +144,8 @@ export component PageSystem inherits Rectangle {
property <bool> show_fade_cover: false; property <bool> show_fade_cover: false;
property <bool> show_throttle_advanced: false; property <bool> show_throttle_advanced: false;
clip: true; clip: true;
padding: 8px; //padding only has effect on layout elements
//padding: 8px;
ScrollView { ScrollView {
VerticalLayout { VerticalLayout {
padding: 10px; padding: 10px;
@@ -185,6 +199,52 @@ export component PageSystem inherits Rectangle {
} }
} }
if SystemPageData.screenpad_brightness != -1: RogItem {
HorizontalLayout {
padding-left: 10px;
padding-right: 20px;
HorizontalLayout {
width: 38%;
alignment: LayoutAlignment.space-between;
padding-right: 15px;
Text {
font-size: 16px;
vertical-alignment: TextVerticalAlignment.center;
color: Palette.control-foreground;
text: @tr("Screenpad brightness");
}
}
HorizontalLayout {
width: 38%;
alignment: LayoutAlignment.stretch;
screen_bright := Slider {
enabled: true;
minimum: 0;
maximum: 100;
value: SystemPageData.screenpad_brightness;
released(value) => {
// SystemPageData.screenpad_brightness = self.value;
SystemPageData.cb_screenpad_brightness(Math.floor(self.value));
}
}
}
HorizontalLayout {
width: 20%;
padding-left: 10px;
alignment: LayoutAlignment.stretch;
Switch {
text: @tr("Sync with primary");
checked <=> SystemPageData.screenpad_sync_with_primary;
toggled => {
SystemPageData.cb_screenpad_sync_with_primary(self.checked);
}
}
}
}
}
Rectangle { Rectangle {
background: Palette.alternate-background; background: Palette.alternate-background;
border-color: Palette.accent-background; border-color: Palette.accent-background;
@@ -244,9 +304,25 @@ export component PageSystem inherits Rectangle {
SystemPageData.cb_boot_sound(SystemPageData.boot_sound) SystemPageData.cb_boot_sound(SystemPageData.boot_sound)
} }
} }
if SystemPageData.screen_auto_brightness != -1: SystemToggleInt {
text: @tr("Screen Auto Brightness");
checked_int <=> SystemPageData.screen_auto_brightness;
toggled => {
SystemPageData.cb_screen_auto_brightness(SystemPageData.screen_auto_brightness)
}
}
if SystemPageData.mcu_powersave != -1: SystemToggleInt {
text: @tr("MCU Powersave");
checked_int <=> SystemPageData.mcu_powersave;
toggled => {
SystemPageData.cb_mcu_powersave(SystemPageData.mcu_powersave)
}
}
} }
if SystemPageData.ppt_pl1_spl.current != -1 || SystemPageData.ppt_pl2_sppt.current != -1 || SystemPageData.ppt_pl3_fppt.current != -1 || SystemPageData.ppt_fppt.current != -1 || SystemPageData.ppt_apu_sppt.current != -1 || SystemPageData.nv_temp_target.current != -1 || SystemPageData.nv_dynamic_boost.current != -1: HorizontalLayout { if (SystemPageData.ppt_pl1_spl.max > 0 && SystemPageData.ppt_pl1_spl.current != -1) || (SystemPageData.ppt_pl2_sppt.max > 0 && SystemPageData.ppt_pl2_sppt.current != -1) || (SystemPageData.ppt_pl3_fppt.max > 0 && SystemPageData.ppt_pl3_fppt.current != -1) || (SystemPageData.ppt_fppt.max > 0 && SystemPageData.ppt_fppt.current != -1) || (SystemPageData.ppt_apu_sppt.max > 0 && SystemPageData.ppt_apu_sppt.current != -1) || (SystemPageData.nv_temp_target.max > 0 && SystemPageData.nv_temp_target.current != -1) || (SystemPageData.nv_dynamic_boost.max > 0 && SystemPageData.nv_dynamic_boost.current != -1): HorizontalLayout {
padding-right: 10px; padding-right: 10px;
padding-left: 10px; padding-left: 10px;
alignment: LayoutAlignment.space-between; alignment: LayoutAlignment.space-between;
@@ -275,7 +351,7 @@ export component PageSystem inherits Rectangle {
} }
} }
if SystemPageData.ppt_pl1_spl.current != -1: SystemSlider { if SystemPageData.ppt_pl1_spl.max > 0 && SystemPageData.ppt_pl1_spl.current != -1: SystemSlider {
text: @tr("ppt_pl1_spl" => "CPU Sustained Power Limit"); text: @tr("ppt_pl1_spl" => "CPU Sustained Power Limit");
title: @tr("ppt_pl1_spl" => "CPU Sustained Power Limit"); title: @tr("ppt_pl1_spl" => "CPU Sustained Power Limit");
help_text: @tr("ppt_pl1_spl_help" => "Long-term CPU power limit that affects sustained workload performance. Higher values may increase heat and power consumption."); help_text: @tr("ppt_pl1_spl_help" => "Long-term CPU power limit that affects sustained workload performance. Higher values may increase heat and power consumption.");
@@ -293,7 +369,7 @@ export component PageSystem inherits Rectangle {
} }
} }
if SystemPageData.ppt_pl2_sppt.current != -1: SystemSlider { if SystemPageData.ppt_pl2_sppt.max > 0 && SystemPageData.ppt_pl2_sppt.current != -1: SystemSlider {
text: @tr("ppt_pl2_sppt" => "CPU Turbo Power Limit"); text: @tr("ppt_pl2_sppt" => "CPU Turbo Power Limit");
title: @tr("ppt_pl2_sppt" => "CPU Turbo Power Limit"); title: @tr("ppt_pl2_sppt" => "CPU Turbo Power Limit");
help_text: @tr("ppt_pl2_sppt_help" => "Short-term CPU power limit for boost periods. Controls maximum power during brief high-performance bursts."); help_text: @tr("ppt_pl2_sppt_help" => "Short-term CPU power limit for boost periods. Controls maximum power during brief high-performance bursts.");
@@ -311,7 +387,7 @@ export component PageSystem inherits Rectangle {
} }
} }
if SystemPageData.ppt_pl3_fppt.current != -1: SystemSlider { if SystemPageData.ppt_pl3_fppt.max > 0 && SystemPageData.ppt_pl3_fppt.current != -1: SystemSlider {
text: @tr("ppt_pl3_fppt" => "CPU Fast Burst Power Limit"); text: @tr("ppt_pl3_fppt" => "CPU Fast Burst Power Limit");
title: @tr("ppt_pl3_fppt" => "CPU Fast Burst Power Limit"); title: @tr("ppt_pl3_fppt" => "CPU Fast Burst Power Limit");
help_text: @tr("ppt_pl3_fppt_help" => "Ultra-short duration power limit for instantaneous CPU bursts. Affects responsiveness during sudden workload spikes."); help_text: @tr("ppt_pl3_fppt_help" => "Ultra-short duration power limit for instantaneous CPU bursts. Affects responsiveness during sudden workload spikes.");
@@ -328,7 +404,7 @@ export component PageSystem inherits Rectangle {
SystemPageData.cb_ppt_pl3_fppt(Math.round(value)); SystemPageData.cb_ppt_pl3_fppt(Math.round(value));
} }
} }
if SystemPageData.ppt_fppt.current != -1: SystemSlider { if SystemPageData.ppt_fppt.max > 0 && SystemPageData.ppt_fppt.current != -1: SystemSlider {
text: @tr("ppt_fppt" => "Fast Package Power Limit"); text: @tr("ppt_fppt" => "Fast Package Power Limit");
title: @tr("ppt_fppt" => "Fast Package Power Limit"); title: @tr("ppt_fppt" => "Fast Package Power Limit");
help_text: @tr("ppt_fppt_help" => "Ultra-short duration power limit for system package. Controls maximum power during millisecond-scale load spikes."); help_text: @tr("ppt_fppt_help" => "Ultra-short duration power limit for system package. Controls maximum power during millisecond-scale load spikes.");
@@ -346,7 +422,7 @@ export component PageSystem inherits Rectangle {
} }
} }
if SystemPageData.ppt_apu_sppt.current != -1: SystemSlider { if SystemPageData.ppt_apu_sppt.max > 0 && SystemPageData.ppt_apu_sppt.current != -1: SystemSlider {
text: @tr("ppt_apu_sppt" => "APU Sustained Power Limit"); text: @tr("ppt_apu_sppt" => "APU Sustained Power Limit");
title: @tr("ppt_apu_sppt" => "APU Sustained Power Limit"); title: @tr("ppt_apu_sppt" => "APU Sustained Power Limit");
help_text: @tr("ppt_apu_sppt_help" => "Long-term power limit for integrated graphics and CPU combined. Affects sustained performance of APU-based workloads."); help_text: @tr("ppt_apu_sppt_help" => "Long-term power limit for integrated graphics and CPU combined. Affects sustained performance of APU-based workloads.");
@@ -364,7 +440,7 @@ export component PageSystem inherits Rectangle {
} }
} }
if SystemPageData.ppt_platform_sppt.current != -1: SystemSlider { if SystemPageData.ppt_platform_sppt.max > 0 && SystemPageData.ppt_platform_sppt.current != -1: SystemSlider {
text: @tr("ppt_platform_sppt" => "Platform Sustained Power Limit"); text: @tr("ppt_platform_sppt" => "Platform Sustained Power Limit");
title: @tr("ppt_platform_sppt" => "Platform Sustained Power Limit"); title: @tr("ppt_platform_sppt" => "Platform Sustained Power Limit");
help_text: @tr("ppt_platform_sppt_help" => "Overall system power limit for sustained operations. Controls total platform power consumption over extended periods."); help_text: @tr("ppt_platform_sppt_help" => "Overall system power limit for sustained operations. Controls total platform power consumption over extended periods.");
@@ -382,7 +458,7 @@ export component PageSystem inherits Rectangle {
} }
} }
if SystemPageData.nv_dynamic_boost.current != -1: SystemSlider { if SystemPageData.nv_dynamic_boost.max > 0 && SystemPageData.nv_dynamic_boost.current != -1: SystemSlider {
text: @tr("nv_dynamic_boost" => "GPU Power Boost"); text: @tr("nv_dynamic_boost" => "GPU Power Boost");
title: @tr("nv_dynamic_boost" => "GPU Power Boost"); title: @tr("nv_dynamic_boost" => "GPU Power Boost");
help_text: @tr("nv_dynamic_boost_help" => "Additional power allocation for GPU dynamic boost. Higher values increase GPU performance but generate more heat."); help_text: @tr("nv_dynamic_boost_help" => "Additional power allocation for GPU dynamic boost. Higher values increase GPU performance but generate more heat.");
@@ -400,7 +476,7 @@ export component PageSystem inherits Rectangle {
} }
} }
if SystemPageData.nv_temp_target.current != -1: SystemSlider { if SystemPageData.nv_temp_target.max > 0 && SystemPageData.nv_temp_target.current != -1: SystemSlider {
text: @tr("nv_temp_target" => "GPU Temperature Limit"); text: @tr("nv_temp_target" => "GPU Temperature Limit");
title: @tr("nv_temp_target" => "GPU Temperature Limit"); title: @tr("nv_temp_target" => "GPU Temperature Limit");
help_text: @tr("nv_temp_target_help" => "Maximum GPU temperature threshold in Celsius. GPU will throttle to maintain temperature below this limit."); help_text: @tr("nv_temp_target_help" => "Maximum GPU temperature threshold in Celsius. GPU will throttle to maintain temperature below this limit.");

View File

@@ -4,7 +4,8 @@
import { Palette, HorizontalBox, VerticalBox } from "std-widgets.slint"; import { Palette, HorizontalBox, VerticalBox } from "std-widgets.slint";
component SideBarItem inherits Rectangle { component SideBarItem inherits Rectangle {
padding: 10px; // padding only has effect on layout elements
// padding: 10px;
in property <bool> selected; in property <bool> selected;
in property <bool> has-focus; in property <bool> has-focus;
in-out property <string> text <=> label.text; in-out property <string> text <=> label.text;

View File

@@ -5,6 +5,7 @@ pub mod asus_armoury;
pub mod scsi_aura; pub mod scsi_aura;
pub mod zbus_anime; pub mod zbus_anime;
pub mod zbus_aura; pub mod zbus_aura;
pub mod zbus_backlight;
pub mod zbus_fan_curves; pub mod zbus_fan_curves;
pub mod zbus_platform; pub mod zbus_platform;
pub mod zbus_slash; pub mod zbus_slash;

View File

@@ -0,0 +1,59 @@
//! # D-Bus interface proxy for: `xyz.ljones.Backlight`
//!
//! This code was generated by `zbus-xmlgen` `5.1.0` from D-Bus introspection
//! data. Source: `Interface '/xyz/ljones' from service 'xyz.ljones.Asusd' on
//! system bus`.
//!
//! You may prefer to adapt it, instead of using it verbatim.
//!
//! More information can be found in the [Writing a client proxy] section of the
//! zbus documentation.
//!
//! This type implements the [D-Bus standard interfaces],
//! (`org.freedesktop.DBus.*`) for which the following zbus API can be used:
//!
//! * [`zbus::fdo::PeerProxy`]
//! * [`zbus::fdo::PropertiesProxy`]
//! * [`zbus::fdo::IntrospectableProxy`]
//!
//! Consequently `zbus-xmlgen` did not generate code for the above interfaces.
//!
//! [Writing a client proxy]: https://dbus2.github.io/zbus/client.html
//! [D-Bus standard interfaces]: https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces,
use zbus::proxy;
#[proxy(
interface = "xyz.ljones.Backlight",
default_service = "xyz.ljones.Asusd",
default_path = "/xyz/ljones"
)]
pub trait Backlight {
/// PrimaryBrightness property
#[zbus(property)]
fn primary_brightness(&self) -> zbus::Result<i32>;
#[zbus(property)]
fn set_primary_brightness(&self, value: i32) -> zbus::Result<()>;
/// ScreenpadBrightness property
#[zbus(property)]
fn screenpad_brightness(&self) -> zbus::Result<i32>;
#[zbus(property)]
fn set_screenpad_brightness(&self, value: i32) -> zbus::Result<()>;
/// ScreenpadGamma property
#[zbus(property)]
fn screenpad_gamma(&self) -> zbus::Result<String>;
#[zbus(property)]
fn set_screenpad_gamma(&self, value: &str) -> zbus::Result<()>;
/// ScreenpadPower property
#[zbus(property)]
fn screenpad_power(&self) -> zbus::Result<bool>;
#[zbus(property)]
fn set_screenpad_power(&self, value: bool) -> zbus::Result<()>;
/// ScreenpadSyncWithPrimary property
#[zbus(property)]
fn screenpad_sync_with_primary(&self) -> zbus::Result<bool>;
#[zbus(property)]
fn set_screenpad_sync_with_primary(&self, value: bool) -> zbus::Result<()>;
}

View File

@@ -95,7 +95,7 @@ impl Attribute {
_ => return Err(PlatformError::InvalidValue), _ => return Err(PlatformError::InvalidValue),
}; };
let mut file = OpenOptions::new().write(true).open(&path)?; let mut file = OpenOptions::new().write(true).truncate(true).open(&path)?;
file.write_all(value_str.as_bytes())?; file.write_all(value_str.as_bytes())?;
Ok(()) Ok(())
} }
@@ -124,6 +124,22 @@ impl Attribute {
&self.scalar_increment &self.scalar_increment
} }
fn read_attr_i32(&self, name: &str) -> Option<i32> {
read_i32(&self.base_path.join(name)).ok()
}
pub fn refresh_min_value(&self) -> Option<i32> {
self.read_attr_i32("min_value")
}
pub fn refresh_max_value(&self) -> Option<i32> {
self.read_attr_i32("max_value")
}
pub fn refresh_scalar_increment(&self) -> Option<i32> {
self.read_attr_i32("scalar_increment")
}
/// Read all the immutable values to struct data. These should *never* /// Read all the immutable values to struct data. These should *never*
/// change, if they do then it is possibly a driver issue - although this is /// change, if they do then it is possibly a driver issue - although this is
/// subject to `firmware_attributes` class changes in kernel. /// subject to `firmware_attributes` class changes in kernel.
@@ -228,6 +244,37 @@ impl FirmwareAttributes {
Self { attrs } Self { attrs }
} }
/// Create attributes collection from an arbitrary base directory. Intended for tests
/// where a fake sysfs-like layout can be supplied.
pub fn from_dir(base_dir: &std::path::Path) -> Self {
let mut attrs = Vec::new();
if let Ok(dir) = read_dir(base_dir) {
for entry in dir.flatten() {
let base_path = entry.path();
let name = base_path.file_name().unwrap().to_string_lossy().to_string();
if name == "pending_reboot" {
continue;
}
let help = read_string(&base_path.join("display_name")).unwrap_or_default();
let (default_value, possible_values, min_value, max_value, scalar_increment) =
Attribute::read_base_values(&base_path);
attrs.push(Attribute {
name,
help,
default_value,
possible_values,
min_value,
max_value,
scalar_increment,
base_path,
});
}
}
Self { attrs }
}
pub fn attributes(&self) -> &Vec<Attribute> { pub fn attributes(&self) -> &Vec<Attribute> {
&self.attrs &self.attrs
} }
@@ -256,15 +303,35 @@ macro_rules! define_attribute_getters {
} }
define_attribute_getters!( define_attribute_getters!(
apu_mem, cores_performance, cores_efficiency, ppt_pl1_spl, ppt_pl2_sppt, ppt_apu_sppt, apu_mem,
ppt_platform_sppt, ppt_fppt, nv_dynamic_boost, nv_temp_target, dgpu_base_tgp, dgpu_tgp, cores_performance,
charge_mode, boot_sound, mcu_powersave, panel_od, panel_hd_mode, egpu_connected, egpu_enable, cores_efficiency,
dgpu_disable, gpu_mux_mode, mini_led_mode ppt_pl1_spl,
ppt_pl2_sppt,
ppt_apu_sppt,
ppt_platform_sppt,
ppt_fppt,
nv_dynamic_boost,
nv_temp_target,
nv_base_tgp,
nv_tgp,
charge_mode,
boot_sound,
mcu_powersave,
panel_od,
panel_hd_mode,
egpu_connected,
egpu_enable,
dgpu_disable,
gpu_mux_mode,
mini_led_mode,
screen_auto_brightness
); );
/// CamelCase names of the properties. Intended for use with DBUS /// CamelCase names of the properties. Intended for use with DBUS
#[repr(u8)] #[repr(u8)]
#[derive( #[derive(
Debug,
Clone, Clone,
Copy, Copy,
Serialize, Serialize,
@@ -306,6 +373,7 @@ pub enum FirmwareAttribute {
PendingReboot = 23, PendingReboot = 23,
PptEnabled = 24, PptEnabled = 24,
None = 25, None = 25,
ScreenAutoBrightness = 26,
} }
impl FirmwareAttribute { impl FirmwareAttribute {
@@ -326,6 +394,7 @@ impl FirmwareAttribute {
self, self,
FirmwareAttribute::NvDynamicBoost FirmwareAttribute::NvDynamicBoost
| FirmwareAttribute::NvTempTarget | FirmwareAttribute::NvTempTarget
| FirmwareAttribute::DgpuBaseTgp
| FirmwareAttribute::DgpuTgp | FirmwareAttribute::DgpuTgp
) )
} }
@@ -346,8 +415,11 @@ impl From<&str> for FirmwareAttribute {
"ppt_platform_sppt" => Self::PptPlatformSppt, "ppt_platform_sppt" => Self::PptPlatformSppt,
"nv_dynamic_boost" => Self::NvDynamicBoost, "nv_dynamic_boost" => Self::NvDynamicBoost,
"nv_temp_target" => Self::NvTempTarget, "nv_temp_target" => Self::NvTempTarget,
"nv_tgp" => Self::DgpuTgp,
"nv_base_tgp" => Self::DgpuBaseTgp, "nv_base_tgp" => Self::DgpuBaseTgp,
/* Backwards compatibility: some kernels expose these attributes with a dgpu_* prefix */
"dgpu_tgp" => Self::DgpuTgp, "dgpu_tgp" => Self::DgpuTgp,
"dgpu_base_tgp" => Self::DgpuBaseTgp,
"charge_mode" => Self::ChargeMode, "charge_mode" => Self::ChargeMode,
"boot_sound" => Self::BootSound, "boot_sound" => Self::BootSound,
"mcu_powersave" => Self::McuPowersave, "mcu_powersave" => Self::McuPowersave,
@@ -359,6 +431,7 @@ impl From<&str> for FirmwareAttribute {
"gpu_mux_mode" => Self::GpuMuxMode, "gpu_mux_mode" => Self::GpuMuxMode,
"mini_led_mode" => Self::MiniLedMode, "mini_led_mode" => Self::MiniLedMode,
"pending_reboot" => Self::PendingReboot, "pending_reboot" => Self::PendingReboot,
"screen_auto_brightness" => Self::ScreenAutoBrightness,
_ => { _ => {
error!("Invalid firmware attribute: {}", s); error!("Invalid firmware attribute: {}", s);
Self::None Self::None
@@ -382,8 +455,8 @@ impl From<FirmwareAttribute> for &str {
FirmwareAttribute::PptPlatformSppt => "ppt_platform_sppt", FirmwareAttribute::PptPlatformSppt => "ppt_platform_sppt",
FirmwareAttribute::NvDynamicBoost => "nv_dynamic_boost", FirmwareAttribute::NvDynamicBoost => "nv_dynamic_boost",
FirmwareAttribute::NvTempTarget => "nv_temp_target", FirmwareAttribute::NvTempTarget => "nv_temp_target",
FirmwareAttribute::DgpuBaseTgp => "dgpu_base_tgp", FirmwareAttribute::DgpuBaseTgp => "nv_base_tgp",
FirmwareAttribute::DgpuTgp => "dgpu_tgp", FirmwareAttribute::DgpuTgp => "nv_tgp",
FirmwareAttribute::ChargeMode => "charge_mode", FirmwareAttribute::ChargeMode => "charge_mode",
FirmwareAttribute::BootSound => "boot_sound", FirmwareAttribute::BootSound => "boot_sound",
FirmwareAttribute::McuPowersave => "mcu_powersave", FirmwareAttribute::McuPowersave => "mcu_powersave",
@@ -395,6 +468,7 @@ impl From<FirmwareAttribute> for &str {
FirmwareAttribute::GpuMuxMode => "gpu_mux_mode", FirmwareAttribute::GpuMuxMode => "gpu_mux_mode",
FirmwareAttribute::MiniLedMode => "mini_led_mode", FirmwareAttribute::MiniLedMode => "mini_led_mode",
FirmwareAttribute::PendingReboot => "pending_reboot", FirmwareAttribute::PendingReboot => "pending_reboot",
FirmwareAttribute::ScreenAutoBrightness => "screen_auto_brightness",
FirmwareAttribute::None => "none", FirmwareAttribute::None => "none",
} }
} }
@@ -481,3 +555,28 @@ mod tests {
attr.set_current_value(&val).unwrap(); attr.set_current_value(&val).unwrap();
} }
} }
#[cfg(test)]
mod alias_tests {
use super::FirmwareAttribute;
#[test]
fn tgp_aliases_map_to_same_variant() {
let nv = FirmwareAttribute::from("nv_tgp");
let dgpu = FirmwareAttribute::from("dgpu_tgp");
assert_eq!(nv, dgpu);
let nv_base = FirmwareAttribute::from("nv_base_tgp");
let dgpu_base = FirmwareAttribute::from("dgpu_base_tgp");
assert_eq!(nv_base, dgpu_base);
}
#[test]
fn tgp_canonical_output_is_nv_tgp() {
let s: &str = FirmwareAttribute::DgpuTgp.into();
assert_eq!(s, "nv_tgp");
let s_base: &str = FirmwareAttribute::DgpuBaseTgp.into();
assert_eq!(s_base, "nv_base_tgp");
}
}

View File

@@ -0,0 +1,75 @@
use std::path::PathBuf;
use log::{info, warn};
use crate::error::{PlatformError, Result};
use crate::{attr_num, to_device};
/// The "backlight" device provides access to screen brightness control
#[derive(Debug, PartialEq, Eq, PartialOrd, Clone)]
pub struct Backlight {
path: PathBuf,
device_type: BacklightType,
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Clone)]
pub enum BacklightType {
Primary,
Screenpad,
}
impl Backlight {
attr_num!("brightness", path, i32);
attr_num!("max_brightness", path, i32);
attr_num!("bl_power", path, i32);
pub fn new(device_type: BacklightType) -> Result<Self> {
let mut enumerator = udev::Enumerator::new().map_err(|err| {
warn!("{}", err);
PlatformError::Udev("enumerator failed".into(), err)
})?;
enumerator.match_subsystem("backlight").map_err(|err| {
warn!("{}", err);
PlatformError::Udev("match_subsystem failed".into(), err)
})?;
for device in enumerator.scan_devices().map_err(|err| {
warn!("{}", err);
PlatformError::Udev("scan_devices failed".into(), err)
})? {
info!("Backlight: Checking {:?}", device.syspath());
match device_type {
BacklightType::Primary => {
if device.sysname().to_string_lossy() == "intel_backlight" {
info!("Found primary backlight at {:?}", device.sysname());
return Ok(Self {
path: device.syspath().to_path_buf(),
device_type,
});
}
}
BacklightType::Screenpad => {
let name = device.sysname().to_string_lossy();
if name == "asus_screenpad" || name == "asus_screenpad_backlight" {
info!("Found screenpad backlight at {:?}", device.sysname());
return Ok(Self {
path: device.syspath().to_path_buf(),
device_type,
});
}
}
}
}
Err(PlatformError::MissingFunction(format!(
"Backlight {:?} not found",
device_type
)))
}
pub fn device_type(&self) -> &BacklightType {
&self.device_type
}
}

View File

@@ -267,18 +267,24 @@ mod tests {
fn check_cpu() { fn check_cpu() {
let cpu = CPUControl::new().unwrap(); let cpu = CPUControl::new().unwrap();
assert_eq!(cpu.get_governor().unwrap(), CPUGovernor::Powersave); assert_eq!(cpu.get_governor().unwrap(), CPUGovernor::Powersave);
assert_eq!(cpu.get_available_governors().unwrap(), vec![ assert_eq!(
CPUGovernor::Performance, cpu.get_available_governors().unwrap(),
CPUGovernor::Powersave vec![
]); CPUGovernor::Performance,
CPUGovernor::Powersave
]
);
assert_eq!(cpu.get_epp().unwrap(), CPUEPP::BalancePower); assert_eq!(cpu.get_epp().unwrap(), CPUEPP::BalancePower);
assert_eq!(cpu.get_available_epp().unwrap(), vec![ assert_eq!(
CPUEPP::Default, cpu.get_available_epp().unwrap(),
CPUEPP::Performance, vec![
CPUEPP::BalancePerformance, CPUEPP::Default,
CPUEPP::BalancePower, CPUEPP::Performance,
CPUEPP::Power, CPUEPP::BalancePerformance,
]); CPUEPP::BalancePower,
CPUEPP::Power,
]
);
} }
} }

View File

@@ -3,7 +3,7 @@ use std::path::PathBuf;
use log::{info, warn}; use log::{info, warn};
use crate::error::{PlatformError, Result}; use crate::error::{PlatformError, Result};
use crate::{attr_u8, has_attr, set_attr_u8_array, to_device}; use crate::{attr_num, has_attr, set_attr_u8_array, to_device};
/// The sysfs control for backlight levels. This is only for the 3-step /// The sysfs control for backlight levels. This is only for the 3-step
/// backlight setting, and for TUF laptops. It is not a hard requirement /// backlight setting, and for TUF laptops. It is not a hard requirement
@@ -14,7 +14,7 @@ pub struct KeyboardBacklight {
} }
impl KeyboardBacklight { impl KeyboardBacklight {
attr_u8!("brightness", path); attr_num!("brightness", path, u8);
has_attr!("kbd_rgb_mode" path); has_attr!("kbd_rgb_mode" path);

View File

@@ -2,6 +2,7 @@
//! on ROG, Strix, and TUF laptops. //! on ROG, Strix, and TUF laptops.
pub mod asus_armoury; pub mod asus_armoury;
pub mod backlight;
pub mod cpu; pub mod cpu;
pub mod error; pub mod error;
pub mod hid_raw; pub mod hid_raw;
@@ -55,18 +56,29 @@ pub fn write_attr_bool(device: &mut Device, attr: &str, value: bool) -> Result<(
}) })
} }
pub fn read_attr_u8(device: &Device, attr_name: &str) -> Result<u8> { pub fn read_attr_num<T>(device: &Device, attr_name: &str) -> Result<T>
where
T: std::str::FromStr,
<T as std::str::FromStr>::Err: std::fmt::Debug,
{
if let Some(value) = device.attribute_value(attr_name) { if let Some(value) = device.attribute_value(attr_name) {
let tmp = value.to_string_lossy(); let tmp = value.to_string_lossy();
return tmp.parse::<u8>().map_err(|_e| PlatformError::ParseNum); return tmp.parse::<T>().map_err(|_e| PlatformError::ParseNum);
} }
Err(PlatformError::AttrNotFound(attr_name.to_owned())) Err(PlatformError::AttrNotFound(attr_name.to_owned()))
} }
pub fn write_attr_u8(device: &mut Device, attr: &str, value: u8) -> Result<()> { pub fn write_attr_num<T>(device: &mut Device, attr_name: &str, value: T) -> Result<()>
device where
.set_attribute_value(attr, value.to_string()) T: std::fmt::Display,
.map_err(|e| PlatformError::IoPath(attr.into(), e)) {
if device
.set_attribute_value(attr_name, format!("{value}"))
.is_err()
{
return Err(PlatformError::AttrNotFound(attr_name.to_owned()));
}
Ok(())
} }
pub fn read_attr_u8_array(device: &Device, attr_name: &str) -> Result<Vec<u8>> { pub fn read_attr_u8_array(device: &Device, attr_name: &str) -> Result<Vec<u8>> {

View File

@@ -74,36 +74,41 @@ macro_rules! attr_bool {
} }
#[macro_export] #[macro_export]
macro_rules! get_attr_u8 { macro_rules! get_attr_num {
($(#[$attr:meta])* $attr_name:literal $item:ident) => { ($(#[$attr:meta])* $attr_name:literal $item:ident $type:ty) => {
concat_idents::concat_idents!(fn_name = get_, $attr_name { concat_idents::concat_idents!(fn_name = get_, $attr_name {
$(#[$attr])* $(#[$attr])*
pub fn fn_name(&self) -> Result<u8> { pub fn fn_name(&self) -> Result<$type> {
$crate::read_attr_u8(&to_device(&self.$item)?, $attr_name) $crate::read_attr_num::<$type>(&to_device(&self.$item)?, $attr_name)
} }
}); });
}; };
($(#[$attr:meta])* $attr_name:literal $item:ident) => {
$crate::get_attr_num!($(#[$attr])* $attr_name $item $type);
};
} }
/// Most attributes expect `u8` as a char, so `1` should be written as `b'1'`.
#[macro_export] #[macro_export]
macro_rules! set_attr_u8 { macro_rules! set_attr_num {
($(#[$attr:meta])* $attr_name:literal $item:ident) => { ($(#[$attr:meta])* $attr_name:literal $item:ident $type:ty) => {
concat_idents::concat_idents!(fn_name = set_, $attr_name { concat_idents::concat_idents!(fn_name = set_, $attr_name {
$(#[$attr])* $(#[$attr])*
pub fn fn_name(&self, value: u8) -> Result<()> { pub fn fn_name(&self, value: $type) -> Result<()> {
$crate::write_attr_u8(&mut to_device(&self.$item)?, $attr_name, value) $crate::write_attr_num(&mut to_device(&self.$item)?, $attr_name, value as $type)
} }
}); });
}; };
($(#[$attr:meta])* $attr_name:literal $item:ident) => {
$crate::set_attr_num!($(#[$attr])* $attr_name $item $type);
};
} }
#[macro_export] #[macro_export]
macro_rules! attr_u8 { macro_rules! attr_num {
($(#[$attr:meta])* $attr_name:literal, $item:ident) => { ($(#[$attr:meta])* $attr_name:literal, $item:ident, $type:ty) => {
$crate::has_attr!($(#[$attr])* $attr_name $item); $crate::has_attr!($(#[$attr])* $attr_name $item);
$crate::get_attr_u8!($(#[$attr])* $attr_name $item); $crate::get_attr_num!($(#[$attr])* $attr_name $item $type);
$crate::set_attr_u8!($(#[$attr])* $attr_name $item); $crate::set_attr_num!($(#[$attr])* $attr_name $item $type);
$crate::watch_attr!($(#[$attr])* $attr_name $item); $crate::watch_attr!($(#[$attr])* $attr_name $item);
}; };
} }

View File

@@ -275,11 +275,16 @@ impl std::str::FromStr for PlatformProfile {
type Err = PlatformError; type Err = PlatformError;
fn from_str(profile: &str) -> Result<Self> { fn from_str(profile: &str) -> Result<Self> {
match profile.to_ascii_lowercase().trim() { match profile
.to_ascii_lowercase()
.trim()
.replace(|c| !char::is_alphabetic(c), "")
.as_str()
{
"balanced" => Ok(PlatformProfile::Balanced), "balanced" => Ok(PlatformProfile::Balanced),
"performance" => Ok(PlatformProfile::Performance), "performance" => Ok(PlatformProfile::Performance),
"quiet" => Ok(PlatformProfile::Quiet), "quiet" => Ok(PlatformProfile::Quiet),
"low-power" => Ok(PlatformProfile::LowPower), "lowpower" => Ok(PlatformProfile::LowPower),
"custom" => Ok(PlatformProfile::Custom), "custom" => Ok(PlatformProfile::Custom),
_ => Err(PlatformError::NotSupported), _ => Err(PlatformError::NotSupported),
} }
@@ -288,11 +293,16 @@ impl std::str::FromStr for PlatformProfile {
impl From<&str> for PlatformProfile { impl From<&str> for PlatformProfile {
fn from(profile: &str) -> Self { fn from(profile: &str) -> Self {
match profile.to_ascii_lowercase().trim() { match profile
.to_ascii_lowercase()
.trim()
.replace(|c| !char::is_alphabetic(c), "")
.as_str()
{
"balanced" => PlatformProfile::Balanced, "balanced" => PlatformProfile::Balanced,
"performance" => PlatformProfile::Performance, "performance" => PlatformProfile::Performance,
"quiet" => PlatformProfile::Quiet, "quiet" => PlatformProfile::Quiet,
"low-power" => PlatformProfile::LowPower, "lowpower" => PlatformProfile::LowPower,
"custom" => PlatformProfile::Custom, "custom" => PlatformProfile::Custom,
_ => { _ => {
warn!("{profile} is unknown, using ThrottlePolicy::Balanced"); warn!("{profile} is unknown, using ThrottlePolicy::Balanced");

View File

@@ -3,7 +3,7 @@ use std::path::PathBuf;
use log::{info, warn}; use log::{info, warn};
use crate::error::{PlatformError, Result}; use crate::error::{PlatformError, Result};
use crate::{attr_u8, to_device}; use crate::{attr_num, to_device};
/// The "platform" device provides access to things like: /// The "platform" device provides access to things like:
/// - `dgpu_disable` /// - `dgpu_disable`
@@ -20,9 +20,9 @@ pub struct AsusPower {
} }
impl AsusPower { impl AsusPower {
attr_u8!("charge_control_end_threshold", battery); attr_num!("charge_control_end_threshold", battery, u8);
attr_u8!("online", mains); attr_num!("online", mains, u8);
/// When checking for battery this will look in order: /// When checking for battery this will look in order:
/// - if attr `manufacturer` contains `asus` /// - if attr `manufacturer` contains `asus`
@@ -106,3 +106,13 @@ impl AsusPower {
)) ))
} }
} }
impl Default for AsusPower {
fn default() -> Self {
Self {
mains: PathBuf::from("/this_shouldNeVErr_exisid"),
battery: PathBuf::from("/this_shouldNeVErr_exisid"),
usb: None,
}
}
}

View File

@@ -37,8 +37,9 @@ pub fn find_fan_curve_node() -> Result<Device, ProfileError> {
derive(Type, Value, OwnedValue), derive(Type, Value, OwnedValue),
zvariant(signature = "s") zvariant(signature = "s")
)] )]
#[derive(Deserialize, Serialize, Debug, Hash, PartialEq, Eq, Clone, Copy)] #[derive(Default, Deserialize, Serialize, Debug, Hash, PartialEq, Eq, Clone, Copy)]
pub enum FanCurvePU { pub enum FanCurvePU {
#[default]
CPU = 0, CPU = 0,
GPU = 1, GPU = 1,
MID = 2, MID = 2,
@@ -100,12 +101,6 @@ impl std::str::FromStr for FanCurvePU {
} }
} }
impl Default for FanCurvePU {
fn default() -> Self {
Self::CPU
}
}
/// Main purpose of `FanCurves` is to enable restoring state on system boot /// Main purpose of `FanCurves` is to enable restoring state on system boot
#[cfg_attr(feature = "dbus", derive(Type))] #[cfg_attr(feature = "dbus", derive(Type))]
#[derive(Deserialize, Serialize, Debug, Default)] #[derive(Deserialize, Serialize, Debug, Default)]

4
rust-toolchain.toml Normal file
View File

@@ -0,0 +1,4 @@
[toolchain]
channel = "stable"
components = ["rustfmt", "clippy"]
profile = "minimal"

View File

@@ -157,13 +157,14 @@ fn main() -> Result<(), Box<dyn Error>> {
for (x_count, b) in dev.buffer[start..=end].iter().enumerate() { for (x_count, b) in dev.buffer[start..=end].iter().enumerate() {
canvas.set_draw_color(Color::RGB(*b, *b, *b)); canvas.set_draw_color(Color::RGB(*b, *b, *b));
let x: i32 = w + x_count as i32 * w let x: i32 = w + x_count as i32 * w - {
- if (y_count + y_offset as usize) % 2 != 0 { #[allow(clippy::manual_is_multiple_of)]
if (y_count + y_offset as usize) % 2 != 0 {
0 0
} else { } else {
w / 2 w / 2
} }
+ row.3 * w; } + row.3 * w;
let y = y_count as i32 * h - y_offset * h; let y = y_count as i32 * h - y_offset * h;
canvas canvas
.fill_rect(Rect::new(x, y, w as u32, h as u32)) .fill_rect(Rect::new(x, y, w as u32, h as u32))