Compare commits

...

164 Commits

Author SHA1 Message Date
Denis Benato
e9c5315bda Feat: Remove supergfxctl notification daemon 2026-01-13 22:05:34 +01:00
Denis Benato
b521a9ffc1 Fix: avoid using deprecated functions 2026-01-13 21:49:14 +01:00
Denis Benato
5e48923db1 Feat: update dependencies 2026-01-13 21:29:58 +01:00
Denis Benato
392436808d Fix text of armoury usage 2026-01-13 20:54:53 +01:00
Denis Benato
3d9a08d7e0 Silence the server 2026-01-13 20:18:49 +01:00
Denis Benato
ff103f98af Chore: change text of an error 2026-01-13 20:14:45 +01:00
Denis Benato
d05182ae64 chore: make the settings save code prettier 2026-01-13 19:29:37 +01:00
Denis Benato
a4957a6eeb Modify changelog and cargo fmt 2026-01-10 13:58:09 +01:00
Denis Benato
dda750cf33 Merge branch 'Support_additional_ga403_2025' into 'devel'
Add slash support for additional ga403 2025 models

See merge request asus-linux/asusctl!238
2026-01-10 12:54:01 +00:00
James Lademann
0b5e04393a Add slash support for additional ga403 2025 models 2026-01-10 12:54:01 +00:00
Denis Benato
c9c9a022a4 Merge branch 'fix/one-shot-charge-persistence' into 'devel'
fix: one-shot charging loses original charge limit after restart

See merge request asus-linux/asusctl!242
2026-01-10 12:51:30 +00:00
bitr8
aa063c20fd fix: persist base_charge_control_end_threshold for one-shot charging
base_charge_control_end_threshold was marked #[serde(skip)] so it only
lived in memory. triggering one-shot charge then restarting asusd would
permanently lose the original charge limit.

- remove #[serde(skip)] so the field gets persisted
- add serde default of 0 for backwards compat (skips restore for
  upgraded configs missing the field)
- add comments explaining Default vs serde default asymmetry
2026-01-05 17:23:59 +11:00
Denis Benato
8551908452 Merge branch 'devel' into 'devel'
slashctl: Add "static" LED profile

See merge request asus-linux/asusctl!240
2025-12-24 00:09:19 +00:00
Denis Benato
5ecb174b8f Merge branch 'main' into 'devel'
feat (rog-aura): Add support to FA617NT and FA617XT and update layout_name on FA617NS and FA617XS models

See merge request asus-linux/asusctl!241
2025-12-23 23:48:32 +00:00
Denis Benato
fa266bff5b Merge branch 'main' into 'devel'
Add G614JU support

See merge request asus-linux/asusctl!239
2025-12-23 23:43:41 +00:00
Seom1177
f53f1f360f Feat: update layout_name for FA617NS and FA617XS models in aura_support.ron 2025-12-22 09:06:06 -05:00
Seom1177
da19216b78 Feat: add support for FA617NT and FA617XT models to aura_support.ron 2025-12-22 09:02:25 -05:00
Some Otters
46efd4190f slashctl: Add "static" LED profile
See https://gitlab.com/asus-linux/reverse-engineering/-/blob/master/slash-bar/packets.txt?ref_type=heads . Tested working on a GU605CR
2025-12-22 10:59:17 +00:00
Hamidreza Khorsand
ed3022e25e Add G614JU support 2025-12-19 01:21:16 +03:30
Denis Benato
7c10d6c6d9 Fix: fans control for LowPower and Quiet 2025-12-18 21:53:42 +01:00
Denis Benato
af5f3a5c71 Fix: memorize last applied brightness settings 2025-12-18 15:07:14 +01:00
Denis Benato
7d5ec5f2c7 Update CHANGELOG.md 2025-12-18 03:40:03 +01:00
Denis Benato
1c8acf6de3 Feat: implement keyboard control for TUFs via asus-armoury 2025-12-18 02:10:45 +01:00
Denis Benato
7b644e7ad6 Merge branch 'main' into 'devel'
fix: add systemd scriptlets to restart asusd on package upgrade

See merge request asus-linux/asusctl!237
2025-12-15 18:12:29 +00:00
Denis Benato
0f02fe868c Fix: re-add G835L 2025-12-15 19:11:09 +01:00
Ali Abdelaal
abd3100e30 Merge upstream main, keep systemd scriptlets 2025-12-15 15:47:18 +00:00
Ali Abdelaal
6f651c2b85 Add systemd scriptlets to restart asusd on upgrade 2025-12-15 15:36:45 +00:00
Denis Benato
93ec5d1bce Feat: improve anime matrix detection 2025-12-14 15:05:10 +01:00
Denis Benato
5aea7f51c0 Chore: fix CHANGELOG.md styling 2025-12-14 15:00:51 +01:00
Denis Benato
d03d8ce67f Release: v6.2.0 2025-12-13 14:41:12 +01:00
Denis Benato
ae3693e0d9 Feat: add aura support for G614F models 2025-12-13 14:17:49 +01:00
Denis Benato
c8b9248eda Chore: update CHANGELOG.md 2025-12-13 13:56:46 +01:00
Denis Benato
22098794fe Fix: ensure upper/lower case doesn't fail the match 2025-12-13 13:48:33 +01:00
Denis Benato
10d49f4fc8 Fix: rever silly change in anime type detection 2025-12-13 13:46:29 +01:00
Denis Benato
5aba2854b0 Feat: add support for GU605C* models 2025-12-13 13:45:55 +01:00
Denis Benato
ea32ad6e0a Feat: add support for FX607V 2025-12-13 13:36:46 +01:00
Denis Benato
ee0e612c04 Feat: add AniMe support for G835LW 2025-12-13 13:35:56 +01:00
Denis Benato
e565ce748a Feat: GA403WR -> GA403W 2025-12-13 13:21:58 +01:00
Denis Benato
7024941663 Chore: fix changelog styling 2025-12-13 13:14:37 +01:00
Denis Benato
817a0165b5 Merge branch 'ga403wr' into 'devel'
add support for ga403wr, zephyrus g14 2025

See merge request asus-linux/asusctl!235
2025-12-13 12:14:19 +00:00
Denis Benato
efcd038f40 Merge branch 'main' into 'devel'
Fix: restore spec file for fedora copr builds

See merge request asus-linux/asusctl!236
2025-12-13 12:06:36 +00:00
Ali
375d99b8fc Fix: restore spec file for fedora copr builds 2025-12-13 12:06:36 +00:00
Ali Abdelaal
3a206eb76f Add asusctl as dependency for rog-gui subpackage 2025-12-11 23:49:24 +00:00
Ali Abdelaal
4449838282 Fix: remove cargo_prep which deletes Cargo.lock 2025-12-11 22:55:49 +00:00
Ali Abdelaal
58d740f77a Fix: use direct cargo build instead of cargo_build macro 2025-12-11 22:52:46 +00:00
Ali Abdelaal
f0488d9750 Build with --locked for reproducible builds 2025-12-11 22:47:00 +00:00
Ali Abdelaal
f1b9ae6f71 Fix: rewrite install section to handle Fedora rpm target dir 2025-12-11 21:48:40 +00:00
Ali Abdelaal
db5de3b854 Fix: add asusctl dir to files, remove duplicate aura_support.ron 2025-12-11 21:17:00 +00:00
Ali Abdelaal
7a3d39b8f1 Add fontconfig BuildRequires for Fedora COPR build 2025-12-11 21:01:16 +00:00
Ali Abdelaal
7a5d6325c0 Restore distro-packaging spec file for Fedora COPR builds 2025-12-11 20:46:03 +00:00
rustysec
574b954866 add support for ga403wr, zephyrus g14 2025 2025-11-29 23:49:24 -08:00
Denis Benato
a811f20f65 Release: v6.1.22 2025-11-29 02:57:34 +01:00
Denis Benato
0c9c263be6 Chore: update CHANGELOG.md 2025-11-29 02:52:27 +01:00
Denis Benato
6571c04bfe Merge branch 'devel' 2025-11-29 02:51:29 +01:00
Denis Benato
e48acbb8a2 Chore: update CHANGELOG.md 2025-11-29 02:51:16 +01:00
Denis Benato
f33496ef68 Merge branch 'main' into 'main'
Support the ROG Strix G18 (2025) G815

See merge request asus-linux/asusctl!234
2025-11-29 01:50:33 +00:00
Denis Benato
cd3176b565 Feat: improve a debug message 2025-11-29 02:48:22 +01:00
Denis Benato
7595613d7e Fix: add EXPERTBOOK to udev rules 2025-11-29 02:00:23 +01:00
Adam Bierman
b8d0245e7a Support G815L 2025-11-27 03:20:26 +00:00
Adam Bierman
54bd2ec800 Update file aura_support.ron 2025-11-27 02:44:30 +00:00
Denis Benato
b6c8566565 Feat: Treat dGPU attributes the same as PPT attributes for power-profile 2025-11-23 17:12:55 +01:00
Denis Benato
052c096014 Fix: use the correct name for nv_tgp 2025-11-23 16:56:47 +01:00
Denis Benato
81cbe3c522 Chore(Makefile): install cargo-vendor-filterer 2025-11-20 14:04:35 +01:00
Denis Benato
09f7492bec Release: fuck fedora 2025-11-20 02:59:41 +01:00
Denis Benato
6adfb2cf48 Fix: Release process 2025-11-18 23:03:58 +01:00
Denis Benato
a2a56792a8 Chore: changelog for 6.1.20 2025-11-18 22:56:42 +01:00
Denis Benato
317daf4ed1 Release: 6.1.20 2025-11-18 22:50:35 +01:00
Denis Benato
eb0d9514b5 Merge branch 'devel' 2025-11-18 22:36:27 +01:00
LucaP
d324b1bce5 Feat: Added support for G635L* models. Lightbar, Logo, Matrix 2025-11-18 22:32:49 +01:00
Denis Benato
d1c7385146 Merge branch 'main' into 'main'
Feat: Added support for G635L* models. Lightbar, Logo, Matrix

See merge request asus-linux/asusctl!233
2025-11-18 21:31:13 +00:00
Denis Benato
48a4935fc7 Fix: don't spam the console 2025-11-18 21:36:48 +01:00
LucaP
7e917b91a5 Feat: Added support for G635L* models. Lightbar, Logo, Matrix 2025-11-17 20:12:30 +02:00
Denis Benato
45f8b8ffb0 Chore: attempt another CI fix 2025-11-16 14:43:40 +01:00
Denis Benato
031a36242b Chore: Spare memory on CI 2025-11-16 14:17:24 +01:00
Denis Benato
8ad26ad136 Fix: CI testing 2025-11-15 18:57:14 +01:00
Denis Benato
907d4694f3 Merge branch 'devel' 2025-11-15 18:17:38 +01:00
Denis Benato
1dcc4ff502 Update CHANGELOG.md 2025-11-15 18:15:55 +01:00
Denis Benato
cf232047b0 Merge branch 'patch-1' into 'main'
Add aura support for G614FR (ROG Strix G16 2025)

See merge request asus-linux/asusctl!232
2025-11-15 15:08:19 +00:00
Henry Zhang
ff99ec9a39 Add aura support for G614FR (ROG Strix G16 2025) 2025-11-15 16:13:38 +08:00
Denis Benato
8a19374a41 Merge branch 'aura-support-fa617xs' into 'main'
Add aura support for ASUS TUF Gaming A16 (FA617XS, AMD Advantage Edition)

Closes #696

See merge request asus-linux/asusctl!231
2025-11-14 06:56:21 +00:00
AB
4cec1f49b4 Add FA617XS (TUF A16 AMD Advantage Edition) support to aura_support.ron 2025-11-12 16:29:38 +05:30
Denis Benato
01aae200f3 Fix: do not crash if no battery is present 2025-11-11 22:41:54 +01:00
Denis Benato
4c6db9f0a9 Chore: ignore push-blocking features that would make older rust toolchains error 2025-11-11 22:21:32 +01:00
Denis Benato
7207d3287a Chore: avoid rebuilding after make 2025-11-11 22:03:45 +01:00
Denis Benato
1b2d8d83fc Chore: prepare for 6.1.18 release 2025-11-11 21:55:42 +01:00
Denis Benato
6d8db91583 Chore: reduce trace logging from libraries 2025-11-11 21:49:00 +01:00
Denis Benato
20c3628476 Chore: update dependencies 2025-11-11 21:44:27 +01:00
Denis Benato
4edecfce1c Merge commit '34699a7021a85e1c0ba3d6ac0876c6beb8ae394f' 2025-11-11 21:39:01 +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
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
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
69 changed files with 4745 additions and 2682 deletions

View File

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

View File

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

1
.gitignore vendored
View File

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

View File

