mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Compare commits
210 Commits
6.1.1
...
remove_sup
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9c5315bda | ||
|
|
b521a9ffc1 | ||
|
|
5e48923db1 | ||
|
|
392436808d | ||
|
|
3d9a08d7e0 | ||
|
|
ff103f98af | ||
|
|
d05182ae64 | ||
|
|
a4957a6eeb | ||
|
|
dda750cf33 | ||
|
|
0b5e04393a | ||
|
|
c9c9a022a4 | ||
|
|
aa063c20fd | ||
|
|
8551908452 | ||
|
|
5ecb174b8f | ||
|
|
fa266bff5b | ||
|
|
f53f1f360f | ||
|
|
da19216b78 | ||
|
|
46efd4190f | ||
|
|
ed3022e25e | ||
|
|
7c10d6c6d9 | ||
|
|
af5f3a5c71 | ||
|
|
7d5ec5f2c7 | ||
|
|
1c8acf6de3 | ||
|
|
7b644e7ad6 | ||
|
|
0f02fe868c | ||
|
|
abd3100e30 | ||
|
|
6f651c2b85 | ||
|
|
93ec5d1bce | ||
|
|
5aea7f51c0 | ||
|
|
d03d8ce67f | ||
|
|
ae3693e0d9 | ||
|
|
c8b9248eda | ||
|
|
22098794fe | ||
|
|
10d49f4fc8 | ||
|
|
5aba2854b0 | ||
|
|
ea32ad6e0a | ||
|
|
ee0e612c04 | ||
|
|
e565ce748a | ||
|
|
7024941663 | ||
|
|
817a0165b5 | ||
|
|
efcd038f40 | ||
|
|
375d99b8fc | ||
|
|
3a206eb76f | ||
|
|
4449838282 | ||
|
|
58d740f77a | ||
|
|
f0488d9750 | ||
|
|
f1b9ae6f71 | ||
|
|
db5de3b854 | ||
|
|
7a3d39b8f1 | ||
|
|
7a5d6325c0 | ||
|
|
574b954866 | ||
|
|
a811f20f65 | ||
|
|
0c9c263be6 | ||
|
|
6571c04bfe | ||
|
|
e48acbb8a2 | ||
|
|
f33496ef68 | ||
|
|
cd3176b565 | ||
|
|
7595613d7e | ||
|
|
b8d0245e7a | ||
|
|
54bd2ec800 | ||
|
|
b6c8566565 | ||
|
|
052c096014 | ||
|
|
81cbe3c522 | ||
|
|
09f7492bec | ||
|
|
6adfb2cf48 | ||
|
|
a2a56792a8 | ||
|
|
317daf4ed1 | ||
|
|
eb0d9514b5 | ||
|
|
d324b1bce5 | ||
|
|
d1c7385146 | ||
|
|
48a4935fc7 | ||
|
|
7e917b91a5 | ||
|
|
45f8b8ffb0 | ||
|
|
031a36242b | ||
|
|
8ad26ad136 | ||
|
|
907d4694f3 | ||
|
|
1dcc4ff502 | ||
|
|
cf232047b0 | ||
|
|
ff99ec9a39 | ||
|
|
8a19374a41 | ||
|
|
4cec1f49b4 | ||
|
|
01aae200f3 | ||
|
|
4c6db9f0a9 | ||
|
|
7207d3287a | ||
|
|
1b2d8d83fc | ||
|
|
6d8db91583 | ||
|
|
20c3628476 | ||
|
|
4edecfce1c | ||
|
|
34699a7021 | ||
|
|
ef311689ec | ||
|
|
8ee0281b4f | ||
|
|
d8504b5430 | ||
|
|
5c4d833fbd | ||
|
|
698999e828 | ||
|
|
0eae9e55c6 | ||
|
|
07171888a1 | ||
|
|
9321fde6af | ||
|
|
f90d0a6673 | ||
|
|
bbd03c128d | ||
|
|
132a2f3665 | ||
|
|
180566e5f1 | ||
|
|
c9e76f3273 | ||
|
|
2997ae83ff | ||
|
|
151d681e16 | ||
|
|
90b3f43a36 | ||
|
|
a345b09ce1 | ||
|
|
f26b0d8de5 | ||
|
|
9366b0ec04 | ||
|
|
415712143b | ||
|
|
60fce30a06 | ||
|
|
d8f06230fa | ||
|
|
834464a527 | ||
|
|
4faa96298a | ||
|
|
78c574b761 | ||
|
|
9785eafd53 | ||
|
|
51cad9ea7e | ||
|
|
319373faea | ||
|
|
f6aa3e3d01 | ||
|
|
d11fc20bab | ||
|
|
b0e1b21e4b | ||
|
|
1c1daaa6d2 | ||
|
|
c3b5de843f | ||
|
|
09dcfb4065 | ||
|
|
b2e7211bbe | ||
|
|
1ab1adf937 | ||
|
|
a21bf779b0 | ||
|
|
0dba22529c | ||
|
|
180d63620b | ||
|
|
daea1f538c | ||
|
|
f5e2484797 | ||
|
|
7105ae40c6 | ||
|
|
33f9900ef9 | ||
|
|
1aa1c62e40 | ||
|
|
3a18ef4c7b | ||
|
|
9dcce77302 | ||
|
|
995df9b51b | ||
|
|
84c8babdb7 | ||
|
|
1014f97b6f | ||
|
|
3c023be57d | ||
|
|
eff20c84d6 | ||
|
|
f8984eb7e9 | ||
|
|
2ffd2a1e1f | ||
|
|
341bd081f8 | ||
|
|
52af4203a1 | ||
|
|
e5a6088392 | ||
|
|
6ee5dfb352 | ||
|
|
3f8336fc5e | ||
|
|
8fc7e8f3a7 | ||
|
|
098b1f2668 | ||
|
|
20df3ad2f2 | ||
|
|
7aaadad6da | ||
|
|
be60c1ba02 | ||
|
|
698a8e8677 | ||
|
|
ce6420eeac | ||
|
|
f5f5e4f720 | ||
|
|
c08503826b | ||
|
|
685345d656 | ||
|
|
59aab24a4a | ||
|
|
c3f0e61ebc | ||
|
|
c143536cd0 | ||
|
|
2a168e93d3 | ||
|
|
c3570a23f1 | ||
|
|
9db6cb5545 | ||
|
|
836575c0a8 | ||
|
|
61f2216c25 | ||
|
|
7f5b3ef376 | ||
|
|
257471a36c | ||
|
|
568f3e848f | ||
|
|
0c9b58755f | ||
|
|
1b47fb7873 | ||
|
|
df93209839 | ||
|
|
11ee7827e9 | ||
|
|
c337de5139 | ||
|
|
d55c2befed | ||
|
|
4cd9918e1a | ||
|
|
3a900f23fe | ||
|
|
aee465aced | ||
|
|
192e5ccaa3 | ||
|
|
f164583792 | ||
|
|
b4d657b866 | ||
|
|
f7bf7aeef9 | ||
|
|
2cd4c4850f | ||
|
|
805ccfe451 | ||
|
|
5655f63dff | ||
|
|
a2795e4d78 | ||
|
|
0684c16bf5 | ||
|
|
a08ca3af98 | ||
|
|
efa379e778 | ||
|
|
5cbf0816fe | ||
|
|
2951d3926c | ||
|
|
eb19d59d52 | ||
|
|
3e4d594b05 | ||
|
|
ae8ce83583 | ||
|
|
5c3348a9f5 | ||
|
|
f299ffeb6e | ||
|
|
21c468cf02 | ||
|
|
7f12f62ad5 | ||
|
|
5fb0e26331 | ||
|
|
4dd29952c8 | ||
|
|
2c006699f2 | ||
|
|
0bdf0474c9 | ||
|
|
66196ceb17 | ||
|
|
b2726f3a67 | ||
|
|
663f87d5e2 | ||
|
|
377bb4d6ad | ||
|
|
98e60db2da | ||
|
|
a206591e97 | ||
|
|
c5c5a9ac67 | ||
|
|
b84bc61f3d | ||
|
|
b4e38e0814 |
53
.cargo-husky/hooks/post-commit
Executable file
53
.cargo-husky/hooks/post-commit
Executable file
@@ -0,0 +1,53 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
ROOT_DIR=$(git rev-parse --show-toplevel)
|
||||||
|
AURA_DATA="${ROOT_DIR}/rog-aura/data/aura_support.ron"
|
||||||
|
SPEC_FILE="${ROOT_DIR}/distro-packaging/asusctl.spec"
|
||||||
|
TRANSLATION="${ROOT_DIR}/rog-control-center/translations/en/rog-control-center.po"
|
||||||
|
VERSION=$(grep -Pm1 'version = "(\d+.\d+.\d+.*)"' "${ROOT_DIR}/Cargo.toml" | cut -d'"' -f2)
|
||||||
|
|
||||||
|
if [ -z "$VERSION" ]; then
|
||||||
|
echo "Error: Could not extract version from Cargo.toml"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ ! -f "$SPEC_FILE" ]; then
|
||||||
|
echo "Error: Spec file not found at ${SPEC_FILE}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update spec file
|
||||||
|
sed -i "s/^%define version.*/%define version ${VERSION}/" "$SPEC_FILE"
|
||||||
|
if git diff --quiet "$SPEC_FILE"; then
|
||||||
|
echo "No changes to spec file"
|
||||||
|
else
|
||||||
|
git add "$SPEC_FILE"
|
||||||
|
git commit --no-verify -m "chore: update spec file version to ${VERSION}"
|
||||||
|
echo "Updated spec file version to ${VERSION}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update translations only if UI files changed
|
||||||
|
if git diff-tree -r HEAD@{1} HEAD --name-only | grep -q "^rog-control-center/ui/"; then
|
||||||
|
echo 'find -name \*.slint | xargs slint-tr-extractor -o ${TRANSLATION}'
|
||||||
|
find -name \*.slint | xargs slint-tr-extractor -o $TRANSLATION
|
||||||
|
if git diff --quiet "$TRANSLATION"; then
|
||||||
|
echo "No changes to translation file"
|
||||||
|
else
|
||||||
|
git add "$TRANSLATION"
|
||||||
|
git commit --no-verify -m "chore: update translations"
|
||||||
|
echo "Updated ${TRANSLATION}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "No changes in rog-control-center/ui/, skipping translation update"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update aura data
|
||||||
|
cargo test --package rog_aura --lib -- aura_detection::tests::check_data_file_parse --exact
|
||||||
|
cargo test --package rog_aura --lib -- aura_detection::tests::find_data_file_groups --exact
|
||||||
|
if git diff --quiet "$AURA_DATA"; then
|
||||||
|
echo "No changes to aura data file"
|
||||||
|
else
|
||||||
|
git add "$AURA_DATA"
|
||||||
|
git commit --no-verify -m "chore: update aura data"
|
||||||
|
echo "Updated $AURA_DATA"
|
||||||
|
fi
|
||||||
@@ -1,18 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
echo 'find -name \*.slint | xargs slint-tr-extractor -o rog-control-center/translations/en/rog-control-center.po'
|
echo '+cargo fmt --all -- --check'
|
||||||
find -name \*.slint | xargs slint-tr-extractor -o rog-control-center/translations/en/rog-control-center.po
|
cargo fmt --all -- --check
|
||||||
|
git add -u
|
||||||
echo '+cargo +nightly fmt --all -- --check'
|
|
||||||
cargo +nightly fmt --all -- --check
|
|
||||||
|
|
||||||
echo '+cargo clippy --all -- -D warnings'
|
|
||||||
cargo clippy --all -- -D warnings
|
|
||||||
|
|
||||||
echo '+cargo test --all'
|
|
||||||
cargo test --all -- --test-threads=1
|
|
||||||
|
|
||||||
echo '+cargo cranky'
|
|
||||||
cargo cranky
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
echo '+cargo +nightly fmt --all -- --check'
|
echo '+cargo fmt --all -- --check'
|
||||||
cargo +nightly fmt --all -- --check
|
cargo fmt --all -- --check
|
||||||
echo '+cargo clippy --all -- -D warnings'
|
echo '+cargo clippy --all -- -D warnings'
|
||||||
cargo clippy --all -- -D warnings
|
cargo clippy --all -- -D warnings
|
||||||
echo '+cargo cranky'
|
echo '+cargo cranky'
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,6 +9,7 @@ vendor_*
|
|||||||
.vscode
|
.vscode
|
||||||
.~lock.*
|
.~lock.*
|
||||||
*.ods#
|
*.ods#
|
||||||
|
*.patch
|
||||||
|
|
||||||
# gnome extension
|
# gnome extension
|
||||||
node-modules
|
node-modules
|
||||||
|
|||||||
@@ -1,22 +1,26 @@
|
|||||||
image: rust:latest
|
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
|
.rust_cache: &rust_cache
|
||||||
cache:
|
cache:
|
||||||
# key: $CI_COMMIT_REF_SLUG
|
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||||
paths:
|
paths:
|
||||||
# Don't include `incremental` to save space
|
- .cargo/registry
|
||||||
# Debug
|
- .cargo/git
|
||||||
- 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
|
|
||||||
|
|
||||||
before_script:
|
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
|
- 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:
|
stages:
|
||||||
@@ -31,20 +35,24 @@ format:
|
|||||||
- tags
|
- tags
|
||||||
<<: *rust_cache
|
<<: *rust_cache
|
||||||
script:
|
script:
|
||||||
- echo "nightly" > rust-toolchain
|
- rustup component add rustfmt || true
|
||||||
- rustup component add rustfmt
|
|
||||||
- cargo fmt --check
|
- cargo fmt --check
|
||||||
|
after_script:
|
||||||
|
- du -sh "$CI_PROJECT_DIR/ci-target" || true
|
||||||
|
- rm -rf "$CI_PROJECT_DIR/ci-target" || true
|
||||||
|
|
||||||
check:
|
check:
|
||||||
except:
|
except:
|
||||||
- tags
|
- tags
|
||||||
<<: *rust_cache
|
<<: *rust_cache
|
||||||
script:
|
script:
|
||||||
- rustup component add clippy
|
- rustup component add clippy || true
|
||||||
- cargo check
|
- cargo check --locked --workspace
|
||||||
# deny currently catches too much
|
# deny currently catches too much
|
||||||
#- cargo install cargo-deny && cargo deny
|
#- cargo install cargo-deny && cargo deny
|
||||||
- cargo install cargo-cranky && cargo cranky
|
- cargo install cargo-cranky && cargo cranky
|
||||||
|
after_script:
|
||||||
|
- rm -rf "$CI_PROJECT_DIR/ci-target" || true
|
||||||
|
|
||||||
test:
|
test:
|
||||||
except:
|
except:
|
||||||
@@ -52,7 +60,9 @@ test:
|
|||||||
<<: *rust_cache
|
<<: *rust_cache
|
||||||
script:
|
script:
|
||||||
- mkdir -p .git/hooks > /dev/null
|
- mkdir -p .git/hooks > /dev/null
|
||||||
- cargo test --all -- --test-threads=1
|
- cargo test --locked --all
|
||||||
|
after_script:
|
||||||
|
- rm -rf "$CI_PROJECT_DIR/ci-target" || true
|
||||||
|
|
||||||
release:
|
release:
|
||||||
only:
|
only:
|
||||||
@@ -60,11 +70,15 @@ release:
|
|||||||
<<: *rust_cache
|
<<: *rust_cache
|
||||||
script:
|
script:
|
||||||
- cargo install cargo-vendor-filterer
|
- cargo install cargo-vendor-filterer
|
||||||
- make && make vendor
|
- cargo fetch
|
||||||
|
- make FROZEN=1 && make vendor
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- vendor_asusctl*.tar.xz
|
- vendor_asusctl*.tar.xz
|
||||||
- cargo-config
|
- cargo-config
|
||||||
|
expire_in: 1 week
|
||||||
|
after_script:
|
||||||
|
- rm -rf vendor vendor_asusctl*.tar.xz "$CI_PROJECT_DIR/ci-target" || true
|
||||||
|
|
||||||
pages:
|
pages:
|
||||||
stage: deploy
|
stage: deploy
|
||||||
@@ -72,14 +86,14 @@ pages:
|
|||||||
- tags
|
- tags
|
||||||
<<: *rust_cache
|
<<: *rust_cache
|
||||||
script:
|
script:
|
||||||
- cargo doc --document-private-items --no-deps --workspace
|
- cargo doc --locked --document-private-items --no-deps --workspace
|
||||||
- rm -rf public
|
- rm -rf public
|
||||||
- mkdir public
|
- mkdir public
|
||||||
- cp -R target/doc/* public
|
- cp -R ci-target/doc/* public
|
||||||
- cp extra/index.html public
|
- cp extra/index.html public
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- public
|
- public
|
||||||
|
expire_in: 1 week
|
||||||
variables:
|
after_script:
|
||||||
GIT_SUBMODULE_STRATEGY: normal
|
- rm -rf "$CI_PROJECT_DIR/ci-target" || true
|
||||||
|
|||||||
140
CHANGELOG.md
140
CHANGELOG.md
@@ -2,8 +2,148 @@
|
|||||||
|
|
||||||
## [Unreleased]
|
## [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
|
||||||
|
- Fix anime flickering issue when using custom anims (@I-Al-Istannen)
|
||||||
|
- Include pt_BR translations file (@PabloKiryu)
|
||||||
|
|
||||||
|
## Added
|
||||||
|
- Support for the screenpad brightness on some Laptops. This includes syncing to the primary screen brightness, and a gamma adjustment to set brightness scaling.
|
||||||
|
- Add asusctl CLI options
|
||||||
|
- Add UI options
|
||||||
|
- Add a fake gamma correction (`asusctl backlight --sync-screenpad-brightness`, 1.5 for example sets screenpad low brightness lower than primary, and scales upwards)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- asusd: single line fix for profile switching
|
||||||
|
|
||||||
|
## [v6.1.9]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- ROGCC: better handling of platform profiles
|
||||||
|
|
||||||
|
## [v6.1.8]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Testing CI for opensuse RPM build
|
||||||
|
- ROGCC: Fixes to showing the PPT enablement toggle
|
||||||
|
- ROGCC: Fixes to how PPT and NV sliders work and enable/disable
|
||||||
|
- RGOCC: Fix quiet fan-curves availability
|
||||||
|
|
||||||
|
## [v6.1.7]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Fix Slash display enable
|
||||||
|
|
||||||
|
## [v6.1.6]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Disable skia bindings for UI again. It causes failures in build pipelines and requires extra dependencies.
|
||||||
|
|
||||||
|
## [v6.1.5]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Update dependencies
|
||||||
|
- Fix fan-curve proxy type signatures
|
||||||
|
|
||||||
|
## [v6.1.4]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Fix git doing me a dirty
|
||||||
|
|
||||||
|
## [v6.1.3]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Many small bugfixes such as for platform profile switching
|
||||||
|
|
||||||
|
## [v6.1.2]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Try a slightly different tact to fix charge control slider
|
||||||
|
|
||||||
|
## [v6.1.1]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Fix aura data matching
|
- Fix aura data matching
|
||||||
|
- Fix charge control slider
|
||||||
|
|
||||||
## [v6.1.0]
|
## [v6.1.0]
|
||||||
|
|
||||||
|
|||||||
3893
Cargo.lock
generated
3893
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
21
Cargo.toml
21
Cargo.toml
@@ -1,5 +1,5 @@
|
|||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "6.1.0"
|
version = "6.2.0"
|
||||||
rust-version = "1.82"
|
rust-version = "1.82"
|
||||||
license = "MPL-2.0"
|
license = "MPL-2.0"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
@@ -43,8 +43,9 @@ dirs = "^4.0"
|
|||||||
smol = "^2.0"
|
smol = "^2.0"
|
||||||
mio = "0.8.11"
|
mio = "0.8.11"
|
||||||
|
|
||||||
zbus = "5.1"
|
futures-util = "0.3.31"
|
||||||
logind-zbus = { version = "5.0.0" } #, default-features = false, features = ["non_blocking"] }
|
zbus = "5.13.1"
|
||||||
|
logind-zbus = { version = "5.2.0" } #, default-features = false, features = ["non_blocking"] }
|
||||||
|
|
||||||
serde = { version = "^1.0", features = ["serde_derive"] }
|
serde = { version = "^1.0", features = ["serde_derive"] }
|
||||||
ron = "*"
|
ron = "*"
|
||||||
@@ -56,16 +57,16 @@ glam = { version = "^0.22", features = ["serde"] }
|
|||||||
gumdrop = "^0.8"
|
gumdrop = "^0.8"
|
||||||
udev = { version = "^0.8", features = ["mio"] }
|
udev = { version = "^0.8", features = ["mio"] }
|
||||||
rusb = "^0.9"
|
rusb = "^0.9"
|
||||||
inotify = "^0.10.0"
|
inotify = "^0.10"
|
||||||
|
|
||||||
png_pong = "^0.8"
|
png_pong = "^0.8"
|
||||||
pix = "^0.13"
|
pix = "^0.13"
|
||||||
tinybmp = "^0.4.0"
|
tinybmp = "^0.4"
|
||||||
gif = "^0.12.0"
|
gif = "^0.12"
|
||||||
|
|
||||||
versions = "6.2"
|
versions = "6.2"
|
||||||
|
|
||||||
notify-rust = { version = "4.11.0", features = ["z", "async"] }
|
notify-rust = { version = "4.11.5", features = ["z", "async"] }
|
||||||
|
|
||||||
sg = { git = "https://github.com/flukejones/sg-rs.git" }
|
sg = { git = "https://github.com/flukejones/sg-rs.git" }
|
||||||
|
|
||||||
@@ -76,15 +77,15 @@ lto = "fat"
|
|||||||
debug = false
|
debug = false
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
codegen-units = 1
|
# codegen-units = 1
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = 1
|
opt-level = 1
|
||||||
codegen-units = 16
|
# codegen-units = 1
|
||||||
|
|
||||||
[profile.dev.package."*"]
|
[profile.dev.package."*"]
|
||||||
opt-level = 1
|
opt-level = 1
|
||||||
codegen-units = 16
|
# codegen-units = 1
|
||||||
|
|
||||||
[profile.bench]
|
[profile.bench]
|
||||||
debug = false
|
debug = false
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ The LED controller (e.g, aura) enables setting many of the factory modes availab
|
|||||||
|
|
||||||
#### Supported laptops
|
#### Supported laptops
|
||||||
|
|
||||||
There are over 60 supported laptops as of 01-01-2023. Please see [the rog-aura crate readme for further details](/rog-aura/README.md).
|
There are over 80 supported laptops as of 01-01-2023. Please see [the rog-aura crate readme for further details](/rog-aura/README.md).
|
||||||
|
|
||||||
### Charge control
|
### Charge control
|
||||||
|
|
||||||
@@ -420,13 +420,13 @@ To switch to next/previous Aura modes you will need to bind both the aura keys (
|
|||||||
**Next**
|
**Next**
|
||||||
|
|
||||||
```
|
```
|
||||||
asusctl led-mode -n
|
asusctl aura -n
|
||||||
```
|
```
|
||||||
|
|
||||||
**Previous**
|
**Previous**
|
||||||
|
|
||||||
```
|
```
|
||||||
asusctl led-mode -p
|
asusctl aura -p
|
||||||
```
|
```
|
||||||
|
|
||||||
To switch Fan/Thermal profiles you need to bind the Fn+F5 key to `asusctl profile -n`.
|
To switch Fan/Thermal profiles you need to bind the Fn+F5 key to `asusctl profile -n`.
|
||||||
|
|||||||
68
Makefile
68
Makefile
@@ -17,6 +17,8 @@ BIN_D := asusd
|
|||||||
BIN_U := asusd-user
|
BIN_U := asusd-user
|
||||||
LEDCFG := aura_support.ron
|
LEDCFG := aura_support.ron
|
||||||
|
|
||||||
|
DESTDIR_REALPATH = $(shell realpath $(DESTDIR))
|
||||||
|
|
||||||
SRC := Cargo.toml Cargo.lock Makefile $(shell find -type f -wholename '**/src/*.rs')
|
SRC := Cargo.toml Cargo.lock Makefile $(shell find -type f -wholename '**/src/*.rs')
|
||||||
|
|
||||||
STRIP_BINARIES ?= 0
|
STRIP_BINARIES ?= 0
|
||||||
@@ -35,6 +37,15 @@ ifeq ($(X11),1)
|
|||||||
ARGS += --features "rog-control-center/x11"
|
ARGS += --features "rog-control-center/x11"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Always use the versions in Cargo.lock by default
|
||||||
|
ARGS += --locked
|
||||||
|
|
||||||
|
# Allow optionally freezing the build to avoid any network access and enforce Cargo.lock strictly
|
||||||
|
FROZEN ?= 0
|
||||||
|
ifeq ($(FROZEN),1)
|
||||||
|
ARGS += --frozen
|
||||||
|
endif
|
||||||
|
|
||||||
VENDORED ?= 0
|
VENDORED ?= 0
|
||||||
ifeq ($(VENDORED),1)
|
ifeq ($(VENDORED),1)
|
||||||
ARGS += --frozen
|
ARGS += --frozen
|
||||||
@@ -48,24 +59,38 @@ clean:
|
|||||||
distclean:
|
distclean:
|
||||||
rm -rf .cargo vendor vendor.tar.xz
|
rm -rf .cargo vendor vendor.tar.xz
|
||||||
|
|
||||||
install-program:
|
target/$(TARGET)/$(BIN_D): $(SRC)
|
||||||
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_ROG)" "$(DESTDIR)$(bindir)/$(BIN_ROG)"
|
$(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_PROGRAM) "./target/$(TARGET)/$(BIN_D)" "$(DESTDIR)$(bindir)/$(BIN_D)"
|
||||||
|
|
||||||
|
install-asusctl: target/$(TARGET)/$(BIN_C)
|
||||||
|
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_C)" "$(DESTDIR)$(bindir)/$(BIN_C)"
|
||||||
|
|
||||||
|
install-asusd_user: target/$(TARGET)/$(BIN_U)
|
||||||
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_U)" "$(DESTDIR)$(bindir)/$(BIN_U)"
|
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_U)" "$(DESTDIR)$(bindir)/$(BIN_U)"
|
||||||
|
|
||||||
install-data:
|
install-rog_gui: target/$(TARGET)/$(BIN_ROG)
|
||||||
|
$(INSTALL_PROGRAM) "./target/$(TARGET)/$(BIN_ROG)" "$(DESTDIR)$(bindir)/$(BIN_ROG)"
|
||||||
|
|
||||||
|
.PHONY: install-asusd install-asusctl install-asusd_user install-rog_gui
|
||||||
|
|
||||||
|
install-program: install-asusd install-asusctl install-asusd_user install-rog_gui
|
||||||
|
|
||||||
|
install-data-rog_gui:
|
||||||
$(INSTALL_DATA) "./rog-control-center/data/$(BIN_ROG).desktop" "$(DESTDIR)$(datarootdir)/applications/$(BIN_ROG).desktop"
|
$(INSTALL_DATA) "./rog-control-center/data/$(BIN_ROG).desktop" "$(DESTDIR)$(datarootdir)/applications/$(BIN_ROG).desktop"
|
||||||
$(INSTALL_DATA) "./rog-control-center/data/$(BIN_ROG).png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/$(BIN_ROG).png"
|
$(INSTALL_DATA) "./rog-control-center/data/$(BIN_ROG).png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/$(BIN_ROG).png"
|
||||||
cd rog-aura/data/layouts && find . -type f -name "*.ron" -exec $(INSTALL_DATA) "{}" "$(DESTDIR)$(datarootdir)/rog-gui/layouts/{}" \;
|
cd rog-aura/data/layouts && find . -type f -name "*.ron" -exec $(INSTALL_DATA) "{}" "$(DESTDIR_REALPATH)$(datarootdir)/rog-gui/layouts/{}" \;
|
||||||
|
|
||||||
$(INSTALL_DATA) "./data/$(BIN_D).rules" "$(DESTDIR)$(libdir)/udev/rules.d/99-$(BIN_D).rules"
|
|
||||||
$(INSTALL_DATA) "./rog-aura/data/$(LEDCFG)" "$(DESTDIR)$(datarootdir)/asusd/$(LEDCFG)"
|
|
||||||
$(INSTALL_DATA) "./data/$(BIN_D).conf" "$(DESTDIR)$(datarootdir)/dbus-1/system.d/$(BIN_D).conf"
|
|
||||||
|
|
||||||
$(INSTALL_DATA) "./data/$(BIN_D).service" "$(DESTDIR)$(libdir)/systemd/system/$(BIN_D).service"
|
|
||||||
$(INSTALL_DATA) "./data/$(BIN_U).service" "$(DESTDIR)$(libdir)/systemd/user/$(BIN_U).service"
|
|
||||||
|
|
||||||
$(INSTALL_DATA) "./data/icons/asus_notif_yellow.png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_yellow.png"
|
$(INSTALL_DATA) "./data/icons/asus_notif_yellow.png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_yellow.png"
|
||||||
$(INSTALL_DATA) "./data/icons/asus_notif_green.png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_green.png"
|
$(INSTALL_DATA) "./data/icons/asus_notif_green.png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_green.png"
|
||||||
@@ -81,9 +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/gpu-vfio.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/gpu-vfio.svg"
|
||||||
$(INSTALL_DATA) "./data/icons/scalable/notification-reboot.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/notification-reboot.svg"
|
$(INSTALL_DATA) "./data/icons/scalable/notification-reboot.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/notification-reboot.svg"
|
||||||
|
|
||||||
cd rog-anime/data && find "./anime" -type f -exec $(INSTALL_DATA) "{}" "$(DESTDIR)$(datarootdir)/asusd/{}" \;
|
install-data-asusd:
|
||||||
|
$(INSTALL_DATA) "./data/$(BIN_D).rules" "$(DESTDIR)$(libdir)/udev/rules.d/99-$(BIN_D).rules"
|
||||||
|
$(INSTALL_DATA) "./rog-aura/data/$(LEDCFG)" "$(DESTDIR)$(datarootdir)/asusd/$(LEDCFG)"
|
||||||
|
$(INSTALL_DATA) "./data/$(BIN_D).conf" "$(DESTDIR)$(datarootdir)/dbus-1/system.d/$(BIN_D).conf"
|
||||||
|
|
||||||
|
$(INSTALL_DATA) "./data/$(BIN_D).service" "$(DESTDIR)$(libdir)/systemd/system/$(BIN_D).service"
|
||||||
|
|
||||||
|
cd rog-anime/data && find "./anime" -type f -exec $(INSTALL_DATA) "{}" "$(DESTDIR_REALPATH)$(datarootdir)/asusd/{}" \;
|
||||||
|
|
||||||
|
install-data-asusd_user:
|
||||||
|
$(INSTALL_DATA) "./data/$(BIN_U).service" "$(DESTDIR)$(libdir)/systemd/user/$(BIN_U).service"
|
||||||
|
|
||||||
|
.PHONY: install-data-asusd install-data-asusd_user
|
||||||
|
|
||||||
|
install-data: install-data-asusd install-data-asusd_user install-data-rog_gui
|
||||||
|
|
||||||
install: install-program install-data
|
install: install-program install-data
|
||||||
|
$(INSTALL_DATA) "./LICENSE" "$(DESTDIR)$(datarootdir)/asusctl/LICENSE"
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -f "$(DESTDIR)$(bindir)/$(BIN_ROG)"
|
rm -f "$(DESTDIR)$(bindir)/$(BIN_ROG)"
|
||||||
@@ -118,6 +158,8 @@ vendor:
|
|||||||
mv .cargo/config ./cargo-config
|
mv .cargo/config ./cargo-config
|
||||||
rm -rf .cargo
|
rm -rf .cargo
|
||||||
rm -rf vendor
|
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
|
cargo vendor-filterer --all-features --platform x86_64-unknown-linux-gnu vendor
|
||||||
tar pcfJ vendor_asusctl_$(VERSION).tar.xz vendor
|
tar pcfJ vendor_asusctl_$(VERSION).tar.xz vendor
|
||||||
rm -rf vendor
|
rm -rf vendor
|
||||||
|
|||||||
61
README.md
61
README.md
@@ -46,13 +46,13 @@ See the [rog-aura readme](./rog-aura/README.md) for more details.
|
|||||||
Most ASUS gaming laptops that have a USB keyboard. If `lsusb` shows something similar
|
Most ASUS gaming laptops that have a USB keyboard. If `lsusb` shows something similar
|
||||||
to this:
|
to this:
|
||||||
|
|
||||||
```
|
```plain
|
||||||
Bus 001 Device 002: ID 0b05:1866 ASUSTek Computer, Inc. N-KEY Device
|
Bus 001 Device 002: ID 0b05:1866 ASUSTek Computer, Inc. N-KEY Device
|
||||||
```
|
```
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
```
|
```plain
|
||||||
Bus 003 Device 002: ID 0b05:19b6 ASUSTek Computer, Inc. [unknown]
|
Bus 003 Device 002: ID 0b05:19b6 ASUSTek Computer, Inc. [unknown]
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -74,43 +74,56 @@ The list is a bit outdated as many features have been enabled in the Linux kerne
|
|||||||
- [x] Toggle bios setting for boot/POST sound
|
- [x] Toggle bios setting for boot/POST sound
|
||||||
- [x] Toggle GPU MUX (g-sync, or called MUX on 2022+ laptops)
|
- [x] Toggle GPU MUX (g-sync, or called MUX on 2022+ laptops)
|
||||||
|
|
||||||
# GUI
|
## GUI
|
||||||
|
|
||||||
A gui is now in the repo - ROG Control Center. At this time it is still a WIP, but it has almost all features in place already.
|
A gui is now in the repo - ROG Control Center. At this time it is still a WIP, but it has almost all features in place already.
|
||||||
|
|
||||||
**NOTE**: Xorg is not supported.
|
**NOTE**: Xorg is not supported.
|
||||||
|
|
||||||
# BUILDING
|
## BUILDING
|
||||||
|
|
||||||
Rust and cargo are required, they can be installed from [rustup.rs](https://rustup.rs/) or from the distro repos if newer than 1.75.
|
Rust and cargo are required, they can be installed from [rustup.rs](https://rustup.rs/).
|
||||||
|
|
||||||
|
Distro packaging should work with the stable toolchain. If your distro does not provide a recent Rust toolchain, install rustup and use the stable toolchain.
|
||||||
|
|
||||||
**fedora:**
|
**fedora:**
|
||||||
|
|
||||||
dnf install cmake clang-devel libxkbcommon-devel systemd-devel expat-devel pcre2-devel libzstd-devel gtk3-devel
|
```sh
|
||||||
make
|
dnf install cmake clang-devel libxkbcommon-devel systemd-devel expat-devel pcre2-devel libzstd-devel gtk3-devel
|
||||||
sudo make install
|
make
|
||||||
|
sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
**openSUSE:**
|
**openSUSE:**
|
||||||
|
|
||||||
Works with KDE Plasma (without GTK packages)
|
Works with KDE Plasma (without GTK packages)
|
||||||
|
|
||||||
zypper in -t pattern devel_basis
|
```sh
|
||||||
zypper in rustup make cmake clang-devel libxkbcommon-devel systemd-devel expat-devel pcre2-devel libzstd-devel gtk3-devel
|
zypper in -t pattern devel_basis
|
||||||
make
|
zypper in rustup make cmake clang-devel libxkbcommon-devel systemd-devel expat-devel pcre2-devel libzstd-devel gtk3-devel
|
||||||
sudo make install
|
make
|
||||||
|
sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
**Debian(unsuported):**
|
**Debian(unsuported):**
|
||||||
|
|
||||||
officially unsuported,but you can still try and test it by yourself(some features may not be available).
|
officially unsuported,but you can still try and test it by yourself(some features may not be available).
|
||||||
|
|
||||||
sudo apt install libclang-dev libudev-dev libfontconfig-dev build-essential cmake libxkbcommon-dev
|
```sh
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
sudo apt install libclang-dev libudev-dev libfontconfig-dev build-essential cmake libxkbcommon-dev
|
||||||
make
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||||
sudo make install
|
make
|
||||||
|
sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
**Ubuntu, Popos (unsuported):**
|
**Ubuntu, Popos (unsuported):**
|
||||||
|
|
||||||
instructions removed as outdated
|
```sh
|
||||||
|
sudo apt install make cargo gcc pkg-config openssl libasound2-dev cmake build-essential python3 libfreetype6-dev libexpat1-dev libxcb-composite0-dev libssl-dev libx11-dev libfontconfig1-dev curl libclang-dev libudev-dev checkinstall libseat-dev libinput-dev libxkbcommon-dev libgbm-dev
|
||||||
|
|
||||||
|
make
|
||||||
|
sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
## Installing
|
## Installing
|
||||||
|
|
||||||
@@ -128,15 +141,15 @@ You may also need to activate the service for debian install. If running Pop!\_O
|
|||||||
|
|
||||||
If you are upgrading from a previous installed version, you will need to restart the service or reboot.
|
If you are upgrading from a previous installed version, you will need to restart the service or reboot.
|
||||||
|
|
||||||
```
|
```sh
|
||||||
$ systemctl daemon-reload && systemctl restart asusd
|
systemctl daemon-reload && systemctl restart asusd
|
||||||
```
|
```
|
||||||
|
|
||||||
## Uninstalling
|
## Uninstalling
|
||||||
|
|
||||||
Run `sudo make uninstall` in the source repo, and remove `/etc/asusd/`.
|
Run `sudo make uninstall` in the source repo, and remove `/etc/asusd/`.
|
||||||
|
|
||||||
# Contributing
|
## Contributing
|
||||||
|
|
||||||
See `CONTRIBUTING.md`. Additionally, also do `cargo clean` and `cargo test` on first checkout to ensure the commit hooks are used (via `cargo-husky`).
|
See `CONTRIBUTING.md`. Additionally, also do `cargo clean` and `cargo test` on first checkout to ensure the commit hooks are used (via `cargo-husky`).
|
||||||
|
|
||||||
@@ -144,17 +157,17 @@ Generation of the bindings with `make bindings` requires `typeshare` to be insta
|
|||||||
|
|
||||||
Dbus introsepction XML requires with `make introspection` requires `anime_sim` to be running before starting `asusd`.
|
Dbus introsepction XML requires with `make introspection` requires `anime_sim` to be running before starting `asusd`.
|
||||||
|
|
||||||
# OTHER
|
## OTHER
|
||||||
|
|
||||||
## AniMe Matrix simulator
|
### AniMe Matrix simulator
|
||||||
|
|
||||||
A simulator using SDL2 can be built using `cargo build --package rog_simulators` and run with `./target/debug/anime_sim`. Once started `asusd` will need restarting to pick it up. If running this sim on a laptop _with_ the display, the simulated display will be used instead of the physical display.
|
A simulator using SDL2 can be built using `cargo build --package rog_simulators` and run with `./target/debug/anime_sim`. Once started `asusd` will need restarting to pick it up. If running this sim on a laptop _with_ the display, the simulated display will be used instead of the physical display.
|
||||||
|
|
||||||
## Supporting more laptops
|
### Supporting more laptops
|
||||||
|
|
||||||
Please file a support request.
|
Please file a support request.
|
||||||
|
|
||||||
# License & Trademarks
|
## License & Trademarks
|
||||||
|
|
||||||
Mozilla Public License 2 (MPL-2.0)
|
Mozilla Public License 2 (MPL-2.0)
|
||||||
|
|
||||||
|
|||||||
@@ -27,3 +27,15 @@ zbus.workspace = true
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rog_dbus = { path = "../rog-dbus" }
|
rog_dbus = { path = "../rog-dbus" }
|
||||||
|
|
||||||
|
[package.metadata.deb]
|
||||||
|
license-file = ["../LICENSE", "4"]
|
||||||
|
extended-description = """\
|
||||||
|
An utility for Linux to control many aspects of various ASUS laptops
|
||||||
|
but can also be used with non-asus laptops with reduced features."""
|
||||||
|
depends = "$auto"
|
||||||
|
section = "utility"
|
||||||
|
priority = "optional"
|
||||||
|
assets = [
|
||||||
|
["target/release/asusctl", "usr/bin/", "755"],
|
||||||
|
]
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
Path::new(&args[1]),
|
Path::new(&args[1]),
|
||||||
None,
|
None,
|
||||||
args[2].parse::<f32>().unwrap(),
|
args[2].parse::<f32>().unwrap(),
|
||||||
AnimeType::GA401
|
AnimeType::GA401,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let anime_type = get_anime_type();
|
let anime_type = get_anime_type();
|
||||||
|
|||||||
@@ -21,11 +21,14 @@ fn main() {
|
|||||||
let brightness = args[2].parse::<f32>().unwrap();
|
let brightness = args[2].parse::<f32>().unwrap();
|
||||||
let anime_type = get_anime_type();
|
let anime_type = get_anime_type();
|
||||||
let mut seq = Sequences::new(anime_type);
|
let mut seq = Sequences::new(anime_type);
|
||||||
seq.insert(0, &ActionLoader::AsusAnimation {
|
seq.insert(
|
||||||
file: path.into(),
|
0,
|
||||||
time: rog_anime::AnimTime::Infinite,
|
&ActionLoader::AsusAnimation {
|
||||||
brightness
|
file: path.into(),
|
||||||
})
|
time: rog_anime::AnimTime::Infinite,
|
||||||
|
brightness,
|
||||||
|
},
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
|||||||
@@ -27,10 +27,10 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
args[3].parse::<f32>().unwrap(),
|
args[3].parse::<f32>().unwrap(),
|
||||||
Vec2::new(
|
Vec2::new(
|
||||||
args[4].parse::<f32>().unwrap(),
|
args[4].parse::<f32>().unwrap(),
|
||||||
args[5].parse::<f32>().unwrap()
|
args[5].parse::<f32>().unwrap(),
|
||||||
),
|
),
|
||||||
args[6].parse::<f32>().unwrap(),
|
args[6].parse::<f32>().unwrap(),
|
||||||
anime_type
|
anime_type,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
proxy.write(<AnimeDataBuffer>::try_from(&matrix)?).unwrap();
|
proxy.write(<AnimeDataBuffer>::try_from(&matrix)?).unwrap();
|
||||||
|
|||||||
@@ -30,10 +30,10 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
args[3].parse::<f32>().unwrap(),
|
args[3].parse::<f32>().unwrap(),
|
||||||
Vec2::new(
|
Vec2::new(
|
||||||
args[4].parse::<f32>().unwrap(),
|
args[4].parse::<f32>().unwrap(),
|
||||||
args[5].parse::<f32>().unwrap()
|
args[5].parse::<f32>().unwrap(),
|
||||||
),
|
),
|
||||||
args[6].parse::<f32>().unwrap(),
|
args[6].parse::<f32>().unwrap(),
|
||||||
anime_type
|
anime_type,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
Colour {
|
Colour {
|
||||||
r: 200,
|
r: 200,
|
||||||
g: 110,
|
g: 110,
|
||||||
b: 0
|
b: 0,
|
||||||
},
|
},
|
||||||
100,
|
100,
|
||||||
10
|
10,
|
||||||
));
|
));
|
||||||
seq.push(zone);
|
seq.push(zone);
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ pub struct AnimeCommand {
|
|||||||
#[options(no_short, meta = "", help = "Off with his head!!!")]
|
#[options(no_short, meta = "", help = "Off with his head!!!")]
|
||||||
pub off_with_his_head: Option<bool>,
|
pub off_with_his_head: Option<bool>,
|
||||||
#[options(command)]
|
#[options(command)]
|
||||||
pub command: Option<AnimeActions>
|
pub command: Option<AnimeActions>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Options)]
|
#[derive(Options)]
|
||||||
@@ -54,7 +54,7 @@ pub enum AnimeActions {
|
|||||||
#[options(help = "display an animated diagonal/pixel-perfect GIF")]
|
#[options(help = "display an animated diagonal/pixel-perfect GIF")]
|
||||||
PixelGif(AnimeGifDiagonal),
|
PixelGif(AnimeGifDiagonal),
|
||||||
#[options(help = "change which builtin animations are shown")]
|
#[options(help = "change which builtin animations are shown")]
|
||||||
SetBuiltins(Builtins)
|
SetBuiltins(Builtins),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Options)]
|
#[derive(Options)]
|
||||||
@@ -82,7 +82,7 @@ pub struct Builtins {
|
|||||||
)]
|
)]
|
||||||
pub shutdown: AnimShutdown,
|
pub shutdown: AnimShutdown,
|
||||||
#[options(meta = "", help = "set/apply the animations <true/false>")]
|
#[options(meta = "", help = "set/apply the animations <true/false>")]
|
||||||
pub set: Option<bool>
|
pub set: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Options)]
|
#[derive(Options)]
|
||||||
@@ -100,7 +100,7 @@ pub struct AnimeImage {
|
|||||||
#[options(meta = "", default = "0.0", help = "the angle in radians")]
|
#[options(meta = "", default = "0.0", help = "the angle in radians")]
|
||||||
pub angle: f32,
|
pub angle: f32,
|
||||||
#[options(meta = "", default = "1.0", help = "brightness 0.0-1.0")]
|
#[options(meta = "", default = "1.0", help = "brightness 0.0-1.0")]
|
||||||
pub bright: f32
|
pub bright: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Options)]
|
#[derive(Options)]
|
||||||
@@ -110,7 +110,7 @@ pub struct AnimeImageDiagonal {
|
|||||||
#[options(meta = "", help = "full path to the png to display")]
|
#[options(meta = "", help = "full path to the png to display")]
|
||||||
pub path: String,
|
pub path: String,
|
||||||
#[options(meta = "", default = "1.0", help = "brightness 0.0-1.0")]
|
#[options(meta = "", default = "1.0", help = "brightness 0.0-1.0")]
|
||||||
pub bright: f32
|
pub bright: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Options)]
|
#[derive(Options)]
|
||||||
@@ -134,7 +134,7 @@ pub struct AnimeGif {
|
|||||||
default = "1",
|
default = "1",
|
||||||
help = "how many loops to play - 0 is infinite"
|
help = "how many loops to play - 0 is infinite"
|
||||||
)]
|
)]
|
||||||
pub loops: u32
|
pub loops: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Options)]
|
#[derive(Options)]
|
||||||
@@ -150,5 +150,5 @@ pub struct AnimeGifDiagonal {
|
|||||||
default = "1",
|
default = "1",
|
||||||
help = "how many loops to play - 0 is infinite"
|
help = "how many loops to play - 0 is infinite"
|
||||||
)]
|
)]
|
||||||
pub loops: u32
|
pub loops: u32,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ pub struct LedPowerCommand1 {
|
|||||||
#[options(meta = "", help = "Control boot animations <true/false>")]
|
#[options(meta = "", help = "Control boot animations <true/false>")]
|
||||||
pub boot: Option<bool>,
|
pub boot: Option<bool>,
|
||||||
#[options(meta = "", help = "Control suspend animations <true/false>")]
|
#[options(meta = "", help = "Control suspend animations <true/false>")]
|
||||||
pub sleep: Option<bool>
|
pub sleep: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Options, Debug)]
|
#[derive(Options, Debug)]
|
||||||
@@ -25,7 +25,7 @@ pub struct LedPowerCommand2 {
|
|||||||
#[options(help = "print help message")]
|
#[options(help = "print help message")]
|
||||||
pub help: bool,
|
pub help: bool,
|
||||||
#[options(command)]
|
#[options(command)]
|
||||||
pub command: Option<SetAuraZoneEnabled>
|
pub command: Option<SetAuraZoneEnabled>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Options, Debug)]
|
#[derive(Options, Debug)]
|
||||||
@@ -42,7 +42,7 @@ pub enum SetAuraZoneEnabled {
|
|||||||
#[options(help = "")]
|
#[options(help = "")]
|
||||||
RearGlow(AuraPowerStates),
|
RearGlow(AuraPowerStates),
|
||||||
#[options(help = "")]
|
#[options(help = "")]
|
||||||
Ally(AuraPowerStates)
|
Ally(AuraPowerStates),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Options)]
|
#[derive(Debug, Clone, Options)]
|
||||||
@@ -56,12 +56,12 @@ pub struct AuraPowerStates {
|
|||||||
#[options(help = "defaults to false if option unused")]
|
#[options(help = "defaults to false if option unused")]
|
||||||
pub sleep: bool,
|
pub sleep: bool,
|
||||||
#[options(help = "defaults to false if option unused")]
|
#[options(help = "defaults to false if option unused")]
|
||||||
pub shutdown: bool
|
pub shutdown: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Options)]
|
#[derive(Options)]
|
||||||
pub struct LedBrightness {
|
pub struct LedBrightness {
|
||||||
level: Option<u8>
|
level: Option<u8>,
|
||||||
}
|
}
|
||||||
impl LedBrightness {
|
impl LedBrightness {
|
||||||
pub fn new(level: Option<u8>) -> Self {
|
pub fn new(level: Option<u8>) -> Self {
|
||||||
@@ -96,7 +96,7 @@ impl ToString for LedBrightness {
|
|||||||
Some(0x00) => "low",
|
Some(0x00) => "low",
|
||||||
Some(0x01) => "med",
|
Some(0x01) => "med",
|
||||||
Some(0x02) => "high",
|
Some(0x02) => "high",
|
||||||
_ => "unknown"
|
_ => "unknown",
|
||||||
};
|
};
|
||||||
s.to_owned()
|
s.to_owned()
|
||||||
}
|
}
|
||||||
@@ -113,7 +113,7 @@ pub struct SingleSpeed {
|
|||||||
meta = "",
|
meta = "",
|
||||||
help = "set the zone for this effect e.g, 0, 1, one, logo, lightbar-left"
|
help = "set the zone for this effect e.g, 0, 1, one, logo, lightbar-left"
|
||||||
)]
|
)]
|
||||||
pub zone: AuraZone
|
pub zone: AuraZone,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Options, Default)]
|
#[derive(Debug, Clone, Options, Default)]
|
||||||
@@ -129,7 +129,7 @@ pub struct SingleSpeedDirection {
|
|||||||
meta = "",
|
meta = "",
|
||||||
help = "set the zone for this effect e.g, 0, 1, one, logo, lightbar-left"
|
help = "set the zone for this effect e.g, 0, 1, one, logo, lightbar-left"
|
||||||
)]
|
)]
|
||||||
pub zone: AuraZone
|
pub zone: AuraZone,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Options)]
|
#[derive(Debug, Clone, Default, Options)]
|
||||||
@@ -143,7 +143,7 @@ pub struct SingleColour {
|
|||||||
meta = "",
|
meta = "",
|
||||||
help = "set the zone for this effect e.g, 0, 1, one, logo, lightbar-left"
|
help = "set the zone for this effect e.g, 0, 1, one, logo, lightbar-left"
|
||||||
)]
|
)]
|
||||||
pub zone: AuraZone
|
pub zone: AuraZone,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Options)]
|
#[derive(Debug, Clone, Default, Options)]
|
||||||
@@ -159,7 +159,7 @@ pub struct SingleColourSpeed {
|
|||||||
meta = "",
|
meta = "",
|
||||||
help = "set the zone for this effect e.g, 0, 1, one, logo, lightbar-left"
|
help = "set the zone for this effect e.g, 0, 1, one, logo, lightbar-left"
|
||||||
)]
|
)]
|
||||||
pub zone: AuraZone
|
pub zone: AuraZone,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Options, Default)]
|
#[derive(Debug, Clone, Options, Default)]
|
||||||
@@ -177,10 +177,11 @@ pub struct TwoColourSpeed {
|
|||||||
meta = "",
|
meta = "",
|
||||||
help = "set the zone for this effect e.g, 0, 1, one, logo, lightbar-left"
|
help = "set the zone for this effect e.g, 0, 1, one, logo, lightbar-left"
|
||||||
)]
|
)]
|
||||||
pub zone: AuraZone
|
pub zone: AuraZone,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Options)]
|
#[derive(Debug, Clone, Default, Options)]
|
||||||
|
#[allow(dead_code)]
|
||||||
pub struct MultiZone {
|
pub struct MultiZone {
|
||||||
#[options(help = "print help message")]
|
#[options(help = "print help message")]
|
||||||
help: bool,
|
help: bool,
|
||||||
@@ -191,10 +192,11 @@ pub struct MultiZone {
|
|||||||
#[options(short = "c", meta = "", help = "set the RGB value e.g, ff00ff")]
|
#[options(short = "c", meta = "", help = "set the RGB value e.g, ff00ff")]
|
||||||
pub colour3: Colour,
|
pub colour3: Colour,
|
||||||
#[options(short = "d", meta = "", help = "set the RGB value e.g, ff00ff")]
|
#[options(short = "d", meta = "", help = "set the RGB value e.g, ff00ff")]
|
||||||
pub colour4: Colour
|
pub colour4: Colour,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Options)]
|
#[derive(Debug, Clone, Default, Options)]
|
||||||
|
#[allow(dead_code)]
|
||||||
pub struct MultiColourSpeed {
|
pub struct MultiColourSpeed {
|
||||||
#[options(help = "print help message")]
|
#[options(help = "print help message")]
|
||||||
help: bool,
|
help: bool,
|
||||||
@@ -207,7 +209,7 @@ pub struct MultiColourSpeed {
|
|||||||
#[options(short = "d", meta = "", help = "set the RGB value e.g, ff00ff")]
|
#[options(short = "d", meta = "", help = "set the RGB value e.g, ff00ff")]
|
||||||
pub colour4: Colour,
|
pub colour4: Colour,
|
||||||
#[options(no_long, meta = "", help = "set the speed: low, med, high")]
|
#[options(no_long, meta = "", help = "set the speed: low, med, high")]
|
||||||
pub speed: Speed
|
pub speed: Speed,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Byte value for setting the built-in mode.
|
/// Byte value for setting the built-in mode.
|
||||||
@@ -239,7 +241,7 @@ pub enum SetAuraBuiltin {
|
|||||||
#[options(help = "set a vertical line zooming from left")]
|
#[options(help = "set a vertical line zooming from left")]
|
||||||
Comet(SingleColour), // 11
|
Comet(SingleColour), // 11
|
||||||
#[options(help = "set a wide vertical line zooming from left")]
|
#[options(help = "set a wide vertical line zooming from left")]
|
||||||
Flash(SingleColour) // 12
|
Flash(SingleColour), // 12
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SetAuraBuiltin {
|
impl Default for SetAuraBuiltin {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ pub struct CliStart {
|
|||||||
#[options(help = "Toggle one-shot battery charge to 100%")]
|
#[options(help = "Toggle one-shot battery charge to 100%")]
|
||||||
pub one_shot_chg: bool,
|
pub one_shot_chg: bool,
|
||||||
#[options(command)]
|
#[options(command)]
|
||||||
pub command: Option<CliCommand>
|
pub command: Option<CliCommand>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Options)]
|
#[derive(Options)]
|
||||||
@@ -53,7 +53,9 @@ pub enum CliCommand {
|
|||||||
help = "Change platform settings. This is a new interface exposed by the asus-armoury \
|
help = "Change platform settings. This is a new interface exposed by the asus-armoury \
|
||||||
driver, some of the settings will be the same as the older platform interface"
|
driver, some of the settings will be the same as the older platform interface"
|
||||||
)]
|
)]
|
||||||
Armoury(ArmouryCommand)
|
Armoury(ArmouryCommand),
|
||||||
|
#[options(name = "backlight", help = "Set screen backlight levels")]
|
||||||
|
Backlight(BacklightCommand),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Options)]
|
#[derive(Debug, Clone, Options)]
|
||||||
@@ -71,7 +73,17 @@ pub struct ProfileCommand {
|
|||||||
pub profile_get: bool,
|
pub profile_get: bool,
|
||||||
|
|
||||||
#[options(meta = "", help = "set the active profile")]
|
#[options(meta = "", help = "set the active profile")]
|
||||||
pub profile_set: Option<PlatformProfile>
|
pub profile_set: Option<PlatformProfile>,
|
||||||
|
|
||||||
|
#[options(short = "a", meta = "", help = "set the profile to use on AC power")]
|
||||||
|
pub profile_set_ac: Option<PlatformProfile>,
|
||||||
|
|
||||||
|
#[options(
|
||||||
|
short = "b",
|
||||||
|
meta = "",
|
||||||
|
help = "set the profile to use on battery power"
|
||||||
|
)]
|
||||||
|
pub profile_set_bat: Option<PlatformProfile>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Options)]
|
#[derive(Options)]
|
||||||
@@ -83,13 +95,13 @@ pub struct LedModeCommand {
|
|||||||
#[options(help = "switch to previous aura mode")]
|
#[options(help = "switch to previous aura mode")]
|
||||||
pub prev_mode: bool,
|
pub prev_mode: bool,
|
||||||
#[options(command)]
|
#[options(command)]
|
||||||
pub command: Option<SetAuraBuiltin>
|
pub command: Option<SetAuraBuiltin>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Options)]
|
#[derive(Options)]
|
||||||
pub struct GraphicsCommand {
|
pub struct GraphicsCommand {
|
||||||
#[options(help = "print help message")]
|
#[options(help = "print help message")]
|
||||||
pub help: bool
|
pub help: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Options, Debug)]
|
#[derive(Options, Debug)]
|
||||||
@@ -100,5 +112,23 @@ pub struct ArmouryCommand {
|
|||||||
free,
|
free,
|
||||||
help = "append each value name followed by the value to set. `-1` sets to default"
|
help = "append each value name followed by the value to set. `-1` sets to default"
|
||||||
)]
|
)]
|
||||||
pub free: Vec<String>
|
pub free: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Options)]
|
||||||
|
pub struct BacklightCommand {
|
||||||
|
#[options(help = "print help message")]
|
||||||
|
pub help: bool,
|
||||||
|
#[options(meta = "", help = "Set screen brightness <0-100>")]
|
||||||
|
pub screenpad_brightness: Option<i32>,
|
||||||
|
#[options(
|
||||||
|
meta = "",
|
||||||
|
help = "Set screenpad gamma brightness 0.5 - 2.2, 1.0 == linear"
|
||||||
|
)]
|
||||||
|
pub screenpad_gamma: Option<f32>,
|
||||||
|
#[options(
|
||||||
|
meta = "",
|
||||||
|
help = "Set screenpad brightness to sync with primary display"
|
||||||
|
)]
|
||||||
|
pub sync_screenpad_brightness: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,5 +45,5 @@ pub struct FanCurveCommand {
|
|||||||
help = "data format = 30c:1%,49c:2%,59c:3%,69c:4%,79c:31%,89c:49%,99c:56%,109c:58%. \
|
help = "data format = 30c:1%,49c:2%,59c:3%,69c:4%,79c:31%,89c:49%,99c:56%,109c:58%. \
|
||||||
`--mod-profile` required. If '%' is omitted the fan range is 0-255"
|
`--mod-profile` required. If '%' is omitted the fan range is 0-255"
|
||||||
)]
|
)]
|
||||||
pub data: Option<CurveData>
|
pub data: Option<CurveData>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use aura_cli::{LedPowerCommand1, LedPowerCommand2};
|
|||||||
use dmi_id::DMIID;
|
use dmi_id::DMIID;
|
||||||
use fan_curve_cli::FanCurveCommand;
|
use fan_curve_cli::FanCurveCommand;
|
||||||
use gumdrop::{Opt, Options};
|
use gumdrop::{Opt, Options};
|
||||||
use log::{error, info};
|
use log::{error, info, LevelFilter};
|
||||||
use rog_anime::usb::get_anime_type;
|
use rog_anime::usb::get_anime_type;
|
||||||
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, AnimeType, Vec2};
|
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, AnimeType, Vec2};
|
||||||
use rog_aura::keyboard::{AuraPowerState, LaptopAuraPower};
|
use rog_aura::keyboard::{AuraPowerState, LaptopAuraPower};
|
||||||
@@ -19,6 +19,7 @@ use rog_dbus::list_iface_blocking;
|
|||||||
use rog_dbus::scsi_aura::ScsiAuraProxyBlocking;
|
use rog_dbus::scsi_aura::ScsiAuraProxyBlocking;
|
||||||
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
||||||
use rog_dbus::zbus_aura::AuraProxyBlocking;
|
use rog_dbus::zbus_aura::AuraProxyBlocking;
|
||||||
|
use rog_dbus::zbus_backlight::BacklightProxyBlocking;
|
||||||
use rog_dbus::zbus_fan_curves::FanCurvesProxyBlocking;
|
use rog_dbus::zbus_fan_curves::FanCurvesProxyBlocking;
|
||||||
use rog_dbus::zbus_platform::PlatformProxyBlocking;
|
use rog_dbus::zbus_platform::PlatformProxyBlocking;
|
||||||
use rog_dbus::zbus_slash::SlashProxyBlocking;
|
use rog_dbus::zbus_slash::SlashProxyBlocking;
|
||||||
@@ -43,12 +44,16 @@ mod scsi_cli;
|
|||||||
mod slash_cli;
|
mod slash_cli;
|
||||||
|
|
||||||
fn main() {
|
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();
|
let mut logger = env_logger::Builder::new();
|
||||||
logger
|
logger
|
||||||
.parse_default_env()
|
.parse_default_env()
|
||||||
.target(env_logger::Target::Stdout)
|
.filter_level(LevelFilter::Info)
|
||||||
|
.target(env_logger::Target::Stderr)
|
||||||
.format_timestamp(None)
|
.format_timestamp(None)
|
||||||
.filter_level(log::LevelFilter::Debug)
|
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
let self_version = env!("CARGO_PKG_VERSION");
|
let self_version = env!("CARGO_PKG_VERSION");
|
||||||
@@ -74,22 +79,36 @@ fn main() {
|
|||||||
println!("\nError: {e}\n");
|
println!("\nError: {e}\n");
|
||||||
print_info();
|
print_info();
|
||||||
}) {
|
}) {
|
||||||
let asusd_version = platform_proxy
|
let asusd_version = match platform_proxy.version() {
|
||||||
.version()
|
Ok(version) => version,
|
||||||
.map_err(|e| {
|
Err(e) => {
|
||||||
error!(
|
error!(
|
||||||
"Could not get asusd version: {e:?}\nIs asusd.service running? {}",
|
"Could not get asusd version: {e:?}\nIs asusd.service running? {}",
|
||||||
check_service("asusd")
|
check_service("asusd")
|
||||||
);
|
);
|
||||||
})
|
return;
|
||||||
.unwrap();
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if asusd_version != self_version {
|
if asusd_version != self_version {
|
||||||
println!("Version mismatch: asusctl = {self_version}, asusd = {asusd_version}");
|
println!("Version mismatch: asusctl = {self_version}, asusd = {asusd_version}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let supported_properties = platform_proxy.supported_properties().unwrap();
|
let supported_properties = match platform_proxy.supported_properties() {
|
||||||
let supported_interfaces = list_iface_blocking().unwrap();
|
Ok(props) => props,
|
||||||
|
Err(e) => {
|
||||||
|
error!("Could not get supported properties: {e:?}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let supported_interfaces = match list_iface_blocking() {
|
||||||
|
Ok(ifaces) => ifaces,
|
||||||
|
Err(e) => {
|
||||||
|
error!("Could not get supported interfaces: {e:?}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if parsed.version {
|
if parsed.version {
|
||||||
println!("asusctl v{}", env!("CARGO_PKG_VERSION"));
|
println!("asusctl v{}", env!("CARGO_PKG_VERSION"));
|
||||||
@@ -106,7 +125,7 @@ fn main() {
|
|||||||
fn print_error_help(
|
fn print_error_help(
|
||||||
err: &dyn std::error::Error,
|
err: &dyn std::error::Error,
|
||||||
supported_interfaces: &[String],
|
supported_interfaces: &[String],
|
||||||
supported_properties: &[Properties]
|
supported_properties: &[Properties],
|
||||||
) {
|
) {
|
||||||
check_service("asusd");
|
check_service("asusd");
|
||||||
println!("\nError: {}\n", err);
|
println!("\nError: {}\n", err);
|
||||||
@@ -147,7 +166,7 @@ fn check_service(name: &str) -> bool {
|
|||||||
|
|
||||||
fn find_iface<T>(iface_name: &str) -> Result<Vec<T>, Box<dyn std::error::Error>>
|
fn find_iface<T>(iface_name: &str) -> Result<Vec<T>, Box<dyn std::error::Error>>
|
||||||
where
|
where
|
||||||
T: ProxyImpl<'static> + From<zbus::Proxy<'static>>
|
T: ProxyImpl<'static> + From<zbus::Proxy<'static>>,
|
||||||
{
|
{
|
||||||
let conn = zbus::blocking::Connection::system().unwrap();
|
let conn = zbus::blocking::Connection::system().unwrap();
|
||||||
let f = zbus::blocking::fdo::ObjectManagerProxy::new(&conn, "xyz.ljones.Asusd", "/").unwrap();
|
let f = zbus::blocking::fdo::ObjectManagerProxy::new(&conn, "xyz.ljones.Asusd", "/").unwrap();
|
||||||
@@ -174,7 +193,7 @@ where
|
|||||||
T::builder(&conn)
|
T::builder(&conn)
|
||||||
.path(path.clone())?
|
.path(path.clone())?
|
||||||
.destination("xyz.ljones.Asusd")?
|
.destination("xyz.ljones.Asusd")?
|
||||||
.build()?
|
.build()?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return Ok(ctrl);
|
return Ok(ctrl);
|
||||||
@@ -187,7 +206,7 @@ fn do_parsed(
|
|||||||
parsed: &CliStart,
|
parsed: &CliStart,
|
||||||
supported_interfaces: &[String],
|
supported_interfaces: &[String],
|
||||||
supported_properties: &[Properties],
|
supported_properties: &[Properties],
|
||||||
conn: Connection
|
conn: Connection,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
match &parsed.command {
|
match &parsed.command {
|
||||||
Some(CliCommand::Aura(mode)) => handle_led_mode(mode)?,
|
Some(CliCommand::Aura(mode)) => handle_led_mode(mode)?,
|
||||||
@@ -204,6 +223,7 @@ fn do_parsed(
|
|||||||
Some(CliCommand::Slash(cmd)) => handle_slash(cmd)?,
|
Some(CliCommand::Slash(cmd)) => handle_slash(cmd)?,
|
||||||
Some(CliCommand::Scsi(cmd)) => handle_scsi(cmd)?,
|
Some(CliCommand::Scsi(cmd)) => handle_scsi(cmd)?,
|
||||||
Some(CliCommand::Armoury(cmd)) => handle_armoury_command(cmd)?,
|
Some(CliCommand::Armoury(cmd)) => handle_armoury_command(cmd)?,
|
||||||
|
Some(CliCommand::Backlight(cmd)) => handle_backlight(cmd)?,
|
||||||
None => {
|
None => {
|
||||||
if (!parsed.show_supported
|
if (!parsed.show_supported
|
||||||
&& parsed.kbd_bright.is_none()
|
&& parsed.kbd_bright.is_none()
|
||||||
@@ -259,12 +279,18 @@ fn do_parsed(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if command.trim().starts_with("platform")
|
if command.trim().starts_with("armoury")
|
||||||
&& !supported_interfaces.contains(&"xyz.ljones.AsusArmoury".to_string())
|
&& !supported_interfaces.contains(&"xyz.ljones.AsusArmoury".to_string())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if command.trim().starts_with("backlight")
|
||||||
|
&& !supported_interfaces.contains(&"xyz.ljones.Backlight".to_string())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if !dev_type.is_old_laptop()
|
if !dev_type.is_old_laptop()
|
||||||
&& !dev_type.is_tuf_laptop()
|
&& !dev_type.is_tuf_laptop()
|
||||||
&& command.trim().starts_with("aura-power-old")
|
&& command.trim().starts_with("aura-power-old")
|
||||||
@@ -295,7 +321,7 @@ fn do_parsed(
|
|||||||
let level = aura.brightness()?;
|
let level = aura.brightness()?;
|
||||||
println!("Current keyboard led brightness: {level:?}");
|
println!("Current keyboard led brightness: {level:?}");
|
||||||
}
|
}
|
||||||
Some(level) => aura.set_brightness(rog_aura::LedBrightness::from(level))?
|
Some(level) => aura.set_brightness(rog_aura::LedBrightness::from(level))?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -367,6 +393,46 @@ fn do_gfx() {
|
|||||||
println!("This command will be removed in future");
|
println!("This command will be removed in future");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_backlight(cmd: &BacklightCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
if (cmd.screenpad_brightness.is_none()
|
||||||
|
&& cmd.screenpad_gamma.is_none()
|
||||||
|
&& cmd.sync_screenpad_brightness.is_none())
|
||||||
|
|| cmd.help
|
||||||
|
{
|
||||||
|
println!("Missing arg or command\n\n{}", cmd.self_usage());
|
||||||
|
|
||||||
|
let backlights = find_iface::<BacklightProxyBlocking>("xyz.ljones.Backlight")?;
|
||||||
|
for backlight in backlights {
|
||||||
|
println!("Current screenpad settings:");
|
||||||
|
println!(" Brightness: {}", backlight.screenpad_brightness()?);
|
||||||
|
println!(" Gamma: {}", backlight.screenpad_gamma()?);
|
||||||
|
println!(
|
||||||
|
" Sync with primary: {}",
|
||||||
|
backlight.screenpad_sync_with_primary()?
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let backlights = find_iface::<BacklightProxyBlocking>("xyz.ljones.Backlight")?;
|
||||||
|
for backlight in backlights {
|
||||||
|
if let Some(brightness) = cmd.screenpad_brightness {
|
||||||
|
backlight.set_screenpad_brightness(brightness)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(gamma) = cmd.screenpad_gamma {
|
||||||
|
backlight.set_screenpad_gamma(gamma.to_string().as_str())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sync) = cmd.sync_screenpad_brightness {
|
||||||
|
backlight.set_screenpad_sync_with_primary(sync)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_anime(cmd: &AnimeCommand) -> Result<(), Box<dyn std::error::Error>> {
|
fn handle_anime(cmd: &AnimeCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
if (cmd.command.is_none()
|
if (cmd.command.is_none()
|
||||||
&& cmd.enable_display.is_none()
|
&& cmd.enable_display.is_none()
|
||||||
@@ -444,7 +510,7 @@ fn handle_anime(cmd: &AnimeCommand) -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
image.angle,
|
image.angle,
|
||||||
Vec2::new(image.x_pos, image.y_pos),
|
Vec2::new(image.x_pos, image.y_pos),
|
||||||
image.bright,
|
image.bright,
|
||||||
anime_type
|
anime_type,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
proxy.write(<AnimeDataBuffer>::try_from(&matrix)?)?;
|
proxy.write(<AnimeDataBuffer>::try_from(&matrix)?)?;
|
||||||
@@ -463,7 +529,7 @@ fn handle_anime(cmd: &AnimeCommand) -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
Path::new(&image.path),
|
Path::new(&image.path),
|
||||||
None,
|
None,
|
||||||
image.bright,
|
image.bright,
|
||||||
anime_type
|
anime_type,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
proxy.write(matrix.into_data_buffer(anime_type)?)?;
|
proxy.write(matrix.into_data_buffer(anime_type)?)?;
|
||||||
@@ -485,7 +551,7 @@ fn handle_anime(cmd: &AnimeCommand) -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
Vec2::new(gif.x_pos, gif.y_pos),
|
Vec2::new(gif.x_pos, gif.y_pos),
|
||||||
AnimTime::Count(1),
|
AnimTime::Count(1),
|
||||||
gif.bright,
|
gif.bright,
|
||||||
anime_type
|
anime_type,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut loops = gif.loops as i32;
|
let mut loops = gif.loops as i32;
|
||||||
@@ -516,7 +582,7 @@ fn handle_anime(cmd: &AnimeCommand) -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
Path::new(&gif.path),
|
Path::new(&gif.path),
|
||||||
AnimTime::Count(1),
|
AnimTime::Count(1),
|
||||||
gif.bright,
|
gif.bright,
|
||||||
anime_type
|
anime_type,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut loops = gif.loops as i32;
|
let mut loops = gif.loops as i32;
|
||||||
@@ -549,7 +615,7 @@ fn handle_anime(cmd: &AnimeCommand) -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
boot: builtins.boot,
|
boot: builtins.boot,
|
||||||
awake: builtins.awake,
|
awake: builtins.awake,
|
||||||
sleep: builtins.sleep,
|
sleep: builtins.sleep,
|
||||||
shutdown: builtins.shutdown
|
shutdown: builtins.shutdown,
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -575,6 +641,7 @@ fn handle_slash(cmd: &SlashCommand) -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
&& cmd.show_on_sleep.is_none()
|
&& cmd.show_on_sleep.is_none()
|
||||||
&& cmd.show_on_battery.is_none()
|
&& cmd.show_on_battery.is_none()
|
||||||
&& cmd.show_battery_warning.is_none()
|
&& cmd.show_battery_warning.is_none()
|
||||||
|
// && cmd.show_on_lid_closed.is_none()
|
||||||
&& cmd.mode.is_none()
|
&& cmd.mode.is_none()
|
||||||
&& !cmd.list
|
&& !cmd.list
|
||||||
&& !cmd.enable
|
&& !cmd.enable
|
||||||
@@ -620,6 +687,9 @@ fn handle_slash(cmd: &SlashCommand) -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
if let Some(show) = cmd.show_battery_warning {
|
if let Some(show) = cmd.show_battery_warning {
|
||||||
proxy.set_show_battery_warning(show)?;
|
proxy.set_show_battery_warning(show)?;
|
||||||
}
|
}
|
||||||
|
// if let Some(show) = cmd.show_on_lid_closed {
|
||||||
|
// proxy.set_show_on_lid_closed(show)?;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
if cmd.list {
|
if cmd.list {
|
||||||
let res = SlashMode::list();
|
let res = SlashMode::list();
|
||||||
@@ -812,7 +882,7 @@ fn handle_led_power1(power: &LedPowerCommand1) -> Result<(), Box<dyn std::error:
|
|||||||
|
|
||||||
fn handle_led_power_1_do_1866(
|
fn handle_led_power_1_do_1866(
|
||||||
aura: &AuraProxyBlocking,
|
aura: &AuraProxyBlocking,
|
||||||
power: &LedPowerCommand1
|
power: &LedPowerCommand1,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut states = Vec::new();
|
let mut states = Vec::new();
|
||||||
if power.keyboard {
|
if power.keyboard {
|
||||||
@@ -821,7 +891,7 @@ fn handle_led_power_1_do_1866(
|
|||||||
boot: power.boot.unwrap_or_default(),
|
boot: power.boot.unwrap_or_default(),
|
||||||
awake: power.awake.unwrap_or_default(),
|
awake: power.awake.unwrap_or_default(),
|
||||||
sleep: power.sleep.unwrap_or_default(),
|
sleep: power.sleep.unwrap_or_default(),
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if power.lightbar {
|
if power.lightbar {
|
||||||
@@ -830,7 +900,7 @@ fn handle_led_power_1_do_1866(
|
|||||||
boot: power.boot.unwrap_or_default(),
|
boot: power.boot.unwrap_or_default(),
|
||||||
awake: power.awake.unwrap_or_default(),
|
awake: power.awake.unwrap_or_default(),
|
||||||
sleep: power.sleep.unwrap_or_default(),
|
sleep: power.sleep.unwrap_or_default(),
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -892,7 +962,7 @@ fn handle_led_power2(power: &LedPowerCommand2) -> Result<(), Box<dyn std::error:
|
|||||||
aura_cli::SetAuraZoneEnabled::Lightbar(l) => set(PowerZones::Lightbar, l),
|
aura_cli::SetAuraZoneEnabled::Lightbar(l) => set(PowerZones::Lightbar, l),
|
||||||
aura_cli::SetAuraZoneEnabled::Lid(l) => set(PowerZones::Lid, l),
|
aura_cli::SetAuraZoneEnabled::Lid(l) => set(PowerZones::Lid, l),
|
||||||
aura_cli::SetAuraZoneEnabled::RearGlow(r) => set(PowerZones::RearGlow, r),
|
aura_cli::SetAuraZoneEnabled::RearGlow(r) => set(PowerZones::RearGlow, r),
|
||||||
aura_cli::SetAuraZoneEnabled::Ally(r) => set(PowerZones::Ally, r)
|
aura_cli::SetAuraZoneEnabled::Ally(r) => set(PowerZones::Ally, r),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -906,14 +976,20 @@ fn handle_led_power2(power: &LedPowerCommand2) -> Result<(), Box<dyn std::error:
|
|||||||
fn handle_throttle_profile(
|
fn handle_throttle_profile(
|
||||||
conn: &Connection,
|
conn: &Connection,
|
||||||
supported: &[Properties],
|
supported: &[Properties],
|
||||||
cmd: &ProfileCommand
|
cmd: &ProfileCommand,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
if !supported.contains(&Properties::ThrottlePolicy) {
|
if !supported.contains(&Properties::ThrottlePolicy) {
|
||||||
println!("Profiles not supported by either this kernel or by the laptop.");
|
println!("Profiles not supported by either this kernel or by the laptop.");
|
||||||
return Err(ProfileError::NotSupported.into());
|
return Err(ProfileError::NotSupported.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
if !cmd.next && !cmd.list && cmd.profile_set.is_none() && !cmd.profile_get {
|
if !cmd.next
|
||||||
|
&& !cmd.list
|
||||||
|
&& cmd.profile_set.is_none()
|
||||||
|
&& !cmd.profile_get
|
||||||
|
&& cmd.profile_set_ac.is_none()
|
||||||
|
&& cmd.profile_set_bat.is_none()
|
||||||
|
{
|
||||||
if !cmd.help {
|
if !cmd.help {
|
||||||
println!("Missing arg or command\n");
|
println!("Missing arg or command\n");
|
||||||
}
|
}
|
||||||
@@ -927,22 +1003,31 @@ fn handle_throttle_profile(
|
|||||||
|
|
||||||
let proxy = PlatformProxyBlocking::new(conn)?;
|
let proxy = PlatformProxyBlocking::new(conn)?;
|
||||||
let current = proxy.platform_profile()?;
|
let current = proxy.platform_profile()?;
|
||||||
|
let choices = proxy.platform_profile_choices()?;
|
||||||
|
|
||||||
if cmd.next {
|
if cmd.next {
|
||||||
proxy.set_platform_profile(current.next())?;
|
proxy.set_platform_profile(PlatformProfile::next(current, &choices))?;
|
||||||
} else if let Some(profile) = cmd.profile_set {
|
} else if let Some(profile) = cmd.profile_set {
|
||||||
proxy.set_platform_profile(profile)?;
|
proxy.set_platform_profile(profile)?;
|
||||||
|
} else if let Some(profile) = cmd.profile_set_ac {
|
||||||
|
proxy.set_platform_profile_on_ac(profile)?;
|
||||||
|
} else if let Some(profile) = cmd.profile_set_bat {
|
||||||
|
proxy.set_platform_profile_on_battery(profile)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.list {
|
if cmd.list {
|
||||||
let res = PlatformProfile::list();
|
for p in &choices {
|
||||||
for p in &res {
|
|
||||||
println!("{:?}", p);
|
println!("{:?}", p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.profile_get {
|
if cmd.profile_get {
|
||||||
println!("Active profile is {current:?}");
|
println!("Active profile is {current:?}");
|
||||||
|
println!("Profile on AC is {:?}", proxy.platform_profile_on_ac()?);
|
||||||
|
println!(
|
||||||
|
"Profile on Battery is {:?}",
|
||||||
|
proxy.platform_profile_on_battery()?
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -950,7 +1035,7 @@ fn handle_throttle_profile(
|
|||||||
|
|
||||||
fn handle_fan_curve(
|
fn handle_fan_curve(
|
||||||
conn: &Connection,
|
conn: &Connection,
|
||||||
cmd: &FanCurveCommand
|
cmd: &FanCurveCommand,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let Ok(fan_proxy) = FanCurvesProxyBlocking::new(conn).map_err(|e| {
|
let Ok(fan_proxy) = FanCurvesProxyBlocking::new(conn).map_err(|e| {
|
||||||
println!("Fan-curves not supported by either this kernel or by the laptop: {e:?}");
|
println!("Fan-curves not supported by either this kernel or by the laptop: {e:?}");
|
||||||
@@ -1045,7 +1130,7 @@ fn check_systemd_unit_enabled(name: &str) -> bool {
|
|||||||
.output()
|
.output()
|
||||||
{
|
{
|
||||||
let buf = String::from_utf8_lossy(&out.stdout);
|
let buf = String::from_utf8_lossy(&out.stdout);
|
||||||
return buf.contains("enabled");
|
return buf.contains("enabled") || buf.contains("linked");
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@@ -1103,10 +1188,11 @@ fn print_firmware_attr(attr: &AsusArmouryProxyBlocking) -> Result<(), Box<dyn st
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::manual_is_multiple_of, clippy::nonminimal_bool)]
|
||||||
fn handle_armoury_command(cmd: &ArmouryCommand) -> Result<(), Box<dyn std::error::Error>> {
|
fn handle_armoury_command(cmd: &ArmouryCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
{
|
{
|
||||||
if cmd.free.is_empty() || cmd.free.len() % 2 != 0 || cmd.help {
|
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";
|
const USAGE: &str = "Usage: asusctl armoury panel_overdrive 1 nv_dynamic_boost 5";
|
||||||
if cmd.free.len() % 2 != 0 {
|
if cmd.free.len() % 2 != 0 {
|
||||||
println!(
|
println!(
|
||||||
"Incorrect number of args, each attribute label must be paired with a setting:"
|
"Incorrect number of args, each attribute label must be paired with a setting:"
|
||||||
|
|||||||
@@ -31,5 +31,5 @@ pub struct ScsiCommand {
|
|||||||
pub colours: Vec<Colour>,
|
pub colours: Vec<Colour>,
|
||||||
|
|
||||||
#[options(help = "list available animations")]
|
#[options(help = "list available animations")]
|
||||||
pub list: bool
|
pub list: bool,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,10 +26,12 @@ pub struct SlashCommand {
|
|||||||
pub show_on_sleep: Option<bool>,
|
pub show_on_sleep: Option<bool>,
|
||||||
#[options(short = "b", meta = "", help = "Show the animation on battery")]
|
#[options(short = "b", meta = "", help = "Show the animation on battery")]
|
||||||
pub show_on_battery: Option<bool>,
|
pub show_on_battery: Option<bool>,
|
||||||
|
// #[options(short = "L", meta = "", help = "Show the animation on lid closed")]
|
||||||
|
// pub show_on_lid_closed: Option<bool>,
|
||||||
#[options(
|
#[options(
|
||||||
short = "w",
|
short = "w",
|
||||||
meta = "",
|
meta = "",
|
||||||
help = "Show the low-battery warning animation"
|
help = "Show the low-battery warning animation"
|
||||||
)]
|
)]
|
||||||
pub show_battery_warning: Option<bool>
|
pub show_battery_warning: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,3 +32,16 @@ config-traits = { path = "../config-traits" }
|
|||||||
|
|
||||||
zbus.workspace = true
|
zbus.workspace = true
|
||||||
env_logger.workspace = true
|
env_logger.workspace = true
|
||||||
|
|
||||||
|
[package.metadata.deb]
|
||||||
|
license-file = ["../LICENSE", "4"]
|
||||||
|
extended-description = """\
|
||||||
|
An user utility for Linux to control fancy things on various ASUS laptops
|
||||||
|
like keyboard effects or anime matrix animation cycles."""
|
||||||
|
depends = "$auto"
|
||||||
|
section = "utility"
|
||||||
|
priority = "optional"
|
||||||
|
assets = [
|
||||||
|
["target/release/asusd-user", "usr/bin/", "755"],
|
||||||
|
["../asusd_user-fakeinstall/usr/lib/systemd/user/*", "usr/lib/systemd/user/", "644"],
|
||||||
|
]
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ fn root_conf_dir() -> PathBuf {
|
|||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
pub struct ConfigAnime {
|
pub struct ConfigAnime {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub anime: Vec<ActionLoader>
|
pub anime: Vec<ActionLoader>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConfigAnime {
|
impl ConfigAnime {
|
||||||
@@ -52,8 +52,8 @@ impl Default for ConfigAnime {
|
|||||||
time: AnimTime::Fade(Fade::new(
|
time: AnimTime::Fade(Fade::new(
|
||||||
Duration::from_secs(2),
|
Duration::from_secs(2),
|
||||||
None,
|
None,
|
||||||
Duration::from_secs(2)
|
Duration::from_secs(2),
|
||||||
))
|
)),
|
||||||
},
|
},
|
||||||
ActionLoader::AsusAnimation {
|
ActionLoader::AsusAnimation {
|
||||||
file: "/usr/share/asusd/anime/asus/rog/Sunset.gif".into(),
|
file: "/usr/share/asusd/anime/asus/rog/Sunset.gif".into(),
|
||||||
@@ -61,8 +61,8 @@ impl Default for ConfigAnime {
|
|||||||
time: AnimTime::Fade(Fade::new(
|
time: AnimTime::Fade(Fade::new(
|
||||||
Duration::from_secs(6),
|
Duration::from_secs(6),
|
||||||
None,
|
None,
|
||||||
Duration::from_secs(3)
|
Duration::from_secs(3),
|
||||||
))
|
)),
|
||||||
},
|
},
|
||||||
ActionLoader::ImageAnimation {
|
ActionLoader::ImageAnimation {
|
||||||
file: "/usr/share/asusd/anime/custom/sonic-run.gif".into(),
|
file: "/usr/share/asusd/anime/custom/sonic-run.gif".into(),
|
||||||
@@ -73,8 +73,8 @@ impl Default for ConfigAnime {
|
|||||||
time: AnimTime::Fade(Fade::new(
|
time: AnimTime::Fade(Fade::new(
|
||||||
Duration::from_secs(2),
|
Duration::from_secs(2),
|
||||||
Some(Duration::from_secs(2)),
|
Some(Duration::from_secs(2)),
|
||||||
Duration::from_secs(2)
|
Duration::from_secs(2),
|
||||||
))
|
)),
|
||||||
},
|
},
|
||||||
ActionLoader::Image {
|
ActionLoader::Image {
|
||||||
file: "/usr/share/asusd/anime/custom/rust.png".into(),
|
file: "/usr/share/asusd/anime/custom/rust.png".into(),
|
||||||
@@ -84,9 +84,9 @@ impl Default for ConfigAnime {
|
|||||||
time: AnimTime::Fade(Fade::new(
|
time: AnimTime::Fade(Fade::new(
|
||||||
Duration::from_secs(2),
|
Duration::from_secs(2),
|
||||||
Some(Duration::from_secs(1)),
|
Some(Duration::from_secs(1)),
|
||||||
Duration::from_secs(2)
|
Duration::from_secs(2),
|
||||||
)),
|
)),
|
||||||
brightness: 0.6
|
brightness: 0.6,
|
||||||
},
|
},
|
||||||
ActionLoader::Pause(Duration::from_secs(1)),
|
ActionLoader::Pause(Duration::from_secs(1)),
|
||||||
ActionLoader::ImageAnimation {
|
ActionLoader::ImageAnimation {
|
||||||
@@ -95,9 +95,9 @@ impl Default for ConfigAnime {
|
|||||||
angle: 0.0,
|
angle: 0.0,
|
||||||
translation: Vec2::new(3.0, 2.0),
|
translation: Vec2::new(3.0, 2.0),
|
||||||
brightness: 0.5,
|
brightness: 0.5,
|
||||||
time: AnimTime::Count(2)
|
time: AnimTime::Count(2),
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,7 +121,7 @@ impl StdConfigLoad for ConfigAnime {}
|
|||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
pub struct ConfigAura {
|
pub struct ConfigAura {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub aura: AuraSequences
|
pub aura: AuraSequences,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConfigAura {
|
impl ConfigAura {
|
||||||
@@ -139,14 +139,14 @@ impl Default for ConfigAura {
|
|||||||
Colour {
|
Colour {
|
||||||
r: 255,
|
r: 255,
|
||||||
g: 0,
|
g: 0,
|
||||||
b: 20
|
b: 20,
|
||||||
},
|
},
|
||||||
Colour {
|
Colour {
|
||||||
r: 20,
|
r: 20,
|
||||||
g: 255,
|
g: 255,
|
||||||
b: 0
|
b: 0,
|
||||||
},
|
},
|
||||||
Speed::Low
|
Speed::Low,
|
||||||
));
|
));
|
||||||
|
|
||||||
seq.push(key.clone());
|
seq.push(key.clone());
|
||||||
@@ -161,7 +161,7 @@ impl Default for ConfigAura {
|
|||||||
LedCode::F,
|
LedCode::F,
|
||||||
Colour { r: 255, g: 0, b: 0 },
|
Colour { r: 255, g: 0, b: 0 },
|
||||||
Colour { r: 255, g: 0, b: 0 },
|
Colour { r: 255, g: 0, b: 0 },
|
||||||
Speed::High
|
Speed::High,
|
||||||
));
|
));
|
||||||
seq.push(key);
|
seq.push(key);
|
||||||
|
|
||||||
@@ -176,13 +176,13 @@ impl Default for ConfigAura {
|
|||||||
LedCode::N9,
|
LedCode::N9,
|
||||||
Colour { r: 0, g: 0, b: 255 },
|
Colour { r: 0, g: 0, b: 255 },
|
||||||
80,
|
80,
|
||||||
40
|
40,
|
||||||
));
|
));
|
||||||
seq.push(key);
|
seq.push(key);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
name: "aura-default".to_owned(),
|
name: "aura-default".to_owned(),
|
||||||
aura: seq
|
aura: seq,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -209,14 +209,14 @@ pub struct ConfigBase {
|
|||||||
/// Name of active anime config file in the user config directory
|
/// Name of active anime config file in the user config directory
|
||||||
pub active_anime: Option<String>,
|
pub active_anime: Option<String>,
|
||||||
/// Name of active aura config file in the user config directory
|
/// Name of active aura config file in the user config directory
|
||||||
pub active_aura: Option<String>
|
pub active_aura: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StdConfig for ConfigBase {
|
impl StdConfig for ConfigBase {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
active_anime: Some("anime-default".to_owned()),
|
active_anime: Some("anime-default".to_owned()),
|
||||||
active_aura: Some("aura-default".to_owned())
|
active_aura: Some("aura-default".to_owned()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ pub struct Timer {
|
|||||||
/// Used only for `TimeType::Timer`, milliseonds to fade the image in for
|
/// Used only for `TimeType::Timer`, milliseonds to fade the image in for
|
||||||
fade_in: u64,
|
fade_in: u64,
|
||||||
/// Used only for `TimeType::Timer`, milliseonds to fade the image out for
|
/// Used only for `TimeType::Timer`, milliseonds to fade the image out for
|
||||||
fade_out: u64
|
fade_out: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Timer> for AnimTime {
|
impl From<Timer> for AnimTime {
|
||||||
@@ -46,7 +46,7 @@ impl From<Timer> for AnimTime {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TimeType::Count => AnimTime::Count(time.count as u32),
|
TimeType::Count => AnimTime::Count(time.count as u32),
|
||||||
TimeType::Infinite => AnimTime::Infinite
|
TimeType::Infinite => AnimTime::Infinite,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ impl From<Timer> for AnimTime {
|
|||||||
pub enum TimeType {
|
pub enum TimeType {
|
||||||
Timer,
|
Timer,
|
||||||
Count,
|
Count,
|
||||||
Infinite
|
Infinite,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The inner object exists to allow the zbus proxy to share it with a runner
|
/// The inner object exists to allow the zbus proxy to share it with a runner
|
||||||
@@ -63,19 +63,19 @@ pub enum TimeType {
|
|||||||
pub struct CtrlAnimeInner<'a> {
|
pub struct CtrlAnimeInner<'a> {
|
||||||
sequences: Sequences,
|
sequences: Sequences,
|
||||||
client: AnimeProxyBlocking<'a>,
|
client: AnimeProxyBlocking<'a>,
|
||||||
do_early_return: Arc<AtomicBool>
|
do_early_return: Arc<AtomicBool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CtrlAnimeInner<'static> {
|
impl CtrlAnimeInner<'static> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
sequences: Sequences,
|
sequences: Sequences,
|
||||||
client: AnimeProxyBlocking<'static>,
|
client: AnimeProxyBlocking<'static>,
|
||||||
do_early_return: Arc<AtomicBool>
|
do_early_return: Arc<AtomicBool>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
sequences,
|
sequences,
|
||||||
client,
|
client,
|
||||||
do_early_return
|
do_early_return,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ pub struct CtrlAnime<'a> {
|
|||||||
client: AnimeProxyBlocking<'a>,
|
client: AnimeProxyBlocking<'a>,
|
||||||
inner: Arc<Mutex<CtrlAnimeInner<'a>>>,
|
inner: Arc<Mutex<CtrlAnimeInner<'a>>>,
|
||||||
/// Must be the same Atomic as in CtrlAnimeInner
|
/// Must be the same Atomic as in CtrlAnimeInner
|
||||||
inner_early_return: Arc<AtomicBool>
|
inner_early_return: Arc<AtomicBool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CtrlAnime<'static> {
|
impl CtrlAnime<'static> {
|
||||||
@@ -138,13 +138,13 @@ impl CtrlAnime<'static> {
|
|||||||
config: Arc<Mutex<ConfigAnime>>,
|
config: Arc<Mutex<ConfigAnime>>,
|
||||||
inner: Arc<Mutex<CtrlAnimeInner<'static>>>,
|
inner: Arc<Mutex<CtrlAnimeInner<'static>>>,
|
||||||
client: AnimeProxyBlocking<'static>,
|
client: AnimeProxyBlocking<'static>,
|
||||||
inner_early_return: Arc<AtomicBool>
|
inner_early_return: Arc<AtomicBool>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
Ok(CtrlAnime {
|
Ok(CtrlAnime {
|
||||||
config,
|
config,
|
||||||
client,
|
client,
|
||||||
inner,
|
inner,
|
||||||
inner_early_return
|
inner_early_return,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ impl CtrlAnime<'static> {
|
|||||||
index: u32,
|
index: u32,
|
||||||
file: &str,
|
file: &str,
|
||||||
time: Timer,
|
time: Timer,
|
||||||
brightness: f32
|
brightness: f32,
|
||||||
) -> zbus::fdo::Result<String> {
|
) -> zbus::fdo::Result<String> {
|
||||||
if let Ok(mut config) = self.config.try_lock() {
|
if let Ok(mut config) = self.config.try_lock() {
|
||||||
let time: AnimTime = time.into();
|
let time: AnimTime = time.into();
|
||||||
@@ -182,7 +182,7 @@ impl CtrlAnime<'static> {
|
|||||||
let action = ActionLoader::AsusAnimation {
|
let action = ActionLoader::AsusAnimation {
|
||||||
file: file.into(),
|
file: file.into(),
|
||||||
brightness,
|
brightness,
|
||||||
time
|
time,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Must make the inner run loop return early
|
// Must make the inner run loop return early
|
||||||
@@ -216,7 +216,7 @@ impl CtrlAnime<'static> {
|
|||||||
angle: f32,
|
angle: f32,
|
||||||
xy: (f32, f32),
|
xy: (f32, f32),
|
||||||
time: Timer,
|
time: Timer,
|
||||||
brightness: f32
|
brightness: f32,
|
||||||
) -> zbus::fdo::Result<String> {
|
) -> zbus::fdo::Result<String> {
|
||||||
if let Ok(mut config) = self.config.try_lock() {
|
if let Ok(mut config) = self.config.try_lock() {
|
||||||
let time: AnimTime = time.into();
|
let time: AnimTime = time.into();
|
||||||
@@ -228,7 +228,7 @@ impl CtrlAnime<'static> {
|
|||||||
angle,
|
angle,
|
||||||
translation,
|
translation,
|
||||||
brightness,
|
brightness,
|
||||||
time
|
time,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Must make the inner run loop return early
|
// Must make the inner run loop return early
|
||||||
@@ -261,7 +261,7 @@ impl CtrlAnime<'static> {
|
|||||||
angle: f32,
|
angle: f32,
|
||||||
xy: (f32, f32),
|
xy: (f32, f32),
|
||||||
time: Timer,
|
time: Timer,
|
||||||
brightness: f32
|
brightness: f32,
|
||||||
) -> zbus::fdo::Result<String> {
|
) -> zbus::fdo::Result<String> {
|
||||||
if let Ok(mut config) = self.config.try_lock() {
|
if let Ok(mut config) = self.config.try_lock() {
|
||||||
let file = Path::new(&file);
|
let file = Path::new(&file);
|
||||||
@@ -272,7 +272,7 @@ impl CtrlAnime<'static> {
|
|||||||
angle,
|
angle,
|
||||||
translation: Vec2::new(xy.0, xy.1),
|
translation: Vec2::new(xy.0, xy.1),
|
||||||
brightness,
|
brightness,
|
||||||
time
|
time,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Must make the inner run loop return early
|
// Must make the inner run loop return early
|
||||||
|
|||||||
@@ -61,16 +61,16 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
CtrlAnimeInner::new(
|
CtrlAnimeInner::new(
|
||||||
anime,
|
anime,
|
||||||
anime_proxy_blocking.clone(),
|
anime_proxy_blocking.clone(),
|
||||||
early_return.clone()
|
early_return.clone(),
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap(),
|
||||||
));
|
));
|
||||||
// Need new client object for dbus control part
|
// Need new client object for dbus control part
|
||||||
let anime_control = CtrlAnime::new(
|
let anime_control = CtrlAnime::new(
|
||||||
anime_config,
|
anime_config,
|
||||||
inner.clone(),
|
inner.clone(),
|
||||||
anime_proxy_blocking,
|
anime_proxy_blocking,
|
||||||
early_return
|
early_return,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
anime_control.add_to_server(&mut connection).await;
|
anime_control.add_to_server(&mut connection).await;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ pub enum Error {
|
|||||||
ConfigLoadFail,
|
ConfigLoadFail,
|
||||||
ConfigLockFail,
|
ConfigLockFail,
|
||||||
XdgVars,
|
XdgVars,
|
||||||
Anime(AnimeError)
|
Anime(AnimeError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
@@ -19,7 +19,7 @@ impl fmt::Display for Error {
|
|||||||
Error::ConfigLoadFail => write!(f, "Failed to load user config"),
|
Error::ConfigLoadFail => write!(f, "Failed to load user config"),
|
||||||
Error::ConfigLockFail => write!(f, "Failed to lock user config"),
|
Error::ConfigLockFail => write!(f, "Failed to lock user config"),
|
||||||
Error::XdgVars => write!(f, "XDG environment vars appear unset"),
|
Error::XdgVars => write!(f, "XDG environment vars appear unset"),
|
||||||
Error::Anime(err) => write!(f, "Anime error: {}", err)
|
Error::Anime(err) => write!(f, "Anime error: {}", err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ trait Daemon {
|
|||||||
file: &str,
|
file: &str,
|
||||||
time: u32,
|
time: u32,
|
||||||
count: u32,
|
count: u32,
|
||||||
brightness: f64
|
brightness: f64,
|
||||||
) -> zbus::Result<String>;
|
) -> zbus::Result<String>;
|
||||||
|
|
||||||
/// InsertImage method
|
/// InsertImage method
|
||||||
@@ -43,7 +43,7 @@ trait Daemon {
|
|||||||
scale: f64,
|
scale: f64,
|
||||||
angle: f64,
|
angle: f64,
|
||||||
xy: &(f64, f64),
|
xy: &(f64, f64),
|
||||||
brightness: f64
|
brightness: f64,
|
||||||
) -> zbus::Result<String>;
|
) -> zbus::Result<String>;
|
||||||
|
|
||||||
/// InsertImageGif method
|
/// InsertImageGif method
|
||||||
@@ -56,7 +56,7 @@ trait Daemon {
|
|||||||
xy: &(f64, f64),
|
xy: &(f64, f64),
|
||||||
time: u32,
|
time: u32,
|
||||||
count: u32,
|
count: u32,
|
||||||
brightness: f64
|
brightness: f64,
|
||||||
) -> zbus::Result<String>;
|
) -> zbus::Result<String>;
|
||||||
|
|
||||||
/// InsertPause method
|
/// InsertPause method
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ tokio.workspace = true
|
|||||||
log.workspace = true
|
log.workspace = true
|
||||||
env_logger.workspace = true
|
env_logger.workspace = true
|
||||||
|
|
||||||
|
futures-util.workspace = true
|
||||||
zbus.workspace = true
|
zbus.workspace = true
|
||||||
logind-zbus.workspace = true
|
logind-zbus.workspace = true
|
||||||
|
|
||||||
@@ -44,3 +45,18 @@ concat-idents.workspace = true
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
cargo-husky.workspace = true
|
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"],
|
||||||
|
]
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ::zbus::export::futures_util::lock::Mutex;
|
|
||||||
use config_traits::StdConfig;
|
use config_traits::StdConfig;
|
||||||
use log::{debug, error, info};
|
use log::{debug, error, info, warn};
|
||||||
use rog_platform::asus_armoury::{AttrValue, Attribute, FirmwareAttribute, FirmwareAttributes};
|
use rog_platform::asus_armoury::{AttrValue, Attribute, FirmwareAttribute, FirmwareAttributes};
|
||||||
use rog_platform::platform::{PlatformProfile, RogPlatform};
|
use rog_platform::platform::{PlatformProfile, RogPlatform};
|
||||||
use rog_platform::power::AsusPower;
|
use rog_platform::power::AsusPower;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tokio::sync::Mutex;
|
||||||
use zbus::object_server::SignalEmitter;
|
use zbus::object_server::SignalEmitter;
|
||||||
use zbus::zvariant::{ObjectPath, OwnedObjectPath, OwnedValue, Type, Value};
|
use zbus::zvariant::{ObjectPath, OwnedObjectPath, OwnedValue, Type, Value};
|
||||||
use zbus::{fdo, interface, Connection};
|
use zbus::{fdo, interface, Connection};
|
||||||
@@ -20,7 +20,7 @@ const MOD_NAME: &str = "asus_armoury";
|
|||||||
#[derive(Debug, Default, Clone, Deserialize, Serialize, Type, Value, OwnedValue)]
|
#[derive(Debug, Default, Clone, Deserialize, Serialize, Type, Value, OwnedValue)]
|
||||||
pub struct PossibleValues {
|
pub struct PossibleValues {
|
||||||
strings: Vec<String>,
|
strings: Vec<String>,
|
||||||
nums: Vec<i32>
|
nums: Vec<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dbus_path_for_attr(attr_name: &str) -> OwnedObjectPath {
|
fn dbus_path_for_attr(attr_name: &str) -> OwnedObjectPath {
|
||||||
@@ -33,7 +33,7 @@ pub struct AsusArmouryAttribute {
|
|||||||
config: Arc<Mutex<Config>>,
|
config: Arc<Mutex<Config>>,
|
||||||
/// platform control required here for access to PPD or Throttle profile
|
/// platform control required here for access to PPD or Throttle profile
|
||||||
platform: RogPlatform,
|
platform: RogPlatform,
|
||||||
power: AsusPower
|
power: AsusPower,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsusArmouryAttribute {
|
impl AsusArmouryAttribute {
|
||||||
@@ -41,16 +41,39 @@ impl AsusArmouryAttribute {
|
|||||||
attr: Attribute,
|
attr: Attribute,
|
||||||
platform: RogPlatform,
|
platform: RogPlatform,
|
||||||
power: AsusPower,
|
power: AsusPower,
|
||||||
config: Arc<Mutex<Config>>
|
config: Arc<Mutex<Config>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
attr,
|
attr,
|
||||||
config,
|
config,
|
||||||
platform,
|
platform,
|
||||||
power
|
power,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn attribute_name(&self) -> String {
|
||||||
|
String::from(self.attr.name())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resolve_i32_value(refreshed: Option<i32>, cached: &AttrValue) -> i32 {
|
||||||
|
refreshed
|
||||||
|
.or(match cached {
|
||||||
|
AttrValue::Integer(i) => Some(*i),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.unwrap_or(-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn emit_limits(&self, connection: &Connection) -> Result<(), RogError> {
|
||||||
|
let path = dbus_path_for_attr(self.attr.name());
|
||||||
|
let signal = SignalEmitter::new(connection, path)?;
|
||||||
|
self.min_value_changed(&signal).await?;
|
||||||
|
self.max_value_changed(&signal).await?;
|
||||||
|
self.scalar_increment_changed(&signal).await?;
|
||||||
|
self.current_value_changed(&signal).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn move_to_zbus(self, connection: &Connection) -> Result<(), RogError> {
|
pub async fn move_to_zbus(self, connection: &Connection) -> Result<(), RogError> {
|
||||||
let path = dbus_path_for_attr(self.attr.name());
|
let path = dbus_path_for_attr(self.attr.name());
|
||||||
connection
|
connection
|
||||||
@@ -64,9 +87,9 @@ impl AsusArmouryAttribute {
|
|||||||
|
|
||||||
async fn watch_and_notify(
|
async fn watch_and_notify(
|
||||||
&mut self,
|
&mut self,
|
||||||
signal_ctxt: SignalEmitter<'static>
|
signal_ctxt: SignalEmitter<'static>,
|
||||||
) -> Result<(), RogError> {
|
) -> Result<(), RogError> {
|
||||||
use zbus::export::futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
|
|
||||||
let name = self.name();
|
let name = self.name();
|
||||||
macro_rules! watch_value_notify {
|
macro_rules! watch_value_notify {
|
||||||
@@ -78,21 +101,27 @@ impl AsusArmouryAttribute {
|
|||||||
let sig = signal_ctxt.clone();
|
let sig = signal_ctxt.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut buffer = [0; 32];
|
let mut buffer = [0; 32];
|
||||||
watch
|
if let Ok(stream) = watch.into_event_stream(&mut buffer) {
|
||||||
.into_event_stream(&mut buffer)
|
stream
|
||||||
.unwrap()
|
.for_each(|_| async {
|
||||||
.for_each(|_| async {
|
debug!("{} changed", name);
|
||||||
debug!("{} changed", name);
|
ctrl.$fn_prop_changed(&sig).await.ok();
|
||||||
ctrl.$fn_prop_changed(&sig).await.ok();
|
})
|
||||||
})
|
.await;
|
||||||
.await;
|
} else {
|
||||||
|
info!(
|
||||||
|
"inotify event stream failed for {} ({}). You can ignore this \
|
||||||
|
if unsupported",
|
||||||
|
name, $attr_str
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Err(e) => info!(
|
Err(e) => info!(
|
||||||
"inotify watch failed: {}. You can ignore this if your device does not \
|
"inotify watch failed: {}. You can ignore this if your device does not \
|
||||||
support the feature",
|
support the feature",
|
||||||
e
|
e
|
||||||
)
|
),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -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 {
|
impl crate::Reloadable for AsusArmouryAttribute {
|
||||||
async fn reload(&mut self) -> Result<(), RogError> {
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
info!("Reloading {}", self.attr.name());
|
info!("Reloading {}", self.attr.name());
|
||||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
let name: FirmwareAttribute = self.attr.name().into();
|
||||||
let power_plugged = self
|
|
||||||
.power
|
// Treat dGPU attributes the same as PPT attributes for power-profile
|
||||||
.get_online()
|
// behaviour so they follow AC/DC tuning groups.
|
||||||
.map_err(|e| {
|
if name.is_ppt() || name.is_dgpu() {
|
||||||
error!("Could not get power status: {e:?}");
|
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||||
e
|
let power_plugged = self
|
||||||
})
|
.power
|
||||||
.unwrap_or_default();
|
.get_online()
|
||||||
let config = if power_plugged == 1 {
|
.map_err(|e| {
|
||||||
&self.config.lock().await.ac_profile_tunings
|
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 {
|
} else {
|
||||||
&self.config.lock().await.dc_profile_tunings
|
// Handle non-PPT attributes (boolean and other settings)
|
||||||
};
|
if let Some(saved_value) = self.config.lock().await.armoury_settings.get(&name) {
|
||||||
if let Some(tuning) = config.get(&profile) {
|
self.attr
|
||||||
if tuning.enabled {
|
.set_current_value(&AttrValue::Integer(*saved_value))
|
||||||
if let Some(tune) = tuning.group.get(&self.name()) {
|
.map_err(|e| {
|
||||||
self.attr
|
error!(
|
||||||
.set_current_value(&AttrValue::Integer(*tune))
|
"Error restoring armoury setting {}: {e:?}",
|
||||||
.map_err(|e| {
|
self.attr.name()
|
||||||
error!("Could not set {} value: {e:?}", self.attr.name());
|
);
|
||||||
self.attr.base_path_exists();
|
self.attr.base_path_exists();
|
||||||
e
|
e
|
||||||
})?;
|
})?;
|
||||||
info!("Set {} to {:?}", self.attr.name(), tune);
|
info!(
|
||||||
}
|
"Restored armoury setting {} to {:?}",
|
||||||
|
self.attr.name(),
|
||||||
|
saved_value
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
info!(
|
||||||
|
"No saved armoury setting for {}: skipping restore",
|
||||||
|
self.attr.name()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,13 +287,13 @@ impl AsusArmouryAttribute {
|
|||||||
async fn default_value(&self) -> i32 {
|
async fn default_value(&self) -> i32 {
|
||||||
match self.attr.default_value() {
|
match self.attr.default_value() {
|
||||||
AttrValue::Integer(i) => *i,
|
AttrValue::Integer(i) => *i,
|
||||||
_ => -1
|
_ => -1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn restore_default(&self) -> fdo::Result<()> {
|
async fn restore_default(&self) -> fdo::Result<()> {
|
||||||
self.attr.restore_default()?;
|
self.attr.restore_default()?;
|
||||||
if self.name().is_ppt() {
|
if self.name().is_ppt() || self.name().is_dgpu() {
|
||||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||||
let power_plugged = self
|
let power_plugged = self
|
||||||
.power
|
.power
|
||||||
@@ -226,39 +326,33 @@ impl AsusArmouryAttribute {
|
|||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
async fn min_value(&self) -> i32 {
|
async fn min_value(&self) -> i32 {
|
||||||
match self.attr.min_value() {
|
Self::resolve_i32_value(self.attr.refresh_min_value(), self.attr.min_value())
|
||||||
AttrValue::Integer(i) => *i,
|
|
||||||
_ => -1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
async fn max_value(&self) -> i32 {
|
async fn max_value(&self) -> i32 {
|
||||||
match self.attr.max_value() {
|
Self::resolve_i32_value(self.attr.refresh_max_value(), self.attr.max_value())
|
||||||
AttrValue::Integer(i) => *i,
|
|
||||||
_ => -1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
async fn scalar_increment(&self) -> i32 {
|
async fn scalar_increment(&self) -> i32 {
|
||||||
match self.attr.scalar_increment() {
|
Self::resolve_i32_value(
|
||||||
AttrValue::Integer(i) => *i,
|
self.attr.refresh_scalar_increment(),
|
||||||
_ => -1
|
self.attr.scalar_increment(),
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
async fn possible_values(&self) -> Vec<i32> {
|
async fn possible_values(&self) -> Vec<i32> {
|
||||||
match self.attr.possible_values() {
|
match self.attr.possible_values() {
|
||||||
AttrValue::EnumInt(i) => i.clone(),
|
AttrValue::EnumInt(i) => i.clone(),
|
||||||
_ => Vec::default()
|
_ => Vec::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
async fn current_value(&self) -> fdo::Result<i32> {
|
async fn current_value(&self) -> fdo::Result<i32> {
|
||||||
if self.name().is_ppt() {
|
if self.name().is_ppt() || self.name().is_dgpu() {
|
||||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||||
let power_plugged = self
|
let power_plugged = self
|
||||||
.power
|
.power
|
||||||
@@ -267,16 +361,19 @@ impl AsusArmouryAttribute {
|
|||||||
error!("Could not get power status: {e:?}");
|
error!("Could not get power status: {e:?}");
|
||||||
e
|
e
|
||||||
})
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default()
|
||||||
let mut config = self.config.lock().await;
|
== 1;
|
||||||
let tuning = config.select_tunings(power_plugged == 1, profile);
|
let config = self.config.lock().await;
|
||||||
if let Some(tune) = tuning.group.get(&self.name()) {
|
if let Some(tuning) = config.select_tunings_ref(power_plugged, profile) {
|
||||||
return Ok(*tune);
|
if let Some(tune) = tuning.group.get(&self.name()) {
|
||||||
} else if let AttrValue::Integer(i) = self.attr.default_value() {
|
return Ok(*tune);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let AttrValue::Integer(i) = self.attr.default_value() {
|
||||||
return Ok(*i);
|
return Ok(*i);
|
||||||
}
|
}
|
||||||
return Err(fdo::Error::Failed(
|
return Err(fdo::Error::Failed(
|
||||||
"Could not read current value".to_string()
|
"Could not read current value".to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,13 +381,13 @@ impl AsusArmouryAttribute {
|
|||||||
return Ok(i);
|
return Ok(i);
|
||||||
}
|
}
|
||||||
Err(fdo::Error::Failed(
|
Err(fdo::Error::Failed(
|
||||||
"Could not read current value".to_string()
|
"Could not read current value".to_string(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
async fn set_current_value(&mut self, value: i32) -> fdo::Result<()> {
|
async fn set_current_value(&mut self, value: i32) -> fdo::Result<()> {
|
||||||
if self.name().is_ppt() {
|
if self.name().is_ppt() || self.name().is_dgpu() {
|
||||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||||
let power_plugged = self
|
let power_plugged = self
|
||||||
.power
|
.power
|
||||||
@@ -314,44 +411,44 @@ impl AsusArmouryAttribute {
|
|||||||
self.attr
|
self.attr
|
||||||
.set_current_value(&AttrValue::Integer(value))
|
.set_current_value(&AttrValue::Integer(value))
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
error!("Could not set value: {e:?}");
|
error!(
|
||||||
|
"Could not set value to PPT property {}: {e:?}",
|
||||||
|
self.attr.name()
|
||||||
|
);
|
||||||
e
|
e
|
||||||
})?;
|
})?;
|
||||||
|
} else {
|
||||||
|
warn!(
|
||||||
|
"Tuning group is disabled: skipping setting value to PPT property {}",
|
||||||
|
self.attr.name()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.attr
|
self.attr
|
||||||
.set_current_value(&AttrValue::Integer(value))
|
.set_current_value(&AttrValue::Integer(value))
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
error!("Could not set value: {e:?}");
|
error!(
|
||||||
|
"Could not set value {value} to attribute {}: {e:?}",
|
||||||
|
self.attr.name()
|
||||||
|
);
|
||||||
e
|
e
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let has_attr = self
|
let mut settings = self.config.lock().await;
|
||||||
.config
|
settings
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.armoury_settings
|
.armoury_settings
|
||||||
.contains_key(&self.name());
|
.entry(self.name())
|
||||||
if has_attr {
|
.and_modify(|setting| {
|
||||||
if let Some(setting) = self
|
debug!("Set config for {} = {value}", self.attr.name());
|
||||||
.config
|
*setting = value;
|
||||||
.lock()
|
})
|
||||||
.await
|
.or_insert_with(|| {
|
||||||
.armoury_settings
|
debug!("Adding config for {} = {value}", self.attr.name());
|
||||||
.get_mut(&self.name())
|
value
|
||||||
{
|
});
|
||||||
*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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write config after setting value
|
||||||
self.config.lock().await.write();
|
self.config.lock().await.write();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -362,35 +459,63 @@ pub async fn start_attributes_zbus(
|
|||||||
platform: RogPlatform,
|
platform: RogPlatform,
|
||||||
power: AsusPower,
|
power: AsusPower,
|
||||||
attributes: FirmwareAttributes,
|
attributes: FirmwareAttributes,
|
||||||
config: Arc<Mutex<Config>>
|
config: Arc<Mutex<Config>>,
|
||||||
) -> Result<(), RogError> {
|
) -> Result<ArmouryAttributeRegistry, RogError> {
|
||||||
|
let mut registry = ArmouryAttributeRegistry::default();
|
||||||
for attr in attributes.attributes() {
|
for attr in attributes.attributes() {
|
||||||
let mut attr = AsusArmouryAttribute::new(
|
let mut attr = AsusArmouryAttribute::new(
|
||||||
attr.clone(),
|
attr.clone(),
|
||||||
platform.clone(),
|
platform.clone(),
|
||||||
power.clone(),
|
power.clone(),
|
||||||
config.clone()
|
config.clone(),
|
||||||
);
|
);
|
||||||
attr.reload().await?;
|
|
||||||
|
|
||||||
let path = dbus_path_for_attr(attr.attr.name());
|
let registry_attr = attr.clone();
|
||||||
let sig = zbus::object_server::SignalEmitter::new(conn, path)?;
|
|
||||||
attr.watch_and_notify(sig).await?;
|
|
||||||
|
|
||||||
attr.move_to_zbus(conn).await?;
|
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(
|
pub async fn set_config_or_default(
|
||||||
attrs: &FirmwareAttributes,
|
attrs: &FirmwareAttributes,
|
||||||
config: &mut Config,
|
config: &mut Config,
|
||||||
power_plugged: bool,
|
power_plugged: bool,
|
||||||
profile: PlatformProfile
|
profile: PlatformProfile,
|
||||||
) {
|
) {
|
||||||
for attr in attrs.attributes().iter() {
|
for attr in attrs.attributes().iter() {
|
||||||
let name: FirmwareAttribute = attr.name().into();
|
let name: FirmwareAttribute = attr.name().into();
|
||||||
if name.is_ppt() {
|
if name.is_ppt() || name.is_dgpu() {
|
||||||
let tuning = config.select_tunings(power_plugged, profile);
|
let tuning = config.select_tunings(power_plugged, profile);
|
||||||
if !tuning.enabled {
|
if !tuning.enabled {
|
||||||
debug!("Tuning group is not enabled, skipping");
|
debug!("Tuning group is not enabled, skipping");
|
||||||
@@ -420,6 +545,20 @@ pub async fn set_config_or_default(
|
|||||||
// config.write();
|
// 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
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use config_traits::{StdConfig, StdConfigLoad};
|
|||||||
use rog_anime::error::AnimeError;
|
use rog_anime::error::AnimeError;
|
||||||
use rog_anime::usb::Brightness;
|
use rog_anime::usb::Brightness;
|
||||||
use rog_anime::{
|
use rog_anime::{
|
||||||
ActionData, ActionLoader, AnimTime, Animations, AnimeType, DeviceState, Fade, Vec2
|
ActionData, ActionLoader, AnimTime, Animations, AnimeType, DeviceState, Fade, Vec2,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@@ -15,14 +15,14 @@ pub struct AniMeConfigCached {
|
|||||||
pub system: Vec<ActionData>,
|
pub system: Vec<ActionData>,
|
||||||
pub boot: Vec<ActionData>,
|
pub boot: Vec<ActionData>,
|
||||||
pub wake: Vec<ActionData>,
|
pub wake: Vec<ActionData>,
|
||||||
pub shutdown: Vec<ActionData>
|
pub shutdown: Vec<ActionData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AniMeConfigCached {
|
impl AniMeConfigCached {
|
||||||
pub fn init_from_config(
|
pub fn init_from_config(
|
||||||
&mut self,
|
&mut self,
|
||||||
config: &AniMeConfig,
|
config: &AniMeConfig,
|
||||||
anime_type: AnimeType
|
anime_type: AnimeType,
|
||||||
) -> Result<(), AnimeError> {
|
) -> Result<(), AnimeError> {
|
||||||
let mut sys = Vec::with_capacity(config.system.len());
|
let mut sys = Vec::with_capacity(config.system.len());
|
||||||
for ani in &config.system {
|
for ani in &config.system {
|
||||||
@@ -68,7 +68,7 @@ pub struct AniMeConfig {
|
|||||||
pub off_when_suspended: bool,
|
pub off_when_suspended: bool,
|
||||||
pub off_when_lid_closed: bool,
|
pub off_when_lid_closed: bool,
|
||||||
pub brightness_on_battery: Brightness,
|
pub brightness_on_battery: Brightness,
|
||||||
pub builtin_anims: Animations
|
pub builtin_anims: Animations,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AniMeConfig {
|
impl Default for AniMeConfig {
|
||||||
@@ -87,7 +87,7 @@ impl Default for AniMeConfig {
|
|||||||
off_when_suspended: true,
|
off_when_suspended: true,
|
||||||
off_when_lid_closed: true,
|
off_when_lid_closed: true,
|
||||||
brightness_on_battery: Brightness::Low,
|
brightness_on_battery: Brightness::Low,
|
||||||
builtin_anims: Animations::default()
|
builtin_anims: Animations::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ impl From<&AniMeConfig> for DeviceState {
|
|||||||
off_when_unplugged: config.off_when_unplugged,
|
off_when_unplugged: config.off_when_unplugged,
|
||||||
off_when_suspended: config.off_when_suspended,
|
off_when_suspended: config.off_when_suspended,
|
||||||
off_when_lid_closed: config.off_when_lid_closed,
|
off_when_lid_closed: config.off_when_lid_closed,
|
||||||
brightness_on_battery: config.brightness_on_battery
|
brightness_on_battery: config.brightness_on_battery,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,8 +148,8 @@ impl AniMeConfig {
|
|||||||
time: AnimTime::Fade(Fade::new(
|
time: AnimTime::Fade(Fade::new(
|
||||||
Duration::from_secs(2),
|
Duration::from_secs(2),
|
||||||
Some(Duration::from_secs(2)),
|
Some(Duration::from_secs(2)),
|
||||||
Duration::from_secs(2)
|
Duration::from_secs(2),
|
||||||
))
|
)),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
wake: vec![
|
wake: vec![
|
||||||
@@ -162,8 +162,8 @@ impl AniMeConfig {
|
|||||||
time: AnimTime::Fade(Fade::new(
|
time: AnimTime::Fade(Fade::new(
|
||||||
Duration::from_secs(2),
|
Duration::from_secs(2),
|
||||||
Some(Duration::from_secs(2)),
|
Some(Duration::from_secs(2)),
|
||||||
Duration::from_secs(2)
|
Duration::from_secs(2),
|
||||||
))
|
)),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
shutdown: vec![
|
shutdown: vec![
|
||||||
@@ -173,7 +173,7 @@ impl AniMeConfig {
|
|||||||
angle: 0.0,
|
angle: 0.0,
|
||||||
translation: Vec2::new(3.0, 2.0),
|
translation: Vec2::new(3.0, 2.0),
|
||||||
brightness: 1.0,
|
brightness: 1.0,
|
||||||
time: AnimTime::Infinite
|
time: AnimTime::Infinite,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use config_traits::StdConfig;
|
|||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use rog_anime::usb::{
|
use rog_anime::usb::{
|
||||||
pkt_flush, pkt_set_brightness, pkt_set_enable_display, pkt_set_enable_powersave_anim,
|
pkt_flush, pkt_set_brightness, pkt_set_enable_display, pkt_set_enable_powersave_anim,
|
||||||
pkts_for_init, Brightness
|
pkts_for_init, Brightness,
|
||||||
};
|
};
|
||||||
use rog_anime::{ActionData, AnimeDataBuffer, AnimePacketType};
|
use rog_anime::{ActionData, AnimeDataBuffer, AnimePacketType};
|
||||||
use rog_platform::hid_raw::HidRaw;
|
use rog_platform::hid_raw::HidRaw;
|
||||||
@@ -30,14 +30,14 @@ pub struct AniMe {
|
|||||||
// set to force thread to exit
|
// set to force thread to exit
|
||||||
thread_exit: Arc<AtomicBool>,
|
thread_exit: Arc<AtomicBool>,
|
||||||
// Set to false when the thread exits
|
// Set to false when the thread exits
|
||||||
thread_running: Arc<AtomicBool>
|
thread_running: Arc<AtomicBool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AniMe {
|
impl AniMe {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
hid: Option<Arc<Mutex<HidRaw>>>,
|
hid: Option<Arc<Mutex<HidRaw>>>,
|
||||||
usb: Option<Arc<Mutex<USBRaw>>>,
|
usb: Option<Arc<Mutex<USBRaw>>>,
|
||||||
config: Arc<Mutex<AniMeConfig>>
|
config: Arc<Mutex<AniMeConfig>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
hid,
|
hid,
|
||||||
@@ -45,7 +45,7 @@ impl AniMe {
|
|||||||
config,
|
config,
|
||||||
cache: AniMeConfigCached::default(),
|
cache: AniMeConfigCached::default(),
|
||||||
thread_exit: Arc::new(AtomicBool::new(false)),
|
thread_exit: Arc::new(AtomicBool::new(false)),
|
||||||
thread_running: Arc::new(AtomicBool::new(false))
|
thread_running: Arc::new(AtomicBool::new(false)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ impl AniMe {
|
|||||||
pub async fn set_builtins_enabled(
|
pub async fn set_builtins_enabled(
|
||||||
&self,
|
&self,
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
bright: Brightness
|
bright: Brightness,
|
||||||
) -> Result<(), RogError> {
|
) -> Result<(), RogError> {
|
||||||
self.write_bytes(&pkt_set_enable_powersave_anim(enabled))
|
self.write_bytes(&pkt_set_enable_powersave_anim(enabled))
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use log::{debug, error, warn};
|
|||||||
use logind_zbus::manager::ManagerProxy;
|
use logind_zbus::manager::ManagerProxy;
|
||||||
use rog_anime::usb::{
|
use rog_anime::usb::{
|
||||||
pkt_set_brightness, pkt_set_builtin_animations, pkt_set_enable_display,
|
pkt_set_brightness, pkt_set_builtin_animations, pkt_set_enable_display,
|
||||||
pkt_set_enable_powersave_anim, Brightness
|
pkt_set_enable_powersave_anim, Brightness,
|
||||||
};
|
};
|
||||||
use rog_anime::{Animations, AnimeDataBuffer, DeviceState};
|
use rog_anime::{Animations, AnimeDataBuffer, DeviceState};
|
||||||
use zbus::object_server::SignalEmitter;
|
use zbus::object_server::SignalEmitter;
|
||||||
@@ -41,7 +41,7 @@ impl AniMeZbus {
|
|||||||
pub async fn start_tasks(
|
pub async fn start_tasks(
|
||||||
mut self,
|
mut self,
|
||||||
connection: &Connection,
|
connection: &Connection,
|
||||||
path: OwnedObjectPath
|
path: OwnedObjectPath,
|
||||||
) -> Result<(), RogError> {
|
) -> Result<(), RogError> {
|
||||||
// let task = zbus.clone();
|
// let task = zbus.clone();
|
||||||
self.reload()
|
self.reload()
|
||||||
@@ -69,7 +69,11 @@ impl AniMeZbus {
|
|||||||
/// it is restarted
|
/// it is restarted
|
||||||
async fn write(&self, input: AnimeDataBuffer) -> zbus::fdo::Result<()> {
|
async fn write(&self, input: AnimeDataBuffer) -> zbus::fdo::Result<()> {
|
||||||
let bright = self.0.config.lock().await.display_brightness;
|
let bright = self.0.config.lock().await.display_brightness;
|
||||||
self.0.set_builtins_enabled(false, bright).await?;
|
if self.0.config.lock().await.builtin_anims_enabled {
|
||||||
|
// This clears the display, causing flickers if done indiscriminately on every
|
||||||
|
// write. Therefore, we guard it behind a config check.
|
||||||
|
self.0.set_builtins_enabled(false, bright).await?;
|
||||||
|
}
|
||||||
self.0.thread_exit.store(true, Ordering::SeqCst);
|
self.0.thread_exit.store(true, Ordering::SeqCst);
|
||||||
self.0.write_data_buffer(input).await.map_err(|err| {
|
self.0.write_data_buffer(input).await.map_err(|err| {
|
||||||
warn!("ctrl_anime::run_animation:callback {}", err);
|
warn!("ctrl_anime::run_animation:callback {}", err);
|
||||||
@@ -169,7 +173,7 @@ impl AniMeZbus {
|
|||||||
async fn set_builtin_animations(&self, settings: Animations) {
|
async fn set_builtin_animations(&self, settings: Animations) {
|
||||||
self.0
|
self.0
|
||||||
.write_bytes(&pkt_set_builtin_animations(
|
.write_bytes(&pkt_set_builtin_animations(
|
||||||
settings.boot, settings.awake, settings.sleep, settings.shutdown
|
settings.boot, settings.awake, settings.sleep, settings.shutdown,
|
||||||
))
|
))
|
||||||
.await
|
.await
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
@@ -319,7 +323,7 @@ impl crate::CtrlTask for AniMeZbus {
|
|||||||
|
|
||||||
inner
|
inner
|
||||||
.write_bytes(&pkt_set_enable_display(
|
.write_bytes(&pkt_set_enable_display(
|
||||||
!(sleeping && config.off_when_suspended)
|
!(sleeping && config.off_when_suspended),
|
||||||
))
|
))
|
||||||
.await
|
.await
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
@@ -330,7 +334,7 @@ impl crate::CtrlTask for AniMeZbus {
|
|||||||
if config.builtin_anims_enabled {
|
if config.builtin_anims_enabled {
|
||||||
inner
|
inner
|
||||||
.write_bytes(&pkt_set_enable_powersave_anim(
|
.write_bytes(&pkt_set_enable_powersave_anim(
|
||||||
!(sleeping && config.off_when_suspended)
|
!(sleeping && config.off_when_suspended),
|
||||||
))
|
))
|
||||||
.await
|
.await
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
@@ -433,7 +437,7 @@ impl crate::CtrlTask for AniMeZbus {
|
|||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -460,7 +464,7 @@ impl crate::Reloadable for AniMeZbus {
|
|||||||
builtin_anims.boot,
|
builtin_anims.boot,
|
||||||
builtin_anims.awake,
|
builtin_anims.awake,
|
||||||
builtin_anims.sleep,
|
builtin_anims.sleep,
|
||||||
builtin_anims.shutdown
|
builtin_anims.shutdown,
|
||||||
))
|
))
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use log::{debug, info, warn};
|
|||||||
use rog_aura::aura_detection::LedSupportData;
|
use rog_aura::aura_detection::LedSupportData;
|
||||||
use rog_aura::keyboard::LaptopAuraPower;
|
use rog_aura::keyboard::LaptopAuraPower;
|
||||||
use rog_aura::{
|
use rog_aura::{
|
||||||
AuraDeviceType, AuraEffect, AuraModeNum, AuraZone, Direction, LedBrightness, Speed, GRADIENT
|
AuraDeviceType, AuraEffect, AuraModeNum, AuraZone, Direction, LedBrightness, Speed, GRADIENT,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ pub struct AuraConfig {
|
|||||||
pub multizone_on: bool,
|
pub multizone_on: bool,
|
||||||
pub enabled: LaptopAuraPower,
|
pub enabled: LaptopAuraPower,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub per_key_mode_active: bool
|
pub per_key_mode_active: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StdConfig for AuraConfig {
|
impl StdConfig for AuraConfig {
|
||||||
@@ -74,7 +74,7 @@ impl AuraConfig {
|
|||||||
multizone: None,
|
multizone: None,
|
||||||
multizone_on: false,
|
multizone_on: false,
|
||||||
enabled,
|
enabled,
|
||||||
per_key_mode_active: false
|
per_key_mode_active: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
for n in &config.support_data.basic_modes {
|
for n in &config.support_data.basic_modes {
|
||||||
@@ -82,8 +82,9 @@ impl AuraConfig {
|
|||||||
config
|
config
|
||||||
.builtins
|
.builtins
|
||||||
.insert(*n, AuraEffect::default_with_mode(*n));
|
.insert(*n, AuraEffect::default_with_mode(*n));
|
||||||
|
}
|
||||||
if !config.support_data.basic_zones.is_empty() {
|
if !config.support_data.basic_zones.is_empty() {
|
||||||
|
for n in &config.support_data.basic_modes {
|
||||||
let mut default = vec![];
|
let mut default = vec![];
|
||||||
for (i, tmp) in config.support_data.basic_zones.iter().enumerate() {
|
for (i, tmp) in config.support_data.basic_zones.iter().enumerate() {
|
||||||
default.push(AuraEffect {
|
default.push(AuraEffect {
|
||||||
@@ -92,7 +93,7 @@ impl AuraConfig {
|
|||||||
colour1: *GRADIENT.get(i).unwrap_or(&GRADIENT[0]),
|
colour1: *GRADIENT.get(i).unwrap_or(&GRADIENT[0]),
|
||||||
colour2: *GRADIENT.get(GRADIENT.len() - i).unwrap_or(&GRADIENT[6]),
|
colour2: *GRADIENT.get(GRADIENT.len() - i).unwrap_or(&GRADIENT[6]),
|
||||||
speed: Speed::Med,
|
speed: Speed::Med,
|
||||||
direction: Direction::Left
|
direction: Direction::Left,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(m) = config.multizone.as_mut() {
|
if let Some(m) = config.multizone.as_mut() {
|
||||||
@@ -118,14 +119,14 @@ impl AuraConfig {
|
|||||||
self.multizone_on = false;
|
self.multizone_on = false;
|
||||||
} else {
|
} else {
|
||||||
if let Some(multi) = self.multizone.as_mut() {
|
if let Some(multi) = self.multizone.as_mut() {
|
||||||
if let Some(fx) = multi.get_mut(effect.mode()) {
|
if let Some(fx_vec) = multi.get_mut(effect.mode()) {
|
||||||
for fx in fx.iter_mut() {
|
for fx in fx_vec.iter_mut() {
|
||||||
if fx.zone == effect.zone {
|
if fx.zone == effect.zone {
|
||||||
*fx = effect;
|
*fx = effect;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fx.push(effect);
|
fx_vec.push(effect);
|
||||||
} else {
|
} else {
|
||||||
multi.insert(*effect.mode(), vec![effect]);
|
multi.insert(*effect.mode(), vec![effect]);
|
||||||
}
|
}
|
||||||
@@ -156,7 +157,7 @@ impl AuraConfig {
|
|||||||
colour1: *GRADIENT.get(i).unwrap_or(&GRADIENT[0]),
|
colour1: *GRADIENT.get(i).unwrap_or(&GRADIENT[0]),
|
||||||
colour2: *GRADIENT.get(GRADIENT.len() - i).unwrap_or(&GRADIENT[6]),
|
colour2: *GRADIENT.get(GRADIENT.len() - i).unwrap_or(&GRADIENT[6]),
|
||||||
speed: Speed::Med,
|
speed: Speed::Med,
|
||||||
direction: Direction::Left
|
direction: Direction::Left,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if default.is_empty() {
|
if default.is_empty() {
|
||||||
@@ -230,15 +231,29 @@ impl AuraConfig {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::sync::{Mutex, MutexGuard, OnceLock};
|
||||||
|
|
||||||
use rog_aura::keyboard::AuraPowerState;
|
use rog_aura::keyboard::AuraPowerState;
|
||||||
use rog_aura::{
|
use rog_aura::{
|
||||||
AuraEffect, AuraModeNum, AuraZone, Colour, Direction, LedBrightness, PowerZones, Speed
|
AuraEffect, AuraModeNum, AuraZone, Colour, Direction, LedBrightness, PowerZones, Speed,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::AuraConfig;
|
use super::AuraConfig;
|
||||||
|
|
||||||
|
// Global mutex to serialize tests that rely on process-wide environment
|
||||||
|
// variables
|
||||||
|
static TEST_MUTEX: OnceLock<Mutex<()>> = OnceLock::new();
|
||||||
|
|
||||||
|
fn test_lock() -> MutexGuard<'static, ()> {
|
||||||
|
TEST_MUTEX
|
||||||
|
.get_or_init(|| Mutex::new(()))
|
||||||
|
.lock()
|
||||||
|
.expect("TEST_MUTEX poisoned")
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn set_multizone_4key_config() {
|
fn set_multizone_4key_config() {
|
||||||
|
let _guard = test_lock();
|
||||||
std::env::set_var("BOARD_NAME", "");
|
std::env::set_var("BOARD_NAME", "");
|
||||||
let mut config = AuraConfig::new("19b6");
|
let mut config = AuraConfig::new("19b6");
|
||||||
|
|
||||||
@@ -246,7 +261,7 @@ mod tests {
|
|||||||
colour1: Colour {
|
colour1: Colour {
|
||||||
r: 0xff,
|
r: 0xff,
|
||||||
g: 0x00,
|
g: 0x00,
|
||||||
b: 0xff
|
b: 0xff,
|
||||||
},
|
},
|
||||||
zone: AuraZone::Key1,
|
zone: AuraZone::Key1,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@@ -259,7 +274,7 @@ mod tests {
|
|||||||
colour1: Colour {
|
colour1: Colour {
|
||||||
r: 0x00,
|
r: 0x00,
|
||||||
g: 0xff,
|
g: 0xff,
|
||||||
b: 0xff
|
b: 0xff,
|
||||||
},
|
},
|
||||||
zone: AuraZone::Key2,
|
zone: AuraZone::Key2,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@@ -270,7 +285,7 @@ mod tests {
|
|||||||
colour1: Colour {
|
colour1: Colour {
|
||||||
r: 0xff,
|
r: 0xff,
|
||||||
g: 0xff,
|
g: 0xff,
|
||||||
b: 0x00
|
b: 0x00,
|
||||||
},
|
},
|
||||||
zone: AuraZone::Key3,
|
zone: AuraZone::Key3,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@@ -281,7 +296,7 @@ mod tests {
|
|||||||
colour1: Colour {
|
colour1: Colour {
|
||||||
r: 0x00,
|
r: 0x00,
|
||||||
g: 0xff,
|
g: 0xff,
|
||||||
b: 0x00
|
b: 0x00,
|
||||||
},
|
},
|
||||||
zone: AuraZone::Key4,
|
zone: AuraZone::Key4,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@@ -294,30 +309,43 @@ mod tests {
|
|||||||
let res = config.multizone.unwrap();
|
let res = config.multizone.unwrap();
|
||||||
let sta = res.get(&AuraModeNum::Static).unwrap();
|
let sta = res.get(&AuraModeNum::Static).unwrap();
|
||||||
assert_eq!(sta.len(), 4);
|
assert_eq!(sta.len(), 4);
|
||||||
assert_eq!(sta[0].colour1, Colour {
|
assert_eq!(
|
||||||
r: 0xff,
|
sta[0].colour1,
|
||||||
g: 0x00,
|
Colour {
|
||||||
b: 0xff
|
r: 0xff,
|
||||||
});
|
g: 0x00,
|
||||||
assert_eq!(sta[1].colour1, Colour {
|
b: 0xff
|
||||||
r: 0x00,
|
}
|
||||||
g: 0xff,
|
);
|
||||||
b: 0xff
|
assert_eq!(
|
||||||
});
|
sta[1].colour1,
|
||||||
assert_eq!(sta[2].colour1, Colour {
|
Colour {
|
||||||
r: 0xff,
|
r: 0x00,
|
||||||
g: 0xff,
|
g: 0xff,
|
||||||
b: 0x00
|
b: 0xff
|
||||||
});
|
}
|
||||||
assert_eq!(sta[3].colour1, Colour {
|
);
|
||||||
r: 0x00,
|
assert_eq!(
|
||||||
g: 0xff,
|
sta[2].colour1,
|
||||||
b: 0x00
|
Colour {
|
||||||
});
|
r: 0xff,
|
||||||
|
g: 0xff,
|
||||||
|
b: 0x00
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
sta[3].colour1,
|
||||||
|
Colour {
|
||||||
|
r: 0x00,
|
||||||
|
g: 0xff,
|
||||||
|
b: 0x00
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn set_multizone_multimode_config() {
|
fn set_multizone_multimode_config() {
|
||||||
|
let _guard = test_lock();
|
||||||
std::env::set_var("BOARD_NAME", "");
|
std::env::set_var("BOARD_NAME", "");
|
||||||
let mut config = AuraConfig::new("19b6");
|
let mut config = AuraConfig::new("19b6");
|
||||||
|
|
||||||
@@ -366,51 +394,65 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn verify_0x1866_g531i() {
|
fn verify_0x1866_g531i() {
|
||||||
|
let _guard = test_lock();
|
||||||
std::env::set_var("BOARD_NAME", "G513I");
|
std::env::set_var("BOARD_NAME", "G513I");
|
||||||
let mut config = AuraConfig::new("1866");
|
let mut config = AuraConfig::new("1866");
|
||||||
|
|
||||||
assert_eq!(config.brightness, LedBrightness::Med);
|
assert_eq!(config.brightness, LedBrightness::Med);
|
||||||
assert_eq!(config.builtins.len(), 5);
|
assert_eq!(config.builtins.len(), 5);
|
||||||
assert_eq!(config.builtins.first_entry().unwrap().get(), &AuraEffect {
|
assert_eq!(
|
||||||
mode: AuraModeNum::Static,
|
config.builtins.first_entry().unwrap().get(),
|
||||||
zone: AuraZone::None,
|
&AuraEffect {
|
||||||
colour1: Colour { r: 166, g: 0, b: 0 },
|
mode: AuraModeNum::Static,
|
||||||
colour2: Colour { r: 0, g: 0, b: 0 },
|
zone: AuraZone::None,
|
||||||
speed: Speed::Med,
|
colour1: Colour { r: 166, g: 0, b: 0 },
|
||||||
direction: Direction::Right
|
colour2: Colour { r: 0, g: 0, b: 0 },
|
||||||
});
|
speed: Speed::Med,
|
||||||
|
direction: Direction::Right
|
||||||
|
}
|
||||||
|
);
|
||||||
assert_eq!(config.enabled.states.len(), 1);
|
assert_eq!(config.enabled.states.len(), 1);
|
||||||
assert_eq!(config.enabled.states[0], AuraPowerState {
|
assert_eq!(
|
||||||
zone: PowerZones::KeyboardAndLightbar,
|
config.enabled.states[0],
|
||||||
boot: true,
|
AuraPowerState {
|
||||||
awake: true,
|
zone: PowerZones::KeyboardAndLightbar,
|
||||||
sleep: true,
|
boot: true,
|
||||||
shutdown: true
|
awake: true,
|
||||||
});
|
sleep: true,
|
||||||
|
shutdown: true
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn verify_0x19b6_g634j() {
|
fn verify_0x19b6_g634j() {
|
||||||
|
let _guard = test_lock();
|
||||||
std::env::set_var("BOARD_NAME", "G634J");
|
std::env::set_var("BOARD_NAME", "G634J");
|
||||||
let mut config = AuraConfig::new("19b6");
|
let mut config = AuraConfig::new("19b6");
|
||||||
|
|
||||||
assert_eq!(config.brightness, LedBrightness::Med);
|
assert_eq!(config.brightness, LedBrightness::Med);
|
||||||
assert_eq!(config.builtins.len(), 12);
|
assert_eq!(config.builtins.len(), 12);
|
||||||
assert_eq!(config.builtins.first_entry().unwrap().get(), &AuraEffect {
|
assert_eq!(
|
||||||
mode: AuraModeNum::Static,
|
config.builtins.first_entry().unwrap().get(),
|
||||||
zone: AuraZone::None,
|
&AuraEffect {
|
||||||
colour1: Colour { r: 166, g: 0, b: 0 },
|
mode: AuraModeNum::Static,
|
||||||
colour2: Colour { r: 0, g: 0, b: 0 },
|
zone: AuraZone::None,
|
||||||
speed: Speed::Med,
|
colour1: Colour { r: 166, g: 0, b: 0 },
|
||||||
direction: Direction::Right
|
colour2: Colour { r: 0, g: 0, b: 0 },
|
||||||
});
|
speed: Speed::Med,
|
||||||
|
direction: Direction::Right
|
||||||
|
}
|
||||||
|
);
|
||||||
assert_eq!(config.enabled.states.len(), 4);
|
assert_eq!(config.enabled.states.len(), 4);
|
||||||
assert_eq!(config.enabled.states[0], AuraPowerState {
|
assert_eq!(
|
||||||
zone: PowerZones::Keyboard,
|
config.enabled.states[0],
|
||||||
boot: true,
|
AuraPowerState {
|
||||||
awake: true,
|
zone: PowerZones::Keyboard,
|
||||||
sleep: true,
|
boot: true,
|
||||||
shutdown: true
|
awake: true,
|
||||||
});
|
sleep: true,
|
||||||
|
shutdown: true
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pub mod trait_impls;
|
|||||||
pub struct Aura {
|
pub struct Aura {
|
||||||
pub hid: Option<Arc<Mutex<HidRaw>>>,
|
pub hid: Option<Arc<Mutex<HidRaw>>>,
|
||||||
pub backlight: Option<Arc<Mutex<KeyboardBacklight>>>,
|
pub backlight: Option<Arc<Mutex<KeyboardBacklight>>>,
|
||||||
pub config: Arc<Mutex<AuraConfig>>
|
pub config: Arc<Mutex<AuraConfig>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Aura {
|
impl Aura {
|
||||||
@@ -28,7 +28,7 @@ impl Aura {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn lock_config(&self) -> MutexGuard<AuraConfig> {
|
pub async fn lock_config(&self) -> MutexGuard<'_, AuraConfig> {
|
||||||
self.config.lock().await
|
self.config.lock().await
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,13 +91,13 @@ impl Aura {
|
|||||||
pub async fn write_effect_and_apply(
|
pub async fn write_effect_and_apply(
|
||||||
&self,
|
&self,
|
||||||
dev_type: AuraDeviceType,
|
dev_type: AuraDeviceType,
|
||||||
mode: &AuraEffect
|
mode: &AuraEffect,
|
||||||
) -> Result<(), RogError> {
|
) -> Result<(), RogError> {
|
||||||
if matches!(dev_type, AuraDeviceType::LaptopKeyboardTuf) {
|
if matches!(dev_type, AuraDeviceType::LaptopKeyboardTuf) {
|
||||||
if let Some(platform) = &self.backlight {
|
if let Some(platform) = &self.backlight {
|
||||||
let buf = [
|
let buf = [
|
||||||
1, mode.mode as u8, mode.colour1.r, mode.colour1.g, mode.colour1.b,
|
1, mode.mode as u8, mode.colour1.r, mode.colour1.g, mode.colour1.b,
|
||||||
mode.speed as u8
|
mode.speed as u8,
|
||||||
];
|
];
|
||||||
platform.lock().await.set_kbd_rgb_mode(&buf)?;
|
platform.lock().await.set_kbd_rgb_mode(&buf)?;
|
||||||
}
|
}
|
||||||
@@ -121,7 +121,7 @@ impl Aura {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Err(RogError::MissingFunction(
|
Err(RogError::MissingFunction(
|
||||||
"No LED backlight control available".to_string()
|
"No LED backlight control available".to_string(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ impl Aura {
|
|||||||
0x01,
|
0x01,
|
||||||
p.new_to_byte() as u8,
|
p.new_to_byte() as u8,
|
||||||
0x0,
|
0x0,
|
||||||
0x0
|
0x0,
|
||||||
];
|
];
|
||||||
hid_raw.write_bytes(&msg)?;
|
hid_raw.write_bytes(&msg)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@@ -154,7 +154,7 @@ impl Aura {
|
|||||||
|
|
||||||
let bytes = config.enabled.to_bytes(config.led_type);
|
let bytes = config.enabled.to_bytes(config.led_type);
|
||||||
let msg = [
|
let msg = [
|
||||||
0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2], bytes[3]
|
0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2], bytes[3],
|
||||||
];
|
];
|
||||||
hid_raw.write_bytes(&msg)?;
|
hid_raw.write_bytes(&msg)?;
|
||||||
}
|
}
|
||||||
@@ -167,7 +167,7 @@ impl Aura {
|
|||||||
pub async fn write_effect_block(
|
pub async fn write_effect_block(
|
||||||
&self,
|
&self,
|
||||||
config: &mut AuraConfig,
|
config: &mut AuraConfig,
|
||||||
effect: &AuraLaptopUsbPackets
|
effect: &AuraLaptopUsbPackets,
|
||||||
) -> Result<(), RogError> {
|
) -> Result<(), RogError> {
|
||||||
if config.brightness == LedBrightness::Off {
|
if config.brightness == LedBrightness::Off {
|
||||||
config.brightness = LedBrightness::Med;
|
config.brightness = LedBrightness::Med;
|
||||||
@@ -201,7 +201,7 @@ impl Aura {
|
|||||||
let g = row[10];
|
let g = row[10];
|
||||||
let b = row[11];
|
let b = row[11];
|
||||||
tuf.lock().await.set_kbd_rgb_mode(&[
|
tuf.lock().await.set_kbd_rgb_mode(&[
|
||||||
0, 0, r, g, b, 0
|
0, 0, r, g, b, 0,
|
||||||
])?;
|
])?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -215,7 +215,7 @@ impl Aura {
|
|||||||
let mut config = self.config.lock().await;
|
let mut config = self.config.lock().await;
|
||||||
if config.ally_fix.is_none() {
|
if config.ally_fix.is_none() {
|
||||||
let msg = [
|
let msg = [
|
||||||
0x5d, 0xbd, 0x01, 0xff, 0xff, 0xff, 0xff
|
0x5d, 0xbd, 0x01, 0xff, 0xff, 0xff, 0xff,
|
||||||
];
|
];
|
||||||
hid_raw.lock().await.write_bytes(&msg)?;
|
hid_raw.lock().await.write_bytes(&msg)?;
|
||||||
info!("Reset Ally power settings to base");
|
info!("Reset Ally power settings to base");
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ impl AuraZbus {
|
|||||||
mut self,
|
mut self,
|
||||||
connection: &Connection,
|
connection: &Connection,
|
||||||
// _signal_ctx: SignalEmitter<'static>,
|
// _signal_ctx: SignalEmitter<'static>,
|
||||||
path: OwnedObjectPath
|
path: OwnedObjectPath,
|
||||||
) -> Result<(), RogError> {
|
) -> Result<(), RogError> {
|
||||||
// let task = zbus.clone();
|
// let task = zbus.clone();
|
||||||
// let signal_ctx = signal_ctx.clone();
|
// let signal_ctx = signal_ctx.clone();
|
||||||
@@ -71,7 +71,13 @@ impl AuraZbus {
|
|||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
async fn set_brightness(&mut self, brightness: LedBrightness) -> Result<(), ZbErr> {
|
async fn set_brightness(&mut self, brightness: LedBrightness) -> Result<(), ZbErr> {
|
||||||
if let Some(bl) = self.0.backlight.as_ref() {
|
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()))
|
Err(ZbErr::Failed("No sysfs brightness control".to_string()))
|
||||||
}
|
}
|
||||||
@@ -144,7 +150,7 @@ impl AuraZbus {
|
|||||||
let mode = config.current_mode;
|
let mode = config.current_mode;
|
||||||
match config.builtins.get(&mode) {
|
match config.builtins.get(&mode) {
|
||||||
Some(effect) => Ok(effect.clone()),
|
Some(effect) => Ok(effect.clone()),
|
||||||
None => Err(ZbErr::Failed("Could not get the current effect".into()))
|
None => Err(ZbErr::Failed("Could not get the current effect".into())),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(ZbErr::Failed("Aura control couldn't lock self".to_string()))
|
Err(ZbErr::Failed("Aura control couldn't lock self".to_string()))
|
||||||
@@ -297,7 +303,7 @@ impl CtrlTask for AuraZbus {
|
|||||||
move |_power_plugged| {
|
move |_power_plugged| {
|
||||||
// power change
|
// power change
|
||||||
async move {}
|
async move {}
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
// - Add it to Zbus server
|
// - Add it to Zbus server
|
||||||
// - If udev sees device removed then remove the zbus path
|
// - If udev sees device removed then remove the zbus path
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use dmi_id::DMIID;
|
use dmi_id::DMIID;
|
||||||
@@ -56,7 +57,7 @@ fn dbus_path_for_dev(parent: &Device) -> Option<OwnedObjectPath> {
|
|||||||
if let Some(filename) = filename_partial(parent) {
|
if let Some(filename) = filename_partial(parent) {
|
||||||
return Some(
|
return Some(
|
||||||
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/{MOD_NAME}/{filename}"))
|
ObjectPath::from_str_unchecked(&format!("{ASUS_ZBUS_PATH}/{MOD_NAME}/{filename}"))
|
||||||
.into()
|
.into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
@@ -91,24 +92,47 @@ fn dev_prop_matches(dev: &Device, prop: &str, value: &str) -> bool {
|
|||||||
/// required.
|
/// required.
|
||||||
pub struct AsusDevice {
|
pub struct AsusDevice {
|
||||||
device: DeviceHandle,
|
device: DeviceHandle,
|
||||||
dbus_path: OwnedObjectPath
|
dbus_path: OwnedObjectPath,
|
||||||
|
hid_key: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DeviceManager {
|
pub struct DeviceManager {
|
||||||
_dbus_connection: Connection
|
_dbus_connection: Connection,
|
||||||
|
_hid_handles: Arc<Mutex<HashMap<String, Arc<Mutex<HidRaw>>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceManager {
|
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(
|
async fn init_hid_devices(
|
||||||
connection: &Connection,
|
connection: &Connection,
|
||||||
device: Device
|
device: Device,
|
||||||
|
handles: Arc<Mutex<HashMap<String, Arc<Mutex<HidRaw>>>>>,
|
||||||
) -> Result<Vec<AsusDevice>, RogError> {
|
) -> Result<Vec<AsusDevice>, RogError> {
|
||||||
let mut devices = Vec::new();
|
let mut devices = Vec::new();
|
||||||
if let Some(usb_device) = device.parent_with_subsystem_devtype("usb", "usb_device")? {
|
if let Some(usb_device) = device.parent_with_subsystem_devtype("usb", "usb_device")? {
|
||||||
if let Some(usb_id) = usb_device.attribute_value("idProduct") {
|
if let Some(usb_id) = usb_device.attribute_value("idProduct") {
|
||||||
if let Some(vendor_id) = usb_device.attribute_value("idVendor") {
|
if let Some(vendor_id) = usb_device.attribute_value("idVendor") {
|
||||||
if vendor_id != "0b05" {
|
if vendor_id != "0b05" {
|
||||||
debug!("Not ASUS vendor ID");
|
debug!("Not ASUS vendor ID: {}", vendor_id.to_string_lossy());
|
||||||
return Ok(devices);
|
return Ok(devices);
|
||||||
}
|
}
|
||||||
// Almost all devices are identified by the productId.
|
// Almost all devices are identified by the productId.
|
||||||
@@ -116,13 +140,14 @@ impl DeviceManager {
|
|||||||
// 1. Generate an interface path
|
// 1. Generate an interface path
|
||||||
// 2. Create the device
|
// 2. Create the device
|
||||||
// Use the top-level endpoint, not the parent
|
// Use the top-level endpoint, not the parent
|
||||||
if let Ok(hidraw) = HidRaw::from_device(device) {
|
if let Ok((dev, hid_key)) =
|
||||||
|
Self::get_or_create_hid_handle(&handles, &device).await
|
||||||
|
{
|
||||||
debug!("Testing device {usb_id:?}");
|
debug!("Testing device {usb_id:?}");
|
||||||
let dev = Arc::new(Mutex::new(hidraw));
|
|
||||||
// SLASH DEVICE
|
// SLASH DEVICE
|
||||||
if let Ok(dev_type) = DeviceHandle::new_slash_hid(
|
if let Ok(dev_type) = DeviceHandle::new_slash_hid(
|
||||||
dev.clone(),
|
dev.clone(),
|
||||||
usb_id.to_str().unwrap_or_default()
|
usb_id.to_str().unwrap_or_default(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@@ -133,14 +158,15 @@ impl DeviceManager {
|
|||||||
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
||||||
devices.push(AsusDevice {
|
devices.push(AsusDevice {
|
||||||
device: dev_type,
|
device: dev_type,
|
||||||
dbus_path: path
|
dbus_path: path,
|
||||||
|
hid_key: Some(hid_key.clone()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ANIME MATRIX DEVICE
|
// ANIME MATRIX DEVICE
|
||||||
if let Ok(dev_type) = DeviceHandle::maybe_anime_hid(
|
if let Ok(dev_type) = DeviceHandle::maybe_anime_hid(
|
||||||
dev.clone(),
|
dev.clone(),
|
||||||
usb_id.to_str().unwrap_or_default()
|
usb_id.to_str().unwrap_or_default(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@@ -151,14 +177,15 @@ impl DeviceManager {
|
|||||||
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
||||||
devices.push(AsusDevice {
|
devices.push(AsusDevice {
|
||||||
device: dev_type,
|
device: dev_type,
|
||||||
dbus_path: path
|
dbus_path: path,
|
||||||
|
hid_key: Some(hid_key.clone()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// AURA LAPTOP DEVICE
|
// AURA LAPTOP DEVICE
|
||||||
if let Ok(dev_type) = DeviceHandle::maybe_laptop_aura(
|
if let Ok(dev_type) = DeviceHandle::maybe_laptop_aura(
|
||||||
Some(dev),
|
Some(dev),
|
||||||
usb_id.to_str().unwrap_or_default()
|
usb_id.to_str().unwrap_or_default(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@@ -169,10 +196,13 @@ impl DeviceManager {
|
|||||||
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
||||||
devices.push(AsusDevice {
|
devices.push(AsusDevice {
|
||||||
device: dev_type,
|
device: dev_type,
|
||||||
dbus_path: path
|
dbus_path: path,
|
||||||
|
hid_key: Some(hid_key),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
warn!("Failed to initialise shared hid handle for {usb_id:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,7 +211,10 @@ impl DeviceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// To be called on daemon startup
|
/// To be called on daemon startup
|
||||||
async fn init_all_hid(connection: &Connection) -> Result<Vec<AsusDevice>, RogError> {
|
async fn init_all_hid(
|
||||||
|
connection: &Connection,
|
||||||
|
handles: Arc<Mutex<HashMap<String, Arc<Mutex<HidRaw>>>>>,
|
||||||
|
) -> Result<Vec<AsusDevice>, RogError> {
|
||||||
// track and ensure we use only one hidraw per prod_id
|
// track and ensure we use only one hidraw per prod_id
|
||||||
// let mut interfaces = HashSet::new();
|
// let mut interfaces = HashSet::new();
|
||||||
let mut devices: Vec<AsusDevice> = Vec::new();
|
let mut devices: Vec<AsusDevice> = Vec::new();
|
||||||
@@ -200,7 +233,7 @@ impl DeviceManager {
|
|||||||
.scan_devices()
|
.scan_devices()
|
||||||
.map_err(|e| PlatformError::IoPath("enumerator".to_owned(), e))?
|
.map_err(|e| PlatformError::IoPath("enumerator".to_owned(), e))?
|
||||||
{
|
{
|
||||||
devices.append(&mut Self::init_hid_devices(connection, device).await?);
|
devices.append(&mut Self::init_hid_devices(connection, device, handles.clone()).await?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(devices)
|
Ok(devices)
|
||||||
@@ -209,7 +242,7 @@ impl DeviceManager {
|
|||||||
async fn init_scsi(
|
async fn init_scsi(
|
||||||
connection: &Connection,
|
connection: &Connection,
|
||||||
device: &Device,
|
device: &Device,
|
||||||
path: OwnedObjectPath
|
path: OwnedObjectPath,
|
||||||
) -> Option<AsusDevice> {
|
) -> Option<AsusDevice> {
|
||||||
// "ID_MODEL_ID" "1932"
|
// "ID_MODEL_ID" "1932"
|
||||||
// "ID_VENDOR_ID" "0b05"
|
// "ID_VENDOR_ID" "0b05"
|
||||||
@@ -227,7 +260,8 @@ impl DeviceManager {
|
|||||||
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
||||||
return Some(AsusDevice {
|
return Some(AsusDevice {
|
||||||
device: dev_type,
|
device: dev_type,
|
||||||
dbus_path: path
|
dbus_path: path,
|
||||||
|
hid_key: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,10 +309,13 @@ impl DeviceManager {
|
|||||||
Ok(devices)
|
Ok(devices)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn find_all_devices(connection: &Connection) -> Vec<AsusDevice> {
|
pub async fn find_all_devices(
|
||||||
|
connection: &Connection,
|
||||||
|
handles: Arc<Mutex<HashMap<String, Arc<Mutex<HidRaw>>>>>,
|
||||||
|
) -> Vec<AsusDevice> {
|
||||||
let mut devices: Vec<AsusDevice> = Vec::new();
|
let mut devices: Vec<AsusDevice> = Vec::new();
|
||||||
// HID first, always
|
// HID first, always
|
||||||
if let Ok(devs) = &mut Self::init_all_hid(connection).await {
|
if let Ok(devs) = &mut Self::init_all_hid(connection, handles.clone()).await {
|
||||||
devices.append(devs);
|
devices.append(devs);
|
||||||
}
|
}
|
||||||
// USB after, need to check if HID picked something up and if so, skip it
|
// USB after, need to check if HID picked something up and if so, skip it
|
||||||
@@ -305,7 +342,8 @@ impl DeviceManager {
|
|||||||
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
||||||
devices.push(AsusDevice {
|
devices.push(AsusDevice {
|
||||||
device: dev_type,
|
device: dev_type,
|
||||||
dbus_path: path
|
dbus_path: path,
|
||||||
|
hid_key: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -327,7 +365,8 @@ impl DeviceManager {
|
|||||||
{
|
{
|
||||||
devices.push(AsusDevice {
|
devices.push(AsusDevice {
|
||||||
device: dev_type,
|
device: dev_type,
|
||||||
dbus_path: path
|
dbus_path: path,
|
||||||
|
hid_key: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -354,7 +393,8 @@ impl DeviceManager {
|
|||||||
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
ctrl.start_tasks(connection, path.clone()).await.unwrap();
|
||||||
devices.push(AsusDevice {
|
devices.push(AsusDevice {
|
||||||
device: dev_type,
|
device: dev_type,
|
||||||
dbus_path: path
|
dbus_path: path,
|
||||||
|
hid_key: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -370,16 +410,19 @@ impl DeviceManager {
|
|||||||
|
|
||||||
pub async fn new(connection: Connection) -> Result<Self, RogError> {
|
pub async fn new(connection: Connection) -> Result<Self, RogError> {
|
||||||
let conn_copy = connection.clone();
|
let conn_copy = connection.clone();
|
||||||
let devices = Self::find_all_devices(&conn_copy).await;
|
let hid_handles = Arc::new(Mutex::new(HashMap::new()));
|
||||||
|
let devices = Self::find_all_devices(&conn_copy, hid_handles.clone()).await;
|
||||||
info!("Found {} valid devices on startup", devices.len());
|
info!("Found {} valid devices on startup", devices.len());
|
||||||
let devices = Arc::new(Mutex::new(devices));
|
let devices = Arc::new(Mutex::new(devices));
|
||||||
let manager = Self {
|
let manager = Self {
|
||||||
_dbus_connection: connection
|
_dbus_connection: connection,
|
||||||
|
_hid_handles: hid_handles.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: The /sysfs/ LEDs don't cause events, so they need to be manually
|
// TODO: The /sysfs/ LEDs don't cause events, so they need to be manually
|
||||||
// checked for and added
|
// checked for and added
|
||||||
|
|
||||||
|
let hid_handles_thread = hid_handles.clone();
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let mut monitor = MonitorBuilder::new()?.listen()?;
|
let mut monitor = MonitorBuilder::new()?.listen()?;
|
||||||
let mut poll = Poll::new()?;
|
let mut poll = Poll::new()?;
|
||||||
@@ -408,6 +451,7 @@ impl DeviceManager {
|
|||||||
|
|
||||||
let devices = devices.clone();
|
let devices = devices.clone();
|
||||||
let conn_copy = conn_copy.clone();
|
let conn_copy = conn_copy.clone();
|
||||||
|
let hid_handles = hid_handles_thread.clone();
|
||||||
block_on(async move {
|
block_on(async move {
|
||||||
// SCSCI devs
|
// SCSCI devs
|
||||||
if subsys == "block" {
|
if subsys == "block" {
|
||||||
@@ -483,6 +527,7 @@ impl DeviceManager {
|
|||||||
// Iter in reverse so as to not screw up indexing
|
// Iter in reverse so as to not screw up indexing
|
||||||
for index in removals.iter().rev() {
|
for index in removals.iter().rev() {
|
||||||
let dev = devices.lock().await.remove(*index);
|
let dev = devices.lock().await.remove(*index);
|
||||||
|
let hid_key = dev.hid_key.clone();
|
||||||
let path = path.clone();
|
let path = path.clone();
|
||||||
let res = match dev.device {
|
let res = match dev.device {
|
||||||
DeviceHandle::Aura(_) => {
|
DeviceHandle::Aura(_) => {
|
||||||
@@ -509,17 +554,23 @@ impl DeviceManager {
|
|||||||
.remove::<ScsiZbus, _>(&path)
|
.remove::<ScsiZbus, _>(&path)
|
||||||
.await?
|
.await?
|
||||||
}
|
}
|
||||||
_ => todo!()
|
_ => todo!(),
|
||||||
};
|
};
|
||||||
info!("AuraManager removed: {path:?}, {res}");
|
info!("AuraManager removed: {path:?}, {res}");
|
||||||
|
if let Some(key) = hid_key {
|
||||||
|
hid_handles.lock().await.remove(&key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if action == "add" {
|
} else if action == "add" {
|
||||||
let evdev = event.device();
|
let evdev = event.device();
|
||||||
if let Ok(mut new_devs) =
|
if let Ok(mut new_devs) = Self::init_hid_devices(
|
||||||
Self::init_hid_devices(&conn_copy, evdev)
|
&conn_copy,
|
||||||
.await
|
evdev,
|
||||||
.map_err(|e| error!("Couldn't add new device: {e:?}"))
|
hid_handles.clone(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|e| error!("Couldn't add new device: {e:?}"))
|
||||||
{
|
{
|
||||||
devices.lock().await.append(&mut new_devs);
|
devices.lock().await.append(&mut new_devs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ pub struct ScsiConfig {
|
|||||||
pub dev_type: AuraDeviceType,
|
pub dev_type: AuraDeviceType,
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
pub current_mode: AuraMode,
|
pub current_mode: AuraMode,
|
||||||
pub modes: BTreeMap<AuraMode, AuraEffect>
|
pub modes: BTreeMap<AuraMode, AuraEffect>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScsiConfig {
|
impl ScsiConfig {
|
||||||
@@ -38,61 +38,61 @@ impl Default for ScsiConfig {
|
|||||||
(AuraMode::Off, AuraEffect::default_with_mode(AuraMode::Off)),
|
(AuraMode::Off, AuraEffect::default_with_mode(AuraMode::Off)),
|
||||||
(
|
(
|
||||||
AuraMode::Static,
|
AuraMode::Static,
|
||||||
AuraEffect::default_with_mode(AuraMode::Static)
|
AuraEffect::default_with_mode(AuraMode::Static),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
AuraMode::Breathe,
|
AuraMode::Breathe,
|
||||||
AuraEffect::default_with_mode(AuraMode::Breathe)
|
AuraEffect::default_with_mode(AuraMode::Breathe),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
AuraMode::Flashing,
|
AuraMode::Flashing,
|
||||||
AuraEffect::default_with_mode(AuraMode::Flashing)
|
AuraEffect::default_with_mode(AuraMode::Flashing),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
AuraMode::RainbowCycle,
|
AuraMode::RainbowCycle,
|
||||||
AuraEffect::default_with_mode(AuraMode::RainbowCycle)
|
AuraEffect::default_with_mode(AuraMode::RainbowCycle),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
AuraMode::RainbowWave,
|
AuraMode::RainbowWave,
|
||||||
AuraEffect::default_with_mode(AuraMode::RainbowWave)
|
AuraEffect::default_with_mode(AuraMode::RainbowWave),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
AuraMode::RainbowCycleBreathe,
|
AuraMode::RainbowCycleBreathe,
|
||||||
AuraEffect::default_with_mode(AuraMode::RainbowCycleBreathe)
|
AuraEffect::default_with_mode(AuraMode::RainbowCycleBreathe),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
AuraMode::ChaseFade,
|
AuraMode::ChaseFade,
|
||||||
AuraEffect::default_with_mode(AuraMode::ChaseFade)
|
AuraEffect::default_with_mode(AuraMode::ChaseFade),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
AuraMode::RainbowCycleChaseFade,
|
AuraMode::RainbowCycleChaseFade,
|
||||||
AuraEffect::default_with_mode(AuraMode::RainbowCycleChaseFade)
|
AuraEffect::default_with_mode(AuraMode::RainbowCycleChaseFade),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
AuraMode::Chase,
|
AuraMode::Chase,
|
||||||
AuraEffect::default_with_mode(AuraMode::Chase)
|
AuraEffect::default_with_mode(AuraMode::Chase),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
AuraMode::RainbowCycleChase,
|
AuraMode::RainbowCycleChase,
|
||||||
AuraEffect::default_with_mode(AuraMode::RainbowCycleChase)
|
AuraEffect::default_with_mode(AuraMode::RainbowCycleChase),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
AuraMode::RainbowCycleWave,
|
AuraMode::RainbowCycleWave,
|
||||||
AuraEffect::default_with_mode(AuraMode::RainbowCycleWave)
|
AuraEffect::default_with_mode(AuraMode::RainbowCycleWave),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
AuraMode::RainbowPulseChase,
|
AuraMode::RainbowPulseChase,
|
||||||
AuraEffect::default_with_mode(AuraMode::RainbowPulseChase)
|
AuraEffect::default_with_mode(AuraMode::RainbowPulseChase),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
AuraMode::RandomFlicker,
|
AuraMode::RandomFlicker,
|
||||||
AuraEffect::default_with_mode(AuraMode::RandomFlicker)
|
AuraEffect::default_with_mode(AuraMode::RandomFlicker),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
AuraMode::DoubleFade,
|
AuraMode::DoubleFade,
|
||||||
AuraEffect::default_with_mode(AuraMode::DoubleFade)
|
AuraEffect::default_with_mode(AuraMode::DoubleFade),
|
||||||
)
|
),
|
||||||
])
|
]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ pub mod trait_impls;
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ScsiAura {
|
pub struct ScsiAura {
|
||||||
device: Arc<Mutex<Device>>,
|
device: Arc<Mutex<Device>>,
|
||||||
config: Arc<Mutex<ScsiConfig>>
|
config: Arc<Mutex<ScsiConfig>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScsiAura {
|
impl ScsiAura {
|
||||||
@@ -20,7 +20,7 @@ impl ScsiAura {
|
|||||||
Self { device, config }
|
Self { device, config }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn lock_config(&self) -> MutexGuard<ScsiConfig> {
|
pub async fn lock_config(&self) -> MutexGuard<'_, ScsiConfig> {
|
||||||
self.config.lock().await
|
self.config.lock().await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ impl ScsiZbus {
|
|||||||
pub async fn start_tasks(
|
pub async fn start_tasks(
|
||||||
self,
|
self,
|
||||||
connection: &Connection,
|
connection: &Connection,
|
||||||
path: OwnedObjectPath
|
path: OwnedObjectPath,
|
||||||
) -> Result<(), RogError> {
|
) -> Result<(), RogError> {
|
||||||
connection
|
connection
|
||||||
.object_server()
|
.object_server()
|
||||||
@@ -87,7 +87,7 @@ impl ScsiZbus {
|
|||||||
let mode = config.current_mode;
|
let mode = config.current_mode;
|
||||||
match config.modes.get(&mode) {
|
match config.modes.get(&mode) {
|
||||||
Some(effect) => Ok(effect.clone()),
|
Some(effect) => Ok(effect.clone()),
|
||||||
None => Err(ZbErr::Failed("Could not get the current effect".into()))
|
None => Err(ZbErr::Failed("Could not get the current effect".into())),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(ZbErr::Failed("Aura control couldn't lock self".to_string()))
|
Err(ZbErr::Failed("Aura control couldn't lock self".to_string()))
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ pub struct SlashConfig {
|
|||||||
pub show_on_shutdown: bool,
|
pub show_on_shutdown: bool,
|
||||||
pub show_on_sleep: bool,
|
pub show_on_sleep: bool,
|
||||||
pub show_on_battery: bool,
|
pub show_on_battery: bool,
|
||||||
pub show_battery_warning: bool
|
pub show_battery_warning: bool,
|
||||||
|
pub show_on_lid_closed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SlashConfig {
|
impl Default for SlashConfig {
|
||||||
@@ -32,7 +33,8 @@ impl Default for SlashConfig {
|
|||||||
show_on_shutdown: true,
|
show_on_shutdown: true,
|
||||||
show_on_sleep: true,
|
show_on_sleep: true,
|
||||||
show_on_battery: true,
|
show_on_battery: true,
|
||||||
show_battery_warning: true
|
show_battery_warning: true,
|
||||||
|
show_on_lid_closed: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,7 +60,7 @@ impl From<&SlashConfig> for DeviceState {
|
|||||||
slash_enabled: config.enabled,
|
slash_enabled: config.enabled,
|
||||||
slash_brightness: config.brightness,
|
slash_brightness: config.brightness,
|
||||||
slash_interval: config.display_interval,
|
slash_interval: config.display_interval,
|
||||||
slash_mode: config.display_mode
|
slash_mode: config.display_mode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ use std::sync::Arc;
|
|||||||
use config::SlashConfig;
|
use config::SlashConfig;
|
||||||
use rog_platform::hid_raw::HidRaw;
|
use rog_platform::hid_raw::HidRaw;
|
||||||
use rog_platform::usb_raw::USBRaw;
|
use rog_platform::usb_raw::USBRaw;
|
||||||
use rog_slash::usb::{get_options_packet, pkt_set_mode, pkts_for_init};
|
use rog_slash::usb::{slash_pkt_enable, slash_pkt_init, slash_pkt_options, slash_pkt_set_mode};
|
||||||
use rog_slash::SlashType;
|
|
||||||
use tokio::sync::{Mutex, MutexGuard};
|
use tokio::sync::{Mutex, MutexGuard};
|
||||||
|
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
@@ -16,19 +15,19 @@ pub mod trait_impls;
|
|||||||
pub struct Slash {
|
pub struct Slash {
|
||||||
hid: Option<Arc<Mutex<HidRaw>>>,
|
hid: Option<Arc<Mutex<HidRaw>>>,
|
||||||
usb: Option<Arc<Mutex<USBRaw>>>,
|
usb: Option<Arc<Mutex<USBRaw>>>,
|
||||||
config: Arc<Mutex<SlashConfig>>
|
config: Arc<Mutex<SlashConfig>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Slash {
|
impl Slash {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
hid: Option<Arc<Mutex<HidRaw>>>,
|
hid: Option<Arc<Mutex<HidRaw>>>,
|
||||||
usb: Option<Arc<Mutex<USBRaw>>>,
|
usb: Option<Arc<Mutex<USBRaw>>>,
|
||||||
config: Arc<Mutex<SlashConfig>>
|
config: Arc<Mutex<SlashConfig>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { hid, usb, config }
|
Self { hid, usb, config }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn lock_config(&self) -> MutexGuard<SlashConfig> {
|
pub async fn lock_config(&self) -> MutexGuard<'_, SlashConfig> {
|
||||||
self.config.lock().await
|
self.config.lock().await
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,22 +45,22 @@ impl Slash {
|
|||||||
pub async fn do_initialization(&self) -> Result<(), RogError> {
|
pub async fn do_initialization(&self) -> Result<(), RogError> {
|
||||||
// Don't try to initialise these models as the asus drivers already did
|
// Don't try to initialise these models as the asus drivers already did
|
||||||
let config = self.config.lock().await;
|
let config = self.config.lock().await;
|
||||||
if !matches!(config.slash_type, SlashType::GA605 | SlashType::GU605) {
|
for pkt in &slash_pkt_init(config.slash_type) {
|
||||||
for pkt in &pkts_for_init(config.slash_type) {
|
self.write_bytes(pkt).await?;
|
||||||
self.write_bytes(pkt).await?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
self.write_bytes(&slash_pkt_enable(config.slash_type, config.enabled))
|
||||||
|
.await?;
|
||||||
|
|
||||||
// Apply config upon initialization
|
// Apply config upon initialization
|
||||||
let option_packets = get_options_packet(
|
let option_packets = slash_pkt_options(
|
||||||
config.slash_type,
|
config.slash_type,
|
||||||
config.enabled,
|
config.enabled,
|
||||||
config.brightness,
|
config.brightness,
|
||||||
config.display_interval
|
config.display_interval,
|
||||||
);
|
);
|
||||||
self.write_bytes(&option_packets).await?;
|
self.write_bytes(&option_packets).await?;
|
||||||
|
|
||||||
let mode_packets = pkt_set_mode(config.slash_type, config.display_mode);
|
let mode_packets = slash_pkt_set_mode(config.slash_type, config.display_mode);
|
||||||
// self.node.write_bytes(&mode_packets[0])?;
|
// self.node.write_bytes(&mode_packets[0])?;
|
||||||
self.write_bytes(&mode_packets[1]).await?;
|
self.write_bytes(&mode_packets[1]).await?;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use config_traits::StdConfig;
|
use config_traits::StdConfig;
|
||||||
use log::{debug, error, warn};
|
use log::{debug, error, warn};
|
||||||
use rog_slash::usb::{
|
use rog_slash::usb::{
|
||||||
get_battery_saver_packet, get_boot_packet, get_low_battery_packet, get_options_packet,
|
slash_pkt_battery_saver, slash_pkt_boot, slash_pkt_enable, slash_pkt_lid_closed,
|
||||||
get_shutdown_packet, get_sleep_packet, pkt_save, pkt_set_mode
|
slash_pkt_low_battery, slash_pkt_options, slash_pkt_save, slash_pkt_set_mode,
|
||||||
|
slash_pkt_shutdown, slash_pkt_sleep,
|
||||||
};
|
};
|
||||||
use rog_slash::{DeviceState, SlashMode};
|
use rog_slash::{DeviceState, SlashMode};
|
||||||
use zbus::zvariant::OwnedObjectPath;
|
use zbus::zvariant::OwnedObjectPath;
|
||||||
@@ -23,7 +24,7 @@ impl SlashZbus {
|
|||||||
pub async fn start_tasks(
|
pub async fn start_tasks(
|
||||||
mut self,
|
mut self,
|
||||||
connection: &Connection,
|
connection: &Connection,
|
||||||
path: OwnedObjectPath
|
path: OwnedObjectPath,
|
||||||
) -> Result<(), RogError> {
|
) -> Result<(), RogError> {
|
||||||
// let task = zbus.clone();
|
// let task = zbus.clone();
|
||||||
self.reload()
|
self.reload()
|
||||||
@@ -58,11 +59,18 @@ impl SlashZbus {
|
|||||||
config.brightness
|
config.brightness
|
||||||
};
|
};
|
||||||
self.0
|
self.0
|
||||||
.write_bytes(&get_options_packet(
|
.write_bytes(&slash_pkt_enable(config.slash_type, enabled))
|
||||||
|
.await
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("ctrl_slash::enable {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
self.0
|
||||||
|
.write_bytes(&slash_pkt_options(
|
||||||
config.slash_type,
|
config.slash_type,
|
||||||
enabled,
|
enabled,
|
||||||
brightness,
|
brightness,
|
||||||
config.display_interval
|
config.display_interval,
|
||||||
))
|
))
|
||||||
.await
|
.await
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
@@ -88,11 +96,11 @@ impl SlashZbus {
|
|||||||
let mut config = self.0.lock_config().await;
|
let mut config = self.0.lock_config().await;
|
||||||
let enabled = brightness > 0;
|
let enabled = brightness > 0;
|
||||||
self.0
|
self.0
|
||||||
.write_bytes(&get_options_packet(
|
.write_bytes(&slash_pkt_options(
|
||||||
config.slash_type,
|
config.slash_type,
|
||||||
enabled,
|
enabled,
|
||||||
brightness,
|
brightness,
|
||||||
config.display_interval
|
config.display_interval,
|
||||||
))
|
))
|
||||||
.await
|
.await
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
@@ -116,8 +124,8 @@ impl SlashZbus {
|
|||||||
async fn set_interval(&self, interval: u8) {
|
async fn set_interval(&self, interval: u8) {
|
||||||
let mut config = self.0.lock_config().await;
|
let mut config = self.0.lock_config().await;
|
||||||
self.0
|
self.0
|
||||||
.write_bytes(&get_options_packet(
|
.write_bytes(&slash_pkt_options(
|
||||||
config.slash_type, config.enabled, config.brightness, interval
|
config.slash_type, config.enabled, config.brightness, interval,
|
||||||
))
|
))
|
||||||
.await
|
.await
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
@@ -140,10 +148,12 @@ impl SlashZbus {
|
|||||||
async fn set_mode(&self, mode: SlashMode) -> zbus::Result<()> {
|
async fn set_mode(&self, mode: SlashMode) -> zbus::Result<()> {
|
||||||
let mut config = self.0.lock_config().await;
|
let mut config = self.0.lock_config().await;
|
||||||
|
|
||||||
let command_packets = pkt_set_mode(config.slash_type, mode);
|
let command_packets = slash_pkt_set_mode(config.slash_type, mode);
|
||||||
// self.node.write_bytes(&command_packets[0])?;
|
// self.node.write_bytes(&command_packets[0])?;
|
||||||
self.0.write_bytes(&command_packets[1]).await?;
|
self.0.write_bytes(&command_packets[1]).await?;
|
||||||
self.0.write_bytes(&pkt_save(config.slash_type)).await?;
|
self.0
|
||||||
|
.write_bytes(&slash_pkt_save(config.slash_type))
|
||||||
|
.await?;
|
||||||
|
|
||||||
config.display_mode = mode;
|
config.display_mode = mode;
|
||||||
config.write();
|
config.write();
|
||||||
@@ -167,7 +177,7 @@ impl SlashZbus {
|
|||||||
async fn set_show_on_boot(&self, enable: bool) -> zbus::Result<()> {
|
async fn set_show_on_boot(&self, enable: bool) -> zbus::Result<()> {
|
||||||
let mut config = self.0.lock_config().await;
|
let mut config = self.0.lock_config().await;
|
||||||
self.0
|
self.0
|
||||||
.write_bytes(&get_boot_packet(config.slash_type, enable))
|
.write_bytes(&slash_pkt_boot(config.slash_type, enable))
|
||||||
.await?;
|
.await?;
|
||||||
config.show_on_boot = enable;
|
config.show_on_boot = enable;
|
||||||
config.write();
|
config.write();
|
||||||
@@ -184,7 +194,7 @@ impl SlashZbus {
|
|||||||
async fn set_show_on_sleep(&self, enable: bool) -> zbus::Result<()> {
|
async fn set_show_on_sleep(&self, enable: bool) -> zbus::Result<()> {
|
||||||
let mut config = self.0.lock_config().await;
|
let mut config = self.0.lock_config().await;
|
||||||
self.0
|
self.0
|
||||||
.write_bytes(&get_sleep_packet(config.slash_type, enable))
|
.write_bytes(&slash_pkt_sleep(config.slash_type, enable))
|
||||||
.await?;
|
.await?;
|
||||||
config.show_on_sleep = enable;
|
config.show_on_sleep = enable;
|
||||||
config.write();
|
config.write();
|
||||||
@@ -201,7 +211,7 @@ impl SlashZbus {
|
|||||||
async fn set_show_on_shutdown(&self, enable: bool) -> zbus::Result<()> {
|
async fn set_show_on_shutdown(&self, enable: bool) -> zbus::Result<()> {
|
||||||
let mut config = self.0.lock_config().await;
|
let mut config = self.0.lock_config().await;
|
||||||
self.0
|
self.0
|
||||||
.write_bytes(&get_shutdown_packet(config.slash_type, enable))
|
.write_bytes(&slash_pkt_shutdown(config.slash_type, enable))
|
||||||
.await?;
|
.await?;
|
||||||
config.show_on_shutdown = enable;
|
config.show_on_shutdown = enable;
|
||||||
config.write();
|
config.write();
|
||||||
@@ -218,7 +228,7 @@ impl SlashZbus {
|
|||||||
async fn set_show_on_battery(&self, enable: bool) -> zbus::Result<()> {
|
async fn set_show_on_battery(&self, enable: bool) -> zbus::Result<()> {
|
||||||
let mut config = self.0.lock_config().await;
|
let mut config = self.0.lock_config().await;
|
||||||
self.0
|
self.0
|
||||||
.write_bytes(&get_battery_saver_packet(config.slash_type, enable))
|
.write_bytes(&slash_pkt_battery_saver(config.slash_type, enable))
|
||||||
.await?;
|
.await?;
|
||||||
config.show_on_battery = enable;
|
config.show_on_battery = enable;
|
||||||
config.write();
|
config.write();
|
||||||
@@ -235,12 +245,32 @@ impl SlashZbus {
|
|||||||
async fn set_show_battery_warning(&self, enable: bool) -> zbus::Result<()> {
|
async fn set_show_battery_warning(&self, enable: bool) -> zbus::Result<()> {
|
||||||
let mut config = self.0.lock_config().await;
|
let mut config = self.0.lock_config().await;
|
||||||
self.0
|
self.0
|
||||||
.write_bytes(&get_low_battery_packet(config.slash_type, enable))
|
.write_bytes(&slash_pkt_low_battery(config.slash_type, enable))
|
||||||
.await?;
|
.await?;
|
||||||
config.show_battery_warning = enable;
|
config.show_battery_warning = enable;
|
||||||
config.write();
|
config.write();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn show_on_lid_closed(&self) -> zbus::fdo::Result<bool> {
|
||||||
|
let config = self.0.lock_config().await;
|
||||||
|
Ok(config.show_on_lid_closed)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn set_show_on_lid_closed(&self, enable: bool) -> zbus::Result<()> {
|
||||||
|
let mut config = self.0.lock_config().await;
|
||||||
|
self.0
|
||||||
|
.write_bytes(&slash_pkt_lid_closed(config.slash_type, enable))
|
||||||
|
.await?;
|
||||||
|
self.0
|
||||||
|
.write_bytes(&slash_pkt_save(config.slash_type))
|
||||||
|
.await?;
|
||||||
|
config.show_on_lid_closed = enable;
|
||||||
|
config.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Reloadable for SlashZbus {
|
impl Reloadable for SlashZbus {
|
||||||
@@ -248,11 +278,11 @@ impl Reloadable for SlashZbus {
|
|||||||
debug!("reloading slash settings");
|
debug!("reloading slash settings");
|
||||||
let config = self.0.lock_config().await;
|
let config = self.0.lock_config().await;
|
||||||
self.0
|
self.0
|
||||||
.write_bytes(&get_options_packet(
|
.write_bytes(&slash_pkt_options(
|
||||||
config.slash_type,
|
config.slash_type,
|
||||||
config.enabled,
|
config.enabled,
|
||||||
config.brightness,
|
config.brightness,
|
||||||
config.display_interval
|
config.display_interval,
|
||||||
))
|
))
|
||||||
.await
|
.await
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
@@ -272,12 +302,12 @@ impl Reloadable for SlashZbus {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
write_bytes_with_warning!(get_boot_packet, show_on_boot, "show_on_boot");
|
write_bytes_with_warning!(slash_pkt_boot, show_on_boot, "show_on_boot");
|
||||||
write_bytes_with_warning!(get_sleep_packet, show_on_sleep, "show_on_sleep");
|
write_bytes_with_warning!(slash_pkt_sleep, show_on_sleep, "show_on_sleep");
|
||||||
write_bytes_with_warning!(get_shutdown_packet, show_on_shutdown, "show_on_shutdown");
|
write_bytes_with_warning!(slash_pkt_shutdown, show_on_shutdown, "show_on_shutdown");
|
||||||
write_bytes_with_warning!(get_battery_saver_packet, show_on_battery, "show_on_battery");
|
write_bytes_with_warning!(slash_pkt_battery_saver, show_on_battery, "show_on_battery");
|
||||||
write_bytes_with_warning!(
|
write_bytes_with_warning!(
|
||||||
get_low_battery_packet,
|
slash_pkt_low_battery,
|
||||||
show_battery_warning,
|
show_battery_warning,
|
||||||
"show_battery_warning"
|
"show_battery_warning"
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ pub enum _DeviceHandle {
|
|||||||
LedClass(KeyboardBacklight),
|
LedClass(KeyboardBacklight),
|
||||||
/// TODO
|
/// TODO
|
||||||
MulticolourLed,
|
MulticolourLed,
|
||||||
None
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -47,14 +47,14 @@ pub enum DeviceHandle {
|
|||||||
TufLedClass(Arc<Mutex<HidRaw>>),
|
TufLedClass(Arc<Mutex<HidRaw>>),
|
||||||
/// TODO
|
/// TODO
|
||||||
MulticolourLed,
|
MulticolourLed,
|
||||||
None
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceHandle {
|
impl DeviceHandle {
|
||||||
/// Try Slash HID. If one exists it is initialsed and returned.
|
/// Try Slash HID. If one exists it is initialsed and returned.
|
||||||
pub async fn new_slash_hid(
|
pub async fn new_slash_hid(
|
||||||
device: Arc<Mutex<HidRaw>>,
|
device: Arc<Mutex<HidRaw>>,
|
||||||
prod_id: &str
|
prod_id: &str,
|
||||||
) -> Result<Self, RogError> {
|
) -> Result<Self, RogError> {
|
||||||
debug!("Testing for HIDRAW Slash");
|
debug!("Testing for HIDRAW Slash");
|
||||||
let slash_type = SlashType::from_dmi();
|
let slash_type = SlashType::from_dmi();
|
||||||
@@ -93,7 +93,7 @@ impl DeviceHandle {
|
|||||||
let slash = Slash::new(
|
let slash = Slash::new(
|
||||||
None,
|
None,
|
||||||
Some(Arc::new(Mutex::new(usb))),
|
Some(Arc::new(Mutex::new(usb))),
|
||||||
Arc::new(Mutex::new(config))
|
Arc::new(Mutex::new(config)),
|
||||||
);
|
);
|
||||||
slash.do_initialization().await?;
|
slash.do_initialization().await?;
|
||||||
Ok(Self::Slash(slash))
|
Ok(Self::Slash(slash))
|
||||||
@@ -105,11 +105,11 @@ impl DeviceHandle {
|
|||||||
/// Try AniMe Matrix HID. If one exists it is initialsed and returned.
|
/// Try AniMe Matrix HID. If one exists it is initialsed and returned.
|
||||||
pub async fn maybe_anime_hid(
|
pub async fn maybe_anime_hid(
|
||||||
_device: Arc<Mutex<HidRaw>>,
|
_device: Arc<Mutex<HidRaw>>,
|
||||||
_prod_id: &str
|
_prod_id: &str,
|
||||||
) -> Result<Self, RogError> {
|
) -> Result<Self, RogError> {
|
||||||
// TODO: can't use HIDRAW for anime at the moment
|
// TODO: can't use HIDRAW for anime at the moment
|
||||||
Err(RogError::NotFound(
|
Err(RogError::NotFound(
|
||||||
"Can't use anime over hidraw yet. Skip.".to_string()
|
"Can't use anime over hidraw yet. Skip.".to_string(),
|
||||||
))
|
))
|
||||||
|
|
||||||
// debug!("Testing for HIDRAW AniMe");
|
// debug!("Testing for HIDRAW AniMe");
|
||||||
@@ -144,13 +144,13 @@ impl DeviceHandle {
|
|||||||
let mut anime = AniMe::new(
|
let mut anime = AniMe::new(
|
||||||
None,
|
None,
|
||||||
Some(Arc::new(Mutex::new(usb))),
|
Some(Arc::new(Mutex::new(usb))),
|
||||||
Arc::new(Mutex::new(config))
|
Arc::new(Mutex::new(config)),
|
||||||
);
|
);
|
||||||
anime.do_initialization().await?;
|
anime.do_initialization().await?;
|
||||||
Ok(Self::AniMe(anime))
|
Ok(Self::AniMe(anime))
|
||||||
} else {
|
} else {
|
||||||
Err(RogError::NotFound(
|
Err(RogError::NotFound(
|
||||||
"No AnimeMatrix device found".to_string()
|
"No AnimeMatrix device found".to_string(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,7 +174,7 @@ impl DeviceHandle {
|
|||||||
|
|
||||||
pub async fn maybe_laptop_aura(
|
pub async fn maybe_laptop_aura(
|
||||||
device: Option<Arc<Mutex<HidRaw>>>,
|
device: Option<Arc<Mutex<HidRaw>>>,
|
||||||
prod_id: &str
|
prod_id: &str,
|
||||||
) -> Result<Self, RogError> {
|
) -> Result<Self, RogError> {
|
||||||
debug!("Testing for laptop aura");
|
debug!("Testing for laptop aura");
|
||||||
let aura_type = AuraDeviceType::from(prod_id);
|
let aura_type = AuraDeviceType::from(prod_id);
|
||||||
@@ -201,7 +201,7 @@ impl DeviceHandle {
|
|||||||
let aura = Aura {
|
let aura = Aura {
|
||||||
hid: device,
|
hid: device,
|
||||||
backlight,
|
backlight,
|
||||||
config: Arc::new(Mutex::new(config))
|
config: Arc::new(Mutex::new(config)),
|
||||||
};
|
};
|
||||||
aura.do_initialization().await?;
|
aura.do_initialization().await?;
|
||||||
Ok(Self::Aura(aura))
|
Ok(Self::Aura(aura))
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use config_traits::{StdConfig, StdConfigLoad1};
|
use config_traits::{StdConfig, StdConfigLoad2};
|
||||||
use rog_platform::asus_armoury::FirmwareAttribute;
|
use rog_platform::asus_armoury::FirmwareAttribute;
|
||||||
use rog_platform::cpu::CPUEPP;
|
use rog_platform::cpu::CPUEPP;
|
||||||
use rog_platform::platform::PlatformProfile;
|
use rog_platform::platform::PlatformProfile;
|
||||||
@@ -8,10 +8,16 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
const CONFIG_FILE: &str = "asusd.ron";
|
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)]
|
#[derive(Default, Clone, Deserialize, Serialize, PartialEq)]
|
||||||
pub struct Tuning {
|
pub struct Tuning {
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
pub group: HashMap<FirmwareAttribute, i32>
|
pub group: HashMap<FirmwareAttribute, i32>,
|
||||||
}
|
}
|
||||||
type Tunings = HashMap<PlatformProfile, Tuning>;
|
type Tunings = HashMap<PlatformProfile, Tuning>;
|
||||||
|
|
||||||
@@ -19,8 +25,8 @@ type Tunings = HashMap<PlatformProfile, Tuning>;
|
|||||||
pub struct Config {
|
pub struct Config {
|
||||||
// The current charge limit applied
|
// The current charge limit applied
|
||||||
pub charge_control_end_threshold: u8,
|
pub charge_control_end_threshold: u8,
|
||||||
/// Save charge limit for restoring
|
/// Save charge limit for restoring after one-shot full charge
|
||||||
#[serde(skip)]
|
#[serde(default = "default_base_charge_limit")]
|
||||||
pub base_charge_control_end_threshold: u8,
|
pub base_charge_control_end_threshold: u8,
|
||||||
pub disable_nvidia_powerd_on_battery: bool,
|
pub disable_nvidia_powerd_on_battery: bool,
|
||||||
/// An optional command/script to run when power is changed to AC
|
/// An optional command/script to run when power is changed to AC
|
||||||
@@ -43,13 +49,19 @@ pub struct Config {
|
|||||||
/// The energy_performance_preference for this platform profile
|
/// The energy_performance_preference for this platform profile
|
||||||
pub profile_balanced_epp: CPUEPP,
|
pub profile_balanced_epp: CPUEPP,
|
||||||
/// The energy_performance_preference for this platform profile
|
/// The energy_performance_preference for this platform profile
|
||||||
|
pub profile_custom_epp: CPUEPP,
|
||||||
|
/// The energy_performance_preference for this platform profile
|
||||||
pub profile_performance_epp: CPUEPP,
|
pub profile_performance_epp: CPUEPP,
|
||||||
pub ac_profile_tunings: Tunings,
|
pub ac_profile_tunings: Tunings,
|
||||||
pub dc_profile_tunings: Tunings,
|
pub dc_profile_tunings: Tunings,
|
||||||
pub armoury_settings: HashMap<FirmwareAttribute, i32>,
|
pub armoury_settings: HashMap<FirmwareAttribute, i32>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none", default)]
|
||||||
|
pub screenpad_gamma: Option<f32>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none", default)]
|
||||||
|
pub screenpad_sync_primary: Option<bool>,
|
||||||
/// Temporary state for AC/Batt
|
/// Temporary state for AC/Batt
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub last_power_plugged: u8
|
pub last_power_plugged: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
@@ -61,12 +73,28 @@ impl Config {
|
|||||||
};
|
};
|
||||||
config.entry(profile).or_insert_with(Tuning::default)
|
config.entry(profile).or_insert_with(Tuning::default)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn select_tunings_ref(
|
||||||
|
&self,
|
||||||
|
power_plugged: bool,
|
||||||
|
profile: PlatformProfile,
|
||||||
|
) -> Option<&Tuning> {
|
||||||
|
let config = if power_plugged {
|
||||||
|
&self.ac_profile_tunings
|
||||||
|
} else {
|
||||||
|
&self.dc_profile_tunings
|
||||||
|
};
|
||||||
|
config.get(&profile)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
charge_control_end_threshold: 100,
|
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,
|
base_charge_control_end_threshold: 100,
|
||||||
disable_nvidia_powerd_on_battery: true,
|
disable_nvidia_powerd_on_battery: true,
|
||||||
ac_command: Default::default(),
|
ac_command: Default::default(),
|
||||||
@@ -79,10 +107,13 @@ impl Default for Config {
|
|||||||
profile_quiet_epp: CPUEPP::Power,
|
profile_quiet_epp: CPUEPP::Power,
|
||||||
profile_balanced_epp: CPUEPP::BalancePower,
|
profile_balanced_epp: CPUEPP::BalancePower,
|
||||||
profile_performance_epp: CPUEPP::Performance,
|
profile_performance_epp: CPUEPP::Performance,
|
||||||
|
profile_custom_epp: CPUEPP::Performance,
|
||||||
ac_profile_tunings: HashMap::default(),
|
ac_profile_tunings: HashMap::default(),
|
||||||
dc_profile_tunings: HashMap::default(),
|
dc_profile_tunings: HashMap::default(),
|
||||||
armoury_settings: HashMap::default(),
|
armoury_settings: HashMap::default(),
|
||||||
last_power_plugged: Default::default()
|
last_power_plugged: Default::default(),
|
||||||
|
screenpad_gamma: Default::default(),
|
||||||
|
screenpad_sync_primary: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,7 +140,64 @@ impl StdConfig for Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StdConfigLoad1<Config601> for Config {}
|
impl StdConfigLoad2<Config611, Config601> for Config {}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct Config611 {
|
||||||
|
pub charge_control_end_threshold: u8,
|
||||||
|
#[serde(skip)]
|
||||||
|
pub base_charge_control_end_threshold: u8,
|
||||||
|
pub disable_nvidia_powerd_on_battery: bool,
|
||||||
|
pub ac_command: String,
|
||||||
|
pub bat_command: String,
|
||||||
|
pub platform_profile_linked_epp: bool,
|
||||||
|
pub platform_profile_on_battery: PlatformProfile,
|
||||||
|
pub change_platform_profile_on_battery: bool,
|
||||||
|
pub platform_profile_on_ac: PlatformProfile,
|
||||||
|
pub change_platform_profile_on_ac: bool,
|
||||||
|
pub profile_quiet_epp: CPUEPP,
|
||||||
|
pub profile_balanced_epp: CPUEPP,
|
||||||
|
pub profile_custom_epp: CPUEPP,
|
||||||
|
pub profile_performance_epp: CPUEPP,
|
||||||
|
pub ac_profile_tunings: Tunings,
|
||||||
|
pub dc_profile_tunings: Tunings,
|
||||||
|
pub armoury_settings: HashMap<FirmwareAttribute, i32>,
|
||||||
|
#[serde(skip)]
|
||||||
|
pub last_power_plugged: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Config611> for Config {
|
||||||
|
fn from(c: Config611) -> Self {
|
||||||
|
let mut config = Self {
|
||||||
|
// Restore the base charge limit
|
||||||
|
charge_control_end_threshold: c.charge_control_end_threshold,
|
||||||
|
base_charge_control_end_threshold: c.charge_control_end_threshold,
|
||||||
|
disable_nvidia_powerd_on_battery: c.disable_nvidia_powerd_on_battery,
|
||||||
|
ac_command: c.ac_command,
|
||||||
|
bat_command: c.bat_command,
|
||||||
|
platform_profile_linked_epp: c.platform_profile_linked_epp,
|
||||||
|
platform_profile_on_battery: c.platform_profile_on_battery,
|
||||||
|
change_platform_profile_on_battery: c.change_platform_profile_on_battery,
|
||||||
|
platform_profile_on_ac: c.platform_profile_on_ac,
|
||||||
|
change_platform_profile_on_ac: c.change_platform_profile_on_ac,
|
||||||
|
profile_quiet_epp: c.profile_quiet_epp,
|
||||||
|
profile_balanced_epp: c.profile_balanced_epp,
|
||||||
|
profile_performance_epp: c.profile_performance_epp,
|
||||||
|
profile_custom_epp: c.profile_performance_epp,
|
||||||
|
last_power_plugged: c.last_power_plugged,
|
||||||
|
ac_profile_tunings: HashMap::default(),
|
||||||
|
dc_profile_tunings: HashMap::default(),
|
||||||
|
armoury_settings: HashMap::default(),
|
||||||
|
screenpad_gamma: None,
|
||||||
|
screenpad_sync_primary: Default::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
config.ac_profile_tunings = c.ac_profile_tunings;
|
||||||
|
config.dc_profile_tunings = c.dc_profile_tunings;
|
||||||
|
config.armoury_settings = c.armoury_settings;
|
||||||
|
config
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct Config601 {
|
pub struct Config601 {
|
||||||
@@ -147,7 +235,7 @@ pub struct Config601 {
|
|||||||
#[serde(skip_serializing_if = "Option::is_none", default)]
|
#[serde(skip_serializing_if = "Option::is_none", default)]
|
||||||
pub nv_temp_target: Option<u8>,
|
pub nv_temp_target: Option<u8>,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub last_power_plugged: u8
|
pub last_power_plugged: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Config601> for Config {
|
impl From<Config601> for Config {
|
||||||
@@ -167,10 +255,13 @@ impl From<Config601> for Config {
|
|||||||
profile_quiet_epp: c.profile_quiet_epp,
|
profile_quiet_epp: c.profile_quiet_epp,
|
||||||
profile_balanced_epp: c.profile_balanced_epp,
|
profile_balanced_epp: c.profile_balanced_epp,
|
||||||
profile_performance_epp: c.profile_performance_epp,
|
profile_performance_epp: c.profile_performance_epp,
|
||||||
|
profile_custom_epp: c.profile_performance_epp,
|
||||||
last_power_plugged: c.last_power_plugged,
|
last_power_plugged: c.last_power_plugged,
|
||||||
ac_profile_tunings: HashMap::default(),
|
ac_profile_tunings: HashMap::default(),
|
||||||
dc_profile_tunings: HashMap::default(),
|
dc_profile_tunings: HashMap::default(),
|
||||||
armoury_settings: HashMap::default()
|
armoury_settings: HashMap::default(),
|
||||||
|
screenpad_gamma: None,
|
||||||
|
screenpad_sync_primary: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
348
asusd/src/ctrl_backlight.rs
Normal file
348
asusd/src/ctrl_backlight.rs
Normal file
@@ -0,0 +1,348 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use config_traits::StdConfig;
|
||||||
|
use log::{info, warn};
|
||||||
|
use rog_platform::backlight::{Backlight, BacklightType};
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
use zbus::fdo::Error as FdoErr;
|
||||||
|
use zbus::object_server::SignalEmitter;
|
||||||
|
use zbus::{interface, Connection};
|
||||||
|
|
||||||
|
use crate::config::Config;
|
||||||
|
use crate::error::RogError;
|
||||||
|
use crate::ASUS_ZBUS_PATH;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct CtrlBacklight {
|
||||||
|
backlights: Vec<Backlight>,
|
||||||
|
config: Arc<Mutex<Config>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CtrlBacklight {
|
||||||
|
pub fn new(config: Arc<Mutex<Config>>) -> Result<Self, RogError> {
|
||||||
|
let mut backlights = Vec::new();
|
||||||
|
|
||||||
|
if let Ok(primary) = Backlight::new(BacklightType::Primary) {
|
||||||
|
info!("Found primary display backlight");
|
||||||
|
backlights.push(primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(screenpad) = Backlight::new(BacklightType::Screenpad) {
|
||||||
|
info!("Found screenpad backlight");
|
||||||
|
backlights.push(screenpad);
|
||||||
|
}
|
||||||
|
|
||||||
|
if backlights.is_empty() {
|
||||||
|
return Err(RogError::MissingFunction("No backlights found".into()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self { backlights, config })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_backlight(&self, device_type: &BacklightType) -> Option<&Backlight> {
|
||||||
|
self.backlights
|
||||||
|
.iter()
|
||||||
|
.find(|b| b.device_type() == device_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_brightness_with_sync(
|
||||||
|
&self,
|
||||||
|
device_type: &BacklightType,
|
||||||
|
level: i32,
|
||||||
|
) -> Result<(), FdoErr> {
|
||||||
|
let sync = self
|
||||||
|
.config
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.screenpad_sync_primary
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
// If sync is enabled and we're setting screenpad brightness, set primary first
|
||||||
|
if sync && *device_type == BacklightType::Screenpad {
|
||||||
|
if let Some(primary) = self.get_backlight(&BacklightType::Primary) {
|
||||||
|
if let Ok(primary_max) = primary.get_max_brightness() {
|
||||||
|
let primary_scaled = level * primary_max / 100;
|
||||||
|
let _ = primary.set_brightness(primary_scaled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(backlight) = self.get_backlight(device_type) {
|
||||||
|
let max = backlight.get_max_brightness().map_err(|e| {
|
||||||
|
warn!("Failed to get max brightness: {}", e);
|
||||||
|
FdoErr::Failed(format!("Failed to get max brightness: {}", e))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let gamma = self.config.lock().await.screenpad_gamma.unwrap_or(1.0);
|
||||||
|
let scaled = if *device_type == BacklightType::Screenpad {
|
||||||
|
// Apply non-linear scaling with the configurable gamma value only for Screenpad
|
||||||
|
let normalized_level = level as f32 / 100.0;
|
||||||
|
let gamma_corrected = normalized_level.powf(gamma);
|
||||||
|
(gamma_corrected * max as f32) as i32
|
||||||
|
} else {
|
||||||
|
// Linear scaling for other devices
|
||||||
|
level * max / 100
|
||||||
|
};
|
||||||
|
|
||||||
|
backlight.set_brightness(scaled).map_err(|e| {
|
||||||
|
warn!("Failed to set brightness: {}", e);
|
||||||
|
FdoErr::Failed(format!("Failed to set brightness: {}", e))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// If sync is enabled and we're setting primary brightness, set screenpad
|
||||||
|
// afterward
|
||||||
|
if sync && *device_type == BacklightType::Primary {
|
||||||
|
for other in self
|
||||||
|
.backlights
|
||||||
|
.iter()
|
||||||
|
.filter(|b| b.device_type() != device_type)
|
||||||
|
{
|
||||||
|
if let Ok(other_max) = other.get_max_brightness() {
|
||||||
|
let other_scaled = if other.device_type() == &BacklightType::Screenpad {
|
||||||
|
// Apply gamma only to Screenpad
|
||||||
|
let normalized_level = level as f32 / 100.0;
|
||||||
|
let gamma_corrected = normalized_level.powf(gamma);
|
||||||
|
(gamma_corrected * other_max as f32) as i32
|
||||||
|
} else {
|
||||||
|
// Linear scaling for other devices
|
||||||
|
level * other_max / 100
|
||||||
|
};
|
||||||
|
let _ = other.set_brightness(other_scaled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(FdoErr::NotSupported(format!(
|
||||||
|
"Backlight {:?} not found",
|
||||||
|
device_type
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_brightness_percent(&self, device_type: &BacklightType) -> Result<i32, FdoErr> {
|
||||||
|
if let Some(backlight) = self.get_backlight(device_type) {
|
||||||
|
let brightness = backlight.get_brightness().map_err(|e| {
|
||||||
|
warn!("Failed to get brightness: {}", e);
|
||||||
|
FdoErr::Failed(format!("Failed to get brightness: {}", e))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let max = backlight.get_max_brightness().map_err(|e| {
|
||||||
|
warn!("Failed to get max brightness: {}", e);
|
||||||
|
FdoErr::Failed(format!("Failed to get max brightness: {}", e))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if *device_type == BacklightType::Screenpad {
|
||||||
|
let gamma = self.config.lock().await.screenpad_gamma.unwrap_or(1.0);
|
||||||
|
let normalized = brightness as f32 / max as f32;
|
||||||
|
let corrected = normalized.powf(1.0 / gamma);
|
||||||
|
Ok((corrected * 100.0).round() as i32)
|
||||||
|
} else {
|
||||||
|
Ok(brightness * 100 / max)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(FdoErr::NotSupported(format!(
|
||||||
|
"Backlight {:?} not found",
|
||||||
|
device_type
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn start_watch_primary(&self) -> Result<(), RogError> {
|
||||||
|
if self.get_backlight(&BacklightType::Screenpad).is_none() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sync) = self.config.lock().await.screenpad_sync_primary {
|
||||||
|
if !sync {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(backlight) = self.get_backlight(&BacklightType::Primary) {
|
||||||
|
let watch = backlight.monitor_brightness()?;
|
||||||
|
|
||||||
|
let backlights = self.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let mut last_level = 0;
|
||||||
|
let mut buffer = [0; 32];
|
||||||
|
use futures_lite::StreamExt;
|
||||||
|
if let Ok(mut stream) = watch.into_event_stream(&mut buffer) {
|
||||||
|
loop {
|
||||||
|
let _ = stream.next().await;
|
||||||
|
|
||||||
|
let sync = backlights.config.lock().await.screenpad_sync_primary;
|
||||||
|
if let Some(sync) = sync {
|
||||||
|
if !sync {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if backlights
|
||||||
|
.config
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.screenpad_sync_primary
|
||||||
|
.is_none()
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let level = backlights
|
||||||
|
.get_brightness_percent(&BacklightType::Primary)
|
||||||
|
.await
|
||||||
|
.unwrap_or(60);
|
||||||
|
if last_level != level {
|
||||||
|
last_level = level;
|
||||||
|
backlights
|
||||||
|
.set_brightness_with_sync(&BacklightType::Screenpad, level)
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
// other processes cause "MODIFY" event and make this spin 100%, so sleep
|
||||||
|
tokio::time::sleep(Duration::from_millis(300)).await;
|
||||||
|
}
|
||||||
|
// watch
|
||||||
|
// .into_event_stream(&mut buffer)
|
||||||
|
// .unwrap()
|
||||||
|
// .for_each(|_| async {})
|
||||||
|
// .await;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[interface(name = "xyz.ljones.Backlight")]
|
||||||
|
impl CtrlBacklight {
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn screenpad_sync_with_primary(&self) -> bool {
|
||||||
|
self.config
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.screenpad_sync_primary
|
||||||
|
.unwrap_or_default()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn set_screenpad_sync_with_primary(&self, sync: bool) -> Result<(), zbus::Error> {
|
||||||
|
self.config.lock().await.screenpad_sync_primary = Some(sync);
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn screenpad_gamma(&self) -> String {
|
||||||
|
(self.config.lock().await.screenpad_gamma.unwrap_or(1.0)).to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn set_screenpad_gamma(&self, value: &str) -> Result<(), zbus::Error> {
|
||||||
|
let gamma: f32 = value
|
||||||
|
.parse()
|
||||||
|
.map_err(|_| FdoErr::Failed("Invalid gamma value, must be a valid number".into()))?;
|
||||||
|
|
||||||
|
if gamma < 0.1 {
|
||||||
|
return Err(FdoErr::Failed("Gamma value must be greater than 0".into()).into());
|
||||||
|
}
|
||||||
|
if gamma > 2.0 {
|
||||||
|
return Err(FdoErr::Failed("Gamma value must be 2.0 or less".into()).into());
|
||||||
|
}
|
||||||
|
self.config.lock().await.screenpad_gamma = Some(gamma);
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn primary_brightness(&self) -> Result<i32, FdoErr> {
|
||||||
|
self.get_brightness_percent(&BacklightType::Primary).await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn set_primary_brightness(
|
||||||
|
&self,
|
||||||
|
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
|
||||||
|
level: i32,
|
||||||
|
) -> Result<(), zbus::Error> {
|
||||||
|
if level > 100 {
|
||||||
|
return Err(FdoErr::Failed("Brightness level must be 0-100".into()).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.set_brightness_with_sync(&BacklightType::Primary, level)
|
||||||
|
.await?;
|
||||||
|
self.primary_brightness_changed(&ctxt).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn screenpad_brightness(&self) -> Result<i32, FdoErr> {
|
||||||
|
self.get_brightness_percent(&BacklightType::Screenpad).await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn set_screenpad_brightness(
|
||||||
|
&self,
|
||||||
|
// #[zbus(signal_context)] ctxt: SignalEmitter<'_>,
|
||||||
|
level: i32,
|
||||||
|
) -> Result<(), zbus::Error> {
|
||||||
|
if level > 100 {
|
||||||
|
return Err(FdoErr::Failed("Brightness level must be 0-100".into()).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.set_brightness_with_sync(&BacklightType::Screenpad, level)
|
||||||
|
.await?;
|
||||||
|
// self.screenpad_brightness_changed(&ctxt).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn screenpad_power(&self) -> Result<bool, FdoErr> {
|
||||||
|
if let Some(backlight) = self.get_backlight(&BacklightType::Screenpad) {
|
||||||
|
let power = backlight.get_bl_power().map_err(|e| {
|
||||||
|
warn!("Failed to get backlight power: {}", e);
|
||||||
|
FdoErr::Failed(format!("Failed to get backlight power: {}", e))
|
||||||
|
})?;
|
||||||
|
Ok(power == 0)
|
||||||
|
} else {
|
||||||
|
Err(FdoErr::NotSupported("Screenpad backlight not found".into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
async fn set_screenpad_power(
|
||||||
|
&self,
|
||||||
|
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
|
||||||
|
power: bool,
|
||||||
|
) -> Result<(), zbus::Error> {
|
||||||
|
if let Some(backlight) = self.get_backlight(&BacklightType::Screenpad) {
|
||||||
|
backlight
|
||||||
|
.set_bl_power(if power { 0 } else { 1 })
|
||||||
|
.map_err(|e| {
|
||||||
|
warn!("Failed to set backlight power: {}", e);
|
||||||
|
FdoErr::Failed(format!("Failed to set backlight power: {}", e))
|
||||||
|
})?;
|
||||||
|
self.screenpad_power_changed(&ctxt).await?;
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(FdoErr::NotSupported("Screenpad backlight not found".into()).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl crate::ZbusRun for CtrlBacklight {
|
||||||
|
async fn add_to_server(self, server: &mut Connection) {
|
||||||
|
Self::add_to_server_helper(self, ASUS_ZBUS_PATH, server).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl crate::Reloadable for CtrlBacklight {
|
||||||
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
|
info!("Reloading backlight settings");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ pub const FAN_CURVE_ZBUS_PATH: &str = "/xyz/ljones";
|
|||||||
pub struct FanCurveConfig {
|
pub struct FanCurveConfig {
|
||||||
pub profiles: FanCurveProfiles,
|
pub profiles: FanCurveProfiles,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub current: PlatformProfile
|
pub current: PlatformProfile,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StdConfig for FanCurveConfig {
|
impl StdConfig for FanCurveConfig {
|
||||||
@@ -47,7 +47,7 @@ impl StdConfigLoad for FanCurveConfig {}
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct CtrlFanCurveZbus {
|
pub struct CtrlFanCurveZbus {
|
||||||
config: Arc<Mutex<FanCurveConfig>>,
|
config: Arc<Mutex<FanCurveConfig>>,
|
||||||
platform: RogPlatform
|
platform: RogPlatform,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-zbus-derive impl
|
// Non-zbus-derive impl
|
||||||
@@ -66,11 +66,8 @@ impl CtrlFanCurveZbus {
|
|||||||
info!("Fetching default fan curves");
|
info!("Fetching default fan curves");
|
||||||
|
|
||||||
let current = platform.get_platform_profile()?;
|
let current = platform.get_platform_profile()?;
|
||||||
for this in [
|
let profiles = platform.get_platform_profile_choices()?;
|
||||||
PlatformProfile::Balanced,
|
for this in profiles {
|
||||||
PlatformProfile::Performance,
|
|
||||||
PlatformProfile::Quiet
|
|
||||||
] {
|
|
||||||
// For each profile we need to switch to it before we
|
// For each profile we need to switch to it before we
|
||||||
// can read the existing values from hardware. The ACPI method used
|
// can read the existing values from hardware. The ACPI method used
|
||||||
// for this is what limits us.
|
// for this is what limits us.
|
||||||
@@ -93,7 +90,7 @@ impl CtrlFanCurveZbus {
|
|||||||
|
|
||||||
return Ok(Self {
|
return Ok(Self {
|
||||||
config: Arc::new(Mutex::new(config)),
|
config: Arc::new(Mutex::new(config)),
|
||||||
platform
|
platform,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +105,7 @@ impl CtrlFanCurveZbus {
|
|||||||
async fn set_fan_curves_enabled(
|
async fn set_fan_curves_enabled(
|
||||||
&mut self,
|
&mut self,
|
||||||
profile: PlatformProfile,
|
profile: PlatformProfile,
|
||||||
enabled: bool
|
enabled: bool,
|
||||||
) -> zbus::fdo::Result<()> {
|
) -> zbus::fdo::Result<()> {
|
||||||
self.config
|
self.config
|
||||||
.lock()
|
.lock()
|
||||||
@@ -130,7 +127,7 @@ impl CtrlFanCurveZbus {
|
|||||||
&mut self,
|
&mut self,
|
||||||
profile: PlatformProfile,
|
profile: PlatformProfile,
|
||||||
fan: FanCurvePU,
|
fan: FanCurvePU,
|
||||||
enabled: bool
|
enabled: bool,
|
||||||
) -> zbus::fdo::Result<()> {
|
) -> zbus::fdo::Result<()> {
|
||||||
self.config
|
self.config
|
||||||
.lock()
|
.lock()
|
||||||
@@ -149,7 +146,7 @@ impl CtrlFanCurveZbus {
|
|||||||
/// Get the fan-curve data for the currently active ThrottlePolicy
|
/// Get the fan-curve data for the currently active ThrottlePolicy
|
||||||
async fn fan_curve_data(
|
async fn fan_curve_data(
|
||||||
&mut self,
|
&mut self,
|
||||||
profile: PlatformProfile
|
profile: PlatformProfile,
|
||||||
) -> zbus::fdo::Result<Vec<CurveData>> {
|
) -> zbus::fdo::Result<Vec<CurveData>> {
|
||||||
let curve = self
|
let curve = self
|
||||||
.config
|
.config
|
||||||
@@ -166,7 +163,7 @@ impl CtrlFanCurveZbus {
|
|||||||
async fn set_fan_curve(
|
async fn set_fan_curve(
|
||||||
&mut self,
|
&mut self,
|
||||||
profile: PlatformProfile,
|
profile: PlatformProfile,
|
||||||
curve: CurveData
|
curve: CurveData,
|
||||||
) -> zbus::fdo::Result<()> {
|
) -> zbus::fdo::Result<()> {
|
||||||
self.config
|
self.config
|
||||||
.lock()
|
.lock()
|
||||||
@@ -216,7 +213,7 @@ impl CtrlFanCurveZbus {
|
|||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
.profiles
|
.profiles
|
||||||
.set_active_curve_to_defaults((&active).into(), &mut find_fan_curve_node()?)?;
|
.set_active_curve_to_defaults(active.as_str().into(), &mut find_fan_curve_node()?)?;
|
||||||
self.platform.set_platform_profile(active.as_str())?;
|
self.platform.set_platform_profile(active.as_str())?;
|
||||||
|
|
||||||
self.config.lock().await.write();
|
self.config.lock().await.write();
|
||||||
@@ -261,7 +258,7 @@ impl CtrlTask for CtrlFanCurveZbus {
|
|||||||
.profiles
|
.profiles
|
||||||
.write_profile_curve_to_platform(
|
.write_profile_curve_to_platform(
|
||||||
profile,
|
profile,
|
||||||
&mut find_fan_curve_node().unwrap()
|
&mut find_fan_curve_node().unwrap(),
|
||||||
)
|
)
|
||||||
.map_err(|e| warn!("write_profile_curve_to_platform, {}", e))
|
.map_err(|e| warn!("write_profile_curve_to_platform, {}", e))
|
||||||
.ok();
|
.ok();
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ use rog_platform::asus_armoury::{AttrValue, FirmwareAttribute, FirmwareAttribute
|
|||||||
use rog_platform::cpu::{CPUControl, CPUGovernor, CPUEPP};
|
use rog_platform::cpu::{CPUControl, CPUGovernor, CPUEPP};
|
||||||
use rog_platform::platform::{PlatformProfile, Properties, RogPlatform};
|
use rog_platform::platform::{PlatformProfile, Properties, RogPlatform};
|
||||||
use rog_platform::power::AsusPower;
|
use rog_platform::power::AsusPower;
|
||||||
use zbus::export::futures_util::lock::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use zbus::fdo::Error as FdoErr;
|
use zbus::fdo::Error as FdoErr;
|
||||||
use zbus::object_server::SignalEmitter;
|
use zbus::object_server::SignalEmitter;
|
||||||
use zbus::{interface, Connection};
|
use zbus::{interface, Connection};
|
||||||
|
|
||||||
use crate::asus_armoury::set_config_or_default;
|
use crate::asus_armoury::{set_config_or_default, ArmouryAttributeRegistry};
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
use crate::{task_watch_item, CtrlTask, ReloadAndNotify};
|
use crate::{task_watch_item, CtrlTask, ReloadAndNotify};
|
||||||
@@ -45,17 +45,22 @@ pub struct CtrlPlatform {
|
|||||||
platform: RogPlatform,
|
platform: RogPlatform,
|
||||||
attributes: FirmwareAttributes,
|
attributes: FirmwareAttributes,
|
||||||
cpu_control: Option<CPUControl>,
|
cpu_control: Option<CPUControl>,
|
||||||
config: Arc<Mutex<Config>>
|
config: Arc<Mutex<Config>>,
|
||||||
|
connection: Connection,
|
||||||
|
armoury_registry: ArmouryAttributeRegistry,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CtrlPlatform {
|
impl CtrlPlatform {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
platform: RogPlatform,
|
platform: RogPlatform,
|
||||||
power: AsusPower,
|
power: AsusPower,
|
||||||
attributes: FirmwareAttributes,
|
attributes: FirmwareAttributes,
|
||||||
config: Arc<Mutex<Config>>,
|
config: Arc<Mutex<Config>>,
|
||||||
config_path: &Path,
|
config_path: &Path,
|
||||||
signal_context: SignalEmitter<'static>
|
signal_context: SignalEmitter<'static>,
|
||||||
|
connection: Connection,
|
||||||
|
armoury_registry: ArmouryAttributeRegistry,
|
||||||
) -> Result<Self, RogError> {
|
) -> Result<Self, RogError> {
|
||||||
let config1 = config.clone();
|
let config1 = config.clone();
|
||||||
let config_path = config_path.to_owned();
|
let config_path = config_path.to_owned();
|
||||||
@@ -67,12 +72,14 @@ impl CtrlPlatform {
|
|||||||
config,
|
config,
|
||||||
cpu_control: CPUControl::new()
|
cpu_control: CPUControl::new()
|
||||||
.map_err(|e| error!("Couldn't get CPU control sysfs: {e}"))
|
.map_err(|e| error!("Couldn't get CPU control sysfs: {e}"))
|
||||||
.ok()
|
.ok(),
|
||||||
|
connection,
|
||||||
|
armoury_registry,
|
||||||
};
|
};
|
||||||
let mut inotify_self = ret_self.clone();
|
let mut inotify_self = ret_self.clone();
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
use zbus::export::futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
info!("Starting inotify watch for asusd config file");
|
info!("Starting inotify watch for asusd config file");
|
||||||
|
|
||||||
let mut buffer = [0; 32];
|
let mut buffer = [0; 32];
|
||||||
@@ -86,7 +93,7 @@ impl CtrlPlatform {
|
|||||||
inotify::WatchMask::MODIFY
|
inotify::WatchMask::MODIFY
|
||||||
| inotify::WatchMask::CLOSE_WRITE
|
| inotify::WatchMask::CLOSE_WRITE
|
||||||
| inotify::WatchMask::ATTRIB
|
| inotify::WatchMask::ATTRIB
|
||||||
| inotify::WatchMask::CREATE
|
| inotify::WatchMask::CREATE,
|
||||||
)
|
)
|
||||||
.inspect_err(|e| {
|
.inspect_err(|e| {
|
||||||
if e.kind() == std::io::ErrorKind::NotFound {
|
if e.kind() == std::io::ErrorKind::NotFound {
|
||||||
@@ -128,7 +135,7 @@ impl CtrlPlatform {
|
|||||||
if limit > 0
|
if limit > 0
|
||||||
&& std::mem::replace(
|
&& std::mem::replace(
|
||||||
&mut self.config.lock().await.charge_control_end_threshold,
|
&mut self.config.lock().await.charge_control_end_threshold,
|
||||||
limit
|
limit,
|
||||||
) != limit
|
) != limit
|
||||||
{
|
{
|
||||||
self.power
|
self.power
|
||||||
@@ -161,7 +168,7 @@ impl CtrlPlatform {
|
|||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
.collect()
|
.collect()
|
||||||
};
|
};
|
||||||
if prog.len() > 1 {
|
if (!prog.is_empty()) && (!prog[0].is_empty()) {
|
||||||
let mut cmd = Command::new(&prog[0]);
|
let mut cmd = Command::new(&prog[0]);
|
||||||
for arg in prog.iter().skip(1) {
|
for arg in prog.iter().skip(1) {
|
||||||
cmd.arg(arg);
|
cmd.arg(arg);
|
||||||
@@ -210,7 +217,9 @@ impl CtrlPlatform {
|
|||||||
match throttle {
|
match throttle {
|
||||||
PlatformProfile::Balanced => self.config.lock().await.profile_balanced_epp,
|
PlatformProfile::Balanced => self.config.lock().await.profile_balanced_epp,
|
||||||
PlatformProfile::Performance => self.config.lock().await.profile_performance_epp,
|
PlatformProfile::Performance => self.config.lock().await.profile_performance_epp,
|
||||||
PlatformProfile::Quiet => self.config.lock().await.profile_quiet_epp
|
PlatformProfile::Quiet => self.config.lock().await.profile_quiet_epp,
|
||||||
|
PlatformProfile::LowPower => self.config.lock().await.profile_quiet_epp,
|
||||||
|
PlatformProfile::Custom => self.config.lock().await.profile_custom_epp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,16 +295,39 @@ impl CtrlPlatform {
|
|||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
fn charge_control_end_threshold(&self) -> Result<u8, FdoErr> {
|
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)
|
Ok(limit)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
async fn set_charge_control_end_threshold(&mut self, limit: u8) -> Result<(), FdoErr> {
|
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) {
|
if !(20..=100).contains(&limit) {
|
||||||
return Err(RogError::ChargeLimit(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.charge_control_end_threshold = limit;
|
||||||
self.config.lock().await.base_charge_control_end_threshold = limit;
|
self.config.lock().await.base_charge_control_end_threshold = limit;
|
||||||
self.config.lock().await.write();
|
self.config.lock().await.write();
|
||||||
@@ -303,12 +335,22 @@ impl CtrlPlatform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn one_shot_full_charge(&self) -> Result<(), FdoErr> {
|
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(
|
let base_limit = std::mem::replace(
|
||||||
&mut self.config.lock().await.charge_control_end_threshold,
|
&mut self.config.lock().await.charge_control_end_threshold,
|
||||||
100
|
100,
|
||||||
);
|
);
|
||||||
if base_limit != 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.base_charge_control_end_threshold = base_limit;
|
||||||
self.config.lock().await.write();
|
self.config.lock().await.write();
|
||||||
}
|
}
|
||||||
@@ -319,11 +361,13 @@ impl CtrlPlatform {
|
|||||||
/// If fan-curves are supported will also activate a fan curve for profile.
|
/// If fan-curves are supported will also activate a fan curve for profile.
|
||||||
async fn next_platform_profile(
|
async fn next_platform_profile(
|
||||||
&mut self,
|
&mut self,
|
||||||
#[zbus(signal_context)] ctxt: SignalEmitter<'_>
|
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
|
||||||
) -> Result<(), FdoErr> {
|
) -> Result<(), FdoErr> {
|
||||||
let policy: PlatformProfile =
|
let policy: PlatformProfile =
|
||||||
platform_get_value!(self, platform_profile, "platform_profile").map(|n| n.into())?;
|
platform_get_value!(self, platform_profile, "platform_profile").map(|n| n.into())?;
|
||||||
let policy = PlatformProfile::next(policy);
|
let choices =
|
||||||
|
platform_get_value!(self, platform_profile_choices, "platform_profile_choices")?;
|
||||||
|
let policy = PlatformProfile::next(policy, &choices);
|
||||||
|
|
||||||
if self.platform.has_platform_profile() {
|
if self.platform.has_platform_profile() {
|
||||||
let change_epp = self.config.lock().await.platform_profile_linked_epp;
|
let change_epp = self.config.lock().await.platform_profile_linked_epp;
|
||||||
@@ -339,21 +383,27 @@ impl CtrlPlatform {
|
|||||||
Ok(self.platform_profile_changed(&ctxt).await?)
|
Ok(self.platform_profile_changed(&ctxt).await?)
|
||||||
} else {
|
} else {
|
||||||
Err(FdoErr::NotSupported(
|
Err(FdoErr::NotSupported(
|
||||||
"RogPlatform: platform_profile not supported".to_owned()
|
"RogPlatform: platform_profile not supported".to_owned(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[zbus(property)]
|
||||||
|
fn platform_profile_choices(&self) -> Result<Vec<PlatformProfile>, FdoErr> {
|
||||||
|
platform_get_value!(self, platform_profile_choices, "platform_profile_choices")
|
||||||
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
fn platform_profile(&self) -> Result<PlatformProfile, FdoErr> {
|
fn platform_profile(&self) -> Result<PlatformProfile, FdoErr> {
|
||||||
platform_get_value!(self, platform_profile, "platform_profile").map(|n| n.into())
|
let policy: PlatformProfile = self.platform.get_platform_profile()?.as_str().into();
|
||||||
|
Ok(policy)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
async fn set_platform_profile(
|
async fn set_platform_profile(
|
||||||
&mut self,
|
&mut self,
|
||||||
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
|
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
|
||||||
policy: PlatformProfile
|
policy: PlatformProfile,
|
||||||
) -> Result<(), FdoErr> {
|
) -> Result<(), FdoErr> {
|
||||||
// TODO: watch for external changes
|
// TODO: watch for external changes
|
||||||
if self.platform.has_platform_profile() {
|
if self.platform.has_platform_profile() {
|
||||||
@@ -362,7 +412,15 @@ impl CtrlPlatform {
|
|||||||
self.check_and_set_epp(epp, change_epp);
|
self.check_and_set_epp(epp, change_epp);
|
||||||
|
|
||||||
self.config.lock().await.write();
|
self.config.lock().await.write();
|
||||||
// TODO: Need to get supported profiles here and ensure we translate to one
|
|
||||||
|
let choices = self.platform.get_platform_profile_choices()?;
|
||||||
|
if !choices.contains(&policy) {
|
||||||
|
return Err(FdoErr::NotSupported(format!(
|
||||||
|
"RogPlatform: platform_profile: {} not supported",
|
||||||
|
policy
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
self.platform
|
self.platform
|
||||||
.set_platform_profile(policy.into())
|
.set_platform_profile(policy.into())
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
@@ -373,7 +431,7 @@ impl CtrlPlatform {
|
|||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(FdoErr::NotSupported(
|
Err(FdoErr::NotSupported(
|
||||||
"RogPlatform: platform_profile not supported".to_owned()
|
"RogPlatform: platform_profile not supported".to_owned(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -399,7 +457,7 @@ impl CtrlPlatform {
|
|||||||
async fn set_platform_profile_on_battery(
|
async fn set_platform_profile_on_battery(
|
||||||
&mut self,
|
&mut self,
|
||||||
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
|
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
|
||||||
policy: PlatformProfile
|
policy: PlatformProfile,
|
||||||
) -> Result<(), FdoErr> {
|
) -> Result<(), FdoErr> {
|
||||||
self.config.lock().await.platform_profile_on_battery = policy;
|
self.config.lock().await.platform_profile_on_battery = policy;
|
||||||
self.set_platform_profile(ctxt, policy).await?;
|
self.set_platform_profile(ctxt, policy).await?;
|
||||||
@@ -428,7 +486,7 @@ impl CtrlPlatform {
|
|||||||
async fn set_platform_profile_on_ac(
|
async fn set_platform_profile_on_ac(
|
||||||
&mut self,
|
&mut self,
|
||||||
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
|
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
|
||||||
policy: PlatformProfile
|
policy: PlatformProfile,
|
||||||
) -> Result<(), FdoErr> {
|
) -> Result<(), FdoErr> {
|
||||||
self.config.lock().await.platform_profile_on_ac = policy;
|
self.config.lock().await.platform_profile_on_ac = policy;
|
||||||
self.set_platform_profile(ctxt, policy).await?;
|
self.set_platform_profile(ctxt, policy).await?;
|
||||||
@@ -593,7 +651,7 @@ impl ReloadAndNotify for CtrlPlatform {
|
|||||||
async fn reload_and_notify(
|
async fn reload_and_notify(
|
||||||
&mut self,
|
&mut self,
|
||||||
signal_context: &SignalEmitter<'static>,
|
signal_context: &SignalEmitter<'static>,
|
||||||
data: Self::Data
|
data: Self::Data,
|
||||||
) -> Result<(), RogError> {
|
) -> Result<(), RogError> {
|
||||||
let mut config = self.config.lock().await;
|
let mut config = self.config.lock().await;
|
||||||
if *config != data {
|
if *config != data {
|
||||||
@@ -622,7 +680,9 @@ impl ReloadAndNotify for CtrlPlatform {
|
|||||||
let epp = match profile {
|
let epp = match profile {
|
||||||
PlatformProfile::Balanced => data.profile_balanced_epp,
|
PlatformProfile::Balanced => data.profile_balanced_epp,
|
||||||
PlatformProfile::Performance => data.profile_performance_epp,
|
PlatformProfile::Performance => data.profile_performance_epp,
|
||||||
PlatformProfile::Quiet => data.profile_quiet_epp
|
PlatformProfile::Quiet => data.profile_quiet_epp,
|
||||||
|
PlatformProfile::LowPower => data.profile_quiet_epp,
|
||||||
|
PlatformProfile::Custom => data.profile_custom_epp,
|
||||||
};
|
};
|
||||||
warn!("setting epp to {epp:?}");
|
warn!("setting epp to {epp:?}");
|
||||||
self.check_and_set_epp(epp, true);
|
self.check_and_set_epp(epp, true);
|
||||||
@@ -694,7 +754,7 @@ impl CtrlTask for CtrlPlatform {
|
|||||||
platform1
|
platform1
|
||||||
.power
|
.power
|
||||||
.set_charge_control_end_threshold(
|
.set_charge_control_end_threshold(
|
||||||
platform1.config.lock().await.charge_control_end_threshold
|
platform1.config.lock().await.charge_control_end_threshold,
|
||||||
)
|
)
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
@@ -709,6 +769,31 @@ impl CtrlTask for CtrlPlatform {
|
|||||||
}
|
}
|
||||||
if !sleeping {
|
if !sleeping {
|
||||||
platform1.run_ac_or_bat_cmd(power_plugged > 0).await;
|
platform1.run_ac_or_bat_cmd(power_plugged > 0).await;
|
||||||
|
if let Ok(profile) =
|
||||||
|
platform1.platform.get_platform_profile().map(|p| p.into())
|
||||||
|
{
|
||||||
|
let attrs = FirmwareAttributes::new();
|
||||||
|
{
|
||||||
|
let mut cfg = platform1.config.lock().await;
|
||||||
|
set_config_or_default(
|
||||||
|
&attrs,
|
||||||
|
&mut cfg,
|
||||||
|
power_plugged > 0,
|
||||||
|
profile,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
if let Err(e) = platform1
|
||||||
|
.armoury_registry
|
||||||
|
.emit_limits(&platform1.connection)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
error!(
|
||||||
|
"Failed to emit armoury updates after power change: \
|
||||||
|
{e:?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
platform1.config.lock().await.last_power_plugged = power_plugged;
|
platform1.config.lock().await.last_power_plugged = power_plugged;
|
||||||
}
|
}
|
||||||
@@ -728,7 +813,7 @@ impl CtrlTask for CtrlPlatform {
|
|||||||
platform2
|
platform2
|
||||||
.power
|
.power
|
||||||
.set_charge_control_end_threshold(
|
.set_charge_control_end_threshold(
|
||||||
lock.base_charge_control_end_threshold
|
lock.base_charge_control_end_threshold,
|
||||||
)
|
)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("CtrlCharge: charge_control_end_threshold {}", err);
|
warn!("CtrlCharge: charge_control_end_threshold {}", err);
|
||||||
@@ -769,20 +854,24 @@ impl CtrlTask for CtrlPlatform {
|
|||||||
{
|
{
|
||||||
// TODO: manage this better, shouldn't need to create every time
|
// TODO: manage this better, shouldn't need to create every time
|
||||||
let attrs = FirmwareAttributes::new();
|
let attrs = FirmwareAttributes::new();
|
||||||
set_config_or_default(
|
{
|
||||||
&attrs,
|
let mut cfg = platform3.config.lock().await;
|
||||||
&mut *platform3.config.lock().await,
|
set_config_or_default(&attrs, &mut cfg, power_plugged, profile).await;
|
||||||
power_plugged,
|
}
|
||||||
profile
|
if let Err(e) = platform3
|
||||||
)
|
.armoury_registry
|
||||||
.await;
|
.emit_limits(&platform3.connection)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
error!("Failed to emit armoury updates after AC/DC toggle: {e:?}");
|
||||||
|
}
|
||||||
platform3
|
platform3
|
||||||
.enable_ppt_group_changed(&signal_ctxt_copy)
|
.enable_ppt_group_changed(&signal_ctxt_copy)
|
||||||
.await
|
.await
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -829,9 +918,12 @@ impl CtrlTask for CtrlPlatform {
|
|||||||
&attrs,
|
&attrs,
|
||||||
&mut *ctrl.config.lock().await,
|
&mut *ctrl.config.lock().await,
|
||||||
power_plugged == 1,
|
power_plugged == 1,
|
||||||
profile
|
profile,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
if let Err(e) = ctrl.armoury_registry.emit_limits(&ctrl.connection).await {
|
||||||
|
error!("Failed to emit armoury updates after profile change: {e:?}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,23 +2,26 @@ use std::env;
|
|||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ::zbus::export::futures_util::lock::Mutex;
|
|
||||||
use ::zbus::Connection;
|
use ::zbus::Connection;
|
||||||
use asusd::asus_armoury::start_attributes_zbus;
|
use asusd::asus_armoury::{start_attributes_zbus, ArmouryAttributeRegistry};
|
||||||
use asusd::aura_manager::DeviceManager;
|
use asusd::aura_manager::DeviceManager;
|
||||||
use asusd::config::Config;
|
use asusd::config::Config;
|
||||||
|
use asusd::ctrl_backlight::CtrlBacklight;
|
||||||
use asusd::ctrl_fancurves::CtrlFanCurveZbus;
|
use asusd::ctrl_fancurves::CtrlFanCurveZbus;
|
||||||
use asusd::ctrl_platform::CtrlPlatform;
|
use asusd::ctrl_platform::CtrlPlatform;
|
||||||
use asusd::{print_board_info, start_tasks, CtrlTask, DBUS_NAME};
|
use asusd::{print_board_info, start_tasks, CtrlTask, ZbusRun, DBUS_NAME};
|
||||||
use config_traits::{StdConfig, StdConfigLoad1};
|
use config_traits::{StdConfig, StdConfigLoad2};
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use rog_platform::asus_armoury::FirmwareAttributes;
|
use rog_platform::asus_armoury::FirmwareAttributes;
|
||||||
use rog_platform::platform::RogPlatform;
|
use rog_platform::platform::RogPlatform;
|
||||||
use rog_platform::power::AsusPower;
|
use rog_platform::power::AsusPower;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
use zbus::fdo::ObjectManager;
|
use zbus::fdo::ObjectManager;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
println!("Starting asusd daemon...");
|
||||||
|
|
||||||
// console_subscriber::init();
|
// console_subscriber::init();
|
||||||
let mut logger = env_logger::Builder::new();
|
let mut logger = env_logger::Builder::new();
|
||||||
logger
|
logger
|
||||||
@@ -30,7 +33,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
let is_service = match env::var_os("IS_SERVICE") {
|
let is_service = match env::var_os("IS_SERVICE") {
|
||||||
Some(val) => val == "1",
|
Some(val) => val == "1",
|
||||||
None => true
|
None => true,
|
||||||
};
|
};
|
||||||
|
|
||||||
if !is_service {
|
if !is_service {
|
||||||
@@ -61,7 +64,9 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
// Start zbus server
|
// Start zbus server
|
||||||
let mut server = Connection::system().await?;
|
let mut server = Connection::system().await?;
|
||||||
server.object_server().at("/", ObjectManager).await.unwrap();
|
if let Err(e) = server.object_server().at("/", ObjectManager).await {
|
||||||
|
error!("Failed to register ObjectManager at root '/': {e:?}");
|
||||||
|
}
|
||||||
|
|
||||||
let config = Config::new().load();
|
let config = Config::new().load();
|
||||||
let cfg_path = config.file_path();
|
let cfg_path = config.file_path();
|
||||||
@@ -71,36 +76,64 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
let platform = RogPlatform::new()?; // TODO: maybe needs async mutex?
|
let platform = RogPlatform::new()?; // TODO: maybe needs async mutex?
|
||||||
let power = AsusPower::new()?; // TODO: maybe needs async mutex?
|
let power = AsusPower::new()?; // TODO: maybe needs async mutex?
|
||||||
let attributes = FirmwareAttributes::new();
|
let attributes = FirmwareAttributes::new();
|
||||||
start_attributes_zbus(
|
let armoury_registry = match start_attributes_zbus(
|
||||||
&server,
|
&server,
|
||||||
platform.clone(),
|
platform.clone(),
|
||||||
power.clone(),
|
power.clone(),
|
||||||
attributes.clone(),
|
attributes.clone(),
|
||||||
config.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() {
|
match CtrlFanCurveZbus::new() {
|
||||||
Ok(ctrl) => {
|
Ok(ctrl) => {
|
||||||
|
info!("FanCurves: found supported fancurves");
|
||||||
let sig_ctx = CtrlFanCurveZbus::signal_context(&server)?;
|
let sig_ctx = CtrlFanCurveZbus::signal_context(&server)?;
|
||||||
start_tasks(ctrl, &mut server, sig_ctx).await?;
|
start_tasks(ctrl, &mut server, sig_ctx).await?;
|
||||||
|
info!("FanCurves: initialized");
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("FanCurves: {}", err);
|
error!("FanCurves: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match CtrlBacklight::new(config.clone()) {
|
||||||
|
Ok(backlight) => {
|
||||||
|
info!("Backlight: found supported backlight");
|
||||||
|
backlight.start_watch_primary().await?;
|
||||||
|
backlight.add_to_server(&mut server).await;
|
||||||
|
info!("Backlight: initialized");
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
error!("Backlight: {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match CtrlPlatform::new(
|
match CtrlPlatform::new(
|
||||||
platform,
|
platform,
|
||||||
power,
|
power,
|
||||||
attributes,
|
attributes,
|
||||||
config.clone(),
|
config.clone(),
|
||||||
&cfg_path,
|
&cfg_path,
|
||||||
CtrlPlatform::signal_context(&server)?
|
CtrlPlatform::signal_context(&server)?,
|
||||||
|
server.clone(),
|
||||||
|
armoury_registry,
|
||||||
) {
|
) {
|
||||||
Ok(ctrl) => {
|
Ok(ctrl) => {
|
||||||
|
info!("CtrlPlatform: initialized");
|
||||||
let sig_ctx = CtrlPlatform::signal_context(&server)?;
|
let sig_ctx = CtrlPlatform::signal_context(&server)?;
|
||||||
start_tasks(ctrl, &mut server, sig_ctx).await?;
|
start_tasks(ctrl, &mut server, sig_ctx).await?;
|
||||||
|
info!("CtrlPlatform: tasks started");
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("CtrlPlatform: {}", err);
|
error!("CtrlPlatform: {}", err);
|
||||||
@@ -109,10 +142,12 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
let _ = DeviceManager::new(server.clone()).await?;
|
let _ = DeviceManager::new(server.clone()).await?;
|
||||||
|
|
||||||
|
info!("DeviceManager initialized");
|
||||||
|
|
||||||
// Request dbus name after finishing initalizing all functions
|
// Request dbus name after finishing initalizing all functions
|
||||||
server.request_name(DBUS_NAME).await?;
|
server.request_name(DBUS_NAME).await?;
|
||||||
|
|
||||||
info!("Startup success, begining dbus server loop");
|
info!("Startup success on dbus name {DBUS_NAME}: begining dbus server loop");
|
||||||
loop {
|
loop {
|
||||||
// This is just a blocker to idle and ensure the reator reacts
|
// This is just a blocker to idle and ensure the reator reacts
|
||||||
server.executor().tick().await;
|
server.executor().tick().await;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ pub enum RogError {
|
|||||||
SystemdUnitAction(String),
|
SystemdUnitAction(String),
|
||||||
SystemdUnitWaitTimeout(String),
|
SystemdUnitWaitTimeout(String),
|
||||||
Command(String, std::io::Error),
|
Command(String, std::io::Error),
|
||||||
ParseRon(ron::Error)
|
ParseRon(ron::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for RogError {
|
impl fmt::Display for RogError {
|
||||||
@@ -87,7 +87,7 @@ impl fmt::Display for RogError {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
RogError::Command(func, error) => write!(f, "Command exec error: {}: {}", func, error),
|
RogError::Command(func, error) => write!(f, "Command exec error: {}: {}", func, error),
|
||||||
RogError::ParseRon(error) => write!(f, "Parse config error: {}", error)
|
RogError::ParseRon(error) => write!(f, "Parse config error: {}", error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#![deny(unused_must_use)]
|
#![deny(unused_must_use)]
|
||||||
/// Configuration loading, saving
|
/// Configuration loading, saving
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
pub mod ctrl_backlight;
|
||||||
/// Control platform profiles + fan-curves if available
|
/// Control platform profiles + fan-curves if available
|
||||||
pub mod ctrl_fancurves;
|
pub mod ctrl_fancurves;
|
||||||
/// Control ASUS bios function such as boot sound, Optimus/Dedicated gfx mode
|
/// Control ASUS bios function such as boot sound, Optimus/Dedicated gfx mode
|
||||||
@@ -67,7 +68,7 @@ macro_rules! task_watch_item {
|
|||||||
&self,
|
&self,
|
||||||
signal_ctxt: SignalEmitter<'static>,
|
signal_ctxt: SignalEmitter<'static>,
|
||||||
) -> Result<(), RogError> {
|
) -> Result<(), RogError> {
|
||||||
use zbus::export::futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
|
|
||||||
let ctrl = self.clone();
|
let ctrl = self.clone();
|
||||||
concat_idents::concat_idents!(watch_fn = monitor_, $name {
|
concat_idents::concat_idents!(watch_fn = monitor_, $name {
|
||||||
@@ -107,7 +108,7 @@ macro_rules! task_watch_item_notify {
|
|||||||
&self,
|
&self,
|
||||||
signal_ctxt: SignalEmitter<'static>,
|
signal_ctxt: SignalEmitter<'static>,
|
||||||
) -> Result<(), RogError> {
|
) -> Result<(), RogError> {
|
||||||
use zbus::export::futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
|
|
||||||
let ctrl = self.clone();
|
let ctrl = self.clone();
|
||||||
concat_idents::concat_idents!(watch_fn = monitor_, $name {
|
concat_idents::concat_idents!(watch_fn = monitor_, $name {
|
||||||
@@ -149,7 +150,7 @@ pub trait ReloadAndNotify {
|
|||||||
fn reload_and_notify(
|
fn reload_and_notify(
|
||||||
&mut self,
|
&mut self,
|
||||||
signal_context: &SignalEmitter<'static>,
|
signal_context: &SignalEmitter<'static>,
|
||||||
data: Self::Data
|
data: Self::Data,
|
||||||
) -> impl Future<Output = Result<(), RogError>> + Send;
|
) -> impl Future<Output = Result<(), RogError>> + Send;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +160,7 @@ pub trait ZbusRun {
|
|||||||
fn add_to_server_helper(
|
fn add_to_server_helper(
|
||||||
iface: impl Interface,
|
iface: impl Interface,
|
||||||
path: &str,
|
path: &str,
|
||||||
server: &mut Connection
|
server: &mut Connection,
|
||||||
) -> impl Future<Output = ()> + Send {
|
) -> impl Future<Output = ()> + Send {
|
||||||
async move {
|
async move {
|
||||||
server
|
server
|
||||||
@@ -188,7 +189,7 @@ pub trait CtrlTask {
|
|||||||
/// separate thread.
|
/// separate thread.
|
||||||
fn create_tasks(
|
fn create_tasks(
|
||||||
&self,
|
&self,
|
||||||
signal: SignalEmitter<'static>
|
signal: SignalEmitter<'static>,
|
||||||
) -> impl Future<Output = Result<(), RogError>> + Send;
|
) -> impl Future<Output = Result<(), RogError>> + Send;
|
||||||
|
|
||||||
// /// Create a timed repeating task
|
// /// Create a timed repeating task
|
||||||
@@ -212,7 +213,7 @@ pub trait CtrlTask {
|
|||||||
mut on_prepare_for_sleep: F1,
|
mut on_prepare_for_sleep: F1,
|
||||||
mut on_prepare_for_shutdown: F2,
|
mut on_prepare_for_shutdown: F2,
|
||||||
mut on_lid_change: F3,
|
mut on_lid_change: F3,
|
||||||
mut on_external_power_change: F4
|
mut on_external_power_change: F4,
|
||||||
) -> impl Future<Output = ()> + Send
|
) -> impl Future<Output = ()> + Send
|
||||||
where
|
where
|
||||||
F1: FnMut(bool) -> Fut1 + Send + 'static,
|
F1: FnMut(bool) -> Fut1 + Send + 'static,
|
||||||
@@ -222,7 +223,7 @@ pub trait CtrlTask {
|
|||||||
Fut1: Future<Output = ()> + Send,
|
Fut1: Future<Output = ()> + Send,
|
||||||
Fut2: Future<Output = ()> + Send,
|
Fut2: Future<Output = ()> + Send,
|
||||||
Fut3: Future<Output = ()> + Send,
|
Fut3: Future<Output = ()> + Send,
|
||||||
Fut4: Future<Output = ()> + Send
|
Fut4: Future<Output = ()> + Send,
|
||||||
{
|
{
|
||||||
async {
|
async {
|
||||||
let connection = Connection::system()
|
let connection = Connection::system()
|
||||||
@@ -302,10 +303,10 @@ pub trait GetSupported {
|
|||||||
pub async fn start_tasks<T>(
|
pub async fn start_tasks<T>(
|
||||||
mut zbus: T,
|
mut zbus: T,
|
||||||
connection: &mut Connection,
|
connection: &mut Connection,
|
||||||
signal_ctx: SignalEmitter<'static>
|
signal_ctx: SignalEmitter<'static>,
|
||||||
) -> Result<(), RogError>
|
) -> Result<(), RogError>
|
||||||
where
|
where
|
||||||
T: ZbusRun + Reloadable + CtrlTask + Clone
|
T: ZbusRun + Reloadable + CtrlTask + Clone,
|
||||||
{
|
{
|
||||||
let zbus_clone = zbus.clone();
|
let zbus_clone = zbus.clone();
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use serde::Serialize;
|
|||||||
/// implemented, the rest are intended to be free methods.
|
/// implemented, the rest are intended to be free methods.
|
||||||
pub trait StdConfig
|
pub trait StdConfig
|
||||||
where
|
where
|
||||||
Self: Serialize + DeserializeOwned
|
Self: Serialize + DeserializeOwned,
|
||||||
{
|
{
|
||||||
/// Taking over the standard `new()` to ensure things can be generic
|
/// Taking over the standard `new()` to ensure things can be generic
|
||||||
fn new() -> Self;
|
fn new() -> Self;
|
||||||
|
|||||||
@@ -9,11 +9,14 @@ ENV{DMI_FAMILY}=="*Strix*", GOTO="asusd_start"
|
|||||||
ENV{DMI_FAMILY}=="*Vivo*ook*", GOTO="asusd_start"
|
ENV{DMI_FAMILY}=="*Vivo*ook*", GOTO="asusd_start"
|
||||||
ENV{DMI_FAMILY}=="*Zenbook*", GOTO="asusd_start"
|
ENV{DMI_FAMILY}=="*Zenbook*", GOTO="asusd_start"
|
||||||
ENV{DMI_FAMILY}=="*ProArt*", GOTO="asusd_start"
|
ENV{DMI_FAMILY}=="*ProArt*", GOTO="asusd_start"
|
||||||
|
ENV{DMI_FAMILY}=="*TX Air*", GOTO="asusd_start"
|
||||||
|
ENV{DMI_FAMILY}=="*TX Gaming*", GOTO="asusd_start"
|
||||||
|
ENV{DMI_FAMILY}=="*EXPERTBOOK*", GOTO="asusd_start"
|
||||||
# No match so
|
# No match so
|
||||||
GOTO="asusd_end"
|
GOTO="asusd_end"
|
||||||
|
|
||||||
LABEL="asusd_start"
|
LABEL="asusd_start"
|
||||||
ACTION=="add|change", DRIVER=="asus-nb-wmi", TAG+="systemd", ENV{SYSTEMD_WANTS}="asusd.service"
|
ACTION=="add|change", DRIVER=="asus-nb-wmi", TAG+="systemd", ENV{SYSTEMD_WANTS}+="asusd.service"
|
||||||
ACTION=="add|remove", DRIVER=="asus-nb-wmi", TAG+="systemd", RUN+="systemctl restart asusd.service"
|
ACTION=="add|remove", DRIVER=="asus-nb-wmi", TAG+="systemd", ENV{SYSTEMD_WANTS}+="asusd.service"
|
||||||
|
|
||||||
LABEL="asusd_end"
|
LABEL="asusd_end"
|
||||||
|
|||||||
@@ -6,7 +6,10 @@ After=nvidia-powerd.service systemd-udevd.service
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Environment=IS_SERVICE=1
|
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
|
# required to prevent init issues with hid_asus and MCU
|
||||||
ExecStartPre=/bin/sleep 1
|
ExecStartPre=/bin/sleep 1
|
||||||
ExecStart=/usr/bin/asusd
|
ExecStart=/usr/bin/asusd
|
||||||
|
|||||||
130
distro-packaging/asusctl.spec
Executable file → Normal file
130
distro-packaging/asusctl.spec
Executable file → Normal file
@@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# spec file for package asus-nb-ctrl
|
# spec file for package asus-nb-ctrl
|
||||||
#
|
#
|
||||||
# Copyright (c) 2020-2021 Luke Jones <luke@ljones.dev>
|
# Copyright (c) 2020-2025 Luke Jones <luke@ljones.dev>
|
||||||
#
|
#
|
||||||
# All modifications and additions to the file contributed by third parties
|
# All modifications and additions to the file contributed by third parties
|
||||||
# remain the property of their copyright owners, unless otherwise agreed
|
# remain the property of their copyright owners, unless otherwise agreed
|
||||||
@@ -20,42 +20,44 @@
|
|||||||
%global debug_package %{nil}
|
%global debug_package %{nil}
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
%define version 6.2.0
|
||||||
%define specrelease %{?dist}
|
%define specrelease %{?dist}
|
||||||
%define pkg_release 3%{specrelease}
|
%define pkg_release 1%{specrelease}
|
||||||
|
|
||||||
# Use hardening ldflags.
|
# Use hardening ldflags.
|
||||||
%global rustflags -Clink-arg=-Wl,-z,relro,-z,now
|
%global rustflags -Clink-arg=-Wl,-z,relro,-z,now
|
||||||
Name: asusctl
|
Name: asusctl
|
||||||
Version: 6.0.7
|
Version: %{version}
|
||||||
Release: %{pkg_release}
|
Release: %{pkg_release}
|
||||||
Summary: Control fan speeds, LEDs, graphics modes, and charge levels for ASUS notebooks
|
Summary: Control fan speeds, LEDs, graphics modes, and charge levels for ASUS notebooks
|
||||||
License: MPLv2
|
License: MPLv2
|
||||||
|
|
||||||
Group: System Environment/Kernel
|
Group: System Environment/Kernel
|
||||||
|
|
||||||
URL: https://gitlab.com/asus-linux/asusctl
|
URL: https://gitlab.com/asus-linux/asusctl
|
||||||
Source: %{name}-%{version}.tar.gz
|
Source: https://gitlab.com/asus-linux/asusctl/-/archive/%{version}/%{name}-%{version}.tar.gz
|
||||||
Source1: vendor_%{name}_%{version}.tar.xz
|
|
||||||
Source2: cargo-config
|
|
||||||
|
|
||||||
BuildRequires: cargo
|
%if %{defined fedora}
|
||||||
BuildRequires: rust-packaging
|
BuildRequires: rust-packaging
|
||||||
BuildRequires: systemd-rpm-macros
|
BuildRequires: systemd-rpm-macros
|
||||||
|
%else
|
||||||
|
BuildRequires: cargo-packaging
|
||||||
|
%endif
|
||||||
|
BuildRequires: git
|
||||||
BuildRequires: clang-devel
|
BuildRequires: clang-devel
|
||||||
|
BuildRequires: cargo
|
||||||
BuildRequires: cmake
|
BuildRequires: cmake
|
||||||
BuildRequires: rust
|
BuildRequires: rust
|
||||||
BuildRequires: rust-std-static
|
BuildRequires: rust-std-static
|
||||||
BuildRequires: pkgconfig(expat)
|
BuildRequires: pkgconfig(gbm)
|
||||||
BuildRequires: pkgconfig(dbus-1)
|
BuildRequires: pkgconfig(libinput)
|
||||||
|
BuildRequires: pkgconfig(libseat)
|
||||||
BuildRequires: pkgconfig(libudev)
|
BuildRequires: pkgconfig(libudev)
|
||||||
BuildRequires: pkgconfig(xkbcommon)
|
BuildRequires: pkgconfig(xkbcommon)
|
||||||
BuildRequires: pkgconfig(libzstd)
|
BuildRequires: pkgconfig(libzstd)
|
||||||
BuildRequires: pkgconfig(gtk+-3.0)
|
BuildRequires: pkgconfig(fontconfig)
|
||||||
BuildRequires: pkgconfig(gdk-3.0)
|
|
||||||
BuildRequires: desktop-file-utils
|
BuildRequires: desktop-file-utils
|
||||||
|
|
||||||
# expat-devel pcre2-devel
|
|
||||||
|
|
||||||
%description
|
%description
|
||||||
asus-nb-ctrl is a utility for Linux to control many aspects of various
|
asus-nb-ctrl is a utility for Linux to control many aspects of various
|
||||||
ASUS laptops but can also be used with non-Asus laptops with reduced features.
|
ASUS laptops but can also be used with non-Asus laptops with reduced features.
|
||||||
@@ -66,38 +68,93 @@ asus-nb-ctrl enables third-party apps to use the above with dbus methods.
|
|||||||
|
|
||||||
%package rog-gui
|
%package rog-gui
|
||||||
Summary: An experimental GUI for %{name}
|
Summary: An experimental GUI for %{name}
|
||||||
|
Requires: %{name} = %{version}-%{release}
|
||||||
|
|
||||||
%description rog-gui
|
%description rog-gui
|
||||||
A one-stop-shop GUI tool for asusd/asusctl. It aims to provide most controls,
|
A one-stop-shop GUI tool for asusd/asusctl. It aims to provide most controls,
|
||||||
a notification service, and ability to run in the background.
|
a notification service, and ability to run in the background.
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
# %setup -D -T -a 1 -c -n %{name}-%{version}/vendor
|
|
||||||
# %setup -D -T -a 0 -c
|
|
||||||
%autosetup
|
%autosetup
|
||||||
%setup -D -T -a 1
|
mkdir -p .cargo
|
||||||
|
cat > .cargo/config.toml << 'EOF'
|
||||||
mv Cargo.lock{,.bak}
|
[term]
|
||||||
%cargo_prep
|
verbose = true
|
||||||
mv Cargo.lock{.bak,}
|
[net]
|
||||||
sed -i 's|replace-with = "local-registry"|replace-with = "vendored-sources"|' .cargo/config
|
offline = false
|
||||||
cat %{SOURCE2} >> .cargo/config
|
EOF
|
||||||
|
|
||||||
%build
|
%build
|
||||||
export RUSTFLAGS="%{rustflags}"
|
export RUSTFLAGS="%{rustflags}"
|
||||||
%cargo_build
|
%if %{defined fedora}
|
||||||
#cargo build --release --frozen --offline --config .cargo/config.toml
|
/usr/bin/cargo build --release --locked
|
||||||
|
%else
|
||||||
|
/usr/bin/cargo auditable build --release --locked
|
||||||
|
%endif
|
||||||
|
|
||||||
%install
|
%install
|
||||||
export RUSTFLAGS="%{rustflags}"
|
export RUSTFLAGS="%{rustflags}"
|
||||||
mkdir -p "%{buildroot}/%{_bindir}" "%{buildroot}%{_docdir}"
|
|
||||||
%make_install
|
|
||||||
|
|
||||||
install -D -m 0644 README.md %{buildroot}/%{_docdir}/%{name}/README.md
|
%define _target_dir target/release
|
||||||
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
|
|
||||||
|
|
||||||
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
|
%files
|
||||||
%license LICENSE
|
%license LICENSE
|
||||||
@@ -107,8 +164,6 @@ desktop-file-validate %{buildroot}/%{_datadir}/applications/rog-control-center.d
|
|||||||
%{_unitdir}/asusd.service
|
%{_unitdir}/asusd.service
|
||||||
%{_userunitdir}/asusd-user.service
|
%{_userunitdir}/asusd-user.service
|
||||||
%{_udevrulesdir}/99-asusd.rules
|
%{_udevrulesdir}/99-asusd.rules
|
||||||
#%dir %{_sysconfdir}/asusd/
|
|
||||||
%{_datadir}/asusd/aura_support.ron
|
|
||||||
%{_datadir}/dbus-1/system.d/asusd.conf
|
%{_datadir}/dbus-1/system.d/asusd.conf
|
||||||
%{_datadir}/icons/hicolor/512x512/apps/asus_notif_yellow.png
|
%{_datadir}/icons/hicolor/512x512/apps/asus_notif_yellow.png
|
||||||
%{_datadir}/icons/hicolor/512x512/apps/asus_notif_green.png
|
%{_datadir}/icons/hicolor/512x512/apps/asus_notif_green.png
|
||||||
@@ -123,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/gpu-vfio.svg
|
||||||
%{_datadir}/icons/hicolor/scalable/status/notification-reboot.svg
|
%{_datadir}/icons/hicolor/scalable/status/notification-reboot.svg
|
||||||
%{_docdir}/%{name}/
|
%{_docdir}/%{name}/
|
||||||
|
%{_datadir}/asusctl/
|
||||||
%{_datadir}/asusd/
|
%{_datadir}/asusd/
|
||||||
|
|
||||||
%files rog-gui
|
%files rog-gui
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ pub struct DMIID {
|
|||||||
pub bios_vendor: String,
|
pub bios_vendor: String,
|
||||||
pub bios_version: String,
|
pub bios_version: String,
|
||||||
pub product_family: String,
|
pub product_family: String,
|
||||||
pub product_name: String
|
pub product_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DMIID {
|
impl DMIID {
|
||||||
@@ -77,7 +77,7 @@ impl DMIID {
|
|||||||
product_name: device
|
product_name: device
|
||||||
.attribute_value("product_name")
|
.attribute_value("product_name")
|
||||||
.map(|s| s.to_string_lossy().to_string())
|
.map(|s| s.to_string_lossy().to_string())
|
||||||
.unwrap_or("Unknown".to_string())
|
.unwrap_or("Unknown".to_string()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Err("dmi not found".into())
|
Err("dmi not found".into())
|
||||||
|
|||||||
@@ -23,15 +23,15 @@ const PANE_LEN: usize = BLOCK_END - BLOCK_START;
|
|||||||
|
|
||||||
/// First packet is for GA401 + GA402
|
/// First packet is for GA401 + GA402
|
||||||
pub const USB_PREFIX1: [u8; 7] = [
|
pub const USB_PREFIX1: [u8; 7] = [
|
||||||
0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02
|
0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02,
|
||||||
];
|
];
|
||||||
/// Second packet is for GA401 + GA402
|
/// Second packet is for GA401 + GA402
|
||||||
pub const USB_PREFIX2: [u8; 7] = [
|
pub const USB_PREFIX2: [u8; 7] = [
|
||||||
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02
|
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02,
|
||||||
];
|
];
|
||||||
/// Third packet is for GA402 matrix
|
/// Third packet is for GA402 matrix
|
||||||
pub const USB_PREFIX3: [u8; 7] = [
|
pub const USB_PREFIX3: [u8; 7] = [
|
||||||
0x5e, 0xc0, 0x02, 0xe7, 0x04, 0x73, 0x02
|
0x5e, 0xc0, 0x02, 0xe7, 0x04, 0x73, 0x02,
|
||||||
];
|
];
|
||||||
|
|
||||||
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
|
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
|
||||||
@@ -40,7 +40,7 @@ pub struct Animations {
|
|||||||
pub boot: AnimBooting,
|
pub boot: AnimBooting,
|
||||||
pub awake: AnimAwake,
|
pub awake: AnimAwake,
|
||||||
pub sleep: AnimSleeping,
|
pub sleep: AnimSleeping,
|
||||||
pub shutdown: AnimShutdown
|
pub shutdown: AnimShutdown,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move this out
|
// TODO: move this out
|
||||||
@@ -54,7 +54,7 @@ pub struct DeviceState {
|
|||||||
pub off_when_unplugged: bool,
|
pub off_when_unplugged: bool,
|
||||||
pub off_when_suspended: bool,
|
pub off_when_suspended: bool,
|
||||||
pub off_when_lid_closed: bool,
|
pub off_when_lid_closed: bool,
|
||||||
pub brightness_on_battery: Brightness
|
pub brightness_on_battery: Brightness,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "dbus", derive(Type), zvariant(signature = "s"))]
|
#[cfg_attr(feature = "dbus", derive(Type), zvariant(signature = "s"))]
|
||||||
@@ -63,20 +63,31 @@ pub enum AnimeType {
|
|||||||
GA401,
|
GA401,
|
||||||
GA402,
|
GA402,
|
||||||
GU604,
|
GU604,
|
||||||
|
G635L,
|
||||||
|
G835L,
|
||||||
#[default]
|
#[default]
|
||||||
Unsupported
|
Unsupported,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for AnimeType {
|
impl FromStr for AnimeType {
|
||||||
type Err = AnimeError;
|
type Err = AnimeError;
|
||||||
|
|
||||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||||
Ok(match s {
|
let dmi = s.to_uppercase();
|
||||||
"ga401" | "GA401" => Self::GA401,
|
|
||||||
"ga402" | "GA402" => Self::GA402,
|
if dmi.contains("GA401") {
|
||||||
"gu604" | "GU604" => Self::GU604,
|
return Ok(Self::GA401);
|
||||||
_ => Self::Unsupported
|
} 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
|
AnimeType::GA402
|
||||||
} else if board_name.contains("GU604V") {
|
} else if board_name.contains("GU604V") {
|
||||||
AnimeType::GU604
|
AnimeType::GU604
|
||||||
|
} else if board_name.contains("G635L") || board_name.contains("G635L") {
|
||||||
|
AnimeType::G635L
|
||||||
} else {
|
} else {
|
||||||
AnimeType::Unsupported
|
AnimeType::Unsupported
|
||||||
}
|
}
|
||||||
@@ -98,7 +111,8 @@ impl AnimeType {
|
|||||||
pub fn width(&self) -> usize {
|
pub fn width(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
AnimeType::GU604 => 70,
|
AnimeType::GU604 => 70,
|
||||||
_ => 74
|
AnimeType::G835L => 74,
|
||||||
|
_ => 74,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +121,8 @@ impl AnimeType {
|
|||||||
match self {
|
match self {
|
||||||
AnimeType::GA401 => 36,
|
AnimeType::GA401 => 36,
|
||||||
AnimeType::GU604 => 43,
|
AnimeType::GU604 => 43,
|
||||||
_ => 39
|
AnimeType::G835L => 39,
|
||||||
|
_ => 39,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +131,8 @@ impl AnimeType {
|
|||||||
match self {
|
match self {
|
||||||
AnimeType::GA401 => PANE_LEN * 2,
|
AnimeType::GA401 => PANE_LEN * 2,
|
||||||
AnimeType::GU604 => PANE_LEN * 3,
|
AnimeType::GU604 => PANE_LEN * 3,
|
||||||
_ => PANE_LEN * 3
|
AnimeType::G835L => PANE_LEN * 3,
|
||||||
|
_ => PANE_LEN * 3,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,7 +143,7 @@ impl AnimeType {
|
|||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
pub struct AnimeDataBuffer {
|
pub struct AnimeDataBuffer {
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
anime: AnimeType
|
anime: AnimeType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AnimeDataBuffer {
|
impl AnimeDataBuffer {
|
||||||
@@ -137,7 +153,7 @@ impl AnimeDataBuffer {
|
|||||||
|
|
||||||
AnimeDataBuffer {
|
AnimeDataBuffer {
|
||||||
data: vec![0u8; len],
|
data: vec![0u8; len],
|
||||||
anime
|
anime,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +196,13 @@ impl TryFrom<AnimeDataBuffer> for AnimePacketType {
|
|||||||
|
|
||||||
let mut buffers = match anime.anime {
|
let mut buffers = match anime.anime {
|
||||||
AnimeType::GA401 => vec![[0; 640]; 2],
|
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() {
|
for (idx, chunk) in anime.data.as_slice().chunks(PANE_LEN).enumerate() {
|
||||||
@@ -191,7 +213,11 @@ impl TryFrom<AnimeDataBuffer> for AnimePacketType {
|
|||||||
|
|
||||||
if matches!(
|
if matches!(
|
||||||
anime.anime,
|
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);
|
buffers[2][..7].copy_from_slice(&USB_PREFIX3);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ impl AnimeDiagonal {
|
|||||||
Self(
|
Self(
|
||||||
anime_type,
|
anime_type,
|
||||||
vec![vec![0; anime_type.width()]; anime_type.height()],
|
vec![vec![0; anime_type.width()]; anime_type.height()],
|
||||||
duration
|
duration,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ impl AnimeDiagonal {
|
|||||||
path: &Path,
|
path: &Path,
|
||||||
duration: Option<Duration>,
|
duration: Option<Duration>,
|
||||||
bright: f32,
|
bright: f32,
|
||||||
anime_type: AnimeType
|
anime_type: AnimeType,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let data = std::fs::read(path).map_err(|e| {
|
let data = std::fs::read(path).map_err(|e| {
|
||||||
error!("Could not open {path:?}: {e:?}");
|
error!("Could not open {path:?}: {e:?}");
|
||||||
@@ -86,7 +86,7 @@ impl AnimeDiagonal {
|
|||||||
png_pong::PngRaster::Rgba16(ras) => {
|
png_pong::PngRaster::Rgba16(ras) => {
|
||||||
Self::pixels_from_16bit(ras, &mut matrix, bright, false);
|
Self::pixels_from_16bit(ras, &mut matrix, bright, false);
|
||||||
}
|
}
|
||||||
png_pong::PngRaster::Palette(..) => return Err(AnimeError::Format)
|
png_pong::PngRaster::Palette(..) => return Err(AnimeError::Format),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(matrix)
|
Ok(matrix)
|
||||||
@@ -96,9 +96,9 @@ impl AnimeDiagonal {
|
|||||||
ras: &pix::Raster<P>,
|
ras: &pix::Raster<P>,
|
||||||
matrix: &mut AnimeDiagonal,
|
matrix: &mut AnimeDiagonal,
|
||||||
bright: f32,
|
bright: f32,
|
||||||
grey: bool
|
grey: bool,
|
||||||
) where
|
) where
|
||||||
P: pix::el::Pixel<Chan = pix::chan::Ch8>
|
P: pix::el::Pixel<Chan = pix::chan::Ch8>,
|
||||||
{
|
{
|
||||||
let width = ras.width();
|
let width = ras.width();
|
||||||
for (y, row) in ras.pixels().chunks(width as usize).enumerate() {
|
for (y, row) in ras.pixels().chunks(width as usize).enumerate() {
|
||||||
@@ -121,9 +121,9 @@ impl AnimeDiagonal {
|
|||||||
ras: &pix::Raster<P>,
|
ras: &pix::Raster<P>,
|
||||||
matrix: &mut AnimeDiagonal,
|
matrix: &mut AnimeDiagonal,
|
||||||
bright: f32,
|
bright: f32,
|
||||||
grey: bool
|
grey: bool,
|
||||||
) where
|
) where
|
||||||
P: pix::el::Pixel<Chan = pix::chan::Ch16>
|
P: pix::el::Pixel<Chan = pix::chan::Ch16>,
|
||||||
{
|
{
|
||||||
let width = ras.width();
|
let width = ras.width();
|
||||||
for (y, row) in ras.pixels().chunks(width as usize).enumerate() {
|
for (y, row) in ras.pixels().chunks(width as usize).enumerate() {
|
||||||
@@ -146,7 +146,7 @@ impl AnimeDiagonal {
|
|||||||
match anime_type {
|
match anime_type {
|
||||||
AnimeType::GA401 => self.to_ga401_packets(),
|
AnimeType::GA401 => self.to_ga401_packets(),
|
||||||
AnimeType::GU604 => self.to_gu604_packets(),
|
AnimeType::GU604 => self.to_gu604_packets(),
|
||||||
_ => self.to_ga402_packets()
|
_ => self.to_ga402_packets(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +224,7 @@ impl AnimeDiagonal {
|
|||||||
x: usize,
|
x: usize,
|
||||||
y: usize,
|
y: usize,
|
||||||
start_index: &mut usize,
|
start_index: &mut usize,
|
||||||
len: usize
|
len: usize,
|
||||||
) {
|
) {
|
||||||
buf[*start_index..*start_index + len].copy_from_slice(&anime.get_row(x, y, len));
|
buf[*start_index..*start_index + len].copy_from_slice(&anime.get_row(x, y, len));
|
||||||
*start_index += len;
|
*start_index += len;
|
||||||
@@ -307,7 +307,7 @@ impl AnimeDiagonal {
|
|||||||
x: usize,
|
x: usize,
|
||||||
y: usize,
|
y: usize,
|
||||||
start_index: &mut usize,
|
start_index: &mut usize,
|
||||||
len: usize
|
len: usize,
|
||||||
) {
|
) {
|
||||||
buf[*start_index..*start_index + len].copy_from_slice(&anime.get_row(x, y, len));
|
buf[*start_index..*start_index + len].copy_from_slice(&anime.get_row(x, y, len));
|
||||||
*start_index += len;
|
*start_index += len;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ pub enum AnimeError {
|
|||||||
DataBufferLength,
|
DataBufferLength,
|
||||||
PixelGifWidth(usize),
|
PixelGifWidth(usize),
|
||||||
PixelGifHeight(usize),
|
PixelGifHeight(usize),
|
||||||
ParseError(String)
|
ParseError(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for AnimeError {
|
impl fmt::Display for AnimeError {
|
||||||
@@ -61,7 +61,7 @@ impl fmt::Display for AnimeError {
|
|||||||
AnimeError::PixelGifHeight(n) => write!(
|
AnimeError::PixelGifHeight(n) => write!(
|
||||||
f,
|
f,
|
||||||
"The gif used for pixel-perfect gif is is taller than {n}"
|
"The gif used for pixel-perfect gif is is taller than {n}"
|
||||||
)
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub struct AnimeFrame {
|
|||||||
/// the `asusd` daemon over dbus or converted to USB packet with
|
/// the `asusd` daemon over dbus or converted to USB packet with
|
||||||
/// `AnimePacketType::from(buffer)`
|
/// `AnimePacketType::from(buffer)`
|
||||||
data: AnimeDataBuffer,
|
data: AnimeDataBuffer,
|
||||||
delay: Duration
|
delay: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AnimeFrame {
|
impl AnimeFrame {
|
||||||
@@ -44,7 +44,7 @@ pub enum AnimTime {
|
|||||||
/// Run for infinite time
|
/// Run for infinite time
|
||||||
Infinite,
|
Infinite,
|
||||||
/// Fade in, play for, fade out
|
/// Fade in, play for, fade out
|
||||||
Fade(Fade)
|
Fade(Fade),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AnimTime {
|
impl Default for AnimTime {
|
||||||
@@ -59,7 +59,7 @@ impl Default for AnimTime {
|
|||||||
pub struct Fade {
|
pub struct Fade {
|
||||||
fade_in: Duration,
|
fade_in: Duration,
|
||||||
show_for: Option<Duration>,
|
show_for: Option<Duration>,
|
||||||
fade_out: Duration
|
fade_out: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Fade {
|
impl Fade {
|
||||||
@@ -67,7 +67,7 @@ impl Fade {
|
|||||||
Self {
|
Self {
|
||||||
fade_in,
|
fade_in,
|
||||||
show_for,
|
show_for,
|
||||||
fade_out
|
fade_out,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ impl AnimeGif {
|
|||||||
file_name: &Path,
|
file_name: &Path,
|
||||||
duration: AnimTime,
|
duration: AnimTime,
|
||||||
brightness: f32,
|
brightness: f32,
|
||||||
anime_type: AnimeType
|
anime_type: AnimeType,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let mut matrix = AnimeDiagonal::new(anime_type, None);
|
let mut matrix = AnimeDiagonal::new(anime_type, None);
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ impl AnimeGif {
|
|||||||
|
|
||||||
frames.push(AnimeFrame {
|
frames.push(AnimeFrame {
|
||||||
data: matrix.into_data_buffer(anime_type)?,
|
data: matrix.into_data_buffer(anime_type)?,
|
||||||
delay: Duration::from_millis(wait as u64)
|
delay: Duration::from_millis(wait as u64),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Ok(Self(frames, duration))
|
Ok(Self(frames, duration))
|
||||||
@@ -154,7 +154,7 @@ impl AnimeGif {
|
|||||||
file_name: &Path,
|
file_name: &Path,
|
||||||
anime_type: AnimeType,
|
anime_type: AnimeType,
|
||||||
duration: AnimTime,
|
duration: AnimTime,
|
||||||
brightness: f32
|
brightness: f32,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let image = AnimeDiagonal::from_png(file_name, None, brightness, anime_type)?;
|
let image = AnimeDiagonal::from_png(file_name, None, brightness, anime_type)?;
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ impl AnimeGif {
|
|||||||
|
|
||||||
let single = AnimeFrame {
|
let single = AnimeFrame {
|
||||||
data: image.into_data_buffer(anime_type)?,
|
data: image.into_data_buffer(anime_type)?,
|
||||||
delay: Duration::from_millis(30)
|
delay: Duration::from_millis(30),
|
||||||
};
|
};
|
||||||
let frames = vec![single; frame_count as usize];
|
let frames = vec![single; frame_count as usize];
|
||||||
|
|
||||||
@@ -187,7 +187,7 @@ impl AnimeGif {
|
|||||||
translation: Vec2,
|
translation: Vec2,
|
||||||
duration: AnimTime,
|
duration: AnimTime,
|
||||||
brightness: f32,
|
brightness: f32,
|
||||||
anime_type: AnimeType
|
anime_type: AnimeType,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let mut frames = Vec::new();
|
let mut frames = Vec::new();
|
||||||
let mut decoder = gif::DecodeOptions::new();
|
let mut decoder = gif::DecodeOptions::new();
|
||||||
@@ -211,7 +211,7 @@ impl AnimeGif {
|
|||||||
brightness,
|
brightness,
|
||||||
pixels,
|
pixels,
|
||||||
decoder.width() as u32,
|
decoder.width() as u32,
|
||||||
anime_type
|
anime_type,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
while let Some(frame) = decoder.read_next_frame()? {
|
while let Some(frame) = decoder.read_next_frame()? {
|
||||||
@@ -226,7 +226,7 @@ impl AnimeGif {
|
|||||||
brightness,
|
brightness,
|
||||||
pixels,
|
pixels,
|
||||||
width as u32,
|
width as u32,
|
||||||
anime_type
|
anime_type,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
for (y, row) in frame.buffer.chunks(frame.width as usize * 4).enumerate() {
|
for (y, row) in frame.buffer.chunks(frame.width as usize * 4).enumerate() {
|
||||||
@@ -239,7 +239,7 @@ impl AnimeGif {
|
|||||||
(x + frame.left as usize) + ((y + frame.top as usize) * width as usize);
|
(x + frame.left as usize) + ((y + frame.top as usize) * width as usize);
|
||||||
image.get_mut()[pos] = Pixel {
|
image.get_mut()[pos] = Pixel {
|
||||||
color: ((px[0] as u32 + px[1] as u32 + px[2] as u32) / 3),
|
color: ((px[0] as u32 + px[1] as u32 + px[2] as u32) / 3),
|
||||||
alpha: 1.0
|
alpha: 1.0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -247,7 +247,7 @@ impl AnimeGif {
|
|||||||
|
|
||||||
frames.push(AnimeFrame {
|
frames.push(AnimeFrame {
|
||||||
data: <AnimeDataBuffer>::try_from(&image)?,
|
data: <AnimeDataBuffer>::try_from(&image)?,
|
||||||
delay: Duration::from_millis(wait as u64)
|
delay: Duration::from_millis(wait as u64),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Ok(Self(frames, duration))
|
Ok(Self(frames, duration))
|
||||||
@@ -265,7 +265,7 @@ impl AnimeGif {
|
|||||||
translation: Vec2,
|
translation: Vec2,
|
||||||
duration: AnimTime,
|
duration: AnimTime,
|
||||||
brightness: f32,
|
brightness: f32,
|
||||||
anime_type: AnimeType
|
anime_type: AnimeType,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let image =
|
let image =
|
||||||
AnimeImage::from_png(file_name, scale, angle, translation, brightness, anime_type)?;
|
AnimeImage::from_png(file_name, scale, angle, translation, brightness, anime_type)?;
|
||||||
@@ -282,7 +282,7 @@ impl AnimeGif {
|
|||||||
|
|
||||||
let single = AnimeFrame {
|
let single = AnimeFrame {
|
||||||
data: <AnimeDataBuffer>::try_from(&image)?,
|
data: <AnimeDataBuffer>::try_from(&image)?,
|
||||||
delay: Duration::from_millis(30)
|
delay: Duration::from_millis(30),
|
||||||
};
|
};
|
||||||
let frames = vec![single; frame_count as usize];
|
let frames = vec![single; frame_count as usize];
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const HEIGHT: usize = 55;
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct AnimeGrid {
|
pub struct AnimeGrid {
|
||||||
anime_type: AnimeType,
|
anime_type: AnimeType,
|
||||||
data: [[u8; WIDTH]; HEIGHT]
|
data: [[u8; WIDTH]; HEIGHT],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AnimeGrid {
|
impl AnimeGrid {
|
||||||
@@ -26,7 +26,7 @@ impl AnimeGrid {
|
|||||||
pub fn new(anime_type: AnimeType) -> Self {
|
pub fn new(anime_type: AnimeType) -> Self {
|
||||||
Self {
|
Self {
|
||||||
anime_type,
|
anime_type,
|
||||||
data: [[0u8; WIDTH]; HEIGHT]
|
data: [[0u8; WIDTH]; HEIGHT],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ mod tests {
|
|||||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
];
|
];
|
||||||
assert_eq!(matrix.data(), &data_cmp);
|
assert_eq!(matrix.data(), &data_cmp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use crate::AnimeType;
|
|||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct Pixel {
|
pub struct Pixel {
|
||||||
pub color: u32,
|
pub color: u32,
|
||||||
pub alpha: f32
|
pub alpha: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Pixel {
|
impl Default for Pixel {
|
||||||
@@ -21,7 +21,7 @@ impl Default for Pixel {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Pixel {
|
Pixel {
|
||||||
color: 0,
|
color: 0,
|
||||||
alpha: 0.0
|
alpha: 0.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ pub struct AnimeImage {
|
|||||||
/// The type of the display. The GA401 and GA402 use the same controller and
|
/// The type of the display. The GA401 and GA402 use the same controller and
|
||||||
/// therefore same ID, so the identifier must be by laptop model in
|
/// therefore same ID, so the identifier must be by laptop model in
|
||||||
/// `AnimeType`.
|
/// `AnimeType`.
|
||||||
anime_type: AnimeType
|
anime_type: AnimeType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AnimeImage {
|
impl AnimeImage {
|
||||||
@@ -88,7 +88,7 @@ impl AnimeImage {
|
|||||||
bright: f32,
|
bright: f32,
|
||||||
pixels: Vec<Pixel>,
|
pixels: Vec<Pixel>,
|
||||||
width: u32,
|
width: u32,
|
||||||
anime_type: AnimeType
|
anime_type: AnimeType,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
if !(0.0..=1.0).contains(&bright) {
|
if !(0.0..=1.0).contains(&bright) {
|
||||||
return Err(AnimeError::InvalidBrightness(bright));
|
return Err(AnimeError::InvalidBrightness(bright));
|
||||||
@@ -102,7 +102,7 @@ impl AnimeImage {
|
|||||||
led_pos: Self::generate_image_positioning(anime_type),
|
led_pos: Self::generate_image_positioning(anime_type),
|
||||||
img_pixels: pixels,
|
img_pixels: pixels,
|
||||||
width,
|
width,
|
||||||
anime_type
|
anime_type,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ impl AnimeImage {
|
|||||||
match anime_type {
|
match anime_type {
|
||||||
AnimeType::GA401 => 0.8,
|
AnimeType::GA401 => 0.8,
|
||||||
AnimeType::GU604 => 0.78,
|
AnimeType::GU604 => 0.78,
|
||||||
_ => 0.77
|
_ => 0.77,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +138,7 @@ impl AnimeImage {
|
|||||||
match anime_type {
|
match anime_type {
|
||||||
AnimeType::GA401 => 0.3,
|
AnimeType::GA401 => 0.3,
|
||||||
AnimeType::GU604 => 0.28,
|
AnimeType::GU604 => 0.28,
|
||||||
_ => 0.283
|
_ => 0.283,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ impl AnimeImage {
|
|||||||
// first 5 rows for GA401 are always at X = 0
|
// first 5 rows for GA401 are always at X = 0
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
(y + 1) / 2 - 3
|
y.div_ceil(2) - 3
|
||||||
}
|
}
|
||||||
AnimeType::GU604 => {
|
AnimeType::GU604 => {
|
||||||
// first 9 rows start at zero
|
// first 9 rows start at zero
|
||||||
@@ -185,7 +185,7 @@ impl AnimeImage {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// and then their offset grows by one every two rows
|
// and then their offset grows by one every two rows
|
||||||
(y + 1) / 2 - 5
|
y.div_ceil(2) - 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -213,7 +213,7 @@ impl AnimeImage {
|
|||||||
// First 5 rows for GA401 are always 33 physical LEDs long
|
// First 5 rows for GA401 are always 33 physical LEDs long
|
||||||
return 33;
|
return 33;
|
||||||
}
|
}
|
||||||
36 - (y + 1) / 2
|
36 - y.div_ceil(2)
|
||||||
}
|
}
|
||||||
AnimeType::GU604 => {
|
AnimeType::GU604 => {
|
||||||
if y <= 9 {
|
if y <= 9 {
|
||||||
@@ -237,7 +237,7 @@ impl AnimeImage {
|
|||||||
AnimeType::GA401 => (33.0 + 0.5) * Self::scale_x(anime_type),
|
AnimeType::GA401 => (33.0 + 0.5) * Self::scale_x(anime_type),
|
||||||
|
|
||||||
AnimeType::GU604 => (38.0 + 0.5) * Self::scale_x(anime_type),
|
AnimeType::GU604 => (38.0 + 0.5) * Self::scale_x(anime_type),
|
||||||
_ => (35.0 + 0.5) * Self::scale_x(anime_type)
|
_ => (35.0 + 0.5) * Self::scale_x(anime_type),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,7 +246,7 @@ impl AnimeImage {
|
|||||||
match anime_type {
|
match anime_type {
|
||||||
AnimeType::GA401 => 55,
|
AnimeType::GA401 => 55,
|
||||||
AnimeType::GU604 => 62,
|
AnimeType::GU604 => 62,
|
||||||
_ => 61
|
_ => 61,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,7 +257,7 @@ impl AnimeImage {
|
|||||||
AnimeType::GA401 => (54.0 + 1.0) * Self::scale_y(anime_type),
|
AnimeType::GA401 => (54.0 + 1.0) * Self::scale_y(anime_type),
|
||||||
AnimeType::GU604 => 62.0 * Self::scale_y(anime_type),
|
AnimeType::GU604 => 62.0 * Self::scale_y(anime_type),
|
||||||
// GA402 may not have dead pixels and require only the physical LED count
|
// GA402 may not have dead pixels and require only the physical LED count
|
||||||
_ => 61.0 * Self::scale_y(anime_type)
|
_ => 61.0 * Self::scale_y(anime_type),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,11 +267,11 @@ impl AnimeImage {
|
|||||||
AnimeType::GA401 => match y {
|
AnimeType::GA401 => match y {
|
||||||
0 | 2 | 4 => 33,
|
0 | 2 | 4 => 33,
|
||||||
1 | 3 => 35, // Some rows are padded
|
1 | 3 => 35, // Some rows are padded
|
||||||
_ => 36 - y / 2
|
_ => 36 - y / 2,
|
||||||
},
|
},
|
||||||
AnimeType::GU604 => AnimeImage::width(anime_type, y),
|
AnimeType::GU604 => AnimeImage::width(anime_type, y),
|
||||||
// GA402 does not have padding, equivalent to width
|
// GA402 does not have padding, equivalent to width
|
||||||
_ => AnimeImage::width(anime_type, y)
|
_ => AnimeImage::width(anime_type, y),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,7 +322,7 @@ impl AnimeImage {
|
|||||||
let x0 = led_from_px.mul_vec3(pos + Vec3::new(0.0, -0.5, 0.0));
|
let x0 = led_from_px.mul_vec3(pos + Vec3::new(0.0, -0.5, 0.0));
|
||||||
|
|
||||||
const GROUP: [f32; 4] = [
|
const GROUP: [f32; 4] = [
|
||||||
0.0, 0.5, 1.0, 1.5
|
0.0, 0.5, 1.0, 1.5,
|
||||||
];
|
];
|
||||||
for u in &GROUP {
|
for u in &GROUP {
|
||||||
for v in &GROUP {
|
for v in &GROUP {
|
||||||
@@ -399,7 +399,7 @@ impl AnimeImage {
|
|||||||
|
|
||||||
let led_from_cm = Mat3::from_scale(Vec2::new(
|
let led_from_cm = Mat3::from_scale(Vec2::new(
|
||||||
1.0 / AnimeImage::scale_x(self.anime_type),
|
1.0 / AnimeImage::scale_x(self.anime_type),
|
||||||
1.0 / AnimeImage::scale_y(self.anime_type)
|
1.0 / AnimeImage::scale_y(self.anime_type),
|
||||||
));
|
));
|
||||||
|
|
||||||
let transform =
|
let transform =
|
||||||
@@ -422,7 +422,7 @@ impl AnimeImage {
|
|||||||
angle: f32,
|
angle: f32,
|
||||||
translation: Vec2,
|
translation: Vec2,
|
||||||
bright: f32,
|
bright: f32,
|
||||||
anime_type: AnimeType
|
anime_type: AnimeType,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let data = std::fs::read(path).map_err(|e| {
|
let data = std::fs::read(path).map_err(|e| {
|
||||||
error!("Could not open {path:?}: {e:?}");
|
error!("Could not open {path:?}: {e:?}");
|
||||||
@@ -466,7 +466,7 @@ impl AnimeImage {
|
|||||||
width = ras.width();
|
width = ras.width();
|
||||||
Self::pixels_from_16bit(ras, false)
|
Self::pixels_from_16bit(ras, false)
|
||||||
}
|
}
|
||||||
png_pong::PngRaster::Palette(..) => return Err(AnimeError::Format)
|
png_pong::PngRaster::Palette(..) => return Err(AnimeError::Format),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut matrix = AnimeImage::new(
|
let mut matrix = AnimeImage::new(
|
||||||
@@ -476,7 +476,7 @@ impl AnimeImage {
|
|||||||
bright,
|
bright,
|
||||||
pixels,
|
pixels,
|
||||||
width,
|
width,
|
||||||
anime_type
|
anime_type,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
matrix.update();
|
matrix.update();
|
||||||
@@ -485,7 +485,7 @@ impl AnimeImage {
|
|||||||
|
|
||||||
fn pixels_from_8bit<P>(ras: &pix::Raster<P>, grey: bool) -> Vec<Pixel>
|
fn pixels_from_8bit<P>(ras: &pix::Raster<P>, grey: bool) -> Vec<Pixel>
|
||||||
where
|
where
|
||||||
P: pix::el::Pixel<Chan = pix::chan::Ch8>
|
P: pix::el::Pixel<Chan = pix::chan::Ch8>,
|
||||||
{
|
{
|
||||||
ras.pixels()
|
ras.pixels()
|
||||||
.iter()
|
.iter()
|
||||||
@@ -497,14 +497,14 @@ impl AnimeImage {
|
|||||||
+ (<u8>::from(px.two()) / 3) as u32
|
+ (<u8>::from(px.two()) / 3) as u32
|
||||||
+ (<u8>::from(px.three()) / 3) as u32
|
+ (<u8>::from(px.three()) / 3) as u32
|
||||||
},
|
},
|
||||||
alpha: <f32>::from(px.alpha())
|
alpha: <f32>::from(px.alpha()),
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pixels_from_16bit<P>(ras: &pix::Raster<P>, grey: bool) -> Vec<Pixel>
|
fn pixels_from_16bit<P>(ras: &pix::Raster<P>, grey: bool) -> Vec<Pixel>
|
||||||
where
|
where
|
||||||
P: pix::el::Pixel<Chan = pix::chan::Ch16>
|
P: pix::el::Pixel<Chan = pix::chan::Ch16>,
|
||||||
{
|
{
|
||||||
ras.pixels()
|
ras.pixels()
|
||||||
.iter()
|
.iter()
|
||||||
@@ -516,7 +516,7 @@ impl AnimeImage {
|
|||||||
+ ((<u16>::from(px.two()) / 3) >> 8) as u32
|
+ ((<u16>::from(px.two()) / 3) >> 8) as u32
|
||||||
+ ((<u16>::from(px.three()) / 3) >> 8) as u32
|
+ ((<u16>::from(px.three()) / 3) >> 8) as u32
|
||||||
},
|
},
|
||||||
alpha: <f32>::from(px.alpha())
|
alpha: <f32>::from(px.alpha()),
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
@@ -653,7 +653,7 @@ mod tests {
|
|||||||
Vec2::default(),
|
Vec2::default(),
|
||||||
AnimTime::Infinite,
|
AnimTime::Infinite,
|
||||||
1.0,
|
1.0,
|
||||||
AnimeType::GA402
|
AnimeType::GA402,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
matrix.frames()[0].frame();
|
matrix.frames()[0].frame();
|
||||||
|
|||||||
@@ -16,13 +16,13 @@ pub enum ActionLoader {
|
|||||||
AsusAnimation {
|
AsusAnimation {
|
||||||
file: PathBuf,
|
file: PathBuf,
|
||||||
time: AnimTime,
|
time: AnimTime,
|
||||||
brightness: f32
|
brightness: f32,
|
||||||
},
|
},
|
||||||
/// Image designed to be pixel perfect using the slanted template
|
/// Image designed to be pixel perfect using the slanted template
|
||||||
AsusImage {
|
AsusImage {
|
||||||
file: PathBuf,
|
file: PathBuf,
|
||||||
time: AnimTime,
|
time: AnimTime,
|
||||||
brightness: f32
|
brightness: f32,
|
||||||
},
|
},
|
||||||
/// Animated gif. If the file is a png a static gif is created using the
|
/// Animated gif. If the file is a png a static gif is created using the
|
||||||
/// `time` properties
|
/// `time` properties
|
||||||
@@ -32,7 +32,7 @@ pub enum ActionLoader {
|
|||||||
angle: f32,
|
angle: f32,
|
||||||
translation: Vec2,
|
translation: Vec2,
|
||||||
time: AnimTime,
|
time: AnimTime,
|
||||||
brightness: f32
|
brightness: f32,
|
||||||
},
|
},
|
||||||
Image {
|
Image {
|
||||||
file: PathBuf,
|
file: PathBuf,
|
||||||
@@ -40,10 +40,10 @@ pub enum ActionLoader {
|
|||||||
angle: f32,
|
angle: f32,
|
||||||
translation: Vec2,
|
translation: Vec2,
|
||||||
time: AnimTime,
|
time: AnimTime,
|
||||||
brightness: f32
|
brightness: f32,
|
||||||
},
|
},
|
||||||
/// A pause to be used between sequences
|
/// A pause to be used between sequences
|
||||||
Pause(Duration)
|
Pause(Duration),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// All the possible `AniMe` actions that can be used. The enum is intended to
|
/// All the possible `AniMe` actions that can be used. The enum is intended to
|
||||||
@@ -64,7 +64,7 @@ pub enum ActionData {
|
|||||||
/// Placeholder
|
/// Placeholder
|
||||||
TimeDate,
|
TimeDate,
|
||||||
/// Placeholder
|
/// Placeholder
|
||||||
Matrix
|
Matrix,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActionData {
|
impl ActionData {
|
||||||
@@ -73,14 +73,14 @@ impl ActionData {
|
|||||||
ActionLoader::AsusAnimation {
|
ActionLoader::AsusAnimation {
|
||||||
file,
|
file,
|
||||||
time,
|
time,
|
||||||
brightness
|
brightness,
|
||||||
} => ActionData::Animation(AnimeGif::from_diagonal_gif(
|
} => ActionData::Animation(AnimeGif::from_diagonal_gif(
|
||||||
file, *time, *brightness, anime_type
|
file, *time, *brightness, anime_type,
|
||||||
)?),
|
)?),
|
||||||
ActionLoader::AsusImage {
|
ActionLoader::AsusImage {
|
||||||
file,
|
file,
|
||||||
time,
|
time,
|
||||||
brightness
|
brightness,
|
||||||
} => match time {
|
} => match time {
|
||||||
AnimTime::Infinite => {
|
AnimTime::Infinite => {
|
||||||
let image = AnimeDiagonal::from_png(file, None, *brightness, anime_type)?;
|
let image = AnimeDiagonal::from_png(file, None, *brightness, anime_type)?;
|
||||||
@@ -88,8 +88,8 @@ impl ActionData {
|
|||||||
ActionData::Image(Box::new(data))
|
ActionData::Image(Box::new(data))
|
||||||
}
|
}
|
||||||
_ => ActionData::Animation(AnimeGif::from_diagonal_png(
|
_ => ActionData::Animation(AnimeGif::from_diagonal_png(
|
||||||
file, anime_type, *time, *brightness
|
file, anime_type, *time, *brightness,
|
||||||
)?)
|
)?),
|
||||||
},
|
},
|
||||||
ActionLoader::ImageAnimation {
|
ActionLoader::ImageAnimation {
|
||||||
file,
|
file,
|
||||||
@@ -97,17 +97,17 @@ impl ActionData {
|
|||||||
angle,
|
angle,
|
||||||
translation,
|
translation,
|
||||||
time,
|
time,
|
||||||
brightness
|
brightness,
|
||||||
} => {
|
} => {
|
||||||
if let Some(ext) = file.extension() {
|
if let Some(ext) = file.extension() {
|
||||||
if ext.to_string_lossy().to_lowercase() == "png" {
|
if ext.to_string_lossy().to_lowercase() == "png" {
|
||||||
return Ok(ActionData::Animation(AnimeGif::from_png(
|
return Ok(ActionData::Animation(AnimeGif::from_png(
|
||||||
file, *scale, *angle, *translation, *time, *brightness, anime_type
|
file, *scale, *angle, *translation, *time, *brightness, anime_type,
|
||||||
)?));
|
)?));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionData::Animation(AnimeGif::from_gif(
|
ActionData::Animation(AnimeGif::from_gif(
|
||||||
file, *scale, *angle, *translation, *time, *brightness, anime_type
|
file, *scale, *angle, *translation, *time, *brightness, anime_type,
|
||||||
)?)
|
)?)
|
||||||
}
|
}
|
||||||
ActionLoader::Image {
|
ActionLoader::Image {
|
||||||
@@ -116,23 +116,23 @@ impl ActionData {
|
|||||||
angle,
|
angle,
|
||||||
translation,
|
translation,
|
||||||
brightness,
|
brightness,
|
||||||
time
|
time,
|
||||||
} => {
|
} => {
|
||||||
match time {
|
match time {
|
||||||
AnimTime::Infinite => {
|
AnimTime::Infinite => {
|
||||||
// If no time then create a plain static image
|
// If no time then create a plain static image
|
||||||
let image = AnimeImage::from_png(
|
let image = AnimeImage::from_png(
|
||||||
file, *scale, *angle, *translation, *brightness, anime_type
|
file, *scale, *angle, *translation, *brightness, anime_type,
|
||||||
)?;
|
)?;
|
||||||
let data = <AnimeDataBuffer>::try_from(&image)?;
|
let data = <AnimeDataBuffer>::try_from(&image)?;
|
||||||
ActionData::Image(Box::new(data))
|
ActionData::Image(Box::new(data))
|
||||||
}
|
}
|
||||||
_ => ActionData::Animation(AnimeGif::from_png(
|
_ => ActionData::Animation(AnimeGif::from_png(
|
||||||
file, *scale, *angle, *translation, *time, *brightness, anime_type
|
file, *scale, *angle, *translation, *time, *brightness, anime_type,
|
||||||
)?)
|
)?),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionLoader::Pause(duration) => ActionData::Pause(*duration)
|
ActionLoader::Pause(duration) => ActionData::Pause(*duration),
|
||||||
};
|
};
|
||||||
Ok(a)
|
Ok(a)
|
||||||
}
|
}
|
||||||
@@ -171,7 +171,7 @@ impl Sequences {
|
|||||||
pub fn iter(&self) -> ActionIterator<'_> {
|
pub fn iter(&self) -> ActionIterator<'_> {
|
||||||
ActionIterator {
|
ActionIterator {
|
||||||
actions: self,
|
actions: self,
|
||||||
next_idx: 0
|
next_idx: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,7 +179,7 @@ impl Sequences {
|
|||||||
/// Iteractor helper for iterating over all the actions in `Sequences`
|
/// Iteractor helper for iterating over all the actions in `Sequences`
|
||||||
pub struct ActionIterator<'a> {
|
pub struct ActionIterator<'a> {
|
||||||
actions: &'a Sequences,
|
actions: &'a Sequences,
|
||||||
next_idx: usize
|
next_idx: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for ActionIterator<'a> {
|
impl<'a> Iterator for ActionIterator<'a> {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ pub enum Brightness {
|
|||||||
Low = 1,
|
Low = 1,
|
||||||
#[default]
|
#[default]
|
||||||
Med = 2,
|
Med = 2,
|
||||||
High = 3
|
High = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for Brightness {
|
impl FromStr for Brightness {
|
||||||
@@ -47,7 +47,7 @@ impl FromStr for Brightness {
|
|||||||
"Low" | "low" => Brightness::Low,
|
"Low" | "low" => Brightness::Low,
|
||||||
"Med" | "med" => Brightness::Med,
|
"Med" | "med" => Brightness::Med,
|
||||||
"High" | "high" => Brightness::High,
|
"High" | "high" => Brightness::High,
|
||||||
_ => Brightness::Med
|
_ => Brightness::Med,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ impl From<u8> for Brightness {
|
|||||||
0 => Brightness::Off,
|
0 => Brightness::Off,
|
||||||
1 => Brightness::Low,
|
1 => Brightness::Low,
|
||||||
3 => Brightness::High,
|
3 => Brightness::High,
|
||||||
_ => Brightness::Med
|
_ => Brightness::Med,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,7 +84,7 @@ impl From<Brightness> for i32 {
|
|||||||
pub enum AnimBooting {
|
pub enum AnimBooting {
|
||||||
#[default]
|
#[default]
|
||||||
GlitchConstruction = 0,
|
GlitchConstruction = 0,
|
||||||
StaticEmergence = 1
|
StaticEmergence = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for AnimBooting {
|
impl FromStr for AnimBooting {
|
||||||
@@ -94,7 +94,7 @@ impl FromStr for AnimBooting {
|
|||||||
match s {
|
match s {
|
||||||
"GlitchConstruction" => Ok(Self::GlitchConstruction),
|
"GlitchConstruction" => Ok(Self::GlitchConstruction),
|
||||||
"StaticEmergence" => Ok(Self::StaticEmergence),
|
"StaticEmergence" => Ok(Self::StaticEmergence),
|
||||||
_ => Err(AnimeError::ParseError(s.to_owned()))
|
_ => Err(AnimeError::ParseError(s.to_owned())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ impl From<i32> for AnimBooting {
|
|||||||
match value {
|
match value {
|
||||||
0 => Self::GlitchConstruction,
|
0 => Self::GlitchConstruction,
|
||||||
1 => Self::StaticEmergence,
|
1 => Self::StaticEmergence,
|
||||||
_ => Self::default()
|
_ => Self::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,7 +124,7 @@ impl From<AnimBooting> for i32 {
|
|||||||
pub enum AnimAwake {
|
pub enum AnimAwake {
|
||||||
#[default]
|
#[default]
|
||||||
BinaryBannerScroll = 0,
|
BinaryBannerScroll = 0,
|
||||||
RogLogoGlitch = 1
|
RogLogoGlitch = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for AnimAwake {
|
impl FromStr for AnimAwake {
|
||||||
@@ -134,7 +134,7 @@ impl FromStr for AnimAwake {
|
|||||||
match s {
|
match s {
|
||||||
"BinaryBannerScroll" => Ok(Self::BinaryBannerScroll),
|
"BinaryBannerScroll" => Ok(Self::BinaryBannerScroll),
|
||||||
"RogLogoGlitch" => Ok(Self::RogLogoGlitch),
|
"RogLogoGlitch" => Ok(Self::RogLogoGlitch),
|
||||||
_ => Err(AnimeError::ParseError(s.to_owned()))
|
_ => Err(AnimeError::ParseError(s.to_owned())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ impl From<i32> for AnimAwake {
|
|||||||
match value {
|
match value {
|
||||||
0 => Self::BinaryBannerScroll,
|
0 => Self::BinaryBannerScroll,
|
||||||
1 => Self::RogLogoGlitch,
|
1 => Self::RogLogoGlitch,
|
||||||
_ => Self::default()
|
_ => Self::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,7 +164,7 @@ impl From<AnimAwake> for i32 {
|
|||||||
pub enum AnimSleeping {
|
pub enum AnimSleeping {
|
||||||
#[default]
|
#[default]
|
||||||
BannerSwipe = 0,
|
BannerSwipe = 0,
|
||||||
Starfield = 1
|
Starfield = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for AnimSleeping {
|
impl FromStr for AnimSleeping {
|
||||||
@@ -174,7 +174,7 @@ impl FromStr for AnimSleeping {
|
|||||||
match s {
|
match s {
|
||||||
"BannerSwipe" => Ok(Self::BannerSwipe),
|
"BannerSwipe" => Ok(Self::BannerSwipe),
|
||||||
"Starfield" => Ok(Self::Starfield),
|
"Starfield" => Ok(Self::Starfield),
|
||||||
_ => Err(AnimeError::ParseError(s.to_owned()))
|
_ => Err(AnimeError::ParseError(s.to_owned())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,7 +184,7 @@ impl From<i32> for AnimSleeping {
|
|||||||
match value {
|
match value {
|
||||||
0 => Self::BannerSwipe,
|
0 => Self::BannerSwipe,
|
||||||
1 => Self::Starfield,
|
1 => Self::Starfield,
|
||||||
_ => Self::default()
|
_ => Self::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,7 +204,7 @@ impl From<AnimSleeping> for i32 {
|
|||||||
pub enum AnimShutdown {
|
pub enum AnimShutdown {
|
||||||
#[default]
|
#[default]
|
||||||
GlitchOut = 0,
|
GlitchOut = 0,
|
||||||
SeeYa = 1
|
SeeYa = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for AnimShutdown {
|
impl FromStr for AnimShutdown {
|
||||||
@@ -214,7 +214,7 @@ impl FromStr for AnimShutdown {
|
|||||||
match s {
|
match s {
|
||||||
"GlitchOut" => Ok(Self::GlitchOut),
|
"GlitchOut" => Ok(Self::GlitchOut),
|
||||||
"SeeYa" => Ok(Self::SeeYa),
|
"SeeYa" => Ok(Self::SeeYa),
|
||||||
_ => Err(AnimeError::ParseError(s.to_owned()))
|
_ => Err(AnimeError::ParseError(s.to_owned())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,7 +224,7 @@ impl From<i32> for AnimShutdown {
|
|||||||
match value {
|
match value {
|
||||||
0 => Self::GlitchOut,
|
0 => Self::GlitchOut,
|
||||||
1 => Self::SeeYa,
|
1 => Self::SeeYa,
|
||||||
_ => Self::default()
|
_ => Self::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,7 +243,7 @@ impl From<AnimShutdown> for i32 {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_anime_type() -> AnimeType {
|
pub fn get_anime_type() -> AnimeType {
|
||||||
let dmi = DMIID::new().unwrap_or_default();
|
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") {
|
if board_name.contains("GA401I") || board_name.contains("GA401Q") {
|
||||||
AnimeType::GA401
|
AnimeType::GA401
|
||||||
@@ -251,6 +251,10 @@ pub fn get_anime_type() -> AnimeType {
|
|||||||
AnimeType::GA402
|
AnimeType::GA402
|
||||||
} else if board_name.contains("GU604V") {
|
} else if board_name.contains("GU604V") {
|
||||||
AnimeType::GU604
|
AnimeType::GU604
|
||||||
|
} else if board_name.contains("G635L") {
|
||||||
|
AnimeType::G635L
|
||||||
|
} else if board_name.contains("G835L") {
|
||||||
|
AnimeType::G835L
|
||||||
} else {
|
} else {
|
||||||
AnimeType::Unsupported
|
AnimeType::Unsupported
|
||||||
}
|
}
|
||||||
@@ -326,7 +330,7 @@ pub const fn pkt_set_builtin_animations(
|
|||||||
boot: AnimBooting,
|
boot: AnimBooting,
|
||||||
awake: AnimAwake,
|
awake: AnimAwake,
|
||||||
sleep: AnimSleeping,
|
sleep: AnimSleeping,
|
||||||
shutdown: AnimShutdown
|
shutdown: AnimShutdown,
|
||||||
) -> [u8; PACKET_SIZE] {
|
) -> [u8; PACKET_SIZE] {
|
||||||
let mut pkt = [0; PACKET_SIZE];
|
let mut pkt = [0; PACKET_SIZE];
|
||||||
pkt[0] = DEV_PAGE;
|
pkt[0] = DEV_PAGE;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
let pkt1_check = [
|
let pkt1_check = [
|
||||||
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
@@ -100,7 +100,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut matrix = AnimeImage::new(
|
let mut matrix = AnimeImage::new(
|
||||||
@@ -110,7 +110,7 @@ mod tests {
|
|||||||
0.0,
|
0.0,
|
||||||
vec![Pixel::default(); 1000],
|
vec![Pixel::default(); 1000],
|
||||||
100,
|
100,
|
||||||
AnimeType::GA401
|
AnimeType::GA401,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
matrix.edge_outline();
|
matrix.edge_outline();
|
||||||
@@ -175,7 +175,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||||
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
let pkt1_check = [
|
let pkt1_check = [
|
||||||
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
@@ -223,7 +223,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
|
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
let pkt1_check = [
|
let pkt1_check = [
|
||||||
0x5e, 0xc0, 0x2, 0x74, 0x2, 0x73, 0x2, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
0x5e, 0xc0, 0x2, 0x74, 0x2, 0x73, 0x2, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||||
@@ -100,7 +100,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
let pkt2_check = [
|
let pkt2_check = [
|
||||||
0x5e, 0xc0, 0x2, 0xe7, 0x4, 0x73, 0x2, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
|
0x5e, 0xc0, 0x2, 0xe7, 0x4, 0x73, 0x2, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||||
@@ -148,7 +148,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut matrix = AnimeImage::new(
|
let mut matrix = AnimeImage::new(
|
||||||
@@ -158,7 +158,7 @@ mod tests {
|
|||||||
0.0,
|
0.0,
|
||||||
vec![Pixel::default(); 1000],
|
vec![Pixel::default(); 1000],
|
||||||
100,
|
100,
|
||||||
AnimeType::GA402
|
AnimeType::GA402,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
matrix.edge_outline();
|
matrix.edge_outline();
|
||||||
@@ -218,7 +218,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
let pkt1_check = [
|
let pkt1_check = [
|
||||||
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
|
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||||
@@ -266,7 +266,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
let pkt2_check = [
|
let pkt2_check = [
|
||||||
0x5e, 0xc0, 0x02, 0xe7, 0x04, 0x73, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
0x5e, 0xc0, 0x02, 0xe7, 0x04, 0x73, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||||
@@ -314,7 +314,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
@@ -378,7 +378,7 @@ mod tests {
|
|||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
let pkt1_check = [
|
let pkt1_check = [
|
||||||
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
@@ -426,7 +426,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
let pkt2_check = [
|
let pkt2_check = [
|
||||||
0x5e, 0xc0, 0x02, 0xe7, 0x04, 0x73, 0x02, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
0x5e, 0xc0, 0x02, 0xe7, 0x04, 0x73, 0x02, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||||
@@ -474,7 +474,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
let pkt1_check = [
|
let pkt1_check = [
|
||||||
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
@@ -100,7 +100,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
let pkt2_check = [
|
let pkt2_check = [
|
||||||
0x5e, 0xc0, 0x02, 0xe7, 0x04, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x5e, 0xc0, 0x02, 0xe7, 0x04, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
@@ -148,7 +148,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut matrix = AnimeImage::new(
|
let mut matrix = AnimeImage::new(
|
||||||
@@ -158,7 +158,7 @@ mod tests {
|
|||||||
0.0,
|
0.0,
|
||||||
vec![Pixel::default(); 1000],
|
vec![Pixel::default(); 1000],
|
||||||
100,
|
100,
|
||||||
AnimeType::GU604
|
AnimeType::GU604,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
matrix.edge_outline();
|
matrix.edge_outline();
|
||||||
@@ -218,7 +218,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
let pkt1_check = [
|
let pkt1_check = [
|
||||||
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
@@ -266,7 +266,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
let pkt2_check = [
|
let pkt2_check = [
|
||||||
0x5e, 0xc0, 0x02, 0xe7, 0x04, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x5e, 0xc0, 0x02, 0xe7, 0x04, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
@@ -314,7 +314,7 @@ mod tests {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
layout_name: "fa506i",
|
layout_name: "fa506i",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
layout_name: "fa506i",
|
layout_name: "fa506i",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle],
|
basic_modes: [Static, Breathe, RainbowCycle],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
layout_name: "fa506i",
|
layout_name: "fa506i",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -32,16 +32,43 @@
|
|||||||
layout_name: "fa507",
|
layout_name: "fa507",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
device_name: "FA617NS",
|
device_name: "FA617NS",
|
||||||
product_id: "",
|
product_id: "",
|
||||||
layout_name: "fa617ns",
|
layout_name: "fa507",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
|
power_zones: [Keyboard],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_name: "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],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -50,7 +77,7 @@
|
|||||||
layout_name: "fx505d",
|
layout_name: "fx505d",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -59,7 +86,7 @@
|
|||||||
layout_name: "fa506i",
|
layout_name: "fa506i",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -68,7 +95,7 @@
|
|||||||
layout_name: "fa506i",
|
layout_name: "fa506i",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -77,7 +104,7 @@
|
|||||||
layout_name: "fa506i",
|
layout_name: "fa506i",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -86,7 +113,25 @@
|
|||||||
layout_name: "fa506i",
|
layout_name: "fa506i",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
|
power_zones: [Keyboard],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_name: "FX607J",
|
||||||
|
product_id: "",
|
||||||
|
layout_name: "fa506i",
|
||||||
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: r#None,
|
||||||
|
power_zones: [Keyboard],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_name: "FX607V",
|
||||||
|
product_id: "",
|
||||||
|
layout_name: "fa506i",
|
||||||
|
basic_modes: [Static, Breathe, RainbowCycle, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: Zoned([SingleZone]),
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -95,7 +140,7 @@
|
|||||||
layout_name: "fa506i",
|
layout_name: "fa506i",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -104,7 +149,16 @@
|
|||||||
layout_name: "fx505d",
|
layout_name: "fx505d",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
|
power_zones: [Keyboard],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_name: "FX706H",
|
||||||
|
product_id: "",
|
||||||
|
layout_name: "fx505d",
|
||||||
|
basic_modes: [Static, Breathe, RainbowCycle],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -113,7 +167,7 @@
|
|||||||
layout_name: "g512",
|
layout_name: "g512",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard, Lightbar],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -131,7 +185,7 @@
|
|||||||
layout_name: "g513i",
|
layout_name: "g513i",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard, Lightbar],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -161,13 +215,22 @@
|
|||||||
advanced_type: Zoned([ZonedKbLeft, ZonedKbLeftMid, ZonedKbRightMid, ZonedKbRight, LightbarRight, LightbarRightCorner, LightbarRightBottom, LightbarLeftBottom, LightbarLeftCorner, LightbarLeft]),
|
advanced_type: Zoned([ZonedKbLeft, ZonedKbLeftMid, ZonedKbRightMid, ZonedKbRight, LightbarRight, LightbarRightCorner, LightbarRightBottom, LightbarLeftBottom, LightbarLeftCorner, LightbarLeft]),
|
||||||
power_zones: [Keyboard, Lightbar],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
device_name: "G513RW",
|
||||||
|
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],
|
||||||
|
),
|
||||||
(
|
(
|
||||||
device_name: "G531G",
|
device_name: "G531G",
|
||||||
product_id: "",
|
product_id: "",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -176,7 +239,7 @@
|
|||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -215,13 +278,31 @@
|
|||||||
advanced_type: PerKey,
|
advanced_type: PerKey,
|
||||||
power_zones: [Keyboard],
|
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",
|
device_name: "G614J",
|
||||||
product_id: "",
|
product_id: "",
|
||||||
layout_name: "g634j-per-key",
|
layout_name: "g634j-per-key",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
|
power_zones: [Keyboard, Lightbar],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
device_name: "G614JIR",
|
||||||
|
product_id: "",
|
||||||
|
layout_name: "g513i-per-key",
|
||||||
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: PerKey,
|
||||||
power_zones: [Keyboard, Lightbar],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -230,16 +311,25 @@
|
|||||||
layout_name: "g634j-per-key",
|
layout_name: "g634j-per-key",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard, Lightbar],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
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",
|
device_name: "G614JZ",
|
||||||
product_id: "",
|
product_id: "",
|
||||||
layout_name: "g634j-per-key",
|
layout_name: "g634j-per-key",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard, Lightbar],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -251,13 +341,22 @@
|
|||||||
advanced_type: PerKey,
|
advanced_type: PerKey,
|
||||||
power_zones: [Keyboard, Lightbar, Logo, RearGlow],
|
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",
|
device_name: "G712LI",
|
||||||
product_id: "",
|
product_id: "",
|
||||||
layout_name: "gl503",
|
layout_name: "gl503",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -266,7 +365,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -275,7 +374,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -284,7 +383,7 @@
|
|||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard, Lightbar],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -293,7 +392,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard, Lightbar],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -302,7 +401,7 @@
|
|||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard, Lightbar],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -311,7 +410,7 @@
|
|||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard, Lightbar],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -347,7 +446,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -365,7 +464,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4, BarLeft, BarRight],
|
basic_zones: [Key1, Key2, Key3, Key4, BarLeft, BarRight],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard, Lightbar],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -383,7 +482,7 @@
|
|||||||
layout_name: "g533q",
|
layout_name: "g533q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -392,7 +491,7 @@
|
|||||||
layout_name: "g533q",
|
layout_name: "g533q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -401,7 +500,7 @@
|
|||||||
layout_name: "g533q",
|
layout_name: "g533q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -449,6 +548,15 @@
|
|||||||
advanced_type: PerKey,
|
advanced_type: PerKey,
|
||||||
power_zones: [Keyboard, Lightbar],
|
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",
|
device_name: "G834J",
|
||||||
product_id: "",
|
product_id: "",
|
||||||
@@ -464,7 +572,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -473,7 +581,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -482,7 +590,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -491,7 +599,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -500,7 +608,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -509,7 +617,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -518,7 +626,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -527,7 +635,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -536,7 +644,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -545,7 +653,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -554,7 +662,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -572,7 +680,7 @@
|
|||||||
layout_name: "gl503",
|
layout_name: "gl503",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -581,7 +689,7 @@
|
|||||||
layout_name: "gl503",
|
layout_name: "gl503",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -590,7 +698,7 @@
|
|||||||
layout_name: "gl503",
|
layout_name: "gl503",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4, Logo, BarLeft, BarRight],
|
basic_zones: [Key1, Key2, Key3, Key4, Logo, BarLeft, BarRight],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -608,7 +716,7 @@
|
|||||||
layout_name: "g533q",
|
layout_name: "g533q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -617,7 +725,7 @@
|
|||||||
layout_name: "gl503",
|
layout_name: "gl503",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -626,7 +734,7 @@
|
|||||||
layout_name: "fa507",
|
layout_name: "fa507",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -674,6 +782,15 @@
|
|||||||
advanced_type: Zoned([SingleZone]),
|
advanced_type: Zoned([SingleZone]),
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
device_name: "GU605C",
|
||||||
|
product_id: "",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: Zoned([SingleZone]),
|
||||||
|
power_zones: [Keyboard],
|
||||||
|
),
|
||||||
(
|
(
|
||||||
device_name: "GU605M",
|
device_name: "GU605M",
|
||||||
product_id: "",
|
product_id: "",
|
||||||
@@ -689,7 +806,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -698,7 +815,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -707,7 +824,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -716,7 +833,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -734,7 +851,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -752,7 +869,7 @@
|
|||||||
layout_name: "gx531-per-key",
|
layout_name: "gx531-per-key",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -806,7 +923,7 @@
|
|||||||
layout_name: "gx531-per-key",
|
layout_name: "gx531-per-key",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -815,7 +932,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -824,7 +941,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -833,8 +950,8 @@
|
|||||||
layout_name: "",
|
layout_name: "",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [None],
|
power_zones: [r#None],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
device_name: "GZ301Z",
|
device_name: "GZ301Z",
|
||||||
@@ -842,7 +959,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -851,7 +968,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Ally],
|
power_zones: [Ally],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@@ -860,7 +977,7 @@
|
|||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: r#None,
|
||||||
power_zones: [Ally],
|
power_zones: [Ally],
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
|
|||||||
375
rog-aura/data/layouts/g635l-per-key_US.ron
Normal file
375
rog-aura/data/layouts/g635l-per-key_US.ron
Normal 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"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -54,7 +54,7 @@ pub struct LedSupportData {
|
|||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub advanced_type: AdvancedAuraType,
|
pub advanced_type: AdvancedAuraType,
|
||||||
/// If empty will default to `Keyboard` power zone
|
/// If empty will default to `Keyboard` power zone
|
||||||
pub power_zones: Vec<PowerZones>
|
pub power_zones: Vec<PowerZones>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LedSupportData {
|
impl LedSupportData {
|
||||||
@@ -116,7 +116,7 @@ impl LedSupportFile {
|
|||||||
basic_modes: vec![AuraModeNum::Static],
|
basic_modes: vec![AuraModeNum::Static],
|
||||||
basic_zones: vec![],
|
basic_zones: vec![],
|
||||||
advanced_type: AdvancedAuraType::None,
|
advanced_type: AdvancedAuraType::None,
|
||||||
power_zones: vec![PowerZones::Keyboard]
|
power_zones: vec![PowerZones::Keyboard],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,6 +164,25 @@ impl LedSupportFile {
|
|||||||
return Some(data);
|
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);
|
warn!("Does {} exist?", ASUS_LED_MODE_USER_CONF);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -200,7 +219,7 @@ mod tests {
|
|||||||
power_zones: vec![
|
power_zones: vec![
|
||||||
PowerZones::Keyboard,
|
PowerZones::Keyboard,
|
||||||
PowerZones::RearGlow,
|
PowerZones::RearGlow,
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(ron::to_string(&led).is_ok());
|
assert!(ron::to_string(&led).is_ok());
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pub enum LedBrightness {
|
|||||||
Low = 1,
|
Low = 1,
|
||||||
#[default]
|
#[default]
|
||||||
Med = 2,
|
Med = 2,
|
||||||
High = 3
|
High = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LedBrightness {
|
impl LedBrightness {
|
||||||
@@ -28,7 +28,7 @@ impl LedBrightness {
|
|||||||
Self::Off => Self::Low,
|
Self::Off => Self::Low,
|
||||||
Self::Low => Self::Med,
|
Self::Low => Self::Med,
|
||||||
Self::Med => Self::High,
|
Self::Med => Self::High,
|
||||||
Self::High => Self::Off
|
Self::High => Self::Off,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ impl LedBrightness {
|
|||||||
Self::Off => Self::High,
|
Self::Off => Self::High,
|
||||||
Self::Low => Self::Off,
|
Self::Low => Self::Off,
|
||||||
Self::Med => Self::Low,
|
Self::Med => Self::Low,
|
||||||
Self::High => Self::Med
|
Self::High => Self::Med,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ impl From<u8> for LedBrightness {
|
|||||||
0 => LedBrightness::Off,
|
0 => LedBrightness::Off,
|
||||||
1 => LedBrightness::Low,
|
1 => LedBrightness::Low,
|
||||||
3 => LedBrightness::High,
|
3 => LedBrightness::High,
|
||||||
_ => LedBrightness::Med
|
_ => LedBrightness::Med,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ impl From<i32> for LedBrightness {
|
|||||||
1 => LedBrightness::Low,
|
1 => LedBrightness::Low,
|
||||||
2 => LedBrightness::Med,
|
2 => LedBrightness::Med,
|
||||||
3 => LedBrightness::High,
|
3 => LedBrightness::High,
|
||||||
_ => LedBrightness::Med
|
_ => LedBrightness::Med,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ impl From<i32> for LedBrightness {
|
|||||||
pub struct Colour {
|
pub struct Colour {
|
||||||
pub r: u8,
|
pub r: u8,
|
||||||
pub g: u8,
|
pub g: u8,
|
||||||
pub b: u8
|
pub b: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Colour {
|
impl Default for Colour {
|
||||||
@@ -110,7 +110,7 @@ impl From<&[f32; 3]> for Colour {
|
|||||||
Self {
|
Self {
|
||||||
r: (255.0 * c[0]) as u8,
|
r: (255.0 * c[0]) as u8,
|
||||||
g: (255.0 * c[1]) as u8,
|
g: (255.0 * c[1]) as u8,
|
||||||
b: (255.0 * c[2]) as u8
|
b: (255.0 * c[2]) as u8,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ impl From<Colour> for [f32; 3] {
|
|||||||
[
|
[
|
||||||
c.r as f32 / 255.0,
|
c.r as f32 / 255.0,
|
||||||
c.g as f32 / 255.0,
|
c.g as f32 / 255.0,
|
||||||
c.b as f32 / 255.0
|
c.b as f32 / 255.0,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,7 +130,7 @@ impl From<&[u8; 3]> for Colour {
|
|||||||
Self {
|
Self {
|
||||||
r: c[0],
|
r: c[0],
|
||||||
g: c[1],
|
g: c[1],
|
||||||
b: c[2]
|
b: c[2],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,7 @@ impl From<&[u8; 3]> for Colour {
|
|||||||
impl From<Colour> for [u8; 3] {
|
impl From<Colour> for [u8; 3] {
|
||||||
fn from(c: Colour) -> Self {
|
fn from(c: Colour) -> Self {
|
||||||
[
|
[
|
||||||
c.r, c.g, c.b
|
c.r, c.g, c.b,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,7 +153,7 @@ pub enum Speed {
|
|||||||
Low = 0xe1,
|
Low = 0xe1,
|
||||||
#[default]
|
#[default]
|
||||||
Med = 0xeb,
|
Med = 0xeb,
|
||||||
High = 0xf5
|
High = 0xf5,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for Speed {
|
impl FromStr for Speed {
|
||||||
@@ -165,7 +165,7 @@ impl FromStr for Speed {
|
|||||||
"low" => Ok(Speed::Low),
|
"low" => Ok(Speed::Low),
|
||||||
"med" => Ok(Speed::Med),
|
"med" => Ok(Speed::Med),
|
||||||
"high" => Ok(Speed::High),
|
"high" => Ok(Speed::High),
|
||||||
_ => Err(Error::ParseSpeed)
|
_ => Err(Error::ParseSpeed),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,7 +175,7 @@ impl From<i32> for Speed {
|
|||||||
match value {
|
match value {
|
||||||
0 => Self::Low,
|
0 => Self::Low,
|
||||||
2 => Self::High,
|
2 => Self::High,
|
||||||
_ => Self::Med
|
_ => Self::Med,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,7 +185,7 @@ impl From<Speed> for i32 {
|
|||||||
match value {
|
match value {
|
||||||
Speed::Low => 0,
|
Speed::Low => 0,
|
||||||
Speed::Med => 1,
|
Speed::Med => 1,
|
||||||
Speed::High => 2
|
Speed::High => 2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,7 +195,7 @@ impl From<Speed> for u8 {
|
|||||||
match s {
|
match s {
|
||||||
Speed::Low => 0,
|
Speed::Low => 0,
|
||||||
Speed::Med => 1,
|
Speed::Med => 1,
|
||||||
Speed::High => 2
|
Speed::High => 2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -213,7 +213,7 @@ pub enum Direction {
|
|||||||
Right = 0,
|
Right = 0,
|
||||||
Left = 1,
|
Left = 1,
|
||||||
Up = 2,
|
Up = 2,
|
||||||
Down = 3
|
Down = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for Direction {
|
impl FromStr for Direction {
|
||||||
@@ -226,7 +226,7 @@ impl FromStr for Direction {
|
|||||||
"up" => Ok(Direction::Up),
|
"up" => Ok(Direction::Up),
|
||||||
"down" => Ok(Direction::Down),
|
"down" => Ok(Direction::Down),
|
||||||
"left" => Ok(Direction::Left),
|
"left" => Ok(Direction::Left),
|
||||||
_ => Err(Error::ParseDirection)
|
_ => Err(Error::ParseDirection),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,7 +237,7 @@ impl From<i32> for Direction {
|
|||||||
1 => Self::Left,
|
1 => Self::Left,
|
||||||
2 => Self::Up,
|
2 => Self::Up,
|
||||||
3 => Self::Down,
|
3 => Self::Down,
|
||||||
_ => Self::Right
|
_ => Self::Right,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,7 +270,7 @@ pub enum AuraModeNum {
|
|||||||
Ripple = 8,
|
Ripple = 8,
|
||||||
Pulse = 10,
|
Pulse = 10,
|
||||||
Comet = 11,
|
Comet = 11,
|
||||||
Flash = 12
|
Flash = 12,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for AuraModeNum {
|
impl Display for AuraModeNum {
|
||||||
@@ -299,7 +299,7 @@ impl From<&AuraModeNum> for &str {
|
|||||||
AuraModeNum::Ripple => "Ripple",
|
AuraModeNum::Ripple => "Ripple",
|
||||||
AuraModeNum::Pulse => "Pulse",
|
AuraModeNum::Pulse => "Pulse",
|
||||||
AuraModeNum::Comet => "Comet",
|
AuraModeNum::Comet => "Comet",
|
||||||
AuraModeNum::Flash => "Flash"
|
AuraModeNum::Flash => "Flash",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -317,7 +317,7 @@ impl From<&str> for AuraModeNum {
|
|||||||
"Pulse" => AuraModeNum::Pulse,
|
"Pulse" => AuraModeNum::Pulse,
|
||||||
"Comet" => AuraModeNum::Comet,
|
"Comet" => AuraModeNum::Comet,
|
||||||
"Flash" => AuraModeNum::Flash,
|
"Flash" => AuraModeNum::Flash,
|
||||||
_ => AuraModeNum::Static
|
_ => AuraModeNum::Static,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -336,7 +336,7 @@ impl From<u8> for AuraModeNum {
|
|||||||
10 => AuraModeNum::Pulse,
|
10 => AuraModeNum::Pulse,
|
||||||
11 => AuraModeNum::Comet,
|
11 => AuraModeNum::Comet,
|
||||||
12 => AuraModeNum::Flash,
|
12 => AuraModeNum::Flash,
|
||||||
_ => AuraModeNum::Static
|
_ => AuraModeNum::Static,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
/// Base effects have no zoning, while multizone is 1-4
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "dbus",
|
feature = "dbus",
|
||||||
@@ -383,7 +389,7 @@ pub enum AuraZone {
|
|||||||
/// The left part of a lightbar (typically on the front of laptop)
|
/// The left part of a lightbar (typically on the front of laptop)
|
||||||
BarLeft = 6,
|
BarLeft = 6,
|
||||||
/// The right part of a lightbar
|
/// The right part of a lightbar
|
||||||
BarRight = 7
|
BarRight = 7,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for AuraZone {
|
impl FromStr for AuraZone {
|
||||||
@@ -400,7 +406,7 @@ impl FromStr for AuraZone {
|
|||||||
"5" | "logo" => Ok(AuraZone::Logo),
|
"5" | "logo" => Ok(AuraZone::Logo),
|
||||||
"6" | "lightbar-left" => Ok(AuraZone::BarLeft),
|
"6" | "lightbar-left" => Ok(AuraZone::BarLeft),
|
||||||
"7" | "lightbar-right" => Ok(AuraZone::BarRight),
|
"7" | "lightbar-right" => Ok(AuraZone::BarRight),
|
||||||
_ => Err(Error::ParseSpeed)
|
_ => Err(Error::ParseSpeed),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -415,7 +421,7 @@ impl From<i32> for AuraZone {
|
|||||||
5 => Self::Logo,
|
5 => Self::Logo,
|
||||||
6 => Self::BarLeft,
|
6 => Self::BarLeft,
|
||||||
7 => Self::BarRight,
|
7 => Self::BarRight,
|
||||||
_ => Self::default()
|
_ => Self::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -445,7 +451,7 @@ pub struct AuraEffect {
|
|||||||
/// One of three speeds for modes that support speed (most that animate)
|
/// One of three speeds for modes that support speed (most that animate)
|
||||||
pub speed: Speed,
|
pub speed: Speed,
|
||||||
/// Up, down, left, right. Only Rainbow mode seems to use this
|
/// Up, down, left, right. Only Rainbow mode seems to use this
|
||||||
pub direction: Direction
|
pub direction: Direction,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AuraEffect {
|
impl AuraEffect {
|
||||||
@@ -481,7 +487,7 @@ impl Default for AuraEffect {
|
|||||||
colour1: Colour { r: 166, g: 0, b: 0 },
|
colour1: Colour { r: 166, g: 0, b: 0 },
|
||||||
colour2: Colour { r: 0, g: 0, b: 0 },
|
colour2: Colour { r: 0, g: 0, b: 0 },
|
||||||
speed: Speed::Med,
|
speed: Speed::Med,
|
||||||
direction: Direction::Right
|
direction: Direction::Right,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -541,7 +547,7 @@ impl From<&AuraEffect> for Vec<u8> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
AuraEffect, AuraModeNum, AuraZone, Colour, Direction, Speed, AURA_LAPTOP_LED_MSG_LEN
|
AuraEffect, AuraModeNum, AuraZone, Colour, Direction, Speed, AURA_LAPTOP_LED_MSG_LEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -552,18 +558,18 @@ mod tests {
|
|||||||
colour1: Colour {
|
colour1: Colour {
|
||||||
r: 0xff,
|
r: 0xff,
|
||||||
g: 0x11,
|
g: 0x11,
|
||||||
b: 0xdd
|
b: 0xdd,
|
||||||
},
|
},
|
||||||
colour2: Colour::default(),
|
colour2: Colour::default(),
|
||||||
speed: Speed::Med,
|
speed: Speed::Med,
|
||||||
direction: Direction::Right
|
direction: Direction::Right,
|
||||||
};
|
};
|
||||||
let ar = <[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st);
|
let ar = <[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st);
|
||||||
|
|
||||||
println!("{:02x?}", ar);
|
println!("{:02x?}", ar);
|
||||||
let check = [
|
let check = [
|
||||||
0x5d, 0xb3, 0x0, 0x0, 0xff, 0x11, 0xdd, 0xeb, 0x0, 0x0, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x5d, 0xb3, 0x0, 0x0, 0xff, 0x11, 0xdd, 0xeb, 0x0, 0x0, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0
|
0x0,
|
||||||
];
|
];
|
||||||
assert_eq!(ar, check);
|
assert_eq!(ar, check);
|
||||||
}
|
}
|
||||||
@@ -576,15 +582,15 @@ mod tests {
|
|||||||
colour1: Colour {
|
colour1: Colour {
|
||||||
r: 0xff,
|
r: 0xff,
|
||||||
g: 0,
|
g: 0,
|
||||||
b: 0
|
b: 0,
|
||||||
},
|
},
|
||||||
colour2: Colour { r: 0, g: 0, b: 0 },
|
colour2: Colour { r: 0, g: 0, b: 0 },
|
||||||
speed: Speed::Low,
|
speed: Speed::Low,
|
||||||
direction: Direction::Left
|
direction: Direction::Left,
|
||||||
};
|
};
|
||||||
let capture = [
|
let capture = [
|
||||||
0x5d, 0xb3, 0x01, 0x00, 0xff, 0x00, 0x00, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x5d, 0xb3, 0x01, 0x00, 0xff, 0x00, 0x00, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0
|
0x0, 0x0,
|
||||||
];
|
];
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
||||||
@@ -595,11 +601,11 @@ mod tests {
|
|||||||
st.colour1 = Colour {
|
st.colour1 = Colour {
|
||||||
r: 0xff,
|
r: 0xff,
|
||||||
g: 0xff,
|
g: 0xff,
|
||||||
b: 0
|
b: 0,
|
||||||
};
|
};
|
||||||
let capture = [
|
let capture = [
|
||||||
0x5d, 0xb3, 0x02, 0x00, 0xff, 0xff, 0x00, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x5d, 0xb3, 0x02, 0x00, 0xff, 0xff, 0x00, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0
|
0x0, 0x0,
|
||||||
];
|
];
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
||||||
@@ -610,11 +616,11 @@ mod tests {
|
|||||||
st.colour1 = Colour {
|
st.colour1 = Colour {
|
||||||
r: 0,
|
r: 0,
|
||||||
g: 0xff,
|
g: 0xff,
|
||||||
b: 0xff
|
b: 0xff,
|
||||||
};
|
};
|
||||||
let capture = [
|
let capture = [
|
||||||
0x5d, 0xb3, 0x03, 0x00, 0x00, 0xff, 0xff, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x5d, 0xb3, 0x03, 0x00, 0x00, 0xff, 0xff, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0
|
0x0, 0x0,
|
||||||
];
|
];
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
||||||
@@ -625,11 +631,11 @@ mod tests {
|
|||||||
st.colour1 = Colour {
|
st.colour1 = Colour {
|
||||||
r: 0xff,
|
r: 0xff,
|
||||||
g: 0x00,
|
g: 0x00,
|
||||||
b: 0xff
|
b: 0xff,
|
||||||
};
|
};
|
||||||
let capture = [
|
let capture = [
|
||||||
0x5d, 0xb3, 0x04, 0x00, 0xff, 0x00, 0xff, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x5d, 0xb3, 0x04, 0x00, 0xff, 0x00, 0xff, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0
|
0x0, 0x0,
|
||||||
];
|
];
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
||||||
@@ -640,11 +646,11 @@ mod tests {
|
|||||||
st.colour1 = Colour {
|
st.colour1 = Colour {
|
||||||
r: 0x2c,
|
r: 0x2c,
|
||||||
g: 0xff,
|
g: 0xff,
|
||||||
b: 0x00
|
b: 0x00,
|
||||||
};
|
};
|
||||||
let capture = [
|
let capture = [
|
||||||
0x5d, 0xb3, 0x05, 0x00, 0x2c, 0xff, 0x00, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x5d, 0xb3, 0x05, 0x00, 0x2c, 0xff, 0x00, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0
|
0x0, 0x0,
|
||||||
];
|
];
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
||||||
@@ -655,11 +661,11 @@ mod tests {
|
|||||||
st.colour1 = Colour {
|
st.colour1 = Colour {
|
||||||
r: 0xff,
|
r: 0xff,
|
||||||
g: 0x00,
|
g: 0x00,
|
||||||
b: 0x00
|
b: 0x00,
|
||||||
};
|
};
|
||||||
let capture = [
|
let capture = [
|
||||||
0x5d, 0xb3, 0x06, 0x00, 0xff, 0x00, 0x00, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x5d, 0xb3, 0x06, 0x00, 0xff, 0x00, 0x00, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0
|
0x0, 0x0,
|
||||||
];
|
];
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
||||||
@@ -670,11 +676,11 @@ mod tests {
|
|||||||
st.colour1 = Colour {
|
st.colour1 = Colour {
|
||||||
r: 0xff,
|
r: 0xff,
|
||||||
g: 0x00,
|
g: 0x00,
|
||||||
b: 0xcd
|
b: 0xcd,
|
||||||
};
|
};
|
||||||
let capture = [
|
let capture = [
|
||||||
0x5d, 0xb3, 0x07, 0x00, 0xff, 0x00, 0xcd, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x5d, 0xb3, 0x07, 0x00, 0xff, 0x00, 0xcd, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0
|
0x0, 0x0,
|
||||||
];
|
];
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
||||||
@@ -684,7 +690,7 @@ mod tests {
|
|||||||
st.mode = AuraModeNum::RainbowWave;
|
st.mode = AuraModeNum::RainbowWave;
|
||||||
let capture = [
|
let capture = [
|
||||||
0x5d, 0xb3, 0x07, 0x03, 0xff, 0x00, 0xcd, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x5d, 0xb3, 0x07, 0x03, 0xff, 0x00, 0xcd, 0xe1, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0
|
0x0, 0x0,
|
||||||
];
|
];
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
<[u8; AURA_LAPTOP_LED_MSG_LEN]>::from(&st)[..9],
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ pub struct InputBased {
|
|||||||
/// - temperature
|
/// - temperature
|
||||||
/// - fan speed
|
/// - fan speed
|
||||||
/// - time
|
/// - time
|
||||||
input: Box<dyn InputForEffect>
|
input: Box<dyn InputForEffect>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EffectState for InputBased {
|
impl EffectState for InputBased {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pub struct Breathe {
|
|||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
count_flipped: bool,
|
count_flipped: bool,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
use_colour1: bool
|
use_colour1: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Breathe {
|
impl Breathe {
|
||||||
@@ -31,7 +31,7 @@ impl Breathe {
|
|||||||
speed,
|
speed,
|
||||||
colour: colour1,
|
colour: colour1,
|
||||||
count_flipped: false,
|
count_flipped: false,
|
||||||
use_colour1: true
|
use_colour1: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ pub struct DoomFlicker {
|
|||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
count: u8,
|
count: u8,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
colour: Colour
|
colour: Colour,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DoomFlicker {
|
impl DoomFlicker {
|
||||||
@@ -24,7 +24,7 @@ impl DoomFlicker {
|
|||||||
count: 4,
|
count: 4,
|
||||||
max_percentage,
|
max_percentage,
|
||||||
min_percentage,
|
min_percentage,
|
||||||
start_colour: colour
|
start_colour: colour,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,13 +53,13 @@ impl EffectState for DoomFlicker {
|
|||||||
let max_light = Colour {
|
let max_light = Colour {
|
||||||
r: (start_colour.r as f32 / 100.0 * *max_percentage as f32) as u8,
|
r: (start_colour.r as f32 / 100.0 * *max_percentage as f32) as u8,
|
||||||
g: (start_colour.g as f32 / 100.0 * *max_percentage as f32) as u8,
|
g: (start_colour.g as f32 / 100.0 * *max_percentage as f32) as u8,
|
||||||
b: (start_colour.b as f32 / 100.0 * *max_percentage as f32) as u8
|
b: (start_colour.b as f32 / 100.0 * *max_percentage as f32) as u8,
|
||||||
};
|
};
|
||||||
// min light is a percentage of the set colour
|
// min light is a percentage of the set colour
|
||||||
let min_light = Colour {
|
let min_light = Colour {
|
||||||
r: (start_colour.r as f32 / 100.0 * *min_percentage as f32) as u8,
|
r: (start_colour.r as f32 / 100.0 * *min_percentage as f32) as u8,
|
||||||
g: (start_colour.g as f32 / 100.0 * *min_percentage as f32) as u8,
|
g: (start_colour.g as f32 / 100.0 * *min_percentage as f32) as u8,
|
||||||
b: (start_colour.b as f32 / 100.0 * *min_percentage as f32) as u8
|
b: (start_colour.b as f32 / 100.0 * *min_percentage as f32) as u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Convert the 255 to percentage
|
// Convert the 255 to percentage
|
||||||
@@ -96,7 +96,7 @@ pub struct DoomLightFlash {
|
|||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
count: u8,
|
count: u8,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
colour: Colour
|
colour: Colour,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DoomLightFlash {
|
impl DoomLightFlash {
|
||||||
@@ -109,7 +109,7 @@ impl DoomLightFlash {
|
|||||||
min_percentage,
|
min_percentage,
|
||||||
start_colour: colour,
|
start_colour: colour,
|
||||||
max_time: 32,
|
max_time: 32,
|
||||||
min_time: 7
|
min_time: 7,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,13 +135,13 @@ impl EffectState for DoomLightFlash {
|
|||||||
let max_light = Colour {
|
let max_light = Colour {
|
||||||
r: (start_colour.r as f32 / 100.0 * *max_percentage as f32) as u8,
|
r: (start_colour.r as f32 / 100.0 * *max_percentage as f32) as u8,
|
||||||
g: (start_colour.g as f32 / 100.0 * *max_percentage as f32) as u8,
|
g: (start_colour.g as f32 / 100.0 * *max_percentage as f32) as u8,
|
||||||
b: (start_colour.b as f32 / 100.0 * *max_percentage as f32) as u8
|
b: (start_colour.b as f32 / 100.0 * *max_percentage as f32) as u8,
|
||||||
};
|
};
|
||||||
// min light is a percentage of the set colour
|
// min light is a percentage of the set colour
|
||||||
let min_light = Colour {
|
let min_light = Colour {
|
||||||
r: (start_colour.r as f32 / 100.0 * *min_percentage as f32) as u8,
|
r: (start_colour.r as f32 / 100.0 * *min_percentage as f32) as u8,
|
||||||
g: (start_colour.g as f32 / 100.0 * *min_percentage as f32) as u8,
|
g: (start_colour.g as f32 / 100.0 * *min_percentage as f32) as u8,
|
||||||
b: (start_colour.b as f32 / 100.0 * *min_percentage as f32) as u8
|
b: (start_colour.b as f32 / 100.0 * *min_percentage as f32) as u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
if *colour == max_light {
|
if *colour == max_light {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ pub const RNDTABLE: [i32; 256] = [
|
|||||||
206, 163, 45, 63, 90, 168, 114, 59, 33, 159, 95, 28, 139, 123, 98, 125, 196, 15, 70, 194, 253,
|
206, 163, 45, 63, 90, 168, 114, 59, 33, 159, 95, 28, 139, 123, 98, 125, 196, 15, 70, 194, 253,
|
||||||
54, 14, 109, 226, 71, 17, 161, 93, 186, 87, 244, 138, 20, 52, 123, 251, 26, 36, 17, 46, 52,
|
54, 14, 109, 226, 71, 17, 161, 93, 186, 87, 244, 138, 20, 52, 123, 251, 26, 36, 17, 46, 52,
|
||||||
231, 232, 76, 31, 221, 84, 37, 216, 165, 212, 106, 197, 242, 98, 43, 39, 175, 254, 145, 190,
|
231, 232, 76, 31, 221, 84, 37, 216, 165, 212, 106, 197, 242, 98, 43, 39, 175, 254, 145, 190,
|
||||||
84, 118, 222, 187, 136, 120, 163, 236, 249
|
84, 118, 222, 187, 136, 120, 163, 236, 249,
|
||||||
];
|
];
|
||||||
|
|
||||||
pub fn p_random() -> i32 {
|
pub fn p_random() -> i32 {
|
||||||
@@ -67,7 +67,7 @@ pub(crate) trait EffectState {
|
|||||||
#[derive(Debug, Deserialize, Serialize, Default)]
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
pub struct AdvancedEffects {
|
pub struct AdvancedEffects {
|
||||||
effects: Vec<Effect>,
|
effects: Vec<Effect>,
|
||||||
zoned: bool
|
zoned: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AdvancedEffects {
|
impl AdvancedEffects {
|
||||||
@@ -75,7 +75,7 @@ impl AdvancedEffects {
|
|||||||
pub fn new(zoned: bool) -> Self {
|
pub fn new(zoned: bool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
effects: Default::default(),
|
effects: Default::default(),
|
||||||
zoned
|
zoned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ pub enum Effect {
|
|||||||
Static(Static),
|
Static(Static),
|
||||||
Breathe(Breathe),
|
Breathe(Breathe),
|
||||||
DoomFlicker(DoomFlicker),
|
DoomFlicker(DoomFlicker),
|
||||||
DoomLightFlash(DoomLightFlash)
|
DoomLightFlash(DoomLightFlash),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Effect {
|
impl Default for Effect {
|
||||||
@@ -207,12 +207,14 @@ mod tests {
|
|||||||
fn single_key_next_state_then_create() {
|
fn single_key_next_state_then_create() {
|
||||||
let layout = KeyLayout::default_layout();
|
let layout = KeyLayout::default_layout();
|
||||||
let mut seq = AdvancedEffects::new(false);
|
let mut seq = AdvancedEffects::new(false);
|
||||||
seq.effects
|
seq.effects.push(Effect::Static(Static::new(
|
||||||
.push(Effect::Static(Static::new(LedCode::F, Colour {
|
LedCode::F,
|
||||||
|
Colour {
|
||||||
r: 255,
|
r: 255,
|
||||||
g: 127,
|
g: 127,
|
||||||
b: 0
|
b: 0,
|
||||||
})));
|
},
|
||||||
|
)));
|
||||||
|
|
||||||
seq.next_state(&layout);
|
seq.next_state(&layout);
|
||||||
let packets = seq.create_packets();
|
let packets = seq.create_packets();
|
||||||
@@ -232,14 +234,14 @@ mod tests {
|
|||||||
Colour {
|
Colour {
|
||||||
r: 255,
|
r: 255,
|
||||||
g: 127,
|
g: 127,
|
||||||
b: 0
|
b: 0,
|
||||||
},
|
},
|
||||||
Colour {
|
Colour {
|
||||||
r: 127,
|
r: 127,
|
||||||
g: 0,
|
g: 0,
|
||||||
b: 255
|
b: 255,
|
||||||
},
|
},
|
||||||
Speed::Med
|
Speed::Med,
|
||||||
)));
|
)));
|
||||||
|
|
||||||
let s =
|
let s =
|
||||||
@@ -274,10 +276,10 @@ mod tests {
|
|||||||
Colour {
|
Colour {
|
||||||
r: 255,
|
r: 255,
|
||||||
g: 127,
|
g: 127,
|
||||||
b: 80
|
b: 80,
|
||||||
},
|
},
|
||||||
100,
|
100,
|
||||||
10
|
10,
|
||||||
)));
|
)));
|
||||||
|
|
||||||
seq.next_state(&layout);
|
seq.next_state(&layout);
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ use crate::{effect_state_impl, Colour};
|
|||||||
pub struct Static {
|
pub struct Static {
|
||||||
led: LedCode,
|
led: LedCode,
|
||||||
/// The starting colour
|
/// The starting colour
|
||||||
colour: Colour
|
colour: Colour,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Static {
|
impl Static {
|
||||||
pub fn new(address: LedCode, colour: Colour) -> Self {
|
pub fn new(address: LedCode, colour: Colour) -> Self {
|
||||||
Self {
|
Self {
|
||||||
led: address,
|
led: address,
|
||||||
colour
|
colour,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ pub enum Error {
|
|||||||
ParseBrightness,
|
ParseBrightness,
|
||||||
IoPath(String, std::io::Error),
|
IoPath(String, std::io::Error),
|
||||||
Ron(ron::Error),
|
Ron(ron::Error),
|
||||||
RonParse(ron::error::SpannedError)
|
RonParse(ron::error::SpannedError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
@@ -21,7 +21,7 @@ impl fmt::Display for Error {
|
|||||||
Error::ParseBrightness => write!(f, "Could not parse brightness"),
|
Error::ParseBrightness => write!(f, "Could not parse brightness"),
|
||||||
Error::IoPath(path, io) => write!(f, "IO Error: {path}, {io}"),
|
Error::IoPath(path, io) => write!(f, "IO Error: {path}, {io}"),
|
||||||
Error::Ron(e) => write!(f, "RON Parse Error: {e}"),
|
Error::Ron(e) => write!(f, "RON Parse Error: {e}"),
|
||||||
Error::RonParse(e) => write!(f, "RON Parse Error: {e}")
|
Error::RonParse(e) => write!(f, "RON Parse Error: {e}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ pub enum LedCode {
|
|||||||
/// To be ignored by effects
|
/// To be ignored by effects
|
||||||
Spacing,
|
Spacing,
|
||||||
/// To be ignored by effects
|
/// To be ignored by effects
|
||||||
Blocking
|
Blocking,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LedCode {
|
impl LedCode {
|
||||||
@@ -210,7 +210,7 @@ pub struct LedUsbPackets {
|
|||||||
/// Wether or not this packet collection is zoned. The determines which
|
/// Wether or not this packet collection is zoned. The determines which
|
||||||
/// starting bytes are used and what the indexing is for lightbar RGB
|
/// starting bytes are used and what the indexing is for lightbar RGB
|
||||||
/// colours
|
/// colours
|
||||||
zoned: bool
|
zoned: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for LedUsbPackets {
|
impl Default for LedUsbPackets {
|
||||||
@@ -244,7 +244,7 @@ impl LedUsbPackets {
|
|||||||
}
|
}
|
||||||
Self {
|
Self {
|
||||||
usb_packets: set,
|
usb_packets: set,
|
||||||
zoned: false
|
zoned: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,7 +274,7 @@ impl LedUsbPackets {
|
|||||||
}
|
}
|
||||||
Self {
|
Self {
|
||||||
usb_packets: vec![pkt],
|
usb_packets: vec![pkt],
|
||||||
zoned: true
|
zoned: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -633,7 +633,7 @@ impl From<&LedCode> for &str {
|
|||||||
LedCode::ZonedKbLeft => "Left Zone (zone 1)",
|
LedCode::ZonedKbLeft => "Left Zone (zone 1)",
|
||||||
LedCode::ZonedKbLeftMid => "Center-left Zone (zone 2)",
|
LedCode::ZonedKbLeftMid => "Center-left Zone (zone 2)",
|
||||||
LedCode::ZonedKbRightMid => "Center-right Zone (zone 3)",
|
LedCode::ZonedKbRightMid => "Center-right Zone (zone 3)",
|
||||||
LedCode::ZonedKbRight => "Right Zone (zone 4)"
|
LedCode::ZonedKbRight => "Right Zone (zone 4)",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ pub enum KeyShape {
|
|||||||
pad_left: f32,
|
pad_left: f32,
|
||||||
pad_right: f32,
|
pad_right: f32,
|
||||||
pad_top: f32,
|
pad_top: f32,
|
||||||
pad_bottom: f32
|
pad_bottom: f32,
|
||||||
},
|
},
|
||||||
Blank {
|
Blank {
|
||||||
width: f32,
|
width: f32,
|
||||||
height: f32
|
height: f32,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyShape {
|
impl KeyShape {
|
||||||
@@ -41,7 +41,7 @@ impl KeyShape {
|
|||||||
pad_left: f32,
|
pad_left: f32,
|
||||||
pad_right: f32,
|
pad_right: f32,
|
||||||
pad_top: f32,
|
pad_top: f32,
|
||||||
pad_bottom: f32
|
pad_bottom: f32,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::Led {
|
Self::Led {
|
||||||
width,
|
width,
|
||||||
@@ -49,7 +49,7 @@ impl KeyShape {
|
|||||||
pad_left,
|
pad_left,
|
||||||
pad_right,
|
pad_right,
|
||||||
pad_top,
|
pad_top,
|
||||||
pad_bottom
|
pad_bottom,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ impl KeyShape {
|
|||||||
pad_left,
|
pad_left,
|
||||||
pad_right,
|
pad_right,
|
||||||
pad_top,
|
pad_top,
|
||||||
pad_bottom
|
pad_bottom,
|
||||||
} => {
|
} => {
|
||||||
*width *= scale;
|
*width *= scale;
|
||||||
*height *= scale;
|
*height *= scale;
|
||||||
@@ -97,7 +97,7 @@ pub struct KeyRow {
|
|||||||
row: Vec<(LedCode, String)>,
|
row: Vec<(LedCode, String)>,
|
||||||
/// The final data structure merged key_shapes and rows
|
/// The final data structure merged key_shapes and rows
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
built_row: Vec<(LedCode, KeyShape)>
|
built_row: Vec<(LedCode, KeyShape)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyRow {
|
impl KeyRow {
|
||||||
@@ -106,7 +106,7 @@ impl KeyRow {
|
|||||||
pad_left,
|
pad_left,
|
||||||
pad_top,
|
pad_top,
|
||||||
row,
|
row,
|
||||||
built_row: Default::default()
|
built_row: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ impl KeyRow {
|
|||||||
pad_bottom,
|
pad_bottom,
|
||||||
..
|
..
|
||||||
} => height + pad_top + pad_bottom,
|
} => height + pad_top + pad_bottom,
|
||||||
KeyShape::Blank { height, .. } => *height
|
KeyShape::Blank { height, .. } => *height,
|
||||||
};
|
};
|
||||||
|
|
||||||
if h < height {
|
if h < height {
|
||||||
@@ -156,7 +156,7 @@ impl KeyRow {
|
|||||||
pad_right,
|
pad_right,
|
||||||
..
|
..
|
||||||
} => w += width + pad_left + pad_right,
|
} => w += width + pad_left + pad_right,
|
||||||
KeyShape::Blank { width, .. } => w += width
|
KeyShape::Blank { width, .. } => w += width,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w
|
w
|
||||||
@@ -185,7 +185,7 @@ pub struct KeyLayout {
|
|||||||
/// Should be copied from the `LaptopLedData` as laptops may have the same
|
/// Should be copied from the `LaptopLedData` as laptops may have the same
|
||||||
/// layout, but different EC features.
|
/// layout, but different EC features.
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
advanced_type: AdvancedAuraType
|
advanced_type: AdvancedAuraType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyLayout {
|
impl KeyLayout {
|
||||||
@@ -195,7 +195,7 @@ impl KeyLayout {
|
|||||||
if buf.is_empty() {
|
if buf.is_empty() {
|
||||||
Err(Error::IoPath(
|
Err(Error::IoPath(
|
||||||
path.to_string_lossy().to_string(),
|
path.to_string_lossy().to_string(),
|
||||||
std::io::ErrorKind::InvalidData.into()
|
std::io::ErrorKind::InvalidData.into(),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
let mut data = ron::from_str::<Self>(&buf)?;
|
let mut data = ron::from_str::<Self>(&buf)?;
|
||||||
@@ -332,97 +332,121 @@ impl KeyLayout {
|
|||||||
advanced_type: AdvancedAuraType::None,
|
advanced_type: AdvancedAuraType::None,
|
||||||
key_shapes: HashMap::from([(
|
key_shapes: HashMap::from([(
|
||||||
"regular".to_owned(),
|
"regular".to_owned(),
|
||||||
KeyShape::new_led(1.0, 1.0, 0.1, 0.1, 0.1, 0.1)
|
KeyShape::new_led(1.0, 1.0, 0.1, 0.1, 0.1, 0.1),
|
||||||
)]),
|
)]),
|
||||||
key_rows: vec![
|
key_rows: vec![
|
||||||
KeyRow::new(0.1, 0.1, vec![
|
KeyRow::new(
|
||||||
(LedCode::Esc, "regular".to_owned()),
|
0.1,
|
||||||
(LedCode::F1, "regular".to_owned()),
|
0.1,
|
||||||
(LedCode::F2, "regular".to_owned()),
|
vec![
|
||||||
(LedCode::F3, "regular".to_owned()),
|
(LedCode::Esc, "regular".to_owned()),
|
||||||
(LedCode::F4, "regular".to_owned()),
|
(LedCode::F1, "regular".to_owned()),
|
||||||
// not sure which key to put here
|
(LedCode::F2, "regular".to_owned()),
|
||||||
(LedCode::F5, "regular".to_owned()),
|
(LedCode::F3, "regular".to_owned()),
|
||||||
(LedCode::F6, "regular".to_owned()),
|
(LedCode::F4, "regular".to_owned()),
|
||||||
(LedCode::F7, "regular".to_owned()),
|
// not sure which key to put here
|
||||||
(LedCode::F8, "regular".to_owned()),
|
(LedCode::F5, "regular".to_owned()),
|
||||||
(LedCode::F9, "regular".to_owned()),
|
(LedCode::F6, "regular".to_owned()),
|
||||||
(LedCode::F10, "regular".to_owned()),
|
(LedCode::F7, "regular".to_owned()),
|
||||||
(LedCode::F11, "regular".to_owned()),
|
(LedCode::F8, "regular".to_owned()),
|
||||||
(LedCode::F12, "regular".to_owned()),
|
(LedCode::F9, "regular".to_owned()),
|
||||||
]),
|
(LedCode::F10, "regular".to_owned()),
|
||||||
KeyRow::new(0.1, 0.1, vec![
|
(LedCode::F11, "regular".to_owned()),
|
||||||
(LedCode::Tilde, "regular".to_owned()),
|
(LedCode::F12, "regular".to_owned()),
|
||||||
(LedCode::N1, "regular".to_owned()),
|
],
|
||||||
(LedCode::N2, "regular".to_owned()),
|
),
|
||||||
(LedCode::N3, "regular".to_owned()),
|
KeyRow::new(
|
||||||
(LedCode::N4, "regular".to_owned()),
|
0.1,
|
||||||
(LedCode::N5, "regular".to_owned()),
|
0.1,
|
||||||
(LedCode::N6, "regular".to_owned()),
|
vec![
|
||||||
(LedCode::N7, "regular".to_owned()),
|
(LedCode::Tilde, "regular".to_owned()),
|
||||||
(LedCode::N8, "regular".to_owned()),
|
(LedCode::N1, "regular".to_owned()),
|
||||||
(LedCode::N9, "regular".to_owned()),
|
(LedCode::N2, "regular".to_owned()),
|
||||||
(LedCode::N0, "regular".to_owned()),
|
(LedCode::N3, "regular".to_owned()),
|
||||||
(LedCode::Hyphen, "regular".to_owned()),
|
(LedCode::N4, "regular".to_owned()),
|
||||||
(LedCode::Equals, "regular".to_owned()),
|
(LedCode::N5, "regular".to_owned()),
|
||||||
(LedCode::Backspace, "regular".to_owned()),
|
(LedCode::N6, "regular".to_owned()),
|
||||||
]),
|
(LedCode::N7, "regular".to_owned()),
|
||||||
KeyRow::new(0.1, 0.1, vec![
|
(LedCode::N8, "regular".to_owned()),
|
||||||
(LedCode::Tab, "regular".to_owned()),
|
(LedCode::N9, "regular".to_owned()),
|
||||||
(LedCode::Q, "regular".to_owned()),
|
(LedCode::N0, "regular".to_owned()),
|
||||||
(LedCode::W, "regular".to_owned()),
|
(LedCode::Hyphen, "regular".to_owned()),
|
||||||
(LedCode::E, "regular".to_owned()),
|
(LedCode::Equals, "regular".to_owned()),
|
||||||
(LedCode::R, "regular".to_owned()),
|
(LedCode::Backspace, "regular".to_owned()),
|
||||||
(LedCode::T, "regular".to_owned()),
|
],
|
||||||
(LedCode::Y, "regular".to_owned()),
|
),
|
||||||
(LedCode::U, "regular".to_owned()),
|
KeyRow::new(
|
||||||
(LedCode::I, "regular".to_owned()),
|
0.1,
|
||||||
(LedCode::O, "regular".to_owned()),
|
0.1,
|
||||||
(LedCode::P, "regular".to_owned()),
|
vec![
|
||||||
(LedCode::LBracket, "regular".to_owned()),
|
(LedCode::Tab, "regular".to_owned()),
|
||||||
(LedCode::RBracket, "regular".to_owned()),
|
(LedCode::Q, "regular".to_owned()),
|
||||||
(LedCode::BackSlash, "regular".to_owned()),
|
(LedCode::W, "regular".to_owned()),
|
||||||
]),
|
(LedCode::E, "regular".to_owned()),
|
||||||
KeyRow::new(0.1, 0.1, vec![
|
(LedCode::R, "regular".to_owned()),
|
||||||
(LedCode::Caps, "regular".to_owned()),
|
(LedCode::T, "regular".to_owned()),
|
||||||
(LedCode::A, "regular".to_owned()),
|
(LedCode::Y, "regular".to_owned()),
|
||||||
(LedCode::S, "regular".to_owned()),
|
(LedCode::U, "regular".to_owned()),
|
||||||
(LedCode::D, "regular".to_owned()),
|
(LedCode::I, "regular".to_owned()),
|
||||||
(LedCode::F, "regular".to_owned()),
|
(LedCode::O, "regular".to_owned()),
|
||||||
(LedCode::G, "regular".to_owned()),
|
(LedCode::P, "regular".to_owned()),
|
||||||
(LedCode::H, "regular".to_owned()),
|
(LedCode::LBracket, "regular".to_owned()),
|
||||||
(LedCode::J, "regular".to_owned()),
|
(LedCode::RBracket, "regular".to_owned()),
|
||||||
(LedCode::K, "regular".to_owned()),
|
(LedCode::BackSlash, "regular".to_owned()),
|
||||||
(LedCode::L, "regular".to_owned()),
|
],
|
||||||
(LedCode::SemiColon, "regular".to_owned()),
|
),
|
||||||
(LedCode::Quote, "regular".to_owned()),
|
KeyRow::new(
|
||||||
(LedCode::Return, "regular".to_owned()),
|
0.1,
|
||||||
]),
|
0.1,
|
||||||
KeyRow::new(0.1, 0.1, vec![
|
vec![
|
||||||
(LedCode::LShift, "regular".to_owned()),
|
(LedCode::Caps, "regular".to_owned()),
|
||||||
(LedCode::Z, "regular".to_owned()),
|
(LedCode::A, "regular".to_owned()),
|
||||||
(LedCode::X, "regular".to_owned()),
|
(LedCode::S, "regular".to_owned()),
|
||||||
(LedCode::C, "regular".to_owned()),
|
(LedCode::D, "regular".to_owned()),
|
||||||
(LedCode::V, "regular".to_owned()),
|
(LedCode::F, "regular".to_owned()),
|
||||||
(LedCode::B, "regular".to_owned()),
|
(LedCode::G, "regular".to_owned()),
|
||||||
(LedCode::N, "regular".to_owned()),
|
(LedCode::H, "regular".to_owned()),
|
||||||
(LedCode::M, "regular".to_owned()),
|
(LedCode::J, "regular".to_owned()),
|
||||||
(LedCode::Comma, "regular".to_owned()),
|
(LedCode::K, "regular".to_owned()),
|
||||||
(LedCode::Period, "regular".to_owned()),
|
(LedCode::L, "regular".to_owned()),
|
||||||
(LedCode::FwdSlash, "regular".to_owned()),
|
(LedCode::SemiColon, "regular".to_owned()),
|
||||||
(LedCode::Rshift, "regular".to_owned()),
|
(LedCode::Quote, "regular".to_owned()),
|
||||||
]),
|
(LedCode::Return, "regular".to_owned()),
|
||||||
KeyRow::new(0.1, 0.1, vec![
|
],
|
||||||
(LedCode::LCtrl, "regular".to_owned()),
|
),
|
||||||
(LedCode::LFn, "regular".to_owned()),
|
KeyRow::new(
|
||||||
(LedCode::Meta, "regular".to_owned()),
|
0.1,
|
||||||
(LedCode::LAlt, "regular".to_owned()),
|
0.1,
|
||||||
(LedCode::Spacebar, "regular".to_owned()),
|
vec![
|
||||||
(LedCode::RAlt, "regular".to_owned()),
|
(LedCode::LShift, "regular".to_owned()),
|
||||||
(LedCode::PrtSc, "regular".to_owned()),
|
(LedCode::Z, "regular".to_owned()),
|
||||||
(LedCode::RCtrl, "regular".to_owned()),
|
(LedCode::X, "regular".to_owned()),
|
||||||
]),
|
(LedCode::C, "regular".to_owned()),
|
||||||
]
|
(LedCode::V, "regular".to_owned()),
|
||||||
|
(LedCode::B, "regular".to_owned()),
|
||||||
|
(LedCode::N, "regular".to_owned()),
|
||||||
|
(LedCode::M, "regular".to_owned()),
|
||||||
|
(LedCode::Comma, "regular".to_owned()),
|
||||||
|
(LedCode::Period, "regular".to_owned()),
|
||||||
|
(LedCode::FwdSlash, "regular".to_owned()),
|
||||||
|
(LedCode::Rshift, "regular".to_owned()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
KeyRow::new(
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
vec![
|
||||||
|
(LedCode::LCtrl, "regular".to_owned()),
|
||||||
|
(LedCode::LFn, "regular".to_owned()),
|
||||||
|
(LedCode::Meta, "regular".to_owned()),
|
||||||
|
(LedCode::LAlt, "regular".to_owned()),
|
||||||
|
(LedCode::Spacebar, "regular".to_owned()),
|
||||||
|
(LedCode::RAlt, "regular".to_owned()),
|
||||||
|
(LedCode::PrtSc, "regular".to_owned()),
|
||||||
|
(LedCode::RCtrl, "regular".to_owned()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,5 +16,5 @@ pub enum AdvancedAuraType {
|
|||||||
#[default]
|
#[default]
|
||||||
None,
|
None,
|
||||||
Zoned(Vec<LedCode>),
|
Zoned(Vec<LedCode>),
|
||||||
PerKey
|
PerKey,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ pub struct AuraPowerState {
|
|||||||
pub awake: bool,
|
pub awake: bool,
|
||||||
pub sleep: bool,
|
pub sleep: bool,
|
||||||
/// Ignored for pre-2021 and Tuf
|
/// Ignored for pre-2021 and Tuf
|
||||||
pub shutdown: bool
|
pub shutdown: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AuraPowerState {
|
impl Default for AuraPowerState {
|
||||||
@@ -34,7 +34,7 @@ impl Default for AuraPowerState {
|
|||||||
boot: true,
|
boot: true,
|
||||||
awake: true,
|
awake: true,
|
||||||
sleep: true,
|
sleep: true,
|
||||||
shutdown: true
|
shutdown: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ impl AuraPowerState {
|
|||||||
boot: true,
|
boot: true,
|
||||||
awake: true,
|
awake: true,
|
||||||
sleep: true,
|
sleep: true,
|
||||||
shutdown: true
|
shutdown: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ impl AuraPowerState {
|
|||||||
| ((self.sleep as u32) << (23 + 3))
|
| ((self.sleep as u32) << (23 + 3))
|
||||||
| ((self.shutdown as u32) << (23 + 4))
|
| ((self.shutdown as u32) << (23 + 4))
|
||||||
}
|
}
|
||||||
PowerZones::None | PowerZones::KeyboardAndLightbar => 0
|
PowerZones::None | PowerZones::KeyboardAndLightbar => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,7 +148,7 @@ impl AuraPowerState {
|
|||||||
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
|
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
|
||||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct LaptopAuraPower {
|
pub struct LaptopAuraPower {
|
||||||
pub states: Vec<AuraPowerState>
|
pub states: Vec<AuraPowerState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LaptopAuraPower {
|
impl LaptopAuraPower {
|
||||||
@@ -206,19 +206,19 @@ impl LaptopAuraPower {
|
|||||||
// 3. KeyboardAndLightbar
|
// 3. KeyboardAndLightbar
|
||||||
if support_data.power_zones.contains(&PowerZones::Lightbar) {
|
if support_data.power_zones.contains(&PowerZones::Lightbar) {
|
||||||
Self {
|
Self {
|
||||||
states: vec![AuraPowerState::default_for(PowerZones::KeyboardAndLightbar)]
|
states: vec![AuraPowerState::default_for(PowerZones::KeyboardAndLightbar)],
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Self {
|
Self {
|
||||||
states: vec![AuraPowerState::default_for(PowerZones::Keyboard)]
|
states: vec![AuraPowerState::default_for(PowerZones::Keyboard)],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AuraDeviceType::LaptopKeyboardTuf => Self {
|
AuraDeviceType::LaptopKeyboardTuf => Self {
|
||||||
states: vec![AuraPowerState::default_for(PowerZones::Keyboard)]
|
states: vec![AuraPowerState::default_for(PowerZones::Keyboard)],
|
||||||
},
|
},
|
||||||
AuraDeviceType::ScsiExtDisk => todo!(),
|
AuraDeviceType::ScsiExtDisk => todo!(),
|
||||||
AuraDeviceType::AnimeOrSlash => todo!()
|
AuraDeviceType::AnimeOrSlash => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +266,7 @@ impl LaptopAuraPower {
|
|||||||
self.new_to_bytes()
|
self.new_to_bytes()
|
||||||
}
|
}
|
||||||
AuraDeviceType::ScsiExtDisk => todo!("scsi disk not implemented yet"),
|
AuraDeviceType::ScsiExtDisk => todo!("scsi disk not implemented yet"),
|
||||||
AuraDeviceType::AnimeOrSlash => todo!("anime/slash not implemented yet")
|
AuraDeviceType::AnimeOrSlash => todo!("anime/slash not implemented yet"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -285,7 +285,7 @@ enum OldAuraPower {
|
|||||||
Boot = 0xc31209,
|
Boot = 0xc31209,
|
||||||
Sleep = 0x300804,
|
Sleep = 0x300804,
|
||||||
Keyboard = 0x080000,
|
Keyboard = 0x080000,
|
||||||
Lightbar = 0x040500
|
Lightbar = 0x040500,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitOr<OldAuraPower> for OldAuraPower {
|
impl BitOr<OldAuraPower> for OldAuraPower {
|
||||||
@@ -332,9 +332,9 @@ mod test {
|
|||||||
boot: false,
|
boot: false,
|
||||||
awake: true,
|
awake: true,
|
||||||
sleep: false,
|
sleep: false,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
let bytes = power.to_bytes(AuraDeviceType::LaptopKeyboardPre2021);
|
let bytes = power.to_bytes(AuraDeviceType::LaptopKeyboardPre2021);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
@@ -347,9 +347,9 @@ mod test {
|
|||||||
boot: false,
|
boot: false,
|
||||||
awake: true,
|
awake: true,
|
||||||
sleep: false,
|
sleep: false,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
let bytes = power.to_bytes(AuraDeviceType::LaptopKeyboardPre2021);
|
let bytes = power.to_bytes(AuraDeviceType::LaptopKeyboardPre2021);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
@@ -369,16 +369,16 @@ mod test {
|
|||||||
boot: true,
|
boot: true,
|
||||||
awake: true,
|
awake: true,
|
||||||
sleep: true,
|
sleep: true,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
AuraPowerState {
|
AuraPowerState {
|
||||||
zone: PowerZones::Lightbar,
|
zone: PowerZones::Lightbar,
|
||||||
boot: true,
|
boot: true,
|
||||||
awake: true,
|
awake: true,
|
||||||
sleep: true,
|
sleep: true,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
let bytes = power.to_bytes(AuraDeviceType::LaptopKeyboardPre2021);
|
let bytes = power.to_bytes(AuraDeviceType::LaptopKeyboardPre2021);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
@@ -394,9 +394,9 @@ mod test {
|
|||||||
boot: true,
|
boot: true,
|
||||||
awake: false,
|
awake: false,
|
||||||
sleep: false,
|
sleep: false,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let boot_keyb_ = to_binary_string_post2021(&LaptopAuraPower {
|
let boot_keyb_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -405,9 +405,9 @@ mod test {
|
|||||||
boot: true,
|
boot: true,
|
||||||
awake: false,
|
awake: false,
|
||||||
sleep: false,
|
sleep: false,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let sleep_logo = to_binary_string_post2021(&LaptopAuraPower {
|
let sleep_logo = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -416,9 +416,9 @@ mod test {
|
|||||||
boot: false,
|
boot: false,
|
||||||
awake: false,
|
awake: false,
|
||||||
sleep: true,
|
sleep: true,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let sleep_keyb = to_binary_string_post2021(&LaptopAuraPower {
|
let sleep_keyb = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -427,9 +427,9 @@ mod test {
|
|||||||
boot: false,
|
boot: false,
|
||||||
awake: false,
|
awake: false,
|
||||||
sleep: true,
|
sleep: true,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let awake_logo = to_binary_string_post2021(&LaptopAuraPower {
|
let awake_logo = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -438,9 +438,9 @@ mod test {
|
|||||||
boot: false,
|
boot: false,
|
||||||
awake: true,
|
awake: true,
|
||||||
sleep: false,
|
sleep: false,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let awake_keyb = to_binary_string_post2021(&LaptopAuraPower {
|
let awake_keyb = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -449,9 +449,9 @@ mod test {
|
|||||||
boot: false,
|
boot: false,
|
||||||
awake: true,
|
awake: true,
|
||||||
sleep: false,
|
sleep: false,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let shut_logo_ = to_binary_string_post2021(&LaptopAuraPower {
|
let shut_logo_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -460,9 +460,9 @@ mod test {
|
|||||||
boot: false,
|
boot: false,
|
||||||
awake: false,
|
awake: false,
|
||||||
sleep: false,
|
sleep: false,
|
||||||
shutdown: true
|
shutdown: true,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let shut_keyb_ = to_binary_string_post2021(&LaptopAuraPower {
|
let shut_keyb_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -471,9 +471,9 @@ mod test {
|
|||||||
boot: false,
|
boot: false,
|
||||||
awake: false,
|
awake: false,
|
||||||
sleep: false,
|
sleep: false,
|
||||||
shutdown: true
|
shutdown: true,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let boot_bar__ = to_binary_string_post2021(&LaptopAuraPower {
|
let boot_bar__ = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -482,9 +482,9 @@ mod test {
|
|||||||
boot: true,
|
boot: true,
|
||||||
awake: false,
|
awake: false,
|
||||||
sleep: false,
|
sleep: false,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let awake_bar_ = to_binary_string_post2021(&LaptopAuraPower {
|
let awake_bar_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -493,9 +493,9 @@ mod test {
|
|||||||
boot: false,
|
boot: false,
|
||||||
awake: true,
|
awake: true,
|
||||||
sleep: false,
|
sleep: false,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let sleep_bar_ = to_binary_string_post2021(&LaptopAuraPower {
|
let sleep_bar_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -504,9 +504,9 @@ mod test {
|
|||||||
boot: false,
|
boot: false,
|
||||||
awake: false,
|
awake: false,
|
||||||
sleep: true,
|
sleep: true,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let shut_bar__ = to_binary_string_post2021(&LaptopAuraPower {
|
let shut_bar__ = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -515,9 +515,9 @@ mod test {
|
|||||||
boot: false,
|
boot: false,
|
||||||
awake: false,
|
awake: false,
|
||||||
sleep: false,
|
sleep: false,
|
||||||
shutdown: true
|
shutdown: true,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let boot_lid__ = to_binary_string_post2021(&LaptopAuraPower {
|
let boot_lid__ = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -526,9 +526,9 @@ mod test {
|
|||||||
boot: true,
|
boot: true,
|
||||||
awake: false,
|
awake: false,
|
||||||
sleep: false,
|
sleep: false,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let awake_lid_ = to_binary_string_post2021(&LaptopAuraPower {
|
let awake_lid_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -537,9 +537,9 @@ mod test {
|
|||||||
boot: false,
|
boot: false,
|
||||||
awake: true,
|
awake: true,
|
||||||
sleep: false,
|
sleep: false,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let sleep_lid_ = to_binary_string_post2021(&LaptopAuraPower {
|
let sleep_lid_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -548,9 +548,9 @@ mod test {
|
|||||||
boot: false,
|
boot: false,
|
||||||
awake: false,
|
awake: false,
|
||||||
sleep: true,
|
sleep: true,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let shut_lid__ = to_binary_string_post2021(&LaptopAuraPower {
|
let shut_lid__ = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -559,9 +559,9 @@ mod test {
|
|||||||
boot: false,
|
boot: false,
|
||||||
awake: false,
|
awake: false,
|
||||||
sleep: false,
|
sleep: false,
|
||||||
shutdown: true
|
shutdown: true,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let boot_rear_ = to_binary_string_post2021(&LaptopAuraPower {
|
let boot_rear_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -570,9 +570,9 @@ mod test {
|
|||||||
boot: true,
|
boot: true,
|
||||||
awake: false,
|
awake: false,
|
||||||
sleep: false,
|
sleep: false,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let awake_rear = to_binary_string_post2021(&LaptopAuraPower {
|
let awake_rear = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -581,9 +581,9 @@ mod test {
|
|||||||
boot: false,
|
boot: false,
|
||||||
awake: true,
|
awake: true,
|
||||||
sleep: false,
|
sleep: false,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let sleep_rear = to_binary_string_post2021(&LaptopAuraPower {
|
let sleep_rear = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -592,9 +592,9 @@ mod test {
|
|||||||
boot: false,
|
boot: false,
|
||||||
awake: false,
|
awake: false,
|
||||||
sleep: true,
|
sleep: true,
|
||||||
shutdown: false
|
shutdown: false,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
let shut_rear_ = to_binary_string_post2021(&LaptopAuraPower {
|
let shut_rear_ = to_binary_string_post2021(&LaptopAuraPower {
|
||||||
states: vec![
|
states: vec![
|
||||||
@@ -603,9 +603,9 @@ mod test {
|
|||||||
boot: false,
|
boot: false,
|
||||||
awake: false,
|
awake: false,
|
||||||
sleep: false,
|
sleep: false,
|
||||||
shutdown: true
|
shutdown: true,
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(boot_logo_, "00000001, 00000000, 00000000, 00000000");
|
assert_eq!(boot_logo_, "00000001, 00000000, 00000000, 00000000");
|
||||||
@@ -655,7 +655,7 @@ mod test {
|
|||||||
zone: PowerZones::RearGlow,
|
zone: PowerZones::RearGlow,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
assert_eq!(byte1, "11111111, 00011110, 00001111, 00001111");
|
assert_eq!(byte1, "11111111, 00011110, 00001111, 00001111");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,40 +29,40 @@ pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
|||||||
pub const RED: Colour = Colour {
|
pub const RED: Colour = Colour {
|
||||||
r: 0xff,
|
r: 0xff,
|
||||||
g: 0x00,
|
g: 0x00,
|
||||||
b: 0x00
|
b: 0x00,
|
||||||
};
|
};
|
||||||
pub const GREEN: Colour = Colour {
|
pub const GREEN: Colour = Colour {
|
||||||
r: 0x00,
|
r: 0x00,
|
||||||
g: 0xff,
|
g: 0xff,
|
||||||
b: 0x00
|
b: 0x00,
|
||||||
};
|
};
|
||||||
pub const BLUE: Colour = Colour {
|
pub const BLUE: Colour = Colour {
|
||||||
r: 0x00,
|
r: 0x00,
|
||||||
g: 0x00,
|
g: 0x00,
|
||||||
b: 0xff
|
b: 0xff,
|
||||||
};
|
};
|
||||||
pub const VIOLET: Colour = Colour {
|
pub const VIOLET: Colour = Colour {
|
||||||
r: 0x9b,
|
r: 0x9b,
|
||||||
g: 0x26,
|
g: 0x26,
|
||||||
b: 0xb6
|
b: 0xb6,
|
||||||
};
|
};
|
||||||
pub const TEAL: Colour = Colour {
|
pub const TEAL: Colour = Colour {
|
||||||
r: 0x00,
|
r: 0x00,
|
||||||
g: 0x7c,
|
g: 0x7c,
|
||||||
b: 0x80
|
b: 0x80,
|
||||||
};
|
};
|
||||||
pub const YELLOW: Colour = Colour {
|
pub const YELLOW: Colour = Colour {
|
||||||
r: 0xff,
|
r: 0xff,
|
||||||
g: 0xef,
|
g: 0xef,
|
||||||
b: 0x00
|
b: 0x00,
|
||||||
};
|
};
|
||||||
pub const ORANGE: Colour = Colour {
|
pub const ORANGE: Colour = Colour {
|
||||||
r: 0xff,
|
r: 0xff,
|
||||||
g: 0xa4,
|
g: 0xa4,
|
||||||
b: 0x00
|
b: 0x00,
|
||||||
};
|
};
|
||||||
pub const GRADIENT: [Colour; 7] = [
|
pub const GRADIENT: [Colour; 7] = [
|
||||||
RED, VIOLET, BLUE, TEAL, GREEN, YELLOW, ORANGE
|
RED, VIOLET, BLUE, TEAL, GREEN, YELLOW, ORANGE,
|
||||||
];
|
];
|
||||||
|
|
||||||
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
|
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
|
||||||
@@ -76,7 +76,7 @@ pub enum AuraDeviceType {
|
|||||||
ScsiExtDisk = 3,
|
ScsiExtDisk = 3,
|
||||||
Ally = 4,
|
Ally = 4,
|
||||||
AnimeOrSlash = 5,
|
AnimeOrSlash = 5,
|
||||||
Unknown = 255
|
Unknown = 255,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AuraDeviceType {
|
impl AuraDeviceType {
|
||||||
@@ -110,7 +110,7 @@ impl From<&str> for AuraDeviceType {
|
|||||||
"1abe" | "1b4c" => Self::Ally,
|
"1abe" | "1b4c" => Self::Ally,
|
||||||
"19b3" | "193b" => Self::AnimeOrSlash,
|
"19b3" | "193b" => Self::AnimeOrSlash,
|
||||||
"19b6" => Self::LaptopKeyboard2021,
|
"19b6" => Self::LaptopKeyboard2021,
|
||||||
_ => Self::Unknown
|
_ => Self::Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,5 +138,5 @@ pub enum PowerZones {
|
|||||||
KeyboardAndLightbar = 5,
|
KeyboardAndLightbar = 5,
|
||||||
/// Ally specific for creating correct packet
|
/// Ally specific for creating correct packet
|
||||||
Ally = 6,
|
Ally = 6,
|
||||||
None = 255
|
None = 255,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Only these two packets must be 17 bytes
|
// Only these two packets must be 17 bytes
|
||||||
pub const AURA_LAPTOP_LED_APPLY: [u8; 17] = [
|
pub const AURA_LAPTOP_LED_APPLY: [u8; 17] = [
|
||||||
0x5d, 0xb4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
0x5d, 0xb4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
];
|
];
|
||||||
pub const AURA_LAPTOP_LED_SET: [u8; 17] = [
|
pub const AURA_LAPTOP_LED_SET: [u8; 17] = [
|
||||||
0x5d, 0xb5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
0x5d, 0xb5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ edition.workspace = true
|
|||||||
default = []
|
default = []
|
||||||
mocking = []
|
mocking = []
|
||||||
x11 = ["slint/backend-winit-x11"]
|
x11 = ["slint/backend-winit-x11"]
|
||||||
# Requires RUSTFLAGS="--cfg tokio_unstable"
|
# Optional tokio debug feature does not require nightly; remove RUSTFLAGS note.
|
||||||
tokio-debug = ["console-subscriber"]
|
tokio-debug = ["console-subscriber"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@@ -41,6 +41,7 @@ zbus.workspace = true
|
|||||||
dirs.workspace = true
|
dirs.workspace = true
|
||||||
notify-rust.workspace = true
|
notify-rust.workspace = true
|
||||||
concat-idents.workspace = true
|
concat-idents.workspace = true
|
||||||
|
futures-util.workspace = true
|
||||||
|
|
||||||
versions.workspace = true
|
versions.workspace = true
|
||||||
|
|
||||||
@@ -48,12 +49,26 @@ versions.workspace = true
|
|||||||
git = "https://github.com/slint-ui/slint.git"
|
git = "https://github.com/slint-ui/slint.git"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = [
|
features = [
|
||||||
"gettext",
|
|
||||||
"compat-1-2",
|
"compat-1-2",
|
||||||
|
"gettext",
|
||||||
"backend-winit-wayland",
|
"backend-winit-wayland",
|
||||||
"renderer-winit-femtovg",
|
"renderer-femtovg",
|
||||||
# "renderer-skia-opengl",
|
# "renderer-skia-opengl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[build-dependencies.slint-build]
|
[build-dependencies.slint-build]
|
||||||
git = "https://github.com/slint-ui/slint.git"
|
git = "https://github.com/slint-ui/slint.git"
|
||||||
|
|
||||||
|
[package.metadata.deb]
|
||||||
|
license-file = ["../LICENSE", "4"]
|
||||||
|
extended-description = """\
|
||||||
|
The dbus server for asusctl and rog-control-center applications."""
|
||||||
|
depends = "$auto"
|
||||||
|
section = "utility"
|
||||||
|
priority = "optional"
|
||||||
|
assets = [
|
||||||
|
["target/release/rog-control-center", "usr/bin/", "755"],
|
||||||
|
["../rog_gui-fakeinstall/usr/share/applications/*", "usr/share/share/applications/", "644"],
|
||||||
|
["../rog_gui-fakeinstall/usr/share/icons/hicolor/512x512/apps/*", "usr/share/icons/hicolor/512x512/apps", "644"],
|
||||||
|
["../rog_gui-fakeinstall/usr/share/icons/hicolor/scalable/status/*", "usr/share/icons/hicolor/scalable/status", "644"],
|
||||||
|
]
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ fn main() {
|
|||||||
CompilerConfiguration::new()
|
CompilerConfiguration::new()
|
||||||
// .embed_resources(EmbedResourcesKind::EmbedFiles)
|
// .embed_resources(EmbedResourcesKind::EmbedFiles)
|
||||||
.with_include_paths(vec![include])
|
.with_include_paths(vec![include])
|
||||||
.with_style("fluent".into())
|
.with_style("fluent".into()),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,5 +23,5 @@ pub struct CliStart {
|
|||||||
help = "put ROGCC in layout viewing mode - this is helpful for finding existing layouts \
|
help = "put ROGCC in layout viewing mode - this is helpful for finding existing layouts \
|
||||||
that might match your laptop"
|
that might match your laptop"
|
||||||
)]
|
)]
|
||||||
pub layout_viewing: bool
|
pub layout_viewing: bool,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ pub struct Config {
|
|||||||
pub fullscreen_width: u32,
|
pub fullscreen_width: u32,
|
||||||
pub fullscreen_height: u32,
|
pub fullscreen_height: u32,
|
||||||
// This field must be last
|
// This field must be last
|
||||||
pub notifications: EnabledNotifications
|
pub notifications: EnabledNotifications,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
@@ -36,7 +36,7 @@ impl Default for Config {
|
|||||||
fullscreen_height: 1080,
|
fullscreen_height: 1080,
|
||||||
notifications: EnabledNotifications::default(),
|
notifications: EnabledNotifications::default(),
|
||||||
ac_command: String::new(),
|
ac_command: String::new(),
|
||||||
bat_command: String::new()
|
bat_command: String::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,7 +77,7 @@ pub struct Config461 {
|
|||||||
pub enable_dgpu_notifications: bool,
|
pub enable_dgpu_notifications: bool,
|
||||||
pub dark_mode: bool,
|
pub dark_mode: bool,
|
||||||
// This field must be last
|
// This field must be last
|
||||||
pub enabled_notifications: EnabledNotifications
|
pub enabled_notifications: EnabledNotifications,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Config461> for Config {
|
impl From<Config461> for Config {
|
||||||
@@ -92,7 +92,7 @@ impl From<Config461> for Config {
|
|||||||
start_fullscreen: false,
|
start_fullscreen: false,
|
||||||
fullscreen_width: 1920,
|
fullscreen_width: 1920,
|
||||||
fullscreen_height: 1080,
|
fullscreen_height: 1080,
|
||||||
notifications: c.enabled_notifications
|
notifications: c.enabled_notifications,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ pub enum Error {
|
|||||||
ConfigLockFail,
|
ConfigLockFail,
|
||||||
XdgVars,
|
XdgVars,
|
||||||
Zbus(zbus::Error),
|
Zbus(zbus::Error),
|
||||||
Notification(notify_rust::error::Error)
|
ZbusFdo(zbus::fdo::Error),
|
||||||
|
Notification(notify_rust::error::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
@@ -21,7 +22,8 @@ impl fmt::Display for Error {
|
|||||||
Error::ConfigLockFail => write!(f, "Failed to lock user config"),
|
Error::ConfigLockFail => write!(f, "Failed to lock user config"),
|
||||||
Error::XdgVars => write!(f, "XDG environment vars appear unset"),
|
Error::XdgVars => write!(f, "XDG environment vars appear unset"),
|
||||||
Error::Zbus(err) => write!(f, "Error: {}", err),
|
Error::Zbus(err) => write!(f, "Error: {}", err),
|
||||||
Error::Notification(err) => write!(f, "Notification Error: {}", err)
|
Error::ZbusFdo(err) => write!(f, "Error: {}", err),
|
||||||
|
Error::Notification(err) => write!(f, "Notification Error: {}", err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,6 +42,12 @@ impl From<zbus::Error> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<zbus::fdo::Error> for Error {
|
||||||
|
fn from(err: zbus::fdo::Error) -> Self {
|
||||||
|
Error::ZbusFdo(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<notify_rust::error::Error> for Error {
|
impl From<notify_rust::error::Error> for Error {
|
||||||
fn from(err: notify_rust::error::Error) -> Self {
|
fn from(err: notify_rust::error::Error) -> Self {
|
||||||
Error::Notification(err)
|
Error::Notification(err)
|
||||||
|
|||||||
@@ -38,5 +38,5 @@ pub enum Page {
|
|||||||
System,
|
System,
|
||||||
AuraEffects,
|
AuraEffects,
|
||||||
AnimeMatrix,
|
AnimeMatrix,
|
||||||
FanCurves
|
FanCurves,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use std::time::Duration;
|
|||||||
use config_traits::{StdConfig, StdConfigLoad1};
|
use config_traits::{StdConfig, StdConfigLoad1};
|
||||||
use dmi_id::DMIID;
|
use dmi_id::DMIID;
|
||||||
use gumdrop::Options;
|
use gumdrop::Options;
|
||||||
use log::{info, warn, LevelFilter};
|
use log::{debug, info, warn, LevelFilter};
|
||||||
use rog_control_center::cli_options::CliStart;
|
use rog_control_center::cli_options::CliStart;
|
||||||
use rog_control_center::config::Config;
|
use rog_control_center::config::Config;
|
||||||
use rog_control_center::error::Result;
|
use rog_control_center::error::Result;
|
||||||
@@ -17,25 +17,42 @@ use rog_control_center::slint::ComponentHandle;
|
|||||||
use rog_control_center::tray::init_tray;
|
use rog_control_center::tray::init_tray;
|
||||||
use rog_control_center::ui::setup_window;
|
use rog_control_center::ui::setup_window;
|
||||||
use rog_control_center::zbus_proxies::{
|
use rog_control_center::zbus_proxies::{
|
||||||
AppState, ROGCCZbus, ROGCCZbusProxyBlocking, ZBUS_IFACE, ZBUS_PATH
|
AppState, ROGCCZbus, ROGCCZbusProxyBlocking, ZBUS_IFACE, ZBUS_PATH,
|
||||||
};
|
};
|
||||||
use rog_control_center::{print_versions, MainWindow};
|
use rog_control_center::{print_versions, MainWindow};
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
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();
|
let mut logger = env_logger::Builder::new();
|
||||||
logger
|
logger
|
||||||
.filter_level(LevelFilter::Warn)
|
|
||||||
.parse_default_env()
|
.parse_default_env()
|
||||||
.target(env_logger::Target::Stdout)
|
.filter_level(LevelFilter::Info)
|
||||||
|
.parse_default_env()
|
||||||
|
.target(env_logger::Target::Stderr)
|
||||||
.format_timestamp(None)
|
.format_timestamp(None)
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
// If we're running under gamescope we have to set WAYLAND_DISPLAY for winit to
|
// If we're running under gamescope we have to set WAYLAND_DISPLAY for winit to
|
||||||
// use
|
// use
|
||||||
if let Ok(gamescope) = env::var("GAMESCOPE_WAYLAND_DISPLAY") {
|
if let Ok(gamescope) = env::var("GAMESCOPE_WAYLAND_DISPLAY") {
|
||||||
env::set_var("WAYLAND_DISPLAY", gamescope);
|
debug!("Gamescope detected");
|
||||||
|
if !gamescope.is_empty() {
|
||||||
|
debug!("Setting WAYLAND_DISPLAY to {}", gamescope);
|
||||||
|
env::set_var("WAYLAND_DISPLAY", gamescope);
|
||||||
|
}
|
||||||
|
// gamescope-0
|
||||||
|
else if let Ok(wayland) = env::var("WAYLAND_DISPLAY") {
|
||||||
|
debug!("Wayland display detected");
|
||||||
|
if wayland.is_empty() {
|
||||||
|
debug!("Setting WAYLAND_DISPLAY to gamescope-0");
|
||||||
|
env::set_var("WAYLAND_DISPLAY", "gamescope-0");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to open a proxy and check for app state first
|
// Try to open a proxy and check for app state first
|
||||||
@@ -63,7 +80,7 @@ async fn main() -> Result<()> {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
if asusd_version != self_version {
|
if asusd_version != self_version {
|
||||||
println!("Version mismatch: asusctl = {self_version}, asusd = {asusd_version}");
|
println!("Version mismatch: asusctl = {self_version}, asusd = {asusd_version}");
|
||||||
return Ok(());
|
// return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// start tokio
|
// start tokio
|
||||||
@@ -90,7 +107,7 @@ async fn main() -> Result<()> {
|
|||||||
let board_name = dmi.board_name;
|
let board_name = dmi.board_name;
|
||||||
let prod_family = dmi.product_family;
|
let prod_family = dmi.product_family;
|
||||||
info!("Running on {board_name}, product: {prod_family}");
|
info!("Running on {board_name}, product: {prod_family}");
|
||||||
let is_rog_ally = prod_family == "RC71L" || prod_family == "RC72L";
|
let is_rog_ally = board_name == "RC71L" || board_name == "RC72L" || prod_family == "ROG Ally";
|
||||||
|
|
||||||
let args: Vec<String> = args().skip(1).collect();
|
let args: Vec<String> = args().skip(1).collect();
|
||||||
|
|
||||||
@@ -161,73 +178,101 @@ async fn main() -> Result<()> {
|
|||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let mut state = AppState::StartingUp;
|
let mut state = AppState::StartingUp;
|
||||||
loop {
|
loop {
|
||||||
// save as a var, don't hold the lock the entire time or deadlocks happen
|
if is_rog_ally {
|
||||||
if let Ok(app_state) = app_state.lock() {
|
let config_copy_2 = config.clone();
|
||||||
state = *app_state;
|
let newui = setup_window(config.clone());
|
||||||
}
|
newui.window().on_close_requested(move || {
|
||||||
|
exit(0);
|
||||||
|
});
|
||||||
|
|
||||||
// This sleep is required to give the event loop time to react
|
let ui_copy = newui.as_weak();
|
||||||
sleep(Duration::from_millis(300));
|
newui
|
||||||
if state == AppState::MainWindowShouldOpen {
|
.window()
|
||||||
if let Ok(mut app_state) = app_state.lock() {
|
.set_rendering_notifier(move |s, _| {
|
||||||
*app_state = AppState::MainWindowOpen;
|
if let slint::RenderingState::BeforeRendering = s {
|
||||||
}
|
let config = config_copy_2.clone();
|
||||||
|
ui_copy
|
||||||
let config_copy = config.clone();
|
.upgrade_in_event_loop(move |w| {
|
||||||
let app_state_copy = app_state.clone();
|
let fullscreen =
|
||||||
slint::invoke_from_event_loop(move || {
|
config.lock().is_ok_and(|c| c.start_fullscreen);
|
||||||
UI.with(|ui| {
|
if fullscreen && !w.window().is_fullscreen() {
|
||||||
let app_state_copy = app_state_copy.clone();
|
w.window().set_fullscreen(fullscreen);
|
||||||
let mut ui = ui.borrow_mut();
|
|
||||||
if let Some(ui) = ui.as_mut() {
|
|
||||||
ui.window().show().unwrap();
|
|
||||||
ui.window().on_close_requested(move || {
|
|
||||||
if let Ok(mut app_state) = app_state_copy.lock() {
|
|
||||||
*app_state = AppState::MainWindowClosed;
|
|
||||||
}
|
|
||||||
slint::CloseRequestResponse::HideWindow
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
let config_copy_2 = config_copy.clone();
|
|
||||||
let newui = setup_window(config_copy);
|
|
||||||
newui.window().on_close_requested(move || {
|
|
||||||
if let Ok(mut app_state) = app_state_copy.lock() {
|
|
||||||
*app_state = AppState::MainWindowClosed;
|
|
||||||
}
|
|
||||||
slint::CloseRequestResponse::HideWindow
|
|
||||||
});
|
|
||||||
|
|
||||||
let ui_copy = newui.as_weak();
|
|
||||||
newui
|
|
||||||
.window()
|
|
||||||
.set_rendering_notifier(move |s, _| {
|
|
||||||
if let slint::RenderingState::RenderingSetup = s {
|
|
||||||
let config = config_copy_2.clone();
|
|
||||||
ui_copy
|
|
||||||
.upgrade_in_event_loop(move |w| {
|
|
||||||
let fullscreen =
|
|
||||||
config.lock().is_ok_and(|c| c.start_fullscreen);
|
|
||||||
if fullscreen && !w.window().is_fullscreen() {
|
|
||||||
w.window().set_fullscreen(fullscreen);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
ui.replace(newui);
|
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
})
|
.ok();
|
||||||
.unwrap();
|
} else {
|
||||||
} else if state == AppState::QuitApp {
|
// save as a var, don't hold the lock the entire time or deadlocks happen
|
||||||
slint::quit_event_loop().unwrap();
|
if let Ok(app_state) = app_state.lock() {
|
||||||
exit(0);
|
state = *app_state;
|
||||||
} else if state != AppState::MainWindowOpen {
|
}
|
||||||
if let Ok(config) = config.lock() {
|
|
||||||
if !config.run_in_background {
|
// This sleep is required to give the event loop time to react
|
||||||
slint::quit_event_loop().unwrap();
|
sleep(Duration::from_millis(300));
|
||||||
exit(0);
|
if state == AppState::MainWindowShouldOpen {
|
||||||
|
if let Ok(mut app_state) = app_state.lock() {
|
||||||
|
*app_state = AppState::MainWindowOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
let config_copy = config.clone();
|
||||||
|
let app_state_copy = app_state.clone();
|
||||||
|
slint::invoke_from_event_loop(move || {
|
||||||
|
UI.with(|ui| {
|
||||||
|
let app_state_copy = app_state_copy.clone();
|
||||||
|
let mut ui = ui.borrow_mut();
|
||||||
|
if let Some(ui) = ui.as_mut() {
|
||||||
|
ui.window().show().unwrap();
|
||||||
|
ui.window().on_close_requested(move || {
|
||||||
|
if let Ok(mut app_state) = app_state_copy.lock() {
|
||||||
|
*app_state = AppState::MainWindowClosed;
|
||||||
|
}
|
||||||
|
slint::CloseRequestResponse::HideWindow
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
let config_copy_2 = config_copy.clone();
|
||||||
|
let newui = setup_window(config_copy);
|
||||||
|
newui.window().on_close_requested(move || {
|
||||||
|
if let Ok(mut app_state) = app_state_copy.lock() {
|
||||||
|
*app_state = AppState::MainWindowClosed;
|
||||||
|
}
|
||||||
|
slint::CloseRequestResponse::HideWindow
|
||||||
|
});
|
||||||
|
|
||||||
|
let ui_copy = newui.as_weak();
|
||||||
|
newui
|
||||||
|
.window()
|
||||||
|
.set_rendering_notifier(move |s, _| {
|
||||||
|
if let slint::RenderingState::RenderingSetup = s {
|
||||||
|
let config = config_copy_2.clone();
|
||||||
|
ui_copy
|
||||||
|
.upgrade_in_event_loop(move |w| {
|
||||||
|
let fullscreen = config
|
||||||
|
.lock()
|
||||||
|
.is_ok_and(|c| c.start_fullscreen);
|
||||||
|
if fullscreen && !w.window().is_fullscreen() {
|
||||||
|
w.window().set_fullscreen(fullscreen);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
ui.replace(newui);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
} else if state == AppState::QuitApp {
|
||||||
|
slint::quit_event_loop().unwrap();
|
||||||
|
exit(0);
|
||||||
|
} else if state != AppState::MainWindowOpen {
|
||||||
|
if let Ok(config) = config.lock() {
|
||||||
|
if !config.run_in_background {
|
||||||
|
slint::quit_event_loop().unwrap();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use rog_aura::{AuraEffect, AuraModeNum, AuraZone};
|
|||||||
use rog_platform::platform::GpuMode;
|
use rog_platform::platform::GpuMode;
|
||||||
use rog_platform::supported::{
|
use rog_platform::supported::{
|
||||||
AdvancedAura, AnimeSupportedFunctions, ChargeSupportedFunctions, LedSupportedFunctions,
|
AdvancedAura, AnimeSupportedFunctions, ChargeSupportedFunctions, LedSupportedFunctions,
|
||||||
PlatformProfileFunctions, RogBiosSupportedFunctions, SupportedFunctions
|
PlatformProfileFunctions, RogBiosSupportedFunctions, SupportedFunctions,
|
||||||
};
|
};
|
||||||
use rog_profiles::fan_curve_set::{CurveData, FanCurveSet};
|
use rog_profiles::fan_curve_set::{CurveData, FanCurveSet};
|
||||||
use supergfxctl::pci_device::{GfxMode, GfxPower};
|
use supergfxctl::pci_device::{GfxMode, GfxPower};
|
||||||
@@ -16,7 +16,7 @@ const NOPE: &str = "";
|
|||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct DaemonProxyBlocking<'a> {
|
pub struct DaemonProxyBlocking<'a> {
|
||||||
_phantom: &'a str
|
_phantom: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DaemonProxyBlocking<'a> {
|
impl<'a> DaemonProxyBlocking<'a> {
|
||||||
@@ -35,7 +35,7 @@ impl<'a> DaemonProxyBlocking<'a> {
|
|||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct RogDbusClientBlocking<'a> {
|
pub struct RogDbusClientBlocking<'a> {
|
||||||
_phantom: &'a str
|
_phantom: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RogDbusClientBlocking<'a> {
|
impl<'a> RogDbusClientBlocking<'a> {
|
||||||
@@ -126,16 +126,16 @@ impl Profile {
|
|||||||
pub fn fan_curve_data(&self, _p: rog_profiles::Profile) -> Result<FanCurveSet> {
|
pub fn fan_curve_data(&self, _p: rog_profiles::Profile) -> Result<FanCurveSet> {
|
||||||
let mut curve = FanCurveSet::default();
|
let mut curve = FanCurveSet::default();
|
||||||
curve.cpu.pwm = [
|
curve.cpu.pwm = [
|
||||||
30, 40, 60, 100, 140, 180, 200, 250
|
30, 40, 60, 100, 140, 180, 200, 250,
|
||||||
];
|
];
|
||||||
curve.cpu.temp = [
|
curve.cpu.temp = [
|
||||||
20, 30, 40, 50, 70, 80, 90, 100
|
20, 30, 40, 50, 70, 80, 90, 100,
|
||||||
];
|
];
|
||||||
curve.gpu.pwm = [
|
curve.gpu.pwm = [
|
||||||
40, 80, 100, 140, 170, 200, 230, 250
|
40, 80, 100, 140, 170, 200, 230, 250,
|
||||||
];
|
];
|
||||||
curve.gpu.temp = [
|
curve.gpu.temp = [
|
||||||
20, 30, 40, 50, 70, 80, 90, 100
|
20, 30, 40, 50, 70, 80, 90, 100,
|
||||||
];
|
];
|
||||||
Ok(curve)
|
Ok(curve)
|
||||||
}
|
}
|
||||||
@@ -204,7 +204,7 @@ impl Led {
|
|||||||
AuraDevRog2::AwakeKeyb,
|
AuraDevRog2::AwakeKeyb,
|
||||||
AuraDevRog2::SleepLogo,
|
AuraDevRog2::SleepLogo,
|
||||||
AuraDevRog2::AwakeLogo,
|
AuraDevRog2::AwakeLogo,
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,11 +242,11 @@ impl Supported {
|
|||||||
Ok(SupportedFunctions {
|
Ok(SupportedFunctions {
|
||||||
anime_ctrl: AnimeSupportedFunctions(true),
|
anime_ctrl: AnimeSupportedFunctions(true),
|
||||||
charge_ctrl: ChargeSupportedFunctions {
|
charge_ctrl: ChargeSupportedFunctions {
|
||||||
charge_level_set: true
|
charge_level_set: true,
|
||||||
},
|
},
|
||||||
platform_profile: PlatformProfileFunctions {
|
platform_profile: PlatformProfileFunctions {
|
||||||
platform_profile: true,
|
platform_profile: true,
|
||||||
fan_curves: true
|
fan_curves: true,
|
||||||
},
|
},
|
||||||
keyboard_led: LedSupportedFunctions {
|
keyboard_led: LedSupportedFunctions {
|
||||||
dev_id: AuraDevice::X19b6,
|
dev_id: AuraDevice::X19b6,
|
||||||
@@ -267,7 +267,7 @@ impl Supported {
|
|||||||
AuraZone::BarRight,
|
AuraZone::BarRight,
|
||||||
AuraZone::Logo,
|
AuraZone::Logo,
|
||||||
],
|
],
|
||||||
advanced_type: AdvancedAura::PerKey
|
advanced_type: AdvancedAura::PerKey,
|
||||||
},
|
},
|
||||||
rog_bios_ctrl: RogBiosSupportedFunctions {
|
rog_bios_ctrl: RogBiosSupportedFunctions {
|
||||||
post_sound: true,
|
post_sound: true,
|
||||||
@@ -275,8 +275,8 @@ impl Supported {
|
|||||||
panel_overdrive: true,
|
panel_overdrive: true,
|
||||||
dgpu_disable: true,
|
dgpu_disable: true,
|
||||||
mini_led_mode: true,
|
mini_led_mode: true,
|
||||||
egpu_enable: true
|
egpu_enable: true,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,16 +10,12 @@ use std::sync::{Arc, Mutex};
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use notify_rust::{Hint, Notification, Timeout, Urgency};
|
use notify_rust::{Hint, Notification, Timeout};
|
||||||
use rog_platform::platform::GpuMode;
|
|
||||||
use rog_platform::power::AsusPower;
|
use rog_platform::power::AsusPower;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use supergfxctl::actions::UserActionRequired as GfxUserAction;
|
use supergfxctl::pci_device::GfxPower;
|
||||||
use supergfxctl::pci_device::{GfxMode, GfxPower};
|
|
||||||
use supergfxctl::zbus_proxy::DaemonProxy as SuperProxy;
|
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
use tokio::task::JoinHandle;
|
use tokio::task::JoinHandle;
|
||||||
use zbus::export::futures_util::StreamExt;
|
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
@@ -31,7 +27,7 @@ const NOTIF_HEADER: &str = "ROG Control";
|
|||||||
pub struct EnabledNotifications {
|
pub struct EnabledNotifications {
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
pub receive_notify_gfx: bool,
|
pub receive_notify_gfx: bool,
|
||||||
pub receive_notify_gfx_status: bool
|
pub receive_notify_gfx_status: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for EnabledNotifications {
|
impl Default for EnabledNotifications {
|
||||||
@@ -39,7 +35,7 @@ impl Default for EnabledNotifications {
|
|||||||
Self {
|
Self {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
receive_notify_gfx: true,
|
receive_notify_gfx: true,
|
||||||
receive_notify_gfx_status: true
|
receive_notify_gfx_status: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,7 +88,7 @@ fn start_dpu_status_mon(config: Arc<Mutex<Config>>) {
|
|||||||
|
|
||||||
pub fn start_notifications(
|
pub fn start_notifications(
|
||||||
config: Arc<Mutex<Config>>,
|
config: Arc<Mutex<Config>>,
|
||||||
rt: &Runtime
|
rt: &Runtime,
|
||||||
) -> Result<Vec<JoinHandle<()>>> {
|
) -> Result<Vec<JoinHandle<()>>> {
|
||||||
// Setup the AC/BAT commands that will run on power status change
|
// Setup the AC/BAT commands that will run on power status change
|
||||||
let config_copy = config.clone();
|
let config_copy = config.clone();
|
||||||
@@ -116,26 +112,26 @@ pub fn start_notifications(
|
|||||||
|
|
||||||
if p == 0 && p != last_state {
|
if p == 0 && p != last_state {
|
||||||
let prog: Vec<&str> = bat.split_whitespace().collect();
|
let prog: Vec<&str> = bat.split_whitespace().collect();
|
||||||
if prog.len() > 1 {
|
if (!prog.is_empty()) && (!prog[0].is_empty()) {
|
||||||
let mut cmd = Command::new(prog[0]);
|
let mut cmd = Command::new(prog[0]);
|
||||||
|
|
||||||
for arg in prog.iter().skip(1) {
|
for arg in prog.iter().skip(1) {
|
||||||
cmd.arg(*arg);
|
cmd.arg(*arg);
|
||||||
}
|
}
|
||||||
cmd.spawn()
|
cmd.spawn()
|
||||||
.map_err(|e| error!("AC command error: {e:?}"))
|
.map_err(|e| error!("Battery power command error: {e:?}"))
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
} else if p != last_state {
|
} else if p != last_state {
|
||||||
let prog: Vec<&str> = ac.split_whitespace().collect();
|
let prog: Vec<&str> = ac.split_whitespace().collect();
|
||||||
if prog.len() > 1 {
|
if (!prog.is_empty()) && (!prog[0].is_empty()) {
|
||||||
let mut cmd = Command::new(prog[0]);
|
let mut cmd = Command::new(prog[0]);
|
||||||
|
|
||||||
for arg in prog.iter().skip(1) {
|
for arg in prog.iter().skip(1) {
|
||||||
cmd.arg(*arg);
|
cmd.arg(*arg);
|
||||||
}
|
}
|
||||||
cmd.spawn()
|
cmd.spawn()
|
||||||
.map_err(|e| error!("AC command error: {e:?}"))
|
.map_err(|e| error!("AC power command error: {e:?}"))
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -145,12 +141,8 @@ pub fn start_notifications(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let enabled_notifications_copy = config.clone();
|
info!("Attempting to start plain dgpu status monitor");
|
||||||
let no_supergfx = move |e: &zbus::Error| {
|
start_dpu_status_mon(config.clone());
|
||||||
error!("zbus signal: receive_notify_gfx_status: {e}");
|
|
||||||
warn!("Attempting to start plain dgpu status monitor");
|
|
||||||
start_dpu_status_mon(enabled_notifications_copy.clone());
|
|
||||||
};
|
|
||||||
|
|
||||||
// GPU MUX Mode notif
|
// GPU MUX Mode notif
|
||||||
// TODO: need to get armoury attrs and iter to find
|
// TODO: need to get armoury attrs and iter to find
|
||||||
@@ -189,90 +181,12 @@ pub fn start_notifications(
|
|||||||
// Ok::<(), zbus::Error>(())
|
// 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])
|
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
|
fn base_notification<T>(message: &str, data: &T) -> Notification
|
||||||
where
|
where
|
||||||
T: Display
|
T: Display,
|
||||||
{
|
{
|
||||||
let mut notif = Notification::new();
|
let mut notif = Notification::new();
|
||||||
notif
|
notif
|
||||||
@@ -290,100 +204,8 @@ fn do_gpu_status_notif(message: &str, data: &GfxPower) -> Notification {
|
|||||||
GfxPower::Off => "asus_notif_green",
|
GfxPower::Off => "asus_notif_green",
|
||||||
GfxPower::AsusDisabled => "asus_notif_white",
|
GfxPower::AsusDisabled => "asus_notif_white",
|
||||||
GfxPower::AsusMuxDiscreet | GfxPower::Active => "asus_notif_red",
|
GfxPower::AsusMuxDiscreet | GfxPower::Active => "asus_notif_red",
|
||||||
GfxPower::Unknown => "gpu-integrated"
|
GfxPower::Unknown => "gpu-integrated",
|
||||||
};
|
};
|
||||||
notif.icon(icon);
|
notif.icon(icon);
|
||||||
notif
|
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(())
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ struct Icons {
|
|||||||
rog_red: Icon,
|
rog_red: Icon,
|
||||||
rog_green: Icon,
|
rog_green: Icon,
|
||||||
rog_white: Icon,
|
rog_white: Icon,
|
||||||
gpu_integrated: Icon
|
gpu_integrated: Icon,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ICONS: OnceLock<Icons> = OnceLock::new();
|
static ICONS: OnceLock<Icons> = OnceLock::new();
|
||||||
@@ -32,7 +32,10 @@ static ICONS: OnceLock<Icons> = OnceLock::new();
|
|||||||
fn read_icon(file: &Path) -> Icon {
|
fn read_icon(file: &Path) -> Icon {
|
||||||
let mut path = PathBuf::from(TRAY_ICON_PATH);
|
let mut path = PathBuf::from(TRAY_ICON_PATH);
|
||||||
path.push(file);
|
path.push(file);
|
||||||
let mut file = OpenOptions::new().read(true).open(path).unwrap();
|
let mut file = OpenOptions::new()
|
||||||
|
.read(true)
|
||||||
|
.open(&path)
|
||||||
|
.unwrap_or_else(|_| panic!("Missing icon: {:?}", path));
|
||||||
let mut bytes = Vec::new();
|
let mut bytes = Vec::new();
|
||||||
file.read_to_end(&mut bytes).unwrap();
|
file.read_to_end(&mut bytes).unwrap();
|
||||||
|
|
||||||
@@ -48,14 +51,14 @@ fn read_icon(file: &Path) -> Icon {
|
|||||||
Icon {
|
Icon {
|
||||||
width: width as i32,
|
width: width as i32,
|
||||||
height: height as i32,
|
height: height as i32,
|
||||||
data: img.into_raw()
|
data: img.into_raw(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AsusTray {
|
struct AsusTray {
|
||||||
current_title: String,
|
current_title: String,
|
||||||
current_icon: Icon,
|
current_icon: Icon,
|
||||||
proxy: ROGCCZbusProxyBlocking<'static>
|
proxy: ROGCCZbusProxyBlocking<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ksni::Tray for AsusTray {
|
impl ksni::Tray for AsusTray {
|
||||||
@@ -103,7 +106,7 @@ async fn set_tray_icon_and_tip(
|
|||||||
mode: GfxMode,
|
mode: GfxMode,
|
||||||
power: GfxPower,
|
power: GfxPower,
|
||||||
tray: &mut Handle<AsusTray>,
|
tray: &mut Handle<AsusTray>,
|
||||||
supergfx_active: bool
|
supergfx_active: bool,
|
||||||
) {
|
) {
|
||||||
if let Some(icons) = ICONS.get() {
|
if let Some(icons) = ICONS.get() {
|
||||||
let icon = match power {
|
let icon = match power {
|
||||||
@@ -162,12 +165,12 @@ pub fn init_tray(_supported_properties: Vec<Properties>, config: Arc<Mutex<Confi
|
|||||||
let tray_init = AsusTray {
|
let tray_init = AsusTray {
|
||||||
current_title: TRAY_LABEL.to_string(),
|
current_title: TRAY_LABEL.to_string(),
|
||||||
current_icon: rog_red.clone(),
|
current_icon: rog_red.clone(),
|
||||||
proxy
|
proxy,
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: return an error to the UI
|
// TODO: return an error to the UI
|
||||||
let mut tray;
|
let mut tray;
|
||||||
match tray_init.spawn_without_dbus_name().await {
|
match tray_init.disable_dbus_name(true).spawn().await {
|
||||||
Ok(t) => tray = t,
|
Ok(t) => tray = t,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!(
|
log::error!(
|
||||||
@@ -187,7 +190,7 @@ pub fn init_tray(_supported_properties: Vec<Properties>, config: Arc<Mutex<Confi
|
|||||||
rog_red: rog_red.clone(),
|
rog_red: rog_red.clone(),
|
||||||
rog_green,
|
rog_green,
|
||||||
rog_white,
|
rog_white,
|
||||||
gpu_integrated
|
gpu_integrated,
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut has_supergfx = false;
|
let mut has_supergfx = false;
|
||||||
@@ -215,8 +218,8 @@ pub fn init_tray(_supported_properties: Vec<Properties>, config: Arc<Mutex<Confi
|
|||||||
may not be running or installed"
|
may not be running or installed"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => warn!("Couldn't get mode from supergfxd: {e:?}")
|
_ => warn!("Couldn't get mode from supergfxd: {e:?}"),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Started ROGTray");
|
info!("Started ROGTray");
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::slint_generatedMainWindow::{
|
use crate::slint_generatedMainWindow::{
|
||||||
AuraDevType as SlintDeviceType, AuraPowerState as SlintAuraPowerState,
|
AuraDevType as SlintDeviceType, AuraPowerState as SlintAuraPowerState,
|
||||||
LaptopAuraPower as SlintLaptopAuraPower
|
LaptopAuraPower as SlintLaptopAuraPower,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl From<rog_aura::AuraEffect> for crate::slint_generatedMainWindow::AuraEffect {
|
impl From<rog_aura::AuraEffect> for crate::slint_generatedMainWindow::AuraEffect {
|
||||||
@@ -10,20 +10,20 @@ impl From<rog_aura::AuraEffect> for crate::slint_generatedMainWindow::AuraEffect
|
|||||||
red: m.colour1.r,
|
red: m.colour1.r,
|
||||||
green: m.colour1.g,
|
green: m.colour1.g,
|
||||||
blue: m.colour1.b,
|
blue: m.colour1.b,
|
||||||
alpha: 255
|
alpha: 255,
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
colour2: RgbaColor {
|
colour2: RgbaColor {
|
||||||
red: m.colour2.r,
|
red: m.colour2.r,
|
||||||
green: m.colour2.g,
|
green: m.colour2.g,
|
||||||
blue: m.colour2.b,
|
blue: m.colour2.b,
|
||||||
alpha: 255
|
alpha: 255,
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
direction: m.direction.into(),
|
direction: m.direction.into(),
|
||||||
mode: m.mode.into(),
|
mode: m.mode.into(),
|
||||||
speed: m.speed.into(),
|
speed: m.speed.into(),
|
||||||
zone: m.zone.into()
|
zone: m.zone.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,17 +36,17 @@ impl From<crate::slint_generatedMainWindow::AuraEffect> for rog_aura::AuraEffect
|
|||||||
colour1: rog_aura::Colour {
|
colour1: rog_aura::Colour {
|
||||||
r: c1.red,
|
r: c1.red,
|
||||||
g: c1.green,
|
g: c1.green,
|
||||||
b: c1.blue
|
b: c1.blue,
|
||||||
},
|
},
|
||||||
colour2: rog_aura::Colour {
|
colour2: rog_aura::Colour {
|
||||||
r: c2.red,
|
r: c2.red,
|
||||||
g: c2.green,
|
g: c2.green,
|
||||||
b: c2.blue
|
b: c2.blue,
|
||||||
},
|
},
|
||||||
direction: m.direction.into(),
|
direction: m.direction.into(),
|
||||||
mode: m.mode.into(),
|
mode: m.mode.into(),
|
||||||
speed: m.speed.into(),
|
speed: m.speed.into(),
|
||||||
zone: m.zone.into()
|
zone: m.zone.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ impl From<PowerZones> for SlintPowerZones {
|
|||||||
PowerZones::RearGlow => SlintPowerZones::RearGlow,
|
PowerZones::RearGlow => SlintPowerZones::RearGlow,
|
||||||
PowerZones::KeyboardAndLightbar => SlintPowerZones::KeyboardAndLightbar,
|
PowerZones::KeyboardAndLightbar => SlintPowerZones::KeyboardAndLightbar,
|
||||||
PowerZones::Ally => SlintPowerZones::Ally,
|
PowerZones::Ally => SlintPowerZones::Ally,
|
||||||
PowerZones::None => SlintPowerZones::Keyboard
|
PowerZones::None => SlintPowerZones::Keyboard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ impl From<SlintPowerZones> for PowerZones {
|
|||||||
SlintPowerZones::Lid => PowerZones::Lid,
|
SlintPowerZones::Lid => PowerZones::Lid,
|
||||||
SlintPowerZones::RearGlow => PowerZones::RearGlow,
|
SlintPowerZones::RearGlow => PowerZones::RearGlow,
|
||||||
SlintPowerZones::KeyboardAndLightbar => PowerZones::KeyboardAndLightbar,
|
SlintPowerZones::KeyboardAndLightbar => PowerZones::KeyboardAndLightbar,
|
||||||
SlintPowerZones::Ally => PowerZones::Ally
|
SlintPowerZones::Ally => PowerZones::Ally,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,7 @@ impl From<SlintAuraPowerState> for AuraPowerState {
|
|||||||
boot: value.boot,
|
boot: value.boot,
|
||||||
awake: value.awake,
|
awake: value.awake,
|
||||||
sleep: value.sleep,
|
sleep: value.sleep,
|
||||||
shutdown: value.shutdown
|
shutdown: value.shutdown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,7 +106,7 @@ impl From<AuraPowerState> for SlintAuraPowerState {
|
|||||||
sleep: value.sleep,
|
sleep: value.sleep,
|
||||||
shutdown: value.shutdown,
|
shutdown: value.shutdown,
|
||||||
zone,
|
zone,
|
||||||
zone_name_idx: zone as i32
|
zone_name_idx: zone as i32,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ impl From<&AuraPowerState> for SlintAuraPowerState {
|
|||||||
sleep: value.sleep,
|
sleep: value.sleep,
|
||||||
shutdown: value.shutdown,
|
shutdown: value.shutdown,
|
||||||
zone,
|
zone,
|
||||||
zone_name_idx: zone as i32
|
zone_name_idx: zone as i32,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@ impl From<LaptopAuraPower> for SlintLaptopAuraPower {
|
|||||||
let converted: Vec<SlintAuraPowerState> =
|
let converted: Vec<SlintAuraPowerState> =
|
||||||
value.states.iter().map(SlintAuraPowerState::from).collect();
|
value.states.iter().map(SlintAuraPowerState::from).collect();
|
||||||
Self {
|
Self {
|
||||||
states: ModelRc::from(converted.as_slice())
|
states: ModelRc::from(converted.as_slice()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,7 +154,7 @@ impl From<SlintDeviceType> for AuraDeviceType {
|
|||||||
SlintDeviceType::ScsiExtDisk => Self::ScsiExtDisk,
|
SlintDeviceType::ScsiExtDisk => Self::ScsiExtDisk,
|
||||||
SlintDeviceType::Unknown => Self::Unknown,
|
SlintDeviceType::Unknown => Self::Unknown,
|
||||||
SlintDeviceType::Ally => Self::Ally,
|
SlintDeviceType::Ally => Self::Ally,
|
||||||
SlintDeviceType::AnimeOrSlash => Self::AnimeOrSlash
|
SlintDeviceType::AnimeOrSlash => Self::AnimeOrSlash,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,7 +168,7 @@ impl From<AuraDeviceType> for SlintDeviceType {
|
|||||||
AuraDeviceType::ScsiExtDisk => SlintDeviceType::ScsiExtDisk,
|
AuraDeviceType::ScsiExtDisk => SlintDeviceType::ScsiExtDisk,
|
||||||
AuraDeviceType::Unknown => SlintDeviceType::Unknown,
|
AuraDeviceType::Unknown => SlintDeviceType::Unknown,
|
||||||
AuraDeviceType::Ally => SlintDeviceType::Ally,
|
AuraDeviceType::Ally => SlintDeviceType::Ally,
|
||||||
AuraDeviceType::AnimeOrSlash => SlintDeviceType::AnimeOrSlash
|
AuraDeviceType::AnimeOrSlash => SlintDeviceType::AnimeOrSlash,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ impl From<Profile> for PlatformProfile {
|
|||||||
match value {
|
match value {
|
||||||
Profile::Balanced => PlatformProfile::Balanced,
|
Profile::Balanced => PlatformProfile::Balanced,
|
||||||
Profile::Performance => PlatformProfile::Performance,
|
Profile::Performance => PlatformProfile::Performance,
|
||||||
Profile::Quiet => PlatformProfile::Quiet
|
Profile::Quiet => PlatformProfile::Quiet,
|
||||||
|
Profile::LowPower => PlatformProfile::LowPower,
|
||||||
|
Profile::Custom => PlatformProfile::Custom,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,7 +20,9 @@ impl From<PlatformProfile> for Profile {
|
|||||||
match value {
|
match value {
|
||||||
PlatformProfile::Balanced => Profile::Balanced,
|
PlatformProfile::Balanced => Profile::Balanced,
|
||||||
PlatformProfile::Performance => Profile::Performance,
|
PlatformProfile::Performance => Profile::Performance,
|
||||||
PlatformProfile::Quiet => Profile::Quiet
|
PlatformProfile::Quiet => Profile::Quiet,
|
||||||
|
PlatformProfile::LowPower => Profile::LowPower,
|
||||||
|
PlatformProfile::Custom => Profile::Custom,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,7 +32,7 @@ impl From<FanType> for FanCurvePU {
|
|||||||
match value {
|
match value {
|
||||||
FanType::CPU => FanCurvePU::CPU,
|
FanType::CPU => FanCurvePU::CPU,
|
||||||
FanType::Middle => FanCurvePU::MID,
|
FanType::Middle => FanCurvePU::MID,
|
||||||
FanType::GPU => FanCurvePU::GPU
|
FanType::GPU => FanCurvePU::GPU,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,7 +42,7 @@ impl From<FanCurvePU> for FanType {
|
|||||||
match value {
|
match value {
|
||||||
FanCurvePU::CPU => FanType::CPU,
|
FanCurvePU::CPU => FanType::CPU,
|
||||||
FanCurvePU::GPU => FanType::GPU,
|
FanCurvePU::GPU => FanType::GPU,
|
||||||
FanCurvePU::MID => FanType::Middle
|
FanCurvePU::MID => FanType::Middle,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ macro_rules! set_ui_callbacks {
|
|||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut x = proxy_copy.receive().await;
|
let mut x = proxy_copy.receive().await;
|
||||||
concat_idents::concat_idents!(set = set_, $proxy_fn {
|
concat_idents::concat_idents!(set = set_, $proxy_fn {
|
||||||
use zbus::export::futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
while let Some(e) = x.next().await {
|
while let Some(e) = x.next().await {
|
||||||
if let Ok(out) = e.get().await {
|
if let Ok(out) = e.get().await {
|
||||||
handle_copy.upgrade_in_event_loop(move |handle| {
|
handle_copy.upgrade_in_event_loop(move |handle| {
|
||||||
@@ -68,7 +68,7 @@ pub fn show_toast(
|
|||||||
success: SharedString,
|
success: SharedString,
|
||||||
fail: SharedString,
|
fail: SharedString,
|
||||||
handle: Weak<MainWindow>,
|
handle: Weak<MainWindow>,
|
||||||
result: zbus::Result<()>
|
result: zbus::Result<()>,
|
||||||
) {
|
) {
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
@@ -78,7 +78,7 @@ pub fn show_toast(
|
|||||||
log::warn!("{fail}: {e}");
|
log::warn!("{fail}: {e}");
|
||||||
handle.unwrap().invoke_show_toast(fail)
|
handle.unwrap().invoke_show_toast(fail)
|
||||||
})
|
})
|
||||||
.ok()
|
.ok(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,8 +86,13 @@ pub fn setup_window(config: Arc<Mutex<Config>>) -> MainWindow {
|
|||||||
slint::set_xdg_app_id("rog-control-center")
|
slint::set_xdg_app_id("rog-control-center")
|
||||||
.map_err(|e| warn!("Couldn't set application ID: {e:?}"))
|
.map_err(|e| warn!("Couldn't set application ID: {e:?}"))
|
||||||
.ok();
|
.ok();
|
||||||
let ui = MainWindow::new().unwrap();
|
let ui = MainWindow::new()
|
||||||
ui.window().show().unwrap();
|
.map_err(|e| warn!("Couldn't create main window: {e:?}"))
|
||||||
|
.unwrap();
|
||||||
|
ui.window()
|
||||||
|
.show()
|
||||||
|
.map_err(|e| warn!("Couldn't show main window: {e:?}"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let available = list_iface_blocking().unwrap_or_default();
|
let available = list_iface_blocking().unwrap_or_default();
|
||||||
ui.set_sidebar_items_avilable(
|
ui.set_sidebar_items_avilable(
|
||||||
@@ -98,9 +103,9 @@ pub fn setup_window(config: Arc<Mutex<Config>>) -> MainWindow {
|
|||||||
available.contains(&"xyz.ljones.Anime".to_string()),
|
available.contains(&"xyz.ljones.Anime".to_string()),
|
||||||
available.contains(&"xyz.ljones.FanCurves".to_string()),
|
available.contains(&"xyz.ljones.FanCurves".to_string()),
|
||||||
true,
|
true,
|
||||||
true
|
true,
|
||||||
]
|
]
|
||||||
.into()
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
||||||
ui.on_exit_app(move || {
|
ui.on_exit_app(move || {
|
||||||
|
|||||||
@@ -51,9 +51,9 @@ pub fn setup_anime_page(ui: &MainWindow, _states: Arc<Mutex<Config>>) {
|
|||||||
boot: boot.into(),
|
boot: boot.into(),
|
||||||
awake: awake.into(),
|
awake: awake.into(),
|
||||||
sleep: sleep.into(),
|
sleep: sleep.into(),
|
||||||
shutdown: shutdown.into()
|
shutdown: shutdown.into(),
|
||||||
})
|
})
|
||||||
.await
|
.await,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -62,7 +62,7 @@ pub fn setup_anime_page(ui: &MainWindow, _states: Arc<Mutex<Config>>) {
|
|||||||
let anime_copy = anime.clone();
|
let anime_copy = anime.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut x = anime_copy.receive_builtin_animations_changed().await;
|
let mut x = anime_copy.receive_builtin_animations_changed().await;
|
||||||
use zbus::export::futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
while let Some(e) = x.next().await {
|
while let Some(e) = x.next().await {
|
||||||
if let Ok(out) = e.get().await {
|
if let Ok(out) = e.get().await {
|
||||||
handle_copy
|
handle_copy
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use slint::{ComponentHandle, Model, RgbaColor, SharedString};
|
|||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::ui::show_toast;
|
use crate::ui::show_toast;
|
||||||
use crate::{
|
use crate::{
|
||||||
set_ui_callbacks, set_ui_props_async, AuraPageData, MainWindow, PowerZones as SlintPowerZones
|
set_ui_callbacks, set_ui_props_async, AuraPageData, MainWindow, PowerZones as SlintPowerZones,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn decode_hex(s: &str) -> RgbaColor<u8> {
|
fn decode_hex(s: &str) -> RgbaColor<u8> {
|
||||||
@@ -19,7 +19,7 @@ fn decode_hex(s: &str) -> RgbaColor<u8> {
|
|||||||
alpha: 255,
|
alpha: 255,
|
||||||
red: 0,
|
red: 0,
|
||||||
green: 0,
|
green: 0,
|
||||||
blue: 0
|
blue: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let c: Vec<u8> = (0..s.len())
|
let c: Vec<u8> = (0..s.len())
|
||||||
@@ -30,7 +30,7 @@ fn decode_hex(s: &str) -> RgbaColor<u8> {
|
|||||||
alpha: 255,
|
alpha: 255,
|
||||||
red: *c.first().unwrap_or(&255),
|
red: *c.first().unwrap_or(&255),
|
||||||
green: *c.get(1).unwrap_or(&128),
|
green: *c.get(1).unwrap_or(&128),
|
||||||
blue: *c.get(2).unwrap_or(&32)
|
blue: *c.get(2).unwrap_or(&32),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ pub fn setup_aura_page(ui: &MainWindow, _states: Arc<Mutex<Config>>) {
|
|||||||
"Aura power settings changed".into(),
|
"Aura power settings changed".into(),
|
||||||
"Failed to set Aura power settings".into(),
|
"Failed to set Aura power settings".into(),
|
||||||
handle_copy,
|
handle_copy,
|
||||||
proxy_copy.set_led_power(power).await
|
proxy_copy.set_led_power(power).await,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -211,7 +211,7 @@ pub fn setup_aura_page(ui: &MainWindow, _states: Arc<Mutex<Config>>) {
|
|||||||
// spawn required since the while let never exits
|
// spawn required since the while let never exits
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut x = proxy_copy.receive_led_mode_data_changed().await;
|
let mut x = proxy_copy.receive_led_mode_data_changed().await;
|
||||||
use zbus::export::futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
while let Some(e) = x.next().await {
|
while let Some(e) = x.next().await {
|
||||||
if let Ok(out) = e.get().await {
|
if let Ok(out) = e.get().await {
|
||||||
handle_copy
|
handle_copy
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user