@@ -1,22 +1,26 @@
image: rust:latest
# Use shallow clone to reduce checkout size
variables:
GIT_DEPTH: "1"
# Put cargo home and target under project dir so we can clean them easily
CARGO_HOME: "$CI_PROJECT_DIR/.cargo"
CARGO_TARGET_DIR: "$CI_PROJECT_DIR/ci-target"
GIT_SUBMODULE_STRATEGY: normal
# Cache only cargo registries/git metadata to speed dependency fetches.
# Avoid caching compiled `target` artifacts which are large and easily fill disk.
.rust_cache: &rust_cache
cache:
# key: $CI_COMMIT_REF_SLUG
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
paths:
# Don't include `incremental` to save space
# Debug
- target/debug/build/
- target/debug/deps/
- target/debug/.fingerprint/
- target/debug/.cargo-lock
# Release
- target/release/build/
- target/release/deps/
- target/release/.fingerprint/
- target/release/.cargo-lock
- .cargo/registry
- .cargo/git
before_script:
- df -h
- echo "Cleaning stale targets to free space if present"
- rm -rf "$CI_PROJECT_DIR/target" "$CI_PROJECT_DIR/ci-target" || true
- apt-get update -qq && apt-get install -y -qq libudev-dev libgtk-3-dev grep llvm clang libclang-dev libsdl2-dev libsdl2-gfx-dev
stages:
@@ -31,20 +35,24 @@ format:
- tags
<<: *rust_cache
script:
- echo "nightly" > rust-toolchain
- rustup component add rustfmt
- rustup component add rustfmt || true
- cargo fmt --check
after_script:
- du -sh "$CI_PROJECT_DIR/ci-target" || true
- rm -rf "$CI_PROJECT_DIR/ci-target" || true
check:
except:
- tags
<<: *rust_cache
script:
- rustup component add clippy
- cargo check
- rustup component add clippy || true
- cargo check --locked --workspace
# deny currently catches too much
#- cargo install cargo-deny && cargo deny
- cargo install cargo-cranky && cargo cranky
after_script:
- rm -rf "$CI_PROJECT_DIR/ci-target" || true
test:
except:
@@ -52,7 +60,9 @@ test:
<<: *rust_cache
script:
- mkdir -p .git/hooks > /dev/null
- cargo test --all -- --test-threads=1
- cargo test --locked --all
after_script:
- rm -rf "$CI_PROJECT_DIR/ci-target" || true
release:
only:
@@ -60,11 +70,15 @@ release:
<<: *rust_cache
script:
- cargo install cargo-vendor-filterer
- make && make vendor
- cargo fetch
- make FROZEN=1 && make vendor
artifacts:
paths:
- vendor_asusctl*.tar.xz
- cargo-config
expire_in: 1 week
after_script:
- rm -rf vendor vendor_asusctl*.tar.xz "$CI_PROJECT_DIR/ci-target" || true
pages:
stage: deploy
@@ -72,14 +86,14 @@ pages:
- tags
<<: *rust_cache
script:
- cargo doc --document-private-items --no-deps --workspace
- cargo doc --locked --document-private-items --no-deps --workspace
- rm -rf public
- mkdir public
- cp -R target/doc/* public
- cp -R ci-target/doc/* public
- cp extra/index.html public
artifacts:
paths:
- public
variables:
GIT_SUBMODULE_STRATEGY: normal
expire_in: 1 week
after_script:
- rm -rf "$CI_PROJECT_DIR/ci-target" || true

View File

@@ -2,6 +2,84 @@
## [Unreleased]
### Changed
- Added support for TUF keyboard powerstate control
- Improved AniMe Matrix support thanks to @Seom1177 !
- Fixed a bug with one-shot battery change, thanks @bitr8 !
## [6.2.0]
### Changed
- Added aura support for FX607V: thanks @jomp16
- Added testing support for G835LW
- Added support for GU605C models slash lighting: thanks @Otters
- Restore fedora: thanks @ali205412
- Add support to G614F models slash lighting
## [6.1.22]
### Changed
- Allow configuration of nv_tgp
- Treat dGPU attributes as power profiles
- Add EXPERTBOOK DMI match to ensure the service is loaded
- Support G815L thanks to @solost !
## [6.1.21]
### Changed
- Kill Fedora: screw your cursed cargo bullshit
- Restore CI building
## [6.1.20]
### Changed
- Addded support for G635L: thanks @luca_pisl !
- Suppress verbose output in applications too, not just daemon
## [6.1.18]
### Changed
- Add aura support for G614FR (ROG Strix G16 2025)
- all notifications now respects the timeout
- improve udev daemon-starting rule
- reduce log noise
## [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

3708
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
[workspace.package]
version = "6.1.11"
version = "6.2.0"
rust-version = "1.82"
license = "MPL-2.0"
readme = "README.md"
@@ -44,7 +44,7 @@ smol = "^2.0"
mio = "0.8.11"
futures-util = "0.3.31"
zbus = "5.5.0"
zbus = "5.13.1"
logind-zbus = { version = "5.2.0" } #, default-features = false, features = ["non_blocking"] }
serde = { version = "^1.0", features = ["serde_derive"] }
@@ -57,12 +57,12 @@ glam = { version = "^0.22", features = ["serde"] }
gumdrop = "^0.8"
udev = { version = "^0.8", features = ["mio"] }
rusb = "^0.9"
inotify = "^0.10.0"
inotify = "^0.10"
png_pong = "^0.8"
pix = "^0.13"
tinybmp = "^0.4.0"
gif = "^0.12.0"
tinybmp = "^0.4"
gif = "^0.12"
versions = "6.2"

View File

@@ -17,6 +17,8 @@ BIN_D := asusd
BIN_U := asusd-user
LEDCFG := aura_support.ron
DESTDIR_REALPATH = $(shell realpath $(DESTDIR))
SRC := Cargo.toml Cargo.lock Makefile $(shell find -type f -wholename '**/src/*.rs')
STRIP_BINARIES ?= 0
@@ -35,6 +37,15 @@ ifeq ($(X11),1)
ARGS += --features "rog-control-center/x11"
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
ifeq ($(VENDORED),1)
ARGS += --frozen
@@ -48,24 +59,38 @@ clean:
distclean:
rm -rf .cargo vendor vendor.tar.xz
install-program:
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_ROG)" "$(DESTDIR)$(bindir)/$(BIN_ROG)"
target/$(TARGET)/$(BIN_D): $(SRC)
$(MAKE) build
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_C)" "$(DESTDIR)$(bindir)/$(BIN_C)"
target/$(TARGET)/$(BIN_C): $(SRC)
$(MAKE) build
target/$(TARGET)/$(BIN_U): $(SRC)
$(MAKE) build
target/$(TARGET)/$(BIN_ROG): $(SRC)
$(MAKE) build
install-asusd: target/$(TARGET)/$(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-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).png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/$(BIN_ROG).png"
cd rog-aura/data/layouts && find . -type f -name "*.ron" -exec $(INSTALL_DATA) "{}" "$(DESTDIR)$(datarootdir)/rog-gui/layouts/{}" \;
$(INSTALL_DATA) "./data/$(BIN_D).rules" "$(DESTDIR)$(libdir)/udev/rules.d/99-$(BIN_D).rules"
$(INSTALL_DATA) "./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"
cd rog-aura/data/layouts && find . -type f -name "*.ron" -exec $(INSTALL_DATA) "{}" "$(DESTDIR_REALPATH)$(datarootdir)/rog-gui/layouts/{}" \;
$(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"
@@ -81,9 +106,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/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_DATA) "./LICENSE" "$(DESTDIR)$(datarootdir)/asusctl/LICENSE"
uninstall:
rm -f "$(DESTDIR)$(bindir)/$(BIN_ROG)"
@@ -118,6 +158,8 @@ vendor:
mv .cargo/config ./cargo-config
rm -rf .cargo
rm -rf vendor
# Ensure cargo-vendor-filterer is installed (CI installs it already)
command -v cargo-vendor-filterer >/dev/null 2>&1 || cargo install --locked cargo-vendor-filterer
cargo vendor-filterer --all-features --platform x86_64-unknown-linux-gnu vendor
tar pcfJ vendor_asusctl_$(VERSION).tar.xz vendor
rm -rf vendor

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
to this:
```
```plain
Bus 001 Device 002: ID 0b05:1866 ASUSTek Computer, Inc. N-KEY Device
```
or
```
```plain
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 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.
**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:**
dnf install cmake clang-devel libxkbcommon-devel systemd-devel expat-devel pcre2-devel libzstd-devel gtk3-devel
make
sudo make install
```sh
dnf install cmake clang-devel libxkbcommon-devel systemd-devel expat-devel pcre2-devel libzstd-devel gtk3-devel
make
sudo make install
```
**openSUSE:**
Works with KDE Plasma (without GTK packages)
zypper in -t pattern devel_basis
zypper in rustup make cmake clang-devel libxkbcommon-devel systemd-devel expat-devel pcre2-devel libzstd-devel gtk3-devel
make
sudo make install
```sh
zypper in -t pattern devel_basis
zypper in rustup make cmake clang-devel libxkbcommon-devel systemd-devel expat-devel pcre2-devel libzstd-devel gtk3-devel
make
sudo make install
```
**Debian(unsuported):**
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
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
make
sudo make install
```sh
sudo apt install libclang-dev libudev-dev libfontconfig-dev build-essential cmake libxkbcommon-dev
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
make
sudo make install
```
**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
@@ -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.
```
$ systemctl daemon-reload && systemctl restart asusd
```sh
systemctl daemon-reload && systemctl restart asusd
```
## Uninstalling
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`).
@@ -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`.
# 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.
## Supporting more laptops
### Supporting more laptops
Please file a support request.
# License & Trademarks
## License & Trademarks
Mozilla Public License 2 (MPL-2.0)

View File

@@ -27,3 +27,15 @@ zbus.workspace = true
[dev-dependencies]
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 anime_type = get_anime_type();
let mut seq = Sequences::new(anime_type);
seq.insert(0, &ActionLoader::AsusAnimation {
file: path.into(),
time: rog_anime::AnimTime::Infinite,
brightness,
})
seq.insert(
0,
&ActionLoader::AsusAnimation {
file: path.into(),
time: rog_anime::AnimTime::Infinite,
brightness,
},
)
.unwrap();
loop {

View File

@@ -181,6 +181,7 @@ pub struct TwoColourSpeed {
}
#[derive(Debug, Clone, Default, Options)]
#[allow(dead_code)]
pub struct MultiZone {
#[options(help = "print help message")]
help: bool,
@@ -195,6 +196,7 @@ pub struct MultiZone {
}
#[derive(Debug, Clone, Default, Options)]
#[allow(dead_code)]
pub struct MultiColourSpeed {
#[options(help = "print help message")]
help: bool,

View File

@@ -74,6 +74,16 @@ pub struct ProfileCommand {
#[options(meta = "", help = "set the active profile")]
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)]

View File

@@ -9,7 +9,7 @@ use aura_cli::{LedPowerCommand1, LedPowerCommand2};
use dmi_id::DMIID;
use fan_curve_cli::FanCurveCommand;
use gumdrop::{Opt, Options};
use log::{error, info};
use log::{error, info, LevelFilter};
use rog_anime::usb::get_anime_type;
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, AnimeType, Vec2};
use rog_aura::keyboard::{AuraPowerState, LaptopAuraPower};
@@ -44,12 +44,16 @@ mod scsi_cli;
mod slash_cli;
fn main() {
// Ensure tracing spans are quiet by default unless user overrides
if std::env::var_os("RUST_LOG").is_none() {
std::env::set_var("RUST_LOG", "warn,tracing=error,zbus=error");
}
let mut logger = env_logger::Builder::new();
logger
.parse_default_env()
.target(env_logger::Target::Stdout)
.filter_level(LevelFilter::Info)
.target(env_logger::Target::Stderr)
.format_timestamp(None)
.filter_level(log::LevelFilter::Debug)
.init();
let self_version = env!("CARGO_PKG_VERSION");
@@ -979,7 +983,13 @@ fn handle_throttle_profile(
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 {
println!("Missing arg or command\n");
}
@@ -999,6 +1009,10 @@ fn handle_throttle_profile(
proxy.set_platform_profile(PlatformProfile::next(current, &choices))?;
} else if let Some(profile) = cmd.profile_set {
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 {
@@ -1009,6 +1023,11 @@ fn handle_throttle_profile(
if cmd.profile_get {
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(())
@@ -1169,10 +1188,11 @@ fn print_firmware_attr(attr: &AsusArmouryProxyBlocking) -> Result<(), Box<dyn st
Ok(())
}
#[allow(clippy::manual_is_multiple_of, clippy::nonminimal_bool)]
fn handle_armoury_command(cmd: &ArmouryCommand) -> Result<(), Box<dyn std::error::Error>> {
{
if cmd.free.is_empty() || cmd.free.len() % 2 != 0 || cmd.help {
const USAGE: &str = "Usage: asusctl platform panel_overdrive 1 nv_dynamic_boost 5";
if cmd.free.is_empty() || (cmd.free.len() % 2 != 0) || cmd.help {
const USAGE: &str = "Usage: asusctl armoury panel_overdrive 1 nv_dynamic_boost 5";
if cmd.free.len() % 2 != 0 {
println!(
"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
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,18 @@ concat-idents.workspace = true
[dev-dependencies]
cargo-husky.workspace = true
[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 config_traits::StdConfig;
use futures_util::lock::Mutex;
use log::{debug, error, info};
use log::{debug, error, info, warn};
use rog_platform::asus_armoury::{AttrValue, Attribute, FirmwareAttribute, FirmwareAttributes};
use rog_platform::platform::{PlatformProfile, RogPlatform};
use rog_platform::power::AsusPower;
use serde::{Deserialize, Serialize};
use tokio::sync::Mutex;
use zbus::object_server::SignalEmitter;
use zbus::zvariant::{ObjectPath, OwnedObjectPath, OwnedValue, Type, Value};
use zbus::{fdo, interface, Connection};
@@ -51,6 +51,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> {
let path = dbus_path_for_attr(self.attr.name());
connection
@@ -78,14 +101,20 @@ impl AsusArmouryAttribute {
let sig = signal_ctxt.clone();
tokio::spawn(async move {
let mut buffer = [0; 32];
watch
.into_event_stream(&mut buffer)
.unwrap()
.for_each(|_| async {
debug!("{} changed", name);
ctrl.$fn_prop_changed(&sig).await.ok();
})
.await;
if let Ok(stream) = watch.into_event_stream(&mut buffer) {
stream
.for_each(|_| async {
debug!("{} changed", name);
ctrl.$fn_prop_changed(&sig).await.ok();
})
.await;
} else {
info!(
"inotify event stream failed for {} ({}). You can ignore this \
if unsupported",
name, $attr_str
);
}
});
}
Err(e) => info!(
@@ -107,35 +136,106 @@ 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 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 {
async fn reload(&mut self) -> Result<(), RogError> {
info!("Reloading {}", self.attr.name());
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
let power_plugged = self
.power
.get_online()
.map_err(|e| {
error!("Could not get power status: {e:?}");
e
})
.unwrap_or_default();
let config = if power_plugged == 1 {
&self.config.lock().await.ac_profile_tunings
let name: FirmwareAttribute = self.attr.name().into();
// Treat dGPU attributes the same as PPT attributes for power-profile
// behaviour so they follow AC/DC tuning groups.
if name.is_ppt() || name.is_dgpu() {
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
let power_plugged = self
.power
.get_online()
.map_err(|e| {
error!("Could not get power status: {e:?}");
e
})
.unwrap_or_default()
== 1;
let apply_value = {
let config = self.config.lock().await;
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 {
self.attr
.set_current_value(&AttrValue::Integer(tune))
.map_err(|e| {
error!("Could not set {} value: {e:?}", self.attr.name());
self.attr.base_path_exists();
e
})?;
info!(
"Restored PPT armoury setting {} to {:?}",
self.attr.name(),
tune
);
} else {
info!("Ignored restoring PPT armoury setting {} as tuning group is disabled or no saved value", self.attr.name());
}
} else {
&self.config.lock().await.dc_profile_tunings
};
if let Some(tuning) = config.get(&profile) {
if tuning.enabled {
if let Some(tune) = tuning.group.get(&self.name()) {
self.attr
.set_current_value(&AttrValue::Integer(*tune))
.map_err(|e| {
error!("Could not set {} value: {e:?}", self.attr.name());
self.attr.base_path_exists();
e
})?;
info!("Set {} to {:?}", self.attr.name(), tune);
}
// 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!(
"Error restoring armoury setting {}: {e:?}",
self.attr.name()
);
self.attr.base_path_exists();
e
})?;
info!(
"Restored armoury setting {} to {:?}",
self.attr.name(),
saved_value
);
} else {
info!(
"No saved armoury setting for {}: skipping restore",
self.attr.name()
);
}
}
@@ -193,7 +293,7 @@ impl AsusArmouryAttribute {
async fn restore_default(&self) -> fdo::Result<()> {
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 power_plugged = self
.power
@@ -226,26 +326,20 @@ impl AsusArmouryAttribute {
#[zbus(property)]
async fn min_value(&self) -> i32 {
match self.attr.min_value() {
AttrValue::Integer(i) => *i,
_ => -1,
}
Self::resolve_i32_value(self.attr.refresh_min_value(), self.attr.min_value())
}
#[zbus(property)]
async fn max_value(&self) -> i32 {
match self.attr.max_value() {
AttrValue::Integer(i) => *i,
_ => -1,
}
Self::resolve_i32_value(self.attr.refresh_max_value(), self.attr.max_value())
}
#[zbus(property)]
async fn scalar_increment(&self) -> i32 {
match self.attr.scalar_increment() {
AttrValue::Integer(i) => *i,
_ => -1,
}
Self::resolve_i32_value(
self.attr.refresh_scalar_increment(),
self.attr.scalar_increment(),
)
}
#[zbus(property)]
@@ -258,7 +352,7 @@ impl AsusArmouryAttribute {
#[zbus(property)]
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 power_plugged = self
.power
@@ -267,12 +361,15 @@ impl AsusArmouryAttribute {
error!("Could not get power status: {e:?}");
e
})
.unwrap_or_default();
let mut config = self.config.lock().await;
let tuning = config.select_tunings(power_plugged == 1, profile);
if let Some(tune) = tuning.group.get(&self.name()) {
return Ok(*tune);
} else if let AttrValue::Integer(i) = self.attr.default_value() {
.unwrap_or_default()
== 1;
let config = self.config.lock().await;
if let Some(tuning) = config.select_tunings_ref(power_plugged, 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);
}
return Err(fdo::Error::Failed(
@@ -290,7 +387,7 @@ impl AsusArmouryAttribute {
#[zbus(property)]
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 power_plugged = self
.power
@@ -314,44 +411,44 @@ impl AsusArmouryAttribute {
self.attr
.set_current_value(&AttrValue::Integer(value))
.map_err(|e| {
error!("Could not set value: {e:?}");
error!(
"Could not set value to PPT property {}: {e:?}",
self.attr.name()
);
e
})?;
} else {
warn!(
"Tuning group is disabled: skipping setting value to PPT property {}",
self.attr.name()
);
}
} else {
self.attr
.set_current_value(&AttrValue::Integer(value))
.map_err(|e| {
error!("Could not set value: {e:?}");
error!(
"Could not set value {value} to attribute {}: {e:?}",
self.attr.name()
);
e
})?;
let has_attr = self
.config
.lock()
.await
let mut settings = self.config.lock().await;
settings
.armoury_settings
.contains_key(&self.name());
if has_attr {
if let Some(setting) = self
.config
.lock()
.await
.armoury_settings
.get_mut(&self.name())
{
*setting = value
}
} else {
debug!("Adding config for {}", self.attr.name());
self.config
.lock()
.await
.armoury_settings
.insert(self.name(), value);
debug!("Set config for {} = {:?}", self.attr.name(), value);
}
.entry(self.name())
.and_modify(|setting| {
debug!("Set config for {} = {value}", self.attr.name());
*setting = value;
})
.or_insert_with(|| {
debug!("Adding config for {} = {value}", self.attr.name());
value
});
}
// write config after setting value
self.config.lock().await.write();
Ok(())
}
@@ -363,7 +460,8 @@ pub async fn start_attributes_zbus(
power: AsusPower,
attributes: FirmwareAttributes,
config: Arc<Mutex<Config>>,
) -> Result<(), RogError> {
) -> Result<ArmouryAttributeRegistry, RogError> {
let mut registry = ArmouryAttributeRegistry::default();
for attr in attributes.attributes() {
let mut attr = AsusArmouryAttribute::new(
attr.clone(),
@@ -371,15 +469,42 @@ pub async fn start_attributes_zbus(
power.clone(),
config.clone(),
);
attr.reload().await?;
let path = dbus_path_for_attr(attr.attr.name());
let sig = zbus::object_server::SignalEmitter::new(conn, path)?;
attr.watch_and_notify(sig).await?;
let registry_attr = attr.clone();
attr.move_to_zbus(conn).await?;
if let Err(e) = attr.reload().await {
error!(
"Skipping attribute '{}' due to reload error: {e:?}",
attr.attr.name()
);
break;
}
let attr_name = attr.attribute_name();
let path = dbus_path_for_attr(attr_name.as_str());
match zbus::object_server::SignalEmitter::new(conn, 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(conn).await {
error!("Failed to register attribute '{attr_name}' on zbus: {e:?}");
continue;
}
registry.push(registry_attr);
}
Ok(())
Ok(registry)
}
pub async fn set_config_or_default(
@@ -390,7 +515,7 @@ pub async fn set_config_or_default(
) {
for attr in attrs.attributes().iter() {
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);
if !tuning.enabled {
debug!("Tuning group is not enabled, skipping");
@@ -420,6 +545,20 @@ pub async fn set_config_or_default(
// config.write();
}
}
} 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
);
}
}
}
}

View File

@@ -8,7 +8,6 @@ use std::sync::Arc;
use std::thread::sleep;
use config_traits::StdConfig;
use futures_util::lock::Mutex;
use log::{debug, error, info, warn};
use rog_anime::usb::{
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_platform::hid_raw::HidRaw;
use rog_platform::usb_raw::USBRaw;
use tokio::sync::Mutex;
use self::config::{AniMeConfig, AniMeConfigCached};
use crate::error::RogError;
@@ -51,7 +51,7 @@ impl AniMe {
/// Will fail if something is already holding the config lock
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) {
error!(
"Trying to cache the Anime Config failed, will reset to default config: {e:?}"

View File

@@ -85,7 +85,7 @@ impl AniMeZbus {
/// Set base brightness level
#[zbus(property)]
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;
}
Brightness::Off
@@ -117,7 +117,7 @@ impl AniMeZbus {
#[zbus(property)]
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;
}
false
@@ -162,7 +162,7 @@ impl AniMeZbus {
#[zbus(property)]
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;
}
Animations::default()
@@ -195,7 +195,7 @@ impl AniMeZbus {
#[zbus(property)]
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;
}
false
@@ -218,7 +218,7 @@ impl AniMeZbus {
#[zbus(property)]
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;
}
false
@@ -245,7 +245,7 @@ impl AniMeZbus {
#[zbus(property)]
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;
}
false
@@ -261,7 +261,7 @@ impl AniMeZbus {
#[zbus(property)]
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;
}
false

View File

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

View File

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

View File

@@ -71,7 +71,13 @@ impl AuraZbus {
#[zbus(property)]
async fn set_brightness(&mut self, brightness: LedBrightness) -> Result<(), ZbErr> {
if let Some(bl) = self.0.backlight.as_ref() {
return Ok(bl.lock().await.set_brightness(brightness.into())?);
let res = bl.lock().await.set_brightness(brightness.into());
if res.is_ok() {
let mut config = self.0.config.lock().await;
config.brightness = brightness;
config.write();
}
return Ok(res?);
}
Err(ZbErr::Failed("No sysfs brightness control".to_string()))
}
@@ -112,7 +118,7 @@ impl AuraZbus {
// entirely possible to deadlock here, so use try instead of lock()
// let ctrl = self.0.lock().await;
// 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)
} else {
Err(ZbErr::Failed("Aura control couldn't lock self".to_string()))
@@ -140,7 +146,7 @@ impl AuraZbus {
#[zbus(property)]
async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> {
// 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;
match config.builtins.get(&mode) {
Some(effect) => Ok(effect.clone()),

View File

@@ -4,15 +4,16 @@
// - Add it to Zbus server
// - If udev sees device removed then remove the zbus path
use std::collections::HashMap;
use std::sync::Arc;
use dmi_id::DMIID;
use futures_lite::future::block_on;
use futures_util::lock::Mutex;
use log::{debug, error, info, warn};
use mio::{Events, Interest, Poll, Token};
use rog_platform::error::PlatformError;
use rog_platform::hid_raw::HidRaw;
use tokio::sync::Mutex;
use udev::{Device, MonitorBuilder};
use zbus::zvariant::{ObjectPath, OwnedObjectPath};
use zbus::Connection;
@@ -92,23 +93,46 @@ fn dev_prop_matches(dev: &Device, prop: &str, value: &str) -> bool {
pub struct AsusDevice {
device: DeviceHandle,
dbus_path: OwnedObjectPath,
hid_key: Option<String>,
}
pub struct DeviceManager {
_dbus_connection: Connection,
_hid_handles: Arc<Mutex<HashMap<String, Arc<Mutex<HidRaw>>>>>,
}
impl DeviceManager {
#[allow(clippy::type_complexity)]
async fn get_or_create_hid_handle(
handles: &Arc<Mutex<HashMap<String, Arc<Mutex<HidRaw>>>>>,
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(
connection: &Connection,
device: Device,
handles: Arc<Mutex<HashMap<String, Arc<Mutex<HidRaw>>>>>,
) -> Result<Vec<AsusDevice>, RogError> {
let mut devices = Vec::new();
if let Some(usb_device) = device.parent_with_subsystem_devtype("usb", "usb_device")? {
if let Some(usb_id) = usb_device.attribute_value("idProduct") {
if let Some(vendor_id) = usb_device.attribute_value("idVendor") {
if vendor_id != "0b05" {
debug!("Not ASUS vendor ID");
debug!("Not ASUS vendor ID: {}", vendor_id.to_string_lossy());
return Ok(devices);
}
// Almost all devices are identified by the productId.
@@ -116,9 +140,10 @@ impl DeviceManager {
// 1. Generate an interface path
// 2. Create the device
// 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:?}");
let dev = Arc::new(Mutex::new(hidraw));
// SLASH DEVICE
if let Ok(dev_type) = DeviceHandle::new_slash_hid(
dev.clone(),
@@ -134,6 +159,7 @@ impl DeviceManager {
devices.push(AsusDevice {
device: dev_type,
dbus_path: path,
hid_key: Some(hid_key.clone()),
});
}
}
@@ -152,6 +178,7 @@ impl DeviceManager {
devices.push(AsusDevice {
device: dev_type,
dbus_path: path,
hid_key: Some(hid_key.clone()),
});
}
}
@@ -170,9 +197,12 @@ impl DeviceManager {
devices.push(AsusDevice {
device: dev_type,
dbus_path: path,
hid_key: Some(hid_key),
});
}
}
} else {
warn!("Failed to initialise shared hid handle for {usb_id:?}");
}
}
}
@@ -181,7 +211,10 @@ impl DeviceManager {
}
/// 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: Arc<Mutex<HashMap<String, Arc<Mutex<HidRaw>>>>>,
) -> Result<Vec<AsusDevice>, RogError> {
// track and ensure we use only one hidraw per prod_id
// let mut interfaces = HashSet::new();
let mut devices: Vec<AsusDevice> = Vec::new();
@@ -200,7 +233,7 @@ impl DeviceManager {
.scan_devices()
.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)
@@ -228,6 +261,7 @@ impl DeviceManager {
return Some(AsusDevice {
device: dev_type,
dbus_path: path,
hid_key: None,
});
}
}
@@ -275,10 +309,13 @@ impl DeviceManager {
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();
// 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);
}
// USB after, need to check if HID picked something up and if so, skip it
@@ -306,6 +343,7 @@ impl DeviceManager {
devices.push(AsusDevice {
device: dev_type,
dbus_path: path,
hid_key: None,
});
}
} else {
@@ -328,6 +366,7 @@ impl DeviceManager {
devices.push(AsusDevice {
device: dev_type,
dbus_path: path,
hid_key: None,
});
}
}
@@ -355,6 +394,7 @@ impl DeviceManager {
devices.push(AsusDevice {
device: dev_type,
dbus_path: path,
hid_key: None,
});
}
}
@@ -370,16 +410,19 @@ impl DeviceManager {
pub async fn new(connection: Connection) -> Result<Self, RogError> {
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());
let devices = Arc::new(Mutex::new(devices));
let manager = Self {
_dbus_connection: connection,
_hid_handles: hid_handles.clone(),
};
// TODO: The /sysfs/ LEDs don't cause events, so they need to be manually
// checked for and added
let hid_handles_thread = hid_handles.clone();
std::thread::spawn(move || {
let mut monitor = MonitorBuilder::new()?.listen()?;
let mut poll = Poll::new()?;
@@ -408,6 +451,7 @@ impl DeviceManager {
let devices = devices.clone();
let conn_copy = conn_copy.clone();
let hid_handles = hid_handles_thread.clone();
block_on(async move {
// SCSCI devs
if subsys == "block" {
@@ -483,6 +527,7 @@ impl DeviceManager {
// Iter in reverse so as to not screw up indexing
for index in removals.iter().rev() {
let dev = devices.lock().await.remove(*index);
let hid_key = dev.hid_key.clone();
let path = path.clone();
let res = match dev.device {
DeviceHandle::Aura(_) => {
@@ -512,14 +557,20 @@ impl DeviceManager {
_ => todo!(),
};
info!("AuraManager removed: {path:?}, {res}");
if let Some(key) = hid_key {
hid_handles.lock().await.remove(&key);
}
}
}
} else if action == "add" {
let evdev = event.device();
if let Ok(mut new_devs) =
Self::init_hid_devices(&conn_copy, evdev)
.await
.map_err(|e| error!("Couldn't add new device: {e:?}"))
if let Ok(mut new_devs) = Self::init_hid_devices(
&conn_copy,
evdev,
hid_handles.clone(),
)
.await
.map_err(|e| error!("Couldn't add new device: {e:?}"))
{
devices.lock().await.append(&mut new_devs);
}

View File

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

View File

@@ -83,7 +83,7 @@ impl ScsiZbus {
#[zbus(property)]
async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> {
// 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;
match config.modes.get(&mode) {
Some(effect) => Ok(effect.clone()),

View File

@@ -1,10 +1,10 @@
use std::sync::Arc;
use config::SlashConfig;
use futures_util::lock::{Mutex, MutexGuard};
use rog_platform::hid_raw::HidRaw;
use rog_platform::usb_raw::USBRaw;
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;
@@ -27,7 +27,7 @@ impl Slash {
Self { hid, usb, config }
}
pub async fn lock_config(&self) -> MutexGuard<SlashConfig> {
pub async fn lock_config(&self) -> MutexGuard<'_, SlashConfig> {
self.config.lock().await
}

View File

@@ -1,7 +1,6 @@
use std::sync::Arc;
use config_traits::{StdConfig, StdConfigLoad};
use futures_util::lock::Mutex;
use log::{debug, error, info};
use rog_anime::error::AnimeError;
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_slash::error::SlashError;
use rog_slash::SlashType;
use tokio::sync::Mutex;
use crate::aura_anime::config::AniMeConfig;
use crate::aura_anime::AniMe;

View File

@@ -8,6 +8,12 @@ use serde::{Deserialize, Serialize};
const CONFIG_FILE: &str = "asusd.ron";
/// Default value for base_charge_control_end_threshold when not present in config.
/// Returns 0 so restore_charge_limit() skips restoration for upgraded configs.
fn default_base_charge_limit() -> u8 {
0
}
#[derive(Default, Clone, Deserialize, Serialize, PartialEq)]
pub struct Tuning {
pub enabled: bool,
@@ -19,8 +25,8 @@ type Tunings = HashMap<PlatformProfile, Tuning>;
pub struct Config {
// The current charge limit applied
pub charge_control_end_threshold: u8,
/// Save charge limit for restoring
#[serde(skip)]
/// Save charge limit for restoring after one-shot full charge
#[serde(default = "default_base_charge_limit")]
pub base_charge_control_end_threshold: u8,
pub disable_nvidia_powerd_on_battery: bool,
/// An optional command/script to run when power is changed to AC
@@ -67,12 +73,28 @@ impl Config {
};
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 {
fn default() -> Self {
Self {
charge_control_end_threshold: 100,
// NOTE: This is intentionally 100 (not 0 like the serde default).
// New installs get 100 (no limit). Upgraded configs missing this
// field get 0 via serde, which skips restore_charge_limit().
base_charge_control_end_threshold: 100,
disable_nvidia_powerd_on_battery: true,
ac_command: Default::default(),
@@ -146,7 +168,7 @@ pub struct Config611 {
impl From<Config611> for Config {
fn from(c: Config611) -> Self {
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,
@@ -168,7 +190,12 @@ impl From<Config611> for Config {
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
}
}

View File

@@ -1,9 +1,10 @@
use std::sync::Arc;
use std::time::Duration;
use config_traits::StdConfig;
use futures_util::lock::Mutex;
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};
@@ -12,7 +13,7 @@ use crate::config::Config;
use crate::error::RogError;
use crate::ASUS_ZBUS_PATH;
#[derive(Debug, Clone)]
#[derive(Clone)]
pub struct CtrlBacklight {
backlights: Vec<Backlight>,
config: Arc<Mutex<Config>>,
@@ -165,10 +166,13 @@ impl CtrlBacklight {
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) {
while (stream.next().await).is_some() {
loop {
let _ = stream.next().await;
let sync = backlights.config.lock().await.screenpad_sync_primary;
if let Some(sync) = sync {
if !sync {
@@ -188,10 +192,16 @@ impl CtrlBacklight {
.get_brightness_percent(&BacklightType::Primary)
.await
.unwrap_or(60);
backlights
.set_brightness_with_sync(&BacklightType::Screenpad, level)
.await
.ok();
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)

View File

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

View File

@@ -3,17 +3,17 @@ use std::process::Command;
use std::sync::Arc;
use config_traits::StdConfig;
use futures_util::lock::Mutex;
use log::{debug, error, info, warn};
use rog_platform::asus_armoury::{AttrValue, FirmwareAttribute, FirmwareAttributes};
use rog_platform::cpu::{CPUControl, CPUGovernor, CPUEPP};
use rog_platform::platform::{PlatformProfile, Properties, RogPlatform};
use rog_platform::power::AsusPower;
use tokio::sync::Mutex;
use zbus::fdo::Error as FdoErr;
use zbus::object_server::SignalEmitter;
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::error::RogError;
use crate::{task_watch_item, CtrlTask, ReloadAndNotify};
@@ -46,9 +46,12 @@ pub struct CtrlPlatform {
attributes: FirmwareAttributes,
cpu_control: Option<CPUControl>,
config: Arc<Mutex<Config>>,
connection: Connection,
armoury_registry: ArmouryAttributeRegistry,
}
impl CtrlPlatform {
#[allow(clippy::too_many_arguments)]
pub fn new(
platform: RogPlatform,
power: AsusPower,
@@ -56,6 +59,8 @@ impl CtrlPlatform {
config: Arc<Mutex<Config>>,
config_path: &Path,
signal_context: SignalEmitter<'static>,
connection: Connection,
armoury_registry: ArmouryAttributeRegistry,
) -> Result<Self, RogError> {
let config1 = config.clone();
let config_path = config_path.to_owned();
@@ -68,6 +73,8 @@ impl CtrlPlatform {
cpu_control: CPUControl::new()
.map_err(|e| error!("Couldn't get CPU control sysfs: {e}"))
.ok(),
connection,
armoury_registry,
};
let mut inotify_self = ret_self.clone();
@@ -161,7 +168,7 @@ impl CtrlPlatform {
.map(|s| s.to_string())
.collect()
};
if prog.len() > 1 {
if (!prog.is_empty()) && (!prog[0].is_empty()) {
let mut cmd = Command::new(&prog[0]);
for arg in prog.iter().skip(1) {
cmd.arg(arg);
@@ -288,16 +295,39 @@ impl CtrlPlatform {
#[zbus(property)]
fn charge_control_end_threshold(&self) -> Result<u8, FdoErr> {
let limit = self.power.get_charge_control_end_threshold()?;
if !self.power.has_charge_control_end_threshold() {
return Err(FdoErr::NotSupported(
"RogPlatform: charge_control_end_threshold not supported".to_owned(),
));
}
let limit = self.power.get_charge_control_end_threshold().map_err(|e| {
FdoErr::Failed(format!(
"Could not read charge_control_end_threshold: {e:?}"
))
})?;
Ok(limit)
}
#[zbus(property)]
async fn set_charge_control_end_threshold(&mut self, limit: u8) -> Result<(), FdoErr> {
if !self.power.has_charge_control_end_threshold() {
return Err(FdoErr::NotSupported(
"RogPlatform: charge_control_end_threshold not supported".to_owned(),
));
}
if !(20..=100).contains(&limit) {
return Err(RogError::ChargeLimit(limit))?;
}
self.power.set_charge_control_end_threshold(limit)?;
self.power
.set_charge_control_end_threshold(limit)
.map_err(|e| {
FdoErr::Failed(format!("Could not set charge_control_end_threshold: {e:?}"))
})?;
self.config.lock().await.charge_control_end_threshold = limit;
self.config.lock().await.base_charge_control_end_threshold = limit;
self.config.lock().await.write();
@@ -305,12 +335,22 @@ impl CtrlPlatform {
}
async fn one_shot_full_charge(&self) -> Result<(), FdoErr> {
if !self.power.has_charge_control_end_threshold() {
return Err(FdoErr::NotSupported(
"RogPlatform: charge_control_end_threshold not supported".to_owned(),
));
}
let base_limit = std::mem::replace(
&mut self.config.lock().await.charge_control_end_threshold,
100,
);
if base_limit != 100 {
self.power.set_charge_control_end_threshold(100)?;
self.power
.set_charge_control_end_threshold(100)
.map_err(|e| {
FdoErr::Failed(format!("Could not set one_shot_full_charge: {e:?}"))
})?;
self.config.lock().await.base_charge_control_end_threshold = base_limit;
self.config.lock().await.write();
}
@@ -729,6 +769,31 @@ impl CtrlTask for CtrlPlatform {
}
if !sleeping {
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;
}
@@ -789,13 +854,17 @@ impl CtrlTask for CtrlPlatform {
{
// TODO: manage this better, shouldn't need to create every time
let attrs = FirmwareAttributes::new();
set_config_or_default(
&attrs,
&mut *platform3.config.lock().await,
power_plugged,
profile,
)
.await;
{
let mut cfg = platform3.config.lock().await;
set_config_or_default(&attrs, &mut cfg, power_plugged, profile).await;
}
if let Err(e) = platform3
.armoury_registry
.emit_limits(&platform3.connection)
.await
{
error!("Failed to emit armoury updates after AC/DC toggle: {e:?}");
}
platform3
.enable_ppt_group_changed(&signal_ctxt_copy)
.await
@@ -852,6 +921,9 @@ impl CtrlTask for CtrlPlatform {
profile,
)
.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,7 +3,7 @@ use std::error::Error;
use std::sync::Arc;
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::config::Config;
use asusd::ctrl_backlight::CtrlBacklight;
@@ -11,15 +11,17 @@ use asusd::ctrl_fancurves::CtrlFanCurveZbus;
use asusd::ctrl_platform::CtrlPlatform;
use asusd::{print_board_info, start_tasks, CtrlTask, ZbusRun, DBUS_NAME};
use config_traits::{StdConfig, StdConfigLoad2};
use futures_util::lock::Mutex;
use log::{error, info};
use rog_platform::asus_armoury::FirmwareAttributes;
use rog_platform::platform::RogPlatform;
use rog_platform::power::AsusPower;
use tokio::sync::Mutex;
use zbus::fdo::ObjectManager;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Starting asusd daemon...");
// console_subscriber::init();
let mut logger = env_logger::Builder::new();
logger
@@ -62,7 +64,9 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
// Start zbus server
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 cfg_path = config.file_path();
@@ -72,19 +76,31 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
let platform = RogPlatform::new()?; // TODO: maybe needs async mutex?
let power = AsusPower::new()?; // TODO: maybe needs async mutex?
let attributes = FirmwareAttributes::new();
start_attributes_zbus(
let armoury_registry = match start_attributes_zbus(
&server,
platform.clone(),
power.clone(),
attributes.clone(),
config.clone(),
)
.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() {
Ok(ctrl) => {
info!("FanCurves: found supported fancurves");
let sig_ctx = CtrlFanCurveZbus::signal_context(&server)?;
start_tasks(ctrl, &mut server, sig_ctx).await?;
info!("FanCurves: initialized");
}
Err(err) => {
error!("FanCurves: {}", err);
@@ -93,8 +109,10 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
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);
@@ -108,10 +126,14 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
config.clone(),
&cfg_path,
CtrlPlatform::signal_context(&server)?,
server.clone(),
armoury_registry,
) {
Ok(ctrl) => {
info!("CtrlPlatform: initialized");
let sig_ctx = CtrlPlatform::signal_context(&server)?;
start_tasks(ctrl, &mut server, sig_ctx).await?;
info!("CtrlPlatform: tasks started");
}
Err(err) => {
error!("CtrlPlatform: {}", err);
@@ -120,10 +142,12 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
let _ = DeviceManager::new(server.clone()).await?;
info!("DeviceManager initialized");
// Request dbus name after finishing initalizing all functions
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 {
// This is just a blocker to idle and ensure the reator reacts
server.executor().tick().await;

View File

@@ -9,11 +9,14 @@ ENV{DMI_FAMILY}=="*Strix*", GOTO="asusd_start"
ENV{DMI_FAMILY}=="*Vivo*ook*", GOTO="asusd_start"
ENV{DMI_FAMILY}=="*Zenbook*", 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"
ENV{DMI_FAMILY}=="*EXPERTBOOK*", GOTO="asusd_start"
# No match so
GOTO="asusd_end"
LABEL="asusd_start"
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|change", DRIVER=="asus-nb-wmi", TAG+="systemd", ENV{SYSTEMD_WANTS}+="asusd.service"
ACTION=="add|remove", DRIVER=="asus-nb-wmi", TAG+="systemd", ENV{SYSTEMD_WANTS}+="asusd.service"
LABEL="asusd_end"

View File

@@ -6,7 +6,10 @@ After=nvidia-powerd.service systemd-udevd.service
[Service]
Environment=IS_SERVICE=1
Environment=RUST_LOG="debug"
# Reduce noisy span logs while keeping useful debug info for asusd and related crates.
# Keep global level at info but allow debug for our crates; silence tracing::span (very noisy)
# RUST_LOG format: <module>=<level>,... (levels: error,warn,info,debug,trace)
Environment=RUST_LOG="info,asusd=debug,rog_platform=debug,tracing::span=error,zbus::object_server=error,zbus::connection::handshake::common=error,zbus::connection::handshake::client=error"
# required to prevent init issues with hid_asus and MCU
ExecStartPre=/bin/sleep 1
ExecStart=/usr/bin/asusd

84
distro-packaging/asusctl.spec Executable file → Normal file
View File

@@ -20,9 +20,9 @@
%global debug_package %{nil}
%endif
%define version 6.1.11
%define version 6.2.0
%define specrelease %{?dist}
%define pkg_release 9%{specrelease}
%define pkg_release 1%{specrelease}
# Use hardening ldflags.
%global rustflags -Clink-arg=-Wl,-z,relro,-z,now
@@ -55,6 +55,7 @@ BuildRequires: pkgconfig(libseat)
BuildRequires: pkgconfig(libudev)
BuildRequires: pkgconfig(xkbcommon)
BuildRequires: pkgconfig(libzstd)
BuildRequires: pkgconfig(fontconfig)
BuildRequires: desktop-file-utils
%description
@@ -67,6 +68,7 @@ asus-nb-ctrl enables third-party apps to use the above with dbus methods.
%package rog-gui
Summary: An experimental GUI for %{name}
Requires: %{name} = %{version}-%{release}
%description rog-gui
A one-stop-shop GUI tool for asusd/asusctl. It aims to provide most controls,
@@ -74,11 +76,6 @@ a notification service, and ability to run in the background.
%prep
%autosetup
%if %{defined fedora}
%cargo_prep
sed -i 's|offline = true|offline = false|' .cargo/config.toml
sed -i 's|source.crates-io|source.ignore_this|' .cargo/config.toml
%else
mkdir -p .cargo
cat > .cargo/config.toml << 'EOF'
[term]
@@ -86,26 +83,78 @@ verbose = true
[net]
offline = false
EOF
%endif
%build
export RUSTFLAGS="%{rustflags}"
%if %{defined fedora}
%cargo_build
/usr/bin/cargo build --release --locked
%else
/usr/bin/cargo auditable build --release
/usr/bin/cargo auditable build --release --locked
%endif
%install
export RUSTFLAGS="%{rustflags}"
mkdir -p "%{buildroot}/%{_bindir}" "%{buildroot}%{_docdir}"
%make_install
install -D -m 0644 README.md %{buildroot}/%{_docdir}/%{name}/README.md
install -D -m 0644 rog-anime/README.md %{buildroot}/%{_docdir}/%{name}/README-anime.md
install -D -m 0644 rog-anime/data/diagonal-template.png %{buildroot}/%{_docdir}/%{name}/diagonal-template.png
%define _target_dir target/release
desktop-file-validate %{buildroot}/%{_datadir}/applications/rog-control-center.desktop
# Install binaries
install -D -m 0755 %{_target_dir}/asusd %{buildroot}%{_bindir}/asusd
install -D -m 0755 %{_target_dir}/asusd-user %{buildroot}%{_bindir}/asusd-user
install -D -m 0755 %{_target_dir}/asusctl %{buildroot}%{_bindir}/asusctl
install -D -m 0755 %{_target_dir}/rog-control-center %{buildroot}%{_bindir}/rog-control-center
# Install systemd units
install -D -m 0644 data/asusd.service %{buildroot}%{_unitdir}/asusd.service
install -D -m 0644 data/asusd-user.service %{buildroot}%{_userunitdir}/asusd-user.service
# Install udev rules
install -D -m 0644 data/asusd.rules %{buildroot}%{_udevrulesdir}/99-asusd.rules
# Install dbus config
install -D -m 0644 data/asusd.conf %{buildroot}%{_datadir}/dbus-1/system.d/asusd.conf
# Install asusd data
install -D -m 0644 rog-aura/data/aura_support.ron %{buildroot}%{_datadir}/asusd/aura_support.ron
cp -r rog-anime/data/anime %{buildroot}%{_datadir}/asusd/
# Install rog-gui data
install -D -m 0644 rog-control-center/data/rog-control-center.desktop %{buildroot}%{_datadir}/applications/rog-control-center.desktop
install -D -m 0644 rog-control-center/data/rog-control-center.png %{buildroot}%{_datadir}/icons/hicolor/512x512/apps/rog-control-center.png
mkdir -p %{buildroot}%{_datadir}/rog-gui/layouts
cp -r rog-aura/data/layouts/*.ron %{buildroot}%{_datadir}/rog-gui/layouts/
# Install icons
install -D -m 0644 data/icons/asus_notif_yellow.png %{buildroot}%{_datadir}/icons/hicolor/512x512/apps/asus_notif_yellow.png
install -D -m 0644 data/icons/asus_notif_green.png %{buildroot}%{_datadir}/icons/hicolor/512x512/apps/asus_notif_green.png
install -D -m 0644 data/icons/asus_notif_blue.png %{buildroot}%{_datadir}/icons/hicolor/512x512/apps/asus_notif_blue.png
install -D -m 0644 data/icons/asus_notif_red.png %{buildroot}%{_datadir}/icons/hicolor/512x512/apps/asus_notif_red.png
install -D -m 0644 data/icons/asus_notif_orange.png %{buildroot}%{_datadir}/icons/hicolor/512x512/apps/asus_notif_orange.png
install -D -m 0644 data/icons/asus_notif_white.png %{buildroot}%{_datadir}/icons/hicolor/512x512/apps/asus_notif_white.png
install -D -m 0644 data/icons/scalable/gpu-compute.svg %{buildroot}%{_datadir}/icons/hicolor/scalable/status/gpu-compute.svg
install -D -m 0644 data/icons/scalable/gpu-hybrid.svg %{buildroot}%{_datadir}/icons/hicolor/scalable/status/gpu-hybrid.svg
install -D -m 0644 data/icons/scalable/gpu-integrated.svg %{buildroot}%{_datadir}/icons/hicolor/scalable/status/gpu-integrated.svg
install -D -m 0644 data/icons/scalable/gpu-nvidia.svg %{buildroot}%{_datadir}/icons/hicolor/scalable/status/gpu-nvidia.svg
install -D -m 0644 data/icons/scalable/gpu-vfio.svg %{buildroot}%{_datadir}/icons/hicolor/scalable/status/gpu-vfio.svg
install -D -m 0644 data/icons/scalable/notification-reboot.svg %{buildroot}%{_datadir}/icons/hicolor/scalable/status/notification-reboot.svg
# Install docs
install -D -m 0644 README.md %{buildroot}%{_docdir}/%{name}/README.md
install -D -m 0644 rog-anime/README.md %{buildroot}%{_docdir}/%{name}/README-anime.md
install -D -m 0644 rog-anime/data/diagonal-template.png %{buildroot}%{_docdir}/%{name}/diagonal-template.png
# Install LICENSE to asusctl datadir
install -D -m 0644 LICENSE %{buildroot}%{_datadir}/asusctl/LICENSE
desktop-file-validate %{buildroot}%{_datadir}/applications/rog-control-center.desktop
%post
%systemd_post asusd.service
%preun
%systemd_preun asusd.service
%postun
%systemd_postun_with_restart asusd.service
%files
%license LICENSE
@@ -115,8 +164,6 @@ desktop-file-validate %{buildroot}/%{_datadir}/applications/rog-control-center.d
%{_unitdir}/asusd.service
%{_userunitdir}/asusd-user.service
%{_udevrulesdir}/99-asusd.rules
#%dir %{_sysconfdir}/asusd/
%{_datadir}/asusd/aura_support.ron
%{_datadir}/dbus-1/system.d/asusd.conf
%{_datadir}/icons/hicolor/512x512/apps/asus_notif_yellow.png
%{_datadir}/icons/hicolor/512x512/apps/asus_notif_green.png
@@ -131,6 +178,7 @@ desktop-file-validate %{buildroot}/%{_datadir}/applications/rog-control-center.d
%{_datadir}/icons/hicolor/scalable/status/gpu-vfio.svg
%{_datadir}/icons/hicolor/scalable/status/notification-reboot.svg
%{_docdir}/%{name}/
%{_datadir}/asusctl/
%{_datadir}/asusd/
%files rog-gui

View File

@@ -63,6 +63,8 @@ pub enum AnimeType {
GA401,
GA402,
GU604,
G635L,
G835L,
#[default]
Unsupported,
}
@@ -71,12 +73,21 @@ impl FromStr for AnimeType {
type Err = AnimeError;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
Ok(match s {
"ga401" | "GA401" => Self::GA401,
"ga402" | "GA402" => Self::GA402,
"gu604" | "GU604" => Self::GU604,
_ => Self::Unsupported,
})
let dmi = s.to_uppercase();
if dmi.contains("GA401") {
return Ok(Self::GA401);
} else if dmi.contains("GA402") {
return Ok(Self::GA402);
} else if dmi.contains("GU604") {
return Ok(Self::GU604);
} else if dmi.contains("G635L") {
return Ok(Self::G635L);
} else if dmi.contains("G835L") {
return Ok(Self::G835L);
}
Ok(Self::Unsupported)
}
}
@@ -89,6 +100,8 @@ impl AnimeType {
AnimeType::GA402
} else if board_name.contains("GU604V") {
AnimeType::GU604
} else if board_name.contains("G635L") || board_name.contains("G635L") {
AnimeType::G635L
} else {
AnimeType::Unsupported
}
@@ -98,6 +111,7 @@ impl AnimeType {
pub fn width(&self) -> usize {
match self {
AnimeType::GU604 => 70,
AnimeType::G835L => 74,
_ => 74,
}
}
@@ -107,6 +121,7 @@ impl AnimeType {
match self {
AnimeType::GA401 => 36,
AnimeType::GU604 => 43,
AnimeType::G835L => 39,
_ => 39,
}
}
@@ -116,6 +131,7 @@ impl AnimeType {
match self {
AnimeType::GA401 => PANE_LEN * 2,
AnimeType::GU604 => PANE_LEN * 3,
AnimeType::G835L => PANE_LEN * 3,
_ => PANE_LEN * 3,
}
}
@@ -180,7 +196,13 @@ impl TryFrom<AnimeDataBuffer> for AnimePacketType {
let mut buffers = match anime.anime {
AnimeType::GA401 => vec![[0; 640]; 2],
AnimeType::GA402 | AnimeType::GU604 | AnimeType::Unsupported => vec![[0; 640]; 3],
AnimeType::GA402
| AnimeType::GU604
| AnimeType::G635L
| AnimeType::G835L
| AnimeType::Unsupported => {
vec![[0; 640]; 3]
}
};
for (idx, chunk) in anime.data.as_slice().chunks(PANE_LEN).enumerate() {
@@ -191,7 +213,11 @@ impl TryFrom<AnimeDataBuffer> for AnimePacketType {
if matches!(
anime.anime,
AnimeType::GA402 | AnimeType::GU604 | AnimeType::Unsupported
AnimeType::GA402
| AnimeType::GU604
| AnimeType::G635L
| AnimeType::G835L
| AnimeType::Unsupported
) {
buffers[2][..7].copy_from_slice(&USB_PREFIX3);
}

View File

@@ -169,7 +169,7 @@ impl AnimeImage {
// first 5 rows for GA401 are always at X = 0
return 0;
}
(y + 1) / 2 - 3
y.div_ceil(2) - 3
}
AnimeType::GU604 => {
// first 9 rows start at zero
@@ -185,7 +185,7 @@ impl AnimeImage {
return 0;
}
// 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
return 33;
}
36 - (y + 1) / 2
36 - y.div_ceil(2)
}
AnimeType::GU604 => {
if y <= 9 {

View File

@@ -243,7 +243,7 @@ impl From<AnimShutdown> for i32 {
#[inline]
pub fn get_anime_type() -> AnimeType {
let dmi = DMIID::new().unwrap_or_default();
let board_name = dmi.board_name;
let board_name = dmi.board_name.to_uppercase();
if board_name.contains("GA401I") || board_name.contains("GA401Q") {
AnimeType::GA401
@@ -251,6 +251,10 @@ pub fn get_anime_type() -> AnimeType {
AnimeType::GA402
} else if board_name.contains("GU604V") {
AnimeType::GU604
} else if board_name.contains("G635L") {
AnimeType::G635L
} else if board_name.contains("G835L") {
AnimeType::G835L
} else {
AnimeType::Unsupported
}

View File

@@ -5,7 +5,7 @@
layout_name: "fa506i",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -14,7 +14,7 @@
layout_name: "fa506i",
basic_modes: [Static, Breathe, RainbowCycle],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -23,7 +23,7 @@
layout_name: "fa506i",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -32,16 +32,43 @@
layout_name: "fa507",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
device_name: "FA617NS",
product_id: "",
layout_name: "fx505d",
layout_name: "fa507",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
device_name: "FA617NT",
product_id: "",
layout_name: "fa507",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: r#None,
power_zones: [Keyboard],
),
(
device_name: "FA617XS",
product_id: "",
layout_name: "fa507",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: r#None,
power_zones: [Keyboard],
),
(
device_name: "FA617XT",
product_id: "",
layout_name: "fa507",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -50,7 +77,7 @@
layout_name: "fx505d",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -59,7 +86,7 @@
layout_name: "fa506i",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -68,7 +95,7 @@
layout_name: "fa506i",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -77,7 +104,7 @@
layout_name: "fa506i",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -86,7 +113,25 @@
layout_name: "fa506i",
basic_modes: [Static, Breathe, Pulse],
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],
),
(
device_name: "FX607V",
product_id: "",
layout_name: "fa506i",
basic_modes: [Static, Breathe, RainbowCycle, Pulse],
basic_zones: [],
advanced_type: Zoned([SingleZone]),
power_zones: [Keyboard],
),
(
@@ -95,7 +140,7 @@
layout_name: "fa506i",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -104,7 +149,16 @@
layout_name: "fx505d",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
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],
),
(
@@ -113,7 +167,7 @@
layout_name: "g512",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard, Lightbar],
),
(
@@ -131,7 +185,7 @@
layout_name: "g513i",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard, Lightbar],
),
(
@@ -176,7 +230,7 @@
layout_name: "gx502",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -185,7 +239,7 @@
layout_name: "gx502",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -224,13 +278,31 @@
advanced_type: PerKey,
power_zones: [Keyboard],
),
(
device_name: "G614FR",
product_id: "",
layout_name: "g634j-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, Logo],
),
(
device_name: "G614J",
product_id: "",
layout_name: "g634j-per-key",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
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],
),
(
@@ -239,16 +311,25 @@
layout_name: "g634j-per-key",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard, Lightbar],
),
(
device_name: "G614JU",
product_id: "",
layout_name: "g634j-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, Logo],
),
(
device_name: "G614JZ",
product_id: "",
layout_name: "g634j-per-key",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard, Lightbar],
),
(
@@ -260,13 +341,22 @@
advanced_type: PerKey,
power_zones: [Keyboard, Lightbar, Logo, RearGlow],
),
(
device_name: "G635L",
product_id: "",
layout_name: "g635l-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, Logo],
),
(
device_name: "G712LI",
product_id: "",
layout_name: "gl503",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -275,7 +365,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -284,7 +374,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -293,7 +383,7 @@
layout_name: "gx502",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard, Lightbar],
),
(
@@ -302,7 +392,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard, Lightbar],
),
(
@@ -311,7 +401,7 @@
layout_name: "gx502",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard, Lightbar],
),
(
@@ -320,7 +410,7 @@
layout_name: "gx502",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard, Lightbar],
),
(
@@ -356,7 +446,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -374,7 +464,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4, BarLeft, BarRight],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard, Lightbar],
),
(
@@ -392,7 +482,7 @@
layout_name: "g533q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -401,7 +491,7 @@
layout_name: "g533q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -410,7 +500,7 @@
layout_name: "g533q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -458,6 +548,15 @@
advanced_type: PerKey,
power_zones: [Keyboard, Lightbar],
),
(
device_name: "G815L",
product_id: "",
layout_name: "g814ji-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],
),
(
device_name: "G834J",
product_id: "",
@@ -473,7 +572,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -482,7 +581,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -491,7 +590,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -500,7 +599,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -509,7 +608,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -518,7 +617,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -527,7 +626,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -536,7 +635,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -545,7 +644,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -554,7 +653,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -563,7 +662,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -581,7 +680,7 @@
layout_name: "gl503",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -590,7 +689,7 @@
layout_name: "gl503",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -599,7 +698,7 @@
layout_name: "gl503",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4, Logo, BarLeft, BarRight],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -617,7 +716,7 @@
layout_name: "g533q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -626,7 +725,7 @@
layout_name: "gl503",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -635,7 +734,7 @@
layout_name: "fa507",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -683,6 +782,15 @@
advanced_type: Zoned([SingleZone]),
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",
product_id: "",
@@ -698,7 +806,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -707,7 +815,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -716,7 +824,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -725,7 +833,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -743,7 +851,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -761,7 +869,7 @@
layout_name: "gx531-per-key",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [Key1, Key2, Key3, Key4],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -815,7 +923,7 @@
layout_name: "gx531-per-key",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -824,7 +932,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -833,7 +941,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -842,8 +950,8 @@
layout_name: "",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: None,
power_zones: [None],
advanced_type: r#None,
power_zones: [r#None],
),
(
device_name: "GZ301Z",
@@ -851,7 +959,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Keyboard],
),
(
@@ -860,7 +968,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Ally],
),
(
@@ -869,7 +977,7 @@
layout_name: "ga401q",
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
basic_zones: [],
advanced_type: None,
advanced_type: r#None,
power_zones: [Ally],
),
])

View File

@@ -0,0 +1,375 @@
(
locale: "US",
key_shapes: {
"regular": Led(
width: 1.0,
height: 1.0,
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
),
"regular_spacing": Blank(
width: 1.2,
height: 0.0,
),
"rog_row": Led(
width: 1.0,
height: 0.7,
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.6,
),
"rog_row_blocking": Blank(
width: 1.2,
height: 0.0,
),
"func_space": Blank(
width: 0.6,
height: 0.0,
),
"backspace": Led(
width: 2.2,
height: 1.0,
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
),
"tab": Led(
width: 1.6,
height: 1.0,
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
),
"backslash": Led(
width: 1.6,
height: 1.0,
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
),
"capsplonk": Led(
width: 2.0,
height: 1.0,
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
),
"return": Led(
width: 2.4,
height: 1.0,
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
),
"lshift": Led(
width: 2.6,
height: 1.0,
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
),
"rshift": Led(
width: 3.0,
height: 1.0,
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
),
"lctrl": Led(
width: 1.4,
height: 1.0,
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
),
"spacebar": Led(
width: 5.8,
height: 1.0,
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
),
"rctrl": Led(
width: 1.2,
height: 1.0,
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
),
"up_arrow": Led(
width: 0.8,
height: 0.8,
pad_left: 1.1,
pad_right: 1.1,
pad_top: 0.1,
pad_bottom: 0.1,
),
"arrows_spacer": Blank(
width: 15.0,
height: 0.0,
),
"arrows": Led(
width: 0.8,
height: 0.8,
pad_left: 0.1,
pad_right: 0.1,
pad_top: -0.1,
pad_bottom: 0.1,
),
"row_end_spacing": Blank(
width: 0.4,
height: 0.0,
),
"lid_logo": Led(
width: 2.6,
height: 1.2,
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.8,
pad_bottom: 0.0,
),
"lightbar_left": Led(
width: 0.6,
height: 3.6,
pad_left: -1.2,
pad_right: 0.2,
pad_top: -3.0,
pad_bottom: 0.3,
),
"lightbar_corner_left": Led(
width: 0.8,
height: 0.6,
pad_left: -0.6,
pad_right: 0.2,
pad_top: 0.8,
pad_bottom: 0.0,
),
"lightbar_bottom": Led(
width: 12.6,
height: 0.5,
pad_left: -0.1,
pad_right: -0.1,
pad_top: 0.8,
pad_bottom: 0.0,
),
"lightbar_corner_right": Led(
width: 0.8,
height: 0.6,
pad_left: 0.0,
pad_right: 0.2,
pad_top: 0.8,
pad_bottom: 0.0,
),
"lightbar_right": Led(
width: 0.6,
height: 3.6,
pad_left: -0.8,
pad_right: 0.2,
pad_top: -3.0,
pad_bottom: 0.3,
),
},
key_rows: [
(
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
row: [
(Blocking, "rog_row_blocking"),
(Blocking, "rog_row_blocking"),
(VolDown, "rog_row"),
(VolUp, "rog_row"),
(MicMute, "rog_row"),
(RogFan, "rog_row"),
(RogApp, "rog_row"),
],
),
(
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
row: [
(Esc, "regular"),
(Spacing, "regular_spacing"),
(F1, "regular"),
(F2, "regular"),
(F3, "regular"),
(F4, "regular"),
(Spacing, "func_space"),
(F5, "regular"),
(F6, "regular"),
(F7, "regular"),
(F8, "regular"),
(Spacing, "func_space"),
(F9, "regular"),
(F10, "regular"),
(F11, "regular"),
(F12, "regular"),
(Spacing, "row_end_spacing"),
(Del, "regular"), // Should be super/insert
],
),
(
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
row: [
(Tilde, "regular"),
(N1, "regular"),
(N2, "regular"),
(N3, "regular"),
(N4, "regular"),
(N5, "regular"),
(N6, "regular"),
(N7, "regular"),
(N8, "regular"),
(N9, "regular"),
(N0, "regular"),
(Hyphen, "regular"),
(Equals, "regular"),
(Backspace, "backspace"),
(Spacing, "row_end_spacing"),
(MediaPlay, "regular"),
],
),
(
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
row: [
(Tab, "tab"),
(Q, "regular"),
(W, "regular"),
(E, "regular"),
(R, "regular"),
(T, "regular"),
(Y, "regular"),
(U, "regular"),
(I, "regular"),
(O, "regular"),
(P, "regular"),
(LBracket, "regular"),
(RBracket, "regular"),
(BackSlash, "backslash"),
(Spacing, "row_end_spacing"),
(MediaStop, "regular"),
],
),
(
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
row: [
(Caps, "capsplonk"),
(A, "regular"),
(S, "regular"),
(D, "regular"),
(F, "regular"),
(G, "regular"),
(H, "regular"),
(J, "regular"),
(K, "regular"),
(L, "regular"),
(SemiColon, "regular"),
(Quote, "regular"),
(Return, "return"),
(Spacing, "row_end_spacing"),
(MediaNext, "regular"),
],
),
(
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
row: [
(LShift, "lshift"),
(Z, "regular"),
(X, "regular"),
(C, "regular"),
(V, "regular"),
(B, "regular"),
(N, "regular"),
(M, "regular"),
(Comma, "regular"),
(Period, "regular"),
(FwdSlash, "regular"),
(Rshift, "rshift"),
(Spacing, "row_end_spacing"),
(MediaPrev, "regular"),
],
),
(
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
row: [
(LCtrl, "lctrl"),
(LFn, "regular"),
(Meta, "regular"),
(LAlt, "regular"),
(Spacebar, "spacebar"),
(RAlt, "regular"),
(PrtSc, "regular"),
(RCtrl, "rctrl"),
(Up, "up_arrow"),
(Spacing, "row_end_spacing"),
(PrtSc, "regular"),
],
),
(
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
row: [
(Spacing, "arrows_spacer"),
(Left, "arrows"),
(Down, "arrows"),
(Right, "arrows"),
],
),
(
pad_left: 6.5,
pad_right: 6.5,
pad_top: 0.2,
pad_bottom: 0.1,
row: [
(LidLogo, "lid_logo"),
],
),
(
pad_left: 0.1,
pad_right: 0.1,
pad_top: 0.1,
pad_bottom: 0.1,
row: [
(LightbarLeft, "lightbar_left"),
(LightbarLeftCorner, "lightbar_corner_left"),
(LightbarLeftBottom, "lightbar_bottom"),
(LightbarRightBottom, "lightbar_bottom"),
(LightbarRightCorner, "lightbar_corner_right"),
(LightbarRight, "lightbar_right"),
],
),
],
)

View File

@@ -164,6 +164,25 @@ impl LedSupportFile {
return Some(data);
}
// If the system-wide files were not found (typical in CI or
// development environments), attempt to load the bundled
// `data/aura_support.ron` from the crate so tests and local runs
// behave the same as when the package is installed.
// Attempt to load a bundled `aura_support.ron` included at compile time.
// Using `include_str!` ensures the data is available regardless of
// runtime `CARGO_MANIFEST_DIR` or CI environment differences.
let bundled_buf = include_str!("../data/aura_support.ron");
if !bundled_buf.is_empty() {
if let Ok(tmp) = ron::from_str::<LedSupportFile>(bundled_buf) {
data.0.append(&mut tmp.0.clone());
data.0.sort_by(|a, b| a.device_name.cmp(&b.device_name));
info!("Loaded bundled LED support data (embedded)");
return Some(data);
} else {
warn!("Could not parse embedded bundled data file");
}
}
warn!("Does {} exist?", ASUS_LED_MODE_USER_CONF);
None
}

View File

@@ -359,6 +359,12 @@ impl From<AuraEffect> for AuraModeNum {
}
}
#[cfg(feature = "dbus")]
impl zbus::zvariant::Basic for AuraModeNum {
const SIGNATURE_CHAR: char = 'u';
const SIGNATURE_STR: &'static str = "u";
}
/// Base effects have no zoning, while multizone is 1-4
#[cfg_attr(
feature = "dbus",

View File

@@ -207,12 +207,14 @@ mod tests {
fn single_key_next_state_then_create() {
let layout = KeyLayout::default_layout();
let mut seq = AdvancedEffects::new(false);
seq.effects
.push(Effect::Static(Static::new(LedCode::F, Colour {
seq.effects.push(Effect::Static(Static::new(
LedCode::F,
Colour {
r: 255,
g: 127,
b: 0,
})));
},
)));
seq.next_state(&layout);
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),
)]),
key_rows: vec![
KeyRow::new(0.1, 0.1, vec![
(LedCode::Esc, "regular".to_owned()),
(LedCode::F1, "regular".to_owned()),
(LedCode::F2, "regular".to_owned()),
(LedCode::F3, "regular".to_owned()),
(LedCode::F4, "regular".to_owned()),
// not sure which key to put here
(LedCode::F5, "regular".to_owned()),
(LedCode::F6, "regular".to_owned()),
(LedCode::F7, "regular".to_owned()),
(LedCode::F8, "regular".to_owned()),
(LedCode::F9, "regular".to_owned()),
(LedCode::F10, "regular".to_owned()),
(LedCode::F11, "regular".to_owned()),
(LedCode::F12, "regular".to_owned()),
]),
KeyRow::new(0.1, 0.1, vec![
(LedCode::Tilde, "regular".to_owned()),
(LedCode::N1, "regular".to_owned()),
(LedCode::N2, "regular".to_owned()),
(LedCode::N3, "regular".to_owned()),
(LedCode::N4, "regular".to_owned()),
(LedCode::N5, "regular".to_owned()),
(LedCode::N6, "regular".to_owned()),
(LedCode::N7, "regular".to_owned()),
(LedCode::N8, "regular".to_owned()),
(LedCode::N9, "regular".to_owned()),
(LedCode::N0, "regular".to_owned()),
(LedCode::Hyphen, "regular".to_owned()),
(LedCode::Equals, "regular".to_owned()),
(LedCode::Backspace, "regular".to_owned()),
]),
KeyRow::new(0.1, 0.1, vec![
(LedCode::Tab, "regular".to_owned()),
(LedCode::Q, "regular".to_owned()),
(LedCode::W, "regular".to_owned()),
(LedCode::E, "regular".to_owned()),
(LedCode::R, "regular".to_owned()),
(LedCode::T, "regular".to_owned()),
(LedCode::Y, "regular".to_owned()),
(LedCode::U, "regular".to_owned()),
(LedCode::I, "regular".to_owned()),
(LedCode::O, "regular".to_owned()),
(LedCode::P, "regular".to_owned()),
(LedCode::LBracket, "regular".to_owned()),
(LedCode::RBracket, "regular".to_owned()),
(LedCode::BackSlash, "regular".to_owned()),
]),
KeyRow::new(0.1, 0.1, vec![
(LedCode::Caps, "regular".to_owned()),
(LedCode::A, "regular".to_owned()),
(LedCode::S, "regular".to_owned()),
(LedCode::D, "regular".to_owned()),
(LedCode::F, "regular".to_owned()),
(LedCode::G, "regular".to_owned()),
(LedCode::H, "regular".to_owned()),
(LedCode::J, "regular".to_owned()),
(LedCode::K, "regular".to_owned()),
(LedCode::L, "regular".to_owned()),
(LedCode::SemiColon, "regular".to_owned()),
(LedCode::Quote, "regular".to_owned()),
(LedCode::Return, "regular".to_owned()),
]),
KeyRow::new(0.1, 0.1, vec![
(LedCode::LShift, "regular".to_owned()),
(LedCode::Z, "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()),
]),
KeyRow::new(
0.1,
0.1,
vec![
(LedCode::Esc, "regular".to_owned()),
(LedCode::F1, "regular".to_owned()),
(LedCode::F2, "regular".to_owned()),
(LedCode::F3, "regular".to_owned()),
(LedCode::F4, "regular".to_owned()),
// not sure which key to put here
(LedCode::F5, "regular".to_owned()),
(LedCode::F6, "regular".to_owned()),
(LedCode::F7, "regular".to_owned()),
(LedCode::F8, "regular".to_owned()),
(LedCode::F9, "regular".to_owned()),
(LedCode::F10, "regular".to_owned()),
(LedCode::F11, "regular".to_owned()),
(LedCode::F12, "regular".to_owned()),
],
),
KeyRow::new(
0.1,
0.1,
vec![
(LedCode::Tilde, "regular".to_owned()),
(LedCode::N1, "regular".to_owned()),
(LedCode::N2, "regular".to_owned()),
(LedCode::N3, "regular".to_owned()),
(LedCode::N4, "regular".to_owned()),
(LedCode::N5, "regular".to_owned()),
(LedCode::N6, "regular".to_owned()),
(LedCode::N7, "regular".to_owned()),
(LedCode::N8, "regular".to_owned()),
(LedCode::N9, "regular".to_owned()),
(LedCode::N0, "regular".to_owned()),
(LedCode::Hyphen, "regular".to_owned()),
(LedCode::Equals, "regular".to_owned()),
(LedCode::Backspace, "regular".to_owned()),
],
),
KeyRow::new(
0.1,
0.1,
vec![
(LedCode::Tab, "regular".to_owned()),
(LedCode::Q, "regular".to_owned()),
(LedCode::W, "regular".to_owned()),
(LedCode::E, "regular".to_owned()),
(LedCode::R, "regular".to_owned()),
(LedCode::T, "regular".to_owned()),
(LedCode::Y, "regular".to_owned()),
(LedCode::U, "regular".to_owned()),
(LedCode::I, "regular".to_owned()),
(LedCode::O, "regular".to_owned()),
(LedCode::P, "regular".to_owned()),
(LedCode::LBracket, "regular".to_owned()),
(LedCode::RBracket, "regular".to_owned()),
(LedCode::BackSlash, "regular".to_owned()),
],
),
KeyRow::new(
0.1,
0.1,
vec![
(LedCode::Caps, "regular".to_owned()),
(LedCode::A, "regular".to_owned()),
(LedCode::S, "regular".to_owned()),
(LedCode::D, "regular".to_owned()),
(LedCode::F, "regular".to_owned()),
(LedCode::G, "regular".to_owned()),
(LedCode::H, "regular".to_owned()),
(LedCode::J, "regular".to_owned()),
(LedCode::K, "regular".to_owned()),
(LedCode::L, "regular".to_owned()),
(LedCode::SemiColon, "regular".to_owned()),
(LedCode::Quote, "regular".to_owned()),
(LedCode::Return, "regular".to_owned()),
],
),
KeyRow::new(
0.1,
0.1,
vec![
(LedCode::LShift, "regular".to_owned()),
(LedCode::Z, "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 = []
mocking = []
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"]
[dependencies]
@@ -58,3 +58,17 @@ features = [
[build-dependencies.slint-build]
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,11 +24,16 @@ use tokio::runtime::Runtime;
#[tokio::main]
async fn main() -> Result<()> {
// Ensure tracing spans are quiet by default unless user overrides
if std::env::var_os("RUST_LOG").is_none() {
std::env::set_var("RUST_LOG", "warn,tracing=error,zbus=error");
}
let mut logger = env_logger::Builder::new();
logger
.filter_level(LevelFilter::Warn)
.parse_default_env()
.target(env_logger::Target::Stdout)
.filter_level(LevelFilter::Info)
.parse_default_env()
.target(env_logger::Target::Stderr)
.format_timestamp(None)
.init();

View File

@@ -9,15 +9,11 @@ use std::process::Command;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use futures_util::StreamExt;
use log::{debug, error, info, warn};
use notify_rust::{Hint, Notification, Timeout, Urgency};
use rog_platform::platform::GpuMode;
use notify_rust::{Hint, Notification, Timeout};
use rog_platform::power::AsusPower;
use serde::{Deserialize, Serialize};
use supergfxctl::actions::UserActionRequired as GfxUserAction;
use supergfxctl::pci_device::{GfxMode, GfxPower};
use supergfxctl::zbus_proxy::DaemonProxy as SuperProxy;
use supergfxctl::pci_device::GfxPower;
use tokio::runtime::Runtime;
use tokio::task::JoinHandle;
@@ -116,26 +112,26 @@ pub fn start_notifications(
if p == 0 && p != last_state {
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]);
for arg in prog.iter().skip(1) {
cmd.arg(*arg);
}
cmd.spawn()
.map_err(|e| error!("AC command error: {e:?}"))
.map_err(|e| error!("Battery power command error: {e:?}"))
.ok();
}
} else if p != last_state {
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]);
for arg in prog.iter().skip(1) {
cmd.arg(*arg);
}
cmd.spawn()
.map_err(|e| error!("AC command error: {e:?}"))
.map_err(|e| error!("AC power command error: {e:?}"))
.ok();
}
}
@@ -145,12 +141,8 @@ pub fn start_notifications(
}
});
let enabled_notifications_copy = config.clone();
let no_supergfx = move |e: &zbus::Error| {
error!("zbus signal: receive_notify_gfx_status: {e}");
warn!("Attempting to start plain dgpu status monitor");
start_dpu_status_mon(enabled_notifications_copy.clone());
};
info!("Attempting to start plain dgpu status monitor");
start_dpu_status_mon(config.clone());
// GPU MUX Mode notif
// TODO: need to get armoury attrs and iter to find
@@ -189,87 +181,9 @@ pub fn start_notifications(
// Ok::<(), zbus::Error>(())
// });
let enabled_notifications_copy = config.clone();
// GPU Mode change/action notif
tokio::spawn(async move {
let conn = zbus::Connection::system().await.inspect_err(|e| {
no_supergfx(e);
})?;
let proxy = SuperProxy::builder(&conn).build().await.inspect_err(|e| {
no_supergfx(e);
})?;
let _ = proxy.mode().await.inspect_err(|e| {
no_supergfx(e);
})?;
let proxy_copy = proxy.clone();
let mut p = proxy.receive_notify_action().await?;
tokio::spawn(async move {
info!("Started zbus signal thread: receive_notify_action");
while let Some(e) = p.next().await {
if let Ok(out) = e.args() {
let action = out.action();
let mode = convert_gfx_mode(proxy.mode().await.unwrap_or_default());
match action {
supergfxctl::actions::UserActionRequired::Reboot => {
do_mux_notification("Graphics mode change requires reboot", &mode)
}
_ => do_gfx_action_notif(<&str>::from(action), *action, mode),
}
.map_err(|e| {
error!("zbus signal: do_gfx_action_notif: {e}");
e
})
.ok();
}
}
});
let mut p = proxy_copy.receive_notify_gfx_status().await?;
tokio::spawn(async move {
info!("Started zbus signal thread: receive_notify_gfx_status");
let mut last_status = GfxPower::Unknown;
while let Some(e) = p.next().await {
if let Ok(out) = e.args() {
let status = out.status;
if status != GfxPower::Unknown && status != last_status {
if let Ok(config) = enabled_notifications_copy.lock() {
if !config.notifications.receive_notify_gfx_status
|| !config.notifications.enabled
{
continue;
}
}
// Required check because status cycles through
// active/unknown/suspended
do_gpu_status_notif("dGPU status changed:", &status)
.show_async()
.await
.unwrap()
.on_close(|_| ());
}
last_status = status;
}
}
});
Ok::<(), zbus::Error>(())
});
Ok(vec![blocking])
}
fn convert_gfx_mode(gfx: GfxMode) -> GpuMode {
match gfx {
GfxMode::Hybrid => GpuMode::Optimus,
GfxMode::Integrated => GpuMode::Integrated,
GfxMode::NvidiaNoModeset => GpuMode::Optimus,
GfxMode::Vfio => GpuMode::Vfio,
GfxMode::AsusEgpu => GpuMode::Egpu,
GfxMode::AsusMuxDgpu => GpuMode::Ultimate,
GfxMode::None => GpuMode::Error,
}
}
fn base_notification<T>(message: &str, data: &T) -> Notification
where
T: Display,
@@ -295,95 +209,3 @@ fn do_gpu_status_notif(message: &str, data: &GfxPower) -> Notification {
notif.icon(icon);
notif
}
fn do_gfx_action_notif(message: &str, action: GfxUserAction, mode: GpuMode) -> Result<()> {
if matches!(action, GfxUserAction::Reboot) {
do_mux_notification("Graphics mode change requires reboot", &mode).ok();
return Ok(());
}
let mut notif = Notification::new();
notif
.appname(NOTIF_HEADER)
.summary(&format!("Changing to {mode}. {message}"))
//.hint(Hint::Resident(true))
.hint(Hint::Category("device".into()))
.urgency(Urgency::Critical)
.timeout(Timeout::Never)
.icon("dialog-warning")
.hint(Hint::Transient(true));
if matches!(action, GfxUserAction::Logout) {
notif.action("gfx-mode-session-action", "Logout");
let handle = notif.show()?;
if let Ok(desktop) = std::env::var("XDG_CURRENT_DESKTOP") {
if desktop.to_lowercase() == "gnome" {
handle.wait_for_action(|id| {
if id == "gfx-mode-session-action" {
let mut cmd = Command::new("gnome-session-quit");
cmd.spawn().ok();
} else if id == "__closed" {
// TODO: cancel the switching
}
});
} else if desktop.to_lowercase() == "kde" {
handle.wait_for_action(|id| {
if id == "gfx-mode-session-action" {
let mut cmd = Command::new("qdbus");
cmd.args([
"org.kde.ksmserver", "/KSMServer", "logout", "1", "0", "0",
]);
cmd.spawn().ok();
} else if id == "__closed" {
// TODO: cancel the switching
}
});
} else {
// todo: handle alternatives
}
}
} else {
notif.show()?;
}
Ok(())
}
/// Actual `GpuMode` unused as data is never correct until switched by reboot
fn do_mux_notification(message: &str, m: &GpuMode) -> Result<()> {
let mut notif = base_notification(message, &m.to_string());
notif
.action("gfx-mode-session-action", "Reboot")
.urgency(Urgency::Critical)
.icon("system-reboot-symbolic")
.hint(Hint::Transient(true));
let handle = notif.show()?;
std::thread::spawn(|| {
if let Ok(desktop) = std::env::var("XDG_CURRENT_DESKTOP") {
if desktop.to_lowercase() == "gnome" {
handle.wait_for_action(|id| {
if id == "gfx-mode-session-action" {
let mut cmd = Command::new("gnome-session-quit");
cmd.arg("--reboot");
cmd.spawn().ok();
} else if id == "__closed" {
// TODO: cancel the switching
}
});
} else if desktop.to_lowercase() == "kde" {
handle.wait_for_action(|id| {
if id == "gfx-mode-session-action" {
let mut cmd = Command::new("qdbus");
cmd.args([
"org.kde.ksmserver", "/KSMServer", "logout", "1", "1", "0",
]);
cmd.spawn().ok();
} else if id == "__closed" {
// TODO: cancel the switching
}
});
}
}
});
Ok(())
}

View File

@@ -170,7 +170,7 @@ pub fn init_tray(_supported_properties: Vec<Properties>, config: Arc<Mutex<Confi
// TODO: return an error to the UI
let mut tray;
match tray_init.spawn_without_dbus_name().await {
match tray_init.disable_dbus_name(true).spawn().await {
Ok(t) => tray = t,
Err(e) => {
log::error!(

View File

@@ -168,15 +168,24 @@ pub fn setup_fan_curve_page(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
update_fan_data(handle, balanced, perf, quiet);
let choices_for_ui = platform_profile_choices.clone();
let handle_next1 = handle_copy.clone();
if let Err(e) = handle_copy.upgrade_in_event_loop(move |handle| {
let global = handle.global::<FanPageData>();
let fans1 = fans.clone();
let choices = choices_for_ui.clone();
global.on_set_profile_default(move |profile| {
let fans = fans1.clone();
let handle_next = handle_next1.clone();
let choices = choices.clone();
tokio::spawn(async move {
if fans.set_curves_to_defaults(profile.into()).await.is_err() {
let mut target: PlatformProfile = profile.into();
if target == PlatformProfile::Quiet
&& !choices.contains(&PlatformProfile::Quiet)
{
target = PlatformProfile::LowPower;
}
if fans.set_curves_to_defaults(target).await.is_err() {
return;
}
let Ok(balanced) = fans

View File

@@ -12,7 +12,7 @@ use slint::{ComponentHandle, Model, ModelRc, SharedString, VecModel};
use super::show_toast;
use crate::config::Config;
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 {
min: 0,
@@ -40,6 +40,12 @@ pub fn setup_system_page(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
ui.global::<SystemPageData>().set_platform_profile(-1);
ui.global::<SystemPageData>().set_panel_overdrive(-1);
ui.global::<SystemPageData>().set_boot_sound(-1);
ui.global::<SystemPageData>().set_kbd_leds_awake(-1);
ui.global::<SystemPageData>().set_kbd_leds_sleep(-1);
ui.global::<SystemPageData>().set_kbd_leds_boot(-1);
ui.global::<SystemPageData>().set_kbd_leds_shutdown(-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_screenpad_brightness(-1);
ui.global::<SystemPageData>().set_ppt_pl1_spl(MINMAX);
@@ -308,6 +314,7 @@ pub fn setup_system_page_callbacks(ui: &MainWindow, _states: Arc<Mutex<Config>>)
let platform_copy = platform.clone();
if let Ok(mut value) = platform.platform_profile_choices().await {
debug!("Available platform profile choices: {:?}", value);
handle
.upgrade_in_event_loop(move |handle| {
value.sort();
@@ -519,7 +526,7 @@ pub fn setup_system_page_callbacks(ui: &MainWindow, _states: Arc<Mutex<Config>>)
set_ui_callbacks!(handle,
SystemPageData(as i32),
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"
);
set_ui_callbacks!(handle,
@@ -572,120 +579,152 @@ pub fn setup_system_page_callbacks(ui: &MainWindow, _states: Arc<Mutex<Config>>)
for attr in armoury_attrs {
if let Ok(value) = attr.current_value().await {
let name = attr.name().await.unwrap();
debug!("Setting up {} = {value}", <&str>::from(name));
let platform = platform.clone();
handle
.upgrade_in_event_loop(move |handle| match name {
FirmwareAttribute::ApuMem => {}
FirmwareAttribute::CoresPerformance => {}
FirmwareAttribute::CoresEfficiency => {}
FirmwareAttribute::PptEnabled => {
init_property!(ppt_enabled, handle, value, bool);
setup_callback!(ppt_enabled, handle, attr, bool);
let handle_copy = handle.as_weak();
let proxy_copy = attr.clone();
tokio::spawn(async move {
let mut x = proxy_copy.receive_current_value_changed().await;
use futures_util::StreamExt;
while let Some(e) = x.next().await {
if let Ok(out) = e.get().await {
handle_copy
.upgrade_in_event_loop(move |handle| {
handle
.global::<SystemPageData>()
.set_enable_ppt_group(out == 1);
handle
.global::<SystemPageData>()
.set_ppt_enabled(out == 1);
})
.ok();
if let Ok(name) = attr.name().await {
debug!("Setting up {} = {value}", <&str>::from(name));
let platform = platform.clone();
handle
.upgrade_in_event_loop(move |handle| match name {
FirmwareAttribute::ApuMem => {}
FirmwareAttribute::CoresPerformance => {}
FirmwareAttribute::CoresEfficiency => {}
FirmwareAttribute::PptEnabled => {
init_property!(ppt_enabled, handle, value, bool);
setup_callback!(ppt_enabled, handle, attr, bool);
let handle_copy = handle.as_weak();
let proxy_copy = attr.clone();
tokio::spawn(async move {
let mut x = proxy_copy.receive_current_value_changed().await;
use futures_util::StreamExt;
while let Some(e) = x.next().await {
if let Ok(out) = e.get().await {
handle_copy
.upgrade_in_event_loop(move |handle| {
handle
.global::<SystemPageData>()
.set_enable_ppt_group(out == 1);
handle
.global::<SystemPageData>()
.set_ppt_enabled(out == 1);
})
.ok();
}
}
}
});
handle
.global::<SystemPageData>()
.set_ppt_enabled_available(true);
handle
.global::<SystemPageData>()
.set_enable_ppt_group(value == 1);
}
FirmwareAttribute::PptPl1Spl => {
init_minmax_property!(ppt_pl1_spl, handle, attr);
setup_callback!(ppt_pl1_spl, handle, attr, i32);
setup_callback_restore_default!(ppt_pl1_spl, handle, attr);
setup_minmax_external!(ppt_pl1_spl, handle, attr, platform);
}
FirmwareAttribute::PptPl2Sppt => {
init_minmax_property!(ppt_pl2_sppt, handle, attr);
setup_callback!(ppt_pl2_sppt, handle, attr, i32);
setup_callback_restore_default!(ppt_pl2_sppt, handle, attr);
setup_minmax_external!(ppt_pl2_sppt, handle, attr, platform);
}
FirmwareAttribute::PptPl3Fppt => {
init_minmax_property!(ppt_pl3_fppt, handle, attr);
setup_callback!(ppt_pl3_fppt, handle, attr, i32);
setup_callback_restore_default!(ppt_pl3_fppt, handle, attr);
setup_minmax_external!(ppt_pl3_fppt, handle, attr, platform);
}
FirmwareAttribute::PptFppt => {
init_minmax_property!(ppt_fppt, handle, attr);
setup_callback!(ppt_fppt, handle, attr, i32);
setup_callback_restore_default!(ppt_fppt, handle, attr);
setup_minmax_external!(ppt_fppt, handle, attr, platform);
}
FirmwareAttribute::PptApuSppt => {
init_minmax_property!(ppt_apu_sppt, handle, attr);
setup_callback!(ppt_apu_sppt, handle, attr, i32);
setup_callback_restore_default!(ppt_apu_sppt, handle, attr);
setup_minmax_external!(ppt_apu_sppt, handle, attr, platform);
}
FirmwareAttribute::PptPlatformSppt => {
init_minmax_property!(ppt_platform_sppt, handle, attr);
setup_callback!(ppt_platform_sppt, handle, attr, i32);
setup_callback_restore_default!(ppt_platform_sppt, handle, attr);
setup_minmax_external!(ppt_platform_sppt, handle, attr, platform);
}
FirmwareAttribute::NvDynamicBoost => {
init_minmax_property!(nv_dynamic_boost, handle, attr);
setup_callback!(nv_dynamic_boost, handle, attr, i32);
setup_callback_restore_default!(nv_dynamic_boost, handle, attr);
setup_minmax_external!(nv_dynamic_boost, handle, attr, platform);
}
FirmwareAttribute::NvTempTarget => {
init_minmax_property!(nv_temp_target, handle, attr);
setup_callback!(nv_temp_target, handle, attr, i32);
setup_callback_restore_default!(nv_temp_target, handle, attr);
setup_minmax_external!(nv_temp_target, handle, attr, platform);
}
FirmwareAttribute::DgpuBaseTgp => {}
FirmwareAttribute::DgpuTgp => {}
FirmwareAttribute::ChargeMode => {}
FirmwareAttribute::BootSound => {
init_property!(boot_sound, handle, value, i32);
setup_callback!(boot_sound, handle, attr, i32);
setup_external!(boot_sound, i32, handle, attr, value)
}
FirmwareAttribute::McuPowersave => {}
FirmwareAttribute::PanelOverdrive => {
init_property!(panel_overdrive, handle, value, i32);
setup_callback!(panel_overdrive, handle, attr, i32);
setup_external!(panel_overdrive, i32, handle, attr, value)
}
FirmwareAttribute::PanelHdMode => {}
FirmwareAttribute::EgpuConnected => {}
FirmwareAttribute::EgpuEnable => {}
FirmwareAttribute::DgpuDisable => {}
FirmwareAttribute::GpuMuxMode => {}
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();
});
handle
.global::<SystemPageData>()
.set_ppt_enabled_available(true);
handle
.global::<SystemPageData>()
.set_enable_ppt_group(value == 1);
}
FirmwareAttribute::PptPl1Spl => {
init_minmax_property!(ppt_pl1_spl, handle, attr);
setup_callback!(ppt_pl1_spl, handle, attr, i32);
setup_callback_restore_default!(ppt_pl1_spl, handle, attr);
setup_minmax_external!(ppt_pl1_spl, handle, attr, platform);
}
FirmwareAttribute::PptPl2Sppt => {
init_minmax_property!(ppt_pl2_sppt, handle, attr);
setup_callback!(ppt_pl2_sppt, handle, attr, i32);
setup_callback_restore_default!(ppt_pl2_sppt, handle, attr);
setup_minmax_external!(ppt_pl2_sppt, handle, attr, platform);
}
FirmwareAttribute::PptPl3Fppt => {
init_minmax_property!(ppt_pl3_fppt, handle, attr);
setup_callback!(ppt_pl3_fppt, handle, attr, i32);
setup_callback_restore_default!(ppt_pl3_fppt, handle, attr);
setup_minmax_external!(ppt_pl3_fppt, handle, attr, platform);
}
FirmwareAttribute::PptFppt => {
init_minmax_property!(ppt_fppt, handle, attr);
setup_callback!(ppt_fppt, handle, attr, i32);
setup_callback_restore_default!(ppt_fppt, handle, attr);
setup_minmax_external!(ppt_fppt, handle, attr, platform);
}
FirmwareAttribute::PptApuSppt => {
init_minmax_property!(ppt_apu_sppt, handle, attr);
setup_callback!(ppt_apu_sppt, handle, attr, i32);
setup_callback_restore_default!(ppt_apu_sppt, handle, attr);
setup_minmax_external!(ppt_apu_sppt, handle, attr, platform);
}
FirmwareAttribute::PptPlatformSppt => {
init_minmax_property!(ppt_platform_sppt, handle, attr);
setup_callback!(ppt_platform_sppt, handle, attr, i32);
setup_callback_restore_default!(ppt_platform_sppt, handle, attr);
setup_minmax_external!(ppt_platform_sppt, handle, attr, platform);
}
FirmwareAttribute::NvDynamicBoost => {
init_minmax_property!(nv_dynamic_boost, handle, attr);
setup_callback!(nv_dynamic_boost, handle, attr, i32);
setup_callback_restore_default!(nv_dynamic_boost, handle, attr);
setup_minmax_external!(nv_dynamic_boost, handle, attr, platform);
}
FirmwareAttribute::NvTempTarget => {
init_minmax_property!(nv_temp_target, handle, attr);
setup_callback!(nv_temp_target, handle, attr, i32);
setup_callback_restore_default!(nv_temp_target, handle, attr);
setup_minmax_external!(nv_temp_target, handle, attr, platform);
}
FirmwareAttribute::DgpuBaseTgp => {}
FirmwareAttribute::DgpuTgp => {}
FirmwareAttribute::ChargeMode => {}
FirmwareAttribute::BootSound => {
init_property!(boot_sound, handle, value, i32);
setup_callback!(boot_sound, handle, attr, i32);
setup_external!(boot_sound, i32, handle, attr, value)
}
FirmwareAttribute::KbdLedsAwake => {
init_property!(kbd_leds_awake, handle, value, i32);
setup_callback!(kbd_leds_awake, handle, attr, i32);
setup_external!(kbd_leds_awake, i32, handle, attr, value)
}
FirmwareAttribute::KbdLedsSleep => {
init_property!(kbd_leds_sleep, handle, value, i32);
setup_callback!(kbd_leds_sleep, handle, attr, i32);
setup_external!(kbd_leds_sleep, i32, handle, attr, value)
}
FirmwareAttribute::KbdLedsBoot => {
init_property!(kbd_leds_boot, handle, value, i32);
setup_callback!(kbd_leds_boot, handle, attr, i32);
setup_external!(kbd_leds_boot, i32, handle, attr, value)
}
FirmwareAttribute::KbdLedsShutdown => {
init_property!(kbd_leds_shutdown, handle, value, i32);
setup_callback!(kbd_leds_shutdown, handle, attr, i32);
setup_external!(kbd_leds_shutdown, i32, handle, attr, value)
}
FirmwareAttribute::ScreenAutoBrightness => {
init_property!(screen_auto_brightness, handle, value, i32);
setup_callback!(screen_auto_brightness, handle, attr, i32);
setup_external!(screen_auto_brightness, i32, handle, attr, value)
}
FirmwareAttribute::McuPowersave => {
init_property!(mcu_powersave, handle, value, i32);
setup_callback!(mcu_powersave, handle, attr, i32);
setup_external!(mcu_powersave, i32, handle, attr, value)
}
FirmwareAttribute::PanelOverdrive => {
init_property!(panel_overdrive, handle, value, i32);
setup_callback!(panel_overdrive, handle, attr, i32);
setup_external!(panel_overdrive, i32, handle, attr, value)
}
FirmwareAttribute::PanelHdMode => {}
FirmwareAttribute::EgpuConnected => {}
FirmwareAttribute::EgpuEnable => {}
FirmwareAttribute::DgpuDisable => {}
FirmwareAttribute::GpuMuxMode => {}
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

View File

@@ -89,7 +89,7 @@ where
}
}
if paths.len() > 1 {
println!("Multiple asusd interfaces devices found");
log::warn!("Multiple asusd interfaces devices found");
}
if !paths.is_empty() {
let mut ctrl = Vec::new();
@@ -129,7 +129,7 @@ where
}
}
if paths.len() > 1 {
println!("Multiple asusd interfaces devices found");
log::warn!("Multiple asusd interfaces devices found");
}
if !paths.is_empty() {
let mut ctrl = Vec::new();

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

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

View File

@@ -37,7 +37,8 @@ export component PageAnime inherits Rectangle {
property <bool> show_builtin_advanced: false;
clip: true;
// 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;
// TODO: border-radius: 8px;
VerticalLayout {

View File

@@ -16,7 +16,9 @@ export component PageAppSettings inherits VerticalLayout {
Rectangle {
clip: true;
// 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;
// TODO: border-radius: 8px;
mainview := VerticalLayout {

View File

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

View File

@@ -51,6 +51,18 @@ export global SystemPageData {
callback cb_panel_overdrive(int);
in-out property <int> boot_sound;
callback cb_boot_sound(int);
in-out property <int> kbd_leds_awake;
callback cb_kbd_leds_awake(int);
in-out property <int> kbd_leds_sleep;
callback cb_kbd_leds_sleep(int);
in-out property <int> kbd_leds_boot;
callback cb_kbd_leds_boot(int);
in-out property <int> kbd_leds_shutdown;
callback cb_kbd_leds_shutdown(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;
callback cb_mini_led_mode(int);
@@ -140,7 +152,8 @@ export component PageSystem inherits Rectangle {
property <bool> show_fade_cover: false;
property <bool> show_throttle_advanced: false;
clip: true;
padding: 8px;
//padding only has effect on layout elements
//padding: 8px;
ScrollView {
VerticalLayout {
padding: 10px;
@@ -273,6 +286,44 @@ export component PageSystem inherits Rectangle {
}
}
GroupBox {
title: @tr("Keyboard Power Management");
HorizontalLayout {
spacing: 10px;
if SystemPageData.kbd_leds_awake != -1: SystemToggleInt {
text: @tr("Keyboard Awake Effect");
checked_int <=> SystemPageData.kbd_leds_awake;
toggled => {
SystemPageData.cb_kbd_leds_awake(SystemPageData.kbd_leds_awake)
}
}
if SystemPageData.kbd_leds_sleep != -1: SystemToggleInt {
text: @tr("Keyboard Sleep Effect");
checked_int <=> SystemPageData.kbd_leds_sleep;
toggled => {
SystemPageData.cb_kbd_leds_sleep(SystemPageData.kbd_leds_sleep)
}
}
if SystemPageData.kbd_leds_boot != -1: SystemToggleInt {
text: @tr("Keyboard Boot Effect");
checked_int <=> SystemPageData.kbd_leds_boot;
toggled => {
SystemPageData.cb_kbd_leds_boot(SystemPageData.kbd_leds_boot)
}
}
if SystemPageData.kbd_leds_shutdown != -1: SystemToggleInt {
text: @tr("Keyboard Shutdown Effect");
checked_int <=> SystemPageData.kbd_leds_shutdown;
toggled => {
SystemPageData.cb_kbd_leds_shutdown(SystemPageData.kbd_leds_shutdown)
}
}
}
}
HorizontalBox {
padding: 0px;
spacing: 10px;
@@ -299,9 +350,25 @@ export component PageSystem inherits Rectangle {
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-left: 10px;
alignment: LayoutAlignment.space-between;
@@ -330,7 +397,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");
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.");
@@ -348,7 +415,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");
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.");
@@ -366,7 +433,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");
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.");
@@ -383,7 +450,7 @@ export component PageSystem inherits Rectangle {
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");
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.");
@@ -401,7 +468,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");
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.");
@@ -419,7 +486,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");
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.");
@@ -437,7 +504,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");
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.");
@@ -455,7 +522,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");
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.");

View File

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

View File

@@ -124,6 +124,22 @@ impl Attribute {
&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*
/// change, if they do then it is possibly a driver issue - although this is
/// subject to `firmware_attributes` class changes in kernel.
@@ -256,10 +272,33 @@ macro_rules! define_attribute_getters {
}
define_attribute_getters!(
apu_mem, cores_performance, cores_efficiency, ppt_pl1_spl, ppt_pl2_sppt, ppt_apu_sppt,
ppt_platform_sppt, ppt_fppt, nv_dynamic_boost, nv_temp_target, dgpu_base_tgp, dgpu_tgp,
charge_mode, boot_sound, mcu_powersave, panel_od, panel_hd_mode, egpu_connected, egpu_enable,
dgpu_disable, gpu_mux_mode, mini_led_mode
apu_mem,
cores_performance,
cores_efficiency,
ppt_pl1_spl,
ppt_pl2_sppt,
ppt_apu_sppt,
ppt_platform_sppt,
ppt_fppt,
nv_dynamic_boost,
nv_temp_target,
dgpu_base_tgp,
dgpu_tgp,
charge_mode,
boot_sound,
kbd_leds_awake,
kbd_leds_sleep,
kbd_leds_boot,
kbd_leds_shutdown,
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
@@ -306,6 +345,11 @@ pub enum FirmwareAttribute {
PendingReboot = 23,
PptEnabled = 24,
None = 25,
ScreenAutoBrightness = 26,
KbdLedsAwake = 27,
KbdLedsSleep = 28,
KbdLedsBoot = 29,
KbdLedsShutdown = 30,
}
impl FirmwareAttribute {
@@ -347,9 +391,13 @@ impl From<&str> for FirmwareAttribute {
"nv_dynamic_boost" => Self::NvDynamicBoost,
"nv_temp_target" => Self::NvTempTarget,
"nv_base_tgp" => Self::DgpuBaseTgp,
"dgpu_tgp" => Self::DgpuTgp,
"nv_tgp" => Self::DgpuTgp,
"charge_mode" => Self::ChargeMode,
"boot_sound" => Self::BootSound,
"kbd_leds_awake" => Self::KbdLedsAwake,
"kbd_leds_sleep" => Self::KbdLedsSleep,
"kbd_leds_boot" => Self::KbdLedsBoot,
"kbd_leds_shutdown" => Self::KbdLedsShutdown,
"mcu_powersave" => Self::McuPowersave,
"panel_overdrive" => Self::PanelOverdrive,
"panel_hd_mode" => Self::PanelHdMode,
@@ -359,6 +407,7 @@ impl From<&str> for FirmwareAttribute {
"gpu_mux_mode" => Self::GpuMuxMode,
"mini_led_mode" => Self::MiniLedMode,
"pending_reboot" => Self::PendingReboot,
"screen_auto_brightness" => Self::ScreenAutoBrightness,
_ => {
error!("Invalid firmware attribute: {}", s);
Self::None
@@ -383,7 +432,7 @@ impl From<FirmwareAttribute> for &str {
FirmwareAttribute::NvDynamicBoost => "nv_dynamic_boost",
FirmwareAttribute::NvTempTarget => "nv_temp_target",
FirmwareAttribute::DgpuBaseTgp => "dgpu_base_tgp",
FirmwareAttribute::DgpuTgp => "dgpu_tgp",
FirmwareAttribute::DgpuTgp => "nv_tgp",
FirmwareAttribute::ChargeMode => "charge_mode",
FirmwareAttribute::BootSound => "boot_sound",
FirmwareAttribute::McuPowersave => "mcu_powersave",
@@ -394,7 +443,12 @@ impl From<FirmwareAttribute> for &str {
FirmwareAttribute::DgpuDisable => "dgpu_disable",
FirmwareAttribute::GpuMuxMode => "gpu_mux_mode",
FirmwareAttribute::MiniLedMode => "mini_led_mode",
FirmwareAttribute::KbdLedsAwake => "kbd_leds_awake",
FirmwareAttribute::KbdLedsSleep => "kbd_leds_sleep",
FirmwareAttribute::KbdLedsBoot => "kbd_leds_boot",
FirmwareAttribute::KbdLedsShutdown => "kbd_leds_shutdown",
FirmwareAttribute::PendingReboot => "pending_reboot",
FirmwareAttribute::ScreenAutoBrightness => "screen_auto_brightness",
FirmwareAttribute::None => "none",
}
}

View File

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

View File

@@ -275,11 +275,16 @@ impl std::str::FromStr for PlatformProfile {
type Err = PlatformError;
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),
"performance" => Ok(PlatformProfile::Performance),
"quiet" => Ok(PlatformProfile::Quiet),
"low-power" => Ok(PlatformProfile::LowPower),
"lowpower" => Ok(PlatformProfile::LowPower),
"custom" => Ok(PlatformProfile::Custom),
_ => Err(PlatformError::NotSupported),
}
@@ -288,11 +293,16 @@ impl std::str::FromStr for PlatformProfile {
impl From<&str> for PlatformProfile {
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,
"performance" => PlatformProfile::Performance,
"quiet" => PlatformProfile::Quiet,
"low-power" => PlatformProfile::LowPower,
"lowpower" => PlatformProfile::LowPower,
"custom" => PlatformProfile::Custom,
_ => {
warn!("{profile} is unknown, using ThrottlePolicy::Balanced");

View File

@@ -101,8 +101,15 @@ impl AsusPower {
});
}
Err(PlatformError::MissingFunction(
"Did not find a battery".to_owned(),
))
// No battery found. Return an AsusPower with an empty battery path so
// callers can still be constructed and query `has_*` methods which
// will correctly report absence. This avoids hard-failing on systems
// where the asus-nb-wmi driver loads on desktops with no battery.
info!("Did not find a battery, continuing without battery support");
Ok(Self {
mains,
battery: PathBuf::new(),
usb,
})
}
}

View File

@@ -37,8 +37,9 @@ pub fn find_fan_curve_node() -> Result<Device, ProfileError> {
derive(Type, Value, OwnedValue),
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 {
#[default]
CPU = 0,
GPU = 1,
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
#[cfg_attr(feature = "dbus", derive(Type))]
#[derive(Deserialize, Serialize, Debug, Default)]

View File

@@ -177,6 +177,12 @@ pub enum AuraMode {
DoubleFade = 14,
}
#[cfg(feature = "dbus")]
impl zbus::zvariant::Basic for AuraMode {
const SIGNATURE_CHAR: char = 'u';
const SIGNATURE_STR: &'static str = "u";
}
impl AuraMode {
pub fn list() -> [String; 15] {
[

View File

@@ -12,9 +12,13 @@ use crate::usb::{PROD_ID1, PROD_ID1_STR, PROD_ID2, PROD_ID2_STR};
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub enum SlashType {
GA403,
GA605,
GU605,
GA403_2024,
GA403_2025,
GA605_2024,
GA605_2025,
GU605_2024,
GU605_2025,
G614_2025,
#[default]
Unsupported,
}
@@ -22,30 +26,51 @@ pub enum SlashType {
impl SlashType {
pub const fn prod_id(&self) -> u16 {
match self {
SlashType::GA403 => PROD_ID1,
SlashType::GA605 => PROD_ID2,
SlashType::GU605 => PROD_ID1,
SlashType::GA403_2025 => PROD_ID2,
SlashType::GA403_2024 => PROD_ID1,
SlashType::GA605_2025 => PROD_ID2,
SlashType::GA605_2024 => PROD_ID2,
SlashType::GU605_2025 => PROD_ID2,
SlashType::GU605_2024 => PROD_ID1,
SlashType::G614_2025 => PROD_ID2,
SlashType::Unsupported => 0,
}
}
pub const fn prod_id_str(&self) -> &str {
match self {
SlashType::GA403 => PROD_ID1_STR,
SlashType::GA605 => PROD_ID2_STR,
SlashType::GU605 => PROD_ID1_STR,
SlashType::GA403_2025 => PROD_ID2_STR,
SlashType::GA403_2024 => PROD_ID1_STR,
SlashType::GA605_2025 => PROD_ID2_STR,
SlashType::GA605_2024 => PROD_ID2_STR,
SlashType::GU605_2025 => PROD_ID2_STR,
SlashType::GU605_2024 => PROD_ID1_STR,
SlashType::G614_2025 => PROD_ID2_STR,
SlashType::Unsupported => "",
}
}
pub fn from_dmi() -> Self {
let board_name = DMIID::new().unwrap_or_default().board_name.to_uppercase();
if board_name.contains("GA403") {
SlashType::GA403
if board_name.contains("G614F") {
SlashType::G614_2025
} else if [
"GA403W", "GA403UH", "GA403UM", "GA403UP",
]
.iter()
.any(|s| board_name.contains(s))
{
SlashType::GA403_2025
} else if board_name.contains("GA403") {
SlashType::GA403_2024
} else if board_name.contains("GA605K") {
SlashType::GA605_2025
} else if board_name.contains("GA605") {
SlashType::GA605
SlashType::GA605_2024
} else if board_name.contains("GU605C") {
SlashType::GU605_2025
} else if board_name.contains("GU605") {
SlashType::GU605
SlashType::GU605_2024
} else {
SlashType::Unsupported
}
@@ -56,10 +81,14 @@ impl FromStr for SlashType {
type Err = SlashError;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
Ok(match s {
"ga403" | "GA403" => Self::GA403,
"ga605" | "GA605" => Self::GA605,
"gu605" | "GU605" => Self::GU605,
Ok(match s.to_uppercase().as_str() {
"GA403_2025" => Self::GA403_2025,
"GA403_2024" => Self::GA403_2024,
"GA605_2025" => Self::GA605_2025,
"GA605_2024" => Self::GA605_2024,
"GU605_2025" => Self::GU605_2025,
"GU605_2024" => Self::GU605_2024,
"G614_2025" => Self::G614_2025,
_ => Self::Unsupported,
})
}
@@ -68,6 +97,7 @@ impl FromStr for SlashType {
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
#[derive(Debug, Default, PartialEq, Eq, Copy, Clone, Deserialize, Serialize)]
pub enum SlashMode {
Static = 0x06,
Bounce = 0x10,
Slash = 0x12,
Loading = 0x13,
@@ -91,6 +121,7 @@ impl FromStr for SlashMode {
fn from_str(s: &str) -> Result<Self, SlashError> {
match s {
"Static" => Ok(SlashMode::Static),
"Bounce" => Ok(SlashMode::Bounce),
"Slash" => Ok(SlashMode::Slash),
"Loading" => Ok(SlashMode::Loading),
@@ -114,6 +145,7 @@ impl FromStr for SlashMode {
impl Display for SlashMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let str = match &self {
SlashMode::Static => String::from("Static"),
SlashMode::Bounce => String::from("Bounce"),
SlashMode::Slash => String::from("Slash"),
SlashMode::Loading => String::from("Loading"),
@@ -135,8 +167,9 @@ impl Display for SlashMode {
}
impl SlashMode {
pub fn list() -> [String; 15] {
pub fn list() -> [String; 16] {
[
SlashMode::Static.to_string(),
SlashMode::Bounce.to_string(),
SlashMode::Slash.to_string(),
SlashMode::Loading.to_string(),

View File

@@ -37,14 +37,26 @@ pub fn get_slash_type() -> SlashType {
let dmi = DMIID::new()
.map_err(|_| SlashError::NoDevice)
.unwrap_or_default();
let board_name = dmi.board_name;
if board_name.contains("GA403") {
SlashType::GA403
let board_name = dmi.board_name.to_uppercase();
if board_name.contains("G614F") {
SlashType::G614_2025
} else if [
"GA403W", "GA403UH", "GA403UM", "GA403UP",
]
.iter()
.any(|s| board_name.contains(s))
{
SlashType::GA403_2025
} else if board_name.contains("GA403") {
SlashType::GA403_2024
} else if board_name.contains("GA605K") {
SlashType::GA605_2025
} else if board_name.contains("GA605") {
SlashType::GA605
SlashType::GA605_2024
} else if board_name.contains("GU605C") {
SlashType::GU605_2025
} else if board_name.contains("GU605") {
SlashType::GU605
SlashType::GU605_2024
} else {
SlashType::Unsupported
}
@@ -52,9 +64,13 @@ pub fn get_slash_type() -> SlashType {
pub const fn report_id(slash_type: SlashType) -> u8 {
match slash_type {
SlashType::GA403 => REPORT_ID_193B,
SlashType::GA605 => REPORT_ID_19B6,
SlashType::GU605 => REPORT_ID_193B,
SlashType::GA403_2025 => REPORT_ID_19B6,
SlashType::GA403_2024 => REPORT_ID_193B,
SlashType::GA605_2025 => REPORT_ID_19B6,
SlashType::GA605_2024 => REPORT_ID_19B6,
SlashType::GU605_2025 => REPORT_ID_19B6,
SlashType::GU605_2024 => REPORT_ID_193B,
SlashType::G614_2025 => REPORT_ID_19B6,
SlashType::Unsupported => REPORT_ID_19B6,
}
}

View File

@@ -43,10 +43,12 @@ impl AniMatrix {
vertical: 2,
horizontal: 5,
},
AnimeType::GA402 | AnimeType::Unsupported => LedShape {
vertical: 2,
horizontal: 5,
},
AnimeType::GA402 | AnimeType::G635L | AnimeType::G835L | AnimeType::Unsupported => {
LedShape {
vertical: 2,
horizontal: 5,
}
}
AnimeType::GU604 => LedShape {
vertical: 2,
horizontal: 5,
@@ -56,7 +58,9 @@ impl AniMatrix {
// Do a hard mapping of each (derived from wireshardk captures)
let rows = match model {
AnimeType::GA401 => GA401.to_vec(),
AnimeType::GA402 | AnimeType::Unsupported => GA402.to_vec(),
AnimeType::GA402 | AnimeType::G635L | AnimeType::G835L | AnimeType::Unsupported => {
GA402.to_vec()
}
AnimeType::GU604 => GU604.to_vec(),
};

View File

@@ -157,6 +157,7 @@ fn main() -> Result<(), Box<dyn Error>> {
for (x_count, b) in dev.buffer[start..=end].iter().enumerate() {
canvas.set_draw_color(Color::RGB(*b, *b, *b));
#[allow(clippy::manual_is_multiple_of)]
let x: i32 = w + x_count as i32 * w
- if (y_count + y_offset as usize) % 2 != 0 {
0